[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Thu Nov 10 14:16:08 UTC 2016


The branch master has been updated
       via  6a69e8694af23dae1d1927813932f4296d133416 (commit)
       via  f07d639edf849413e24845301fd514ff4a606000 (commit)
       via  9d7ce8d42b80fda2566c70f0d4de4069bb34e72c (commit)
       via  70d8b304d01b9e0c4ec182db20c33aa0698cda51 (commit)
       via  c5a569927fb7bcfa34dde76dbc021d4f8a5c8fb1 (commit)
       via  a378a46985698bf2576b2990e7faf21f62dd176a (commit)
       via  f962541d0be200055e508641ddf3a8ec8819e4df (commit)
       via  bf52165bda53524a267c784696bd074111a2f178 (commit)
      from  a54aba531327285f64cf13a909bc129e9f9d5970 (commit)


- Log -----------------------------------------------------------------
commit 6a69e8694af23dae1d1927813932f4296d133416
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Nov 10 11:49:06 2016 +0000

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

commit f07d639edf849413e24845301fd514ff4a606000
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Nov 10 11:27:07 2016 +0000

    Fix the no-tls option
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit 9d7ce8d42b80fda2566c70f0d4de4069bb34e72c
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Nov 10 01:49:47 2016 +0100

    Fix no-cms (CVE-2016-7053)
    
    Reviewed-by: Matt Caswell <matt at openssl.org>

commit 70d8b304d01b9e0c4ec182db20c33aa0698cda51
Author: Andy Polyakov <appro at openssl.org>
Date:   Tue Nov 1 22:06:42 2016 +0100

    test/evptests.txt: add negative tests for AEAD ciphers.
    
    This is done by taking one vector, "corrupting" last bit of the
    tag value and verifying that decrypt fails.
    
    Reviewed-by: Emilia Käsper <emilia at openssl.org>

commit c5a569927fb7bcfa34dde76dbc021d4f8a5c8fb1
Author: Andy Polyakov <appro at openssl.org>
Date:   Mon Oct 31 21:50:26 2016 +0100

    test: add TLS application data corruption test.
    
    Reviewed-by: Emilia Käsper <emilia at openssl.org>

commit a378a46985698bf2576b2990e7faf21f62dd176a
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Oct 14 12:02:12 2016 +0100

    add test for CVE-2016-7053
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit f962541d0be200055e508641ddf3a8ec8819e4df
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Oct 14 11:51:43 2016 +0100

    Don't set choice selector on parse failure.
    
    Don't set choice selector on parse failure: this can pass unexpected
    values to the choice callback. Instead free up partial structure
    directly.
    
    CVE-2016-7053
    
    Thanks to Tyler Nighswander of ForAllSecure for reporting this issue.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

commit bf52165bda53524a267c784696bd074111a2f178
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Nov 4 14:21:46 2016 +0100

    chacha20/poly1305: make sure to clear the buffer at correct position
    
    The offset to the memory to clear was incorrect, causing a heap buffer
    overflow.
    
    CVE-2016-7054
    
    Thanks to Robert Święcki for reporting this
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

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

Summary of changes:
 CHANGES                                            |  46 ++++
 NEWS                                               |   3 +
 crypto/asn1/tasn_dec.c                             |  14 +-
 crypto/evp/e_chacha20_poly1305.c                   |   2 +-
 test/build.info                                    |   6 +-
 test/d2i-tests/bad-cms.der                         |   1 +
 test/evptests.txt                                  |  59 +++++
 test/recipes/25-test_d2i.t                         |  14 +-
 test/recipes/80-test_ssl_new.t                     |   2 +-
 .../{90-test_sslapi.t => 80-test_sslcorrupt.t}     |  11 +-
 test/sslcorrupttest.c                              | 282 +++++++++++++++++++++
 test/ssltestlib.c                                  |   4 +
 12 files changed, 427 insertions(+), 17 deletions(-)
 create mode 100644 test/d2i-tests/bad-cms.der
 copy test/recipes/{90-test_sslapi.t => 80-test_sslcorrupt.t} (58%)
 create mode 100644 test/sslcorrupttest.c

diff --git a/CHANGES b/CHANGES
index ba661db..518a70b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,52 @@
 
  Changes between 1.1.0b and 1.1.0c [xx XXX xxxx]
 
+  *) ChaCha20/Poly1305 heap-buffer-overflow
+
+     TLS connections using *-CHACHA20-POLY1305 ciphersuites are susceptible to
+     a DoS attack by corrupting larger payloads. This can result in an OpenSSL
+     crash. This issue is not considered to be exploitable beyond a DoS.
+
+     This issue was reported to OpenSSL by Robert Święcki (Google Security Team)
+     (CVE-2016-7054)
+     [Richard Levitte]
+
+  *) CMS Null dereference
+
+     Applications parsing invalid CMS structures can crash with a NULL pointer
+     dereference. This is caused by a bug in the handling of the ASN.1 CHOICE
+     type in OpenSSL 1.1.0 which can result in a NULL value being passed to the
+     structure callback if an attempt is made to free certain invalid encodings.
+     Only CHOICE structures using a callback which do not handle NULL value are
+     affected.
+
+     This issue was reported to OpenSSL by Tyler Nighswander of ForAllSecure.
+     (CVE-2016-7053)
+     [Stephen Henson]
+
+  *) Montgomery multiplication may produce incorrect results
+
+     There is a carry propagating bug in the Broadwell-specific Montgomery
+     multiplication procedure that handles input lengths divisible by, but
+     longer than 256 bits. Analysis suggests that attacks against RSA, DSA
+     and DH private keys are impossible. This is because the subroutine in
+     question is not used in operations with the private key itself and an input
+     of the attacker's direct choice. Otherwise the bug can manifest itself as
+     transient authentication and key negotiation failures or reproducible
+     erroneous outcome of public-key operations with specially crafted input.
+     Among EC algorithms only Brainpool P-512 curves are affected and one
+     presumably can attack ECDH key negotiation. Impact was not analyzed in
+     detail, because pre-requisites for attack are considered unlikely. Namely
+     multiple clients have to choose the curve in question and the server has to
+     share the private key among them, neither of which is default behaviour.
+     Even then only clients that chose the curve will be affected.
+
+     This issue was publicly reported as transient failures and was not
+     initially recognized as a security issue. Thanks to Richard Morgan for
+     providing reproducible case.
+     (CVE-2016-7055)
+     [Andy Polyakov]
+
   *) Removed automatic addition of RPATH in shared libraries and executables,
      as this was a remainder from OpenSSL 1.0.x and isn't needed any more.
      [Richard Levitte]
