mirror of
https://github.com/eclipse/tinydtls.git
synced 2025-10-14 03:10:09 +08:00
dtls.c: add RFC5746 minimal version implementation.
Supports RFC5746 minimal version without renegotiation. Add detailed documentation about the message length calculations. Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV to DTLS_CH_LENGTH_MAX. Remove eclipse_curves from ServerHello length. Signed-off-by: Achim Kraus <achim.kraus@cloudcoap.net>
This commit is contained in:
2
crypto.h
2
crypto.h
@@ -140,6 +140,7 @@ typedef struct dtls_user_parameters_t {
|
||||
*/
|
||||
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_renegotiation_info:1; /** force renegotiation info extension (RFC5746) */
|
||||
} dtls_user_parameters_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -159,6 +160,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;
|
||||
|
50
dtls.c
50
dtls.c
@@ -140,6 +140,9 @@ memarray_t dtlscontext_storage;
|
||||
* ec point format := 6 bytes => 26
|
||||
* sign. and hash algos := 8 bytes
|
||||
* extended master secret := 4 bytes => 12
|
||||
*
|
||||
* (The ClientHello uses TLS_EMPTY_RENEGOTIATION_INFO_SCSV
|
||||
* instead of renegotiation info)
|
||||
*/
|
||||
#define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */
|
||||
#define DTLS_COOKIE_LENGTH_MAX 32
|
||||
@@ -660,6 +663,7 @@ static const dtls_user_parameters_t default_user_parameters = {
|
||||
},
|
||||
#endif /* DTLS_DEFAULT_CIPHER_SUITES */
|
||||
.force_extended_master_secret = 1,
|
||||
.force_renegotiation_info = 1,
|
||||
};
|
||||
|
||||
/** only one compression method is currently defined */
|
||||
@@ -1260,6 +1264,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) {
|
||||
config->renegotiation_info = 1;
|
||||
} else {
|
||||
dtls_warn("only empty renegotiation info is supported.\n");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dtls_notice("unsupported tls extension: %i\n", i);
|
||||
break;
|
||||
@@ -1288,6 +1301,11 @@ check_forced_extensions:
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (config->user_parameters.force_renegotiation_info) {
|
||||
if (!config->renegotiation_info) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
@@ -1366,9 +1384,13 @@ dtls_update_parameters(dtls_context_t *ctx,
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
while ((i >= (int)sizeof(uint16)) && !ok) {
|
||||
config->cipher_index = get_cipher_index(config->user_parameters.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 if (!ok) {
|
||||
config->cipher_index = get_cipher_index(config->user_parameters.cipher_suites, dtls_uint16_to_int(data));
|
||||
ok = known_cipher(ctx, config->cipher_index, 0);
|
||||
}
|
||||
i -= sizeof(uint16);
|
||||
data += sizeof(uint16);
|
||||
}
|
||||
@@ -2435,10 +2457,11 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
|
||||
* server certificate type := 5 bytes
|
||||
* ec_point_formats := 6 bytes
|
||||
* extended master secret := 4 bytes
|
||||
* renegotiation info := 5 bytes
|
||||
*
|
||||
* (no elliptic_curves in ServerHello.)
|
||||
*/
|
||||
uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 6 + 4];
|
||||
uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 6 + 4 + 5];
|
||||
uint8 *p;
|
||||
uint8 extension_size;
|
||||
dtls_handshake_parameters_t * const handshake = peer->handshake_params;
|
||||
@@ -2446,6 +2469,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 */
|
||||
@@ -2527,6 +2551,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, 5 bytes */
|
||||
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,
|
||||
@@ -3098,6 +3135,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);
|
||||
|
||||
|
4
global.h
4
global.h
@@ -74,10 +74,11 @@ typedef unsigned char uint48[6];
|
||||
/** Known cipher suites.*/
|
||||
typedef enum {
|
||||
TLS_NULL_WITH_NULL_NULL = 0x0000, /**< NULL cipher */
|
||||
TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF, /**< see RFC 5746 */
|
||||
TLS_PSK_WITH_AES_128_CCM = 0xC0A4, /**< see RFC 6655 */
|
||||
TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC, /**< see RFC 7251 */
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE /**< see RFC 7251 */
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE, /**< see RFC 7251 */
|
||||
} dtls_cipher_t;
|
||||
|
||||
/** Known compression suites.*/
|
||||
@@ -92,6 +93,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 */
|
||||
|
||||
|
Reference in New Issue
Block a user