Bug 1304407 - Update beta to NSS 3.26.2 a=ritu
authorWes Kocher <wkocher@mozilla.com>
Mon, 10 Oct 2016 14:27:24 -0700
changeset 428787 f48198e165031b2741df8b64367b65a63c17a263
parent 428786 0c41036b9e63facf1beb52b8ced744d525ca77d1
child 428788 70abfe99097824fd510544b188f24c588fd6d5a0
push id33416
push userpaul@paul.cx
push dateMon, 24 Oct 2016 16:26:20 +0000
reviewersritu
bugs1304407
milestone50.0
Bug 1304407 - Update beta to NSS 3.26.2 a=ritu
security/nss/TAG-INFO
security/nss/coreconf/coreconf.dep
security/nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
security/nss/external_tests/ssl_gtest/tls_parser.h
security/nss/lib/nss/nss.h
security/nss/lib/softoken/softkver.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/util/nssutil.h
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_26_1_RTM
+NSS_3_26_2_RTM
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
@@ -17,16 +17,48 @@ extern "C" {
 #include "scoped_ptrs.h"
 #include "tls_parser.h"
 #include "tls_filter.h"
 #include "tls_connect.h"
 #include "gtest_utils.h"
 
 namespace nss_test {
 
+class TlsInspectorCertificateRequestSigAlgSetter : public TlsHandshakeFilter {
+ public:
+  TlsInspectorCertificateRequestSigAlgSetter(SSLSignatureAndHashAlg sig_alg)
+    : sig_alg_(sig_alg) {}
+
+  virtual PacketFilter::Action FilterHandshake(
+      const HandshakeHeader& header,
+      const DataBuffer& input, DataBuffer* output) {
+    if (header.handshake_type() != kTlsHandshakeCertificateRequest) {
+      return KEEP;
+    }
+
+    TlsParser parser(input);
+    *output = input;
+
+    // Skip certificate types.
+    parser.SkipVariable(1);
+
+    // Skip sig algs length.
+    parser.Skip(2);
+
+    // Write signature algorithm.
+    output->Write(parser.consumed(), sig_alg_.hashAlg, 1);
+    output->Write(parser.consumed() + 1, sig_alg_.sigAlg, 1);
+
+    return CHANGE;
+  }
+
+ private:
+  SSLSignatureAndHashAlg sig_alg_;
+};
+
 TEST_P(TlsConnectGeneric, ClientAuth) {
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
 }
 
 // In TLS 1.3, the client sends its cert rejection on the
@@ -332,9 +364,46 @@ TEST_P(TlsConnectGenericPre13, AuthCompl
         client_->SendData(10);
       }));
 
   Connect();
   server_->SendData(10);
   Receive(10);
 }
 
+TEST_P(TlsConnectTls12, ClientAuthNoMatchingSigAlgs) {
+  Reset(TlsAgent::kServerEcdsa);
+  server_->RequestClientAuth(false);
+  client_->SetupClientAuth();
+
+  server_->EnableCiphersByAuthType(ssl_auth_ecdh_ecdsa);
+  server_->SetSignatureAlgorithms(SignatureEcdsaSha256,
+                                  PR_ARRAY_SIZE(SignatureEcdsaSha256));
+
+  Connect();
+  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+  EXPECT_TRUE(!SSL_PeerCertificate(server_->ssl_fd()));
 }
+
+TEST_P(TlsConnectTls12, CertificateRequestMd5) {
+  const SSLSignatureAndHashAlg md5_sig_alg = {ssl_hash_md5, ssl_sign_rsa};
+
+  const SSLSignatureAndHashAlg serverAlgorithms[] = {
+    {ssl_hash_sha1, ssl_sign_rsa},
+    {ssl_hash_sha256, ssl_sign_rsa}
+  };
+
+  client_->SetupClientAuth();
+  server_->RequestClientAuth(true);
+  server_->SetPacketFilter(new TlsInspectorCertificateRequestSigAlgSetter
+                           (md5_sig_alg));
+  server_->SetSignatureAlgorithms(serverAlgorithms,
+                                  PR_ARRAY_SIZE(serverAlgorithms));
+
+  client_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384);
+  server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384);
+
+  ConnectExpectFail();
+  ASSERT_EQ(SEC_ERROR_BAD_SIGNATURE, server_->error_code());
+  ASSERT_EQ(SSL_ERROR_DECRYPT_ERROR_ALERT, client_->error_code());
+}
+
+}
--- a/security/nss/external_tests/ssl_gtest/tls_parser.h
+++ b/security/nss/external_tests/ssl_gtest/tls_parser.h
@@ -24,16 +24,17 @@ const uint8_t kTlsAlertType = 21;
 const uint8_t kTlsHandshakeType = 22;
 const uint8_t kTlsApplicationDataType = 23;
 
 const uint8_t kTlsHandshakeClientHello = 1;
 const uint8_t kTlsHandshakeServerHello = 2;
 const uint8_t kTlsHandshakeEncryptedExtensions = 8;
 const uint8_t kTlsHandshakeCertificate = 11;
 const uint8_t kTlsHandshakeServerKeyExchange = 12;