diff --git a/NEWS b/NEWS
index 82d1cb1..e88c5f4 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,9 @@
 
   Major changes between OpenSSL 1.1.0a and OpenSSL 1.1.0b [26 Sep 2016]
 
+      o ChaCha20/Poly1305 heap-buffer-overflow (CVE-2016-7054)
+      o CMS Null dereference (CVE-2016-7053)
+      o Montgomery multiplication may produce incorrect results (CVE-2016-7055)
       o Fix Use After Free for large message sizes (CVE-2016-6309)
 
   Major changes between OpenSSL 1.1.0 and OpenSSL 1.1.0a [22 Sep 2016]
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 679a50d..c9b6375 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -225,16 +225,14 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
             /* If field not present, try the next one */
             if (ret == -1)
                 continue;
-            /*
-             * Set the choice selector here to ensure that the value is
-             * correctly freed upon error. It may be partially initialized
-             * even if parsing failed.
-             */
-            asn1_set_choice_selector(pval, i, it);
             /* If positive return, read OK, break loop */
             if (ret > 0)
                 break;
-            /* Otherwise must be an ASN1 parsing error */
+            /*
+             * Must be an ASN1 parsing error.
+             * Free up any partial choice value
+             */
+            asn1_template_free(pchptr, tt);
             errtt = tt;
             ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
             goto err;
