GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-core_kx.c File Reference

code for managing the key exchange (SET_KEY, PING, PONG) with other peers More...

#include "platform.h"
#include "gnunet-service-core_kx.h"
#include "gnunet-service-core.h"
#include "gnunet-service-core_sessions.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
#include "gnunet_constants.h"
#include "gnunet_signatures.h"
#include "gnunet_protocols.h"
#include "core.h"
Include dependency graph for gnunet-service-core_kx.c:

Go to the source code of this file.

Data Structures

struct  EphemeralKeyMessage
 Message transmitted with the signed ephemeral key of a peer. More...
 
struct  PingMessage
 We're sending an (encrypted) PING to the other peer to check if it can decrypt. More...
 
struct  PongMessage
 Response to a PING. More...
 
struct  EncryptedMessage
 Encapsulation for encrypted messages exchanged between peers. More...
 
struct  GSC_KeyExchangeInfo
 Information about the status of a key exchange with another peer. More...
 

Macros

#define DEBUG_KX   0
 Enable expensive (and possibly problematic for privacy!) logging of KX. More...
 
#define INITIAL_SET_KEY_RETRY_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
 How long do we wait for SET_KEY confirmation initially? More...
 
#define MIN_PING_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
 What is the minimum frequency for a PING message? More...
 
#define REKEY_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
 How often do we rekey? More...
 
#define REKEY_TOLERANCE   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 What time difference do we tolerate? More...
 
#define MAX_MESSAGE_AGE   GNUNET_TIME_UNIT_DAYS
 What is the maximum age of a message for us to consider processing it? Note that this looks at the timestamp used by the other peer, so clock skew between machines does come into play here. More...
 
#define ENCRYPTED_HEADER_SIZE   (offsetof (struct EncryptedMessage, sequence_number))
 Number of bytes (at the beginning) of struct EncryptedMessage that are NOT encrypted. More...
 

Functions

static uint32_t calculate_seed (struct GSC_KeyExchangeInfo *kx)
 Calculate seed value we should use for a message. More...
 
static void monitor_notify_all (struct GSC_KeyExchangeInfo *kx)
 Inform all monitors about the KX state of the given peer. More...
 
static void derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed)
 Derive an authentication key from "set key" information. More...
 
static void derive_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, const struct GNUNET_PeerIdentity *identity)
 Derive an IV from packet information. More...
 
static void derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
 Derive an IV from pong packet information. More...
 
static void derive_aes_key (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_PeerIdentity *receiver, const struct GNUNET_HashCode *key_material, struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
 Derive an AES key from key material. More...
 
static int do_encrypt (struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
 Encrypt size bytes from in and write the result to out. More...
 
static int do_decrypt (struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
 Decrypt size bytes from in and write the result to out. More...
 
static void send_key (struct GSC_KeyExchangeInfo *kx)
 Send our key (and encrypted PING) to the other peer. More...
 
static void set_key_retry_task (void *cls)
 Task that will retry send_key() if our previous attempt failed. More...
 
static void setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
 Create a fresh PING message for transmission to the other peer. More...
 
static int deliver_message (void *cls, const struct GNUNET_MessageHeader *m)
 Deliver P2P message to interested clients. More...
 
static void * handle_transport_notify_connect (void *cls, const struct GNUNET_PeerIdentity *pid, struct GNUNET_MQ_Handle *mq)
 Function called by transport to notify us that a peer connected to us (on the network level). More...
 
static void handle_transport_notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer, void *handler_cls)
 Function called by transport telling us that a peer disconnected. More...
 
static void send_ping (struct GSC_KeyExchangeInfo *kx)
 Send our PING to the other peer. More...
 
static void derive_session_keys (struct GSC_KeyExchangeInfo *kx)
 Derive fresh session keys from the current ephemeral keys. More...
 
static void handle_ephemeral_key (void *cls, const struct EphemeralKeyMessage *m)
 We received a GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY message. More...
 
static void handle_ping (void *cls, const struct PingMessage *m)
 We received a PING message. More...
 
static void send_keep_alive (void *cls)
 Task triggered when a neighbour entry is about to time out (and we should prevent this by sending a PING). More...
 
static void update_timeout (struct GSC_KeyExchangeInfo *kx)
 We've seen a valid message from the other peer. More...
 
static void handle_pong (void *cls, const struct PongMessage *m)
 We received a PONG message. More...
 
void GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, const void *payload, size_t payload_size)
 Encrypt and transmit a message with the given payload. More...
 
static int check_encrypted (void *cls, const struct EncryptedMessage *m)
 We received an encrypted message. More...
 
static void handle_encrypted (void *cls, const struct EncryptedMessage *m)
 We received an encrypted message. More...
 
static void handle_transport_notify_excess_bw (void *cls, const struct GNUNET_PeerIdentity *pid, void *connect_cls)
 One of our neighbours has excess bandwidth, remember this. More...
 
static void sign_ephemeral_key ()
 Setup the message that links the ephemeral key to our persistent public key and generate the appropriate signature. More...
 
static void do_rekey (void *cls)
 Task run to trigger rekeying. More...
 
int GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
 Initialize KX subsystem. More...
 
void GSC_KX_done ()
 Shutdown KX subsystem. More...
 
unsigned int GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *kxinfo)
 Check how many messages are queued for the given neighbour. More...
 
int GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *kxinfo)
 Check if the given neighbour has excess bandwidth available. More...
 
void GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
 Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. More...
 

Variables

static struct GNUNET_TRANSPORT_CoreHandletransport
 Transport service. More...
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Our private key. More...
 
static struct GNUNET_CRYPTO_EcdhePrivateKeymy_ephemeral_key
 Our ephemeral private key. More...
 
static struct EphemeralKeyMessage current_ekm
 Current message we send for a key exchange. More...
 
static struct GSC_KeyExchangeInfokx_head
 DLL head. More...
 
static struct GSC_KeyExchangeInfokx_tail
 DLL tail. More...
 
static struct GNUNET_SCHEDULER_Taskrekey_task
 Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key. More...
 
static struct GNUNET_NotificationContextnc
 Notification context for broadcasting to monitors. More...
 

Detailed Description

code for managing the key exchange (SET_KEY, PING, PONG) with other peers

Author
Christian Grothoff

Definition in file gnunet-service-core_kx.c.

Macro Definition Documentation

◆ DEBUG_KX

#define DEBUG_KX   0

Enable expensive (and possibly problematic for privacy!) logging of KX.

Definition at line 41 of file gnunet-service-core_kx.c.

◆ INITIAL_SET_KEY_RETRY_FREQUENCY

#define INITIAL_SET_KEY_RETRY_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)

How long do we wait for SET_KEY confirmation initially?

Definition at line 46 of file gnunet-service-core_kx.c.

Referenced by handle_transport_notify_connect().

◆ MIN_PING_FREQUENCY

#define MIN_PING_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)

What is the minimum frequency for a PING message?

Definition at line 52 of file gnunet-service-core_kx.c.

Referenced by send_keep_alive().

◆ REKEY_FREQUENCY

#define REKEY_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)

How often do we rekey?

Definition at line 58 of file gnunet-service-core_kx.c.

Referenced by do_rekey(), GSC_KX_init(), and sign_ephemeral_key().

◆ REKEY_TOLERANCE

#define REKEY_TOLERANCE   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

What time difference do we tolerate?

Definition at line 64 of file gnunet-service-core_kx.c.

Referenced by handle_ephemeral_key(), and sign_ephemeral_key().

◆ MAX_MESSAGE_AGE

#define MAX_MESSAGE_AGE   GNUNET_TIME_UNIT_DAYS

What is the maximum age of a message for us to consider processing it? Note that this looks at the timestamp used by the other peer, so clock skew between machines does come into play here.

So this should be picked high enough so that a little bit of clock skew does not prevent peers from connecting to us.

Definition at line 74 of file gnunet-service-core_kx.c.

Referenced by handle_encrypted().

◆ ENCRYPTED_HEADER_SIZE

#define ENCRYPTED_HEADER_SIZE   (offsetof (struct EncryptedMessage, sequence_number))

Number of bytes (at the beginning) of struct EncryptedMessage that are NOT encrypted.

Definition at line 241 of file gnunet-service-core_kx.c.

Referenced by GSC_KX_encrypt_and_transmit(), and handle_encrypted().

Function Documentation

◆ calculate_seed()

static uint32_t calculate_seed ( struct GSC_KeyExchangeInfo kx)
static

Calculate seed value we should use for a message.

Parameters
kxkey exchange context

Definition at line 409 of file gnunet-service-core_kx.c.

References GNUNET_CRYPTO_QUALITY_NONCE, and GNUNET_CRYPTO_random_u32().

Referenced by GSC_KX_encrypt_and_transmit(), handle_ping(), and setup_fresh_ping().

410 {
411  /* Note: may want to make this non-random and instead
412  derive from key material to avoid having an undetectable
413  side-channel */
414  return htonl (
416 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
Randomness for IVs etc.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ monitor_notify_all()

static void monitor_notify_all ( struct GSC_KeyExchangeInfo kx)
static

Inform all monitors about the KX state of the given peer.

Parameters
kxkey exchange state to inform about

Definition at line 425 of file gnunet-service-core_kx.c.

References GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY, GNUNET_NO, GNUNET_notification_context_broadcast(), GNUNET_TIME_absolute_hton(), MonitorNotifyMessage::header, GSC_KeyExchangeInfo::last_notify_timeout, GSC_KeyExchangeInfo::peer, MonitorNotifyMessage::peer, GNUNET_MessageHeader::size, MonitorNotifyMessage::state, GSC_KeyExchangeInfo::status, GSC_KeyExchangeInfo::timeout, MonitorNotifyMessage::timeout, and GNUNET_MessageHeader::type.

Referenced by do_rekey(), handle_encrypted(), handle_ephemeral_key(), handle_pong(), handle_transport_notify_connect(), handle_transport_notify_disconnect(), send_keep_alive(), and update_timeout().

426 {
427  struct MonitorNotifyMessage msg;
428 
430  msg.header.size = htons (sizeof(msg));
431  msg.state = htonl ((uint32_t) kx->status);
432  msg.peer = *kx->peer;
433  msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
435  kx->last_notify_timeout = kx->timeout;
436 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_TIME_Absolute last_notify_timeout
What was the last timeout we informed our monitors about?
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:189
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no PONGs)?
Message sent by the service to monitor clients to notify them about a peer changing status...
Definition: core.h:302
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY
Reply for monitor by CORE service.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ derive_auth_key()

static void derive_auth_key ( struct GNUNET_CRYPTO_AuthKey akey,
const struct GNUNET_CRYPTO_SymmetricSessionKey skey,
uint32_t  seed 
)
static

Derive an authentication key from "set key" information.

Parameters
akeyauthentication key to derive
skeysession key to use
seedseed to use

Definition at line 447 of file gnunet-service-core_kx.c.

References ctx, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hmac_derive_key(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), and GNUNET_log.

Referenced by GSC_KX_encrypt_and_transmit(), and handle_encrypted().

450 {
451  static const char ctx[] = "authentication key";
452 
453 #if DEBUG_KX
454  struct GNUNET_HashCode sh;
455 
456  GNUNET_CRYPTO_hash (skey, sizeof(*skey), &sh);
458  "Deriving Auth key from SKEY %s and seed %u\n",
459  GNUNET_h2s (&sh),
460  (unsigned int) seed);
461 #endif
463  skey,
464  &seed,
465  sizeof(seed),
466  skey,
467  sizeof(
469  ctx,
470  sizeof(ctx),
471  NULL);
472 }
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct SolverHandle * sh
A 512-bit hashcode.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len,...)
Derive an authentication key.
Definition: crypto_hash.c:356
Here is the call graph for this function:
Here is the caller graph for this function:

