Skip to content

Commit

Permalink
[~] added token complexity for client-server interaction
Browse files Browse the repository at this point in the history
Fixes #266 issue
  • Loading branch information
Ya-Pasha-364shy committed May 13, 2024
1 parent ae6f7f7 commit 2747e9d
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 10 deletions.
9 changes: 9 additions & 0 deletions src/transport/xqc_cid.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@ xqc_cid_set(xqc_cid_t *cid, const unsigned char *data, uint8_t len)
}
}

static unsigned char g_token_buf[XQC_MAX_TOKEN_LEN];
static unsigned char g_scid_buf[XQC_MAX_CID_LEN * 2 + 1];
static unsigned char g_dcid_buf[XQC_MAX_CID_LEN * 2 + 1];
static unsigned char g_sr_token_buf[XQC_STATELESS_RESET_TOKENLEN * 2 + 1];


unsigned char *
xqc_dcid_str(const xqc_cid_t *dcid)
{
Expand All @@ -110,6 +112,13 @@ xqc_sr_token_str(const char *sr_token)
return g_sr_token_buf;
}

unsigned char *
xqc_token_str(const char *token, size_t token_len) {
xqc_hex_dump(g_token_buf, token, token_len);
g_token_buf[token_len] = '\0';
return g_token_buf;
}

unsigned char *
xqc_dcid_str_by_scid(xqc_engine_t *engine, const xqc_cid_t *scid)
{
Expand Down
1 change: 1 addition & 0 deletions src/transport/xqc_cid.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ xqc_int_t xqc_get_unused_cid(xqc_cid_set_t *cid_set, xqc_cid_t *cid);
xqc_bool_t xqc_validate_retire_cid_frame(xqc_cid_set_t *cid_set, xqc_cid_inner_t *cid);

unsigned char *xqc_sr_token_str(const char *sr_token);
unsigned char *xqc_token_str(const char *token, size_t token_len);

#endif /* _XQC_CID_H_INCLUDED_ */

75 changes: 66 additions & 9 deletions src/transport/xqc_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,36 @@ xqc_conn_set_default_sched_params(xqc_conn_settings_t *settings)
}
}

static void
xqc_conn_gen_secret(const xqc_engine_t *engine, xqc_connection_t *conn,
const xqc_cid_t *scid)
{
/* initialization of secret for token */
uint8_t iv_length = strlen(engine->init_vector);
uint8_t iterator;
uint8_t remainder = iv_length % scid->cid_len;
uint8_t steps = iv_length / scid->cid_len;
uint8_t tmp_array[iv_length];

uint8_t *pointer = tmp_array;

for (iterator = 0; iterator < steps; ++iterator) {
xqc_memcpy(pointer, scid->cid_buf, scid->cid_len);
pointer += scid->cid_len;
}
for (iterator = 0; iterator < remainder; ++iterator) {
*pointer++ = scid->cid_buf[iterator % scid->cid_len];
}
assert((pointer - tmp_array) == iv_length);

/* saving connection's secret */
for (iterator = 0; iterator < iv_length; ++iterator) {
conn->conn_secret[iterator] = engine->init_vector[iterator] ^
tmp_array[iterator];
}
conn->conn_secret_len = iv_length;
}

xqc_connection_t *
xqc_conn_create(xqc_engine_t *engine, xqc_cid_t *dcid, xqc_cid_t *scid,
const xqc_conn_settings_t *settings, void *user_data, xqc_conn_type_t type)
Expand Down Expand Up @@ -806,6 +836,8 @@ xqc_conn_create(xqc_engine_t *engine, xqc_cid_t *dcid, xqc_cid_t *scid,
xqc_init_list_head(&xc->dgram_0rtt_buffer_list);
xqc_init_list_head(&xc->ping_notification_list);

xqc_conn_gen_secret(engine, xc, &xc->scid_set.user_scid);

xqc_log(xc->log, XQC_LOG_DEBUG, "|success|scid:%s|dcid:%s|conn:%p|",
xqc_scid_str(&xc->scid_set.user_scid), xqc_dcid_str(&xc->dcid_set.current_dcid), xc);
xqc_log_event(xc->log, TRA_PARAMETERS_SET, xc, XQC_LOG_LOCAL_EVENT);
Expand Down Expand Up @@ -3277,9 +3309,8 @@ xqc_conn_get_lastest_rtt(xqc_engine_t *engine, const xqc_cid_t *cid)
return path->path_send_ctl->ctl_latest_rtt;
}


