[openssl-commits] [openssl] OpenSSL_1_1_0-stable update

Matt Caswell matt at openssl.org
Thu Feb 16 12:04:33 UTC 2017


The branch OpenSSL_1_1_0-stable has been updated
       via  ffb1e659b2546cb704ef56ae01176b9062ef1c6f (commit)
       via  0453163e9a9052884cce288ff3e2acb77725a239 (commit)
       via  aed24635b8c3a0635448c90ebee6eb2447be4a66 (commit)
       via  60747ea22f8b25b2a7e54e7fe4ad47dfe8f93383 (commit)
       via  4ad93618d26a3ea23d36ad5498ff4f59eff3a4d2 (commit)
       via  9c5a691d578a4debfd6ecacc030a85900906bf0d (commit)
      from  3bdc1dc8fcc97a8945ddbc2748e7059207ea3914 (commit)


- Log -----------------------------------------------------------------
commit ffb1e659b2546cb704ef56ae01176b9062ef1c6f
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Feb 16 11:59:36 2017 +0000

    Prepare for 1.1.0f-dev
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit 0453163e9a9052884cce288ff3e2acb77725a239
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Feb 16 11:58:19 2017 +0000

    Prepare for 1.1.0e release
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit aed24635b8c3a0635448c90ebee6eb2447be4a66
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Feb 16 09:51:56 2017 +0000

    Update CHANGES and NEWS for new release
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit 60747ea22f8b25b2a7e54e7fe4ad47dfe8f93383
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Feb 3 14:54:43 2017 +0000

    Remove an OPENSSL_assert() and replace with a soft assert and check
    
    Following on from CVE-2017-3733, this removes the OPENSSL_assert() check
    that failed and replaces it with a soft assert, and an explicit check of
    value with an error return if it fails.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit 4ad93618d26a3ea23d36ad5498ff4f59eff3a4d2
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Feb 3 14:06:20 2017 +0000

    Don't change the state of the ETM flags until CCS processing
    
    Changing the ciphersuite during a renegotiation can result in a crash
    leading to a DoS attack. ETM has not been implemented in 1.1.0 for DTLS
    so this is TLS only.
    
    The problem is caused by changing the flag indicating whether to use ETM
    or not immediately on negotiation of ETM, rather than at CCS. Therefore,
    during a renegotiation, if the ETM state is changing (usually due to a
    change of ciphersuite), then an error/crash will occur.
    
    Due to the fact that there are separate CCS messages for read and write
    we actually now need two flags to determine whether to use ETM or not.
    
    CVE-2017-3733
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit 9c5a691d578a4debfd6ecacc030a85900906bf0d
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Feb 3 11:21:07 2017 +0000

    Provide a test for the Encrypt-Then-Mac renegotiation crash
    
    Changing the ciphersuite during a renegotiation can result in a crash
    leading to a DoS attack. ETM has not been implemented in 1.1.0 for DTLS
    so this is TLS only.
    
    This commit provides a test for the issue.
    
    CVE-2017-3733
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 CHANGES                                    |  15 +++-
 NEWS                                       |   6 +-
 README                                     |   2 +-
 include/openssl/opensslv.h                 |   6 +-
 include/openssl/ssl3.h                     |   5 +-
 ssl/record/rec_layer_s3.c                  |   6 +-
 ssl/record/ssl3_record.c                   |  24 ++++--
 ssl/ssl_locl.h                             |   7 +-
 ssl/t1_enc.c                               |  15 +++-
 ssl/t1_lib.c                               |  12 +--
 test/handshake_helper.c                    |  16 +++-
 test/ssl-tests/17-renegotiate.conf         | 134 ++++++++++++++++++++++++++++-
 test/ssl-tests/17-renegotiate.conf.in      |  78 ++++++++++++++++-
 test/ssl-tests/18-dtls-renegotiate.conf    | 130 +++++++++++++++++++++++++++-
 test/ssl-tests/18-dtls-renegotiate.conf.in |  74 +++++++++++++++-
 test/ssl_test_ctx.c                        |  59 ++++---------
 test/ssl_test_ctx.h                        |   2 +
 17 files changed, 515 insertions(+), 76 deletions(-)

diff --git a/CHANGES b/CHANGES
index d516e2c..76041ce 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,10 +2,23 @@
  OpenSSL CHANGES
  _______________
 
