summaryrefslogtreecommitdiffstats
path: root/ssl/statem/extensions_clnt.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-08-16 12:50:32 +0100
committerMatt Caswell <matt@openssl.org>2017-08-31 15:03:35 +0100
commit4be3a7c7aa8bc93ba68253638030d2e5a92bc946 (patch)
tree90658f181026727bf396de9fda5e5874ee7b4817 /ssl/statem/extensions_clnt.c
parentfff202e5f7312f60285a61592301189d35b8450e (diff)
Client side sanity check of ALPN after server has accepted early_data
Reviewed-by: Ben Kaduk <kaduk@mit.edu> (Merged from https://github.com/openssl/openssl/pull/3926)
Diffstat (limited to 'ssl/statem/extensions_clnt.c')
-rw-r--r--ssl/statem/extensions_clnt.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index cb7b211f7c..bcbcbac873 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -771,6 +771,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
* extension, we set it to accepted.
*/
s->ext.early_data = SSL_EARLY_DATA_REJECTED;
+ s->ext.early_data_ok = 1;
return EXT_RETURN_SENT;
}
@@ -1400,15 +1401,22 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
}
s->s3->alpn_selected_len = len;
- /* We also put a copy in the session */
- OPENSSL_free(s->session->ext.alpn_selected);
- s->session->ext.alpn_selected = OPENSSL_memdup(s->s3->alpn_selected,
- s->s3->alpn_selected_len);
- s->session->ext.alpn_selected_len = s->s3->alpn_selected_len;
-
- if (s->session->ext.alpn_selected == NULL) {
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
+ if (s->session->ext.alpn_selected != NULL
+ && (s->session->ext.alpn_selected_len != len
+ || memcmp(s->session->ext.alpn_selected, s->s3->alpn_selected,
+ len) != 0)) {
+ /* ALPN not consistent with the old session so cannot use early_data */
+ s->ext.early_data_ok = 0;
+ }
+ if (!s->hit) {
+ /* If a new session then update it with the selected ALPN */
+ s->session->ext.alpn_selected =
+ OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len);
+ if (s->session->ext.alpn_selected == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->session->ext.alpn_selected_len = s->s3->alpn_selected_len;
}
return 1;
@@ -1637,12 +1645,13 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context,
return 0;
}
- if (s->ext.early_data != SSL_EARLY_DATA_REJECTED
+ if (!s->ext.early_data_ok
|| !s->hit
|| s->session->ext.tick_identity != 0) {
/*
* If we get here then we didn't send early data, or we didn't resume
- * using the first identity so the server should not be accepting it.
+ * using the first identity, or the SNI/ALPN is not consistent so the
+ * server should not be accepting it.
*/
*al = SSL_AD_ILLEGAL_PARAMETER;
return 0;