more information why nat tests fail
[oweals/gnunet.git] / src / core / gnunet-service-core_kx.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2013 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, 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_neighbours.h"
31 #include "gnunet-service-core_sessions.h"
32 #include "gnunet_statistics_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 'origin' asserting the validity of
91    * 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 ephemeral public key).
117    */
118   struct GNUNET_PeerIdentity origin_identity;
119
120 };
121
122
123 /**
124  * We're sending an (encrypted) PING to the other peer to check if he
125  * can decrypt.  The other peer should respond with a PONG with the
126  * same content, except this time encrypted with the receiver's key.
127  */
128 struct PingMessage
129 {
130   /**
131    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
132    */
133   struct GNUNET_MessageHeader header;
134
135   /**
136    * Seed for the IV
137    */
138   uint32_t iv_seed GNUNET_PACKED;
139
140   /**
141    * Intended target of the PING, used primarily to check
142    * that decryption actually worked.
143    */
144   struct GNUNET_PeerIdentity target;
145
146   /**
147    * Random number chosen to make reply harder.
148    */
149   uint32_t challenge GNUNET_PACKED;
150 };
151
152
153 /**
154  * Response to a PING.  Includes data from the original PING.
155  */
156 struct PongMessage
157 {
158   /**
159    * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
160    */
161   struct GNUNET_MessageHeader header;
162
163   /**
164    * Seed for the IV
165    */
166   uint32_t iv_seed GNUNET_PACKED;
167
168   /**
169    * Random number to make faking the reply harder.  Must be
170    * first field after header (this is where we start to encrypt!).
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 either #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 'sequence_number'),
205    * used to verify message integrity. Everything after this value
206    * (excluding this value itself) will be encrypted and authenticated.
207    * ENCRYPTED_HEADER_SIZE must be set to the offset of the *next* field.
208    */
209   struct GNUNET_HashCode hmac;
210
211   /**
212    * Sequence number, in network byte order.  This field
213    * must be the first encrypted/decrypted field
214    */
215   uint32_t sequence_number GNUNET_PACKED;
216
217   /**
218    * Reserved, always zero.
219    */
220   uint32_t reserved;
221
222   /**
223    * Timestamp.  Used to prevent reply of ancient messages
224    * (recent messages are caught with the sequence number).
225    */
226   struct GNUNET_TIME_AbsoluteNBO timestamp;
227
228 };
229 GNUNET_NETWORK_STRUCT_END
230
231
232 /**
233  * Number of bytes (at the beginning) of "struct EncryptedMessage"
234  * that are NOT encrypted.
235  */
236 #define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number))
237
238
239 /**
240  * State machine for our P2P encryption handshake.  Everyone starts in
241  * "DOWN", if we receive the other peer's key (other peer initiated)
242  * we start in state RECEIVED (since we will immediately send our
243  * own); otherwise we start in SENT.  If we get back a PONG from
244  * within either state, we move up to CONFIRMED (the PONG will always
245  * be sent back encrypted with the key we sent to the other peer).
246  */
247 enum KxStateMachine
248 {
249   /**
250    * No handshake yet.
251    */
252   KX_STATE_DOWN,
253
254   /**
255    * We've sent our session key.
256    */
257   KX_STATE_KEY_SENT,
258
259   /**
260    * We've received the other peers session key.
261    */
262   KX_STATE_KEY_RECEIVED,
263
264   /**
265    * The other peer has confirmed our session key + PING with a PONG
266    * message encrypted with his session key (which we got).  Key
267    * exchange is done.
268    */
269   KX_STATE_UP,
270
271   /**
272    * We're rekeying (or had a timeout), so we have sent the other peer
273    * our new ephemeral key, but we did not get a matching PONG yet.
274    * This is equivalent to being 'KX_STATE_KEY_RECEIVED', except that
275    * the session is marked as 'up' with sessions (as we don't want to
276    * drop and re-establish P2P connections simply due to rekeying).
277    */
278   KX_STATE_REKEY_SENT
279
280 };
281
282
283 /**
284  * Information about the status of a key exchange with another peer.
285  */
286 struct GSC_KeyExchangeInfo
287 {
288
289   /**
290    * DLL.
291    */
292   struct GSC_KeyExchangeInfo *next;
293
294   /**
295    * DLL.
296    */
297   struct GSC_KeyExchangeInfo *prev;
298
299   /**
300    * Identity of the peer.
301    */
302   struct GNUNET_PeerIdentity peer;
303
304   /**
305    * PING message we transmit to the other peer.
306    */
307   struct PingMessage ping;
308
309   /**
310    * Ephemeral public ECC key of the other peer.
311    */
312   struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key;
313
314   /**
315    * Key we use to encrypt our messages for the other peer
316    * (initialized by us when we do the handshake).
317    */
318   struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key;
319
320   /**
321    * Key we use to decrypt messages from the other peer
322    * (given to us by the other peer during the handshake).
323    */
324   struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key;
325
326   /**
327    * At what time did the other peer generate the decryption key?
328    */
329   struct GNUNET_TIME_Absolute foreign_key_expires;
330
331   /**
332    * When should the session time out (if there are no PONGs)?
333    */
334   struct GNUNET_TIME_Absolute timeout;
335
336   /**
337    * At what frequency are we currently re-trying SET_KEY messages?
338    */
339   struct GNUNET_TIME_Relative set_key_retry_frequency;
340
341   /**
342    * ID of task used for re-trying SET_KEY and PING message.
343    */
344   GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
345
346   /**
347    * ID of task used for sending keep-alive pings.
348    */
349   GNUNET_SCHEDULER_TaskIdentifier keep_alive_task;
350
351   /**
352    * Bit map indicating which of the 32 sequence numbers before the last
353    * were received (good for accepting out-of-order packets and
354    * estimating reliability of the connection)
355    */
356   unsigned int last_packets_bitmap;
357
358   /**
359    * last sequence number received on this connection (highest)
360    */
361   uint32_t last_sequence_number_received;
362
363   /**
364    * last sequence number transmitted
365    */
366   uint32_t last_sequence_number_sent;
367
368   /**
369    * What was our PING challenge number (for this peer)?
370    */
371   uint32_t ping_challenge;
372
373   /**
374    * What is our connection status?
375    */
376   enum KxStateMachine status;
377
378 };
379
380
381 /**
382  * Our private key.
383  */
384 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
385
386 /**
387  * Our ephemeral private key.
388  */
389 static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key;
390
391 /**
392  * Current message we send for a key exchange.
393  */
394 static struct EphemeralKeyMessage current_ekm;
395
396 /**
397  * Our message stream tokenizer (for encrypted payload).
398  */
399 static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
400
401 /**
402  * DLL head.
403  */
404 static struct GSC_KeyExchangeInfo *kx_head;
405
406 /**
407  * DLL tail.
408  */
409 static struct GSC_KeyExchangeInfo *kx_tail;
410
411 /**
412  * Task scheduled for periodic re-generation (and thus rekeying) of our
413  * ephemeral key.
414  */
415 static GNUNET_SCHEDULER_TaskIdentifier rekey_task;
416
417
418 /**
419  * Derive an authentication key from "set key" information
420  *
421  * @param akey authentication key to derive
422  * @param skey session key to use
423  * @param seed seed to use
424  */
425 static void
426 derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
427                  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed)
428 {
429   static const char ctx[] = "authentication key";
430
431   GNUNET_CRYPTO_hmac_derive_key (akey, skey,
432                                  &seed, sizeof (seed),
433                                  skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
434                                  ctx, sizeof (ctx),
435                                  NULL);
436 }
437
438
439 /**
440  * Derive an IV from packet information
441  *
442  * @param iv initialization vector to initialize
443  * @param skey session key to use
444  * @param seed seed to use
445  * @param identity identity of the other peer to use
446  */
447 static void
448 derive_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
449            const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed,
450            const struct GNUNET_PeerIdentity *identity)
451 {
452   static const char ctx[] = "initialization vector";
453
454   GNUNET_CRYPTO_symmetric_derive_iv (iv, skey, &seed, sizeof (seed),
455                                      identity,
456                                      sizeof (struct GNUNET_PeerIdentity), ctx,
457                                      sizeof (ctx), NULL);
458 }
459
460
461 /**
462  * Derive an IV from pong packet information
463  *
464  * @param iv initialization vector to initialize
465  * @param skey session key to use
466  * @param seed seed to use
467  * @param challenge nonce to use
468  * @param identity identity of the other peer to use
469  */
470 static void
471 derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
472                 const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed,
473                 uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
474 {
475   static const char ctx[] = "pong initialization vector";
476
477   GNUNET_CRYPTO_symmetric_derive_iv (iv, skey, &seed, sizeof (seed),
478                                      identity,
479                                      sizeof (struct GNUNET_PeerIdentity),
480                                      &challenge, sizeof (challenge),
481                                      ctx, sizeof (ctx),
482                                      NULL);
483 }
484
485
486 /**
487  * Derive an AES key from key material
488  *
489  * @param sender peer identity of the sender
490  * @param receiver peer identity of the sender
491  * @param key_material high entropy key material to use
492  * @param skey set to derived session key
493  */
494 static void
495 derive_aes_key (const struct GNUNET_PeerIdentity *sender,
496                 const struct GNUNET_PeerIdentity *receiver,
497                 const struct GNUNET_HashCode *key_material,
498                 struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
499 {
500   static const char ctx[] = "aes key generation vector";
501
502   GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
503                      ctx, sizeof (ctx),
504                      key_material, sizeof (struct GNUNET_HashCode),
505                      sender, sizeof (struct GNUNET_PeerIdentity),
506                      receiver, sizeof (struct GNUNET_PeerIdentity),
507                      NULL);
508 }
509
510
511 /**
512  * Encrypt size bytes from @a in and write the result to @a out.  Use the
513  * @a kx key for outbound traffic of the given neighbour.
514  *
515  * @param kx key information context
516  * @param iv initialization vector to use
517  * @param in ciphertext
518  * @param out plaintext
519  * @param size size of @a in/@a out
520  * @return #GNUNET_OK on success
521  */
522 static int
523 do_encrypt (struct GSC_KeyExchangeInfo *kx,
524             const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
525             const void *in, void *out, size_t size)
526 {
527   if (size != (uint16_t) size)
528   {
529     GNUNET_break (0);
530     return GNUNET_NO;
531   }
532   GNUNET_assert (size ==
533                  GNUNET_CRYPTO_symmetric_encrypt (in, (uint16_t) size,
534                                             &kx->encrypt_key, iv, out));
535   GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes encrypted"), size,
536                             GNUNET_NO);
537   /* the following is too sensitive to write to log files by accident,
538      so we require manual intervention to get this one... */
539 #if 0
540   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
541               "Encrypted %u bytes for `%4s' using key %u, IV %u\n",
542               (unsigned int) size, GNUNET_i2s (&kx->peer),
543               (unsigned int) kx->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv,
544                                                                            sizeof
545                                                                            (iv)));
546 #endif
547   return GNUNET_OK;
548 }
549
550
551 /**
552  * Decrypt size bytes from @a in and write the result to @a out.  Use the
553  * @a kx key for inbound traffic of the given neighbour.  This function does
554  * NOT do any integrity-checks on the result.
555  *
556  * @param kx key information context
557  * @param iv initialization vector to use
558  * @param in ciphertext
559  * @param out plaintext
560  * @param size size of @a in / @a out
561  * @return #GNUNET_OK on success
562  */
563 static int
564 do_decrypt (struct GSC_KeyExchangeInfo *kx,
565             const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
566             const void *in, void *out, size_t size)
567 {
568   if (size != (uint16_t) size)
569   {
570     GNUNET_break (0);
571     return GNUNET_NO;
572   }
573   if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
574        (kx->status != KX_STATE_REKEY_SENT) )
575   {
576     GNUNET_break_op (0);
577     return GNUNET_SYSERR;
578   }
579   if (size !=
580       GNUNET_CRYPTO_symmetric_decrypt (in, (uint16_t) size, &kx->decrypt_key, iv,
581                                  out))
582   {
583     GNUNET_break (0);
584     return GNUNET_SYSERR;
585   }
586   GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes decrypted"), size,
587                             GNUNET_NO);
588   /* the following is too sensitive to write to log files by accident,
589      so we require manual intervention to get this one... */
590 #if 0
591   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
592               "Decrypted %u bytes from `%4s' using key %u, IV %u\n",
593               (unsigned int) size, GNUNET_i2s (&kx->peer),
594               (unsigned int) kx->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv,
595                                                                            sizeof
596                                                                            (*iv)));
597 #endif
598   return GNUNET_OK;
599 }
600
601
602 /**
603  * Send our key (and encrypted PING) to the other peer.
604  *
605  * @param kx key exchange context
606  */
607 static void
608 send_key (struct GSC_KeyExchangeInfo *kx);
609
610
611 /**
612  * Task that will retry #send_key() if our previous attempt failed.
613  *
614  * @param cls our `struct GSC_KeyExchangeInfo`
615  * @param tc scheduler context
616  */
617 static void
618 set_key_retry_task (void *cls,
619                     const struct GNUNET_SCHEDULER_TaskContext *tc)
620 {
621   struct GSC_KeyExchangeInfo *kx = cls;
622
623   kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
624   kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency);
625   GNUNET_assert (KX_STATE_DOWN != kx->status);
626   send_key (kx);
627 }
628
629
630 /**
631  * Create a fresh PING message for transmission to the other peer.
632  *
633  * @param kx key exchange context to create PING for
634  */
635 static void
636 setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
637 {
638   struct PingMessage pp;
639   struct PingMessage *pm;
640   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
641
642   pm = &kx->ping;
643   pm->header.size = htons (sizeof (struct PingMessage));
644   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
645   pm->iv_seed =
646       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
647   derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, &kx->peer);
648   pp.challenge = kx->ping_challenge;
649   pp.target = kx->peer;
650   do_encrypt (kx, &iv, &pp.target, &pm->target,
651               sizeof (struct PingMessage) - ((void *) &pm->target -
652                                              (void *) pm));
653 }
654
655
656 /**
657  * Start the key exchange with the given peer.
658  *
659  * @param pid identity of the peer to do a key exchange with
660  * @return key exchange information context
661  */
662 struct GSC_KeyExchangeInfo *
663 GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
664 {
665   struct GSC_KeyExchangeInfo *kx;
666   struct GNUNET_HashCode h1;
667   struct GNUNET_HashCode h2;
668
669   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
670               "Initiating key exchange with `%s'\n",
671               GNUNET_i2s (pid));
672   GNUNET_STATISTICS_update (GSC_stats,
673                             gettext_noop ("# key exchanges initiated"), 1,
674                             GNUNET_NO);
675   kx = GNUNET_new (struct GSC_KeyExchangeInfo);
676   kx->peer = *pid;
677   kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
678   GNUNET_CONTAINER_DLL_insert (kx_head,
679                                kx_tail,
680                                kx);
681   GNUNET_CRYPTO_hash (pid, sizeof (struct GNUNET_PeerIdentity), &h1);
682   GNUNET_CRYPTO_hash (&GSC_my_identity, sizeof (struct GNUNET_PeerIdentity), &h2);
683
684   kx->status = KX_STATE_KEY_SENT;
685   if (0 < GNUNET_CRYPTO_hash_cmp (&h1,
686                                   &h2))
687   {
688     /* peer with "lower" identity starts KX, otherwise we typically end up
689        with both peers starting the exchange and transmit the 'set key'
690        message twice */
691     send_key (kx);
692   }
693   else
694   {
695     /* peer with "higher" identity starts a delayed  KX, if the "lower" peer
696      * does not start a KX since he sees no reasons to do so  */
697     kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
698                                                            &set_key_retry_task, kx);
699   }
700   return kx;
701 }
702
703
704 /**
705  * Stop key exchange with the given peer.  Clean up key material.
706  *
707  * @param kx key exchange to stop
708  */
709 void
710 GSC_KX_stop (struct GSC_KeyExchangeInfo *kx)
711 {
712   GSC_SESSIONS_end (&kx->peer);
713   GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges stopped"),
714                             1, GNUNET_NO);
715   if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
716   {
717     GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
718     kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
719   }
720   if (kx->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
721   {
722     GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
723     kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
724   }
725   GNUNET_CONTAINER_DLL_remove (kx_head,
726                                kx_tail,
727                                kx);
728   GNUNET_free (kx);
729 }
730
731
732 /**
733  * Send our PING to the other peer.
734  *
735  * @param kx key exchange context
736  */
737 static void
738 send_ping (struct GSC_KeyExchangeInfo *kx)
739 {
740   GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
741                            MIN_PING_FREQUENCY);
742 }
743
744
745 /**
746  * Derive fresh session keys from the current ephemeral keys.
747  *
748  * @param kx session to derive keys for
749  */
750 static void
751 derive_session_keys (struct GSC_KeyExchangeInfo *kx)
752 {
753   struct GNUNET_HashCode key_material;
754
755   if (GNUNET_OK !=
756       GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key,
757                               &kx->other_ephemeral_key,
758                               &key_material))
759   {
760     GNUNET_break (0);
761     return;
762   }
763   derive_aes_key (&GSC_my_identity,
764                   &kx->peer,
765                   &key_material,
766                   &kx->encrypt_key);
767   derive_aes_key (&kx->peer,
768                   &GSC_my_identity,
769                   &key_material,
770                   &kx->decrypt_key);
771   memset (&key_material, 0, sizeof (key_material));
772   /* fresh key, reset sequence numbers */
773   kx->last_sequence_number_received = 0;
774   kx->last_packets_bitmap = 0;
775   setup_fresh_ping (kx);
776 }
777
778
779 /**
780  * We received a SET_KEY message.  Validate and update
781  * our key material and status.
782  *
783  * @param kx key exchange status for the corresponding peer
784  * @param msg the set key message we received
785  */
786 void
787 GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
788                              const struct GNUNET_MessageHeader *msg)
789 {
790   const struct EphemeralKeyMessage *m;
791   struct GNUNET_TIME_Absolute start_t;
792   struct GNUNET_TIME_Absolute end_t;
793   struct GNUNET_TIME_Absolute now;
794   enum KxStateMachine sender_status;
795   uint16_t size;
796
797   size = ntohs (msg->size);
798   if (sizeof (struct EphemeralKeyMessage) != size)
799   {
800     GNUNET_break_op (0);
801     return;
802   }
803   m = (const struct EphemeralKeyMessage *) msg;
804   end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time);
805   if ( ( (KX_STATE_KEY_RECEIVED == kx->status) ||
806          (KX_STATE_UP == kx->status) ||
807          (KX_STATE_REKEY_SENT == kx->status) ) &&
808        (end_t.abs_value_us <= kx->foreign_key_expires.abs_value_us) )
809   {
810     GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# old ephemeral keys ignored"),
811                               1, GNUNET_NO);
812     return;
813   }
814   start_t = GNUNET_TIME_absolute_ntoh (m->creation_time);
815
816   GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# ephemeral keys received"),
817                             1, GNUNET_NO);
818
819   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
820               "Core service receives `%s' request from `%4s'.\n", "EPHEMERAL_KEY",
821               GNUNET_i2s (&kx->peer));
822   if (0 !=
823       memcmp (&m->origin_identity,
824               &kx->peer.public_key,
825               sizeof (struct GNUNET_PeerIdentity)))
826   {
827     GNUNET_break_op (0);
828     return;
829   }
830   if ((ntohl (m->purpose.size) !=
831        sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
832        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
833        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
834        sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) +
835        sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) ||
836       (GNUNET_OK !=
837        GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY,
838                                  &m->purpose,
839                                  &m->signature, &m->origin_identity.public_key)))
840   {
841     /* invalid signature */
842     GNUNET_break_op (0);
843     return;
844   }
845   now = GNUNET_TIME_absolute_get ();
846   if ( (end_t.abs_value_us < GNUNET_TIME_absolute_subtract (now, REKEY_TOLERANCE).abs_value_us) ||
847        (start_t.abs_value_us > GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us) )
848   {
849     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
850                 _("Ephemeral key message from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
851                 GNUNET_i2s (&kx->peer),
852                 now.abs_value_us,
853                 start_t.abs_value_us,
854                 end_t.abs_value_us);
855     return;
856   }
857   kx->other_ephemeral_key = m->ephemeral_key;
858   kx->foreign_key_expires = end_t;
859   derive_session_keys (kx);
860   GNUNET_STATISTICS_update (GSC_stats,
861                             gettext_noop ("# EPHEMERAL_KEY messages received"), 1,
862                             GNUNET_NO);
863
864   /* check if we still need to send the sender our key */
865   sender_status = (enum KxStateMachine) ntohl (m->sender_status);
866   switch (sender_status)
867   {
868   case KX_STATE_DOWN:
869     GNUNET_break_op (0);
870     break;
871   case KX_STATE_KEY_SENT:
872     /* fine, need to send our key after updating our status, see below */
873     break;
874   case KX_STATE_KEY_RECEIVED:
875   case KX_STATE_UP:
876   case KX_STATE_REKEY_SENT:
877     /* other peer already got our key */
878     break;
879   default:
880     GNUNET_break (0);
881     break;
882   }
883   /* check if we need to confirm everything is fine via PING + PONG */
884   switch (kx->status)
885   {
886   case KX_STATE_DOWN:
887     GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
888     kx->status = KX_STATE_KEY_RECEIVED;
889     if (KX_STATE_KEY_SENT == sender_status)
890       send_key (kx);
891     send_ping (kx);
892     break;
893   case KX_STATE_KEY_SENT:
894     GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
895     kx->status = KX_STATE_KEY_RECEIVED;
896     if (KX_STATE_KEY_SENT == sender_status)
897       send_key (kx);
898     send_ping (kx);
899     break;
900   case KX_STATE_KEY_RECEIVED:
901     GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
902     if (KX_STATE_KEY_SENT == sender_status)
903       send_key (kx);
904     send_ping (kx);
905     break;
906   case KX_STATE_UP:
907     kx->status = KX_STATE_REKEY_SENT;
908     if (KX_STATE_KEY_SENT == sender_status)
909       send_key (kx);
910     /* we got a new key, need to reconfirm! */
911     send_ping (kx);
912     break;
913   case KX_STATE_REKEY_SENT:
914     if (KX_STATE_KEY_SENT == sender_status)
915       send_key (kx);
916     /* we got a new key, need to reconfirm! */
917     send_ping (kx);
918     break;
919   default:
920     GNUNET_break (0);
921     break;
922   }
923 }
924
925
926 /**
927  * We received a PING message.  Validate and transmit
928  * a PONG message.
929  *
930  * @param kx key exchange status for the corresponding peer
931  * @param msg the encrypted PING message itself
932  */
933 void
934 GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
935                     const struct GNUNET_MessageHeader *msg)
936 {
937   const struct PingMessage *m;
938   struct PingMessage t;
939   struct PongMessage tx;
940   struct PongMessage tp;
941   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
942   uint16_t msize;
943
944   msize = ntohs (msg->size);
945   if (msize != sizeof (struct PingMessage))
946   {
947     GNUNET_break_op (0);
948     return;
949   }
950   GNUNET_STATISTICS_update (GSC_stats,
951                             gettext_noop ("# PING messages received"), 1,
952                             GNUNET_NO);
953   if ( (kx->status != KX_STATE_KEY_RECEIVED) &&
954        (kx->status != KX_STATE_UP) &&
955        (kx->status != KX_STATE_REKEY_SENT))
956   {
957     /* ignore */
958     GNUNET_STATISTICS_update (GSC_stats,
959                               gettext_noop ("# PING messages dropped (out of order)"), 1,
960                               GNUNET_NO);
961     return;
962   }
963   m = (const struct PingMessage *) msg;
964   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
965               "Core service receives `%s' request from `%4s'.\n", "PING",
966               GNUNET_i2s (&kx->peer));
967   derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
968   if (GNUNET_OK !=
969       do_decrypt (kx, &iv, &m->target, &t.target,
970                   sizeof (struct PingMessage) - ((void *) &m->target -
971                                                  (void *) m)))
972   {
973     GNUNET_break_op (0);
974     return;
975   }
976   if (0 !=
977       memcmp (&t.target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
978   {
979     char sender[9];
980     char peer[9];
981
982     GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&kx->peer));
983     GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target));
984     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
985                 _
986                 ("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"),
987                 sender, GNUNET_i2s (&GSC_my_identity), peer);
988     GNUNET_break_op (0);
989     return;
990   }
991   /* construct PONG */
992   tx.reserved = 0;
993   tx.challenge = t.challenge;
994   tx.target = t.target;
995   tp.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
996   tp.header.size = htons (sizeof (struct PongMessage));
997   tp.iv_seed =
998       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
999   derive_pong_iv (&iv, &kx->encrypt_key, tp.iv_seed, t.challenge, &kx->peer);
1000   do_encrypt (kx, &iv, &tx.challenge, &tp.challenge,
1001               sizeof (struct PongMessage) - ((void *) &tp.challenge -
1002                                              (void *) &tp));
1003   GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# PONG messages created"),
1004                             1, GNUNET_NO);
1005   GSC_NEIGHBOURS_transmit (&kx->peer, &tp.header,
1006                            GNUNET_TIME_UNIT_FOREVER_REL /* FIXME: timeout */ );
1007 }
1008
1009
1010 /**
1011  * Task triggered when a neighbour entry is about to time out
1012  * (and we should prevent this by sending a PING).
1013  *
1014  * @param cls the 'struct GSC_KeyExchangeInfo'
1015  * @param tc scheduler context (not used)
1016  */
1017 static void
1018 send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1019 {
1020   struct GSC_KeyExchangeInfo *kx = cls;
1021   struct GNUNET_TIME_Relative retry;
1022   struct GNUNET_TIME_Relative left;
1023
1024   kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
1025   left = GNUNET_TIME_absolute_get_remaining (kx->timeout);
1026   if (0 == left.rel_value_us)
1027   {
1028     GNUNET_STATISTICS_update (GSC_stats,
1029                               gettext_noop ("# sessions terminated by timeout"),
1030                               1, GNUNET_NO);
1031     GSC_SESSIONS_end (&kx->peer);
1032     kx->status = KX_STATE_KEY_SENT;
1033     send_key (kx);
1034     return;
1035   }
1036   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending KEEPALIVE to `%s'\n",
1037               GNUNET_i2s (&kx->peer));
1038   GNUNET_STATISTICS_update (GSC_stats,
1039                             gettext_noop ("# keepalive messages sent"), 1,
1040                             GNUNET_NO);
1041   setup_fresh_ping (kx);
1042   GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
1043                            kx->set_key_retry_frequency);
1044   retry =
1045       GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2),
1046                                 MIN_PING_FREQUENCY);
1047   kx->keep_alive_task =
1048       GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, kx);
1049 }
1050
1051
1052 /**
1053  * We've seen a valid message from the other peer.
1054  * Update the time when the session would time out
1055  * and delay sending our keep alive message further.
1056  *
1057  * @param kx key exchange where we saw activity
1058  */
1059 static void
1060 update_timeout (struct GSC_KeyExchangeInfo *kx)
1061 {
1062   kx->timeout =
1063       GNUNET_TIME_relative_to_absolute
1064       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1065   if (kx->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
1066     GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1067   kx->keep_alive_task =
1068       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
1069                                     (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1070                                      2), &send_keep_alive, kx);
1071 }
1072
1073
1074 /**
1075  * We received a PONG message.  Validate and update our status.
1076  *
1077  * @param kx key exchange context for the the PONG
1078  * @param msg the encrypted PONG message itself
1079  */
1080 void
1081 GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1082                     const struct GNUNET_MessageHeader *msg)
1083 {
1084   const struct PongMessage *m;
1085   struct PongMessage t;
1086   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1087   uint16_t msize;
1088
1089   msize = ntohs (msg->size);
1090   if (sizeof (struct PongMessage) != msize)
1091   {
1092     GNUNET_break_op (0);
1093     return;
1094   }
1095   GNUNET_STATISTICS_update (GSC_stats,
1096                             gettext_noop ("# PONG messages received"), 1,
1097                             GNUNET_NO);
1098   switch (kx->status)
1099   {
1100   case KX_STATE_DOWN:
1101     GNUNET_STATISTICS_update (GSC_stats,
1102                               gettext_noop ("# PONG messages dropped (connection down)"), 1,
1103                               GNUNET_NO);
1104     return;
1105   case KX_STATE_KEY_SENT:
1106     GNUNET_STATISTICS_update (GSC_stats,
1107                               gettext_noop ("# PONG messages dropped (out of order)"), 1,
1108                               GNUNET_NO);
1109     return;
1110   case KX_STATE_KEY_RECEIVED:
1111     break;
1112   case KX_STATE_UP:
1113     break;
1114   case KX_STATE_REKEY_SENT:
1115     break;
1116   default:
1117     GNUNET_break (0);
1118     return;
1119   }
1120   m = (const struct PongMessage *) msg;
1121   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1122               "Core service receives `%s' response from `%4s'.\n", "PONG",
1123               GNUNET_i2s (&kx->peer));
1124   /* mark as garbage, just to be sure */
1125   memset (&t, 255, sizeof (t));
1126   derive_pong_iv (&iv, &kx->decrypt_key, m->iv_seed, kx->ping_challenge,
1127                   &GSC_my_identity);
1128   if (GNUNET_OK !=
1129       do_decrypt (kx, &iv, &m->challenge, &t.challenge,
1130                   sizeof (struct PongMessage) - ((void *) &m->challenge -
1131                                                  (void *) m)))
1132   {
1133     GNUNET_break_op (0);
1134     return;
1135   }
1136   GNUNET_STATISTICS_update (GSC_stats,
1137                             gettext_noop ("# PONG messages decrypted"), 1,
1138                             GNUNET_NO);
1139   if ((0 != memcmp (&t.target, &kx->peer, sizeof (struct GNUNET_PeerIdentity)))
1140       || (kx->ping_challenge != t.challenge))
1141   {
1142     /* PONG malformed */
1143     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1144                 "Received malformed `%s' wanted sender `%4s' with challenge %u\n",
1145                 "PONG", GNUNET_i2s (&kx->peer),
1146                 (unsigned int) kx->ping_challenge);
1147     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1148                 "Received malformed `%s' received from `%4s' with challenge %u\n",
1149                 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge);
1150     return;
1151   }
1152   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n",
1153               GNUNET_i2s (&kx->peer));
1154   /* no need to resend key any longer */
1155   if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
1156   {
1157     GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1158     kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
1159   }
1160   switch (kx->status)
1161   {
1162   case KX_STATE_DOWN:
1163     GNUNET_assert (0);           /* should be impossible */
1164     return;
1165   case KX_STATE_KEY_SENT:
1166     GNUNET_assert (0);           /* should be impossible */
1167     return;
1168   case KX_STATE_KEY_RECEIVED:
1169     GNUNET_STATISTICS_update (GSC_stats,
1170                               gettext_noop
1171                               ("# session keys confirmed via PONG"), 1,
1172                               GNUNET_NO);
1173     kx->status = KX_STATE_UP;
1174     GSC_SESSIONS_create (&kx->peer, kx);
1175     GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
1176     update_timeout (kx);
1177     break;
1178   case KX_STATE_UP:
1179     GNUNET_STATISTICS_update (GSC_stats,
1180                               gettext_noop
1181                               ("# timeouts prevented via PONG"), 1,
1182                               GNUNET_NO);
1183     update_timeout (kx);
1184     break;
1185   case KX_STATE_REKEY_SENT:
1186     GNUNET_STATISTICS_update (GSC_stats,
1187                               gettext_noop
1188                               ("# rekey operations confirmed via PONG"), 1,
1189                               GNUNET_NO);
1190     kx->status = KX_STATE_UP;
1191     update_timeout (kx);
1192     break;
1193   default:
1194     GNUNET_break (0);
1195     break;
1196   }
1197 }
1198
1199
1200 /**
1201  * Send our key to the other peer.
1202  *
1203  * @param kx key exchange context
1204  */
1205 static void
1206 send_key (struct GSC_KeyExchangeInfo *kx)
1207 {
1208   GNUNET_assert (KX_STATE_DOWN != kx->status);
1209   if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
1210   {
1211      GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1212      kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
1213   }
1214   /* always update sender status in SET KEY message */
1215   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1216               "Sending key to `%s' (my status: %d)\n",
1217               GNUNET_i2s (&kx->peer),
1218               kx->status);
1219   current_ekm.sender_status = htonl ((int32_t) (kx->status));
1220   GSC_NEIGHBOURS_transmit (&kx->peer, &current_ekm.header,
1221                            kx->set_key_retry_frequency);
1222   kx->retry_set_key_task =
1223       GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
1224                                     &set_key_retry_task, kx);
1225 }
1226
1227
1228 /**
1229  * Encrypt and transmit a message with the given payload.
1230  *
1231  * @param kx key exchange context
1232  * @param payload payload of the message
1233  * @param payload_size number of bytes in 'payload'
1234  */
1235 void
1236 GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1237                              const void *payload, size_t payload_size)
1238 {
1239   size_t used = payload_size + sizeof (struct EncryptedMessage);
1240   char pbuf[used];              /* plaintext */
1241   char cbuf[used];              /* ciphertext */
1242   struct EncryptedMessage *em;  /* encrypted message */
1243   struct EncryptedMessage *ph;  /* plaintext header */
1244   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1245   struct GNUNET_CRYPTO_AuthKey auth_key;
1246
1247   ph = (struct EncryptedMessage *) pbuf;
1248   ph->iv_seed =
1249       htonl (GNUNET_CRYPTO_random_u32
1250              (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
1251   ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1252   ph->reserved = 0;
1253   ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1254   memcpy (&ph[1], payload, payload_size);
1255
1256   em = (struct EncryptedMessage *) cbuf;
1257   em->header.size = htons (used);
1258   em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1259   em->iv_seed = ph->iv_seed;
1260   derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, &kx->peer);
1261   GNUNET_assert (GNUNET_OK ==
1262                  do_encrypt (kx, &iv, &ph->sequence_number,
1263                              &em->sequence_number,
1264                              used - ENCRYPTED_HEADER_SIZE));
1265   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n",
1266               used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer));
1267   derive_auth_key (&auth_key,
1268                    &kx->encrypt_key,
1269                    ph->iv_seed);
1270   GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
1271                       used - ENCRYPTED_HEADER_SIZE, &em->hmac);
1272   GSC_NEIGHBOURS_transmit (&kx->peer, &em->header,
1273                            GNUNET_TIME_UNIT_FOREVER_REL);
1274 }
1275
1276
1277 /**
1278  * Closure for #deliver_message()
1279  */
1280 struct DeliverMessageContext
1281 {
1282
1283   /**
1284    * Key exchange context.
1285    */
1286   struct GSC_KeyExchangeInfo *kx;
1287
1288   /**
1289    * Sender of the message.
1290    */
1291   const struct GNUNET_PeerIdentity *peer;
1292 };
1293
1294
1295 /**
1296  * We received an encrypted message.  Decrypt, validate and
1297  * pass on to the appropriate clients.
1298  *
1299  * @param kx key exchange context for encrypting the message
1300  * @param msg encrypted message
1301  */
1302 void
1303 GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1304                                  const struct GNUNET_MessageHeader *msg)
1305 {
1306   const struct EncryptedMessage *m;
1307   struct EncryptedMessage *pt;  /* plaintext */
1308   struct GNUNET_HashCode ph;
1309   uint32_t snum;
1310   struct GNUNET_TIME_Absolute t;
1311   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1312   struct GNUNET_CRYPTO_AuthKey auth_key;
1313   struct DeliverMessageContext dmc;
1314   uint16_t size = ntohs (msg->size);
1315   char buf[size] GNUNET_ALIGN;
1316
1317   if (size <
1318       sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
1319   {
1320     GNUNET_break_op (0);
1321     return;
1322   }
1323   m = (const struct EncryptedMessage *) msg;
1324   if (KX_STATE_UP != kx->status)
1325   {
1326     GNUNET_STATISTICS_update (GSC_stats,
1327                               gettext_noop
1328                               ("# DATA message dropped (out of order)"),
1329                               1, GNUNET_NO);
1330     return;
1331   }
1332   if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value_us)
1333   {
1334     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1335                 _("Session to peer `%s' went down due to key expiration (should not happen)\n"),
1336                 GNUNET_i2s (&kx->peer));
1337     GNUNET_STATISTICS_update (GSC_stats,
1338                               gettext_noop ("# sessions terminated by key expiration"),
1339                               1, GNUNET_NO);
1340     GSC_SESSIONS_end (&kx->peer);
1341     if (GNUNET_SCHEDULER_NO_TASK != kx->keep_alive_task)
1342     {
1343       GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1344       kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
1345     }
1346     kx->status = KX_STATE_KEY_SENT;
1347     send_key (kx);
1348     return;
1349   }
1350
1351   /* validate hash */
1352   derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed);
1353   GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number,
1354                       size - ENCRYPTED_HEADER_SIZE, &ph);
1355   if (0 != memcmp (&ph, &m->hmac, sizeof (struct GNUNET_HashCode)))
1356   {
1357     /* checksum failed */
1358     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1359                 "Failed checksum validation for a message from `%s'\n",
1360                 GNUNET_i2s (&kx->peer));
1361     return;
1362   }
1363   derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1364   /* decrypt */
1365   if (GNUNET_OK !=
1366       do_decrypt (kx, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE],
1367                   size - ENCRYPTED_HEADER_SIZE))
1368     return;
1369   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1370               "Decrypted %u bytes from %s\n",
1371               size - ENCRYPTED_HEADER_SIZE,
1372               GNUNET_i2s (&kx->peer));
1373   pt = (struct EncryptedMessage *) buf;
1374
1375   /* validate sequence number */
1376   snum = ntohl (pt->sequence_number);
1377   if (kx->last_sequence_number_received == snum)
1378   {
1379     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1380                 "Received duplicate message, ignoring.\n");
1381     /* duplicate, ignore */
1382     GNUNET_STATISTICS_update (GSC_stats,
1383                               gettext_noop ("# bytes dropped (duplicates)"),
1384                               size, GNUNET_NO);
1385     return;
1386   }
1387   if ((kx->last_sequence_number_received > snum) &&
1388       (kx->last_sequence_number_received - snum > 32))
1389   {
1390     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1391                 "Received ancient out of sequence message, ignoring.\n");
1392     /* ancient out of sequence, ignore */
1393     GNUNET_STATISTICS_update (GSC_stats,
1394                               gettext_noop
1395                               ("# bytes dropped (out of sequence)"), size,
1396                               GNUNET_NO);
1397     return;
1398   }
1399   if (kx->last_sequence_number_received > snum)
1400   {
1401     unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1);
1402
1403     if ((kx->last_packets_bitmap & rotbit) != 0)
1404     {
1405       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1406                   "Received duplicate message, ignoring.\n");
1407       GNUNET_STATISTICS_update (GSC_stats,
1408                                 gettext_noop ("# bytes dropped (duplicates)"),
1409                                 size, GNUNET_NO);
1410       /* duplicate, ignore */
1411       return;
1412     }
1413     kx->last_packets_bitmap |= rotbit;
1414   }
1415   if (kx->last_sequence_number_received < snum)
1416   {
1417     unsigned int shift = (snum - kx->last_sequence_number_received);
1418
1419     if (shift >= 8 * sizeof (kx->last_packets_bitmap))
1420       kx->last_packets_bitmap = 0;
1421     else
1422       kx->last_packets_bitmap <<= shift;
1423     kx->last_sequence_number_received = snum;
1424   }
1425
1426   /* check timestamp */
1427   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
1428   if (GNUNET_TIME_absolute_get_duration (t).rel_value_us >
1429       MAX_MESSAGE_AGE.rel_value_us)
1430   {
1431     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1432                 "Message received far too old (%s). Content ignored.\n",
1433                 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (t),
1434                                                         GNUNET_YES));
1435     GNUNET_STATISTICS_update (GSC_stats,
1436                               gettext_noop
1437                               ("# bytes dropped (ancient message)"), size,
1438                               GNUNET_NO);
1439     return;
1440   }
1441
1442   /* process decrypted message(s) */
1443   update_timeout (kx);
1444   GNUNET_STATISTICS_update (GSC_stats,
1445                             gettext_noop ("# bytes of payload decrypted"),
1446                             size - sizeof (struct EncryptedMessage),
1447                             GNUNET_NO);
1448   dmc.kx = kx;
1449   dmc.peer = &kx->peer;
1450   if (GNUNET_OK !=
1451       GNUNET_SERVER_mst_receive (mst, &dmc,
1452                                  &buf[sizeof (struct EncryptedMessage)],
1453                                  size - sizeof (struct EncryptedMessage),
1454                                  GNUNET_YES,
1455                                  GNUNET_NO))
1456     GNUNET_break_op (0);
1457 }
1458
1459
1460 /**
1461  * Deliver P2P message to interested clients.
1462  * Invokes send twice, once for clients that want the full message, and once
1463  * for clients that only want the header
1464  *
1465  * @param cls always NULL
1466  * @param client who sent us the message (struct GSC_KeyExchangeInfo)
1467  * @param m the message
1468  */
1469 static int
1470 deliver_message (void *cls,
1471                  void *client,
1472                  const struct GNUNET_MessageHeader *m)
1473 {
1474   struct DeliverMessageContext *dmc = client;
1475
1476   if (KX_STATE_UP != dmc->kx->status)
1477   {
1478     GNUNET_STATISTICS_update (GSC_stats,
1479                               gettext_noop
1480                               ("# PAYLOAD dropped (out of order)"),
1481                               1, GNUNET_NO);
1482     return GNUNET_OK;
1483   }
1484   switch (ntohs (m->type))
1485   {
1486   case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
1487   case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
1488     GSC_SESSIONS_set_typemap (dmc->peer, m);
1489     return GNUNET_OK;
1490   default:
1491     GSC_CLIENTS_deliver_message (dmc->peer, m,
1492                                  ntohs (m->size),
1493                                  GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
1494     GSC_CLIENTS_deliver_message (dmc->peer, m,
1495                                  sizeof (struct GNUNET_MessageHeader),
1496                                  GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
1497   }
1498   return GNUNET_OK;
1499 }
1500
1501
1502 /**
1503  * Setup the message that links the ephemeral key to our persistent
1504  * public key and generate the appropriate signature.
1505  */
1506 static void
1507 sign_ephemeral_key ()
1508 {
1509   current_ekm.header.size = htons (sizeof (struct EphemeralKeyMessage));
1510   current_ekm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY);
1511   current_ekm.sender_status = 0; /* to be set later */
1512   current_ekm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY);
1513   current_ekm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
1514                                     sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1515                                     sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1516                                     sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
1517                                     sizeof (struct GNUNET_PeerIdentity));
1518   current_ekm.creation_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1519   if (GNUNET_YES ==
1520       GNUNET_CONFIGURATION_get_value_yesno (GSC_cfg,
1521                                             "core",
1522                                             "USE_EPHEMERAL_KEYS"))
1523   {
1524     current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_add (REKEY_FREQUENCY,
1525                                                                                                                          REKEY_TOLERANCE)));
1526   }
1527   else
1528   {
1529     current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1530   }
1531   GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key,
1532                                       &current_ekm.ephemeral_key);
1533   current_ekm.origin_identity = GSC_my_identity;
1534   GNUNET_assert (GNUNET_OK ==
1535                  GNUNET_CRYPTO_eddsa_sign (my_private_key,
1536                                          &current_ekm.purpose,
1537                                          &current_ekm.signature));
1538 }
1539
1540
1541 /**
1542  * Task run to trigger rekeying.
1543  *
1544  * @param cls closure, NULL
1545  * @param tc scheduler context
1546  */
1547 static void
1548 do_rekey (void *cls,
1549           const struct GNUNET_SCHEDULER_TaskContext *tc)
1550 {
1551   struct GSC_KeyExchangeInfo *pos;
1552
1553   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1554                                              &do_rekey,
1555                                              NULL);
1556   if (NULL != my_ephemeral_key)
1557     GNUNET_free (my_ephemeral_key);
1558   my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1559   GNUNET_assert (NULL != my_ephemeral_key);
1560   sign_ephemeral_key ();
1561   for (pos = kx_head; NULL != pos; pos = pos->next)
1562   {
1563     if (KX_STATE_UP == pos->status)
1564     {
1565       pos->status = KX_STATE_REKEY_SENT;
1566       derive_session_keys (pos);
1567     }
1568     if (KX_STATE_DOWN == pos->status)
1569     {
1570       pos->status = KX_STATE_KEY_SENT;
1571     }
1572     send_key (pos);
1573   }
1574 }
1575
1576
1577 /**
1578  * Initialize KX subsystem.
1579  *
1580  * @param pk private key to use for the peer
1581  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
1582  */
1583 int
1584 GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
1585 {
1586   my_private_key = pk;
1587   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1588                                                   &GSC_my_identity.public_key);
1589   my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1590   if (NULL == my_ephemeral_key)
1591   {
1592     GNUNET_break (0);
1593     GNUNET_free (my_private_key);
1594     my_private_key = NULL;
1595     return GNUNET_SYSERR;
1596   }
1597   sign_ephemeral_key ();
1598   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1599                                              &do_rekey,
1600                                              NULL);
1601   mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
1602   return GNUNET_OK;
1603 }
1604
1605
1606 /**
1607  * Shutdown KX subsystem.
1608  */
1609 void
1610 GSC_KX_done ()
1611 {
1612   if (GNUNET_SCHEDULER_NO_TASK != rekey_task)
1613   {
1614     GNUNET_SCHEDULER_cancel (rekey_task);
1615     rekey_task = GNUNET_SCHEDULER_NO_TASK;
1616   }
1617   if (NULL != my_ephemeral_key)
1618   {
1619     GNUNET_free (my_ephemeral_key);
1620     my_ephemeral_key = NULL;
1621   }
1622   if (NULL != my_private_key)
1623   {
1624     GNUNET_free (my_private_key);
1625     my_private_key = NULL;
1626   }
1627   if (NULL != mst)
1628   {
1629     GNUNET_SERVER_mst_destroy (mst);
1630     mst = NULL;
1631   }
1632 }
1633
1634 /* end of gnunet-service-core_kx.c */