- Changes between 1.1.0d and 1.1.0e [xx XXX xxxx]
+ Changes between 1.1.0e and 1.1.0f [xx XXX xxxx]
 
   *)
 
+ Changes between 1.1.0d and 1.1.0e [16 Feb 2017]
+
+  *) Encrypt-Then-Mac renegotiation crash
+
+     During a renegotiation handshake if the Encrypt-Then-Mac extension is
+     negotiated where it was not in the original handshake (or vice-versa) then
+     this can cause OpenSSL to crash (dependant on ciphersuite). Both clients
+     and servers are affected.
+
+     This issue was reported to OpenSSL by Joe Orton (Red Hat).
+     (CVE-2017-3733)
+     [Matt Caswell]
+
  Changes between 1.1.0c and 1.1.0d [26 Jan 2017]
 
   *) Truncated packet could crash via OOB read
diff --git a/NEWS b/NEWS
index 693bbec..582d66e 100644
--- a/NEWS
+++ b/NEWS
@@ -5,10 +5,14 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
-  Major changes between OpenSSL 1.1.0d and OpenSSL 1.1.0e [under development]
+  Major changes between OpenSSL 1.1.0e and OpenSSL 1.1.0f [under development]
 
       o
 
+  Major changes between OpenSSL 1.1.0d and OpenSSL 1.1.0e [16 Feb 2017]
+
+      o Encrypt-Then-Mac renegotiation crash (CVE-2017-3733)
+
   Major changes between OpenSSL 1.1.0c and OpenSSL 1.1.0d [26 Jan 2017]
 
       o Truncated packet could crash via OOB read (CVE-2017-3731)
diff --git a/README b/README
index 03ad75c..105a676 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 
- OpenSSL 1.1.0e-dev
+ OpenSSL 1.1.0f-dev
 
  Copyright (c) 1998-2016 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index 098c957..cffeb01 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -39,11 +39,11 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x10100050L
+# define OPENSSL_VERSION_NUMBER  0x10100060L
 # ifdef OPENSSL_FIPS
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.0e-fips-dev  xx XXX xxxx"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.0f-fips-dev  xx XXX xxxx"
 # else
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.0e-dev  xx XXX xxxx"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.0f-dev  xx XXX xxxx"
 # endif
 
 /*-
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index aca1922..4ca434e 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -264,11 +264,14 @@ extern "C" {
 # define TLS1_FLAGS_SKIP_CERT_VERIFY             0x0010
 
 /* Set if we encrypt then mac instead of usual mac then encrypt */
-# define TLS1_FLAGS_ENCRYPT_THEN_MAC             0x0100
+# define TLS1_FLAGS_ENCRYPT_THEN_MAC_READ        0x0100
+# define TLS1_FLAGS_ENCRYPT_THEN_MAC             TLS1_FLAGS_ENCRYPT_THEN_MAC_READ
 
 /* Set if extended master secret extension received from peer */
 # define TLS1_FLAGS_RECEIVED_EXTMS               0x0200
 
