diff options
Diffstat (limited to 'src/identity/identity_api.c')
-rw-r--r-- | src/identity/identity_api.c | 1373 |
1 files changed, 0 insertions, 1373 deletions
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c deleted file mode 100644 index bfb9d40fb..000000000 --- a/src/identity/identity_api.c +++ /dev/null | |||
@@ -1,1373 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013, 2016, 2021, 2023 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 | /** | ||
22 | * @file identity/identity_api.c | ||
23 | * @brief api to interact with the identity service | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_constants.h" | ||
29 | #include "gnunet_error_codes.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | #include "gnunet_identity_service.h" | ||
32 | #include "identity.h" | ||
33 | |||
34 | #define LOG(kind, ...) GNUNET_log_from (kind, "identity-api", __VA_ARGS__) | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Handle for an operation with the identity service. | ||
39 | */ | ||
40 | struct GNUNET_IDENTITY_Operation | ||
41 | { | ||
42 | /** | ||
43 | * Main identity handle. | ||
44 | */ | ||
45 | struct GNUNET_IDENTITY_Handle *h; | ||
46 | |||
47 | /** | ||
48 | * We keep operations in a DLL. | ||
49 | */ | ||
50 | struct GNUNET_IDENTITY_Operation *next; | ||
51 | |||
52 | /** | ||
53 | * We keep operations in a DLL. | ||
54 | */ | ||
55 | struct GNUNET_IDENTITY_Operation *prev; | ||
56 | |||
57 | /** | ||
58 | * Message to send to the identity service. | ||
59 | * Allocated at the end of this struct. | ||
60 | */ | ||
61 | const struct GNUNET_MessageHeader *msg; | ||
62 | |||
63 | /** | ||
64 | * Continuation to invoke with the result of the transmission; @e cb | ||
65 | * and @e create_cont will be NULL in this case. | ||
66 | */ | ||
67 | GNUNET_IDENTITY_Continuation cont; | ||
68 | |||
69 | /** | ||
70 | * Continuation to invoke with the result of the transmission; @e cb | ||
71 | * and @a cb will be NULL in this case. | ||
72 | */ | ||
73 | GNUNET_IDENTITY_CreateContinuation create_cont; | ||
74 | |||
75 | /** | ||
76 | * Private key to return to @e create_cont, or NULL. | ||
77 | */ | ||
78 | struct GNUNET_IDENTITY_PrivateKey pk; | ||
79 | |||
80 | /** | ||
81 | * Continuation to invoke with the result of the transmission for | ||
82 | * 'get' operations (@e cont and @a create_cont will be NULL in this case). | ||
83 | */ | ||
84 | GNUNET_IDENTITY_Callback cb; | ||
85 | |||
86 | /** | ||
87 | * Closure for @e cont or @e cb. | ||
88 | */ | ||
89 | void *cls; | ||
90 | }; | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Handle for the service. | ||
95 | */ | ||
96 | struct GNUNET_IDENTITY_Handle | ||
97 | { | ||
98 | /** | ||
99 | * Configuration to use. | ||
100 | */ | ||
101 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
102 | |||
103 | /** | ||
104 | * Connection to service. | ||
105 | */ | ||
106 | struct GNUNET_MQ_Handle *mq; | ||
107 | |||
108 | /** | ||
109 | * Hash map from the hash of the private key to the | ||
110 | * respective `GNUNET_IDENTITY_Ego` handle. | ||
111 | */ | ||
112 | struct GNUNET_CONTAINER_MultiHashMap *egos; | ||
113 | |||
114 | /** | ||
115 | * Function to call when we receive updates. | ||
116 | */ | ||
117 | GNUNET_IDENTITY_Callback cb; | ||
118 | |||
119 | /** | ||
120 | * Closure for @e cb. | ||
121 | */ | ||
122 | void *cb_cls; | ||
123 | |||
124 | /** | ||
125 | * Head of active operations. | ||
126 | */ | ||
127 | struct GNUNET_IDENTITY_Operation *op_head; | ||
128 | |||
129 | /** | ||
130 | * Tail of active operations. | ||
131 | */ | ||
132 | struct GNUNET_IDENTITY_Operation *op_tail; | ||
133 | |||
134 | /** | ||
135 | * Task doing exponential back-off trying to reconnect. | ||
136 | */ | ||
137 | struct GNUNET_SCHEDULER_Task *reconnect_task; | ||
138 | |||
139 | /** | ||
140 | * Time for next connect retry. | ||
141 | */ | ||
142 | struct GNUNET_TIME_Relative reconnect_delay; | ||
143 | |||
144 | /** | ||
145 | * Are we polling for incoming messages right now? | ||
146 | */ | ||
147 | int in_receive; | ||
148 | }; | ||
149 | |||
150 | |||
151 | /** | ||
152 | * Obtain the ego representing 'anonymous' users. | ||
153 | * | ||
154 | * @return handle for the anonymous user, MUST NOT be freed | ||
155 | */ | ||
156 | struct GNUNET_IDENTITY_Ego * | ||
157 | GNUNET_IDENTITY_ego_get_anonymous () | ||
158 | { | ||
159 | static struct GNUNET_IDENTITY_Ego anon; | ||
160 | static int setup; | ||
161 | ssize_t key_len; | ||
162 | |||
163 | if (setup) | ||
164 | return &anon; | ||
165 | anon.pk.type = htonl (GNUNET_IDENTITY_TYPE_ECDSA); | ||
166 | anon.pub.type = htonl (GNUNET_IDENTITY_TYPE_ECDSA); | ||
167 | anon.pk.ecdsa_key = *GNUNET_CRYPTO_ecdsa_key_get_anonymous (); | ||
168 | key_len = GNUNET_IDENTITY_private_key_get_length (&anon.pk); | ||
169 | GNUNET_assert (0 < key_len); | ||
170 | GNUNET_CRYPTO_hash (&anon.pk, | ||
171 | key_len, | ||
172 | &anon.id); | ||
173 | setup = 1; | ||
174 | return &anon; | ||
175 | } | ||
176 | |||
177 | |||
178 | enum GNUNET_GenericReturnValue | ||
179 | GNUNET_IDENTITY_key_get_public (const struct | ||
180 | GNUNET_IDENTITY_PrivateKey *privkey, | ||
181 | struct GNUNET_IDENTITY_PublicKey *key) | ||
182 | { | ||
183 | key->type = privkey->type; | ||
184 | switch (ntohl (privkey->type)) | ||
185 | { | ||
186 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
187 | GNUNET_CRYPTO_ecdsa_key_get_public (&privkey->ecdsa_key, | ||
188 | &key->ecdsa_key); | ||
189 | break; | ||
190 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
191 | GNUNET_CRYPTO_eddsa_key_get_public (&privkey->eddsa_key, | ||
192 | &key->eddsa_key); | ||
193 | break; | ||
194 | default: | ||
195 | GNUNET_break (0); | ||
196 | return GNUNET_SYSERR; | ||
197 | } | ||
198 | return GNUNET_OK; | ||
199 | } | ||
200 | |||
201 | |||
202 | static enum GNUNET_GenericReturnValue | ||
203 | private_key_create (enum GNUNET_IDENTITY_KeyType ktype, | ||
204 | struct GNUNET_IDENTITY_PrivateKey *key) | ||
205 | { | ||
206 | key->type = htonl (ktype); | ||
207 | switch (ktype) | ||
208 | { | ||
209 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
210 | GNUNET_CRYPTO_ecdsa_key_create (&key->ecdsa_key); | ||
211 | break; | ||
212 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
213 | GNUNET_CRYPTO_eddsa_key_create (&key->eddsa_key); | ||
214 | break; | ||
215 | default: | ||
216 | GNUNET_break (0); | ||
217 | return GNUNET_SYSERR; | ||
218 | } | ||
219 | return GNUNET_OK; | ||
220 | } | ||
221 | |||
222 | |||
223 | /** | ||
224 | * Try again to connect to the identity service. | ||
225 | * | ||
226 | * @param cls handle to the identity service. | ||
227 | */ | ||
228 | static void | ||
229 | reconnect (void *cls); | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Free ego from hash map. | ||
234 | * | ||
235 | * @param cls identity service handle | ||
236 | * @param key unused | ||
237 | * @param value ego to free | ||
238 | * @return #GNUNET_OK (continue to iterate) | ||
239 | */ | ||
240 | static int | ||
241 | free_ego (void *cls, | ||
242 | const struct GNUNET_HashCode *key, | ||
243 | void *value) | ||
244 | { | ||
245 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
246 | struct GNUNET_IDENTITY_Ego *ego = value; | ||
247 | |||
248 | if (NULL != h->cb) | ||
249 | h->cb (h->cb_cls, ego, | ||
250 | &ego->ctx, | ||
251 | NULL); | ||
252 | GNUNET_free (ego->name); | ||
253 | GNUNET_assert (GNUNET_YES == | ||
254 | GNUNET_CONTAINER_multihashmap_remove (h->egos, | ||
255 | key, | ||
256 | value)); | ||
257 | GNUNET_free (ego); | ||
258 | return GNUNET_OK; | ||
259 | } | ||
260 | |||
261 | |||
262 | /** | ||
263 | * Reschedule a connect attempt to the service. | ||
264 | * | ||
265 | * @param h transport service to reconnect | ||
266 | */ | ||
267 | static void | ||
268 | reschedule_connect (struct GNUNET_IDENTITY_Handle *h) | ||
269 | { | ||
270 | struct GNUNET_IDENTITY_Operation *op; | ||
271 | |||
272 | GNUNET_assert (NULL == h->reconnect_task); | ||
273 | |||
274 | if (NULL != h->mq) | ||
275 | { | ||
276 | GNUNET_MQ_destroy (h->mq); | ||
277 | h->mq = NULL; | ||
278 | } | ||
279 | while (NULL != (op = h->op_head)) | ||
280 | { | ||
281 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
282 | h->op_tail, | ||
283 | op); | ||
284 | if (NULL != op->cont) | ||
285 | op->cont (op->cls, | ||
286 | GNUNET_EC_SERVICE_COMMUNICATION_FAILED); | ||
287 | else if (NULL != op->cb) | ||
288 | op->cb (op->cls, NULL, NULL, NULL); | ||
289 | else if (NULL != op->create_cont) | ||
290 | op->create_cont (op->cls, | ||
291 | NULL, | ||
292 | GNUNET_EC_SERVICE_COMMUNICATION_FAILED); | ||
293 | GNUNET_free (op); | ||
294 | } | ||
295 | GNUNET_CONTAINER_multihashmap_iterate (h->egos, | ||
296 | &free_ego, | ||
297 | h); | ||
298 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
299 | "Scheduling task to reconnect to identity service in %s.\n", | ||
300 | GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, | ||
301 | GNUNET_YES)); | ||
302 | h->reconnect_task = | ||
303 | GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, | ||
304 | &reconnect, | ||
305 | h); | ||
306 | h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); | ||
307 | } | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Generic error handler, called with the appropriate error code and | ||
312 | * the same closure specified at the creation of the message queue. | ||
313 | * Not every message queue implementation supports an error handler. | ||
314 | * | ||
315 | * @param cls closure with the `struct GNUNET_IDENTITY_Handle *` | ||
316 | * @param error error code | ||
317 | */ | ||
318 | static void | ||
319 | mq_error_handler (void *cls, | ||
320 | enum GNUNET_MQ_Error error) | ||
321 | { | ||
322 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
323 | |||
324 | reschedule_connect (h); | ||
325 | } | ||
326 | |||
327 | |||
328 | /** | ||
329 | * We received a result code from the service. | ||
330 | * | ||
331 | * @param cls closure | ||
332 | * @param rcm result message received | ||
333 | */ | ||
334 | static void | ||
335 | handle_identity_result_code (void *cls, | ||
336 | const struct ResultCodeMessage *rcm) | ||
337 | { | ||
338 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
339 | struct GNUNET_IDENTITY_Operation *op; | ||
340 | enum GNUNET_ErrorCode ec = ntohl (rcm->result_code); | ||
341 | |||
342 | op = h->op_head; | ||
343 | if (NULL == op) | ||
344 | { | ||
345 | GNUNET_break (0); | ||
346 | reschedule_connect (h); | ||
347 | return; | ||
348 | } | ||
349 | GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); | ||
350 | if (NULL != op->cont) | ||
351 | op->cont (op->cls, ec); | ||
352 | else if (NULL != op->cb) | ||
353 | op->cb (op->cls, NULL, NULL, NULL); | ||
354 | else if (NULL != op->create_cont) | ||
355 | op->create_cont (op->cls, (GNUNET_EC_NONE == ec) ? &op->pk : NULL, ec); | ||
356 | GNUNET_free (op); | ||
357 | } | ||
358 | |||
359 | |||
360 | /** | ||
361 | * Check validity of identity update message. | ||
362 | * | ||
363 | * @param cls closure | ||
364 | * @param um message received | ||
365 | * @return #GNUNET_OK if the message is well-formed | ||
366 | */ | ||
367 | static int | ||
368 | check_identity_update (void *cls, | ||
369 | const struct UpdateMessage *um) | ||
370 | { | ||
371 | uint16_t size = ntohs (um->header.size); | ||
372 | uint16_t name_len = ntohs (um->name_len); | ||
373 | const char *str = (const char *) &um[1]; | ||
374 | |||
375 | if ((size < name_len + sizeof(struct UpdateMessage)) || | ||
376 | ((0 != name_len) && ('\0' != str[name_len - 1]))) | ||
377 | { | ||
378 | GNUNET_break (0); | ||
379 | return GNUNET_SYSERR; | ||
380 | } | ||
381 | return GNUNET_OK; | ||
382 | } | ||
383 | |||
384 | |||
385 | /** | ||
386 | * Handle identity update message. | ||
387 | * | ||
388 | * @param cls closure | ||
389 | * @param um message received | ||
390 | */ | ||
391 | static void | ||
392 | handle_identity_update (void *cls, | ||
393 | const struct UpdateMessage *um) | ||
394 | { | ||
395 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
396 | uint16_t name_len = ntohs (um->name_len); | ||
397 | const char *str; | ||
398 | size_t key_len; | ||
399 | size_t kb_read; | ||
400 | struct GNUNET_HashCode id; | ||
401 | struct GNUNET_IDENTITY_Ego *ego; | ||
402 | struct GNUNET_IDENTITY_PrivateKey private_key; | ||
403 | const char *tmp; | ||
404 | |||
405 | if (GNUNET_YES == ntohs (um->end_of_list)) | ||
406 | { | ||
407 | /* end of initial list of data */ | ||
408 | if (NULL != h->cb) | ||
409 | h->cb (h->cb_cls, NULL, NULL, NULL); | ||
410 | return; | ||
411 | } | ||
412 | tmp = (const char*) &um[1]; | ||
413 | str = (0 == name_len) ? NULL : tmp; | ||
414 | memset (&private_key, 0, sizeof (private_key)); | ||
415 | key_len = ntohs (um->key_len); | ||
416 | GNUNET_assert (GNUNET_SYSERR != | ||
417 | GNUNET_IDENTITY_read_private_key_from_buffer (tmp + name_len, | ||
418 | key_len, | ||
419 | &private_key, | ||
420 | &kb_read)); | ||
421 | GNUNET_assert (0 <= GNUNET_IDENTITY_private_key_get_length (&private_key)); | ||
422 | GNUNET_CRYPTO_hash (&private_key, | ||
423 | GNUNET_IDENTITY_private_key_get_length (&private_key), | ||
424 | &id); | ||
425 | ego = GNUNET_CONTAINER_multihashmap_get (h->egos, | ||
426 | &id); | ||
427 | if (NULL == ego) | ||
428 | { | ||
429 | /* ego was created */ | ||
430 | if (NULL == str) | ||
431 | { | ||
432 | /* deletion of unknown ego? not allowed */ | ||
433 | GNUNET_break (0); | ||
434 | reschedule_connect (h); | ||
435 | return; | ||
436 | } | ||
437 | ego = GNUNET_new (struct GNUNET_IDENTITY_Ego); | ||
438 | ego->pub_initialized = GNUNET_NO; | ||
439 | ego->pk = private_key; | ||
440 | ego->name = GNUNET_strdup (str); | ||
441 | ego->id = id; | ||
442 | GNUNET_assert (GNUNET_YES == | ||
443 | GNUNET_CONTAINER_multihashmap_put ( | ||
444 | h->egos, | ||
445 | &ego->id, | ||
446 | ego, | ||
447 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
448 | } | ||
449 | if (NULL == str) | ||
450 | { | ||
451 | /* ego was deleted */ | ||
452 | GNUNET_assert (GNUNET_YES == | ||
453 | GNUNET_CONTAINER_multihashmap_remove (h->egos, | ||
454 | &ego->id, | ||
455 | ego)); | ||
456 | } | ||
457 | else | ||
458 | { | ||
459 | /* ego changed name */ | ||
460 | GNUNET_free (ego->name); | ||
461 | ego->name = GNUNET_strdup (str); | ||
462 | } | ||
463 | /* inform application about change */ | ||
464 | if (NULL != h->cb) | ||
465 | h->cb (h->cb_cls, | ||
466 | ego, | ||
467 | &ego->ctx, | ||
468 | str); | ||
469 | /* complete deletion */ | ||
470 | if (NULL == str) | ||
471 | { | ||
472 | GNUNET_free (ego->name); | ||
473 | GNUNET_free (ego); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | |||
478 | /** | ||
479 | * Try again to connect to the identity service. | ||
480 | * | ||
481 | * @param cls handle to the identity service. | ||
482 | */ | ||
483 | static void | ||
484 | reconnect (void *cls) | ||
485 | { | ||
486 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
487 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
488 | GNUNET_MQ_hd_fixed_size (identity_result_code, | ||
489 | GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE, | ||
490 | struct ResultCodeMessage, | ||
491 | h), | ||
492 | GNUNET_MQ_hd_var_size (identity_update, | ||
493 | GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE, | ||
494 | struct UpdateMessage, | ||
495 | h), | ||
496 | GNUNET_MQ_handler_end () | ||
497 | }; | ||
498 | struct GNUNET_MQ_Envelope *env; | ||
499 | struct GNUNET_MessageHeader *msg; | ||
500 | |||
501 | h->reconnect_task = NULL; | ||
502 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
503 | "Connecting to identity service.\n"); | ||
504 | GNUNET_assert (NULL == h->mq); | ||
505 | h->mq = GNUNET_CLIENT_connect (h->cfg, | ||
506 | "identity", | ||
507 | handlers, | ||
508 | &mq_error_handler, | ||
509 | h); | ||
510 | if (NULL == h->mq) | ||
511 | return; | ||
512 | if (NULL != h->cb) | ||
513 | { | ||
514 | env = GNUNET_MQ_msg (msg, | ||
515 | GNUNET_MESSAGE_TYPE_IDENTITY_START); | ||
516 | GNUNET_MQ_send (h->mq, | ||
517 | env); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | |||
522 | /** | ||
523 | * Connect to the identity service. | ||
524 | * | ||
525 | * @param cfg the configuration to use | ||
526 | * @param cb function to call on all identity events, can be NULL | ||
527 | * @param cb_cls closure for @a cb | ||
528 | * @return handle to use | ||
529 | */ | ||
530 | struct GNUNET_IDENTITY_Handle * | ||
531 | GNUNET_IDENTITY_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
532 | GNUNET_IDENTITY_Callback cb, | ||
533 | void *cb_cls) | ||
534 | { | ||
535 | struct GNUNET_IDENTITY_Handle *h; | ||
536 | |||
537 | h = GNUNET_new (struct GNUNET_IDENTITY_Handle); | ||
538 | h->cfg = cfg; | ||
539 | h->cb = cb; | ||
540 | h->cb_cls = cb_cls; | ||
541 | h->egos = GNUNET_CONTAINER_multihashmap_create (16, | ||
542 | GNUNET_YES); | ||
543 | reconnect (h); | ||
544 | if (NULL == h->mq) | ||
545 | { | ||
546 | GNUNET_free (h); | ||
547 | return NULL; | ||
548 | } | ||
549 | return h; | ||
550 | } | ||
551 | |||
552 | |||
553 | /** | ||
554 | * Obtain the ECC key associated with a ego. | ||
555 | * | ||
556 | * @param ego the ego | ||
557 | * @return associated ECC key, valid as long as the ego is valid | ||
558 | */ | ||
559 | const struct GNUNET_IDENTITY_PrivateKey * | ||
560 | GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego) | ||
561 | { | ||
562 | return &ego->pk; | ||
563 | } | ||
564 | |||
565 | |||
566 | /** | ||
567 | * Get the identifier (public key) of an ego. | ||
568 | * | ||
569 | * @param ego identity handle with the private key | ||
570 | * @param pk set to ego's public key | ||
571 | */ | ||
572 | void | ||
573 | GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, | ||
574 | struct GNUNET_IDENTITY_PublicKey *pk) | ||
575 | { | ||
576 | if (GNUNET_NO == ego->pub_initialized) | ||
577 | { | ||
578 | GNUNET_IDENTITY_key_get_public (&ego->pk, &ego->pub); | ||
579 | ego->pub_initialized = GNUNET_YES; | ||
580 | } | ||
581 | *pk = ego->pub; | ||
582 | } | ||
583 | |||
584 | |||
585 | /** | ||
586 | * Obtain the name associated with an ego. | ||
587 | * | ||
588 | * @param ego the ego | ||
589 | * @return associated name, valid as long as the ego is valid | ||
590 | */ | ||
591 | const char* | ||
592 | GNUNET_IDENTITY_ego_get_name (const struct GNUNET_IDENTITY_Ego *ego) | ||
593 | { | ||
594 | return ego->name; | ||
595 | } | ||
596 | |||
597 | |||
598 | struct GNUNET_IDENTITY_Operation * | ||
599 | GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *h, | ||
600 | const char *name, | ||
601 | const struct GNUNET_IDENTITY_PrivateKey *privkey, | ||
602 | enum GNUNET_IDENTITY_KeyType ktype, | ||
603 | GNUNET_IDENTITY_CreateContinuation cont, | ||
604 | void *cont_cls) | ||
605 | { | ||
606 | struct GNUNET_IDENTITY_PrivateKey private_key; | ||
607 | struct GNUNET_IDENTITY_Operation *op; | ||
608 | struct GNUNET_MQ_Envelope *env; | ||
609 | struct CreateRequestMessage *crm; | ||
610 | size_t slen; | ||
611 | size_t key_len; | ||
612 | |||
613 | if (NULL == h->mq) | ||
614 | return NULL; | ||
615 | slen = strlen (name) + 1; | ||
616 | if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(struct CreateRequestMessage)) | ||
617 | { | ||
618 | GNUNET_break (0); | ||
619 | return NULL; | ||
620 | } | ||
621 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); | ||
622 | op->h = h; | ||
623 | op->create_cont = cont; | ||
624 | op->cls = cont_cls; | ||
625 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); | ||
626 | if (NULL == privkey) | ||
627 | { | ||
628 | GNUNET_assert (GNUNET_OK == | ||
629 | private_key_create (ktype, &private_key)); | ||
630 | } | ||
631 | else | ||
632 | private_key = *privkey; | ||
633 | key_len = GNUNET_IDENTITY_private_key_get_length (&private_key); | ||
634 | env = GNUNET_MQ_msg_extra (crm, slen + key_len, | ||
635 | GNUNET_MESSAGE_TYPE_IDENTITY_CREATE); | ||
636 | crm->name_len = htons (slen); | ||
637 | GNUNET_IDENTITY_write_private_key_to_buffer (&private_key, | ||
638 | &crm[1], | ||
639 | key_len); | ||
640 | crm->key_len = htons (key_len); | ||
641 | op->pk = private_key; | ||
642 | GNUNET_memcpy ((char*) &crm[1] + key_len, name, slen); | ||
643 | GNUNET_MQ_send (h->mq, env); | ||
644 | return op; | ||
645 | } | ||
646 | |||
647 | |||
648 | /** | ||
649 | * Renames an existing identity. | ||
650 | * | ||
651 | * @param h identity service to use | ||
652 | * @param old_name old name | ||
653 | * @param new_name desired new name | ||
654 | * @param cb function to call with the result (will only be called once) | ||
655 | * @param cb_cls closure for @a cb | ||
656 | * @return handle to abort the operation | ||
657 | */ | ||
658 | struct GNUNET_IDENTITY_Operation * | ||
659 | GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *h, | ||
660 | const char *old_name, | ||
661 | const char *new_name, | ||
662 | GNUNET_IDENTITY_Continuation cb, | ||
663 | void *cb_cls) | ||
664 | { | ||
665 | struct GNUNET_IDENTITY_Operation *op; | ||
666 | struct GNUNET_MQ_Envelope *env; | ||
667 | struct RenameMessage *grm; | ||
668 | size_t slen_old; | ||
669 | size_t slen_new; | ||
670 | char *dst; | ||
671 | |||
672 | if (NULL == h->mq) | ||
673 | return NULL; | ||
674 | slen_old = strlen (old_name) + 1; | ||
675 | slen_new = strlen (new_name) + 1; | ||
676 | if ((slen_old >= GNUNET_MAX_MESSAGE_SIZE) || | ||
677 | (slen_new >= GNUNET_MAX_MESSAGE_SIZE) || | ||
678 | (slen_old + slen_new >= | ||
679 | GNUNET_MAX_MESSAGE_SIZE - sizeof(struct RenameMessage))) | ||
680 | { | ||
681 | GNUNET_break (0); | ||
682 | return NULL; | ||
683 | } | ||
684 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); | ||
685 | op->h = h; | ||
686 | op->cont = cb; | ||
687 | op->cls = cb_cls; | ||
688 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); | ||
689 | env = GNUNET_MQ_msg_extra (grm, | ||
690 | slen_old + slen_new, | ||
691 | GNUNET_MESSAGE_TYPE_IDENTITY_RENAME); | ||
692 | grm->old_name_len = htons (slen_old); | ||
693 | grm->new_name_len = htons (slen_new); | ||
694 | dst = (char *) &grm[1]; | ||
695 | GNUNET_memcpy (dst, old_name, slen_old); | ||
696 | GNUNET_memcpy (&dst[slen_old], new_name, slen_new); | ||
697 | GNUNET_MQ_send (h->mq, env); | ||
698 | return op; | ||
699 | } | ||
700 | |||
701 | |||
702 | /** | ||
703 | * Delete an existing identity. | ||
704 | * | ||
705 | * @param h identity service to use | ||
706 | * @param name name of the identity to delete | ||
707 | * @param cb function to call with the result (will only be called once) | ||
708 | * @param cb_cls closure for @a cb | ||
709 | * @return handle to abort the operation | ||
710 | */ | ||
711 | struct GNUNET_IDENTITY_Operation * | ||
712 | GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *h, | ||
713 | const char *name, | ||
714 | GNUNET_IDENTITY_Continuation cb, | ||
715 | void *cb_cls) | ||
716 | { | ||
717 | struct GNUNET_IDENTITY_Operation *op; | ||
718 | struct GNUNET_MQ_Envelope *env; | ||
719 | struct DeleteMessage *gdm; | ||
720 | size_t slen; | ||
721 | |||
722 | if (NULL == h->mq) | ||
723 | return NULL; | ||
724 | slen = strlen (name) + 1; | ||
725 | if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(struct DeleteMessage)) | ||
726 | { | ||
727 | GNUNET_break (0); | ||
728 | return NULL; | ||
729 | } | ||
730 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); | ||
731 | op->h = h; | ||
732 | op->cont = cb; | ||
733 | op->cls = cb_cls; | ||
734 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); | ||
735 | env = GNUNET_MQ_msg_extra (gdm, slen, GNUNET_MESSAGE_TYPE_IDENTITY_DELETE); | ||
736 | gdm->name_len = htons (slen); | ||
737 | gdm->reserved = htons (0); | ||
738 | GNUNET_memcpy (&gdm[1], name, slen); | ||
739 | GNUNET_MQ_send (h->mq, env); | ||
740 | return op; | ||
741 | } | ||
742 | |||
743 | |||
744 | /** | ||
745 | * Cancel an identity operation. Note that the operation MAY still | ||
746 | * be executed; this merely cancels the continuation; if the request | ||
747 | * was already transmitted, the service may still choose to complete | ||
748 | * the operation. | ||
749 | * | ||
750 | * @param op operation to cancel | ||
751 | */ | ||
752 | void | ||
753 | GNUNET_IDENTITY_cancel (struct GNUNET_IDENTITY_Operation *op) | ||
754 | { | ||
755 | op->cont = NULL; | ||
756 | op->cb = NULL; | ||
757 | op->create_cont = NULL; | ||
758 | memset (&op->pk, | ||
759 | 0, | ||
760 | sizeof (op->pk)); | ||
761 | } | ||
762 | |||
763 | |||
764 | /** | ||
765 | * Disconnect from identity service | ||
766 | * | ||
767 | * @param h handle to destroy | ||
768 | */ | ||
769 | void | ||
770 | GNUNET_IDENTITY_disconnect (struct GNUNET_IDENTITY_Handle *h) | ||
771 | { | ||
772 | struct GNUNET_IDENTITY_Operation *op; | ||
773 | |||
774 | GNUNET_assert (NULL != h); | ||
775 | if (h->reconnect_task != NULL) | ||
776 | { | ||
777 | GNUNET_SCHEDULER_cancel (h->reconnect_task); | ||
778 | h->reconnect_task = NULL; | ||
779 | } | ||
780 | if (NULL != h->egos) | ||
781 | { | ||
782 | GNUNET_CONTAINER_multihashmap_iterate (h->egos, | ||
783 | &free_ego, | ||
784 | h); | ||
785 | GNUNET_CONTAINER_multihashmap_destroy (h->egos); | ||
786 | h->egos = NULL; | ||
787 | } | ||
788 | while (NULL != (op = h->op_head)) | ||
789 | { | ||
790 | GNUNET_break (NULL == op->cont); | ||
791 | GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); | ||
792 | memset (&op->pk, | ||
793 | 0, | ||
794 | sizeof (op->pk)); | ||
795 | GNUNET_free (op); | ||
796 | } | ||
797 | if (NULL != h->mq) | ||
798 | { | ||
799 | GNUNET_MQ_destroy (h->mq); | ||
800 | h->mq = NULL; | ||
801 | } | ||
802 | GNUNET_free (h); | ||
803 | } | ||
804 | |||
805 | |||
806 | static enum GNUNET_GenericReturnValue | ||
807 | check_key_type (uint32_t type) | ||
808 | { | ||
809 | switch (type) | ||
810 | { | ||
811 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
812 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
813 | return GNUNET_OK; | ||
814 | default: | ||
815 | return GNUNET_SYSERR; | ||
816 | } | ||
817 | return GNUNET_SYSERR; | ||
818 | } | ||
819 | |||
820 | |||
821 | ssize_t | ||
822 | GNUNET_IDENTITY_private_key_get_length (const struct | ||
823 | GNUNET_IDENTITY_PrivateKey *key) | ||
824 | { | ||
825 | switch (ntohl (key->type)) | ||
826 | { | ||
827 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
828 | return sizeof (key->type) + sizeof (key->ecdsa_key); | ||
829 | break; | ||
830 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
831 | return sizeof (key->type) + sizeof (key->eddsa_key); | ||
832 | break; | ||
833 | default: | ||
834 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
835 | "Got key type %u\n", ntohl (key->type)); | ||
836 | GNUNET_break (0); | ||
837 | } | ||
838 | return -1; | ||
839 | } | ||
840 | |||
841 | |||
842 | ssize_t | ||
843 | GNUNET_IDENTITY_public_key_get_length (const struct | ||
844 | GNUNET_IDENTITY_PublicKey *key) | ||
845 | { | ||
846 | switch (ntohl (key->type)) | ||
847 | { | ||
848 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
849 | return sizeof (key->type) + sizeof (key->ecdsa_key); | ||
850 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
851 | return sizeof (key->type) + sizeof (key->eddsa_key); | ||
852 | default: | ||
853 | GNUNET_break (0); | ||
854 | } | ||
855 | return -1; | ||
856 | } | ||
857 | |||
858 | |||
859 | ssize_t | ||
860 | GNUNET_IDENTITY_private_key_length_by_type (enum GNUNET_IDENTITY_KeyType kt) | ||
861 | { | ||
862 | switch (kt) | ||
863 | { | ||
864 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
865 | return sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); | ||
866 | break; | ||
867 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
868 | return sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); | ||
869 | break; | ||
870 | default: | ||
871 | GNUNET_break (0); | ||
872 | } | ||
873 | return -1; | ||
874 | } | ||
875 | |||
876 | |||
877 | enum GNUNET_GenericReturnValue | ||
878 | GNUNET_IDENTITY_read_public_key_from_buffer (const void *buffer, | ||
879 | size_t len, | ||
880 | struct GNUNET_IDENTITY_PublicKey * | ||
881 | key, | ||
882 | size_t *kb_read) | ||
883 | { | ||
884 | if (len < sizeof (key->type)) | ||
885 | return GNUNET_SYSERR; | ||
886 | GNUNET_memcpy (&key->type, | ||
887 | buffer, | ||
888 | sizeof (key->type)); | ||
889 | ssize_t length = GNUNET_IDENTITY_public_key_get_length (key); | ||
890 | if (len < length) | ||
891 | return GNUNET_SYSERR; | ||
892 | if (length < 0) | ||
893 | return GNUNET_SYSERR; | ||
894 | GNUNET_memcpy (&key->ecdsa_key, | ||
895 | buffer + sizeof (key->type), | ||
896 | length - sizeof (key->type)); | ||
897 | *kb_read = length; | ||
898 | return GNUNET_OK; | ||
899 | } | ||
900 | |||
901 | |||
902 | ssize_t | ||
903 | GNUNET_IDENTITY_write_public_key_to_buffer (const struct | ||
904 | GNUNET_IDENTITY_PublicKey *key, | ||
905 | void*buffer, | ||
906 | size_t len) | ||
907 | { | ||
908 | const ssize_t length = GNUNET_IDENTITY_public_key_get_length (key); | ||
909 | if (len < length) | ||
910 | return -1; | ||
911 | if (length < 0) | ||
912 | return -2; | ||
913 | GNUNET_memcpy (buffer, &(key->type), sizeof (key->type)); | ||
914 | GNUNET_memcpy (buffer + sizeof (key->type), &(key->ecdsa_key), length | ||
915 | - sizeof (key->type)); | ||
916 | return length; | ||
917 | } | ||
918 | |||
919 | |||
920 | enum GNUNET_GenericReturnValue | ||
921 | GNUNET_IDENTITY_read_private_key_from_buffer (const void *buffer, | ||
922 | size_t len, | ||
923 | struct | ||
924 | GNUNET_IDENTITY_PrivateKey *key, | ||
925 | size_t *kb_read) | ||
926 | { | ||
927 | if (len < sizeof (key->type)) | ||
928 | return GNUNET_SYSERR; | ||
929 | GNUNET_memcpy (&key->type, | ||
930 | buffer, | ||
931 | sizeof (key->type)); | ||
932 | ssize_t length = GNUNET_IDENTITY_private_key_get_length (key); | ||
933 | if (len < length) | ||
934 | return GNUNET_SYSERR; | ||
935 | if (length < 0) | ||
936 | return GNUNET_SYSERR; | ||
937 | GNUNET_memcpy (&key->ecdsa_key, | ||
938 | buffer + sizeof (key->type), | ||
939 | length - sizeof (key->type)); | ||
940 | *kb_read = length; | ||
941 | return GNUNET_OK; | ||
942 | } | ||
943 | |||
944 | |||
945 | ssize_t | ||
946 | GNUNET_IDENTITY_write_private_key_to_buffer (const struct | ||
947 | GNUNET_IDENTITY_PrivateKey *key, | ||
948 | void *buffer, | ||
949 | size_t len) | ||
950 | { | ||
951 | const ssize_t length = GNUNET_IDENTITY_private_key_get_length (key); | ||
952 | if (len < length) | ||
953 | return -1; | ||
954 | if (length < 0) | ||
955 | return -2; | ||
956 | GNUNET_memcpy (buffer, &(key->type), sizeof (key->type)); | ||
957 | GNUNET_memcpy (buffer + sizeof (key->type), &(key->ecdsa_key), length | ||
958 | - sizeof (key->type)); | ||
959 | return length; | ||
960 | } | ||
961 | |||
962 | |||
963 | ssize_t | ||
964 | GNUNET_IDENTITY_signature_get_length (const struct | ||
965 | GNUNET_IDENTITY_Signature *sig) | ||
966 | { | ||
967 | switch (ntohl (sig->type)) | ||
968 | { | ||
969 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
970 | return sizeof (sig->type) + sizeof (sig->ecdsa_signature); | ||
971 | break; | ||
972 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
973 | return sizeof (sig->type) + sizeof (sig->eddsa_signature); | ||
974 | break; | ||
975 | default: | ||
976 | GNUNET_break (0); | ||
977 | } | ||
978 | return -1; | ||
979 | } | ||
980 | |||
981 | |||
982 | ssize_t | ||
983 | GNUNET_IDENTITY_signature_get_raw_length_by_type (uint32_t type) | ||
984 | { | ||
985 | switch (ntohl (type)) | ||
986 | { | ||
987 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
988 | return sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | ||
989 | break; | ||
990 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
991 | return sizeof (struct GNUNET_CRYPTO_EddsaSignature); | ||
992 | break; | ||
993 | default: | ||
994 | GNUNET_break (0); | ||
995 | } | ||
996 | return -1; | ||
997 | } | ||
998 | |||
999 | |||
1000 | ssize_t | ||
1001 | GNUNET_IDENTITY_read_signature_from_buffer (struct | ||
1002 | GNUNET_IDENTITY_Signature *sig, | ||
1003 | const void*buffer, | ||
1004 | size_t len) | ||
1005 | { | ||
1006 | if (len < sizeof (sig->type)) | ||
1007 | return -1; | ||
1008 | GNUNET_memcpy (&(sig->type), buffer, sizeof (sig->type)); | ||
1009 | const ssize_t length = GNUNET_IDENTITY_signature_get_length (sig); | ||
1010 | if (len < length) | ||
1011 | return -1; | ||
1012 | if (length < 0) | ||
1013 | return -2; | ||
1014 | GNUNET_memcpy (&(sig->ecdsa_signature), buffer + sizeof (sig->type), length | ||
1015 | - sizeof (sig->type)); | ||
1016 | return length; | ||
1017 | } | ||
1018 | |||
1019 | |||
1020 | ssize_t | ||
1021 | GNUNET_IDENTITY_write_signature_to_buffer (const struct | ||
1022 | GNUNET_IDENTITY_Signature *sig, | ||
1023 | void*buffer, | ||
1024 | size_t len) | ||
1025 | { | ||
1026 | const ssize_t length = GNUNET_IDENTITY_signature_get_length (sig); | ||
1027 | if (len < length) | ||
1028 | return -1; | ||
1029 | if (length < 0) | ||
1030 | return -2; | ||
1031 | GNUNET_memcpy (buffer, &(sig->type), sizeof (sig->type)); | ||
1032 | GNUNET_memcpy (buffer + sizeof (sig->type), &(sig->ecdsa_signature), length | ||
1033 | - sizeof (sig->type)); | ||
1034 | return length; | ||
1035 | } | ||
1036 | |||
1037 | |||
1038 | enum GNUNET_GenericReturnValue | ||
1039 | GNUNET_IDENTITY_sign_raw_ (const struct | ||
1040 | GNUNET_IDENTITY_PrivateKey *priv, | ||
1041 | const struct | ||
1042 | GNUNET_CRYPTO_EccSignaturePurpose *purpose, | ||
1043 | unsigned char *sig) | ||
1044 | { | ||
1045 | switch (ntohl (priv->type)) | ||
1046 | { | ||
1047 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1048 | return GNUNET_CRYPTO_ecdsa_sign_ (&(priv->ecdsa_key), purpose, | ||
1049 | (struct | ||
1050 | GNUNET_CRYPTO_EcdsaSignature*) sig); | ||
1051 | break; | ||
1052 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1053 | return GNUNET_CRYPTO_eddsa_sign_ (&(priv->eddsa_key), purpose, | ||
1054 | (struct | ||
1055 | GNUNET_CRYPTO_EddsaSignature*) sig); | ||
1056 | break; | ||
1057 | default: | ||
1058 | GNUNET_break (0); | ||
1059 | } | ||
1060 | |||
1061 | return GNUNET_SYSERR; | ||
1062 | } | ||
1063 | |||
1064 | |||
1065 | enum GNUNET_GenericReturnValue | ||
1066 | GNUNET_IDENTITY_sign_ (const struct | ||
1067 | GNUNET_IDENTITY_PrivateKey *priv, | ||
1068 | const struct | ||
1069 | GNUNET_CRYPTO_EccSignaturePurpose *purpose, | ||
1070 | struct GNUNET_IDENTITY_Signature *sig) | ||
1071 | { | ||
1072 | sig->type = priv->type; | ||
1073 | switch (ntohl (priv->type)) | ||
1074 | { | ||
1075 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1076 | return GNUNET_CRYPTO_ecdsa_sign_ (&(priv->ecdsa_key), purpose, | ||
1077 | &(sig->ecdsa_signature)); | ||
1078 | break; | ||
1079 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1080 | return GNUNET_CRYPTO_eddsa_sign_ (&(priv->eddsa_key), purpose, | ||
1081 | &(sig->eddsa_signature)); | ||
1082 | break; | ||
1083 | default: | ||
1084 | GNUNET_break (0); | ||
1085 | } | ||
1086 | |||
1087 | return GNUNET_SYSERR; | ||
1088 | } | ||
1089 | |||
1090 | |||
1091 | enum GNUNET_GenericReturnValue | ||
1092 | GNUNET_IDENTITY_signature_verify_ (uint32_t purpose, | ||
1093 | const struct | ||
1094 | GNUNET_CRYPTO_EccSignaturePurpose *validate, | ||
1095 | const struct GNUNET_IDENTITY_Signature *sig, | ||
1096 | const struct GNUNET_IDENTITY_PublicKey *pub) | ||
1097 | { | ||
1098 | /* check type matching of 'sig' and 'pub' */ | ||
1099 | GNUNET_assert (ntohl (pub->type) == ntohl (sig->type)); | ||
1100 | switch (ntohl (pub->type)) | ||
1101 | { | ||
1102 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1103 | return GNUNET_CRYPTO_ecdsa_verify_ (purpose, validate, | ||
1104 | &(sig->ecdsa_signature), | ||
1105 | &(pub->ecdsa_key)); | ||
1106 | break; | ||
1107 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1108 | return GNUNET_CRYPTO_eddsa_verify_ (purpose, validate, | ||
1109 | &(sig->eddsa_signature), | ||
1110 | &(pub->eddsa_key)); | ||
1111 | break; | ||
1112 | default: | ||
1113 | GNUNET_break (0); | ||
1114 | } | ||
1115 | |||
1116 | return GNUNET_SYSERR; | ||
1117 | } | ||
1118 | |||
1119 | |||
1120 | enum GNUNET_GenericReturnValue | ||
1121 | GNUNET_IDENTITY_signature_verify_raw_ (uint32_t purpose, | ||
1122 | const struct | ||
1123 | GNUNET_CRYPTO_EccSignaturePurpose * | ||
1124 | validate, | ||
1125 | const unsigned char *sig, | ||
1126 | const struct | ||
1127 | GNUNET_IDENTITY_PublicKey *pub) | ||
1128 | { | ||
1129 | switch (ntohl (pub->type)) | ||
1130 | { | ||
1131 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1132 | return GNUNET_CRYPTO_ecdsa_verify_ (purpose, validate, | ||
1133 | (struct | ||
1134 | GNUNET_CRYPTO_EcdsaSignature*) sig, | ||
1135 | &(pub->ecdsa_key)); | ||
1136 | break; | ||
1137 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1138 | return GNUNET_CRYPTO_eddsa_verify_ (purpose, validate, | ||
1139 | (struct | ||
1140 | GNUNET_CRYPTO_EddsaSignature*) sig, | ||
1141 | &(pub->eddsa_key)); | ||
1142 | break; | ||
1143 | default: | ||
1144 | GNUNET_break (0); | ||
1145 | } | ||
1146 | |||
1147 | return GNUNET_SYSERR; | ||
1148 | } | ||
1149 | |||
1150 | |||
1151 | ssize_t | ||
1152 | GNUNET_IDENTITY_encrypt_old (const void *block, | ||
1153 | size_t size, | ||
1154 | const struct GNUNET_IDENTITY_PublicKey *pub, | ||
1155 | struct GNUNET_CRYPTO_EcdhePublicKey *ecc, | ||
1156 | void *result) | ||
1157 | { | ||
1158 | struct GNUNET_CRYPTO_EcdhePrivateKey pk; | ||
1159 | GNUNET_CRYPTO_ecdhe_key_create (&pk); | ||
1160 | struct GNUNET_HashCode hash; | ||
1161 | switch (ntohl (pub->type)) | ||
1162 | { | ||
1163 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1164 | if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdh_ecdsa (&pk, &(pub->ecdsa_key), | ||
1165 | &hash)) | ||
1166 | return -1; | ||
1167 | break; | ||
1168 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1169 | if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdh_eddsa (&pk, &(pub->eddsa_key), | ||
1170 | &hash)) | ||
1171 | return -1; | ||
1172 | break; | ||
1173 | default: | ||
1174 | return -1; | ||
1175 | } | ||
1176 | GNUNET_CRYPTO_ecdhe_key_get_public (&pk, ecc); | ||
1177 | GNUNET_CRYPTO_ecdhe_key_clear (&pk); | ||
1178 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
1179 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
1180 | GNUNET_CRYPTO_hash_to_aes_key (&hash, &key, &iv); | ||
1181 | GNUNET_CRYPTO_zero_keys (&hash, sizeof(hash)); | ||
1182 | const ssize_t encrypted = GNUNET_CRYPTO_symmetric_encrypt (block, size, &key, | ||
1183 | &iv, result); | ||
1184 | GNUNET_CRYPTO_zero_keys (&key, sizeof(key)); | ||
1185 | GNUNET_CRYPTO_zero_keys (&iv, sizeof(iv)); | ||
1186 | return encrypted; | ||
1187 | } | ||
1188 | |||
1189 | |||
1190 | enum GNUNET_GenericReturnValue | ||
1191 | GNUNET_IDENTITY_encrypt (const void *pt, | ||
1192 | size_t pt_size, | ||
1193 | const struct GNUNET_IDENTITY_PublicKey *pub, | ||
1194 | void *ct_buf, | ||
1195 | size_t ct_size) | ||
1196 | { | ||
1197 | struct GNUNET_HashCode k; | ||
1198 | struct GNUNET_CRYPTO_FoKemC kemc; | ||
1199 | struct GNUNET_CRYPTO_FoKemC *kemc_buf = (struct GNUNET_CRYPTO_FoKemC*) ct_buf; | ||
1200 | unsigned char *encrypted_data = (unsigned char*) &kemc_buf[1]; | ||
1201 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | ||
1202 | unsigned char key[crypto_secretbox_KEYBYTES]; | ||
1203 | |||
1204 | if (ct_size < pt_size + GNUNET_IDENTITY_ENCRYPT_OVERHEAD_BYTES) | ||
1205 | { | ||
1206 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1207 | "Output buffer size for ciphertext too small: Got %lu, want >=%lu\n", | ||
1208 | ct_size, pt_size + GNUNET_IDENTITY_ENCRYPT_OVERHEAD_BYTES); | ||
1209 | return GNUNET_SYSERR; | ||
1210 | } | ||
1211 | switch (ntohl (pub->type)) | ||
1212 | { | ||
1213 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1214 | if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_fo_kem_encaps (&(pub->ecdsa_key), | ||
1215 | &kemc, | ||
1216 | &k)) | ||
1217 | return GNUNET_SYSERR; | ||
1218 | break; | ||
1219 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1220 | if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_fo_kem_encaps (&pub->eddsa_key, | ||
1221 | &kemc, | ||
1222 | &k)) | ||
1223 | return GNUNET_SYSERR; | ||
1224 | break; | ||
1225 | default: | ||
1226 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported key type\n"); | ||
1227 | return GNUNET_SYSERR; | ||
1228 | } | ||
1229 | memcpy (key, &k, crypto_secretbox_KEYBYTES); | ||
1230 | memcpy (nonce, ((char* ) &k) + crypto_secretbox_KEYBYTES, | ||
1231 | crypto_secretbox_NONCEBYTES); | ||
1232 | if (crypto_secretbox_easy (encrypted_data, pt, pt_size, nonce, key)) | ||
1233 | return GNUNET_SYSERR; | ||
1234 | memcpy (kemc_buf, &kemc, sizeof (kemc)); | ||
1235 | return GNUNET_OK; | ||
1236 | } | ||
1237 | |||
1238 | |||
1239 | enum GNUNET_GenericReturnValue | ||
1240 | GNUNET_IDENTITY_decrypt (const void *ct_buf, | ||
1241 | size_t ct_size, | ||
1242 | const struct GNUNET_IDENTITY_PrivateKey *priv, | ||
1243 | void *pt, | ||
1244 | size_t pt_size) | ||
1245 | { | ||
1246 | struct GNUNET_HashCode k; | ||
1247 | struct GNUNET_CRYPTO_FoKemC *kemc = (struct GNUNET_CRYPTO_FoKemC*) ct_buf; | ||
1248 | unsigned char *encrypted_data = (unsigned char*) &kemc[1]; | ||
1249 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | ||
1250 | unsigned char key[crypto_secretbox_KEYBYTES]; | ||
1251 | size_t expected_pt_len = ct_size - GNUNET_IDENTITY_ENCRYPT_OVERHEAD_BYTES; | ||
1252 | |||
1253 | if (pt_size < expected_pt_len) | ||
1254 | { | ||
1255 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1256 | "Output buffer size for plaintext too small: Got %lu, want >=%lu\n", | ||
1257 | pt_size, expected_pt_len); | ||
1258 | return GNUNET_SYSERR; | ||
1259 | } | ||
1260 | switch (ntohl (priv->type)) | ||
1261 | { | ||
1262 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1263 | if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_fo_kem_decaps (&(priv->ecdsa_key), | ||
1264 | kemc, | ||
1265 | &k)) | ||
1266 | return GNUNET_SYSERR; | ||
1267 | break; | ||
1268 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1269 | if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_fo_kem_decaps (&(priv->eddsa_key), | ||
1270 | kemc, | ||
1271 | &k)) | ||
1272 | return GNUNET_SYSERR; | ||
1273 | break; | ||
1274 | default: | ||
1275 | return GNUNET_SYSERR; | ||
1276 | } | ||
1277 | memcpy (key, &k, crypto_secretbox_KEYBYTES); | ||
1278 | memcpy (nonce, ((char* ) &k) + crypto_secretbox_KEYBYTES, | ||
1279 | crypto_secretbox_NONCEBYTES); | ||
1280 | if (crypto_secretbox_open_easy (pt, encrypted_data, ct_size - sizeof (*kemc), | ||
1281 | nonce, key)) | ||
1282 | return GNUNET_SYSERR; | ||
1283 | return GNUNET_OK; | ||
1284 | } | ||
1285 | |||
1286 | |||
1287 | ssize_t | ||
1288 | GNUNET_IDENTITY_decrypt_old (const void *block, | ||
1289 | size_t size, | ||
1290 | const struct GNUNET_IDENTITY_PrivateKey *priv, | ||
1291 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecc, | ||
1292 | void *result) | ||
1293 | { | ||
1294 | struct GNUNET_HashCode hash; | ||
1295 | switch (ntohl (priv->type)) | ||
1296 | { | ||
1297 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
1298 | if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_ecdh (&(priv->ecdsa_key), ecc, | ||
1299 | &hash)) | ||
1300 | return -1; | ||
1301 | break; | ||
1302 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1303 | if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_ecdh (&(priv->eddsa_key), ecc, | ||
1304 | &hash)) | ||
1305 | return -1; | ||
1306 | break; | ||
1307 | default: | ||
1308 | return -1; | ||
1309 | } | ||
1310 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
1311 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
1312 | GNUNET_CRYPTO_hash_to_aes_key (&hash, &key, &iv); | ||
1313 | GNUNET_CRYPTO_zero_keys (&hash, sizeof(hash)); | ||
1314 | const ssize_t decrypted = GNUNET_CRYPTO_symmetric_decrypt (block, size, &key, | ||
1315 | &iv, result); | ||
1316 | GNUNET_CRYPTO_zero_keys (&key, sizeof(key)); | ||
1317 | GNUNET_CRYPTO_zero_keys (&iv, sizeof(iv)); | ||
1318 | return decrypted; | ||
1319 | } | ||
1320 | |||
1321 | |||
1322 | char * | ||
1323 | GNUNET_IDENTITY_public_key_to_string (const struct | ||
1324 | GNUNET_IDENTITY_PublicKey *key) | ||
1325 | { | ||
1326 | size_t size = GNUNET_IDENTITY_public_key_get_length (key); | ||
1327 | return GNUNET_STRINGS_data_to_string_alloc (key, | ||
1328 | size); | ||
1329 | } | ||
1330 | |||
1331 | |||
1332 | char * | ||
1333 | GNUNET_IDENTITY_private_key_to_string (const struct | ||
1334 | GNUNET_IDENTITY_PrivateKey *key) | ||
1335 | { | ||
1336 | size_t size = GNUNET_IDENTITY_private_key_get_length (key); | ||
1337 | return GNUNET_STRINGS_data_to_string_alloc (key, | ||
1338 | size); | ||
1339 | } | ||
1340 | |||
1341 | |||
1342 | enum GNUNET_GenericReturnValue | ||
1343 | GNUNET_IDENTITY_public_key_from_string (const char *str, | ||
1344 | struct GNUNET_IDENTITY_PublicKey *key) | ||
1345 | { | ||
1346 | enum GNUNET_GenericReturnValue ret; | ||
1347 | ret = GNUNET_STRINGS_string_to_data (str, | ||
1348 | strlen (str), | ||
1349 | key, | ||
1350 | sizeof (*key)); | ||
1351 | if (GNUNET_OK != ret) | ||
1352 | return GNUNET_SYSERR; | ||
1353 | return check_key_type (ntohl (key->type)); | ||
1354 | |||
1355 | } | ||
1356 | |||
1357 | |||
1358 | enum GNUNET_GenericReturnValue | ||
1359 | GNUNET_IDENTITY_private_key_from_string (const char *str, | ||
1360 | struct GNUNET_IDENTITY_PrivateKey *key) | ||
1361 | { | ||
1362 | enum GNUNET_GenericReturnValue ret; | ||
1363 | ret = GNUNET_STRINGS_string_to_data (str, | ||
1364 | strlen (str), | ||
1365 | key, | ||
1366 | sizeof (*key)); | ||
1367 | if (GNUNET_OK != ret) | ||
1368 | return GNUNET_SYSERR; | ||
1369 | return check_key_type (ntohl (key->type)); | ||
1370 | } | ||
1371 | |||
1372 | |||
1373 | /* end of identity_api.c */ | ||