◆ derive_iv()

static void derive_iv ( struct GNUNET_CRYPTO_SymmetricInitializationVector iv,
const struct GNUNET_CRYPTO_SymmetricSessionKey skey,
uint32_t  seed,
const struct GNUNET_PeerIdentity identity 
)
static

Derive an IV from packet information.

Parameters
ivinitialization vector to initialize
skeysession key to use
seedseed to use
identityidentity of the other peer to use

Definition at line 484 of file gnunet-service-core_kx.c.

References ctx, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_symmetric_derive_iv(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), and GNUNET_log.

Referenced by GSC_KX_encrypt_and_transmit(), handle_encrypted(), handle_ping(), and setup_fresh_ping().

488 {
489  static const char ctx[] = "initialization vector";
490 
491 #if DEBUG_KX
492  struct GNUNET_HashCode sh;
493 
494  GNUNET_CRYPTO_hash (skey, sizeof(*skey), &sh);
496  "Deriving IV from SKEY %s and seed %u for peer %s\n",
497  GNUNET_h2s (&sh),
498  (unsigned int) seed,
499  GNUNET_i2s (identity));
500 #endif
502  skey,
503  &seed,
504  sizeof(seed),
505  identity,
506  sizeof(struct GNUNET_PeerIdentity),
507  ctx,
508  sizeof(ctx),
509  NULL);
510 }
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct SolverHandle * sh
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ derive_pong_iv()

static void derive_pong_iv ( struct GNUNET_CRYPTO_SymmetricInitializationVector iv,
const struct GNUNET_CRYPTO_SymmetricSessionKey skey,
uint32_t  seed,
uint32_t  challenge,
const struct GNUNET_PeerIdentity identity 
)
static

Derive an IV from pong packet information.

Parameters
ivinitialization vector to initialize
skeysession key to use
seedseed to use
challengenonce to use
identityidentity of the other peer to use

Definition at line 523 of file gnunet-service-core_kx.c.

References ctx, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_symmetric_derive_iv(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), and GNUNET_log.

Referenced by handle_ping(), and handle_pong().

528 {
529  static const char ctx[] = "pong initialization vector";
530 
531 #if DEBUG_KX
532  struct GNUNET_HashCode sh;
533 
534  GNUNET_CRYPTO_hash (skey, sizeof(*skey), &sh);
536  "Deriving PONG IV from SKEY %s and seed %u/%u for %s\n",
537  GNUNET_h2s (&sh),
538  (unsigned int) seed,
539  (unsigned int) challenge,
540  GNUNET_i2s (identity));
541 #endif
543  skey,
544  &seed,
545  sizeof(seed),
546  identity,
547  sizeof(struct GNUNET_PeerIdentity),
548  &challenge,
549  sizeof(challenge),
550  ctx,
551  sizeof(ctx),
552  NULL);
553 }
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct SolverHandle * sh
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ derive_aes_key()

static void derive_aes_key ( const struct GNUNET_PeerIdentity sender,
const struct GNUNET_PeerIdentity receiver,
const struct GNUNET_HashCode key_material,
struct GNUNET_CRYPTO_SymmetricSessionKey skey 
)
static

Derive an AES key from key material.

Parameters
senderpeer identity of the sender
receiverpeer identity of the sender
key_materialhigh entropy key material to use
skeyset to derived session key

Definition at line 565 of file gnunet-service-core_kx.c.

References ctx, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_kdf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_i2s2(), and GNUNET_log.

Referenced by derive_session_keys().

569 {
570  static const char ctx[] = "aes key generation vector";
571 
572 #if DEBUG_KX
573  struct GNUNET_HashCode sh;
574 
575  GNUNET_CRYPTO_hash (skey, sizeof(*skey), &sh);
577  "Deriving AES Keys for %s to %s from %s\n",
578  GNUNET_i2s (sender),
579  GNUNET_i2s2 (receiver),
580  GNUNET_h2s (key_material));
581 #endif
582  GNUNET_CRYPTO_kdf (skey,
583  sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
584  ctx,
585  sizeof(ctx),
586  key_material,
587  sizeof(struct GNUNET_HashCode),
588  sender,
589  sizeof(struct GNUNET_PeerIdentity),
590  receiver,
591  sizeof(struct GNUNET_PeerIdentity),
592  NULL);
593 }
const char * GNUNET_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct SolverHandle * sh
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_encrypt()

static int do_encrypt ( struct GSC_KeyExchangeInfo kx,
const struct GNUNET_CRYPTO_SymmetricInitializationVector iv,
const void *  in,
void *  out,
size_t  size 
)
static

Encrypt size bytes from in and write the result to out.

Use the kx key for outbound traffic of the given neighbour.

Parameters
kxkey information context
ivinitialization vector to use
inciphertext
outplaintext
sizesize of in/out GNUNET_OK on success

Definition at line 608 of file gnunet-service-core_kx.c.

References GSC_KeyExchangeInfo::encrypt_key, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_crc32_n(), GNUNET_CRYPTO_symmetric_encrypt(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GSC_stats, and GSC_KeyExchangeInfo::peer.

Referenced by GSC_KX_encrypt_and_transmit(), handle_ping(), and setup_fresh_ping().

613 {
614  if (size != (uint16_t) size)
615  {
616  GNUNET_break (0);
617  return GNUNET_NO;
618  }
620  (uint16_t) size,
621  &kx->encrypt_key,
622  iv,
623  out));
625  gettext_noop ("# bytes encrypted"),
626  size,
627  GNUNET_NO);
628  /* the following is too sensitive to write to log files by accident,
629  so we require manual intervention to get this one... */
630 #if DEBUG_KX
632  "Encrypted %u bytes for `%s' using key %u, IV %u\n",
633  (unsigned int) size,
634  GNUNET_i2s (kx->peer),
635  (unsigned int) kx->encrypt_key.crc32,
636  GNUNET_CRYPTO_crc32_n (iv, sizeof(iv)));
637 #endif
638  return GNUNET_OK;
639 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
int32_t GNUNET_CRYPTO_crc32_n(const void *buf, size_t len)
Compute the CRC32 checksum for the first len bytes of the buffer.
Definition: crypto_crc.c:106
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define GNUNET_log(kind,...)
struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key
Key we use to encrypt our messages for the other peer (initialized by us when we do the handshake)...
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_decrypt()

static int do_decrypt ( struct GSC_KeyExchangeInfo kx,
const struct GNUNET_CRYPTO_SymmetricInitializationVector iv,
const void *  in,
void *  out,
size_t  size 
)
static

Decrypt size bytes from in and write the result to out.

Use the kx key for inbound traffic of the given neighbour. This function does NOT do any integrity-checks on the result.

Parameters
kxkey information context
ivinitialization vector to use
inciphertext
outplaintext
sizesize of in / out
Returns
GNUNET_OK on success

Definition at line 655 of file gnunet-service-core_kx.c.

References GSC_KeyExchangeInfo::decrypt_key, gettext_noop, GNUNET_break, GNUNET_break_op, GNUNET_CORE_KX_STATE_KEY_RECEIVED, GNUNET_CORE_KX_STATE_REKEY_SENT, GNUNET_CORE_KX_STATE_UP, GNUNET_CRYPTO_crc32_n(), GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GSC_stats, GSC_KeyExchangeInfo::peer, send_key(), and GSC_KeyExchangeInfo::status.

Referenced by handle_encrypted(), handle_ping(), and handle_pong().

660 {
661  if (size != (uint16_t) size)
662  {
663  GNUNET_break (0);
664  return GNUNET_NO;
665  }
667  (kx->status != GNUNET_CORE_KX_STATE_UP) &&
669  {
670  GNUNET_break_op (0);
671  return GNUNET_SYSERR;
672  }
673  if (size != GNUNET_CRYPTO_symmetric_decrypt (in,
674  (uint16_t) size,
675  &kx->decrypt_key,
676  iv,
677  out))
678  {
679  GNUNET_break (0);
680  return GNUNET_SYSERR;
681  }
683  gettext_noop ("# bytes decrypted"),
684  size,
685  GNUNET_NO);
686  /* the following is too sensitive to write to log files by accident,
687  so we require manual intervention to get this one... */
688 #if DEBUG_KX
690  "Decrypted %u bytes from `%s' using key %u, IV %u\n",
691  (unsigned int) size,
692  GNUNET_i2s (kx->peer),
693  (unsigned int) kx->decrypt_key.crc32,
694  GNUNET_CRYPTO_crc32_n (iv, sizeof(*iv)));
695 #endif
696  return GNUNET_OK;
697 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
int32_t GNUNET_CRYPTO_crc32_n(const void *buf, size_t len)
Compute the CRC32 checksum for the first len bytes of the buffer.
Definition: crypto_crc.c:106
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
We've received the other peers session key.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key
Key we use to decrypt messages from the other peer (given to us by the other peer during the handshak...
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
#define GNUNET_log(kind,...)
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
We're rekeying (or had a timeout), so we have sent the other peer our new ephemeral key...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_key()

static void send_key ( struct GSC_KeyExchangeInfo kx)
static

Send our key (and encrypted PING) to the other peer.

Send our key to the other peer.

Parameters
kxkey exchange context

Definition at line 1470 of file gnunet-service-core_kx.c.

References current_ekm, env, EphemeralKeyMessage::ephemeral_key, GNUNET_assert, GNUNET_CORE_KX_STATE_DOWN, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_MQ_msg_copy(), GNUNET_MQ_send(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), EphemeralKeyMessage::header, GSC_KeyExchangeInfo::mq, GSC_KeyExchangeInfo::peer, GSC_KeyExchangeInfo::retry_set_key_task, send_ping(), EphemeralKeyMessage::sender_status, GSC_KeyExchangeInfo::set_key_retry_frequency, set_key_retry_task(), and GSC_KeyExchangeInfo::status.

Referenced by do_decrypt(), do_rekey(), handle_encrypted(), handle_ephemeral_key(), handle_transport_notify_connect(), send_keep_alive(), and set_key_retry_task().

1471 {
1472  struct GNUNET_MQ_Envelope *env;
1473 
1475  if (NULL != kx->retry_set_key_task)
1476  {
1478  kx->retry_set_key_task = NULL;
1479  }
1480  /* always update sender status in SET KEY message */
1481 #if DEBUG_KX
1482  {
1483  struct GNUNET_HashCode hc;
1484 
1486  sizeof(current_ekm.ephemeral_key),
1487  &hc);
1489  "Sending EPHEMERAL_KEY %s to `%s' (my status: %d)\n",
1490  GNUNET_h2s (&hc),
1491  GNUNET_i2s (kx->peer),
1492  kx->status);
1493  }
1494 #endif
1495  current_ekm.sender_status = htonl ((int32_t) (kx->status));
1497  GNUNET_MQ_send (kx->mq, env);
1499  send_ping (kx);
1500  kx->retry_set_key_task =
1503  kx);
1504 }
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:653
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
struct GNUNET_TIME_Relative set_key_retry_frequency
At what frequency are we currently re-trying SET_KEY messages?
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_SCHEDULER_Task * retry_set_key_task
ID of task used for re-trying SET_KEY and PING message.
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
static void send_ping(struct GSC_KeyExchangeInfo *kx)
Send our PING to the other peer.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
A 512-bit hashcode.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
static void set_key_retry_task(void *cls)
Task that will retry send_key() if our previous attempt failed.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
#define GNUNET_log(kind,...)
int32_t sender_status
Status of the sender (should be in enum PeerStateMachine), nbo.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
static struct EphemeralKeyMessage current_ekm
Current message we send for a key exchange.
We've sent our session key.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_key_retry_task()