@@ -252,6 +250,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
             goto err;
         }
 
+        asn1_set_choice_selector(pval, i, it);
+
         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
             goto auxerr;
         *in = p;
diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c
index cf4097b..952bd3f 100644
--- a/crypto/evp/e_chacha20_poly1305.c
+++ b/crypto/evp/e_chacha20_poly1305.c
@@ -299,7 +299,7 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                 memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
             } else {
                 if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) {
-                    memset(out, 0, plen);
+                    memset(out - plen, 0, plen);
                     return -1;
                 }
             }
diff --git a/test/build.info b/test/build.info
index 0ec31d9..f51866a 100644
--- a/test/build.info
+++ b/test/build.info
@@ -24,7 +24,7 @@ IF[{- !$disabled{tests} -}]
           packettest asynctest secmemtest srptest memleaktest \
           dtlsv1listentest ct_test threadstest afalgtest d2i_test \
           ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \
-          bioprinttest sslapitest dtlstest bio_enc_test
+          bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test
 
   SOURCE[aborttest]=aborttest.c
   INCLUDE[aborttest]=../include
@@ -279,6 +279,10 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[dtlstest]=../include .
   DEPEND[dtlstest]=../libcrypto ../libssl
 
+  SOURCE[sslcorrupttest]=sslcorrupttest.c ssltestlib.c testutil.c
+  INCLUDE[sslcorrupttest]=../include .
+  DEPEND[sslcorrupttest]=../libcrypto ../libssl
+
   SOURCE[bio_enc_test]=bio_enc_test.c
   INCLUDE[bio_enc_test]=../include
   DEPEND[bio_enc_test]=../libcrypto
diff --git a/test/d2i-tests/bad-cms.der b/test/d2i-tests/bad-cms.der
new file mode 100644
index 0000000..19cd3cc
--- /dev/null
+++ b/test/d2i-tests/bad-cms.der
@@ -0,0 +1 @@
+0	*†H†÷
 	010
\ No newline at end of file
diff --git a/test/evptests.txt b/test/evptests.txt
index 5c427b3..173f0df 100644
--- a/test/evptests.txt
+++ b/test/evptests.txt
@@ -1602,6 +1602,15 @@ Tag = 2024931d73bca480c24a24ece6b6c2bf
 Plaintext = 53bd72a97089e312422bf72e242377b3c6ee3e2075389b999c4ef7f28bd2b80a
 Ciphertext = 9a5fcccdb4cf04e7293d2775cc76a488f042382d949b43b7d6bb2b9864786726
 
+Cipher = aes-256-ccm
+Key = 1bde3251d41a8b5ea013c195ae128b218b3e0306376357077ef1c1c78548b92e
+IV = 5b8e40746f6b98e00f1d13ff41
+AAD = c17a32514eb6103f3249e076d4c871dc97e04b286699e54491dc18f6d734d4c0
+Tag = 2024931d73bca480c24a24ece6b6c2be
+Plaintext = 53bd72a97089e312422bf72e242377b3c6ee3e2075389b999c4ef7f28bd2b80a
+Ciphertext = 9a5fcccdb4cf04e7293d2775cc76a488f042382d949b43b7d6bb2b9864786726
+Operation = DECRYPT
+Result = CIPHERUPDATE_ERROR
 
 # AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
 Cipher = aes-128-gcm
@@ -1652,6 +1661,16 @@ Tag = 619cc5aefffe0bfa462af43c1699d050
 Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
 Ciphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
 
+Cipher = aes-128-gcm
+Key = feffe9928665731c6d6a8f9467308308
+IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = 619cc5aefffe0bfa462af43c1699d051
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
+Operation = DECRYPT
+Result = CIPHERFINAL_ERROR
+
 Cipher = aes-192-gcm
 Key = 000000000000000000000000000000000000000000000000
 IV = 000000000000000000000000
