From 5d5b3fba1fc15e3a63876aa9c8deae351369781b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 20 Feb 2017 14:56:51 +0000 Subject: [PATCH] Parse the ticket_early_data_info extension Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2737) --- include/openssl/ssl.h | 2 ++ ssl/ssl_asn1.c | 6 +++++- ssl/ssl_err.c | 3 +++ ssl/ssl_locl.h | 2 ++ ssl/statem/extensions.c | 3 ++- ssl/statem/extensions_clnt.c | 18 ++++++++++++++++++ ssl/statem/statem_locl.h | 2 ++ 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index a4dc2c97ab..7f84e0a265 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2382,6 +2382,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_PARSE_CTOS_PSK 505 # define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 464 # define SSL_F_TLS_PARSE_CTOS_USE_SRTP 465 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 520 # define SSL_F_TLS_PARSE_STOC_KEY_SHARE 445 # define SSL_F_TLS_PARSE_STOC_PSK 502 # define SSL_F_TLS_PARSE_STOC_RENEGOTIATE 448 @@ -2525,6 +2526,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_INVALID_CONFIGURATION_NAME 113 # define SSL_R_INVALID_CT_VALIDATION_TYPE 212 # define SSL_R_INVALID_KEY_UPDATE_TYPE 120 +# define SSL_R_INVALID_MAX_EARLY_DATA 174 # define SSL_R_INVALID_NULL_CMD_NAME 385 # define SSL_R_INVALID_SEQUENCE_NUMBER 402 # define SSL_R_INVALID_SERVERINFO_DATA 388 diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 8141471915..705db16470 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -65,6 +65,7 @@ typedef struct { ASN1_OCTET_STRING *srp_username; #endif long flags; + uint32_t max_early_data; } SSL_SESSION_ASN1; ASN1_SEQUENCE(SSL_SESSION_ASN1) = { @@ -91,7 +92,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = { ASN1_EXP_OPT(SSL_SESSION_ASN1, srp_username, ASN1_OCTET_STRING, 12), #endif ASN1_EXP_OPT(SSL_SESSION_ASN1, flags, ZLONG, 13), - ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_age_add, ZLONG, 14) + ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_age_add, ZLONG, 14), + ASN1_EXP_OPT(SSL_SESSION_ASN1, max_early_data, ZLONG, 15) } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) @@ -203,6 +205,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) #endif /* OPENSSL_NO_SRP */ as.flags = in->flags; + as.max_early_data = in->ext.max_early_data; return i2d_SSL_SESSION_ASN1(&as, pp); @@ -357,6 +360,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, #endif /* OPENSSL_NO_SRP */ /* Flags defaults to zero which is fine */ ret->flags = as->flags; + ret->ext.max_early_data = as->max_early_data; M_ASN1_free_of(as, SSL_SESSION_ASN1); diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 788417ecdf..69d9adc9d7 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -392,6 +392,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_TLS_PARSE_CTOS_RENEGOTIATE), "tls_parse_ctos_renegotiate"}, {ERR_FUNC(SSL_F_TLS_PARSE_CTOS_USE_SRTP), "tls_parse_ctos_use_srtp"}, + {ERR_FUNC(SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO), + "tls_parse_stoc_early_data_info"}, {ERR_FUNC(SSL_F_TLS_PARSE_STOC_KEY_SHARE), "tls_parse_stoc_key_share"}, {ERR_FUNC(SSL_F_TLS_PARSE_STOC_PSK), "tls_parse_stoc_psk"}, {ERR_FUNC(SSL_F_TLS_PARSE_STOC_RENEGOTIATE), @@ -587,6 +589,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = { {ERR_REASON(SSL_R_INVALID_CT_VALIDATION_TYPE), "invalid ct validation type"}, {ERR_REASON(SSL_R_INVALID_KEY_UPDATE_TYPE), "invalid key update type"}, + {ERR_REASON(SSL_R_INVALID_MAX_EARLY_DATA), "invalid max early data"}, {ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"}, {ERR_REASON(SSL_R_INVALID_SEQUENCE_NUMBER), "invalid sequence number"}, {ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index f8350afda2..a7fa0b52c2 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -575,6 +575,8 @@ struct ssl_session_st { unsigned long tick_lifetime_hint; uint32_t tick_age_add; int tick_identity; + /* Max number of bytes that can be sent as early data */ + uint32_t max_early_data; } ext; # ifndef OPENSSL_NO_SRP char *srp_username; diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 19795b1595..05e6acf340 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -132,7 +132,8 @@ static const EXTENSION_DEFINITION ext_defs[] = { { TLSEXT_TYPE_early_data_info, EXT_TLS1_3_NEW_SESSION_TICKET, - NULL, NULL, NULL, tls_construct_stoc_early_data_info, NULL, NULL + NULL, NULL, tls_parse_stoc_early_data_info, + tls_construct_stoc_early_data_info, NULL, NULL }, #ifndef OPENSSL_NO_EC { diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 09780a9495..7ef4c716cc 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -879,6 +879,24 @@ int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, return 1; } +int tls_parse_stoc_early_data_info(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) +{ + unsigned long max_early_data; + + if (!PACKET_get_net_4(pkt, &max_early_data) + || PACKET_remaining(pkt) != 0) { + SSLerr(SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO, + SSL_R_INVALID_MAX_EARLY_DATA); + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + s->session->ext.max_early_data = max_early_data; + + return 1; +} + #ifndef OPENSSL_NO_EC int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index 41ebbbcbc5..0274dcbcbe 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -331,6 +331,8 @@ int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); +int tls_parse_stoc_early_data_info(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #ifndef OPENSSL_NO_EC int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); -- 2.25.1