static void set_key_retry_task ( void *  cls)
static

Task that will retry send_key() if our previous attempt failed.

Parameters
clsour struct GSC_KeyExchangeInfo

Definition at line 715 of file gnunet-service-core_kx.c.

References GNUNET_assert, GNUNET_CORE_KX_STATE_DOWN, GNUNET_TIME_STD_BACKOFF, GSC_KeyExchangeInfo::retry_set_key_task, send_key(), GSC_KeyExchangeInfo::set_key_retry_frequency, and GSC_KeyExchangeInfo::status.

Referenced by handle_transport_notify_connect(), and send_key().

716 {
717  struct GSC_KeyExchangeInfo *kx = cls;
718 
719  kx->retry_set_key_task = NULL;
723  send_key (kx);
724 }
struct GNUNET_TIME_Relative set_key_retry_frequency
At what frequency are we currently re-trying SET_KEY messages?
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
struct GNUNET_SCHEDULER_Task * retry_set_key_task
ID of task used for re-trying SET_KEY and PING message.
Information about the status of a key exchange with another peer.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_fresh_ping()

static void setup_fresh_ping ( struct GSC_KeyExchangeInfo kx)
static

Create a fresh PING message for transmission to the other peer.

Parameters
kxkey exchange context to create PING for

Definition at line 733 of file gnunet-service-core_kx.c.

References calculate_seed(), PingMessage::challenge, derive_iv(), do_encrypt(), GSC_KeyExchangeInfo::encrypt_key, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_MESSAGE_TYPE_CORE_PING, GSC_KeyExchangeInfo::peer, GSC_KeyExchangeInfo::ping, GSC_KeyExchangeInfo::ping_challenge, pm, and PingMessage::target.

Referenced by derive_session_keys(), and send_keep_alive().

734 {
735  struct PingMessage pp;
736  struct PingMessage *pm;
738 
739  pm = &kx->ping;
740  kx->ping_challenge =
742  pm->header.size = htons (sizeof(struct PingMessage));
743  pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
744  pm->iv_seed = calculate_seed (kx);
745  derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, kx->peer);
746  pp.challenge = kx->ping_challenge;
747  pp.target = *kx->peer;
748  do_encrypt (kx,
749  &iv,
750  &pp.target,
751  &pm->target,
752  sizeof(struct PingMessage)
753  - ((void *) &pm->target - (void *) pm));
754 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
struct PingMessage ping
PING message we transmit to the other peer.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
static int do_encrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Encrypt size bytes from in and write the result to out.
We're sending an (encrypted) PING to the other peer to check if it can decrypt.
uint32_t ping_challenge
What was our PING challenge number (for this peer)?
static uint32_t calculate_seed(struct GSC_KeyExchangeInfo *kx)
Calculate seed value we should use for a message.
#define GNUNET_MESSAGE_TYPE_CORE_PING
Check that other peer is alive (challenge).
static void derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, const struct GNUNET_PeerIdentity *identity)
Derive an IV from packet information.
struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key
Key we use to encrypt our messages for the other peer (initialized by us when we do the handshake)...
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ deliver_message()

static int deliver_message ( void *  cls,
const struct GNUNET_MessageHeader m 
)
static

Deliver P2P message to interested clients.

Invokes send twice, once for clients that want the full message, and once for clients that only want the header

Parameters
clsthe struct GSC_KeyExchangeInfo
mthe message
Returns
GNUNET_OK on success, GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 769 of file gnunet-service-core_kx.c.

References gettext_noop, GNUNET_CORE_KX_STATE_UP, GNUNET_CORE_OPTION_SEND_FULL_INBOUND, GNUNET_CORE_OPTION_SEND_HDR_INBOUND, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP, GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP, GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GSC_CLIENTS_deliver_message(), GSC_SESSIONS_confirm_typemap(), GSC_SESSIONS_set_typemap(), GSC_stats, GSC_KeyExchangeInfo::peer, GNUNET_MessageHeader::size, GSC_KeyExchangeInfo::status, and GNUNET_MessageHeader::type.

Referenced by handle_transport_notify_connect().

770 {
771  struct GSC_KeyExchangeInfo *kx = cls;
772 
774  "Decrypted message of type %d from %s\n",
775  ntohs (m->type),
776  GNUNET_i2s (kx->peer));
777  if (GNUNET_CORE_KX_STATE_UP != kx->status)
778  {
780  gettext_noop ("# PAYLOAD dropped (out of order)"),
781  1,
782  GNUNET_NO);
783  return GNUNET_OK;
784  }
785  switch (ntohs (m->type))
786  {
790  return GNUNET_OK;
791 
794  return GNUNET_OK;
795 
796  default:
798  m,
799  ntohs (m->size),
802  m,
803  sizeof(struct GNUNET_MessageHeader),
805  }
806  return GNUNET_OK;
807 }
void GSC_SESSIONS_confirm_typemap(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
The other peer has confirmed receiving our type map, check if it is current and if so...
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
#define GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP
gzip-compressed type map of the sender
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP
Other peer confirms having received the type map.
void GSC_SESSIONS_set_typemap(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
We have received a typemap message from a peer, update ours.
#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND
Client wants all inbound messages in full.
Definition: core.h:55
Information about the status of a key exchange with another peer.
void GSC_CLIENTS_deliver_message(const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, uint16_t msize, uint32_t options)
Deliver P2P message to interested clients.
#define GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP
uncompressed type map of the sender
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
#define GNUNET_log(kind,...)
Header for all communications.
#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND
Client just wants the 4-byte message headers of all inbound messages.
Definition: core.h:61
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_transport_notify_connect()

static void* handle_transport_notify_connect ( void *  cls,
const struct GNUNET_PeerIdentity pid,
struct GNUNET_MQ_Handle mq 
)
static

Function called by transport to notify us that a peer connected to us (on the network level).

Starts the key exchange with the given peer.

Parameters
clsclosure (NULL)
pididentity of the peer to do a key exchange with
Returns
key exchange information context

Definition at line 820 of file gnunet-service-core_kx.c.

References deliver_message(), gettext_noop, GNUNET_CONTAINER_DLL_insert, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hash_cmp(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MST_create(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TIME_UNIT_SECONDS, GSC_my_identity, GSC_stats, INITIAL_SET_KEY_RETRY_FREQUENCY, monitor_notify_all(), mq, GSC_KeyExchangeInfo::mq, GSC_KeyExchangeInfo::mst, GSC_KeyExchangeInfo::peer, pid, GSC_KeyExchangeInfo::retry_set_key_task, send_key(), GSC_KeyExchangeInfo::set_key_retry_frequency, set_key_retry_task(), and GSC_KeyExchangeInfo::status.

Referenced by GSC_KX_init().

823 {
824  struct GSC_KeyExchangeInfo *kx;
825  struct GNUNET_HashCode h1;
826  struct GNUNET_HashCode h2;
827 
829  "Initiating key exchange with `%s'\n",
830  GNUNET_i2s (pid));
832  gettext_noop ("# key exchanges initiated"),
833  1,
834  GNUNET_NO);
835  kx = GNUNET_new (struct GSC_KeyExchangeInfo);
837  kx->mq = mq;
838  kx->peer = pid;
842  monitor_notify_all (kx);
843  GNUNET_CRYPTO_hash (pid, sizeof(struct GNUNET_PeerIdentity), &h1);
845  sizeof(struct GNUNET_PeerIdentity),
846  &h2);
847  if (0 < GNUNET_CRYPTO_hash_cmp (&h1, &h2))
848  {
849  /* peer with "lower" identity starts KX, otherwise we typically end up
850  with both peers starting the exchange and transmit the 'set key'
851  message twice */
852  send_key (kx);
853  }
854  else
855  {
856  /* peer with "higher" identity starts a delayed KX, if the "lower" peer
857  * does not start a KX since it sees no reasons to do so */
858  kx->retry_set_key_task =
861  kx);
862  }
863  return kx;
864 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
struct GNUNET_TIME_Relative set_key_retry_frequency
At what frequency are we currently re-trying SET_KEY messages?
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_CORE_KxState status
What is our connection status?
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
#define GNUNET_TIME_UNIT_SECONDS
One second.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
struct GNUNET_MessageStreamTokenizer * mst
Our message stream tokenizer (for encrypted payload).
static int deliver_message(void *cls, const struct GNUNET_MessageHeader *m)
Deliver P2P message to interested clients.
struct GNUNET_SCHEDULER_Task * retry_set_key_task
ID of task used for re-trying SET_KEY and PING message.
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct GSC_KeyExchangeInfo * kx_tail
DLL tail.
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:85
Information about the status of a key exchange with another peer.
A 512-bit hashcode.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
static void set_key_retry_task(void *cls)
Task that will retry send_key() if our previous attempt failed.
The identity of the host (wraps the signing key of the peer).
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:294
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
We&#39;ve sent our session key.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define INITIAL_SET_KEY_RETRY_FREQUENCY
How long do we wait for SET_KEY confirmation initially?
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_transport_notify_disconnect()

static void handle_transport_notify_disconnect ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  handler_cls 
)
static

Function called by transport telling us that a peer disconnected.

Stop key exchange with the given peer. Clean up key material.

Parameters
clsclosure
peerthe peer that disconnected
handler_clsthe struct GSC_KeyExchangeInfo of the peer

Definition at line 877 of file gnunet-service-core_kx.c.

References gettext_noop, GNUNET_CONTAINER_DLL_remove, GNUNET_CORE_KX_PEER_DISCONNECT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_MST_destroy(), GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GSC_SESSIONS_end(), GSC_stats, GSC_KeyExchangeInfo::keep_alive_task, monitor_notify_all(), GSC_KeyExchangeInfo::mst, GSC_KeyExchangeInfo::peer, GSC_KeyExchangeInfo::retry_set_key_task, and GSC_KeyExchangeInfo::status.

Referenced by GSC_KX_init().

880 {
881  struct GSC_KeyExchangeInfo *kx = handler_cls;
882 
884  "Peer `%s' disconnected from us.\n",
885  GNUNET_i2s (peer));
886  GSC_SESSIONS_end (kx->peer);
888  gettext_noop ("# key exchanges stopped"),
889  1,
890  GNUNET_NO);
891  if (NULL != kx->retry_set_key_task)
892  {
894  kx->retry_set_key_task = NULL;
895  }
896  if (NULL != kx->keep_alive_task)
897  {
899  kx->keep_alive_task = NULL;
900  }
902  monitor_notify_all (kx);
904  GNUNET_MST_destroy (kx->mst);
905  GNUNET_free (kx);
906 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_NO
Definition: gnunet_common.h:78
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
struct GNUNET_MessageStreamTokenizer * mst
Our message stream tokenizer (for encrypted payload).
struct GNUNET_SCHEDULER_Task * retry_set_key_task
ID of task used for re-trying SET_KEY and PING message.
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:411
static struct GSC_KeyExchangeInfo * kx_tail
DLL tail.
Information about the status of a key exchange with another peer.
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
#define GNUNET_log(kind,...)
Last state of a KX (when it is being terminated).
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_ping()

static void send_ping ( struct GSC_KeyExchangeInfo kx)
static

Send our PING to the other peer.

Parameters
kxkey exchange context

Definition at line 915 of file gnunet-service-core_kx.c.

