Disable NPN and Channel ID in DTLS.
They're not in the duplicated handshake state machines anyway. But we still
shouldn't negotiate them. d1_pkt.c assumes Finished is the only post-CCS
handshake message. An unexpected handshake message in the current epoch may
either be a retransmit/out-of-order message from the previous handshake, or a
message from the next handshake (also potentially out-of-order). In the former
case, we shouldn't spin up another handshake state machine instance.
(This assumption is required due to a protocol bug. DTLS resets sequence
numbers after a handshake, so it is necessary to categorize handshake fragments
by pre-CCS and post-CCS to distinguish between retransmit and renego.)
Change-Id: Ib3c1c7085c729e36a40f7ff14494733156924a24
Reviewed-on: https://boringssl-review.googlesource.com/3028
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d2d2bc3..64e8ea0 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -945,7 +945,8 @@
s2n(0, ret);
}
- if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
+ if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len &&
+ !SSL_IS_DTLS(s)) {
/* The client advertises an emtpy extension to indicate its support for
* Next Protocol Negotiation */
if (limit - ret - 4 < 0) {
@@ -976,7 +977,7 @@
ret += s->alpn_client_proto_list_len;
}
- if (s->tlsext_channel_id_enabled) {
+ if (s->tlsext_channel_id_enabled && !SSL_IS_DTLS(s)) {
/* The client advertises an emtpy extension to indicate its support for
* Channel ID. */
if (limit - ret - 4 < 0) {
@@ -1591,7 +1592,8 @@
return 0;
}
} else if (type == TLSEXT_TYPE_next_proto_neg &&
- s->s3->tmp.finish_md_len == 0 && s->s3->alpn_selected == NULL) {
+ s->s3->tmp.finish_md_len == 0 && s->s3->alpn_selected == NULL &&
+ !SSL_IS_DTLS(s)) {
/* The extension must be empty. */
if (CBS_len(&extension) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
@@ -1618,7 +1620,8 @@
}
/* ALPN takes precedence over NPN. */
s->s3->next_proto_neg_seen = 0;
- } else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled) {
+ } else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled &&
+ !SSL_IS_DTLS(s)) {
/* The extension must be empty. */
if (CBS_len(&extension) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
@@ -1627,7 +1630,7 @@
s->s3->tlsext_channel_id_valid = 1;
} else if (type == TLSEXT_TYPE_channel_id_new &&
- s->tlsext_channel_id_enabled) {
+ s->tlsext_channel_id_enabled && !SSL_IS_DTLS(s)) {
/* The extension must be empty. */
if (CBS_len(&extension) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
@@ -1802,7 +1805,8 @@
/* Set a flag to expect a CertificateStatus message */
s->s3->tmp.certificate_status_expected = 1;
} else if (type == TLSEXT_TYPE_next_proto_neg &&
- s->s3->tmp.finish_md_len == 0) {
+ s->s3->tmp.finish_md_len == 0 &&
+ !SSL_IS_DTLS(s)) {
uint8_t *selected;
uint8_t selected_len;
@@ -1858,14 +1862,14 @@
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- } else if (type == TLSEXT_TYPE_channel_id) {
+ } else if (type == TLSEXT_TYPE_channel_id && !SSL_IS_DTLS(s)) {
if (CBS_len(&extension) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
s->s3->tlsext_channel_id_valid = 1;
- } else if (type == TLSEXT_TYPE_channel_id_new) {
+ } else if (type == TLSEXT_TYPE_channel_id_new && !SSL_IS_DTLS(s)) {
if (CBS_len(&extension) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;