+# define TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE       0x0400
+
 # define SSL3_MT_HELLO_REQUEST                   0
 # define SSL3_MT_CLIENT_HELLO                    1
 # define SSL3_MT_SERVER_HELLO                    2
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index 00379ea..4a7e59b 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -395,7 +395,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
     if (type == SSL3_RT_APPLICATION_DATA &&
         u_len >= 4 * (max_send_fragment = s->max_send_fragment) &&
         s->compress == NULL && s->msg_callback == NULL &&
-        !SSL_USE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
+        !SSL_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
         EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
         EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
         unsigned char aad[13];
@@ -791,7 +791,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
          * wb->buf
          */
 
-        if (!SSL_USE_ETM(s) && mac_size != 0) {
+        if (!SSL_WRITE_ETM(s) && mac_size != 0) {
             if (s->method->ssl3_enc->mac(s, &wr[j],
                                          &(outbuf[j][wr[j].length + eivlen]),
                                          1) < 0)
@@ -814,7 +814,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
         goto err;
 
     for (j = 0; j < numpipes; j++) {
-        if (SSL_USE_ETM(s) && mac_size != 0) {
+        if (SSL_WRITE_ETM(s) && mac_size != 0) {
             if (s->method->ssl3_enc->mac(s, &wr[j],
                                          outbuf[j] + wr[j].length, 1) < 0)
                 goto err;
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index e5cbd61..03c5294 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -7,6 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include <assert.h>
 #include "../ssl_locl.h"
 #include "internal/constant_time_locl.h"
 #include <openssl/rand.h>
@@ -133,6 +134,7 @@ int ssl3_get_record(SSL *s)
     unsigned char md[EVP_MAX_MD_SIZE];
     short version;
     unsigned mac_size;
+    int imac_size;
     unsigned int num_recs = 0;
     unsigned int max_recs;
     unsigned int j;
@@ -346,10 +348,18 @@ int ssl3_get_record(SSL *s)
      * If in encrypt-then-mac mode calculate mac from encrypted record. All
      * the details below are public so no timing details can leak.
      */
-    if (SSL_USE_ETM(s) && s->read_hash) {
+    if (SSL_READ_ETM(s) && s->read_hash) {
         unsigned char *mac;
-        mac_size = EVP_MD_CTX_size(s->read_hash);
-        OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+        imac_size = EVP_MD_CTX_size(s->read_hash);
+        assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE);
+        if (imac_size < 0 || imac_size > EVP_MAX_MD_SIZE) {
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_SSL3_GET_RECORD, ERR_LIB_EVP);
+                goto f_err;
+        }
+        mac_size = (unsigned)imac_size;
+
         for (j = 0; j < num_recs; j++) {
             if (rr[j].length < mac_size) {
                 al = SSL_AD_DECODE_ERROR;
@@ -393,7 +403,7 @@ int ssl3_get_record(SSL *s)
     /* r->length is now the compressed data plus mac */
     if ((sess != NULL) &&
         (s->enc_read_ctx != NULL) &&
-        (EVP_MD_CTX_md(s->read_hash) != NULL) && !SSL_USE_ETM(s)) {
+        (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) {
         /* s->read_hash != NULL => mac_size != -1 */
         unsigned char *mac = NULL;
         unsigned char mac_tmp[EVP_MAX_MD_SIZE];
@@ -823,7 +833,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, unsigned int n_recs, int send)
         }
 
         ret = 1;
-        if (!SSL_USE_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)
+        if (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)
             mac_size = EVP_MD_CTX_size(s->read_hash);
         if ((bs != 1) && !send) {
             int tmpret;
@@ -997,7 +1007,7 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send)
     header[11] = (rec->length) >> 8;
     header[12] = (rec->length) & 0xff;
 
-    if (!send && !SSL_USE_ETM(ssl) &&
+    if (!send && !SSL_READ_ETM(ssl) &&
         EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
         ssl3_cbc_record_digest_supported(mac_ctx)) {
         /*
@@ -1022,7 +1032,7 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send)
             EVP_MD_CTX_free(hmac);
             return -1;
         }
-        if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())
+        if (!send && !SSL_READ_ETM(ssl) && FIPS_mode())
             if (!tls_fips_digest_extra(ssl->enc_read_ctx,
                                        mac_ctx, rec->input,
                                        rec->length, rec->orig_len)) {
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 1586a46..08de52e 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -378,7 +378,8 @@
 # define SSL_CLIENT_USE_SIGALGS(s)        \
     SSL_CLIENT_USE_TLS1_2_CIPHERS(s)
 
-# define SSL_USE_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC)
+# define SSL_READ_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_READ)
+# define SSL_WRITE_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE)
 
 /* Mostly for SSLv3 */
 # define SSL_PKEY_RSA_ENC        0
@@ -1110,6 +1111,10 @@ struct ssl_st {
      */
     unsigned char *alpn_client_proto_list;
     unsigned alpn_client_proto_list_len;
+
+    /* Set to one if we have negotiated ETM */
+    int tlsext_use_etm;
+
     /*-
      * 1 if we are renegotiating.
      * 2 if we are a server and are inside a handshake
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 4aa5ddd..0fb88af 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -130,6 +130,11 @@ int tls1_change_cipher_state(SSL *s, int which)
 #endif
 
     if (which & SSL3_CC_READ) {
+        if (s->tlsext_use_etm)
+            s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
+        else
+            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
+
         if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
             s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
         else
@@ -168,6 +173,11 @@ 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 {
+        if (s->tlsext_use_etm)
+            s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
+        else
+            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
+
         if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
             s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
         else
@@ -367,9 +377,8 @@ int tls1_setup_key_block(SSL *s)
     if (s->s3->tmp.key_block_length != 0)
         return (1);
 
-    if (!ssl_cipher_get_evp
-        (s->session, &c, &hash, &mac_type, &mac_secret_size, &comp,
-         SSL_USE_ETM(s))) {
+    if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type, &mac_secret_size,
+                            &comp, s->tlsext_use_etm)) {
         SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
         return (0);
     }
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index b51d60a..b2688f6 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1674,7 +1674,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
 #endif
     if (!custom_ext_add(s, 1, &ret, limit, al))
         return NULL;
-    if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) {
+    if (s->tlsext_use_etm) {
         /*
          * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
          * for other cases too.
@@ -1683,7 +1683,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
             || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
             || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
             || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12)
-            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+            s->tlsext_use_etm = 0;
         else {
             /*-
              * check for enough space.
@@ -1916,7 +1916,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
     /* Clear any signature algorithms extension received */
     OPENSSL_free(s->s3->tmp.peer_sigalgs);
     s->s3->tmp.peer_sigalgs = NULL;
-    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+    s->tlsext_use_etm = 0;
 
 #ifndef OPENSSL_NO_SRP
     OPENSSL_free(s->srp_ctx.login);
@@ -2264,7 +2264,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
         }
 #endif
         else if (type == TLSEXT_TYPE_encrypt_then_mac)
-            s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
+            s->tlsext_use_etm = 1;
         /*
          * Note: extended master secret extension handled in
          * tls_check_serverhello_tlsext_early()
@@ -2366,7 +2366,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
                              SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
 #endif
 
-    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+    s->tlsext_use_etm = 0;
 
     s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
 
@@ -2585,7 +2585,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
             /* Ignore if inappropriate ciphersuite */
             if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
                 && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
-                s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
+                s->tlsext_use_etm = 1;
         } else if (type == TLSEXT_TYPE_extended_master_secret) {
             s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
             if (!s->hit)
diff --git a/test/handshake_helper.c b/test/handshake_helper.c
index 0a421b1..7ef015f 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -607,10 +607,20 @@ static void do_reneg_setup_step(const SSL_TEST_CTX *test_ctx, PEER *peer)
              * session. The server may or may not resume dependant on the
              * setting of SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
              */
-            if (SSL_is_server(peer->ssl))
+            if (SSL_is_server(peer->ssl)) {
                 ret = SSL_renegotiate(peer->ssl);
-            else
-                ret = SSL_renegotiate_abbreviated(peer->ssl);
+            } else {
+                if (test_ctx->extra.client.reneg_ciphers != NULL) {
+                    if (!SSL_set_cipher_list(peer->ssl,
+                                test_ctx->extra.client.reneg_ciphers)) {
+                        peer->status = PEER_ERROR;
+                        return;
+                    }
+                    ret = SSL_renegotiate(peer->ssl);
+                } else {
+                    ret = SSL_renegotiate_abbreviated(peer->ssl);
+                }
+            }
             if (!ret) {
                 peer->status = PEER_ERROR;
                 return;
diff --git a/test/ssl-tests/17-renegotiate.conf b/test/ssl-tests/17-renegotiate.conf
index fb9f97b..9ea1d8c 100644
--- a/test/ssl-tests/17-renegotiate.conf
+++ b/test/ssl-tests/17-renegotiate.conf
@@ -1,6 +1,6 @@
 # Generated with generate_ssl_tests.pl
 
-num_tests = 6
+num_tests = 10
 
 test-0 = 0-renegotiate-client-no-resume
 test-1 = 1-renegotiate-client-resume
@@ -8,6 +8,10 @@ test-2 = 2-renegotiate-server-no-resume
 test-3 = 3-renegotiate-server-resume
 test-4 = 4-renegotiate-client-auth-require
 test-5 = 5-renegotiate-client-auth-once
+test-6 = 6-renegotiate-aead-to-non-aead
+test-7 = 7-renegotiate-non-aead-to-aead
+test-8 = 8-renegotiate-non-aead-to-non-aead
+test-9 = 9-renegotiate-aead-to-aead
 # ===========================================================
 
 [0-renegotiate-client-no-resume]
@@ -178,3 +182,131 @@ Method = TLS
 ResumptionExpected = No
 
 
+# ===========================================================
+
+[6-renegotiate-aead-to-non-aead]
+ssl_conf = 6-renegotiate-aead-to-non-aead-ssl
+
+[6-renegotiate-aead-to-non-aead-ssl]
+server = 6-renegotiate-aead-to-non-aead-server
+client = 6-renegotiate-aead-to-non-aead-client
+
+[6-renegotiate-aead-to-non-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+MaxProtocol = TLSv1.2
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[6-renegotiate-aead-to-non-aead-client]
+CipherString = AES128-GCM-SHA256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-6]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = TLS
+ResumptionExpected = No
+client = 6-renegotiate-aead-to-non-aead-client-extra
+
+[6-renegotiate-aead-to-non-aead-client-extra]
+RenegotiateCiphers = AES128-SHA
+
+
+# ===========================================================
+
+[7-renegotiate-non-aead-to-aead]
+ssl_conf = 7-renegotiate-non-aead-to-aead-ssl
+
+[7-renegotiate-non-aead-to-aead-ssl]
+server = 7-renegotiate-non-aead-to-aead-server
+client = 7-renegotiate-non-aead-to-aead-client
+
+[7-renegotiate-non-aead-to-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+MaxProtocol = TLSv1.2
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[7-renegotiate-non-aead-to-aead-client]
+CipherString = AES128-SHA
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-7]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = TLS
+ResumptionExpected = No
+client = 7-renegotiate-non-aead-to-aead-client-extra
+
+[7-renegotiate-non-aead-to-aead-client-extra]
+RenegotiateCiphers = AES128-GCM-SHA256
+
+
+# ===========================================================
+
+[8-renegotiate-non-aead-to-non-aead]
+ssl_conf = 8-renegotiate-non-aead-to-non-aead-ssl
+
+[8-renegotiate-non-aead-to-non-aead-ssl]
+server = 8-renegotiate-non-aead-to-non-aead-server
+client = 8-renegotiate-non-aead-to-non-aead-client
+
+[8-renegotiate-non-aead-to-non-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+MaxProtocol = TLSv1.2
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[8-renegotiate-non-aead-to-non-aead-client]
+CipherString = AES128-SHA
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-8]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = TLS
+ResumptionExpected = No
+client = 8-renegotiate-non-aead-to-non-aead-client-extra
+
+[8-renegotiate-non-aead-to-non-aead-client-extra]
+RenegotiateCiphers = AES256-SHA
+
+
+# ===========================================================
+
+[9-renegotiate-aead-to-aead]
+ssl_conf = 9-renegotiate-aead-to-aead-ssl
+
+[9-renegotiate-aead-to-aead-ssl]
+server = 9-renegotiate-aead-to-aead-server
+client = 9-renegotiate-aead-to-aead-client
+
+[9-renegotiate-aead-to-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+MaxProtocol = TLSv1.2
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[9-renegotiate-aead-to-aead-client]
+CipherString = AES128-GCM-SHA256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-9]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = TLS
+ResumptionExpected = No
+client = 9-renegotiate-aead-to-aead-client-extra
+
+[9-renegotiate-aead-to-aead-client-extra]
+RenegotiateCiphers = AES256-GCM-SHA384
+
+
diff --git a/test/ssl-tests/17-renegotiate.conf.in b/test/ssl-tests/17-renegotiate.conf.in
index 104b1fe..fde57bc 100644
--- a/test/ssl-tests/17-renegotiate.conf.in
+++ b/test/ssl-tests/17-renegotiate.conf.in
@@ -102,5 +102,81 @@ our @tests = (
             "ResumptionExpected" => "No",
             "ExpectedResult" => "Success"
         }
-    }
+    },
+    {
+        name => "renegotiate-aead-to-non-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation",
+            "MaxProtocol" => "TLSv1.2"
+        },
+        client => {
+            "CipherString" => "AES128-GCM-SHA256",
+            extra => {
+                "RenegotiateCiphers" => "AES128-SHA"
+            }
+        },
+        test => {
+            "Method" => "TLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
+    {
+        name => "renegotiate-non-aead-to-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation",
+            "MaxProtocol" => "TLSv1.2"
+        },
+        client => {
+            "CipherString" => "AES128-SHA",
+            extra => {
+                "RenegotiateCiphers" => "AES128-GCM-SHA256"
+            }
+        },
+        test => {
+            "Method" => "TLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
+    {
+        name => "renegotiate-non-aead-to-non-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation",
+            "MaxProtocol" => "TLSv1.2"
+        },
+        client => {
+            "CipherString" => "AES128-SHA",
+            extra => {
+                "RenegotiateCiphers" => "AES256-SHA"
+            }
+        },
+        test => {
+            "Method" => "TLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
+    {
+        name => "renegotiate-aead-to-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation",
+            "MaxProtocol" => "TLSv1.2"
+        },
+        client => {
+            "CipherString" => "AES128-GCM-SHA256",
+            extra => {
+                "RenegotiateCiphers" => "AES256-GCM-SHA384"
+            }
+        },
+        test => {
+            "Method" => "TLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
 );
diff --git a/test/ssl-tests/18-dtls-renegotiate.conf b/test/ssl-tests/18-dtls-renegotiate.conf
index fbde68a..3d8ebd7 100644
--- a/test/ssl-tests/18-dtls-renegotiate.conf
+++ b/test/ssl-tests/18-dtls-renegotiate.conf
@@ -1,12 +1,16 @@
 # Generated with generate_ssl_tests.pl
 
-num_tests = 5
+num_tests = 9
 
 test-0 = 0-renegotiate-client-no-resume
 test-1 = 1-renegotiate-client-resume
 test-2 = 2-renegotiate-server-resume
 test-3 = 3-renegotiate-client-auth-require
 test-4 = 4-renegotiate-client-auth-once
+test-5 = 5-renegotiate-aead-to-non-aead
+test-6 = 6-renegotiate-non-aead-to-aead
+test-7 = 7-renegotiate-non-aead-to-non-aead
+test-8 = 8-renegotiate-aead-to-aead
 # ===========================================================
 
 [0-renegotiate-client-no-resume]
@@ -146,3 +150,127 @@ Method = DTLS
 ResumptionExpected = No
 
 
+# ===========================================================
+
+[5-renegotiate-aead-to-non-aead]
+ssl_conf = 5-renegotiate-aead-to-non-aead-ssl
+
+[5-renegotiate-aead-to-non-aead-ssl]
+server = 5-renegotiate-aead-to-non-aead-server
+client = 5-renegotiate-aead-to-non-aead-client
+
+[5-renegotiate-aead-to-non-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[5-renegotiate-aead-to-non-aead-client]
+CipherString = AES128-GCM-SHA256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-5]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = DTLS
+ResumptionExpected = No
+client = 5-renegotiate-aead-to-non-aead-client-extra
+
+[5-renegotiate-aead-to-non-aead-client-extra]
+RenegotiateCiphers = AES128-SHA
+
+
+# ===========================================================
+
+[6-renegotiate-non-aead-to-aead]
+ssl_conf = 6-renegotiate-non-aead-to-aead-ssl
+
+[6-renegotiate-non-aead-to-aead-ssl]
+server = 6-renegotiate-non-aead-to-aead-server
+client = 6-renegotiate-non-aead-to-aead-client
+
+[6-renegotiate-non-aead-to-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[6-renegotiate-non-aead-to-aead-client]
+CipherString = AES128-SHA
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-6]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = DTLS
+ResumptionExpected = No
+client = 6-renegotiate-non-aead-to-aead-client-extra
+
+[6-renegotiate-non-aead-to-aead-client-extra]
+RenegotiateCiphers = AES128-GCM-SHA256
+
+
+# ===========================================================
+
+[7-renegotiate-non-aead-to-non-aead]
+ssl_conf = 7-renegotiate-non-aead-to-non-aead-ssl
+
+[7-renegotiate-non-aead-to-non-aead-ssl]
+server = 7-renegotiate-non-aead-to-non-aead-server
+client = 7-renegotiate-non-aead-to-non-aead-client
+
+[7-renegotiate-non-aead-to-non-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[7-renegotiate-non-aead-to-non-aead-client]
+CipherString = AES128-SHA
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-7]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = DTLS
+ResumptionExpected = No
+client = 7-renegotiate-non-aead-to-non-aead-client-extra
+
+[7-renegotiate-non-aead-to-non-aead-client-extra]
+RenegotiateCiphers = AES256-SHA
+
+
+# ===========================================================
+
+[8-renegotiate-aead-to-aead]
+ssl_conf = 8-renegotiate-aead-to-aead-ssl
+
+[8-renegotiate-aead-to-aead-ssl]
+server = 8-renegotiate-aead-to-aead-server
+client = 8-renegotiate-aead-to-aead-client
+
+[8-renegotiate-aead-to-aead-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+Options = NoResumptionOnRenegotiation
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[8-renegotiate-aead-to-aead-client]
+CipherString = AES128-GCM-SHA256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-8]
+ExpectedResult = Success
+HandshakeMode = RenegotiateClient
+Method = DTLS
+ResumptionExpected = No
+client = 8-renegotiate-aead-to-aead-client-extra
+
+[8-renegotiate-aead-to-aead-client-extra]
+RenegotiateCiphers = AES256-GCM-SHA384
+
+
diff --git a/test/ssl-tests/18-dtls-renegotiate.conf.in b/test/ssl-tests/18-dtls-renegotiate.conf.in
index 3f877f6..43046e3 100644
--- a/test/ssl-tests/18-dtls-renegotiate.conf.in
+++ b/test/ssl-tests/18-dtls-renegotiate.conf.in
@@ -94,5 +94,77 @@ our @tests = (
             "ResumptionExpected" => "No",
             "ExpectedResult" => "Success"
         }
-    }
+    },
+    {
+        name => "renegotiate-aead-to-non-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation"
+        },
+        client => {
+            "CipherString" => "AES128-GCM-SHA256",
+            extra => {
+                "RenegotiateCiphers" => "AES128-SHA"
+            }
+        },
+        test => {
+            "Method" => "DTLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
+    {
+        name => "renegotiate-non-aead-to-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation"
+        },
+        client => {
+            "CipherString" => "AES128-SHA",
+            extra => {
+                "RenegotiateCiphers" => "AES128-GCM-SHA256"
+            }
+        },
+        test => {
+            "Method" => "DTLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
+    {
+        name => "renegotiate-non-aead-to-non-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation"
+        },
+        client => {
+            "CipherString" => "AES128-SHA",
+            extra => {
+                "RenegotiateCiphers" => "AES256-SHA"
+            }
+        },
+        test => {
+            "Method" => "DTLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
+    {
+        name => "renegotiate-aead-to-aead",
+        server => {
+            "Options" => "NoResumptionOnRenegotiation"
+        },
+        client => {
+            "CipherString" => "AES128-GCM-SHA256",
+            extra => {
+                "RenegotiateCiphers" => "AES256-GCM-SHA384"
+            }
+        },
+        test => {
+            "Method" => "DTLS",
+            "HandshakeMode" => "RenegotiateClient",
+            "ResumptionExpected" => "No",
+            "ExpectedResult" => "Success"
+        }
+    },
 );
diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c
index 09e7a89..c21decf 100644
--- a/test/ssl_test_ctx.c
+++ b/test/ssl_test_ctx.c
@@ -88,9 +88,7 @@ static const char *enum_name(const test_enum *enums, size_t num_enums,
 }
 
 
-/*******************/
-/* ExpectedResult. */
-/*******************/
+/* ExpectedResult */
 
 static const test_enum ssl_test_results[] = {
     {"Success", SSL_TEST_SUCCESS},
@@ -115,9 +113,7 @@ const char *ssl_test_result_name(ssl_test_result_t result)
     return enum_name(ssl_test_results, OSSL_NELEM(ssl_test_results), result);
 }
 
-/**********************************************/
-/* ExpectedClientAlert / ExpectedServerAlert. */
-/**********************************************/
+/* ExpectedClientAlert / ExpectedServerAlert */
 
 static const test_enum ssl_alerts[] = {
     {"UnknownCA", SSL_AD_UNKNOWN_CA},
@@ -147,9 +143,7 @@ const char *ssl_alert_name(int alert)
     return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert);
 }
 
-/********************/
 /* ExpectedProtocol */
-/********************/
 
 static const test_enum ssl_protocols[] = {
      {"TLSv1.2", TLS1_2_VERSION},
@@ -171,9 +165,7 @@ const char *ssl_protocol_name(int protocol)
     return enum_name(ssl_protocols, OSSL_NELEM(ssl_protocols), protocol);
 }
 
-/***********************/
-/* VerifyCallback.     */
-/***********************/
+/* VerifyCallback */
 
 static const test_enum ssl_verify_callbacks[] = {
     {"None", SSL_TEST_VERIFY_NONE},
@@ -199,9 +191,7 @@ const char *ssl_verify_callback_name(ssl_verify_callback_t callback)
                      callback);
 }
 
-/**************/
 /* ServerName */
-/**************/
 
 static const test_enum ssl_servername[] = {
     {"None", SSL_TEST_SERVERNAME_NONE},
@@ -240,9 +230,7 @@ const char *ssl_servername_name(ssl_servername_t server)
                      server);
 }
 
-/**********************/
 /* ServerNameCallback */
-/**********************/
 
 static const test_enum ssl_servername_callbacks[] = {
     {"None", SSL_TEST_SERVERNAME_CB_NONE},
@@ -268,9 +256,7 @@ const char *ssl_servername_callback_name(ssl_servername_callback_t callback)
                      OSSL_NELEM(ssl_servername_callbacks), callback);
 }
 
-/*************************/
 /* SessionTicketExpected */
-/*************************/
 
 static const test_enum ssl_session_ticket[] = {
     {"Ignore", SSL_TEST_SESSION_TICKET_IGNORE},
@@ -296,9 +282,7 @@ const char *ssl_session_ticket_name(ssl_session_ticket_t server)
                      server);
 }
 
-/***********************/
-/* Method              */
-/***********************/
+/* Method */
 
 static const test_enum ssl_test_methods[] = {
     {"TLS", SSL_TEST_METHOD_TLS},
@@ -321,9 +305,7 @@ const char *ssl_test_method_name(ssl_test_method_t method)
     return enum_name(ssl_test_methods, OSSL_NELEM(ssl_test_methods), method);
 }
 
-/************************************/
-/* NPN and ALPN options             */
-/************************************/
+/* NPN and ALPN options */
 
 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, npn_protocols)
 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, npn_protocols)
@@ -332,9 +314,7 @@ IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, alpn_protocols)
 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, alpn_protocols)
 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_alpn_protocol)
 
-/***********************/
-/* Handshake mode      */
-/***********************/
+/* Handshake mode */
 
 static const test_enum ssl_handshake_modes[] = {
     {"Simple", SSL_TEST_HANDSHAKE_SIMPLE},
@@ -360,9 +340,11 @@ const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode)
                      mode);
 }
 