References env, gettext_noop, GNUNET_MQ_msg_copy(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), GSC_stats, PingMessage::header, GSC_KeyExchangeInfo::mq, and GSC_KeyExchangeInfo::ping.

Referenced by handle_ephemeral_key(), send_keep_alive(), and send_key().

916 {
917  struct GNUNET_MQ_Envelope *env;
918 
920  gettext_noop ("# PING messages transmitted"),
921  1,
922  GNUNET_NO);
923  env = GNUNET_MQ_msg_copy (&kx->ping.header);
924  GNUNET_MQ_send (kx->mq, env);
925 }
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:653
struct PingMessage ping
PING message we transmit to the other peer.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_PING.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ derive_session_keys()

static void derive_session_keys ( struct GSC_KeyExchangeInfo kx)
static

Derive fresh session keys from the current ephemeral keys.

Parameters
kxsession to derive keys for

Definition at line 934 of file gnunet-service-core_kx.c.

References GSC_KeyExchangeInfo::decrypt_key, derive_aes_key(), GSC_KeyExchangeInfo::encrypt_key, GNUNET_break, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_OK, GSC_my_identity, GSC_KeyExchangeInfo::last_packets_bitmap, GSC_KeyExchangeInfo::last_sequence_number_received, GSC_KeyExchangeInfo::other_ephemeral_key, GSC_KeyExchangeInfo::peer, and setup_fresh_ping().

Referenced by do_rekey(), and handle_ephemeral_key().

935 {
936  struct GNUNET_HashCode key_material;
937 
939  &kx->other_ephemeral_key,
940  &key_material))
941  {
942  GNUNET_break (0);
943  return;
944  }
945  derive_aes_key (&GSC_my_identity, kx->peer, &key_material, &kx->encrypt_key);
946  derive_aes_key (kx->peer, &GSC_my_identity, &key_material, &kx->decrypt_key);
947  memset (&key_material, 0, sizeof(key_material));
948  /* fresh key, reset sequence numbers */
950  kx->last_packets_bitmap = 0;
951  setup_fresh_ping (kx);
952 }
static void derive_aes_key(const struct GNUNET_PeerIdentity *sender, const struct GNUNET_PeerIdentity *receiver, const struct GNUNET_HashCode *key_material, struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
Derive an AES key from key material.
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
uint32_t last_packets_bitmap
Bit map indicating which of the 32 sequence numbers before the last were received (good for accepting...
static struct GNUNET_CRYPTO_EcdhePrivateKey * my_ephemeral_key
Our ephemeral private key.
int GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition: crypto_ecc.c:1182
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key
Ephemeral public ECC key of the other peer.
A 512-bit hashcode.
struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key
Key we use to decrypt messages from the other peer (given to us by the other peer during the handshak...
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
static void setup_fresh_ping(struct GSC_KeyExchangeInfo *kx)
Create a fresh PING message for transmission to the other peer.
uint32_t last_sequence_number_received
last sequence number received on this connection (highest)
struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key
Key we use to encrypt our messages for the other peer (initialized by us when we do the handshake)...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_ephemeral_key()

static void handle_ephemeral_key ( void *  cls,
const struct EphemeralKeyMessage m 
)
static

We received a GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY message.

Validate and update our key material and status.

Parameters
clskey exchange status for the corresponding peer
mthe set key message we received

Definition at line 963 of file gnunet-service-core_kx.c.

References _, GNUNET_TIME_Absolute::abs_value_us, EphemeralKeyMessage::creation_time, derive_session_keys(), EphemeralKeyMessage::ephemeral_key, EphemeralKeyMessage::expiration_time, GSC_KeyExchangeInfo::foreign_key_expires, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CORE_KX_STATE_DOWN, GNUNET_CORE_KX_STATE_KEY_RECEIVED, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_CORE_KX_STATE_REKEY_SENT, GNUNET_CORE_KX_STATE_UP, GNUNET_CRYPTO_eddsa_verify(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_i2s(), GNUNET_i2s_full(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_absolute_subtract(), GSC_SESSIONS_reinit(), GSC_stats, GSC_KeyExchangeInfo::keep_alive_task, monitor_notify_all(), EphemeralKeyMessage::origin_identity, GSC_KeyExchangeInfo::other_ephemeral_key, GSC_KeyExchangeInfo::peer, GNUNET_PeerIdentity::public_key, EphemeralKeyMessage::purpose, REKEY_TOLERANCE, send_key(), send_ping(), EphemeralKeyMessage::sender_status, EphemeralKeyMessage::signature, GNUNET_CRYPTO_EccSignaturePurpose::size, and GSC_KeyExchangeInfo::status.

964 {
965  struct GSC_KeyExchangeInfo *kx = cls;
966  struct GNUNET_TIME_Absolute start_t;
967  struct GNUNET_TIME_Absolute end_t;
968  struct GNUNET_TIME_Absolute now;
969  enum GNUNET_CORE_KxState sender_status;
970 
973  (GNUNET_CORE_KX_STATE_UP == kx->status) ||
975  (end_t.abs_value_us < kx->foreign_key_expires.abs_value_us))
976  {
978  gettext_noop ("# old ephemeral keys ignored"),
979  1,
980  GNUNET_NO);
982  "Received expired EPHEMERAL_KEY from %s\n",
984  return;
985  }
986  if (0 == memcmp (&m->ephemeral_key,
987  &kx->other_ephemeral_key,
988  sizeof(m->ephemeral_key)))
989  {
991  gettext_noop (
992  "# duplicate ephemeral keys ignored"),
993  1,
994  GNUNET_NO);
996  "Ignoring duplicate EPHEMERAL_KEY from %s\n",
998  return;
999  }
1000  if (0 != memcmp (&m->origin_identity,
1001  kx->peer,
1002  sizeof(struct GNUNET_PeerIdentity)))
1003  {
1005  "Received EPHEMERAL_KEY from %s, but expected %s\n",
1007  GNUNET_i2s_full (kx->peer));
1008  GNUNET_break_op (0);
1009  return;
1010  }
1011  if ((ntohl (m->purpose.size) !=
1012  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
1013  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
1014  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
1015  + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
1016  + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) ||
1017  (GNUNET_OK !=
1019  &m->purpose,
1020  &m->signature,
1022  {
1023  /* invalid signature */
1024  GNUNET_break_op (0);
1026  gettext_noop (
1027  "# EPHEMERAL_KEYs rejected (bad signature)"),
1028  1,
1029  GNUNET_NO);
1031  "Received EPHEMERAL_KEY from %s with bad signature\n",
1032  GNUNET_i2s (&m->origin_identity));
1033  return;
1034  }
1035  now = GNUNET_TIME_absolute_get ();
1037  if ((end_t.abs_value_us <
1039  (start_t.abs_value_us >
1040  GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us))
1041  {
1042  GNUNET_log (
1044  _ (
1045  "EPHEMERAL_KEY from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
1046  GNUNET_i2s (kx->peer),
1047  (unsigned long long) now.abs_value_us,
1048  (unsigned long long) start_t.abs_value_us,
1049  (unsigned long long) end_t.abs_value_us);
1051  gettext_noop (
1052  "# EPHEMERAL_KEY messages rejected due to time"),
1053  1,
1054  GNUNET_NO);
1055  return;
1056  }
1057 #if DEBUG_KX
1058  {
1059  struct GNUNET_HashCode eh;
1060 
1061  GNUNET_CRYPTO_hash (&m->ephemeral_key, sizeof(m->ephemeral_key), &eh);
1063  "Received valid EPHEMERAL_KEY `%s' from `%s' in state %d.\n",
1064  GNUNET_h2s (&eh),
1065  GNUNET_i2s (kx->peer),
1066  kx->status);
1067  }
1068 #endif
1070  gettext_noop ("# valid ephemeral keys received"),
1071  1,
1072  GNUNET_NO);
1074  kx->foreign_key_expires = end_t;
1075  derive_session_keys (kx);
1076 
1077  /* check if we still need to send the sender our key */
1078  sender_status = (enum GNUNET_CORE_KxState) ntohl (m->sender_status);
1079  switch (sender_status)
1080  {
1082  GNUNET_break_op (0);
1083  break;
1084 
1086  /* fine, need to send our key after updating our status, see below */
1087  GSC_SESSIONS_reinit (kx->peer);
1088  break;
1089 
1091  /* other peer already got our key, but typemap did go down */
1092  GSC_SESSIONS_reinit (kx->peer);
1093  break;
1094 
1096  /* other peer already got our key, typemap NOT down */
1097  break;
1098 
1100  /* other peer already got our key, typemap NOT down */
1101  break;
1102 
1103  default:
1104  GNUNET_break (0);
1105  break;
1106  }
1107  /* check if we need to confirm everything is fine via PING + PONG */
1108  switch (kx->status)
1109  {
1111  GNUNET_assert (NULL == kx->keep_alive_task);
1113  monitor_notify_all (kx);
1114  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1115  send_key (kx);
1116  else
1117  send_ping (kx);
1118  break;
1119 
1121  GNUNET_assert (NULL == kx->keep_alive_task);
1123  monitor_notify_all (kx);
1124  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1125  send_key (kx);
1126  else
1127  send_ping (kx);
1128  break;
1129 
1131  GNUNET_assert (NULL == kx->keep_alive_task);
1132  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1133  send_key (kx);
1134  else
1135  send_ping (kx);
1136  break;
1137 
1140  monitor_notify_all (kx);
1141  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1142  send_key (kx);
1143  else
1144  send_ping (kx);
1145  break;
1146 
1148  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1149  send_key (kx);
1150  else
1151  send_ping (kx);
1152  break;
1153 
1154  default:
1155  GNUNET_break (0);
1156  break;
1157  }
1158 }
#define GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY
Purpose is to set a session key.
#define REKEY_TOLERANCE
What time difference do we tolerate?
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_subtract(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Subtract a given relative duration from the given start time.
Definition: time.c:422
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
static void derive_session_keys(struct GSC_KeyExchangeInfo *kx)
Derive fresh session keys from the current ephemeral keys.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:395
GNUNET_CORE_KxState
State machine for our P2P encryption handshake.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
We&#39;ve received the other peers session key.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the given ephemeral key expire (end of validity).
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
struct GNUNET_CRYPTO_EddsaSignature signature
An ECC signature of the origin_identity asserting the validity of the given ephemeral key...
struct GNUNET_TIME_AbsoluteNBO creation_time
At what time was this key created (beginning of validity).
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
int GNUNET_CRYPTO_eddsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:1113
static void send_ping(struct GSC_KeyExchangeInfo *kx)
Send our PING to the other peer.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key
Ephemeral public ECC key of the other peer.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Information about the status of a key exchange with another peer.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Information about what is being signed.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
The identity of the host (wraps the signing key of the peer).
struct GNUNET_TIME_Absolute foreign_key_expires
At what time did the other peer generate the decryption key?
#define GNUNET_log(kind,...)
int32_t sender_status
Status of the sender (should be in enum PeerStateMachine), nbo.
Time for absolute times used by GNUnet, in microseconds.
We&#39;ve sent our session key.
struct GNUNET_PeerIdentity origin_identity
Public key of the signing peer (persistent version, not the ephemeral public key).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GSC_SESSIONS_reinit(const struct GNUNET_PeerIdentity *peer)
The other peer has indicated that it &#39;lost&#39; the session (KX down), reinitialize the session on our en...
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define gettext_noop(String)
Definition: gettext.h:69
We&#39;re rekeying (or had a timeout), so we have sent the other peer our new ephemeral key...
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
Here is the call graph for this function:

◆ handle_ping()

static void handle_ping ( void *  cls,
const struct PingMessage m 
)
static

We received a PING message.

Validate and transmit a PONG message.

Parameters
clskey exchange status for the corresponding peer
mthe encrypted PING message itself

Definition at line 1169 of file gnunet-service-core_kx.c.

References calculate_seed(), PingMessage::challenge, PongMessage::challenge, GSC_KeyExchangeInfo::decrypt_key, derive_iv(), derive_pong_iv(), do_decrypt(), do_encrypt(), GSC_KeyExchangeInfo::encrypt_key, env, gettext_noop, GNUNET_break_op, GNUNET_CORE_KX_STATE_KEY_RECEIVED, GNUNET_CORE_KX_STATE_REKEY_SENT, GNUNET_CORE_KX_STATE_UP, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_i2s2(), GNUNET_log, GNUNET_MESSAGE_TYPE_CORE_PONG, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GSC_my_identity, GSC_stats, PingMessage::iv_seed, PongMessage::iv_seed, GSC_KeyExchangeInfo::mq, GSC_KeyExchangeInfo::peer, PongMessage::reserved, GSC_KeyExchangeInfo::status, PingMessage::target, and PongMessage::target.

1170 {
1171  struct GSC_KeyExchangeInfo *kx = cls;
1172  struct PingMessage t;
1173  struct PongMessage tx;
1174  struct PongMessage *tp;
1175  struct GNUNET_MQ_Envelope *env;
1177 
1179  gettext_noop ("# PING messages received"),
1180  1,
1181  GNUNET_NO);
1183  (kx->status != GNUNET_CORE_KX_STATE_UP) &&
1185  {
1186  /* ignore */
1188  gettext_noop (
1189  "# PING messages dropped (out of order)"),
1190  1,
1191  GNUNET_NO);
1192  return;
1193  }
1195  "Core service receives PING request from `%s'.\n",
1196  GNUNET_i2s (kx->peer));
1197  derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1198  if (GNUNET_OK != do_decrypt (kx,
1199  &iv,
1200  &m->target,
1201  &t.target,
1202  sizeof(struct PingMessage)
1203  - ((void *) &m->target - (void *) m)))
1204  {
1205  GNUNET_break_op (0);
1206  return;
1207  }
1208  if (0 !=
1209  memcmp (&t.target, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity)))
1210  {
1213  "Decryption of PING from peer `%s' failed, PING for `%s'?\n",
1214  GNUNET_i2s (kx->peer),
1215  GNUNET_i2s2 (&t.target));
1216  else
1217  GNUNET_log (
1219  "Decryption of PING from peer `%s' failed after rekey (harmless)\n",
1220  GNUNET_i2s (kx->peer));
1221  GNUNET_break_op (0);
1222  return;
1223  }
1224  /* construct PONG */
1225  tx.reserved = 0;
1226  tx.challenge = t.challenge;
1227  tx.target = t.target;
1229  tp->iv_seed = calculate_seed (kx);
1230  derive_pong_iv (&iv, &kx->encrypt_key, tp->iv_seed, t.challenge, kx->peer);
1231  do_encrypt (kx,
1232  &iv,
1233  &tx.challenge,
1234  &tp->challenge,
1235  sizeof(struct PongMessage)
1236  - ((void *) &tp->challenge - (void *) tp));
1238  gettext_noop ("# PONG messages created"),
1239  1,
1240  GNUNET_NO);
1241  GNUNET_MQ_send (kx->mq, env);
1242 }
const char * GNUNET_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
uint32_t iv_seed
Seed for the IV.
enum GNUNET_CORE_KxState status
What is our connection status?
struct GNUNET_PeerIdentity target
Intended target of the PING, used primarily to check that decryption actually worked.
Response to a PING.
static int do_encrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Encrypt size bytes from in and write the result to out.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_SCHEDULER_Task * t
Main task.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
We&#39;ve received the other peers session key.
#define GNUNET_MESSAGE_TYPE_CORE_PONG
Confirmation that other peer is alive.
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
static int do_decrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Decrypt size bytes from in and write the result to out.
uint32_t challenge
Random number to make replay attacks harder.
We&#39;re sending an (encrypted) PING to the other peer to check if it can decrypt.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t iv_seed
Seed for the IV.
Information about the status of a key exchange with another peer.
struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key
Key we use to decrypt messages from the other peer (given to us by the other peer during the handshak...
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
static uint32_t calculate_seed(struct GSC_KeyExchangeInfo *kx)
Calculate seed value we should use for a message.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
static void derive_pong_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
Derive an IV from pong packet information.
The identity of the host (wraps the signing key of the peer).
static void derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, const struct GNUNET_PeerIdentity *identity)
Derive an IV from packet information.
#define GNUNET_log(kind,...)
struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key
Key we use to encrypt our messages for the other peer (initialized by us when we do the handshake)...
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
We&#39;re rekeying (or had a timeout), so we have sent the other peer our new ephemeral key...
Here is the call graph for this function:

