use NULL value in load_path_suffix to NOT load any files
[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_attribute_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_Claim *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 *flag_str = NULL;
52   char *data;
53   int unpack_state;
54   uint32_t type;
55   size_t data_size;
56
57   GNUNET_assert (NULL != root);
58
59   if (! json_is_object (root))
60   {
61     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
62                 "Error json is not array nor object!\n");
63     return GNUNET_SYSERR;
64   }
65   // interpret single attribute
66   unpack_state = json_unpack (root,
67                               "{s:s, s?s, s:s, s:s, s?s!}",
68                               "name",
69                               &name_str,
70                               "id",
71                               &id_str,
72                               "type",
73                               &type_str,
74                               "value",
75                               &val_str,
76                               "flag",
77                               &flag_str);
78   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
79       (NULL == type_str))
80   {
81     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
82                 "Error json object has a wrong format!\n");
83     return GNUNET_SYSERR;
84   }
85   type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
86   if (GNUNET_SYSERR ==
87       (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
88                                                  val_str,
89                                                  (void **) &data,
90                                                  &data_size)))
91   {
92     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute value invalid!\n");
93     return GNUNET_SYSERR;
94   }
95   attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str, type, data, data_size);
96   if ((NULL == id_str) || (0 == strlen (id_str)))
97     attr->id = 0;
98   else
99     GNUNET_STRINGS_string_to_data (id_str,
100                                    strlen (id_str),
101                                    &attr->id,
102                                    sizeof(uint64_t));
103
104   *(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr = attr;
105   return GNUNET_OK;
106 }
107
108
109 /**
110  * Cleanup data left from parsing RSA public key.
111  *
112  * @param cls closure, NULL
113  * @param[out] spec where to free the data
114  */
115 static void
116 clean_attr (void *cls, struct GNUNET_JSON_Specification *spec)
117 {
118   struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr;
119
120   attr = (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr;
121   if (NULL != *attr)
122   {
123     GNUNET_free (*attr);
124     *attr = NULL;
125   }
126 }
127
128
129 /**
130  * JSON Specification for Reclaim claims.
131  *
132  * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill
133  * @return JSON Specification
134  */
135 struct GNUNET_JSON_Specification
136 GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr)
137 {
138   struct GNUNET_JSON_Specification ret = { .parser = &parse_attr,
139                                            .cleaner = &clean_attr,
140                                            .cls = NULL,
141                                            .field = NULL,
142                                            .ptr = attr,
143                                            .ptr_size = 0,
144                                            .size_ptr = NULL };
145
146   *attr = NULL;
147   return ret;
148 }
149
150
151 /**
152  * Parse given JSON object to a ticket
153  *
154  * @param cls closure, NULL
155  * @param root the json object representing data
156  * @param spec where to write the data
157  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
158  */
159 static int
160 parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
161 {
162   struct GNUNET_RECLAIM_Ticket *ticket;
163   const char *rnd_str;
164   const char *aud_str;
165   const char *id_str;
166   int unpack_state;
167
168   GNUNET_assert (NULL != root);
169
170   if (! json_is_object (root))
171   {
172     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
173                 "Error json is not array nor object!\n");
174     return GNUNET_SYSERR;
175   }
176   // interpret single ticket
177   unpack_state = json_unpack (root,
178                               "{s:s, s:s, s:s!}",
179                               "rnd",
180                               &rnd_str,
181                               "audience",
182                               &aud_str,
183                               "issuer",
184                               &id_str);
185   if (0 != unpack_state)
186   {
187     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
188                 "Error json object has a wrong format!\n");
189     return GNUNET_SYSERR;
190   }
191   ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
192   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str,
193                                                   strlen (rnd_str),
194                                                   &ticket->rnd,
195                                                   sizeof(uint64_t)))
196   {
197     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rnd invalid\n");
198     GNUNET_free (ticket);
199     return GNUNET_SYSERR;
200   }
201   if (GNUNET_OK !=
202       GNUNET_STRINGS_string_to_data (id_str,
203                                      strlen (id_str),
204                                      &ticket->identity,
205                                      sizeof(
206                                        struct GNUNET_CRYPTO_EcdsaPublicKey)))
207   {
208     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity invalid\n");
209     GNUNET_free (ticket);
210     return GNUNET_SYSERR;
211   }
212
213   if (GNUNET_OK !=
214       GNUNET_STRINGS_string_to_data (aud_str,
215                                      strlen (aud_str),
216                                      &ticket->audience,
217                                      sizeof(struct
218                                             GNUNET_CRYPTO_EcdsaPublicKey)))
219   {
220     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience invalid\n");
221     GNUNET_free (ticket);
222     return GNUNET_SYSERR;
223   }
224
225   *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket;
226   return GNUNET_OK;
227 }
228
229
230 /**
231  * Cleanup data left from parsing RSA public key.
232  *
233  * @param cls closure, NULL
234  * @param[out] spec where to free the data
235  */
236 static void
237 clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
238 {
239   struct GNUNET_RECLAIM_Ticket **ticket;
240
241   ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr;
242   if (NULL != *ticket)
243   {
244     GNUNET_free (*ticket);
245     *ticket = NULL;
246   }
247 }
248
249
250 /**
251  * JSON Specification for Reclaim tickets.
252  *
253  * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
254  * @return JSON Specification
255  */
256 struct GNUNET_JSON_Specification
257 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
258 {
259   struct GNUNET_JSON_Specification ret = { .parser = &parse_ticket,
260                                            .cleaner = &clean_ticket,
261                                            .cls = NULL,
262                                            .field = NULL,
263                                            .ptr = ticket,
264                                            .ptr_size = 0,
265                                            .size_ptr = NULL };
266
267   *ticket = NULL;
268   return ret;
269 }
270
271 /**
272    * Parse given JSON object to an attestation claim
273    *
274    * @param cls closure, NULL
275    * @param root the json object representing data
276    * @param spec where to write the data
277    * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
278    */
279 static int
280 parse_attest (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
281 {
282   struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
283   const char *name_str = NULL;
284   const char *val_str = NULL;
285   const char *type_str = NULL;
286   const char *id_str = NULL;
287   char *data;
288   int unpack_state;
289   uint32_t type;
290   size_t data_size;
291
292   GNUNET_assert (NULL != root);
293
294   if (! json_is_object (root))
295   {
296     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
297                 "Error json is not array nor object!\n");
298     return GNUNET_SYSERR;
299   }
300   // interpret single attribute
301   unpack_state = json_unpack (root,
302                               "{s:s, s?s, s:s, s:s!}",
303                               "name",
304                               &name_str,
305                               "id",
306                               &id_str,
307                               "type",
308                               &type_str,
309                               "value",
310                               &val_str);
311   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
312       (NULL == type_str))
313   {
314     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
315                 "Error json object has a wrong format!\n");
316     return GNUNET_SYSERR;
317   }
318   type = GNUNET_RECLAIM_ATTESTATION_typename_to_number (type_str);
319   if (GNUNET_SYSERR ==
320       (GNUNET_RECLAIM_ATTESTATION_string_to_value (type,
321                                                    val_str,
322                                                    (void **) &data,
323                                                    &data_size)))
324   {
325     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attestation value invalid!\n");
326     return GNUNET_SYSERR;
327   }
328   attr = GNUNET_RECLAIM_ATTESTATION_claim_new (name_str, type, data, data_size);
329   if ((NULL == id_str) || (0 == strlen (id_str)))
330     attr->id = 0;
331   else
332     GNUNET_STRINGS_string_to_data (id_str,
333                                    strlen (id_str),
334                                    &attr->id,
335                                    sizeof(uint64_t));
336
337   *(struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr = attr;
338   return GNUNET_OK;
339 }
340
341 /**
342  * Cleanup data left from parsing RSA public key.
343  *
344  * @param cls closure, NULL
345  * @param[out] spec where to free the data
346  */
347 static void
348 clean_attest (void *cls, struct GNUNET_JSON_Specification *spec)
349 {
350   struct GNUNET_RECLAIM_ATTESTATION_Claim **attr;
351
352   attr = (struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr;
353   if (NULL != *attr)
354   {
355     GNUNET_free (*attr);
356     *attr = NULL;
357   }
358 }
359 /**
360  * JSON Specification for Reclaim attestation claims.
361  *
362  * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
363  * @return JSON Specification
364  */
365 struct GNUNET_JSON_Specification
366 GNUNET_RECLAIM_JSON_spec_claim_attest (struct
367                                        GNUNET_RECLAIM_ATTESTATION_Claim **attr)
368 {
369   struct GNUNET_JSON_Specification ret = { .parser = &parse_attest,
370                                            .cleaner = &clean_attest,
371                                            .cls = NULL,
372                                            .field = NULL,
373                                            .ptr = attr,
374                                            .ptr_size = 0,
375                                            .size_ptr = NULL };
376
377   *attr = NULL;
378   return ret;
379 }
380
381 /**
382    * Parse given JSON object to an attestation claim
383    *
384    * @param cls closure, NULL
385    * @param root the json object representing data
386    * @param spec where to write the data
387    * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
388    */
389 static int
390 parse_attest_ref (void *cls, json_t *root, struct
391                   GNUNET_JSON_Specification *spec)
392 {
393   struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
394   const char *name_str = NULL;
395   const char *ref_val_str = NULL;
396   const char *ref_id_str = NULL;
397   const char *id_str = NULL;
398   int unpack_state;
399
400   GNUNET_assert (NULL != root);
401
402   if (! json_is_object (root))
403   {
404     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
405                 "Error json is not array nor object!\n");
406     return GNUNET_SYSERR;
407   }
408   // interpret single reference
409   unpack_state = json_unpack (root,
410                               "{s:s, s?s, s:s, s:s!}",
411                               "name",
412                               &name_str,
413                               "id",
414                               &id_str,
415                               "ref_id",
416                               &ref_id_str,
417                               "ref_value",
418                               &ref_val_str);
419   if ((0 != unpack_state) || (NULL == name_str) || (NULL == ref_val_str) ||
420       (NULL == ref_id_str))
421   {
422     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
423                 "Error json object has a wrong format!\n");
424     return GNUNET_SYSERR;
425   }
426
427   attr = GNUNET_RECLAIM_ATTESTATION_reference_new (name_str, ref_val_str);
428
429   attr->id = 0;
430
431   if ((NULL == ref_id_str) || (0 == strlen (ref_id_str)))
432     attr->id_attest = 0;
433   else
434     GNUNET_STRINGS_string_to_data (ref_id_str,
435                                    strlen (ref_id_str),
436                                    &attr->id_attest,
437                                    sizeof(uint64_t));
438
439   *(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr = attr;
440   return GNUNET_OK;
441 }
442
443 /**
444  * Cleanup data left from parsing RSA public key.
445  *
446  * @param cls closure, NULL
447  * @param[out] spec where to free the data
448  */
449 static void
450 clean_attest_ref (void *cls, struct GNUNET_JSON_Specification *spec)
451 {
452   struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr;
453
454   attr = (struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr;
455   if (NULL != *attr)
456   {
457     GNUNET_free (*attr);
458     *attr = NULL;
459   }
460 }
461
462 /**
463  * JSON Specification for Reclaim attestation references.
464  *
465  * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
466  * @return JSON Specification
467  */
468 struct GNUNET_JSON_Specification
469 GNUNET_RECLAIM_JSON_spec_claim_attest_ref (struct
470                                            GNUNET_RECLAIM_ATTESTATION_REFERENCE
471                                            **attr)
472 {
473   struct GNUNET_JSON_Specification ret = { .parser = &parse_attest_ref,
474                                            .cleaner = &clean_attest_ref,
475                                            .cls = NULL,
476                                            .field = NULL,
477                                            .ptr = attr,
478                                            .ptr_size = 0,
479                                            .size_ptr = NULL };
480
481   *attr = NULL;
482   return ret;
483 }