abd_api.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009-2013, 2016 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 abd/abd_api.c
  18. * @brief library to access the ABD service
  19. * @author Martin Schanzenbach
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include "gnunet_constants.h"
  24. #include "gnunet_arm_service.h"
  25. #include "gnunet_hello_lib.h"
  26. #include "gnunet_protocols.h"
  27. #include "gnunet_signatures.h"
  28. #include "abd.h"
  29. #include "abd_serialization.h"
  30. #include "gnunet_abd_service.h"
  31. #include "gnunet_identity_service.h"
  32. #define LOG(kind, ...) GNUNET_log_from (kind, "abd-api", __VA_ARGS__)
  33. /**
  34. * Handle to a verify request
  35. */
  36. struct GNUNET_ABD_Request
  37. {
  38. /**
  39. * DLL
  40. */
  41. struct GNUNET_ABD_Request *next;
  42. /**
  43. * DLL
  44. */
  45. struct GNUNET_ABD_Request *prev;
  46. /**
  47. * handle to abd service
  48. */
  49. struct GNUNET_ABD_Handle *abd_handle;
  50. /**
  51. * processor to call on verify result
  52. */
  53. GNUNET_ABD_CredentialResultProcessor verify_proc;
  54. /**
  55. * @e verify_proc closure
  56. */
  57. void *proc_cls;
  58. /**
  59. * processor to call on intermediate result
  60. */
  61. GNUNET_ABD_IntermediateResultProcessor int_proc;
  62. /**
  63. * @e verify_proc2 closure
  64. */
  65. void *proc2_cls;
  66. /**
  67. * Envelope with the message for this queue entry.
  68. */
  69. struct GNUNET_MQ_Envelope *env;
  70. /**
  71. * request id
  72. */
  73. uint32_t r_id;
  74. };
  75. /**
  76. * Connection to the ABD service.
  77. */
  78. struct GNUNET_ABD_Handle
  79. {
  80. /**
  81. * Configuration to use.
  82. */
  83. const struct GNUNET_CONFIGURATION_Handle *cfg;
  84. /**
  85. * Connection to service (if available).
  86. */
  87. struct GNUNET_MQ_Handle *mq;
  88. /**
  89. * Head of linked list of active verify requests.
  90. */
  91. struct GNUNET_ABD_Request *request_head;
  92. /**
  93. * Tail of linked list of active verify requests.
  94. */
  95. struct GNUNET_ABD_Request *request_tail;
  96. /**
  97. * Reconnect task
  98. */
  99. struct GNUNET_SCHEDULER_Task *reconnect_task;
  100. /**
  101. * How long do we wait until we try to reconnect?
  102. */
  103. struct GNUNET_TIME_Relative reconnect_backoff;
  104. /**
  105. * Request Id generator. Incremented by one for each request.
  106. */
  107. uint32_t r_id_gen;
  108. };
  109. /**
  110. * Reconnect to ABD service.
  111. *
  112. * @param handle the handle to the ABD service
  113. */
  114. static void
  115. reconnect (struct GNUNET_ABD_Handle *handle);
  116. /**
  117. * Reconnect to ABD
  118. *
  119. * @param cls the handle
  120. */
  121. static void
  122. reconnect_task (void *cls)
  123. {
  124. struct GNUNET_ABD_Handle *handle = cls;
  125. handle->reconnect_task = NULL;
  126. reconnect (handle);
  127. }
  128. /**
  129. * Disconnect from service and then reconnect.
  130. *
  131. * @param handle our handle
  132. */
  133. static void
  134. force_reconnect (struct GNUNET_ABD_Handle *handle)
  135. {
  136. GNUNET_MQ_destroy (handle->mq);
  137. handle->mq = NULL;
  138. handle->reconnect_backoff =
  139. GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
  140. handle->reconnect_task =
  141. GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
  142. &reconnect_task,
  143. handle);
  144. }
  145. /**
  146. * Generic error handler, called with the appropriate error code and
  147. * the same closure specified at the creation of the message queue.
  148. * Not every message queue implementation supports an error handler.
  149. *
  150. * @param cls closure with the `struct GNUNET_ABD_Handle *`
  151. * @param error error code
  152. */
  153. static void
  154. mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
  155. {
  156. struct GNUNET_ABD_Handle *handle = cls;
  157. force_reconnect (handle);
  158. }
  159. /**
  160. * Check validity of message received from the ABD service
  161. *
  162. * @param cls the `struct GNUNET_ABD_Handle *`
  163. * @param vr_msg the incoming message
  164. */
  165. static int
  166. check_result (void *cls, const struct DelegationChainResultMessage *vr_msg)
  167. {
  168. //TODO
  169. return GNUNET_OK;
  170. }
  171. /**
  172. * Handler for messages received from the ABD service
  173. *
  174. * @param cls the `struct GNUNET_ABD_Handle *`
  175. * @param vr_msg the incoming message
  176. */
  177. static void
  178. handle_result (void *cls, const struct DelegationChainResultMessage *vr_msg)
  179. {
  180. struct GNUNET_ABD_Handle *handle = cls;
  181. uint32_t r_id = ntohl (vr_msg->id);
  182. struct GNUNET_ABD_Request *vr;
  183. size_t mlen = ntohs (vr_msg->header.size) - sizeof (*vr_msg);
  184. uint32_t d_count = ntohl (vr_msg->d_count);
  185. uint32_t c_count = ntohl (vr_msg->c_count);
  186. struct GNUNET_ABD_Delegation d_chain[d_count];
  187. struct GNUNET_ABD_Delegate dels[c_count];
  188. GNUNET_ABD_CredentialResultProcessor proc;
  189. void *proc_cls;
  190. LOG (GNUNET_ERROR_TYPE_DEBUG,
  191. "Received verify reply from ABD service\n");
  192. for (vr = handle->request_head; NULL != vr; vr = vr->next)
  193. if (vr->r_id == r_id)
  194. break;
  195. if (NULL == vr)
  196. return;
  197. proc = vr->verify_proc;
  198. proc_cls = vr->proc_cls;
  199. GNUNET_CONTAINER_DLL_remove (handle->request_head, handle->request_tail, vr);
  200. GNUNET_MQ_discard (vr->env);
  201. GNUNET_free (vr);
  202. GNUNET_assert (
  203. GNUNET_OK ==
  204. GNUNET_ABD_delegation_chain_deserialize (mlen,
  205. (const char *) &vr_msg[1],
  206. d_count,
  207. d_chain,
  208. c_count,
  209. dels));
  210. if (GNUNET_NO == ntohl (vr_msg->del_found))
  211. {
  212. proc (proc_cls, 0, NULL, 0,
  213. NULL);
  214. }
  215. else
  216. {
  217. proc (proc_cls, d_count, d_chain, c_count, dels);
  218. }
  219. }
  220. static int
  221. check_intermediate (void *cls, const struct DelegationChainIntermediateMessage *vr_msg)
  222. {
  223. //TODO
  224. return GNUNET_OK;
  225. }
  226. static void
  227. handle_intermediate (void *cls, const struct DelegationChainIntermediateMessage *vr_msg)
  228. {
  229. struct GNUNET_ABD_Handle *handle = cls;
  230. uint32_t r_id = ntohl (vr_msg->id);
  231. uint32_t size = ntohl (vr_msg->size);
  232. bool is_bw = ntohs(vr_msg->is_bw);
  233. struct GNUNET_ABD_Request *vr;
  234. GNUNET_ABD_IntermediateResultProcessor proc;
  235. void *proc_cls;
  236. struct GNUNET_ABD_Delegation *dd;
  237. LOG (GNUNET_ERROR_TYPE_DEBUG, "Received intermediate reply from ABD service\n");
  238. for (vr = handle->request_head; NULL != vr; vr = vr->next)
  239. if (vr->r_id == r_id)
  240. break;
  241. if (NULL == vr)
  242. return;
  243. proc = vr->int_proc;
  244. proc_cls = vr->proc2_cls;
  245. dd = GNUNET_new (struct GNUNET_ABD_Delegation);
  246. GNUNET_assert (
  247. GNUNET_OK ==
  248. GNUNET_ABD_delegation_chain_deserialize (size,
  249. (const char *) &vr_msg[1],
  250. 1,
  251. dd,
  252. 0,
  253. NULL));
  254. proc (proc_cls, dd, is_bw);
  255. }
  256. /**
  257. * Reconnect to ABD service.
  258. *
  259. * @param handle the handle to the ABD service
  260. */
  261. static void
  262. reconnect (struct GNUNET_ABD_Handle *handle)
  263. {
  264. struct GNUNET_MQ_MessageHandler handlers[] =
  265. {GNUNET_MQ_hd_var_size (result,
  266. GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT,
  267. struct DelegationChainResultMessage,
  268. handle),
  269. GNUNET_MQ_hd_var_size (result,
  270. GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT,
  271. struct DelegationChainResultMessage,
  272. handle),
  273. GNUNET_MQ_hd_var_size (intermediate,
  274. GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT,
  275. struct DelegationChainIntermediateMessage,
  276. handle),
  277. GNUNET_MQ_handler_end ()};
  278. struct GNUNET_ABD_Request *vr;
  279. GNUNET_assert (NULL == handle->mq);
  280. LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to ABD\n");
  281. handle->mq = GNUNET_CLIENT_connect (handle->cfg,
  282. "abd",
  283. handlers,
  284. &mq_error_handler,
  285. handle);
  286. if (NULL == handle->mq)
  287. return;
  288. for (vr = handle->request_head; NULL != vr; vr = vr->next)
  289. GNUNET_MQ_send_copy (handle->mq, vr->env);
  290. }
  291. /**
  292. * Initialize the connection with the ABD service.
  293. *
  294. * @param cfg configuration to use
  295. * @return handle to the ABD service, or NULL on error
  296. */
  297. struct GNUNET_ABD_Handle *
  298. GNUNET_ABD_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
  299. {
  300. struct GNUNET_ABD_Handle *handle;
  301. handle = GNUNET_new (struct GNUNET_ABD_Handle);
  302. handle->cfg = cfg;
  303. reconnect (handle);
  304. if (NULL == handle->mq)
  305. {
  306. GNUNET_free (handle);
  307. return NULL;
  308. }
  309. return handle;
  310. }
  311. /**
  312. * Shutdown connection with the ABD service.
  313. *
  314. * @param handle handle of the ABD connection to stop
  315. */
  316. void
  317. GNUNET_ABD_disconnect (struct GNUNET_ABD_Handle *handle)
  318. {
  319. if (NULL != handle->mq)
  320. {
  321. GNUNET_MQ_destroy (handle->mq);
  322. handle->mq = NULL;
  323. }
  324. if (NULL != handle->reconnect_task)
  325. {
  326. GNUNET_SCHEDULER_cancel (handle->reconnect_task);
  327. handle->reconnect_task = NULL;
  328. }
  329. GNUNET_assert (NULL == handle->request_head);
  330. GNUNET_free (handle);
  331. }
  332. /**
  333. * Cancel pending verify request
  334. *
  335. * @param lr the verify request to cancel
  336. */
  337. void
  338. GNUNET_ABD_request_cancel (struct GNUNET_ABD_Request *lr)
  339. {
  340. struct GNUNET_ABD_Handle *handle = lr->abd_handle;
  341. GNUNET_CONTAINER_DLL_remove (handle->request_head, handle->request_tail, lr);
  342. GNUNET_MQ_discard (lr->env);
  343. GNUNET_free (lr);
  344. }
  345. /**
  346. * Performs attribute collection.
  347. * Collects all abds of subject to fulfill the
  348. * attribute, if possible
  349. *
  350. * @param handle handle to the Credential service
  351. * @param issuer_key the issuer public key
  352. * @param issuer_attribute the issuer attribute
  353. * @param subject_key the subject public key
  354. * @param proc function to call on result
  355. * @param proc_cls closure for processor
  356. * @return handle to the queued request
  357. */
  358. struct GNUNET_ABD_Request *
  359. GNUNET_ABD_collect (
  360. struct GNUNET_ABD_Handle *handle,
  361. const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
  362. const char *issuer_attribute,
  363. const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key,
  364. enum GNUNET_ABD_AlgoDirectionFlags direction,
  365. GNUNET_ABD_CredentialResultProcessor proc,
  366. void *proc_cls,
  367. GNUNET_ABD_IntermediateResultProcessor proc2,
  368. void *proc2_cls)
  369. {
  370. /* IPC to shorten abd names, return shorten_handle */
  371. struct CollectMessage *c_msg;
  372. struct GNUNET_ABD_Request *vr;
  373. size_t nlen;
  374. if (NULL == issuer_attribute)
  375. {
  376. GNUNET_break (0);
  377. return NULL;
  378. }
  379. //DEBUG LOG
  380. LOG (GNUNET_ERROR_TYPE_DEBUG,
  381. "Trying to collect `%s' in ABD\n",
  382. issuer_attribute);
  383. nlen = strlen (issuer_attribute) + 1;
  384. if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
  385. {
  386. GNUNET_break (0);
  387. return NULL;
  388. }
  389. vr = GNUNET_new (struct GNUNET_ABD_Request);
  390. vr->abd_handle = handle;
  391. vr->verify_proc = proc;
  392. vr->proc_cls = proc_cls;
  393. vr->int_proc = proc2;
  394. vr->proc2_cls = proc2_cls;
  395. vr->r_id = handle->r_id_gen++;
  396. vr->env =
  397. GNUNET_MQ_msg_extra (c_msg, nlen, GNUNET_MESSAGE_TYPE_ABD_COLLECT);
  398. c_msg->id = htonl (vr->r_id);
  399. c_msg->subject_key = *subject_key;
  400. c_msg->issuer_key = *issuer_key;
  401. c_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
  402. c_msg->resolution_algo = htons (direction);
  403. GNUNET_memcpy (&c_msg[1], issuer_attribute, strlen (issuer_attribute));
  404. GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, vr);
  405. if (NULL != handle->mq)
  406. GNUNET_MQ_send_copy (handle->mq, vr->env);
  407. return vr;
  408. }
  409. /**
  410. * Performs attribute verification.
  411. * Checks if there is a delegation chain from
  412. * attribute ``issuer_attribute'' issued by the issuer
  413. * with public key ``issuer_key'' maps to the attribute
  414. * ``subject_attribute'' claimed by the subject with key
  415. * ``subject_key''
  416. *
  417. * @param handle handle to the Credential service
  418. * @param issuer_key the issuer public key
  419. * @param issuer_attribute the issuer attribute
  420. * @param subject_key the subject public key
  421. * @param delegate_count number of delegates provided
  422. * @param delegates subject delegates
  423. * @param proc function to call on result
  424. * @param proc_cls closure for processor
  425. * @return handle to the queued request
  426. */
  427. struct GNUNET_ABD_Request *
  428. GNUNET_ABD_verify (
  429. struct GNUNET_ABD_Handle *handle,
  430. const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
  431. const char *issuer_attribute,
  432. const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
  433. uint32_t delegate_count,
  434. const struct GNUNET_ABD_Delegate *delegates,
  435. enum GNUNET_ABD_AlgoDirectionFlags direction,
  436. GNUNET_ABD_CredentialResultProcessor proc,
  437. void *proc_cls,
  438. GNUNET_ABD_IntermediateResultProcessor proc2,
  439. void *proc2_cls)
  440. {
  441. /* IPC to shorten abd names, return shorten_handle */
  442. struct VerifyMessage *v_msg;
  443. struct GNUNET_ABD_Request *vr;
  444. size_t nlen;
  445. size_t clen;
  446. if (NULL == issuer_attribute || NULL == delegates)
  447. {
  448. GNUNET_break (0);
  449. return NULL;
  450. }
  451. clen = GNUNET_ABD_delegates_get_size (delegate_count, delegates);
  452. //DEBUG LOG
  453. LOG (GNUNET_ERROR_TYPE_DEBUG,
  454. "Trying to verify `%s' in ABD\n",
  455. issuer_attribute);
  456. nlen = strlen (issuer_attribute) + 1 + clen;
  457. if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
  458. {
  459. GNUNET_break (0);
  460. return NULL;
  461. }
  462. vr = GNUNET_new (struct GNUNET_ABD_Request);
  463. vr->abd_handle = handle;
  464. vr->verify_proc = proc;
  465. vr->proc_cls = proc_cls;
  466. vr->int_proc = proc2;
  467. vr->proc2_cls = proc2_cls;
  468. vr->r_id = handle->r_id_gen++;
  469. vr->env =
  470. GNUNET_MQ_msg_extra (v_msg, nlen, GNUNET_MESSAGE_TYPE_ABD_VERIFY);
  471. v_msg->id = htonl (vr->r_id);
  472. v_msg->subject_key = *subject_key;
  473. v_msg->d_count = htonl (delegate_count);
  474. v_msg->issuer_key = *issuer_key;
  475. v_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
  476. v_msg->resolution_algo = htons (direction);
  477. GNUNET_memcpy (&v_msg[1], issuer_attribute, strlen (issuer_attribute));
  478. GNUNET_ABD_delegates_serialize (delegate_count,
  479. delegates,
  480. clen,
  481. ((char *) &v_msg[1]) +
  482. strlen (issuer_attribute) + 1);
  483. GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, vr);
  484. if (NULL != handle->mq)
  485. GNUNET_MQ_send_copy (handle->mq, vr->env);
  486. return vr;
  487. }
  488. /* end of abd_api.c */