◆ send_keep_alive()

static void send_keep_alive ( void *  cls)
static

Task triggered when a neighbour entry is about to time out (and we should prevent this by sending a PING).

Parameters
clsthe struct GSC_KeyExchangeInfo

Definition at line 1252 of file gnunet-service-core_kx.c.

References gettext_noop, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_divide(), GNUNET_TIME_relative_max(), GSC_SESSIONS_end(), GSC_stats, GSC_KeyExchangeInfo::keep_alive_task, MIN_PING_FREQUENCY, monitor_notify_all(), GSC_KeyExchangeInfo::peer, GNUNET_TIME_Relative::rel_value_us, send_key(), send_ping(), setup_fresh_ping(), GSC_KeyExchangeInfo::status, and GSC_KeyExchangeInfo::timeout.

Referenced by update_timeout().

1253 {
1254  struct GSC_KeyExchangeInfo *kx = cls;
1255  struct GNUNET_TIME_Relative retry;
1256  struct GNUNET_TIME_Relative left;
1257 
1258  kx->keep_alive_task = NULL;
1260  if (0 == left.rel_value_us)
1261  {
1263  gettext_noop ("# sessions terminated by timeout"),
1264  1,
1265  GNUNET_NO);
1266  GSC_SESSIONS_end (kx->peer);
1268  monitor_notify_all (kx);
1269  send_key (kx);
1270  return;
1271  }
1273  "Sending KEEPALIVE to `%s'\n",
1274  GNUNET_i2s (kx->peer));
1276  gettext_noop ("# keepalive messages sent"),
1277  1,
1278  GNUNET_NO);
1279  setup_fresh_ping (kx);
1280  send_ping (kx);
1283  kx->keep_alive_task =
1285 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
static void send_ping(struct GSC_KeyExchangeInfo *kx)
Send our PING to the other peer.
static void send_keep_alive(void *cls)
Task triggered when a neighbour entry is about to time out (and we should prevent this by sending a P...
#define MIN_PING_FREQUENCY
What is the minimum frequency for a PING message?
Information about the status of a key exchange with another peer.
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
static void setup_fresh_ping(struct GSC_KeyExchangeInfo *kx)
Create a fresh PING message for transmission to the other peer.
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no PONGs)?
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:527
We&#39;ve sent our session key.
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_timeout()

static void update_timeout ( struct GSC_KeyExchangeInfo kx)
static

We've seen a valid message from the other peer.

Update the time when the session would time out and delay sending our keep alive message further.

Parameters
kxkey exchange where we saw activity

Definition at line 1296 of file gnunet-service-core_kx.c.

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_absolute_get_difference(), GNUNET_TIME_relative_divide(), GNUNET_TIME_relative_to_absolute(), GSC_KeyExchangeInfo::keep_alive_task, GSC_KeyExchangeInfo::last_notify_timeout, monitor_notify_all(), GNUNET_TIME_Relative::rel_value_us, send_keep_alive(), and GSC_KeyExchangeInfo::timeout.

Referenced by handle_encrypted(), and handle_pong().

1297 {
1298  struct GNUNET_TIME_Relative delta;
1299 
1300  kx->timeout =
1302  delta =
1304  if (delta.rel_value_us > 5LL * 1000LL * 1000LL)
1305  {
1306  /* we only notify monitors about timeout changes if those
1307  are bigger than the threshold (5s) */
1308  monitor_notify_all (kx);
1309  }
1310  if (NULL != kx->keep_alive_task)
1314  &send_keep_alive,
1315  kx);
1316 }
uint64_t rel_value_us
The actual value.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
struct GNUNET_TIME_Absolute last_notify_timeout
What was the last timeout we informed our monitors about?
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
static void send_keep_alive(void *cls)
Task triggered when a neighbour entry is about to time out (and we should prevent this by sending a P...
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no PONGs)?
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:527
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_difference(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute end)
Compute the time difference between the given start and end times.
Definition: time.c:354
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_pong()

static void handle_pong ( void *  cls,
const struct PongMessage m 
)
static

We received a PONG message.

Validate and update our status.

Parameters
kxkey exchange context for the the PONG
mthe encrypted PONG message itself

Definition at line 1326 of file gnunet-service-core_kx.c.

References PongMessage::challenge, GSC_KeyExchangeInfo::decrypt_key, derive_pong_iv(), do_decrypt(), gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CORE_KX_STATE_DOWN, GNUNET_CORE_KX_STATE_KEY_RECEIVED, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_CORE_KX_STATE_REKEY_SENT, GNUNET_CORE_KX_STATE_UP, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GSC_my_identity, GSC_SESSIONS_create(), GSC_stats, PongMessage::iv_seed, GSC_KeyExchangeInfo::keep_alive_task, monitor_notify_all(), GSC_KeyExchangeInfo::peer, GSC_KeyExchangeInfo::ping_challenge, GSC_KeyExchangeInfo::retry_set_key_task, GSC_KeyExchangeInfo::status, PongMessage::target, and update_timeout().

