Add SSL_is_dtls.

OpenSSL 1.1.0 added a function to tell if an SSL* is DTLS or not. This
is probably a good idea, especially since SSL_version returns
non-normalized versions.

BUG=91

Change-Id: I25c6cf08b2ebabf0c610c74691de103399f729bc
Reviewed-on: https://boringssl-review.googlesource.com/9077
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2016-08-02 16:22:34 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent dc7a786d31
commit ce079fda12
9 changed files with 39 additions and 37 deletions

View File

@ -231,7 +231,10 @@ OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl);
/* SSL_is_server returns one if |ssl| is configured as a server and zero /* SSL_is_server returns one if |ssl| is configured as a server and zero
* otherwise. */ * otherwise. */
OPENSSL_EXPORT int SSL_is_server(SSL *ssl); OPENSSL_EXPORT int SSL_is_server(const SSL *ssl);
/* SSL_is_dtls returns one if |ssl| is a DTLS connection and zero otherwise. */
OPENSSL_EXPORT int SSL_is_dtls(const SSL *ssl);
/* SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl| /* SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl|
* takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl| * takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl|

View File

@ -153,7 +153,7 @@ void dtls1_start_timer(SSL *ssl) {
} }
int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
if (!SSL_IS_DTLS(ssl)) { if (!SSL_is_dtls(ssl)) {
return 0; return 0;
} }
@ -254,7 +254,7 @@ int DTLSv1_handle_timeout(SSL *ssl) {
/* Functions which use SSL_get_error must clear the error queue on entry. */ /* Functions which use SSL_get_error must clear the error queue on entry. */
ERR_clear_error(); ERR_clear_error();
if (!SSL_IS_DTLS(ssl)) { if (!SSL_is_dtls(ssl)) {
return -1; return -1;
} }

View File

