Bug 1337580 - Upgrade Firefox 52 to NSS 3.28.2. r=franziskus, a=jcristau
authorMartin Thomson <martin.thomson@gmail.com>
Wed, 08 Feb 2017 16:09:14 +1100
changeset 369213 1855ca2813a522d78cb4641aed9f098e19380a0d
parent 369212 429938019d58b716fc7e99a2892c0597d18142a6
child 369214 037e7115de25d93b90573d2385e0bb675e0b56fe
push id1369
push userjlorenzo@mozilla.com
push dateMon, 27 Feb 2017 14:59:41 +0000
treeherdermozilla-release@d75a1dba431f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfranziskus, jcristau
bugs1337580
milestone52.0
Bug 1337580 - Upgrade Firefox 52 to NSS 3.28.2. r=franziskus, a=jcristau MozReview-Commit-ID: EGbb1l1Gnof
security/nss/TAG-INFO
security/nss/automation/taskcluster/docker/setup.sh
security/nss/coreconf/coreconf.dep
security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
security/nss/lib/softoken/legacydb/dbmshim.c
security/nss/lib/ssl/ssl.h
security/nss/lib/ssl/ssl3con.c
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_28_1_RTM
+NSS_3_28_2_RTM
--- a/security/nss/automation/taskcluster/docker/setup.sh
+++ b/security/nss/automation/taskcluster/docker/setup.sh
@@ -44,17 +44,17 @@ echo "deb http://ppa.launchpad.net/ubunt
 # Install packages.
 apt-get -y update
 apt-get install -y --no-install-recommends ${apt_packages[@]}
 
 # 32-bit builds
 ln -s /usr/include/x86_64-linux-gnu/zconf.h /usr/include
 
 # Install clang-3.9 into /usr/local/.
-curl http://llvm.org/releases/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1
+curl -L http://llvm.org/releases/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1
 
 locale-gen en_US.UTF-8
 dpkg-reconfigure locales
 
 # Cleanup.
 rm -rf ~/.ccache ~/.cache
 apt-get autoremove -y
 apt-get clean
--- 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/gtests/ssl_gtest/ssl_auth_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
@@ -193,26 +193,44 @@ TEST_P(TlsConnectGeneric, SignatureAlgor
   Reset(TlsAgent::kServerEcdsa384);
   server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
                                PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
   Connect();
   CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
             ssl_sig_ecdsa_secp384r1_sha384);
 }
 
-TEST_P(TlsConnectTls12Plus, SignatureSchemeCurveMismatch) {
+// In TLS 1.2, curve and hash aren't bound together.
+TEST_P(TlsConnectTls12, SignatureSchemeCurveMismatch) {
+  Reset(TlsAgent::kServerEcdsa256);
+  client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
+                               PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
+  Connect();
+}
+
+// In TLS 1.3, curve and hash are coupled.
+TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
   Reset(TlsAgent::kServerEcdsa256);
   client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
                                PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
   ConnectExpectFail();
   server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
 }
 
-TEST_P(TlsConnectTls12Plus, SignatureSchemeBadConfig) {
+// Configuring a P-256 cert with only SHA-384 signatures is OK in TLS 1.2.
+TEST_P(TlsConnectTls12, SignatureSchemeBadConfig) {
+  Reset(TlsAgent::kServerEcdsa256);  // P-256 cert can't be used.
+  server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
+                               PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
+  Connect();
+}
+
+// A P-256 certificate in TLS 1.3 needs a SHA-256 signature scheme.
+TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
   Reset(TlsAgent::kServerEcdsa256);  // P-256 cert can't be used.
   server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
                                PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
   ConnectExpectFail();
   server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
 }
 
