From 45e53e043ea0512215316a5ba21bd4cfd0a300e1 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 26 Apr 2024 23:59:18 +0200 Subject: fixed shared key invalidation --- ecp/src/ecp/core.c | 225 +++++++++++++++++++++++------------------------------ ecp/src/ecp/core.h | 9 +-- 2 files changed, 101 insertions(+), 133 deletions(-) (limited to 'ecp') diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index 6355a03..3e4aae1 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -694,7 +694,18 @@ int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *pub return ECP_ERR_COOKIE; } -static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key) { +static ECPDHKey *conn_dhkey_get(ECPConnection *conn, unsigned char idx) { + ECPDHKey *key = NULL; + + if (idx < ECP_MAX_CONN_KEY) { + key = &conn->key[idx]; + } + + if (key && key->valid) return key; + return NULL; +} + +static int conn_dhkey_set(ECPConnection *conn, unsigned char idx, ECPDHKey *key) { ECPSocket *sock = conn->sock; if (idx >= ECP_MAX_CONN_KEY) return ECP_ERR_ECDH_IDX; @@ -705,6 +716,15 @@ static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key) } #endif + if (conn->key[idx].valid) { + unsigned char _idx = idx % ECP_MAX_NODE_KEY; + int i; + + for (i=0; ishkey[i][_idx].valid = 0; + } + } + conn->key[idx] = *key; #ifdef ECP_WITH_HTABLE @@ -719,67 +739,58 @@ static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key) return ECP_OK; } -static void conn_dhkey_del(ECPConnection *conn, unsigned char idx) { - ECPSocket *sock = conn->sock; +static int conn_dhkey_new(ECPConnection *conn, ECPDHKey *key) { + unsigned char idx; + int rv; - if (idx >= ECP_MAX_CONN_KEY) return; + idx = conn->key_curr; + if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX; -#ifdef ECP_WITH_HTABLE - if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn) && conn->key[idx].valid) { - ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public); - } -#endif + idx = (idx + 1) % ECP_MAX_CONN_KEY; + rv = conn_dhkey_set(conn, idx, key); + if (rv) return rv; + conn->key_next = idx; - memset(&conn->key[idx], 0, sizeof(conn->key[idx])); + return ECP_OK; } -static ECPDHKey *conn_dhkey_get(ECPConnection *conn, unsigned char idx) { - ECPDHKey *key = NULL; - - /* always outbound */ - if (idx < ECP_MAX_CONN_KEY) { - key = &conn->key[idx]; +static void conn_dhkey_set_curr(ECPConnection *conn) { + if (conn->key_next != ECP_ECDH_IDX_INV) { + conn->key_curr = conn->key_next; + conn->key_next = ECP_ECDH_IDX_INV; } - - if (key && key->valid) return key; - return NULL; } -static ECPDHPub *conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx) { - ECPDHPub *key = NULL; - - if (idx == ECP_ECDH_IDX_PERMA) { - key = &conn->remote.key_perma; - } else if ((idx & ECP_ECDH_IDX_MASK) == idx) { - key = &conn->rkey[idx % ECP_MAX_NODE_KEY]; - } - - if (key && key->valid) return key; - return NULL; -} +static int conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public) { + if (ecp_conn_is_inb(conn)) { + ECPSocket *sock = conn->sock; + int rv; -/* node will send public key */ -static void conn_dhkey_send_pub(ECPConnection *conn, unsigned char idx) { - unsigned char _idx; - int i; + rv = ecp_sock_dhkey_get_pub(sock, idx, public); + if (rv) return rv; - _idx = idx % ECP_MAX_NODE_KEY; - if (ecp_conn_is_outb(conn)) { - if (idx == conn->key_curr) return; + if (*idx != conn->key_curr) { + unsigned char _idx = *idx % ECP_MAX_NODE_KEY; + int i; - for (i=0; ishkey[i][_idx].valid = 0; + for (i=0; ishkey[_idx][i].valid = 0; + } } } else { - if (idx == conn->rkey_curr) return; - - for (i=0; ishkey[_idx][i].valid = 0; + if (conn->key_next != ECP_ECDH_IDX_INV) { + *idx = conn->key_next; + } else { + *idx = conn->key_curr; } + if ((*idx == ECP_ECDH_IDX_INV) || !conn->key[*idx].valid) return ECP_ERR_ECDH_IDX; + + memcpy(public, &conn->key[*idx].public, sizeof(conn->key[*idx].public)); } + + return ECP_OK; } -/* node received public key */ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public) { unsigned char _idx; ECPDHPub *key; @@ -824,9 +835,23 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p conn->shkey[i][_idx].valid = 0; } } + return ECP_OK; } +static ECPDHPub *conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx) { + ECPDHPub *key = NULL; + + if (idx == ECP_ECDH_IDX_PERMA) { + key = &conn->remote.key_perma; + } else if ((idx & ECP_ECDH_IDX_MASK) == idx) { + key = &conn->rkey[idx % ECP_MAX_NODE_KEY]; + } + + if (key && key->valid) return key; + return NULL; +} + static int conn_shkey_get(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, ecp_aead_key_t *shkey) { ECPDHPub *pub; ECPDHKey *priv; @@ -909,19 +934,6 @@ void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { conn->keyx_ts = 0; } -int ecp_conn_init_outb(ECPConnection *conn) { - ECPDHKey key; - int rv; - - rv = ecp_dhkey_gen(&key); - if (rv) return rv; - - conn->key_curr = 0; - conn->key[conn->key_curr] = key; - - return ECP_OK; -} - void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) { flags &= ECP_CONN_FLAG_MASK; conn->flags_im |= flags; @@ -1342,9 +1354,7 @@ void ecp_conn_refcount_dec(ECPConnection *conn) { int ecp_conn_dhkey_new(ECPConnection *conn) { ECPSocket *sock = conn->sock; ECPDHKey new_key; - unsigned char idx; int rv; - ssize_t _rv; rv = ecp_dhkey_gen(&new_key); if (rv) return rv; @@ -1354,104 +1364,59 @@ int ecp_conn_dhkey_new(ECPConnection *conn) { pthread_mutex_lock(&conn->mutex); #endif - idx = conn->key_curr; - if (idx != ECP_ECDH_IDX_INV) { - idx = (idx + 1) % ECP_MAX_CONN_KEY; - rv = conn_dhkey_new(conn, idx, &new_key); - conn->key_next = idx; - } + rv = conn_dhkey_new(conn, &new_key); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); if (ecp_conn_is_outb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX; return rv; } int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key) { - int rv = ECP_OK; + ECPDHKey *_key; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - if (idx < ECP_MAX_CONN_KEY) { - *key = conn->key[idx]; - } else { - rv = ECP_ERR_ECDH_IDX; - } + if (idx == ECP_ECDH_IDX_INV) idx = conn->key_curr; + _key = conn_dhkey_get(conn, idx); + if (_key) *key = *_key; #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif - if (!rv && !key->valid) rv = ECP_ERR_ECDH_IDX; - return rv; + if (_key == NULL) return ECP_ERR_ECDH_IDX; + return ECP_OK; } -int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key) { - int rv = ECP_OK; - +void ecp_conn_dhkey_set_curr(ECPConnection *conn) { #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - if (idx == ECP_ECDH_IDX_PERMA) { - *key = conn->remote.key_perma; - } else if ((idx & ECP_ECDH_IDX_MASK) == idx) { - *key = conn->rkey[idx % ECP_MAX_NODE_KEY]; - } else { - rv = ECP_ERR_ECDH_IDX; - } + conn_dhkey_set_curr(conn); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif - - if (!rv && !key->valid) rv = ECP_ERR_ECDH_IDX; - return rv; } -int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public, int will_send) { +int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public) { int rv = ECP_OK; unsigned char _idx; - if (ecp_conn_is_inb(conn)) { - ECPSocket *sock = conn->sock; - - rv = ecp_sock_dhkey_get_pub(sock, &_idx, public); - if (rv) return rv; - -#ifdef ECP_WITH_PTHREAD - if (will_send) pthread_mutex_lock(&conn->mutex); -#endif - } else { - ECPDHKey *key; - #ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(&conn->mutex); #endif - if (will_send && (conn->key_next != ECP_ECDH_IDX_INV)) { - _idx = conn->key_next; - } else { - _idx = conn->key_curr; - } - if (_idx == ECP_ECDH_IDX_INV) rv = ECP_ERR_ECDH_IDX; - - if (!rv) { - key = &conn->key[_idx]; - if (!key->valid) rv = ECP_ERR_ECDH_IDX; - } - if (!rv) memcpy(public, &key->public, sizeof(key->public)); - } - - if (!rv && will_send) conn_dhkey_send_pub(conn, _idx); + rv = conn_dhkey_get_pub(conn, &_idx, public); #ifdef ECP_WITH_PTHREAD - if (will_send || ecp_conn_is_outb(conn)) pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(&conn->mutex); #endif if (rv) return rv; @@ -1481,19 +1446,23 @@ int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_publ return rv; } -void ecp_conn_dhkey_set_curr(ECPConnection *conn) { +int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key) { + ECPDHPub *_key; + #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - if (conn->key_next != ECP_ECDH_IDX_INV) { - conn->key_curr = conn->key_next; - conn->key_next = ECP_ECDH_IDX_INV; - } + if (idx == ECP_ECDH_IDX_INV) idx = conn->rkey_curr; + _key = conn_dhkey_get_remote(conn, idx); + if (_key) *key = *_key; #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif + + if (_key == NULL) return ECP_ERR_ECDH_IDX; + return ECP_OK; } void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_send_open_t send_open) { @@ -1617,7 +1586,7 @@ static ssize_t _retry_ireq(ECPConnection *conn, ECPTimerItem *ti) { refcount_ok = (conn->refcount == refcount_ok); if (refcount_ok) { - rv = conn_dhkey_new(conn, conn->key_curr, &key); + rv = conn_dhkey_set(conn, conn->key_curr, &key); } } @@ -1771,8 +1740,8 @@ ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload) { _rv = ecp_sock_dhkey_get(sock, ECP_ECDH_IDX_PERMA, &key_perma); if (!_rv) _rv = ecp_conn_dhkey_get_remote(conn, ECP_ECDH_IDX_PERMA, &rkey_perma); - if (!_rv) _rv = ecp_conn_dhkey_get_remote(conn, conn->rkey_curr, &rkey_curr); - if (!_rv) _rv = ecp_conn_dhkey_get_pub(conn, NULL, &public, 0); + if (!_rv) _rv = ecp_conn_dhkey_get_remote(conn, ECP_ECDH_IDX_INV, &rkey_curr); + if (!_rv) _rv = ecp_conn_dhkey_get_pub(conn, NULL, &public); if (_rv) return _rv; memcpy(vbox_buf, &public, ECP_SIZE_ECDH_PUB); @@ -2011,7 +1980,7 @@ static ssize_t _send_kxreq(ECPConnection *conn, ECPTimerItem *ti) { ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KEYX_REQ); msg = ecp_pld_get_msg(payload.buffer, payload.size); - _rv = ecp_conn_dhkey_get_pub(conn, msg, (ecp_ecdh_public_t *)(msg+1), 1); + _rv = ecp_conn_dhkey_get_pub(conn, msg, (ecp_ecdh_public_t *)(msg+1)); if (_rv) return _rv; rv = ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REQ), 0, ti); @@ -2047,7 +2016,7 @@ ssize_t ecp_send_keyx_rep(ECPConnection *conn) { ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KEYX_REP); msg = ecp_pld_get_msg(payload.buffer, payload.size); - _rv = ecp_conn_dhkey_get_pub(conn, msg, (ecp_ecdh_public_t *)(msg+1), 1); + _rv = ecp_conn_dhkey_get_pub(conn, msg, (ecp_ecdh_public_t *)(msg+1)); if (_rv) return _rv; rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REP), 0); diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index 3b1d7b4..212bee1 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -47,7 +47,7 @@ #define ECP_MAX_MTYPE 16 #define ECP_MAX_PARENT 3 #define ECP_MAX_SEQ_FWD 1024 -#define ECP_MAX_NONCE_FWD 100 /* max diff between current sock nonce and auth tag nonce (open req message) */ +#define ECP_MAX_NONCE_FWD 100 /* max diff between current irep nonce and auth tag nonce */ #define ECP_MAX_EXPIRED 100 #define ECP_MIN_KEYX_DT 3600 @@ -401,7 +401,6 @@ int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *pub ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype); void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); -int ecp_conn_init_outb(ECPConnection *conn); void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags); void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags); void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key); @@ -435,10 +434,10 @@ void ecp_conn_refcount_dec(ECPConnection *conn); int ecp_conn_dhkey_new(ECPConnection *conn); int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key); -int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key); -int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public, int will_send); -int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public); void ecp_conn_dhkey_set_curr(ECPConnection *conn); +int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public); +int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public); +int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key); void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_send_open_t send_open); ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn); -- cgit v1.2.3