summaryrefslogtreecommitdiff
path: root/ecp
diff options
context:
space:
mode:
Diffstat (limited to 'ecp')
-rw-r--r--ecp/doc/protocol.md1
-rw-r--r--ecp/src/ecp/core.c40
-rw-r--r--ecp/src/ecp/core.h1
-rw-r--r--ecp/src/ecp/vconn/vconn.c2
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;
}