Skip to content

Commit

Permalink
Add RFC5746 minimal version implementation.
Browse files Browse the repository at this point in the history
Supports RFC5746 minimal version without renegotiation.

Signed-off-by: Achim Kraus <achim.kraus@cloudcoap.net>
  • Loading branch information
boaks committed Nov 29, 2022
1 parent 688ce26 commit 0bbd4f1
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
1 change: 1 addition & 0 deletions crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ typedef struct {
dtls_cipher_index_t cipher_index; /**< internal index for cipher_suite_params, DTLS_CIPHER_INDEX_NULL for TLS_NULL_WITH_NULL_NULL */
unsigned int do_client_auth:1;
unsigned int extended_master_secret:1;
unsigned int renegotiation_info:1;
union {
#ifdef DTLS_ECC
dtls_handshake_parameters_ecdsa_t ecdsa;
Expand Down
48 changes: 40 additions & 8 deletions dtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ static int verify_ext_sig_hash_algo(uint8 *data, size_t data_length) {
*/
static int
dtls_check_tls_extension(dtls_peer_t *peer,
uint8 *data, size_t data_length, int client_hello)
uint8 *data, size_t data_length, int is_client_hello)
{
uint16_t i, j;
int ext_elliptic_curve = 0;
Expand Down Expand Up @@ -1109,7 +1109,7 @@ dtls_check_tls_extension(dtls_peer_t *peer,
break;
case TLS_EXT_CLIENT_CERTIFICATE_TYPE:
ext_client_cert_type = 1;
if (client_hello) {
if (is_client_hello) {
if (verify_ext_cert_type(data, j))
goto error;
} else {
Expand All @@ -1119,7 +1119,7 @@ dtls_check_tls_extension(dtls_peer_t *peer,
break;
case TLS_EXT_SERVER_CERTIFICATE_TYPE:
ext_server_cert_type = 1;
if (client_hello) {
if (is_client_hello) {
if (verify_ext_cert_type(data, j))
goto error;
} else {
Expand All @@ -1145,6 +1145,15 @@ dtls_check_tls_extension(dtls_peer_t *peer,
if (verify_ext_sig_hash_algo(data, j))
goto error;
break;
case TLS_EXT_RENEGOTIATION_INFO:
/* RFC 5746, minimal version, only empty info is supported */
if (j == 1 && *data == 0) {
peer->handshake_params->renegotiation_info = 1;
} else {
dtls_warn("only empty renegotiation info is supported.\n");
goto error;
}
break;
default:
dtls_warn("unsupported tls extension: %i\n", i);
break;
Expand All @@ -1153,7 +1162,7 @@ dtls_check_tls_extension(dtls_peer_t *peer,
data_length -= j;
}
if (ecdsa) {
if (client_hello) {
if (is_client_hello) {
if (!ext_elliptic_curve || !ext_client_cert_type || !ext_server_cert_type || !ext_ec_point_formats) {
dtls_warn("not all required tls extensions found in client hello\n");
goto error;
Expand All @@ -1168,7 +1177,7 @@ dtls_check_tls_extension(dtls_peer_t *peer,
return 0;

error:
if (client_hello && peer->state == DTLS_STATE_CONNECTED) {
if (is_client_hello && peer->state == DTLS_STATE_CONNECTED) {
return dtls_alert_create(DTLS_ALERT_LEVEL_WARNING, DTLS_ALERT_NO_RENEGOTIATION);
} else {
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
Expand Down Expand Up @@ -1245,9 +1254,13 @@ dtls_update_parameters(dtls_context_t *ctx,
}

ok = 0;
while ((i >= (int)sizeof(uint16)) && !ok) {
config->cipher_index = get_cipher_index(config->cipher_suites, dtls_uint16_to_int(data));
ok = known_cipher(ctx, config->cipher_index, 0);
while ((i >= (int)sizeof(uint16)) && (!ok || !config->renegotiation_info)) {
if (dtls_uint16_to_int(data) == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
config->renegotiation_info = 1;
} else {
config->cipher_index = get_cipher_index(config->cipher_suites, dtls_uint16_to_int(data));
ok = known_cipher(ctx, config->cipher_index, 0);
}
i -= sizeof(uint16);
data += sizeof(uint16);
}
Expand Down Expand Up @@ -2312,6 +2325,7 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
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 */
Expand Down Expand Up @@ -2393,6 +2407,19 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
p += sizeof(uint16);
}

if (handshake->renegotiation_info) {
/* RFC5746 minimal version, empty renegotiation info */
dtls_int_to_uint16(p, TLS_EXT_RENEGOTIATION_INFO);
p += sizeof(uint16);

/* length of this extension type */
dtls_int_to_uint16(p, 1);
p += sizeof(uint16);

/* empty renegotiation info */
*p++ = 0;
}

assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf)));

/* TODO use the same record sequence number as in the ClientHello,
Expand Down Expand Up @@ -2966,6 +2993,11 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
}

/* RFC5746 add RENEGOTIATION_INFO_SCSV */
dtls_int_to_uint16(p, TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
p += sizeof(uint16);
cipher_suites_size += sizeof(uint16);

/* set size of known cipher suites */
dtls_int_to_uint16(p_cipher_suites_size, cipher_suites_size);

Expand Down
1 change: 1 addition & 0 deletions global.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ typedef enum {
#define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */
#define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */
#define TLS_EXT_EXTENDED_MASTER_SECRET 23 /* see RFC 7627 */
#define TLS_EXT_RENEGOTIATION_INFO 65281 /* see RFC 5746 */

#define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */

Expand Down

0 comments on commit 0bbd4f1

Please sign in to comment.