diff options
Diffstat (limited to 'ecp/src')
-rw-r--r-- | ecp/src/ecp/core.c | 60 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 6 |
2 files changed, 37 insertions, 29 deletions
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index 96b1034..dc0fb2c 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -987,11 +987,11 @@ int ecp_conn_create(ECPConnection *conn, ECPConnection *parent) { return ECP_OK; } -int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey) { +int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *rkey_perma, ecp_aead_key_t *shkey) { ECPSocket *sock = conn->sock; int rv; - if (ecp_conn_has_vbox(conn) && ((remote_key == NULL) || !remote_key->valid)) return ECP_ERR_VBOX; + if (ecp_conn_has_vbox(conn) && ((rkey_perma == NULL) || !rkey_perma->valid)) return ECP_ERR_VBOX; ecp_conn_set_inb(conn); @@ -1005,8 +1005,8 @@ int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned cha conn->refcount = 1; conn->key_curr = s_idx; conn->rkey_curr = c_idx; - if (remote_key && remote_key->valid) { - conn->remote.key_perma = *remote_key; + if (rkey_perma && rkey_perma->valid) { + conn->remote.key_perma = *rkey_perma; } else { ECPDHPub *key_perma = &conn->remote.key_perma; memcpy(&key_perma->public, public, sizeof(key_perma->public)); @@ -1671,28 +1671,33 @@ ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload) { rv = 0; if (vbox) { ECPSocket *sock = conn->sock; - ECPDHKey key; - ECPDHPub remote_key; + ECPDHKey key_perma; + ECPDHPub rkey_perma; + ECPDHPub rkey_curr; ecp_ecdh_public_t public; ecp_aead_key_t vbox_shkey; ecp_nonce_t vbox_nonce; + unsigned char vbox_buf[2*ECP_SIZE_ECDH_PUB]; + + if (payload->size < ECP_SIZE_PLD(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ)) return ECP_ERR_SIZE; - _rv = ECP_OK; - if (payload->size < ECP_SIZE_PLD(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ)) _rv = ECP_ERR_SIZE; - if (!_rv) _rv = ecp_sock_dhkey_get(sock, ECP_ECDH_IDX_PERMA, &key); - if (!_rv) _rv = ecp_conn_dhkey_get_remote(conn, ECP_ECDH_IDX_PERMA, &remote_key); + _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) return _rv; - memcpy(msg, &key.public, ECP_SIZE_ECDH_PUB); + memcpy(vbox_buf, &public, ECP_SIZE_ECDH_PUB); + memcpy(vbox_buf+ECP_SIZE_ECDH_PUB, &rkey_curr.public, ECP_SIZE_ECDH_PUB); + memcpy(msg, &key_perma.public, ECP_SIZE_ECDH_PUB); msg += ECP_SIZE_ECDH_PUB; arc4random_buf(&vbox_nonce, sizeof(vbox_nonce)); ecp_nonce2buf(msg, &vbox_nonce); msg += ECP_SIZE_NONCE; - ecp_ecdh_shkey(&vbox_shkey, &remote_key.public, &key.private); - rv = ecp_aead_enc(msg, payload->size - (msg - payload->buffer), (unsigned char *)&public, ECP_SIZE_ECDH_PUB, &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX); + ecp_ecdh_shkey(&vbox_shkey, &rkey_perma.public, &key_perma.private); + rv = ecp_aead_enc(msg, payload->size - (msg - payload->buffer), vbox_buf, sizeof(vbox_buf), &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX); if (rv < 0) return rv; rv += ECP_SIZE_ECDH_PUB + ECP_SIZE_NONCE; } @@ -1721,7 +1726,7 @@ ssize_t ecp_send_open_req(ECPConnection *conn, unsigned char *cookie) { ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, unsigned char *public_buf, unsigned char *msg, size_t msg_size, ecp_aead_key_t *shkey, ECPConnection **_conn) { ECPConnection *conn; - ECPDHPub remote_key; + ECPDHPub rkey_perma; unsigned char ctype; unsigned char vbox; ssize_t rv; @@ -1735,19 +1740,21 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha msg++; msg_size -= 2; - remote_key.valid = 0; + rkey_perma.valid = 0; if (vbox) { - ECPDHKey key; - ecp_ecdh_public_t public; + ECPDHKey key_perma; + ECPDHKey key_curr; ecp_aead_key_t vbox_shkey; ecp_nonce_t vbox_nonce; + unsigned char vbox_buf[2*ECP_SIZE_ECDH_PUB]; if (msg_size < ECP_SIZE_VBOX) return ECP_ERR_SIZE; - _rv = ecp_sock_dhkey_get(sock, ECP_ECDH_IDX_PERMA, &key); + _rv = ecp_sock_dhkey_get(sock, ECP_ECDH_IDX_PERMA, &key_perma); + if (!_rv) _rv = ecp_sock_dhkey_get(sock, s_idx, &key_curr); if (_rv) return _rv; - memcpy(&remote_key.public, msg, ECP_SIZE_ECDH_PUB); + memcpy(&rkey_perma.public, msg, ECP_SIZE_ECDH_PUB); msg+= ECP_SIZE_ECDH_PUB; msg_size -= ECP_SIZE_ECDH_PUB; @@ -1755,15 +1762,16 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha msg+= ECP_SIZE_NONCE; msg_size -= ECP_SIZE_NONCE; - ecp_ecdh_shkey(&vbox_shkey, &remote_key.public, &key.private); - rv = ecp_aead_dec((unsigned char *)&public, ECP_SIZE_ECDH_PUB, msg, msg_size, &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX); - if (rv != ECP_SIZE_ECDH_PUB) return ECP_ERR_VBOX; + ecp_ecdh_shkey(&vbox_shkey, &rkey_perma.public, &key_perma.private); + rv = ecp_aead_dec(vbox_buf, sizeof(vbox_buf), msg, msg_size, &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX); + if (rv < 0) return ECP_ERR_VBOX; - if (memcmp(&public, public_buf, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_VBOX; - remote_key.valid = 1; + if (memcmp(vbox_buf, public_buf, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_VBOX; + if (memcmp(vbox_buf+ECP_SIZE_ECDH_PUB, &key_curr.public, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_VBOX; + rkey_perma.valid = 1; if (sock->ctx->key_checker) { - _rv = sock->ctx->key_checker(sock, &public); + _rv = sock->ctx->key_checker(sock, ctype, &rkey_perma.public); if (_rv) return _rv; } } @@ -1771,7 +1779,7 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha conn = ecp_conn_new_inb(sock, ctype); if (conn == NULL) return ECP_ERR_ALLOC; - _rv = ecp_conn_create_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, remote_key.valid ? &remote_key : NULL, shkey); + _rv = ecp_conn_create_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, rkey_perma.valid ? &rkey_perma : NULL, shkey); if (_rv) return _rv; _rv = ecp_conn_insert(conn); diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index 2e5bf14..a574cd5 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -71,7 +71,7 @@ #define ECP_MIN_PKT (ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG) #define ECP_MIN_PLD (ECP_SIZE_MTYPE) -#define ECP_SIZE_VBOX (ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE+ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG) +#define ECP_SIZE_VBOX (ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE+2*ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG) #define ECP_SIZE_MT_FRAG(T) ((T) & ECP_MTYPE_FLAG_FRAG ? 2 + sizeof(uint16_t) : 0) #define ECP_SIZE_MT_PTS(T) ((T) & ECP_MTYPE_FLAG_PTS ? sizeof(ecp_pts_t) : 0) @@ -221,7 +221,7 @@ typedef int (*ecp_conn_expired_t) (struct ECPConnection *conn, ecp_sts_t now, ec typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err); typedef struct ECPConnection * (*ecp_conn_new_t) (struct ECPSocket *sock, unsigned char type); typedef void (*ecp_conn_free_t) (struct ECPConnection *conn); -typedef int (*ecp_key_checker_t) (struct ECPSocket *sock, ecp_ecdh_public_t *pub); +typedef int (*ecp_key_checker_t) (struct ECPSocket *sock, unsigned char ctype, ecp_ecdh_public_t *pub); typedef ssize_t (*ecp_msg_handler_t) (struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); typedef int (*ecp_open_handler_t) (struct ECPConnection *conn, struct ECP2Buffer *b); @@ -382,7 +382,7 @@ ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype); void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); int ecp_conn_reset(ECPConnection *conn); int ecp_conn_create(ECPConnection *conn, ECPConnection *parent); -int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey); +int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *rkey_perma, ecp_aead_key_t *shkey); int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node); int ecp_conn_reset_outb(ECPConnection *conn); void ecp_conn_destroy(ECPConnection *conn); |