-/***********************/
-/* CT Validation       */
-/***********************/
+/* Renegotiation Ciphersuites */
+
+IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, reneg_ciphers)
+
+/* CT Validation */
 
 static const test_enum ssl_ct_validation_modes[] = {
     {"None", SSL_TEST_CT_VALIDATION_NONE},
@@ -391,9 +373,7 @@ const char *ssl_ct_validation_name(ssl_ct_validation_t mode)
 IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, resumption_expected)
 IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, broken_session_ticket)
 
-/**************/
 /* CertStatus */
-/**************/
 
 static const test_enum ssl_certstatus[] = {
     {"None", SSL_TEST_CERT_STATUS_NONE},
@@ -419,21 +399,17 @@ const char *ssl_certstatus_name(ssl_cert_status_t cert_status)
                      OSSL_NELEM(ssl_certstatus), cert_status);
 }
 
-/***********************/
-/* ApplicationData     */
-/***********************/
+/* ApplicationData */
 
 IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, app_data_size)
 
-/***********************/
-/* MaxFragmentSize     */
-/***********************/
+
+/* MaxFragmentSize */
 
 IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, max_fragment_size)
 
-/***********************/
-/* ExpectedTmpKeyType  */
-/***********************/
+
+/* ExpectedTmpKeyType */
 
 __owur static int parse_expected_tmp_key_type(SSL_TEST_CTX *test_ctx,
                                               const char *value)
@@ -455,9 +431,7 @@ __owur static int parse_expected_tmp_key_type(SSL_TEST_CTX *test_ctx,
     return 1;
 }
 
-/*************************************************************/
 /* Known test options and their corresponding parse methods. */
-/*************************************************************/
 
 /* Top-level options. */
 typedef struct {
@@ -494,6 +468,7 @@ static const ssl_test_client_option ssl_test_client_options[] = {
     { "NPNProtocols", &parse_client_npn_protocols },
     { "ALPNProtocols", &parse_client_alpn_protocols },
     { "CTValidation", &parse_ct_validation },
+    { "RenegotiateCiphers", &parse_client_reneg_ciphers},
 };
 
 /* Nested server options. */
diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h
index 995d518..28a4566 100644
--- a/test/ssl_test_ctx.h
+++ b/test/ssl_test_ctx.h
@@ -84,6 +84,8 @@ typedef struct {
     char *npn_protocols;
     char *alpn_protocols;
     ssl_ct_validation_t ct_validation;
+    /* Ciphersuites to set on a renegotiation */
+    char *reneg_ciphers;
 } SSL_TEST_CLIENT_CONF;
 
 typedef struct {


More information about the openssl-commits mailing list