summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/openssl/ssl.h2
-rw-r--r--include/openssl/tls1.h1
-rw-r--r--ssl/ssl_err.c2
-rw-r--r--ssl/ssl_lib.c1
-rw-r--r--ssl/ssl_locl.h5
-rw-r--r--ssl/statem/extensions.c7
-rw-r--r--ssl/statem/extensions_clnt.c43
-rw-r--r--ssl/statem/statem_locl.h4
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);