Add basic TLSv1.3 cookie support

We do not allow the generation of TLSv1.3 cookies. But if we receive one
in an HRR we will echo it back in the ClientHello.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2839)
This commit is contained in:
Matt Caswell 2017-03-02 17:37:03 +00:00
parent 6356716ac0
commit cfef5027bf
8 changed files with 65 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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"},

View file

@ -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);

View file

@ -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,

View file

@ -269,6 +269,13 @@ static const EXTENSION_DEFINITION ext_defs[] = {
final_key_share
},
#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

View file

@ -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)
{

View file

@ -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);