GNUnet 0.22.1
gnunet-service-core_kx.h File Reference

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

#include "gnunet_util_lib.h"
Include dependency graph for gnunet-service-core_kx.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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...
 
int GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
 Initialize KX subsystem. More...
 
void GSC_KX_done (void)
 Shutdown KX subsystem. More...
 
int GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *target)
 Check if the given neighbour has excess bandwidth available. More...
 
unsigned int GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *target)
 Check how many messages are queued for the given neighbour. More...
 
void GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
 Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. 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.h.

Function Documentation

◆ 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 1630 of file gnunet-service-core_kx.c.

1633{
1634 size_t used = payload_size + sizeof(struct EncryptedMessage);
1635 char pbuf[used]; /* plaintext */
1636 struct EncryptedMessage *em; /* encrypted message */
1637 struct EncryptedMessage *ph; /* plaintext header */
1638 struct GNUNET_MQ_Envelope *env;
1639#if CONG_CRYPTO_ENABLED
1640#else
1642 struct GNUNET_CRYPTO_AuthKey auth_key;
1643#endif
1644
1645 ph = (struct EncryptedMessage *) pbuf;
1646 ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1647 ph->reserved = 0;
1649 GNUNET_memcpy (&ph[1], payload, payload_size);
1651 payload_size,
1653#if CONG_CRYPTO_ENABLED
1654 randombytes_buf (ph->nonce, sizeof (ph->nonce));
1655 GNUNET_assert (0 ==
1656 crypto_aead_xchacha20poly1305_ietf_encrypt_detached (
1657 (unsigned char*) &em->sequence_number,
1658 em->tag,
1659 NULL,
1660 (unsigned char*) &ph->sequence_number,
1661 used - ENCRYPTED_HEADER_SIZE,
1662 NULL, 0,
1663 NULL,
1664 ph->nonce,
1665 kx->encrypt_key));
1666#else
1667 ph->iv_seed = calculate_seed (kx);
1668 em->iv_seed = ph->iv_seed;
1669 derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, kx->peer);
1671 &iv,
1672 &ph->sequence_number,
1673 &em->sequence_number,
1674 used - ENCRYPTED_HEADER_SIZE));
1675#if DEBUG_KX
1676 {
1677 struct GNUNET_HashCode hc;
1678
1680 used - ENCRYPTED_HEADER_SIZE,
1681 &hc);
1683 "Encrypted payload `%s' of %u bytes for %s\n",
1684 GNUNET_h2s (&hc),
1685 (unsigned int) (used - ENCRYPTED_HEADER_SIZE),
1686 GNUNET_i2s (kx->peer));
1687 }
1688#endif
1689 derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed);
1690 GNUNET_CRYPTO_hmac (&auth_key,
1691 &em->sequence_number,
1692 used - ENCRYPTED_HEADER_SIZE,
1693 &em->hmac);
1694#if DEBUG_KX
1695 {
1696 struct GNUNET_HashCode hc;
1697
1698 GNUNET_CRYPTO_hash (&auth_key, sizeof(auth_key), &hc);
1700 "For peer %s, used AC %s to create hmac %s\n",
1701 GNUNET_i2s (kx->peer),
1702 GNUNET_h2s (&hc),
1703 GNUNET_h2s2 (&em->hmac));
1704 }
1705#endif
1706#endif
1708 GNUNET_MQ_send (kx->mq, env);
1709}
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static uint32_t calculate_seed(struct GSC_KeyExchangeInfo *kx)
Calculate seed value we should use for a message.
#define ENCRYPTED_HEADER_SIZE
Number of bytes (at the beginning) of struct EncryptedMessage that are NOT encrypted.
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.
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.
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.
static unsigned long long payload
How much data are we currently storing in the database?
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
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:330
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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).
const char * GNUNET_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
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:305
#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:63
#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE
Encapsulation for an encrypted message between peers.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:640
Encapsulation for encrypted messages exchanged between peers.
uint32_t iv_seed
Random value used for IV generation.
struct GNUNET_TIME_AbsoluteNBO timestamp
Timestamp.
uint32_t sequence_number
Sequence number, in network byte order.
struct GNUNET_HashCode hmac
MAC of the encrypted message (starting at sequence_number), used to verify message integrity.
uint32_t reserved
Reserved, always zero.
type for (message) authentication keys
A 512-bit hashcode.
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 struct GNUNET_PeerIdentity * peer
Identity of the peer.
uint32_t last_sequence_number_sent
last sequence number transmitted
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
int has_excess_bandwidth
GNUNET_YES if this peer currently has excess bandwidth.

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, payload, GSC_KeyExchangeInfo::peer, EncryptedMessage::reserved, EncryptedMessage::sequence_number, and EncryptedMessage::timestamp.

Referenced by transmit_typemap_task(), and try_transmission().

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 2050 of file gnunet-service-core_kx.c.

