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