summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2024-04-26 19:13:23 +0200
committerUros Majstorovic <majstor@majstor.org>2024-04-26 19:13:23 +0200
commit4d50119033c574806d393643d96f11e065142822 (patch)
treefb208e960c6ce948fa6cc6ce10e77889bfe02252
parent8428b7703c2b5d510aed8f57f146d2717b5529bc (diff)
added max diff between current irep nonce and auth tag nonce
-rw-r--r--ecp/doc/protocol.md2
-rw-r--r--ecp/src/ecp/core.c44
-rw-r--r--ecp/src/ecp/core.h8
3 files changed, 18 insertions, 36 deletions
diff --git a/ecp/doc/protocol.md b/ecp/doc/protocol.md
index 12378a6..ec69e6b 100644
--- a/ecp/doc/protocol.md
+++ b/ecp/doc/protocol.md
@@ -64,7 +64,7 @@ Client periodically sends key exchange packet to check if server has changed its
Server will encrypt subsequent packets to client with new key only after it receives packet from client which was encrypted with that new key. Client can use new key immediately after receiving key exchange response.
If client does not receive response to key exchange after some number of tries, it should consider connection broken.
-Server can purge connections after some time of inactivity. <!-- Before purging connections server must generate new "cookie key" &mdash; see authentication tag in init reply message below. -->
+Server can purge connections after some time of inactivity.
##Messages defined by EllipticCP
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c
index d111a97..6355a03 100644
--- a/ecp/src/ecp/core.c
+++ b/ecp/src/ecp/core.c
@@ -378,7 +378,7 @@ static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ec
static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired) {
ECPConnection *conn;
- ECPConnection *to_remove[ECP_MAX_EXP];
+ ECPConnection *to_remove[ECP_MAX_EXPIRED];
int i, remove_cnt, expired;
ecp_sts_t now = ecp_tm_get_s();
@@ -421,7 +421,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t
to_remove[remove_cnt] = conn;
remove_cnt++;
- if (remove_cnt == ECP_MAX_EXP) {
+ if (remove_cnt == ECP_MAX_EXPIRED) {
if (!rv) {
remove_next = ecp_ht_itr_key(&itr);
} else {
@@ -471,7 +471,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t
if (expired) {
to_remove[remove_cnt] = conn;
remove_cnt++;
- if (remove_cnt == ECP_MAX_EXP) break;
+ if (remove_cnt == ECP_MAX_EXPIRED) break;
}
}
@@ -484,7 +484,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t
ecp_conn_refcount_dec(to_remove[i]);
}
- } while (remove_cnt < ECP_MAX_EXP);
+ } while (remove_cnt < ECP_MAX_EXPIRED);
#endif /* ECP_WITH_HTABLE */
}
@@ -639,34 +639,11 @@ int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_
return ECP_OK;
}
-void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce) {
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->mutex);
-#endif
-
- *nonce = sock->nonce_out;
- sock->nonce_out++;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&sock->mutex);
-#endif
-}
-
-static int _conn_expired_inb(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) {
- if (ecp_conn_is_inb(conn) && _ecp_conn_is_zombie(conn, now, to)) return 1;
- return 0;
-}
-
void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired) {
conn_table_expire(sock, to, conn_expired);
}
-void ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to) {
- ecp_sock_ckey_new(sock);
- conn_table_expire(sock, to, _conn_expired_inb);
-}
-
-void ecp_atag_gen(ECPSocket *sock, unsigned char *atag, unsigned char *public_buf, ecp_nonce_t *nonce) {
+void ecp_atag_gen(ECPSocket *sock, unsigned char *public_buf, unsigned char *atag, ecp_nonce_t *nonce) {
unsigned char msg[ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE];
ecp_hmac_key_t key;
@@ -675,6 +652,8 @@ void ecp_atag_gen(ECPSocket *sock, unsigned char *atag, unsigned char *public_bu
#endif
memcpy(&key, &sock->ckey, sizeof(sock->ckey));
+ *nonce = sock->nonce_out;
+ sock->nonce_out++;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&sock->mutex);
@@ -690,17 +669,23 @@ int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *pub
unsigned char msg[ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE];
unsigned char atag[ECP_SIZE_ATAG];
ecp_hmac_key_t key;
+ ecp_nonce_t nonce_sock, nonce_cookie, nonce_offset;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&sock->mutex);
#endif
memcpy(&key, &sock->ckey, sizeof(sock->ckey));
+ nonce_sock = sock->nonce_out - 1;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&sock->mutex);
#endif
+ ecp_buf2nonce(&nonce_cookie, cookie);
+ nonce_offset = nonce_sock - nonce_cookie;
+ if (nonce_offset > ECP_MAX_NONCE_FWD) return ECP_ERR_COOKIE;
+
memcpy(msg, public_buf, ECP_SIZE_ECDH_PUB);
memcpy(msg+ECP_SIZE_ECDH_PUB, cookie, ECP_SIZE_NONCE);
ecp_hmac(atag, &key, msg, sizeof(msg));
@@ -1710,8 +1695,7 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t
ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_INIT_REP);
msg = ecp_pld_get_msg(payload.buffer, payload.size);
- ecp_sock_get_nonce(sock, &nonce);
- ecp_atag_gen(sock, atag, public_buf, &nonce);
+ ecp_atag_gen(sock, public_buf, atag, &nonce);
_rv = ecp_sock_dhkey_get_pub(sock, msg, (ecp_ecdh_public_t *)(msg+1));
if (_rv) return _rv;
diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h
index 6f1dbab..3b1d7b4 100644
--- a/ecp/src/ecp/core.h
+++ b/ecp/src/ecp/core.h
@@ -47,7 +47,8 @@
#define ECP_MAX_MTYPE 16
#define ECP_MAX_PARENT 3
#define ECP_MAX_SEQ_FWD 1024
-#define ECP_MAX_EXP 100
+#define ECP_MAX_NONCE_FWD 100 /* max diff between current sock nonce and auth tag nonce (open req message) */
+#define ECP_MAX_EXPIRED 100
#define ECP_MIN_KEYX_DT 3600
@@ -393,12 +394,9 @@ void ecp_sock_ckey_new(ECPSocket *sock);
int ecp_sock_dhkey_new(ECPSocket *sock);
int ecp_sock_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key);
int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_t *public);
-void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce);
-
void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired);
-void ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to);
-void ecp_atag_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf, ecp_nonce_t *nonce);
+void ecp_atag_gen(ECPSocket *sock, unsigned char *public_buf, unsigned char *atag, ecp_nonce_t *nonce);
int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf);
ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype);