diff options
Diffstat (limited to 'ecp')
-rw-r--r-- | ecp/doc/protocol.md | 2 | ||||
-rw-r--r-- | ecp/src/ecp/core.c | 44 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 8 |
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" — 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); |