diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_tunnels.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_tunnels.c | 2249 |
1 files changed, 2249 insertions, 0 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c new file mode 100644 index 000000000..23b270b82 --- /dev/null +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c | |||
@@ -0,0 +1,2249 @@ | |||
1 | |||
2 | /* | ||
3 | This file is part of GNUnet. | ||
4 | Copyright (C) 2013, 2017 GNUnet e.V. | ||
5 | |||
6 | GNUnet is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published | ||
8 | by the Free Software Foundation; either version 3, or (at your | ||
9 | option) any later version. | ||
10 | |||
11 | GNUnet is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with GNUnet; see the file COPYING. If not, write to the | ||
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
19 | Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @file cadet/gnunet-service-cadet-new_tunnels.c | ||
24 | * @brief Information we track per tunnel. | ||
25 | * @author Bartlomiej Polot | ||
26 | * @author Christian Grothoff | ||
27 | * | ||
28 | * FIXME: | ||
29 | * - when managing connections, distinguish those that | ||
30 | * have (recently) had traffic from those that were | ||
31 | * never ready (or not recently) | ||
32 | * - implement sending and receiving KX messages | ||
33 | * - implement processing of incoming decrypted plaintext messages | ||
34 | * - clean up KX logic! | ||
35 | */ | ||
36 | #include "platform.h" | ||
37 | #include "gnunet_util_lib.h" | ||
38 | #include "gnunet_statistics_service.h" | ||
39 | #include "gnunet_signatures.h" | ||
40 | #include "cadet_protocol.h" | ||
41 | #include "cadet_path.h" | ||
42 | #include "gnunet-service-cadet-new.h" | ||
43 | #include "gnunet-service-cadet-new_channel.h" | ||
44 | #include "gnunet-service-cadet-new_connection.h" | ||
45 | #include "gnunet-service-cadet-new_tunnels.h" | ||
46 | #include "gnunet-service-cadet-new_peer.h" | ||
47 | #include "gnunet-service-cadet-new_paths.h" | ||
48 | |||
49 | |||
50 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__) | ||
51 | |||
52 | |||
53 | /** | ||
54 | * How long do we wait until tearing down an idle tunnel? | ||
55 | */ | ||
56 | #define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) | ||
57 | |||
58 | /** | ||
59 | * Yuck, replace by 'offsetof' expression? | ||
60 | * FIXME. | ||
61 | */ | ||
62 | #define AX_HEADER_SIZE (sizeof (uint32_t) * 2\ | ||
63 | + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)) | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Maximum number of skipped keys we keep in memory per tunnel. | ||
68 | */ | ||
69 | #define MAX_SKIPPED_KEYS 64 | ||
70 | |||
71 | /** | ||
72 | * Maximum number of keys (and thus ratchet steps) we are willing to | ||
73 | * skip before we decide this is either a bogus packet or a DoS-attempt. | ||
74 | */ | ||
75 | #define MAX_KEY_GAP 256 | ||
76 | |||
77 | |||
78 | /** | ||
79 | * Struct to old keys for skipped messages while advancing the Axolotl ratchet. | ||
80 | */ | ||
81 | struct CadetTunnelSkippedKey | ||
82 | { | ||
83 | /** | ||
84 | * DLL next. | ||
85 | */ | ||
86 | struct CadetTunnelSkippedKey *next; | ||
87 | |||
88 | /** | ||
89 | * DLL prev. | ||
90 | */ | ||
91 | struct CadetTunnelSkippedKey *prev; | ||
92 | |||
93 | /** | ||
94 | * When was this key stored (for timeout). | ||
95 | */ | ||
96 | struct GNUNET_TIME_Absolute timestamp; | ||
97 | |||
98 | /** | ||
99 | * Header key. | ||
100 | */ | ||
101 | struct GNUNET_CRYPTO_SymmetricSessionKey HK; | ||
102 | |||
103 | /** | ||
104 | * Message key. | ||
105 | */ | ||
106 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
107 | |||
108 | /** | ||
109 | * Key number for a given HK. | ||
110 | */ | ||
111 | unsigned int Kn; | ||
112 | }; | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Axolotl data, according to https://github.com/trevp/axolotl/wiki . | ||
117 | */ | ||
118 | struct CadetTunnelAxolotl | ||
119 | { | ||
120 | /** | ||
121 | * A (double linked) list of stored message keys and associated header keys | ||
122 | * for "skipped" messages, i.e. messages that have not been | ||
123 | * received despite the reception of more recent messages, (head). | ||
124 | */ | ||
125 | struct CadetTunnelSkippedKey *skipped_head; | ||
126 | |||
127 | /** | ||
128 | * Skipped messages' keys DLL, tail. | ||
129 | */ | ||
130 | struct CadetTunnelSkippedKey *skipped_tail; | ||
131 | |||
132 | /** | ||
133 | * 32-byte root key which gets updated by DH ratchet. | ||
134 | */ | ||
135 | struct GNUNET_CRYPTO_SymmetricSessionKey RK; | ||
136 | |||
137 | /** | ||
138 | * 32-byte header key (send). | ||
139 | */ | ||
140 | struct GNUNET_CRYPTO_SymmetricSessionKey HKs; | ||
141 | |||
142 | /** | ||
143 | * 32-byte header key (recv) | ||
144 | */ | ||
145 | struct GNUNET_CRYPTO_SymmetricSessionKey HKr; | ||
146 | |||
147 | /** | ||
148 | * 32-byte next header key (send). | ||
149 | */ | ||
150 | struct GNUNET_CRYPTO_SymmetricSessionKey NHKs; | ||
151 | |||
152 | /** | ||
153 | * 32-byte next header key (recv). | ||
154 | */ | ||
155 | struct GNUNET_CRYPTO_SymmetricSessionKey NHKr; | ||
156 | |||
157 | /** | ||
158 | * 32-byte chain keys (used for forward-secrecy updating, send). | ||
159 | */ | ||
160 | struct GNUNET_CRYPTO_SymmetricSessionKey CKs; | ||
161 | |||
162 | /** | ||
163 | * 32-byte chain keys (used for forward-secrecy updating, recv). | ||
164 | */ | ||
165 | struct GNUNET_CRYPTO_SymmetricSessionKey CKr; | ||
166 | |||
167 | /** | ||
168 | * ECDH for key exchange (A0 / B0). | ||
169 | */ | ||
170 | struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0; | ||
171 | |||
172 | /** | ||
173 | * ECDH Ratchet key (send). | ||
174 | */ | ||
175 | struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs; | ||
176 | |||
177 | /** | ||
178 | * ECDH Ratchet key (recv). | ||
179 | */ | ||
180 | struct GNUNET_CRYPTO_EcdhePublicKey DHRr; | ||
181 | |||
182 | /** | ||
183 | * When does this ratchet expire and a new one is triggered. | ||
184 | */ | ||
185 | struct GNUNET_TIME_Absolute ratchet_expiration; | ||
186 | |||
187 | /** | ||
188 | * Number of elements in @a skipped_head <-> @a skipped_tail. | ||
189 | */ | ||
190 | unsigned int skipped; | ||
191 | |||
192 | /** | ||
193 | * Message number (reset to 0 with each new ratchet, next message to send). | ||
194 | */ | ||
195 | uint32_t Ns; | ||
196 | |||
197 | /** | ||
198 | * Message number (reset to 0 with each new ratchet, next message to recv). | ||
199 | */ | ||
200 | uint32_t Nr; | ||
201 | |||
202 | /** | ||
203 | * Previous message numbers (# of msgs sent under prev ratchet) | ||
204 | */ | ||
205 | uint32_t PNs; | ||
206 | |||
207 | /** | ||
208 | * True (#GNUNET_YES) if we have to send a new ratchet key in next msg. | ||
209 | */ | ||
210 | int ratchet_flag; | ||
211 | |||
212 | /** | ||
213 | * Number of messages recieved since our last ratchet advance. | ||
214 | * - If this counter = 0, we cannot send a new ratchet key in next msg. | ||
215 | * - If this counter > 0, we can (but don't yet have to) send a new key. | ||
216 | */ | ||
217 | unsigned int ratchet_allowed; | ||
218 | |||
219 | /** | ||
220 | * Number of messages recieved since our last ratchet advance. | ||
221 | * - If this counter = 0, we cannot send a new ratchet key in next msg. | ||
222 | * - If this counter > 0, we can (but don't yet have to) send a new key. | ||
223 | */ | ||
224 | unsigned int ratchet_counter; | ||
225 | |||
226 | }; | ||
227 | |||
228 | |||
229 | /** | ||
230 | * Struct used to save messages in a non-ready tunnel to send once connected. | ||
231 | */ | ||
232 | struct CadetTunnelQueueEntry | ||
233 | { | ||
234 | /** | ||
235 | * We are entries in a DLL | ||
236 | */ | ||
237 | struct CadetTunnelQueueEntry *next; | ||
238 | |||
239 | /** | ||
240 | * We are entries in a DLL | ||
241 | */ | ||
242 | struct CadetTunnelQueueEntry *prev; | ||
243 | |||
244 | /** | ||
245 | * Tunnel these messages belong in. | ||
246 | */ | ||
247 | struct CadetTunnel *t; | ||
248 | |||
249 | /** | ||
250 | * Continuation to call once sent (on the channel layer). | ||
251 | */ | ||
252 | GNUNET_SCHEDULER_TaskCallback cont; | ||
253 | |||
254 | /** | ||
255 | * Closure for @c cont. | ||
256 | */ | ||
257 | void *cont_cls; | ||
258 | |||
259 | /** | ||
260 | * Envelope of message to send follows. | ||
261 | */ | ||
262 | struct GNUNET_MQ_Envelope *env; | ||
263 | |||
264 | /** | ||
265 | * Where to put the connection identifier into the payload | ||
266 | * of the message in @e env once we have it? | ||
267 | */ | ||
268 | struct GNUNET_CADET_ConnectionTunnelIdentifier *cid; | ||
269 | }; | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Struct containing all information regarding a tunnel to a peer. | ||
274 | */ | ||
275 | struct CadetTunnel | ||
276 | { | ||
277 | /** | ||
278 | * Destination of the tunnel. | ||
279 | */ | ||
280 | struct CadetPeer *destination; | ||
281 | |||
282 | /** | ||
283 | * Peer's ephemeral key, to recreate @c e_key and @c d_key when own | ||
284 | * ephemeral key changes. | ||
285 | */ | ||
286 | struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key; | ||
287 | |||
288 | /** | ||
289 | * Encryption ("our") key. It is only "confirmed" if kx_ctx is NULL. | ||
290 | */ | ||
291 | struct GNUNET_CRYPTO_SymmetricSessionKey e_key; | ||
292 | |||
293 | /** | ||
294 | * Decryption ("their") key. It is only "confirmed" if kx_ctx is NULL. | ||
295 | */ | ||
296 | struct GNUNET_CRYPTO_SymmetricSessionKey d_key; | ||
297 | |||
298 | /** | ||
299 | * Axolotl info. | ||
300 | */ | ||
301 | struct CadetTunnelAxolotl ax; | ||
302 | |||
303 | /** | ||
304 | * State of the tunnel connectivity. | ||
305 | */ | ||
306 | enum CadetTunnelCState cstate; | ||
307 | |||
308 | /** | ||
309 | * State of the tunnel encryption. | ||
310 | */ | ||
311 | enum CadetTunnelEState estate; | ||
312 | |||
313 | /** | ||
314 | * Task to start the rekey process. | ||
315 | */ | ||
316 | struct GNUNET_SCHEDULER_Task *rekey_task; | ||
317 | |||
318 | /** | ||
319 | * Tokenizer for decrypted messages. | ||
320 | */ | ||
321 | struct GNUNET_MessageStreamTokenizer *mst; | ||
322 | |||
323 | /** | ||
324 | * Dispatcher for decrypted messages only (do NOT use for sending!). | ||
325 | */ | ||
326 | struct GNUNET_MQ_Handle *mq; | ||
327 | |||
328 | /** | ||
329 | * DLL of connections that are actively used to reach the destination peer. | ||
330 | */ | ||
331 | struct CadetTConnection *connection_head; | ||
332 | |||
333 | /** | ||
334 | * DLL of connections that are actively used to reach the destination peer. | ||
335 | */ | ||
336 | struct CadetTConnection *connection_tail; | ||
337 | |||
338 | /** | ||
339 | * Channels inside this tunnel. Maps | ||
340 | * `struct GNUNET_CADET_ChannelTunnelNumber` to a `struct CadetChannel`. | ||
341 | */ | ||
342 | struct GNUNET_CONTAINER_MultiHashMap32 *channels; | ||
343 | |||
344 | /** | ||
345 | * Channel ID for the next created channel in this tunnel. | ||
346 | */ | ||
347 | struct GNUNET_CADET_ChannelTunnelNumber next_chid; | ||
348 | |||
349 | /** | ||
350 | * Queued messages, to transmit once tunnel gets connected. | ||
351 | */ | ||
352 | struct CadetTunnelQueueEntry *tq_head; | ||
353 | |||
354 | /** | ||
355 | * Queued messages, to transmit once tunnel gets connected. | ||
356 | */ | ||
357 | struct CadetTunnelQueueEntry *tq_tail; | ||
358 | |||
359 | /** | ||
360 | * Task scheduled if there are no more channels using the tunnel. | ||
361 | */ | ||
362 | struct GNUNET_SCHEDULER_Task *destroy_task; | ||
363 | |||
364 | /** | ||
365 | * Task to trim connections if too many are present. | ||
366 | */ | ||
367 | struct GNUNET_SCHEDULER_Task *maintain_connections_task; | ||
368 | |||
369 | /** | ||
370 | * Ephemeral message in the queue (to avoid queueing more than one). | ||
371 | */ | ||
372 | struct CadetConnectionQueue *ephm_hKILL; | ||
373 | |||
374 | /** | ||
375 | * Pong message in the queue. | ||
376 | */ | ||
377 | struct CadetConnectionQueue *pong_hKILL; | ||
378 | |||
379 | /** | ||
380 | * Number of connections in the @e connection_head DLL. | ||
381 | */ | ||
382 | unsigned int num_connections; | ||
383 | |||
384 | /** | ||
385 | * Number of entries in the @e tq_head DLL. | ||
386 | */ | ||
387 | unsigned int tq_len; | ||
388 | }; | ||
389 | |||
390 | |||
391 | /** | ||
392 | * Get the static string for the peer this tunnel is directed. | ||
393 | * | ||
394 | * @param t Tunnel. | ||
395 | * | ||
396 | * @return Static string the destination peer's ID. | ||
397 | */ | ||
398 | const char * | ||
399 | GCT_2s (const struct CadetTunnel *t) | ||
400 | { | ||
401 | static char buf[64]; | ||
402 | |||
403 | if (NULL == t) | ||
404 | return "T(NULL)"; | ||
405 | |||
406 | GNUNET_snprintf (buf, | ||
407 | sizeof (buf), | ||
408 | "T(%s)", | ||
409 | GCP_2s (t->destination)); | ||
410 | return buf; | ||
411 | } | ||
412 | |||
413 | |||
414 | /** | ||
415 | * Return the peer to which this tunnel goes. | ||
416 | * | ||
417 | * @param t a tunnel | ||
418 | * @return the destination of the tunnel | ||
419 | */ | ||
420 | struct CadetPeer * | ||
421 | GCT_get_destination (struct CadetTunnel *t) | ||
422 | { | ||
423 | return t->destination; | ||
424 | } | ||
425 | |||
426 | |||
427 | /** | ||
428 | * Count channels of a tunnel. | ||
429 | * | ||
430 | * @param t Tunnel on which to count. | ||
431 | * | ||
432 | * @return Number of channels. | ||
433 | */ | ||
434 | unsigned int | ||
435 | GCT_count_channels (struct CadetTunnel *t) | ||
436 | { | ||
437 | return GNUNET_CONTAINER_multihashmap32_size (t->channels); | ||
438 | } | ||
439 | |||
440 | |||
441 | /** | ||
442 | * Lookup a channel by its @a chid. | ||
443 | * | ||
444 | * @param t tunnel to look in | ||
445 | * @param chid number of channel to find | ||
446 | * @return NULL if channel does not exist | ||
447 | */ | ||
448 | struct CadetChannel * | ||
449 | lookup_channel (struct CadetTunnel *t, | ||
450 | struct GNUNET_CADET_ChannelTunnelNumber chid) | ||
451 | { | ||
452 | return GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
453 | ntohl (chid.cn)); | ||
454 | } | ||
455 | |||
456 | |||
457 | /** | ||
458 | * Count all created connections of a tunnel. Not necessarily ready connections! | ||
459 | * | ||
460 | * @param t Tunnel on which to count. | ||
461 | * | ||
462 | * @return Number of connections created, either being established or ready. | ||
463 | */ | ||
464 | unsigned int | ||
465 | GCT_count_any_connections (struct CadetTunnel *t) | ||
466 | { | ||
467 | return t->num_connections; | ||
468 | } | ||
469 | |||
470 | |||
471 | /** | ||
472 | * Get the connectivity state of a tunnel. | ||
473 | * | ||
474 | * @param t Tunnel. | ||
475 | * | ||
476 | * @return Tunnel's connectivity state. | ||
477 | */ | ||
478 | enum CadetTunnelCState | ||
479 | GCT_get_cstate (struct CadetTunnel *t) | ||
480 | { | ||
481 | return t->cstate; | ||
482 | } | ||
483 | |||
484 | |||
485 | /** | ||
486 | * Get the encryption state of a tunnel. | ||
487 | * | ||
488 | * @param t Tunnel. | ||
489 | * | ||
490 | * @return Tunnel's encryption state. | ||
491 | */ | ||
492 | enum CadetTunnelEState | ||
493 | GCT_get_estate (struct CadetTunnel *t) | ||
494 | { | ||
495 | return t->estate; | ||
496 | } | ||
497 | |||
498 | |||
499 | /** | ||
500 | * Create a new Axolotl ephemeral (ratchet) key. | ||
501 | * | ||
502 | * @param t Tunnel. | ||
503 | */ | ||
504 | static void | ||
505 | new_ephemeral (struct CadetTunnel *t) | ||
506 | { | ||
507 | GNUNET_free_non_null (t->ax.DHRs); | ||
508 | t->ax.DHRs = GNUNET_CRYPTO_ecdhe_key_create (); | ||
509 | } | ||
510 | |||
511 | |||
512 | /* ************************************** start core crypto ***************************** */ | ||
513 | |||
514 | |||
515 | /** | ||
516 | * Calculate HMAC. | ||
517 | * | ||
518 | * @param plaintext Content to HMAC. | ||
519 | * @param size Size of @c plaintext. | ||
520 | * @param iv Initialization vector for the message. | ||
521 | * @param key Key to use. | ||
522 | * @param hmac[out] Destination to store the HMAC. | ||
523 | */ | ||
524 | static void | ||
525 | t_hmac (const void *plaintext, | ||
526 | size_t size, | ||
527 | uint32_t iv, | ||
528 | const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
529 | struct GNUNET_ShortHashCode *hmac) | ||
530 | { | ||
531 | static const char ctx[] = "cadet authentication key"; | ||
532 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
533 | struct GNUNET_HashCode hash; | ||
534 | |||
535 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, | ||
536 | key, | ||
537 | &iv, sizeof (iv), | ||
538 | key, sizeof (*key), | ||
539 | ctx, sizeof (ctx), | ||
540 | NULL); | ||
541 | /* Two step: CADET_Hash is only 256 bits, HashCode is 512. */ | ||
542 | GNUNET_CRYPTO_hmac (&auth_key, | ||
543 | plaintext, | ||
544 | size, | ||
545 | &hash); | ||
546 | GNUNET_memcpy (hmac, | ||
547 | &hash, | ||
548 | sizeof (*hmac)); | ||
549 | } | ||
550 | |||
551 | |||
552 | /** | ||
553 | * Perform a HMAC. | ||
554 | * | ||
555 | * @param key Key to use. | ||
556 | * @param hash[out] Resulting HMAC. | ||
557 | * @param source Source key material (data to HMAC). | ||
558 | * @param len Length of @a source. | ||
559 | */ | ||
560 | static void | ||
561 | t_ax_hmac_hash (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
562 | struct GNUNET_HashCode *hash, | ||
563 | const void *source, | ||
564 | unsigned int len) | ||
565 | { | ||
566 | static const char ctx[] = "axolotl HMAC-HASH"; | ||
567 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
568 | |||
569 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, | ||
570 | key, | ||
571 | ctx, sizeof (ctx), | ||
572 | NULL); | ||
573 | GNUNET_CRYPTO_hmac (&auth_key, | ||
574 | source, | ||
575 | len, | ||
576 | hash); | ||
577 | } | ||
578 | |||
579 | |||
580 | /** | ||
581 | * Derive a symmetric encryption key from an HMAC-HASH. | ||
582 | * | ||
583 | * @param key Key to use for the HMAC. | ||
584 | * @param[out] out Key to generate. | ||
585 | * @param source Source key material (data to HMAC). | ||
586 | * @param len Length of @a source. | ||
587 | */ | ||
588 | static void | ||
589 | t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
590 | struct GNUNET_CRYPTO_SymmetricSessionKey *out, | ||
591 | const void *source, | ||
592 | unsigned int len) | ||
593 | { | ||
594 | static const char ctx[] = "axolotl derive key"; | ||
595 | struct GNUNET_HashCode h; | ||
596 | |||
597 | t_ax_hmac_hash (key, | ||
598 | &h, | ||
599 | source, | ||
600 | len); | ||
601 | GNUNET_CRYPTO_kdf (out, sizeof (*out), | ||
602 | ctx, sizeof (ctx), | ||
603 | &h, sizeof (h), | ||
604 | NULL); | ||
605 | } | ||
606 | |||
607 | |||
608 | /** | ||
609 | * Encrypt data with the axolotl tunnel key. | ||
610 | * | ||
611 | * @param t Tunnel whose key to use. | ||
612 | * @param dst Destination with @a size bytes for the encrypted data. | ||
613 | * @param src Source of the plaintext. Can overlap with @c dst, must contain @a size bytes | ||
614 | * @param size Size of the buffers at @a src and @a dst | ||
615 | */ | ||
616 | static void | ||
617 | t_ax_encrypt (struct CadetTunnel *t, | ||
618 | void *dst, | ||
619 | const void *src, | ||
620 | size_t size) | ||
621 | { | ||
622 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
623 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
624 | struct CadetTunnelAxolotl *ax; | ||
625 | size_t out_size; | ||
626 | |||
627 | ax = &t->ax; | ||
628 | ax->ratchet_counter++; | ||
629 | if ( (GNUNET_YES == ax->ratchet_allowed) && | ||
630 | ( (ratchet_messages <= ax->ratchet_counter) || | ||
631 | (0 == GNUNET_TIME_absolute_get_remaining (ax->ratchet_expiration).rel_value_us)) ) | ||
632 | { | ||
633 | ax->ratchet_flag = GNUNET_YES; | ||
634 | } | ||
635 | if (GNUNET_YES == ax->ratchet_flag) | ||
636 | { | ||
637 | /* Advance ratchet */ | ||
638 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; | ||
639 | struct GNUNET_HashCode dh; | ||
640 | struct GNUNET_HashCode hmac; | ||
641 | static const char ctx[] = "axolotl ratchet"; | ||
642 | |||
643 | new_ephemeral (t); | ||
644 | ax->HKs = ax->NHKs; | ||
645 | |||
646 | /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */ | ||
647 | GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, | ||
648 | &ax->DHRr, | ||
649 | &dh); | ||
650 | t_ax_hmac_hash (&ax->RK, | ||
651 | &hmac, | ||
652 | &dh, | ||
653 | sizeof (dh)); | ||
654 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), | ||
655 | ctx, sizeof (ctx), | ||
656 | &hmac, sizeof (hmac), | ||
657 | NULL); | ||
658 | ax->RK = keys[0]; | ||
659 | ax->NHKs = keys[1]; | ||
660 | ax->CKs = keys[2]; | ||
661 | |||
662 | ax->PNs = ax->Ns; | ||
663 | ax->Ns = 0; | ||
664 | ax->ratchet_flag = GNUNET_NO; | ||
665 | ax->ratchet_allowed = GNUNET_NO; | ||
666 | ax->ratchet_counter = 0; | ||
667 | ax->ratchet_expiration | ||
668 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), | ||
669 | ratchet_time); | ||
670 | } | ||
671 | |||
672 | t_hmac_derive_key (&ax->CKs, | ||
673 | &MK, | ||
674 | "0", | ||
675 | 1); | ||
676 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
677 | &MK, | ||
678 | NULL, 0, | ||
679 | NULL); | ||
680 | |||
681 | out_size = GNUNET_CRYPTO_symmetric_encrypt (src, | ||
682 | size, | ||
683 | &MK, | ||
684 | &iv, | ||
685 | dst); | ||
686 | GNUNET_assert (size == out_size); | ||
687 | t_hmac_derive_key (&ax->CKs, | ||
688 | &ax->CKs, | ||
689 | "1", | ||
690 | 1); | ||
691 | } | ||
692 | |||
693 | |||
694 | /** | ||
695 | * Decrypt data with the axolotl tunnel key. | ||
696 | * | ||
697 | * @param t Tunnel whose key to use. | ||
698 | * @param dst Destination for the decrypted data, must contain @a size bytes. | ||
699 | * @param src Source of the ciphertext. Can overlap with @c dst, must contain @a size bytes. | ||
700 | * @param size Size of the @a src and @a dst buffers | ||
701 | */ | ||
702 | static void | ||
703 | t_ax_decrypt (struct CadetTunnel *t, | ||
704 | void *dst, | ||
705 | const void *src, | ||
706 | size_t size) | ||
707 | { | ||
708 | struct GNUNET_CRYPTO_SymmetricSessionKey MK; | ||
709 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
710 | struct CadetTunnelAxolotl *ax; | ||
711 | size_t out_size; | ||
712 | |||
713 | ax = &t->ax; | ||
714 | t_hmac_derive_key (&ax->CKr, | ||
715 | &MK, | ||
716 | "0", | ||
717 | 1); | ||
718 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
719 | &MK, | ||
720 | NULL, 0, | ||
721 | NULL); | ||
722 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | ||
723 | out_size = GNUNET_CRYPTO_symmetric_decrypt (src, | ||
724 | size, | ||
725 | &MK, | ||
726 | &iv, | ||
727 | dst); | ||
728 | GNUNET_assert (out_size == size); | ||
729 | t_hmac_derive_key (&ax->CKr, | ||
730 | &ax->CKr, | ||
731 | "1", | ||
732 | 1); | ||
733 | } | ||
734 | |||
735 | |||
736 | /** | ||
737 | * Encrypt header with the axolotl header key. | ||
738 | * | ||
739 | * @param t Tunnel whose key to use. | ||
740 | * @param msg Message whose header to encrypt. | ||
741 | */ | ||
742 | static void | ||
743 | t_h_encrypt (struct CadetTunnel *t, | ||
744 | struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
745 | { | ||
746 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
747 | struct CadetTunnelAxolotl *ax; | ||
748 | size_t out_size; | ||
749 | |||
750 | ax = &t->ax; | ||
751 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
752 | &ax->HKs, | ||
753 | NULL, 0, | ||
754 | NULL); | ||
755 | out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->Ns, | ||
756 | AX_HEADER_SIZE, | ||
757 | &ax->HKs, | ||
758 | &iv, | ||
759 | &msg->Ns); | ||
760 | GNUNET_assert (AX_HEADER_SIZE == out_size); | ||
761 | } | ||
762 | |||
763 | |||
764 | /** | ||
765 | * Decrypt header with the current axolotl header key. | ||
766 | * | ||
767 | * @param t Tunnel whose current ax HK to use. | ||
768 | * @param src Message whose header to decrypt. | ||
769 | * @param dst Where to decrypt header to. | ||
770 | */ | ||
771 | static void | ||
772 | t_h_decrypt (struct CadetTunnel *t, | ||
773 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
774 | struct GNUNET_CADET_TunnelEncryptedMessage *dst) | ||
775 | { | ||
776 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
777 | struct CadetTunnelAxolotl *ax; | ||
778 | size_t out_size; | ||
779 | |||
780 | ax = &t->ax; | ||
781 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
782 | &ax->HKr, | ||
783 | NULL, 0, | ||
784 | NULL); | ||
785 | out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, | ||
786 | AX_HEADER_SIZE, | ||
787 | &ax->HKr, | ||
788 | &iv, | ||
789 | &dst->Ns); | ||
790 | GNUNET_assert (AX_HEADER_SIZE == out_size); | ||
791 | } | ||
792 | |||
793 | |||
794 | /** | ||
795 | * Delete a key from the list of skipped keys. | ||
796 | * | ||
797 | * @param t Tunnel to delete from. | ||
798 | * @param key Key to delete. | ||
799 | */ | ||
800 | static void | ||
801 | delete_skipped_key (struct CadetTunnel *t, | ||
802 | struct CadetTunnelSkippedKey *key) | ||
803 | { | ||
804 | GNUNET_CONTAINER_DLL_remove (t->ax.skipped_head, | ||
805 | t->ax.skipped_tail, | ||
806 | key); | ||
807 | GNUNET_free (key); | ||
808 | t->ax.skipped--; | ||
809 | } | ||
810 | |||
811 | |||
812 | /** | ||
813 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
814 | * data has not been altered since it was sent by the remote peer. | ||
815 | * | ||
816 | * @param t Tunnel whose key to use. | ||
817 | * @param dst Destination for the plaintext. | ||
818 | * @param src Source of the message. Can overlap with @c dst. | ||
819 | * @param size Size of the message. | ||
820 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
821 | */ | ||
822 | static ssize_t | ||
823 | try_old_ax_keys (struct CadetTunnel *t, | ||
824 | void *dst, | ||
825 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
826 | size_t size) | ||
827 | { | ||
828 | struct CadetTunnelSkippedKey *key; | ||
829 | struct GNUNET_ShortHashCode *hmac; | ||
830 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
831 | struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; | ||
832 | struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK; | ||
833 | size_t esize; | ||
834 | size_t res; | ||
835 | size_t len; | ||
836 | unsigned int N; | ||
837 | |||
838 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
839 | "Trying skipped keys\n"); | ||
840 | hmac = &plaintext_header.hmac; | ||
841 | esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
842 | |||
843 | /* Find a correct Header Key */ | ||
844 | valid_HK = NULL; | ||
845 | for (key = t->ax.skipped_head; NULL != key; key = key->next) | ||
846 | { | ||
847 | t_hmac (&src->Ns, | ||
848 | AX_HEADER_SIZE + esize, | ||
849 | 0, | ||
850 | &key->HK, | ||
851 | hmac); | ||
852 | if (0 == memcmp (hmac, | ||
853 | &src->hmac, | ||
854 | sizeof (*hmac))) | ||
855 | { | ||
856 | valid_HK = &key->HK; | ||
857 | break; | ||
858 | } | ||
859 | } | ||
860 | if (NULL == key) | ||
861 | return -1; | ||
862 | |||
863 | /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */ | ||
864 | GNUNET_assert (size > sizeof (struct GNUNET_CADET_TunnelEncryptedMessage)); | ||
865 | len = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
866 | GNUNET_assert (len >= sizeof (struct GNUNET_MessageHeader)); | ||
867 | |||
868 | /* Decrypt header */ | ||
869 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
870 | &key->HK, | ||
871 | NULL, 0, | ||
872 | NULL); | ||
873 | res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, | ||
874 | AX_HEADER_SIZE, | ||
875 | &key->HK, | ||
876 | &iv, | ||
877 | &plaintext_header.Ns); | ||
878 | GNUNET_assert (AX_HEADER_SIZE == res); | ||
879 | |||
880 | /* Find the correct message key */ | ||
881 | N = ntohl (plaintext_header.Ns); | ||
882 | while ( (NULL != key) && | ||
883 | (N != key->Kn) ) | ||
884 | key = key->next; | ||
885 | if ( (NULL == key) || | ||
886 | (0 != memcmp (&key->HK, | ||
887 | valid_HK, | ||
888 | sizeof (*valid_HK))) ) | ||
889 | return -1; | ||
890 | |||
891 | /* Decrypt payload */ | ||
892 | GNUNET_CRYPTO_symmetric_derive_iv (&iv, | ||
893 | &key->MK, | ||
894 | NULL, | ||
895 | 0, | ||
896 | NULL); | ||
897 | res = GNUNET_CRYPTO_symmetric_decrypt (&src[1], | ||
898 | len, | ||
899 | &key->MK, | ||
900 | &iv, | ||
901 | dst); | ||
902 | delete_skipped_key (t, | ||
903 | key); | ||
904 | return res; | ||
905 | } | ||
906 | |||
907 | |||
908 | /** | ||
909 | * Delete a key from the list of skipped keys. | ||
910 | * | ||
911 | * @param t Tunnel to delete from. | ||
912 | * @param HKr Header Key to use. | ||
913 | */ | ||
914 | static void | ||
915 | store_skipped_key (struct CadetTunnel *t, | ||
916 | const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr) | ||
917 | { | ||
918 | struct CadetTunnelSkippedKey *key; | ||
919 | |||
920 | key = GNUNET_new (struct CadetTunnelSkippedKey); | ||
921 | key->timestamp = GNUNET_TIME_absolute_get (); | ||
922 | key->Kn = t->ax.Nr; | ||
923 | key->HK = t->ax.HKr; | ||
924 | t_hmac_derive_key (&t->ax.CKr, | ||
925 | &key->MK, | ||
926 | "0", | ||
927 | 1); | ||
928 | t_hmac_derive_key (&t->ax.CKr, | ||
929 | &t->ax.CKr, | ||
930 | "1", | ||
931 | 1); | ||
932 | GNUNET_CONTAINER_DLL_insert (t->ax.skipped_head, | ||
933 | t->ax.skipped_tail, | ||
934 | key); | ||
935 | t->ax.skipped++; | ||
936 | t->ax.Nr++; | ||
937 | } | ||
938 | |||
939 | |||
940 | /** | ||
941 | * Stage skipped AX keys and calculate the message key. | ||
942 | * Stores each HK and MK for skipped messages. | ||
943 | * | ||
944 | * @param t Tunnel where to stage the keys. | ||
945 | * @param HKr Header key. | ||
946 | * @param Np Received meesage number. | ||
947 | * @return #GNUNET_OK if keys were stored. | ||
948 | * #GNUNET_SYSERR if an error ocurred (Np not expected). | ||
949 | */ | ||
950 | static int | ||
951 | store_ax_keys (struct CadetTunnel *t, | ||
952 | const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, | ||
953 | uint32_t Np) | ||
954 | { | ||
955 | int gap; | ||
956 | |||
957 | gap = Np - t->ax.Nr; | ||
958 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
959 | "Storing skipped keys [%u, %u)\n", | ||
960 | t->ax.Nr, | ||
961 | Np); | ||
962 | if (MAX_KEY_GAP < gap) | ||
963 | { | ||
964 | /* Avoid DoS (forcing peer to do 2^33 chain HMAC operations) */ | ||
965 | /* TODO: start new key exchange on return */ | ||
966 | GNUNET_break_op (0); | ||
967 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
968 | "Got message %u, expected %u+\n", | ||
969 | Np, | ||
970 | t->ax.Nr); | ||
971 | return GNUNET_SYSERR; | ||
972 | } | ||
973 | if (0 > gap) | ||
974 | { | ||
975 | /* Delayed message: don't store keys, flag to try old keys. */ | ||
976 | return GNUNET_SYSERR; | ||
977 | } | ||
978 | |||
979 | while (t->ax.Nr < Np) | ||
980 | store_skipped_key (t, | ||
981 | HKr); | ||
982 | |||
983 | while (t->ax.skipped > MAX_SKIPPED_KEYS) | ||
984 | delete_skipped_key (t, | ||
985 | t->ax.skipped_tail); | ||
986 | return GNUNET_OK; | ||
987 | } | ||
988 | |||
989 | |||
990 | /** | ||
991 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
992 | * data has not been altered since it was sent by the remote peer. | ||
993 | * | ||
994 | * @param t Tunnel whose key to use. | ||
995 | * @param dst Destination for the plaintext. | ||
996 | * @param src Source of the message. Can overlap with @c dst. | ||
997 | * @param size Size of the message. | ||
998 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
999 | */ | ||
1000 | static ssize_t | ||
1001 | t_ax_decrypt_and_validate (struct CadetTunnel *t, | ||
1002 | void *dst, | ||
1003 | const struct GNUNET_CADET_TunnelEncryptedMessage *src, | ||
1004 | size_t size) | ||
1005 | { | ||
1006 | struct CadetTunnelAxolotl *ax; | ||
1007 | struct GNUNET_ShortHashCode msg_hmac; | ||
1008 | struct GNUNET_HashCode hmac; | ||
1009 | struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; | ||
1010 | uint32_t Np; | ||
1011 | uint32_t PNp; | ||
1012 | size_t esize; /* Size of encryped payload */ | ||
1013 | |||
1014 | esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); | ||
1015 | ax = &t->ax; | ||
1016 | |||
1017 | /* Try current HK */ | ||
1018 | t_hmac (&src->Ns, | ||
1019 | AX_HEADER_SIZE + esize, | ||
1020 | 0, &ax->HKr, | ||
1021 | &msg_hmac); | ||
1022 | if (0 != memcmp (&msg_hmac, | ||
1023 | &src->hmac, | ||
1024 | sizeof (msg_hmac))) | ||
1025 | { | ||
1026 | static const char ctx[] = "axolotl ratchet"; | ||
1027 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */ | ||
1028 | struct GNUNET_CRYPTO_SymmetricSessionKey HK; | ||
1029 | struct GNUNET_HashCode dh; | ||
1030 | struct GNUNET_CRYPTO_EcdhePublicKey *DHRp; | ||
1031 | |||
1032 | /* Try Next HK */ | ||
1033 | t_hmac (&src->Ns, | ||
1034 | AX_HEADER_SIZE + esize, | ||
1035 | 0, | ||
1036 | &ax->NHKr, | ||
1037 | &msg_hmac); | ||
1038 | if (0 != memcmp (&msg_hmac, | ||
1039 | &src->hmac, | ||
1040 | sizeof (msg_hmac))) | ||
1041 | { | ||
1042 | /* Try the skipped keys, if that fails, we're out of luck. */ | ||
1043 | return try_old_ax_keys (t, | ||
1044 | dst, | ||
1045 | src, | ||
1046 | size); | ||
1047 | } | ||
1048 | HK = ax->HKr; | ||
1049 | ax->HKr = ax->NHKr; | ||
1050 | t_h_decrypt (t, | ||
1051 | src, | ||
1052 | &plaintext_header); | ||
1053 | Np = ntohl (plaintext_header.Ns); | ||
1054 | PNp = ntohl (plaintext_header.PNs); | ||
1055 | DHRp = &plaintext_header.DHRs; | ||
1056 | store_ax_keys (t, | ||
1057 | &HK, | ||
1058 | PNp); | ||
1059 | |||
1060 | /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */ | ||
1061 | GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, | ||
1062 | DHRp, | ||
1063 | &dh); | ||
1064 | t_ax_hmac_hash (&ax->RK, | ||
1065 | &hmac, | ||
1066 | &dh, sizeof (dh)); | ||
1067 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), | ||
1068 | ctx, sizeof (ctx), | ||
1069 | &hmac, sizeof (hmac), | ||
1070 | NULL); | ||
1071 | |||
1072 | /* Commit "purported" keys */ | ||
1073 | ax->RK = keys[0]; | ||
1074 | ax->NHKr = keys[1]; | ||
1075 | ax->CKr = keys[2]; | ||
1076 | ax->DHRr = *DHRp; | ||
1077 | ax->Nr = 0; | ||
1078 | ax->ratchet_allowed = GNUNET_YES; | ||
1079 | } | ||
1080 | else | ||
1081 | { | ||
1082 | t_h_decrypt (t, | ||
1083 | src, | ||
1084 | &plaintext_header); | ||
1085 | Np = ntohl (plaintext_header.Ns); | ||
1086 | PNp = ntohl (plaintext_header.PNs); | ||
1087 | } | ||
1088 | if ( (Np != ax->Nr) && | ||
1089 | (GNUNET_OK != store_ax_keys (t, | ||
1090 | &ax->HKr, | ||
1091 | Np)) ) | ||
1092 | { | ||
1093 | /* Try the skipped keys, if that fails, we're out of luck. */ | ||
1094 | return try_old_ax_keys (t, | ||
1095 | dst, | ||
1096 | src, | ||
1097 | size); | ||
1098 | } | ||
1099 | |||
1100 | t_ax_decrypt (t, | ||
1101 | dst, | ||
1102 | &src[1], | ||
1103 | esize); | ||
1104 | ax->Nr = Np + 1; | ||
1105 | return esize; | ||
1106 | } | ||
1107 | |||
1108 | |||
1109 | /** | ||
1110 | * Send a KX message. | ||
1111 | * | ||
1112 | * FIXME: does not take care of sender-authentication yet! | ||
1113 | * | ||
1114 | * @param t Tunnel on which to send it. | ||
1115 | * @param force_reply Force the other peer to reply with a KX message. | ||
1116 | */ | ||
1117 | static void | ||
1118 | send_kx (struct CadetTunnel *t, | ||
1119 | int force_reply) | ||
1120 | { | ||
1121 | struct CadetTunnelAxolotl *ax = &t->ax; | ||
1122 | struct CadetConnection *c; | ||
1123 | struct GNUNET_MQ_Envelope *env; | ||
1124 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; | ||
1125 | enum GNUNET_CADET_KX_Flags flags; | ||
1126 | |||
1127 | #if FIXME | ||
1128 | if (NULL != t->ephm_h) | ||
1129 | { | ||
1130 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1131 | " already queued, nop\n"); | ||
1132 | return; | ||
1133 | } | ||
1134 | #endif | ||
1135 | c = NULL; // FIXME: figure out where to transmit... | ||
1136 | |||
1137 | // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); | ||
1138 | env = GNUNET_MQ_msg (msg, | ||
1139 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); | ||
1140 | flags = GNUNET_CADET_KX_FLAG_NONE; | ||
1141 | if (GNUNET_YES == force_reply) | ||
1142 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | ||
1143 | msg->flags = htonl (flags); | ||
1144 | msg->cid = *GCC_get_id (c); | ||
1145 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, | ||
1146 | &msg->ephemeral_key); | ||
1147 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, | ||
1148 | &msg->ratchet_key); | ||
1149 | |||
1150 | // FIXME: send 'env'. | ||
1151 | #if FIXME | ||
1152 | t->ephm_h = GCC_send_prebuilt_message (&msg.header, | ||
1153 | UINT16_MAX, | ||
1154 | zero, | ||
1155 | c, | ||
1156 | GCC_is_origin (c, GNUNET_YES), | ||
1157 | GNUNET_YES, &ephm_sent, t); | ||
1158 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
1159 | GCT_change_estate (t, CADET_TUNNEL_KEY_SENT); | ||
1160 | #endif | ||
1161 | } | ||
1162 | |||
1163 | |||
1164 | /** | ||
1165 | * Handle KX message. | ||
1166 | * | ||
1167 | * FIXME: sender-authentication in KX is missing! | ||
1168 | * | ||
1169 | * @param ct connection/tunnel combo that received encrypted message | ||
1170 | * @param msg the key exchange message | ||
1171 | */ | ||
1172 | void | ||
1173 | GCT_handle_kx (struct CadetTConnection *ct, | ||
1174 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
1175 | { | ||
1176 | struct CadetTunnel *t = ct->t; | ||
1177 | struct CadetTunnelAxolotl *ax = &t->ax; | ||
1178 | struct GNUNET_HashCode key_material[3]; | ||
1179 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[5]; | ||
1180 | const char salt[] = "CADET Axolotl salt"; | ||
1181 | const struct GNUNET_PeerIdentity *pid; | ||
1182 | int am_I_alice; | ||
1183 | |||
1184 | pid = GCP_get_id (t->destination); | ||
1185 | if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, | ||
1186 | pid)) | ||
1187 | am_I_alice = GNUNET_YES; | ||
1188 | else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, | ||
1189 | pid)) | ||
1190 | am_I_alice = GNUNET_NO; | ||
1191 | else | ||
1192 | { | ||
1193 | GNUNET_break_op (0); | ||
1194 | return; | ||
1195 | } | ||
1196 | |||
1197 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags))) | ||
1198 | { | ||
1199 | if (NULL != t->rekey_task) | ||
1200 | { | ||
1201 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1202 | t->rekey_task = NULL; | ||
1203 | } | ||
1204 | send_kx (t, | ||
1205 | GNUNET_NO); | ||
1206 | } | ||
1207 | |||
1208 | if (0 == memcmp (&ax->DHRr, | ||
1209 | &msg->ratchet_key, | ||
1210 | sizeof (msg->ratchet_key))) | ||
1211 | { | ||
1212 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1213 | " known ratchet key, exit\n"); | ||
1214 | return; | ||
1215 | } | ||
1216 | |||
1217 | ax->DHRr = msg->ratchet_key; | ||
1218 | |||
1219 | /* ECDH A B0 */ | ||
1220 | if (GNUNET_YES == am_I_alice) | ||
1221 | { | ||
1222 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ | ||
1223 | &msg->ephemeral_key, /* B0 */ | ||
1224 | &key_material[0]); | ||
1225 | } | ||
1226 | else | ||
1227 | { | ||
1228 | GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* B0 */ | ||
1229 | &pid->public_key, /* A */ | ||
1230 | &key_material[0]); | ||
1231 | } | ||
1232 | |||
1233 | /* ECDH A0 B */ | ||
1234 | if (GNUNET_YES == am_I_alice) | ||
1235 | { | ||
1236 | GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* A0 */ | ||
1237 | &pid->public_key, /* B */ | ||
1238 | &key_material[1]); | ||
1239 | } | ||
1240 | else | ||
1241 | { | ||
1242 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ | ||
1243 | &msg->ephemeral_key, /* B0 */ | ||
1244 | &key_material[1]); | ||
1245 | |||
1246 | |||
1247 | } | ||
1248 | |||
1249 | /* ECDH A0 B0 */ | ||
1250 | /* (This is the triple-DH, we could probably safely skip this, | ||
1251 | as A0/B0 are already in the key material.) */ | ||
1252 | GNUNET_CRYPTO_ecc_ecdh (ax->kx_0, /* A0 or B0 */ | ||
1253 | &msg->ephemeral_key, /* B0 or A0 */ | ||
1254 | &key_material[2]); | ||
1255 | |||
1256 | /* KDF */ | ||
1257 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), | ||
1258 | salt, sizeof (salt), | ||
1259 | &key_material, sizeof (key_material), | ||
1260 | NULL); | ||
1261 | |||
1262 | if (0 == memcmp (&ax->RK, | ||
1263 | &keys[0], | ||
1264 | sizeof (ax->RK))) | ||
1265 | { | ||
1266 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1267 | " known handshake key, exit\n"); | ||
1268 | return; | ||
1269 | } | ||
1270 | ax->RK = keys[0]; | ||
1271 | if (GNUNET_YES == am_I_alice) | ||
1272 | { | ||
1273 | ax->HKr = keys[1]; | ||
1274 | ax->NHKs = keys[2]; | ||
1275 | ax->NHKr = keys[3]; | ||
1276 | ax->CKr = keys[4]; | ||
1277 | ax->ratchet_flag = GNUNET_YES; | ||
1278 | } | ||
1279 | else | ||
1280 | { | ||
1281 | ax->HKs = keys[1]; | ||
1282 | ax->NHKr = keys[2]; | ||
1283 | ax->NHKs = keys[3]; | ||
1284 | ax->CKs = keys[4]; | ||
1285 | ax->ratchet_flag = GNUNET_NO; | ||
1286 | ax->ratchet_allowed = GNUNET_NO; | ||
1287 | ax->ratchet_counter = 0; | ||
1288 | ax->ratchet_expiration | ||
1289 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), | ||
1290 | ratchet_time); | ||
1291 | } | ||
1292 | ax->PNs = 0; | ||
1293 | ax->Nr = 0; | ||
1294 | ax->Ns = 0; | ||
1295 | |||
1296 | #if FIXME | ||
1297 | /* After KX is done, update state machine and begin transmissions... */ | ||
1298 | GCT_change_estate (t, | ||
1299 | CADET_TUNNEL_KEY_PING); | ||
1300 | send_queued_data (t); | ||
1301 | #endif | ||
1302 | } | ||
1303 | |||
1304 | |||
1305 | /* ************************************** end core crypto ***************************** */ | ||
1306 | |||
1307 | |||
1308 | /** | ||
1309 | * Add a channel to a tunnel. | ||
1310 | * | ||
1311 | * @param t Tunnel. | ||
1312 | * @param ch Channel | ||
1313 | * @return unique number identifying @a ch within @a t | ||
1314 | */ | ||
1315 | struct GNUNET_CADET_ChannelTunnelNumber | ||
1316 | GCT_add_channel (struct CadetTunnel *t, | ||
1317 | struct CadetChannel *ch) | ||
1318 | { | ||
1319 | struct GNUNET_CADET_ChannelTunnelNumber ret; | ||
1320 | uint32_t chid; | ||
1321 | |||
1322 | chid = ntohl (t->next_chid.cn); | ||
1323 | while (NULL != | ||
1324 | GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
1325 | chid)) | ||
1326 | chid++; | ||
1327 | GNUNET_assert (GNUNET_YES == | ||
1328 | GNUNET_CONTAINER_multihashmap32_put (t->channels, | ||
1329 | chid, | ||
1330 | ch, | ||
1331 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1332 | t->next_chid.cn = htonl (chid + 1); | ||
1333 | ret.cn = htonl (chid); | ||
1334 | return ret; | ||
1335 | } | ||
1336 | |||
1337 | |||
1338 | /** | ||
1339 | * This tunnel is no longer used, destroy it. | ||
1340 | * | ||
1341 | * @param cls the idle tunnel | ||
1342 | */ | ||
1343 | static void | ||
1344 | destroy_tunnel (void *cls) | ||
1345 | { | ||
1346 | struct CadetTunnel *t = cls; | ||
1347 | struct CadetTConnection *ct; | ||
1348 | struct CadetTunnelQueueEntry *tqe; | ||
1349 | |||
1350 | t->destroy_task = NULL; | ||
1351 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels)); | ||
1352 | while (NULL != (ct = t->connection_head)) | ||
1353 | { | ||
1354 | GNUNET_assert (ct->t == t); | ||
1355 | GNUNET_CONTAINER_DLL_remove (t->connection_head, | ||
1356 | t->connection_tail, | ||
1357 | ct); | ||
1358 | GCC_destroy (ct->cc); | ||
1359 | GNUNET_free (ct); | ||
1360 | } | ||
1361 | while (NULL != (tqe = t->tq_head)) | ||
1362 | { | ||
1363 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | ||
1364 | t->tq_tail, | ||
1365 | tqe); | ||
1366 | GNUNET_MQ_discard (tqe->env); | ||
1367 | GNUNET_free (tqe); | ||
1368 | } | ||
1369 | GCP_drop_tunnel (t->destination, | ||
1370 | t); | ||
1371 | GNUNET_CONTAINER_multihashmap32_destroy (t->channels); | ||
1372 | if (NULL != t->maintain_connections_task) | ||
1373 | { | ||
1374 | GNUNET_SCHEDULER_cancel (t->maintain_connections_task); | ||
1375 | t->maintain_connections_task = NULL; | ||
1376 | } | ||
1377 | GNUNET_MST_destroy (t->mst); | ||
1378 | GNUNET_MQ_destroy (t->mq); | ||
1379 | GNUNET_free (t); | ||
1380 | } | ||
1381 | |||
1382 | |||
1383 | /** | ||
1384 | * A connection is @a is_ready for transmission. Looks at our message | ||
1385 | * queue and if there is a message, sends it out via the connection. | ||
1386 | * | ||
1387 | * @param cls the `struct CadetTConnection` that is @a is_ready | ||
1388 | * @param is_ready #GNUNET_YES if connection are now ready, | ||
1389 | * #GNUNET_NO if connection are no longer ready | ||
1390 | */ | ||
1391 | static void | ||
1392 | connection_ready_cb (void *cls, | ||
1393 | int is_ready) | ||
1394 | { | ||
1395 | struct CadetTConnection *ct = cls; | ||
1396 | struct CadetTunnel *t = ct->t; | ||
1397 | struct CadetTunnelQueueEntry *tq = t->tq_head; | ||
1398 | |||
1399 | if (GNUNET_NO == ct->is_ready) | ||
1400 | { | ||
1401 | ct->is_ready = GNUNET_NO; | ||
1402 | return; | ||
1403 | } | ||
1404 | ct->is_ready = GNUNET_YES; | ||
1405 | if (NULL == tq) | ||
1406 | return; /* no messages pending right now */ | ||
1407 | |||
1408 | /* ready to send message 'tq' on tunnel 'ct' */ | ||
1409 | GNUNET_assert (t == tq->t); | ||
1410 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | ||
1411 | t->tq_tail, | ||
1412 | tq); | ||
1413 | if (NULL != tq->cid) | ||
1414 | *tq->cid = *GCC_get_id (ct->cc); | ||
1415 | ct->is_ready = GNUNET_NO; | ||
1416 | GCC_transmit (ct->cc, | ||
1417 | tq->env); | ||
1418 | tq->cont (tq->cont_cls); | ||
1419 | GNUNET_free (tq); | ||
1420 | } | ||
1421 | |||
1422 | |||
1423 | /** | ||
1424 | * Called when either we have a new connection, or a new message in the | ||
1425 | * queue, or some existing connection has transmission capacity. Looks | ||
1426 | * at our message queue and if there is a message, picks a connection | ||
1427 | * to send it on. | ||
1428 | * | ||
1429 | * FIXME: yuck... Need better selection logic! | ||
1430 | * | ||
1431 | * @param t tunnel to process messages on | ||
1432 | */ | ||
1433 | static void | ||
1434 | trigger_transmissions (struct CadetTunnel *t) | ||
1435 | { | ||
1436 | struct CadetTConnection *ct; | ||
1437 | |||
1438 | if (NULL == t->tq_head) | ||
1439 | return; /* no messages pending right now */ | ||
1440 | for (ct = t->connection_head; | ||
1441 | NULL != ct; | ||
1442 | ct = ct->next) | ||
1443 | if (GNUNET_YES == ct->is_ready) | ||
1444 | break; | ||
1445 | if (NULL == ct) | ||
1446 | return; /* no connections ready */ | ||
1447 | |||
1448 | /* FIXME: a bit hackish to do it like this... */ | ||
1449 | connection_ready_cb (ct, | ||
1450 | GNUNET_YES); | ||
1451 | } | ||
1452 | |||
1453 | |||
1454 | /** | ||
1455 | * Function called to maintain the connections underlying our tunnel. | ||
1456 | * Tries to maintain (incl. tear down) connections for the tunnel, and | ||
1457 | * if there is a significant change, may trigger transmissions. | ||
1458 | * | ||
1459 | * Basically, needs to check if there are connections that perform | ||
1460 | * badly, and if so eventually kill them and trigger a replacement. | ||
1461 | * The strategy is to open one more connection than | ||
1462 | * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the | ||
1463 | * least-performing one, and then inquire for new ones. | ||
1464 | * | ||
1465 | * @param cls the `struct CadetTunnel` | ||
1466 | */ | ||
1467 | static void | ||
1468 | maintain_connections_cb (void *cls) | ||
1469 | { | ||
1470 | struct CadetTunnel *t = cls; | ||
1471 | |||
1472 | GNUNET_break (0); // FIXME: implement! | ||
1473 | } | ||
1474 | |||
1475 | |||
1476 | /** | ||
1477 | * Consider using the path @a p for the tunnel @a t. | ||
1478 | * The tunnel destination is at offset @a off in path @a p. | ||
1479 | * | ||
1480 | * @param cls our tunnel | ||
1481 | * @param path a path to our destination | ||
1482 | * @param off offset of the destination on path @a path | ||
1483 | * @return #GNUNET_YES (should keep iterating) | ||
1484 | */ | ||
1485 | static int | ||
1486 | consider_path_cb (void *cls, | ||
1487 | struct CadetPeerPath *path, | ||
1488 | unsigned int off) | ||
1489 | { | ||
1490 | struct CadetTunnel *t = cls; | ||
1491 | unsigned int min_length = UINT_MAX; | ||
1492 | GNUNET_CONTAINER_HeapCostType max_desire = 0; | ||
1493 | struct CadetTConnection *ct; | ||
1494 | |||
1495 | /* Check if we care about the new path. */ | ||
1496 | for (ct = t->connection_head; | ||
1497 | NULL != ct; | ||
1498 | ct = ct->next) | ||
1499 | { | ||
1500 | struct CadetPeerPath *ps; | ||
1501 | |||
1502 | ps = GCC_get_path (ct->cc); | ||
1503 | if (ps == path) | ||
1504 | return GNUNET_YES; /* duplicate */ | ||
1505 | min_length = GNUNET_MIN (min_length, | ||
1506 | GCPP_get_length (ps)); | ||
1507 | max_desire = GNUNET_MAX (max_desire, | ||
1508 | GCPP_get_desirability (ps)); | ||
1509 | } | ||
1510 | |||
1511 | /* FIXME: not sure we should really just count | ||
1512 | 'num_connections' here, as they may all have | ||
1513 | consistently failed to connect. */ | ||
1514 | |||
1515 | /* We iterate by increasing path length; if we have enough paths and | ||
1516 | this one is more than twice as long than what we are currently | ||
1517 | using, then ignore all of these super-long ones! */ | ||
1518 | if ( (t->num_connections > DESIRED_CONNECTIONS_PER_TUNNEL) && | ||
1519 | (min_length * 2 < off) ) | ||
1520 | { | ||
1521 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1522 | "Ignoring paths of length %u, they are way too long.\n", | ||
1523 | min_length * 2); | ||
1524 | return GNUNET_NO; | ||
1525 | } | ||
1526 | /* If we have enough paths and this one looks no better, ignore it. */ | ||
1527 | if ( (t->num_connections >= DESIRED_CONNECTIONS_PER_TUNNEL) && | ||
1528 | (min_length < GCPP_get_length (path)) && | ||
1529 | (max_desire > GCPP_get_desirability (path)) ) | ||
1530 | { | ||
1531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1532 | "Ignoring path (%u/%llu) to %s, got something better already.\n", | ||
1533 | GCPP_get_length (path), | ||
1534 | (unsigned long long) GCPP_get_desirability (path), | ||
1535 | GCP_2s (t->destination)); | ||
1536 | return GNUNET_YES; | ||
1537 | } | ||
1538 | |||
1539 | /* Path is interesting (better by some metric, or we don't have | ||
1540 | enough paths yet). */ | ||
1541 | ct = GNUNET_new (struct CadetTConnection); | ||
1542 | ct->created = GNUNET_TIME_absolute_get (); | ||
1543 | ct->t = t; | ||
1544 | ct->cc = GCC_create (t->destination, | ||
1545 | path, | ||
1546 | ct, | ||
1547 | &connection_ready_cb, | ||
1548 | ct); | ||
1549 | /* FIXME: schedule job to kill connection (and path?) if it takes | ||
1550 | too long to get ready! (And track performance data on how long | ||
1551 | other connections took with the tunnel!) | ||
1552 | => Note: to be done within 'connection'-logic! */ | ||
1553 | GNUNET_CONTAINER_DLL_insert (t->connection_head, | ||
1554 | t->connection_tail, | ||
1555 | ct); | ||
1556 | t->num_connections++; | ||
1557 | return GNUNET_YES; | ||
1558 | } | ||
1559 | |||
1560 | |||
1561 | /** | ||
1562 | * Consider using the path @a p for the tunnel @a t. | ||
1563 | * The tunnel destination is at offset @a off in path @a p. | ||
1564 | * | ||
1565 | * @param cls our tunnel | ||
1566 | * @param path a path to our destination | ||
1567 | * @param off offset of the destination on path @a path | ||
1568 | */ | ||
1569 | void | ||
1570 | GCT_consider_path (struct CadetTunnel *t, | ||
1571 | struct CadetPeerPath *p, | ||
1572 | unsigned int off) | ||
1573 | { | ||
1574 | (void) consider_path_cb (t, | ||
1575 | p, | ||
1576 | off); | ||
1577 | } | ||
1578 | |||
1579 | |||
1580 | /** | ||
1581 | * | ||
1582 | * | ||
1583 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1584 | * @param msg the message we received on the tunnel | ||
1585 | */ | ||
1586 | static void | ||
1587 | handle_plaintext_keepalive (void *cls, | ||
1588 | const struct GNUNET_MessageHeader *msg) | ||
1589 | { | ||
1590 | struct CadetTunnel *t = cls; | ||
1591 | GNUNET_break (0); // FIXME | ||
1592 | } | ||
1593 | |||
1594 | |||
1595 | /** | ||
1596 | * Check that @a msg is well-formed. | ||
1597 | * | ||
1598 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1599 | * @param msg the message we received on the tunnel | ||
1600 | * @return #GNUNET_OK (any variable-size payload goes) | ||
1601 | */ | ||
1602 | static int | ||
1603 | check_plaintext_data (void *cls, | ||
1604 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) | ||
1605 | { | ||
1606 | return GNUNET_OK; | ||
1607 | } | ||
1608 | |||
1609 | |||
1610 | /** | ||
1611 | * | ||
1612 | * | ||
1613 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1614 | * @param msg the message we received on the tunnel | ||
1615 | */ | ||
1616 | static void | ||
1617 | handle_plaintext_data (void *cls, | ||
1618 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) | ||
1619 | { | ||
1620 | struct CadetTunnel *t = cls; | ||
1621 | GNUNET_break (0); // FIXME! | ||
1622 | } | ||
1623 | |||
1624 | |||
1625 | /** | ||
1626 | * | ||
1627 | * | ||
1628 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1629 | * @param ack the message we received on the tunnel | ||
1630 | */ | ||
1631 | static void | ||
1632 | handle_plaintext_data_ack (void *cls, | ||
1633 | const struct GNUNET_CADET_ChannelDataAckMessage *ack) | ||
1634 | { | ||
1635 | struct CadetTunnel *t = cls; | ||
1636 | GNUNET_break (0); // FIXME! | ||
1637 | } | ||
1638 | |||
1639 | |||
1640 | /** | ||
1641 | * | ||
1642 | * | ||
1643 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1644 | * @param cc the message we received on the tunnel | ||
1645 | */ | ||
1646 | static void | ||
1647 | handle_plaintext_channel_create (void *cls, | ||
1648 | const struct GNUNET_CADET_ChannelOpenMessage *cc) | ||
1649 | { | ||
1650 | struct CadetTunnel *t = cls; | ||
1651 | GNUNET_break (0); // FIXME! | ||
1652 | } | ||
1653 | |||
1654 | |||
1655 | /** | ||
1656 | * | ||
1657 | * | ||
1658 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1659 | * @param cm the message we received on the tunnel | ||
1660 | */ | ||
1661 | static void | ||
1662 | handle_plaintext_channel_nack (void *cls, | ||
1663 | const struct GNUNET_CADET_ChannelManageMessage *cm) | ||
1664 | { | ||
1665 | struct CadetTunnel *t = cls; | ||
1666 | GNUNET_break (0); // FIXME! | ||
1667 | } | ||
1668 | |||
1669 | |||
1670 | /** | ||
1671 | * | ||
1672 | * | ||
1673 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1674 | * @param cm the message we received on the tunnel | ||
1675 | */ | ||
1676 | static void | ||
1677 | handle_plaintext_channel_ack (void *cls, | ||
1678 | const struct GNUNET_CADET_ChannelManageMessage *cm) | ||
1679 | { | ||
1680 | struct CadetTunnel *t = cls; | ||
1681 | GNUNET_break (0); // FIXME! | ||
1682 | } | ||
1683 | |||
1684 | |||
1685 | /** | ||
1686 | * We received a message saying that a channel should be destroyed. | ||
1687 | * Pass it on to the correct channel. | ||
1688 | * | ||
1689 | * @param cls the `struct CadetTunnel` for which we decrypted the message | ||
1690 | * @param cm the message we received on the tunnel | ||
1691 | */ | ||
1692 | static void | ||
1693 | handle_plaintext_channel_destroy (void *cls, | ||
1694 | const struct GNUNET_CADET_ChannelManageMessage *cm) | ||
1695 | { | ||
1696 | struct CadetTunnel *t = cls; | ||
1697 | struct CadetChannel *cc = lookup_channel (t, | ||
1698 | cm->chid); | ||
1699 | |||
1700 | GCCH_channel_remote_destroy (cc); | ||
1701 | } | ||
1702 | |||
1703 | |||
1704 | /** | ||
1705 | * Handles a message we decrypted, by injecting it into | ||
1706 | * our message queue (which will do the dispatching). | ||
1707 | * | ||
1708 | * @param cls the `struct CadetTunnel` that got the message | ||
1709 | * @param msg the message | ||
1710 | * @return #GNUNET_OK (continue to process) | ||
1711 | */ | ||
1712 | static int | ||
1713 | handle_decrypted (void *cls, | ||
1714 | const struct GNUNET_MessageHeader *msg) | ||
1715 | { | ||
1716 | struct CadetTunnel *t = cls; | ||
1717 | |||
1718 | GNUNET_MQ_inject_message (t->mq, | ||
1719 | msg); | ||
1720 | return GNUNET_OK; | ||
1721 | } | ||
1722 | |||
1723 | |||
1724 | /** | ||
1725 | * Function called if we had an error processing | ||
1726 | * an incoming decrypted message. | ||
1727 | * | ||
1728 | * @param cls the `struct CadetTunnel` | ||
1729 | * @param error error code | ||
1730 | */ | ||
1731 | static void | ||
1732 | decrypted_error_cb (void *cls, | ||
1733 | enum GNUNET_MQ_Error error) | ||
1734 | { | ||
1735 | GNUNET_break_op (0); | ||
1736 | } | ||
1737 | |||
1738 | |||
1739 | /** | ||
1740 | * Create a tunnel to @a destionation. Must only be called | ||
1741 | * from within #GCP_get_tunnel(). | ||
1742 | * | ||
1743 | * @param destination where to create the tunnel to | ||
1744 | * @return new tunnel to @a destination | ||
1745 | */ | ||
1746 | struct CadetTunnel * | ||
1747 | GCT_create_tunnel (struct CadetPeer *destination) | ||
1748 | { | ||
1749 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
1750 | GNUNET_MQ_hd_fixed_size (plaintext_keepalive, | ||
1751 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE, | ||
1752 | struct GNUNET_MessageHeader, | ||
1753 | NULL), | ||
1754 | GNUNET_MQ_hd_var_size (plaintext_data, | ||
1755 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, | ||
1756 | struct GNUNET_CADET_ChannelAppDataMessage, | ||
1757 | NULL), | ||
1758 | GNUNET_MQ_hd_fixed_size (plaintext_data_ack, | ||
1759 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, | ||
1760 | struct GNUNET_CADET_ChannelDataAckMessage, | ||
1761 | NULL), | ||
1762 | GNUNET_MQ_hd_fixed_size (plaintext_channel_create, | ||
1763 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, | ||
1764 | struct GNUNET_CADET_ChannelOpenMessage, | ||
1765 | NULL), | ||
1766 | GNUNET_MQ_hd_fixed_size (plaintext_channel_nack, | ||
1767 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED, | ||
1768 | struct GNUNET_CADET_ChannelManageMessage, | ||
1769 | NULL), | ||
1770 | GNUNET_MQ_hd_fixed_size (plaintext_channel_ack, | ||
1771 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, | ||
1772 | struct GNUNET_CADET_ChannelManageMessage, | ||
1773 | NULL), | ||
1774 | GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy, | ||
1775 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, | ||
1776 | struct GNUNET_CADET_ChannelManageMessage, | ||
1777 | NULL), | ||
1778 | GNUNET_MQ_handler_end () | ||
1779 | }; | ||
1780 | struct CadetTunnel *t; | ||
1781 | |||
1782 | t = GNUNET_new (struct CadetTunnel); | ||
1783 | t->destination = destination; | ||
1784 | t->channels = GNUNET_CONTAINER_multihashmap32_create (8); | ||
1785 | (void) GCP_iterate_paths (destination, | ||
1786 | &consider_path_cb, | ||
1787 | t); | ||
1788 | t->maintain_connections_task | ||
1789 | = GNUNET_SCHEDULER_add_now (&maintain_connections_cb, | ||
1790 | t); | ||
1791 | t->mq = GNUNET_MQ_queue_for_callbacks (NULL, | ||
1792 | NULL, | ||
1793 | NULL, | ||
1794 | NULL, | ||
1795 | handlers, | ||
1796 | &decrypted_error_cb, | ||
1797 | t); | ||
1798 | t->mst = GNUNET_MST_create (&handle_decrypted, | ||
1799 | t); | ||
1800 | return t; | ||
1801 | } | ||
1802 | |||
1803 | |||
1804 | /** | ||
1805 | * Remove a channel from a tunnel. | ||
1806 | * | ||
1807 | * @param t Tunnel. | ||
1808 | * @param ch Channel | ||
1809 | * @param gid unique number identifying @a ch within @a t | ||
1810 | */ | ||
1811 | void | ||
1812 | GCT_remove_channel (struct CadetTunnel *t, | ||
1813 | struct CadetChannel *ch, | ||
1814 | struct GNUNET_CADET_ChannelTunnelNumber gid) | ||
1815 | { | ||
1816 | GNUNET_assert (GNUNET_YES == | ||
1817 | GNUNET_CONTAINER_multihashmap32_remove (t->channels, | ||
1818 | ntohl (gid.cn), | ||
1819 | ch)); | ||
1820 | if (0 == | ||
1821 | GNUNET_CONTAINER_multihashmap32_size (t->channels)) | ||
1822 | { | ||
1823 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, | ||
1824 | &destroy_tunnel, | ||
1825 | t); | ||
1826 | } | ||
1827 | } | ||
1828 | |||
1829 | |||
1830 | /** | ||
1831 | * Change the tunnel encryption state. | ||
1832 | * If the encryption state changes to OK, stop the rekey task. | ||
1833 | * | ||
1834 | * @param t Tunnel whose encryption state to change, or NULL. | ||
1835 | * @param state New encryption state. | ||
1836 | */ | ||
1837 | void | ||
1838 | GCT_change_estate (struct CadetTunnel *t, | ||
1839 | enum CadetTunnelEState state) | ||
1840 | { | ||
1841 | enum CadetTunnelEState old = t->estate; | ||
1842 | |||
1843 | t->estate = state; | ||
1844 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1845 | "Tunnel %s estate changed from %d to %d\n", | ||
1846 | GCT_2s (t), | ||
1847 | old, | ||
1848 | state); | ||
1849 | |||
1850 | if ( (CADET_TUNNEL_KEY_OK != old) && | ||
1851 | (CADET_TUNNEL_KEY_OK == t->estate) ) | ||
1852 | { | ||
1853 | if (NULL != t->rekey_task) | ||
1854 | { | ||
1855 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1856 | t->rekey_task = NULL; | ||
1857 | } | ||
1858 | #if FIXME | ||
1859 | /* Send queued data if tunnel is not loopback */ | ||
1860 | if (myid != GCP_get_short_id (t->peer)) | ||
1861 | send_queued_data (t); | ||
1862 | #endif | ||
1863 | } | ||
1864 | } | ||
1865 | |||
1866 | |||
1867 | /** | ||
1868 | * Add a @a connection to the @a tunnel. | ||
1869 | * | ||
1870 | * @param t a tunnel | ||
1871 | * @param cid connection identifer to use for the connection | ||
1872 | * @param path path to use for the connection | ||
1873 | */ | ||
1874 | void | ||
1875 | GCT_add_inbound_connection (struct CadetTunnel *t, | ||
1876 | const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, | ||
1877 | struct CadetPeerPath *path) | ||
1878 | { | ||
1879 | struct CadetConnection *cc; | ||
1880 | struct CadetTConnection *ct; | ||
1881 | |||
1882 | ct = GNUNET_new (struct CadetTConnection); | ||
1883 | ct->created = GNUNET_TIME_absolute_get (); | ||
1884 | ct->t = t; | ||
1885 | ct->cc = GCC_create_inbound (t->destination, | ||
1886 | path, | ||
1887 | ct, | ||
1888 | cid, | ||
1889 | &connection_ready_cb, | ||
1890 | t); | ||
1891 | /* FIXME: schedule job to kill connection (and path?) if it takes | ||
1892 | too long to get ready! (And track performance data on how long | ||
1893 | other connections took with the tunnel!) | ||
1894 | => Note: to be done within 'connection'-logic! */ | ||
1895 | GNUNET_CONTAINER_DLL_insert (t->connection_head, | ||
1896 | t->connection_tail, | ||
1897 | ct); | ||
1898 | t->num_connections++; | ||
1899 | } | ||
1900 | |||
1901 | |||
1902 | /** | ||
1903 | * Handle encrypted message. | ||
1904 | * | ||
1905 | * @param ct connection/tunnel combo that received encrypted message | ||
1906 | * @param msg the encrypted message to decrypt | ||
1907 | */ | ||
1908 | void | ||
1909 | GCT_handle_encrypted (struct CadetTConnection *ct, | ||
1910 | const struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
1911 | { | ||
1912 | struct CadetTunnel *t = ct->t; | ||
1913 | uint16_t size = ntohs (msg->header.size); | ||
1914 | char cbuf [size] GNUNET_ALIGN; | ||
1915 | ssize_t decrypted_size; | ||
1916 | |||
1917 | GNUNET_STATISTICS_update (stats, | ||
1918 | "# received encrypted", | ||
1919 | 1, | ||
1920 | GNUNET_NO); | ||
1921 | |||
1922 | decrypted_size = t_ax_decrypt_and_validate (t, | ||
1923 | cbuf, | ||
1924 | msg, | ||
1925 | size); | ||
1926 | |||
1927 | if (-1 == decrypted_size) | ||
1928 | { | ||
1929 | GNUNET_STATISTICS_update (stats, | ||
1930 | "# unable to decrypt", | ||
1931 | 1, | ||
1932 | GNUNET_NO); | ||
1933 | if (CADET_TUNNEL_KEY_PING <= t->estate) | ||
1934 | { | ||
1935 | GNUNET_break_op (0); | ||
1936 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1937 | "Wrong crypto, tunnel %s\n", | ||
1938 | GCT_2s (t)); | ||
1939 | GCT_debug (t, | ||
1940 | GNUNET_ERROR_TYPE_WARNING); | ||
1941 | } | ||
1942 | return; | ||
1943 | } | ||
1944 | |||
1945 | GCT_change_estate (t, | ||
1946 | CADET_TUNNEL_KEY_OK); | ||
1947 | /* The MST will ultimately call #handle_decrypted() on each message. */ | ||
1948 | GNUNET_break_op (GNUNET_OK == | ||
1949 | GNUNET_MST_from_buffer (t->mst, | ||
1950 | cbuf, | ||
1951 | decrypted_size, | ||
1952 | GNUNET_YES, | ||
1953 | GNUNET_NO)); | ||
1954 | } | ||
1955 | |||
1956 | |||
1957 | /** | ||
1958 | * Sends an already built message on a tunnel, encrypting it and | ||
1959 | * choosing the best connection if not provided. | ||
1960 | * | ||
1961 | * @param message Message to send. Function modifies it. | ||
1962 | * @param t Tunnel on which this message is transmitted. | ||
1963 | * @param cont Continuation to call once message is really sent. | ||
1964 | * @param cont_cls Closure for @c cont. | ||
1965 | * @return Handle to cancel message. NULL if @c cont is NULL. | ||
1966 | */ | ||
1967 | struct CadetTunnelQueueEntry * | ||
1968 | GCT_send (struct CadetTunnel *t, | ||
1969 | const struct GNUNET_MessageHeader *message, | ||
1970 | GNUNET_SCHEDULER_TaskCallback cont, | ||
1971 | void *cont_cls) | ||
1972 | { | ||
1973 | struct CadetTunnelQueueEntry *tq; | ||
1974 | uint16_t payload_size; | ||
1975 | struct GNUNET_MQ_Envelope *env; | ||
1976 | struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg; | ||
1977 | |||
1978 | /* FIXME: what about KX not yet being ready? (see "is_ready()" check in old code!) */ | ||
1979 | |||
1980 | payload_size = ntohs (message->size); | ||
1981 | env = GNUNET_MQ_msg_extra (ax_msg, | ||
1982 | payload_size, | ||
1983 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED); | ||
1984 | t_ax_encrypt (t, | ||
1985 | &ax_msg[1], | ||
1986 | message, | ||
1987 | payload_size); | ||
1988 | ax_msg->Ns = htonl (t->ax.Ns++); | ||
1989 | ax_msg->PNs = htonl (t->ax.PNs); | ||
1990 | GNUNET_CRYPTO_ecdhe_key_get_public (t->ax.DHRs, | ||
1991 | &ax_msg->DHRs); | ||
1992 | t_h_encrypt (t, | ||
1993 | ax_msg); | ||
1994 | t_hmac (&ax_msg->Ns, | ||
1995 | AX_HEADER_SIZE + payload_size, | ||
1996 | 0, | ||
1997 | &t->ax.HKs, | ||
1998 | &ax_msg->hmac); | ||
1999 | // ax_msg->pid = htonl (GCC_get_pid (c, fwd)); // FIXME: connection flow-control not (re)implemented yet! | ||
2000 | |||
2001 | tq = GNUNET_malloc (sizeof (*tq)); | ||
2002 | tq->t = t; | ||
2003 | tq->env = env; | ||
2004 | tq->cid = &ax_msg->cid; | ||
2005 | tq->cont = cont; | ||
2006 | tq->cont_cls = cont_cls; | ||
2007 | GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, | ||
2008 | t->tq_tail, | ||
2009 | tq); | ||
2010 | trigger_transmissions (t); | ||
2011 | return tq; | ||
2012 | } | ||
2013 | |||
2014 | |||
2015 | /** | ||
2016 | * Cancel a previously sent message while it's in the queue. | ||
2017 | * | ||
2018 | * ONLY can be called before the continuation given to the send | ||
2019 | * function is called. Once the continuation is called, the message is | ||
2020 | * no longer in the queue! | ||
2021 | * | ||
2022 | * @param q Handle to the queue entry to cancel. | ||
2023 | */ | ||
2024 | void | ||
2025 | GCT_send_cancel (struct CadetTunnelQueueEntry *q) | ||
2026 | { | ||
2027 | struct CadetTunnel *t = q->t; | ||
2028 | |||
2029 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | ||
2030 | t->tq_tail, | ||
2031 | q); | ||
2032 | GNUNET_free (q); | ||
2033 | } | ||
2034 | |||
2035 | |||
2036 | /** | ||
2037 | * Iterate over all connections of a tunnel. | ||
2038 | * | ||
2039 | * @param t Tunnel whose connections to iterate. | ||
2040 | * @param iter Iterator. | ||
2041 | * @param iter_cls Closure for @c iter. | ||
2042 | */ | ||
2043 | void | ||
2044 | GCT_iterate_connections (struct CadetTunnel *t, | ||
2045 | GCT_ConnectionIterator iter, | ||
2046 | void *iter_cls) | ||
2047 | { | ||
2048 | for (struct CadetTConnection *ct = t->connection_head; | ||
2049 | NULL != ct; | ||
2050 | ct = ct->next) | ||
2051 | iter (iter_cls, | ||
2052 | ct->cc); | ||
2053 | } | ||
2054 | |||
2055 | |||
2056 | /** | ||
2057 | * Closure for #iterate_channels_cb. | ||
2058 | */ | ||
2059 | struct ChanIterCls | ||
2060 | { | ||
2061 | /** | ||
2062 | * Function to call. | ||
2063 | */ | ||
2064 | GCT_ChannelIterator iter; | ||
2065 | |||
2066 | /** | ||
2067 | * Closure for @e iter. | ||
2068 | */ | ||
2069 | void *iter_cls; | ||
2070 | }; | ||
2071 | |||
2072 | |||
2073 | /** | ||
2074 | * Helper function for #GCT_iterate_channels. | ||
2075 | * | ||
2076 | * @param cls the `struct ChanIterCls` | ||
2077 | * @param key unused | ||
2078 | * @param value a `struct CadetChannel` | ||
2079 | * @return #GNUNET_OK | ||
2080 | */ | ||
2081 | static int | ||
2082 | iterate_channels_cb (void *cls, | ||
2083 | uint32_t key, | ||
2084 | void *value) | ||
2085 | { | ||
2086 | struct ChanIterCls *ctx = cls; | ||
2087 | struct CadetChannel *ch = value; | ||
2088 | |||
2089 | ctx->iter (ctx->iter_cls, | ||
2090 | ch); | ||
2091 | return GNUNET_OK; | ||
2092 | } | ||
2093 | |||
2094 | |||
2095 | /** | ||
2096 | * Iterate over all channels of a tunnel. | ||
2097 | * | ||
2098 | * @param t Tunnel whose channels to iterate. | ||
2099 | * @param iter Iterator. | ||
2100 | * @param iter_cls Closure for @c iter. | ||
2101 | */ | ||
2102 | void | ||
2103 | GCT_iterate_channels (struct CadetTunnel *t, | ||
2104 | GCT_ChannelIterator iter, | ||
2105 | void *iter_cls) | ||
2106 | { | ||
2107 | struct ChanIterCls ctx; | ||
2108 | |||
2109 | ctx.iter = iter; | ||
2110 | ctx.iter_cls = iter_cls; | ||
2111 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
2112 | &iterate_channels_cb, | ||
2113 | &ctx); | ||
2114 | |||
2115 | } | ||
2116 | |||
2117 | |||
2118 | /** | ||
2119 | * Call #GCCH_debug() on a channel. | ||
2120 | * | ||
2121 | * @param cls points to the log level to use | ||
2122 | * @param key unused | ||
2123 | * @param value the `struct CadetChannel` to dump | ||
2124 | * @return #GNUNET_OK (continue iteration) | ||
2125 | */ | ||
2126 | static int | ||
2127 | debug_channel (void *cls, | ||
2128 | uint32_t key, | ||
2129 | void *value) | ||
2130 | { | ||
2131 | const enum GNUNET_ErrorType *level = cls; | ||
2132 | struct CadetChannel *ch = value; | ||
2133 | |||
2134 | GCCH_debug (ch, *level); | ||
2135 | return GNUNET_OK; | ||
2136 | } | ||
2137 | |||
2138 | |||
2139 | /** | ||
2140 | * Get string description for tunnel connectivity state. | ||
2141 | * | ||
2142 | * @param cs Tunnel state. | ||
2143 | * | ||
2144 | * @return String representation. | ||
2145 | */ | ||
2146 | static const char * | ||
2147 | cstate2s (enum CadetTunnelCState cs) | ||
2148 | { | ||
2149 | static char buf[32]; | ||
2150 | |||
2151 | switch (cs) | ||
2152 | { | ||
2153 | case CADET_TUNNEL_NEW: | ||
2154 | return "CADET_TUNNEL_NEW"; | ||
2155 | case CADET_TUNNEL_SEARCHING: | ||
2156 | return "CADET_TUNNEL_SEARCHING"; | ||
2157 | case CADET_TUNNEL_WAITING: | ||
2158 | return "CADET_TUNNEL_WAITING"; | ||
2159 | case CADET_TUNNEL_READY: | ||
2160 | return "CADET_TUNNEL_READY"; | ||
2161 | case CADET_TUNNEL_SHUTDOWN: | ||
2162 | return "CADET_TUNNEL_SHUTDOWN"; | ||
2163 | default: | ||
2164 | SPRINTF (buf, "%u (UNKNOWN STATE)", cs); | ||
2165 | return buf; | ||
2166 | } | ||
2167 | } | ||
2168 | |||
2169 | |||
2170 | /** | ||
2171 | * Get string description for tunnel encryption state. | ||
2172 | * | ||
2173 | * @param es Tunnel state. | ||
2174 | * | ||
2175 | * @return String representation. | ||
2176 | */ | ||
2177 | static const char * | ||
2178 | estate2s (enum CadetTunnelEState es) | ||
2179 | { | ||
2180 | static char buf[32]; | ||
2181 | |||
2182 | switch (es) | ||
2183 | { | ||
2184 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
2185 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; | ||
2186 | case CADET_TUNNEL_KEY_SENT: | ||
2187 | return "CADET_TUNNEL_KEY_SENT"; | ||
2188 | case CADET_TUNNEL_KEY_PING: | ||
2189 | return "CADET_TUNNEL_KEY_PING"; | ||
2190 | case CADET_TUNNEL_KEY_OK: | ||
2191 | return "CADET_TUNNEL_KEY_OK"; | ||
2192 | case CADET_TUNNEL_KEY_REKEY: | ||
2193 | return "CADET_TUNNEL_KEY_REKEY"; | ||
2194 | default: | ||
2195 | SPRINTF (buf, "%u (UNKNOWN STATE)", es); | ||
2196 | return buf; | ||
2197 | } | ||
2198 | } | ||
2199 | |||
2200 | |||
2201 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-tun",__VA_ARGS__) | ||
2202 | |||
2203 | |||
2204 | /** | ||
2205 | * Log all possible info about the tunnel state. | ||
2206 | * | ||
2207 | * @param t Tunnel to debug. | ||
2208 | * @param level Debug level to use. | ||
2209 | */ | ||
2210 | void | ||
2211 | GCT_debug (const struct CadetTunnel *t, | ||
2212 | enum GNUNET_ErrorType level) | ||
2213 | { | ||
2214 | struct CadetTConnection *iter_c; | ||
2215 | int do_log; | ||
2216 | |||
2217 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | ||
2218 | "cadet-tun", | ||
2219 | __FILE__, __FUNCTION__, __LINE__); | ||
2220 | if (0 == do_log) | ||
2221 | return; | ||
2222 | |||
2223 | LOG2 (level, | ||
2224 | "TTT TUNNEL TOWARDS %s in cstate %s, estate %s tq_len: %u #cons: %u\n", | ||
2225 | GCT_2s (t), | ||
2226 | cstate2s (t->cstate), | ||
2227 | estate2s (t->estate), | ||
2228 | t->tq_len, | ||
2229 | t->num_connections); | ||
2230 | #if DUMP_KEYS_TO_STDERR | ||
2231 | ax_debug (t->ax, level); | ||
2232 | #endif | ||
2233 | LOG2 (level, | ||
2234 | "TTT channels:\n"); | ||
2235 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
2236 | &debug_channel, | ||
2237 | &level); | ||
2238 | LOG2 (level, | ||
2239 | "TTT connections:\n"); | ||
2240 | for (iter_c = t->connection_head; NULL != iter_c; iter_c = iter_c->next) | ||
2241 | GCC_debug (iter_c->cc, | ||
2242 | level); | ||
2243 | |||
2244 | LOG2 (level, | ||
2245 | "TTT TUNNEL END\n"); | ||
2246 | } | ||
2247 | |||
2248 | |||
2249 | /* end of gnunet-service-cadet-new_tunnels.c */ | ||