@ -221,7 +221,7 @@ int ssl3_connect(SSL *ssl) {
goto end; goto end;
} }
if (!SSL_IS_DTLS(ssl) || ssl->d1->send_cookie) { if (!SSL_is_dtls(ssl) || ssl->d1->send_cookie) {
ssl->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; ssl->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
} else { } else {
ssl->s3->tmp.next_state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; ssl->s3->tmp.next_state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
@ -230,7 +230,7 @@ int ssl3_connect(SSL *ssl) {
break; break;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
assert(SSL_IS_DTLS(ssl)); assert(SSL_is_dtls(ssl));
ret = dtls1_get_hello_verify(ssl); ret = dtls1_get_hello_verify(ssl);
if (ret <= 0) { if (ret <= 0) {
goto end; goto end;
@ -655,7 +655,7 @@ int ssl_add_client_hello_body(SSL *ssl, CBB *body) {
return 0; return 0;
} }
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
if (!CBB_add_u8_length_prefixed(body, &child) || if (!CBB_add_u8_length_prefixed(body, &child) ||
!CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) { !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) {
return 0; return 0;
@ -663,7 +663,7 @@ int ssl_add_client_hello_body(SSL *ssl, CBB *body) {
} }
size_t header_len = size_t header_len =
SSL_IS_DTLS(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH; SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH;
if (!ssl_write_client_cipher_list(ssl, body, min_version, max_version, if (!ssl_write_client_cipher_list(ssl, body, min_version, max_version,
real_max_version) || real_max_version) ||
!CBB_add_u8(body, 1 /* one compression method */) || !CBB_add_u8(body, 1 /* one compression method */) ||
@ -719,7 +719,7 @@ static int ssl3_send_client_hello(SSL *ssl) {
/* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
* renegerate the client_random. The random must be reused. */ * renegerate the client_random. The random must be reused. */
if ((!SSL_IS_DTLS(ssl) || !ssl->d1->send_cookie) && if ((!SSL_is_dtls(ssl) || !ssl->d1->send_cookie) &&
!RAND_bytes(ssl->s3->client_random, sizeof(ssl->s3->client_random))) { !RAND_bytes(ssl->s3->client_random, sizeof(ssl->s3->client_random))) {
goto err; goto err;
} }

View File

@ -652,7 +652,7 @@ static int ssl3_get_client_hello(SSL *ssl) {
/* Load the client random. */ /* Load the client random. */
memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE); memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
CBS cookie; CBS cookie;
if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) || if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) ||

View File

@ -961,9 +961,6 @@ int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret,
#define TLSEXT_CHANNEL_ID_SIZE 128 #define TLSEXT_CHANNEL_ID_SIZE 128
/* Check if an SSL structure is using DTLS */
#define SSL_IS_DTLS(ssl) (ssl->method->is_dtls)
/* From RFC4492, used in encoding the curve type in ECParameters */ /* From RFC4492, used in encoding the curve type in ECParameters */
#define NAMED_CURVE_TYPE 3 #define NAMED_CURVE_TYPE 3

View File

@ -85,7 +85,7 @@ static int setup_read_buffer(SSL *ssl) {
size_t header_len = ssl_record_prefix_len(ssl); size_t header_len = ssl_record_prefix_len(ssl);
size_t cap = SSL3_RT_MAX_ENCRYPTED_LENGTH; size_t cap = SSL3_RT_MAX_ENCRYPTED_LENGTH;
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
cap += DTLS1_RT_HEADER_LENGTH; cap += DTLS1_RT_HEADER_LENGTH;
} else { } else {
cap += SSL3_RT_HEADER_LENGTH; cap += SSL3_RT_HEADER_LENGTH;
@ -163,7 +163,7 @@ int ssl_read_buffer_extend_to(SSL *ssl, size_t len) {
} }
int ret; int ret;
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
/* |len| is ignored for a datagram transport. */ /* |len| is ignored for a datagram transport. */
ret = dtls_read_buffer_next_packet(ssl); ret = dtls_read_buffer_next_packet(ssl);
} else { } else {
@ -188,7 +188,7 @@ void ssl_read_buffer_consume(SSL *ssl, size_t len) {
* |ssl_read_buffer_discard| will require a |memcpy| to shift the excess back * |ssl_read_buffer_discard| will require a |memcpy| to shift the excess back
* to the front of the buffer, to ensure there is enough space for the next * to the front of the buffer, to ensure there is enough space for the next
* record. */ * record. */
assert(SSL_IS_DTLS(ssl) || len == 0 || buf->len == 0); assert(SSL_is_dtls(ssl) || len == 0 || buf->len == 0);
} }
void ssl_read_buffer_discard(SSL *ssl) { void ssl_read_buffer_discard(SSL *ssl) {
@ -229,7 +229,7 @@ int ssl_write_buffer_init(SSL *ssl, uint8_t **out_ptr, size_t max_len) {
/* TODO(davidben): This matches the original behavior in keeping the malloc /* TODO(davidben): This matches the original behavior in keeping the malloc
* size consistent. Does this matter? |cap| could just be |max_len|. */ * size consistent. Does this matter? |cap| could just be |max_len|. */
size_t cap = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; size_t cap = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
cap += DTLS1_RT_HEADER_LENGTH; cap += DTLS1_RT_HEADER_LENGTH;
} else { } else {
cap += SSL3_RT_HEADER_LENGTH; cap += SSL3_RT_HEADER_LENGTH;
@ -299,7 +299,7 @@ int ssl_write_buffer_flush(SSL *ssl) {
return -1; return -1;
} }
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
return dtls_write_buffer_flush(ssl); return dtls_write_buffer_flush(ssl);
} else { } else {
return tls_write_buffer_flush(ssl); return tls_write_buffer_flush(ssl);

View File

@ -1375,7 +1375,7 @@ int SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
} }
int SSL_set_mtu(SSL *ssl, unsigned mtu) { int SSL_set_mtu(SSL *ssl, unsigned mtu) {
if (!SSL_IS_DTLS(ssl) || mtu < dtls1_min_mtu()) { if (!SSL_is_dtls(ssl) || mtu < dtls1_min_mtu()) {
return 0; return 0;
} }
ssl->d1->mtu = mtu; ssl->d1->mtu = mtu;
@ -2644,7 +2644,7 @@ int ssl3_can_false_start(const SSL *ssl) {
const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl); const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl);
/* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */ /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */
return !SSL_IS_DTLS(ssl) && return !SSL_is_dtls(ssl) &&
SSL_version(ssl) == TLS1_2_VERSION && SSL_version(ssl) == TLS1_2_VERSION &&
(ssl->s3->alpn_selected || ssl->s3->next_proto_neg_seen) && (ssl->s3->alpn_selected || ssl->s3->next_proto_neg_seen) &&
cipher != NULL && cipher != NULL &&
@ -2688,7 +2688,7 @@ int ssl_get_full_version_range(const SSL *ssl, uint16_t *out_min_version,
/* For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but /* For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but
* DTLS 1.0 should be mapped to TLS 1.1. */ * DTLS 1.0 should be mapped to TLS 1.1. */
uint32_t options = ssl->options; uint32_t options = ssl->options;
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
options &= ~SSL_OP_NO_TLSv1_1; options &= ~SSL_OP_NO_TLSv1_1;
if (options & SSL_OP_NO_DTLSv1) { if (options & SSL_OP_NO_DTLSv1) {
options |= SSL_OP_NO_TLSv1_1; options |= SSL_OP_NO_TLSv1_1;
@ -2775,7 +2775,9 @@ uint16_t ssl3_protocol_version(const SSL *ssl) {
return ssl->method->version_from_wire(ssl->version); return ssl->method->version_from_wire(ssl->version);
} }
int SSL_is_server(SSL *ssl) { return ssl->server; } int SSL_is_server(const SSL *ssl) { return ssl->server; }
int SSL_is_dtls(const SSL *ssl) { return ssl->method->is_dtls; }
void SSL_CTX_set_select_certificate_cb( void SSL_CTX_set_select_certificate_cb(
SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) { SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
@ -2833,7 +2835,7 @@ static uint64_t be_to_u64(const uint8_t in[8]) {
uint64_t SSL_get_read_sequence(const SSL *ssl) { uint64_t SSL_get_read_sequence(const SSL *ssl) {
/* TODO(davidben): Internally represent sequence numbers as uint64_t. */ /* TODO(davidben): Internally represent sequence numbers as uint64_t. */
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
/* max_seq_num already includes the epoch. */ /* max_seq_num already includes the epoch. */
assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48)); assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48));
return ssl->d1->bitmap.max_seq_num; return ssl->d1->bitmap.max_seq_num;
@ -2843,7 +2845,7 @@ uint64_t SSL_get_read_sequence(const SSL *ssl) {
uint64_t SSL_get_write_sequence(const SSL *ssl) { uint64_t SSL_get_write_sequence(const SSL *ssl) {
uint64_t ret = be_to_u64(ssl->s3->write_sequence); uint64_t ret = be_to_u64(ssl->s3->write_sequence);
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
assert((ret >> 48) == 0); assert((ret >> 48) == 0);
ret |= ((uint64_t)ssl->d1->w_epoch) << 48; ret |= ((uint64_t)ssl->d1->w_epoch) << 48;
} }
@ -2938,7 +2940,7 @@ int SSL_clear(SSL *ssl) {
return 0; return 0;
} }
if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { if (SSL_is_dtls(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
ssl->d1->mtu = mtu; ssl->d1->mtu = mtu;
} }

View File

@ -225,7 +225,7 @@ int ssl_early_callback_init(SSL *ssl, struct ssl_early_callback_ctx *ctx,
ctx->session_id_len = CBS_len(&session_id); ctx->session_id_len = CBS_len(&session_id);
/* Skip past DTLS cookie */ /* Skip past DTLS cookie */
if (SSL_IS_DTLS(ctx->ssl)) { if (SSL_is_dtls(ctx->ssl)) {
CBS cookie; CBS cookie;
if (!CBS_get_u8_length_prefixed(&client_hello, &cookie)) { if (!CBS_get_u8_length_prefixed(&client_hello, &cookie)) {
@ -1279,7 +1279,7 @@ static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
if (ssl->s3->initial_handshake_complete || if (ssl->s3->initial_handshake_complete ||
ssl->ctx->next_proto_select_cb == NULL || ssl->ctx->next_proto_select_cb == NULL ||
(ssl->options & SSL_OP_DISABLE_NPN) || (ssl->options & SSL_OP_DISABLE_NPN) ||
SSL_IS_DTLS(ssl)) { SSL_is_dtls(ssl)) {
return 1; return 1;
} }
@ -1305,7 +1305,7 @@ static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
* extension in the ClientHello and thus this function should never have been * extension in the ClientHello and thus this function should never have been
* called. */ * called. */
assert(!ssl->s3->initial_handshake_complete); assert(!ssl->s3->initial_handshake_complete);
assert(!SSL_IS_DTLS(ssl)); assert(!SSL_is_dtls(ssl));
assert(ssl->ctx->next_proto_select_cb != NULL); assert(ssl->ctx->next_proto_select_cb != NULL);
assert(!(ssl->options & SSL_OP_DISABLE_NPN)); assert(!(ssl->options & SSL_OP_DISABLE_NPN));
@ -1366,7 +1366,7 @@ static int ext_npn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
* |next_proto_neg_seen|. */ * |next_proto_neg_seen|. */
ssl->s3->alpn_selected != NULL || ssl->s3->alpn_selected != NULL ||
ssl->ctx->next_protos_advertised_cb == NULL || ssl->ctx->next_protos_advertised_cb == NULL ||
SSL_IS_DTLS(ssl)) { SSL_is_dtls(ssl)) {
return 1; return 1;
} }
@ -1615,7 +1615,7 @@ static void ext_channel_id_init(SSL *ssl) {
static int ext_channel_id_add_clienthello(SSL *ssl, CBB *out) { static int ext_channel_id_add_clienthello(SSL *ssl, CBB *out) {
if (!ssl->tlsext_channel_id_enabled || if (!ssl->tlsext_channel_id_enabled ||
SSL_IS_DTLS(ssl)) { SSL_is_dtls(ssl)) {
return 1; return 1;
} }
@ -1637,7 +1637,7 @@ static int ext_channel_id_parse_serverhello(SSL *ssl, uint8_t *out_alert,
return 0; return 0;
} }
assert(!SSL_IS_DTLS(ssl)); assert(!SSL_is_dtls(ssl));
assert(ssl->tlsext_channel_id_enabled); assert(ssl->tlsext_channel_id_enabled);
if (CBS_len(contents) != 0) { if (CBS_len(contents) != 0) {
@ -1652,7 +1652,7 @@ static int ext_channel_id_parse_clienthello(SSL *ssl, uint8_t *out_alert,
CBS *contents) { CBS *contents) {
if (contents == NULL || if (contents == NULL ||
!ssl->tlsext_channel_id_enabled || !ssl->tlsext_channel_id_enabled ||
SSL_IS_DTLS(ssl)) { SSL_is_dtls(ssl)) {
return 1; return 1;
} }
@ -1840,7 +1840,7 @@ static int ext_srtp_add_serverhello(SSL *ssl, CBB *out) {
* https://tools.ietf.org/html/rfc4492#section-5.1.2 */ * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
static int ssl_any_ec_cipher_suites_enabled(const SSL *ssl) { static int ssl_any_ec_cipher_suites_enabled(const SSL *ssl) {
if (ssl->version < TLS1_VERSION && !SSL_IS_DTLS(ssl)) { if (ssl->version < TLS1_VERSION && !SSL_is_dtls(ssl)) {
return 0; return 0;
} }
@ -2424,7 +2424,7 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
goto err; goto err;
} }
if (!SSL_IS_DTLS(ssl)) { if (!SSL_is_dtls(ssl)) {
header_len += 2 + CBB_len(&extensions); header_len += 2 + CBB_len(&extensions);
if (header_len > 0xff && header_len < 0x200) { if (header_len > 0xff && header_len < 0x200) {
/* Add padding to workaround bugs in F5 terminators. See RFC 7685. /* Add padding to workaround bugs in F5 terminators. See RFC 7685.

View File

@ -151,7 +151,7 @@ int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
} }
size_t ssl_record_prefix_len(const SSL *ssl) { size_t ssl_record_prefix_len(const SSL *ssl) {
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
return DTLS1_RT_HEADER_LENGTH + return DTLS1_RT_HEADER_LENGTH +
SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx); SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx);
} else { } else {
@ -161,7 +161,7 @@ size_t ssl_record_prefix_len(const SSL *ssl) {
} }
size_t ssl_seal_align_prefix_len(const SSL *ssl) { size_t ssl_seal_align_prefix_len(const SSL *ssl) {
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
return DTLS1_RT_HEADER_LENGTH + return DTLS1_RT_HEADER_LENGTH +
SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx); SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
} else { } else {
@ -177,7 +177,7 @@ size_t ssl_seal_align_prefix_len(const SSL *ssl) {
size_t ssl_max_seal_overhead(const SSL *ssl) { size_t ssl_max_seal_overhead(const SSL *ssl) {
size_t ret = SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx); size_t ret = SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
if (SSL_IS_DTLS(ssl)) { if (SSL_is_dtls(ssl)) {
ret += DTLS1_RT_HEADER_LENGTH; ret += DTLS1_RT_HEADER_LENGTH;
} else { } else {
ret += SSL3_RT_HEADER_LENGTH; ret += SSL3_RT_HEADER_LENGTH;
@ -187,7 +187,7 @@ size_t ssl_max_seal_overhead(const SSL *ssl) {
ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
ret += 1; ret += 1;
} }
if (!SSL_IS_DTLS(ssl) && ssl_needs_record_splitting(ssl)) { if (!SSL_is_dtls(ssl) && ssl_needs_record_splitting(ssl)) {
ret *= 2; ret *= 2;
} }
return ret; return ret;