1327 {
1328  struct GSC_KeyExchangeInfo *kx = cls;
1329  struct PongMessage t;
1331 
1333  gettext_noop ("# PONG messages received"),
1334  1,
1335  GNUNET_NO);
1336  switch (kx->status)
1337  {
1340  gettext_noop (
1341  "# PONG messages dropped (connection down)"),
1342  1,
1343  GNUNET_NO);
1344  return;
1345 
1348  gettext_noop (
1349  "# PONG messages dropped (out of order)"),
1350  1,
1351  GNUNET_NO);
1352  return;
1353 
1355  break;
1356 
1358  break;
1359 
1361  break;
1362 
1363  default:
1364  GNUNET_break (0);
1365  return;
1366  }
1368  "Core service receives PONG response from `%s'.\n",
1369  GNUNET_i2s (kx->peer));
1370  /* mark as garbage, just to be sure */
1371  memset (&t, 255, sizeof(t));
1372  derive_pong_iv (&iv,
1373  &kx->decrypt_key,
1374  m->iv_seed,
1375  kx->ping_challenge,
1376  &GSC_my_identity);
1377  if (GNUNET_OK != do_decrypt (kx,
1378  &iv,
1379  &m->challenge,
1380  &t.challenge,
1381  sizeof(struct PongMessage)
1382  - ((void *) &m->challenge - (void *) m)))
1383  {
1384  GNUNET_break_op (0);
1385  return;
1386  }
1388  gettext_noop ("# PONG messages decrypted"),
1389  1,
1390  GNUNET_NO);
1391  if ((0 !=
1392  memcmp (&t.target, kx->peer, sizeof(struct GNUNET_PeerIdentity))) ||
1393  (kx->ping_challenge != t.challenge))
1394  {
1395  /* PONG malformed */
1397  "Received malformed PONG wanted sender `%s' with challenge %u\n",
1398  GNUNET_i2s (kx->peer),
1399  (unsigned int) kx->ping_challenge);
1401  "Received malformed PONG received from `%s' with challenge %u\n",
1402  GNUNET_i2s (&t.target),
1403  (unsigned int) t.challenge);
1404  return;
1405  }
1407  "Received valid PONG from `%s'\n",
1408  GNUNET_i2s (kx->peer));
1409  /* no need to resend key any longer */
1410  if (NULL != kx->retry_set_key_task)
1411  {
1413  kx->retry_set_key_task = NULL;
1414  }
1415  switch (kx->status)
1416  {
1418  GNUNET_assert (0); /* should be impossible */
1419  return;
1420 
1422  GNUNET_assert (0); /* should be impossible */
1423  return;
1424 
1427  gettext_noop (
1428  "# session keys confirmed via PONG"),
1429  1,
1430  GNUNET_NO);
1432  monitor_notify_all (kx);
1433  GSC_SESSIONS_create (kx->peer, kx);
1434  GNUNET_assert (NULL == kx->keep_alive_task);
1435  update_timeout (kx);
1436  break;
1437 
1440  gettext_noop ("# timeouts prevented via PONG"),
1441  1,
1442  GNUNET_NO);
1443  update_timeout (kx);
1444  break;
1445 
1448  gettext_noop (
1449  "# rekey operations confirmed via PONG"),
1450  1,
1451  GNUNET_NO);
1453  monitor_notify_all (kx);
1454  update_timeout (kx);
1455  break;
1456 
1457  default:
1458  GNUNET_break (0);
1459  break;
1460  }
1461 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Response to a PING.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_SCHEDULER_Task * t
Main task.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
We&#39;ve received the other peers session key.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * retry_set_key_task
ID of task used for re-trying SET_KEY and PING message.
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
static int do_decrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Decrypt size bytes from in and write the result to out.
uint32_t challenge
Random number to make replay attacks harder.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t iv_seed
Seed for the IV.
uint32_t ping_challenge
What was our PING challenge number (for this peer)?
Information about the status of a key exchange with another peer.
struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key
Key we use to decrypt messages from the other peer (given to us by the other peer during the handshak...
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
static void update_timeout(struct GSC_KeyExchangeInfo *kx)
We&#39;ve seen a valid message from the other peer.
void GSC_SESSIONS_create(const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx)
Create a session, a key exchange was just completed.
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
static void derive_pong_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
Derive an IV from pong packet information.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
We&#39;ve sent our session key.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
We&#39;re rekeying (or had a timeout), so we have sent the other peer our new ephemeral key...
Here is the call graph for this function:

◆ GSC_KX_encrypt_and_transmit()

void GSC_KX_encrypt_and_transmit ( struct GSC_KeyExchangeInfo kx,
const void *  payload,
size_t  payload_size 
)

Encrypt and transmit a message with the given payload.

Parameters
kxkey exchange context
payloadpayload of the message
payload_sizenumber of bytes in payload

Definition at line 1515 of file gnunet-service-core_kx.c.

References calculate_seed(), derive_auth_key(), derive_iv(), do_encrypt(), GSC_KeyExchangeInfo::encrypt_key, ENCRYPTED_HEADER_SIZE, env, GNUNET_assert, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hmac(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_h2s2(), GNUNET_i2s(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_hton(), GSC_KeyExchangeInfo::has_excess_bandwidth, EncryptedMessage::hmac, EncryptedMessage::iv_seed, GSC_KeyExchangeInfo::last_sequence_number_sent, GSC_KeyExchangeInfo::mq, GSC_KeyExchangeInfo::peer, ph, and EncryptedMessage::sequence_number.

Referenced by transmit_typemap_task(), and try_transmission().

1518 {
1519  size_t used = payload_size + sizeof(struct EncryptedMessage);
1520  char pbuf[used]; /* plaintext */
1521  struct EncryptedMessage *em; /* encrypted message */
1522  struct EncryptedMessage *ph; /* plaintext header */
1523  struct GNUNET_MQ_Envelope *env;
1525  struct GNUNET_CRYPTO_AuthKey auth_key;
1526 
1527  ph = (struct EncryptedMessage *) pbuf;
1528  ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1529  ph->iv_seed = calculate_seed (kx);
1530  ph->reserved = 0;
1532  GNUNET_memcpy (&ph[1], payload, payload_size);
1533  env = GNUNET_MQ_msg_extra (em,
1534  payload_size,
1536  em->iv_seed = ph->iv_seed;
1537  derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, kx->peer);
1539  &iv,
1540  &ph->sequence_number,
1541  &em->sequence_number,
1542  used - ENCRYPTED_HEADER_SIZE));
1543 #if DEBUG_KX
1544  {
1545  struct GNUNET_HashCode hc;
1546 
1547  GNUNET_CRYPTO_hash (&ph->sequence_number,
1548  used - ENCRYPTED_HEADER_SIZE,
1549  &hc);
1551  "Encrypted payload `%s' of %u bytes for %s\n",
1552  GNUNET_h2s (&hc),
1553  (unsigned int) (used - ENCRYPTED_HEADER_SIZE),
1554  GNUNET_i2s (kx->peer));
1555  }
1556 #endif
1557  derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed);
1558  GNUNET_CRYPTO_hmac (&auth_key,
1559  &em->sequence_number,
1560  used - ENCRYPTED_HEADER_SIZE,
1561  &em->hmac);
1562 #if DEBUG_KX
1563  {
1564  struct GNUNET_HashCode hc;
1565 
1566  GNUNET_CRYPTO_hash (&auth_key, sizeof(auth_key), &hc);
1568  "For peer %s, used AC %s to create hmac %s\n",
1569  GNUNET_i2s (kx->peer),
1570  GNUNET_h2s (&hc),
1571  GNUNET_h2s2 (&em->hmac));
1572  }
1573 #endif
1575  GNUNET_MQ_send (kx->mq, env);
1576 }
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
uint32_t sequence_number
Sequence number, in network byte order.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
uint32_t last_sequence_number_sent
last sequence number transmitted
static int do_encrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Encrypt size bytes from in and write the result to out.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_HashCode hmac
MAC of the encrypted message (starting at sequence_number), used to verify message integrity...
static void derive_auth_key(struct GNUNET_CRYPTO_AuthKey *akey, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed)
Derive an authentication key from "set key" information.
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
Definition: crypto_hash.c:438
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
const char * GNUNET_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
Encapsulation for encrypted messages exchanged between peers.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
uint32_t iv_seed
Random value used for IV generation.
static uint32_t calculate_seed(struct GSC_KeyExchangeInfo *kx)
Calculate seed value we should use for a message.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static unsigned long long payload
How much data are we currently storing in the database?
#define ENCRYPTED_HEADER_SIZE
Number of bytes (at the beginning) of struct EncryptedMessage that are NOT encrypted.
#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE
Encapsulation for an encrypted message between peers.
static void derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, const struct GNUNET_PeerIdentity *identity)
Derive an IV from packet information.
int has_excess_bandwidth
GNUNET_YES if this peer currently has excess bandwidth.
#define GNUNET_log(kind,...)
struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key
Key we use to encrypt our messages for the other peer (initialized by us when we do the handshake)...
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
type for (message) authentication keys
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_encrypted()

static int check_encrypted ( void *  cls,
const struct EncryptedMessage m 
)
static

We received an encrypted message.

Check that it is well-formed (size-wise).

Parameters
clskey exchange context for encrypting the message
mencrypted message
Returns
GNUNET_OK if msg is well-formed (size-wise)

Definition at line 1588 of file gnunet-service-core_kx.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, EncryptedMessage::header, size, and GNUNET_MessageHeader::size.

