summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-07-21 11:41:05 +0100
committerMatt Caswell <matt@openssl.org>2017-08-31 15:03:34 +0100
commitffc5bbaaee2bfaba8d420e912c4d77b4090b896f (patch)
tree9dd6c92e4c0e5a009b21e58d8a8b342aad53e55c /ssl
parent67738645dc0b044fc7d120a3c67af5635d0d78ec (diff)
Complain if we are writing early data but SNI or ALPN is incorrect
SNI and ALPN must be set to be consistent with the PSK. Otherwise this is an error. Reviewed-by: Ben Kaduk <kaduk@mit.edu> (Merged from https://github.com/openssl/openssl/pull/3926)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_err.c4
-rw-r--r--ssl/statem/extensions_clnt.c52
2 files changed, 52 insertions, 4 deletions
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index dc1d439b1b..0ce7f271f3 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -724,6 +724,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"inappropriate fallback"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_COMPRESSION),
"inconsistent compression"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EARLY_DATA_ALPN),
+ "inconsistent early data alpn"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EARLY_DATA_SNI),
+ "inconsistent early data sni"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_ALERT), "invalid alert"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMMAND), "invalid command"},
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 86a1cab9ae..3a198f421c 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -682,13 +682,17 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
const unsigned char *id;
size_t idlen;
SSL_SESSION *psksess = NULL;
+ SSL_SESSION *edsess = NULL;
const EVP_MD *handmd = NULL;
if (s->hello_retry_request)
handmd = ssl_handshake_md(s);
if (s->psk_use_session_cb != NULL
- && !s->psk_use_session_cb(s, handmd, &id, &idlen, &psksess)) {
+ && (!s->psk_use_session_cb(s, handmd, &id, &idlen, &psksess)
+ || (psksess != NULL
+ && psksess->ssl_version != TLS1_3_VERSION))) {
+ SSL_SESSION_free(psksess);
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, SSL_R_BAD_PSK);
return EXT_RETURN_FAIL;
}
@@ -711,9 +715,49 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
s->max_early_data = 0;
return EXT_RETURN_NOT_SENT;
}
- s->max_early_data = s->session->ext.max_early_data != 0 ?
- s->session->ext.max_early_data
- : psksess->ext.max_early_data;
+ edsess = s->session->ext.max_early_data != 0 ? s->session : psksess;
+ s->max_early_data = edsess->ext.max_early_data;
+
+ if ((s->ext.hostname == NULL && edsess->ext.hostname != NULL)
+ || (s->ext.hostname != NULL
+ && (edsess->ext.hostname == NULL
+ || strcmp(s->ext.hostname, edsess->ext.hostname) != 0))) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
+ SSL_R_INCONSISTENT_EARLY_DATA_SNI);
+ return EXT_RETURN_FAIL;
+ }
+
+ if ((s->ext.alpn == NULL && edsess->ext.alpn_selected != NULL)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
+ SSL_R_INCONSISTENT_EARLY_DATA_ALPN);
+ return EXT_RETURN_FAIL;
+ }
+
+ /*
+ * Verify that we are offering an ALPN protocol consistent with the early
+ * data.
+ */
+ if (edsess->ext.alpn_selected != NULL) {
+ PACKET prots, alpnpkt;
+ int found = 0;
+
+ if (!PACKET_buf_init(&prots, s->ext.alpn, s->ext.alpn_len)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR);
+ return EXT_RETURN_FAIL;
+ }
+ while (PACKET_get_length_prefixed_1(&prots, &alpnpkt)) {
+ if (PACKET_equal(&alpnpkt, edsess->ext.alpn_selected,
+ edsess->ext.alpn_selected_len)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
+ SSL_R_INCONSISTENT_EARLY_DATA_ALPN);
+ return EXT_RETURN_FAIL;
+ }
+ }
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data)
|| !WPACKET_start_sub_packet_u16(pkt)