-rps doxygen
[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   kx->has_excess_bandwidth = GNUNET_NO;
1440   GNUNET_MQ_send (kx->mq,
1441                   env);
1442 }
1443
1444
1445 /**
1446  * Closure for #deliver_message()
1447  */
1448 struct DeliverMessageContext
1449 {
1450
1451   /**
1452    * Key exchange context.
1453    */
1454   struct GSC_KeyExchangeInfo *kx;
1455
1456   /**
1457    * Sender of the message.
1458    */
1459   const struct GNUNET_PeerIdentity *peer;
1460 };
1461
1462
1463 /**
1464  * We received an encrypted message.  Check that it is
1465  * well-formed (size-wise).
1466  *
1467  * @param cls key exchange context for encrypting the message
1468  * @param m encrypted message
1469  * @return #GNUNET_OK if @a msg is well-formed (size-wise)
1470  */
1471 static int
1472 check_encrypted (void *cls,
1473                  const struct EncryptedMessage *m)
1474 {
1475   uint16_t size = ntohs (m->header.size) - sizeof (*m);
1476
1477   if (size < sizeof (struct GNUNET_MessageHeader))
1478   {
1479     GNUNET_break_op (0);
1480     return GNUNET_SYSERR;
1481   }
1482   return GNUNET_OK;
1483 }
1484
1485
1486 /**
1487  * We received an encrypted message.  Decrypt, validate and
1488  * pass on to the appropriate clients.
1489  *
1490  * @param cls key exchange context for encrypting the message
1491  * @param m encrypted message
1492  */
1493 static void
1494 handle_encrypted (void *cls,
1495                   const struct EncryptedMessage *m)
1496 {
1497   struct GSC_KeyExchangeInfo *kx = cls;
1498   struct EncryptedMessage *pt;  /* plaintext */
1499   struct GNUNET_HashCode ph;
1500   uint32_t snum;
1501   struct GNUNET_TIME_Absolute t;
1502   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1503   struct GNUNET_CRYPTO_AuthKey auth_key;
1504   struct DeliverMessageContext dmc;
1505   uint16_t size = ntohs (m->header.size);
1506   char buf[size] GNUNET_ALIGN;
1507
1508   if (GNUNET_CORE_KX_STATE_UP != kx->status)
1509   {
1510     GNUNET_STATISTICS_update (GSC_stats,
1511                               gettext_noop ("# DATA message dropped (out of order)"),
1512                               1,
1513                               GNUNET_NO);
1514     return;
1515   }
1516   if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value_us)
1517   {
1518     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1519                 _("Session to peer `%s' went down due to key expiration (should not happen)\n"),
1520                 GNUNET_i2s (kx->peer));
1521     GNUNET_STATISTICS_update (GSC_stats,
1522                               gettext_noop ("# sessions terminated by key expiration"),
1523                               1, GNUNET_NO);
1524     GSC_SESSIONS_end (kx->peer);
1525     if (NULL != kx->keep_alive_task)
1526     {
1527       GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1528       kx->keep_alive_task = NULL;
1529     }
1530     kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
1531     monitor_notify_all (kx);
1532     send_key (kx);
1533     return;
1534   }
1535
1536   /* validate hash */
1537   derive_auth_key (&auth_key,
1538                    &kx->decrypt_key,
1539                    m->iv_seed);
1540   GNUNET_CRYPTO_hmac (&auth_key,
1541                       &m->sequence_number,
1542                       size - ENCRYPTED_HEADER_SIZE,
1543                       &ph);
1544   if (0 != memcmp (&ph,
1545                    &m->hmac,
1546                    sizeof (struct GNUNET_HashCode)))
1547   {
1548     /* checksum failed */
1549     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1550                 "Failed checksum validation for a message from `%s'\n",
1551                 GNUNET_i2s (kx->peer));
1552     return;
1553   }
1554   derive_iv (&iv,
1555              &kx->decrypt_key,
1556              m->iv_seed,
1557              &GSC_my_identity);
1558   /* decrypt */
1559   if (GNUNET_OK !=
1560       do_decrypt (kx,
1561                   &iv,
1562                   &m->sequence_number,
1563                   &buf[ENCRYPTED_HEADER_SIZE],
1564                   size - ENCRYPTED_HEADER_SIZE))
1565     return;
1566   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1567               "Decrypted %u bytes from %s\n",
1568               (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1569               GNUNET_i2s (kx->peer));
1570   pt = (struct EncryptedMessage *) buf;
1571
1572   /* validate sequence number */
1573   snum = ntohl (pt->sequence_number);
1574   if (kx->last_sequence_number_received == snum)
1575   {
1576     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1577                 "Received duplicate message, ignoring.\n");
1578     /* duplicate, ignore */
1579     GNUNET_STATISTICS_update (GSC_stats,
1580                               gettext_noop ("# bytes dropped (duplicates)"),
1581                               size,
1582                               GNUNET_NO);
1583     return;
1584   }
1585   if ((kx->last_sequence_number_received > snum) &&
1586       (kx->last_sequence_number_received - snum > 32))
1587   {
1588     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1589                 "Received ancient out of sequence message, ignoring.\n");
1590     /* ancient out of sequence, ignore */
1591     GNUNET_STATISTICS_update (GSC_stats,
1592                               gettext_noop
1593                               ("# bytes dropped (out of sequence)"), size,
1594                               GNUNET_NO);
1595     return;
1596   }
1597   if (kx->last_sequence_number_received > snum)
1598   {
1599     unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1);
1600
1601     if ((kx->last_packets_bitmap & rotbit) != 0)
1602     {
1603       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1604                   "Received duplicate message, ignoring.\n");
1605       GNUNET_STATISTICS_update (GSC_stats,
1606                                 gettext_noop ("# bytes dropped (duplicates)"),
1607                                 size, GNUNET_NO);
1608       /* duplicate, ignore */
1609       return;
1610     }
1611     kx->last_packets_bitmap |= rotbit;
1612   }
1613   if (kx->last_sequence_number_received < snum)
1614   {
1615     unsigned int shift = (snum - kx->last_sequence_number_received);
1616
1617     if (shift >= 8 * sizeof (kx->last_packets_bitmap))
1618       kx->last_packets_bitmap = 0;
1619     else
1620       kx->last_packets_bitmap <<= shift;
1621     kx->last_sequence_number_received = snum;
1622   }
1623
1624   /* check timestamp */
1625   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
1626   if (GNUNET_TIME_absolute_get_duration (t).rel_value_us >
1627       MAX_MESSAGE_AGE.rel_value_us)
1628   {
1629     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1630                 "Message received far too old (%s). Content ignored.\n",
1631                 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (t),
1632                                                         GNUNET_YES));
1633     GNUNET_STATISTICS_update (GSC_stats,
1634                               gettext_noop
1635                               ("# bytes dropped (ancient message)"), size,
1636                               GNUNET_NO);
1637     return;
1638   }
1639
1640   /* process decrypted message(s) */
1641   update_timeout (kx);
1642   GNUNET_STATISTICS_update (GSC_stats,
1643                             gettext_noop ("# bytes of payload decrypted"),
1644                             size - sizeof (struct EncryptedMessage),
1645                             GNUNET_NO);
1646   dmc.kx = kx;
1647   dmc.peer = kx->peer;
1648   if (GNUNET_OK !=
1649       GNUNET_SERVER_mst_receive (mst,
1650                                  &dmc,
1651                                  &buf[sizeof (struct EncryptedMessage)],
1652                                  size - sizeof (struct EncryptedMessage),
1653                                  GNUNET_YES,
1654                                  GNUNET_NO))
1655     GNUNET_break_op (0);
1656 }
1657
1658
1659 /**
1660  * One of our neighbours has excess bandwidth, remember this.
1661  *
1662  * @param cls NULL
1663  * @param pid identity of the peer with excess bandwidth
1664  * @param connect_cls the `struct Neighbour`
1665  */
1666 static void
1667 handle_transport_notify_excess_bw (void *cls,
1668                                    const struct GNUNET_PeerIdentity *pid,
1669                                    void *connect_cls)
1670 {
1671   struct GSC_KeyExchangeInfo *kx = connect_cls;  
1672
1673   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1674               "Peer %s has excess bandwidth available\n",
1675               GNUNET_i2s (pid));
1676   kx->has_excess_bandwidth = GNUNET_YES;
1677   GSC_SESSIONS_solicit (pid);
1678 }
1679
1680
1681 /**
1682  * Deliver P2P message to interested clients.  Invokes send twice,
1683  * once for clients that want the full message, and once for clients
1684  * that only want the header
1685  *
1686  * @param cls always NULL
1687  * @param client who sent us the message (struct GSC_KeyExchangeInfo)
1688  * @param m the message
1689  */
1690 static int
1691 deliver_message (void *cls,
1692                  void *client,
1693                  const struct GNUNET_MessageHeader *m)
1694 {
1695   struct DeliverMessageContext *dmc = client;
1696
1697   if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
1698   {
1699     GNUNET_STATISTICS_update (GSC_stats,
1700                               gettext_noop ("# PAYLOAD dropped (out of order)"),
1701                               1,
1702                               GNUNET_NO);
1703     return GNUNET_OK;
1704   }
1705   switch (ntohs (m->type))
1706   {
1707   case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
1708   case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
1709     GSC_SESSIONS_set_typemap (dmc->peer, m);
1710     return GNUNET_OK;
1711   case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
1712     GSC_SESSIONS_confirm_typemap (dmc->peer, m);
1713     return GNUNET_OK;
1714   default:
1715     GSC_CLIENTS_deliver_message (dmc->peer,
1716                                  m,
1717                                  ntohs (m->size),
1718                                  GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
1719     GSC_CLIENTS_deliver_message (dmc->peer,
1720                                  m,
1721                                  sizeof (struct GNUNET_MessageHeader),
1722                                  GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
1723   }
1724   return GNUNET_OK;
1725 }
1726
1727
1728 /**
1729  * Setup the message that links the ephemeral key to our persistent
1730  * public key and generate the appropriate signature.
1731  */
1732 static void
1733 sign_ephemeral_key ()
1734 {
1735   current_ekm.header.size = htons (sizeof (struct EphemeralKeyMessage));
1736   current_ekm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY);
1737   current_ekm.sender_status = 0; /* to be set later */
1738   current_ekm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY);
1739   current_ekm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
1740                                     sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1741                                     sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1742                                     sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
1743                                     sizeof (struct GNUNET_PeerIdentity));
1744   current_ekm.creation_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1745   if (GNUNET_YES ==
1746       GNUNET_CONFIGURATION_get_value_yesno (GSC_cfg,
1747                                             "core",
1748                                             "USE_EPHEMERAL_KEYS"))
1749   {
1750     current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_add (REKEY_FREQUENCY,
1751                                                                                                                          REKEY_TOLERANCE)));
1752   }
1753   else
1754   {
1755     current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1756   }
1757   GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key,
1758                                       &current_ekm.ephemeral_key);
1759   current_ekm.origin_identity = GSC_my_identity;
1760   GNUNET_assert (GNUNET_OK ==
1761                  GNUNET_CRYPTO_eddsa_sign (my_private_key,
1762                                            &current_ekm.purpose,
1763                                            &current_ekm.signature));
1764 }
1765
1766
1767 /**
1768  * Task run to trigger rekeying.
1769  *
1770  * @param cls closure, NULL
1771  */
1772 static void
1773 do_rekey (void *cls)
1774 {
1775   struct GSC_KeyExchangeInfo *pos;
1776
1777   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1778                                              &do_rekey,
1779                                              NULL);
1780   if (NULL != my_ephemeral_key)
1781     GNUNET_free (my_ephemeral_key);
1782   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1783               "Rekeying\n");
1784   my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1785   GNUNET_assert (NULL != my_ephemeral_key);
1786   sign_ephemeral_key ();
1787   for (pos = kx_head; NULL != pos; pos = pos->next)
1788   {
1789     if (GNUNET_CORE_KX_STATE_UP == pos->status)
1790     {
1791       pos->status = GNUNET_CORE_KX_STATE_REKEY_SENT;
1792       monitor_notify_all (pos);
1793       derive_session_keys (pos);
1794     }
1795     if (GNUNET_CORE_KX_STATE_DOWN == pos->status)
1796     {
1797       pos->status = GNUNET_CORE_KX_STATE_KEY_SENT;
1798       monitor_notify_all (pos);
1799     }
1800     monitor_notify_all (pos);
1801     send_key (pos);
1802   }
1803 }
1804
1805
1806 /**
1807  * Initialize KX subsystem.
1808  *
1809  * @param pk private key to use for the peer
1810  * @param server the server of the CORE service
1811  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
1812  */
1813 int
1814 GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
1815              struct GNUNET_SERVER_Handle *server)
1816 {
1817   struct GNUNET_MQ_MessageHandler handlers[] = {
1818     GNUNET_MQ_hd_fixed_size (ephemeral_key,
1819                              GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY,
1820                              struct EphemeralKeyMessage,
1821                              NULL),
1822     GNUNET_MQ_hd_fixed_size (ping,
1823                              GNUNET_MESSAGE_TYPE_CORE_PING,
1824                              struct PingMessage,
1825                              NULL),
1826     GNUNET_MQ_hd_fixed_size (pong,
1827                              GNUNET_MESSAGE_TYPE_CORE_PONG,
1828                              struct PongMessage,
1829                              NULL),
1830     GNUNET_MQ_hd_var_size (encrypted,
1831                            GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE,
1832                            struct EncryptedMessage,
1833                            NULL),
1834     GNUNET_MQ_handler_end()
1835   };
1836
1837   nc = GNUNET_SERVER_notification_context_create (server,
1838                                                   1);
1839   my_private_key = pk;
1840   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1841                                       &GSC_my_identity.public_key);
1842   my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1843   if (NULL == my_ephemeral_key)
1844   {
1845     GNUNET_break (0);
1846     GNUNET_free (my_private_key);
1847     my_private_key = NULL;
1848     return GNUNET_SYSERR;
1849   }
1850   sign_ephemeral_key ();
1851   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1852                                              &do_rekey,
1853                                              NULL);
1854   mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
1855   transport 
1856     = GNUNET_TRANSPORT_core_connect (GSC_cfg,
1857                                      &GSC_my_identity,
1858                                      handlers,
1859                                      NULL,
1860                                      &handle_transport_notify_connect,
1861                                      &handle_transport_notify_disconnect,
1862                                      &handle_transport_notify_excess_bw);
1863   if (NULL == transport)
1864   {
1865     GSC_KX_done ();
1866     return GNUNET_SYSERR;
1867   }
1868   return GNUNET_OK;
1869 }
1870
1871
1872 /**
1873  * Shutdown KX subsystem.
1874  */
1875 void
1876 GSC_KX_done ()
1877 {
1878   if (NULL != transport)
1879   {
1880     GNUNET_TRANSPORT_core_disconnect (transport);
1881     transport = NULL;
1882   }
1883   if (NULL != rekey_task)
1884   {
1885     GNUNET_SCHEDULER_cancel (rekey_task);
1886     rekey_task = NULL;
1887   }
1888   if (NULL != my_ephemeral_key)
1889   {
1890     GNUNET_free (my_ephemeral_key);
1891     my_ephemeral_key = NULL;
1892   }
1893   if (NULL != my_private_key)
1894   {
1895     GNUNET_free (my_private_key);
1896     my_private_key = NULL;
1897   }
1898   if (NULL != mst)
1899   {
1900     GNUNET_SERVER_mst_destroy (mst);
1901     mst = NULL;
1902   }
1903   if (NULL != nc)
1904   {
1905     GNUNET_SERVER_notification_context_destroy (nc);
1906     nc = NULL;
1907   }
1908 }
1909
1910
1911  /**
1912  * Check how many messages are queued for the given neighbour.
1913  *
1914  * @param kxinfo data about neighbour to check
1915  * @return number of items in the message queue
1916  */
1917 unsigned int
1918 GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *kxinfo)
1919 {
1920   return GNUNET_MQ_get_length (kxinfo->mq);
1921 }
1922
1923
1924 /**
1925  * Check if the given neighbour has excess bandwidth available.
1926  *
1927  * @param target neighbour to check
1928  * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
1929  */
1930 int
1931 GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *kxinfo)
1932 {
1933   return kxinfo->has_excess_bandwidth;
1934 }
1935
1936
1937 /**
1938  * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.  For this
1939  * request type, the client does not have to have transmitted an INIT
1940  * request.  All current peers are returned, regardless of which
1941  * message types they accept.
1942  *
1943  * @param cls unused
1944  * @param client client sending the iteration request
1945  * @param message iteration request message
1946  */
1947 void
1948 GSC_KX_handle_client_monitor_peers (void *cls,
1949                                     struct GNUNET_SERVER_Client *client,
1950                                     const struct GNUNET_MessageHeader *message)
1951 {
1952   struct MonitorNotifyMessage done_msg;
1953   struct GSC_KeyExchangeInfo *kx;
1954
1955   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1956   GNUNET_SERVER_notification_context_add (nc,
1957                                           client);
1958   for (kx = kx_head; NULL != kx; kx = kx->next)
1959     monitor_notify (client, kx);
1960   done_msg.header.size = htons (sizeof (struct MonitorNotifyMessage));
1961   done_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
1962   done_msg.state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
1963   memset (&done_msg.peer,
1964           0,
1965           sizeof (struct GNUNET_PeerIdentity));
1966   done_msg.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1967   GNUNET_SERVER_notification_context_unicast (nc,
1968                                               client,
1969                                               &done_msg.header,
1970                                               GNUNET_NO);
1971 }
1972
1973
1974 /* end of gnunet-service-core_kx.c */