2 This file is part of GNUnet.
3 (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
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.
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.
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.
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
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_peerinfo_service.h"
34 #include "gnunet_hello_lib.h"
35 #include "gnunet_constants.h"
36 #include "gnunet_signatures.h"
37 #include "gnunet_protocols.h"
42 * How long do we wait for SET_KEY confirmation initially?
44 #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 1)
47 * What is the minimum frequency for a PING message?
49 #define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
52 * How often do we rekey?
54 #define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 90)
58 * What is the maximum age of a message for us to consider processing
59 * it? Note that this looks at the timestamp used by the other peer,
60 * so clock skew between machines does come into play here. So this
61 * should be picked high enough so that a little bit of clock skew
62 * does not prevent peers from connecting to us.
64 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
67 * What is the maximum delay for a SET_KEY message?
69 #define MAX_SET_KEY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
72 GNUNET_NETWORK_STRUCT_BEGIN
75 * We're sending an (encrypted) PING to the other peer to check if he
76 * can decrypt. The other peer should respond with a PONG with the
77 * same content, except this time encrypted with the receiver's key.
82 * Message type is CORE_PING.
84 struct GNUNET_MessageHeader header;
89 uint32_t iv_seed GNUNET_PACKED;
92 * Intended target of the PING, used primarily to check
93 * that decryption actually worked.
95 struct GNUNET_PeerIdentity target;
98 * Random number chosen to make reply harder.
100 uint32_t challenge GNUNET_PACKED;
105 * Response to a PING. Includes data from the original PING.
110 * Message type is CORE_PONG.
112 struct GNUNET_MessageHeader header;
117 uint32_t iv_seed GNUNET_PACKED;
120 * Random number to make faking the reply harder. Must be
121 * first field after header (this is where we start to encrypt!).
123 uint32_t challenge GNUNET_PACKED;
126 * Reserved, always 'GNUNET_BANDWIDTH_VALUE_MAX'.
128 struct GNUNET_BANDWIDTH_Value32NBO reserved;
131 * Intended target of the PING, used primarily to check
132 * that decryption actually worked.
134 struct GNUNET_PeerIdentity target;
139 * Message transmitted to set (or update) a session key.
145 * Message type is either CORE_SET_KEY.
147 struct GNUNET_MessageHeader header;
150 * Status of the sender (should be in "enum PeerStateMachine"), nbo.
152 int32_t sender_status GNUNET_PACKED;
155 * Purpose of the signature, will be
156 * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
158 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
161 * At what time was this key created?
163 struct GNUNET_TIME_AbsoluteNBO creation_time;
166 * The encrypted session key.
168 struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
171 * Who is the intended recipient?
173 struct GNUNET_PeerIdentity target;
176 * Signature of the stuff above (starting at purpose).
178 struct GNUNET_CRYPTO_RsaSignature signature;
184 * Encapsulation for encrypted messages exchanged between
185 * peers. Followed by the actual encrypted data.
187 struct EncryptedMessage
190 * Message type is either CORE_ENCRYPTED_MESSAGE.
192 struct GNUNET_MessageHeader header;
195 * Random value used for IV generation.
197 uint32_t iv_seed GNUNET_PACKED;
200 * MAC of the encrypted message (starting at 'sequence_number'),
201 * used to verify message integrity. Everything after this value
202 * (excluding this value itself) will be encrypted and authenticated.
203 * ENCRYPTED_HEADER_SIZE must be set to the offset of the *next* field.
205 GNUNET_HashCode hmac;
208 * Sequence number, in network byte order. This field
209 * must be the first encrypted/decrypted field
211 uint32_t sequence_number GNUNET_PACKED;
214 * Reserved, always 'GNUNET_BANDWIDTH_VALUE_MAX'.
216 struct GNUNET_BANDWIDTH_Value32NBO reserved;
219 * Timestamp. Used to prevent reply of ancient messages
220 * (recent messages are caught with the sequence number).
222 struct GNUNET_TIME_AbsoluteNBO timestamp;
225 GNUNET_NETWORK_STRUCT_END
229 * Number of bytes (at the beginning) of "struct EncryptedMessage"
230 * that are NOT encrypted.
232 #define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number))
236 * State machine for our P2P encryption handshake. Everyone starts in
237 * "DOWN", if we receive the other peer's key (other peer initiated)
238 * we start in state RECEIVED (since we will immediately send our
239 * own); otherwise we start in SENT. If we get back a PONG from
240 * within either state, we move up to CONFIRMED (the PONG will always
241 * be sent back encrypted with the key we sent to the other peer).
251 * We've sent our session key.
256 * We've received the other peers session key.
258 KX_STATE_KEY_RECEIVED,
261 * The other peer has confirmed our session key with a message
262 * encrypted with his session key (which we got). Key exchange
268 * We're rekeying, so we have received the other peer's session
269 * key, but he didn't get ours yet.
274 * We're rekeying but have not yet received confirmation for our new
275 * key from the other peer.
282 * Information about the status of a key exchange with another peer.
284 struct GSC_KeyExchangeInfo
287 * Identity of the peer.
289 struct GNUNET_PeerIdentity peer;
292 * SetKeyMessage to transmit (initialized the first
293 * time our status goes past 'KX_STATE_KEY_SENT').
295 struct SetKeyMessage skm;
298 * PING message we transmit to the other peer.
300 struct PingMessage ping;
303 * SetKeyMessage we received and did not process yet.
305 struct SetKeyMessage *skm_received;
308 * PING message we received from the other peer and
309 * did not process yet (or NULL).
311 struct PingMessage *ping_received;
314 * PONG message we received from the other peer and
315 * did not process yet (or NULL).
317 struct PongMessage *pong_received;
320 * Encrypted message we received from the other peer and
321 * did not process yet (or NULL).
323 struct EncryptedMessage *emsg_received;
326 * Non-NULL if we are currently looking up HELLOs for this peer.
329 struct GNUNET_PEERINFO_IteratorContext *pitr;
332 * Public key of the neighbour, NULL if we don't have it yet.
334 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key;
337 * We received a PONG message before we got the "public_key"
338 * (or the SET_KEY). We keep it here until we have a key
339 * to decrypt it. NULL if no PONG is pending.
341 struct PongMessage *pending_pong;
344 * Key we use to encrypt our messages for the other peer
345 * (initialized by us when we do the handshake).
347 struct GNUNET_CRYPTO_AesSessionKey encrypt_key;
350 * Key we use to decrypt messages from the other peer
351 * (given to us by the other peer during the handshake).
353 struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
356 * At what time did we generate our encryption key?
358 struct GNUNET_TIME_Absolute encrypt_key_created;
361 * At what time did the other peer generate the decryption key?
363 struct GNUNET_TIME_Absolute decrypt_key_created;
366 * When should the session time out (if there are no PONGs)?
368 struct GNUNET_TIME_Absolute timeout;
371 * At what frequency are we currently re-trying SET_KEY messages?
373 struct GNUNET_TIME_Relative set_key_retry_frequency;
376 * ID of task used for re-trying SET_KEY and PING message.
378 GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
381 * ID of task used for sending keep-alive pings.
383 GNUNET_SCHEDULER_TaskIdentifier keep_alive_task;
386 * Bit map indicating which of the 32 sequence numbers before the last
387 * were received (good for accepting out-of-order packets and
388 * estimating reliability of the connection)
390 unsigned int last_packets_bitmap;
393 * last sequence number received on this connection (highest)
395 uint32_t last_sequence_number_received;
398 * last sequence number transmitted
400 uint32_t last_sequence_number_sent;
403 * What was our PING challenge number (for this peer)?
405 uint32_t ping_challenge;
408 * What is our connection status?
410 enum KxStateMachine status;
416 * Handle to peerinfo service.
418 static struct GNUNET_PEERINFO_Handle *peerinfo;
423 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
428 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
431 * Our message stream tokenizer (for encrypted payload).
433 static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
437 * Derive an authentication key from "set key" information
439 * @param akey authentication key to derive
440 * @param skey session key to use
441 * @param seed seed to use
442 * @param creation_time creation time to use
445 derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
446 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
447 struct GNUNET_TIME_Absolute creation_time)
449 static const char ctx[] = "authentication key";
450 struct GNUNET_TIME_AbsoluteNBO ctbe;
452 ctbe = GNUNET_TIME_absolute_hton (creation_time);
453 GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key,
454 sizeof (skey->key), &ctbe, sizeof (ctbe), ctx,
460 * Derive an IV from packet information
462 * @param iv initialization vector to initialize
463 * @param skey session key to use
464 * @param seed seed to use
465 * @param identity identity of the other peer to use
468 derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
469 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
470 const struct GNUNET_PeerIdentity *identity)
472 static const char ctx[] = "initialization vector";
474 GNUNET_CRYPTO_aes_derive_iv (iv, skey, &seed, sizeof (seed),
475 &identity->hashPubKey.bits,
476 sizeof (identity->hashPubKey.bits), ctx,
482 * Derive an IV from pong packet information
484 * @param iv initialization vector to initialize
485 * @param skey session key to use
486 * @param seed seed to use
487 * @param challenge nonce to use
488 * @param identity identity of the other peer to use
491 derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
492 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
493 uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
495 static const char ctx[] = "pong initialization vector";
497 GNUNET_CRYPTO_aes_derive_iv (iv, skey, &seed, sizeof (seed),
498 &identity->hashPubKey.bits,
499 sizeof (identity->hashPubKey.bits), &challenge,
500 sizeof (challenge), ctx, sizeof (ctx), NULL);
505 * Encrypt size bytes from in and write the result to out. Use the
506 * key for outbound traffic of the given neighbour.
508 * @param kx key information context
509 * @param iv initialization vector to use
510 * @param in ciphertext
511 * @param out plaintext
512 * @param size size of in/out
513 * @return GNUNET_OK on success
516 do_encrypt (struct GSC_KeyExchangeInfo *kx,
517 const struct GNUNET_CRYPTO_AesInitializationVector *iv,
518 const void *in, void *out, size_t size)
520 if (size != (uint16_t) size)
525 GNUNET_assert (size ==
526 GNUNET_CRYPTO_aes_encrypt (in, (uint16_t) size,
527 &kx->encrypt_key, iv, out));
528 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes encrypted"), size,
530 /* the following is too sensitive to write to log files by accident,
531 so we require manual intervention to get this one... */
533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
534 "Encrypted %u bytes for `%4s' using key %u, IV %u\n",
535 (unsigned int) size, GNUNET_i2s (&kx->peer),
536 (unsigned int) kx->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv,
545 * Decrypt size bytes from in and write the result to out. Use the
546 * key for inbound traffic of the given neighbour. This function does
547 * NOT do any integrity-checks on the result.
549 * @param kx key information context
550 * @param iv initialization vector to use
551 * @param in ciphertext
552 * @param out plaintext
553 * @param size size of in/out
554 * @return GNUNET_OK on success
557 do_decrypt (struct GSC_KeyExchangeInfo *kx,
558 const struct GNUNET_CRYPTO_AesInitializationVector *iv,
559 const void *in, void *out, size_t size)
561 if (size != (uint16_t) size)
566 if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
567 (kx->status != KX_STATE_REKEY_SENT) &&
568 (kx->status != KX_STATE_REKEY) )
571 return GNUNET_SYSERR;
574 GNUNET_CRYPTO_aes_decrypt (in, (uint16_t) size, &kx->decrypt_key, iv,
578 return GNUNET_SYSERR;
580 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes decrypted"), size,
582 /* the following is too sensitive to write to log files by accident,
583 so we require manual intervention to get this one... */
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,
597 * Send our key (and encrypted PING) to the other peer.
599 * @param kx key exchange context
602 send_key (struct GSC_KeyExchangeInfo *kx);
606 * Task that will retry "send_key" if our previous attempt failed.
608 * @param cls our 'struct GSC_KeyExchangeInfo'
609 * @param tc scheduler context
612 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
614 struct GSC_KeyExchangeInfo *kx = cls;
616 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
617 kx->set_key_retry_frequency =
618 GNUNET_TIME_relative_multiply (kx->set_key_retry_frequency, 2);
624 * PEERINFO is giving us a HELLO for a peer. Add the public key to
625 * the neighbour's struct and continue with the key exchange. Or, if
626 * we did not get a HELLO, just do nothing.
628 * @param cls the 'struct GSC_KeyExchangeInfo' to retry sending the key for
629 * @param peer the peer for which this is the HELLO
630 * @param hello HELLO message of that peer
631 * @param err_msg NULL if successful, otherwise contains error message
634 process_hello (void *cls, const struct GNUNET_PeerIdentity *peer,
635 const struct GNUNET_HELLO_Message *hello, const char *err_msg)
637 struct GSC_KeyExchangeInfo *kx = cls;
638 struct SetKeyMessage *skm;
642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
643 _("Error in communication with PEERINFO service\n"));
645 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
646 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
647 kx->retry_set_key_task =
648 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
649 &set_key_retry_task, kx);
655 if (kx->public_key != NULL)
656 return; /* done here */
657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
658 "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n",
659 GNUNET_i2s (&kx->peer));
660 GNUNET_STATISTICS_update (GSC_stats,
662 ("# Delayed connecting due to lack of public key"),
664 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
665 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
666 kx->retry_set_key_task =
667 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
668 &set_key_retry_task, kx);
671 if (kx->public_key != NULL)
673 /* already have public key, why are we here? */
677 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->retry_set_key_task);
679 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
680 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, kx->public_key))
683 GNUNET_free (kx->public_key);
684 kx->public_key = NULL;
688 if (NULL != kx->skm_received)
690 skm = kx->skm_received;
691 kx->skm_received = NULL;
692 GSC_KX_handle_set_key (kx, &skm->header);
699 * Start the key exchange with the given peer.
701 * @param pid identity of the peer to do a key exchange with
702 * @return key exchange information context
704 struct GSC_KeyExchangeInfo *
705 GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
707 struct GSC_KeyExchangeInfo *kx;
709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initiating key exchange with `%s'\n",
711 GNUNET_STATISTICS_update (GSC_stats,
712 gettext_noop ("# key exchanges initiated"), 1,
714 kx = GNUNET_malloc (sizeof (struct GSC_KeyExchangeInfo));
716 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
718 GNUNET_PEERINFO_iterate (peerinfo, pid,
719 GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ ,
726 * Stop key exchange with the given peer. Clean up key material.
728 * @param kx key exchange to stop
731 GSC_KX_stop (struct GSC_KeyExchangeInfo *kx)
733 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges stopped"),
735 if (kx->pitr != NULL)
737 GNUNET_PEERINFO_iterate_cancel (kx->pitr);
740 if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
742 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
743 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
745 if (kx->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
747 GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
748 kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
750 GNUNET_free_non_null (kx->skm_received);
751 GNUNET_free_non_null (kx->ping_received);
752 GNUNET_free_non_null (kx->pong_received);
753 GNUNET_free_non_null (kx->emsg_received);
754 GNUNET_free_non_null (kx->public_key);
760 * We received a SET_KEY message. Validate and update
761 * our key material and status.
763 * @param kx key exchange status for the corresponding peer
764 * @param msg the set key message we received
767 GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx,
768 const struct GNUNET_MessageHeader *msg)
770 const struct SetKeyMessage *m;
771 struct GNUNET_TIME_Absolute t;
772 struct GNUNET_CRYPTO_AesSessionKey k;
773 struct PingMessage *ping;
774 struct PongMessage *pong;
775 enum KxStateMachine sender_status;
778 size = ntohs (msg->size);
779 if (size != sizeof (struct SetKeyMessage))
784 m = (const struct SetKeyMessage *) msg;
785 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# session keys received"),
788 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
789 "Core service receives `%s' request from `%4s'.\n", "SET_KEY",
790 GNUNET_i2s (&kx->peer));
791 if (kx->public_key == NULL)
793 GNUNET_free_non_null (kx->skm_received);
794 kx->skm_received = (struct SetKeyMessage *) GNUNET_copy_message (msg);
798 memcmp (&m->target, &GSC_my_identity,
799 sizeof (struct GNUNET_PeerIdentity)))
801 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
802 _("`%s' is for `%s', not for me. Ignoring.\n"), "SET_KEY",
803 GNUNET_i2s (&m->target));
806 if ((ntohl (m->purpose.size) !=
807 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
808 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
809 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
810 sizeof (struct GNUNET_PeerIdentity)) ||
812 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose,
813 &m->signature, kx->public_key)))
815 /* invalid signature */
819 t = GNUNET_TIME_absolute_ntoh (m->creation_time);
820 if (((kx->status == KX_STATE_KEY_RECEIVED) || (kx->status == KX_STATE_UP)) &&
821 (t.abs_value < kx->decrypt_key_created.abs_value))
823 /* this could rarely happen due to massive re-ordering of
824 * messages on the network level, but is most likely either
825 * a bug or some adversary messing with us. Report. */
829 if ((GNUNET_CRYPTO_rsa_decrypt
830 (my_private_key, &m->encrypted_key, &k,
831 sizeof (struct GNUNET_CRYPTO_AesSessionKey)) !=
832 sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
833 (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
835 /* failed to decrypt !? */
839 GNUNET_STATISTICS_update (GSC_stats,
840 gettext_noop ("# SET_KEY messages decrypted"), 1,
842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received SET_KEY from `%s'\n",
843 GNUNET_i2s (&kx->peer));
845 if (kx->decrypt_key_created.abs_value != t.abs_value)
847 /* fresh key, reset sequence numbers */
848 kx->last_sequence_number_received = 0;
849 kx->last_packets_bitmap = 0;
850 kx->decrypt_key_created = t;
852 sender_status = (enum KxStateMachine) ntohl (m->sender_status);
856 kx->status = KX_STATE_KEY_RECEIVED;
857 /* we're not up, so we are already doing 'send_key' */
859 case KX_STATE_KEY_SENT:
860 kx->status = KX_STATE_KEY_RECEIVED;
861 /* we're not up, so we are already doing 'send_key' */
863 case KX_STATE_KEY_RECEIVED:
864 /* we're not up, so we are already doing 'send_key' */
867 if ((sender_status == KX_STATE_DOWN) ||
868 (sender_status == KX_STATE_KEY_SENT))
869 send_key (kx); /* we are up, but other peer is not! */
872 if ((sender_status == KX_STATE_DOWN) ||
873 (sender_status == KX_STATE_KEY_SENT))
874 send_key (kx); /* we are up, but other peer is not! */
876 case KX_STATE_REKEY_SENT:
877 if ((sender_status == KX_STATE_DOWN) ||
878 (sender_status == KX_STATE_KEY_SENT))
879 send_key (kx); /* we are up, but other peer is not! */
885 if (kx->ping_received != NULL)
887 ping = kx->ping_received;
888 kx->ping_received = NULL;
889 GSC_KX_handle_ping (kx, &ping->header);
892 if (kx->pong_received != NULL)
894 pong = kx->pong_received;
895 kx->pong_received = NULL;
896 GSC_KX_handle_pong (kx, &pong->header);
903 * We received a PING message. Validate and transmit
906 * @param kx key exchange status for the corresponding peer
907 * @param msg the encrypted PING message itself
910 GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
911 const struct GNUNET_MessageHeader *msg)
913 const struct PingMessage *m;
914 struct PingMessage t;
915 struct PongMessage tx;
916 struct PongMessage tp;
917 struct GNUNET_CRYPTO_AesInitializationVector iv;
920 msize = ntohs (msg->size);
921 if (msize != sizeof (struct PingMessage))
926 GNUNET_STATISTICS_update (GSC_stats,
927 gettext_noop ("# PING messages received"), 1,
929 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
930 (kx->status != KX_STATE_REKEY_SENT))
933 GNUNET_free_non_null (kx->ping_received);
934 kx->ping_received = (struct PingMessage *) GNUNET_copy_message (msg);
937 m = (const struct PingMessage *) msg;
938 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
939 "Core service receives `%s' request from `%4s'.\n", "PING",
940 GNUNET_i2s (&kx->peer));
941 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
943 do_decrypt (kx, &iv, &m->target, &t.target,
944 sizeof (struct PingMessage) - ((void *) &m->target -
951 memcmp (&t.target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
956 GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&kx->peer));
957 GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target));
958 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
960 ("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"),
961 sender, GNUNET_i2s (&GSC_my_identity), peer);
965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PING from `%s'\n",
966 GNUNET_i2s (&kx->peer));
968 tx.reserved = GNUNET_BANDWIDTH_VALUE_MAX;
969 tx.challenge = t.challenge;
970 tx.target = t.target;
971 tp.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
972 tp.header.size = htons (sizeof (struct PongMessage));
974 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
975 derive_pong_iv (&iv, &kx->encrypt_key, tp.iv_seed, t.challenge, &kx->peer);
976 do_encrypt (kx, &iv, &tx.challenge, &tp.challenge,
977 sizeof (struct PongMessage) - ((void *) &tp.challenge -
979 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# PONG messages created"),
981 GSC_NEIGHBOURS_transmit (&kx->peer, &tp.header,
982 GNUNET_TIME_UNIT_FOREVER_REL /* FIXME: timeout */ );
987 * Create a fresh SET KEY message for transmission to the other peer.
988 * Also creates a new key.
990 * @param kx key exchange context to create SET KEY message for
993 setup_fresh_setkey (struct GSC_KeyExchangeInfo *kx)
995 struct SetKeyMessage *skm;
997 GNUNET_CRYPTO_aes_create_session_key (&kx->encrypt_key);
998 kx->encrypt_key_created = GNUNET_TIME_absolute_get ();
1000 skm->header.size = htons (sizeof (struct SetKeyMessage));
1001 skm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
1003 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
1004 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1005 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
1006 sizeof (struct GNUNET_PeerIdentity));
1007 skm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
1008 skm->creation_time = GNUNET_TIME_absolute_hton (kx->encrypt_key_created);
1009 skm->target = kx->peer;
1010 GNUNET_assert (GNUNET_OK ==
1011 GNUNET_CRYPTO_rsa_encrypt (&kx->encrypt_key,
1013 GNUNET_CRYPTO_AesSessionKey),
1015 &skm->encrypted_key));
1016 GNUNET_assert (GNUNET_OK ==
1017 GNUNET_CRYPTO_rsa_sign (my_private_key, &skm->purpose,
1023 * Create a fresh PING message for transmission to the other peer.
1025 * @param kx key exchange context to create PING for
1028 setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
1030 struct PingMessage pp;
1031 struct PingMessage *pm;
1032 struct GNUNET_CRYPTO_AesInitializationVector iv;
1035 pm->header.size = htons (sizeof (struct PingMessage));
1036 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1038 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
1039 derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, &kx->peer);
1040 pp.challenge = kx->ping_challenge;
1041 pp.target = kx->peer;
1042 do_encrypt (kx, &iv, &pp.target, &pm->target,
1043 sizeof (struct PingMessage) - ((void *) &pm->target -
1049 * Task triggered when a neighbour entry is about to time out
1050 * (and we should prevent this by sending a PING).
1052 * @param cls the 'struct GSC_KeyExchangeInfo'
1053 * @param tc scheduler context (not used)
1056 send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1058 struct GSC_KeyExchangeInfo *kx = cls;
1059 struct GNUNET_TIME_Relative retry;
1060 struct GNUNET_TIME_Relative left;
1062 kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
1063 left = GNUNET_TIME_absolute_get_remaining (kx->timeout);
1064 if (left.rel_value == 0)
1066 GNUNET_STATISTICS_update (GSC_stats,
1067 gettext_noop ("# sessions terminated by timeout"),
1069 GSC_SESSIONS_end (&kx->peer);
1070 kx->status = KX_STATE_DOWN;
1073 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending KEEPALIVE to `%s'\n",
1074 GNUNET_i2s (&kx->peer));
1075 GNUNET_STATISTICS_update (GSC_stats,
1076 gettext_noop ("# keepalive messages sent"), 1,
1078 setup_fresh_ping (kx);
1079 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
1080 kx->set_key_retry_frequency);
1082 GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2),
1083 MIN_PING_FREQUENCY);
1084 kx->keep_alive_task =
1085 GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, kx);
1090 * We've seen a valid message from the other peer.
1091 * Update the time when the session would time out
1092 * and delay sending our keep alive message further.
1094 * @param kx key exchange where we saw activity
1097 update_timeout (struct GSC_KeyExchangeInfo *kx)
1100 GNUNET_TIME_relative_to_absolute
1101 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1102 if (kx->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
1103 GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1104 kx->keep_alive_task =
1105 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
1106 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1107 2), &send_keep_alive, kx);
1112 * Trigger rekeying event.
1114 * @param cls the 'struct GSC_KeyExchangeInfo'
1115 * @param tc schedule context (unused)
1118 trigger_rekey (void *cls,
1119 const struct GNUNET_SCHEDULER_TaskContext *tc)
1121 struct GSC_KeyExchangeInfo *kx = cls;
1123 kx->status = KX_STATE_REKEY;
1124 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
1125 kx->retry_set_key_task =
1126 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
1127 &set_key_retry_task, kx);
1132 * Schedule rekey operation.
1134 * @param kx key exchange to schedule rekey for
1137 schedule_rekey (struct GSC_KeyExchangeInfo *kx)
1139 struct GNUNET_TIME_Relative rdelay;
1141 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
1142 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1143 rdelay = REKEY_FREQUENCY;
1144 /* randomize rekey frequency by one minute to avoid synchronization */
1145 rdelay.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1147 kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1154 * We received a PONG message. Validate and update our status.
1156 * @param kx key exchange context for the the PONG
1157 * @param msg the encrypted PONG message itself
1160 GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1161 const struct GNUNET_MessageHeader *msg)
1163 const struct PongMessage *m;
1164 struct PongMessage t;
1165 struct EncryptedMessage *emsg;
1166 struct GNUNET_CRYPTO_AesInitializationVector iv;
1169 msize = ntohs (msg->size);
1170 if (msize != sizeof (struct PongMessage))
1172 GNUNET_break_op (0);
1175 GNUNET_STATISTICS_update (GSC_stats,
1176 gettext_noop ("# PONG messages received"), 1,
1182 case KX_STATE_KEY_SENT:
1183 GNUNET_free_non_null (kx->pong_received);
1184 kx->pong_received = (struct PongMessage *) GNUNET_copy_message (msg);
1186 case KX_STATE_KEY_RECEIVED:
1190 case KX_STATE_REKEY:
1192 case KX_STATE_REKEY_SENT:
1198 m = (const struct PongMessage *) msg;
1199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1200 "Core service receives `%s' response from `%4s'.\n", "PONG",
1201 GNUNET_i2s (&kx->peer));
1202 /* mark as garbage, just to be sure */
1203 memset (&t, 255, sizeof (t));
1204 derive_pong_iv (&iv, &kx->decrypt_key, m->iv_seed, kx->ping_challenge,
1207 do_decrypt (kx, &iv, &m->challenge, &t.challenge,
1208 sizeof (struct PongMessage) - ((void *) &m->challenge -
1211 GNUNET_break_op (0);
1214 GNUNET_STATISTICS_update (GSC_stats,
1215 gettext_noop ("# PONG messages decrypted"), 1,
1217 if ((0 != memcmp (&t.target, &kx->peer, sizeof (struct GNUNET_PeerIdentity)))
1218 || (kx->ping_challenge != t.challenge))
1220 /* PONG malformed */
1221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1222 "Received malformed `%s' wanted sender `%4s' with challenge %u\n",
1223 "PONG", GNUNET_i2s (&kx->peer),
1224 (unsigned int) kx->ping_challenge);
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1226 "Received malformed `%s' received from `%4s' with challenge %u\n",
1227 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge);
1230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n",
1231 GNUNET_i2s (&kx->peer));
1235 GNUNET_break (0); /* should be impossible */
1237 case KX_STATE_KEY_SENT:
1238 GNUNET_break (0); /* should be impossible */
1240 case KX_STATE_KEY_RECEIVED:
1241 GNUNET_STATISTICS_update (GSC_stats,
1243 ("# session keys confirmed via PONG"), 1,
1245 kx->status = KX_STATE_UP;
1246 GSC_SESSIONS_create (&kx->peer, kx);
1247 schedule_rekey (kx);
1248 GNUNET_assert (kx->keep_alive_task == GNUNET_SCHEDULER_NO_TASK);
1249 if (kx->emsg_received != NULL)
1251 emsg = kx->emsg_received;
1252 kx->emsg_received = NULL;
1253 GSC_KX_handle_encrypted_message (kx, &emsg->header, NULL,
1254 0 /* FIXME: ATSI */ );
1257 update_timeout (kx);
1260 update_timeout (kx);
1262 case KX_STATE_REKEY:
1263 update_timeout (kx);
1265 case KX_STATE_REKEY_SENT:
1266 GNUNET_STATISTICS_update (GSC_stats,
1268 ("# rekey operations confirmed via PONG"), 1,
1270 kx->status = KX_STATE_UP;
1271 schedule_rekey (kx);
1272 update_timeout (kx);
1282 * Send our key (and encrypted PING) to the other peer.
1284 * @param kx key exchange context
1287 send_key (struct GSC_KeyExchangeInfo *kx)
1289 GNUNET_assert (kx->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK);
1290 if (KX_STATE_UP == kx->status)
1291 return; /* nothing to do */
1292 if (kx->public_key == NULL)
1294 /* lookup public key, then try again */
1295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1296 "Trying to obtain public key for `%s'\n",
1297 GNUNET_i2s (&kx->peer));
1299 GNUNET_PEERINFO_iterate (peerinfo, &kx->peer,
1300 GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ ,
1301 &process_hello, kx);
1309 kx->status = KX_STATE_KEY_SENT;
1310 /* setup SET KEY message */
1311 setup_fresh_setkey (kx);
1312 setup_fresh_ping (kx);
1313 GNUNET_STATISTICS_update (GSC_stats,
1315 ("# SET_KEY and PING messages created"), 1,
1318 case KX_STATE_KEY_SENT:
1320 case KX_STATE_KEY_RECEIVED:
1325 case KX_STATE_REKEY:
1326 kx->status = KX_STATE_REKEY_SENT;
1327 /* setup fresh SET KEY message */
1328 setup_fresh_setkey (kx);
1329 setup_fresh_ping (kx);
1330 GNUNET_STATISTICS_update (GSC_stats,
1332 ("# SET_KEY and PING messages created"), 1,
1334 GNUNET_STATISTICS_update (GSC_stats,
1336 ("# REKEY operations performed"), 1,
1339 case KX_STATE_REKEY_SENT:
1346 /* always update sender status in SET KEY message */
1347 /* Not sending rekey sent state to be compatible with GNUnet 0.9.2 */
1348 kx->skm.sender_status = htonl ((int32_t) ((kx->status == KX_STATE_REKEY_SENT) ?
1349 KX_STATE_KEY_RECEIVED : kx->status));
1350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SET_KEY and PING to `%s'\n",
1351 GNUNET_i2s (&kx->peer));
1352 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->skm.header,
1353 kx->set_key_retry_frequency);
1354 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
1355 kx->set_key_retry_frequency);
1356 kx->retry_set_key_task =
1357 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
1358 &set_key_retry_task, kx);
1363 * Encrypt and transmit a message with the given payload.
1365 * @param kx key exchange context
1366 * @param payload payload of the message
1367 * @param payload_size number of bytes in 'payload'
1370 GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1371 const void *payload, size_t payload_size)
1373 size_t used = payload_size + sizeof (struct EncryptedMessage);
1374 char pbuf[used]; /* plaintext */
1375 char cbuf[used]; /* ciphertext */
1376 struct EncryptedMessage *em; /* encrypted message */
1377 struct EncryptedMessage *ph; /* plaintext header */
1378 struct GNUNET_CRYPTO_AesInitializationVector iv;
1379 struct GNUNET_CRYPTO_AuthKey auth_key;
1381 ph = (struct EncryptedMessage *) pbuf;
1383 htonl (GNUNET_CRYPTO_random_u32
1384 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
1385 ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1386 ph->reserved = GNUNET_BANDWIDTH_VALUE_MAX;
1387 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1388 memcpy (&ph[1], payload, payload_size);
1390 em = (struct EncryptedMessage *) cbuf;
1391 em->header.size = htons (used);
1392 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1393 em->iv_seed = ph->iv_seed;
1394 derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, &kx->peer);
1395 GNUNET_assert (GNUNET_OK ==
1396 do_encrypt (kx, &iv, &ph->sequence_number,
1397 &em->sequence_number,
1398 used - ENCRYPTED_HEADER_SIZE));
1399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n",
1400 used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer));
1401 derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed,
1402 kx->encrypt_key_created);
1403 GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
1404 used - ENCRYPTED_HEADER_SIZE, &em->hmac);
1405 GSC_NEIGHBOURS_transmit (&kx->peer, &em->header,
1406 GNUNET_TIME_UNIT_FOREVER_REL);
1411 * Closure for 'deliver_message'
1413 struct DeliverMessageContext
1417 * Performance information for the connection.
1419 const struct GNUNET_ATS_Information *atsi;
1422 * Sender of the message.
1424 const struct GNUNET_PeerIdentity *peer;
1427 * Number of entries in 'atsi' array.
1429 uint32_t atsi_count;
1434 * We received an encrypted message. Decrypt, validate and
1435 * pass on to the appropriate clients.
1437 * @param kx key exchange context for encrypting the message
1438 * @param msg encrypted message
1439 * @param atsi performance data
1440 * @param atsi_count number of entries in ats (excluding 0-termination)
1443 GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1444 const struct GNUNET_MessageHeader *msg,
1445 const struct GNUNET_ATS_Information *atsi,
1446 uint32_t atsi_count)
1448 const struct EncryptedMessage *m;
1449 struct EncryptedMessage *pt; /* plaintext */
1452 struct GNUNET_TIME_Absolute t;
1453 struct GNUNET_CRYPTO_AesInitializationVector iv;
1454 struct GNUNET_CRYPTO_AuthKey auth_key;
1455 struct DeliverMessageContext dmc;
1456 uint16_t size = ntohs (msg->size);
1460 sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
1462 GNUNET_break_op (0);
1465 m = (const struct EncryptedMessage *) msg;
1466 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
1467 (kx->status != KX_STATE_REKEY_SENT) )
1469 GNUNET_STATISTICS_update (GSC_stats,
1471 ("# failed to decrypt message (no session key)"),
1475 if (kx->status == KX_STATE_KEY_RECEIVED)
1478 GNUNET_free_non_null (kx->ping_received);
1479 kx->emsg_received = (struct EncryptedMessage *) GNUNET_copy_message (msg);
1483 derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed,
1484 kx->decrypt_key_created);
1485 GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number,
1486 size - ENCRYPTED_HEADER_SIZE, &ph);
1487 if (0 != memcmp (&ph, &m->hmac, sizeof (GNUNET_HashCode)))
1489 /* checksum failed */
1490 GNUNET_break_op (0);
1493 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1496 do_decrypt (kx, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE],
1497 size - ENCRYPTED_HEADER_SIZE))
1499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted %u bytes from %s\n",
1500 size - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer));
1501 pt = (struct EncryptedMessage *) buf;
1503 /* validate sequence number */
1504 snum = ntohl (pt->sequence_number);
1505 if (kx->last_sequence_number_received == snum)
1507 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1508 "Received duplicate message, ignoring.\n");
1509 /* duplicate, ignore */
1510 GNUNET_STATISTICS_update (GSC_stats,
1511 gettext_noop ("# bytes dropped (duplicates)"),
1515 if ((kx->last_sequence_number_received > snum) &&
1516 (kx->last_sequence_number_received - snum > 32))
1518 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1519 "Received ancient out of sequence message, ignoring.\n");
1520 /* ancient out of sequence, ignore */
1521 GNUNET_STATISTICS_update (GSC_stats,
1523 ("# bytes dropped (out of sequence)"), size,
1527 if (kx->last_sequence_number_received > snum)
1529 unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1);
1531 if ((kx->last_packets_bitmap & rotbit) != 0)
1533 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1534 "Received duplicate message, ignoring.\n");
1535 GNUNET_STATISTICS_update (GSC_stats,
1536 gettext_noop ("# bytes dropped (duplicates)"),
1538 /* duplicate, ignore */
1541 kx->last_packets_bitmap |= rotbit;
1543 if (kx->last_sequence_number_received < snum)
1545 unsigned int shift = (snum - kx->last_sequence_number_received);
1547 if (shift >= 8 * sizeof (kx->last_packets_bitmap))
1548 kx->last_packets_bitmap = 0;
1550 kx->last_packets_bitmap <<= shift;
1551 kx->last_sequence_number_received = snum;
1554 /* check timestamp */
1555 t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
1556 if (GNUNET_TIME_absolute_get_duration (t).rel_value >
1557 MAX_MESSAGE_AGE.rel_value)
1559 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1560 _("Message received far too old (%llu ms). Content ignored.\n"),
1561 GNUNET_TIME_absolute_get_duration (t).rel_value);
1562 GNUNET_STATISTICS_update (GSC_stats,
1564 ("# bytes dropped (ancient message)"), size,
1569 /* process decrypted message(s) */
1570 update_timeout (kx);
1571 GNUNET_STATISTICS_update (GSC_stats,
1572 gettext_noop ("# bytes of payload decrypted"),
1573 size - sizeof (struct EncryptedMessage), GNUNET_NO);
1575 dmc.atsi_count = atsi_count;
1576 dmc.peer = &kx->peer;
1578 GNUNET_SERVER_mst_receive (mst, &dmc,
1579 &buf[sizeof (struct EncryptedMessage)],
1580 size - sizeof (struct EncryptedMessage),
1581 GNUNET_YES, GNUNET_NO))
1582 GNUNET_break_op (0);
1587 * Deliver P2P message to interested clients.
1588 * Invokes send twice, once for clients that want the full message, and once
1589 * for clients that only want the header
1591 * @param cls always NULL
1592 * @param client who sent us the message (struct GSC_KeyExchangeInfo)
1593 * @param m the message
1596 deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
1598 struct DeliverMessageContext *dmc = client;
1600 switch (ntohs (m->type))
1602 case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
1603 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
1604 GSC_SESSIONS_set_typemap (dmc->peer, m);
1607 GSC_CLIENTS_deliver_message (dmc->peer, dmc->atsi, dmc->atsi_count, m,
1609 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
1610 GSC_CLIENTS_deliver_message (dmc->peer, dmc->atsi, dmc->atsi_count, m,
1611 sizeof (struct GNUNET_MessageHeader),
1612 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
1618 * Initialize KX subsystem.
1620 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1628 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
1631 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1633 ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
1634 return GNUNET_SYSERR;
1636 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1637 GNUNET_free (keyfile);
1638 if (my_private_key == NULL)
1640 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1641 _("Core service could not access hostkey. Exiting.\n"));
1642 return GNUNET_SYSERR;
1644 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
1645 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
1646 &GSC_my_identity.hashPubKey);
1647 peerinfo = GNUNET_PEERINFO_connect (GSC_cfg);
1648 if (NULL == peerinfo)
1650 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1651 _("Could not access PEERINFO service. Exiting.\n"));
1652 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1653 my_private_key = NULL;
1654 return GNUNET_SYSERR;
1656 mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
1662 * Shutdown KX subsystem.
1667 if (my_private_key != NULL)
1669 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1670 my_private_key = NULL;
1672 if (peerinfo != NULL)
1674 GNUNET_PEERINFO_disconnect (peerinfo);
1679 GNUNET_SERVER_mst_destroy (mst);
1684 /* end of gnunet-service-core_kx.c */