Fix a crash in SSLfatal due to invalid enc_write_ctx
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Fri, 16 Mar 2018 12:29:51 +0000 (13:29 +0100)
committerBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 19 Mar 2018 13:16:54 +0000 (14:16 +0100)
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5645)

ssl/s3_enc.c
ssl/statem/statem.c
ssl/statem/statem.h
ssl/t1_enc.c
ssl/tls13_enc.c

index f775f26..966d498 100644 (file)
@@ -155,6 +155,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
         RECORD_LAYER_reset_read_sequence(&s->rlayer);
         mac_secret = &(s->s3->read_mac_secret[0]);
     } else {
         RECORD_LAYER_reset_read_sequence(&s->rlayer);
         mac_secret = &(s->s3->read_mac_secret[0]);
     } else {
+        s->statem.invalid_enc_write_ctx = 1;
         if (s->enc_write_ctx != NULL) {
             reuse_dd = 1;
         } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
         if (s->enc_write_ctx != NULL) {
             reuse_dd = 1;
         } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
@@ -238,6 +239,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
         goto err;
     }
 
         goto err;
     }
 
+    s->statem.invalid_enc_write_ctx = 0;
     OPENSSL_cleanse(exp_key, sizeof(exp_key));
     OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
     return 1;
     OPENSSL_cleanse(exp_key, sizeof(exp_key));
     OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
     return 1;
index a574853..1f221e7 100644 (file)
@@ -123,7 +123,7 @@ void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file,
     s->statem.in_init = 1;
     s->statem.state = MSG_FLOW_ERROR;
     ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
     s->statem.in_init = 1;
     s->statem.state = MSG_FLOW_ERROR;
     ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
-    if (al != SSL_AD_NO_ALERT)
+    if (al != SSL_AD_NO_ALERT && !s->statem.invalid_enc_write_ctx)
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
 }
 
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
 }
 
index 1935718..95dd881 100644 (file)
@@ -100,6 +100,7 @@ struct ossl_statem_st {
     /* Should we skip the CertificateVerify message? */
     unsigned int no_cert_verify;
     int use_timer;
     /* Should we skip the CertificateVerify message? */
     unsigned int no_cert_verify;
     int use_timer;
+    int invalid_enc_write_ctx;
 };
 typedef struct ossl_statem_st OSSL_STATEM;
 
 };
 typedef struct ossl_statem_st OSSL_STATEM;
 
index bd7ff50..a138b60 100644 (file)
@@ -154,6 +154,7 @@ int tls1_change_cipher_state(SSL *s, int which)
         mac_secret = &(s->s3->read_mac_secret[0]);
         mac_secret_size = &(s->s3->read_mac_secret_size);
     } else {
         mac_secret = &(s->s3->read_mac_secret[0]);
         mac_secret_size = &(s->s3->read_mac_secret_size);
     } else {
+        s->statem.invalid_enc_write_ctx = 1;
         if (s->ext.use_etm)
             s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
         else
         if (s->ext.use_etm)
             s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
         else
@@ -316,6 +317,7 @@ int tls1_change_cipher_state(SSL *s, int which)
                  ERR_R_INTERNAL_ERROR);
         goto err;
     }
                  ERR_R_INTERNAL_ERROR);
         goto err;
     }
+    s->statem.invalid_enc_write_ctx = 0;
 
 #ifdef SSL_DEBUG
     printf("which = %04X\nkey=", which);
 
 #ifdef SSL_DEBUG
     printf("which = %04X\nkey=", which);
index 08fbee5..7f43958 100644 (file)
@@ -397,6 +397,7 @@ int tls13_change_cipher_state(SSL *s, int which)
 
         RECORD_LAYER_reset_read_sequence(&s->rlayer);
     } else {
 
         RECORD_LAYER_reset_read_sequence(&s->rlayer);
     } else {
+        s->statem.invalid_enc_write_ctx = 1;
         if (s->enc_write_ctx != NULL) {
             EVP_CIPHER_CTX_reset(s->enc_write_ctx);
         } else {
         if (s->enc_write_ctx != NULL) {
             EVP_CIPHER_CTX_reset(s->enc_write_ctx);
         } else {
@@ -609,6 +610,7 @@ int tls13_change_cipher_state(SSL *s, int which)
         goto err;
     }
 
         goto err;
     }
 
+    s->statem.invalid_enc_write_ctx = 0;
     ret = 1;
  err:
     OPENSSL_cleanse(secret, sizeof(secret));
     ret = 1;
  err:
     OPENSSL_cleanse(secret, sizeof(secret));
@@ -631,6 +633,7 @@ int tls13_update_key(SSL *s, int sending)
         insecret = s->client_app_traffic_secret;
 
     if (sending) {
         insecret = s->client_app_traffic_secret;
 
     if (sending) {
+        s->statem.invalid_enc_write_ctx = 1;
         iv = s->write_iv;
         ciph_ctx = s->enc_write_ctx;
         RECORD_LAYER_reset_write_sequence(&s->rlayer);
         iv = s->write_iv;
         ciph_ctx = s->enc_write_ctx;
         RECORD_LAYER_reset_write_sequence(&s->rlayer);
@@ -651,6 +654,7 @@ int tls13_update_key(SSL *s, int sending)
 
     memcpy(insecret, secret, hashlen);
 
 
     memcpy(insecret, secret, hashlen);
 
+    s->statem.invalid_enc_write_ctx = 0;
     ret = 1;
  err:
     OPENSSL_cleanse(secret, sizeof(secret));
     ret = 1;
  err:
     OPENSSL_cleanse(secret, sizeof(secret));