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