Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / core / gnunet-service-core_kx.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2013, 2016 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file core/gnunet-service-core_kx.c
23  * @brief code for managing the key exchange (SET_KEY, PING, PONG) with other peers
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet-service-core_kx.h"
28 #include "gnunet-service-core.h"
29 #include "gnunet-service-core_sessions.h"
30 #include "gnunet_statistics_service.h"
31 #include "gnunet_transport_core_service.h"
32 #include "gnunet_constants.h"
33 #include "gnunet_signatures.h"
34 #include "gnunet_protocols.h"
35 #include "core.h"
36
37
38 /**
39  * How long do we wait for SET_KEY confirmation initially?
40  */
41 #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
42
43 /**
44  * What is the minimum frequency for a PING message?
45  */
46 #define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
47
48 /**
49  * How often do we rekey?
50  */
51 #define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
52
53 /**
54  * What time difference do we tolerate?
55  */
56 #define REKEY_TOLERANCE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
57
58 /**
59  * What is the maximum age of a message for us to consider processing
60  * it?  Note that this looks at the timestamp used by the other peer,
61  * so clock skew between machines does come into play here.  So this
62  * should be picked high enough so that a little bit of clock skew
63  * does not prevent peers from connecting to us.
64  */
65 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
66
67
68
69 GNUNET_NETWORK_STRUCT_BEGIN
70
71 /**
72  * Message transmitted with the signed ephemeral key of a peer.  The
73  * session key is then derived from the two ephemeral keys (ECDHE).
74  */
75 struct EphemeralKeyMessage
76 {
77
78   /**
79    * Message type is #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
80    */
81   struct GNUNET_MessageHeader header;
82
83   /**
84    * Status of the sender (should be in `enum PeerStateMachine`), nbo.
85    */
86   int32_t sender_status GNUNET_PACKED;
87
88   /**
89    * An ECC signature of the @e origin_identity asserting the validity
90    * of the given ephemeral key.
91    */
92   struct GNUNET_CRYPTO_EddsaSignature signature;
93
94   /**
95    * Information about what is being signed.
96    */
97   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
98
99   /**
100    * At what time was this key created (beginning of validity).
101    */
102   struct GNUNET_TIME_AbsoluteNBO creation_time;
103
104   /**
105    * When does the given ephemeral key expire (end of validity).
106    */
107   struct GNUNET_TIME_AbsoluteNBO expiration_time;
108
109   /**
110    * Ephemeral public ECC key.
111    */
112   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
113
114   /**
115    * Public key of the signing peer (persistent version, not the
116    * ephemeral public key).
117    */
118   struct GNUNET_PeerIdentity origin_identity;
119
120 };
121
122
123 /**
124  * We're sending an (encrypted) PING to the other peer to check if he
125  * can decrypt.  The other peer should respond with a PONG with the
126  * same content, except this time encrypted with the receiver's key.
127  */
128 struct PingMessage
129 {
130   /**
131    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
132    */
133   struct GNUNET_MessageHeader header;
134
135   /**
136    * Seed for the IV
137    */
138   uint32_t iv_seed GNUNET_PACKED;
139
140   /**
141    * Intended target of the PING, used primarily to check
142    * that decryption actually worked.
143    */
144   struct GNUNET_PeerIdentity target;
145
146   /**
147    * Random number chosen to make replay harder.
148    */
149   uint32_t challenge GNUNET_PACKED;
150 };
151
152
153 /**
154  * Response to a PING.  Includes data from the original PING.
155  */
156 struct PongMessage
157 {
158   /**
159    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
160    */
161   struct GNUNET_MessageHeader header;
162
163   /**
164    * Seed for the IV
165    */
166   uint32_t iv_seed GNUNET_PACKED;
167
168   /**
169    * Random number to make replay attacks harder.
170    */
171   uint32_t challenge GNUNET_PACKED;
172
173   /**
174    * Reserved, always zero.
175    */
176   uint32_t reserved;
177
178   /**
179    * Intended target of the PING, used primarily to check
180    * that decryption actually worked.
181    */
182   struct GNUNET_PeerIdentity target;
183 };
184
185
186 /**
187  * Encapsulation for encrypted messages exchanged between
188  * peers.  Followed by the actual encrypted data.
189  */
190 struct EncryptedMessage
191 {
192   /**
193    * Message type is #GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE.
194    */
195   struct GNUNET_MessageHeader header;
196
197   /**
198    * Random value used for IV generation.
199    */
200   uint32_t iv_seed GNUNET_PACKED;
201
202   /**
203    * MAC of the encrypted message (starting at @e sequence_number),
204    * used to verify message integrity. Everything after this value
205    * (excluding this value itself) will be encrypted and
206    * authenticated.  #ENCRYPTED_HEADER_SIZE must be set to the offset
207    * of the *next* field.
208    */
209   struct GNUNET_HashCode hmac;
210
211   /**
212    * Sequence number, in network byte order.  This field
213    * must be the first encrypted/decrypted field
214    */
215   uint32_t sequence_number GNUNET_PACKED;
216
217   /**
218    * Reserved, always zero.
219    */
220   uint32_t reserved GNUNET_PACKED;
221
222   /**
223    * Timestamp.  Used to prevent replay of ancient messages
224    * (recent messages are caught with the sequence number).
225    */
226   struct GNUNET_TIME_AbsoluteNBO timestamp;
227
228 };
229 GNUNET_NETWORK_STRUCT_END
230
231
232 /**
233  * Number of bytes (at the beginning) of `struct EncryptedMessage`
234  * that are NOT encrypted.
235  */
236 #define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number))
237
238
239 /**
240  * Information about the status of a key exchange with another peer.
241  */
242 struct GSC_KeyExchangeInfo
243 {
244
245   /**
246    * DLL.
247    */
248   struct GSC_KeyExchangeInfo *next;
249
250   /**
251    * DLL.
252    */
253   struct GSC_KeyExchangeInfo *prev;
254
255   /**
256    * Identity of the peer.
257    */
258   const struct GNUNET_PeerIdentity *peer;
259
260   /**
261    * Message queue for sending messages to @a peer.
262    */
263   struct GNUNET_MQ_Handle *mq;
264
265   /**
266    * PING message we transmit to the other peer.
267    */
268   struct PingMessage ping;
269
270   /**
271    * Ephemeral public ECC key of the other peer.
272    */
273   struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key;
274
275   /**
276    * Key we use to encrypt our messages for the other peer
277    * (initialized by us when we do the handshake).
278    */
279   struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key;
280
281   /**
282    * Key we use to decrypt messages from the other peer
283    * (given to us by the other peer during the handshake).
284    */
285   struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key;
286
287   /**
288    * At what time did the other peer generate the decryption key?
289    */
290   struct GNUNET_TIME_Absolute foreign_key_expires;
291
292   /**
293    * When should the session time out (if there are no PONGs)?
294    */
295   struct GNUNET_TIME_Absolute timeout;
296
297   /**
298    * What was the last timeout we informed our monitors about?
299    */
300   struct GNUNET_TIME_Absolute last_notify_timeout;
301
302   /**
303    * At what frequency are we currently re-trying SET_KEY messages?
304    */
305   struct GNUNET_TIME_Relative set_key_retry_frequency;
306
307   /**
308    * ID of task used for re-trying SET_KEY and PING message.
309    */
310   struct GNUNET_SCHEDULER_Task *retry_set_key_task;
311
312   /**
313    * ID of task used for sending keep-alive pings.
314    */
315   struct GNUNET_SCHEDULER_Task *keep_alive_task;
316
317   /**
318    * Bit map indicating which of the 32 sequence numbers before the
319    * last were received (good for accepting out-of-order packets and
320    * estimating reliability of the connection)
321    */
322   uint32_t last_packets_bitmap;
323
324   /**
325    * last sequence number received on this connection (highest)
326    */
327   uint32_t last_sequence_number_received;
328
329   /**
330    * last sequence number transmitted
331    */
332   uint32_t last_sequence_number_sent;
333
334   /**
335    * What was our PING challenge number (for this peer)?
336    */
337   uint32_t ping_challenge;
338
339   /**
340    * #GNUNET_YES if this peer currently has excess bandwidth.
341    */
342   int has_excess_bandwidth;
343
344   /**
345    * What is our connection status?
346    */
347   enum GNUNET_CORE_KxState status;
348
349 };
350
351
352 /**
353  * Transport service.
354  */
355 static struct GNUNET_TRANSPORT_CoreHandle *transport;
356
357 /**
358  * Our private key.
359  */
360 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
361
362 /**
363  * Our ephemeral private key.
364  */
365 static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key;
366
367 /**
368  * Current message we send for a key exchange.
369  */
370 static struct EphemeralKeyMessage current_ekm;
371
372 /**
373  * Our message stream tokenizer (for encrypted payload).
374  */
375 static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
376
377 /**
378  * DLL head.
379  */
380 static struct GSC_KeyExchangeInfo *kx_head;
381
382 /**
383  * DLL tail.
384  */
385 static struct GSC_KeyExchangeInfo *kx_tail;
386
387 /**
388  * Task scheduled for periodic re-generation (and thus rekeying) of our
389  * ephemeral key.
390  */
391 static struct GNUNET_SCHEDULER_Task *rekey_task;
392
393 /**
394  * Notification context for broadcasting to monitors.
395  */
396 static struct GNUNET_NotificationContext *nc;
397
398
399 /**
400  * Calculate seed value we should use for a message.
401  *
402  * @param kx key exchange context
403  */
404 static uint32_t
405 calculate_seed (struct GSC_KeyExchangeInfo *kx)
406 {
407   /* Note: may want to make this non-random and instead
408      derive from key material to avoid having an undetectable
409      side-channel */
410   return htonl (GNUNET_CRYPTO_random_u32
411                 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
412 }
413
414
415 /**
416  * Inform all monitors about the KX state of the given peer.
417  *
418  * @param kx key exchange state to inform about
419  */
420 static void
421 monitor_notify_all (struct GSC_KeyExchangeInfo *kx)
422 {
423   struct MonitorNotifyMessage msg;
424
425   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
426   msg.header.size = htons (sizeof (msg));
427   msg.state = htonl ((uint32_t) kx->status);
428   msg.peer = *kx->peer;
429   msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
430   GNUNET_notification_context_broadcast (nc,
431                                          &msg.header,
432                                          GNUNET_NO);
433   kx->last_notify_timeout = kx->timeout;
434 }
435
436
437 /**
438  * Derive an authentication key from "set key" information
439  *
440  * @param akey authentication key to derive
441  * @param skey session key to use
442  * @param seed seed to use
443  */
444 static void
445 derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
446                  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
447                  uint32_t seed)
448 {
449   static const char ctx[] = "authentication key";
450
451   GNUNET_CRYPTO_hmac_derive_key (akey, skey,
452                                  &seed, sizeof (seed),
453                                  skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
454                                  ctx, sizeof (ctx),
455                                  NULL);
456 }
457
458
459 /**
460  * Derive an IV from packet information
461  *
462  * @param iv initialization vector to initialize
463  * @param skey session key to use
464  * @param seed seed to use
465  * @param identity identity of the other peer to use
466  */
467 static void
468 derive_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
469            const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
470            uint32_t seed,
471            const struct GNUNET_PeerIdentity *identity)
472 {
473   static const char ctx[] = "initialization vector";
474
475   GNUNET_CRYPTO_symmetric_derive_iv (iv, skey,
476                                      &seed, sizeof (seed),
477                                      identity,
478                                      sizeof (struct GNUNET_PeerIdentity), ctx,
479                                      sizeof (ctx), NULL);
480 }
481
482
483 /**
484  * Derive an IV from pong packet information
485  *
486  * @param iv initialization vector to initialize
487  * @param skey session key to use
488  * @param seed seed to use
489  * @param challenge nonce to use
490  * @param identity identity of the other peer to use
491  */
492 static void
493 derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
494                 const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
495                 uint32_t seed,
496                 uint32_t challenge,
497                 const struct GNUNET_PeerIdentity *identity)
498 {
499   static const char ctx[] = "pong initialization vector";
500
501   GNUNET_CRYPTO_symmetric_derive_iv (iv, skey,
502                                      &seed, sizeof (seed),
503                                      identity,
504                                      sizeof (struct GNUNET_PeerIdentity),
505                                      &challenge, sizeof (challenge),
506                                      ctx, sizeof (ctx),
507                                      NULL);
508 }
509
510
511 /**
512  * Derive an AES key from key material
513  *
514  * @param sender peer identity of the sender
515  * @param receiver peer identity of the sender
516  * @param key_material high entropy key material to use
517  * @param skey set to derived session key
518  */
519 static void
520 derive_aes_key (const struct GNUNET_PeerIdentity *sender,
521                 const struct GNUNET_PeerIdentity *receiver,
522                 const struct GNUNET_HashCode *key_material,
523                 struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
524 {
525   static const char ctx[] = "aes key generation vector";
526
527   GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
528                      ctx, sizeof (ctx),
529                      key_material, sizeof (struct GNUNET_HashCode),
530                      sender, sizeof (struct GNUNET_PeerIdentity),
531                      receiver, sizeof (struct GNUNET_PeerIdentity),
532                      NULL);
533 }
534
535
536 /**
537  * Encrypt size bytes from @a in and write the result to @a out.  Use the
538  * @a kx key for outbound traffic of the given neighbour.
539  *
540  * @param kx key information context
541  * @param iv initialization vector to use
542  * @param in ciphertext
543  * @param out plaintext
544  * @param size size of @a in/@a out
545  * @return #GNUNET_OK on success
546  */
547 static int
548 do_encrypt (struct GSC_KeyExchangeInfo *kx,
549             const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
550             const void *in,
551             void *out,
552             size_t size)
553 {
554   if (size != (uint16_t) size)
555   {
556     GNUNET_break (0);
557     return GNUNET_NO;
558   }
559   GNUNET_assert (size ==
560                  GNUNET_CRYPTO_symmetric_encrypt (in,
561                                                   (uint16_t) size,
562                                                   &kx->encrypt_key,
563                                                   iv,
564                                                   out));
565   GNUNET_STATISTICS_update (GSC_stats,
566                             gettext_noop ("# bytes encrypted"),
567                             size,
568                             GNUNET_NO);
569   /* the following is too sensitive to write to log files by accident,
570      so we require manual intervention to get this one... */
571 #if 0
572   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
573               "Encrypted %u bytes for `%s' using key %u, IV %u\n",
574               (unsigned int) size,
575               GNUNET_i2s (kx->peer),
576               (unsigned int) kx->encrypt_key.crc32,
577               GNUNET_CRYPTO_crc32_n (iv,
578                                      sizeof (iv)));
579 #endif
580   return GNUNET_OK;
581 }
582
583
584 /**
585  * Decrypt size bytes from @a in and write the result to @a out.  Use
586  * the @a kx key for inbound traffic of the given neighbour.  This
587  * function does NOT do any integrity-checks on the result.
588  *
589  * @param kx key information context
590  * @param iv initialization vector to use
591  * @param in ciphertext
592  * @param out plaintext
593  * @param size size of @a in / @a out
594  * @return #GNUNET_OK on success
595  */
596 static int
597 do_decrypt (struct GSC_KeyExchangeInfo *kx,
598             const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
599             const void *in,
600             void *out,
601             size_t size)
602 {
603   if (size != (uint16_t) size)
604   {
605     GNUNET_break (0);
606     return GNUNET_NO;
607   }
608   if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) &&
609        (kx->status != GNUNET_CORE_KX_STATE_UP) &&
610        (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT) )
611   {
612     GNUNET_break_op (0);
613     return GNUNET_SYSERR;
614   }
615   if (size !=
616       GNUNET_CRYPTO_symmetric_decrypt (in,
617                                        (uint16_t) size,
618                                        &kx->decrypt_key,
619                                        iv,
620                                        out))
621   {
622     GNUNET_break (0);
623     return GNUNET_SYSERR;
624   }
625   GNUNET_STATISTICS_update (GSC_stats,
626                             gettext_noop ("# bytes decrypted"),
627                             size,
628                             GNUNET_NO);
629   /* the following is too sensitive to write to log files by accident,
630      so we require manual intervention to get this one... */
631 #if 0
632   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
633               "Decrypted %u bytes from `%s' using key %u, IV %u\n",
634               (unsigned int) size,
635               GNUNET_i2s (kx->peer),
636               (unsigned int) kx->decrypt_key.crc32,
637               GNUNET_CRYPTO_crc32_n (iv,
638                                      sizeof
639                                      (*iv)));
640 #endif
641   return GNUNET_OK;
642 }
643
644
645 /**
646  * Send our key (and encrypted PING) to the other peer.
647  *
648  * @param kx key exchange context
649  */
650 static void
651 send_key (struct GSC_KeyExchangeInfo *kx);
652
653
654 /**
655  * Task that will retry #send_key() if our previous attempt failed.
656  *
657  * @param cls our `struct GSC_KeyExchangeInfo`
658  */
659 static void
660 set_key_retry_task (void *cls)
661 {
662   struct GSC_KeyExchangeInfo *kx = cls;
663
664   kx->retry_set_key_task = NULL;
665   kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency);
666   GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
667   send_key (kx);
668 }
669
670
671 /**
672  * Create a fresh PING message for transmission to the other peer.
673  *
674  * @param kx key exchange context to create PING for
675  */
676 static void
677 setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
678 {
679   struct PingMessage pp;
680   struct PingMessage *pm;
681   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
682
683   pm = &kx->ping;
684   kx->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
685                                                  UINT32_MAX);
686   pm->header.size = htons (sizeof (struct PingMessage));
687   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
688   pm->iv_seed = calculate_seed (kx);
689   derive_iv (&iv,
690              &kx->encrypt_key,
691              pm->iv_seed,
692              kx->peer);
693   pp.challenge = kx->ping_challenge;
694   pp.target = *kx->peer;
695   do_encrypt (kx,
696               &iv,
697               &pp.target,
698               &pm->target,
699               sizeof (struct PingMessage) - ((void *) &pm->target -
700                                              (void *) pm));
701 }
702
703
704 /**
705  * Function called by transport to notify us that
706  * a peer connected to us (on the network level).
707  * Starts the key exchange with the given peer.
708  *
709  * @param cls closure (NULL)
710  * @param pid identity of the peer to do a key exchange with
711  * @return key exchange information context
712  */
713 static void *
714 handle_transport_notify_connect (void *cls,
715                                  const struct GNUNET_PeerIdentity *pid,
716                                  struct GNUNET_MQ_Handle *mq)
717 {
718   struct GSC_KeyExchangeInfo *kx;
719   struct GNUNET_HashCode h1;
720   struct GNUNET_HashCode h2;
721
722   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
723               "Initiating key exchange with `%s'\n",
724               GNUNET_i2s (pid));
725   GNUNET_STATISTICS_update (GSC_stats,
726                             gettext_noop ("# key exchanges initiated"),
727                             1,
728                             GNUNET_NO);
729   kx = GNUNET_new (struct GSC_KeyExchangeInfo);
730   kx->mq = mq;
731   kx->peer = pid;
732   kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
733   GNUNET_CONTAINER_DLL_insert (kx_head,
734                                kx_tail,
735                                kx);
736   kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
737   monitor_notify_all (kx);
738   GNUNET_CRYPTO_hash (pid,
739                       sizeof (struct GNUNET_PeerIdentity),
740                       &h1);
741   GNUNET_CRYPTO_hash (&GSC_my_identity,
742                       sizeof (struct GNUNET_PeerIdentity),
743                       &h2);
744   if (0 < GNUNET_CRYPTO_hash_cmp (&h1,
745                                   &h2))
746   {
747     /* peer with "lower" identity starts KX, otherwise we typically end up
748        with both peers starting the exchange and transmit the 'set key'
749        message twice */
750     send_key (kx);
751   }
752   else
753   {
754     /* peer with "higher" identity starts a delayed  KX, if the "lower" peer
755      * does not start a KX since he sees no reasons to do so  */
756     kx->retry_set_key_task
757       = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
758                                       &set_key_retry_task,
759                                       kx);
760   }
761   return kx;
762 }
763
764
765 /**
766  * Function called by transport telling us that a peer
767  * disconnected.
768  * Stop key exchange with the given peer.  Clean up key material.
769  *
770  * @param cls closure
771  * @param peer the peer that disconnected
772  * @param handler_cls the `struct GSC_KeyExchangeInfo` of the peer
773  */
774 static void
775 handle_transport_notify_disconnect (void *cls,
776                                     const struct GNUNET_PeerIdentity *peer,
777                                     void *handler_cls)
778 {
779   struct GSC_KeyExchangeInfo *kx = handler_cls;
780
781   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
782               "Peer `%s' disconnected from us.\n",
783               GNUNET_i2s (peer));
784   GSC_SESSIONS_end (kx->peer);
785   GNUNET_STATISTICS_update (GSC_stats,
786                             gettext_noop ("# key exchanges stopped"),
787                             1,
788                             GNUNET_NO);
789   if (NULL != kx->retry_set_key_task)
790   {
791     GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
792     kx->retry_set_key_task = NULL;
793   }
794   if (NULL != kx->keep_alive_task)
795   {
796     GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
797     kx->keep_alive_task = NULL;
798   }
799   kx->status = GNUNET_CORE_KX_PEER_DISCONNECT;
800   monitor_notify_all (kx);
801   GNUNET_CONTAINER_DLL_remove (kx_head,
802                                kx_tail,
803                                kx);
804   GNUNET_free (kx);
805 }
806
807
808 /**
809  * Send our PING to the other peer.
810  *
811  * @param kx key exchange context
812  */
813 static void
814 send_ping (struct GSC_KeyExchangeInfo *kx)
815 {
816   struct GNUNET_MQ_Envelope *env;
817
818   GNUNET_STATISTICS_update (GSC_stats,
819                             gettext_noop ("# PING messages transmitted"),
820                             1,
821                             GNUNET_NO);
822   env = GNUNET_MQ_msg_copy (&kx->ping.header);
823   GNUNET_MQ_send (kx->mq,
824                   env);
825 }
826
827
828 /**
829  * Derive fresh session keys from the current ephemeral keys.
830  *
831  * @param kx session to derive keys for
832  */
833 static void
834 derive_session_keys (struct GSC_KeyExchangeInfo *kx)
835 {
836   struct GNUNET_HashCode key_material;
837
838   if (GNUNET_OK !=
839       GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key,
840                               &kx->other_ephemeral_key,
841                               &key_material))
842   {
843     GNUNET_break (0);
844     return;
845   }
846   derive_aes_key (&GSC_my_identity,
847                   kx->peer,
848                   &key_material,
849                   &kx->encrypt_key);
850   derive_aes_key (kx->peer,
851                   &GSC_my_identity,
852                   &key_material,
853                   &kx->decrypt_key);
854   memset (&key_material, 0, sizeof (key_material));
855   /* fresh key, reset sequence numbers */
856   kx->last_sequence_number_received = 0;
857   kx->last_packets_bitmap = 0;
858   setup_fresh_ping (kx);
859 }
860
861
862 /**
863  * We received a #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY message.
864  * Validate and update our key material and status.
865  *
866  * @param cls key exchange status for the corresponding peer
867  * @param m the set key message we received
868  */
869 static void
870 handle_ephemeral_key (void *cls,
871                       const struct EphemeralKeyMessage *m)
872 {
873   struct GSC_KeyExchangeInfo *kx = cls;
874   struct GNUNET_TIME_Absolute start_t;
875   struct GNUNET_TIME_Absolute end_t;
876   struct GNUNET_TIME_Absolute now;
877   enum GNUNET_CORE_KxState sender_status;
878
879   end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time);
880   if ( ( (GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) ||
881          (GNUNET_CORE_KX_STATE_UP == kx->status) ||
882          (GNUNET_CORE_KX_STATE_REKEY_SENT == kx->status) ) &&
883        (end_t.abs_value_us < kx->foreign_key_expires.abs_value_us) )
884   {
885     GNUNET_STATISTICS_update (GSC_stats,
886                               gettext_noop ("# old ephemeral keys ignored"),
887                               1, GNUNET_NO);
888     return;
889   }
890   start_t = GNUNET_TIME_absolute_ntoh (m->creation_time);
891
892   GNUNET_STATISTICS_update (GSC_stats,
893                             gettext_noop ("# ephemeral keys received"),
894                             1, GNUNET_NO);
895
896   if (0 !=
897       memcmp (&m->origin_identity,
898               kx->peer,
899               sizeof (struct GNUNET_PeerIdentity)))
900   {
901     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
902                 "Received EPHEMERAL_KEY from %s, but expected %s\n",
903                 GNUNET_i2s (&m->origin_identity),
904                 GNUNET_i2s_full (kx->peer));
905     GNUNET_break_op (0);
906     return;
907   }
908   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
909               "Core service receives EPHEMERAL_KEY request from `%s'.\n",
910               GNUNET_i2s (kx->peer));
911   if ((ntohl (m->purpose.size) !=
912        sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
913        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
914        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
915        sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) +
916        sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) ||
917       (GNUNET_OK !=
918        GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY,
919                                    &m->purpose,
920                                    &m->signature,
921                                    &m->origin_identity.public_key)))
922   {
923     /* invalid signature */
924     GNUNET_break_op (0);
925     return;
926   }
927   now = GNUNET_TIME_absolute_get ();
928   if ( (end_t.abs_value_us < GNUNET_TIME_absolute_subtract (now, REKEY_TOLERANCE).abs_value_us) ||
929        (start_t.abs_value_us > GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us) )
930   {
931     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
932                 _("Ephemeral key message from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
933                 GNUNET_i2s (kx->peer),
934                 (unsigned long long) now.abs_value_us,
935                 (unsigned long long) start_t.abs_value_us,
936                 (unsigned long long) end_t.abs_value_us);
937     return;
938   }
939   kx->other_ephemeral_key = m->ephemeral_key;
940   kx->foreign_key_expires = end_t;
941   derive_session_keys (kx);
942   GNUNET_STATISTICS_update (GSC_stats,
943                             gettext_noop ("# EPHEMERAL_KEY messages received"), 1,
944                             GNUNET_NO);
945
946   /* check if we still need to send the sender our key */
947   sender_status = (enum GNUNET_CORE_KxState) ntohl (m->sender_status);
948   switch (sender_status)
949   {
950   case GNUNET_CORE_KX_STATE_DOWN:
951     GNUNET_break_op (0);
952     break;
953   case GNUNET_CORE_KX_STATE_KEY_SENT:
954     /* fine, need to send our key after updating our status, see below */
955     GSC_SESSIONS_reinit (kx->peer);
956     break;
957   case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
958     /* other peer already got our key, but typemap did go down */
959     GSC_SESSIONS_reinit (kx->peer);
960     break;
961   case GNUNET_CORE_KX_STATE_UP:
962     /* other peer already got our key, typemap NOT down */
963     break;
964   case GNUNET_CORE_KX_STATE_REKEY_SENT:
965     /* other peer already got our key, typemap NOT down */
966     break;
967   default:
968     GNUNET_break (0);
969     break;
970   }
971   /* check if we need to confirm everything is fine via PING + PONG */
972   switch (kx->status)
973   {
974   case GNUNET_CORE_KX_STATE_DOWN:
975     GNUNET_assert (NULL == kx->keep_alive_task);
976     kx->status = GNUNET_CORE_KX_STATE_KEY_RECEIVED;
977     monitor_notify_all (kx);
978     if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
979       send_key (kx);
980     else
981       send_ping (kx);
982     break;
983   case GNUNET_CORE_KX_STATE_KEY_SENT:
984     GNUNET_assert (NULL == kx->keep_alive_task);
985     kx->status = GNUNET_CORE_KX_STATE_KEY_RECEIVED;
986     monitor_notify_all (kx);
987     if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
988       send_key (kx);
989     else
990       send_ping (kx);
991     break;
992   case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
993     GNUNET_assert (NULL == kx->keep_alive_task);
994     if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
995       send_key (kx);
996     else
997       send_ping (kx);
998     break;
999   case GNUNET_CORE_KX_STATE_UP:
1000     kx->status = GNUNET_CORE_KX_STATE_REKEY_SENT;
1001     monitor_notify_all (kx);
1002     if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1003       send_key (kx);
1004     else
1005       send_ping (kx);
1006     break;
1007   case GNUNET_CORE_KX_STATE_REKEY_SENT:
1008     if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1009       send_key (kx);
1010     else
1011       send_ping (kx);
1012     break;
1013   default:
1014     GNUNET_break (0);
1015     break;
1016   }
1017 }
1018
1019
1020 /**
1021  * We received a PING message.  Validate and transmit
1022  * a PONG message.
1023  *
1024  * @param cls key exchange status for the corresponding peer
1025  * @param m the encrypted PING message itself
1026  */
1027 static void
1028 handle_ping (void *cls,
1029              const struct PingMessage *m)
1030 {
1031   struct GSC_KeyExchangeInfo *kx = cls;
1032   struct PingMessage t;
1033   struct PongMessage tx;
1034   struct PongMessage *tp;
1035   struct GNUNET_MQ_Envelope *env;
1036   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1037
1038   GNUNET_STATISTICS_update (GSC_stats,
1039                             gettext_noop ("# PING messages received"),
1040                             1,
1041                             GNUNET_NO);
1042   if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) &&
1043        (kx->status != GNUNET_CORE_KX_STATE_UP) &&
1044        (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT))
1045   {
1046     /* ignore */
1047     GNUNET_STATISTICS_update (GSC_stats,
1048                               gettext_noop ("# PING messages dropped (out of order)"),
1049                               1,
1050                               GNUNET_NO);
1051     return;
1052   }
1053   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1054               "Core service receives PING request from `%s'.\n",
1055               GNUNET_i2s (kx->peer));
1056   derive_iv (&iv,
1057              &kx->decrypt_key,
1058              m->iv_seed,
1059              &GSC_my_identity);
1060   if (GNUNET_OK !=
1061       do_decrypt (kx,
1062                   &iv,
1063                   &m->target,
1064                   &t.target,
1065                   sizeof (struct PingMessage) - ((void *) &m->target -
1066                                                  (void *) m)))
1067   {
1068     GNUNET_break_op (0);
1069     return;
1070   }
1071   if (0 !=
1072       memcmp (&t.target,
1073               &GSC_my_identity,
1074               sizeof (struct GNUNET_PeerIdentity)))
1075   {
1076     if (GNUNET_CORE_KX_STATE_REKEY_SENT != kx->status)
1077       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1078                   "Decryption of PING from peer `%s' failed\n",
1079                   GNUNET_i2s (kx->peer));
1080     else
1081       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1082                   "Decryption of PING from peer `%s' failed after rekey (harmless)\n",
1083                   GNUNET_i2s (kx->peer));
1084     GNUNET_break_op (0);
1085     return;
1086   }
1087   /* construct PONG */
1088   tx.reserved = 0;
1089   tx.challenge = t.challenge;
1090   tx.target = t.target;
1091   env = GNUNET_MQ_msg (tp,
1092                        GNUNET_MESSAGE_TYPE_CORE_PONG);
1093   tp->iv_seed = calculate_seed (kx);
1094   derive_pong_iv (&iv,
1095                   &kx->encrypt_key,
1096                   tp->iv_seed,
1097                   t.challenge,
1098                   kx->peer);
1099   do_encrypt (kx,
1100               &iv,
1101               &tx.challenge,
1102               &tp->challenge,
1103               sizeof (struct PongMessage) - ((void *) &tp->challenge -
1104                                              (void *) tp));
1105   GNUNET_STATISTICS_update (GSC_stats,
1106                             gettext_noop ("# PONG messages created"),
1107                             1,
1108                             GNUNET_NO);
1109   GNUNET_MQ_send (kx->mq,
1110                   env);
1111 }
1112
1113
1114 /**
1115  * Task triggered when a neighbour entry is about to time out
1116  * (and we should prevent this by sending a PING).
1117  *
1118  * @param cls the `struct GSC_KeyExchangeInfo`
1119  */
1120 static void
1121 send_keep_alive (void *cls)
1122 {
1123   struct GSC_KeyExchangeInfo *kx = cls;
1124   struct GNUNET_TIME_Relative retry;
1125   struct GNUNET_TIME_Relative left;
1126
1127   kx->keep_alive_task = NULL;
1128   left = GNUNET_TIME_absolute_get_remaining (kx->timeout);
1129   if (0 == left.rel_value_us)
1130   {
1131     GNUNET_STATISTICS_update (GSC_stats,
1132                               gettext_noop ("# sessions terminated by timeout"),
1133                               1,
1134                               GNUNET_NO);
1135     GSC_SESSIONS_end (kx->peer);
1136     kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
1137     monitor_notify_all (kx);
1138     send_key (kx);
1139     return;
1140   }
1141   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1142               "Sending KEEPALIVE to `%s'\n",
1143               GNUNET_i2s (kx->peer));
1144   GNUNET_STATISTICS_update (GSC_stats,
1145                             gettext_noop ("# keepalive messages sent"),
1146                             1,
1147                             GNUNET_NO);
1148   setup_fresh_ping (kx);
1149   send_ping (kx);
1150   retry =
1151       GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2),
1152                                 MIN_PING_FREQUENCY);
1153   kx->keep_alive_task =
1154       GNUNET_SCHEDULER_add_delayed (retry,
1155                                     &send_keep_alive,
1156                                     kx);
1157 }
1158
1159
1160 /**
1161  * We've seen a valid message from the other peer.
1162  * Update the time when the session would time out
1163  * and delay sending our keep alive message further.
1164  *
1165  * @param kx key exchange where we saw activity
1166  */
1167 static void
1168 update_timeout (struct GSC_KeyExchangeInfo *kx)
1169 {
1170   struct GNUNET_TIME_Relative delta;
1171
1172   kx->timeout =
1173       GNUNET_TIME_relative_to_absolute
1174       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1175   delta = GNUNET_TIME_absolute_get_difference (kx->last_notify_timeout,
1176                                                kx->timeout);
1177   if (delta.rel_value_us > 5LL * 1000LL * 1000LL)
1178   {
1179     /* we only notify monitors about timeout changes if those
1180        are bigger than the threshold (5s) */
1181     monitor_notify_all (kx);
1182   }
1183   if (NULL != kx->keep_alive_task)
1184     GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1185   kx->keep_alive_task =
1186       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
1187                                     (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1188                                      2),
1189                                     &send_keep_alive,
1190                                     kx);
1191 }
1192
1193
1194 /**
1195  * We received a PONG message.  Validate and update our status.
1196  *
1197  * @param kx key exchange context for the the PONG
1198  * @param m the encrypted PONG message itself
1199  */
1200 static void
1201 handle_pong (void *cls,
1202              const struct PongMessage *m)
1203 {
1204   struct GSC_KeyExchangeInfo *kx = cls;
1205   struct PongMessage t;
1206   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1207
1208   GNUNET_STATISTICS_update (GSC_stats,
1209                             gettext_noop ("# PONG messages received"),
1210                             1,
1211                             GNUNET_NO);
1212   switch (kx->status)
1213   {
1214   case GNUNET_CORE_KX_STATE_DOWN:
1215     GNUNET_STATISTICS_update (GSC_stats,
1216                               gettext_noop ("# PONG messages dropped (connection down)"), 1,
1217                               GNUNET_NO);
1218     return;
1219   case GNUNET_CORE_KX_STATE_KEY_SENT:
1220     GNUNET_STATISTICS_update (GSC_stats,
1221                               gettext_noop ("# PONG messages dropped (out of order)"), 1,
1222                               GNUNET_NO);
1223     return;
1224   case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
1225     break;
1226   case GNUNET_CORE_KX_STATE_UP:
1227     break;
1228   case GNUNET_CORE_KX_STATE_REKEY_SENT:
1229     break;
1230   default:
1231     GNUNET_break (0);
1232     return;
1233   }
1234   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1235               "Core service receives PONG response from `%s'.\n",
1236               GNUNET_i2s (kx->peer));
1237   /* mark as garbage, just to be sure */
1238   memset (&t, 255, sizeof (t));
1239   derive_pong_iv (&iv,
1240                   &kx->decrypt_key,
1241                   m->iv_seed,
1242                   kx->ping_challenge,
1243                   &GSC_my_identity);
1244   if (GNUNET_OK !=
1245       do_decrypt (kx,
1246                   &iv,
1247                   &m->challenge,
1248                   &t.challenge,
1249                   sizeof (struct PongMessage) - ((void *) &m->challenge -
1250                                                  (void *) m)))
1251   {
1252     GNUNET_break_op (0);
1253     return;
1254   }
1255   GNUNET_STATISTICS_update (GSC_stats,
1256                             gettext_noop ("# PONG messages decrypted"),
1257                             1,
1258                             GNUNET_NO);
1259   if ((0 != memcmp (&t.target,
1260                     kx->peer,
1261                     sizeof (struct GNUNET_PeerIdentity))) ||
1262       (kx->ping_challenge != t.challenge))
1263   {
1264     /* PONG malformed */
1265     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1266                 "Received malformed PONG wanted sender `%s' with challenge %u\n",
1267                 GNUNET_i2s (kx->peer),
1268                 (unsigned int) kx->ping_challenge);
1269     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1270                 "Received malformed PONG received from `%s' with challenge %u\n",
1271                 GNUNET_i2s (&t.target),
1272                 (unsigned int) t.challenge);
1273     return;
1274   }
1275   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1276               "Received PONG from `%s'\n",
1277               GNUNET_i2s (kx->peer));
1278   /* no need to resend key any longer */
1279   if (NULL != kx->retry_set_key_task)
1280   {
1281     GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1282     kx->retry_set_key_task = NULL;
1283   }
1284   switch (kx->status)
1285   {
1286   case GNUNET_CORE_KX_STATE_DOWN:
1287     GNUNET_assert (0);           /* should be impossible */
1288     return;
1289   case GNUNET_CORE_KX_STATE_KEY_SENT:
1290     GNUNET_assert (0);           /* should be impossible */
1291     return;
1292   case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
1293     GNUNET_STATISTICS_update (GSC_stats,
1294                               gettext_noop ("# session keys confirmed via PONG"),
1295                               1,
1296                               GNUNET_NO);
1297     kx->status = GNUNET_CORE_KX_STATE_UP;
1298     monitor_notify_all (kx);
1299     GSC_SESSIONS_create (kx->peer, kx);
1300     GNUNET_assert (NULL == kx->keep_alive_task);
1301     update_timeout (kx);
1302     break;
1303   case GNUNET_CORE_KX_STATE_UP:
1304     GNUNET_STATISTICS_update (GSC_stats,
1305                               gettext_noop ("# timeouts prevented via PONG"),
1306                               1,
1307                               GNUNET_NO);
1308     update_timeout (kx);
1309     break;
1310   case GNUNET_CORE_KX_STATE_REKEY_SENT:
1311     GNUNET_STATISTICS_update (GSC_stats,
1312                               gettext_noop ("# rekey operations confirmed via PONG"),
1313                               1,
1314                               GNUNET_NO);
1315     kx->status = GNUNET_CORE_KX_STATE_UP;
1316     monitor_notify_all (kx);
1317     update_timeout (kx);
1318     break;
1319   default:
1320     GNUNET_break (0);
1321     break;
1322   }
1323 }
1324
1325
1326 /**
1327  * Send our key to the other peer.
1328  *
1329  * @param kx key exchange context
1330  */
1331 static void
1332 send_key (struct GSC_KeyExchangeInfo *kx)
1333 {
1334   struct GNUNET_MQ_Envelope *env;
1335
1336   GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
1337   if (NULL != kx->retry_set_key_task)
1338   {
1339      GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1340      kx->retry_set_key_task = NULL;
1341   }
1342   /* always update sender status in SET KEY message */
1343   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1344               "Sending key to `%s' (my status: %d)\n",
1345               GNUNET_i2s (kx->peer),
1346               kx->status);
1347   current_ekm.sender_status = htonl ((int32_t) (kx->status));
1348   env = GNUNET_MQ_msg_copy (&current_ekm.header);
1349   GNUNET_MQ_send (kx->mq,
1350                   env);
1351   if (GNUNET_CORE_KX_STATE_KEY_SENT != kx->status)
1352     send_ping (kx);
1353   kx->retry_set_key_task =
1354       GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
1355                                     &set_key_retry_task,
1356                                     kx);
1357 }
1358
1359
1360 /**
1361  * Encrypt and transmit a message with the given payload.
1362  *
1363  * @param kx key exchange context
1364  * @param payload payload of the message
1365  * @param payload_size number of bytes in @a payload
1366  */
1367 void
1368 GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1369                              const void *payload,
1370                              size_t payload_size)
1371 {
1372   size_t used = payload_size + sizeof (struct EncryptedMessage);
1373   char pbuf[used];              /* plaintext */
1374   struct EncryptedMessage *em;  /* encrypted message */
1375   struct EncryptedMessage *ph;  /* plaintext header */
1376   struct GNUNET_MQ_Envelope *env;
1377   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1378   struct GNUNET_CRYPTO_AuthKey auth_key;
1379
1380   ph = (struct EncryptedMessage *) pbuf;
1381   ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1382   ph->iv_seed = calculate_seed (kx);
1383   ph->reserved = 0;
1384   ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1385   GNUNET_memcpy (&ph[1],
1386                  payload,
1387                  payload_size);
1388   env = GNUNET_MQ_msg_extra (em,
1389                              payload_size,
1390                              GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1391   em->iv_seed = ph->iv_seed;
1392   derive_iv (&iv,
1393              &kx->encrypt_key,
1394              ph->iv_seed,
1395              kx->peer);
1396   GNUNET_assert (GNUNET_OK ==
1397                  do_encrypt (kx,
1398                              &iv,
1399                              &ph->sequence_number,
1400                              &em->sequence_number,
1401                              used - ENCRYPTED_HEADER_SIZE));
1402   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1403               "Encrypted %u bytes for %s\n",
1404               (unsigned int) (used - ENCRYPTED_HEADER_SIZE),
1405               GNUNET_i2s (kx->peer));
1406   derive_auth_key (&auth_key,
1407                    &kx->encrypt_key,
1408                    ph->iv_seed);
1409   GNUNET_CRYPTO_hmac (&auth_key,
1410                       &em->sequence_number,
1411                       used - ENCRYPTED_HEADER_SIZE,
1412                       &em->hmac);
1413   kx->has_excess_bandwidth = GNUNET_NO;
1414   GNUNET_MQ_send (kx->mq,
1415                   env);
1416 }
1417
1418
1419 /**
1420  * Closure for #deliver_message()
1421  */
1422 struct DeliverMessageContext
1423 {
1424
1425   /**
1426    * Key exchange context.
1427    */
1428   struct GSC_KeyExchangeInfo *kx;
1429
1430   /**
1431    * Sender of the message.
1432    */
1433   const struct GNUNET_PeerIdentity *peer;
1434 };
1435
1436
1437 /**
1438  * We received an encrypted message.  Check that it is
1439  * well-formed (size-wise).
1440  *
1441  * @param cls key exchange context for encrypting the message
1442  * @param m encrypted message
1443  * @return #GNUNET_OK if @a msg is well-formed (size-wise)
1444  */
1445 static int
1446 check_encrypted (void *cls,
1447                  const struct EncryptedMessage *m)
1448 {
1449   uint16_t size = ntohs (m->header.size) - sizeof (*m);
1450
1451   if (size < sizeof (struct GNUNET_MessageHeader))
1452   {
1453     GNUNET_break_op (0);
1454     return GNUNET_SYSERR;
1455   }
1456   return GNUNET_OK;
1457 }
1458
1459
1460 /**
1461  * We received an encrypted message.  Decrypt, validate and
1462  * pass on to the appropriate clients.
1463  *
1464  * @param cls key exchange context for encrypting the message
1465  * @param m encrypted message
1466  */
1467 static void
1468 handle_encrypted (void *cls,
1469                   const struct EncryptedMessage *m)
1470 {
1471   struct GSC_KeyExchangeInfo *kx = cls;
1472   struct EncryptedMessage *pt;  /* plaintext */
1473   struct GNUNET_HashCode ph;
1474   uint32_t snum;
1475   struct GNUNET_TIME_Absolute t;
1476   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1477   struct GNUNET_CRYPTO_AuthKey auth_key;
1478   struct DeliverMessageContext dmc;
1479   uint16_t size = ntohs (m->header.size);
1480   char buf[size] GNUNET_ALIGN;
1481
1482   if (GNUNET_CORE_KX_STATE_UP != kx->status)
1483   {
1484     GNUNET_STATISTICS_update (GSC_stats,
1485                               gettext_noop ("# DATA message dropped (out of order)"),
1486                               1,
1487                               GNUNET_NO);
1488     return;
1489   }
1490   if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value_us)
1491   {
1492     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1493                 _("Session to peer `%s' went down due to key expiration (should not happen)\n"),
1494                 GNUNET_i2s (kx->peer));
1495     GNUNET_STATISTICS_update (GSC_stats,
1496                               gettext_noop ("# sessions terminated by key expiration"),
1497                               1, GNUNET_NO);
1498     GSC_SESSIONS_end (kx->peer);
1499     if (NULL != kx->keep_alive_task)
1500     {
1501       GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1502       kx->keep_alive_task = NULL;
1503     }
1504     kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
1505     monitor_notify_all (kx);
1506     send_key (kx);
1507     return;
1508   }
1509
1510   /* validate hash */
1511   derive_auth_key (&auth_key,
1512                    &kx->decrypt_key,
1513                    m->iv_seed);
1514   GNUNET_CRYPTO_hmac (&auth_key,
1515                       &m->sequence_number,
1516                       size - ENCRYPTED_HEADER_SIZE,
1517                       &ph);
1518   if (0 != memcmp (&ph,
1519                    &m->hmac,
1520                    sizeof (struct GNUNET_HashCode)))
1521   {
1522     /* checksum failed */
1523     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1524                 "Failed checksum validation for a message from `%s'\n",
1525                 GNUNET_i2s (kx->peer));
1526     return;
1527   }
1528   derive_iv (&iv,
1529              &kx->decrypt_key,
1530              m->iv_seed,
1531              &GSC_my_identity);
1532   /* decrypt */
1533   if (GNUNET_OK !=
1534       do_decrypt (kx,
1535                   &iv,
1536                   &m->sequence_number,
1537                   &buf[ENCRYPTED_HEADER_SIZE],
1538                   size - ENCRYPTED_HEADER_SIZE))
1539   {
1540     GNUNET_break_op (0);
1541     return;
1542   }
1543   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1544               "Decrypted %u bytes from %s\n",
1545               (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1546               GNUNET_i2s (kx->peer));
1547   pt = (struct EncryptedMessage *) buf;
1548
1549   /* validate sequence number */
1550   snum = ntohl (pt->sequence_number);
1551   if (kx->last_sequence_number_received == snum)
1552   {
1553     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1554                 "Received duplicate message, ignoring.\n");
1555     /* duplicate, ignore */
1556     GNUNET_STATISTICS_update (GSC_stats,
1557                               gettext_noop ("# bytes dropped (duplicates)"),
1558                               size,
1559                               GNUNET_NO);
1560     return;
1561   }
1562   if ((kx->last_sequence_number_received > snum) &&
1563       (kx->last_sequence_number_received - snum > 32))
1564   {
1565     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1566                 "Received ancient out of sequence message, ignoring.\n");
1567     /* ancient out of sequence, ignore */
1568     GNUNET_STATISTICS_update (GSC_stats,
1569                               gettext_noop
1570                               ("# bytes dropped (out of sequence)"), size,
1571                               GNUNET_NO);
1572     return;
1573   }
1574   if (kx->last_sequence_number_received > snum)
1575   {
1576     uint32_t rotbit = 1U << (kx->last_sequence_number_received - snum - 1);
1577
1578     if ((kx->last_packets_bitmap & rotbit) != 0)
1579     {
1580       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1581                   "Received duplicate message, ignoring.\n");
1582       GNUNET_STATISTICS_update (GSC_stats,
1583                                 gettext_noop ("# bytes dropped (duplicates)"),
1584                                 size, GNUNET_NO);
1585       /* duplicate, ignore */
1586       return;
1587     }
1588     kx->last_packets_bitmap |= rotbit;
1589   }
1590   if (kx->last_sequence_number_received < snum)
1591   {
1592     unsigned int shift = (snum - kx->last_sequence_number_received);
1593
1594     if (shift >= 8 * sizeof (kx->last_packets_bitmap))
1595       kx->last_packets_bitmap = 0;
1596     else
1597       kx->last_packets_bitmap <<= shift;
1598     kx->last_sequence_number_received = snum;
1599   }
1600
1601   /* check timestamp */
1602   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
1603   if (GNUNET_TIME_absolute_get_duration (t).rel_value_us >
1604       MAX_MESSAGE_AGE.rel_value_us)
1605   {
1606     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1607                 "Message received far too old (%s). Content ignored.\n",
1608                 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (t),
1609                                                         GNUNET_YES));
1610     GNUNET_STATISTICS_update (GSC_stats,
1611                               gettext_noop
1612                               ("# bytes dropped (ancient message)"), size,
1613                               GNUNET_NO);
1614     return;
1615   }
1616
1617   /* process decrypted message(s) */
1618   update_timeout (kx);
1619   GNUNET_STATISTICS_update (GSC_stats,
1620                             gettext_noop ("# bytes of payload decrypted"),
1621                             size - sizeof (struct EncryptedMessage),
1622                             GNUNET_NO);
1623   dmc.kx = kx;
1624   dmc.peer = kx->peer;
1625   if (GNUNET_OK !=
1626       GNUNET_SERVER_mst_receive (mst,
1627                                  &dmc,
1628                                  &buf[sizeof (struct EncryptedMessage)],
1629                                  size - sizeof (struct EncryptedMessage),
1630                                  GNUNET_YES,
1631                                  GNUNET_NO))
1632     GNUNET_break_op (0);
1633 }
1634
1635
1636 /**
1637  * One of our neighbours has excess bandwidth, remember this.
1638  *
1639  * @param cls NULL
1640  * @param pid identity of the peer with excess bandwidth
1641  * @param connect_cls the `struct Neighbour`
1642  */
1643 static void
1644 handle_transport_notify_excess_bw (void *cls,
1645                                    const struct GNUNET_PeerIdentity *pid,
1646                                    void *connect_cls)
1647 {
1648   struct GSC_KeyExchangeInfo *kx = connect_cls;
1649
1650   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1651               "Peer %s has excess bandwidth available\n",
1652               GNUNET_i2s (pid));
1653   kx->has_excess_bandwidth = GNUNET_YES;
1654   GSC_SESSIONS_solicit (pid);
1655 }
1656
1657
1658 /**
1659  * Deliver P2P message to interested clients.  Invokes send twice,
1660  * once for clients that want the full message, and once for clients
1661  * that only want the header
1662  *
1663  * @param cls always NULL
1664  * @param client who sent us the message (struct GSC_KeyExchangeInfo)
1665  * @param m the message
1666  */
1667 static int
1668 deliver_message (void *cls,
1669                  void *client,
1670                  const struct GNUNET_MessageHeader *m)
1671 {
1672   struct DeliverMessageContext *dmc = client;
1673
1674   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1675               "Decrypted message of type %d from %s\n",
1676               ntohs (m->type),
1677               GNUNET_i2s (dmc->peer));
1678   if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
1679   {
1680     GNUNET_STATISTICS_update (GSC_stats,
1681                               gettext_noop ("# PAYLOAD dropped (out of order)"),
1682                               1,
1683                               GNUNET_NO);
1684     return GNUNET_OK;
1685   }
1686   switch (ntohs (m->type))
1687   {
1688   case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
1689   case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
1690     GSC_SESSIONS_set_typemap (dmc->peer, m);
1691     return GNUNET_OK;
1692   case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
1693     GSC_SESSIONS_confirm_typemap (dmc->peer, m);
1694     return GNUNET_OK;
1695   default:
1696     GSC_CLIENTS_deliver_message (dmc->peer,
1697                                  m,
1698                                  ntohs (m->size),
1699                                  GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
1700     GSC_CLIENTS_deliver_message (dmc->peer,
1701                                  m,
1702                                  sizeof (struct GNUNET_MessageHeader),
1703                                  GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
1704   }
1705   return GNUNET_OK;
1706 }
1707
1708
1709 /**
1710  * Setup the message that links the ephemeral key to our persistent
1711  * public key and generate the appropriate signature.
1712  */
1713 static void
1714 sign_ephemeral_key ()
1715 {
1716   current_ekm.header.size = htons (sizeof (struct EphemeralKeyMessage));
1717   current_ekm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY);
1718   current_ekm.sender_status = 0; /* to be set later */
1719   current_ekm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY);
1720   current_ekm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
1721                                     sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1722                                     sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1723                                     sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
1724                                     sizeof (struct GNUNET_PeerIdentity));
1725   current_ekm.creation_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1726   if (GNUNET_YES ==
1727       GNUNET_CONFIGURATION_get_value_yesno (GSC_cfg,
1728                                             "core",
1729                                             "USE_EPHEMERAL_KEYS"))
1730   {
1731     current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_add (REKEY_FREQUENCY,
1732                                                                                                                          REKEY_TOLERANCE)));
1733   }
1734   else
1735   {
1736     current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1737   }
1738   GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key,
1739                                       &current_ekm.ephemeral_key);
1740   current_ekm.origin_identity = GSC_my_identity;
1741   GNUNET_assert (GNUNET_OK ==
1742                  GNUNET_CRYPTO_eddsa_sign (my_private_key,
1743                                            &current_ekm.purpose,
1744                                            &current_ekm.signature));
1745 }
1746
1747
1748 /**
1749  * Task run to trigger rekeying.
1750  *
1751  * @param cls closure, NULL
1752  */
1753 static void
1754 do_rekey (void *cls)
1755 {
1756   struct GSC_KeyExchangeInfo *pos;
1757
1758   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1759                                              &do_rekey,
1760                                              NULL);
1761   if (NULL != my_ephemeral_key)
1762     GNUNET_free (my_ephemeral_key);
1763   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1764               "Rekeying\n");
1765   my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1766   GNUNET_assert (NULL != my_ephemeral_key);
1767   sign_ephemeral_key ();
1768   for (pos = kx_head; NULL != pos; pos = pos->next)
1769   {
1770     if (GNUNET_CORE_KX_STATE_UP == pos->status)
1771     {
1772       pos->status = GNUNET_CORE_KX_STATE_REKEY_SENT;
1773       monitor_notify_all (pos);
1774       derive_session_keys (pos);
1775     }
1776     if (GNUNET_CORE_KX_STATE_DOWN == pos->status)
1777     {
1778       pos->status = GNUNET_CORE_KX_STATE_KEY_SENT;
1779       monitor_notify_all (pos);
1780     }
1781     monitor_notify_all (pos);
1782     send_key (pos);
1783   }
1784 }
1785
1786
1787 /**
1788  * Initialize KX subsystem.
1789  *
1790  * @param pk private key to use for the peer
1791  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
1792  */
1793 int
1794 GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
1795 {
1796   struct GNUNET_MQ_MessageHandler handlers[] = {
1797     GNUNET_MQ_hd_fixed_size (ephemeral_key,
1798                              GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY,
1799                              struct EphemeralKeyMessage,
1800                              NULL),
1801     GNUNET_MQ_hd_fixed_size (ping,
1802                              GNUNET_MESSAGE_TYPE_CORE_PING,
1803                              struct PingMessage,
1804                              NULL),
1805     GNUNET_MQ_hd_fixed_size (pong,
1806                              GNUNET_MESSAGE_TYPE_CORE_PONG,
1807                              struct PongMessage,
1808                              NULL),
1809     GNUNET_MQ_hd_var_size (encrypted,
1810                            GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE,
1811                            struct EncryptedMessage,
1812                            NULL),
1813     GNUNET_MQ_handler_end()
1814   };
1815
1816   my_private_key = pk;
1817   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1818                                       &GSC_my_identity.public_key);
1819   my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1820   if (NULL == my_ephemeral_key)
1821   {
1822     GNUNET_break (0);
1823     GNUNET_free (my_private_key);
1824     my_private_key = NULL;
1825     return GNUNET_SYSERR;
1826   }
1827   sign_ephemeral_key ();
1828   nc = GNUNET_notification_context_create (1);
1829   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1830                                              &do_rekey,
1831                                              NULL);
1832   mst = GNUNET_SERVER_mst_create (&deliver_message,
1833                                   NULL);
1834   transport
1835     = GNUNET_TRANSPORT_core_connect (GSC_cfg,
1836                                      &GSC_my_identity,
1837                                      handlers,
1838                                      NULL,
1839                                      &handle_transport_notify_connect,
1840                                      &handle_transport_notify_disconnect,
1841                                      &handle_transport_notify_excess_bw);
1842   if (NULL == transport)
1843   {
1844     GSC_KX_done ();
1845     return GNUNET_SYSERR;
1846   }
1847   return GNUNET_OK;
1848 }
1849
1850
1851 /**
1852  * Shutdown KX subsystem.
1853  */
1854 void
1855 GSC_KX_done ()
1856 {
1857   if (NULL != transport)
1858   {
1859     GNUNET_TRANSPORT_core_disconnect (transport);
1860     transport = NULL;
1861   }
1862   if (NULL != rekey_task)
1863   {
1864     GNUNET_SCHEDULER_cancel (rekey_task);
1865     rekey_task = NULL;
1866   }
1867   if (NULL != my_ephemeral_key)
1868   {
1869     GNUNET_free (my_ephemeral_key);
1870     my_ephemeral_key = NULL;
1871   }
1872   if (NULL != my_private_key)
1873   {
1874     GNUNET_free (my_private_key);
1875     my_private_key = NULL;
1876   }
1877   if (NULL != mst)
1878   {
1879     GNUNET_SERVER_mst_destroy (mst);
1880     mst = NULL;
1881   }
1882   if (NULL != nc)
1883   {
1884     GNUNET_notification_context_destroy (nc);
1885     nc = NULL;
1886   }
1887 }
1888
1889
1890  /**
1891  * Check how many messages are queued for the given neighbour.
1892  *
1893  * @param kxinfo data about neighbour to check
1894  * @return number of items in the message queue
1895  */
1896 unsigned int
1897 GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *kxinfo)
1898 {
1899   return GNUNET_MQ_get_length (kxinfo->mq);
1900 }
1901
1902
1903 /**
1904  * Check if the given neighbour has excess bandwidth available.
1905  *
1906  * @param target neighbour to check
1907  * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
1908  */
1909 int
1910 GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *kxinfo)
1911 {
1912   return kxinfo->has_excess_bandwidth;
1913 }
1914
1915
1916 /**
1917  * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.  For this
1918  * request type, the client does not have to have transmitted an INIT
1919  * request.  All current peers are returned, regardless of which
1920  * message types they accept.
1921  *
1922  * @param mq message queue to add for monitoring
1923  */
1924 void
1925 GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
1926 {
1927   struct GNUNET_MQ_Envelope *env;
1928   struct MonitorNotifyMessage *done_msg;
1929   struct GSC_KeyExchangeInfo *kx;
1930
1931   GNUNET_notification_context_add (nc,
1932                                    mq);
1933   for (kx = kx_head; NULL != kx; kx = kx->next)
1934   {
1935     struct GNUNET_MQ_Envelope *env;
1936     struct MonitorNotifyMessage *msg;
1937
1938     env = GNUNET_MQ_msg (msg,
1939                          GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
1940     msg->state = htonl ((uint32_t) kx->status);
1941     msg->peer = *kx->peer;
1942     msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout);
1943     GNUNET_MQ_send (mq,
1944                     env);
1945   }
1946   env = GNUNET_MQ_msg (done_msg,
1947                        GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
1948   done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
1949   done_msg->timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1950   GNUNET_MQ_send (mq,
1951                   env);
1952 }
1953
1954
1955 /* end of gnunet-service-core_kx.c */