Add client dtls connection ID.

Simple client side implementation indicates support and uses the cid of
the server, when negotiated by that.

Signed-off-by: Achim Kraus <achim.kraus@cloudcoap.net>
This commit is contained in:
Achim Kraus
2021-11-18 21:50:52 +01:00
parent 431079debd
commit 7cf7699e88
4 changed files with 198 additions and 52 deletions

View File

@@ -113,6 +113,17 @@ typedef struct {
uint64_t bitfield; uint64_t bitfield;
} seqnum_t; } seqnum_t;
/* Maximum CID length. */
#ifndef DTLS_MAX_CID_LENGTH
#define DTLS_MAX_CID_LENGTH 16
#endif
#if (DTLS_MAX_CID_LENGTH > 0)
#ifndef DTLS_USE_CID_DEFAULT
#define DTLS_USE_CID_DEFAULT 1
#endif /* DTLS_USE_CID_DEFAULT */
#endif /* DTLS_MAX_CID_LENGTH > 0 */
typedef struct { typedef struct {
dtls_compression_t compression; /**< compression method */ dtls_compression_t compression; /**< compression method */
@@ -127,7 +138,12 @@ typedef struct {
* access the components of the key block. * access the components of the key block.
*/ */
uint8 key_block[MAX_KEYBLOCK_LENGTH]; uint8 key_block[MAX_KEYBLOCK_LENGTH];
#if (DTLS_MAX_CID_LENGTH > 0)
uint8_t write_cid[DTLS_MAX_CID_LENGTH];
uint8_t write_cid_length;
#endif /* DTLS_MAX_CID_LENGTH > 0 */
seqnum_t cseq; /**<sequence number of last record received*/ seqnum_t cseq; /**<sequence number of last record received*/
} dtls_security_parameters_t; } dtls_security_parameters_t;
@@ -148,6 +164,9 @@ typedef struct dtls_user_parameters_t {
dtls_cipher_t cipher_suites[DTLS_MAX_CIPHER_SUITES + 1]; dtls_cipher_t cipher_suites[DTLS_MAX_CIPHER_SUITES + 1];
unsigned int force_extended_master_secret:1; /** force extended master secret extension (RFC7627) */ unsigned int force_extended_master_secret:1; /** force extended master secret extension (RFC7627) */
unsigned int force_renegotiation_info:1; /** force renegotiation info extension (RFC5746) */ unsigned int force_renegotiation_info:1; /** force renegotiation info extension (RFC5746) */
#if (DTLS_MAX_CID_LENGTH > 0)
unsigned int support_cid:1; /** indicate CID support (RFC9146) */
#endif
} dtls_user_parameters_t; } dtls_user_parameters_t;
typedef struct { typedef struct {
@@ -165,6 +184,12 @@ typedef struct {
dtls_compression_t compression; /**< compression method */ dtls_compression_t compression; /**< compression method */
dtls_user_parameters_t user_parameters; /**< user parameters */ dtls_user_parameters_t user_parameters; /**< user parameters */
dtls_cipher_index_t cipher_index; /**< internal index for cipher_suite_params, DTLS_CIPHER_INDEX_NULL for TLS_NULL_WITH_NULL_NULL */ dtls_cipher_index_t cipher_index; /**< internal index for cipher_suite_params, DTLS_CIPHER_INDEX_NULL for TLS_NULL_WITH_NULL_NULL */
#if (DTLS_MAX_CID_LENGTH > 0)
uint8_t write_cid[DTLS_MAX_CID_LENGTH];
uint8_t write_cid_length;
#endif /* DTLS_MAX_CID_LENGTH > 0 */
unsigned int do_client_auth:1; unsigned int do_client_auth:1;
unsigned int extended_master_secret:1; unsigned int extended_master_secret:1;
unsigned int renegotiation_info:1; unsigned int renegotiation_info:1;

221
dtls.c
View File

@@ -142,14 +142,15 @@ memarray_t dtlscontext_storage;
* ec curves := 8 bytes * ec curves := 8 bytes
* ec point format := 6 bytes => 26 * ec point format := 6 bytes => 26
* sign. and hash algos := 8 bytes * sign. and hash algos := 8 bytes
* extended master secret := 4 bytes => 12 * extended master secret := 4 bytes
* connection id, empty := 5 bytes => 17
* *
* (The ClientHello uses TLS_EMPTY_RENEGOTIATION_INFO_SCSV * (The ClientHello uses TLS_EMPTY_RENEGOTIATION_INFO_SCSV
* instead of renegotiation info) * instead of renegotiation info)
*/ */
#define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */ #define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */
#define DTLS_COOKIE_LENGTH_MAX 32 #define DTLS_COOKIE_LENGTH_MAX 32
#define DTLS_CH_LENGTH_MAX DTLS_CH_LENGTH + DTLS_COOKIE_LENGTH_MAX + 10 + (2 * DTLS_MAX_CIPHER_SUITES) + 26 + 12 #define DTLS_CH_LENGTH_MAX DTLS_CH_LENGTH + DTLS_COOKIE_LENGTH_MAX + 10 + (2 * DTLS_MAX_CIPHER_SUITES) + 26 + 17
#define DTLS_HV_LENGTH sizeof(dtls_hello_verify_t) #define DTLS_HV_LENGTH sizeof(dtls_hello_verify_t)
/* /*
* ServerHello: * ServerHello:
@@ -541,6 +542,7 @@ static char const content_types[] = {
DTLS_CT_ALERT, DTLS_CT_ALERT,
DTLS_CT_HANDSHAKE, DTLS_CT_HANDSHAKE,
DTLS_CT_APPLICATION_DATA, DTLS_CT_APPLICATION_DATA,
DTLS_CT_TLS12_CID,
0 /* end marker */ 0 /* end marker */
}; };
@@ -696,6 +698,9 @@ static const dtls_user_parameters_t default_user_parameters = {
#endif /* DTLS_DEFAULT_CIPHER_SUITES */ #endif /* DTLS_DEFAULT_CIPHER_SUITES */
.force_extended_master_secret = 1, .force_extended_master_secret = 1,
.force_renegotiation_info = 1, .force_renegotiation_info = 1,
#if (DTLS_MAX_CID_LENGTH > 0)
.support_cid = DTLS_USE_CID_DEFAULT,
#endif /* DTLS_MAX_CID_LENGTH > 0 */
}; };
/** only one compression method is currently defined */ /** only one compression method is currently defined */
@@ -958,6 +963,8 @@ dtls_message_type_to_name(int type) {
return "handshake"; return "handshake";
case DTLS_CT_APPLICATION_DATA: case DTLS_CT_APPLICATION_DATA:
return "application_data"; return "application_data";
case DTLS_CT_TLS12_CID:
return "connection_id";
default: default:
return NULL; return NULL;
} }
@@ -1097,6 +1104,10 @@ calculate_key_block(dtls_context_t *ctx,
security->cipher_index = handshake->cipher_index; security->cipher_index = handshake->cipher_index;
security->compression = handshake->compression; security->compression = handshake->compression;
security->rseq = 0; security->rseq = 0;
#if (DTLS_MAX_CID_LENGTH > 0)
security->write_cid_length = handshake->write_cid_length;
memcpy(security->write_cid, handshake->write_cid, handshake->write_cid_length);
#endif /* DTLS_MAX_CID_LENGTH > 0 */
return 0; return 0;
} }
@@ -1203,6 +1214,39 @@ static int verify_ext_sig_hash_algo(uint8 *data, size_t data_length) {
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
} }
#if (DTLS_MAX_CID_LENGTH > 0)
static int
get_ext_connection_id(dtls_handshake_parameters_t *handshake, uint8 *data,
size_t data_length) {
uint8_t i;
if (sizeof(uint8) > data_length) {
dtls_warn("invalid length (%zu) for extension connection id\n", data_length);
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
}
/* length of the connection id */
i = dtls_uint8_to_int(data);
data += sizeof(uint8);
if (i + sizeof(uint8) != data_length) {
dtls_warn("invalid connection id length (%d)\n", i);
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
}
if (DTLS_MAX_CID_LENGTH < i) {
dtls_warn("connection id length (%d) exceeds maximum (%d)!\n", i, DTLS_MAX_CID_LENGTH);
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
}
handshake->write_cid_length = i;
memcpy(handshake->write_cid, data, i);
return 0;
}
#endif /* DTLS_MAX_CID_LENGTH > 0*/
/* /*
* Check for some TLS Extensions used by the ECDHE_ECDSA cipher. * Check for some TLS Extensions used by the ECDHE_ECDSA cipher.
*/ */
@@ -1296,6 +1340,16 @@ dtls_check_tls_extension(dtls_peer_t *peer,
if (verify_ext_sig_hash_algo(data, j)) if (verify_ext_sig_hash_algo(data, j))
goto error; goto error;
break; break;
#if (DTLS_MAX_CID_LENGTH > 0)
case TLS_EXT_CONNECTION_ID:
if (!is_client_hello && !peer->handshake_params->user_parameters.support_cid) {
dtls_warn("connection id was not sent by client!\n");
goto error;
}
if (get_ext_connection_id(peer->handshake_params, data, j))
goto error;
break;
#endif /* DTLS_MAX_CID_LENGTH */
case TLS_EXT_RENEGOTIATION_INFO: case TLS_EXT_RENEGOTIATION_INFO:
/* RFC 5746, minimal version, only empty info is supported */ /* RFC 5746, minimal version, only empty info is supported */
if (j == 1 && *data == 0) { if (j == 1 && *data == 0) {
@@ -1673,9 +1727,10 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
uint8 *data_array[], size_t data_len_array[], uint8 *data_array[], size_t data_len_array[],
size_t data_array_len, size_t data_array_len,
uint8 *sendbuf, size_t *rlen) { uint8 *sendbuf, size_t *rlen) {
uint8 *p, *start; uint8 *p;
int res; int res;
unsigned int i; unsigned int i;
uint8_t cid_length = 0;
if (*rlen < DTLS_RH_LENGTH) { if (*rlen < DTLS_RH_LENGTH) {
dtls_alert("The sendbuf (%zu bytes) is too small\n", *rlen); dtls_alert("The sendbuf (%zu bytes) is too small\n", *rlen);
@@ -1688,7 +1743,6 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
} }
p = dtls_set_record_header(type, security->epoch, &(security->rseq), sendbuf); p = dtls_set_record_header(type, security->epoch, &(security->rseq), sendbuf);
start = p;
if (security->cipher_index == DTLS_CIPHER_INDEX_NULL) { if (security->cipher_index == DTLS_CIPHER_INDEX_NULL) {
/* no cipher suite */ /* no cipher suite */
@@ -1709,15 +1763,31 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 or TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 or
TLS_ECDHE_ECDSA_WITH_AES_128_CCM */ TLS_ECDHE_ECDSA_WITH_AES_128_CCM */
/** /**
* RFC6347
* length of additional_data for the AEAD cipher which consists of * length of additional_data for the AEAD cipher which consists of
* seq_num(2+6) + type(1) + version(2) + length(2) * seq_num(2+6) + type(1) + version(2) + length(2)
*/ */
#define A_DATA_LEN 13 #define A_DATA_LEN 13
#if (DTLS_MAX_CID_LENGTH > 0)
/**
* RFC9146
* length of extra additional_data for the AEAD cipher which consists of
* seq_num_placeholder(8) + type(1) + cid_length(1)
*/
#define A_DATA_CID_EXTRA_LEN 10
#define A_DATA_MAX_LEN (A_DATA_LEN + A_DATA_CID_EXTRA_LEN + DTLS_MAX_CID_LENGTH)
#else
#define A_DATA_MAX_LEN A_DATA_LEN
#endif
uint8 *start = p;
unsigned char nonce[DTLS_CCM_BLOCKSIZE]; unsigned char nonce[DTLS_CCM_BLOCKSIZE];
unsigned char A_DATA[A_DATA_LEN]; unsigned char A_DATA[A_DATA_MAX_LEN];
const uint8_t mac_len = get_cipher_suite_mac_len(security->cipher_index); const uint8_t mac_len = get_cipher_suite_mac_len(security->cipher_index);
const cipher_suite_key_exchange_algorithm_t key_exchange_algorithm = const cipher_suite_key_exchange_algorithm_t key_exchange_algorithm =
get_key_exchange_algorithm(security->cipher_index); get_key_exchange_algorithm(security->cipher_index);
uint8_t a_data_len = A_DATA_LEN;
/* For backwards-compatibility, dtls_encrypt_params is called with /* For backwards-compatibility, dtls_encrypt_params is called with
* M=<macLen> and L=3. */ * M=<macLen> and L=3. */
const dtls_ccm_params_t params = { nonce, mac_len, 3 }; const dtls_ccm_params_t params = { nonce, mac_len, 3 };
@@ -1734,6 +1804,16 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
} }
} }
#if (DTLS_MAX_CID_LENGTH > 0)
cid_length = security->write_cid_length;
if (cid_length > 0) {
/* add cid to record header */
memcpy(p - sizeof(uint16_t), security->write_cid, cid_length);
p += cid_length;
start = p;
}
#endif /* DTLS_MAX_CID_LENGTH > 0 */
/* set nonce /* set nonce
from RFC 6655: from RFC 6655:
The "nonce" input to the AEAD algorithm is exactly that of [RFC5288]: The "nonce" input to the AEAD algorithm is exactly that of [RFC5288]:
@@ -1799,31 +1879,62 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
dtls_debug_dump("key:", dtls_kb_local_write_key(security, peer->role), dtls_debug_dump("key:", dtls_kb_local_write_key(security, peer->role),
dtls_kb_key_size(security, peer->role)); dtls_kb_key_size(security, peer->role));
/* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: #if (DTLS_MAX_CID_LENGTH > 0)
* if (cid_length > 0) {
* additional_data = seq_num + TLSCompressed.type + /* RFC 9146 */
* TLSCompressed.version + TLSCompressed.length;
*/ /* inner content type */
memcpy(A_DATA, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); /* epoch and seq_num */ *p = *sendbuf;
memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */ *sendbuf = DTLS_CT_TLS12_CID;
dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */ p += sizeof(uint8_t);
res += sizeof(uint8_t);
/* seq_num_placeholder: 8x 0xff */
memset(A_DATA, 0xff, 8);
/* tls_cid: 25 */
A_DATA[8] = DTLS_CT_TLS12_CID;
/* cid length */
A_DATA[9] = cid_length;
/* copy record header */
memcpy(A_DATA + A_DATA_CID_EXTRA_LEN, sendbuf, A_DATA_LEN + cid_length);
dtls_int_to_uint16(A_DATA + A_DATA_CID_EXTRA_LEN + 11 + cid_length, res - 8); /* length */
a_data_len = A_DATA_LEN + A_DATA_CID_EXTRA_LEN + cid_length;
} else {
#endif /* DTLS_MAX_CID_LENGTH > 0 */
/* RFC 6347 */
/* re-use N to create additional data according to RFC 5246, Section 6.2.3.3:
*
* additional_data = seq_num + TLSCompressed.type +
* TLSCompressed.version + TLSCompressed.length;
*/
memcpy(A_DATA, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); /* epoch and seq_num */
memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */
dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */
a_data_len = A_DATA_LEN;
#if (DTLS_MAX_CID_LENGTH > 0)
}
#endif /* DTLS_MAX_CID_LENGTH > 0 */
dtls_debug_dump("adata:", A_DATA, a_data_len);
dtls_debug_dump("message:", start, res);
res = dtls_encrypt_params(&params, start + 8, res - 8, start + 8, res = dtls_encrypt_params(&params, start + 8, res - 8, start + 8,
dtls_kb_local_write_key(security, peer->role), dtls_kb_local_write_key(security, peer->role),
dtls_kb_key_size(security, peer->role), dtls_kb_key_size(security, peer->role),
A_DATA, A_DATA_LEN); A_DATA, a_data_len);
if (res < 0) if (res < 0)
return res; return res;
res += 8; /* increment res by size of nonce_explicit */ res += 8; /* increment res by size of nonce_explicit */
dtls_debug_dump("message:", start, res); dtls_debug_dump("encrypted-message:", start, res);
} }
/* fix length of fragment in sendbuf */ /* fix length of fragment in sendbuf */
dtls_int_to_uint16(sendbuf + 11, res); dtls_int_to_uint16(sendbuf + 11 + cid_length, res);
*rlen = DTLS_RH_LENGTH + res; *rlen = DTLS_RH_LENGTH + res + cid_length;
return 0; return 0;
} }
@@ -2495,15 +2606,12 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
*/ */
uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 6 + 4 + 5]; uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 6 + 4 + 5];
uint8 *p; uint8 *p;
uint8 extension_size; uint8_t *p_extension_size = NULL;
uint16_t extension_size = 0;
dtls_handshake_parameters_t * const handshake = peer->handshake_params; dtls_handshake_parameters_t * const handshake = peer->handshake_params;
const dtls_cipher_t cipher_suite = get_cipher_suite(handshake->cipher_index); const dtls_cipher_t cipher_suite = get_cipher_suite(handshake->cipher_index);
const int ecdsa = is_key_exchange_ecdhe_ecdsa(handshake->cipher_index); const int ecdsa = is_key_exchange_ecdhe_ecdsa(handshake->cipher_index);
extension_size = (handshake->extended_master_secret ? 4 : 0) +
(handshake->renegotiation_info ? 5 : 0) +
(ecdsa ? 5 + 5 + 6 : 0);
/* Handshake header */ /* Handshake header */
p = buf; p = buf;
@@ -2517,7 +2625,8 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
memcpy(p, handshake->tmp.random.server, DTLS_RANDOM_LENGTH); memcpy(p, handshake->tmp.random.server, DTLS_RANDOM_LENGTH);
p += DTLS_RANDOM_LENGTH; p += DTLS_RANDOM_LENGTH;
*p++ = 0; /* no session id */ /* no session id */
*p++ = 0;
if (cipher_suite != TLS_NULL_WITH_NULL_NULL) { if (cipher_suite != TLS_NULL_WITH_NULL_NULL) {
/* selected cipher suite */ /* selected cipher suite */
@@ -2528,11 +2637,10 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
*p++ = compression_methods[handshake->compression]; *p++ = compression_methods[handshake->compression];
} }
if (extension_size) { /* keep pointer to length of the extensions */
/* length of the extensions */ p_extension_size = p;
dtls_int_to_uint16(p, extension_size); /* skip length of extensions field */
p += sizeof(uint16); p += sizeof(uint16);
}
if (ecdsa) { if (ecdsa) {
/* client certificate type extension, 5 bytes */ /* client certificate type extension, 5 bytes */
@@ -2596,6 +2704,10 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
*p++ = 0; *p++ = 0;
} }
/* length of the extensions */
extension_size = (p - p_extension_size) - sizeof(uint16);
dtls_int_to_uint16(p_extension_size, extension_size);
assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf))); assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf)));
/* TODO use the same record sequence number as in the ClientHello, /* TODO use the same record sequence number as in the ClientHello,
@@ -3111,10 +3223,9 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
uint8 cookie[], size_t cookie_length) { uint8 cookie[], size_t cookie_length) {
uint8 buf[DTLS_CH_LENGTH_MAX]; uint8 buf[DTLS_CH_LENGTH_MAX];
uint8_t *p = buf; uint8_t *p = buf;
uint8_t *p_cipher_suites_size = NULL; uint8_t *p_size = NULL;
uint16_t size = 0;
uint8_t index = 0; uint8_t index = 0;
uint8_t cipher_suites_size = 0;
uint8_t extension_size = 4; /* extended master secret extension */
#ifdef DTLS_ECC #ifdef DTLS_ECC
uint8_t ecdsa = 0; uint8_t ecdsa = 0;
#endif #endif
@@ -3154,7 +3265,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
} }
/* keep pointer to size of cipher suites */ /* keep pointer to size of cipher suites */
p_cipher_suites_size = p; p_size = p;
/* skip size of cipher suites field */ /* skip size of cipher suites field */
p += sizeof(uint16); p += sizeof(uint16);
@@ -3173,8 +3284,8 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
credentials callback is missing */ credentials callback is missing */
} }
cipher_suites_size = (p - p_cipher_suites_size) - sizeof(uint16); size = (p - p_size) - sizeof(uint16);
if (cipher_suites_size == 0) { if (size == 0) {
dtls_crit("no supported cipher suite provided!\n"); dtls_crit("no supported cipher suite provided!\n");
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
} }
@@ -3182,23 +3293,10 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
/* RFC5746 add RENEGOTIATION_INFO_SCSV */ /* RFC5746 add RENEGOTIATION_INFO_SCSV */
dtls_int_to_uint16(p, TLS_EMPTY_RENEGOTIATION_INFO_SCSV); dtls_int_to_uint16(p, TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
p += sizeof(uint16); p += sizeof(uint16);
cipher_suites_size += sizeof(uint16); size += sizeof(uint16);
/* set size of known cipher suites */ /* set size of known cipher suites */
dtls_int_to_uint16(p_cipher_suites_size, cipher_suites_size); dtls_int_to_uint16(p_size, size);
#ifdef DTLS_ECC
if (ecdsa) {
/*
* client_cert_type := 6 bytes
* server_cert_type := 6 bytes
* ec curves := 8 bytes
* ec point format := 6 bytes
* sign. and hash algos := 8 bytes
*/
extension_size += 6 + 6 + 8 + 6 + 8;
}
#endif
/* compression method */ /* compression method */
dtls_int_to_uint8(p, 1); dtls_int_to_uint8(p, 1);
@@ -3207,8 +3305,9 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
dtls_int_to_uint8(p, TLS_COMPRESSION_NULL); dtls_int_to_uint8(p, TLS_COMPRESSION_NULL);
p += sizeof(uint8); p += sizeof(uint8);
/* length of the extensions */ /* keep pointer to length of the extensions */
dtls_int_to_uint16(p, extension_size); p_size = p;
/* skip length of extensions field */
p += sizeof(uint16); p += sizeof(uint16);
#ifdef DTLS_ECC #ifdef DTLS_ECC
@@ -3305,6 +3404,26 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
p += sizeof(uint16); p += sizeof(uint16);
handshake->extended_master_secret = 1; handshake->extended_master_secret = 1;
#if (DTLS_MAX_CID_LENGTH > 0)
if (handshake->user_parameters.support_cid) {
/* connection id, empty to indicate support, 5 bytes */
dtls_int_to_uint16(p, TLS_EXT_CONNECTION_ID);
p += sizeof(uint16);
/* length of this extension type */
dtls_int_to_uint16(p, sizeof(uint8));
p += sizeof(uint16);
/* empty cid, indicating support for cid extension */
dtls_int_to_uint8(p, 0);
p += sizeof(uint8);
}
#endif /* DTLS_MAX_CID_LENGTH > 0 */
/* length of the extensions */
size = (p - p_size) - sizeof(uint16);
dtls_int_to_uint16(p_size, size);
handshake->hs_state.read_epoch = dtls_security_params(peer)->epoch; handshake->hs_state.read_epoch = dtls_security_params(peer)->epoch;
assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf))); assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf)));

1
dtls.h
View File

@@ -341,6 +341,7 @@ void dtls_check_retransmit(dtls_context_t *context, clock_time_t *next);
#define DTLS_CT_ALERT 21 #define DTLS_CT_ALERT 21
#define DTLS_CT_HANDSHAKE 22 #define DTLS_CT_HANDSHAKE 22
#define DTLS_CT_APPLICATION_DATA 23 #define DTLS_CT_APPLICATION_DATA 23
#define DTLS_CT_TLS12_CID 25
#ifdef __GNUC__ #ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))

View File

@@ -93,6 +93,7 @@ typedef enum {
#define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */ #define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */
#define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */ #define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */
#define TLS_EXT_EXTENDED_MASTER_SECRET 23 /* see RFC 7627 */ #define TLS_EXT_EXTENDED_MASTER_SECRET 23 /* see RFC 7627 */
#define TLS_EXT_CONNECTION_ID 54 /* see RFC 9146 */
#define TLS_EXT_RENEGOTIATION_INFO 65281 /* see RFC 5746 */ #define TLS_EXT_RENEGOTIATION_INFO 65281 /* see RFC 5746 */
#define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */ #define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */