aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-02-05 20:49:21 +0000
committerChristian Grothoff <christian@grothoff.org>2013-02-05 20:49:21 +0000
commitca35f67faee8371fa763bdf49f04a8d5d4cdc021 (patch)
tree5535df5e5a2428ed838c6a0e60b2c6c68a7842c5 /src/core
parentdd7cca21c5dbaef4d56f92bab3932f0f73d092d1 (diff)
downloadgnunet-ca35f67faee8371fa763bdf49f04a8d5d4cdc021.tar.gz
gnunet-ca35f67faee8371fa763bdf49f04a8d5d4cdc021.zip
switching to ECDHE cryptography f, implementation is incomplete and INSECURE, do not use for anything but testing
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Makefile.am2
-rw-r--r--src/core/gnunet-service-core.c12
-rw-r--r--src/core/gnunet-service-core_kx.c963
-rw-r--r--src/core/gnunet-service-core_kx.h8
-rw-r--r--src/core/gnunet-service-core_neighbours.c4
5 files changed, 396 insertions, 593 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 6d073da1f..a3ef13f5a 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -46,8 +46,6 @@ gnunet_service_core_SOURCES = \
46 gnunet-service-core_sessions.c gnunet-service-core_sessions.h \ 46 gnunet-service-core_sessions.c gnunet-service-core_sessions.h \
47 gnunet-service-core_typemap.c gnunet-service-core_typemap.h 47 gnunet-service-core_typemap.c gnunet-service-core_typemap.h
48gnunet_service_core_LDADD = \ 48gnunet_service_core_LDADD = \
49 $(top_builddir)/src/hello/libgnunethello.la \
50 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
51 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 49 $(top_builddir)/src/statistics/libgnunetstatistics.la \
52 $(top_builddir)/src/transport/libgnunettransport.la \ 50 $(top_builddir)/src/transport/libgnunettransport.la \
53 $(top_builddir)/src/util/libgnunetutil.la \ 51 $(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 095e12405..2be833fa0 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -56,7 +56,7 @@ static struct GNUNET_SERVER_Handle *GSC_server;
56/** 56/**
57 * Hostkey generation context 57 * Hostkey generation context
58 */ 58 */
59static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen; 59static struct GNUNET_CRYPTO_EccKeyGenerationContext *keygen;
60 60
61 61
62/** 62/**
@@ -72,7 +72,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
72 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n"); 72 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
73 if (NULL != keygen) 73 if (NULL != keygen)
74 { 74 {
75 GNUNET_CRYPTO_rsa_key_create_stop (keygen); 75 GNUNET_CRYPTO_ecc_key_create_stop (keygen);
76 keygen = NULL; 76 keygen = NULL;
77 } 77 }
78 GSC_CLIENTS_done (); 78 GSC_CLIENTS_done ();
@@ -99,14 +99,14 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
99 */ 99 */
100static void 100static void
101key_generation_cb (void *cls, 101key_generation_cb (void *cls,
102 struct GNUNET_CRYPTO_RsaPrivateKey *pk, 102 struct GNUNET_CRYPTO_EccPrivateKey *pk,
103 const char *emsg) 103 const char *emsg)
104{ 104{
105 keygen = NULL; 105 keygen = NULL;
106 if (NULL == pk) 106 if (NULL == pk)
107 { 107 {
108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
109 _("Failed to read hostkey: %s\n"), 109 _("Failed to read or generate private key: %s\n"),
110 emsg); 110 emsg);
111 GNUNET_SCHEDULER_shutdown (); 111 GNUNET_SCHEDULER_shutdown ();
112 return; 112 return;
@@ -141,7 +141,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
141 GSC_cfg = c; 141 GSC_cfg = c;
142 GSC_server = server; 142 GSC_server = server;
143 if (GNUNET_OK != 143 if (GNUNET_OK !=
144 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY", 144 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "PEER", "PRIVATE_KEY",
145 &keyfile)) 145 &keyfile))
146 { 146 {
147 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 147 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -155,7 +155,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
155 NULL); 155 NULL);
156 GNUNET_SERVER_suspend (server); 156 GNUNET_SERVER_suspend (server);
157 GSC_TYPEMAP_init (); 157 GSC_TYPEMAP_init ();
158 keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL); 158 keygen = GNUNET_CRYPTO_ecc_key_create_start (keyfile, &key_generation_cb, NULL);
159 GNUNET_free (keyfile); 159 GNUNET_free (keyfile);
160 if (NULL == keygen) 160 if (NULL == keygen)
161 { 161 {
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index b2fc2a971..f7fbfcf68 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -30,8 +30,6 @@
30#include "gnunet-service-core_neighbours.h" 30#include "gnunet-service-core_neighbours.h"
31#include "gnunet-service-core_sessions.h" 31#include "gnunet-service-core_sessions.h"
32#include "gnunet_statistics_service.h" 32#include "gnunet_statistics_service.h"
33#include "gnunet_peerinfo_service.h"
34#include "gnunet_hello_lib.h"
35#include "gnunet_constants.h" 33#include "gnunet_constants.h"
36#include "gnunet_signatures.h" 34#include "gnunet_signatures.h"
37#include "gnunet_protocols.h" 35#include "gnunet_protocols.h"
@@ -39,14 +37,9 @@
39 37
40 38
41/** 39/**
42 * Set to GNUNET_YES to perform some slightly expensive internal invariant checks.
43 */
44#define EXTRA_CHECKS GNUNET_YES
45
46/**
47 * How long do we wait for SET_KEY confirmation initially? 40 * How long do we wait for SET_KEY confirmation initially?
48 */ 41 */
49#define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 1) 42#define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
50 43
51/** 44/**
52 * What is the minimum frequency for a PING message? 45 * What is the minimum frequency for a PING message?
@@ -56,8 +49,12 @@
56/** 49/**
57 * How often do we rekey? 50 * How often do we rekey?
58 */ 51 */
59#define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 90) 52#define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
60 53
54/**
55 * What time difference do we tolerate?
56 */
57#define REKEY_TOLERANCE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
61 58
62/** 59/**
63 * What is the maximum age of a message for us to consider processing 60 * What is the maximum age of a message for us to consider processing
@@ -68,13 +65,61 @@
68 */ 65 */
69#define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS 66#define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
70 67
68
69
70GNUNET_NETWORK_STRUCT_BEGIN
71
71/** 72/**
72 * What is the maximum delay for a SET_KEY message? 73 * Message transmitted with the signed ephemeral key of a peer. The
74 * session key is then derived from the two ephemeral keys (ECDHE).
73 */ 75 */
74#define MAX_SET_KEY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 76struct 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;
75 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};
76 122
77GNUNET_NETWORK_STRUCT_BEGIN
78 123
79/** 124/**
80 * We're sending an (encrypted) PING to the other peer to check if he 125 * We're sending an (encrypted) PING to the other peer to check if he
@@ -128,9 +173,9 @@ struct PongMessage
128 uint32_t challenge GNUNET_PACKED; 173 uint32_t challenge GNUNET_PACKED;
129 174
130 /** 175 /**
131 * Reserved, always 'GNUNET_BANDWIDTH_VALUE_MAX'. 176 * Reserved, always zero.
132 */ 177 */
133 struct GNUNET_BANDWIDTH_Value32NBO reserved; 178 uint32_t reserved;
134 179
135 /** 180 /**
136 * Intended target of the PING, used primarily to check 181 * Intended target of the PING, used primarily to check
@@ -141,51 +186,6 @@ struct PongMessage
141 186
142 187
143/** 188/**
144 * Message transmitted to set (or update) a session key.
145 */
146struct SetKeyMessage
147{
148
149 /**
150 * Message type is either CORE_SET_KEY.
151 */
152 struct GNUNET_MessageHeader header;
153
154 /**
155 * Status of the sender (should be in "enum PeerStateMachine"), nbo.
156 */
157 int32_t sender_status GNUNET_PACKED;
158
159 /**
160 * Purpose of the signature, will be
161 * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
162 */
163 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
164
165 /**
166 * At what time was this key created?
167 */
168 struct GNUNET_TIME_AbsoluteNBO creation_time;
169
170 /**
171 * The encrypted session key.
172 */
173 struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
174
175 /**
176 * Who is the intended recipient?
177 */
178 struct GNUNET_PeerIdentity target;
179
180 /**
181 * Signature of the stuff above (starting at purpose).
182 */
183 struct GNUNET_CRYPTO_RsaSignature signature;
184
185};
186
187
188/**
189 * Encapsulation for encrypted messages exchanged between 189 * Encapsulation for encrypted messages exchanged between
190 * peers. Followed by the actual encrypted data. 190 * peers. Followed by the actual encrypted data.
191 */ 191 */
@@ -216,9 +216,9 @@ struct EncryptedMessage
216 uint32_t sequence_number GNUNET_PACKED; 216 uint32_t sequence_number GNUNET_PACKED;
217 217
218 /** 218 /**
219 * Reserved, always 'GNUNET_BANDWIDTH_VALUE_MAX'. 219 * Reserved, always zero.
220 */ 220 */
221 struct GNUNET_BANDWIDTH_Value32NBO reserved; 221 uint32_t reserved;
222 222
223 /** 223 /**
224 * Timestamp. Used to prevent reply of ancient messages 224 * Timestamp. Used to prevent reply of ancient messages
@@ -263,23 +263,18 @@ enum KxStateMachine
263 KX_STATE_KEY_RECEIVED, 263 KX_STATE_KEY_RECEIVED,
264 264
265 /** 265 /**
266 * The other peer has confirmed our session key with a message 266 * The other peer has confirmed our session key + PING with a PONG
267 * encrypted with his session key (which we got). Key exchange 267 * message encrypted with his session key (which we got). Key
268 * is done. 268 * exchange is done.
269 */ 269 */
270 KX_STATE_UP, 270 KX_STATE_UP,
271 271
272 /** 272 /**
273 * We're rekeying, so we have received the other peer's session 273 * We're rekeying, so we have sent the other peer our new ephemeral
274 * key, but he didn't get ours yet. 274 * key, but we did not get a matching PONG yet.
275 */
276 KX_STATE_REKEY,
277
278 /**
279 * We're rekeying but have not yet received confirmation for our new
280 * key from the other peer.
281 */ 275 */
282 KX_STATE_REKEY_SENT 276 KX_STATE_REKEY_SENT
277
283}; 278};
284 279
285 280
@@ -288,62 +283,26 @@ enum KxStateMachine
288 */ 283 */
289struct GSC_KeyExchangeInfo 284struct GSC_KeyExchangeInfo
290{ 285{
291 /**
292 * Identity of the peer.
293 */
294 struct GNUNET_PeerIdentity peer;
295 286
296 /** 287 /**
297 * SetKeyMessage to transmit (initialized the first 288 * DLL.
298 * time our status goes past 'KX_STATE_KEY_SENT').
299 */ 289 */
300 struct SetKeyMessage skm; 290 struct GSC_KeyExchangeInfo *next;
301 291
302 /** 292 /**
303 * PING message we transmit to the other peer. 293 * DLL.
304 */ 294 */
305 struct PingMessage ping; 295 struct GSC_KeyExchangeInfo *prev;
306
307 /**
308 * SetKeyMessage we received and did not process yet.
309 */
310 struct SetKeyMessage *skm_received;
311 296
312 /** 297 /**
313 * PING message we received from the other peer and 298 * Identity of the peer.
314 * did not process yet (or NULL).
315 */
316 struct PingMessage *ping_received;
317
318 /**
319 * PONG message we received from the other peer and
320 * did not process yet (or NULL).
321 */
322 struct PongMessage *pong_received;
323
324 /**
325 * Encrypted message we received from the other peer and
326 * did not process yet (or NULL).
327 */
328 struct EncryptedMessage *emsg_received;
329
330 /**
331 * Non-NULL if we are currently looking up HELLOs for this peer.
332 * for this peer.
333 */
334 struct GNUNET_PEERINFO_IteratorContext *pitr;
335
336 /**
337 * Public key of the neighbour, NULL if we don't have it yet.
338 */ 299 */
339 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key; 300 struct GNUNET_PeerIdentity peer;
340 301
341 /** 302 /**
342 * We received a PONG message before we got the "public_key" 303 * PING message we transmit to the other peer.
343 * (or the SET_KEY). We keep it here until we have a key
344 * to decrypt it. NULL if no PONG is pending.
345 */ 304 */
346 struct PongMessage *pending_pong; 305 struct PingMessage ping;
347 306
348 /** 307 /**
349 * Key we use to encrypt our messages for the other peer 308 * Key we use to encrypt our messages for the other peer
@@ -358,14 +317,9 @@ struct GSC_KeyExchangeInfo
358 struct GNUNET_CRYPTO_AesSessionKey decrypt_key; 317 struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
359 318
360 /** 319 /**
361 * At what time did we generate our encryption key?
362 */
363 struct GNUNET_TIME_Absolute encrypt_key_created;
364
365 /**
366 * At what time did the other peer generate the decryption key? 320 * At what time did the other peer generate the decryption key?
367 */ 321 */
368 struct GNUNET_TIME_Absolute decrypt_key_created; 322 struct GNUNET_TIME_Absolute foreign_key_expires;
369 323
370 /** 324 /**
371 * When should the session time out (if there are no PONGs)? 325 * When should the session time out (if there are no PONGs)?
@@ -418,57 +372,46 @@ struct GSC_KeyExchangeInfo
418 372
419 373
420/** 374/**
421 * Handle to peerinfo service. 375 * Our private key.
422 */ 376 */
423static struct GNUNET_PEERINFO_Handle *peerinfo; 377static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
424 378
425/** 379/**
426 * Our private key. 380 * Our ephemeral private key.
381 */
382static struct GNUNET_CRYPTO_EccPrivateKey *my_ephemeral_key;
383
384/**
385 * Current message we send for a key exchange.
427 */ 386 */
428static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; 387static struct EphemeralKeyMessage current_ekm;
429 388
430/** 389/**
431 * Our public key. 390 * Our public key.
432 */ 391 */
433static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; 392static struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded my_public_key;
434 393
435/** 394/**
436 * Our message stream tokenizer (for encrypted payload). 395 * Our message stream tokenizer (for encrypted payload).
437 */ 396 */
438static struct GNUNET_SERVER_MessageStreamTokenizer *mst; 397static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
439 398
440
441#if EXTRA_CHECKS
442/** 399/**
443 * Check internal invariants of the given KX record. 400 * DLL head.
444 * 401 */
445 * @param kx record to check 402static struct GSC_KeyExchangeInfo *kx_head;
446 * @param file filename for error reporting
447 * @param line line number for error reporting
448 */
449static void
450check_kx_record (struct GSC_KeyExchangeInfo *kx,
451 const char *file,
452 int line)
453{
454 struct GNUNET_HashCode hc;
455
456 if (NULL == kx->public_key)
457 return;
458 GNUNET_CRYPTO_hash (kx->public_key, sizeof (*kx->public_key), &hc);
459 GNUNET_assert_at (0 == memcmp (&hc, &kx->peer, sizeof (struct GNUNET_HashCode)), file, line);
460}
461
462 403
463/** 404/**
464 * Check internal invariants of the given KX record. 405 * DLL tail.
465 *
466 * @param kx record to check
467 */ 406 */
468#define CHECK_KX(kx) check_kx_record(kx, __FILE__, __LINE__) 407static struct GSC_KeyExchangeInfo *kx_tail;
469#else 408
470#define CHECK_KX(kx) 409/**
471#endif 410 * Task scheduled for periodic re-generation (and thus rekeying) of our
411 * ephemeral key.
412 */
413static GNUNET_SCHEDULER_TaskIdentifier rekey_task;
414
472 415
473/** 416/**
474 * Derive an authentication key from "set key" information 417 * Derive an authentication key from "set key" information
@@ -476,19 +419,15 @@ check_kx_record (struct GSC_KeyExchangeInfo *kx,
476 * @param akey authentication key to derive 419 * @param akey authentication key to derive
477 * @param skey session key to use 420 * @param skey session key to use
478 * @param seed seed to use 421 * @param seed seed to use
479 * @param creation_time creation time to use
480 */ 422 */
481static void 423static void
482derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, 424derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
483 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed, 425 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed)
484 struct GNUNET_TIME_Absolute creation_time)
485{ 426{
486 static const char ctx[] = "authentication key"; 427 static const char ctx[] = "authentication key";
487 struct GNUNET_TIME_AbsoluteNBO ctbe;
488 428
489 ctbe = GNUNET_TIME_absolute_hton (creation_time);
490 GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key, 429 GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key,
491 sizeof (skey->key), &ctbe, sizeof (ctbe), ctx, 430 sizeof (skey->key), ctx,
492 sizeof (ctx), NULL); 431 sizeof (ctx), NULL);
493} 432}
494 433
@@ -539,6 +478,31 @@ derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
539 478
540 479
541/** 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 */
488static void
489derive_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/**
542 * Encrypt size bytes from in and write the result to out. Use the 506 * Encrypt size bytes from in and write the result to out. Use the
543 * key for outbound traffic of the given neighbour. 507 * key for outbound traffic of the given neighbour.
544 * 508 *
@@ -601,8 +565,7 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx,
601 return GNUNET_NO; 565 return GNUNET_NO;
602 } 566 }
603 if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && 567 if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
604 (kx->status != KX_STATE_REKEY_SENT) && 568 (kx->status != KX_STATE_REKEY_SENT) )
605 (kx->status != KX_STATE_REKEY) )
606 { 569 {
607 GNUNET_break_op (0); 570 GNUNET_break_op (0);
608 return GNUNET_SYSERR; 571 return GNUNET_SYSERR;
@@ -651,88 +614,34 @@ set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
651 struct GSC_KeyExchangeInfo *kx = cls; 614 struct GSC_KeyExchangeInfo *kx = cls;
652 615
653 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; 616 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
654 kx->set_key_retry_frequency = 617 kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency);
655 GNUNET_TIME_relative_multiply (kx->set_key_retry_frequency, 2);
656 send_key (kx); 618 send_key (kx);
657} 619}
658 620
659 621
660/** 622/**
661 * PEERINFO is giving us a HELLO for a peer. Add the public key to 623 * Create a fresh PING message for transmission to the other peer.
662 * the neighbour's struct and continue with the key exchange. Or, if
663 * we did not get a HELLO, just do nothing.
664 * 624 *
665 * @param cls the 'struct GSC_KeyExchangeInfo' to retry sending the key for 625 * @param kx key exchange context to create PING for
666 * @param peer the peer for which this is the HELLO
667 * @param hello HELLO message of that peer
668 * @param err_msg NULL if successful, otherwise contains error message
669 */ 626 */
670static void 627static void
671process_hello (void *cls, const struct GNUNET_PeerIdentity *peer, 628setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
672 const struct GNUNET_HELLO_Message *hello, const char *err_msg)
673{ 629{
674 struct GSC_KeyExchangeInfo *kx = cls; 630 struct PingMessage pp;
675 struct SetKeyMessage *skm; 631 struct PingMessage *pm;
632 struct GNUNET_CRYPTO_AesInitializationVector iv;
676 633
677 CHECK_KX (kx); 634 pm = &kx->ping;
678 if (NULL != err_msg) 635 pm->header.size = htons (sizeof (struct PingMessage));
679 { 636 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 637 pm->iv_seed =
681 _("Error in communication with PEERINFO service\n")); 638 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
682 kx->pitr = NULL; 639 derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, &kx->peer);
683 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) 640 pp.challenge = kx->ping_challenge;
684 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); 641 pp.target = kx->peer;
685 kx->retry_set_key_task = 642 do_encrypt (kx, &iv, &pp.target, &pm->target,
686 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, 643 sizeof (struct PingMessage) - ((void *) &pm->target -
687 &set_key_retry_task, kx); 644 (void *) pm));
688 return;
689 }
690 if (NULL == peer)
691 {
692 kx->pitr = NULL;
693 if (NULL != kx->public_key)
694 return; /* done here */
695 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
696 "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n",
697 GNUNET_i2s (&kx->peer));
698 GNUNET_STATISTICS_update (GSC_stats,
699 gettext_noop
700 ("# Delayed connecting due to lack of public key"),
701 1, GNUNET_NO);
702 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
703 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
704 kx->retry_set_key_task =
705 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
706 &set_key_retry_task, kx);
707 return;
708 }
709 GNUNET_break (0 == memcmp (peer, &kx->peer, sizeof (struct GNUNET_PeerIdentity)));
710 if (NULL != kx->public_key)
711 {
712 /* already have public key, why are we here? */
713 GNUNET_break (0);
714 return;
715 }
716 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->retry_set_key_task);
717 kx->public_key =
718 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
719 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, kx->public_key))
720 {
721 GNUNET_break (0);
722 GNUNET_free (kx->public_key);
723 kx->public_key = NULL;
724 CHECK_KX (kx);
725 return;
726 }
727 CHECK_KX (kx);
728 send_key (kx);
729 if (NULL != kx->skm_received)
730 {
731 skm = kx->skm_received;
732 kx->skm_received = NULL;
733 GSC_KX_handle_set_key (kx, &skm->header);
734 GNUNET_free (skm);
735 }
736} 645}
737 646
738 647
@@ -747,7 +656,8 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
747{ 656{
748 struct GSC_KeyExchangeInfo *kx; 657 struct GSC_KeyExchangeInfo *kx;
749 658
750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initiating key exchange with `%s'\n", 659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
660 "Initiating key exchange with `%s'\n",
751 GNUNET_i2s (pid)); 661 GNUNET_i2s (pid));
752 GNUNET_STATISTICS_update (GSC_stats, 662 GNUNET_STATISTICS_update (GSC_stats,
753 gettext_noop ("# key exchanges initiated"), 1, 663 gettext_noop ("# key exchanges initiated"), 1,
@@ -755,11 +665,11 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
755 kx = GNUNET_malloc (sizeof (struct GSC_KeyExchangeInfo)); 665 kx = GNUNET_malloc (sizeof (struct GSC_KeyExchangeInfo));
756 kx->peer = *pid; 666 kx->peer = *pid;
757 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; 667 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
758 kx->pitr = 668 GNUNET_CONTAINER_DLL_insert (kx_head,
759 GNUNET_PEERINFO_iterate (peerinfo, pid, 669 kx_tail,
760 GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ , 670 kx);
761 &process_hello, kx); 671 kx->status = KX_STATE_KEY_SENT;
762 CHECK_KX (kx); 672 send_key (kx);
763 return kx; 673 return kx;
764} 674}
765 675
@@ -774,11 +684,6 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx)
774{ 684{
775 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges stopped"), 685 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges stopped"),
776 1, GNUNET_NO); 686 1, GNUNET_NO);
777 if (NULL != kx->pitr)
778 {
779 GNUNET_PEERINFO_iterate_cancel (kx->pitr);
780 kx->pitr = NULL;
781 }
782 if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) 687 if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
783 { 688 {
784 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); 689 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
@@ -789,16 +694,26 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx)
789 GNUNET_SCHEDULER_cancel (kx->keep_alive_task); 694 GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
790 kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; 695 kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
791 } 696 }
792 GNUNET_free_non_null (kx->skm_received); 697 GNUNET_CONTAINER_DLL_remove (kx_head,
793 GNUNET_free_non_null (kx->ping_received); 698 kx_tail,
794 GNUNET_free_non_null (kx->pong_received); 699 kx);
795 GNUNET_free_non_null (kx->emsg_received);
796 GNUNET_free_non_null (kx->public_key);
797 GNUNET_free (kx); 700 GNUNET_free (kx);
798} 701}
799 702
800 703
801/** 704/**
705 * Send our PING to the other peer.
706 *
707 * @param kx key exchange context
708 */
709static void
710send_ping (struct GSC_KeyExchangeInfo *kx)
711{
712 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
713 MIN_PING_FREQUENCY);
714}
715
716/**
802 * We received a SET_KEY message. Validate and update 717 * We received a SET_KEY message. Validate and update
803 * our key material and status. 718 * our key material and status.
804 * 719 *
@@ -806,146 +721,142 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx)
806 * @param msg the set key message we received 721 * @param msg the set key message we received
807 */ 722 */
808void 723void
809GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, 724GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
810 const struct GNUNET_MessageHeader *msg) 725 const struct GNUNET_MessageHeader *msg)
811{ 726{
812 const struct SetKeyMessage *m; 727 const struct EphemeralKeyMessage *m;
813 struct GNUNET_TIME_Absolute t; 728 struct GNUNET_TIME_Absolute start_t;
814 struct GNUNET_CRYPTO_AesSessionKey k; 729 struct GNUNET_TIME_Absolute end_t;
815 struct PingMessage *ping; 730 struct GNUNET_TIME_Absolute now;
816 struct PongMessage *pong; 731 struct GNUNET_PeerIdentity signer_id;
817 enum KxStateMachine sender_status; 732 enum KxStateMachine sender_status;
818 uint16_t size; 733 uint16_t size;
734 struct GNUNET_HashCode key_material;
819 735
820 CHECK_KX (kx);
821 size = ntohs (msg->size); 736 size = ntohs (msg->size);
822 if (size != sizeof (struct SetKeyMessage)) 737 if (sizeof (struct EphemeralKeyMessage) != size)
823 { 738 {
824 GNUNET_break_op (0); 739 GNUNET_break_op (0);
825 return; 740 return;
826 } 741 }
827 m = (const struct SetKeyMessage *) msg; 742 m = (const struct EphemeralKeyMessage *) msg;
828 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# session keys received"), 743 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# ephemeral keys received"),
829 1, GNUNET_NO); 744 1, GNUNET_NO);
830 745
831 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 746 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
832 "Core service receives `%s' request from `%4s'.\n", "SET_KEY", 747 "Core service receives `%s' request from `%4s'.\n", "EPHEMERAL_KEY",
833 GNUNET_i2s (&kx->peer)); 748 GNUNET_i2s (&kx->peer));
834 if (NULL == kx->public_key) 749 GNUNET_CRYPTO_hash (&m->origin_public_key,
835 { 750 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded),
836 GNUNET_free_non_null (kx->skm_received); 751 &signer_id.hashPubKey);
837 kx->skm_received = (struct SetKeyMessage *) GNUNET_copy_message (msg);
838 return;
839 }
840 if (0 != 752 if (0 !=
841 memcmp (&m->target, &GSC_my_identity, 753 memcmp (&signer_id, &kx->peer,
842 sizeof (struct GNUNET_PeerIdentity))) 754 sizeof (struct GNUNET_PeerIdentity)))
843 { 755 {
844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 756 GNUNET_break_op (0);
845 _("`%s' is for `%s', not for me. Ignoring.\n"), "SET_KEY",
846 GNUNET_i2s (&m->target));
847 return; 757 return;
848 } 758 }
849 if ((ntohl (m->purpose.size) != 759 if ((ntohl (m->purpose.size) !=
850 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + 760 sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
761 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
851 sizeof (struct GNUNET_TIME_AbsoluteNBO) + 762 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
852 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) + 763 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded) +
853 sizeof (struct GNUNET_PeerIdentity)) || 764 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded)) ||
854 (GNUNET_OK != 765 (GNUNET_OK !=
855 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose, 766 GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY,
856 &m->signature, kx->public_key))) 767 &m->purpose,
768 &m->signature, &m->origin_public_key)))
857 { 769 {
858 /* invalid signature */ 770 /* invalid signature */
859 CHECK_KX (kx);
860 GNUNET_break_op (0); 771 GNUNET_break_op (0);
861 return; 772 return;
862 } 773 }
863 t = GNUNET_TIME_absolute_ntoh (m->creation_time); 774 start_t = GNUNET_TIME_absolute_ntoh (m->creation_time);
864 if (((kx->status == KX_STATE_KEY_RECEIVED) || (kx->status == KX_STATE_UP)) && 775 end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time);
865 (t.abs_value < kx->decrypt_key_created.abs_value)) 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) )
866 { 779 {
867 /* this could rarely happen due to massive re-ordering of 780 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
868 * messages on the network level, but is most likely either 781 _("Ephemeral key message rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
869 * a bug or some adversary messing with us. Report. */ 782 now.abs_value,
870 GNUNET_break_op (0); 783 start_t.abs_value,
784 end_t.abs_value);
871 return; 785 return;
872 } 786 }
873 if ((GNUNET_CRYPTO_rsa_decrypt 787 if (GNUNET_OK !=
874 (my_private_key, &m->encrypted_key, &k, 788 GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key,
875 sizeof (struct GNUNET_CRYPTO_AesSessionKey)) != 789 &m->ephemeral_key,
876 sizeof (struct GNUNET_CRYPTO_AesSessionKey)) || 790 &key_material))
877 (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
878 { 791 {
879 /* failed to decrypt !? */ 792 GNUNET_break (0);
880 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
881 "Invalid key %x decrypted by %s from message %u (origin: %s)\n",
882 (unsigned int) GNUNET_CRYPTO_crc32_n (&k, sizeof (struct GNUNET_CRYPTO_AesSessionKey)),
883 GNUNET_i2s (&GSC_my_identity),
884 (unsigned int) GNUNET_CRYPTO_crc32_n (&m->encrypted_key, sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)),
885 GNUNET_h2s (&kx->peer.hashPubKey));
886 GNUNET_break_op (0);
887 return; 793 return;
888 } 794 }
889 GNUNET_STATISTICS_update (GSC_stats, 795 GNUNET_STATISTICS_update (GSC_stats,
890 gettext_noop ("# SET_KEY messages decrypted"), 1, 796 gettext_noop ("# EPHEMERAL_KEY messages decrypted"), 1,
891 GNUNET_NO); 797 GNUNET_NO);
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received SET_KEY from `%s'\n", 798 derive_aes_key (&GSC_my_identity,
893 GNUNET_i2s (&kx->peer)); 799 &kx->peer,
894 kx->decrypt_key = k; 800 &key_material,
895 if (kx->decrypt_key_created.abs_value != t.abs_value) 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)
896 { 815 {
897 /* fresh key, reset sequence numbers */ 816 case KX_STATE_DOWN:
898 kx->last_sequence_number_received = 0; 817 /* makes no sense, should be at least KX_STATE_KEY_SENT */
899 kx->last_packets_bitmap = 0; 818 GNUNET_break_op (0);
900 kx->decrypt_key_created = t; 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;
901 } 831 }
902 sender_status = (enum KxStateMachine) ntohl (m->sender_status); 832 /* check if we need to confirm everything is fine via PING + PONG */
903 switch (kx->status) 833 switch (kx->status)
904 { 834 {
905 case KX_STATE_DOWN: 835 case KX_STATE_DOWN:
906 kx->status = KX_STATE_KEY_RECEIVED; 836 kx->status = KX_STATE_KEY_RECEIVED;
907 /* we're not up, so we are already doing 'send_key' */ 837 send_ping (kx);
908 break; 838 break;
909 case KX_STATE_KEY_SENT: 839 case KX_STATE_KEY_SENT:
910 kx->status = KX_STATE_KEY_RECEIVED; 840 kx->status = KX_STATE_KEY_RECEIVED;
911 /* we're not up, so we are already doing 'send_key' */ 841 send_ping (kx);
912 break; 842 break;
913 case KX_STATE_KEY_RECEIVED: 843 case KX_STATE_KEY_RECEIVED:
914 /* we're not up, so we are already doing 'send_key' */ 844 send_ping (kx);
915 break; 845 break;
916 case KX_STATE_UP: 846 case KX_STATE_UP:
917 if ((sender_status == KX_STATE_DOWN) || 847 kx->status = KX_STATE_KEY_RECEIVED;
918 (sender_status == KX_STATE_KEY_SENT)) 848 /* we got a new key, need to reconfirm! */
919 send_key (kx); /* we are up, but other peer is not! */ 849 send_ping (kx);
920 break;
921 case KX_STATE_REKEY:
922 if ((sender_status == KX_STATE_DOWN) ||
923 (sender_status == KX_STATE_KEY_SENT))
924 send_key (kx); /* we are up, but other peer is not! */
925 break; 850 break;
926 case KX_STATE_REKEY_SENT: 851 case KX_STATE_REKEY_SENT:
927 if ((sender_status == KX_STATE_DOWN) || 852 kx->status = KX_STATE_KEY_RECEIVED;
928 (sender_status == KX_STATE_KEY_SENT)) 853 /* we got a new key, need to reconfirm! */
929 send_key (kx); /* we are up, but other peer is not! */ 854 send_ping (kx);
930 break; 855 break;
931 default: 856 default:
932 GNUNET_break (0); 857 GNUNET_break (0);
933 break; 858 break;
934 } 859 }
935 if (NULL != kx->ping_received)
936 {
937 ping = kx->ping_received;
938 kx->ping_received = NULL;
939 GSC_KX_handle_ping (kx, &ping->header);
940 GNUNET_free (ping);
941 }
942 if (NULL != kx->pong_received)
943 {
944 pong = kx->pong_received;
945 kx->pong_received = NULL;
946 GSC_KX_handle_pong (kx, &pong->header);
947 GNUNET_free (pong);
948 }
949} 860}
950 861
951 862
@@ -976,12 +887,14 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
976 GNUNET_STATISTICS_update (GSC_stats, 887 GNUNET_STATISTICS_update (GSC_stats,
977 gettext_noop ("# PING messages received"), 1, 888 gettext_noop ("# PING messages received"), 1,
978 GNUNET_NO); 889 GNUNET_NO);
979 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && 890 if ( (kx->status != KX_STATE_KEY_RECEIVED) &&
980 (kx->status != KX_STATE_REKEY_SENT)) 891 (kx->status != KX_STATE_UP) &&
892 (kx->status != KX_STATE_REKEY_SENT))
981 { 893 {
982 /* defer */ 894 /* ignore */
983 GNUNET_free_non_null (kx->ping_received); 895 GNUNET_STATISTICS_update (GSC_stats,
984 kx->ping_received = (struct PingMessage *) GNUNET_copy_message (msg); 896 gettext_noop ("# PING messages dropped (out of order)"), 1,
897 GNUNET_NO);
985 return; 898 return;
986 } 899 }
987 m = (const struct PingMessage *) msg; 900 m = (const struct PingMessage *) msg;
@@ -1012,10 +925,8 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
1012 GNUNET_break_op (0); 925 GNUNET_break_op (0);
1013 return; 926 return;
1014 } 927 }
1015 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PING from `%s'\n",
1016 GNUNET_i2s (&kx->peer));
1017 /* construct PONG */ 928 /* construct PONG */
1018 tx.reserved = GNUNET_BANDWIDTH_VALUE_MAX; 929 tx.reserved = 0;
1019 tx.challenge = t.challenge; 930 tx.challenge = t.challenge;
1020 tx.target = t.target; 931 tx.target = t.target;
1021 tp.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG); 932 tp.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
@@ -1034,76 +945,6 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
1034 945
1035 946
1036/** 947/**
1037 * Create a fresh SET KEY message for transmission to the other peer.
1038 * Also creates a new key.
1039 *
1040 * @param kx key exchange context to create SET KEY message for
1041 */
1042static void
1043setup_fresh_setkey (struct GSC_KeyExchangeInfo *kx)
1044{
1045 struct SetKeyMessage *skm;
1046
1047 GNUNET_CRYPTO_aes_create_session_key (&kx->encrypt_key);
1048 kx->encrypt_key_created = GNUNET_TIME_absolute_get ();
1049 skm = &kx->skm;
1050 skm->header.size = htons (sizeof (struct SetKeyMessage));
1051 skm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
1052 skm->purpose.size =
1053 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
1054 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1055 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
1056 sizeof (struct GNUNET_PeerIdentity));
1057 skm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
1058 skm->creation_time = GNUNET_TIME_absolute_hton (kx->encrypt_key_created);
1059 skm->target = kx->peer;
1060 CHECK_KX (kx);
1061 GNUNET_assert (GNUNET_OK ==
1062 GNUNET_CRYPTO_rsa_encrypt (&kx->encrypt_key,
1063 sizeof (struct
1064 GNUNET_CRYPTO_AesSessionKey),
1065 kx->public_key,
1066 &skm->encrypted_key));
1067 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1068 "Encrypting key %x for %s resulting in message %u (origin: %s)\n",
1069 (unsigned int) GNUNET_CRYPTO_crc32_n (&kx->encrypt_key, sizeof (struct GNUNET_CRYPTO_AesSessionKey)),
1070 GNUNET_i2s (&kx->peer),
1071 (unsigned int) GNUNET_CRYPTO_crc32_n (&skm->encrypted_key, sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)),
1072 GNUNET_h2s (&GSC_my_identity.hashPubKey));
1073
1074 GNUNET_assert (GNUNET_OK ==
1075 GNUNET_CRYPTO_rsa_sign (my_private_key, &skm->purpose,
1076 &skm->signature));
1077}
1078
1079
1080/**
1081 * Create a fresh PING message for transmission to the other peer.
1082 *
1083 * @param kx key exchange context to create PING for
1084 */
1085static void
1086setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
1087{
1088 struct PingMessage pp;
1089 struct PingMessage *pm;
1090 struct GNUNET_CRYPTO_AesInitializationVector iv;
1091
1092 pm = &kx->ping;
1093 pm->header.size = htons (sizeof (struct PingMessage));
1094 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1095 pm->iv_seed =
1096 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
1097 derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, &kx->peer);
1098 pp.challenge = kx->ping_challenge;
1099 pp.target = kx->peer;
1100 do_encrypt (kx, &iv, &pp.target, &pm->target,
1101 sizeof (struct PingMessage) - ((void *) &pm->target -
1102 (void *) pm));
1103}
1104
1105
1106/**
1107 * Task triggered when a neighbour entry is about to time out 948 * Task triggered when a neighbour entry is about to time out
1108 * (and we should prevent this by sending a PING). 949 * (and we should prevent this by sending a PING).
1109 * 950 *
@@ -1125,7 +966,7 @@ send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1125 gettext_noop ("# sessions terminated by timeout"), 966 gettext_noop ("# sessions terminated by timeout"),
1126 1, GNUNET_NO); 967 1, GNUNET_NO);
1127 GSC_SESSIONS_end (&kx->peer); 968 GSC_SESSIONS_end (&kx->peer);
1128 kx->status = KX_STATE_DOWN; 969 kx->status = KX_STATE_KEY_SENT;
1129 send_key (kx); 970 send_key (kx);
1130 return; 971 return;
1131 } 972 }
@@ -1168,49 +1009,6 @@ update_timeout (struct GSC_KeyExchangeInfo *kx)
1168 1009
1169 1010
1170/** 1011/**
1171 * Trigger rekeying event.
1172 *
1173 * @param cls the 'struct GSC_KeyExchangeInfo'
1174 * @param tc schedule context (unused)
1175 */
1176static void
1177trigger_rekey (void *cls,
1178 const struct GNUNET_SCHEDULER_TaskContext *tc)
1179{
1180 struct GSC_KeyExchangeInfo *kx = cls;
1181
1182 GNUNET_break (KX_STATE_UP == kx->status);
1183 kx->status = KX_STATE_REKEY;
1184 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
1185 kx->retry_set_key_task =
1186 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
1187 &set_key_retry_task, kx);
1188}
1189
1190
1191/**
1192 * Schedule rekey operation.
1193 *
1194 * @param kx key exchange to schedule rekey for
1195 */
1196static void
1197schedule_rekey (struct GSC_KeyExchangeInfo *kx)
1198{
1199 struct GNUNET_TIME_Relative rdelay;
1200
1201 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
1202 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1203 rdelay = REKEY_FREQUENCY;
1204 /* randomize rekey frequency by one minute to avoid synchronization */
1205 rdelay.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1206 60 * 1000);
1207 kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1208 &trigger_rekey,
1209 kx);
1210}
1211
1212
1213/**
1214 * We received a PONG message. Validate and update our status. 1012 * We received a PONG message. Validate and update our status.
1215 * 1013 *
1216 * @param kx key exchange context for the the PONG 1014 * @param kx key exchange context for the the PONG
@@ -1222,7 +1020,6 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1222{ 1020{
1223 const struct PongMessage *m; 1021 const struct PongMessage *m;
1224 struct PongMessage t; 1022 struct PongMessage t;
1225 struct EncryptedMessage *emsg;
1226 struct GNUNET_CRYPTO_AesInitializationVector iv; 1023 struct GNUNET_CRYPTO_AesInitializationVector iv;
1227 uint16_t msize; 1024 uint16_t msize;
1228 1025
@@ -1238,17 +1035,19 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1238 switch (kx->status) 1035 switch (kx->status)
1239 { 1036 {
1240 case KX_STATE_DOWN: 1037 case KX_STATE_DOWN:
1038 GNUNET_STATISTICS_update (GSC_stats,
1039 gettext_noop ("# PONG messages dropped (connection down)"), 1,
1040 GNUNET_NO);
1241 return; 1041 return;
1242 case KX_STATE_KEY_SENT: 1042 case KX_STATE_KEY_SENT:
1243 GNUNET_free_non_null (kx->pong_received); 1043 GNUNET_STATISTICS_update (GSC_stats,
1244 kx->pong_received = (struct PongMessage *) GNUNET_copy_message (msg); 1044 gettext_noop ("# PONG messages dropped (out of order)"), 1,
1045 GNUNET_NO);
1245 return; 1046 return;
1246 case KX_STATE_KEY_RECEIVED: 1047 case KX_STATE_KEY_RECEIVED:
1247 break; 1048 break;
1248 case KX_STATE_UP: 1049 case KX_STATE_UP:
1249 break; 1050 break;
1250 case KX_STATE_REKEY:
1251 break;
1252 case KX_STATE_REKEY_SENT: 1051 case KX_STATE_REKEY_SENT:
1253 break; 1052 break;
1254 default: 1053 default:
@@ -1289,13 +1088,19 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1289 } 1088 }
1290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n", 1089 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n",
1291 GNUNET_i2s (&kx->peer)); 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 }
1292 switch (kx->status) 1097 switch (kx->status)
1293 { 1098 {
1294 case KX_STATE_DOWN: 1099 case KX_STATE_DOWN:
1295 GNUNET_break (0); /* should be impossible */ 1100 GNUNET_assert (0); /* should be impossible */
1296 return; 1101 return;
1297 case KX_STATE_KEY_SENT: 1102 case KX_STATE_KEY_SENT:
1298 GNUNET_break (0); /* should be impossible */ 1103 GNUNET_assert (0); /* should be impossible */
1299 return; 1104 return;
1300 case KX_STATE_KEY_RECEIVED: 1105 case KX_STATE_KEY_RECEIVED:
1301 GNUNET_STATISTICS_update (GSC_stats, 1106 GNUNET_STATISTICS_update (GSC_stats,
@@ -1304,23 +1109,14 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1304 GNUNET_NO); 1109 GNUNET_NO);
1305 kx->status = KX_STATE_UP; 1110 kx->status = KX_STATE_UP;
1306 GSC_SESSIONS_create (&kx->peer, kx); 1111 GSC_SESSIONS_create (&kx->peer, kx);
1307 CHECK_KX (kx);
1308 schedule_rekey (kx);
1309 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); 1112 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
1310 if (NULL != kx->emsg_received)
1311 {
1312 emsg = kx->emsg_received;
1313 kx->emsg_received = NULL;
1314 GSC_KX_handle_encrypted_message (kx, &emsg->header, NULL,
1315 0 /* FIXME: ATSI */ );
1316 GNUNET_free (emsg);
1317 }
1318 update_timeout (kx); 1113 update_timeout (kx);
1319 break; 1114 break;
1320 case KX_STATE_UP: 1115 case KX_STATE_UP:
1321 update_timeout (kx); 1116 GNUNET_STATISTICS_update (GSC_stats,
1322 break; 1117 gettext_noop
1323 case KX_STATE_REKEY: 1118 ("# timeouts prevented via PONG"), 1,
1119 GNUNET_NO);
1324 update_timeout (kx); 1120 update_timeout (kx);
1325 break; 1121 break;
1326 case KX_STATE_REKEY_SENT: 1122 case KX_STATE_REKEY_SENT:
@@ -1329,7 +1125,6 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1329 ("# rekey operations confirmed via PONG"), 1, 1125 ("# rekey operations confirmed via PONG"), 1,
1330 GNUNET_NO); 1126 GNUNET_NO);
1331 kx->status = KX_STATE_UP; 1127 kx->status = KX_STATE_UP;
1332 schedule_rekey (kx);
1333 update_timeout (kx); 1128 update_timeout (kx);
1334 break; 1129 break;
1335 default: 1130 default:
@@ -1340,86 +1135,25 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1340 1135
1341 1136
1342/** 1137/**
1343 * Send our key (and encrypted PING) to the other peer. 1138 * Send our key to the other peer.
1344 * 1139 *
1345 * @param kx key exchange context 1140 * @param kx key exchange context
1346 */ 1141 */
1347static void 1142static void
1348send_key (struct GSC_KeyExchangeInfo *kx) 1143send_key (struct GSC_KeyExchangeInfo *kx)
1349{ 1144{
1350 CHECK_KX (kx);
1351 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) 1145 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
1352 { 1146 {
1353 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); 1147 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1354 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; 1148 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
1355 } 1149 }
1356 if (KX_STATE_UP == kx->status)
1357 return; /* nothing to do */
1358 if (NULL == kx->public_key)
1359 {
1360 if (NULL != kx->pitr)
1361 return;
1362 /* lookup public key, then try again */
1363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1364 "Trying to obtain public key for `%s'\n",
1365 GNUNET_i2s (&kx->peer));
1366 kx->pitr =
1367 GNUNET_PEERINFO_iterate (peerinfo, &kx->peer,
1368 GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ ,
1369 &process_hello, kx);
1370 return;
1371 }
1372
1373 /* update status */
1374 switch (kx->status)
1375 {
1376 case KX_STATE_DOWN:
1377 kx->status = KX_STATE_KEY_SENT;
1378 /* setup SET KEY message */
1379 setup_fresh_setkey (kx);
1380 setup_fresh_ping (kx);
1381 GNUNET_STATISTICS_update (GSC_stats,
1382 gettext_noop
1383 ("# SET_KEY and PING messages created"), 1,
1384 GNUNET_NO);
1385 break;
1386 case KX_STATE_KEY_SENT:
1387 break;
1388 case KX_STATE_KEY_RECEIVED:
1389 break;
1390 case KX_STATE_UP:
1391 GNUNET_break (0);
1392 return;
1393 case KX_STATE_REKEY:
1394 kx->status = KX_STATE_REKEY_SENT;
1395 /* setup fresh SET KEY message */
1396 setup_fresh_setkey (kx);
1397 setup_fresh_ping (kx);
1398 GNUNET_STATISTICS_update (GSC_stats,
1399 gettext_noop
1400 ("# SET_KEY and PING messages created"), 1,
1401 GNUNET_NO);
1402 GNUNET_STATISTICS_update (GSC_stats,
1403 gettext_noop
1404 ("# REKEY operations performed"), 1,
1405 GNUNET_NO);
1406 break;
1407 case KX_STATE_REKEY_SENT:
1408 break;
1409 default:
1410 GNUNET_break (0);
1411 return;
1412 }
1413
1414 /* always update sender status in SET KEY message */ 1150 /* always update sender status in SET KEY message */
1415 /* Not sending rekey sent state to be compatible with GNUnet 0.9.2 */ 1151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1416 kx->skm.sender_status = htonl ((int32_t) ((kx->status == KX_STATE_REKEY_SENT) ? 1152 "Sending key to `%s' (my status: %d)\n",
1417 KX_STATE_KEY_RECEIVED : kx->status)); 1153 GNUNET_i2s (&kx->peer),
1418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SET_KEY and PING to `%s'\n", 1154 kx->status);
1419 GNUNET_i2s (&kx->peer)); 1155 current_ekm.sender_status = htonl ((int32_t) (kx->status));
1420 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->skm.header, 1156 GSC_NEIGHBOURS_transmit (&kx->peer, &current_ekm.header,
1421 kx->set_key_retry_frequency);
1422 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
1423 kx->set_key_retry_frequency); 1157 kx->set_key_retry_frequency);
1424 kx->retry_set_key_task = 1158 kx->retry_set_key_task =
1425 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, 1159 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
@@ -1451,7 +1185,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1451 htonl (GNUNET_CRYPTO_random_u32 1185 htonl (GNUNET_CRYPTO_random_u32
1452 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); 1186 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
1453 ph->sequence_number = htonl (++kx->last_sequence_number_sent); 1187 ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1454 ph->reserved = GNUNET_BANDWIDTH_VALUE_MAX; 1188 ph->reserved = 0;
1455 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 1189 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1456 memcpy (&ph[1], payload, payload_size); 1190 memcpy (&ph[1], payload, payload_size);
1457 1191
@@ -1466,8 +1200,9 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1466 used - ENCRYPTED_HEADER_SIZE)); 1200 used - ENCRYPTED_HEADER_SIZE));
1467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n", 1201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n",
1468 used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer)); 1202 used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer));
1469 derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed, 1203 derive_auth_key (&auth_key,
1470 kx->encrypt_key_created); 1204 &kx->encrypt_key,
1205 ph->iv_seed);
1471 GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number, 1206 GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
1472 used - ENCRYPTED_HEADER_SIZE, &em->hmac); 1207 used - ENCRYPTED_HEADER_SIZE, &em->hmac);
1473 GSC_NEIGHBOURS_transmit (&kx->peer, &em->header, 1208 GSC_NEIGHBOURS_transmit (&kx->peer, &em->header,
@@ -1531,31 +1266,35 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1531 return; 1266 return;
1532 } 1267 }
1533 m = (const struct EncryptedMessage *) msg; 1268 m = (const struct EncryptedMessage *) msg;
1534 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && 1269 if (kx->status != KX_STATE_UP)
1535 (kx->status != KX_STATE_REKEY_SENT) )
1536 { 1270 {
1537 GNUNET_STATISTICS_update (GSC_stats, 1271 GNUNET_STATISTICS_update (GSC_stats,
1538 gettext_noop 1272 gettext_noop
1539 ("# failed to decrypt message (no session key)"), 1273 ("# DATA message dropped (out of order)"),
1540 1, GNUNET_NO); 1274 1, GNUNET_NO);
1541 return; 1275 return;
1542 } 1276 }
1543 if (KX_STATE_KEY_RECEIVED == kx->status) 1277 if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value)
1544 { 1278 {
1545 /* defer */ 1279 kx->status = KX_STATE_KEY_SENT;
1546 GNUNET_free_non_null (kx->emsg_received); 1280 GNUNET_STATISTICS_update (GSC_stats,
1547 kx->emsg_received = (struct EncryptedMessage *) GNUNET_copy_message (msg); 1281 gettext_noop
1282 ("# DATA message dropped (session key expired)"),
1283 1, GNUNET_NO);
1284 send_key (kx);
1548 return; 1285 return;
1549 } 1286 }
1287
1550 /* validate hash */ 1288 /* validate hash */
1551 derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed, 1289 derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed);
1552 kx->decrypt_key_created);
1553 GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number, 1290 GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number,
1554 size - ENCRYPTED_HEADER_SIZE, &ph); 1291 size - ENCRYPTED_HEADER_SIZE, &ph);
1555 if (0 != memcmp (&ph, &m->hmac, sizeof (struct GNUNET_HashCode))) 1292 if (0 != memcmp (&ph, &m->hmac, sizeof (struct GNUNET_HashCode)))
1556 { 1293 {
1557 /* checksum failed */ 1294 /* checksum failed */
1558 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed checksum validation for a message from `%s'\n", GNUNET_i2s (&kx->peer)); 1295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1296 "Failed checksum validation for a message from `%s'\n",
1297 GNUNET_i2s (&kx->peer));
1559 return; 1298 return;
1560 } 1299 }
1561 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); 1300 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
@@ -1572,7 +1311,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1572 snum = ntohl (pt->sequence_number); 1311 snum = ntohl (pt->sequence_number);
1573 if (kx->last_sequence_number_received == snum) 1312 if (kx->last_sequence_number_received == snum)
1574 { 1313 {
1575 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1314 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1576 "Received duplicate message, ignoring.\n"); 1315 "Received duplicate message, ignoring.\n");
1577 /* duplicate, ignore */ 1316 /* duplicate, ignore */
1578 GNUNET_STATISTICS_update (GSC_stats, 1317 GNUNET_STATISTICS_update (GSC_stats,
@@ -1583,7 +1322,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1583 if ((kx->last_sequence_number_received > snum) && 1322 if ((kx->last_sequence_number_received > snum) &&
1584 (kx->last_sequence_number_received - snum > 32)) 1323 (kx->last_sequence_number_received - snum > 32))
1585 { 1324 {
1586 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1587 "Received ancient out of sequence message, ignoring.\n"); 1326 "Received ancient out of sequence message, ignoring.\n");
1588 /* ancient out of sequence, ignore */ 1327 /* ancient out of sequence, ignore */
1589 GNUNET_STATISTICS_update (GSC_stats, 1328 GNUNET_STATISTICS_update (GSC_stats,
@@ -1598,7 +1337,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1598 1337
1599 if ((kx->last_packets_bitmap & rotbit) != 0) 1338 if ((kx->last_packets_bitmap & rotbit) != 0)
1600 { 1339 {
1601 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1602 "Received duplicate message, ignoring.\n"); 1341 "Received duplicate message, ignoring.\n");
1603 GNUNET_STATISTICS_update (GSC_stats, 1342 GNUNET_STATISTICS_update (GSC_stats,
1604 gettext_noop ("# bytes dropped (duplicates)"), 1343 gettext_noop ("# bytes dropped (duplicates)"),
@@ -1624,8 +1363,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1624 if (GNUNET_TIME_absolute_get_duration (t).rel_value > 1363 if (GNUNET_TIME_absolute_get_duration (t).rel_value >
1625 MAX_MESSAGE_AGE.rel_value) 1364 MAX_MESSAGE_AGE.rel_value)
1626 { 1365 {
1627 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1628 _("Message received far too old (%s). Content ignored.\n"), 1367 "Message received far too old (%s). Content ignored.\n",
1629 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (t), GNUNET_YES)); 1368 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (t), GNUNET_YES));
1630 GNUNET_STATISTICS_update (GSC_stats, 1369 GNUNET_STATISTICS_update (GSC_stats,
1631 gettext_noop 1370 gettext_noop
@@ -1684,28 +1423,89 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
1684 1423
1685 1424
1686/** 1425/**
1426 * Setup the message that links the ephemeral key to our persistent
1427 * public key and generate the appropriate signature.
1428 */
1429static void
1430sign_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 */
1460static void
1461do_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/**
1687 * Initialize KX subsystem. 1483 * Initialize KX subsystem.
1688 * 1484 *
1689 * @param pk private key to use for the peer 1485 * @param pk private key to use for the peer
1690 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 1486 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1691 */ 1487 */
1692int 1488int
1693GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk) 1489GSC_KX_init (struct GNUNET_CRYPTO_EccPrivateKey *pk)
1694{ 1490{
1491 GNUNET_assert (NULL != pk);
1695 my_private_key = pk; 1492 my_private_key = pk;
1696 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); 1493 GNUNET_CRYPTO_ecc_key_get_public (my_private_key, &my_public_key);
1697 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), 1494 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
1698 &GSC_my_identity.hashPubKey); 1495 &GSC_my_identity.hashPubKey);
1699 peerinfo = GNUNET_PEERINFO_connect (GSC_cfg); 1496 my_ephemeral_key = GNUNET_CRYPTO_ecc_key_create ();
1700 if (NULL == peerinfo) 1497 if (NULL == my_ephemeral_key)
1701 { 1498 {
1702 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1499 GNUNET_break (0);
1703 _("Could not access PEERINFO service. Exiting.\n")); 1500 GNUNET_CRYPTO_ecc_key_free (my_private_key);
1704 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1705 my_private_key = NULL; 1501 my_private_key = NULL;
1706 return GNUNET_SYSERR; 1502 return GNUNET_SYSERR;
1707 } 1503 }
1504 sign_ephemeral_key ();
1708 mst = GNUNET_SERVER_mst_create (&deliver_message, NULL); 1505 mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
1506 rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1507 &do_rekey,
1508 NULL);
1709 return GNUNET_OK; 1509 return GNUNET_OK;
1710} 1510}
1711 1511
@@ -1716,15 +1516,20 @@ GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk)
1716void 1516void
1717GSC_KX_done () 1517GSC_KX_done ()
1718{ 1518{
1519 if (GNUNET_SCHEDULER_NO_TASK != rekey_task)
1520 {
1521 GNUNET_SCHEDULER_cancel (rekey_task);
1522 rekey_task = GNUNET_SCHEDULER_NO_TASK;
1523 }
1719 if (NULL != my_private_key) 1524 if (NULL != my_private_key)
1720 { 1525 {
1721 GNUNET_CRYPTO_rsa_key_free (my_private_key); 1526 GNUNET_CRYPTO_ecc_key_free (my_private_key);
1722 my_private_key = NULL; 1527 my_private_key = NULL;
1723 } 1528 }
1724 if (NULL != peerinfo) 1529 if (NULL != my_ephemeral_key)
1725 { 1530 {
1726 GNUNET_PEERINFO_disconnect (peerinfo); 1531 GNUNET_CRYPTO_ecc_key_free (my_ephemeral_key);
1727 peerinfo = NULL; 1532 my_ephemeral_key = NULL;
1728 } 1533 }
1729 if (NULL != mst) 1534 if (NULL != mst)
1730 { 1535 {
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h
index fcb561e01..6e6d30d8d 100644
--- a/src/core/gnunet-service-core_kx.h
+++ b/src/core/gnunet-service-core_kx.h
@@ -37,15 +37,15 @@ struct GSC_KeyExchangeInfo;
37 37
38 38
39/** 39/**
40 * We received a SET_KEY message. Validate and update 40 * We received a EPHEMERAL_KEY message. Validate and update
41 * our key material and status. 41 * our key material and status.
42 * 42 *
43 * @param kx key exchange status for the corresponding peer 43 * @param kx key exchange status for the corresponding peer
44 * @param msg the set key message we received 44 * @param msg the set key message we received
45 */ 45 */
46void 46void
47GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, 47GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
48 const struct GNUNET_MessageHeader *msg); 48 const struct GNUNET_MessageHeader *msg);
49 49
50 50
51/** 51/**
@@ -125,7 +125,7 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx);
125 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 125 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
126 */ 126 */
127int 127int
128GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk); 128GSC_KX_init (struct GNUNET_CRYPTO_EccPrivateKey *pk);
129 129
130 130
131/** 131/**
diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c
index aa77fe47e..7e0086fd6 100644
--- a/src/core/gnunet-service-core_neighbours.c
+++ b/src/core/gnunet-service-core_neighbours.c
@@ -400,8 +400,8 @@ handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
400 type = ntohs (message->type); 400 type = ntohs (message->type);
401 switch (type) 401 switch (type)
402 { 402 {
403 case GNUNET_MESSAGE_TYPE_CORE_SET_KEY: 403 case GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY:
404 GSC_KX_handle_set_key (n->kxinfo, message); 404 GSC_KX_handle_ephemeral_key (n->kxinfo, message);
405 break; 405 break;
406 case GNUNET_MESSAGE_TYPE_CORE_PING: 406 case GNUNET_MESSAGE_TYPE_CORE_PING:
407 GSC_KX_handle_ping (n->kxinfo, message); 407 GSC_KX_handle_ping (n->kxinfo, message);