xqc_int_t
xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *token, unsigned token_len)
xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *enc_token, unsigned token_len)
{
if (token_len > XQC_MAX_TOKEN_LEN) {
xqc_log(conn->log, XQC_LOG_ERROR, "|%ud exceed XQC_MAX_TOKEN_LEN|", token_len);
Expand All @@ -3291,8 +3322,17 @@ xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *token, unsigne
}

struct sockaddr *sa = (struct sockaddr *)conn->peer_addr;
unsigned char token[token_len];

for (unsigned i = 0; i < token_len; ++i) {
token[i] = (enc_token[i] ^ conn->engine->init_vector[i]) ^
conn->conn_secret[i];
}

const unsigned char *pos = token;
if (*pos++ & 0x80) {
if (*pos == 0x80) {
++pos;

struct in6_addr *in6 = (struct in6_addr *)pos;
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
if (token_len != 21) {
Expand All @@ -3305,7 +3345,9 @@ xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *token, unsigne
}
pos += sizeof(struct in6_addr);

} else {
} else if (*pos == 0x00) {
++pos;

struct in_addr *in4 = (struct in_addr *)pos;
struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
if (token_len != 9) {
Expand All @@ -3319,6 +3361,9 @@ xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *token, unsigne
return XQC_ERROR;
}
pos += sizeof(struct in_addr);
} else {
xqc_log(conn->log, XQC_LOG_ERROR, "|invalid version|");
return XQC_ERROR;
}

/* check token lifetime */
Expand Down Expand Up @@ -3352,28 +3397,40 @@ xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *token, unsigne
void
xqc_conn_gen_token(xqc_connection_t *conn, unsigned char *token, unsigned *token_len)
{
unsigned char *saved_pointer_on_token = token;
struct sockaddr *sa = (struct sockaddr *)conn->peer_addr;

if (sa->sa_family == AF_INET) {
*token++ = 0x00;
struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
memcpy(token, &sa4->sin_addr, sizeof(struct in_addr));
token += sizeof(struct in_addr);

*token_len = 9;

/* "+ 1" - version byte */
*token_len = sizeof(struct in_addr) + 1;
} else {
*token++ = 0x80;
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
memcpy(token, &sa6->sin6_addr, sizeof(struct in6_addr));
token += sizeof(struct in6_addr);

*token_len = 21;
/* "+ 1" - version byte */
*token_len = sizeof(struct in6_addr) + 1;
}

uint32_t expire = xqc_monotonic_timestamp() / 1000000 + XQC_TOKEN_EXPIRE_DELTA;
xqc_log(conn->log, XQC_LOG_DEBUG, "|expire:%ud|", expire);
expire = htonl(expire);

memcpy(token, &expire, sizeof(expire));
*token_len += sizeof(uint32_t);

token = saved_pointer_on_token;

for (unsigned i = 0; i < *token_len; ++i) {
token[i] = (token[i] ^ conn->conn_secret[i]) ^
conn->engine->init_vector[i];
}

xqc_log(conn->log, XQC_LOG_DEBUG, "|token:%s|", xqc_token_str(token, *token_len));
}

void
Expand Down
5 changes: 4 additions & 1 deletion src/transport/xqc_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ struct xqc_connection_s {
uint32_t cli_bidi_streams;
uint32_t svr_bidi_streams;

uint8_t conn_secret_len;
uint8_t conn_secret[XQC_MAX_TOKEN_LEN];

/* receved pkts stats */
struct {
xqc_pkt_type_t pkt_types[3];
Expand Down Expand Up @@ -494,7 +497,7 @@ xqc_int_t xqc_conn_immediate_close(xqc_connection_t *conn);
xqc_int_t xqc_conn_send_retry(xqc_connection_t *conn, unsigned char *token, unsigned token_len);
xqc_int_t xqc_conn_version_check(xqc_connection_t *c, uint32_t version);
xqc_int_t xqc_conn_send_version_negotiation(xqc_connection_t *c);
xqc_int_t xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *token, unsigned token_len);
xqc_int_t xqc_conn_check_token(xqc_connection_t *conn, const unsigned char *enc_token, unsigned token_len);
void xqc_conn_gen_token(xqc_connection_t *conn, unsigned char *token, unsigned *token_len);
xqc_int_t xqc_conn_early_data_reject(xqc_connection_t *conn);
xqc_int_t xqc_conn_early_data_accept(xqc_connection_t *conn);
Expand Down
13 changes: 13 additions & 0 deletions src/transport/xqc_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,19 @@ xqc_engine_create(xqc_engine_type_t engine_type,
goto fail;
}

srand(time(NULL));

uint8_t tmp = 0;
uint8_t length_iv = (rand() % (XQC_MAX_LEN_IV - XQC_MIN_BLOCK_LEN)) +
XQC_MIN_BLOCK_LEN;
for (uint8_t i = 0; i < length_iv; ++i) {
/* range of symbols: [33, 127) */
engine->init_vector[i] = (rand() % (XQC_ASCII_UPPER_BOUND -
XQC_ASCII_LOWER_BOUND) +
XQC_ASCII_LOWER_BOUND);
}
engine->init_vector[length_iv] = '\0';

return engine;

fail:
Expand Down
11 changes: 11 additions & 0 deletions src/transport/xqc_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
#include "src/tls/xqc_tls.h"
#include "src/common/xqc_list.h"

/* follow "XQC_MAX_TOKEN_LEN" from xqc_defs.h */
#define XQC_MAX_LEN_IV (256)
/* follow "XQC_MAX_CID_LEN" xquic_typedef.h */
#define XQC_MIN_BLOCK_LEN (XQC_MAX_CID_LEN + 1)

#define XQC_ASCII_LOWER_BOUND (33)
#define XQC_ASCII_UPPER_BOUND (127)

#define XQC_RESET_CNT_ARRAY_LEN 16384


Expand Down Expand Up @@ -68,6 +76,9 @@ typedef struct xqc_engine_s {
/* list of xqc_alpn_registration_t */
xqc_list_head_t alpn_reg_list;

/* engine initialization vector for token encryption */
uint8_t init_vector[XQC_MAX_LEN_IV];

} xqc_engine_t;


Expand Down

0 comments on commit 2747e9d

Please sign in to comment.