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