提交 fe5e20fd 编写于 作者: M Matt Caswell

Fix changing of the cipher state when dealing with early data

Reviewed-by: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)
上级 1ea4d09a
...@@ -1657,6 +1657,7 @@ int ssl_end_of_early_data_seen(SSL *s) ...@@ -1657,6 +1657,7 @@ int ssl_end_of_early_data_seen(SSL *s)
{ {
if (s->early_data_state == SSL_EARLY_DATA_READING) { if (s->early_data_state == SSL_EARLY_DATA_READING) {
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
ossl_statem_finish_early_data(s);
return 1; return 1;
} }
......
...@@ -1027,6 +1027,7 @@ struct ssl_st { ...@@ -1027,6 +1027,7 @@ struct ssl_st {
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];
unsigned char handshake_traffic_hash[EVP_MAX_MD_SIZE];
unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE]; unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE];
unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE]; unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE];
EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
......
...@@ -129,3 +129,4 @@ __owur int ossl_statem_app_data_allowed(SSL *s); ...@@ -129,3 +129,4 @@ __owur int ossl_statem_app_data_allowed(SSL *s);
void ossl_statem_set_sctp_read_sock(SSL *s, int read_sock); void ossl_statem_set_sctp_read_sock(SSL *s, int read_sock);
__owur int ossl_statem_in_sctp_read_sock(SSL *s); __owur int ossl_statem_in_sctp_read_sock(SSL *s);
#endif #endif
int ossl_statem_finish_early_data(SSL *s);
...@@ -787,10 +787,13 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) ...@@ -787,10 +787,13 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
if (SSL_IS_TLS13(s)) { if (SSL_IS_TLS13(s)) {
if (!s->method->ssl3_enc->setup_key_block(s) if (!s->method->ssl3_enc->setup_key_block(s)
|| !s->method->ssl3_enc->change_cipher_state(s, || !s->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE) SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE))
|| !s->method->ssl3_enc->change_cipher_state(s, return WORK_ERROR;
if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED
&& !s->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE |SSL3_CHANGE_CIPHER_SERVER_READ)) SSL3_CC_HANDSHAKE |SSL3_CHANGE_CIPHER_SERVER_READ))
return WORK_ERROR; return WORK_ERROR;
} }
break; break;
...@@ -1104,6 +1107,15 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst) ...@@ -1104,6 +1107,15 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst)
return WORK_FINISHED_CONTINUE; return WORK_FINISHED_CONTINUE;
} }
int ossl_statem_finish_early_data(SSL *s)
{
if (!s->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ))
return 0;
return 1;
}
#ifndef OPENSSL_NO_SRP #ifndef OPENSSL_NO_SRP
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{ {
......
...@@ -422,6 +422,16 @@ int tls13_change_cipher_state(SSL *s, int which) ...@@ -422,6 +422,16 @@ int tls13_change_cipher_state(SSL *s, int which)
label = client_handshake_traffic; label = client_handshake_traffic;
labellen = sizeof(client_handshake_traffic) - 1; labellen = sizeof(client_handshake_traffic) - 1;
log_label = CLIENT_HANDSHAKE_LABEL; log_label = CLIENT_HANDSHAKE_LABEL;
/*
* The hanshake hash used for the server read handshake traffic
* secret is the same as the hash for the server write handshake
* traffic secret. However, if we processed early data then we delay
* changing the server read cipher state until later, and the
* handshake hashes have moved on. Therefore we use the value saved
* earlier when we did the server write change cipher state.
*/
if (s->server)
hash = s->handshake_traffic_hash;
} else { } else {
insecret = s->master_secret; insecret = s->master_secret;
label = client_application_traffic; label = client_application_traffic;
...@@ -469,6 +479,9 @@ int tls13_change_cipher_state(SSL *s, int which) ...@@ -469,6 +479,9 @@ int tls13_change_cipher_state(SSL *s, int which)
if (label == server_application_traffic) if (label == server_application_traffic)
memcpy(s->server_finished_hash, hashval, hashlen); memcpy(s->server_finished_hash, hashval, hashlen);
if (s->server && label == server_handshake_traffic)
memcpy(s->handshake_traffic_hash, hashval, hashlen);
if (label == client_application_traffic) { if (label == client_application_traffic) {
/* /*
* We also create the resumption master secret, but this time use the * We also create the resumption master secret, but this time use the
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册