From 6cc0b3c2171e26379e898574cb6d42b8d8dcc113 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 13 Jun 2018 15:57:39 +0100 Subject: [PATCH] Respect SSL_OP_NO_TICKET in TLSv1.3 Implement support for stateful TLSv1.3 tickets, and use them if SSL_OP_NO_TICKET is set. Reviewed-by: Rich Salz Reviewed-by: Viktor Dukhovni (Merged from https://github.com/openssl/openssl/pull/6563) --- crypto/err/openssl.txt | 3 + include/openssl/sslerr.h | 4 +- ssl/ssl_err.c | 4 + ssl/ssl_lib.c | 9 +- ssl/ssl_locl.h | 2 + ssl/ssl_sess.c | 134 +++++++++++++------------ ssl/statem/extensions_srvr.c | 36 ++++++- ssl/statem/statem_srvr.c | 67 +++++++++---- test/handshake_helper.c | 26 ++++- test/ssl-tests/10-resumption.conf | 32 ++++++ test/ssl-tests/11-dtls_resumption.conf | 8 ++ test/ssl-tests/protocol_version.pm | 1 + test/sslapitest.c | 3 +- 13 files changed, 232 insertions(+), 97 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index e0580a871d..e65a80670d 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1089,7 +1089,10 @@ SSL_F_CHECK_SUITEB_CIPHER_LIST:331:check_suiteb_cipher_list SSL_F_CIPHERSUITE_CB:622:ciphersuite_cb SSL_F_CONSTRUCT_CA_NAMES:552:construct_ca_names SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS:553:construct_key_exchange_tbs +SSL_F_CONSTRUCT_STATEFUL_TICKET:636:construct_stateful_ticket +SSL_F_CONSTRUCT_STATELESS_TICKET:637:construct_stateless_ticket SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH:539:create_synthetic_message_hash +SSL_F_CREATE_TICKET_PREQUEL:638:create_ticket_prequel SSL_F_CT_MOVE_SCTS:345:ct_move_scts SSL_F_CT_STRICT:349:ct_strict SSL_F_CUSTOM_EXT_ADD:554:custom_ext_add diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index d7d58e5eef..b2c6c1ee37 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -26,8 +26,10 @@ int ERR_load_SSL_strings(void); # define SSL_F_CIPHERSUITE_CB 622 # define SSL_F_CONSTRUCT_CA_NAMES 552 # define SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS 553 +# define SSL_F_CONSTRUCT_STATEFUL_TICKET 636 +# define SSL_F_CONSTRUCT_STATELESS_TICKET 637 # define SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH 539 -# define SSL_F_CREATE_TICKET_PREQUEL 636 +# define SSL_F_CREATE_TICKET_PREQUEL 638 # define SSL_F_CT_MOVE_SCTS 345 # define SSL_F_CT_STRICT 349 # define SSL_F_CUSTOM_EXT_ADD 554 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 6f6430e337..03c5bf255e 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -24,6 +24,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = { {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_CA_NAMES, 0), "construct_ca_names"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS, 0), "construct_key_exchange_tbs"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_STATEFUL_TICKET, 0), + "construct_stateful_ticket"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_STATELESS_TICKET, 0), + "construct_stateless_ticket"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH, 0), "create_synthetic_message_hash"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_CREATE_TICKET_PREQUEL, 0), diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 22f729c284..6ced147ab8 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -3369,18 +3369,21 @@ void ssl_update_cache(SSL *s, int mode) && (!s->hit || SSL_IS_TLS13(s))) { /* * Add the session to the internal cache. In server side TLSv1.3 we - * normally don't do this because its a full stateless ticket with only - * a dummy session id so there is no reason to cache it, unless: + * normally don't do this because by default it's a full stateless ticket + * with only a dummy session id so there is no reason to cache it, + * unless: * - we are doing early_data, in which case we cache so that we can * detect replays * - the application has set a remove_session_cb so needs to know about * session timeout events + * - SSL_OP_NO_TICKET is set in which case it is a stateful ticket */ if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0 && (!SSL_IS_TLS13(s) || !s->server || s->max_early_data > 0 - || s->session_ctx->remove_session_cb != NULL)) + || s->session_ctx->remove_session_cb != NULL + || (s->options & SSL_OP_NO_TICKET) != 0)) SSL_CTX_add_session(s->session_ctx, s->session); /* diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 86c250b695..a4d1376cc3 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -2212,6 +2212,8 @@ void ssl_cert_clear_certs(CERT *c); void ssl_cert_free(CERT *c); __owur int ssl_generate_session_id(SSL *s, SSL_SESSION *ss); __owur int ssl_get_new_session(SSL *s, int session); +__owur SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, + size_t sess_id_len); __owur int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello); __owur SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index fde4187d9c..628b9f060b 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -12,6 +12,7 @@ #include #include #include "internal/refcount.h" +#include "internal/cryptlib.h" #include "ssl_locl.h" #include "statem/statem_locl.h" @@ -452,6 +453,73 @@ int ssl_get_new_session(SSL *s, int session) return 1; } +SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, + size_t sess_id_len) +{ + SSL_SESSION *ret = NULL; + int discard; + + if ((s->session_ctx->session_cache_mode + & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) { + SSL_SESSION data; + + data.ssl_version = s->version; + if (!ossl_assert(sess_id_len <= SSL_MAX_SSL_SESSION_ID_LENGTH)) + return NULL; + + memcpy(data.session_id, sess_id, sess_id_len); + data.session_id_length = sess_id_len; + + CRYPTO_THREAD_read_lock(s->session_ctx->lock); + ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); + if (ret != NULL) { + /* don't allow other threads to steal it: */ + SSL_SESSION_up_ref(ret); + } + CRYPTO_THREAD_unlock(s->session_ctx->lock); + if (ret == NULL) + CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard, + s->session_ctx->lock); + } + + if (ret == NULL && s->session_ctx->get_session_cb != NULL) { + int copy = 1; + + ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©); + + if (ret != NULL) { + CRYPTO_atomic_add(&s->session_ctx->stats.sess_cb_hit, 1, &discard, + s->session_ctx->lock); + + /* + * Increment reference count now if the session callback asks us + * to do so (note that if the session structures returned by the + * callback are shared between threads, it must handle the + * reference count itself [i.e. copy == 0], or things won't be + * thread-safe). + */ + if (copy) + SSL_SESSION_up_ref(ret); + + /* + * Add the externally cached session to the internal cache as + * well if and only if we are supposed to. + */ + if ((s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0) { + /* + * Either return value of SSL_CTX_add_session should not + * interrupt the session resumption process. The return + * value is intentionally ignored. + */ + (void)SSL_CTX_add_session(s->session_ctx, ret); + } + } + } + + return ret; +} + /*- * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this * connection. It is only called by servers. @@ -504,8 +572,11 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) goto err; case SSL_TICKET_NONE: case SSL_TICKET_EMPTY: - if (hello->session_id_len > 0) + if (hello->session_id_len > 0) { try_session_cache = 1; + ret = lookup_sess_in_cache(s, hello->session_id, + hello->session_id_len); + } break; case SSL_TICKET_NO_DECRYPT: case SSL_TICKET_SUCCESS: @@ -514,67 +585,6 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) } } - if (try_session_cache && - ret == NULL && - !(s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { - SSL_SESSION data; - - data.ssl_version = s->version; - memcpy(data.session_id, hello->session_id, hello->session_id_len); - data.session_id_length = hello->session_id_len; - - CRYPTO_THREAD_read_lock(s->session_ctx->lock); - ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); - if (ret != NULL) { - /* don't allow other threads to steal it: */ - SSL_SESSION_up_ref(ret); - } - CRYPTO_THREAD_unlock(s->session_ctx->lock); - if (ret == NULL) - CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard, - s->session_ctx->lock); - } - - if (try_session_cache && - ret == NULL && s->session_ctx->get_session_cb != NULL) { - int copy = 1; - - ret = s->session_ctx->get_session_cb(s, hello->session_id, - hello->session_id_len, - ©); - - if (ret != NULL) { - CRYPTO_atomic_add(&s->session_ctx->stats.sess_cb_hit, 1, &discard, - s->session_ctx->lock); - - /* - * Increment reference count now if the session callback asks us - * to do so (note that if the session structures returned by the - * callback are shared between threads, it must handle the - * reference count itself [i.e. copy == 0], or things won't be - * thread-safe). - */ - if (copy) - SSL_SESSION_up_ref(ret); - - /* - * Add the externally cached session to the internal cache as - * well if and only if we are supposed to. - */ - if (! - (s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_STORE)) { - /* - * Either return value of SSL_CTX_add_session should not - * interrupt the session resumption process. The return - * value is intentionally ignored. - */ - SSL_CTX_add_session(s->session_ctx, ret); - } - } - } - if (ret == NULL) goto err; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 7c756c03a0..48be0444af 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1009,6 +1009,33 @@ int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, return 1; } +static SSL_TICKET_STATUS tls_get_stateful_ticket(SSL *s, PACKET *tick, + SSL_SESSION **sess) +{ + SSL_SESSION *tmpsess = NULL; + + switch (PACKET_remaining(tick)) { + case 0: + return SSL_TICKET_EMPTY; + + case SSL_MAX_SSL_SESSION_ID_LENGTH: + break; + + default: + return SSL_TICKET_NO_DECRYPT; + } + + tmpsess = lookup_sess_in_cache(s, PACKET_data(tick), + SSL_MAX_SSL_SESSION_ID_LENGTH); + + if (tmpsess == NULL) + return SSL_TICKET_NO_DECRYPT; + + s->ext.ticket_expected = 1; + *sess = tmpsess; + return SSL_TICKET_SUCCESS; +} + int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1132,9 +1159,12 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, uint32_t ticket_age = 0, now, agesec, agems; int ret; - ret = tls_decrypt_ticket(s, PACKET_data(&identity), - PACKET_remaining(&identity), NULL, 0, - &sess); + if ((s->options & SSL_OP_NO_TICKET) != 0) + ret = tls_get_stateful_ticket(s, &identity, &sess); + else + ret = tls_decrypt_ticket(s, PACKET_data(&identity), + PACKET_remaining(&identity), NULL, 0, + &sess); if (ret == SSL_TICKET_EMPTY) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index a4a0ea2438..ab16e632fd 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -3799,29 +3799,29 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, * long */ if (slen_full == 0 || slen_full > 0xFF00) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_INTERNAL_ERROR); goto err; } senc = OPENSSL_malloc(slen_full); if (senc == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_MALLOC_FAILURE); goto err; } ctx = EVP_CIPHER_CTX_new(); hctx = HMAC_CTX_new(); if (ctx == NULL || hctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_MALLOC_FAILURE); goto err; } p = senc; if (!i2d_SSL_SESSION(s->session, &p)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_INTERNAL_ERROR); goto err; } @@ -3831,23 +3831,23 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, const_p = senc; sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); if (sess == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_INTERNAL_ERROR); goto err; } slen = i2d_SSL_SESSION(sess, NULL); if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_INTERNAL_ERROR); SSL_SESSION_free(sess); goto err; } p = senc; if (!i2d_SSL_SESSION(sess, &p)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_INTERNAL_ERROR); SSL_SESSION_free(sess); goto err; } @@ -3868,7 +3868,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, if (!WPACKET_put_bytes_u32(pkt, 0) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, + SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_INTERNAL_ERROR); goto err; } @@ -3878,8 +3878,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, return 1; } if (ret < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, SSL_R_CALLBACK_FAILED); goto err; } @@ -3894,8 +3893,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, || !HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key, sizeof(tctx->ext.secure->tick_hmac_key), EVP_sha256(), NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_INTERNAL_ERROR); goto err; } @@ -3933,14 +3931,14 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, || !WPACKET_allocate_bytes(pkt, hlen, &macdata2) || macdata1 != macdata2) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_INTERNAL_ERROR); goto err; } /* Close the sub-packet created by create_ticket_prequel() */ if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, + ERR_R_INTERNAL_ERROR); goto err; } @@ -3952,6 +3950,25 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, return ok; } +static int construct_stateful_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, + unsigned char *tick_nonce) +{ + if (!create_ticket_prequel(s, pkt, age_add, tick_nonce)) { + /* SSLfatal() already called */ + return 0; + } + + if (!WPACKET_memcpy(pkt, s->session->session_id, + s->session->session_id_length) + || !WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATEFUL_TICKET, + ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) { SSL_CTX *tctx = s->session_ctx; @@ -4065,7 +4082,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) tctx->generate_ticket_cb(s, tctx->ticket_cb_data) == 0) goto err; - if (!construct_stateless_ticket(s, pkt, age_add_u.age_add, tick_nonce)) { + if ((s->options & SSL_OP_NO_TICKET) != 0 && SSL_IS_TLS13(s)) { + if (!construct_stateful_ticket(s, pkt, age_add_u.age_add, tick_nonce)) { + /* SSLfatal() already called */ + goto err; + } + } else if (!construct_stateless_ticket(s, pkt, age_add_u.age_add, + tick_nonce)) { /* SSLfatal() already called */ goto err; } diff --git a/test/handshake_helper.c b/test/handshake_helper.c index 3ebf64dfe3..c40a0e7c92 100644 --- a/test/handshake_helper.c +++ b/test/handshake_helper.c @@ -1396,7 +1396,8 @@ static int create_sctp_socks(int *ssock, int *csock) static HANDSHAKE_RESULT *do_handshake_internal( SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx, const SSL_TEST_CTX *test_ctx, const SSL_TEST_EXTRA_CONF *extra, - SSL_SESSION *session_in, SSL_SESSION **session_out) + SSL_SESSION *session_in, SSL_SESSION *serv_sess_in, + SSL_SESSION **session_out, SSL_SESSION **serv_sess_out) { PEER server, client; BIO *client_to_server = NULL, *server_to_client = NULL; @@ -1452,10 +1453,14 @@ static HANDSHAKE_RESULT *do_handshake_internal( configure_handshake_ssl(server.ssl, client.ssl, extra); if (session_in != NULL) { + SSL_SESSION_get_id(serv_sess_in, &sess_id_len); /* In case we're testing resumption without tickets. */ - if (!TEST_true(SSL_CTX_add_session(server_ctx, session_in)) + if ((sess_id_len > 0 + && !TEST_true(SSL_CTX_add_session(server_ctx, + serv_sess_in))) || !TEST_true(SSL_set_session(client.ssl, session_in))) goto err; + sess_id_len = 0; } ret->result = SSL_TEST_INTERNAL_ERROR; @@ -1657,6 +1662,16 @@ static HANDSHAKE_RESULT *do_handshake_internal( if (session_out != NULL) *session_out = SSL_get1_session(client.ssl); + if (serv_sess_out != NULL) { + SSL_SESSION *tmp = SSL_get_session(server.ssl); + + /* + * We create a fresh copy that is not in the server session ctx linked + * list. + */ + if (tmp != NULL) + *serv_sess_out = SSL_SESSION_dup(tmp); + } if (SSL_get_server_tmp_key(client.ssl, &tmp_key)) { ret->tmp_key_type = pkey_type(tmp_key); @@ -1699,11 +1714,11 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, const SSL_TEST_CTX *test_ctx) { HANDSHAKE_RESULT *result; - SSL_SESSION *session = NULL; + SSL_SESSION *session = NULL, *serv_sess = NULL; result = do_handshake_internal(server_ctx, server2_ctx, client_ctx, test_ctx, &test_ctx->extra, - NULL, &session); + NULL, NULL, &session, &serv_sess); if (result == NULL || test_ctx->handshake_mode != SSL_TEST_HANDSHAKE_RESUME || result->result == SSL_TEST_INTERNAL_ERROR) @@ -1718,8 +1733,9 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, /* We don't support SNI on second handshake yet, so server2_ctx is NULL. */ result = do_handshake_internal(resume_server_ctx, NULL, resume_client_ctx, test_ctx, &test_ctx->resume_extra, - session, NULL); + session, serv_sess, NULL, NULL); end: SSL_SESSION_free(session); + SSL_SESSION_free(serv_sess); return result; } diff --git a/test/ssl-tests/10-resumption.conf b/test/ssl-tests/10-resumption.conf index 73955de754..73de974ab0 100644 --- a/test/ssl-tests/10-resumption.conf +++ b/test/ssl-tests/10-resumption.conf @@ -90,6 +90,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [0-resumption-client] @@ -126,6 +127,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [1-resumption-client] @@ -162,6 +164,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [2-resumption-client] @@ -198,6 +201,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [3-resumption-client] @@ -234,6 +238,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [4-resumption-client] @@ -270,6 +275,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [5-resumption-client] @@ -306,6 +312,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [6-resumption-client] @@ -342,6 +349,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [7-resumption-client] @@ -378,6 +386,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [8-resumption-client] @@ -414,6 +423,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [9-resumption-client] @@ -450,6 +460,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [10-resumption-client] @@ -486,6 +497,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [11-resumption-client] @@ -522,6 +534,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [12-resumption-client] @@ -558,6 +571,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [13-resumption-client] @@ -594,6 +608,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [14-resumption-client] @@ -630,6 +645,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [15-resumption-client] @@ -666,6 +682,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [16-resumption-client] @@ -702,6 +719,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [17-resumption-client] @@ -738,6 +756,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [18-resumption-client] @@ -774,6 +793,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [19-resumption-client] @@ -810,6 +830,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [20-resumption-client] @@ -846,6 +867,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [21-resumption-client] @@ -882,6 +904,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [22-resumption-client] @@ -918,6 +941,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [23-resumption-client] @@ -954,6 +978,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [24-resumption-client] @@ -990,6 +1015,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [25-resumption-client] @@ -1026,6 +1052,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [26-resumption-client] @@ -1062,6 +1089,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [27-resumption-client] @@ -1098,6 +1126,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [28-resumption-client] @@ -1134,6 +1163,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [29-resumption-client] @@ -1170,6 +1200,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [30-resumption-client] @@ -1206,6 +1237,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.3 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [31-resumption-client] diff --git a/test/ssl-tests/11-dtls_resumption.conf b/test/ssl-tests/11-dtls_resumption.conf index ceed959744..a981fa51df 100644 --- a/test/ssl-tests/11-dtls_resumption.conf +++ b/test/ssl-tests/11-dtls_resumption.conf @@ -41,6 +41,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [0-resumption-client] @@ -78,6 +79,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [1-resumption-client] @@ -115,6 +117,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1.2 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [2-resumption-client] @@ -152,6 +155,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1.2 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [3-resumption-client] @@ -189,6 +193,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [4-resumption-client] @@ -226,6 +231,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [5-resumption-client] @@ -263,6 +269,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1.2 +Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [6-resumption-client] @@ -300,6 +307,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = DTLSv1.2 +Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [7-resumption-client] diff --git a/test/ssl-tests/protocol_version.pm b/test/ssl-tests/protocol_version.pm index 215f9e8c4f..943719e84a 100644 --- a/test/ssl-tests/protocol_version.pm +++ b/test/ssl-tests/protocol_version.pm @@ -210,6 +210,7 @@ sub generate_resumption_tests { }, "resume_server" => { "MaxProtocol" => $protocols[$resume_protocol], + "Options" => $ticket, }, "test" => { "ExpectedProtocol" => $protocols[$resume_protocol], diff --git a/test/sslapitest.c b/test/sslapitest.c index 9b0237e060..61619a327c 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -1062,7 +1062,8 @@ static int execute_test_session(int maxprot, int use_int_cache, sess2 = NULL; SSL_CTX_set_max_proto_version(sctx, maxprot); - SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); + if (maxprot == TLS1_2_VERSION) + SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); new_called = remove_called = get_called = 0; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL, NULL))