diff options
-rw-r--r-- | include/openssl/ssl.h | 2 | ||||
-rw-r--r-- | include/openssl/tls1.h | 1 | ||||
-rw-r--r-- | ssl/ssl_err.c | 2 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 1 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 5 | ||||
-rw-r--r-- | ssl/statem/extensions.c | 7 | ||||
-rw-r--r-- | ssl/statem/extensions_clnt.c | 43 | ||||
-rw-r--r-- | ssl/statem/statem_locl.h | 4 |
8 files changed, 65 insertions, 0 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 64a312c588..c569407701 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2348,6 +2348,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 489 # define SSL_F_TLS_CONSTRUCT_CTOS_ALPN 466 # define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE 355 +# define SSL_F_TLS_CONSTRUCT_CTOS_COOKIE 535 # define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 530 # define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS 467 # define SSL_F_TLS_CONSTRUCT_CTOS_EMS 468 @@ -2408,6 +2409,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_COOKIE 534 # define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 528 # define SSL_F_TLS_PARSE_STOC_KEY_SHARE 445 # define SSL_F_TLS_PARSE_STOC_PSK 502 diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 10544872b3..280d131c6f 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -181,6 +181,7 @@ extern "C" { # define TLSEXT_TYPE_psk 41 # define TLSEXT_TYPE_early_data 42 # define TLSEXT_TYPE_supported_versions 43 +# define TLSEXT_TYPE_cookie 44 # define TLSEXT_TYPE_psk_kex_modes 45 # define TLSEXT_TYPE_early_data_info 46 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 0ace985cf2..ee1ca6293c 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -304,6 +304,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_ALPN), "tls_construct_ctos_alpn"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE), "TLS_CONSTRUCT_CTOS_CERTIFICATE"}, + {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_COOKIE), "tls_construct_ctos_cookie"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA), "tls_construct_ctos_early_data"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS), @@ -401,6 +402,7 @@ 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_COOKIE), "tls_parse_stoc_cookie"}, {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"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index fcf4f4d347..f0e8639d61 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1017,6 +1017,7 @@ void SSL_free(SSL *s) #endif OPENSSL_free(s->ext.ocsp.resp); OPENSSL_free(s->ext.alpn); + OPENSSL_free(s->ext.tls13_cookie); OPENSSL_free(s->clienthello); sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 6811b4f3f4..f4860ea1fd 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1211,6 +1211,10 @@ struct ssl_st { int early_data; /* Is the session suitable for early data? */ int early_data_ok; + + /* May be sent by a server in HRR. Must be echoed back in ClientHello */ + unsigned char *tls13_cookie; + size_t tls13_cookie_len; } ext; /* Parsed form of the ClientHello, kept around across early_cb calls. */ @@ -1801,6 +1805,7 @@ typedef enum tlsext_index_en { TLSEXT_IDX_supported_versions, TLSEXT_IDX_psk_kex_modes, TLSEXT_IDX_key_share, + TLSEXT_IDX_cookie, TLSEXT_IDX_cryptopro_bug, TLSEXT_IDX_early_data, TLSEXT_IDX_padding, diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index edcfe718c4..8c4013e416 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -270,6 +270,13 @@ static const EXTENSION_DEFINITION ext_defs[] = { }, #endif { + TLSEXT_TYPE_cookie, + EXT_CLIENT_HELLO | EXT_TLS1_3_HELLO_RETRY_REQUEST + | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY, + NULL, NULL, tls_parse_stoc_cookie, NULL, tls_construct_ctos_cookie, + NULL + }, + { /* * Special unsolicited ServerHello extension only used when * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 0af4d1b588..23dc8d3363 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -636,6 +636,33 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context, return 1; } +int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) +{ + int ret = 0; + + /* Should only be set if we've had an HRR */ + if (s->ext.tls13_cookie_len == 0) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie) + /* Extension data sub-packet */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u16(pkt, s->ext.tls13_cookie, + s->ext.tls13_cookie_len) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_COOKIE, ERR_R_INTERNAL_ERROR); + goto end; + } + + ret = 1; + end: + OPENSSL_free(s->ext.tls13_cookie); + s->ext.tls13_cookie_len = 0; + + return ret; +} + int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { @@ -1338,6 +1365,22 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } +int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + PACKET cookie; + + if (!PACKET_as_length_prefixed_2(pkt, &cookie) + || !PACKET_memdup(&cookie, &s->ext.tls13_cookie, + &s->ext.tls13_cookie_len)) { + *al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PARSE_STOC_COOKIE, SSL_R_LENGTH_MISMATCH); + return 0; + } + + return 1; +} + int tls_parse_stoc_early_data(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 c52ce2bd16..68160c9bc7 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -332,6 +332,8 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); int tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); +int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, @@ -374,5 +376,7 @@ int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); +int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + size_t chainidx, int *al); int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); |