json_reclaim.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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. GNUNET_free (data);
  90. if ((NULL != cred_str) && (0 != strlen (cred_str)))
  91. {
  92. GNUNET_STRINGS_string_to_data (cred_str,
  93. strlen (cred_str),
  94. &attr->credential,
  95. sizeof(attr->credential));
  96. }
  97. if ((NULL == id_str) || (0 == strlen (id_str)))
  98. memset (&attr->id, 0, sizeof (attr->id));
  99. else
  100. GNUNET_STRINGS_string_to_data (id_str,
  101. strlen (id_str),
  102. &attr->id,
  103. sizeof(attr->id));
  104. *(struct GNUNET_RECLAIM_Attribute **) spec->ptr = attr;
  105. return GNUNET_OK;
  106. }
  107. /**
  108. * Cleanup data left from parsing RSA public key.
  109. *
  110. * @param cls closure, NULL
  111. * @param[out] spec where to free the data
  112. */
  113. static void
  114. clean_attr (void *cls, struct GNUNET_JSON_Specification *spec)
  115. {
  116. struct GNUNET_RECLAIM_Attribute **attr;
  117. attr = (struct GNUNET_RECLAIM_Attribute **) spec->ptr;
  118. if (NULL != *attr)
  119. {
  120. GNUNET_free (*attr);
  121. *attr = NULL;
  122. }
  123. }
  124. /**
  125. * JSON Specification for Reclaim claims.
  126. *
  127. * @param ticket struct of GNUNET_RECLAIM_Attribute to fill
  128. * @return JSON Specification
  129. */
  130. struct GNUNET_JSON_Specification
  131. GNUNET_RECLAIM_JSON_spec_attribute (struct GNUNET_RECLAIM_Attribute **attr)
  132. {
  133. struct GNUNET_JSON_Specification ret = { .parser = &parse_attr,
  134. .cleaner = &clean_attr,
  135. .cls = NULL,
  136. .field = NULL,
  137. .ptr = attr,
  138. .ptr_size = 0,
  139. .size_ptr = NULL };
  140. *attr = NULL;
  141. return ret;
  142. }
  143. /**
  144. * Parse given JSON object to a ticket
  145. *
  146. * @param cls closure, NULL
  147. * @param root the json object representing data
  148. * @param spec where to write the data
  149. * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
  150. */
  151. static int
  152. parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
  153. {
  154. struct GNUNET_RECLAIM_Ticket *ticket;
  155. const char *rnd_str;
  156. const char *aud_str;
  157. const char *id_str;
  158. int unpack_state;
  159. GNUNET_assert (NULL != root);
  160. if (! json_is_object (root))
  161. {
  162. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  163. "Error json is not array nor object!\n");
  164. return GNUNET_SYSERR;
  165. }
  166. // interpret single ticket
  167. unpack_state = json_unpack (root,
  168. "{s:s, s:s, s:s!}",
  169. "rnd",
  170. &rnd_str,
  171. "audience",
  172. &aud_str,
  173. "issuer",
  174. &id_str);
  175. if (0 != unpack_state)
  176. {
  177. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  178. "Error json object has a wrong format!\n");
  179. return GNUNET_SYSERR;
  180. }
  181. ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
  182. if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str,
  183. strlen (rnd_str),
  184. &ticket->rnd,
  185. sizeof(ticket->rnd)))
  186. {
  187. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rnd invalid\n");
  188. GNUNET_free (ticket);
  189. return GNUNET_SYSERR;
  190. }
  191. if (GNUNET_OK !=
  192. GNUNET_STRINGS_string_to_data (id_str,
  193. strlen (id_str),
  194. &ticket->identity,
  195. sizeof(ticket->identity)))
  196. {
  197. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity invalid\n");
  198. GNUNET_free (ticket);
  199. return GNUNET_SYSERR;
  200. }
  201. if (GNUNET_OK !=
  202. GNUNET_STRINGS_string_to_data (aud_str,
  203. strlen (aud_str),
  204. &ticket->audience,
  205. sizeof(ticket->audience)))
  206. {
  207. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience invalid\n");
  208. GNUNET_free (ticket);
  209. return GNUNET_SYSERR;
  210. }
  211. *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket;
  212. return GNUNET_OK;
  213. }
  214. /**
  215. * Cleanup data left from parsing RSA public key.
  216. *
  217. * @param cls closure, NULL
  218. * @param[out] spec where to free the data
  219. */
  220. static void
  221. clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
  222. {
  223. struct GNUNET_RECLAIM_Ticket **ticket;
  224. ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr;
  225. if (NULL != *ticket)
  226. {
  227. GNUNET_free (*ticket);
  228. *ticket = NULL;
  229. }
  230. }
  231. /**
  232. * JSON Specification for Reclaim tickets.
  233. *
  234. * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
  235. * @return JSON Specification
  236. */
  237. struct GNUNET_JSON_Specification
  238. GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
  239. {
  240. struct GNUNET_JSON_Specification ret = { .parser = &parse_ticket,
  241. .cleaner = &clean_ticket,
  242. .cls = NULL,
  243. .field = NULL,
  244. .ptr = ticket,
  245. .ptr_size = 0,
  246. .size_ptr = NULL };
  247. *ticket = NULL;
  248. return ret;
  249. }
  250. /**
  251. * Parse given JSON object to a credential claim
  252. *
  253. * @param cls closure, NULL
  254. * @param root the json object representing data
  255. * @param spec where to write the data
  256. * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
  257. */
  258. static int
  259. parse_credential (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
  260. {
  261. struct GNUNET_RECLAIM_Credential *cred;
  262. const char *name_str = NULL;
  263. const char *type_str = NULL;
  264. const char *id_str = NULL;
  265. json_t *val_json;
  266. char *data = NULL;
  267. char *val_str = NULL;
  268. int unpack_state;
  269. uint32_t type;
  270. size_t data_size;
  271. GNUNET_assert (NULL != root);
  272. if (! json_is_object (root))
  273. {
  274. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  275. "Error json is not array nor object!\n");
  276. return GNUNET_SYSERR;
  277. }
  278. // interpret single attribute
  279. unpack_state = json_unpack (root,
  280. "{s:s, s?s, s:s, s:o!}",
  281. "name",
  282. &name_str,
  283. "id",
  284. &id_str,
  285. "type",
  286. &type_str,
  287. "value",
  288. &val_json);
  289. if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_json) ||
  290. (NULL == type_str))
  291. {
  292. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  293. "Error json object has a wrong format!\n");
  294. return GNUNET_SYSERR;
  295. }
  296. if (json_is_string (val_json)) {
  297. val_str = GNUNET_strdup (json_string_value (val_json));
  298. } else {
  299. val_str = json_dumps (val_json, JSON_COMPACT);
  300. }
  301. type = GNUNET_RECLAIM_credential_typename_to_number (type_str);
  302. if (GNUNET_SYSERR ==
  303. (GNUNET_RECLAIM_credential_string_to_value (type,
  304. val_str,
  305. (void **) &data,
  306. &data_size)))
  307. {
  308. GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Credential value invalid!\n");
  309. return GNUNET_SYSERR;
  310. }
  311. cred = GNUNET_RECLAIM_credential_new (name_str, type, data, data_size);
  312. GNUNET_free (data);
  313. if ((NULL == id_str) || (0 == strlen (id_str)))
  314. memset (&cred->id, 0, sizeof (cred->id));
  315. else
  316. GNUNET_STRINGS_string_to_data (id_str,
  317. strlen (id_str),
  318. &cred->id,
  319. sizeof(cred->id));
  320. *(struct GNUNET_RECLAIM_Credential **) spec->ptr = cred;
  321. return GNUNET_OK;
  322. }
  323. /**
  324. * Cleanup data left from parsing RSA public key.
  325. *
  326. * @param cls closure, NULL
  327. * @param[out] spec where to free the data
  328. */
  329. static void
  330. clean_credential (void *cls, struct GNUNET_JSON_Specification *spec)
  331. {
  332. struct GNUNET_RECLAIM_Credential **attr;
  333. attr = (struct GNUNET_RECLAIM_Credential **) spec->ptr;
  334. if (NULL != *attr)
  335. {
  336. GNUNET_free (*attr);
  337. *attr = NULL;
  338. }
  339. }
  340. /**
  341. * JSON Specification for credential claims.
  342. *
  343. * @param attr struct of GNUNET_RECLAIM_Credential to fill
  344. * @return JSON Specification
  345. */
  346. struct GNUNET_JSON_Specification
  347. GNUNET_RECLAIM_JSON_spec_credential (struct
  348. GNUNET_RECLAIM_Credential **cred)
  349. {
  350. struct GNUNET_JSON_Specification ret = { .parser = &parse_credential,
  351. .cleaner = &clean_credential,
  352. .cls = NULL,
  353. .field = NULL,
  354. .ptr = cred,
  355. .ptr_size = 0,
  356. .size_ptr = NULL };
  357. *cred = NULL;
  358. return ret;
  359. }