1589 {
1590  uint16_t size = ntohs (m->header.size) - sizeof(*m);
1591 
1592  if (size < sizeof(struct GNUNET_MessageHeader))
1593  {
1594  GNUNET_break_op (0);
1595  return GNUNET_SYSERR;
1596  }
1597  return GNUNET_OK;
1598 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
Header for all communications.

◆ handle_encrypted()

static void handle_encrypted ( void *  cls,
const struct EncryptedMessage m 
)
static

We received an encrypted message.

Decrypt, validate and pass on to the appropriate clients.

Parameters
clskey exchange context for encrypting the message
mencrypted message

Definition at line 1609 of file gnunet-service-core_kx.c.

References _, buf, GSC_KeyExchangeInfo::decrypt_key, derive_auth_key(), derive_iv(), do_decrypt(), ENCRYPTED_HEADER_SIZE, GSC_KeyExchangeInfo::foreign_key_expires, gettext_noop, GNUNET_ALIGN, GNUNET_break_op, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_CORE_KX_STATE_UP, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hmac(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_h2s2(), GNUNET_i2s(), GNUNET_log, GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, GSC_my_identity, GSC_SESSIONS_end(), GSC_stats, EncryptedMessage::header, EncryptedMessage::hmac, EncryptedMessage::iv_seed, GSC_KeyExchangeInfo::keep_alive_task, GSC_KeyExchangeInfo::last_packets_bitmap, GSC_KeyExchangeInfo::last_sequence_number_received, MAX_MESSAGE_AGE, monitor_notify_all(), GSC_KeyExchangeInfo::mst, GSC_KeyExchangeInfo::peer, GNUNET_TIME_Relative::rel_value_us, send_key(), EncryptedMessage::sequence_number, size, GNUNET_MessageHeader::size, GSC_KeyExchangeInfo::status, EncryptedMessage::timestamp, and update_timeout().

1610 {
1611  struct GSC_KeyExchangeInfo *kx = cls;
1612  struct EncryptedMessage *pt; /* plaintext */
1613  struct GNUNET_HashCode ph;
1614  uint32_t snum;
1615  struct GNUNET_TIME_Absolute t;
1617  struct GNUNET_CRYPTO_AuthKey auth_key;
1618  uint16_t size = ntohs (m->header.size);
1619  char buf[size] GNUNET_ALIGN;
1620 
1621  if (GNUNET_CORE_KX_STATE_UP != kx->status)
1622  {
1624  gettext_noop (
1625  "# DATA message dropped (out of order)"),
1626  1,
1627  GNUNET_NO);
1628  return;
1629  }
1630  if (0 ==
1632  {
1633  GNUNET_log (
1635  _ (
1636  "Session to peer `%s' went down due to key expiration (should not happen)\n"),
1637  GNUNET_i2s (kx->peer));
1639  gettext_noop (
1640  "# sessions terminated by key expiration"),
1641  1,
1642  GNUNET_NO);
1643  GSC_SESSIONS_end (kx->peer);
1644  if (NULL != kx->keep_alive_task)
1645  {
1647  kx->keep_alive_task = NULL;
1648  }
1650  monitor_notify_all (kx);
1651  send_key (kx);
1652  return;
1653  }
1654 
1655  /* validate hash */
1656 #if DEBUG_KX
1657  {
1658  struct GNUNET_HashCode hc;
1659 
1662  "Received encrypted payload `%s' of %u bytes from %s\n",
1663  GNUNET_h2s (&hc),
1664  (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1665  GNUNET_i2s (kx->peer));
1666  }
1667 #endif
1668  derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed);
1669  GNUNET_CRYPTO_hmac (&auth_key,
1670  &m->sequence_number,
1671  size - ENCRYPTED_HEADER_SIZE,
1672  &ph);
1673 #if DEBUG_KX
1674  {
1675  struct GNUNET_HashCode hc;
1676 
1677  GNUNET_CRYPTO_hash (&auth_key, sizeof(auth_key), &hc);
1679  "For peer %s, used AC %s to verify hmac %s\n",
1680  GNUNET_i2s (kx->peer),
1681  GNUNET_h2s (&hc),
1682  GNUNET_h2s2 (&m->hmac));
1683  }
1684 #endif
1685  if (0 != memcmp (&ph, &m->hmac, sizeof(struct GNUNET_HashCode)))
1686  {
1687  /* checksum failed */
1689  "Failed checksum validation for a message from `%s'\n",
1690  GNUNET_i2s (kx->peer));
1691  return;
1692  }
1693  derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1694  /* decrypt */
1695  if (GNUNET_OK != do_decrypt (kx,
1696  &iv,
1697  &m->sequence_number,
1699  size - ENCRYPTED_HEADER_SIZE))
1700  {
1701  GNUNET_break_op (0);
1702  return;
1703  }
1705  "Decrypted %u bytes from %s\n",
1706  (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1707  GNUNET_i2s (kx->peer));
1708  pt = (struct EncryptedMessage *) buf;
1709 
1710  /* validate sequence number */
1711  snum = ntohl (pt->sequence_number);
1712  if (kx->last_sequence_number_received == snum)
1713  {
1715  "Received duplicate message, ignoring.\n");
1716  /* duplicate, ignore */
1718  gettext_noop ("# bytes dropped (duplicates)"),
1719  size,
1720  GNUNET_NO);
1721  return;
1722  }
1723  if ((kx->last_sequence_number_received > snum) &&
1724  (kx->last_sequence_number_received - snum > 32))
1725  {
1727  "Received ancient out of sequence message, ignoring.\n");
1728  /* ancient out of sequence, ignore */
1730  gettext_noop (
1731  "# bytes dropped (out of sequence)"),
1732  size,
1733  GNUNET_NO);
1734  return;
1735  }
1736  if (kx->last_sequence_number_received > snum)
1737  {
1738  uint32_t rotbit = 1U << (kx->last_sequence_number_received - snum - 1);
1739 
1740  if ((kx->last_packets_bitmap & rotbit) != 0)
1741  {
1743  "Received duplicate message, ignoring.\n");
1745  gettext_noop ("# bytes dropped (duplicates)"),
1746  size,
1747  GNUNET_NO);
1748  /* duplicate, ignore */
1749  return;
1750  }
1751  kx->last_packets_bitmap |= rotbit;
1752  }
1753  if (kx->last_sequence_number_received < snum)
1754  {
1755  unsigned int shift = (snum - kx->last_sequence_number_received);
1756 
1757  if (shift >= 8 * sizeof(kx->last_packets_bitmap))
1758  kx->last_packets_bitmap = 0;
1759  else
1760  kx->last_packets_bitmap <<= shift;
1761  kx->last_sequence_number_received = snum;
1762  }
1763 
1764  /* check timestamp */
1766  if (GNUNET_TIME_absolute_get_duration (t).rel_value_us >
1767  MAX_MESSAGE_AGE.rel_value_us)
1768  {
1770  "Message received far too old (%s). Content ignored.\n",
1773  GNUNET_YES));
1775  gettext_noop (
1776  "# bytes dropped (ancient message)"),
1777  size,
1778  GNUNET_NO);
1779  return;
1780  }
1781 
1782  /* process decrypted message(s) */
1783  update_timeout (kx);
1785  gettext_noop ("# bytes of payload decrypted"),
1786  size - sizeof(struct EncryptedMessage),
1787  GNUNET_NO);
1788  if (GNUNET_OK !=
1790  &buf[sizeof(struct EncryptedMessage)],
1791  size - sizeof(struct EncryptedMessage),
1792  GNUNET_YES,
1793  GNUNET_NO))
1794  GNUNET_break_op (0);
1795 }
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
uint64_t rel_value_us
The actual value.
enum GNUNET_CORE_KxState status
What is our connection status?
uint32_t last_packets_bitmap
Bit map indicating which of the 32 sequence numbers before the last were received (good for accepting...
uint32_t sequence_number
Sequence number, in network byte order.
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_HashCode hmac
MAC of the encrypted message (starting at sequence_number), used to verify message integrity...
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
struct GNUNET_MessageStreamTokenizer * mst
Our message stream tokenizer (for encrypted payload).
static void derive_auth_key(struct GNUNET_CRYPTO_AuthKey *akey, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed)
Derive an authentication key from "set key" information.
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
Definition: crypto_hash.c:438
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE.
const char * GNUNET_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
static int do_decrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Decrypt size bytes from in and write the result to out.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
Encapsulation for encrypted messages exchanged between peers.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:687
static char buf[2048]
int GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:114
Information about the status of a key exchange with another peer.
A 512-bit hashcode.
struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key
Key we use to decrypt messages from the other peer (given to us by the other peer during the handshak...
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
static void update_timeout(struct GSC_KeyExchangeInfo *kx)
We&#39;ve seen a valid message from the other peer.
static unsigned int size
Size of the "table".
Definition: peer.c:67
uint32_t iv_seed
Random value used for IV generation.
#define MAX_MESSAGE_AGE
What is the maximum age of a message for us to consider processing it? Note that this looks at the ti...
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
#define ENCRYPTED_HEADER_SIZE
Number of bytes (at the beginning) of struct EncryptedMessage that are NOT encrypted.
static void derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, const struct GNUNET_PeerIdentity *identity)
Derive an IV from packet information.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
uint32_t last_sequence_number_received
last sequence number received on this connection (highest)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:375
struct GNUNET_TIME_Absolute foreign_key_expires
At what time did the other peer generate the decryption key?
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
We&#39;ve sent our session key.
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_TIME_AbsoluteNBO timestamp
Timestamp.
type for (message) authentication keys
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:

◆ handle_transport_notify_excess_bw()

static void handle_transport_notify_excess_bw ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  connect_cls 
)
static

One of our neighbours has excess bandwidth, remember this.

Parameters
clsNULL
pididentity of the peer with excess bandwidth
connect_clsthe struct Neighbour

Definition at line 1806 of file gnunet-service-core_kx.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_YES, GSC_SESSIONS_solicit(), and GSC_KeyExchangeInfo::has_excess_bandwidth.

Referenced by GSC_KX_init().

1809 {
1810  struct GSC_KeyExchangeInfo *kx = connect_cls;
1811 
1813  "Peer %s has excess bandwidth available\n",
1814  GNUNET_i2s (pid));
1816  GSC_SESSIONS_solicit (pid);
1817 }
Information about the status of a key exchange with another peer.
void GSC_SESSIONS_solicit(const struct GNUNET_PeerIdentity *pid)
Traffic is being solicited for the given peer.
int has_excess_bandwidth
GNUNET_YES if this peer currently has excess bandwidth.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sign_ephemeral_key()

static void sign_ephemeral_key ( )
static

Setup the message that links the ephemeral key to our persistent public key and generate the appropriate signature.

Definition at line 1825 of file gnunet-service-core_kx.c.

References EphemeralKeyMessage::creation_time, current_ekm, EphemeralKeyMessage::ephemeral_key, EphemeralKeyMessage::expiration_time, GNUNET_assert, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_eddsa_sign(), GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_relative_add(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_YES, GSC_cfg, GSC_my_identity, EphemeralKeyMessage::header, EphemeralKeyMessage::origin_identity, EphemeralKeyMessage::purpose, GNUNET_CRYPTO_EccSignaturePurpose::purpose, REKEY_FREQUENCY, REKEY_TOLERANCE, EphemeralKeyMessage::sender_status, EphemeralKeyMessage::signature, GNUNET_CRYPTO_EccSignaturePurpose::size, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by do_rekey(), and GSC_KX_init().

1826 {
1827  current_ekm.header.size = htons (sizeof(struct EphemeralKeyMessage));
1829  current_ekm.sender_status = 0; /* to be set later */
1832  htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
1833  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
1834  + sizeof(struct GNUNET_TIME_AbsoluteNBO)
1835  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
1836  + sizeof(struct GNUNET_PeerIdentity));
1840  "core",
1841  "USE_EPHEMERAL_KEYS"))
1842  {
1846  REKEY_TOLERANCE)));
1847  }
1848  else
1849  {
1852  }
1860 }
#define GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY
Purpose is to set a session key.
#define REKEY_TOLERANCE
What time difference do we tolerate?
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
static struct GNUNET_CRYPTO_EcdhePrivateKey * my_ephemeral_key
Our ephemeral private key.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_CRYPTO_eddsa_sign(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:986
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the given ephemeral key expire (end of validity).
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
struct GNUNET_CRYPTO_EddsaSignature signature
An ECC signature of the origin_identity asserting the validity of the given ephemeral key...
struct GNUNET_TIME_AbsoluteNBO creation_time
At what time was this key created (beginning of validity).
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Information about what is being signed.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY
Session key exchange between peers.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:301
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:579
The identity of the host (wraps the signing key of the peer).
#define REKEY_FREQUENCY
How often do we rekey?
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
int32_t sender_status
Status of the sender (should be in enum PeerStateMachine), nbo.
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct EphemeralKeyMessage current_ekm
Current message we send for a key exchange.
Message transmitted with the signed ephemeral key of a peer.
struct GNUNET_PeerIdentity origin_identity
Public key of the signing peer (persistent version, not the ephemeral public key).
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_rekey()

static void do_rekey ( void *  cls)
static

Task run to trigger rekeying.

Parameters
clsclosure, NULL

Definition at line 1869 of file gnunet-service-core_kx.c.

References current_ekm, derive_session_keys(), EphemeralKeyMessage::ephemeral_key, GNUNET_assert, GNUNET_CORE_KX_STATE_DOWN, GNUNET_CORE_KX_STATE_KEY_SENT, GNUNET_CORE_KX_STATE_REKEY_SENT, GNUNET_CORE_KX_STATE_UP, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_SCHEDULER_add_delayed(), monitor_notify_all(), GSC_KeyExchangeInfo::next, REKEY_FREQUENCY, send_key(), sign_ephemeral_key(), and GSC_KeyExchangeInfo::status.

Referenced by GSC_KX_init().

1870 {
1871  struct GSC_KeyExchangeInfo *pos;
1872 
1874  if (NULL != my_ephemeral_key)
1877  GNUNET_assert (NULL != my_ephemeral_key);
1878  sign_ephemeral_key ();
1879  {
1880  struct GNUNET_HashCode eh;
1881 
1883  sizeof(current_ekm.ephemeral_key),
1884  &eh);
1885  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Rekeying to %s\n", GNUNET_h2s (&eh));
1886  }
1887  for (pos = kx_head; NULL != pos; pos = pos->next)
1888  {
1889  if (GNUNET_CORE_KX_STATE_UP == pos->status)
1890  {
1892  monitor_notify_all (pos);
1893  derive_session_keys (pos);
1894  }
1895  if (GNUNET_CORE_KX_STATE_DOWN == pos->status)
1896  {
1898  monitor_notify_all (pos);
1899  }
1900  monitor_notify_all (pos);
1901  send_key (pos);
1902  }
1903 }
enum GNUNET_CORE_KxState status
What is our connection status?
static struct GNUNET_CRYPTO_EcdhePrivateKey * my_ephemeral_key
Our ephemeral private key.
static void do_rekey(void *cls)
Task run to trigger rekeying.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
static void derive_session_keys(struct GSC_KeyExchangeInfo *kx)
Derive fresh session keys from the current ephemeral keys.
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create(void)
Create a new private key.
Definition: crypto_ecc.c:608
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void sign_ephemeral_key()
Setup the message that links the ephemeral key to our persistent public key and generate the appropri...
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GSC_KeyExchangeInfo * next
DLL.
Information about the status of a key exchange with another peer.
A 512-bit hashcode.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
static struct GNUNET_SCHEDULER_Task * rekey_task
Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.
#define REKEY_FREQUENCY
How often do we rekey?
#define GNUNET_log(kind,...)
static struct EphemeralKeyMessage current_ekm
Current message we send for a key exchange.
We&#39;ve sent our session key.
#define GNUNET_free(ptr)
Wrapper around free.
We&#39;re rekeying (or had a timeout), so we have sent the other peer our new ephemeral key...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_KX_init()