+const uint8_t kTlsHandshakeCertificateRequest = 13;
 const uint8_t kTlsHandshakeCertificateVerify = 15;
 const uint8_t kTlsHandshakeClientKeyExchange = 16;
 const uint8_t kTlsHandshakeFinished = 20;
 
 const uint8_t kTlsAlertWarning = 1;
 const uint8_t kTlsAlertFatal = 2;
 
 const uint8_t kTlsAlertUnexpectedMessage = 10;
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -17,20 +17,20 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.26.1" _NSS_CUSTOMIZED
+#define NSS_VERSION  "3.26.2" _NSS_CUSTOMIZED
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   26
-#define NSS_VPATCH   1
+#define NSS_VPATCH   2
 #define NSS_VBUILD   0
 #define NSS_BETA     PR_FALSE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -20,16 +20,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.26.1" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.26.2" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   26
-#define SOFTOKEN_VPATCH   1
+#define SOFTOKEN_VPATCH   2
 #define SOFTOKEN_VBUILD   0
 #define SOFTOKEN_BETA     PR_FALSE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -7876,17 +7876,17 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss,
     }
 
 done:
     if (pubk)
         SECKEY_DestroyPublicKey(pubk);
     return rv;
 }
 
-static void
+static SECStatus
 ssl3_DecideTls12CertVerifyHash(sslSocket *ss, const SECItem *algorithms);
 
 typedef struct dnameNode {
     struct dnameNode *next;
     SECItem name;
 } dnameNode;
 
 /*
@@ -8107,17 +8107,20 @@ ssl3_CompleteHandleCertificateRequest(ss
                 CERT_DestroyCertificate(ss->ssl3.clientCertificate);
                 ss->ssl3.clientCertificate = NULL;
                 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
                 ss->ssl3.clientPrivateKey = NULL;
                 goto send_no_certificate;
             }
             if (ss->ssl3.hs.hashType == handshake_hash_record ||
                 ss->ssl3.hs.hashType == handshake_hash_single) {
-                ssl3_DecideTls12CertVerifyHash(ss, algorithms);
+                rv = ssl3_DecideTls12CertVerifyHash(ss, algorithms);
+                if (rv != SECSuccess) {
+                    goto send_no_certificate;
+                }
             }
             break; /* not an error */
 
         case SECFailure:
         default:
         send_no_certificate:
             if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) {
                 ss->ssl3.sendEmptyCert = PR_TRUE;
@@ -10182,39 +10185,42 @@ ssl3_PickSignatureHashAlgorithm(sslSocke
             }
         }
     }
 
     PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
     return SECFailure;
 }
 
-static void
+static SECStatus
 ssl3_DecideTls12CertVerifyHash(sslSocket *ss, const SECItem *algorithms)
 {
     SECStatus rv;
     SSLSignType sigAlg;
     PRBool preferSha1 = PR_FALSE;
     PRBool supportsSha1 = PR_FALSE;
     PRBool supportsHandshakeHash = PR_FALSE;
     unsigned int i;
     SSLHashType otherHashAlg = ssl_hash_none;
 
     /* Determine the key's signature algorithm and whether it prefers SHA-1. */
     rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1);
     if (rv != SECSuccess) {
-        return;
+        return SECFailure;
     }
 
     /* Determine the server's hash support for that signature algorithm. */
     for (i = 0; i < algorithms->len; i += 2) {
         if (algorithms->data[i + 1] == sigAlg) {
             SSLHashType hashAlg = algorithms->data[i];
             SECOidTag hashOID;
             PRUint32 policy;
+            if (hashAlg == ssl_hash_md5) {
+                continue; /* No MD5 signature support. */
+            }
             if (hashAlg == ssl_hash_sha1 &&
                 ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
                 /* TLS 1.3 explicitly forbids using SHA-1 with certificate_verify. */
                 continue;
             }
             hashOID = ssl3_TLSHashAlgorithmToOID(hashAlg);
             if ((NSS_GetAlgorithmPolicy(hashOID, &policy) == SECSuccess) &&
                 !(policy & NSS_USE_ALG_IN_SSL_KX)) {
@@ -10234,16 +10240,23 @@ ssl3_DecideTls12CertVerifyHash(sslSocket
 
     if (supportsSha1 && preferSha1) {
         ss->ssl3.hs.tls12CertVerifyHash = ssl_hash_sha1;
     } else if (supportsHandshakeHash) {
         ss->ssl3.hs.tls12CertVerifyHash = ssl3_GetSuitePrfHash(ss); /* Use suite PRF hash. */
     } else {
         ss->ssl3.hs.tls12CertVerifyHash = otherHashAlg;
     }
+
+    /* We didn't find a sigAlg matching the client cert's key type. */
+    if (ss->ssl3.hs.tls12CertVerifyHash == ssl_hash_none) {
+        return SECFailure;
+    }
+
+    return SECSuccess;
 }
 
 static SECStatus
 ssl3_SendServerKeyExchange(sslSocket *ss)
 {
     const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
     SECStatus rv = SECFailure;
     int length;
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,20 +14,20 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.26.1"
+#define NSSUTIL_VERSION  "3.26.2"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   26
-#define NSSUTIL_VPATCH   1
+#define NSSUTIL_VPATCH   2
 #define NSSUTIL_VBUILD   0
 #define NSSUTIL_BETA     PR_FALSE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */