提交 4ff1a526 编写于 作者: M Matt Caswell

Fix TLSv1.3 ticket nonces

All tickets on a connection need to have a unique nonce. When this was
originally implemented we only ever sent one ticket on the conneciton so
this didn't matter. We were just using the value 0. Now we can get multiple
tickets to we need to start doing the ticket nonce properly.

Fixes #6387
Reviewed-by: NAndy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6415)
上级 309371d6
...@@ -48,7 +48,6 @@ extern "C" { ...@@ -48,7 +48,6 @@ extern "C" {
# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) # define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8)
# define SSL_MAX_KEY_ARG_LENGTH 8 # define SSL_MAX_KEY_ARG_LENGTH 8
# define SSL_MAX_MASTER_KEY_LENGTH 48 # define SSL_MAX_MASTER_KEY_LENGTH 48
# define TLS13_MAX_RESUMPTION_MASTER_LENGTH 64
/* The maximum number of encrypt/decrypt pipelines we can support */ /* The maximum number of encrypt/decrypt pipelines we can support */
# define SSL_MAX_PIPELINES 32 # define SSL_MAX_PIPELINES 32
......
...@@ -299,7 +299,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, ...@@ -299,7 +299,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
goto err; goto err;
if (!ssl_session_memcpy(ret->master_key, &tmpl, if (!ssl_session_memcpy(ret->master_key, &tmpl,
as->master_key, TLS13_MAX_RESUMPTION_MASTER_LENGTH)) as->master_key, TLS13_MAX_RESUMPTION_PSK_LENGTH))
goto err; goto err;
ret->master_key_length = tmpl; ret->master_key_length = tmpl;
......
...@@ -470,6 +470,8 @@ struct ssl_method_st { ...@@ -470,6 +470,8 @@ struct ssl_method_st {
long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void));
}; };
# define TLS13_MAX_RESUMPTION_PSK_LENGTH 64
/*- /*-
* Lets make this into an ASN.1 type structure as follows * Lets make this into an ASN.1 type structure as follows
* SSL_SESSION_ID ::= SEQUENCE { * SSL_SESSION_ID ::= SEQUENCE {
...@@ -505,9 +507,9 @@ struct ssl_session_st { ...@@ -505,9 +507,9 @@ struct ssl_session_st {
unsigned char early_secret[EVP_MAX_MD_SIZE]; unsigned char early_secret[EVP_MAX_MD_SIZE];
/* /*
* For <=TLS1.2 this is the master_key. For TLS1.3 this is the resumption * For <=TLS1.2 this is the master_key. For TLS1.3 this is the resumption
* master secret * PSK
*/ */
unsigned char master_key[TLS13_MAX_RESUMPTION_MASTER_LENGTH]; unsigned char master_key[TLS13_MAX_RESUMPTION_PSK_LENGTH];
/* session_id - valid? */ /* session_id - valid? */
size_t session_id_length; size_t session_id_length;
unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
...@@ -1125,12 +1127,12 @@ struct ssl_st { ...@@ -1125,12 +1127,12 @@ struct ssl_st {
*/ */
uint32_t mac_flags; uint32_t mac_flags;
/* /*
* The TLS1.3 secrets. The resumption master secret is stored in the * The TLS1.3 secrets.
* session.
*/ */
unsigned char early_secret[EVP_MAX_MD_SIZE]; unsigned char early_secret[EVP_MAX_MD_SIZE];
unsigned char handshake_secret[EVP_MAX_MD_SIZE]; unsigned char handshake_secret[EVP_MAX_MD_SIZE];
unsigned char master_secret[EVP_MAX_MD_SIZE]; unsigned char master_secret[EVP_MAX_MD_SIZE];
unsigned char resumption_master_secret[EVP_MAX_MD_SIZE];
unsigned char client_finished_secret[EVP_MAX_MD_SIZE]; unsigned char client_finished_secret[EVP_MAX_MD_SIZE];
unsigned char server_finished_secret[EVP_MAX_MD_SIZE]; unsigned char server_finished_secret[EVP_MAX_MD_SIZE];
unsigned char server_finished_hash[EVP_MAX_MD_SIZE]; unsigned char server_finished_hash[EVP_MAX_MD_SIZE];
...@@ -1422,6 +1424,8 @@ struct ssl_st { ...@@ -1422,6 +1424,8 @@ struct ssl_st {
size_t num_tickets; size_t num_tickets;
/* The number of TLS1.3 tickets actually sent so far */ /* The number of TLS1.3 tickets actually sent so far */
size_t sent_tickets; size_t sent_tickets;
/* The next nonce value to use when we send a ticket on this connection */
uint64_t next_ticket_nonce;
}; };
/* /*
......
...@@ -1421,13 +1421,11 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, ...@@ -1421,13 +1421,11 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
EVP_MD_CTX *mctx = NULL; EVP_MD_CTX *mctx = NULL;
unsigned char hash[EVP_MAX_MD_SIZE], binderkey[EVP_MAX_MD_SIZE]; unsigned char hash[EVP_MAX_MD_SIZE], binderkey[EVP_MAX_MD_SIZE];
unsigned char finishedkey[EVP_MAX_MD_SIZE], tmpbinder[EVP_MAX_MD_SIZE]; unsigned char finishedkey[EVP_MAX_MD_SIZE], tmpbinder[EVP_MAX_MD_SIZE];
unsigned char tmppsk[EVP_MAX_MD_SIZE]; unsigned char *early_secret;
unsigned char *early_secret, *psk; static const unsigned char resumption_label[] = "res binder";
const char resumption_label[] = "res binder"; static const unsigned char external_label[] = "ext binder";
const char external_label[] = "ext binder"; const unsigned char *label;
const char nonce_label[] = "resumption"; size_t bindersize, labelsize, hashsize;
const char *label;
size_t bindersize, labelsize, psklen, hashsize;
int hashsizei = EVP_MD_size(md); int hashsizei = EVP_MD_size(md);
int ret = -1; int ret = -1;
int usepskfored = 0; int usepskfored = 0;
...@@ -1454,21 +1452,6 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, ...@@ -1454,21 +1452,6 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
labelsize = sizeof(resumption_label) - 1; labelsize = sizeof(resumption_label) - 1;
} }
if (external) {
psk = sess->master_key;
psklen = sess->master_key_length;
} else {
psk = tmppsk;
psklen = hashsize;
if (!tls13_hkdf_expand(s, md, sess->master_key,
(const unsigned char *)nonce_label,
sizeof(nonce_label) - 1, sess->ext.tick_nonce,
sess->ext.tick_nonce_len, psk, hashsize)) {
/* SSLfatal() already called */
goto err;
}
}
/* /*
* Generate the early_secret. On the server side we've selected a PSK to * Generate the early_secret. On the server side we've selected a PSK to
* resume with (internal or external) so we always do this. On the client * resume with (internal or external) so we always do this. On the client
...@@ -1481,7 +1464,9 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, ...@@ -1481,7 +1464,9 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
early_secret = (unsigned char *)s->early_secret; early_secret = (unsigned char *)s->early_secret;
else else
early_secret = (unsigned char *)sess->early_secret; early_secret = (unsigned char *)sess->early_secret;
if (!tls13_generate_secret(s, md, NULL, psk, psklen, early_secret)) {
if (!tls13_generate_secret(s, md, NULL, sess->master_key,
sess->master_key_length, early_secret)) {
/* SSLfatal() already called */ /* SSLfatal() already called */
goto err; goto err;
} }
...@@ -1500,8 +1485,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, ...@@ -1500,8 +1485,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
} }
/* Generate the binder key */ /* Generate the binder key */
if (!tls13_hkdf_expand(s, md, early_secret, (unsigned char *)label, if (!tls13_hkdf_expand(s, md, early_secret, label, labelsize, hash,
labelsize, hash, hashsize, binderkey, hashsize)) { hashsize, binderkey, hashsize)) {
/* SSLfatal() already called */ /* SSLfatal() already called */
goto err; goto err;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <openssl/dh.h> #include <openssl/dh.h>
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/engine.h> #include <openssl/engine.h>
#include <internal/cryptlib.h>
static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt);
static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt);
...@@ -2674,6 +2675,32 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) ...@@ -2674,6 +2675,32 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
/* This is a standalone message in TLSv1.3, so there is no more to read */ /* This is a standalone message in TLSv1.3, so there is no more to read */
if (SSL_IS_TLS13(s)) { if (SSL_IS_TLS13(s)) {
const EVP_MD *md = ssl_handshake_md(s);
int hashleni = EVP_MD_size(md);
size_t hashlen;
static const unsigned char nonce_label[] = "resumption";
/* Ensure cast to size_t is safe */
if (!ossl_assert(hashleni >= 0)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PROCESS_NEW_SESSION_TICKET,
ERR_R_INTERNAL_ERROR);
goto err;
}
hashlen = (size_t)hashleni;
if (!tls13_hkdf_expand(s, md, s->resumption_master_secret,
nonce_label,
sizeof(nonce_label) - 1,
s->session->ext.tick_nonce,
s->session->ext.tick_nonce_len,
s->session->master_key,
hashlen)) {
/* SSLfatal() already called */
goto err;
}
s->session->master_key_length = hashlen;
OPENSSL_free(exts); OPENSSL_free(exts);
ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
return MSG_PROCESS_FINISHED_READING; return MSG_PROCESS_FINISHED_READING;
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#define TICKET_NONCE_SIZE 8
static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt); static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt);
/* /*
...@@ -3758,7 +3760,21 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) ...@@ -3758,7 +3760,21 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
} age_add_u; } age_add_u;
if (SSL_IS_TLS13(s)) { if (SSL_IS_TLS13(s)) {
size_t i, hashlen;
uint64_t nonce;
const char nonce_label[] = "resumption";
const EVP_MD *md = ssl_handshake_md(s);
void (*cb) (const SSL *ssl, int type, int val) = NULL; void (*cb) (const SSL *ssl, int type, int val) = NULL;
int hashleni = EVP_MD_size(md);
/* Ensure cast to size_t is safe */
if (!ossl_assert(hashleni >= 0)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
ERR_R_INTERNAL_ERROR);
goto err;
}
hashlen = (size_t)hashleni;
if (s->info_callback != NULL) if (s->info_callback != NULL)
cb = s->info_callback; cb = s->info_callback;
...@@ -3806,20 +3822,34 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) ...@@ -3806,20 +3822,34 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
goto err; goto err;
} }
s->session->ext.tick_age_add = age_add_u.age_add; s->session->ext.tick_age_add = age_add_u.age_add;
/*
* ticket_nonce is set to a single 0 byte because we only ever send a
* single ticket per connection. IMPORTANT: If we ever support multiple
* tickets per connection then this will need to be changed.
*/
OPENSSL_free(s->session->ext.tick_nonce); OPENSSL_free(s->session->ext.tick_nonce);
s->session->ext.tick_nonce = OPENSSL_zalloc(sizeof(char)); s->session->ext.tick_nonce = OPENSSL_zalloc(TICKET_NONCE_SIZE);
if (s->session->ext.tick_nonce == NULL) { if (s->session->ext.tick_nonce == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
ERR_R_MALLOC_FAILURE); ERR_R_MALLOC_FAILURE);
goto err; goto err;
} }
s->session->ext.tick_nonce_len = 1; nonce = s->next_ticket_nonce;
for (i = TICKET_NONCE_SIZE; nonce > 0 && i > 0; i--) {
s->session->ext.tick_nonce[i - 1] = nonce & 0xff;
nonce >>= 8;
}
s->session->ext.tick_nonce_len = TICKET_NONCE_SIZE;
if (!tls13_hkdf_expand(s, md, s->resumption_master_secret,
(const unsigned char *)nonce_label,
sizeof(nonce_label) - 1,
s->session->ext.tick_nonce,
s->session->ext.tick_nonce_len,
s->session->master_key,
hashlen)) {
/* SSLfatal() already called */
goto err;
}
s->session->master_key_length = hashlen;
s->session->time = (long)time(NULL); s->session->time = (long)time(NULL);
if (s->s3->alpn_selected != NULL) { if (s->s3->alpn_selected != NULL) {
OPENSSL_free(s->session->ext.alpn_selected); OPENSSL_free(s->session->ext.alpn_selected);
...@@ -4002,7 +4032,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) ...@@ -4002,7 +4032,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
/* SSLfatal() already called */ /* SSLfatal() already called */
goto err; goto err;
} }
/*
* Increment both |sent_tickets| and |next_ticket_nonce|. |sent_tickets|
* gets reset to 0 if we send more tickets following a post-handshake
* auth, but |next_ticket_nonce| does not.
*/
s->sent_tickets++; s->sent_tickets++;
s->next_ticket_nonce++;
ssl_update_cache(s, SSL_SESS_CACHE_SERVER); ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
} }
EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_CTX_free(ctx);
......
...@@ -602,12 +602,11 @@ int tls13_change_cipher_state(SSL *s, int which) ...@@ -602,12 +602,11 @@ int tls13_change_cipher_state(SSL *s, int which)
if (!tls13_hkdf_expand(s, ssl_handshake_md(s), insecret, if (!tls13_hkdf_expand(s, ssl_handshake_md(s), insecret,
resumption_master_secret, resumption_master_secret,
sizeof(resumption_master_secret) - 1, sizeof(resumption_master_secret) - 1,
hashval, hashlen, s->session->master_key, hashval, hashlen, s->resumption_master_secret,
hashlen)) { hashlen)) {
/* SSLfatal() already called */ /* SSLfatal() already called */
goto err; goto err;
} }
s->session->master_key_length = hashlen;
} }
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册