int GSC_KX_init ( struct GNUNET_CRYPTO_EddsaPrivateKey pk)

Initialize KX subsystem.

Parameters
pkprivate key to use for the peer
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1913 of file gnunet-service-core_kx.c.

References current_ekm, do_rekey(), EphemeralKeyMessage::ephemeral_key, GNUNET_break, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE, GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY, GNUNET_MESSAGE_TYPE_CORE_PING, GNUNET_MESSAGE_TYPE_CORE_PONG, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_notification_context_create(), GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SYSERR, GNUNET_TRANSPORT_core_connect(), GSC_cfg, GSC_KX_done(), GSC_my_identity, handle_transport_notify_connect(), handle_transport_notify_disconnect(), handle_transport_notify_excess_bw(), ping(), pk, pong(), GNUNET_PeerIdentity::public_key, REKEY_FREQUENCY, and sign_ephemeral_key().

Referenced by run().

1914 {
1916  { GNUNET_MQ_hd_fixed_size (ephemeral_key,
1918  struct EphemeralKeyMessage,
1919  NULL),
1922  struct PingMessage,
1923  NULL),
1926  struct PongMessage,
1927  NULL),
1928  GNUNET_MQ_hd_var_size (encrypted,
1930  struct EncryptedMessage,
1931  NULL),
1932  GNUNET_MQ_handler_end () };
1933 
1934  my_private_key = pk;
1938  if (NULL == my_ephemeral_key)
1939  {
1940  GNUNET_break (0);
1942  my_private_key = NULL;
1943  return GNUNET_SYSERR;
1944  }
1945  sign_ephemeral_key ();
1946  {
1947  struct GNUNET_HashCode eh;
1948 
1950  sizeof(current_ekm.ephemeral_key),
1951  &eh);
1953  "Starting with ephemeral key %s\n",
1954  GNUNET_h2s (&eh));
1955  }
1956 
1959  transport =
1961  &GSC_my_identity,
1962  handlers,
1963  NULL,
1967  if (NULL == transport)
1968  {
1969  GSC_KX_done ();
1970  return GNUNET_SYSERR;
1971  }
1972  return GNUNET_OK;
1973 }
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
static void ping(void *cls)
Send a ping to destination.
static struct GNUNET_CRYPTO_EcdhePrivateKey * my_ephemeral_key
Our ephemeral private key.
static void do_rekey(void *cls)
Task run to trigger rekeying.
Response to a PING.
static struct GNUNET_TRANSPORT_CoreHandle * transport
Transport service.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
static void handle_transport_notify_excess_bw(void *cls, const struct GNUNET_PeerIdentity *pid, void *connect_cls)
One of our neighbours has excess bandwidth, remember this.
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create(void)
Create a new private key.
Definition: crypto_ecc.c:608
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void sign_ephemeral_key()
Setup the message that links the ephemeral key to our persistent public key and generate the appropri...
struct GNUNET_TRANSPORT_CoreHandle * GNUNET_TRANSPORT_core_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_PeerIdentity *self, const struct GNUNET_MQ_MessageHandler *handlers, void *cls, GNUNET_TRANSPORT_NotifyConnect nc, GNUNET_TRANSPORT_NotifyDisconnect nd)
Connect to the transport service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_CORE_PONG
Confirmation that other peer is alive.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
We&#39;re sending an (encrypted) PING to the other peer to check if it can decrypt.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
Encapsulation for encrypted messages exchanged between peers.
A 512-bit hashcode.
Message handler for a specific message type.
#define GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY
Session key exchange between peers.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
static void pong(struct GNUNET_CADET_Channel *channel, const struct CadetPingMessage *ping)
Reply with a pong to origin.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
static void * handle_transport_notify_connect(void *cls, const struct GNUNET_PeerIdentity *pid, struct GNUNET_MQ_Handle *mq)
Function called by transport to notify us that a peer connected to us (on the network level)...
#define GNUNET_MESSAGE_TYPE_CORE_PING
Check that other peer is alive (challenge).
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:270
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:121
#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE
Encapsulation for an encrypted message between peers.
static struct GNUNET_SCHEDULER_Task * rekey_task
Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.
#define REKEY_FREQUENCY
How often do we rekey?
#define GNUNET_log(kind,...)
static struct EphemeralKeyMessage current_ekm
Current message we send for a key exchange.
static void handle_transport_notify_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *handler_cls)
Function called by transport telling us that a peer disconnected.
Message transmitted with the signed ephemeral key of a peer.
void GSC_KX_done()
Shutdown KX subsystem.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_KX_done()

void GSC_KX_done ( void  )

Shutdown KX subsystem.

Definition at line 1980 of file gnunet-service-core_kx.c.

References GNUNET_free, GNUNET_notification_context_destroy(), GNUNET_SCHEDULER_cancel(), and GNUNET_TRANSPORT_core_disconnect().

Referenced by GSC_KX_init(), and shutdown_task().

1981 {
1982  if (NULL != transport)
1983  {
1985  transport = NULL;
1986  }
1987  if (NULL != rekey_task)
1988  {
1990  rekey_task = NULL;
1991  }
1992  if (NULL != my_ephemeral_key)
1993  {
1995  my_ephemeral_key = NULL;
1996  }
1997  if (NULL != my_private_key)
1998  {
2000  my_private_key = NULL;
2001  }
2002  if (NULL != nc)
2003  {
2005  nc = NULL;
2006  }
2007 }
static struct GNUNET_CRYPTO_EcdhePrivateKey * my_ephemeral_key
Our ephemeral private key.
static struct GNUNET_TRANSPORT_CoreHandle * transport
Transport service.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
static struct GNUNET_SCHEDULER_Task * rekey_task
Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.
void GNUNET_TRANSPORT_core_disconnect(struct GNUNET_TRANSPORT_CoreHandle *handle)
Disconnect from the transport service.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_NEIGHBOURS_get_queue_length()

unsigned int GSC_NEIGHBOURS_get_queue_length ( const struct GSC_KeyExchangeInfo kxinfo)

Check how many messages are queued for the given neighbour.

Parameters
kxinfodata about neighbour to check
Returns
number of items in the message queue

Definition at line 2017 of file gnunet-service-core_kx.c.

References GNUNET_MQ_get_length(), and GSC_KeyExchangeInfo::mq.

Referenced by try_transmission().

2018 {
2019  return GNUNET_MQ_get_length (kxinfo->mq);
2020 }
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_NEIGHBOURS_check_excess_bandwidth()

int GSC_NEIGHBOURS_check_excess_bandwidth ( const struct GSC_KeyExchangeInfo kxinfo)

Check if the given neighbour has excess bandwidth available.

Parameters
targetneighbour to check
Returns
GNUNET_YES if excess bandwidth is available, GNUNET_NO if not

Definition at line 2030 of file gnunet-service-core_kx.c.

References GSC_KeyExchangeInfo::has_excess_bandwidth.

Referenced by try_transmission().

2031 {
2032  return kxinfo->has_excess_bandwidth;
2033 }
int has_excess_bandwidth
GNUNET_YES if this peer currently has excess bandwidth.
Here is the caller graph for this function:

◆ GSC_KX_handle_client_monitor_peers()

void GSC_KX_handle_client_monitor_peers ( struct GNUNET_MQ_Handle mq)

Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.

For this request type, the client does not have to have transmitted an INIT request. All current peers are returned, regardless of which message types they accept.

Parameters
mqmessage queue to add for monitoring

Definition at line 2045 of file gnunet-service-core_kx.c.

References env, GNUNET_CORE_KX_ITERATION_FINISHED, GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_notification_context_add(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_UNIT_FOREVER_ABS, msg, GSC_KeyExchangeInfo::next, GSC_KeyExchangeInfo::peer, MonitorNotifyMessage::peer, MonitorNotifyMessage::state, GSC_KeyExchangeInfo::status, GSC_KeyExchangeInfo::timeout, and MonitorNotifyMessage::timeout.

Referenced by handle_client_monitor_peers().

2046 {
2047  struct GNUNET_MQ_Envelope *env;
2048  struct MonitorNotifyMessage *done_msg;
2049  struct GSC_KeyExchangeInfo *kx;
2050 
2052  for (kx = kx_head; NULL != kx; kx = kx->next)
2053  {
2054  struct GNUNET_MQ_Envelope *env;
2055  struct MonitorNotifyMessage *msg;
2056 
2058  msg->state = htonl ((uint32_t) kx->status);
2059  msg->peer = *kx->peer;
2061  GNUNET_MQ_send (mq, env);
2062  }
2064  done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
2066  GNUNET_MQ_send (mq, env);
2067 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
enum GNUNET_CORE_KxState status
What is our connection status?
struct GNUNET_TIME_AbsoluteNBO timeout
How long will we stay in this state (if nothing else happens)?
Definition: core.h:322
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:160
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
struct GSC_KeyExchangeInfo * next
DLL.
Information about the status of a key exchange with another peer.
This is not a state in a peer&#39;s state machine, but a special value used with the GNUNET_CORE_MonitorC...
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
uint32_t state
New peer state, an enum GNUNET_CORE_KxState in NBO.
Definition: core.h:312
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no PONGs)?
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
Message sent by the service to monitor clients to notify them about a peer changing status...
Definition: core.h:302
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY
Reply for monitor by CORE service.
struct GNUNET_PeerIdentity peer
Identity of the peer.
Definition: core.h:317
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ transport

struct GNUNET_TRANSPORT_CoreHandle* transport
static

Transport service.

Definition at line 364 of file gnunet-service-core_kx.c.

Referenced by GST_blacklist_add_peer().

◆ my_private_key

struct GNUNET_CRYPTO_EddsaPrivateKey* my_private_key
static

Our private key.

Definition at line 369 of file gnunet-service-core_kx.c.

◆ my_ephemeral_key

struct GNUNET_CRYPTO_EcdhePrivateKey* my_ephemeral_key
static

Our ephemeral private key.

Definition at line 374 of file gnunet-service-core_kx.c.

◆ current_ekm

struct EphemeralKeyMessage current_ekm
static

Current message we send for a key exchange.

Definition at line 379 of file gnunet-service-core_kx.c.

Referenced by do_rekey(), GSC_KX_init(), send_key(), and sign_ephemeral_key().

◆ kx_head

struct GSC_KeyExchangeInfo* kx_head
static

DLL head.

Definition at line 384 of file gnunet-service-core_kx.c.

◆ kx_tail

struct GSC_KeyExchangeInfo* kx_tail
static

DLL tail.

Definition at line 389 of file gnunet-service-core_kx.c.

◆ rekey_task

struct GNUNET_SCHEDULER_Task* rekey_task
static

Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.

Definition at line 395 of file gnunet-service-core_kx.c.

◆ nc

struct GNUNET_NotificationContext* nc
static

Notification context for broadcasting to monitors.

Definition at line 400 of file gnunet-service-core_kx.c.