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