Merge remote-tracking branch 'origin/master' into identity_abe
[oweals/gnunet.git] / src / identity-provider / plugin_gnsrecord_identity_provider.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2013, 2014 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file identity/plugin_gnsrecord_identity.c
23  * @brief gnsrecord plugin to provide the API for identity records
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_gnsrecord_lib.h"
29 #include "gnunet_gnsrecord_plugin.h"
30
31
32 /**
33  * Convert the 'value' of a record to a string.
34  *
35  * @param cls closure, unused
36  * @param type type of the record
37  * @param data value in binary encoding
38  * @param data_size number of bytes in @a data
39  * @return NULL on error, otherwise human-readable representation of the value
40  */
41 static char *
42 value_to_string (void *cls,
43                  uint32_t type,
44                  const void *data,
45                  size_t data_size)
46 {
47   const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
48   const struct GNUNET_CRYPTO_EcdsaPublicKey *audience_pubkey;
49   const char *scopes;
50   char *ecdhe_str;
51   char *aud_str;
52   char *result;
53
54   switch (type)
55   {
56     case GNUNET_GNSRECORD_TYPE_ID_ATTR:
57       return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
58     case GNUNET_GNSRECORD_TYPE_ID_TOKEN: //DEPRECATED
59       return GNUNET_strndup (data, data_size);
60     case GNUNET_GNSRECORD_TYPE_ABE_KEY:
61     case GNUNET_GNSRECORD_TYPE_ABE_MASTER:
62       return GNUNET_STRINGS_data_to_string_alloc (data, data_size); 
63     case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA: //DEPRECATED
64         ecdhe_privkey = data;
65         audience_pubkey = data+sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
66         scopes =  (char*) audience_pubkey+(sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
67         ecdhe_str = GNUNET_STRINGS_data_to_string_alloc (ecdhe_privkey,
68                                                         sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
69         aud_str = GNUNET_STRINGS_data_to_string_alloc (audience_pubkey,
70                                                        sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
71         GNUNET_asprintf (&result,
72                          "%s;%s;%s",
73                          ecdhe_str, aud_str, scopes);
74         GNUNET_free (aud_str);
75         GNUNET_free (ecdhe_str);
76         return result;
77
78     default:
79       return NULL;
80   }
81 }
82
83
84 /**
85  * Convert human-readable version of a 'value' of a record to the binary
86  * representation.
87  *
88  * @param cls closure, unused
89  * @param type type of the record
90  * @param s human-readable string
91  * @param data set to value in binary encoding (will be allocated)
92  * @param data_size set to number of bytes in @a data
93  * @return #GNUNET_OK on success
94  */
95 static int
96 string_to_value (void *cls,
97                  uint32_t type,
98                  const char *s,
99                  void **data,
100                  size_t *data_size)
101 {
102   char* ecdhe_str;
103   char* aud_keystr;
104   char* write_ptr;
105   char* tmp_tok;
106   char* str;
107
108   if (NULL == s)
109     return GNUNET_SYSERR;
110   switch (type)
111   {
112     case GNUNET_GNSRECORD_TYPE_ID_ATTR:
113       return GNUNET_STRINGS_string_to_data (s,
114                                             strlen (s),
115                                             *data,
116                                             *data_size);
117     case GNUNET_GNSRECORD_TYPE_ID_TOKEN:
118       *data = GNUNET_strdup (s);
119       *data_size = strlen (s);
120       return GNUNET_OK;
121     case GNUNET_GNSRECORD_TYPE_ABE_KEY:
122     case GNUNET_GNSRECORD_TYPE_ABE_MASTER:
123       return GNUNET_STRINGS_string_to_data (s,
124                                             strlen (s),
125                                             *data,
126                                             *data_size);
127     case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA:
128       tmp_tok = GNUNET_strdup (s);
129       ecdhe_str = strtok (tmp_tok, ";");
130       if (NULL == ecdhe_str)
131       {
132         GNUNET_free (tmp_tok);
133         return GNUNET_SYSERR;
134       }
135       aud_keystr = strtok (NULL, ";");
136       if (NULL == aud_keystr)
137       {
138         GNUNET_free (tmp_tok);
139         return GNUNET_SYSERR;
140       }
141       str = strtok (NULL, ";");
142       if (NULL == str)
143       {
144         GNUNET_free (tmp_tok);
145         return GNUNET_SYSERR;
146       }
147       *data_size = strlen (str) + 1
148         +sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
149         +sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
150       *data = GNUNET_malloc (*data_size);
151
152       write_ptr = *data;
153       GNUNET_STRINGS_string_to_data (ecdhe_str,
154                                      strlen (ecdhe_str),
155                                      write_ptr,
156                                      sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
157       write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
158       GNUNET_STRINGS_string_to_data (aud_keystr,
159                                      strlen (aud_keystr),
160                                      write_ptr,
161                                      sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
162       write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
163       GNUNET_memcpy (write_ptr, str, strlen (str) + 1); //with 0-Terminator
164       GNUNET_free (tmp_tok);
165       return GNUNET_OK;
166
167     default:
168       return GNUNET_SYSERR;
169   }
170 }
171
172
173 /**
174  * Mapping of record type numbers to human-readable
175  * record type names.
176  */
177 static struct {
178   const char *name;
179   uint32_t number;
180 } name_map[] = {
181   { "ID_ATTR", GNUNET_GNSRECORD_TYPE_ID_ATTR },
182   { "ID_TOKEN", GNUNET_GNSRECORD_TYPE_ID_TOKEN },
183   { "ABE_KEY", GNUNET_GNSRECORD_TYPE_ABE_KEY },
184   { "ABE_MASTER", GNUNET_GNSRECORD_TYPE_ABE_MASTER },
185   { "ID_TOKEN_METADATA", GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA },
186   { NULL, UINT32_MAX }
187 };
188
189
190 /**
191  * Convert a type name (i.e. "AAAA") to the corresponding number.
192  *
193  * @param cls closure, unused
194  * @param dns_typename name to convert
195  * @return corresponding number, UINT32_MAX on error
196  */
197 static uint32_t
198 typename_to_number (void *cls,
199                     const char *dns_typename)
200 {
201   unsigned int i;
202
203   i=0;
204   while ( (NULL != name_map[i].name) &&
205           (0 != strcasecmp (dns_typename, name_map[i].name)) )
206     i++;
207   return name_map[i].number;
208 }
209
210
211 /**
212  * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
213  *
214  * @param cls closure, unused
215  * @param type number of a type to convert
216  * @return corresponding typestring, NULL on error
217  */
218 static const char *
219 number_to_typename (void *cls,
220                     uint32_t type)
221 {
222   unsigned int i;
223
224   i=0;
225   while ( (NULL != name_map[i].name) &&
226           (type != name_map[i].number) )
227     i++;
228   return name_map[i].name;
229 }
230
231
232 /**
233  * Entry point for the plugin.
234  *
235  * @param cls NULL
236  * @return the exported block API
237  */
238 void *
239 libgnunet_plugin_gnsrecord_identity_provider_init (void *cls)
240 {
241   struct GNUNET_GNSRECORD_PluginFunctions *api;
242
243   api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
244   api->value_to_string = &value_to_string;
245   api->string_to_value = &string_to_value;
246   api->typename_to_number = &typename_to_number;
247   api->number_to_typename = &number_to_typename;
248   return api;
249 }
250
251
252 /**
253  * Exit point from the plugin.
254  *
255  * @param cls the return value from #libgnunet_plugin_block_test_init
256  * @return NULL
257  */
258 void *
259 libgnunet_plugin_gnsrecord_identity_provider_done (void *cls)
260 {
261   struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
262
263   GNUNET_free (api);
264   return NULL;
265 }
266
267 /* end of plugin_gnsrecord_dns.c */