2051{
2053 GNUNET_MQ_hd_fixed_size (ephemeral_key,
2055 struct EphemeralKeyMessage,
2056 NULL),
2059 struct PingMessage,
2060 NULL),
2063 struct PongMessage,
2064 NULL),
2065 GNUNET_MQ_hd_var_size (encrypted,
2067 struct EncryptedMessage,
2068 NULL),
2070 };
2071
2072 my_private_key = *pk;
2077 {
2078 struct GNUNET_HashCode eh;
2079
2081 sizeof(current_ekm.ephemeral_key),
2082 &eh);
2084 "Starting with ephemeral key %s\n",
2085 GNUNET_h2s (&eh));
2086 }
2087
2090 transport =
2093 handlers,
2094 NULL,
2097 if (NULL == transport)
2098 {
2099 GSC_KX_done ();
2100 return GNUNET_SYSERR;
2101 }
2102 return GNUNET_OK;
2103}
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
static struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key
Our private key.
static struct GNUNET_CRYPTO_EcdhePrivateKey my_ephemeral_key
Our ephemeral private key.
#define REKEY_FREQUENCY
How often do we rekey?
static void sign_ephemeral_key()
Setup the message that links the ephemeral key to our persistent public key and generate the appropri...
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.
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
static struct EphemeralKeyMessage current_ekm
Current message we send for a key exchange.
static void do_rekey(void *cls)
Task run to trigger rekeying.
void GSC_KX_done()
Shutdown KX subsystem.
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).
static struct GNUNET_SCHEDULER_Task * rekey_task
Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.
static struct GNUNET_TRANSPORT_CoreHandle * transport
Transport service.
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.
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:454
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:201
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:122
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_CORE_PING
Check that other peer is alive (challenge).
#define GNUNET_MESSAGE_TYPE_CORE_PONG
Confirmation that other peer is alive.
#define GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY
Session key exchange between peers.
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:1276
Message transmitted with the signed ephemeral key of a peer.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
Message handler for a specific message type.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
We're sending an (encrypted) PING to the other peer to check if it can decrypt.
Response to a PING.

References current_ekm, do_rekey(), EphemeralKeyMessage::ephemeral_key, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_INFO, 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(), handlers, my_ephemeral_key, my_private_key, nc, pk, GNUNET_PeerIdentity::public_key, REKEY_FREQUENCY, rekey_task, sign_ephemeral_key(), and transport.

Referenced by run().

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 2110 of file gnunet-service-core_kx.c.

2111{
2112 if (NULL != transport)
2113 {
2115 transport = NULL;
2116 }
2117 if (NULL != rekey_task)
2118 {
2120 rekey_task = NULL;
2121 }
2122 memset (&my_ephemeral_key,
2123 0,
2124 sizeof (my_ephemeral_key));
2125 memset (&my_private_key,
2126 0,
2127 sizeof (my_private_key));
2128 if (NULL != nc)
2129 {
2131 nc = NULL;
2132 }
2133}
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:138
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979

References GNUNET_notification_context_destroy(), GNUNET_SCHEDULER_cancel(), GNUNET_TRANSPORT_core_disconnect(), my_ephemeral_key, my_private_key, nc, rekey_task, and transport.

Referenced by GSC_KX_init(), and shutdown_task().

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 target)

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 2150 of file gnunet-service-core_kx.c.

2151{
2152 return kxinfo->has_excess_bandwidth;
2153}

References GSC_KeyExchangeInfo::has_excess_bandwidth.

Referenced by try_transmission().

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
targetneighbour to check
Returns
number of items in the message queue
Parameters
kxinfodata about neighbour to check
Returns
number of items in the message queue

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

2144{
2145 return GNUNET_MQ_get_length (kxinfo->mq);
2146}
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:293

References GNUNET_MQ_get_length(), and GSC_KeyExchangeInfo::mq.

Referenced by try_transmission().

Here is the call graph for this function:
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 2165 of file gnunet-service-core_kx.c.

2166{
2167 struct GNUNET_MQ_Envelope *env;
2168 struct MonitorNotifyMessage *done_msg;
2169 struct GSC_KeyExchangeInfo *kx;
2170
2172 for (kx = kx_head; NULL != kx; kx = kx->next)
2173 {
2174 struct GNUNET_MQ_Envelope *env_notify;
2175 struct MonitorNotifyMessage *msg;
2176
2178 msg->state = htonl ((uint32_t) kx->status);
2179 msg->peer = *kx->peer;
2180 msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout);
2181 GNUNET_MQ_send (mq, env_notify);
2182 }
2184 done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
2187}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
@ GNUNET_CORE_KX_ITERATION_FINISHED
This is not a state in a peer's state machine, but a special value used with the GNUNET_CORE_MonitorC...
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:161
#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY
Reply for monitor by CORE service.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
Information about the status of a key exchange with another peer.
struct GSC_KeyExchangeInfo * next
DLL.
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no PONGs)?
enum GNUNET_CORE_KxState status
What is our connection status?
Message sent by the service to monitor clients to notify them about a peer changing status.
Definition: core.h:301
uint32_t state
New peer state, an enum GNUNET_CORE_KxState in NBO.
Definition: core.h:310
struct GNUNET_TIME_AbsoluteNBO timeout
How long will we stay in this state (if nothing else happens)?
Definition: core.h:320

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, kx_head, mq, msg, nc, GSC_KeyExchangeInfo::next, GSC_KeyExchangeInfo::peer, MonitorNotifyMessage::state, GSC_KeyExchangeInfo::status, MonitorNotifyMessage::timeout, and GSC_KeyExchangeInfo::timeout.

Referenced by handle_client_monitor_peers().

Here is the call graph for this function:
Here is the caller graph for this function: