json_reclaim.c 12 KB

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