abd_api.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  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
  222. DelegationChainIntermediateMessage *vr_msg)
  223. {
  224. // TODO
  225. return GNUNET_OK;
  226. }
  227. static void
  228. handle_intermediate (void *cls, const struct
  229. DelegationChainIntermediateMessage *vr_msg)
  230. {
  231. struct GNUNET_ABD_Handle *handle = cls;
  232. uint32_t r_id = ntohl (vr_msg->id);
  233. uint32_t size = ntohl (vr_msg->size);
  234. bool is_bw = ntohs (vr_msg->is_bw);
  235. struct GNUNET_ABD_Request *vr;
  236. GNUNET_ABD_IntermediateResultProcessor proc;
  237. void *proc_cls;
  238. struct GNUNET_ABD_Delegation *dd;
  239. LOG (GNUNET_ERROR_TYPE_DEBUG,
  240. "Received intermediate reply from ABD service\n");
  241. for (vr = handle->request_head; NULL != vr; vr = vr->next)
  242. if (vr->r_id == r_id)
  243. break;
  244. if (NULL == vr)
  245. return;
  246. proc = vr->int_proc;
  247. proc_cls = vr->proc2_cls;
  248. dd = GNUNET_new (struct GNUNET_ABD_Delegation);
  249. GNUNET_assert (
  250. GNUNET_OK ==
  251. GNUNET_ABD_delegation_chain_deserialize (size,
  252. (const char *) &vr_msg[1],
  253. 1,
  254. dd,
  255. 0,
  256. NULL));
  257. proc (proc_cls, dd, is_bw);
  258. }
  259. /**
  260. * Reconnect to ABD service.
  261. *
  262. * @param handle the handle to the ABD service
  263. */
  264. static void
  265. reconnect (struct GNUNET_ABD_Handle *handle)
  266. {
  267. struct GNUNET_MQ_MessageHandler handlers[] =
  268. {GNUNET_MQ_hd_var_size (result,
  269. GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT,
  270. struct DelegationChainResultMessage,
  271. handle),
  272. GNUNET_MQ_hd_var_size (result,
  273. GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT,
  274. struct DelegationChainResultMessage,
  275. handle),
  276. GNUNET_MQ_hd_var_size (intermediate,
  277. GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT,
  278. struct DelegationChainIntermediateMessage,
  279. handle),
  280. GNUNET_MQ_handler_end ()};
  281. struct GNUNET_ABD_Request *vr;
  282. GNUNET_assert (NULL == handle->mq);
  283. LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to ABD\n");
  284. handle->mq = GNUNET_CLIENT_connect (handle->cfg,
  285. "abd",
  286. handlers,
  287. &mq_error_handler,
  288. handle);
  289. if (NULL == handle->mq)
  290. return;
  291. for (vr = handle->request_head; NULL != vr; vr = vr->next)
  292. GNUNET_MQ_send_copy (handle->mq, vr->env);
  293. }
  294. /**
  295. * Initialize the connection with the ABD service.
  296. *
  297. * @param cfg configuration to use
  298. * @return handle to the ABD service, or NULL on error
  299. */
  300. struct GNUNET_ABD_Handle *
  301. GNUNET_ABD_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
  302. {
  303. struct GNUNET_ABD_Handle *handle;
  304. handle = GNUNET_new (struct GNUNET_ABD_Handle);
  305. handle->cfg = cfg;
  306. reconnect (handle);
  307. if (NULL == handle->mq)
  308. {
  309. GNUNET_free (handle);
  310. return NULL;
  311. }
  312. return handle;
  313. }
  314. /**
  315. * Shutdown connection with the ABD service.
  316. *
  317. * @param handle handle of the ABD connection to stop
  318. */
  319. void
  320. GNUNET_ABD_disconnect (struct GNUNET_ABD_Handle *handle)
  321. {
  322. if (NULL != handle->mq)
  323. {
  324. GNUNET_MQ_destroy (handle->mq);
  325. handle->mq = NULL;
  326. }
  327. if (NULL != handle->reconnect_task)
  328. {
  329. GNUNET_SCHEDULER_cancel (handle->reconnect_task);
  330. handle->reconnect_task = NULL;
  331. }
  332. GNUNET_assert (NULL == handle->request_head);
  333. GNUNET_free (handle);
  334. }
  335. /**
  336. * Cancel pending verify request
  337. *
  338. * @param lr the verify request to cancel
  339. */
  340. void
  341. GNUNET_ABD_request_cancel (struct GNUNET_ABD_Request *lr)
  342. {
  343. struct GNUNET_ABD_Handle *handle = lr->abd_handle;
  344. GNUNET_CONTAINER_DLL_remove (handle->request_head, handle->request_tail, lr);
  345. GNUNET_MQ_discard (lr->env);
  346. GNUNET_free (lr);
  347. }
  348. /**
  349. * Performs attribute collection.
  350. * Collects all abds of subject to fulfill the
  351. * attribute, if possible
  352. *
  353. * @param handle handle to the Credential service
  354. * @param issuer_key the issuer public key
  355. * @param issuer_attribute the issuer attribute
  356. * @param subject_key the subject public key
  357. * @param proc function to call on result
  358. * @param proc_cls closure for processor
  359. * @return handle to the queued request
  360. */
  361. struct GNUNET_ABD_Request *
  362. GNUNET_ABD_collect (
  363. struct GNUNET_ABD_Handle *handle,
  364. const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
  365. const char *issuer_attribute,
  366. const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key,
  367. enum GNUNET_ABD_AlgoDirectionFlags direction,
  368. GNUNET_ABD_CredentialResultProcessor proc,
  369. void *proc_cls,
  370. GNUNET_ABD_IntermediateResultProcessor proc2,
  371. void *proc2_cls)
  372. {
  373. /* IPC to shorten abd names, return shorten_handle */
  374. struct CollectMessage *c_msg;
  375. struct GNUNET_ABD_Request *vr;
  376. size_t nlen;
  377. if (NULL == issuer_attribute)
  378. {
  379. GNUNET_break (0);
  380. return NULL;
  381. }
  382. // DEBUG LOG
  383. LOG (GNUNET_ERROR_TYPE_DEBUG,
  384. "Trying to collect `%s' in ABD\n",
  385. issuer_attribute);
  386. nlen = strlen (issuer_attribute) + 1;
  387. if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
  388. {
  389. GNUNET_break (0);
  390. return NULL;
  391. }
  392. vr = GNUNET_new (struct GNUNET_ABD_Request);
  393. vr->abd_handle = handle;
  394. vr->verify_proc = proc;
  395. vr->proc_cls = proc_cls;
  396. vr->int_proc = proc2;
  397. vr->proc2_cls = proc2_cls;
  398. vr->r_id = handle->r_id_gen++;
  399. vr->env =
  400. GNUNET_MQ_msg_extra (c_msg, nlen, GNUNET_MESSAGE_TYPE_ABD_COLLECT);
  401. c_msg->id = htonl (vr->r_id);
  402. c_msg->subject_key = *subject_key;
  403. c_msg->issuer_key = *issuer_key;
  404. c_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
  405. c_msg->resolution_algo = htons (direction);
  406. GNUNET_memcpy (&c_msg[1], issuer_attribute, strlen (issuer_attribute));
  407. GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, vr);
  408. if (NULL != handle->mq)
  409. GNUNET_MQ_send_copy (handle->mq, vr->env);
  410. return vr;
  411. }
  412. /**
  413. * Performs attribute verification.
  414. * Checks if there is a delegation chain from
  415. * attribute ``issuer_attribute'' issued by the issuer
  416. * with public key ``issuer_key'' maps to the attribute
  417. * ``subject_attribute'' claimed by the subject with key
  418. * ``subject_key''
  419. *
  420. * @param handle handle to the Credential service
  421. * @param issuer_key the issuer public key
  422. * @param issuer_attribute the issuer attribute
  423. * @param subject_key the subject public key
  424. * @param delegate_count number of delegates provided
  425. * @param delegates subject delegates
  426. * @param proc function to call on result
  427. * @param proc_cls closure for processor
  428. * @return handle to the queued request
  429. */
  430. struct GNUNET_ABD_Request *
  431. GNUNET_ABD_verify (
  432. struct GNUNET_ABD_Handle *handle,
  433. const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
  434. const char *issuer_attribute,
  435. const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
  436. uint32_t delegate_count,
  437. const struct GNUNET_ABD_Delegate *delegates,
  438. enum GNUNET_ABD_AlgoDirectionFlags direction,
  439. GNUNET_ABD_CredentialResultProcessor proc,
  440. void *proc_cls,
  441. GNUNET_ABD_IntermediateResultProcessor proc2,
  442. void *proc2_cls)
  443. {
  444. /* IPC to shorten abd names, return shorten_handle */
  445. struct VerifyMessage *v_msg;
  446. struct GNUNET_ABD_Request *vr;
  447. size_t nlen;
  448. size_t clen;
  449. if ((NULL == issuer_attribute) || (NULL == delegates))
  450. {
  451. GNUNET_break (0);
  452. return NULL;
  453. }
  454. clen = GNUNET_ABD_delegates_get_size (delegate_count, delegates);
  455. // DEBUG LOG
  456. LOG (GNUNET_ERROR_TYPE_DEBUG,
  457. "Trying to verify `%s' in ABD\n",
  458. issuer_attribute);
  459. nlen = strlen (issuer_attribute) + 1 + clen;
  460. if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
  461. {
  462. GNUNET_break (0);
  463. return NULL;
  464. }
  465. vr = GNUNET_new (struct GNUNET_ABD_Request);
  466. vr->abd_handle = handle;
  467. vr->verify_proc = proc;
  468. vr->proc_cls = proc_cls;
  469. vr->int_proc = proc2;
  470. vr->proc2_cls = proc2_cls;
  471. vr->r_id = handle->r_id_gen++;
  472. vr->env =
  473. GNUNET_MQ_msg_extra (v_msg, nlen, GNUNET_MESSAGE_TYPE_ABD_VERIFY);
  474. v_msg->id = htonl (vr->r_id);
  475. v_msg->subject_key = *subject_key;
  476. v_msg->d_count = htonl (delegate_count);
  477. v_msg->issuer_key = *issuer_key;
  478. v_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
  479. v_msg->resolution_algo = htons (direction);
  480. GNUNET_memcpy (&v_msg[1], issuer_attribute, strlen (issuer_attribute));
  481. GNUNET_ABD_delegates_serialize (delegate_count,
  482. delegates,
  483. clen,
  484. ((char *) &v_msg[1])
  485. + strlen (issuer_attribute) + 1);
  486. GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, vr);
  487. if (NULL != handle->mq)
  488. GNUNET_MQ_send_copy (handle->mq, vr->env);
  489. return vr;
  490. }
  491. /* end of abd_api.c */