From 3fc8d856105e4716d3121348996ea3c61e7e4b7d Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 17 Feb 2017 16:52:12 +0000 Subject: [PATCH] Construct the ticket_early_data_info extension Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2737) --- include/openssl/ssl.h | 6 ++++++ include/openssl/tls1.h | 1 + ssl/ssl_err.c | 2 ++ ssl/ssl_lib.c | 25 +++++++++++++++++++++++++ ssl/ssl_locl.h | 7 +++++++ ssl/statem/extensions.c | 5 +++++ ssl/statem/extensions_srvr.c | 18 ++++++++++++++++++ ssl/statem/statem_locl.h | 3 +++ util/libssl.num | 4 ++++ 9 files changed, 71 insertions(+) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 9e87c6b823..a4dc2c97ab 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -797,6 +797,11 @@ void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb); */ SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx); +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data); +uint32_t SSL_CTX_get_max_early_data(SSL_CTX *ctx); +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data); +uint32_t SSL_get_max_early_data(SSL_CTX *s); + #ifdef __cplusplus } #endif @@ -2355,6 +2360,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE 374 # define SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG 452 # define SSL_F_TLS_CONSTRUCT_STOC_DONE 375 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO 525 # define SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS 453 # define SSL_F_TLS_CONSTRUCT_STOC_EMS 454 # define SSL_F_TLS_CONSTRUCT_STOC_ETM 455 diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 6902f5010c..4fb5a560ad 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -180,6 +180,7 @@ extern "C" { # define TLSEXT_TYPE_psk 41 # define TLSEXT_TYPE_supported_versions 43 # define TLSEXT_TYPE_psk_kex_modes 45 +# define TLSEXT_TYPE_early_data_info 46 /* Temporary extension type */ # define TLSEXT_TYPE_renegotiate 0xff01 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 70764b370b..788417ecdf 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -357,6 +357,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG), "tls_construct_stoc_cryptopro_bug"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_DONE), "TLS_CONSTRUCT_STOC_DONE"}, + {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO), + "tls_construct_stoc_early_data_info"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS), "tls_construct_stoc_ec_pt_formats"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_EMS), "tls_construct_stoc_ems"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 39254f16f9..d3dddafad7 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -551,6 +551,7 @@ SSL *SSL_new(SSL_CTX *ctx) s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; s->references = 1; + s->max_early_data = ctx->max_early_data; /* * Earlier library versions used to copy the pointer to the CERT, not @@ -4657,3 +4658,27 @@ int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, sk_SSL_CIPHER_free(scsvs); return 0; } + +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data) +{ + ctx->max_early_data = max_early_data; + + return 1; +} + +uint32_t SSL_CTX_get_max_early_data(SSL_CTX *ctx) +{ + return ctx->max_early_data; +} + +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data) +{ + s->max_early_data = max_early_data; + + return 1; +} + +uint32_t SSL_get_max_early_data(SSL_CTX *s) +{ + return s->max_early_data; +} diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index c253c992b0..f8350afda2 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -922,6 +922,9 @@ struct ssl_ctx_st { * Wireshark. The callback should log `line` followed by a newline. */ SSL_CTX_keylog_cb_func keylog_callback; + + /* The maximum number of bytes that can be sent as early data */ + uint32_t max_early_data; }; struct ssl_st { @@ -1218,6 +1221,9 @@ struct ssl_st { ASYNC_WAIT_CTX *waitctx; size_t asyncrw; + /* The maximum number of bytes that can be sent as early data */ + uint32_t max_early_data; + CRYPTO_RWLOCK *lock; }; @@ -1724,6 +1730,7 @@ typedef enum tlsext_index_en { TLSEXT_IDX_renegotiate, TLSEXT_IDX_server_name, TLSEXT_IDX_srp, + TLSEXT_IDX_early_data_info, TLSEXT_IDX_ec_point_formats, TLSEXT_IDX_supported_groups, TLSEXT_IDX_session_ticket, diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index c0114457cb..19795b1595 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -129,6 +129,11 @@ static const EXTENSION_DEFINITION ext_defs[] = { #else INVALID_EXTENSION, #endif + { + TLSEXT_TYPE_early_data_info, + EXT_TLS1_3_NEW_SESSION_TICKET, + NULL, NULL, NULL, tls_construct_stoc_early_data_info, NULL, NULL + }, #ifndef OPENSSL_NO_EC { TLSEXT_TYPE_ec_point_formats, diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index ecfd00b098..690cc30cf3 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -801,6 +801,24 @@ int tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, unsigned int context, return 1; } +int tls_construct_stoc_early_data_info(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + if (s->max_early_data == 0) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data_info) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u32(pkt, s->max_early_data) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + #ifndef OPENSSL_NO_EC int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *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 9230332bf4..41ebbbcbc5 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -230,6 +230,9 @@ int tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); int tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); +int tls_construct_stoc_early_data_info(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #ifndef OPENSSL_NO_EC int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); diff --git a/util/libssl.num b/util/libssl.num index 20642ce758..d3f7a4f596 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -424,3 +424,7 @@ SSL_early_get0_random 424 1_1_1 EXIST::FUNCTION: SSL_CTX_set_early_cb 425 1_1_1 EXIST::FUNCTION: SSL_early_get0_legacy_version 426 1_1_1 EXIST::FUNCTION: SSL_early_isv2 427 1_1_1 EXIST::FUNCTION: +SSL_set_max_early_data 428 1_1_1 EXIST::FUNCTION: +SSL_CTX_set_max_early_data 429 1_1_1 EXIST::FUNCTION: +SSL_get_max_early_data 430 1_1_1 EXIST::FUNCTION: +SSL_CTX_get_max_early_data 431 1_1_1 EXIST::FUNCTION: -- 2.25.1