more work on route_message() logic
[oweals/gnunet.git] / src / json / json_helper.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2014, 2015, 2016 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  * @file json/json_helper.c
22  * @brief functions to generate specifciations for JSON parsing
23  * @author Florian Dold
24  * @author Benedikt Mueller
25  * @author Christian Grothoff
26  */
27 #include "platform.h"
28 #include "gnunet_json_lib.h"
29
30
31 /**
32  * End of a parser specification.
33  */
34 struct GNUNET_JSON_Specification
35 GNUNET_JSON_spec_end ()
36 {
37   struct GNUNET_JSON_Specification ret = {
38     .parser = NULL,
39     .cleaner = NULL,
40     .cls = NULL
41   };
42   return ret;
43 }
44
45
46 /**
47  * Parse given JSON object to fixed size data
48  *
49  * @param cls closure, NULL
50  * @param root the json object representing data
51  * @param[out] spec where to write the data
52  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
53  */
54 static int
55 parse_fixed_data (void *cls,
56                   json_t *root,
57                   struct GNUNET_JSON_Specification *spec)
58 {
59   const char *enc;
60   unsigned int len;
61
62   if (NULL == (enc = json_string_value (root)))
63   {
64     GNUNET_break_op (0);
65     return GNUNET_SYSERR;
66   }
67   len = strlen (enc);
68   if (((len * 5) / 8) != spec->ptr_size)
69   {
70     GNUNET_break_op (0);
71     return GNUNET_SYSERR;
72   }
73   if (GNUNET_OK !=
74       GNUNET_STRINGS_string_to_data (enc,
75                                      len,
76                                      spec->ptr,
77                                      spec->ptr_size))
78   {
79     GNUNET_break_op (0);
80     return GNUNET_SYSERR;
81   }
82   return GNUNET_OK;
83 }
84
85
86 /**
87  * Variable size object (in network byte order, encoded using Crockford
88  * Base32hex encoding).
89  *
90  * @param name name of the JSON field
91  * @param[out] obj pointer where to write the data, must have @a size bytes
92  * @param size number of bytes expected in @a obj
93  */
94 struct GNUNET_JSON_Specification
95 GNUNET_JSON_spec_fixed (const char *name,
96                         void *obj,
97                         size_t size)
98 {
99   struct GNUNET_JSON_Specification ret = {
100     .parser = &parse_fixed_data,
101     .cleaner = NULL,
102     .cls = NULL,
103     .field = name,
104     .ptr = obj,
105     .ptr_size = size,
106     .size_ptr = NULL
107   };
108   return ret;
109 }
110
111
112 /**
113  * Parse given JSON object to variable size data
114  *
115  * @param cls closure, NULL
116  * @param root the json object representing data
117  * @param[out] spec where to write the data
118  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
119  */
120 static int
121 parse_variable_data (void *cls,
122                      json_t *root,
123                      struct GNUNET_JSON_Specification *spec)
124 {
125   const char *str;
126   size_t size;
127   void *data;
128   int res;
129
130   str = json_string_value (root);
131   if (NULL == str)
132   {
133     GNUNET_break_op (0);
134     return GNUNET_SYSERR;
135   }
136   size = (strlen (str) * 5) / 8;
137   if (size >= 1024)
138   {
139     GNUNET_break_op (0);
140     return GNUNET_SYSERR;
141   }
142   data = GNUNET_malloc (size);
143   res = GNUNET_STRINGS_string_to_data (str,
144                                        strlen (str),
145                                        data,
146                                        size);
147   if (GNUNET_OK != res)
148   {
149     GNUNET_break_op (0);
150     GNUNET_free (data);
151     return GNUNET_SYSERR;
152   }
153   *(void**) spec->ptr = data;
154   *spec->size_ptr = size;
155   return GNUNET_OK;
156 }
157
158
159 /**
160  * Cleanup data left from parsing variable size data
161  *
162  * @param cls closure, NULL
163  * @param[out] spec where to free the data
164  */
165 static void
166 clean_variable_data (void *cls,
167                      struct GNUNET_JSON_Specification *spec)
168 {
169   if (0 != *spec->size_ptr)
170   {
171     GNUNET_free (*(void **) spec->ptr);
172     *(void**) spec->ptr = NULL;
173     *spec->size_ptr = 0;
174   }
175 }
176
177
178 /**
179  * Variable size object (in network byte order, encoded using
180  * Crockford Base32hex encoding).
181  *
182  * @param name name of the JSON field
183  * @param[out] obj pointer where to write the data, will be allocated
184  * @param[out] size where to store the number of bytes allocated for @a obj
185  */
186 struct GNUNET_JSON_Specification
187 GNUNET_JSON_spec_varsize (const char *name,
188                           void **obj,
189                           size_t *size)
190 {
191   struct GNUNET_JSON_Specification ret = {
192     .parser = &parse_variable_data,
193     .cleaner = &clean_variable_data,
194     .cls = NULL,
195     .field = name,
196     .ptr = obj,
197     .ptr_size = 0,
198     .size_ptr = size
199   };
200   *obj = NULL;
201   *size = 0;
202   return ret;
203 }
204
205
206 /**
207  * Parse given JSON object to string.
208  *
209  * @param cls closure, NULL
210  * @param root the json object representing data
211  * @param[out] spec where to write the data
212  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
213  */
214 static int
215 parse_string (void *cls,
216               json_t *root,
217               struct GNUNET_JSON_Specification *spec)
218 {
219   const char *str;
220
221   str = json_string_value (root);
222   if (NULL == str)
223   {
224     GNUNET_break_op (0);
225     return GNUNET_SYSERR;
226   }
227   *(const char **) spec->ptr = str;
228   return GNUNET_OK;
229 }
230
231
232 /**
233  * The expected field stores a string.
234  *
235  * @param name name of the JSON field
236  * @param strptr where to store a pointer to the field
237  */
238 struct GNUNET_JSON_Specification
239 GNUNET_JSON_spec_string (const char *name,
240                          const char **strptr)
241 {
242   struct GNUNET_JSON_Specification ret = {
243     .parser = &parse_string,
244     .cleaner = NULL,
245     .cls = NULL,
246     .field = name,
247     .ptr = strptr,
248     .ptr_size = 0,
249     .size_ptr = NULL
250   };
251   *strptr = NULL;
252   return ret;
253 }
254
255
256 /**
257  * Parse given JSON object to a JSON object. (Yes, trivial.)
258  *
259  * @param cls closure, NULL
260  * @param root the json object representing data
261  * @param[out] spec where to write the data
262  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
263  */
264 static int
265 parse_object (void *cls,
266               json_t *root,
267               struct GNUNET_JSON_Specification *spec)
268 {
269   if (! (json_is_object (root) || json_is_array (root)) )
270   {
271     GNUNET_break_op (0);
272     return GNUNET_SYSERR;
273   }
274   json_incref (root);
275   *(json_t **) spec->ptr = root;
276   return GNUNET_OK;
277 }
278
279
280 /**
281  * Cleanup data left from parsing JSON object.
282  *
283  * @param cls closure, NULL
284  * @param[out] spec where to free the data
285  */
286 static void
287 clean_object (void *cls,
288               struct GNUNET_JSON_Specification *spec)
289 {
290   json_t **ptr = (json_t **) spec->ptr;
291
292   if (NULL != *ptr)
293   {
294     json_decref (*ptr);
295     *ptr = NULL;
296   }
297 }
298
299
300 /**
301  * JSON object.
302  *
303  * @param name name of the JSON field
304  * @param[out] jsonp where to store the JSON found under @a name
305  */
306 struct GNUNET_JSON_Specification
307 GNUNET_JSON_spec_json (const char *name,
308                        json_t **jsonp)
309 {
310   struct GNUNET_JSON_Specification ret = {
311     .parser = &parse_object,
312     .cleaner = &clean_object,
313     .cls = NULL,
314     .field = name,
315     .ptr = jsonp,
316     .ptr_size = 0,
317     .size_ptr = NULL
318   };
319   *jsonp = NULL;
320   return ret;
321 }
322
323
324 /**
325  * Parse given JSON object to a uint8_t.
326  *
327  * @param cls closure, NULL
328  * @param root the json object representing data
329  * @param[out] spec where to write the data
330  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
331  */
332 static int
333 parse_u8 (void *cls,
334           json_t *root,
335           struct GNUNET_JSON_Specification *spec)
336 {
337   json_int_t val;
338   uint8_t *up = spec->ptr;
339
340   if (! json_is_integer (root))
341   {
342     GNUNET_break_op (0);
343     return GNUNET_SYSERR;
344   }
345   val = json_integer_value (root);
346   if ( (0 > val) || (val > UINT8_MAX) )
347   {
348     GNUNET_break_op (0);
349     return GNUNET_SYSERR;
350   }
351   *up = (uint8_t) val;
352   return GNUNET_OK;
353 }
354
355
356 /**
357  * 8-bit integer.
358  *
359  * @param name name of the JSON field
360  * @param[out] u8 where to store the integer found under @a name
361  */
362 struct GNUNET_JSON_Specification
363 GNUNET_JSON_spec_uint8 (const char *name,
364                         uint8_t *u8)
365 {
366   struct GNUNET_JSON_Specification ret = {
367     .parser = &parse_u8,
368     .cleaner = NULL,
369     .cls = NULL,
370     .field = name,
371     .ptr = u8,
372     .ptr_size = sizeof (uint8_t),
373     .size_ptr = NULL
374   };
375   return ret;
376 }
377
378
379 /**
380  * Parse given JSON object to a uint16_t.
381  *
382  * @param cls closure, NULL
383  * @param root the json object representing data
384  * @param[out] spec where to write the data
385  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
386  */
387 static int
388 parse_u16 (void *cls,
389            json_t *root,
390            struct GNUNET_JSON_Specification *spec)
391 {
392   json_int_t val;
393   uint16_t *up = spec->ptr;
394
395   if (! json_is_integer (root))
396   {
397     GNUNET_break_op (0);
398     return GNUNET_SYSERR;
399   }
400   val = json_integer_value (root);
401   if ( (0 > val) || (val > UINT16_MAX) )
402   {
403     GNUNET_break_op (0);
404     return GNUNET_SYSERR;
405   }
406   *up = (uint16_t) val;
407   return GNUNET_OK;
408 }
409
410
411 /**
412  * 16-bit integer.
413  *
414  * @param name name of the JSON field
415  * @param[out] u16 where to store the integer found under @a name
416  */
417 struct GNUNET_JSON_Specification
418 GNUNET_JSON_spec_uint16 (const char *name,
419                          uint16_t *u16)
420 {
421   struct GNUNET_JSON_Specification ret = {
422     .parser = &parse_u16,
423     .cleaner = NULL,
424     .cls = NULL,
425     .field = name,
426     .ptr = u16,
427     .ptr_size = sizeof (uint16_t),
428     .size_ptr = NULL
429   };
430   return ret;
431 }
432
433
434 /**
435  * Parse given JSON object to a uint32_t.
436  *
437  * @param cls closure, NULL
438  * @param root the json object representing data
439  * @param[out] spec where to write the data
440  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
441  */
442 static int
443 parse_u32 (void *cls,
444            json_t *root,
445            struct GNUNET_JSON_Specification *spec)
446 {
447   json_int_t val;
448   uint32_t *up = spec->ptr;
449
450   if (! json_is_integer (root))
451   {
452     GNUNET_break_op (0);
453     return GNUNET_SYSERR;
454   }
455   val = json_integer_value (root);
456   if ( (0 > val) || (val > UINT32_MAX) )
457   {
458     GNUNET_break_op (0);
459     return GNUNET_SYSERR;
460   }
461   *up = (uint32_t) val;
462   return GNUNET_OK;
463 }
464
465
466 /**
467  * 32-bit integer.
468  *
469  * @param name name of the JSON field
470  * @param[out] u32 where to store the integer found under @a name
471  */
472 struct GNUNET_JSON_Specification
473 GNUNET_JSON_spec_uint32 (const char *name,
474                          uint32_t *u32)
475 {
476   struct GNUNET_JSON_Specification ret = {
477     .parser = &parse_u32,
478     .cleaner = NULL,
479     .cls = NULL,
480     .field = name,
481     .ptr = u32,
482     .ptr_size = sizeof (uint32_t),
483     .size_ptr = NULL
484   };
485   return ret;
486 }
487
488
489 /**
490  * Parse given JSON object to a uint8_t.
491  *
492  * @param cls closure, NULL
493  * @param root the json object representing data
494  * @param[out] spec where to write the data
495  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
496  */
497 static int
498 parse_u64 (void *cls,
499            json_t *root,
500            struct GNUNET_JSON_Specification *spec)
501 {
502   json_int_t val;
503   uint64_t *up = spec->ptr;
504
505   if (! json_is_integer (root))
506   {
507     GNUNET_break_op (0);
508     return GNUNET_SYSERR;
509   }
510   val = json_integer_value (root);
511   *up = (uint64_t) val;
512   return GNUNET_OK;
513 }
514
515
516 /**
517  * 64-bit integer.
518  *
519  * @param name name of the JSON field
520  * @param[out] u64 where to store the integer found under @a name
521  */
522 struct GNUNET_JSON_Specification
523 GNUNET_JSON_spec_uint64 (const char *name,
524                          uint64_t *u64)
525 {
526   struct GNUNET_JSON_Specification ret = {
527     .parser = &parse_u64,
528     .cleaner = NULL,
529     .cls = NULL,
530     .field = name,
531     .ptr = u64,
532     .ptr_size = sizeof (uint64_t),
533     .size_ptr = NULL
534   };
535   return ret;
536 }
537
538
539 /* ************ GNUnet-specific parser specifications ******************* */
540
541 /**
542  * Parse given JSON object to absolute time.
543  *
544  * @param cls closure, NULL
545  * @param root the json object representing data
546  * @param[out] spec where to write the data
547  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
548  */
549 static int
550 parse_abs_time (void *cls,
551                 json_t *root,
552                 struct GNUNET_JSON_Specification *spec)
553 {
554   struct GNUNET_TIME_Absolute *abs = spec->ptr;
555   const char *val;
556   unsigned long long int tval;
557
558   val = json_string_value (root);
559   if (NULL == val)
560   {
561     GNUNET_break_op (0);
562     return GNUNET_SYSERR;
563   }
564   if ( (0 == strcasecmp (val,
565                          "/forever/")) ||
566        (0 == strcasecmp (val,
567                          "/end of time/")) ||
568        (0 == strcasecmp (val,
569                          "/never/")) )
570   {
571     *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
572     return GNUNET_OK;
573   }
574   if (1 != sscanf (val,
575                    "/Date(%llu)/",
576                    &tval))
577   {
578     GNUNET_break_op (0);
579     return GNUNET_SYSERR;
580   }
581   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
582   abs->abs_value_us = tval * 1000LL * 1000LL;
583   if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
584   {
585     /* Integer overflow */
586     GNUNET_break_op (0);
587     return GNUNET_SYSERR;
588   }
589   return GNUNET_OK;
590 }
591
592
593 /**
594  * Absolute time.
595  *
596  * @param name name of the JSON field
597  * @param[out] at where to store the absolute time found under @a name
598  */
599 struct GNUNET_JSON_Specification
600 GNUNET_JSON_spec_absolute_time (const char *name,
601                                 struct GNUNET_TIME_Absolute *at)
602 {
603   struct GNUNET_JSON_Specification ret = {
604     .parser = &parse_abs_time,
605     .cleaner = NULL,
606     .cls = NULL,
607     .field = name,
608     .ptr = at,
609     .ptr_size = sizeof (uint64_t),
610     .size_ptr = NULL
611   };
612   return ret;
613 }
614
615
616 /**
617  * Parse given JSON object to absolute time.
618  *
619  * @param cls closure, NULL
620  * @param root the json object representing data
621  * @param[out] spec where to write the data
622  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
623  */
624 static int
625 parse_abs_time_nbo (void *cls,
626                     json_t *root,
627                     struct GNUNET_JSON_Specification *spec)
628 {
629   struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr;
630   const char *val;
631   unsigned long long int tval;
632   struct GNUNET_TIME_Absolute a;
633
634   val = json_string_value (root);
635   if (NULL == val)
636   {
637     GNUNET_break_op (0);
638     return GNUNET_SYSERR;
639   }
640   if ( (0 == strcasecmp (val,
641                          "/forever/")) ||
642        (0 == strcasecmp (val,
643                          "/end of time/")) ||
644        (0 == strcasecmp (val,
645                          "/never/")) )
646   {
647     *abs = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
648     return GNUNET_OK;
649   }
650   if (1 != sscanf (val,
651                    "/Date(%llu)/",
652                    &tval))
653   {
654     GNUNET_break_op (0);
655     return GNUNET_SYSERR;
656   }
657   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
658   a.abs_value_us = tval * 1000LL * 1000LL;
659   if ( (a.abs_value_us) / 1000LL / 1000LL != tval)
660   {
661     /* Integer overflow */
662     GNUNET_break_op (0);
663     return GNUNET_SYSERR;
664   }
665   *abs = GNUNET_TIME_absolute_hton (a);
666   return GNUNET_OK;
667 }
668
669
670 /**
671  * Absolute time in network byte order.
672  *
673  * @param name name of the JSON field
674  * @param[out] at where to store the absolute time found under @a name
675  */
676 struct GNUNET_JSON_Specification
677 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
678                                     struct GNUNET_TIME_AbsoluteNBO *at)
679 {
680   struct GNUNET_JSON_Specification ret = {
681     .parser = &parse_abs_time_nbo,
682     .cleaner = NULL,
683     .cls = NULL,
684     .field = name,
685     .ptr = at,
686     .ptr_size = sizeof (uint64_t),
687     .size_ptr = NULL
688   };
689   return ret;
690 }
691
692
693 /**
694  * Parse given JSON object to relative time.
695  *
696  * @param cls closure, NULL
697  * @param root the json object representing data
698  * @param[out] spec where to write the data
699  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
700  */
701 static int
702 parse_rel_time (void *cls,
703                 json_t *root,
704                 struct GNUNET_JSON_Specification *spec)
705 {
706   struct GNUNET_TIME_Relative *rel = spec->ptr;
707   const char *val;
708   unsigned long long int tval;
709
710   val = json_string_value (root);
711   if (NULL == val)
712   {
713     GNUNET_break_op (0);
714     return GNUNET_SYSERR;
715   }
716   if ( (0 == strcasecmp (val,
717                          "/forever/")) )
718   {
719     *rel = GNUNET_TIME_UNIT_FOREVER_REL;
720     return GNUNET_OK;
721   }
722   if (1 != sscanf (val,
723                    "/Delay(%llu)/",
724                    &tval))
725   {
726     GNUNET_break_op (0);
727     return GNUNET_SYSERR;
728   }
729   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
730   rel->rel_value_us = tval * 1000LL * 1000LL;
731   if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
732   {
733     /* Integer overflow */
734     GNUNET_break_op (0);
735     return GNUNET_SYSERR;
736   }
737   return GNUNET_OK;
738 }
739
740
741 /**
742  * Relative time.
743  *
744  * @param name name of the JSON field
745  * @param[out] rt where to store the relative time found under @a name
746  */
747 struct GNUNET_JSON_Specification
748 GNUNET_JSON_spec_relative_time (const char *name,
749                                 struct GNUNET_TIME_Relative *rt)
750 {
751   struct GNUNET_JSON_Specification ret = {
752     .parser = &parse_rel_time,
753     .cleaner = NULL,
754     .cls = NULL,
755     .field = name,
756     .ptr = rt,
757     .ptr_size = sizeof (uint64_t),
758     .size_ptr = NULL
759   };
760   return ret;
761 }
762
763
764 /**
765  * Parse given JSON object to RSA public key.
766  *
767  * @param cls closure, NULL
768  * @param root the json object representing data
769  * @param[out] spec where to write the data
770  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
771  */
772 static int
773 parse_rsa_public_key (void *cls,
774                       json_t *root,
775                       struct GNUNET_JSON_Specification *spec)
776 {
777   struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
778   const char *enc;
779   char *buf;
780   size_t len;
781   size_t buf_len;
782
783   if (NULL == (enc = json_string_value (root)))
784   {
785     GNUNET_break_op (0);
786     return GNUNET_SYSERR;
787   }
788   len = strlen (enc);
789   buf_len =  (len * 5) / 8;
790   buf = GNUNET_malloc (buf_len);
791   if (GNUNET_OK !=
792       GNUNET_STRINGS_string_to_data (enc,
793                                      len,
794                                      buf,
795                                      buf_len))
796   {
797     GNUNET_break_op (0);
798     GNUNET_free (buf);
799     return GNUNET_SYSERR;
800   }
801   if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
802                                                           buf_len)))
803   {
804     GNUNET_break_op (0);
805     GNUNET_free (buf);
806     return GNUNET_SYSERR;
807   }
808   GNUNET_free (buf);
809   return GNUNET_OK;
810 }
811
812
813 /**
814  * Cleanup data left from parsing RSA public key.
815  *
816  * @param cls closure, NULL
817  * @param[out] spec where to free the data
818  */
819 static void
820 clean_rsa_public_key (void *cls,
821                       struct GNUNET_JSON_Specification *spec)
822 {
823   struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
824
825   if (NULL != *pk)
826   {
827     GNUNET_CRYPTO_rsa_public_key_free (*pk);
828     *pk = NULL;
829   }
830 }
831
832
833 /**
834  * Specification for parsing an RSA public key.
835  *
836  * @param name name of the JSON field
837  * @param pk where to store the RSA key found under @a name
838  */
839 struct GNUNET_JSON_Specification
840 GNUNET_JSON_spec_rsa_public_key (const char *name,
841                                  struct GNUNET_CRYPTO_RsaPublicKey **pk)
842 {
843   struct GNUNET_JSON_Specification ret = {
844     .parser = &parse_rsa_public_key,
845     .cleaner = &clean_rsa_public_key,
846     .cls = NULL,
847     .field = name,
848     .ptr = pk,
849     .ptr_size = 0,
850     .size_ptr = NULL
851   };
852   *pk = NULL;
853   return ret;
854 }
855
856
857 /**
858  * Parse given JSON object to RSA signature.
859  *
860  * @param cls closure, NULL
861  * @param root the json object representing data
862  * @param[out] spec where to write the data
863  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
864  */
865 static int
866 parse_rsa_signature (void *cls,
867                      json_t *root,
868                      struct GNUNET_JSON_Specification *spec)
869 {
870   struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
871   size_t size;
872   const char *str;
873   int res;
874   void *buf;
875
876   str = json_string_value (root);
877   if (NULL == str)
878   {
879     GNUNET_break_op (0);
880     return GNUNET_SYSERR;
881   }
882   size = (strlen (str) * 5) / 8;
883   buf = GNUNET_malloc (size);
884   res = GNUNET_STRINGS_string_to_data (str,
885                                        strlen (str),
886                                        buf,
887                                        size);
888   if (GNUNET_OK != res)
889   {
890     GNUNET_free (buf);
891     GNUNET_break_op (0);
892     return GNUNET_SYSERR;
893   }
894   if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
895                                                           size)))
896   {
897     GNUNET_break_op (0);
898     GNUNET_free (buf);
899     return GNUNET_SYSERR;
900   }
901   GNUNET_free (buf);
902   return GNUNET_OK;
903 }
904
905
906 /**
907  * Cleanup data left from parsing RSA signature.
908  *
909  * @param cls closure, NULL
910  * @param[out] spec where to free the data
911  */
912 static void
913 clean_rsa_signature (void *cls,
914                      struct GNUNET_JSON_Specification *spec)
915 {
916   struct GNUNET_CRYPTO_RsaSignature  **sig = spec->ptr;
917
918   if (NULL != *sig)
919   {
920     GNUNET_CRYPTO_rsa_signature_free (*sig);
921     *sig = NULL;
922   }
923 }
924
925
926 /**
927  * Specification for parsing an RSA signature.
928  *
929  * @param name name of the JSON field
930  * @param sig where to store the RSA signature found under @a name
931  */
932 struct GNUNET_JSON_Specification
933 GNUNET_JSON_spec_rsa_signature (const char *name,
934                                 struct GNUNET_CRYPTO_RsaSignature **sig)
935 {
936   struct GNUNET_JSON_Specification ret = {
937     .parser = &parse_rsa_signature,
938     .cleaner = &clean_rsa_signature,
939     .cls = NULL,
940     .field = name,
941     .ptr = sig,
942     .ptr_size = 0,
943     .size_ptr = NULL
944   };
945   *sig = NULL;
946   return ret;
947 }
948
949
950 /**
951  * Parse given JSON object to an int as a boolean.
952  *
953  * @param cls closure, NULL
954  * @param root the json object representing data
955  * @param[out] spec where to write the data
956  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
957  */
958 static int
959 parse_boolean (void *cls,
960                json_t *root,
961                struct GNUNET_JSON_Specification *spec)
962 {
963   int *bp = spec->ptr;
964
965   if (! json_is_boolean (root))
966   {
967     GNUNET_break_op (0);
968     return GNUNET_SYSERR;
969   }
970   *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
971   return GNUNET_OK;
972 }
973
974
975 /**
976  * Boolean (true mapped to GNUNET_YES, false mapped to GNUNET_NO).
977  *
978  * @param name name of the JSON field
979  * @param[out] boolean where to store the boolean found under @a name
980  */
981 struct GNUNET_JSON_Specification
982 GNUNET_JSON_spec_boolean (const char *name,
983                           int *boolean)
984 {
985   struct GNUNET_JSON_Specification ret = {
986     .parser = &parse_boolean,
987     .cleaner = NULL,
988     .cls = NULL,
989     .field = name,
990     .ptr = boolean,
991     .ptr_size = sizeof (int),
992     .size_ptr = NULL
993   };
994   return ret;
995 }
996
997
998 /* end of json_helper.c */