@@ -1700,6 +1719,16 @@ Tag = dcf566ff291c25bbb8568fc3d376a6d9
 Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
 Ciphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b
 
+Cipher = aes-192-gcm
+Key = feffe9928665731c6d6a8f9467308308feffe9928665731c
+IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = dcf566ff291c25bbb8568fc3d376a6d8
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b
+Operation = DECRYPT
+Result = CIPHERFINAL_ERROR
+
 Cipher = aes-256-gcm
 Key = 0000000000000000000000000000000000000000000000000000000000000000
 IV = 000000000000000000000000
@@ -1748,6 +1777,16 @@ Tag = a44a8266ee1c8eb0c8b5d4cf5ae9f19a
 Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
 Ciphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
 
+Cipher = aes-256-gcm
+Key = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = a44a8266ee1c8eb0c8b5d4cf5ae9f19b
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
+Operation = DECRYPT
+Result = CIPHERFINAL_ERROR
+
 # local add-ons, primarily streaming ghash tests
 # 128 bytes aad
 Cipher = aes-128-gcm
@@ -2007,6 +2046,16 @@ Tag = 3E52A01D068DE85456DB03B7
 Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071
 Ciphertext = 09A4FD29DE949D9A9AA9924248422097AD4883B4713E6C214FF6567ADA08A967B2176C12F110DD441B7CAA3A509B13C86A023AFCEE998BEE42028D44507B15F77C528A1DE6406B519BCEE8FCB829417001E54E15A7576C4DF32366E0F439C7051CB4824B8114E9A720CBC1CE0185B156B486
 
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000102030405060708090A0B
+AAD = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+Tag = 3E52A01D068DE85456DB03B6
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071
+Ciphertext = 09A4FD29DE949D9A9AA9924248422097AD4883B4713E6C214FF6567ADA08A967B2176C12F110DD441B7CAA3A509B13C86A023AFCEE998BEE42028D44507B15F77C528A1DE6406B519BCEE8FCB829417001E54E15A7576C4DF32366E0F439C7051CB4824B8114E9A720CBC1CE0185B156B486
+Operation = DECRYPT
+Result = CIPHERFINAL_ERROR
+
 # AES XTS test vectors from IEEE Std 1619-2007
 Cipher = aes-128-xts
 Key = 0000000000000000000000000000000000000000000000000000000000000000
@@ -3306,6 +3355,16 @@ Tag = eead9d67890cbb22392336fea1851f38
 Plaintext = 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d
 Ciphertext = 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b
 
+Cipher = chacha20-poly1305
+Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0
+IV = 000000000102030405060708
+AAD = f33388860000000000004e91
+Tag = eead9d67890cbb22392336fea1851f39
+Plaintext = 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d
+Ciphertext = 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b
+Operation = DECRYPT
+Result = CIPHERFINAL_ERROR
+
 # TLS1 PRF tests, from NIST test vectors
 
 KDF=TLS1-PRF
diff --git a/test/recipes/25-test_d2i.t b/test/recipes/25-test_d2i.t
index 9db0b2b..688c8ed 100644
--- a/test/recipes/25-test_d2i.t
+++ b/test/recipes/25-test_d2i.t
@@ -12,10 +12,11 @@ use warnings;
 
 use File::Spec;
 use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test::Utils;
 
 setup("test_d2i");
 
