diff options
author | Uros Majstorovic <majstor@majstor.org> | 2024-05-22 19:10:08 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2024-05-22 19:10:08 +0200 |
commit | 34ab7d2f73d351158875effa175d2daf6a4ed976 (patch) | |
tree | c8e1378e7966e270572e451f4d5c4caa8ddc2259 /ecp/src | |
parent | 7f06f7fb26ee52547d30b620a4137bca0395da6d (diff) |
added zero padding for vconn fixed packet feature
Diffstat (limited to 'ecp/src')
-rw-r--r-- | ecp/src/ecp/core.c | 159 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 124 | ||||
-rw-r--r-- | ecp/src/ecp/htable/htable.c | 4 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.c | 71 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.h | 10 |
5 files changed, 271 insertions, 97 deletions
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index 6934587..6c17def 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -768,7 +768,7 @@ int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *pub ecp_buf2nonce(&nonce_cookie, cookie); nonce_offset = nonce_sock - nonce_cookie; - if (nonce_offset > ECP_MAX_NONCE_FWD) return ECP_ERR_COOKIE; + if (nonce_offset > ECP_MAX_ATAG_FWD) return ECP_ERR_COOKIE; memcpy(msg, public_buf, ECP_SIZE_ECDH_PUB); memcpy(msg+ECP_SIZE_ECDH_PUB, cookie, ECP_SIZE_NONCE); @@ -1806,7 +1806,7 @@ static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) { msg = ecp_pld_get_msg(payload.buffer, payload.size); memset(msg, 0, ECP_SIZE_ZPAD_PLD); - rv = _ecp_pld_send(conn, &packet, ECP_KEYID_PERMA, ECP_KEYID_INV, ECP_SIZE_ZPAD_HDR, NULL, NULL, &payload, ECP_SIZE_PLD(ECP_SIZE_ZPAD_PLD, ECP_MTYPE_INIT_REQ), 0, ti); + rv = _ecp_pld_send(conn, &packet, -1, ECP_KEYID_PERMA, ECP_KEYID_INV, ECP_SIZE_ZPAD_HDR, NULL, NULL, &payload, ECP_SIZE_PLD(ECP_SIZE_ZPAD_PLD, ECP_MTYPE_INIT_REQ), 0, ti); return rv; } @@ -1922,12 +1922,19 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t pkt_meta.zpad = 0; pkt_meta.cookie = NULL; + pkt_meta.public = (ecp_ecdh_public_t *)public_buf; pkt_meta.shkey = shkey; pkt_meta.nonce = &nonce; pkt_meta.ntype = ECP_NTYPE_INB; - pkt_meta.public = (ecp_ecdh_public_t *)public_buf; pkt_meta.s_idx = ECP_KEYID_PERMA; pkt_meta.c_idx = c_idx; + pkt_meta.pkt_size = 0; + +#ifdef ECP_WITH_VCONN + if (parent) { + pkt_meta.pkt_size = ECP_SIZE_VCONN_PKT_INNER; + } +#endif rv = ecp_pld_send_irep(sock, parent, addr, &packet, &pkt_meta, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ATAG, ECP_MTYPE_INIT_REP), 0); return rv; @@ -2062,20 +2069,23 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha if (_rv) return _rv; memcpy(&rkey_perma.public, msg, ECP_SIZE_ECDH_PUB); - msg+= ECP_SIZE_ECDH_PUB; + msg += ECP_SIZE_ECDH_PUB; msg_size -= ECP_SIZE_ECDH_PUB; ecp_buf2nonce(&vbox_nonce, msg); - msg+= ECP_SIZE_NONCE; + msg += ECP_SIZE_NONCE; msg_size -= ECP_SIZE_NONCE; 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); + rv = ecp_aead_dec(vbox_buf, sizeof(vbox_buf), msg, 2*ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG, &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX); if (rv < 0) return ECP_ERR_AUTH; if (memcmp(vbox_buf, public_buf, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_AUTH; if (memcmp(vbox_buf+ECP_SIZE_ECDH_PUB, &key_curr.public, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_AUTH; + rkey_perma.valid = 1; + msg += 2*ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG; + msg_size -= 2*ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG; } rv = 0; @@ -2172,8 +2182,11 @@ int ecp_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { #endif if (ecp_conn_is_inb(conn)) { + ssize_t _rv; + ecp_tr_release(bufs->packet, 1); - ecp_send_open_rep(conn); + _rv = ecp_send_open_rep(conn); + if (_rv < 0) return _rv; } else if (ecp_conn_is_root(conn)) { ecp_conn_remove_addr(conn); } @@ -2268,6 +2281,15 @@ ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { if (mtype & ECP_MTYPE_FLAG_SYS) { switch (mtype) { + case ECP_MTYPE_ZPAD: { + int i; + + for (i=0; i<msg_size; i++) { + if (msg[i] != 0) return ECP_ERR_ZPAD; + } + return msg_size; + } + case ECP_MTYPE_OPEN_REP: return ecp_handle_open_rep(conn, mtype, msg, msg_size, bufs); @@ -2542,10 +2564,6 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, if (rv < 0) goto unpack_fin; pld_size = rv; - if (pld_size < ECP_MIN_PLD) { - rv = ECP_ERR_SIZE; - goto unpack_fin; - } if (!(conn && is_open)) { unsigned char mtype; @@ -2638,11 +2656,11 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, #endif *_conn = conn; - *_payload = payload; *_seq = seq; *_is_open_msg = is_open_msg; } + *_payload = payload; rv = _pkt_size - pld_size; unpack_fin: @@ -2664,7 +2682,24 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *ad pld_size = pkt_size - rv; if (conn == NULL) { - if (pld_size) return ECP_ERR; + if (pld_size) { + unsigned char mtype; + unsigned char *msg; + size_t hdr_size, msg_size; + int i; + + _rv = ecp_pld_get_type(payload, pld_size, &mtype); + if (_rv) return ECP_ERR_SIZE; + if (mtype != ECP_MTYPE_ZPAD) return ECP_ERR_SIZE; + + msg = ecp_pld_get_msg(payload, pld_size); + if (msg == NULL) return ECP_ERR_ZPAD; + hdr_size = msg - payload; + msg_size = pld_size - hdr_size; + for (i=0; i<msg_size; i++) { + if (msg[i] != 0) return ECP_ERR_ZPAD; + } + } return pkt_size; } @@ -2729,7 +2764,7 @@ void ecp_buf2nonce(ecp_nonce_t *n, unsigned char *b) { int ecp_pkt_get_seq(unsigned char *pkt, size_t pkt_size, ecp_seq_t *s) { *s = 0; - if (pkt_size < ECP_MIN_PKT) return ECP_ERR_SIZE; + if (pkt_size < ECP_SIZE_PKT_HDR) return ECP_ERR_SIZE; pkt += ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB; *s |= (ecp_seq_t)pkt[4] << 24; @@ -2779,18 +2814,46 @@ static ssize_t _pack(ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload pkt_buf += ECP_SIZE_NONCE; hdr_size = pkt_buf - packet->buffer; - rv = ecp_aead_enc(pkt_buf, packet->size-hdr_size, payload->buffer, pld_size, pkt_meta->shkey, pkt_meta->nonce, pkt_meta->ntype); + if (pkt_meta->pkt_size) { + size_t _hdr_size; + + _hdr_size = hdr_size + ECP_SIZE_AEAD_TAG; + if (pld_size + _hdr_size < pkt_meta->pkt_size) { + unsigned char *msg, *_payload; + size_t hdr_size, msg_size, _pld_size; + size_t zpad; + + zpad = pkt_meta->pkt_size - _hdr_size - pld_size; + if (pld_size + zpad > payload->size) return ECP_ERR_SIZE; + + _payload = payload->buffer + pld_size; + _pld_size = payload->size - pld_size; + + ecp_pld_set_type(_payload, _pld_size, ECP_MTYPE_ZPAD); + msg = ecp_pld_get_msg(_payload, _pld_size); + hdr_size = msg - _payload; + msg_size = zpad - hdr_size; + if (msg_size) { + memset(msg, 0, msg_size); + } + pld_size += zpad; + } else if (pld_size + _hdr_size > pkt_meta->pkt_size) { + return ECP_ERR_SIZE; + } + } + rv = ecp_aead_enc(pkt_buf, packet->size - hdr_size, payload->buffer, pld_size, pkt_meta->shkey, pkt_meta->nonce, pkt_meta->ntype); if (rv < 0) return rv; - return rv+hdr_size; + return rv + hdr_size; } -static ssize_t _pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *_nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) { +static ssize_t _pack_conn(ECPConnection *conn, ECPBuffer *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *_nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) { ECPPktMeta pkt_meta; ecp_ecdh_public_t public; ecp_aead_key_t shkey; ecp_nonce_t nonce; - int rv = ECP_OK; + ssize_t rv; + int _rv = ECP_OK; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); @@ -2810,8 +2873,8 @@ static ssize_t _pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char c_idx = conn->rkey_curr; } } - rv = conn_shkey_get(conn, s_idx, c_idx, &shkey); - if (rv) goto pack_conn_fin; + _rv = conn_shkey_get(conn, s_idx, c_idx, &shkey); + if (_rv) goto pack_conn_fin; if (ecp_conn_is_outb(conn)) { ECPDHKey *key = conn_dhkey_get(conn, c_idx); @@ -2819,7 +2882,7 @@ static ssize_t _pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char if (key) { memcpy(&public, &key->public, sizeof(public)); } else { - rv = ECP_ERR_KEYID; + _rv = ECP_ERR_KEYID; } } else { ECPDHPub *key = conn_dhkey_get_remote(conn, c_idx); @@ -2827,11 +2890,11 @@ static ssize_t _pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char if (key) { memcpy(&public, &key->public, sizeof(public)); } else { - rv = ECP_ERR_KEYID; + _rv = ECP_ERR_KEYID; } memcpy(&public, &key->public, sizeof(public)); } - if (rv) goto pack_conn_fin; + if (_rv) goto pack_conn_fin; if (_nonce) { nonce = *_nonce; @@ -2847,7 +2910,7 @@ pack_conn_fin: pthread_mutex_unlock(&conn->mutex); #endif - if (rv) return rv; + if (_rv) return _rv; pkt_meta.zpad = zpad; pkt_meta.cookie = cookie; @@ -2857,7 +2920,10 @@ pack_conn_fin: pkt_meta.ntype = (ecp_conn_is_inb(conn) ? ECP_NTYPE_INB : ECP_NTYPE_OUTB); pkt_meta.s_idx = s_idx; pkt_meta.c_idx = c_idx; - return _pack(packet, &pkt_meta, payload, pld_size); + pkt_meta.pkt_size = pkt_size; + + rv = _pack(packet, &pkt_meta, payload, pld_size); + return rv; } ssize_t ecp_pack_irep(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) { @@ -2873,22 +2939,28 @@ ssize_t ecp_pack_irep(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_ #ifdef ECP_WITH_VCONN if (parent) { - rv = ecp_vconn_pack_parent(parent, payload, packet, rv, addr); + size_t _pkt_size; + + _pkt_size = rv; + rv = ecp_vconn_pack_parent(parent, payload, packet, _pkt_size, addr); } #endif return rv; } -ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) { +ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) { ssize_t rv; - rv = _pack_conn(conn, packet, s_idx, c_idx, zpad, cookie, nonce, payload, pld_size, addr); + rv = _pack_conn(conn, packet, pkt_size, s_idx, c_idx, zpad, cookie, nonce, payload, pld_size, addr); if (rv < 0) return rv; #ifdef ECP_WITH_VCONN if (conn->parent) { - rv = ecp_vconn_pack_parent(conn->parent, payload, packet, rv, addr); + size_t _pkt_size; + + _pkt_size = rv; + rv = ecp_vconn_pack_parent(conn->parent, payload, packet, _pkt_size, addr); } #endif @@ -3062,35 +3134,46 @@ void ecp_frag_end(ECPConnection *conn, ecp_seq_t seq, unsigned char frag_cnt, in #endif } -ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { +ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ssize_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { ecp_tr_addr_t addr; - size_t pkt_size; + size_t _pkt_size; ssize_t rv; - rv = ecp_pack_conn(conn, packet, s_idx, c_idx, zpad, cookie, n, payload, pld_size, &addr); +#ifdef ECP_WITH_VCONN + if (conn->parent && (pkt_size < 0)) { + pkt_size = ECP_SIZE_VCONN_PKT_INNER; + } +#endif + if (pkt_size < 0) pkt_size = 0; + + rv = ecp_pack_conn(conn, packet, pkt_size, s_idx, c_idx, zpad, cookie, n, payload, pld_size, &addr); if (rv < 0) return rv; - pkt_size = rv; - rv = ecp_pkt_send(conn->sock, packet, pkt_size, flags, ti, &addr); + _pkt_size = rv; + rv = ecp_pkt_send(conn->sock, packet, _pkt_size, flags, ti, &addr); if (rv < 0) return rv; return pld_size; } ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags) { - return _ecp_pld_send(conn, packet, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, pld_size, flags, NULL); + return _ecp_pld_send(conn, packet, -1, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, pld_size, flags, NULL); } ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { - return _ecp_pld_send(conn, packet, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, pld_size, flags, ti); + return _ecp_pld_send(conn, packet, -1, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, pld_size, flags, ti); } ssize_t ecp_pld_send_wcookie(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, unsigned char *cookie) { - return _ecp_pld_send(conn, packet, ECP_KEYID_INV, ECP_KEYID_INV, 0, cookie, NULL, payload, pld_size, flags, NULL); + return _ecp_pld_send(conn, packet, -1, ECP_KEYID_INV, ECP_KEYID_INV, 0, cookie, NULL, payload, pld_size, flags, NULL); } ssize_t ecp_pld_send_wnonce(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_nonce_t *nonce) { - return _ecp_pld_send(conn, packet, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, nonce, payload, pld_size, flags, NULL); + return _ecp_pld_send(conn, packet, -1, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, nonce, payload, pld_size, flags, NULL); +} + +ssize_t ecp_pld_send_wsize(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, size_t pkt_size) { + return _ecp_pld_send(conn, packet, pkt_size, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, pld_size, flags, NULL); } ssize_t ecp_pld_send_irep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags) { diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index c5b18ce..2cd8750 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -7,20 +7,20 @@ #endif #define ECP_OK 0 -#define ECP_ITR_END 1 #define ECP_ERR -1 -#define ECP_ERR_TIMEOUT -2 -#define ECP_ERR_ALLOC -3 -#define ECP_ERR_SIZE -4 -#define ECP_ERR_BUSY -5 -#define ECP_ERR_DUP -6 -#define ECP_ERR_EMPTY -7 -#define ECP_ERR_FULL -8 -#define ECP_ERR_MTYPE -9 -#define ECP_ERR_CTYPE -10 -#define ECP_ERR_HANDLER -11 -#define ECP_ERR_CLOSED -12 +#define ECP_ERR_ITER -2 +#define ECP_ERR_TIMEOUT -3 +#define ECP_ERR_ALLOC -4 +#define ECP_ERR_SIZE -5 +#define ECP_ERR_BUSY -6 +#define ECP_ERR_DUP -7 +#define ECP_ERR_EMPTY -8 +#define ECP_ERR_FULL -9 +#define ECP_ERR_MTYPE -10 +#define ECP_ERR_CTYPE -11 +#define ECP_ERR_HANDLER -12 +#define ECP_ERR_CLOSED -13 #define ECP_ERR_PKT -20 #define ECP_ERR_ZPAD -21 @@ -40,6 +40,7 @@ #define ECP_ERR_BIND -42 #define ECP_ERR_SEND -43 #define ECP_ERR_RECV -44 +#define ECP_ERR_EOF -45 #define ECP_ERR_MAX_PARENT -50 #define ECP_ERR_NEXT -51 @@ -51,9 +52,8 @@ #define ECP_MAX_CTYPE 8 #define ECP_MAX_CTYPE_SYS 3 #define ECP_MAX_MTYPE 16 -#define ECP_MAX_PARENT 3 #define ECP_MAX_SEQ_FWD 1024 -#define ECP_MAX_NONCE_FWD 100 /* max diff between current irep nonce and auth tag nonce */ +#define ECP_MAX_ATAG_FWD 100 /* max diff between current irep nonce and auth tag nonce */ #define ECP_MAX_EXPIRED 100 #define ECP_MIN_KEYX_DT 3600 @@ -71,12 +71,15 @@ #define ECP_SIZE_PKT_HDR_IREP (ECP_SIZE_PROTO+1+ECP_SIZE_NONCE) #define ECP_SIZE_PKT_HDR_OREQ (ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE+ECP_SIZE_NONCE) +#define ECP_SIZE_PKT_FRM (ECP_SIZE_PKT_HDR+ECP_SIZE_AEAD_TAG) +#define ECP_SIZE_PKT_FRM_IREQ (ECP_SIZE_PKT_HDR_IREQ+ECP_SIZE_AEAD_TAG) +#define ECP_SIZE_PKT_FRM_IREP (ECP_SIZE_PKT_HDR_IREP+ECP_SIZE_AEAD_TAG) +#define ECP_SIZE_PKT_FRM_OREQ (ECP_SIZE_PKT_HDR_OREQ+ECP_SIZE_AEAD_TAG) + #define ECP_MAX_PKT 1432 // 1500 MTU - 60 bytes max IPv4 hdr - 8 bytes UDP hdr -#define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_HDR-ECP_SIZE_AEAD_TAG) -#define ECP_MAX_MSG (ECP_MAX_PLD-ECP_SIZE_MTYPE) +#define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_FRM) -#define ECP_MIN_PKT (ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG) -#define ECP_MIN_PLD (ECP_SIZE_MTYPE) +#define ECP_MIN_PKT (ECP_SIZE_PKT_FRM+ECP_SIZE_MTYPE) #define ECP_SIZE_VBOX (ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE+2*ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG) @@ -85,40 +88,90 @@ #define ECP_SIZE_MT_FLAG(T) (ECP_SIZE_MT_FRAG(T)+ECP_SIZE_MT_PTS(T)) #define ECP_SIZE_PLD(X,T) ((X)+ECP_SIZE_MTYPE+ECP_SIZE_MT_FLAG(T)) +#ifdef ECP_WITH_VCONN +#define ECP_SIZE_VCONN_PKT 512 + +#ifndef ECP_SIZE_VCONN_PKT +#define ECP_SIZE_VCONN_PKT 0 +#endif + +#define ECP_MAX_PARENT 3 + /* #define ECP_CONN_PCOUNT(C) ((C)->pcount) */ #define ECP_CONN_PCOUNT(C) ECP_MAX_PARENT +#define ECP_SIZE_VCONN_MSG_HDR (ECP_SIZE_MTYPE+sizeof(uint16_t)) +#define ECP_SIZE_VCONN_PKT_FRM (ECP_SIZE_PKT_FRM+ECP_SIZE_VCONN_MSG_HDR) + +#if ECP_SIZE_VCONN_PKT +#define ECP_SIZE_VCONN_PLD (ECP_SIZE_VCONN_PKT-ECP_SIZE_PKT_FRM) +#define ECP_SIZE_VCONN_PKT_INNER (ECP_SIZE_VCONN_PKT-(ECP_MAX_PARENT*ECP_SIZE_VCONN_PKT_FRM)) +#else +#define ECP_SIZE_VCONN_PKT_INNER 0 +#endif +#endif // ECP_WITH_VCONN + #ifdef ECP_WITH_VCONN -#define ECP_SIZE_PLD_BUF(X,C) ((X)+ECP_CONN_PCOUNT(C)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG)) +#define _ECP_SIZE_PLD_BUF(X,C) ((X)+ECP_CONN_PCOUNT(C)*ECP_SIZE_VCONN_PKT_FRM) +#define _ECP_SIZE_PKT_BUF(X,C) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF(X,C)) +#if ECP_SIZE_VCONN_PKT +#define ECP_SIZE_PLD_BUF(X,C) ((C)->parent ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF(X,C)) +#define ECP_SIZE_PKT_BUF(X,C) ((C)->parent ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF(X,C)) #else -#define ECP_SIZE_PLD_BUF(X,C) (X) +#define ECP_SIZE_PLD_BUF(X,C) _ECP_SIZE_PLD_BUF(X,C) +#define ECP_SIZE_PKT_BUF(X,C) _ECP_SIZE_PKT_BUF(X,C) #endif -#define ECP_SIZE_PKT_BUF(X,C) (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD_BUF(X,C)+ECP_SIZE_AEAD_TAG) +#else // ECP_WITH_VCONN +#define ECP_SIZE_PLD_BUF(X,C) (X) +#define ECP_SIZE_PKT_BUF(X,C) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF(X,C)) +#endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN -#define ECP_SIZE_PLD_BUF_IREP(X,P) ((X)+((P) ? (ECP_CONN_PCOUNT(P)+1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG) : 0)) +#define _ECP_SIZE_PLD_BUF_IREP(X,P) ((X)+((P) ? (ECP_CONN_PCOUNT(P)+1)*ECP_SIZE_VCONN_PKT_FRM : 0)) +#define _ECP_SIZE_PKT_BUF_IREP(X,P) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF_IREP(X,P)) +#if ECP_SIZE_VCONN_PKT +#define ECP_SIZE_PLD_BUF_IREP(X,P) ((P) ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF_IREP(X,P)) +#define ECP_SIZE_PKT_BUF_IREP(X,P) ((P) ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF_IREP(X,P)) #else -#define ECP_SIZE_PLD_BUF_IREP(X,P) (X) +#define ECP_SIZE_PLD_BUF_IREP(X,P) _ECP_SIZE_PLD_BUF_IREP(X,P) +#define ECP_SIZE_PKT_BUF_IREP(X,P) _ECP_SIZE_PKT_BUF_IREP(X,P) #endif -#define ECP_SIZE_PKT_BUF_IREP(X,P) (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD_BUF_IREP(X,P)+ECP_SIZE_AEAD_TAG) +#else // ECP_WITH_VCONN +#define ECP_SIZE_PLD_BUF_IREP(X,P) (X) +#define ECP_SIZE_PKT_BUF_IREP(X,P) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF_IREP(X,P)) +#endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN -#define ECP_SIZE_PLD_BUF_IREQ(X,C) ((X)+(ECP_CONN_PCOUNT(C) ? (ECP_CONN_PCOUNT(C)-1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG)+ECP_SIZE_PKT_HDR_IREQ+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG : 0)) -#define ECP_SIZE_PKT_BUF_IREQ(X,C) (ECP_SIZE_PKT_HDR_IREQ+(X)+ECP_SIZE_AEAD_TAG+ECP_CONN_PCOUNT(C)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG)) +#define _ECP_SIZE_PLD_BUF_IREQ(X,C) ((X)+(ECP_CONN_PCOUNT(C) ? (ECP_CONN_PCOUNT(C)-1)*ECP_SIZE_VCONN_PKT_FRM+ECP_SIZE_PKT_FRM_IREQ+ECP_SIZE_VCONN_MSG_HDR : 0)) +#define _ECP_SIZE_PKT_BUF_IREQ(X,C) (ECP_SIZE_PKT_FRM_IREQ+(X)+ECP_CONN_PCOUNT(C)*ECP_SIZE_VCONN_PKT_FRM) +#if ECP_SIZE_VCONN_PKT +#define ECP_SIZE_PLD_BUF_IREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF_IREQ(X,C)) +#define ECP_SIZE_PKT_BUF_IREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF_IREQ(X,C)) #else -#define ECP_SIZE_PLD_BUF_IREQ(X,C) (X) -#define ECP_SIZE_PKT_BUF_IREQ(X,C) (ECP_SIZE_PKT_HDR_IREQ+(X)+ECP_SIZE_AEAD_TAG) +#define ECP_SIZE_PLD_BUF_IREQ(X,C) _ECP_SIZE_PLD_BUF_IREQ(X,C) +#define ECP_SIZE_PKT_BUF_IREQ(X,C) _ECP_SIZE_PKT_BUF_IREQ(X,C) #endif +#else // ECP_WITH_VCONN +#define ECP_SIZE_PLD_BUF_IREQ(X,C) (X) +#define ECP_SIZE_PKT_BUF_IREQ(X,C) (ECP_SIZE_PKT_FRM_IREQ+(X)) +#endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN -#define ECP_SIZE_PLD_BUF_OREQ(X,C) ((X)+(ECP_CONN_PCOUNT(C) ? (ECP_CONN_PCOUNT(C)-1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG)+ECP_SIZE_PKT_HDR_OREQ+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG : 0)) -#define ECP_SIZE_PKT_BUF_OREQ(X,C) (ECP_SIZE_PKT_HDR_OREQ+(X)+ECP_SIZE_AEAD_TAG+ECP_CONN_PCOUNT(C)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG)) +#define _ECP_SIZE_PLD_BUF_OREQ(X,C) ((X)+(ECP_CONN_PCOUNT(C) ? (ECP_CONN_PCOUNT(C)-1)*ECP_SIZE_VCONN_PKT_FRM+ECP_SIZE_PKT_FRM_OREQ+ECP_SIZE_VCONN_MSG_HDR : 0)) +#define _ECP_SIZE_PKT_BUF_OREQ(X,C) (ECP_SIZE_PKT_FRM_OREQ+(X)+ECP_CONN_PCOUNT(C)*ECP_SIZE_VCONN_PKT_FRM) +#if ECP_SIZE_VCONN_PKT +#define ECP_SIZE_PLD_BUF_OREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF_OREQ(X,C)) +#define ECP_SIZE_PKT_BUF_OREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF_OREQ(X,C)) #else -#define ECP_SIZE_PLD_BUF_OREQ(X,C) (X) -#define ECP_SIZE_PKT_BUF_OREQ(X,C) (ECP_SIZE_PKT_HDR_OREQ+(X)+ECP_SIZE_AEAD_TAG) +#define ECP_SIZE_PLD_BUF_OREQ(X,C) _ECP_SIZE_PLD_BUF_OREQ(X,C) +#define ECP_SIZE_PKT_BUF_OREQ(X,C) _ECP_SIZE_PKT_BUF_OREQ(X,C) #endif +#else // ECP_WITH_VCONN +#define ECP_SIZE_PLD_BUF_OREQ(X,C) (X) +#define ECP_SIZE_PKT_BUF_OREQ(X,C) (ECP_SIZE_PKT_FRM_OREQ+(X)) +#endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN #define ecp_conn_is_root(C) ((C)->parent == NULL) @@ -144,6 +197,7 @@ #define ECP_MTYPE_FLAG_PTS 0x20 #define ECP_MTYPE_MASK 0x1F +#define ECP_MTYPE_ZPAD (0x1F | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_INIT_REQ (0x00 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_INIT_REP (0x01 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_OPEN_REQ (0x02 | ECP_MTYPE_FLAG_SYS) @@ -288,6 +342,7 @@ typedef struct ECPPktMeta { unsigned char ntype; unsigned char s_idx; unsigned char c_idx; + size_t pkt_size; } ECPPktMeta; typedef struct ECPConnHandler { @@ -506,7 +561,7 @@ void ecp_nonce2buf(unsigned char *b, ecp_nonce_t *n); void ecp_buf2nonce(ecp_nonce_t *n, unsigned char *b); int ecp_pkt_get_seq(unsigned char *pkt, size_t pkt_size, ecp_seq_t *s); ssize_t ecp_pack_irep(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr); -ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr); +ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr); int ecp_pld_get_type(unsigned char *pld, size_t pld_size, unsigned char *mtype); int ecp_pld_set_type(unsigned char *pld, size_t pld_size, unsigned char mtype); @@ -521,11 +576,12 @@ int ecp_msg_get_pts(unsigned char mtype, unsigned char *msg, ecp_pts_t *pts); int ecp_frag_start(ECPConnection *conn, ecp_seq_t seq, unsigned char frag_cnt, unsigned char frag_tot, int *is_first, int *is_last); void ecp_frag_end(ECPConnection *conn, ecp_seq_t seq, unsigned char frag_cnt, int err); -ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); +ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ssize_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags); ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); ssize_t ecp_pld_send_wcookie(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, unsigned char *cookie); ssize_t ecp_pld_send_wnonce(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_nonce_t *nonce); +ssize_t ecp_pld_send_wsize(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, size_t pkt_size); ssize_t ecp_pld_send_irep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags); ssize_t ecp_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size); diff --git a/ecp/src/ecp/htable/htable.c b/ecp/src/ecp/htable/htable.c index 85a9339..ef5d0d9 100644 --- a/ecp/src/ecp/htable/htable.c +++ b/ecp/src/ecp/htable/htable.c @@ -64,7 +64,7 @@ int ecp_ht_itr_advance(ecp_ht_itr_t *i) { int rv; rv = hashtable_iterator_advance(i); - if (rv == 0) return ECP_ITR_END; + if (rv == 0) return ECP_ERR_ITER; return ECP_OK; } @@ -72,7 +72,7 @@ int ecp_ht_itr_remove(ecp_ht_itr_t *i) { int rv; rv = hashtable_iterator_remove(i); - if (rv == 0) return ECP_ITR_END; + if (rv == 0) return ECP_ERR_ITER; return ECP_OK; } diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c index c0e269f..780faab 100644 --- a/ecp/src/ecp/vconn/vconn.c +++ b/ecp/src/ecp/vconn/vconn.c @@ -72,16 +72,24 @@ static ssize_t handle_next(ECPConnection *conn, unsigned char *msg, size_t msg_s return ECP_SIZE_ECDH_PUB; } -static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { +static ssize_t handle_relay(ECPConnection *conn, unsigned char *_msg, size_t msg_size, ECP2Buffer *bufs) { ECPSocket *sock = conn->sock; ECPConnection *conn_next; ECPBuffer payload; unsigned char idx, _idx; - size_t _msg_size = msg_size; + unsigned char *msg = _msg; + uint16_t pkt_size; + size_t _pkt_size; ssize_t rv; int _rv; - if (msg_size < ECP_MIN_PKT) return ECP_ERR_SIZE; + if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE; + + pkt_size = (uint16_t)msg[0] << 8; + pkt_size |= (uint16_t)msg[1]; + msg += sizeof(uint16_t); + + if (msg_size < sizeof(uint16_t) + pkt_size) return ECP_ERR_SIZE; idx = msg[ECP_SIZE_PROTO]; if (idx == ECP_KEYID_INV) return ECP_ERR_KEYID; @@ -154,8 +162,10 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_ if (_idx == ECP_KEYID_PERMA) { /* this is init reply */ msg[ECP_SIZE_PROTO] = (ECP_KEYID_PERMA << 4) | ECP_KEYID_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; + memmove(msg+ECP_SIZE_PROTO+1, msg+ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB, pkt_size-(ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB)); + pkt_size -= ECP_SIZE_ECDH_PUB; + _msg[0] = pkt_size >> 8; + _msg[1] = pkt_size; } break; @@ -165,15 +175,22 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_ return ECP_ERR_CTYPE; } - payload.buffer = msg - ECP_SIZE_MTYPE; + payload.buffer = ecp_msg_get_pld(ECP_MTYPE_RELAY, _msg); payload.size = bufs->payload->size - (payload.buffer - bufs->payload->buffer); ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_EXEC); - rv = ecp_pld_send(conn_next, bufs->packet, &payload, ECP_SIZE_MTYPE + _msg_size, ECP_SEND_FLAG_REPLY); - ecp_conn_refcount_dec(conn_next); + if (conn_next->parent) { + _pkt_size = 0; + } else { + _pkt_size = ECP_SIZE_VCONN_PKT; + } + rv = ecp_pld_send_wsize(conn_next, bufs->packet, &payload, ECP_SIZE_MTYPE + sizeof(uint16_t) + pkt_size, ECP_SEND_FLAG_REPLY, _pkt_size); + ecp_conn_refcount_dec(conn_next); if (rv < 0) return rv; + + /* payload buffer is reused, so we must return msg_size */ return msg_size; } @@ -181,21 +198,31 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_ static ssize_t handle_exec(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { ECPBuffer *packet; + uint16_t pkt_size; ssize_t rv; - if (bufs == NULL) return ECP_ERR; + if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE; + + pkt_size = (uint16_t)msg[0] << 8; + pkt_size |= (uint16_t)msg[1]; + msg += sizeof(uint16_t); + + if (msg_size < sizeof(uint16_t) + pkt_size) return ECP_ERR_SIZE; packet = bufs->packet; - if (packet->size < msg_size) return ECP_ERR_SIZE; + if (packet->size < pkt_size) return ECP_ERR_SIZE; - memcpy(packet->buffer, msg, msg_size); - rv = ecp_pkt_handle(conn->sock, conn, NULL, bufs, msg_size); - return rv; + memcpy(packet->buffer, msg, pkt_size); + rv = ecp_pkt_handle(conn->sock, conn, NULL, bufs, pkt_size); + if (rv < 0) return rv; + + /* payload buffer can be reused, so we must return msg_size */ + return msg_size; } ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr) { unsigned char *msg; - size_t hdr_size; + size_t hdr_size, _pkt_size; ssize_t rv; int _rv; @@ -206,10 +233,19 @@ ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer if (msg == NULL) return ECP_ERR; hdr_size = msg - payload->buffer; - if (payload->size < pkt_size+hdr_size) return ECP_ERR_SIZE; + if (payload->size < hdr_size + sizeof(uint16_t) + pkt_size) return ECP_ERR_SIZE; + + msg[0] = pkt_size >> 8; + msg[1] = pkt_size; + memcpy(msg + sizeof(uint16_t), packet->buffer, pkt_size); + + if (conn->parent) { + _pkt_size = 0; + } else { + _pkt_size = ECP_SIZE_VCONN_PKT; + } - memcpy(msg, packet->buffer, pkt_size); - rv = ecp_pack_conn(conn, packet, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, pkt_size+hdr_size, addr); + rv = ecp_pack_conn(conn, packet, _pkt_size, ECP_KEYID_INV, ECP_KEYID_INV, 0, NULL, NULL, payload, hdr_size + sizeof(uint16_t) + pkt_size, addr); return rv; } @@ -272,7 +308,6 @@ int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { /* we should release incoming packet before sending next open packet */ ecp_tr_release(bufs->packet, 1); rv = _ecp_conn_open(vconn->next, conn, NULL, 1); - if (rv) rv = ECP_ERR_NEXT; return rv; } diff --git a/ecp/src/ecp/vconn/vconn.h b/ecp/src/ecp/vconn/vconn.h index f343846..d024f8e 100644 --- a/ecp/src/ecp/vconn/vconn.h +++ b/ecp/src/ecp/vconn/vconn.h @@ -1,9 +1,9 @@ -#define ECP_CTYPE_VCONN (0x01 | ECP_CTYPE_FLAG_SYS) -#define ECP_CTYPE_VLINK (0x02 | ECP_CTYPE_FLAG_SYS) +#define ECP_CTYPE_VCONN (0x01 | ECP_CTYPE_FLAG_SYS) +#define ECP_CTYPE_VLINK (0x02 | ECP_CTYPE_FLAG_SYS) -#define ECP_MTYPE_NEXT 0x00 -#define ECP_MTYPE_EXEC 0x02 -#define ECP_MTYPE_RELAY 0x01 +#define ECP_MTYPE_NEXT 0x00 +#define ECP_MTYPE_EXEC 0x02 +#define ECP_MTYPE_RELAY 0x01 #ifndef ECP_WITH_HTABLE #define ecp_vconn_handle_close NULL |