--- a/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
@@ -53,17 +53,17 @@ TEST_P(TlsConnectGeneric, ConnectEcdhe) 
 // If we pick a 256-bit cipher suite and use a P-384 certificate, the server
 // should choose P-384 for key exchange too.  Only valid for TLS == 1.2 because
 // we don't have 256-bit ciphers before then and 1.3 doesn't try to couple
 // DHE size to symmetric size.
 TEST_P(TlsConnectTls12, ConnectEcdheP384) {
   Reset(TlsAgent::kServerEcdsa384);
   ConnectWithCipherSuite(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_ecdsa,
-            ssl_sig_ecdsa_secp384r1_sha384);
+            ssl_sig_ecdsa_secp256r1_sha256);
 }
 
 TEST_P(TlsConnectGeneric, ConnectEcdheP384Client) {
   EnsureTlsSetup();
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
                                              ssl_grp_ffdhe_2048};
   client_->ConfigNamedGroups(groups);
   server_->ConfigNamedGroups(groups);
@@ -186,16 +186,68 @@ TEST_P(TlsConnectGenericPre13, P384Prior
   server_model_->ConfigNamedGroups(groups);
 
   Connect();
 
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_sha256);
 }
 
+class TlsKeyExchangeGroupCapture : public TlsHandshakeFilter {
+ public:
+  TlsKeyExchangeGroupCapture() : group_(ssl_grp_none) {}
+
+  SSLNamedGroup group() const { return group_; }
+
+ protected:
+  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
+                                               const DataBuffer &input,
+                                               DataBuffer *output) {
+    if (header.handshake_type() != kTlsHandshakeServerKeyExchange) {
+      return KEEP;
+    }
+
+    uint32_t value = 0;
+    EXPECT_TRUE(input.Read(0, 1, &value));
+    EXPECT_EQ(3U, value) << "curve type has to be 3";
+
+    EXPECT_TRUE(input.Read(1, 2, &value));
+    group_ = static_cast<SSLNamedGroup>(value);
+
+    return KEEP;
+  }
+
+ private:
+  SSLNamedGroup group_;
+};
+
+// If we strip the client's supported groups extension, the server should assume
+// P-256 is supported by the client (<= 1.2 only).
+TEST_P(TlsConnectGenericPre13, DropSupportedGroupExtensionP256) {
+  EnsureTlsSetup();
+  client_->SetPacketFilter(new TlsExtensionDropper(ssl_supported_groups_xtn));
+  auto group_capture = new TlsKeyExchangeGroupCapture();
+  server_->SetPacketFilter(group_capture);
+
+  ConnectExpectFail();
+  client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
+  server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
+
+  EXPECT_EQ(ssl_grp_ec_secp256r1, group_capture->group());
+}
+
+// Supported groups is mandatory in TLS 1.3.
+TEST_P(TlsConnectTls13, DropSupportedGroupExtension) {
+  EnsureTlsSetup();
+  client_->SetPacketFilter(new TlsExtensionDropper(ssl_supported_groups_xtn));
+  ConnectExpectFail();
+  client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
+  server_->CheckErrorCode(SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION);
+}
+
 // If we only have a lame group, we fall back to static RSA.
 TEST_P(TlsConnectGenericPre13, UseLameGroup) {
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp192r1};
   client_->ConfigNamedGroups(groups);
   server_->ConfigNamedGroups(groups);
   Connect();
   CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
 }
--- a/security/nss/lib/softoken/legacydb/dbmshim.c
+++ b/security/nss/lib/softoken/legacydb/dbmshim.c
@@ -329,28 +329,22 @@ dbs_readBlob(DBS *dbsp, DBT *data)
     filed = PR_OpenFile(file, PR_RDONLY, 0);
     PR_smprintf_free(file);
     file = NULL;
     if (filed == NULL) {
         goto loser;
     }
 
     len = dbs_getBlobSize(data);