-plan tests => 13;
+plan tests => 14;
 
 ok(run(test(["d2i_test", "X509", "decode",
              srctop_file('test','d2i-tests','bad_cert.der')])),
@@ -79,3 +80,14 @@ ok(run(test(["d2i_test", "ASN1_INTEGER", "decode",
 ok(run(test(["d2i_test", "ASN1_INTEGER", "decode",
              srctop_file('test','d2i-tests','bad-int-padminus1.der')])),
    "Running d2i_test bad-int-padminus1.der INTEGER");
+
+SKIP: {
+  skip "No CMS support in this configuration", 1 if disabled("cms");
+
+  # Invalid CMS structure with decode error in CHOICE value.
+  # Test for CVE-2016-7053
+
+  ok(run(test(["d2i_test", "CMS_ContentInfo", "decode",
+               srctop_file('test','d2i-tests','bad-cms.der')])),
+     "Running d2i_test bad-cms.der CMS ContentInfo");
+}
diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t
index 1e92907..d89aa3c 100644
--- a/test/recipes/80-test_ssl_new.t
+++ b/test/recipes/80-test_ssl_new.t
@@ -72,7 +72,7 @@ my %skip = (
   # We should review this once we have TLS 1.3.
   "13-fragmentation.conf" => disabled("tls1_2"),
   "14-curves.conf" => disabled("tls1_2") || $no_ec || $no_ec2m,
-  "15-certstatus.conf" => $no_ocsp,
+  "15-certstatus.conf" => $no_tls || $no_ocsp,
   "16-dtls-certstatus.conf" => $no_dtls || $no_ocsp,
   "18-dtls-renegotiate.conf" => $no_dtls,
 );
diff --git a/test/recipes/90-test_sslapi.t b/test/recipes/80-test_sslcorrupt.t
similarity index 58%
copy from test/recipes/90-test_sslapi.t
copy to test/recipes/80-test_sslcorrupt.t
index efaae3b..53f8a82 100644
--- a/test/recipes/90-test_sslapi.t
+++ b/test/recipes/80-test_sslcorrupt.t
@@ -6,16 +6,15 @@
 # in the file LICENSE in the source distribution or at
 # https://www.openssl.org/source/license.html
 
-
 use OpenSSL::Test::Utils;
 use OpenSSL::Test qw/:DEFAULT srctop_file/;
 
-setup("test_sslapi");
+setup("test_sslcorrupt");
 
-plan skip_all => "No TLS/SSL protocols are supported by this OpenSSL build"
-    if alldisabled(grep { $_ ne "ssl3" } available_protocols("tls"));
+plan skip_all => "No TLS protocols are supported by this OpenSSL build"
+    if alldisabled(available_protocols("tls"));
 
 plan tests => 1;
 
-ok(run(test(["sslapitest", srctop_file("apps", "server.pem"),
-             srctop_file("apps", "server.pem")])), "running sslapitest");
+ok(run(test(["sslcorrupttest", srctop_file("apps", "server.pem"),
+             srctop_file("apps", "server.pem")])), "running sslcorrupttest");
diff --git a/test/sslcorrupttest.c b/test/sslcorrupttest.c
new file mode 100644
index 0000000..34ac8f7
--- /dev/null
+++ b/test/sslcorrupttest.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "ssltestlib.h"
+#include "testutil.h"
+
+static void copy_flags(BIO *bio)
+{
+    int flags;
+    BIO *next = BIO_next(bio);
+
+    flags = BIO_test_flags(next, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
+    BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
+    BIO_set_flags(bio, flags);
+}
+
+static int tls_corrupt_read(BIO *bio, char *out, int outl)
+{
+    int ret;
+    BIO *next = BIO_next(bio);
+
+    ret = BIO_read(next, out, outl);
+    copy_flags(bio);
+
+    return ret;
+}
+
+static int tls_corrupt_write(BIO *bio, const char *in, int inl)
+{
+    int ret;
+    BIO *next = BIO_next(bio);
+    char *copy;
+
+    if (in[0] == SSL3_RT_APPLICATION_DATA) {
+        copy = BUF_memdup(in, inl);
+        TEST_check(copy != NULL);
+        /* corrupt last bit of application data */
+        copy[inl-1] ^= 1;
+        ret = BIO_write(next, copy, inl);
+        OPENSSL_free(copy);
+    } else {
+        ret = BIO_write(next, in, inl);
+    }
+    copy_flags(bio);
+
+    return ret;
+}
+
+static long tls_corrupt_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+    long ret;
+    BIO *next = BIO_next(bio);
+
+    if (next == NULL)
+        return 0;
+
+    switch (cmd) {
+    case BIO_CTRL_DUP:
+        ret = 0L;
+        break;
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    }
+    return ret;
+}
+
+static int tls_corrupt_gets(BIO *bio, char *buf, int size)
+{
+    /* We don't support this - not needed anyway */
+    return -1;
+}
+
+static int tls_corrupt_puts(BIO *bio, const char *str)
+{
+    /* We don't support this - not needed anyway */
+    return -1;
+}
+
+static int tls_corrupt_new(BIO *bio)
+{
+    BIO_set_init(bio, 1);
+
+    return 1;
+}
+
+static int tls_corrupt_free(BIO *bio)
+{
+    BIO_set_init(bio, 0);
+
+    return 1;
+}
+
+#define BIO_TYPE_CUSTOM_FILTER  (0x80 | BIO_TYPE_FILTER)
+
+static BIO_METHOD *method_tls_corrupt = NULL;
+
+/* Note: Not thread safe! */
+static const BIO_METHOD *bio_f_tls_corrupt_filter(void)
+{
+    if (method_tls_corrupt == NULL) {
+        method_tls_corrupt = BIO_meth_new(BIO_TYPE_CUSTOM_FILTER,
+                                          "TLS corrupt filter");
+        if (   method_tls_corrupt == NULL
+            || !BIO_meth_set_write(method_tls_corrupt, tls_corrupt_write)
+            || !BIO_meth_set_read(method_tls_corrupt, tls_corrupt_read)
+            || !BIO_meth_set_puts(method_tls_corrupt, tls_corrupt_puts)
+            || !BIO_meth_set_gets(method_tls_corrupt, tls_corrupt_gets)
+            || !BIO_meth_set_ctrl(method_tls_corrupt, tls_corrupt_ctrl)
+            || !BIO_meth_set_create(method_tls_corrupt, tls_corrupt_new)
+            || !BIO_meth_set_destroy(method_tls_corrupt, tls_corrupt_free))
+            return NULL;
+    }
+    return method_tls_corrupt;
+}
+
+static void bio_f_tls_corrupt_filter_free(void)
+{
+    BIO_meth_free(method_tls_corrupt);
+}
+
+/*
+ * The test is supposed to be executed with RSA key, customarily
+ * with apps/server.pem used even in other tests. For this reason
+ * |cipher_list| is initialized with RSA ciphers' names. This
+ * naturally means that if test is to be re-purposed for other
+ * type of key, then NID_auth_* filter below would need adjustment.
+ */
+static const char **cipher_list = NULL;
+
+static int setup_cipher_list()
+{
+    SSL_CTX *ctx = NULL;
+    SSL *ssl = NULL;
+    static STACK_OF(SSL_CIPHER) *sk_ciphers = NULL;
+    int i, numciphers;
+
+    ctx = SSL_CTX_new(TLS_server_method());
+    TEST_check(ctx != NULL);
+    ssl = SSL_new(ctx);
+    TEST_check(ssl != NULL);
+    sk_ciphers = SSL_get1_supported_ciphers(ssl);
+    TEST_check(sk_ciphers != NULL);
+
+    /*
+     * The |cipher_list| will be filled only with names of RSA ciphers,
+     * so that some of the allocated space will be wasted, but the loss
+     * is deemed acceptable...
+     */
+    cipher_list = OPENSSL_malloc(sk_SSL_CIPHER_num(sk_ciphers) *
+                                 sizeof(cipher_list[0]));
+    TEST_check(cipher_list != NULL);
+
+    for (numciphers = 0, i = 0; i < sk_SSL_CIPHER_num(sk_ciphers); i++) {
+        const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(sk_ciphers, i);
+
+        if (SSL_CIPHER_get_auth_nid(cipher) == NID_auth_rsa)
+            cipher_list[numciphers++] = SSL_CIPHER_get_name(cipher);
+    }
+    TEST_check(numciphers != 0);
+
+    sk_SSL_CIPHER_free(sk_ciphers);
+    SSL_free(ssl);
+    SSL_CTX_free(ctx);
+
+    return numciphers;
+}
+
+static char *cert = NULL;
+static char *privkey = NULL;
+
+static int test_ssl_corrupt(int testidx)
+{
+    SSL_CTX *sctx = NULL, *cctx = NULL;
+    SSL *server = NULL, *client = NULL;
+    BIO *c_to_s_fbio;
+    int testresult = 0;
+    static unsigned char junk[16000] = { 0 };
+
+    printf("Starting Test %d, %s\n", testidx, cipher_list[testidx]);
+
+    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
+                             &cctx, cert, privkey)) {
+        printf("Unable to create SSL_CTX pair\n");
+        return 0;
+    }
+
+    if (!SSL_CTX_set_cipher_list(cctx, cipher_list[testidx])) {
+        printf("Failed setting cipher list\n");
+        goto end;
+    }
+
+    c_to_s_fbio = BIO_new(bio_f_tls_corrupt_filter());
+    if (c_to_s_fbio == NULL) {
+        printf("Failed to create filter BIO\n");
+        goto end;
+    }
+
+    /* BIO is freed by create_ssl_connection on error */
+    if (!create_ssl_objects(sctx, cctx, &server, &client, NULL,
+                            c_to_s_fbio)) {
+        printf("Unable to create SSL objects\n");
+        ERR_print_errors_fp(stdout);
+        goto end;
+    }
+
+    if (!create_ssl_connection(server, client)) {
+        printf("Unable to create SSL connection\n");
+        ERR_print_errors_fp(stdout);
+        goto end;
+    }
+
+    if (SSL_write(client, junk, sizeof(junk)) < 0) {
+        printf("Unable to SSL_write\n");
+        ERR_print_errors_fp(stdout);
+        goto end;
+    }
+
+    if (SSL_read(server, junk, sizeof(junk)) >= 0) {
+        printf("Read should have failed with \"bad record mac\"\n");
+        goto end;
+    }
+
+    if (ERR_GET_REASON(ERR_peek_error()) !=
+        SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC) {
+        ERR_print_errors_fp(stdout);
+        goto end;
+    }
+
+    testresult = 1;
+ end:
+    SSL_free(server);
+    SSL_free(client);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+
+    return testresult;
+}
+
+int main(int argc, char *argv[])
+{
+    BIO *err = NULL;
+    int testresult = 1;
+
+    if (argc != 3) {
+        printf("Invalid argument count\n");
+        return 1;
+    }
+
+    cert = argv[1];
+    privkey = argv[2];
+
+    err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+
+    CRYPTO_set_mem_debug(1);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+    ADD_ALL_TESTS(test_ssl_corrupt, setup_cipher_list());
+
+    testresult = run_tests(argv[0]);
+
+    bio_f_tls_corrupt_filter_free();
+
+    OPENSSL_free(cipher_list);
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    if (CRYPTO_mem_leaks(err) <= 0)
+        testresult = 1;
+#endif
+    BIO_free(err);
+
+    if (!testresult)
+        printf("PASS\n");
+
+    return testresult;
+}
diff --git a/test/ssltestlib.c b/test/ssltestlib.c
index 655fc05..4e20763 100644
--- a/test/ssltestlib.c
+++ b/test/ssltestlib.c
@@ -550,6 +550,10 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
         goto err;
     }
 
+#ifndef OPENSSL_NO_DH
+    SSL_CTX_set_dh_auto(serverctx, 1);
+#endif
+
     *sctx = serverctx;
     *cctx = clientctx;
 


More information about the openssl-commits mailing list