ftbfs
[oweals/gnunet.git] / src / reclaim / json_reclaim.c
1 /*
2    This file is part of GNUnet.
3    Copyright (C) 2009-2018 GNUnet e.V.
4
5    GNUnet is free software: you can redistribute it and/or modify it
6    under the terms of the GNU Affero General Public License as published
7    by the Free Software Foundation, either version 3 of the License,
8    or (at your 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    Affero General Public License for more details.
14
15    You should have received a copy of the GNU Affero General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18    SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file rest-plugins/json_reclaim.c
23  * @brief JSON handling of reclaim data
24  * @author Martin Schanzenbach
25  */
26 #include "platform.h"
27
28 #include "gnunet_util_lib.h"
29
30 #include "gnunet_json_lib.h"
31 #include "gnunet_reclaim_lib.h"
32 #include "gnunet_reclaim_service.h"
33
34
35 /**
36  * Parse given JSON object to a claim
37  *
38  * @param cls closure, NULL
39  * @param root the json object representing data
40  * @param spec where to write the data
41  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
42  */
43 static int
44 parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
45 {
46   struct GNUNET_RECLAIM_Attribute *attr;
47   const char *name_str = NULL;
48   const char *val_str = NULL;
49   const char *type_str = NULL;
50   const char *id_str = NULL;
51   const char *attest_str = NULL;
52   const char *flag_str = NULL;
53   char *data;
54   int unpack_state;
55   uint32_t type;
56   size_t data_size;
57
58   GNUNET_assert (NULL != root);
59
60   if (! json_is_object (root))
61   {
62     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
63                 "Error json is not array nor object!\n");
64     return GNUNET_SYSERR;
65   }
66   // interpret single attribute
67   unpack_state = json_unpack (root,
68                               "{s:s, s?s, s?s, s:s, s:s, s?s!}",
69                               "name",
70                               &name_str,
71                               "id",
72                               &id_str,
73                               "attestation",
74                               &attest_str,
75                               "type",
76                               &type_str,
77                               "value",
78                               &val_str,
79                               "flag",
80                               &flag_str);
81   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
82       (NULL == type_str))
83   {
84     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
85                 "Error json object has a wrong format!\n");
86     return GNUNET_SYSERR;
87   }
88   type = GNUNET_RECLAIM_attribute_typename_to_number (type_str);
89   if (GNUNET_SYSERR ==
90       (GNUNET_RECLAIM_attribute_string_to_value (type,
91                                                  val_str,
92                                                  (void **) &data,
93                                                  &data_size)))
94   {
95     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute value invalid!\n");
96     return GNUNET_SYSERR;
97   }
98   attr = GNUNET_RECLAIM_attribute_new (name_str, NULL,
99                                        type, data, data_size);
100   if ((NULL != attest_str) && (0 != strlen (attest_str)))
101   {
102      GNUNET_STRINGS_string_to_data (attest_str,
103                                    strlen (attest_str),
104                                    &attr->attestation,
105                                    sizeof(attr->attestation));
106   }
107   if ((NULL == id_str) || (0 == strlen (id_str)))
108     memset (&attr->id, 0, sizeof (attr->id));
109   else
110     GNUNET_STRINGS_string_to_data (id_str,
111                                    strlen (id_str),
112                                    &attr->id,
113                                    sizeof(attr->id));
114
115   *(struct GNUNET_RECLAIM_Attribute **) spec->ptr = attr;
116   return GNUNET_OK;
117 }
118
119
120 /**
121  * Cleanup data left from parsing RSA public key.
122  *
123  * @param cls closure, NULL
124  * @param[out] spec where to free the data
125  */
126 static void
127 clean_attr (void *cls, struct GNUNET_JSON_Specification *spec)
128 {
129   struct GNUNET_RECLAIM_Attribute **attr;
130
131   attr = (struct GNUNET_RECLAIM_Attribute **) spec->ptr;
132   if (NULL != *attr)
133   {
134     GNUNET_free (*attr);
135     *attr = NULL;
136   }
137 }
138
139
140 /**
141  * JSON Specification for Reclaim claims.
142  *
143  * @param ticket struct of GNUNET_RECLAIM_Attribute to fill
144  * @return JSON Specification
145  */
146 struct GNUNET_JSON_Specification
147 GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_Attribute **attr)
148 {
149   struct GNUNET_JSON_Specification ret = { .parser = &parse_attr,
150                                            .cleaner = &clean_attr,
151                                            .cls = NULL,
152                                            .field = NULL,
153                                            .ptr = attr,
154                                            .ptr_size = 0,
155                                            .size_ptr = NULL };
156
157   *attr = NULL;
158   return ret;
159 }
160
161
162 /**
163  * Parse given JSON object to a ticket
164  *
165  * @param cls closure, NULL
166  * @param root the json object representing data
167  * @param spec where to write the data
168  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
169  */
170 static int
171 parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
172 {
173   struct GNUNET_RECLAIM_Ticket *ticket;
174   const char *rnd_str;
175   const char *aud_str;
176   const char *id_str;
177   int unpack_state;
178
179   GNUNET_assert (NULL != root);
180
181   if (! json_is_object (root))
182   {
183     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
184                 "Error json is not array nor object!\n");
185     return GNUNET_SYSERR;
186   }
187   // interpret single ticket
188   unpack_state = json_unpack (root,
189                               "{s:s, s:s, s:s!}",
190                               "rnd",
191                               &rnd_str,
192                               "audience",
193                               &aud_str,
194                               "issuer",
195                               &id_str);
196   if (0 != unpack_state)
197   {
198     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
199                 "Error json object has a wrong format!\n");
200     return GNUNET_SYSERR;
201   }
202   ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
203   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str,
204                                                   strlen (rnd_str),
205                                                   &ticket->rnd,
206                                                   sizeof(ticket->rnd)))
207   {
208     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rnd invalid\n");
209     GNUNET_free (ticket);
210     return GNUNET_SYSERR;
211   }
212   if (GNUNET_OK !=
213       GNUNET_STRINGS_string_to_data (id_str,
214                                      strlen (id_str),
215                                      &ticket->identity,
216                                      sizeof(
217                                        struct GNUNET_CRYPTO_EcdsaPublicKey)))
218   {
219     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity invalid\n");
220     GNUNET_free (ticket);
221     return GNUNET_SYSERR;
222   }
223
224   if (GNUNET_OK !=
225       GNUNET_STRINGS_string_to_data (aud_str,
226                                      strlen (aud_str),
227                                      &ticket->audience,
228                                      sizeof(struct
229                                             GNUNET_CRYPTO_EcdsaPublicKey)))
230   {
231     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience invalid\n");
232     GNUNET_free (ticket);
233     return GNUNET_SYSERR;
234   }
235
236   *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket;
237   return GNUNET_OK;
238 }
239
240
241 /**
242  * Cleanup data left from parsing RSA public key.
243  *
244  * @param cls closure, NULL
245  * @param[out] spec where to free the data
246  */
247 static void
248 clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
249 {
250   struct GNUNET_RECLAIM_Ticket **ticket;
251
252   ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr;
253   if (NULL != *ticket)
254   {
255     GNUNET_free (*ticket);
256     *ticket = NULL;
257   }
258 }
259
260
261 /**
262  * JSON Specification for Reclaim tickets.
263  *
264  * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
265  * @return JSON Specification
266  */
267 struct GNUNET_JSON_Specification
268 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
269 {
270   struct GNUNET_JSON_Specification ret = { .parser = &parse_ticket,
271                                            .cleaner = &clean_ticket,
272                                            .cls = NULL,
273                                            .field = NULL,
274                                            .ptr = ticket,
275                                            .ptr_size = 0,
276                                            .size_ptr = NULL };
277
278   *ticket = NULL;
279   return ret;
280 }
281
282 /**
283    * Parse given JSON object to an attestation claim
284    *
285    * @param cls closure, NULL
286    * @param root the json object representing data
287    * @param spec where to write the data
288    * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
289    */
290 static int
291 parse_attest (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
292 {
293   struct GNUNET_RECLAIM_Attestation *attr;
294   const char *name_str = NULL;
295   const char *val_str = NULL;
296   const char *type_str = NULL;
297   const char *id_str = NULL;
298   char *data;
299   int unpack_state;
300   uint32_t type;
301   size_t data_size;
302
303   GNUNET_assert (NULL != root);
304
305   if (! json_is_object (root))
306   {
307     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
308                 "Error json is not array nor object!\n");
309     return GNUNET_SYSERR;
310   }
311   // interpret single attribute
312   unpack_state = json_unpack (root,
313                               "{s:s, s?s, s:s, s:s!}",
314                               "name",
315                               &name_str,
316                               "id",
317                               &id_str,
318                               "type",
319                               &type_str,
320                               "value",
321                               &val_str);
322   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
323       (NULL == type_str))
324   {
325     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
326                 "Error json object has a wrong format!\n");
327     return GNUNET_SYSERR;
328   }
329   type = GNUNET_RECLAIM_attestation_typename_to_number (type_str);
330   if (GNUNET_SYSERR ==
331       (GNUNET_RECLAIM_attestation_string_to_value (type,
332                                                    val_str,
333                                                    (void **) &data,
334                                                    &data_size)))
335   {
336     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attestation value invalid!\n");
337     return GNUNET_SYSERR;
338   }
339   attr = GNUNET_RECLAIM_attestation_new (name_str, type, data, data_size);
340   if ((NULL == id_str) || (0 == strlen (id_str)))
341     memset (&attr->id, 0, sizeof (attr->id));
342   else
343     GNUNET_STRINGS_string_to_data (id_str,
344                                    strlen (id_str),
345                                    &attr->id,
346                                    sizeof(attr->id));
347
348   *(struct GNUNET_RECLAIM_Attestation **) spec->ptr = attr;
349   return GNUNET_OK;
350 }
351
352 /**
353  * Cleanup data left from parsing RSA public key.
354  *
355  * @param cls closure, NULL
356  * @param[out] spec where to free the data
357  */
358 static void
359 clean_attest (void *cls, struct GNUNET_JSON_Specification *spec)
360 {
361   struct GNUNET_RECLAIM_Attestation **attr;
362
363   attr = (struct GNUNET_RECLAIM_Attestation **) spec->ptr;
364   if (NULL != *attr)
365   {
366     GNUNET_free (*attr);
367     *attr = NULL;
368   }
369 }
370 /**
371  * JSON Specification for Reclaim attestation claims.
372  *
373  * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
374  * @return JSON Specification
375  */
376 struct GNUNET_JSON_Specification
377 GNUNET_RECLAIM_JSON_spec_claim_attest (struct
378                                        GNUNET_RECLAIM_Attestation **attr)
379 {
380   struct GNUNET_JSON_Specification ret = { .parser = &parse_attest,
381                                            .cleaner = &clean_attest,
382                                            .cls = NULL,
383                                            .field = NULL,
384                                            .ptr = attr,
385                                            .ptr_size = 0,
386                                            .size_ptr = NULL };
387
388   *attr = NULL;
389   return ret;
390 }
391