summaryrefslogtreecommitdiff
path: root/ecp
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2024-04-26 23:59:18 +0200
committerUros Majstorovic <majstor@majstor.org>2024-04-26 23:59:18 +0200
commit45e53e043ea0512215316a5ba21bd4cfd0a300e1 (patch)
tree34485b2660edc6bfa99b4090cfc7365eec983838 /ecp
parent4d50119033c574806d393643d96f11e065142822 (diff)
fixed shared key invalidation
Diffstat (limited to 'ecp')
-rw-r--r--ecp/src/ecp/core.c225
-rw-r--r--ecp/src/ecp/core.h9
2 files changed, 101 insertions, 133 deletions
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; i<ECP_MAX_NODE_KEY; i++) {
+ conn->shkey[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; i<ECP_MAX_NODE_KEY; i++) {
- conn->shkey[i][_idx].valid = 0;
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ conn->shkey[_idx][i].valid = 0;
+ }
}
} else {
- if (idx == conn->rkey_curr) return;
-
- for (i=0; i<ECP_MAX_NODE_KEY; i++) {
- conn->shkey[_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);