diff options
-rw-r--r-- | ecp/doc/protocol.md | 1 | ||||
-rw-r--r-- | ecp/src/ecp/core.c | 40 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 1 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.c | 2 |
4 files changed, 24 insertions, 20 deletions
diff --git a/ecp/doc/protocol.md b/ecp/doc/protocol.md index a386c21..12378a6 100644 --- a/ecp/doc/protocol.md +++ b/ecp/doc/protocol.md @@ -48,6 +48,7 @@ Key identifier (KEYID) contains information about keys used to encrypt and authe - b0000 if 'even' servers's short-term key is used; - b0001 if 'odd' server's short-term key is used; - KEYID[3:0]: + - b1000 if 'even' client's short-term key is used but client's short-term key is not present in packet header (init reply packet only); - b0000 if 'even' client's short-term key is used; - b0001 if 'odd' client's short-term key is used. diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index dc0fb2c..2088e32 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -324,6 +324,7 @@ static ECPConnection *conn_table_search_pub(ECPSocket *sock, unsigned char c_idx return NULL; #endif /* ECP_WITH_HTABLE */ } + static ECPConnection *conn_table_search_addr(ECPSocket *sock, ecp_tr_addr_t *addr) { #ifdef ECP_WITH_HTABLE return ecp_ht_search(sock->conn_table.addrs, addr); @@ -2062,8 +2063,8 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ssize_t pld_size; size_t pkt_size = _pkt_size; ecp_aead_key_t shkey; - unsigned char *public_buf = NULL; - unsigned char *nonce_buf = NULL; + unsigned char *public_buf; + unsigned char *nonce_buf; unsigned char is_inb = 0; unsigned char is_open = 0; unsigned char is_open_msg = 0; @@ -2082,7 +2083,10 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, idx = packet[ECP_SIZE_PROTO]; s_idx = (idx & 0xF0) >> 4; c_idx = (idx & 0x0F); - if (idx != ECP_ECDH_IDX_INV) { + if ((s_idx == ECP_ECDH_IDX_PERMA) && (c_idx == ECP_ECDH_IDX_NOKEY)) { + public_buf = NULL; + c_idx = 0; + } else { public_buf = packet+ECP_SIZE_PROTO+1; } @@ -2101,16 +2105,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, is_inb = ecp_conn_is_inb(conn); is_open = _ecp_conn_is_open(conn); - if (!is_open && !is_inb && (idx == ECP_ECDH_IDX_INV)) { - /* init reply message */ - nonce_buf = packet+ECP_SIZE_PROTO+1; - packet += ECP_SIZE_PKT_HDR_IREP; - pkt_size -= ECP_SIZE_PKT_HDR_IREP; - - s_idx = ECP_ECDH_IDX_PERMA; - c_idx = conn->key_curr; - } else { - public_buf = packet+ECP_SIZE_PROTO+1; + if (public_buf) { nonce_buf = public_buf+ECP_SIZE_ECDH_PUB; packet += ECP_SIZE_PKT_HDR; pkt_size -= ECP_SIZE_PKT_HDR; @@ -2119,8 +2114,15 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, nonce_conn = conn->nonce_in; nonce_map = conn->nonce_map; } + } else if (!is_open && !is_inb) { + /* init reply message */ + nonce_buf = packet+ECP_SIZE_PROTO+1; + packet += ECP_SIZE_PKT_HDR_IREP; + pkt_size -= ECP_SIZE_PKT_HDR_IREP; + } else { + _rv = ECP_ERR; } - _rv = conn_shkey_get(conn, s_idx, c_idx, &shkey); + if (!_rv) _rv = conn_shkey_get(conn, s_idx, c_idx, &shkey); if (!_rv) conn->refcount++; #ifdef ECP_WITH_PTHREAD @@ -2128,11 +2130,10 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, #endif if (_rv) return _rv; - } else { + } else if (public_buf) { ECPDHKey key; is_inb = 1; - public_buf = packet+ECP_SIZE_PROTO+1; if (s_idx == ECP_ECDH_IDX_PERMA) { /* init request message */ @@ -2172,6 +2173,8 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, } else { return ECP_ERR; } + } else { + return ECP_ERR; } ecp_buf2nonce(&nonce_pkt, nonce_buf); @@ -2212,7 +2215,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, rv = ecp_aead_dec(payload, bufs->payload->size, packet, pkt_size, &shkey, &nonce_pkt, is_inb ? ECP_NTYPE_INB : ECP_NTYPE_OUTB); /* init reply collision */ - if ((rv == ECP_ERR_DECRYPT) && conn && !is_open && !is_inb && (idx == ECP_ECDH_IDX_INV)) { + if ((rv == ECP_ERR_DECRYPT) && (public_buf == NULL) && conn) { ECPConnection *_conn = conn; #ifdef ECP_WITH_PTHREAD @@ -2584,8 +2587,7 @@ ssize_t ecp_pack_irep(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_ if (parent == NULL) { pkt_meta->public = NULL; - pkt_meta->c_idx = 0xf; - pkt_meta->s_idx = 0xf; + pkt_meta->c_idx = ECP_ECDH_IDX_NOKEY; } rv = _pack(packet, pkt_meta, payload, pld_size); diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index a574cd5..843b5e9 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -125,6 +125,7 @@ #define ECP_ECDH_IDX_INV 0xFF #define ECP_ECDH_IDX_PERMA 0x0F +#define ECP_ECDH_IDX_NOKEY 0x08 #define ECP_ECDH_IDX_MASK 0x07 #define ECP_NTYPE_INB 1 diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c index 4ab71be..28620a6 100644 --- a/ecp/src/ecp/vconn/vconn.c +++ b/ecp/src/ecp/vconn/vconn.c @@ -146,7 +146,7 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_ _idx = (idx & 0xF0) >> 4; if (conn_next && (_idx == ECP_ECDH_IDX_PERMA)) { /* this is init reply */ - msg[ECP_SIZE_PROTO] = ECP_ECDH_IDX_INV; + msg[ECP_SIZE_PROTO] = (ECP_ECDH_IDX_PERMA << 4) | ECP_ECDH_IDX_NOKEY; memmove(msg+ECP_SIZE_PROTO+1, msg+ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB, msg_size-(ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB)); _msg_size -= ECP_SIZE_ECDH_PUB; } |