-    mapfile = PR_CreateFileMap(filed, len, PR_PROT_READONLY);
-    if (mapfile == NULL) {
-        /* USE PR_GetError instead of PORT_GetError here
-	     * because we are getting the error from PR_xxx
-	     * function */
-        if (PR_GetError() != PR_NOT_IMPLEMENTED_ERROR) {
-            goto loser;
-        }
-        addr = dbs_EmulateMap(filed, len);
-    } else {
-        addr = PR_MemMap(mapfile, 0, len);
-    }
+    /* Bug 1323150
+     * PR_MemMap fails on Windows for larger certificates.
+     * https://msdn.microsoft.com/en-us/library/windows/desktop/aa366761(v=vs.85).aspx
+     * Let's always use the emulated map, i.e. read the file.
+     */
+    addr = dbs_EmulateMap(filed, len);
     if (addr == NULL) {
         goto loser;
     }
     PR_Close(filed);
     dbs_setmap(dbsp, mapfile, addr, len);
 
     data->data = addr;
     data->size = len;
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -351,20 +351,21 @@ SSL_IMPORT SECStatus SSL_CipherPolicyGet
 ** This also governs what the server sends in the supported_signature_algorithms
 ** field of a CertificateRequest.
 **
 ** This changes what the server uses to sign ServerKeyExchange and
 ** CertificateVerify messages.  An endpoint uses the first entry from this list
 ** that is compatible with both its certificate and its peer's supported
 ** values.
 **
-** NSS uses the strict signature schemes from TLS 1.3 in TLS 1.2.  That means
-** that if a peer indicates support for SHA-384 and ECDSA, NSS will not
-** generate a signature if it has a P-256 key, even though that is permitted in
-** TLS 1.2.
+** This configuration affects TLS 1.2, but the combination of EC group and hash
+** algorithm is interpreted loosely to be compatible with other implementations.
+** For TLS 1.2, NSS will ignore the curve group when generating or verifying
+** ECDSA signatures.  For example, a P-384 ECDSA certificate is used with
+** SHA-256 if ssl_sig_ecdsa_secp256r1_sha256 is enabled.
 **
 ** Omitting SHA-256 schemes from this list might be foolish.  Support is
 ** mandatory in TLS 1.2 and 1.3 and there might be interoperability issues.
 */
 SSL_IMPORT SECStatus SSL_SignatureSchemePrefSet(
     PRFileDesc *fd, const SSLSignatureScheme *schemes, unsigned int count);
 
 /* Deprecated, use SSL_SignatureSchemePrefSet() instead. */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -6372,17 +6372,17 @@ ssl_PickSignatureScheme(sslSocket *ss,
      * indicated support for in their signature_algorithms extension. */
     for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
         SSLHashType hashType;
         SECOidTag hashOID;
         SSLSignatureScheme preferred = ss->ssl3.signatureSchemes[i];
         PRUint32 policy;
 
         if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */,
-                                            PR_TRUE /* matchGroup */,
+                                            isTLS13 /* matchGroup */,
                                             keyType, group, preferred)) {
             continue;
         }
 
         /* Skip RSA-PSS schemes when the certificate's private key slot does
          * not support this signature mechanism. */
         if (ssl_IsRsaPssSignatureScheme(preferred) && !slotDoesPss) {
             continue;
@@ -8198,16 +8198,30 @@ alert_loser:
 }
 
 SECStatus
 ssl3_SelectServerCert(sslSocket *ss)
 {
     const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
     PRCList *cursor;
 
+    /* If the client didn't include the supported groups extension, assume just
+     * P-256 support and disable all the other ECDHE groups.  This also affects
+     * ECDHE group selection, but this function is called first. */
+    if (!ssl3_ExtensionNegotiated(ss, ssl_supported_groups_xtn)) {
+        unsigned int i;
+        for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+            if (ss->namedGroupPreferences[i] &&
+                ss->namedGroupPreferences[i]->keaType == ssl_kea_ecdh &&
+                ss->namedGroupPreferences[i]->name != ssl_grp_ec_secp256r1) {
+                ss->namedGroupPreferences[i] = NULL;
+            }
+        }
+    }
+
     /* This picks the first certificate that has:
      * a) the right authentication method, and
      * b) the right named curve (EC only)
      *
      * We might want to do some sort of ranking here later.  For now, it's all
      * based on what order they are configured in. */
     for (cursor = PR_NEXT_LINK(&ss->serverCerts);
          cursor != &ss->serverCerts;