diff --git a/qt5-qtwebengine.spec b/qt5-qtwebengine.spec index f55bc50..d9d3bde 100644 --- a/qt5-qtwebengine.spec +++ b/qt5-qtwebengine.spec @@ -24,7 +24,7 @@ Summary: Qt5 - QtWebEngine components Name: qt5-qtwebengine Version: 5.6.0 -Release: 0.11.beta%{?dist} +Release: 0.12.beta%{?dist} # See LICENSE.GPL LICENSE.LGPL LGPL_EXCEPTION.txt, for details # See also http://qt-project.org/doc/qt-5.0/qtdoc/licensing.html @@ -60,6 +60,9 @@ Patch5: qtwebengine-opensource-src-5.6.0-beta-system-nspr-prtime.patch # I checked the history of that directory, and other than the renames I am # undoing, there were no modifications at all. Must be applied after Patch5. Patch6: qtwebengine-opensource-src-5.6.0-beta-system-icu-utf.patch +# update the bundled patched NSS SSL implementation to NSS 3.21, matching the +# system NSS (backport of https://codereview.chromium.org/1511123006) +Patch7: qtwebengine-opensource-src-5.6.0-beta-nss321.patch # the architectures theoretically supported by the version of V8 used (#1298011) # You may need some minor patching to build on one of the secondary @@ -217,7 +220,10 @@ Provides: bundled(xdg-user-dirs) = 0.10 Provides: bundled(mozilla_security_manager) = 1.9.2 # Ewww... Chromium uses the system NSS, but bundles a heavily patched version of # its SSL implementation. This might crash and burn sooner or later! -Provides: bundled(nss) = 3.19 +# See also Patch7, which updates it from 3.19 to 3.21, because the mix of +# versions was indeed causing issues. (Ironically, HTTPS not working on Google's +# own sites!) +Provides: bundled(nss) = 3.21 # Bundled in src/3rdparty/chromium/url/third_party: # Check src/3rdparty/chromium/third_party/url/*/README.chromium for version @@ -273,6 +279,7 @@ BuildArch: noarch %patch4 -p1 -b .no-neon %patch5 -p1 -b .system-nspr-prtime %patch6 -p1 -b .system-icu-utf +%patch7 -p1 -b .nss321 %build export STRIP=strip @@ -342,6 +349,9 @@ popd %changelog +* Wed Jan 13 2016 Kevin Kofler - 5.6.0-0.12.beta +- Update forked NSS SSL code to 3.21, match system NSS (backport from Chromium) + * Wed Jan 13 2016 Kevin Kofler - 5.6.0-0.11.beta - Add an (optimistic) ExclusiveArch list because of V8 (tracking bug: #1298011) diff --git a/qtwebengine-opensource-src-5.6.0-beta-nss321.patch b/qtwebengine-opensource-src-5.6.0-beta-nss321.patch new file mode 100644 index 0000000..1a5ebbd --- /dev/null +++ b/qtwebengine-opensource-src-5.6.0-beta-nss321.patch @@ -0,0 +1,7898 @@ +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/build/secondary/third_party/nss/BUILD.gn qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/build/secondary/third_party/nss/BUILD.gn +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/build/secondary/third_party/nss/BUILD.gn 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/build/secondary/third_party/nss/BUILD.gn 2016-01-13 14:18:55.587954670 +0100 +@@ -695,6 +695,8 @@ + "nss/lib/freebl/win_rand.c", + "nss/lib/nss/nss.h", + "nss/lib/nss/nssinit.c", ++ "nss/lib/nss/nssoptions.c", ++ "nss/lib/nss/nssoptions.h", + "nss/lib/nss/nssrenam.h", + "nss/lib/nss/utilwrap.c", + "nss/lib/pk11wrap/debug_module.c", +@@ -859,6 +861,7 @@ + "nss/lib/util/utilpars.h", + "nss/lib/util/utilparst.h", + "nss/lib/util/utilrename.h", ++ "nss/lib/util/verref.h", + ] + + sources -= [ +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/aesgcmchromium.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/aesgcmchromium.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/aesgcmchromium.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/aesgcmchromium.patch 2016-01-13 14:18:55.588954676 +0100 +@@ -1,7 +1,7 @@ +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 1167d6d..dabe333 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index c5cb1eb..299e414 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c + @@ -8,6 +8,7 @@ + + /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ +@@ -10,7 +10,7 @@ + #include "cert.h" + #include "ssl.h" + #include "cryptohi.h" /* for DSAU_ stuff */ +-@@ -44,6 +45,9 @@ ++@@ -46,6 +47,9 @@ + #ifdef NSS_ENABLE_ZLIB + #include "zlib.h" + #endif +@@ -20,7 +20,7 @@ + + #ifndef PK11_SETATTRS + #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ +-@@ -1874,6 +1878,63 @@ ssl3_BuildRecordPseudoHeader(unsigned char *out, ++@@ -1897,6 +1901,63 @@ ssl3_BuildRecordPseudoHeader(unsigned char *out, + return 13; + } + +@@ -84,7 +84,7 @@ + static SECStatus + ssl3_AESGCM(ssl3KeyMaterial *keys, + PRBool doDecrypt, +-@@ -1925,10 +1986,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys, ++@@ -1948,10 +2009,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys, + gcmParams.ulTagBits = tagSize * 8; + + if (doDecrypt) { +@@ -97,7 +97,7 @@ + maxout, in, inlen); + } + *outlen += (int) uOutLen; +-@@ -5162,6 +5223,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5337,6 +5398,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + ssl3_DisableNonDTLSSuites(ss); + } + +@@ -108,7 +108,7 @@ + /* how many suites are permitted by policy and user preference? */ + num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE); + if (!num_suites) { +-@@ -8172,6 +8237,10 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -8400,6 +8465,10 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + ssl3_DisableNonDTLSSuites(ss); + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/applypatches.sh qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/applypatches.sh +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/applypatches.sh 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/applypatches.sh 2016-01-13 14:18:55.588954676 +0100 +@@ -46,9 +46,3 @@ + patch -p2 < $patches_dir/nssrwlock.patch + + patch -p2 < $patches_dir/reorderextensions.patch +- +-patch -p2 < $patches_dir/removebuildmetadata.patch +- +-patch -p2 < $patches_dir/norenegotiatelock.patch +- +-patch -p2 < $patches_dir/dh1024.patch +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/cachecerts.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/cachecerts.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/cachecerts.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/cachecerts.patch 2016-01-13 14:18:55.589954682 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 163572c..60af5b0 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -43,6 +43,7 @@ ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 8f1c547..9aaf601 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -45,6 +45,7 @@ + + static SECStatus ssl3_AuthCertificate(sslSocket *ss); + static void ssl3_CleanupPeerCerts(sslSocket *ss); +@@ -10,15 +10,15 @@ + static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, + PK11SlotInfo * serverKeySlot); + static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); +-@@ -6549,6 +6550,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -6751,6 +6752,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + /* copy the peer cert from the SID */ + if (sid->peerCert != NULL) { + ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); + + ssl3_CopyPeerCertsFromSID(ss, sid); + } + +- /* NULL value for PMS signifies re-use of the old MS */ +-@@ -8140,6 +8142,7 @@ compression_found: ++ /* NULL value for PMS because we are reusing the old MS */ ++@@ -8405,6 +8407,7 @@ compression_found: + ss->sec.ci.sid = sid; + if (sid->peerCert != NULL) { + ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); +@@ -26,7 +26,7 @@ + } + + /* +-@@ -9763,6 +9766,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss) ++@@ -10389,6 +10392,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss) + ss->ssl3.peerCertChain = NULL; + } + +@@ -71,7 +71,7 @@ + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete + * ssl3 CertificateStatus message. + * Caller must hold Handshake and RecvBuf locks. +-@@ -10041,6 +10082,7 @@ ssl3_AuthCertificate(sslSocket *ss) ++@@ -10669,6 +10710,7 @@ ssl3_AuthCertificate(sslSocket *ss) + } + + ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); +@@ -79,11 +79,11 @@ + + if (!ss->sec.isServer) { + CERTCertificate *cert = ss->sec.peerCert; +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 1b38a52..086f6d2 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -597,6 +597,8 @@ typedef enum { never_cached, ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index ad31aae..9dcc29e 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -608,6 +608,8 @@ typedef enum { never_cached, + invalid_cache /* no longer in any cache. */ + } Cached; + +@@ -92,7 +92,7 @@ + struct sslSessionIDStr { + /* The global cache lock must be held when accessing these members when the + * sid is in any cache. +-@@ -611,6 +613,7 @@ struct sslSessionIDStr { ++@@ -622,6 +624,7 @@ struct sslSessionIDStr { + */ + + CERTCertificate * peerCert; +@@ -100,10 +100,10 @@ + SECItemArray peerCertStatus; /* client only */ + const char * peerID; /* client only */ + const char * urlSvrName; /* client only */ +-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c ++diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c + index 2e861f1..be11008 100644 +---- a/ssl/sslnonce.c +-+++ b/ssl/sslnonce.c ++--- a/lib/ssl/sslnonce.c +++++ b/lib/ssl/sslnonce.c + @@ -164,6 +164,7 @@ lock_cache(void) + static void + ssl_DestroySID(sslSessionID *sid) +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/cachelocks.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/cachelocks.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/cachelocks.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/cachelocks.patch 2016-01-13 14:18:55.589954682 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 6819b03..6a4a443 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -5748,7 +5748,6 @@ SSL3_ShutdownServerCache(void) ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 2533679..ba3d012 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -5921,7 +5921,6 @@ SSL3_ShutdownServerCache(void) + } + + PZ_Unlock(symWrapKeysLock); +@@ -10,7 +10,7 @@ + return SECSuccess; + } + +-@@ -5800,7 +5799,7 @@ getWrappingKey( sslSocket * ss, ++@@ -5973,7 +5972,7 @@ getWrappingKey( sslSocket * ss, + + pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType]; + +@@ -19,11 +19,11 @@ + + PZ_Lock(symWrapKeysLock); + +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 88b2eba..c4c87b4 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -1924,9 +1924,7 @@ extern SECStatus ssl_InitSymWrapKeysLock(void); ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index d5f326f..d53c446 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -1957,9 +1957,7 @@ extern SECStatus ssl_InitSymWrapKeysLock(void); + + extern SECStatus ssl_FreeSymWrapKeysLock(void); + +@@ -34,10 +34,10 @@ + + /***************** platform client auth ****************/ + +-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c ++diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c + index 1326a8b..c45849d 100644 +---- a/ssl/sslnonce.c +-+++ b/ssl/sslnonce.c ++--- a/lib/ssl/sslnonce.c +++++ b/lib/ssl/sslnonce.c + @@ -35,91 +35,55 @@ static PZLock * cacheLock = NULL; + #define LOCK_CACHE lock_cache() + #define UNLOCK_CACHE PZ_Unlock(cacheLock) +@@ -204,11 +204,11 @@ + PZ_Lock(cacheLock); + } + +-diff --git a/ssl/sslsnce.c b/ssl/sslsnce.c +-index 4d9ef38..3279200 100644 +---- a/ssl/sslsnce.c +-+++ b/ssl/sslsnce.c +-@@ -1352,7 +1352,7 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries, ++diff --git a/lib/ssl/sslsnce.c b/lib/ssl/sslsnce.c ++index f31b2e9..3856c13 100644 ++--- a/lib/ssl/sslsnce.c +++++ b/lib/ssl/sslsnce.c ++@@ -1363,7 +1363,7 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries, + PRUint32 ssl3_timeout, + const char * directory) + { +@@ -217,7 +217,7 @@ + return SSL_ConfigServerSessionIDCacheInstance(&globalCache, + maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE); + } +-@@ -1466,7 +1466,7 @@ SSL_ConfigServerSessionIDCacheWithOpt( ++@@ -1477,7 +1477,7 @@ SSL_ConfigServerSessionIDCacheWithOpt( + PRBool enableMPCache) + { + if (!enableMPCache) { +@@ -226,7 +226,7 @@ + return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache, + ssl2_timeout, ssl3_timeout, directory, PR_FALSE, + maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries); +-@@ -1511,7 +1511,7 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString) ++@@ -1521,7 +1521,7 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString) + return SECSuccess; /* already done. */ + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/chacha20poly1305.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/chacha20poly1305.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/chacha20poly1305.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/chacha20poly1305.patch 2016-01-13 14:18:55.590954688 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index dabe333..6819b03 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -41,6 +41,21 @@ ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 299e414..2533679 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -43,6 +43,21 @@ + #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24) + #endif + +@@ -24,16 +24,16 @@ + #include + #ifdef NSS_ENABLE_ZLIB + #include "zlib.h" +-@@ -105,6 +120,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { ++@@ -110,6 +125,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { + /* cipher_suite policy enabled isPresent */ + + #ifndef NSS_DISABLE_ECC + + { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + + { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around +-@@ -296,6 +313,7 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = { ++@@ -307,6 +324,7 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = { + {cipher_camellia_256, calg_camellia, 32,32, type_block, 16,16, 0, 0}, + {cipher_seed, calg_seed, 16,16, type_block, 16,16, 0, 0}, + {cipher_aes_128_gcm, calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8}, +@@ -41,16 +41,16 @@ + {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0}, + }; + +-@@ -422,6 +440,8 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = ++@@ -433,6 +451,8 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = + {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa}, + {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa}, + {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa}, + + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa}, + + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa}, + +- #ifndef NSS_DISABLE_ECC +- {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, +-@@ -487,6 +507,7 @@ static const SSLCipher2Mech alg2Mech[] = { ++ {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss}, ++ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss}, ++@@ -502,6 +522,7 @@ static const SSLCipher2Mech alg2Mech[] = { + { calg_camellia , CKM_CAMELLIA_CBC }, + { calg_seed , CKM_SEED_CBC }, + { calg_aes_gcm , CKM_AES_GCM }, +@@ -58,7 +58,7 @@ + /* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */ + }; + +-@@ -662,6 +683,8 @@ ssl3_CipherSuiteAllowedForVersionRange( ++@@ -679,6 +700,8 @@ ssl3_CipherSuiteAllowedForVersionRange( + case TLS_RSA_WITH_NULL_SHA256: + return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2; + +@@ -67,7 +67,7 @@ + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: +-@@ -2070,6 +2093,46 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys, ++@@ -2093,6 +2116,46 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys, + } + #endif + +@@ -114,7 +114,7 @@ + /* Initialize encryption and MAC contexts for pending spec. + * Master Secret already is derived. + * Caller holds Spec write lock. +-@@ -2103,13 +2166,17 @@ ssl3_InitPendingContextsPKCS11(sslSocket *ss) ++@@ -2126,13 +2189,17 @@ ssl3_InitPendingContextsPKCS11(sslSocket *ss) + pwSpec->client.write_mac_context = NULL; + pwSpec->server.write_mac_context = NULL; + +@@ -134,11 +134,11 @@ + return SECSuccess; + } + +-diff --git a/ssl/ssl3ecc.c b/ssl/ssl3ecc.c +-index 9b91270..31e0774 100644 +---- a/ssl/ssl3ecc.c +-+++ b/ssl/ssl3ecc.c +-@@ -921,6 +921,7 @@ static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { ++diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c ++index cf8e741..ab5ab14 100644 ++--- a/lib/ssl/ssl3ecc.c +++++ b/lib/ssl/ssl3ecc.c ++@@ -926,6 +926,7 @@ static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, +@@ -146,7 +146,7 @@ + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +-@@ -932,6 +933,7 @@ static const ssl3CipherSuite ecdhe_rsa_suites[] = { ++@@ -937,6 +938,7 @@ static const ssl3CipherSuite ecdhe_rsa_suites[] = { + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, +@@ -154,7 +154,7 @@ + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +-@@ -944,6 +946,7 @@ static const ssl3CipherSuite ecSuites[] = { ++@@ -949,6 +951,7 @@ static const ssl3CipherSuite ecSuites[] = { + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, +@@ -162,7 +162,7 @@ + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, +-@@ -951,6 +954,7 @@ static const ssl3CipherSuite ecSuites[] = { ++@@ -956,6 +959,7 @@ static const ssl3CipherSuite ecSuites[] = { + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, +@@ -170,10 +170,10 @@ + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, +-diff --git a/ssl/sslenum.c b/ssl/sslenum.c +-index 09ce43f..a036627 100644 +---- a/ssl/sslenum.c +-+++ b/ssl/sslenum.c ++diff --git a/lib/ssl/sslenum.c b/lib/ssl/sslenum.c ++index f69aed2..b4a8844 100644 ++--- a/lib/ssl/sslenum.c +++++ b/lib/ssl/sslenum.c + @@ -37,17 +37,21 @@ + * + * Exception: Because some servers ignore the high-order byte of the cipher +@@ -199,11 +199,11 @@ + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index ea71975..88b2eba 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -65,6 +65,7 @@ typedef SSLSignType SSL3SignType; ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index 60dd243..d5f326f 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -66,6 +66,7 @@ typedef SSLSignType SSL3SignType; + #define calg_camellia ssl_calg_camellia + #define calg_seed ssl_calg_seed + #define calg_aes_gcm ssl_calg_aes_gcm +@@ -211,16 +211,16 @@ + + #define mac_null ssl_mac_null + #define mac_md5 ssl_mac_md5 +-@@ -299,7 +300,7 @@ typedef struct { ++@@ -301,7 +302,7 @@ typedef struct { + } ssl3CipherSuiteCfg; + + #ifndef NSS_DISABLE_ECC +--#define ssl_V3_SUITES_IMPLEMENTED 61 +-+#define ssl_V3_SUITES_IMPLEMENTED 63 ++-#define ssl_V3_SUITES_IMPLEMENTED 64 +++#define ssl_V3_SUITES_IMPLEMENTED 66 + #else +- #define ssl_V3_SUITES_IMPLEMENTED 37 ++ #define ssl_V3_SUITES_IMPLEMENTED 40 + #endif /* NSS_DISABLE_ECC */ +-@@ -485,6 +486,7 @@ typedef enum { ++@@ -495,6 +496,7 @@ typedef enum { + cipher_camellia_256, + cipher_seed, + cipher_aes_128_gcm, +@@ -228,11 +228,11 @@ + cipher_missing /* reserved for no such supported cipher */ + /* This enum must match ssl3_cipherName[] in ssl3con.c. */ + } SSL3BulkCipher; +-diff --git a/ssl/sslinfo.c b/ssl/sslinfo.c +-index ba230d2..845d9f0 100644 +---- a/ssl/sslinfo.c +-+++ b/ssl/sslinfo.c +-@@ -110,6 +110,7 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) ++diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c ++index 7048eb8..bef3190 100644 ++--- a/lib/ssl/sslinfo.c +++++ b/lib/ssl/sslinfo.c ++@@ -148,6 +148,7 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, + #define C_NULL "NULL", calg_null + #define C_SJ "SKIPJACK", calg_sj + #define C_AESGCM "AES-GCM", calg_aes_gcm +@@ -240,7 +240,7 @@ + + #define B_256 256, 256, 256 + #define B_128 128, 128, 128 +-@@ -188,12 +189,14 @@ static const SSLCipherSuiteInfo suiteInfo[] = { ++@@ -229,12 +230,14 @@ static const SSLCipherSuiteInfo suiteInfo[] = { + {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, + {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, }, + {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, }, +@@ -255,11 +255,11 @@ + + {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, }, + {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, +-diff --git a/ssl/sslproto.h b/ssl/sslproto.h +-index e02442c..dc653c9 100644 +---- a/ssl/sslproto.h +-+++ b/ssl/sslproto.h +-@@ -258,6 +258,9 @@ ++diff --git a/lib/ssl/sslproto.h b/lib/ssl/sslproto.h ++index 2db47a5..36ae6c9 100644 ++--- a/lib/ssl/sslproto.h +++++ b/lib/ssl/sslproto.h ++@@ -260,6 +260,9 @@ + #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F + #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 + +@@ -269,11 +269,11 @@ + /* Netscape "experimental" cipher suites. */ + #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0 + #define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1 +-diff --git a/ssl/sslt.h b/ssl/sslt.h +-index 430d216..fe0ad07 100644 +---- a/ssl/sslt.h +-+++ b/ssl/sslt.h +-@@ -94,7 +94,8 @@ typedef enum { ++diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h ++index 5593579..a2eff62 100644 ++--- a/lib/ssl/sslt.h +++++ b/lib/ssl/sslt.h ++@@ -117,7 +117,8 @@ typedef enum { + ssl_calg_aes = 7, + ssl_calg_camellia = 8, + ssl_calg_seed = 9, +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/channelid.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/channelid.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/channelid.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/channelid.patch 2016-01-13 14:18:55.591954693 +0100 +@@ -1,25 +1,25 @@ +-diff --git a/ssl/SSLerrs.h b/ssl/SSLerrs.h +-index 174037b..81da41c 100644 +---- a/ssl/SSLerrs.h +-+++ b/ssl/SSLerrs.h +-@@ -422,3 +422,12 @@ ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130), +- ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131), +- "The server rejected the handshake because the client downgraded to a lower " +- "TLS version than the server supports.") ++diff --git a/lib/ssl/SSLerrs.h b/lib/ssl/SSLerrs.h ++index 6028396..3d21ab8 100644 ++--- a/lib/ssl/SSLerrs.h +++++ b/lib/ssl/SSLerrs.h ++@@ -440,3 +440,12 @@ ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136), ++ ++ ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137), ++ "The peer tried to resume with an unexpected extended_master_secret extension") + + +-+ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 132), +++ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 138), + +"SSL received a malformed TLS Channel ID extension.") + + +-+ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 133), +++ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 139), + +"The application provided an invalid TLS Channel ID key.") + + +-+ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 134), +++ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 140), + +"The application could not get a TLS Channel ID.") +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index 593dd00..716537d 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -1025,6 +1025,34 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index 85ced8a..120c257 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -1135,6 +1135,34 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, + SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd, + PRBool *last_handshake_resumed); + +@@ -54,11 +54,11 @@ + /* + ** How long should we wait before retransmitting the next flight of + ** the DTLS handshake? Returns SECFailure if not DTLS or not in a +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 29e8f1c..c0e8e79 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -55,6 +55,7 @@ static SECStatus ssl3_SendCertificateStatus( sslSocket *ss); ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 304e03b..2ae8ce9 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -57,6 +57,7 @@ static SECStatus ssl3_SendCertificateStatus( sslSocket *ss); + static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); + static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); + static SECStatus ssl3_SendNextProto( sslSocket *ss); +@@ -66,7 +66,7 @@ + static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); + static SECStatus ssl3_SendServerHello( sslSocket *ss); + static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); +-@@ -6296,6 +6297,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -6470,6 +6471,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + } + #endif /* NSS_PLATFORM_CLIENT_AUTH */ + +@@ -82,7 +82,7 @@ + temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); + if (temp < 0) { + goto loser; /* alert has been sent */ +-@@ -6578,7 +6588,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -6780,7 +6790,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + if (rv != SECSuccess) { + goto alert_loser; /* err code was set */ + } +@@ -91,9 +91,9 @@ + } while (0); + + if (sid_match) +-@@ -6613,6 +6623,27 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +- } else { +- ss->ssl3.hs.ws = wait_cert_request; ++@@ -6819,6 +6829,27 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++ PORT_Assert(ss->ssl3.hs.kea_def->ephemeral); ++ ss->ssl3.hs.ws = wait_server_key; + } + + + +winner: +@@ -119,7 +119,7 @@ + return SECSuccess; + + alert_loser: +-@@ -7565,7 +7596,14 @@ ssl3_SendClientSecondRound(sslSocket *ss) ++@@ -7774,7 +7805,14 @@ ssl3_SendClientSecondRound(sslSocket *ss) + if (rv != SECSuccess) { + goto loser; /* err code was set. */ + } +@@ -134,7 +134,7 @@ + if (ss->opt.enableFalseStart) { + if (!ss->ssl3.hs.authCertificatePending) { + /* When we fix bug 589047, we will need to know whether we are +-@@ -7602,6 +7640,33 @@ ssl3_SendClientSecondRound(sslSocket *ss) ++@@ -7811,6 +7849,33 @@ ssl3_SendClientSecondRound(sslSocket *ss) + + ssl_ReleaseXmitBufLock(ss); /*******************************/ + +@@ -168,7 +168,7 @@ + if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) + ss->ssl3.hs.ws = wait_new_session_ticket; + else +-@@ -10590,6 +10655,184 @@ ssl3_RecordKeyLog(sslSocket *ss) ++@@ -11264,6 +11329,184 @@ ssl3_RecordKeyLog(sslSocket *ss) + } + + /* called from ssl3_SendClientSecondRound +@@ -353,7 +353,7 @@ + * ssl3_HandleClientHello + * ssl3_HandleFinished + */ +-@@ -10849,11 +11092,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, ++@@ -11531,11 +11774,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, + flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; + } + +@@ -374,7 +374,7 @@ + } + + if (IS_DTLS(ss)) { +-@@ -12333,6 +12581,11 @@ ssl3_DestroySSL3Info(sslSocket *ss) ++@@ -13095,6 +13343,11 @@ ssl3_DestroySSL3Info(sslSocket *ss) + ssl_FreePlatformKey(ss->ssl3.platformClientKey); + #endif /* NSS_PLATFORM_CLIENT_AUTH */ + +@@ -386,10 +386,10 @@ + if (ss->ssl3.peerCertArena != NULL) + ssl3_CleanupPeerCerts(ss); + +-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c +-index 0a2288a..4d17587 100644 +---- a/ssl/ssl3ext.c +-+++ b/ssl/ssl3ext.c ++diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c ++index 5661a5c..78825cb 100644 ++--- a/lib/ssl/ssl3ext.c +++++ b/lib/ssl/ssl3ext.c + @@ -73,6 +73,10 @@ static SECStatus ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, + SECItem *data); + static SECStatus ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, +@@ -401,15 +401,15 @@ + static PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket * ss, + PRBool append, PRUint32 maxBytes); + static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, +-@@ -269,6 +273,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { ++@@ -276,6 +280,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, + { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn }, + { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn }, + + { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, ++ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, + { -1, NULL } +- }; +-@@ -296,6 +301,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { ++@@ -304,6 +309,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, + { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn }, + { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn }, +@@ -417,7 +417,7 @@ + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn }, +-@@ -930,6 +936,61 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) ++@@ -945,6 +951,61 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) + } + + static SECStatus +@@ -479,10 +479,10 @@ + ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) + { +-diff --git a/ssl/ssl3prot.h b/ssl/ssl3prot.h +-index 485d7dd..78fbcaa 100644 +---- a/ssl/ssl3prot.h +-+++ b/ssl/ssl3prot.h ++diff --git a/lib/ssl/ssl3prot.h b/lib/ssl/ssl3prot.h ++index a93bef1..848bdee 100644 ++--- a/lib/ssl/ssl3prot.h +++++ b/lib/ssl/ssl3prot.h + @@ -136,7 +136,8 @@ typedef enum { + client_key_exchange = 16, + finished = 20, +@@ -493,10 +493,10 @@ + } SSL3HandshakeType; + + typedef struct { +-diff --git a/ssl/sslauth.c b/ssl/sslauth.c +-index 7f9c43b..c2d9201 100644 +---- a/ssl/sslauth.c +-+++ b/ssl/sslauth.c ++diff --git a/lib/ssl/sslauth.c b/lib/ssl/sslauth.c ++index e6981f0..03b23b4 100644 ++--- a/lib/ssl/sslauth.c +++++ b/lib/ssl/sslauth.c + @@ -216,6 +216,24 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, + return SECSuccess; + } +@@ -522,26 +522,26 @@ + #ifdef NSS_PLATFORM_CLIENT_AUTH + /* NEED LOCKS IN HERE. */ + SECStatus +-diff --git a/ssl/sslerr.h b/ssl/sslerr.h +-index 12dbb1d..24bf893 100644 +---- a/ssl/sslerr.h +-+++ b/ssl/sslerr.h +-@@ -198,6 +198,10 @@ SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130), +- +- SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131), +- +-+SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 132), +-+SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 133), +-+SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 134), ++diff --git a/lib/ssl/sslerr.h b/lib/ssl/sslerr.h ++index 192a107..835b812 100644 ++--- a/lib/ssl/sslerr.h +++++ b/lib/ssl/sslerr.h ++@@ -208,6 +208,10 @@ SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135), ++ SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136), ++ SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137), ++ +++SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 138), +++SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 139), +++SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 140), + + + SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ + } SSLErrorCodes; + #endif /* NO_SECURITY_ERROR_ENUM */ +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 2cf0b3a..e11860e 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -711,6 +711,14 @@ struct sslSessionIDStr { ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index c089889..c286518 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -722,6 +722,14 @@ struct sslSessionIDStr { + + SECItem srvName; + +@@ -556,7 +556,7 @@ + /* This lock is lazily initialized by CacheSID when a sid is first + * cached. Before then, there is no need to lock anything because + * the sid isn't being shared by anything. +-@@ -986,6 +994,9 @@ struct ssl3StateStr { ++@@ -999,6 +1007,9 @@ struct ssl3StateStr { + CERTCertificateList *clientCertChain; /* used by client */ + PRBool sendEmptyCert; /* used by client */ + +@@ -566,7 +566,7 @@ + int policy; + /* This says what cipher suites we can do, and should + * be either SSL_ALLOWED or SSL_RESTRICTED +-@@ -1264,6 +1275,8 @@ const unsigned char * preferredCipher; ++@@ -1294,6 +1305,8 @@ const unsigned char * preferredCipher; + void *pkcs11PinArg; + SSLNextProtoCallback nextProtoCallback; + void *nextProtoArg; +@@ -575,7 +575,7 @@ + + PRIntervalTime rTimeout; /* timeout for NSPR I/O */ + PRIntervalTime wTimeout; /* timeout for NSPR I/O */ +-@@ -1610,6 +1623,11 @@ extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, ++@@ -1640,6 +1653,11 @@ extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, + SECKEYPrivateKey * key, + CERTCertificateList *certChain); + +@@ -587,10 +587,10 @@ + extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error); + + /* +-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c ++diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c + index be11008..1326a8b 100644 +---- a/ssl/sslnonce.c +-+++ b/ssl/sslnonce.c ++--- a/lib/ssl/sslnonce.c +++++ b/lib/ssl/sslnonce.c + @@ -180,6 +180,9 @@ ssl_DestroySID(sslSessionID *sid) + if (sid->u.ssl3.srvName.data) { + SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); +@@ -601,11 +601,11 @@ + + if (sid->u.ssl3.lock) { + PR_DestroyRWLock(sid->u.ssl3.lock); +-diff --git a/ssl/sslsecur.c b/ssl/sslsecur.c +-index d44336e..5c6751a 100644 +---- a/ssl/sslsecur.c +-+++ b/ssl/sslsecur.c +-@@ -1582,6 +1582,42 @@ SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd, ++diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c ++index f77d6fa..cca55bb 100644 ++--- a/lib/ssl/sslsecur.c +++++ b/lib/ssl/sslsecur.c ++@@ -1598,6 +1598,42 @@ SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd, + return ret; + } + +@@ -648,11 +648,11 @@ + /* DO NOT USE. This function was exported in ssl.def with the wrong signature; + * this implementation exists to maintain link-time compatibility. + */ +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 9431fe4..042f24f 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -288,6 +288,8 @@ ssl_DupSocket(sslSocket *os) ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index 11e66f2..efba686 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -313,6 +313,8 @@ ssl_DupSocket(sslSocket *os) + ss->canFalseStartCallback = os->canFalseStartCallback; + ss->canFalseStartCallbackData = os->canFalseStartCallbackData; + ss->pkcs11PinArg = os->pkcs11PinArg; +@@ -661,7 +661,7 @@ + + /* Create security data */ + rv = ssl_CopySecurityInfo(ss, os); +-@@ -1733,6 +1735,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) ++@@ -1987,6 +1989,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) + ss->handshakeCallbackData = sm->handshakeCallbackData; + if (sm->pkcs11PinArg) + ss->pkcs11PinArg = sm->pkcs11PinArg; +@@ -672,7 +672,7 @@ + return fd; + loser: + return NULL; +-@@ -3021,6 +3027,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) ++@@ -3279,6 +3285,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) + ss->badCertArg = NULL; + ss->pkcs11PinArg = NULL; + ss->ephemeralECDHKeyPair = NULL; +@@ -681,12 +681,12 @@ + + ssl_ChooseOps(ss); + ssl2_InitSocketPolicy(ss); +-diff --git a/ssl/sslt.h b/ssl/sslt.h +-index 1d28feb..0900f28 100644 +---- a/ssl/sslt.h +-+++ b/ssl/sslt.h +-@@ -191,10 +191,11 @@ typedef enum { +- ssl_padding_xtn = 21, ++diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h ++index cd742bb..b6616e2 100644 ++--- a/lib/ssl/sslt.h +++++ b/lib/ssl/sslt.h ++@@ -238,11 +238,12 @@ typedef enum { ++ ssl_extended_master_secret_xtn = 23, + ssl_session_ticket_xtn = 35, + ssl_next_proto_nego_xtn = 13172, + + ssl_channel_id_xtn = 30032, +@@ -694,7 +694,8 @@ + ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */ + } SSLExtensionType; + +--#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */ +-+#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */ ++-#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */ +++#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */ + +- #endif /* __sslt_h_ */ ++ typedef enum { ++ ssl_dhe_group_none = 0, +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/cipherorder.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/cipherorder.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/cipherorder.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/cipherorder.patch 2016-01-13 14:18:55.591954693 +0100 +@@ -1,10 +1,10 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index e9f5fb0..be6d88e 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -295,6 +295,13 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled); +- SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy); +- SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy); ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index db09425..437a822 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -387,6 +387,13 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd, ++ */ ++ SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled); + + +/* SSL_CipherOrderSet sets the cipher suite preference order from |ciphers|, + + * which must be an array of cipher suite ids of length |len|. All the given +@@ -16,12 +16,12 @@ + /* SSLChannelBindingType enumerates the types of supported channel binding + * values. See RFC 5929. */ + typedef enum SSLChannelBindingType { +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 54c5b80..26b87c6 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -12631,6 +12631,46 @@ ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled) +- return rv; ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 5c09f25..572bba9 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -13390,6 +13390,46 @@ SSL_SignatureMaxCount() { ++ return MAX_SIGNATURE_ALGORITHMS; + } + + +SECStatus +@@ -67,11 +67,11 @@ + /* copy global default policy into socket. */ + void + ssl3_InitSocketPolicy(sslSocket *ss) +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 0fd0a89..d12228e 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -1754,6 +1754,8 @@ extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index 080debe..3403091 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -1786,6 +1786,8 @@ extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool + extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on); + extern SECStatus ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled); + extern SECStatus ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled); +@@ -80,11 +80,11 @@ + + extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy); + extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy); +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 72058f5..09a0fb5 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -1316,6 +1316,19 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled) ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index 28e3543..8ad1517 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -1369,6 +1369,19 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled) + } + + SECStatus +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/clientauth.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/clientauth.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/clientauth.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/clientauth.patch 2016-01-13 14:18:55.609954798 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index 91a47a6..4e7d52e 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -543,6 +543,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg, ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index 2a52769..48fa018 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -636,6 +636,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg, + SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd, + SSLGetClientAuthData f, void *a); + +@@ -51,11 +51,11 @@ + + /* + ** SNI extension processing callback function. +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 60af5b0..b9014ef 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -2503,6 +2503,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 9aaf601..cc193cd 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -2530,6 +2530,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { + PRBool isPresent = PR_TRUE; + + /* we only care if we are doing client auth */ +@@ -65,7 +65,7 @@ + if (!sid || !sid->u.ssl3.clAuthValid) { + return PR_TRUE; + } +-@@ -6178,25 +6181,36 @@ ssl3_SendCertificateVerify(sslSocket *ss) ++@@ -6352,25 +6355,36 @@ ssl3_SendCertificateVerify(sslSocket *ss) + + isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); +@@ -119,7 +119,7 @@ + if (rv != SECSuccess) { + goto done; /* err code was set by ssl3_SignHashes */ + } +-@@ -6275,6 +6289,12 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -6449,6 +6463,12 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); + ss->ssl3.clientPrivateKey = NULL; + } +@@ -132,7 +132,7 @@ + + temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); + if (temp < 0) { +-@@ -6904,6 +6924,18 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss, ++@@ -7109,6 +7129,18 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss, + goto done; + } + +@@ -151,7 +151,7 @@ + /* If the key is a 1024-bit RSA or DSA key, assume conservatively that + * it may be unable to sign SHA-256 hashes. This is the case for older + * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and +-@@ -7002,6 +7034,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -7207,6 +7239,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + SECItem cert_types = {siBuffer, NULL, 0}; + SECItem algorithms = {siBuffer, NULL, 0}; + CERTDistNames ca_list; +@@ -162,7 +162,7 @@ + + SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake", + SSL_GETPID(), ss->fd)); +-@@ -7017,6 +7053,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -7222,6 +7258,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + PORT_Assert(ss->ssl3.clientCertChain == NULL); + PORT_Assert(ss->ssl3.clientCertificate == NULL); + PORT_Assert(ss->ssl3.clientPrivateKey == NULL); +@@ -170,7 +170,7 @@ + + isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); +-@@ -7096,6 +7133,18 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -7301,6 +7338,18 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + desc = no_certificate; + ss->ssl3.hs.ws = wait_hello_done; + +@@ -187,9 +187,9 @@ + + } else + +#endif + if (ss->getClientAuthData != NULL) { +- /* XXX Should pass cert_types and algorithms in this call!! */ +- rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg, +-@@ -7105,12 +7154,55 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == ++ ssl_preinfo_all); ++@@ -7312,12 +7361,55 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + } else { + rv = SECFailure; /* force it to send a no_certificate alert */ + } +@@ -245,7 +245,7 @@ + /* check what the callback function returned */ + if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { + /* we are missing either the key or cert */ +-@@ -7172,6 +7264,10 @@ loser: ++@@ -7379,6 +7471,10 @@ loser: + done: + if (arena != NULL) + PORT_FreeArena(arena, PR_FALSE); +@@ -256,7 +256,7 @@ + return rv; + } + +-@@ -7288,7 +7384,8 @@ ssl3_SendClientSecondRound(sslSocket *ss) ++@@ -7497,7 +7593,8 @@ ssl3_SendClientSecondRound(sslSocket *ss) + + sendClientCert = !ss->ssl3.sendEmptyCert && + ss->ssl3.clientCertChain != NULL && +@@ -266,7 +266,7 @@ + + if (!sendClientCert && + ss->ssl3.hs.hashType == handshake_hash_single && +-@@ -12148,6 +12245,10 @@ ssl3_DestroySSL3Info(sslSocket *ss) ++@@ -12910,6 +13007,10 @@ ssl3_DestroySSL3Info(sslSocket *ss) + + if (ss->ssl3.clientPrivateKey != NULL) + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); +@@ -277,10 +277,10 @@ + + if (ss->ssl3.peerCertArena != NULL) + ssl3_CleanupPeerCerts(ss); +-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c +-index 28d21c4..0a2288a 100644 +---- a/ssl/ssl3ext.c +-+++ b/ssl/ssl3ext.c ++diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c ++index cf04aba..5661a5c 100644 ++--- a/lib/ssl/ssl3ext.c +++++ b/lib/ssl/ssl3ext.c + @@ -11,8 +11,8 @@ + #include "nssrenam.h" + #include "nss.h" +@@ -291,10 +291,10 @@ + #include "pk11pub.h" + #ifdef NO_PKCS11_BYPASS + #include "blapit.h" +-diff --git a/ssl/sslauth.c b/ssl/sslauth.c +-index ed74d94..7f9c43b 100644 +---- a/ssl/sslauth.c +-+++ b/ssl/sslauth.c ++diff --git a/lib/ssl/sslauth.c b/lib/ssl/sslauth.c ++index b144336..e6981f0 100644 ++--- a/lib/ssl/sslauth.c +++++ b/lib/ssl/sslauth.c + @@ -216,6 +216,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, + return SECSuccess; + } +@@ -324,11 +324,11 @@ + /* NEED LOCKS IN HERE. */ + SECStatus + SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 086f6d2..bbc9bd2 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -20,6 +20,7 @@ ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index 9dcc29e..94bb9f4 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -21,6 +21,7 @@ + #include "sslerr.h" + #include "ssl3prot.h" + #include "hasht.h" +@@ -336,7 +336,7 @@ + #include "nssilock.h" + #include "pkcs11t.h" + #if defined(XP_UNIX) || defined(XP_BEOS) +-@@ -31,6 +32,15 @@ ++@@ -32,6 +33,15 @@ + + #include "sslt.h" /* for some formerly private types, now public */ + +@@ -352,7 +352,7 @@ + /* to make some of these old enums public without namespace pollution, + ** it was necessary to prepend ssl_ to the names. + ** These #defines preserve compatibility with the old code here in libssl. +-@@ -443,6 +453,14 @@ struct sslGatherStr { ++@@ -453,6 +463,14 @@ struct sslGatherStr { + #define GS_DATA 3 + #define GS_PAD 4 + +@@ -367,7 +367,7 @@ + + + /* +-@@ -961,6 +979,10 @@ struct ssl3StateStr { ++@@ -974,6 +992,10 @@ struct ssl3StateStr { + + CERTCertificate * clientCertificate; /* used by client */ + SECKEYPrivateKey * clientPrivateKey; /* used by client */ +@@ -378,7 +378,7 @@ + CERTCertificateList *clientCertChain; /* used by client */ + PRBool sendEmptyCert; /* used by client */ + +-@@ -1223,6 +1245,10 @@ const unsigned char * preferredCipher; ++@@ -1253,6 +1275,10 @@ const unsigned char * preferredCipher; + void *authCertificateArg; + SSLGetClientAuthData getClientAuthData; + void *getClientAuthDataArg; +@@ -389,7 +389,7 @@ + SSLSNISocketConfig sniSocketConfig; + void *sniSocketConfigArg; + SSLBadCertHandler handleBadCert; +-@@ -1863,6 +1889,26 @@ extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); ++@@ -1896,6 +1922,26 @@ extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); + + extern SECStatus ssl_FreeSessionCacheLocks(void); + +@@ -416,11 +416,11 @@ + + /**************** DTLS-specific functions **************/ + extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg); +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 282bb85..6c09992 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -275,6 +275,10 @@ ssl_DupSocket(sslSocket *os) ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index f735009..21754d6 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -300,6 +300,10 @@ ssl_DupSocket(sslSocket *os) + ss->authCertificateArg = os->authCertificateArg; + ss->getClientAuthData = os->getClientAuthData; + ss->getClientAuthDataArg = os->getClientAuthDataArg; +@@ -431,7 +431,7 @@ + ss->sniSocketConfig = os->sniSocketConfig; + ss->sniSocketConfigArg = os->sniSocketConfigArg; + ss->handleBadCert = os->handleBadCert; +-@@ -1709,6 +1713,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) ++@@ -1963,6 +1967,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) + ss->getClientAuthData = sm->getClientAuthData; + if (sm->getClientAuthDataArg) + ss->getClientAuthDataArg = sm->getClientAuthDataArg; +@@ -444,7 +444,7 @@ + if (sm->sniSocketConfig) + ss->sniSocketConfig = sm->sniSocketConfig; + if (sm->sniSocketConfigArg) +-@@ -2974,6 +2984,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) ++@@ -3232,6 +3242,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) + ss->sniSocketConfig = NULL; + ss->sniSocketConfigArg = NULL; + ss->getClientAuthData = NULL; +Nur in qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches: dh1024.patch. +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/didhandshakeresume.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/didhandshakeresume.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/didhandshakeresume.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/didhandshakeresume.patch 2016-01-13 14:18:55.609954798 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index 4e7d52e..34142fc 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -1007,6 +1007,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index 48fa018..0983b5f 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -1117,6 +1117,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, + SSLExtensionType extId, + PRBool *yes); + +@@ -12,11 +12,11 @@ + /* + ** How long should we wait before retransmitting the next flight of + ** the DTLS handshake? Returns SECFailure if not DTLS or not in a +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 6c09992..1a9c584 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -1897,6 +1897,20 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd) ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index 21754d6..b73f8f6 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -2151,6 +2151,20 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd) + return &ss->sec.ci.sid->peerCertStatus; + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch 2016-01-13 14:18:55.609954798 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index 34142fc..e2d1b09 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -803,6 +803,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index 0983b5f..cf9f6db 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -896,6 +896,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, + PRBool flushCache, + PRIntervalTime timeout); + +@@ -19,11 +19,11 @@ + + #ifdef SSL_DEPRECATED_FUNCTION + /* deprecated! +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index b9014ef..800c28e 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -7061,6 +7061,9 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index cc193cd..27038f3 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -7266,6 +7266,9 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + if (rv != SECSuccess) + goto loser; /* malformed, alert has been sent */ + +@@ -33,7 +33,7 @@ + if (isTLS12) { + rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &b, &length); + if (rv != SECSuccess) +-@@ -7262,6 +7265,7 @@ loser: ++@@ -7469,6 +7472,7 @@ loser: + PORT_SetError(errCode); + rv = SECFailure; + done: +@@ -41,11 +41,11 @@ + if (arena != NULL) + PORT_FreeArena(arena, PR_FALSE); + #ifdef NSS_PLATFORM_CLIENT_AUTH +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index bbc9bd2..46e618a 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -1238,6 +1238,10 @@ struct sslSocketStr { ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index 94bb9f4..c7231a7 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -1265,6 +1265,10 @@ struct sslSocketStr { + unsigned int sizeCipherSpecs; + const unsigned char * preferredCipher; + +@@ -55,12 +55,12 @@ + + + ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */ + +- /* Callbacks */ +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 1a9c584..9431fe4 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -1911,6 +1911,20 @@ SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) { ++ const ssl3DHParams *dheParams; /* DHE param */ ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index b73f8f6..11e66f2 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -2165,6 +2165,20 @@ SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) { + return SECSuccess; + } + +@@ -81,11 +81,11 @@ + /************************************************************************/ + /* The following functions are the TOP LEVEL SSL functions. + ** They all get called through the NSPRIOMethods table below. +-@@ -2989,6 +3003,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) ++@@ -3243,6 +3257,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) + sc->serverKeyBits = 0; + ss->certStatusArray[i] = NULL; + } + + ss->requestedCertTypes = NULL; + ss->stepDownKeyPair = NULL; +- ss->dbHandle = CERT_GetDefaultCertDB(); + ++ ss->dheParams = NULL; +Nur in qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches: norenegotiatelock.patch. +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/nssrwlock.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/nssrwlock.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/nssrwlock.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/nssrwlock.patch 2016-01-13 14:18:55.610954804 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 0ac85da..f5afab7 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -5261,7 +5261,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index afab931..e5e620f 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -5436,7 +5436,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + * the lock across the calls to ssl3_CallHelloExtensionSenders. + */ + if (sid->u.ssl3.lock) { +@@ -11,7 +11,7 @@ + } + + if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) { +-@@ -5270,7 +5270,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5445,7 +5445,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + + extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL); + if (extLen < 0) { +@@ -20,7 +20,7 @@ + return SECFailure; + } + total_exten_len += extLen; +-@@ -5297,7 +5297,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5472,7 +5472,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + /* how many suites are permitted by policy and user preference? */ + num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE); + if (!num_suites) { +@@ -29,7 +29,7 @@ + return SECFailure; /* count_cipher_suites has set error code. */ + } + +-@@ -5342,7 +5342,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5517,7 +5517,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + + rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); + if (rv != SECSuccess) { +@@ -38,7 +38,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + +-@@ -5361,21 +5361,21 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5536,21 +5536,21 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); + } + if (rv != SECSuccess) { +@@ -63,7 +63,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + +-@@ -5385,7 +5385,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5560,7 +5560,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + else + rv = ssl3_AppendHandshakeNumber(ss, 0, 1); + if (rv != SECSuccess) { +@@ -72,7 +72,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + +-@@ -5393,14 +5393,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5568,14 +5568,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + rv = ssl3_AppendHandshakeVariable( + ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1); + if (rv != SECSuccess) { +@@ -89,7 +89,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + +-@@ -5409,7 +5409,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5584,7 +5584,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, + sizeof(ssl3CipherSuite)); + if (rv != SECSuccess) { +@@ -98,7 +98,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + actual_count++; +-@@ -5418,7 +5418,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5593,7 +5593,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV, + sizeof(ssl3CipherSuite)); + if (rv != SECSuccess) { +@@ -107,8 +107,8 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + actual_count++; +-@@ -5428,7 +5428,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) +- if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) { ++@@ -5603,7 +5603,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++ if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange, ss)) { + actual_count++; + if (actual_count > num_suites) { + - if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } +@@ -116,7 +116,7 @@ + /* set error card removal/insertion error */ + PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); + return SECFailure; +-@@ -5436,7 +5436,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5611,7 +5611,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite, + sizeof(ssl3CipherSuite)); + if (rv != SECSuccess) { +@@ -125,7 +125,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + } +-@@ -5447,14 +5447,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5622,14 +5622,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + * the server.. */ + if (actual_count != num_suites) { + /* Card removal/insertion error */ +@@ -142,7 +142,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + for (i = 0; i < compressionMethodsCount; i++) { +-@@ -5462,7 +5462,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5637,7 +5637,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + continue; + rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1); + if (rv != SECSuccess) { +@@ -151,7 +151,7 @@ + return rv; /* err set by ssl3_AppendHandshake* */ + } + } +-@@ -5473,20 +5473,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5648,20 +5648,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + + rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2); + if (rv != SECSuccess) { +@@ -175,7 +175,7 @@ + return SECFailure; + } + maxBytes -= extLen; +-@@ -5495,7 +5495,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) ++@@ -5670,7 +5670,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + } + + if (sid->u.ssl3.lock) { +@@ -184,11 +184,11 @@ + } + + if (ss->xtnData.sentSessionTicketInClientHello) { +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index d12228e..efcbf9f 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -731,7 +731,7 @@ struct sslSessionIDStr { ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index 3403091..874e59c 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -742,7 +742,7 @@ struct sslSessionIDStr { + * cached. Before then, there is no need to lock anything because + * the sid isn't being shared by anything. + */ +@@ -197,10 +197,10 @@ + + /* The lock must be held while reading or writing these members + * because they change while the sid is cached. +-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c ++diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c + index cefdda6..28ad364 100644 +---- a/ssl/sslnonce.c +-+++ b/ssl/sslnonce.c ++--- a/lib/ssl/sslnonce.c +++++ b/lib/ssl/sslnonce.c + @@ -136,7 +136,7 @@ ssl_DestroySID(sslSessionID *sid) + } + +Nur in qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches: removebuildmetadata.patch. +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/reorderextensions.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/reorderextensions.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/reorderextensions.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/reorderextensions.patch 2016-01-13 14:18:55.610954804 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c +-index c18d6f6..9214a2e 100644 +---- a/ssl/ssl3ext.c +-+++ b/ssl/ssl3ext.c +-@@ -313,6 +313,10 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { ++diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c ++index 9cfd541..eb3fb70 100644 ++--- a/lib/ssl/ssl3ext.c +++++ b/lib/ssl/ssl3ext.c ++@@ -321,6 +321,10 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, + { ssl_signed_certificate_timestamp_xtn, + &ssl3_ClientSendSignedCertTimestampXtn }, +@@ -12,8 +12,8 @@ + + * extension. */ + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn }, +- /* any extra entries will appear as { 0, NULL } */ +-@@ -2507,9 +2511,11 @@ ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) ++ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn}, ++@@ -2546,9 +2550,11 @@ ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) + } + + extensionLength = 512 - recordLength; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/restartclientauth.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/restartclientauth.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/restartclientauth.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/restartclientauth.patch 2016-01-13 14:18:55.610954804 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index e2d1b09..593dd00 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -409,6 +409,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd); ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index cf9f6db..85ced8a 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -502,6 +502,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd); + SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, + PRIntervalTime timeout); + +@@ -14,11 +14,11 @@ + /* + ** Query security status of socket. *on is set to one if security is + ** enabled. *keySize will contain the stream key size used. *issuer will +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 800c28e..29e8f1c 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -7275,6 +7275,85 @@ done: ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 27038f3..304e03b 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -7482,6 +7482,85 @@ done: + return rv; + } + +@@ -104,11 +104,11 @@ + static SECStatus + ssl3_CheckFalseStart(sslSocket *ss) + { +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 46e618a..2cf0b3a 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -1599,16 +1599,17 @@ extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index c7231a7..c089889 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -1629,16 +1629,17 @@ extern SECStatus ssl3_MasterSecretDeriveBypass( ssl3CipherSpec * pwSpec, + /* These functions are called from secnav, even though they're "private". */ + + extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error); +@@ -130,11 +130,11 @@ + extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error); + + /* +-diff --git a/ssl/sslsecur.c b/ssl/sslsecur.c +-index ea2d408..d44336e 100644 +---- a/ssl/sslsecur.c +-+++ b/ssl/sslsecur.c +-@@ -1516,17 +1516,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) ++diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c ++index 53b4885..f77d6fa 100644 ++--- a/lib/ssl/sslsecur.c +++++ b/lib/ssl/sslsecur.c ++@@ -1532,17 +1532,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) + return SECSuccess; + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/secitemarray.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/secitemarray.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/secitemarray.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/secitemarray.patch 2016-01-13 14:18:55.610954804 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index 0ece0ed..ea71975 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -1373,6 +1373,15 @@ extern sslSessionIDUncacheFunc ssl_sid_uncache; ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index 976330e..60dd243 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -1403,6 +1403,15 @@ extern sslSessionIDUncacheFunc ssl_sid_uncache; + + SEC_BEGIN_PROTOS + +@@ -18,11 +18,11 @@ + /* Internal initialization and installation of the SSL error tables */ + extern SECStatus ssl_Init(void); + extern SECStatus ssl_InitializePRErrorTable(void); +-diff --git a/ssl/sslt.h b/ssl/sslt.h +-index 0900f28..430d216 100644 +---- a/ssl/sslt.h +-+++ b/ssl/sslt.h +-@@ -10,6 +10,19 @@ ++diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h ++index b6616e2..5593579 100644 ++--- a/lib/ssl/sslt.h +++++ b/lib/ssl/sslt.h ++@@ -11,6 +11,19 @@ + + #include "prtypes.h" + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/secretexporterlocks.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/secretexporterlocks.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/secretexporterlocks.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/secretexporterlocks.patch 2016-01-13 14:18:55.611954809 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/sslinfo.c b/ssl/sslinfo.c +-index 00f2f38..ba230d2 100644 +---- a/ssl/sslinfo.c +-+++ b/ssl/sslinfo.c +-@@ -350,8 +350,13 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, ++diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c ++index 216ab0f..7048eb8 100644 ++--- a/lib/ssl/sslinfo.c +++++ b/lib/ssl/sslinfo.c ++@@ -387,8 +387,13 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, + return SECFailure; + } + +@@ -16,7 +16,7 @@ + return SECFailure; + } + +-@@ -362,13 +367,17 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, ++@@ -399,13 +404,17 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, + } + val = PORT_Alloc(valLen); + if (!val) { +@@ -34,7 +34,7 @@ + if (hasContext) { + val[i++] = contextLen >> 8; + val[i++] = contextLen; +-@@ -389,6 +398,8 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, ++@@ -426,6 +435,8 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, + valLen, out, outLen); + } + ssl_ReleaseSpecReadLock(ss); +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/sessioncache.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/sessioncache.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/sessioncache.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/sessioncache.patch 2016-01-13 14:18:55.611954809 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index be6d88e..57771cd 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -900,6 +900,18 @@ SSL_IMPORT int SSL_DataPending(PRFileDesc *fd); ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index 437a822..bc417a5 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -992,6 +992,18 @@ SSL_IMPORT int SSL_DataPending(PRFileDesc *fd); + SSL_IMPORT SECStatus SSL_InvalidateSession(PRFileDesc *fd); + + /* +@@ -21,11 +21,11 @@ + ** Return a SECItem containing the SSL session ID associated with the fd. + */ + SSL_IMPORT SECItem *SSL_GetSessionID(PRFileDesc *fd); +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 26b87c6..0ac85da 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -11375,7 +11375,7 @@ ssl3_FinishHandshake(sslSocket * ss) ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 572bba9..afab931 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -12058,7 +12058,7 @@ ssl3_FinishHandshake(sslSocket * ss) + ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE; + } + +@@ -34,11 +34,11 @@ + PORT_Assert(ss->sec.ci.sid->cached == never_cached); + (*ss->sec.cache)(ss->sec.ci.sid); + ss->ssl3.hs.cacheSID = PR_FALSE; +-diff --git a/ssl/sslsecur.c b/ssl/sslsecur.c +-index 5c6751a..00ab455 100644 +---- a/ssl/sslsecur.c +-+++ b/ssl/sslsecur.c +-@@ -1467,6 +1467,49 @@ SSL_InvalidateSession(PRFileDesc *fd) ++diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c ++index cca55bb..b4b8e95 100644 ++--- a/lib/ssl/sslsecur.c +++++ b/lib/ssl/sslsecur.c ++@@ -1483,6 +1483,49 @@ SSL_InvalidateSession(PRFileDesc *fd) + return rv; + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch 2016-01-13 14:18:55.612954815 +0100 +@@ -1,18 +1,17 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index 80717db..e9f5fb0 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -191,6 +191,9 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); +- #define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in +- * handshakes. */ ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index eb7f7ec..db09425 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -203,6 +203,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); ++ */ ++ #define SSL_ENABLE_EXTENDED_MASTER_SECRET 30 + + +/* Request Signed Certificate Timestamps via TLS extension (client) */ +-+#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 29 +-+ +++#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 31 ++ + #ifdef SSL_DEPRECATED_FUNCTION + /* Old deprecated function names */ +- SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on); +-@@ -493,6 +496,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd); ++@@ -586,6 +588,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd); + */ + SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd); + +@@ -36,13 +35,13 @@ + /* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses + * in the fd's data, which may be sent as part of a server side cert_status + * handshake message. Parameter |responses| is for the server certificate of +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 6a4a443..54c5b80 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -6752,6 +6752,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +- sid->u.ssl3.sessionIDLength = sidBytes.len; +- PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len); ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index ba3d012..5c09f25 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -6957,6 +6957,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++ sid->u.ssl3.keys.extendedMasterSecretUsed = ++ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn); + + + /* Copy Signed Certificate Timestamps, if any. */ + + if (ss->xtnData.signedCertTimestamps.data) { +@@ -55,7 +54,7 @@ + ss->ssl3.hs.isResuming = PR_FALSE; + if (ss->ssl3.hs.kea_def->signKeyType != sign_null) { + /* All current cipher suites other than those with sign_null (i.e., +-@@ -6765,6 +6773,10 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ++@@ -6971,6 +6979,10 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) + } + + winner: +@@ -66,7 +65,7 @@ + /* If we will need a ChannelID key then we make the callback now. This + * allows the handshake to be restarted cleanly if the callback returns + * SECWouldBlock. */ +-@@ -6790,6 +6802,9 @@ alert_loser: ++@@ -6996,6 +7008,9 @@ alert_loser: + (void)SSL3_SendAlert(ss, alert_fatal, desc); + + loser: +@@ -76,10 +75,10 @@ + errCode = ssl_MapLowLevelError(errCode); + return SECFailure; + } +-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c +-index 4d17587..c18d6f6 100644 +---- a/ssl/ssl3ext.c +-+++ b/ssl/ssl3ext.c ++diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c ++index 78825cb..9cfd541 100644 ++--- a/lib/ssl/ssl3ext.c +++++ b/lib/ssl/ssl3ext.c + @@ -90,6 +90,12 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); + static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, +@@ -93,16 +92,16 @@ + + static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); +-@@ -275,6 +281,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { +- { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn }, ++@@ -283,6 +289,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { + { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, ++ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, + + { ssl_signed_certificate_timestamp_xtn, + + &ssl3_ClientHandleSignedCertTimestampXtn }, + { -1, NULL } + }; + +-@@ -303,6 +311,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { ++@@ -311,6 +319,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { + { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn }, + { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, +@@ -110,12 +109,16 @@ + + &ssl3_ClientSendSignedCertTimestampXtn }, + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn }, +- /* any extra entries will appear as { 0, NULL } */ +-@@ -2616,3 +2626,65 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type, ++ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn}, ++@@ -2698,11 +2708,48 @@ ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append, ++ } + +- return SECSuccess; ++ return extension_length; ++- ++ loser: ++ return -1; + } +-+ ++ + +/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp + + * extension for TLS ClientHellos. */ + +static PRInt32 +@@ -129,7 +132,12 @@ + + if (!ss->opt.enableSignedCertTimestamps) + + return 0; + + +-+ if (append && maxBytes >= extension_length) { +++ if (maxBytes < extension_length) { +++ PORT_Assert(0); +++ return 0; +++ } +++ +++ if (append) { + + SECStatus rv; + + /* extension_type */ + + rv = ssl3_AppendHandshakeNumber(ss, +@@ -143,15 +151,19 @@ + + goto loser; + + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + + ssl_signed_certificate_timestamp_xtn; +-+ } else if (maxBytes < extension_length) { +-+ PORT_Assert(0); +-+ return 0; + + } + + + + return extension_length; + +loser: + + return -1; + +} ++ ++ static SECStatus ++ ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type, ++@@ -2743,3 +2790,28 @@ ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type, ++ } ++ return SECSuccess; ++ } + + + +static SECStatus + +ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, +@@ -177,19 +189,19 @@ + + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + + return SECSuccess; + +} +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index c4c87b4..0fd0a89 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -339,6 +339,7 @@ typedef struct sslOptionsStr { +- unsigned int enableALPN : 1; /* 27 */ +- unsigned int reuseServerECDHEKey : 1; /* 28 */ ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index d53c446..080debe 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -349,6 +349,7 @@ typedef struct sslOptionsStr { + unsigned int enableFallbackSCSV : 1; /* 29 */ +-+ unsigned int enableSignedCertTimestamps : 1; /* 30 */ ++ unsigned int enableServerDhe : 1; /* 30 */ ++ unsigned int enableExtendedMS : 1; /* 31 */ +++ unsigned int enableSignedCertTimestamps : 1; /* 32 */ + } sslOptions; + + typedef enum { sslHandshakingUndetermined = 0, +-@@ -721,6 +722,11 @@ struct sslSessionIDStr { ++@@ -732,6 +733,11 @@ struct sslSessionIDStr { + * resumption handshake to the original handshake. */ + SECItem originalHandshakeHash; + +@@ -201,7 +213,7 @@ + /* This lock is lazily initialized by CacheSID when a sid is first + * cached. Before then, there is no need to lock anything because + * the sid isn't being shared by anything. +-@@ -835,6 +841,18 @@ struct TLSExtensionDataStr { ++@@ -846,6 +852,18 @@ struct TLSExtensionDataStr { + * is beyond ssl3_HandleClientHello function. */ + SECItem *sniNameArr; + PRUint32 sniNameArrSize; +@@ -220,10 +232,10 @@ + }; + + typedef SECStatus (*sslRestartTarget)(sslSocket *); +-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c ++diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c + index c45849d..cefdda6 100644 +---- a/ssl/sslnonce.c +-+++ b/ssl/sslnonce.c ++--- a/lib/ssl/sslnonce.c +++++ b/lib/ssl/sslnonce.c + @@ -131,6 +131,9 @@ ssl_DestroySID(sslSessionID *sid) + if (sid->u.ssl3.originalHandshakeHash.data) { + SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); +@@ -234,22 +246,22 @@ + + if (sid->u.ssl3.lock) { + PR_DestroyRWLock(sid->u.ssl3.lock); +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 6a6c8d1..72058f5 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -89,7 +89,8 @@ static sslOptions ssl_defaults = { +- PR_TRUE, /* enableNPN */ +- PR_FALSE, /* enableALPN */ ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index 6d700a7..28e3543 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -92,7 +92,8 @@ static sslOptions ssl_defaults = { + PR_TRUE, /* reuseServerECDHEKey */ +-- PR_FALSE /* enableFallbackSCSV */ +-+ PR_FALSE, /* enableFallbackSCSV */ ++ PR_FALSE, /* enableFallbackSCSV */ ++ PR_TRUE, /* enableServerDhe */ ++- PR_FALSE /* enableExtendedMS */ +++ PR_FALSE, /* enableExtendedMS */ + + PR_FALSE, /* enableSignedCertTimestamps */ + }; + + /* +-@@ -807,6 +808,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) +- ss->opt.enableFallbackSCSV = on; ++@@ -843,6 +844,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) ++ ss->opt.enableExtendedMS = on; + break; + + + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: +@@ -259,19 +271,19 @@ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; +-@@ -882,6 +887,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) +- case SSL_REUSE_SERVER_ECDHE_KEY: +- on = ss->opt.reuseServerECDHEKey; break; +- case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break; ++@@ -921,6 +926,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) ++ case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break; ++ case SSL_ENABLE_EXTENDED_MASTER_SECRET: ++ on = ss->opt.enableExtendedMS; break; + + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: + + on = ss->opt.enableSignedCertTimestamps; + + break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +-@@ -951,6 +959,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) +- case SSL_ENABLE_FALLBACK_SCSV: +- on = ssl_defaults.enableFallbackSCSV; ++@@ -996,6 +1004,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) ++ case SSL_ENABLE_EXTENDED_MASTER_SECRET: ++ on = ssl_defaults.enableExtendedMS; + break; + + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: + + on = ssl_defaults.enableSignedCertTimestamps; +@@ -279,8 +291,8 @@ + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +-@@ -1134,6 +1145,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) +- ssl_defaults.enableFallbackSCSV = on; ++@@ -1187,6 +1198,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) ++ ssl_defaults.enableExtendedMS = on; + break; + + + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: +@@ -290,7 +302,7 @@ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +-@@ -1963,6 +1978,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd) ++@@ -2218,6 +2233,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd) + return &ss->sec.ci.sid->peerCertStatus; + } + +@@ -320,23 +332,24 @@ + SECStatus + SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) { + sslSocket *ss = ssl_FindSocket(fd); +-diff --git a/ssl/sslt.h b/ssl/sslt.h +-index fe0ad07..c36b8c7 100644 +---- a/ssl/sslt.h +-+++ b/ssl/sslt.h +-@@ -202,6 +202,7 @@ typedef enum { ++diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h ++index a2eff62..36e34df 100644 ++--- a/lib/ssl/sslt.h +++++ b/lib/ssl/sslt.h ++@@ -248,6 +248,7 @@ typedef enum { + ssl_signature_algorithms_xtn = 13, + ssl_use_srtp_xtn = 14, + ssl_app_layer_protocol_xtn = 16, + + ssl_signed_certificate_timestamp_xtn = 18, /* RFC 6962 */ + ssl_padding_xtn = 21, ++ ssl_extended_master_secret_xtn = 23, + ssl_session_ticket_xtn = 35, +- ssl_next_proto_nego_xtn = 13172, +-@@ -210,6 +211,6 @@ typedef enum { ++@@ -257,7 +258,7 @@ typedef enum { + ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */ + } SSLExtensionType; + +--#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */ +-+#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */ ++-#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */ +++#define SSL_MAX_EXTENSIONS 14 /* doesn't include ssl_padding_xtn. */ + +- #endif /* __sslt_h_ */ ++ typedef enum { ++ ssl_dhe_group_none = 0, +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/suitebonly.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/suitebonly.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/suitebonly.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/suitebonly.patch 2016-01-13 14:18:55.612954815 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3ecc.c b/ssl/ssl3ecc.c +-index aca2b74..dac7a9e 100644 +---- a/ssl/ssl3ecc.c +-+++ b/ssl/ssl3ecc.c +-@@ -1090,6 +1090,7 @@ static const PRUint8 ecPtFmt[6] = { ++diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c ++index 94008a0..6d89bbe 100644 ++--- a/lib/ssl/ssl3ecc.c +++++ b/lib/ssl/ssl3ecc.c ++@@ -1093,6 +1093,7 @@ static const PRUint8 ecPtFmt[6] = { + static PRBool + ssl3_SuiteBOnly(sslSocket *ss) + { +@@ -10,7 +10,7 @@ + /* See if we can support small curves (like 163). If not, assume we can + * only support Suite-B curves (P-256, P-384, P-521). */ + PK11SlotInfo *slot = +-@@ -1103,6 +1104,9 @@ ssl3_SuiteBOnly(sslSocket *ss) ++@@ -1106,6 +1107,9 @@ ssl3_SuiteBOnly(sslSocket *ss) + /* we can, presume we can do all curves */ + PK11_FreeSlot(slot); + return PR_FALSE; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/tls12chromium.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/tls12chromium.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/tls12chromium.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/tls12chromium.patch 2016-01-13 14:18:55.612954815 +0100 +@@ -1,8 +1,8 @@ +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index 7c06815..1167d6d 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -31,6 +31,15 @@ ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index ce92cf1..c5cb1eb 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -33,6 +33,15 @@ + #include "blapi.h" + #endif + +@@ -18,10 +18,10 @@ + #include + #ifdef NSS_ENABLE_ZLIB + #include "zlib.h" +-diff --git a/ssl/ssl3ecc.c b/ssl/ssl3ecc.c +-index dac7a9e..9b91270 100644 +---- a/ssl/ssl3ecc.c +-+++ b/ssl/ssl3ecc.c ++diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c ++index 6d89bbe..cf8e741 100644 ++--- a/lib/ssl/ssl3ecc.c +++++ b/lib/ssl/ssl3ecc.c + @@ -31,6 +31,12 @@ + + #include +@@ -35,16 +35,17 @@ + #ifndef NSS_DISABLE_ECC + + #ifndef PK11_SETATTRS +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 14ff328..6a6c8d1 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -17,8 +17,15 @@ ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index c9a4493..6d700a7 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -17,9 +17,16 @@ + #ifndef NO_PKCS11_BYPASS + #include "blapi.h" + #endif + +#include "pk11pub.h" + #include "nss.h" ++ #include "pk11pqg.h" + + +/* This is a bodge to allow this code to be compiled against older NSS headers + + * that don't contain the TLS 1.2 changes. */ +@@ -55,7 +56,7 @@ + #define SET_ERROR_CODE /* reminder */ + + static const sslSocketOps ssl_default_ops = { /* No SSL. */ +-@@ -1878,6 +1885,24 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange) ++@@ -2133,6 +2140,24 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange) + return SECSuccess; + } + +@@ -80,7 +81,7 @@ + SECStatus + SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange) + { +-@@ -1898,6 +1923,20 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange) ++@@ -2153,6 +2178,20 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange) + ssl_GetSSL3HandshakeLock(ss); + + ss->vrange = *vrange; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/tlsunique.patch qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/tlsunique.patch +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/patches/tlsunique.patch 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/patches/tlsunique.patch 2016-01-13 14:18:55.612954815 +0100 +@@ -1,10 +1,10 @@ +-diff --git a/ssl/ssl.h b/ssl/ssl.h +-index 716537d..80717db 100644 +---- a/ssl/ssl.h +-+++ b/ssl/ssl.h +-@@ -292,6 +292,27 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled); +- SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy); +- SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy); ++diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h ++index 120c257..eb7f7ec 100644 ++--- a/lib/ssl/ssl.h +++++ b/lib/ssl/ssl.h ++@@ -385,6 +385,27 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd, ++ */ ++ SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled); + + +/* SSLChannelBindingType enumerates the types of supported channel binding + + * values. See RFC 5929. */ +@@ -30,12 +30,12 @@ + /* SSL Version Range API + ** + ** This API should be used to control SSL 3.0 & TLS support instead of the +-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c +-index c0e8e79..7c06815 100644 +---- a/ssl/ssl3con.c +-+++ b/ssl/ssl3con.c +-@@ -12479,6 +12479,68 @@ ssl3_InitSocketPolicy(sslSocket *ss) +- PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites); ++diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c ++index 2ae8ce9..ce92cf1 100644 ++--- a/lib/ssl/ssl3con.c +++++ b/lib/ssl/ssl3con.c ++@@ -13241,6 +13241,68 @@ ssl3_InitSocketPolicy(sslSocket *ss) ++ ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms); + } + + +SECStatus +@@ -103,11 +103,11 @@ + /* ssl3_config_match_init must have already been called by + * the caller of this function. + */ +-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h +-index e11860e..0ece0ed 100644 +---- a/ssl/sslimpl.h +-+++ b/ssl/sslimpl.h +-@@ -1864,6 +1864,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey, ++diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h ++index c286518..976330e 100644 ++--- a/lib/ssl/sslimpl.h +++++ b/lib/ssl/sslimpl.h ++@@ -1897,6 +1897,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey, + extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, + unsigned int length); + +@@ -119,12 +119,12 @@ + /* Construct a new NSPR socket for the app to use */ + extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd); + extern void ssl_FreePRSocket(PRFileDesc *fd); +-diff --git a/ssl/sslsock.c b/ssl/sslsock.c +-index 042f24f..14ff328 100644 +---- a/ssl/sslsock.c +-+++ b/ssl/sslsock.c +-@@ -1345,6 +1345,27 @@ NSS_SetFrancePolicy(void) +- return NSS_SetDomesticPolicy(); ++diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c ++index efba686..c9a4493 100644 ++--- a/lib/ssl/sslsock.c +++++ b/lib/ssl/sslsock.c ++@@ -1540,6 +1540,28 @@ SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled) ++ return SECSuccess; + } + + +SECStatus +@@ -148,6 +148,7 @@ + + + + return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax); + +} +++ ++ #include "dhe-param.c" + +- +- /* LOCKS ??? XXX */ ++ static const SSLDHEGroupType ssl_default_dhe_groups[] = { +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/README.chromium qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/README.chromium +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/README.chromium 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/README.chromium 2016-01-13 14:18:55.588954676 +0100 +@@ -1,6 +1,6 @@ + Name: Network Security Services (NSS) + URL: http://www.mozilla.org/projects/security/pki/nss/ +-Version: 3.19 RTM ++Version: 3.21 RTM + Security Critical: Yes + License: MPL 2 + License File: NOT_SHIPPED +@@ -11,7 +11,7 @@ + The same module appears in crypto/third_party/nss (and third_party/nss on some + platforms), so we don't repeat the license file here. + +-The snapshot was updated to the hg tag: NSS_3_19_RTM ++The snapshot was updated to the hg tag: NSS_3_21_RTM + + Patches: + +@@ -100,16 +100,6 @@ + length. + patches/reorderextensions.patch + +- * Make the build metadata deterministic +- patches/removebuildmetadata.patch +- +- * Fix locking bug in ssl3_HandleHelloRequest when rejecting a renegotiation. +- patches/norenegotiatelock.patch +- https://bugzilla.mozilla.org/show_bug.cgi?id=1162521 +- +- * Increase the minimum DH group size to 1024 +- patches/dh1024.patch +- + Apply the patches to NSS by running the patches/applypatches.sh script. Read + the comments at the top of patches/applypatches.sh for instructions. + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/derive.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/derive.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/derive.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/derive.c 2016-01-13 14:18:55.613954821 +0100 +@@ -431,7 +431,7 @@ + * so isRSA is always true. + */ + SECStatus +-ssl3_MasterKeyDeriveBypass( ++ssl3_MasterSecretDeriveBypass( + ssl3CipherSpec * pwSpec, + const unsigned char * cr, + const unsigned char * sr, +Nur in qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl: dhe-param.c. +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/dtlscon.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/dtlscon.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/dtlscon.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/dtlscon.c 2016-01-13 14:18:55.614954827 +0100 +@@ -104,9 +104,7 @@ + const ssl3CipherSuite * suite; + + for (suite = nonDTLSSuites; *suite; ++suite) { +- SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); +- +- PORT_Assert(rv == SECSuccess); /* else is coding error */ ++ PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); + } + return SECSuccess; + } +@@ -229,7 +227,7 @@ + #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ + if (message_length > MAX_HANDSHAKE_MSG_LEN) { + (void)ssl3_DecodeError(ss); +- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); ++ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); + return SECFailure; + } + #undef MAX_HANDSHAKE_MSG_LEN +@@ -396,7 +394,7 @@ + * This avoids having to fill in the bitmask in the common + * case of adjacent fragments received in sequence + */ +- if (fragment_offset <= ss->ssl3.hs.recvdHighWater) { ++ if (fragment_offset <= (unsigned int)ss->ssl3.hs.recvdHighWater) { + /* Either this is the adjacent fragment or an overlapping + * fragment */ + ss->ssl3.hs.recvdHighWater = fragment_offset + +@@ -676,7 +674,7 @@ + + /* The reason we use 8 here is that that's the length of + * the new DTLS data that we add to the header */ +- fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8), ++ fragment_len = PR_MIN((PRUint32)room_left - (SSL3_BUFFER_FUDGE + 8), + content_len - fragment_offset); + PORT_Assert(fragment_len < DTLS_MAX_MTU - 12); + /* Make totally sure that we are within the buffer. +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3con.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3con.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3con.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3con.c 2016-01-13 14:18:55.620954862 +0100 +@@ -25,6 +25,8 @@ + #include "prerror.h" + #include "pratom.h" + #include "prthread.h" ++#include "nss.h" ++#include "nssoptions.h" + + #include "pk11func.h" + #include "secmod.h" +@@ -91,8 +93,11 @@ + static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, + const unsigned char *b, + unsigned int l); ++static SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss, ++ ssl3CipherSpec *spec, ++ SSL3Hashes *hashes, ++ PRUint32 sender); + static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); +-static int ssl3_OIDToTLSHashAlgorithm(SECOidTag oid); + + static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, + int maxOutputLen, const unsigned char *input, +@@ -122,17 +127,17 @@ + #ifndef NSS_DISABLE_ECC + { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around + * bug 946147. + */ +- { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +@@ -140,14 +145,17 @@ + #endif /* NSS_DISABLE_ECC */ + + { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, +@@ -205,6 +213,23 @@ + { TLS_RSA_WITH_NULL_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + }; + ++static const SSLSignatureAndHashAlg defaultSignatureAlgorithms[] = { ++ {ssl_hash_sha256, ssl_sign_rsa}, ++ {ssl_hash_sha384, ssl_sign_rsa}, ++ {ssl_hash_sha512, ssl_sign_rsa}, ++ {ssl_hash_sha1, ssl_sign_rsa}, ++#ifndef NSS_DISABLE_ECC ++ {ssl_hash_sha256, ssl_sign_ecdsa}, ++ {ssl_hash_sha384, ssl_sign_ecdsa}, ++ {ssl_hash_sha512, ssl_sign_ecdsa}, ++ {ssl_hash_sha1, ssl_sign_ecdsa}, ++#endif ++ {ssl_hash_sha256, ssl_sign_dsa}, ++ {ssl_hash_sha1, ssl_sign_dsa} ++}; ++PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureAlgorithms) <= ++ MAX_SIGNATURE_ALGORITHMS); ++ + /* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order. + */ + #ifdef DEBUG +@@ -265,20 +290,6 @@ + ct_DSS_sign, + }; + +-/* This block is the contents of the supported_signature_algorithms field of +- * our TLS 1.2 CertificateRequest message, in wire format. See +- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 +- * +- * This block contains only sha256 entries because we only support TLS 1.2 +- * CertificateVerify messages that use the handshake hash. */ +-static const PRUint8 supported_signature_algorithms[] = { +- tls_hash_sha256, tls_sig_rsa, +-#ifndef NSS_DISABLE_ECC +- tls_hash_sha256, tls_sig_ecdsa, +-#endif +- tls_hash_sha256, tls_sig_dsa, +-}; +- + #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */ + + +@@ -322,8 +333,8 @@ + /* kea exchKeyType signKeyType is_limited limit tls_keygen ephemeral */ + {kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE, PR_FALSE}, + {kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE}, +- {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_TRUE}, +- {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE, PR_TRUE}, ++ {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_FALSE}, ++ {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE, PR_FALSE}, + {kea_dh_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE, PR_FALSE}, + {kea_dh_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE, PR_FALSE}, + {kea_dh_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE}, +@@ -443,6 +454,10 @@ + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa}, + ++ {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss}, ++ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss}, ++ {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss}, ++ + #ifndef NSS_DISABLE_ECC + {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, + {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa}, +@@ -680,6 +695,8 @@ + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case TLS_RSA_WITH_AES_128_CBC_SHA256: + case TLS_RSA_WITH_AES_128_GCM_SHA256: ++ case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: ++ case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case TLS_RSA_WITH_NULL_SHA256: + return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2; + +@@ -688,6 +705,7 @@ + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: ++ case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2; + + /* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and +@@ -810,16 +828,11 @@ + * that the server uses an RSA cert for (EC)DHE-RSA. + */ + switch (cipher_def->key_exchange_alg) { ++ case kea_dhe_dss: ++ svrAuth = ss->serverCerts + ssl_kea_dh; ++ break; + case kea_ecdhe_rsa: +-#if NSS_SERVER_DHE_IMPLEMENTED +- /* XXX NSS does not yet implement the server side of _DHE_ +- * cipher suites. Correcting the computation for svrAuth, +- * as the case below does, causes NSS SSL servers to begin to +- * negotiate cipher suites they do not implement. So, until +- * server side _DHE_ is implemented, keep this disabled. +- */ + case kea_dhe_rsa: +-#endif + svrAuth = ss->serverCerts + kt_rsa; + break; + case kea_ecdh_ecdsa: +@@ -831,6 +844,8 @@ + * simultaneously. For now, both of them use + * whatever is in the certificate slot for kt_ecdh + */ ++ case kea_dhe_dss_export: ++ case kea_dhe_rsa_export: + default: + svrAuth = ss->serverCerts + exchKeyType; + break; +@@ -867,11 +882,22 @@ + * cipher suite. */ + static PRBool + config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled, +- const SSLVersionRange *vrange) ++ const SSLVersionRange *vrange, const sslSocket *ss) + { ++ const ssl3CipherSuiteDef *cipher_def; ++ + PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE); + if (policy == SSL_NOT_ALLOWED || !enabled) +- return PR_FALSE; ++ return PR_FALSE; ++ ++ cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite); ++ PORT_Assert(cipher_def != NULL); ++ ++ PORT_Assert(ss != NULL); ++ if (ss->sec.isServer && !ss->opt.enableServerDhe && ++ kea_defs[cipher_def->key_exchange_alg].exchKeyType == ssl_kea_dh) ++ return PR_FALSE; ++ + return (PRBool)(suite->enabled && + suite->isPresent && + suite->policy != SSL_NOT_ALLOWED && +@@ -892,7 +918,7 @@ + return 0; + } + for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { +- if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange)) ++ if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange, ss)) + count++; + } + if (count <= 0) { +@@ -984,9 +1010,9 @@ + break; + case dsaKey: + doDerEncode = isTLS; +- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. ++ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash. + * In that case, we use just the SHA1 part. */ +- if (hash->hashAlg == SEC_OID_UNKNOWN) { ++ if (hash->hashAlg == ssl_hash_none) { + hashItem.data = hash->u.s.sha; + hashItem.len = sizeof(hash->u.s.sha); + } else { +@@ -997,9 +1023,9 @@ + #ifndef NSS_DISABLE_ECC + case ecKey: + doDerEncode = PR_TRUE; +- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. ++ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash. + * In that case, we use just the SHA1 part. */ +- if (hash->hashAlg == SEC_OID_UNKNOWN) { ++ if (hash->hashAlg == ssl_hash_none) { + hashItem.data = hash->u.s.sha; + hashItem.len = sizeof(hash->u.s.sha); + } else { +@@ -1014,7 +1040,7 @@ + } + PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); + +- if (hash->hashAlg == SEC_OID_UNKNOWN) { ++ if (hash->hashAlg == ssl_hash_none) { + signatureLen = PK11_SignatureLen(key); + if (signatureLen <= 0) { + PORT_SetError(SEC_ERROR_INVALID_KEY); +@@ -1028,7 +1054,8 @@ + + rv = PK11_Sign(key, buf, &hashItem); + } else { +- rv = SGN_Digest(key, hash->hashAlg, buf, &hashItem); ++ SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(hash->hashAlg); ++ rv = SGN_Digest(key, hashOID, buf, &hashItem); + } + if (rv != SECSuccess) { + ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE); +@@ -1076,7 +1103,7 @@ + return SECFailure; + } + +- hashAlg = hash->hashAlg; ++ hashAlg = ssl3_TLSHashAlgorithmToOID(hash->hashAlg); + switch (key->keyType) { + case rsaKey: + encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION; +@@ -1085,9 +1112,9 @@ + break; + case dsaKey: + encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; +- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. ++ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash. + * In that case, we use just the SHA1 part. */ +- if (hash->hashAlg == SEC_OID_UNKNOWN) { ++ if (hash->hashAlg == ssl_hash_none) { + hashItem.data = hash->u.s.sha; + hashItem.len = sizeof(hash->u.s.sha); + } else { +@@ -1108,13 +1135,13 @@ + #ifndef NSS_DISABLE_ECC + case ecKey: + encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; +- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. ++ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash. + * In that case, we use just the SHA1 part. + * ECDSA signatures always encode the integers r and s using ASN.1 + * (unlike DSA where ASN.1 encoding is used with TLS but not with + * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA. + */ +- if (hash->hashAlg == SEC_OID_UNKNOWN) { ++ if (hash->hashAlg == ssl_hash_none) { + hashAlg = SEC_OID_SHA1; + hashItem.data = hash->u.s.sha; + hashItem.len = sizeof(hash->u.s.sha); +@@ -1142,8 +1169,8 @@ + */ + rv = PK11_Verify(key, buf, &hashItem, pwArg); + } else { +- rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg, +- pwArg); ++ rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg, ++ pwArg); + } + SECKEY_DestroyPublicKey(key); + if (signature) { +@@ -1159,75 +1186,71 @@ + /* Caller must set hiLevel error code. */ + /* Called from ssl3_ComputeExportRSAKeyHash + * ssl3_ComputeDHKeyHash +- * which are called from ssl3_HandleServerKeyExchange. ++ * which are called from ssl3_HandleServerKeyExchange. + * +- * hashAlg: either the OID for a hash algorithm or SEC_OID_UNKNOWN to specify +- * the pre-1.2, MD5/SHA1 combination hash. ++ * hashAlg: ssl_hash_none indicates the pre-1.2, MD5/SHA1 combination hash. + */ + SECStatus +-ssl3_ComputeCommonKeyHash(SECOidTag hashAlg, +- PRUint8 * hashBuf, unsigned int bufLen, +- SSL3Hashes *hashes, PRBool bypassPKCS11) ++ssl3_ComputeCommonKeyHash(SSLHashType hashAlg, ++ PRUint8 * hashBuf, unsigned int bufLen, ++ SSL3Hashes *hashes, PRBool bypassPKCS11) + { +- SECStatus rv = SECSuccess; ++ SECStatus rv; ++ SECOidTag hashOID; + + #ifndef NO_PKCS11_BYPASS + if (bypassPKCS11) { +- if (hashAlg == SEC_OID_UNKNOWN) { +- MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen); +- SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen); +- hashes->len = MD5_LENGTH + SHA1_LENGTH; +- } else if (hashAlg == SEC_OID_SHA1) { +- SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen); +- hashes->len = SHA1_LENGTH; +- } else if (hashAlg == SEC_OID_SHA256) { +- SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen); +- hashes->len = SHA256_LENGTH; +- } else if (hashAlg == SEC_OID_SHA384) { +- SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen); +- hashes->len = SHA384_LENGTH; +- } else if (hashAlg == SEC_OID_SHA512) { +- SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen); +- hashes->len = SHA512_LENGTH; +- } else { +- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); +- return SECFailure; +- } +- } else ++ if (hashAlg == ssl_hash_none) { ++ MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen); ++ SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen); ++ hashes->len = MD5_LENGTH + SHA1_LENGTH; ++ } else if (hashAlg == ssl_hash_sha1) { ++ SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen); ++ hashes->len = SHA1_LENGTH; ++ } else if (hashAlg == ssl_hash_sha256) { ++ SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen); ++ hashes->len = SHA256_LENGTH; ++ } else if (hashAlg == ssl_hash_sha384) { ++ SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen); ++ hashes->len = SHA384_LENGTH; ++ } else if (hashAlg == ssl_hash_sha512) { ++ SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen); ++ hashes->len = SHA512_LENGTH; ++ } else { ++ PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); ++ return SECFailure; ++ } ++ } else + #endif + { +- if (hashAlg == SEC_OID_UNKNOWN) { +- rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen); +- if (rv != SECSuccess) { +- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); +- rv = SECFailure; +- goto done; +- } +- +- rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen); +- if (rv != SECSuccess) { +- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); +- rv = SECFailure; +- } +- hashes->len = MD5_LENGTH + SHA1_LENGTH; +- } else { +- hashes->len = HASH_ResultLenByOidTag(hashAlg); +- if (hashes->len > sizeof(hashes->u.raw)) { +- ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); +- rv = SECFailure; +- goto done; +- } +- rv = PK11_HashBuf(hashAlg, hashes->u.raw, hashBuf, bufLen); +- if (rv != SECSuccess) { +- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); +- rv = SECFailure; +- } +- } ++ if (hashAlg == ssl_hash_none) { ++ rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen); ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); ++ return rv; ++ } ++ rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen); ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); ++ return rv; ++ } ++ hashes->len = MD5_LENGTH + SHA1_LENGTH; ++ } else { ++ hashOID = ssl3_TLSHashAlgorithmToOID(hashAlg); ++ hashes->len = HASH_ResultLenByOidTag(hashOID); ++ if (hashes->len == 0 || hashes->len > sizeof(hashes->u.raw)) { ++ ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); ++ return SECFailure; ++ } ++ rv = PK11_HashBuf(hashOID, hashes->u.raw, hashBuf, bufLen); ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); ++ return rv; ++ } ++ } + } + hashes->hashAlg = hashAlg; +- +-done: +- return rv; ++ return SECSuccess; + } + + /* Caller must set hiLevel error code. +@@ -1235,10 +1258,10 @@ + ** ssl3_HandleServerKeyExchange. + */ + static SECStatus +-ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg, +- SECItem modulus, SECItem publicExponent, +- SSL3Random *client_rand, SSL3Random *server_rand, +- SSL3Hashes *hashes, PRBool bypassPKCS11) ++ssl3_ComputeExportRSAKeyHash(SSLHashType hashAlg, ++ SECItem modulus, SECItem publicExponent, ++ SSL3Random *client_rand, SSL3Random *server_rand, ++ SSL3Hashes *hashes, PRBool bypassPKCS11) + { + PRUint8 * hashBuf; + PRUint8 * pBuf; +@@ -1276,7 +1299,7 @@ + bypassPKCS11); + + PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen)); +- if (hashAlg == SEC_OID_UNKNOWN) { ++ if (hashAlg == ssl_hash_none) { + PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", + hashes->u.s.md5, MD5_LENGTH)); + PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", +@@ -1294,10 +1317,10 @@ + /* Caller must set hiLevel error code. */ + /* Called from ssl3_HandleServerKeyExchange. */ + static SECStatus +-ssl3_ComputeDHKeyHash(SECOidTag hashAlg, +- SECItem dh_p, SECItem dh_g, SECItem dh_Ys, +- SSL3Random *client_rand, SSL3Random *server_rand, +- SSL3Hashes *hashes, PRBool bypassPKCS11) ++ssl3_ComputeDHKeyHash(SSLHashType hashAlg, ++ SECItem dh_p, SECItem dh_g, SECItem dh_Ys, ++ SSL3Random *client_rand, SSL3Random *server_rand, ++ SSL3Hashes *hashes, PRBool bypassPKCS11) + { + PRUint8 * hashBuf; + PRUint8 * pBuf; +@@ -1340,7 +1363,7 @@ + bypassPKCS11); + + PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen)); +- if (hashAlg == SEC_OID_UNKNOWN) { ++ if (hashAlg == ssl_hash_none) { + PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", + hashes->u.s.md5, MD5_LENGTH)); + PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", +@@ -2298,7 +2321,11 @@ + * Sets error code, but caller probably should override to disambiguate. + * NULL pms means re-use old master_secret. + * +- * This code is common to the bypass and PKCS11 execution paths. ++ * This code is common to the bypass and PKCS11 execution paths. For ++ * the bypass case, pms is NULL. If the old master secret is reused, ++ * pms is NULL and the master secret is already in either ++ * pwSpec->msItem.len (the bypass case) or pwSpec->master_secret. ++ * + * For the bypass case, pms is NULL. + */ + SECStatus +@@ -2682,7 +2709,7 @@ + PRUint32 fragLen; + PRUint32 p1Len, p2Len, oddLen = 0; + PRUint16 headerLen; +- int ivLen = 0; ++ unsigned int ivLen = 0; + int cipherBytes = 0; + unsigned char pseudoHeader[13]; + unsigned int pseudoHeaderLen; +@@ -3244,7 +3271,8 @@ + { + static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER | + ssl_SEND_FLAG_CAP_RECORD_VERSION; +- PRInt32 rv = SECSuccess; ++ PRInt32 count = -1; ++ SECStatus rv = SECSuccess; + + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); +@@ -3258,18 +3286,19 @@ + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; + } else { +- rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf, ++ count = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf, + ss->sec.ci.sendBuf.len, flags); + } +- if (rv < 0) { ++ if (count < 0) { + int err = PORT_GetError(); + PORT_Assert(err != PR_WOULD_BLOCK_ERROR); + if (err == PR_WOULD_BLOCK_ERROR) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + } +- } else if (rv < ss->sec.ci.sendBuf.len) { ++ rv = SECFailure; ++ } else if ((unsigned int)count < ss->sec.ci.sendBuf.len) { + /* short write should never happen */ +- PORT_Assert(rv >= ss->sec.ci.sendBuf.len); ++ PORT_Assert((unsigned int)count >= ss->sec.ci.sendBuf.len); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + } else { +@@ -3705,13 +3734,70 @@ + return SECSuccess; + } + +-/* This method uses PKCS11 to derive the MS from the PMS, where PMS +-** is a PKCS11 symkey. This is used in all cases except the +-** "triple bypass" with RSA key exchange. +-** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec. ++/* This method completes the derivation of the MS from the PMS. ++** ++** 1. Derive the MS, if possible, else return an error. ++** ++** 2. Check the version if |pms_version| is non-zero and if wrong, ++** return an error. ++** ++** 3. If |msp| is nonzero, return MS in |*msp|. ++ ++** Called from: ++** ssl3_ComputeMasterSecretInt ++** tls_ComputeExtendedMasterSecretInt + */ + static SECStatus +-ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) ++ssl3_ComputeMasterSecretFinish(sslSocket *ss, ++ CK_MECHANISM_TYPE master_derive, ++ CK_MECHANISM_TYPE key_derive, ++ CK_VERSION *pms_version, ++ SECItem *params, CK_FLAGS keyFlags, ++ PK11SymKey *pms, PK11SymKey **msp) ++{ ++ PK11SymKey *ms = NULL; ++ ++ ms = PK11_DeriveWithFlags(pms, master_derive, ++ params, key_derive, ++ CKA_DERIVE, 0, keyFlags); ++ if (!ms) { ++ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); ++ return SECFailure; ++ } ++ ++ if (pms_version && ss->opt.detectRollBack) { ++ SSL3ProtocolVersion client_version; ++ client_version = pms_version->major << 8 | pms_version->minor; ++ ++ if (IS_DTLS(ss)) { ++ client_version = dtls_DTLSVersionToTLSVersion(client_version); ++ } ++ ++ if (client_version != ss->clientHelloVersion) { ++ /* Destroy MS. Version roll-back detected. */ ++ PK11_FreeSymKey(ms); ++ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); ++ return SECFailure; ++ } ++ } ++ ++ if (msp) { ++ *msp = ms; ++ } else { ++ PK11_FreeSymKey(ms); ++ } ++ ++ return SECSuccess; ++} ++ ++/* Compute the ordinary (pre draft-ietf-tls-session-hash) master ++ ** secret and return it in |*msp|. ++ ** ++ ** Called from: ssl3_ComputeMasterSecret ++ */ ++static SECStatus ++ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms, ++ PK11SymKey **msp) + { + ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; + const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def; +@@ -3721,28 +3807,27 @@ + (pwSpec->version > SSL_LIBRARY_VERSION_3_0)); + PRBool isTLS12= + (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); +- /* ++ /* + * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH + * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size +- * data into a 48-byte value. ++ * data into a 48-byte value, and does not expect to return the version. + */ + PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) || + (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh)); +- SECStatus rv = SECFailure; + CK_MECHANISM_TYPE master_derive; + CK_MECHANISM_TYPE key_derive; + SECItem params; + CK_FLAGS keyFlags; + CK_VERSION pms_version; +- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; ++ CK_VERSION *pms_version_ptr = NULL; ++ /* master_params may be used as a CK_SSL3_MASTER_KEY_DERIVE_PARAMS */ ++ CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params; ++ unsigned int master_params_len; + +- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); +- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); +- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); + if (isTLS12) { +- if(isDH) master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; +- else master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256; +- key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256; ++ if(isDH) master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH; ++ else master_derive = CKM_TLS12_MASTER_KEY_DERIVE; ++ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE; + keyFlags = CKF_SIGN | CKF_VERIFY; + } else if (isTLS) { + if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; +@@ -3756,87 +3841,142 @@ + keyFlags = 0; + } + +- if (pms || !pwSpec->master_secret) { +- if (isDH) { +- master_params.pVersion = NULL; +- } else { +- master_params.pVersion = &pms_version; +- } +- master_params.RandomInfo.pClientRandom = cr; +- master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; +- master_params.RandomInfo.pServerRandom = sr; +- master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; ++ if (!isDH) { ++ pms_version_ptr = &pms_version; ++ } + +- params.data = (unsigned char *) &master_params; +- params.len = sizeof master_params; ++ master_params.pVersion = pms_version_ptr; ++ master_params.RandomInfo.pClientRandom = cr; ++ master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; ++ master_params.RandomInfo.pServerRandom = sr; ++ master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; ++ if (isTLS12) { ++ master_params.prfHashMechanism = CKM_SHA256; ++ master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS); ++ } else { ++ /* prfHashMechanism is not relevant with this PRF */ ++ master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS); + } + +- if (pms != NULL) { +-#if defined(TRACE) +- if (ssl_trace >= 100) { +- SECStatus extractRV = PK11_ExtractKeyValue(pms); +- if (extractRV == SECSuccess) { +- SECItem * keyData = PK11_GetKeyData(pms); +- if (keyData && keyData->data && keyData->len) { +- ssl_PrintBuf(ss, "Pre-Master Secret", +- keyData->data, keyData->len); +- } +- } +- } +-#endif +- pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive, +- ¶ms, key_derive, CKA_DERIVE, 0, keyFlags); +- if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) { +- SSL3ProtocolVersion client_version; +- client_version = pms_version.major << 8 | pms_version.minor; ++ params.data = (unsigned char *) &master_params; ++ params.len = master_params_len; + +- if (IS_DTLS(ss)) { +- client_version = dtls_DTLSVersionToTLSVersion(client_version); +- } ++ return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive, ++ pms_version_ptr, ¶ms, ++ keyFlags, pms, msp); ++} + +- if (client_version != ss->clientHelloVersion) { +- /* Destroy it. Version roll-back detected. */ +- PK11_FreeSymKey(pwSpec->master_secret); +- pwSpec->master_secret = NULL; +- } +- } +- if (pwSpec->master_secret == NULL) { +- /* Generate a faux master secret in the same slot as the old one. */ +- PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms); +- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot); ++/* Compute the draft-ietf-tls-session-hash master ++** secret and return it in |*msp|. ++** ++** Called from: ssl3_ComputeMasterSecret ++*/ ++static SECStatus ++tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms, ++ PK11SymKey **msp) ++{ ++ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; ++ CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS extended_master_params; ++ SSL3Hashes hashes; ++ /* ++ * Determine whether to use the DH/ECDH or RSA derivation modes. ++ */ ++ /* ++ * TODO(ekr@rtfm.com): Verify that the slot can handle this key expansion ++ * mode. Bug 1198298 */ ++ PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) || ++ (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh)); ++ CK_MECHANISM_TYPE master_derive; ++ CK_MECHANISM_TYPE key_derive; ++ SECItem params; ++ const CK_FLAGS keyFlags = CKF_SIGN | CKF_VERIFY; ++ CK_VERSION pms_version; ++ CK_VERSION *pms_version_ptr = NULL; ++ SECStatus rv; + +- PK11_FreeSlot(slot); +- if (fpms != NULL) { +- pwSpec->master_secret = PK11_DeriveWithFlags(fpms, +- master_derive, ¶ms, key_derive, +- CKA_DERIVE, 0, keyFlags); +- PK11_FreeSymKey(fpms); +- } +- } ++ rv = ssl3_ComputeHandshakeHashes(ss, pwSpec, &hashes, 0); ++ if (rv != SECSuccess) { ++ PORT_Assert(0); /* Should never fail */ ++ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); ++ return SECFailure; + } +- if (pwSpec->master_secret == NULL) { +- /* Generate a faux master secret from the internal slot. */ +- PK11SlotInfo * slot = PK11_GetInternalSlot(); +- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot); + +- PK11_FreeSlot(slot); +- if (fpms != NULL) { +- pwSpec->master_secret = PK11_DeriveWithFlags(fpms, +- master_derive, ¶ms, key_derive, +- CKA_DERIVE, 0, keyFlags); +- if (pwSpec->master_secret == NULL) { +- pwSpec->master_secret = fpms; /* use the fpms as the master. */ +- fpms = NULL; +- } +- } +- if (fpms) { +- PK11_FreeSymKey(fpms); +- } ++ if (isDH) { ++ master_derive = CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH; ++ } else { ++ master_derive = CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE; ++ pms_version_ptr = &pms_version; + } +- if (pwSpec->master_secret == NULL) { +- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); +- return rv; ++ ++ if (pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { ++ /* TLS 1.2 */ ++ extended_master_params.prfHashMechanism = CKM_SHA256; ++ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE; ++ } else { ++ /* TLS < 1.2 */ ++ extended_master_params.prfHashMechanism = CKM_TLS_PRF; ++ key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; ++ } ++ ++ extended_master_params.pVersion = pms_version_ptr; ++ extended_master_params.pSessionHash = hashes.u.raw; ++ extended_master_params.ulSessionHashLen = hashes.len; ++ ++ params.data = (unsigned char *) &extended_master_params; ++ params.len = sizeof extended_master_params; ++ ++ return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive, ++ pms_version_ptr, ¶ms, ++ keyFlags, pms, msp); ++} ++ ++ ++/* Wrapper method to compute the master secret and return it in |*msp|. ++** ++** Called from ssl3_ComputeMasterSecret ++*/ ++static SECStatus ++ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms, ++ PK11SymKey **msp) ++{ ++ PORT_Assert(pms != NULL); ++ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); ++ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); ++ ++ if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) { ++ return tls_ComputeExtendedMasterSecretInt(ss, pms, msp); ++ } else { ++ return ssl3_ComputeMasterSecretInt(ss, pms, msp); ++ } ++} ++ ++/* This method uses PKCS11 to derive the MS from the PMS, where PMS ++** is a PKCS11 symkey. We call ssl3_ComputeMasterSecret to do the ++** computations and then modify the pwSpec->state as a side effect. ++** ++** This is used in all cases except the "triple bypass" with RSA key ++** exchange. ++** ++** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec. ++*/ ++static SECStatus ++ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) ++{ ++ SECStatus rv; ++ PK11SymKey* ms = NULL; ++ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; ++ ++ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); ++ PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); ++ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); ++ ++ if (pms) { ++ rv = ssl3_ComputeMasterSecret(ss, pms, &ms); ++ pwSpec->master_secret = ms; ++ if (rv != SECSuccess) ++ return rv; + } ++ + #ifndef NO_PKCS11_BYPASS + if (ss->opt.bypassPKCS11) { + SECItem * keydata; +@@ -3847,7 +3987,7 @@ + rv = PK11_ExtractKeyValue(pwSpec->master_secret); + if (rv != SECSuccess) { + return rv; +- } ++ } + /* This returns the address of the secItem inside the key struct, + * not a copy or a reference. So, there's no need to free it. + */ +@@ -3862,10 +4002,10 @@ + } + } + #endif ++ + return SECSuccess; + } + +- + /* + * Derive encryption and MAC Keys (and IVs) from master secret + * Sets a useful error code when returning SECFailure. +@@ -3898,7 +4038,9 @@ + PK11SymKey * symKey = NULL; + void * pwArg = ss->pkcs11PinArg; + int keySize; +- CK_SSL3_KEY_MAT_PARAMS key_material_params; ++ CK_TLS12_KEY_MAT_PARAMS key_material_params; /* may be used as a ++ * CK_SSL3_KEY_MAT_PARAMS */ ++ unsigned int key_material_params_len; + CK_SSL3_KEY_MAT_OUT returnedKeys; + CK_MECHANISM_TYPE key_derive; + CK_MECHANISM_TYPE bulk_mechanism; +@@ -3952,17 +4094,21 @@ + PORT_Assert( alg2Mech[calg].calg == calg); + bulk_mechanism = alg2Mech[calg].cmech; + +- params.data = (unsigned char *)&key_material_params; +- params.len = sizeof(key_material_params); +- + if (isTLS12) { +- key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256; ++ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE; ++ key_material_params.prfHashMechanism = CKM_SHA256; ++ key_material_params_len = sizeof(CK_TLS12_KEY_MAT_PARAMS); + } else if (isTLS) { + key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; ++ key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS); + } else { + key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; ++ key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS); + } + ++ params.data = (unsigned char *)&key_material_params; ++ params.len = key_material_params_len; ++ + /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and + * DERIVE by DEFAULT */ + symKey = PK11_Derive(pwSpec->master_secret, key_derive, ¶ms, +@@ -4273,6 +4419,12 @@ + PRUint8 b[4]; + PRUint8 * p = b; + ++ PORT_Assert(lenSize <= 4 && lenSize > 0); ++ if (lenSize < 4 && num >= (1L << (lenSize * 8))) { ++ PORT_SetError(SSL_ERROR_TX_RECORD_TOO_LONG); ++ return SECFailure; ++ } ++ + switch (lenSize) { + case 4: + *p++ = (num >> 24) & 0xff; +@@ -4365,17 +4517,12 @@ + * |sigAndHash| to the current handshake message. */ + SECStatus + ssl3_AppendSignatureAndHashAlgorithm( +- sslSocket *ss, const SSL3SignatureAndHashAlgorithm* sigAndHash) ++ sslSocket *ss, const SSLSignatureAndHashAlg* sigAndHash) + { +- unsigned char serialized[2]; ++ PRUint8 serialized[2]; + +- serialized[0] = ssl3_OIDToTLSHashAlgorithm(sigAndHash->hashAlg); +- if (serialized[0] == 0) { +- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); +- return SECFailure; +- } +- +- serialized[1] = sigAndHash->sigAlg; ++ serialized[0] = (PRUint8)sigAndHash->hashAlg; ++ serialized[1] = (PRUint8)sigAndHash->sigAlg; + + return ssl3_AppendHandshake(ss, serialized, sizeof(serialized)); + } +@@ -4470,6 +4617,7 @@ + PORT_Assert(bytes <= 3); + i->len = 0; + i->data = NULL; ++ i->type = siBuffer; + count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length); + if (count < 0) { /* Can't test for SECSuccess here. */ + return SECFailure; +@@ -4489,15 +4637,13 @@ + /* tlsHashOIDMap contains the mapping between TLS hash identifiers and the + * SECOidTag used internally by NSS. */ + static const struct { +- int tlsHash; ++ SSLHashType tlsHash; + SECOidTag oid; + } tlsHashOIDMap[] = { +- { tls_hash_md5, SEC_OID_MD5 }, +- { tls_hash_sha1, SEC_OID_SHA1 }, +- { tls_hash_sha224, SEC_OID_SHA224 }, +- { tls_hash_sha256, SEC_OID_SHA256 }, +- { tls_hash_sha384, SEC_OID_SHA384 }, +- { tls_hash_sha512, SEC_OID_SHA512 } ++ { ssl_hash_sha1, SEC_OID_SHA1 }, ++ { ssl_hash_sha256, SEC_OID_SHA256 }, ++ { ssl_hash_sha384, SEC_OID_SHA384 }, ++ { ssl_hash_sha512, SEC_OID_SHA512 } + }; + + /* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value. +@@ -4505,7 +4651,7 @@ + * + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ + SECOidTag +-ssl3_TLSHashAlgorithmToOID(int hashFunc) ++ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc) + { + unsigned int i; + +@@ -4517,42 +4663,24 @@ + return SEC_OID_UNKNOWN; + } + +-/* ssl3_OIDToTLSHashAlgorithm converts an OID to a TLS hash algorithm +- * identifier. If the hash is not recognised, zero is returned. +- * +- * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ +-static int +-ssl3_OIDToTLSHashAlgorithm(SECOidTag oid) +-{ +- unsigned int i; +- +- for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) { +- if (oid == tlsHashOIDMap[i].oid) { +- return tlsHashOIDMap[i].tlsHash; +- } +- } +- return 0; +-} +- + /* ssl3_TLSSignatureAlgorithmForKeyType returns the TLS 1.2 signature algorithm + * identifier for a given KeyType. */ + static SECStatus +-ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType, +- TLSSignatureAlgorithm *out) ++ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType, SSLSignType *out) + { + switch (keyType) { + case rsaKey: +- *out = tls_sig_rsa; +- return SECSuccess; ++ *out = ssl_sign_rsa; ++ return SECSuccess; + case dsaKey: +- *out = tls_sig_dsa; +- return SECSuccess; ++ *out = ssl_sign_dsa; ++ return SECSuccess; + case ecKey: +- *out = tls_sig_ecdsa; +- return SECSuccess; ++ *out = ssl_sign_ecdsa; ++ return SECSuccess; + default: +- PORT_SetError(SEC_ERROR_INVALID_KEY); +- return SECFailure; ++ PORT_SetError(SEC_ERROR_INVALID_KEY); ++ return SECFailure; + } + } + +@@ -4560,15 +4688,15 @@ + * algorithm identifier for the given certificate. */ + static SECStatus + ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert, +- TLSSignatureAlgorithm *out) ++ SSLSignType *out) + { + SECKEYPublicKey *key; + KeyType keyType; + + key = CERT_ExtractPublicKey(cert); + if (key == NULL) { +- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); +- return SECFailure; ++ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); ++ return SECFailure; + } + + keyType = key->keyType; +@@ -4578,24 +4706,75 @@ + + /* ssl3_CheckSignatureAndHashAlgorithmConsistency checks that the signature + * algorithm identifier in |sigAndHash| is consistent with the public key in +- * |cert|. If so, SECSuccess is returned. Otherwise, PORT_SetError is called +- * and SECFailure is returned. */ ++ * |cert|. It also checks the hash algorithm against the configured signature ++ * algorithms. If all the tests pass, SECSuccess is returned. Otherwise, ++ * PORT_SetError is called and SECFailure is returned. */ + SECStatus + ssl3_CheckSignatureAndHashAlgorithmConsistency( +- const SSL3SignatureAndHashAlgorithm *sigAndHash, CERTCertificate* cert) ++ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash, ++ CERTCertificate* cert) + { + SECStatus rv; +- TLSSignatureAlgorithm sigAlg; ++ SSLSignType sigAlg; ++ unsigned int i; + + rv = ssl3_TLSSignatureAlgorithmForCertificate(cert, &sigAlg); + if (rv != SECSuccess) { +- return rv; ++ return rv; + } + if (sigAlg != sigAndHash->sigAlg) { +- PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); +- return SECFailure; ++ PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); ++ return SECFailure; + } +- return SECSuccess; ++ ++ for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) { ++ const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i]; ++ if (sigAndHash->sigAlg == alg->sigAlg && ++ sigAndHash->hashAlg == alg->hashAlg) { ++ return SECSuccess; ++ } ++ } ++ PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); ++ return SECFailure; ++} ++ ++PRBool ++ssl3_IsSupportedSignatureAlgorithm(const SSLSignatureAndHashAlg *alg) ++{ ++ static const SSLHashType supportedHashes[] = { ++ ssl_hash_sha1, ++ ssl_hash_sha256, ++ ssl_hash_sha384, ++ ssl_hash_sha512 ++ }; ++ ++ static const SSLSignType supportedSigAlgs[] = { ++ ssl_sign_rsa, ++#ifndef NSS_DISABLE_ECC ++ ssl_sign_ecdsa, ++#endif ++ ssl_sign_dsa ++ }; ++ ++ unsigned int i; ++ PRBool hashOK = PR_FALSE; ++ PRBool signOK = PR_FALSE; ++ ++ for (i = 0; i < PR_ARRAY_SIZE(supportedHashes); ++i) { ++ if (alg->hashAlg == supportedHashes[i]) { ++ hashOK = PR_TRUE; ++ break; ++ } ++ } ++ ++ for (i = 0; i < PR_ARRAY_SIZE(supportedSigAlgs); ++i) { ++ if (alg->sigAlg == supportedSigAlgs[i]) { ++ signOK = PR_TRUE; ++ break; ++ } ++ } ++ ++ return hashOK && signOK; + } + + /* ssl3_ConsumeSignatureAndHashAlgorithm reads a SignatureAndHashAlgorithm +@@ -4605,25 +4784,24 @@ + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ + SECStatus + ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss, +- SSL3Opaque **b, +- PRUint32 *length, +- SSL3SignatureAndHashAlgorithm *out) ++ SSL3Opaque **b, ++ PRUint32 *length, ++ SSLSignatureAndHashAlg *out) + { +- unsigned char bytes[2]; ++ PRUint8 bytes[2]; + SECStatus rv; + + rv = ssl3_ConsumeHandshake(ss, bytes, sizeof(bytes), b, length); + if (rv != SECSuccess) { +- return rv; ++ return rv; + } + +- out->hashAlg = ssl3_TLSHashAlgorithmToOID(bytes[0]); +- if (out->hashAlg == SEC_OID_UNKNOWN) { +- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); +- return SECFailure; ++ out->hashAlg = (SSLHashType)bytes[0]; ++ out->sigAlg = (SSLSignType)bytes[1]; ++ if (!ssl3_IsSupportedSignatureAlgorithm(out)) { ++ PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); ++ return SECFailure; + } +- +- out->sigAlg = bytes[1]; + return SECSuccess; + } + +@@ -4653,7 +4831,12 @@ + SSL3Opaque sha_inner[MAX_MAC_LENGTH]; + + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); +- hashes->hashAlg = SEC_OID_UNKNOWN; ++ if (ss->ssl3.hs.hashType == handshake_hash_unknown) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } ++ ++ hashes->hashAlg = ssl_hash_none; + + #ifndef NO_PKCS11_BYPASS + if (ss->opt.bypassPKCS11 && +@@ -4661,11 +4844,6 @@ + /* compute them without PKCS11 */ + PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS]; + +- if (!spec->msItem.data) { +- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); +- return SECFailure; +- } +- + ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx); + ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len, + sizeof(hashes->u.raw)); +@@ -4674,7 +4852,7 @@ + + /* If we ever support ciphersuites where the PRF hash isn't SHA-256 + * then this will need to be updated. */ +- hashes->hashAlg = SEC_OID_SHA256; ++ hashes->hashAlg = ssl_hash_sha256; + rv = SECSuccess; + } else if (ss->opt.bypassPKCS11) { + /* compute them without PKCS11 */ +@@ -4684,11 +4862,6 @@ + #define md5cx ((MD5Context *)md5_cx) + #define shacx ((SHA1Context *)sha_cx) + +- if (!spec->msItem.data) { +- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); +- return SECFailure; +- } +- + MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx); + SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx); + +@@ -4696,6 +4869,11 @@ + /* compute hashes for SSL3. */ + unsigned char s[4]; + ++ if (!spec->msItem.data) { ++ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); ++ return SECFailure; ++ } ++ + s[0] = (unsigned char)(sender >> 24); + s[1] = (unsigned char)(sender >> 16); + s[2] = (unsigned char)(sender >> 8); +@@ -4768,11 +4946,6 @@ + unsigned char stackBuf[1024]; + unsigned char *stateBuf = NULL; + +- if (!spec->master_secret) { +- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); +- return SECFailure; +- } +- + h = ss->ssl3.hs.sha; + stateBuf = PK11_SaveContextAlloc(h, stackBuf, + sizeof(stackBuf), &stateLen); +@@ -4789,7 +4962,7 @@ + } + /* If we ever support ciphersuites where the PRF hash isn't SHA-256 + * then this will need to be updated. */ +- hashes->hashAlg = SEC_OID_SHA256; ++ hashes->hashAlg = ssl_hash_sha256; + rv = SECSuccess; + + tls12_loser: +@@ -4812,11 +4985,6 @@ + unsigned char md5StackBuf[256]; + unsigned char shaStackBuf[512]; + +- if (!spec->master_secret) { +- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); +- return SECFailure; +- } +- + md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf, + sizeof md5StackBuf, &md5StateLen); + if (md5StateBuf == NULL) { +@@ -4837,6 +5005,11 @@ + /* compute hashes for SSL3. */ + unsigned char s[4]; + ++ if (!spec->master_secret) { ++ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); ++ return SECFailure; ++ } ++ + s[0] = (unsigned char)(sender >> 24); + s[1] = (unsigned char)(sender >> 16); + s[2] = (unsigned char)(sender >> 8); +@@ -4968,7 +5141,7 @@ + rv = SECFailure; + goto loser; + } +- hashes->hashAlg = SEC_OID_SHA1; ++ hashes->hashAlg = ssl_hash_sha1; + + loser: + PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE); +@@ -5049,7 +5222,9 @@ + if (rv != SECSuccess) { + return rv; /* ssl3_InitState has set the error code. */ + } +- ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */ ++ /* These must be reset every handshake. */ ++ ss->ssl3.hs.sendingSCSV = PR_FALSE; ++ ss->ssl3.hs.preliminaryInfo = 0; + PORT_Assert(IS_DTLS(ss) || !resending); + + SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE); +@@ -5425,7 +5600,7 @@ + } + for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { + ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; +- if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) { ++ if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange, ss)) { + actual_count++; + if (actual_count > num_suites) { + if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); } +@@ -6083,14 +6258,6 @@ + } + } + +- rv = ssl3_InitPendingCipherSpec(ss, pms); +- PK11_FreeSymKey(pms); pms = NULL; +- +- if (rv != SECSuccess) { +- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); +- goto loser; +- } +- + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, + isTLS ? enc_pms.len + 2 : enc_pms.len); + if (rv != SECSuccess) { +@@ -6105,6 +6272,15 @@ + goto loser; /* err set by ssl3_AppendHandshake* */ + } + ++ rv = ssl3_InitPendingCipherSpec(ss, pms); ++ PK11_FreeSymKey(pms); ++ pms = NULL; ++ ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); ++ goto loser; ++ } ++ + rv = SECSuccess; + + loser: +@@ -6174,14 +6350,6 @@ + SECKEY_DestroyPrivateKey(privKey); + privKey = NULL; + +- rv = ssl3_InitPendingCipherSpec(ss, pms); +- PK11_FreeSymKey(pms); pms = NULL; +- +- if (rv != SECSuccess) { +- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); +- goto loser; +- } +- + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, + pubKey->u.dh.publicValue.len + 2); + if (rv != SECSuccess) { +@@ -6197,8 +6365,16 @@ + goto loser; /* err set by ssl3_AppendHandshake* */ + } + +- rv = SECSuccess; ++ rv = ssl3_InitPendingCipherSpec(ss, pms); ++ PK11_FreeSymKey(pms); ++ pms = NULL; + ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); ++ goto loser; ++ } ++ ++ rv = SECSuccess; + + loser: + +@@ -6240,9 +6416,9 @@ + isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); + /* enforce limits on kea key sizes. */ + if (ss->ssl3.hs.kea_def->is_limited) { +- int keyLen = SECKEY_PublicKeyStrength(serverKey); /* bytes */ ++ unsigned int keyLen = SECKEY_PublicKeyStrengthInBits(serverKey); + +- if (keyLen * BPB > ss->ssl3.hs.kea_def->key_size_limit) { ++ if (keyLen > ss->ssl3.hs.kea_def->key_size_limit) { + if (isTLS) + (void)SSL3_SendAlert(ss, alert_fatal, export_restriction); + else +@@ -6297,7 +6473,7 @@ + SSL3Hashes hashes; + KeyType keyType; + unsigned int len; +- SSL3SignatureAndHashAlgorithm sigAndHash; ++ SSLSignatureAndHashAlg sigAndHash; + + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); +@@ -6362,11 +6538,11 @@ + } + if (isTLS12) { + rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, +- &sigAndHash.sigAlg); ++ &sigAndHash.sigAlg); + if (rv != SECSuccess) { + goto done; + } +- sigAndHash.hashAlg = hashes.hashAlg; ++ sigAndHash.hashAlg = hashes.hashAlg; + + rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); + if (rv != SECSuccess) { +@@ -6474,6 +6650,7 @@ + errCode = SSL_ERROR_UNSUPPORTED_VERSION; + goto alert_loser; + } ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; + isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); + + rv = ssl3_InitHandshakeHashes(ss); +@@ -6509,7 +6686,7 @@ + ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; + if (temp == suite->cipher_suite) { + SSLVersionRange vrange = {ss->version, ss->version}; +- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) { ++ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) { + /* config_match already checks whether the cipher suite is + * acceptable for the version, but the check is repeated here + * in order to give a more precise error code. */ +@@ -6533,6 +6710,7 @@ + } + ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp; + ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp); ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + PORT_Assert(ss->ssl3.hs.suite_def); + if (!ss->ssl3.hs.suite_def) { + PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE); +@@ -6619,6 +6797,32 @@ + + SECItem wrappedMS; /* wrapped master secret. */ + ++ /* [draft-ietf-tls-session-hash-06; Section 5.3] ++ * ++ * o If the original session did not use the "extended_master_secret" ++ * extension but the new ServerHello contains the extension, the ++ * client MUST abort the handshake. ++ */ ++ if (!sid->u.ssl3.keys.extendedMasterSecretUsed && ++ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) { ++ errCode = SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET; ++ goto alert_loser; ++ } ++ ++ /* ++ * o If the original session used an extended master secret but the new ++ * ServerHello does not contain the "extended_master_secret" ++ * extension, the client SHOULD abort the handshake. ++ * ++ * TODO(ekr@rtfm.com): Add option to refuse to resume when EMS is not ++ * used at all (bug 1176526). ++ */ ++ if (sid->u.ssl3.keys.extendedMasterSecretUsed && ++ !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) { ++ errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET; ++ goto alert_loser; ++ } ++ + ss->sec.authAlgorithm = sid->authAlgorithm; + ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.keaType = sid->keaType; +@@ -6721,7 +6925,7 @@ + ssl3_CopyPeerCertsFromSID(ss, sid); + } + +- /* NULL value for PMS signifies re-use of the old MS */ ++ /* NULL value for PMS because we are reusing the old MS */ + rv = ssl3_InitPendingCipherSpec(ss, NULL); + if (rv != SECSuccess) { + goto alert_loser; /* err code was set */ +@@ -6750,6 +6954,9 @@ + sid->u.ssl3.sessionIDLength = sidBytes.len; + PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len); + ++ sid->u.ssl3.keys.extendedMasterSecretUsed = ++ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn); ++ + /* Copy Signed Certificate Timestamps, if any. */ + if (ss->xtnData.signedCertTimestamps.data) { + rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps, +@@ -6761,13 +6968,14 @@ + ss->ssl3.hs.isResuming = PR_FALSE; + if (ss->ssl3.hs.kea_def->signKeyType != sign_null) { + /* All current cipher suites other than those with sign_null (i.e., +- * DH_anon_* suites) require a certificate, so use that signal. */ ++ * (EC)DH_anon_* suites) require a certificate, so use that signal. */ + ss->ssl3.hs.ws = wait_server_cert; +- } else if (ss->ssl3.hs.kea_def->ephemeral) { +- /* Only ephemeral cipher suites use ServerKeyExchange. */ +- ss->ssl3.hs.ws = wait_server_key; + } else { +- ss->ssl3.hs.ws = wait_cert_request; ++ /* All the remaining cipher suites must be (EC)DH_anon_* and so ++ * must be ephemeral. Note, if we ever add PSK this might ++ * change. */ ++ PORT_Assert(ss->ssl3.hs.kea_def->ephemeral); ++ ss->ssl3.hs.ws = wait_server_key; + } + + winner: +@@ -6807,29 +7015,6 @@ + return SECFailure; + } + +-/* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned, +- * big-endian integer is > 1 */ +-static PRBool +-ssl3_BigIntGreaterThanOne(const SECItem* mpint) { +- unsigned char firstNonZeroByte = 0; +- unsigned int i; +- +- for (i = 0; i < mpint->len; i++) { +- if (mpint->data[i]) { +- firstNonZeroByte = mpint->data[i]; +- break; +- } +- } +- +- if (firstNonZeroByte == 0) +- return PR_FALSE; +- if (firstNonZeroByte > 1) +- return PR_TRUE; +- +- /* firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte +- * is followed by another byte. */ +- return (i < mpint->len - 1); +-} + + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete + * ssl3 ServerKeyExchange message. +@@ -6846,9 +7031,9 @@ + SSL3AlertDescription desc = illegal_parameter; + SSL3Hashes hashes; + SECItem signature = {siBuffer, NULL, 0}; +- SSL3SignatureAndHashAlgorithm sigAndHash; ++ SSLSignatureAndHashAlg sigAndHash; + +- sigAndHash.hashAlg = SEC_OID_UNKNOWN; ++ sigAndHash.hashAlg = ssl_hash_none; + + SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake", + SSL_GETPID(), ss->fd)); +@@ -6874,6 +7059,12 @@ + if (rv != SECSuccess) { + goto loser; /* malformed. */ + } ++ /* This exchange method is only used by export cipher suites. ++ * Those are broken and so this code will eventually be removed. */ ++ if (SECKEY_BigIntegerBitLength(&modulus) < 512) { ++ desc = isTLS ? insufficient_security : illegal_parameter; ++ goto alert_loser; ++ } + rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length); + if (rv != SECSuccess) { + goto loser; /* malformed. */ +@@ -6884,7 +7075,7 @@ + if (rv != SECSuccess) { + goto loser; /* malformed or unsupported. */ + } +- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( ++ rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(ss, + &sigAndHash, ss->sec.peerCert); + if (rv != SECSuccess) { + goto loser; +@@ -6907,10 +7098,10 @@ + /* + * check to make sure the hash is signed by right guy + */ +- rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent, +- &ss->ssl3.hs.client_random, +- &ss->ssl3.hs.server_random, +- &hashes, ss->opt.bypassPKCS11); ++ rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent, ++ &ss->ssl3.hs.client_random, ++ &ss->ssl3.hs.server_random, ++ &hashes, ss->opt.bypassPKCS11); + if (rv != SECSuccess) { + errCode = + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); +@@ -6936,7 +7127,6 @@ + + peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); + if (peerKey == NULL) { +- PORT_FreeArena(arena, PR_FALSE); + goto no_memory; + } + +@@ -6947,7 +7137,6 @@ + if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus, &modulus) || + SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent)) + { +- PORT_FreeArena(arena, PR_FALSE); + goto no_memory; + } + ss->sec.peerKey = peerKey; +@@ -6959,13 +7148,22 @@ + SECItem dh_p = {siBuffer, NULL, 0}; + SECItem dh_g = {siBuffer, NULL, 0}; + SECItem dh_Ys = {siBuffer, NULL, 0}; ++ unsigned dh_p_bits; ++ unsigned dh_g_bits; ++ unsigned dh_Ys_bits; ++ PRInt32 minDH; + + rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length); + if (rv != SECSuccess) { + goto loser; /* malformed. */ + } +- if (dh_p.len < 1024/8 || +- (dh_p.len == 1024/8 && (dh_p.data[0] & 0x80) == 0)) { ++ ++ rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH); ++ if (rv != SECSuccess) { ++ minDH = SSL_DH_MIN_P_BITS; ++ } ++ dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p); ++ if (dh_p_bits < minDH) { + errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY; + goto alert_loser; + } +@@ -6973,13 +7171,16 @@ + if (rv != SECSuccess) { + goto loser; /* malformed. */ + } +- if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g)) ++ /* Abort if dh_g is 0, 1, or obviously too big. */ ++ dh_g_bits = SECKEY_BigIntegerBitLength(&dh_g); ++ if (dh_g_bits > dh_p_bits || dh_g_bits <= 1) + goto alert_loser; + rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length); + if (rv != SECSuccess) { + goto loser; /* malformed. */ + } +- if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys)) ++ dh_Ys_bits = SECKEY_BigIntegerBitLength(&dh_Ys); ++ if (dh_Ys_bits > dh_p_bits || dh_Ys_bits <= 1) + goto alert_loser; + if (isTLS12) { + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, +@@ -6987,7 +7188,7 @@ + if (rv != SECSuccess) { + goto loser; /* malformed or unsupported. */ + } +- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( ++ rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(ss, + &sigAndHash, ss->sec.peerCert); + if (rv != SECSuccess) { + goto loser; +@@ -7014,10 +7215,10 @@ + /* + * check to make sure the hash is signed by right guy + */ +- rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys, +- &ss->ssl3.hs.client_random, +- &ss->ssl3.hs.server_random, +- &hashes, ss->opt.bypassPKCS11); ++ rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys, ++ &ss->ssl3.hs.client_random, ++ &ss->ssl3.hs.server_random, ++ &hashes, ss->opt.bypassPKCS11); + if (rv != SECSuccess) { + errCode = + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); +@@ -7041,7 +7242,7 @@ + goto no_memory; + } + +- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); ++ peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); + if (peerKey == NULL) { + goto no_memory; + } +@@ -7055,7 +7256,6 @@ + SECITEM_CopyItem(arena, &peerKey->u.dh.base, &dh_g) || + SECITEM_CopyItem(arena, &peerKey->u.dh.publicValue, &dh_Ys)) + { +- PORT_FreeArena(arena, PR_FALSE); + goto no_memory; + } + ss->sec.peerKey = peerKey; +@@ -7078,10 +7278,16 @@ + alert_loser: + (void)SSL3_SendAlert(ss, alert_fatal, desc); + loser: ++ if (arena) { ++ PORT_FreeArena(arena, PR_FALSE); ++ } + PORT_SetError( errCode ); + return SECFailure; + + no_memory: /* no-memory error has already been set. */ ++ if (arena) { ++ PORT_FreeArena(arena, PR_FALSE); ++ } + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); + return SECFailure; + } +@@ -7092,7 +7298,7 @@ + */ + static SECStatus + ssl3_ExtractClientKeyInfo(sslSocket *ss, +- TLSSignatureAlgorithm *sigAlg, ++ SSLSignType *sigAlg, + PRBool *preferSha1) + { + SECStatus rv = SECSuccess; +@@ -7148,7 +7354,7 @@ + const SECItem *algorithms) + { + SECStatus rv; +- TLSSignatureAlgorithm sigAlg; ++ SSLSignType sigAlg; + PRBool preferSha1; + PRBool supportsSha1 = PR_FALSE; + PRBool supportsSha256 = PR_FALSE; +@@ -7173,9 +7379,9 @@ + /* Determine the server's hash support for that signature algorithm. */ + for (i = 0; i < algorithms->len; i += 2) { + if (algorithms->data[i+1] == sigAlg) { +- if (algorithms->data[i] == tls_hash_sha1) { ++ if (algorithms->data[i] == ssl_hash_sha1) { + supportsSha1 = PR_TRUE; +- } else if (algorithms->data[i] == tls_hash_sha256) { ++ } else if (algorithms->data[i] == ssl_hash_sha256) { + supportsSha256 = PR_TRUE; + } + } +@@ -7334,6 +7540,8 @@ + } else + #endif + if (ss->getClientAuthData != NULL) { ++ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == ++ ssl_preinfo_all); + /* XXX Should pass cert_types and algorithms in this call!! */ + rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg, + ss->fd, &ca_list, +@@ -7565,6 +7773,8 @@ + SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher", + SSL_GETPID(), ss->fd)); + } else { ++ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == ++ ssl_preinfo_all); + rv = (ss->canFalseStartCallback)(ss->fd, + ss->canFalseStartCallbackData, + &ss->ssl3.hs.canFalseStart); +@@ -7923,6 +8133,7 @@ + sid->u.ssl3.policy = SSL_ALLOWED; + sid->u.ssl3.clientWriteKey = NULL; + sid->u.ssl3.serverWriteKey = NULL; ++ sid->u.ssl3.keys.extendedMasterSecretUsed = PR_FALSE; + + if (is_server) { + SECStatus rv; +@@ -7975,7 +8186,7 @@ + + if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) { + /* see if we can legally use the key in the cert. */ +- int keyLen; /* bytes */ ++ unsigned int keyLen; /* bytes */ + + keyLen = PK11_GetPrivateModulusLen( + ss->serverCerts[kea_def->exchKeyType].SERVERKEY); +@@ -8022,6 +8233,22 @@ + /* An empty TLS Renegotiation Info (RI) extension */ + static const PRUint8 emptyRIext[5] = {0xff, 0x01, 0x00, 0x01, 0x00}; + ++static PRBool ++ssl3_KEAAllowsSessionTicket(SSL3KeyExchangeAlgorithm kea) ++{ ++ switch (kea) { ++ case kea_dhe_dss: ++ case kea_dhe_dss_export: ++ case kea_dh_dss_export: ++ case kea_dh_dss: ++ /* TODO: Fix session tickets for DSS. The server code rejects the ++ * session ticket received from the client. Bug 1174677 */ ++ return PR_FALSE; ++ default: ++ return PR_TRUE; ++ }; ++} ++ + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete + * ssl3 Client Hello message. + * Caller must hold Handshake and RecvBuf locks. +@@ -8044,6 +8271,7 @@ + SECItem comps = {siBuffer, NULL, 0}; + PRBool haveSpecWriteLock = PR_FALSE; + PRBool haveXmitBufLock = PR_FALSE; ++ PRBool canOfferSessionTicket = PR_FALSE; + + SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake", + SSL_GETPID(), ss->fd)); +@@ -8051,6 +8279,7 @@ + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + PORT_Assert( ss->ssl3.initialized ); ++ ss->ssl3.hs.preliminaryInfo = 0; + + if (!ss->sec.isServer || + (ss->ssl3.hs.ws != wait_client_hello && +@@ -8116,6 +8345,7 @@ + errCode = SSL_ERROR_UNSUPPORTED_VERSION; + goto alert_loser; + } ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; + + rv = ssl3_InitHandshakeHashes(ss); + if (rv != SECSuccess) { +@@ -8283,8 +8513,7 @@ + * resuming.) + */ + if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && sid == NULL) { +- ssl3_RegisterServerHelloExtensionSender(ss, +- ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn); ++ canOfferSessionTicket = PR_TRUE; + } + + if (sid != NULL) { +@@ -8367,7 +8596,7 @@ + * The product policy won't change during the process lifetime. + * Implemented ("isPresent") shouldn't change for servers. + */ +- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) ++ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) + break; + #else + if (!suite->enabled) +@@ -8380,6 +8609,7 @@ + ss->ssl3.hs.cipher_suite = suite->cipher_suite; + ss->ssl3.hs.suite_def = + ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + + /* Use the cached compression method. */ + ss->ssl3.hs.compression = sid->u.ssl3.compression; +@@ -8416,7 +8646,7 @@ + for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) { + ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j]; + SSLVersionRange vrange = {ss->version, ss->version}; +- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) { ++ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) { + continue; + } + for (i = 0; i + 1 < suites.len; i += 2) { +@@ -8425,6 +8655,7 @@ + ss->ssl3.hs.cipher_suite = suite->cipher_suite; + ss->ssl3.hs.suite_def = + ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + goto suite_found; + } + } +@@ -8433,6 +8664,15 @@ + goto alert_loser; + + suite_found: ++ if (canOfferSessionTicket) ++ canOfferSessionTicket = ssl3_KEAAllowsSessionTicket( ++ ss->ssl3.hs.suite_def->key_exchange_alg); ++ ++ if (canOfferSessionTicket) { ++ ssl3_RegisterServerHelloExtensionSender(ss, ++ ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn); ++ } ++ + /* Select a compression algorithm. */ + for (i = 0; i < comps.len; i++) { + if (!compressionEnabled(ss, comps.data[i])) +@@ -8458,6 +8698,8 @@ + /* If there are any failures while processing the old sid, + * we don't consider them to be errors. Instead, We just behave + * as if the client had sent us no sid to begin with, and make a new one. ++ * The exception here is attempts to resume extended_master_secret ++ * sessions without the extension, which causes an alert. + */ + if (sid != NULL) do { + ssl3CipherSpec *pwSpec; +@@ -8469,6 +8711,30 @@ + break; /* not an error */ + } + ++ /* [draft-ietf-tls-session-hash-06; Section 5.3] ++ * o If the original session did not use the "extended_master_secret" ++ * extension but the new ClientHello contains the extension, then the ++ * server MUST NOT perform the abbreviated handshake. Instead, it ++ * SHOULD continue with a full handshake (as described in ++ * Section 5.2) to negotiate a new session. ++ * ++ * o If the original session used the "extended_master_secret" ++ * extension but the new ClientHello does not contain the extension, ++ * the server MUST abort the abbreviated handshake. ++ */ ++ if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) { ++ if (!sid->u.ssl3.keys.extendedMasterSecretUsed) { ++ break; /* not an error */ ++ } ++ } else { ++ if (sid->u.ssl3.keys.extendedMasterSecretUsed) { ++ /* Note: we do not destroy the session */ ++ desc = handshake_failure; ++ errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET; ++ goto alert_loser; ++ } ++ } ++ + if (ss->sec.ci.sid) { + if (ss->sec.uncache) + ss->sec.uncache(ss->sec.ci.sid); +@@ -8610,7 +8876,7 @@ + haveSpecWriteLock = PR_FALSE; + } + +- /* NULL value for PMS signifies re-use of the old MS */ ++ /* NULL value for PMS because we are re-using the old MS */ + rv = ssl3_InitPendingCipherSpec(ss, NULL); + if (rv != SECSuccess) { + errCode = PORT_GetError(); +@@ -8654,6 +8920,9 @@ + if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) { + int ret = 0; + if (ss->sniSocketConfig) do { /* not a loop */ ++ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == ++ ssl_preinfo_all); ++ + ret = SSL_SNI_SEND_ALERT; + /* If extension is negotiated, the len of names should > 0. */ + if (ss->xtnData.sniNameArrSize) { +@@ -8701,7 +8970,7 @@ + ret = SSL_SNI_SEND_ALERT; + break; + } +- } else if (ret < ss->xtnData.sniNameArrSize) { ++ } else if ((unsigned int)ret < ss->xtnData.sniNameArrSize) { + /* Application has configured new socket info. Lets check it + * and save the name. */ + SECStatus rv; +@@ -8752,7 +9021,7 @@ + ssl3_SendServerNameXtn); + } else { + /* Callback returned index outside of the boundary. */ +- PORT_Assert(ret < ss->xtnData.sniNameArrSize); ++ PORT_Assert((unsigned int)ret < ss->xtnData.sniNameArrSize); + errCode = SSL_ERROR_INTERNAL_ERROR_ALERT; + desc = internal_error; + ret = SSL_SNI_SEND_ALERT; +@@ -8798,13 +9067,16 @@ + } + ss->sec.ci.sid = sid; + ++ sid->u.ssl3.keys.extendedMasterSecretUsed = ++ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn); + ss->ssl3.hs.isResuming = PR_FALSE; + ssl_GetXmitBufLock(ss); + rv = ssl3_SendServerHelloSequence(ss); + ssl_ReleaseXmitBufLock(ss); + if (rv != SECSuccess) { +- errCode = PORT_GetError(); +- goto loser; ++ errCode = PORT_GetError(); ++ desc = handshake_failure; ++ goto alert_loser; + } + + if (haveXmitBufLock) { +@@ -8896,6 +9168,7 @@ + errCode = SSL_ERROR_UNSUPPORTED_VERSION; + goto alert_loser; + } ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; + + rv = ssl3_InitHandshakeHashes(ss); + if (rv != SECSuccess) { +@@ -8951,7 +9224,7 @@ + for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) { + ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j]; + SSLVersionRange vrange = {ss->version, ss->version}; +- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) { ++ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) { + continue; + } + for (i = 0; i+2 < suite_length; i += 3) { +@@ -8960,6 +9233,7 @@ + ss->ssl3.hs.cipher_suite = suite->cipher_suite; + ss->ssl3.hs.suite_def = + ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); ++ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + goto suite_found; + } + } +@@ -9150,6 +9424,154 @@ + return SECSuccess; + } + ++static SECStatus ++ssl3_PickSignatureHashAlgorithm(sslSocket *ss, ++ SSLSignatureAndHashAlg* out); ++ ++static SECStatus ++ssl3_SendDHServerKeyExchange(sslSocket *ss) ++{ ++ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; ++ SECStatus rv = SECFailure; ++ int length; ++ PRBool isTLS; ++ SECItem signed_hash = {siBuffer, NULL, 0}; ++ SSL3Hashes hashes; ++ SSLSignatureAndHashAlg sigAndHash; ++ SECKEYDHParams dhParam; ++ ++ ssl3KeyPair *keyPair = NULL; ++ SECKEYPublicKey *pubKey = NULL; /* Ephemeral DH key */ ++ SECKEYPrivateKey *privKey = NULL; /* Ephemeral DH key */ ++ int certIndex = -1; ++ ++ if (kea_def->kea != kea_dhe_dss && kea_def->kea != kea_dhe_rsa) { ++ /* TODO: Support DH_anon. It might be sufficient to drop the signature. ++ See bug 1170510. */ ++ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); ++ return SECFailure; ++ } ++ ++ dhParam.prime.data = ss->dheParams->prime.data; ++ dhParam.prime.len = ss->dheParams->prime.len; ++ dhParam.base.data = ss->dheParams->base.data; ++ dhParam.base.len = ss->dheParams->base.len; ++ ++ PRINT_BUF(60, (NULL, "Server DH p", dhParam.prime.data, ++ dhParam.prime.len)); ++ PRINT_BUF(60, (NULL, "Server DH g", dhParam.base.data, ++ dhParam.base.len)); ++ ++ /* Generate ephemeral DH keypair */ ++ privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL); ++ if (!privKey || !pubKey) { ++ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); ++ rv = SECFailure; ++ goto loser; ++ } ++ ++ keyPair = ssl3_NewKeyPair(privKey, pubKey); ++ if (!keyPair) { ++ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); ++ goto loser; ++ } ++ ++ PRINT_BUF(50, (ss, "DH public value:", ++ pubKey->u.dh.publicValue.data, ++ pubKey->u.dh.publicValue.len)); ++ ++ if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) { ++ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); ++ goto loser; ++ } ++ ++ rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, ++ pubKey->u.dh.prime, ++ pubKey->u.dh.base, ++ pubKey->u.dh.publicValue, ++ &ss->ssl3.hs.client_random, ++ &ss->ssl3.hs.server_random, ++ &hashes, ss->opt.bypassPKCS11); ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); ++ goto loser; ++ } ++ ++ /* It has been suggested to test kea_def->signKeyType instead, and to use ++ * ssl_auth_* instead. Investigate what to do. See bug 102794. */ ++ if (kea_def->kea == kea_dhe_rsa) ++ certIndex = ssl_kea_rsa; ++ else ++ certIndex = ssl_kea_dh; ++ ++ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); ++ rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, ++ &signed_hash, isTLS); ++ if (rv != SECSuccess) { ++ goto loser; /* ssl3_SignHashes has set err. */ ++ } ++ if (signed_hash.data == NULL) { ++ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); ++ goto loser; ++ } ++ length = 2 + pubKey->u.dh.prime.len + ++ 2 + pubKey->u.dh.base.len + ++ 2 + pubKey->u.dh.publicValue.len + ++ 2 + signed_hash.len; ++ ++ if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { ++ length += 2; ++ } ++ ++ rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); ++ if (rv != SECSuccess) { ++ goto loser; /* err set by AppendHandshake. */ ++ } ++ ++ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.prime.data, ++ pubKey->u.dh.prime.len, 2); ++ if (rv != SECSuccess) { ++ goto loser; /* err set by AppendHandshake. */ ++ } ++ ++ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.base.data, ++ pubKey->u.dh.base.len, 2); ++ if (rv != SECSuccess) { ++ goto loser; /* err set by AppendHandshake. */ ++ } ++ ++ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.publicValue.data, ++ pubKey->u.dh.publicValue.len, 2); ++ if (rv != SECSuccess) { ++ goto loser; /* err set by AppendHandshake. */ ++ } ++ ++ if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { ++ rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); ++ if (rv != SECSuccess) { ++ goto loser; /* err set by AppendHandshake. */ ++ } ++ } ++ ++ rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, ++ signed_hash.len, 2); ++ if (rv != SECSuccess) { ++ goto loser; /* err set by AppendHandshake. */ ++ } ++ PORT_Free(signed_hash.data); ++ ss->dheKeyPair = keyPair; ++ return SECSuccess; ++ ++loser: ++ if (signed_hash.data) ++ PORT_Free(signed_hash.data); ++ if (privKey) ++ SECKEY_DestroyPrivateKey(privKey); ++ if (pubKey) ++ SECKEY_DestroyPublicKey(pubKey); ++ return SECFailure; ++} ++ + /* ssl3_PickSignatureHashAlgorithm selects a hash algorithm to use when signing + * elements of the handshake. (The negotiated cipher suite determines the + * signature algorithm.) Prior to TLS 1.2, the MD5/SHA1 combination is always +@@ -9157,18 +9579,11 @@ + * hash combinations. */ + static SECStatus + ssl3_PickSignatureHashAlgorithm(sslSocket *ss, +- SSL3SignatureAndHashAlgorithm* out) ++ SSLSignatureAndHashAlg* out) + { +- TLSSignatureAlgorithm sigAlg; ++ SSLSignType sigAlg; ++ PRUint32 policy; + unsigned int i, j; +- /* hashPreference expresses our preferences for hash algorithms, most +- * preferable first. */ +- static const SECOidTag hashPreference[] = { +- SEC_OID_SHA256, +- SEC_OID_SHA384, +- SEC_OID_SHA512, +- SEC_OID_SHA1, +- }; + + switch (ss->ssl3.hs.kea_def->kea) { + case kea_rsa: +@@ -9181,48 +9596,63 @@ + case kea_rsa_fips: + case kea_ecdh_rsa: + case kea_ecdhe_rsa: +- sigAlg = tls_sig_rsa; +- break; ++ sigAlg = ssl_sign_rsa; ++ break; + case kea_dh_dss: + case kea_dh_dss_export: + case kea_dhe_dss: + case kea_dhe_dss_export: +- sigAlg = tls_sig_dsa; +- break; ++ sigAlg = ssl_sign_dsa; ++ break; + case kea_ecdh_ecdsa: + case kea_ecdhe_ecdsa: +- sigAlg = tls_sig_ecdsa; +- break; ++ sigAlg = ssl_sign_ecdsa; ++ break; + default: +- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); +- return SECFailure; ++ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); ++ return SECFailure; + } + out->sigAlg = sigAlg; + + if (ss->version <= SSL_LIBRARY_VERSION_TLS_1_1) { +- /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and +- * prior. */ +- out->hashAlg = SEC_OID_UNKNOWN; +- return SECSuccess; ++ /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and ++ * prior. */ ++ out->hashAlg = ssl_hash_none; ++ return SECSuccess; + } + + if (ss->ssl3.hs.numClientSigAndHash == 0) { +- /* If the client didn't provide any signature_algorithms extension then +- * we can assume that they support SHA-1: +- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ +- out->hashAlg = SEC_OID_SHA1; +- return SECSuccess; ++ /* If the client didn't provide any signature_algorithms extension then ++ * we can assume that they support SHA-1: ++ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ ++ out->hashAlg = ssl_hash_sha1; ++ return SECSuccess; + } + +- for (i = 0; i < PR_ARRAY_SIZE(hashPreference); i++) { +- for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) { +- const SSL3SignatureAndHashAlgorithm* sh = +- &ss->ssl3.hs.clientSigAndHash[j]; +- if (sh->sigAlg == sigAlg && sh->hashAlg == hashPreference[i]) { +- out->hashAlg = sh->hashAlg; +- return SECSuccess; +- } ++ /* Here we look for the first server preference that the client has ++ * indicated support for in their signature_algorithms extension. */ ++ for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) { ++ const SSLSignatureAndHashAlg *serverPref = ++ &ss->ssl3.signatureAlgorithms[i]; ++ SECOidTag hashOID; ++ if (serverPref->sigAlg != sigAlg) { ++ continue; ++ } ++ hashOID = ssl3_TLSHashAlgorithmToOID(serverPref->hashAlg); ++ if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess) ++ || !(policy & NSS_USE_ALG_IN_SSL_KX)) { ++ /* we ignore hashes we don't support */ ++ continue; + } ++ for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) { ++ const SSLSignatureAndHashAlg *clientPref = ++ &ss->ssl3.hs.clientSigAndHash[j]; ++ if (clientPref->hashAlg == serverPref->hashAlg && ++ clientPref->sigAlg == sigAlg) { ++ out->hashAlg = serverPref->hashAlg; ++ return SECSuccess; ++ } ++ } + } + + PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); +@@ -9240,7 +9670,7 @@ + SECItem signed_hash = {siBuffer, NULL, 0}; + SSL3Hashes hashes; + SECKEYPublicKey * sdPub; /* public key for step-down */ +- SSL3SignatureAndHashAlgorithm sigAndHash; ++ SSLSignatureAndHashAlg sigAndHash; + + SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake", + SSL_GETPID(), ss->fd)); +@@ -9287,6 +9717,10 @@ + 2 + sdPub->u.rsa.publicExponent.len + + 2 + signed_hash.len; + ++ if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { ++ length += 2; ++ } ++ + rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); + if (rv != SECSuccess) { + goto loser; /* err set by AppendHandshake. */ +@@ -9320,6 +9754,11 @@ + PORT_Free(signed_hash.data); + return SECSuccess; + ++ case ssl_kea_dh: { ++ rv = ssl3_SendDHServerKeyExchange(ss); ++ return rv; ++ } ++ + #ifndef NSS_DISABLE_ECC + case kt_ecdh: { + rv = ssl3_SendECDHServerKeyExchange(ss, &sigAndHash); +@@ -9327,7 +9766,6 @@ + } + #endif /* NSS_DISABLE_ECC */ + +- case kt_dh: + case kt_null: + default: + PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); +@@ -9339,6 +9777,36 @@ + return SECFailure; + } + ++static SECStatus ++ssl3_EncodeCertificateRequestSigAlgs(sslSocket *ss, PRUint8 *buf, ++ unsigned maxLen, PRUint32 *len) ++{ ++ unsigned int i; ++ ++ PORT_Assert(maxLen >= ss->ssl3.signatureAlgorithmCount * 2); ++ if (maxLen < ss->ssl3.signatureAlgorithmCount * 2) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } ++ ++ *len = 0; ++ for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) { ++ const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i]; ++ /* Note that we don't support a handshake hash with anything other than ++ * SHA-256, so asking for a signature from clients for something else ++ * would be inviting disaster. */ ++ if (alg->hashAlg == ssl_hash_sha256) { ++ buf[(*len)++] = (PRUint8)alg->hashAlg; ++ buf[(*len)++] = (PRUint8)alg->sigAlg; ++ } ++ } ++ ++ if (*len == 0) { ++ PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM); ++ return SECFailure; ++ } ++ return SECSuccess; ++} + + static SECStatus + ssl3_SendCertificateRequest(sslSocket *ss) +@@ -9347,7 +9815,6 @@ + SECItem * name; + CERTDistNames *ca_list; + const PRUint8 *certTypes; +- const PRUint8 *sigAlgs; + SECItem * names = NULL; + SECStatus rv; + int length; +@@ -9355,7 +9822,8 @@ + int calen = 0; + int nnames = 0; + int certTypesLength; +- int sigAlgsLength; ++ PRUint8 sigAlgs[MAX_SIGNATURE_ALGORITHMS * 2]; ++ unsigned int sigAlgsLength = 0; + + SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake", + SSL_GETPID(), ss->fd)); +@@ -9382,12 +9850,15 @@ + + certTypes = certificate_types; + certTypesLength = sizeof certificate_types; +- sigAlgs = supported_signature_algorithms; +- sigAlgsLength = sizeof supported_signature_algorithms; + + length = 1 + certTypesLength + 2 + calen; + if (isTLS12) { +- length += 2 + sigAlgsLength; ++ rv = ssl3_EncodeCertificateRequestSigAlgs(ss, sigAlgs, sizeof(sigAlgs), ++ &sigAlgsLength); ++ if (rv != SECSuccess) { ++ return rv; ++ } ++ length += 2 + sigAlgsLength; + } + + rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length); +@@ -9453,7 +9924,7 @@ + int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY; + SSL3AlertDescription desc = handshake_failure; + PRBool isTLS, isTLS12; +- SSL3SignatureAndHashAlgorithm sigAndHash; ++ SSLSignatureAndHashAlg sigAndHash; + + SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake", + SSL_GETPID(), ss->fd)); +@@ -9469,6 +9940,13 @@ + goto alert_loser; + } + ++ if (!hashes) { ++ PORT_Assert(0); ++ desc = internal_error; ++ errCode = SEC_ERROR_LIBRARY_FAILURE; ++ goto alert_loser; ++ } ++ + if (isTLS12) { + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, + &sigAndHash); +@@ -9476,7 +9954,7 @@ + goto loser; /* malformed or unsupported. */ + } + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( +- &sigAndHash, ss->sec.peerCert); ++ ss, &sigAndHash, ss->sec.peerCert); + if (rv != SECSuccess) { + errCode = PORT_GetError(); + desc = decrypt_error; +@@ -9485,7 +9963,7 @@ + + /* We only support CertificateVerify messages that use the handshake + * hash. */ +- if (sigAndHash.hashAlg != hashes->hashAlg) { ++ if (sigAndHash.hashAlg != hashes->hashAlg) { + errCode = SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM; + desc = decrypt_error; + goto alert_loser; +@@ -9616,18 +10094,17 @@ + PRUint32 length, + SECKEYPrivateKey *serverKey) + { +- PK11SymKey * pms; + #ifndef NO_PKCS11_BYPASS + unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random; + unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random; + ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; + unsigned int outLen = 0; +-#endif + PRBool isTLS = PR_FALSE; ++ SECItem pmsItem = {siBuffer, NULL, 0}; ++ unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; ++#endif + SECStatus rv; + SECItem enc_pms; +- unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; +- SECItem pmsItem = {siBuffer, NULL, 0}; + + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); +@@ -9635,8 +10112,10 @@ + + enc_pms.data = b; + enc_pms.len = length; ++#ifndef NO_PKCS11_BYPASS + pmsItem.data = rsaPmsBuf; + pmsItem.len = sizeof rsaPmsBuf; ++#endif + + if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */ + PRInt32 kLen; +@@ -9648,13 +10127,24 @@ + if ((unsigned)kLen < enc_pms.len) { + enc_pms.len = kLen; + } ++#ifndef NO_PKCS11_BYPASS + isTLS = PR_TRUE; ++#endif + } else { ++#ifndef NO_PKCS11_BYPASS + isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0); ++#endif + } + + #ifndef NO_PKCS11_BYPASS + if (ss->opt.bypassPKCS11) { ++ /* We have not implemented a tls_ExtendedMasterKeyDeriveBypass ++ * and will not negotiate this extension in bypass mode. This ++ * assert just double-checks that. ++ */ ++ PORT_Assert( ++ !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)); ++ + /* TRIPLE BYPASS, get PMS directly from RSA decryption. + * Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer, + * then, check for version rollback attack, then +@@ -9682,8 +10172,8 @@ + } + } + /* have PMS, build MS without PKCS11 */ +- rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS, +- PR_TRUE); ++ rv = ssl3_MasterSecretDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS, ++ PR_TRUE); + if (rv != SECSuccess) { + pwSpec->msItem.data = pwSpec->raw_master_secret; + pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; +@@ -9693,49 +10183,163 @@ + } else + #endif + { ++ PK11SymKey *tmpPms[2] = {NULL, NULL}; ++ PK11SlotInfo *slot; ++ int useFauxPms = 0; ++#define currentPms tmpPms[!useFauxPms] ++#define unusedPms tmpPms[useFauxPms] ++#define realPms tmpPms[1] ++#define fauxPms tmpPms[0] ++ + #ifndef NO_PKCS11_BYPASS + double_bypass: + #endif +- /* +- * unwrap pms out of the incoming buffer +- * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do +- * the unwrap. Rather, it is the mechanism with which the +- * unwrapped pms will be used. +- */ +- pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms, +- CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0); +- if (pms != NULL) { +- PRINT_BUF(60, (ss, "decrypted premaster secret:", +- PK11_GetKeyData(pms)->data, +- PK11_GetKeyData(pms)->len)); +- } else { +- /* unwrap failed. Generate a bogus PMS and carry on. */ +- PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey); + +- ssl_GetSpecWriteLock(ss); +- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot); +- ssl_ReleaseSpecWriteLock(ss); +- PK11_FreeSlot(slot); +- } ++ /* ++ * Get as close to algorithm 2 from RFC 5246; Section 7.4.7.1 ++ * as we can within the constraints of the PKCS#11 interface. ++ * ++ * 1. Unconditionally generate a bogus PMS (what RFC 5246 ++ * calls R). ++ * 2. Attempt the RSA decryption to recover the PMS (what ++ * RFC 5246 calls M). ++ * 3. Set PMS = (M == NULL) ? R : M ++ * 4. Use ssl3_ComputeMasterSecret(PMS) to attempt to derive ++ * the MS from PMS. This includes performing the version ++ * check and length check. ++ * 5. If either the initial RSA decryption failed or ++ * ssl3_ComputeMasterSecret(PMS) failed, then discard ++ * M and set PMS = R. Else, discard R and set PMS = M. ++ * ++ * We do two derivations here because we can't rely on having ++ * a function that only performs the PMS version and length ++ * check. The only redundant cost is that this runs the PRF, ++ * which isn't necessary here. ++ */ ++ ++ /* Generate the bogus PMS (R) */ ++ slot = PK11_GetSlotFromPrivateKey(serverKey); ++ if (!slot) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } + +- if (pms == NULL) { +- /* last gasp. */ ++ if (!PK11_DoesMechanism(slot, CKM_SSL3_MASTER_KEY_DERIVE)) { ++ PK11_FreeSlot(slot); ++ slot = PK11_GetBestSlot(CKM_SSL3_MASTER_KEY_DERIVE, NULL); ++ if (!slot) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } ++ } ++ ++ ssl_GetSpecWriteLock(ss); ++ fauxPms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot); ++ ssl_ReleaseSpecWriteLock(ss); ++ PK11_FreeSlot(slot); ++ ++ if (fauxPms == NULL) { + ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); + return SECFailure; + } + ++ /* ++ * unwrap pms out of the incoming buffer ++ * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do ++ * the unwrap. Rather, it is the mechanism with which the ++ * unwrapped pms will be used. ++ */ ++ realPms = PK11_PubUnwrapSymKey(serverKey, &enc_pms, ++ CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0); ++ /* Temporarily use the PMS if unwrapping the real PMS fails. */ ++ useFauxPms |= (realPms == NULL); ++ ++ /* Attempt to derive the MS from the PMS. This is the only way to ++ * check the version field in the RSA PMS. If this fails, we ++ * then use the faux PMS in place of the PMS. Note that this ++ * operation should never fail if we are using the faux PMS ++ * since it is correctly formatted. */ ++ rv = ssl3_ComputeMasterSecret(ss, currentPms, NULL); ++ ++ /* If we succeeded, then select the true PMS and discard the ++ * FPMS. Else, select the FPMS and select the true PMS */ ++ useFauxPms |= (rv != SECSuccess); ++ ++ if (unusedPms) { ++ PK11_FreeSymKey(unusedPms); ++ } ++ + /* This step will derive the MS from the PMS, among other things. */ +- rv = ssl3_InitPendingCipherSpec(ss, pms); +- PK11_FreeSymKey(pms); ++ rv = ssl3_InitPendingCipherSpec(ss, currentPms); ++ PK11_FreeSymKey(currentPms); + } + + if (rv != SECSuccess) { + SEND_ALERT + return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */ + } ++ ++#undef currentPms ++#undef unusedPms ++#undef realPms ++#undef fauxPms ++ + return SECSuccess; + } + ++static SECStatus ++ssl3_HandleDHClientKeyExchange(sslSocket *ss, ++ SSL3Opaque *b, ++ PRUint32 length, ++ SECKEYPublicKey *srvrPubKey, ++ SECKEYPrivateKey *serverKey) ++{ ++ PK11SymKey *pms; ++ SECStatus rv; ++ SECKEYPublicKey clntPubKey; ++ CK_MECHANISM_TYPE target; ++ PRBool isTLS; ++ ++ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); ++ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); ++ PORT_Assert( srvrPubKey ); ++ ++ clntPubKey.keyType = dhKey; ++ clntPubKey.u.dh.prime.len = srvrPubKey->u.dh.prime.len; ++ clntPubKey.u.dh.prime.data = srvrPubKey->u.dh.prime.data; ++ clntPubKey.u.dh.base.len = srvrPubKey->u.dh.base.len; ++ clntPubKey.u.dh.base.data = srvrPubKey->u.dh.base.data; ++ ++ rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.dh.publicValue, ++ 2, &b, &length); ++ if (rv != SECSuccess) { ++ goto loser; ++ } ++ ++ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); ++ ++ if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; ++ else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; ++ ++ /* Determine the PMS */ ++ pms = PK11_PubDerive(serverKey, &clntPubKey, PR_FALSE, NULL, NULL, ++ CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL); ++ if (pms == NULL) { ++ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); ++ goto loser; ++ } ++ ++ rv = ssl3_InitPendingCipherSpec(ss, pms); ++ PK11_FreeSymKey(pms); pms = NULL; ++ ++loser: ++ if (ss->dheKeyPair) { ++ ssl3_FreeKeyPair(ss->dheKeyPair); ++ ss->dheKeyPair = NULL; ++ } ++ return rv; ++} ++ + + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete + * ssl3 ClientKeyExchange message from the remote client +@@ -9748,9 +10352,7 @@ + SECStatus rv; + const ssl3KEADef *kea_def; + ssl3KeyPair *serverKeyPair = NULL; +-#ifndef NSS_DISABLE_ECC + SECKEYPublicKey *serverPubKey = NULL; +-#endif /* NSS_DISABLE_ECC */ + + SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake", + SSL_GETPID(), ss->fd)); +@@ -9780,6 +10382,16 @@ + ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; + } else + skip: ++ if (kea_def->kea == kea_dhe_dss || ++ kea_def->kea == kea_dhe_rsa) { ++ if (ss->dheKeyPair) { ++ serverKeyPair = ss->dheKeyPair; ++ if (serverKeyPair->pubKey) { ++ ss->sec.keaKeyBits = ++ SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey); ++ } ++ } ++ } else + #ifndef NSS_DISABLE_ECC + /* XXX Using SSLKEAType to index server certifiates + * does not work for (EC)DHE ciphers. Until we have +@@ -9825,6 +10437,21 @@ + } + break; + ++ case ssl_kea_dh: ++ if (ss->dheKeyPair && ss->dheKeyPair->pubKey) { ++ serverPubKey = ss->dheKeyPair->pubKey; ++ } ++ if (!serverPubKey) { ++ PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); ++ return SECFailure; ++ } ++ rv = ssl3_HandleDHClientKeyExchange(ss, b, length, ++ serverPubKey, serverKey); ++ if (rv != SECSuccess) { ++ SSL3_SendAlert(ss, alert_fatal, handshake_failure); ++ return SECFailure; /* error code set */ ++ } ++ break; + + #ifndef NSS_DISABLE_ECC + case kt_ecdh: +@@ -10454,6 +11081,8 @@ + + ss->ssl3.hs.authCertificatePending = PR_FALSE; + ++ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == ++ ssl_preinfo_all); + /* + * Ask caller-supplied callback function to validate cert chain. + */ +@@ -10498,40 +11127,60 @@ + ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType; + ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType; + if (pubKey) { ++ KeyType pubKeyType; ++ PRInt32 minKey; + ss->sec.keaKeyBits = ss->sec.authKeyBits = + SECKEY_PublicKeyStrengthInBits(pubKey); +-#ifndef NSS_DISABLE_ECC +- if (ss->sec.keaType == kt_ecdh) { +- /* Get authKeyBits from signing key. +- * XXX The code below uses a quick approximation of +- * key size based on cert->signatureWrap.signature.data +- * (which contains the DER encoded signature). The field +- * cert->signatureWrap.signature.len contains the +- * length of the encoded signature in bits. +- */ +- if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) { +- ss->sec.authKeyBits = +- cert->signatureWrap.signature.data[3]*8; +- if (cert->signatureWrap.signature.data[4] == 0x00) +- ss->sec.authKeyBits -= 8; +- /* +- * XXX: if cert is not signed by ecdsa we should +- * destroy pubKey and goto bad_cert +- */ +- } else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) { +- ss->sec.authKeyBits = cert->signatureWrap.signature.len; +- /* +- * XXX: if cert is not signed by rsa we should +- * destroy pubKey and goto bad_cert +- */ ++ pubKeyType = SECKEY_GetPublicKeyType(pubKey); ++ minKey = ss->sec.authKeyBits; ++ switch (pubKeyType) { ++ case rsaKey: ++ case rsaPssKey: ++ case rsaOaepKey: ++ rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minKey); ++ if (rv != SECSuccess) { ++ minKey = SSL_RSA_MIN_MODULUS_BITS; + } ++ break; ++ case dsaKey: ++ rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minKey); ++ if (rv != SECSuccess) { ++ minKey = SSL_DSA_MIN_P_BITS; ++ } ++ break; ++ case dhKey: ++ rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minKey); ++ if (rv != SECSuccess) { ++ minKey = SSL_DH_MIN_P_BITS; ++ } ++ break; ++ default: ++ break; + } +-#endif /* NSS_DISABLE_ECC */ ++ ++ /* Too small: not good enough. Send a fatal alert. */ ++ /* We aren't checking EC here on the understanding that we only ++ * support curves we like, a decision that might need revisiting. */ ++ if ( ss->sec.authKeyBits < minKey) { ++ PORT_SetError(SSL_ERROR_WEAK_SERVER_CERT_KEY); ++ (void)SSL3_SendAlert(ss, alert_fatal, ++ ss->version >= SSL_LIBRARY_VERSION_TLS_1_0 ++ ? insufficient_security ++ : illegal_parameter); ++ SECKEY_DestroyPublicKey(pubKey); ++ return SECFailure; ++ } + SECKEY_DestroyPublicKey(pubKey); + pubKey = NULL; + } + +- if (ss->ssl3.hs.kea_def->ephemeral) { ++ /* Ephemeral suites require ServerKeyExchange. Export cipher suites ++ * with RSA key exchange also require ServerKeyExchange if the ++ * authentication key exceeds the key size limit. */ ++ if (ss->ssl3.hs.kea_def->ephemeral || ++ (ss->ssl3.hs.kea_def->is_limited && ++ ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa && ++ ss->sec.authKeyBits > ss->ssl3.hs.kea_def->key_size_limit)) { + ss->ssl3.hs.ws = wait_server_key; /* require server_key_exchange */ + } else { + ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ +@@ -10643,16 +11292,42 @@ + const SSL3Hashes * hashes, + TLSFinished * tlsFinished) + { +- const char * label; +- unsigned int len; +- SECStatus rv; ++ SECStatus rv; ++ CK_TLS_MAC_PARAMS tls_mac_params; ++ SECItem param = {siBuffer, NULL, 0}; ++ PK11Context *prf_context; ++ unsigned int retLen; + +- label = isServer ? "server finished" : "client finished"; +- len = 15; ++ if (!spec->master_secret || spec->bypassCiphers) { ++ const char *label = isServer ? "server finished" : "client finished"; ++ unsigned int len = 15; + +- rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw, +- hashes->len, tlsFinished->verify_data, +- sizeof tlsFinished->verify_data); ++ return ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw, ++ hashes->len, tlsFinished->verify_data, ++ sizeof tlsFinished->verify_data); ++ } ++ ++ if (spec->version < SSL_LIBRARY_VERSION_TLS_1_2) { ++ tls_mac_params.prfMechanism = CKM_TLS_PRF; ++ } else { ++ tls_mac_params.prfMechanism = CKM_SHA256; ++ } ++ tls_mac_params.ulMacLength = 12; ++ tls_mac_params.ulServerOrClient = isServer ? 1 : 2; ++ param.data = (unsigned char *)&tls_mac_params; ++ param.len = sizeof(tls_mac_params); ++ prf_context = PK11_CreateContextBySymKey(CKM_TLS_MAC, CKA_SIGN, ++ spec->master_secret, ¶m); ++ if (!prf_context) ++ return SECFailure; ++ ++ rv = PK11_DigestBegin(prf_context); ++ rv |= PK11_DigestOp(prf_context, hashes->u.raw, hashes->len); ++ rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data, &retLen, ++ sizeof tlsFinished->verify_data); ++ PORT_Assert(rv != SECSuccess || retLen == sizeof tlsFinished->verify_data); ++ ++ PK11_DestroyContext(prf_context, PR_TRUE); + + return rv; + } +@@ -11170,6 +11845,13 @@ + return SECFailure; + } + ++ if (!hashes) { ++ PORT_Assert(0); ++ SSL3_SendAlert(ss, alert_fatal, internal_error); ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } ++ + isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0); + if (isTLS) { + TLSFinished tlsFinished; +@@ -11225,7 +11907,8 @@ + * ServerHello message.) + */ + if (isServer && !ss->ssl3.hs.isResuming && +- ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) { ++ ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && ++ ssl3_KEAAllowsSessionTicket(ss->ssl3.hs.suite_def->key_exchange_alg)) { + /* RFC 5077 Section 3.3: "In the case of a full handshake, the + * server MUST verify the client's Finished message before sending + * the ticket." Presumably, this also means that the client's +@@ -11278,7 +11961,8 @@ + return rv; + } + +- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { ++ if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || ++ ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) { + effectiveExchKeyType = kt_rsa; + } else { + effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; +@@ -11398,6 +12082,7 @@ + SECStatus rv = SECSuccess; + SSL3HandshakeType type = ss->ssl3.hs.msg_type; + SSL3Hashes hashes; /* computed hashes are put here. */ ++ SSL3Hashes *hashesPtr = NULL; /* Set when hashes are computed */ + PRUint8 hdr[4]; + PRUint8 dtlsData[8]; + +@@ -11408,7 +12093,8 @@ + * current message. + */ + ssl_GetSpecReadLock(ss); /************************************/ +- if((type == finished) || (type == certificate_verify)) { ++ if(((type == finished) && (ss->ssl3.hs.ws == wait_finished)) || ++ ((type == certificate_verify) && (ss->ssl3.hs.ws == wait_cert_verify))) { + SSL3Sender sender = (SSL3Sender)0; + ssl3CipherSpec *rSpec = ss->ssl3.prSpec; + +@@ -11417,6 +12103,9 @@ + rSpec = ss->ssl3.crSpec; + } + rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); ++ if (rv == SECSuccess) { ++ hashesPtr = &hashes; ++ } + } + ssl_ReleaseSpecReadLock(ss); /************************************/ + if (rv != SECSuccess) { +@@ -11567,7 +12256,7 @@ + PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); + return SECFailure; + } +- rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes); ++ rv = ssl3_HandleCertificateVerify(ss, b, length, hashesPtr); + break; + case client_key_exchange: + if (!ss->sec.isServer) { +@@ -11586,7 +12275,7 @@ + rv = ssl3_HandleNewSessionTicket(ss, b, length); + break; + case finished: +- rv = ssl3_HandleFinished(ss, b, length, &hashes); ++ rv = ssl3_HandleFinished(ss, b, length, hashesPtr); + break; + default: + (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); +@@ -11641,7 +12330,7 @@ + #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ + if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) { + (void)ssl3_DecodeError(ss); +- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); ++ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); + return SECFailure; + } + #undef MAX_HANDSHAKE_MSG_LEN +@@ -11942,7 +12631,7 @@ + SSL3Opaque *givenHash; + sslBuffer *plaintext; + sslBuffer temp_buf; +- PRUint64 dtls_seq_num; ++ PRUint64 dtls_seq_num = 0; + unsigned int ivLen = 0; + unsigned int originalLen = 0; + unsigned int good; +@@ -12423,6 +13112,7 @@ + ss->ssl3.hs.sendingSCSV = PR_FALSE; + ssl3_InitCipherSpec(ss, ss->ssl3.crSpec); + ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); ++ ss->ssl3.hs.preliminaryInfo = 0; + + ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; + #ifndef NSS_DISABLE_ECC +@@ -12496,8 +13186,6 @@ + } + } + +- +- + /* + * Creates the public and private RSA keys for SSL Step down. + * Called from SSL_ConfigSecureServer in sslsecur.c +@@ -12529,7 +13217,6 @@ + return rv; + } + +- + /* record the export policy for this cipher suite */ + SECStatus + ssl3_SetPolicy(ssl3CipherSuite which, int policy) +@@ -12631,6 +13318,79 @@ + } + + SECStatus ++SSL_SignaturePrefSet(PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms, ++ unsigned int count) ++{ ++ sslSocket *ss; ++ unsigned int i; ++ ++ ss = ssl_FindSocket(fd); ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignaturePrefSet", ++ SSL_GETPID(), fd)); ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ if (!count || count > MAX_SIGNATURE_ALGORITHMS) { ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ ss->ssl3.signatureAlgorithmCount = 0; ++ for (i = 0; i < count; ++i) { ++ if (!ssl3_IsSupportedSignatureAlgorithm(&algorithms[i])) { ++ SSL_DBG(("%d: SSL[%d]: invalid signature algorithm set %d/%d", ++ SSL_GETPID(), fd, algorithms[i].sigAlg, ++ algorithms[i].hashAlg)); ++ continue; ++ } ++ ++ ss->ssl3.signatureAlgorithms[ss->ssl3.signatureAlgorithmCount++] = ++ algorithms[i]; ++ } ++ ++ if (ss->ssl3.signatureAlgorithmCount == 0) { ++ PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM); ++ return SECFailure; ++ } ++ return SECSuccess; ++} ++ ++SECStatus ++SSL_SignaturePrefGet(PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms, ++ unsigned int *count, unsigned int maxCount) ++{ ++ sslSocket *ss; ++ unsigned int requiredSpace; ++ ++ ss = ssl_FindSocket(fd); ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignaturePrefGet", ++ SSL_GETPID(), fd)); ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ if (!algorithms || !count || ++ maxCount < ss->ssl3.signatureAlgorithmCount) { ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ requiredSpace = ++ ss->ssl3.signatureAlgorithmCount * sizeof(SSLSignatureAndHashAlg); ++ PORT_Memcpy(algorithms, ss->ssl3.signatureAlgorithms, requiredSpace); ++ *count = ss->ssl3.signatureAlgorithmCount; ++ return SECSuccess; ++} ++ ++unsigned int ++SSL_SignatureMaxCount() { ++ return MAX_SIGNATURE_ALGORITHMS; ++} ++ ++SECStatus + ssl3_CipherOrderSet(sslSocket *ss, const ssl3CipherSuite *ciphers, unsigned int len) + { + /* |i| iterates over |ciphers| while |done| and |j| iterate over +@@ -12675,6 +13435,9 @@ + ssl3_InitSocketPolicy(sslSocket *ss) + { + PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites); ++ PORT_Memcpy(ss->ssl3.signatureAlgorithms, defaultSignatureAlgorithms, ++ sizeof(defaultSignatureAlgorithms)); ++ ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms); + } + + SECStatus +@@ -12764,7 +13527,7 @@ + /* ssl3_config_match_init was called by the caller of this function. */ + for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { + ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; +- if (config_match(suite, SSL_ALLOWED, PR_TRUE, &ss->vrange)) { ++ if (config_match(suite, SSL_ALLOWED, PR_TRUE, &ss->vrange, ss)) { + if (cs != NULL) { + *cs++ = 0x00; + *cs++ = (suite->cipher_suite >> 8) & 0xFF; +@@ -12898,6 +13661,10 @@ + } + } + ++ if (ss->ssl3.dheGroups) { ++ PORT_Free(ss->ssl3.dheGroups); ++ } ++ + ss->ssl3.initialized = PR_FALSE; + + SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ecc.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ecc.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ecc.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ecc.c 2016-01-13 14:18:55.621954867 +0100 +@@ -214,7 +214,7 @@ + + /* Caller must set hiLevel error code. */ + static SECStatus +-ssl3_ComputeECDHKeyHash(SECOidTag hashAlg, ++ssl3_ComputeECDHKeyHash(SSLHashType hashAlg, + SECItem ec_params, SECItem server_ecpoint, + SSL3Random *client_rand, SSL3Random *server_rand, + SSL3Hashes *hashes, PRBool bypassPKCS11) +@@ -303,7 +303,7 @@ + pubKey->u.ec.publicValue.len)); + + if (isTLS12) { +- target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; ++ target = CKM_TLS12_MASTER_KEY_DERIVE_DH; + } else if (isTLS) { + target = CKM_TLS_MASTER_KEY_DERIVE_DH; + } else { +@@ -325,14 +325,6 @@ + SECKEY_DestroyPrivateKey(privKey); + privKey = NULL; + +- rv = ssl3_InitPendingCipherSpec(ss, pms); +- PK11_FreeSymKey(pms); pms = NULL; +- +- if (rv != SECSuccess) { +- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); +- goto loser; +- } +- + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, + pubKey->u.ec.publicValue.len + 1); + if (rv != SECSuccess) { +@@ -349,6 +341,14 @@ + goto loser; /* err set by ssl3_AppendHandshake* */ + } + ++ rv = ssl3_InitPendingCipherSpec(ss, pms); ++ PK11_FreeSymKey(pms); pms = NULL; ++ ++ if (rv != SECSuccess) { ++ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); ++ goto loser; ++ } ++ + rv = SECSuccess; + + loser: +@@ -394,7 +394,7 @@ + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); + + if (isTLS12) { +- target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; ++ target = CKM_TLS12_MASTER_KEY_DERIVE_DH; + } else if (isTLS) { + target = CKM_TLS_MASTER_KEY_DERIVE_DH; + } else { +@@ -615,9 +615,9 @@ + SECItem ec_params = {siBuffer, NULL, 0}; + SECItem ec_point = {siBuffer, NULL, 0}; + unsigned char paramBuf[3]; /* only for curve_type == named_curve */ +- SSL3SignatureAndHashAlgorithm sigAndHash; ++ SSLSignatureAndHashAlg sigAndHash; + +- sigAndHash.hashAlg = SEC_OID_UNKNOWN; ++ sigAndHash.hashAlg = ssl_hash_none; + + isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); +@@ -659,7 +659,7 @@ + goto loser; /* malformed or unsupported. */ + } + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( +- &sigAndHash, ss->sec.peerCert); ++ ss, &sigAndHash, ss->sec.peerCert); + if (rv != SECSuccess) { + goto loser; + } +@@ -710,7 +710,7 @@ + goto no_memory; + } + +- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); ++ peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); + if (peerKey == NULL) { + goto no_memory; + } +@@ -731,7 +731,6 @@ + /* copy publicValue in peerKey */ + if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point)) + { +- PORT_FreeArena(arena, PR_FALSE); + goto no_memory; + } + peerKey->pkcs11Slot = NULL; +@@ -745,10 +744,16 @@ + alert_loser: + (void)SSL3_SendAlert(ss, alert_fatal, desc); + loser: ++ if (arena) { ++ PORT_FreeArena(arena, PR_FALSE); ++ } + PORT_SetError( errCode ); + return SECFailure; + + no_memory: /* no-memory error has already been set. */ ++ if (arena) { ++ PORT_FreeArena(arena, PR_FALSE); ++ } + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); + return SECFailure; + } +@@ -756,7 +761,7 @@ + SECStatus + ssl3_SendECDHServerKeyExchange( + sslSocket *ss, +- const SSL3SignatureAndHashAlgorithm *sigAndHash) ++ const SSLSignatureAndHashAlg *sigAndHash) + { + const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; + SECStatus rv = SECFailure; +@@ -977,9 +982,7 @@ + if (!suite) + suite = ecSuites; + for (; *suite; ++suite) { +- SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); +- +- PORT_Assert(rv == SECSuccess); /* else is coding error */ ++ PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); + } + return SECSuccess; + } +@@ -1142,7 +1145,10 @@ + ecList = tlsECList; + } + +- if (append && maxBytes >= ecListSize) { ++ if (maxBytes < (PRUint32)ecListSize) { ++ return 0; ++ } ++ if (append) { + SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize); + if (rv != SECSuccess) + return -1; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ext.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ext.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ext.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3ext.c 2016-01-13 14:18:55.623954879 +0100 +@@ -101,6 +101,12 @@ + PRUint32 maxBytes); + static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data); ++static PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append, ++ PRUint32 maxBytes); ++static SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss, ++ PRUint16 ex_type, ++ SECItem *data); ++ + + /* + * Write bytes. Using this function means the SECItem structure +@@ -266,6 +272,7 @@ + { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, + { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn }, ++ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, + { -1, NULL } + }; + +@@ -281,6 +288,7 @@ + { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn }, + { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, ++ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, + { ssl_signed_certificate_timestamp_xtn, + &ssl3_ClientHandleSignedCertTimestampXtn }, + { -1, NULL } +@@ -319,6 +327,7 @@ + * extension. */ + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn }, ++ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn}, + /* any extra entries will appear as { 0, NULL } */ + }; + +@@ -331,7 +340,7 @@ + static PRBool + arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) + { +- int i; ++ unsigned int i; + for (i = 0; i < len; i++) { + if (ex_type == array[i]) + return PR_TRUE; +@@ -433,12 +442,12 @@ + } + /* length of server_name_list */ + listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); +- if (listLenBytes < 0 || listLenBytes != data->len) { +- (void)ssl3_DecodeError(ss); ++ if (listLenBytes < 0) { + return SECFailure; + } +- if (listLenBytes == 0) { +- return SECSuccess; /* ignore an empty extension */ ++ if (listLenBytes == 0 || listLenBytes != data->len) { ++ (void)ssl3_DecodeError(ss); ++ return SECFailure; + } + ldata = *data; + /* Calculate the size of the array.*/ +@@ -463,15 +472,12 @@ + } + listCount += 1; + } +- if (!listCount) { +- return SECFailure; /* nothing we can act on */ +- } + names = PORT_ZNewArray(SECItem, listCount); + if (!names) { + return SECFailure; + } + for (i = 0;i < listCount;i++) { +- int j; ++ unsigned int j; + PRInt32 type; + SECStatus rv; + PRBool nametypePresent = PR_FALSE; +@@ -559,7 +565,11 @@ + } + } + +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ PORT_Assert(0); ++ return 0; ++ } ++ if (append) { + SECStatus rv; + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); +@@ -582,9 +592,6 @@ + xtnData->advertised[xtnData->numAdvertised++] = + ssl_session_ticket_xtn; + } +- } else if (maxBytes < extension_length) { +- PORT_Assert(0); +- return 0; + } + return extension_length; + +@@ -645,12 +652,17 @@ + + rv = ssl3_ValidateNextProtoNego(data->data, data->len); + if (rv != SECSuccess) { +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + (void)SSL3_SendAlert(ss, alert_fatal, decode_error); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return rv; + } + + PORT_Assert(ss->nextProtoCallback); ++ /* For ALPN, the cipher suite isn't selected yet. Note that extensions ++ * sometimes affect what cipher suite is selected, e.g., for ECC. */ ++ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ++ ssl_preinfo_all & ~ssl_preinfo_cipher_suite) == ++ (ssl_preinfo_all & ~ssl_preinfo_cipher_suite)); + rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, + result.data, &result.len, sizeof(resultBuffer)); + if (rv != SECSuccess) { +@@ -673,8 +685,8 @@ + ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) { + /* The callback might say OK, but then it picks a default value - one + * that was not listed. That's OK for NPN, but not ALPN. */ +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL); + (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL); + return SECFailure; + } + +@@ -693,8 +705,8 @@ + * despite it being permitted by the spec. */ + if (ss->firstHsDone || data->len == 0) { + /* Clients MUST send a non-empty ALPN extension. */ +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return SECFailure; + } + +@@ -721,8 +733,8 @@ + rv = ssl3_RegisterServerHelloExtensionSender( + ss, ex_type, ssl3_ServerSendAppProtoXtn); + if (rv != SECSuccess) { +- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return rv; + } + } +@@ -742,8 +754,8 @@ + * we've negotiated NPN then we're required to send the NPN handshake + * message. Thus, these two extensions cannot both be negotiated on the + * same connection. */ +- PORT_SetError(SSL_ERROR_BAD_SERVER); + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); ++ PORT_SetError(SSL_ERROR_BAD_SERVER); + return SECFailure; + } + +@@ -753,8 +765,8 @@ + * we sent the ClientHello and now. */ + if (!ss->nextProtoCallback) { + PORT_Assert(0); +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK); + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK); + return SECFailure; + } + +@@ -778,16 +790,16 @@ + * uint8 len; // where len >= 1 + * uint8 protocol_name[len]; */ + if (data->len < 4 || data->len > 2 + 1 + 255) { +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + (void)SSL3_SendAlert(ss, alert_fatal, decode_error); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return SECFailure; + } + + list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + /* The list has to be the entire extension. */ + if (list_len != data->len) { +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + (void)SSL3_SendAlert(ss, alert_fatal, decode_error); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return SECFailure; + } + +@@ -795,8 +807,8 @@ + &data->data, &data->len); + /* The list must have exactly one value. */ + if (rv != SECSuccess || data->len != 0) { +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + (void)SSL3_SendAlert(ss, alert_fatal, decode_error); ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return SECFailure; + } + +@@ -819,7 +831,10 @@ + + extension_length = 4; + +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ return 0; ++ } ++ if (append) { + SECStatus rv; + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); + if (rv != SECSuccess) +@@ -829,8 +844,6 @@ + goto loser; + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_next_proto_nego_xtn; +- } else if (maxBytes < extension_length) { +- return 0; + } + + return extension_length; +@@ -854,7 +867,10 @@ + 2 /* protocol name list length */ + + ss->opt.nextProtoNego.len; + +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ return 0; ++ } ++ if (append) { + /* NPN requires that the client's fallback protocol is first in the + * list. However, ALPN sends protocols in preference order. So we + * allocate a buffer and move the first protocol to the end of the +@@ -894,8 +910,6 @@ + } + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_app_layer_protocol_xtn; +- } else if (maxBytes < extension_length) { +- return 0; + } + + return extension_length; +@@ -923,7 +937,10 @@ + 2 /* protocol name list */ + 1 /* name length */ + + ss->ssl3.nextProto.len; + +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ return 0; ++ } ++ if (append) { + SECStatus rv; + rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); + if (rv != SECSuccess) { +@@ -942,8 +959,6 @@ + if (rv != SECSuccess) { + return -1; + } +- } else if (maxBytes < extension_length) { +- return 0; + } + + return extension_length; +@@ -1045,7 +1060,10 @@ + return 0; + + extension_length = 2 + 2; +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ return 0; ++ } ++ if (append) { + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); + if (rv != SECSuccess) +@@ -1078,7 +1096,11 @@ + */ + extension_length = 9; + +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ PORT_Assert(0); ++ return 0; ++ } ++ if (append) { + SECStatus rv; + TLSExtensionData *xtnData; + +@@ -1106,9 +1128,6 @@ + + xtnData = &ss->xtnData; + xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn; +- } else if (maxBytes < extension_length) { +- PORT_Assert(0); +- return 0; + } + return extension_length; + } +@@ -1120,7 +1139,7 @@ + SECStatus + ssl3_SendNewSessionTicket(sslSocket *ss) + { +- int i; ++ PRUint32 i; + SECStatus rv; + NewSessionTicket ticket; + SECItem plaintext; +@@ -1152,7 +1171,7 @@ + CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; + PK11Context *aes_ctx_pkcs11; + CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; +- PK11Context *hmac_ctx_pkcs11; ++ PK11Context *hmac_ctx_pkcs11 = NULL; + unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; + unsigned int computed_mac_length; + unsigned char iv[AES_BLOCK_SIZE]; +@@ -1200,7 +1219,8 @@ + sslSessionID sid; + PORT_Memset(&sid, 0, sizeof(sslSessionID)); + +- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { ++ if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || ++ ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) { + effectiveExchKeyType = kt_rsa; + } else { + effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; +@@ -1243,6 +1263,7 @@ + + cert_length /* cert */ + + 1 /* server name type */ + + srvNameLen /* name len + length field */ ++ + 1 /* extendedMasterSecretUsed */ + + sizeof(ticket.ticket_lifetime_hint); + padding_length = AES_BLOCK_SIZE - + (ciphertext_length % AES_BLOCK_SIZE); +@@ -1341,6 +1362,11 @@ + if (rv != SECSuccess) goto loser; + } + ++ /* extendedMasterSecretUsed */ ++ rv = ssl3_AppendNumberToItem( ++ &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1); ++ if (rv != SECSuccess) goto loser; ++ + PORT_Assert(plaintext.len == padding_length); + for (i = 0; i < padding_length; i++) + plaintext.data[i] = (unsigned char)padding_length; +@@ -1410,14 +1436,18 @@ + goto loser; + + rv = PK11_DigestBegin(hmac_ctx_pkcs11); ++ if (rv != SECSuccess) goto loser; + rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name, + SESS_TICKET_KEY_NAME_LEN); ++ if (rv != SECSuccess) goto loser; + rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv)); ++ if (rv != SECSuccess) goto loser; + rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2); ++ if (rv != SECSuccess) goto loser; + rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len); ++ if (rv != SECSuccess) goto loser; + rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac, + &computed_mac_length, sizeof(computed_mac)); +- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); + if (rv != SECSuccess) goto loser; + } + +@@ -1446,6 +1476,8 @@ + if (rv != SECSuccess) goto loser; + + loser: ++ if (hmac_ctx_pkcs11) ++ PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); + if (plaintext_item.data) + SECITEM_FreeItem(&plaintext_item, PR_FALSE); + if (ciphertext.data) +@@ -1495,7 +1527,7 @@ + if (data->len == 0) { + ss->xtnData.emptySessionTicket = PR_TRUE; + } else { +- int i; ++ PRUint32 i; + SECItem extension_data; + EncryptedSessionTicket enc_session_ticket; + unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; +@@ -1698,9 +1730,10 @@ + goto loser; + } + +- /* Read ticket_version (which is ignored for now.) */ ++ /* Read ticket_version and reject if the version is wrong */ + temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); +- if (temp < 0) goto no_ticket; ++ if (temp != TLS_EX_SESS_TICKET_VERSION) goto no_ticket; ++ + parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp; + + /* Read SSLVersion. */ +@@ -1801,6 +1834,13 @@ + parsed_session_ticket->srvName.type = nameType; + } + ++ /* Read extendedMasterSecretUsed */ ++ temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); ++ if (temp < 0) ++ goto no_ticket; ++ PORT_Assert(temp == PR_TRUE || temp == PR_FALSE); ++ parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp; ++ + /* Done parsing. Check that all bytes have been consumed. */ + if (buffer_len != padding_length) + goto no_ticket; +@@ -1847,6 +1887,8 @@ + parsed_session_ticket->ms_is_wrapped; + sid->u.ssl3.masterValid = PR_TRUE; + sid->u.ssl3.keys.resumable = PR_TRUE; ++ sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket-> ++ extendedMasterSecretUsed; + + /* Copy over client cert from session ticket if there is one. */ + if (parsed_session_ticket->peer_cert.data != NULL) { +@@ -2085,7 +2127,10 @@ + (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 + : ss->ssl3.hs.finishedBytes); + needed = 5 + len; +- if (append && maxBytes >= needed) { ++ if (maxBytes < (PRUint32)needed) { ++ return 0; ++ } ++ if (append) { + SECStatus rv; + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); +@@ -2138,8 +2183,8 @@ + } + if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data, + data->data + 1, len)) { +- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); + (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); ++ PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); + return SECFailure; + } + /* remember that we got this extension and it was correct. */ +@@ -2263,8 +2308,8 @@ + } + + if (!found) { +- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); ++ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + return SECFailure; + } + +@@ -2277,8 +2322,8 @@ + + /* We didn't offer an MKI, so this must be 0 length */ + if (litem.len != 0) { +- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); ++ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + return SECFailure; + } + +@@ -2374,7 +2419,7 @@ + SECStatus rv; + SECItem algorithms; + const unsigned char *b; +- unsigned int numAlgorithms, i, j; ++ unsigned int numAlgorithms, i; + + /* Ignore this extension if we aren't doing TLS 1.2 or greater. */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { +@@ -2388,8 +2433,8 @@ + } + /* Trailing data, empty value, or odd-length value is invalid. */ + if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) { +- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + (void)SSL3_SendAlert(ss, alert_fatal, decode_error); ++ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; + } + +@@ -2401,30 +2446,24 @@ + } + + ss->ssl3.hs.clientSigAndHash = +- PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms); ++ PORT_NewArray(SSLSignatureAndHashAlg, numAlgorithms); + if (!ss->ssl3.hs.clientSigAndHash) { +- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); ++ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; + } + ss->ssl3.hs.numClientSigAndHash = 0; + + b = algorithms.data; +- for (i = j = 0; i < numAlgorithms; i++) { +- unsigned char tls_hash = *(b++); +- unsigned char tls_sig = *(b++); +- SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash); +- +- if (hash == SEC_OID_UNKNOWN) { +- /* We ignore formats that we don't understand. */ +- continue; +- } +- /* tls_sig support will be checked later in +- * ssl3_PickSignatureHashAlgorithm. */ +- ss->ssl3.hs.clientSigAndHash[j].hashAlg = hash; +- ss->ssl3.hs.clientSigAndHash[j].sigAlg = tls_sig; +- ++j; +- ++ss->ssl3.hs.numClientSigAndHash; ++ ss->ssl3.hs.numClientSigAndHash = 0; ++ for (i = 0; i < numAlgorithms; i++) { ++ SSLSignatureAndHashAlg *sigAndHash = ++ &ss->ssl3.hs.clientSigAndHash[ss->ssl3.hs.numClientSigAndHash]; ++ sigAndHash->hashAlg = (SSLHashType)*(b++); ++ sigAndHash->sigAlg = (SSLSignType)*(b++); ++ if (ssl3_IsSupportedSignatureAlgorithm(sigAndHash)) { ++ ++ss->ssl3.hs.numClientSigAndHash; ++ } + } + + if (!ss->ssl3.hs.numClientSigAndHash) { +@@ -2442,60 +2481,60 @@ + /* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS + * 1.2 ClientHellos. */ + static PRInt32 +-ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) ++ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) + { +- static const unsigned char signatureAlgorithms[] = { +- /* This block is the contents of our signature_algorithms extension, in +- * wire format. See +- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ +- tls_hash_sha256, tls_sig_rsa, +- tls_hash_sha384, tls_sig_rsa, +- tls_hash_sha512, tls_sig_rsa, +- tls_hash_sha1, tls_sig_rsa, +-#ifndef NSS_DISABLE_ECC +- tls_hash_sha256, tls_sig_ecdsa, +- tls_hash_sha384, tls_sig_ecdsa, +- tls_hash_sha512, tls_sig_ecdsa, +- tls_hash_sha1, tls_sig_ecdsa, +-#endif +- tls_hash_sha256, tls_sig_dsa, +- tls_hash_sha1, tls_sig_dsa, +- }; + PRInt32 extension_length; ++ unsigned int i; ++ PRInt32 pos=0; ++ PRUint32 policy; ++ PRUint8 buf[MAX_SIGNATURE_ALGORITHMS * 2]; + + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { + return 0; + } + ++ for (i=0; i < ss->ssl3.signatureAlgorithmCount; i++) { ++ SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID( ++ ss->ssl3.signatureAlgorithms[i].hashAlg); ++ if ((NSS_GetAlgorithmPolicy(hashOID, & policy) != SECSuccess) || ++ (policy & NSS_USE_ALG_IN_SSL_KX)) { ++ buf[pos++] = ss->ssl3.signatureAlgorithms[i].hashAlg; ++ buf[pos++] = ss->ssl3.signatureAlgorithms[i].sigAlg; ++ } ++ } ++ + extension_length = + 2 /* extension type */ + + 2 /* extension length */ + + 2 /* supported_signature_algorithms length */ + +- sizeof(signatureAlgorithms); ++ pos; ++ ++ if (maxBytes < extension_length) { ++ PORT_Assert(0); ++ return 0; ++ } + +- if (append && maxBytes >= extension_length) { ++ if (append) { + SECStatus rv; + rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); +- if (rv != SECSuccess) +- goto loser; ++ if (rv != SECSuccess) { ++ return -1; ++ } + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); +- if (rv != SECSuccess) +- goto loser; +- rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms, +- sizeof(signatureAlgorithms), 2); +- if (rv != SECSuccess) +- goto loser; ++ if (rv != SECSuccess) { ++ return -1; ++ } ++ ++ rv = ssl3_AppendHandshakeVariable(ss, buf, extension_length - 6, 2); ++ if (rv != SECSuccess) { ++ return -1; ++ } ++ + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_signature_algorithms_xtn; +- } else if (maxBytes < extension_length) { +- PORT_Assert(0); +- return 0; + } + + return extension_length; +- +-loser: +- return -1; + } + + unsigned int +@@ -2565,7 +2604,11 @@ + } + + extension_length = 6; /* Type + length + number */ +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < (PRUint32)extension_length) { ++ PORT_Assert(0); ++ return 0; ++ } ++ if (append) { + SECStatus rv; + rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_draft_version_xtn, 2); + if (rv != SECSuccess) +@@ -2578,9 +2621,6 @@ + goto loser; + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_tls13_draft_version_xtn; +- } else if (maxBytes < extension_length) { +- PORT_Assert(0); +- return 0; + } + + return extension_length; +@@ -2633,6 +2673,51 @@ + return SECSuccess; + } + ++static PRInt32 ++ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append, ++ PRUint32 maxBytes) ++{ ++ PRInt32 extension_length; ++ ++ if (!ss->opt.enableExtendedMS) { ++ return 0; ++ } ++ ++#ifndef NO_PKCS11_BYPASS ++ /* Extended MS can only be used w/o bypass mode */ ++ if (ss->opt.bypassPKCS11) { ++ PORT_Assert(0); ++ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); ++ return -1; ++ } ++#endif ++ ++ /* Always send the extension in this function, since the ++ * client always sends it and this function is only called on ++ * the server if we negotiated the extension. */ ++ extension_length = 4; /* Type + length (0) */ ++ if (maxBytes < extension_length) { ++ PORT_Assert(0); ++ return 0; ++ } ++ ++ if (append) { ++ SECStatus rv; ++ rv = ssl3_AppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2); ++ if (rv != SECSuccess) ++ goto loser; ++ rv = ssl3_AppendHandshakeNumber(ss, 0, 2); ++ if (rv != SECSuccess) ++ goto loser; ++ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = ++ ssl_extended_master_secret_xtn; ++ } ++ ++ return extension_length; ++loser: ++ return -1; ++} ++ + /* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp + * extension for TLS ClientHellos. */ + static PRInt32 +@@ -2646,7 +2731,12 @@ + if (!ss->opt.enableSignedCertTimestamps) + return 0; + +- if (append && maxBytes >= extension_length) { ++ if (maxBytes < extension_length) { ++ PORT_Assert(0); ++ return 0; ++ } ++ ++ if (append) { + SECStatus rv; + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, +@@ -2660,9 +2750,6 @@ + goto loser; + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_signed_certificate_timestamp_xtn; +- } else if (maxBytes < extension_length) { +- PORT_Assert(0); +- return 0; + } + + return extension_length; +@@ -2671,6 +2758,46 @@ + } + + static SECStatus ++ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) { ++ return SECSuccess; ++ } ++ ++ if (!ss->opt.enableExtendedMS) { ++ return SECSuccess; ++ } ++ ++#ifndef NO_PKCS11_BYPASS ++ /* Extended MS can only be used w/o bypass mode */ ++ if (ss->opt.bypassPKCS11) { ++ PORT_Assert(0); ++ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); ++ return SECFailure; ++ } ++#endif ++ ++ if (data->len != 0) { ++ SSL_TRC(30, ("%d: SSL3[%d]: Bogus extended master secret extension", ++ SSL_GETPID(), ss->fd)); ++ return SECFailure; ++ } ++ ++ SSL_DBG(("%d: SSL[%d]: Negotiated extended master secret extension.", ++ SSL_GETPID(), ss->fd)); ++ ++ /* Keep track of negotiated extensions. */ ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ ++ if (ss->sec.isServer) { ++ return ssl3_RegisterServerHelloExtensionSender( ++ ss, ex_type, ssl3_SendExtendedMasterSecretXtn); ++ } ++ return SECSuccess; ++} ++ ++static SECStatus + ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) + { +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3gthr.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3gthr.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3gthr.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3gthr.c 2016-01-13 14:18:55.623954879 +0100 +@@ -71,8 +71,8 @@ + break; + } + +- PORT_Assert( nb <= gs->remainder ); +- if (nb > gs->remainder) { ++ PORT_Assert( (unsigned int)nb <= gs->remainder ); ++ if ((unsigned int)nb > gs->remainder) { + /* ssl_DefRecv is misbehaving! this error is fatal to SSL. */ + gs->state = GS_INIT; /* so we don't crash next time */ + rv = SECFailure; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3prot.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3prot.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3prot.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl3prot.h 2016-01-13 14:18:55.623954879 +0100 +@@ -218,32 +218,6 @@ + } u; + } SSL3ServerParams; + +-/* This enum reflects HashAlgorithm enum from +- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 +- * +- * When updating, be sure to also update ssl3_TLSHashAlgorithmToOID. */ +-enum { +- tls_hash_md5 = 1, +- tls_hash_sha1 = 2, +- tls_hash_sha224 = 3, +- tls_hash_sha256 = 4, +- tls_hash_sha384 = 5, +- tls_hash_sha512 = 6 +-}; +- +-/* This enum reflects SignatureAlgorithm enum from +- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ +-typedef enum { +- tls_sig_rsa = 1, +- tls_sig_dsa = 2, +- tls_sig_ecdsa = 3 +-} TLSSignatureAlgorithm; +- +-typedef struct { +- SECOidTag hashAlg; +- TLSSignatureAlgorithm sigAlg; +-} SSL3SignatureAndHashAlgorithm; +- + /* SSL3HashesIndividually contains a combination MD5/SHA1 hash, as used in TLS + * prior to 1.2. */ + typedef struct { +@@ -252,11 +226,11 @@ + } SSL3HashesIndividually; + + /* SSL3Hashes contains an SSL hash value. The digest is contained in |u.raw| +- * which, if |hashAlg==SEC_OID_UNKNOWN| is also a SSL3HashesIndividually ++ * which, if |hashAlg==ssl_hash_none| is also a SSL3HashesIndividually + * struct. */ + typedef struct { + unsigned int len; +- SECOidTag hashAlg; ++ SSLHashType hashAlg; + union { + PRUint8 raw[64]; + SSL3HashesIndividually s; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslauth.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslauth.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslauth.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslauth.c 2016-01-13 14:18:55.624954885 +0100 +@@ -304,8 +304,7 @@ + &certStatusArray->items[0], + ss->pkcs11PinArg) + != SECSuccess) { +- PRErrorCode error = PR_GetError(); +- PORT_Assert(error != 0); ++ PORT_Assert(PR_GetError() != 0); + } + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslcon.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslcon.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslcon.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslcon.c 2016-01-13 14:18:55.625954891 +0100 +@@ -22,20 +22,6 @@ + + static PRBool policyWasSet; + +-/* This ordered list is indexed by (SSL_CK_xx * 3) */ +-/* Second and third bytes are MSB and LSB of master key length. */ +-static const PRUint8 allCipherSuites[] = { +- 0, 0, 0, +- SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80, +- SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80, +- SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80, +- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80, +- SSL_CK_IDEA_128_CBC_WITH_MD5, 0x00, 0x80, +- SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40, +- SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0, +- 0, 0, 0 +-}; +- + #define ssl2_NUM_SUITES_IMPLEMENTED 6 + + /* This list is sent back to the client when the client-hello message +@@ -851,7 +837,7 @@ + { + PRUint8 * out; + int rv; +- int amount; ++ unsigned int amount; + int count = 0; + + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); +@@ -927,7 +913,7 @@ + int amount; + PRUint8 macLen; + int nout; +- int buflen; ++ unsigned int buflen; + + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); + +@@ -1031,7 +1017,7 @@ + int amount; /* of plaintext to go in record. */ + unsigned int padding; /* add this many padding byte. */ + int nout; /* ciphertext size after header. */ +- int buflen; /* size of generated record. */ ++ unsigned int buflen; /* size of generated record. */ + + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); + +@@ -1555,7 +1541,7 @@ + unsigned int ddLen; /* length of RSA decrypted data in kbuf */ + unsigned int keySize; + unsigned int dkLen; /* decrypted key length in bytes */ +- int modulusLen; ++ int modulusLen; + SECStatus rv; + PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ + PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; +@@ -1617,11 +1603,11 @@ + } + + modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); +- if (modulusLen == -1) { ++ if (modulusLen < 0) { + /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */ + modulusLen = ekLen; + } +- if (ekLen > modulusLen || ekLen + ckLen < keySize) { ++ if (ekLen > (unsigned int)modulusLen || ekLen + ckLen < keySize) { + SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", + SSL_GETPID(), ss->fd, ekLen)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); +@@ -2495,7 +2481,6 @@ + PRUint8 * cid; + unsigned len, certType, certLen, responseLen; + int rv; +- int rv2; + + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); + +@@ -2613,7 +2598,7 @@ + data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen, + responseLen); + if (rv) { +- rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); ++ (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); + SET_ERROR_CODE + goto loser; + } +@@ -2741,7 +2726,7 @@ + PRUint8 * cs; + PRUint8 * data; + SECStatus rv; +- int needed, sidHit, certLen, csLen, cidLen, certType, err; ++ unsigned int needed, sidHit, certLen, csLen, cidLen, certType, err; + + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); + +@@ -3669,12 +3654,14 @@ + */ + + #include "nss.h" +-extern const char __nss_ssl_rcsid[]; +-extern const char __nss_ssl_sccsid[]; ++extern const char __nss_ssl_version[]; + + PRBool + NSSSSL_VersionCheck(const char *importedVersion) + { ++#define NSS_VERSION_VARIABLE __nss_ssl_version ++#include "verref.h" ++ + /* + * This is the secret handshake algorithm. + * +@@ -3684,9 +3671,6 @@ + * not compatible with future major, minor, or + * patch releases. + */ +- volatile char c; /* force a reference that won't get optimized away */ +- +- c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; + return NSS_VersionCheck(importedVersion); + } + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslenum.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslenum.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslenum.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslenum.c 2016-01-13 14:18:55.625954891 +0100 +@@ -70,14 +70,17 @@ + #endif /* NSS_DISABLE_ECC */ + + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, ++ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, ++ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, ++ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslerr.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslerr.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslerr.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslerr.h 2016-01-13 14:18:55.626954897 +0100 +@@ -198,9 +198,19 @@ + + SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131), + +-SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 132), +-SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 133), +-SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 134), ++SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132), ++ ++SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133), ++ ++SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134), ++SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135), ++ ++SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136), ++SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137), ++ ++SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 138), ++SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 139), ++SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 140), + + SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ + } SSLErrorCodes; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/SSLerrs.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/SSLerrs.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/SSLerrs.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/SSLerrs.h 2016-01-13 14:18:55.613954821 +0100 +@@ -423,11 +423,29 @@ + "The server rejected the handshake because the client downgraded to a lower " + "TLS version than the server supports.") + +-ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 132), ++ER3(SSL_ERROR_WEAK_SERVER_CERT_KEY, (SSL_ERROR_BASE + 132), ++"The server certificate included a public key that was too weak.") ++ ++ER3(SSL_ERROR_RX_SHORT_DTLS_READ, (SSL_ERROR_BASE + 133), ++"Not enough room in buffer for DTLS record.") ++ ++ER3(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 134), ++"No supported TLS signature algorithm was configured.") ++ ++ER3(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 135), ++"The peer used an unsupported combination of signature and hash algorithm.") ++ ++ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136), ++"The peer tried to resume without a correct extended_master_secret extension") ++ ++ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137), ++"The peer tried to resume with an unexpected extended_master_secret extension") ++ ++ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 138), + "SSL received a malformed TLS Channel ID extension.") + +-ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 133), ++ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 139), + "The application provided an invalid TLS Channel ID key.") + +-ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 134), ++ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 140), + "The application could not get a TLS Channel ID.") +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/ssl.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/ssl.h 2016-01-13 14:18:55.614954827 +0100 +@@ -185,14 +185,26 @@ + /* SSL_REUSE_SERVER_ECDHE_KEY controls whether the ECDHE server key is + * reused for multiple handshakes or generated each time. + * SSL_REUSE_SERVER_ECDHE_KEY is currently enabled by default. ++ * This socket option is for ECDHE, only. It is unrelated to DHE. + */ + #define SSL_REUSE_SERVER_ECDHE_KEY 27 + + #define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in + * handshakes. */ + ++/* SSL_ENABLE_SERVER_DHE controls whether DHE is enabled for the server socket. ++ */ ++#define SSL_ENABLE_SERVER_DHE 29 ++ ++/* Use draft-ietf-tls-session-hash. Controls whether we offer the ++ * extended_master_secret extension which, when accepted, hashes ++ * the handshake transcript into the master secret. This option is ++ * disabled by default. ++ */ ++#define SSL_ENABLE_EXTENDED_MASTER_SECRET 30 ++ + /* Request Signed Certificate Timestamps via TLS extension (client) */ +-#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 29 ++#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 31 + + #ifdef SSL_DEPRECATED_FUNCTION + /* Old deprecated function names */ +@@ -295,6 +307,86 @@ + SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy); + SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy); + ++/* ++** Control for TLS signature algorithms for TLS 1.2 only. ++** ++** This governs what signature algorithms are sent by a client in the ++** signature_algorithms extension. A client will not accept a signature from a ++** server unless it uses an enabled algorithm. ++** ++** This also governs what the server sends in the supported_signature_algorithms ++** field of a CertificateRequest. It also changes what the server uses to sign ++** ServerKeyExchange: a server uses the first entry from this list that is ++** compatible with the client's advertised signature_algorithms extension and ++** the selected server certificate. ++** ++** Omitting SHA-256 from this list might be foolish. Support is mandatory in ++** TLS 1.2 and there might be interoperability issues. For a server, NSS only ++** supports SHA-256 for verifying a TLS 1.2 CertificateVerify. This list needs ++** to include SHA-256 if client authentication is requested or required, or ++** creating a CertificateRequest will fail. ++*/ ++SSL_IMPORT SECStatus SSL_SignaturePrefSet( ++ PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms, ++ unsigned int count); ++ ++/* ++** Get the currently configured signature algorithms. ++** ++** The algorithms are written to |algorithms| but not if there are more than ++** |maxCount| values configured. The number of algorithms that are in use are ++** written to |count|. This fails if |maxCount| is insufficiently large. ++*/ ++SSL_IMPORT SECStatus SSL_SignaturePrefGet( ++ PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms, unsigned int *count, ++ unsigned int maxCount); ++ ++/* ++** Returns the maximum number of signature algorithms that are supported and ++** can be set or retrieved using SSL_SignaturePrefSet or SSL_SignaturePrefGet. ++*/ ++SSL_IMPORT unsigned int SSL_SignatureMaxCount(); ++ ++/* SSL_DHEGroupPrefSet is used to configure the set of allowed/enabled DHE group ++** parameters that can be used by NSS for the given server socket. ++** The first item in the array is used as the default group, if no other ++** selection criteria can be used by NSS. ++** The set is provided as an array of identifiers as defined by SSLDHEGroupType. ++** If more than one group identifier is provided, NSS will select the one to use. ++** For example, a TLS extension sent by the client might indicate a preference. ++*/ ++SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd, ++ SSLDHEGroupType *groups, ++ PRUint16 num_groups); ++ ++/* Enable the use of a DHE group that's smaller than the library default, ++** for backwards compatibility reasons. The DH parameters will be created ++** at the time this function is called, which might take a very long time. ++** The function will block until generation is completed. ++** The intention is to enforce that fresh and safe parameters are generated ++** each time a process is started. ++** At the time this API was initially implemented, the API will enable the ++** use of 1024 bit DHE parameters. This value might get increased in future ++** versions of NSS. ++** ++** It is allowed to call this API will a NULL value for parameter fd, ++** which will prepare the global parameters that NSS will reuse for the remainder ++** of the process lifetime. This can be used early after startup of a process, ++** to avoid a delay when handling incoming client connections. ++** This preparation with a NULL for parameter fd will NOT enable the weak group ++** on sockets. The function needs to be called again for every socket that ++** should use the weak group. ++** ++** It is allowed to use this API in combination with the SSL_DHEGroupPrefSet API. ++** If both APIs have been called, the weakest group will be used, ++** unless it is certain that the client supports larger group parameters. ++** The weak group will be used as the default group, overriding the preference ++** for the first group potentially set with a call to SSL_DHEGroupPrefSet ++** (The first group set using SSL_DHEGroupPrefSet will still be enabled, but ++** it's no longer the default group.) ++*/ ++SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled); ++ + /* SSL_CipherOrderSet sets the cipher suite preference order from |ciphers|, + * which must be an array of cipher suite ids of length |len|. All the given + * cipher suite ids must appear in the array that is returned by +@@ -1012,10 +1104,27 @@ + SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void); + + /* Report more information than SSL_SecurityStatus. +-** Caller supplies the info struct. Function fills it in. +-*/ ++ * Caller supplies the info struct. This function fills it in. ++ * The information here will be zeroed prior to details being confirmed. The ++ * details are confirmed either when a Finished message is received, or - for a ++ * client - when the second flight of messages have been sent. This function ++ * therefore produces unreliable results prior to receiving the ++ * SSLHandshakeCallback or the SSLCanFalseStartCallback. ++ */ + SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, + PRUintn len); ++/* Get preliminary information about a channel. ++ * This function can be called prior to handshake details being confirmed (see ++ * SSL_GetChannelInfo above for what that means). Thus, information provided by ++ * this function is available to SSLAuthCertificate, SSLGetClientAuthData, ++ * SSLSNISocketConfig, and other callbacks that might be called during the ++ * processing of the first flight of client of server handshake messages. ++ * Values are marked as being unavailable when renegotiation is initiated. ++ */ ++SSL_IMPORT SECStatus ++SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, ++ SSLPreliminaryChannelInfo *info, ++ PRUintn len); + SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, + SSLCipherSuiteInfo *info, PRUintn len); + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslimpl.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslimpl.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslimpl.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslimpl.h 2016-01-13 14:18:55.627954902 +0100 +@@ -1,3 +1,4 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /* + * This file is PRIVATE to SSL and should be the first thing included by + * any SSL implementation file. +@@ -181,6 +182,7 @@ + typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef; + typedef struct ssl3MACDefStr ssl3MACDef; + typedef struct ssl3KeyPairStr ssl3KeyPair; ++typedef struct ssl3DHParamsStr ssl3DHParams; + + struct ssl3CertNodeStr { + struct ssl3CertNodeStr *next; +@@ -300,13 +302,19 @@ + } ssl3CipherSuiteCfg; + + #ifndef NSS_DISABLE_ECC +-#define ssl_V3_SUITES_IMPLEMENTED 63 ++#define ssl_V3_SUITES_IMPLEMENTED 66 + #else +-#define ssl_V3_SUITES_IMPLEMENTED 37 ++#define ssl_V3_SUITES_IMPLEMENTED 40 + #endif /* NSS_DISABLE_ECC */ + + #define MAX_DTLS_SRTP_CIPHER_SUITES 4 + ++/* MAX_SIGNATURE_ALGORITHMS allows for a large number of combinations of ++ * SSLSignType and SSLHashType, but not all combinations (specifically, this ++ * doesn't allow space for combinations with MD5). */ ++#define MAX_SIGNATURE_ALGORITHMS 15 ++ ++ + typedef struct sslOptionsStr { + /* If SSL_SetNextProtoNego has been called, then this contains the + * list of supported protocols. */ +@@ -339,7 +347,9 @@ + unsigned int enableALPN : 1; /* 27 */ + unsigned int reuseServerECDHEKey : 1; /* 28 */ + unsigned int enableFallbackSCSV : 1; /* 29 */ +- unsigned int enableSignedCertTimestamps : 1; /* 30 */ ++ unsigned int enableServerDhe : 1; /* 30 */ ++ unsigned int enableExtendedMS : 1; /* 31 */ ++ unsigned int enableSignedCertTimestamps : 1; /* 32 */ + } sslOptions; + + typedef enum { sslHandshakingUndetermined = 0, +@@ -521,6 +531,7 @@ + PRUint16 wrapped_master_secret_len; + PRUint8 msIsWrapped; + PRUint8 resumable; ++ PRUint8 extendedMasterSecretUsed; + } ssl3SidKeys; /* 52 bytes */ + + typedef struct { +@@ -766,10 +777,10 @@ + * is_limited identifies a suite as having a limit on the key size. + * key_size_limit provides the corresponding limit. */ + PRBool is_limited; +- int key_size_limit; ++ unsigned int key_size_limit; + PRBool tls_keygen; +- /* True if the key exchange for the suite can be ephemeral. Or to be more +- * precise: true if the ServerKeyExchange message is required. */ ++ /* True if the key exchange for the suite is ephemeral. Or to be more ++ * precise: true if the ServerKeyExchange message is always required. */ + PRBool ephemeral; + } ssl3KEADef; + +@@ -955,12 +966,14 @@ + PRBool cacheSID; + + PRBool canFalseStart; /* Can/did we False Start */ ++ /* Which preliminaryinfo values have been set. */ ++ PRUint32 preliminaryInfo; + + /* clientSigAndHash contains the contents of the signature_algorithms + * extension (if any) from the client. This is only valid for TLS 1.2 + * or later. */ +- SSL3SignatureAndHashAlgorithm *clientSigAndHash; +- unsigned int numClientSigAndHash; ++ SSLSignatureAndHashAlg *clientSigAndHash; ++ unsigned int numClientSigAndHash; + + /* This group of values is used for DTLS */ + PRUint16 sendMessageSeq; /* The sending message sequence +@@ -1044,9 +1057,17 @@ + PRUint16 dtlsSRTPCipherCount; + PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */ + PRBool fatalAlertSent; ++ PRUint16 numDHEGroups; /* used by server */ ++ SSLDHEGroupType * dheGroups; /* used by server */ ++ PRBool dheWeakGroupEnabled; /* used by server */ ++ ++ /* TLS 1.2 introduces separate signature algorithm negotiation. ++ * This is our preference order. */ ++ SSLSignatureAndHashAlg signatureAlgorithms[MAX_SIGNATURE_ALGORITHMS]; ++ unsigned int signatureAlgorithmCount; + }; + +-#define DTLS_MAX_MTU 1500 /* Ethernet MTU but without subtracting the ++#define DTLS_MAX_MTU 1500U /* Ethernet MTU but without subtracting the + * headers, so slightly larger than expected */ + #define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram) + +@@ -1063,6 +1084,11 @@ + PRInt32 refCount; /* use PR_Atomic calls for this. */ + }; + ++struct ssl3DHParamsStr { ++ SECItem prime; /* p */ ++ SECItem base; /* g */ ++}; ++ + typedef struct SSLWrappedSymWrappingKeyStr { + SSL3Opaque wrappedSymmetricWrappingkey[512]; + CK_MECHANISM_TYPE symWrapMechanism; +@@ -1093,6 +1119,7 @@ + CK_MECHANISM_TYPE msWrapMech; + PRUint16 ms_length; + SSL3Opaque master_secret[48]; ++ PRBool extendedMasterSecretUsed; + ClientIdentity client_identity; + SECItem peer_cert; + PRUint32 timestamp; +@@ -1275,6 +1302,9 @@ + + ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */ + ++ const ssl3DHParams *dheParams; /* DHE param */ ++ ssl3KeyPair * dheKeyPair; /* DHE keys */ ++ + /* Callbacks */ + SSLAuthCertificate authCertificate; + void *authCertificateArg; +@@ -1634,7 +1664,7 @@ + extern SECStatus ssl3_KeyAndMacDeriveBypass(ssl3CipherSpec * pwSpec, + const unsigned char * cr, const unsigned char * sr, + PRBool isTLS, PRBool isExport); +-extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, ++extern SECStatus ssl3_MasterSecretDeriveBypass( ssl3CipherSpec * pwSpec, + const unsigned char * cr, const unsigned char * sr, + const SECItem * pms, PRBool isTLS, PRBool isRSA); + +@@ -1688,6 +1718,8 @@ + */ + extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss); + ++extern SECStatus ssl3_SelectDHParams(sslSocket *ss); ++ + #ifndef NSS_DISABLE_ECC + extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss); + extern PRBool ssl3_IsECCEnabled(sslSocket *ss); +@@ -1790,11 +1822,11 @@ + SSL3Opaque *b, PRUint32 length, + SECKEYPublicKey *srvrPubKey, + SECKEYPrivateKey *srvrPrivKey); +-extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss, +- const SSL3SignatureAndHashAlgorithm *sigAndHash); ++extern SECStatus ssl3_SendECDHServerKeyExchange( ++ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash); + #endif + +-extern SECStatus ssl3_ComputeCommonKeyHash(SECOidTag hashAlg, ++extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg, + PRUint8 * hashBuf, + unsigned int bufLen, SSL3Hashes *hashes, + PRBool bypassPKCS11); +@@ -1808,21 +1840,22 @@ + PRInt32 lenSize); + extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss, + const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize); +-extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(sslSocket *ss, +- const SSL3SignatureAndHashAlgorithm* sigAndHash); ++extern SECStatus ssl3_AppendSignatureAndHashAlgorithm( ++ sslSocket *ss, const SSLSignatureAndHashAlg* sigAndHash); + extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length); + extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length); + extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, + PRInt32 bytes, SSL3Opaque **b, PRUint32 *length); +-extern SECOidTag ssl3_TLSHashAlgorithmToOID(int hashFunc); ++extern PRBool ssl3_IsSupportedSignatureAlgorithm( ++ const SSLSignatureAndHashAlg *alg); + extern SECStatus ssl3_CheckSignatureAndHashAlgorithmConsistency( +- const SSL3SignatureAndHashAlgorithm *sigAndHash, +- CERTCertificate* cert); +-extern SECStatus ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss, +- SSL3Opaque **b, PRUint32 *length, +- SSL3SignatureAndHashAlgorithm *out); ++ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash, ++ CERTCertificate* cert); ++extern SECStatus ssl3_ConsumeSignatureAndHashAlgorithm( ++ sslSocket *ss, SSL3Opaque **b, PRUint32 *length, ++ SSLSignatureAndHashAlg *out); + extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, + SECItem *buf, PRBool isTLS); + extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash, +@@ -1890,7 +1923,7 @@ + + /* Tell clients to consider tickets valid for this long. */ + #define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */ +-#define TLS_EX_SESS_TICKET_VERSION (0x0100) ++#define TLS_EX_SESS_TICKET_VERSION (0x0101) + + extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, + unsigned int length); +@@ -2024,6 +2057,8 @@ + const char *label, unsigned int labelLen, + const unsigned char *val, unsigned int valLen, + unsigned char *out, unsigned int outLen); ++extern SECOidTag ++ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc); + + #ifdef TRACE + #define SSL_TRACE(msg) ssl_Trace msg +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslinfo.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslinfo.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslinfo.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslinfo.c 2016-01-13 14:18:55.628954908 +0100 +@@ -67,6 +67,8 @@ + inf.creationTime = sid->creationTime; + inf.lastAccessTime = sid->lastAccessTime; + inf.expirationTime = sid->expirationTime; ++ inf.extendedMasterSecretUsed = sid->u.ssl3.keys.extendedMasterSecretUsed; ++ + if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */ + inf.sessionIDLength = SSL2_SESSIONID_BYTES; + memcpy(inf.sessionID, sid->u.ssl2.sessionID, +@@ -85,6 +87,42 @@ + return SECSuccess; + } + ++SECStatus ++SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, ++ SSLPreliminaryChannelInfo *info, ++ PRUintn len) ++{ ++ sslSocket *ss; ++ SSLPreliminaryChannelInfo inf; ++ ++ if (!info || len < sizeof inf.length) { ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ ss = ssl_FindSocket(fd); ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPreliminaryChannelInfo", ++ SSL_GETPID(), fd)); ++ return SECFailure; ++ } ++ ++ if (ss->version < SSL_LIBRARY_VERSION_3_0) { ++ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION); ++ return SECFailure; ++ } ++ ++ memset(&inf, 0, sizeof(inf)); ++ inf.length = PR_MIN(sizeof(inf), len); ++ ++ inf.valuesSet = ss->ssl3.hs.preliminaryInfo; ++ inf.protocolVersion = ss->version; ++ inf.cipherSuite = ss->ssl3.hs.cipher_suite; ++ ++ memcpy(info, &inf, inf.length); ++ return SECSuccess; ++} ++ + + #define CS(x) x, #x + #define CK(x) x | 0xff00, #x +@@ -136,6 +174,7 @@ + {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, }, + {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, }, + {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, }, ++{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, }, + {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, }, + {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 0, 0, }, + {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, }, +@@ -146,7 +185,9 @@ + {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, }, + {0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, }, + {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, }, ++{0,CS(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, }, + {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, }, ++{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, }, + {0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, }, + {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, }, + {0,CS(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, }, +@@ -247,12 +288,10 @@ + { + const SSLCipherSuiteInfo * pInfo = suiteInfo; + unsigned int i; +- SECStatus rv; + + for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) { + if (pInfo->isExportable) { +- rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE); +- PORT_Assert(rv == SECSuccess); ++ PORT_CheckSuccess(SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE)); + } + } + return SECSuccess; +@@ -268,12 +307,10 @@ + { + const SSLCipherSuiteInfo * pInfo = suiteInfo; + unsigned int i; +- SECStatus rv; + + for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) { + if (pInfo->isExportable) { +- rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE); +- PORT_Assert(rv == SECSuccess); ++ PORT_CheckSuccess(SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE)); + } + } + return SECSuccess; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.c 2016-01-13 14:18:55.628954908 +0100 +@@ -504,7 +504,7 @@ + return SECSuccess; + } + +-#elif defined(XP_UNIX) ++#elif defined(XP_UNIX) && !defined(DARWIN) + + #include + #include "unix_err.h" +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslmutex.h 2016-01-13 14:18:55.628954908 +0100 +@@ -67,7 +67,8 @@ + } sslMutex; + typedef pid_t sslPID; + +-#elif defined(XP_UNIX) /* other types of Unix */ ++/* other types of unix, except OS X */ ++#elif defined(XP_UNIX) && !defined(DARWIN) + + #include /* for pid_t */ + #include /* for sem_t, and sem_* functions */ +@@ -83,7 +84,7 @@ + + typedef pid_t sslPID; + +-#else ++#else /* no support for cross-process locking */ + + /* what platform is this ?? */ + +@@ -95,7 +96,11 @@ + } u; + } sslMutex; + ++#ifdef DARWIN ++typedef pid_t sslPID; ++#else + typedef int sslPID; ++#endif + + #endif + +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslproto.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslproto.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslproto.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslproto.h 2016-01-13 14:18:55.629954914 +0100 +@@ -177,6 +177,7 @@ + #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C + #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D + ++#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040 + #define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0041 + #define TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0042 + #define TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0043 +@@ -191,6 +192,7 @@ + #define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065 + #define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066 + #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 ++#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A + #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B + + #define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0084 +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslsecur.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslsecur.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslsecur.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslsecur.c 2016-01-13 14:18:55.629954914 +0100 +@@ -138,6 +138,9 @@ + ss->gs.readOffset = 0; + + if (ss->handshakeCallback) { ++ PORT_Assert(ss->version < SSL_LIBRARY_VERSION_3_0 || ++ (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == ++ ssl_preinfo_all); + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); + } + } +@@ -654,6 +657,16 @@ + SSL_GETPID(), ss->fd, available)); + } + ++ if (IS_DTLS(ss) && (len < available)) { ++ /* DTLS does not allow you to do partial reads */ ++ SSL_TRC(30, ("%d: SSL[%d]: DTLS short read. len=%d available=%d", ++ SSL_GETPID(), ss->fd, len, available)); ++ ss->gs.readOffset += available; ++ PORT_SetError(SSL_ERROR_RX_SHORT_DTLS_READ); ++ rv = SECFailure; ++ goto done; ++ } ++ + /* Dole out clear data to reader */ + amount = PR_MIN(len, available); + PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); +@@ -693,6 +706,7 @@ + case SEC_OID_PKCS1_RSA_ENCRYPTION: + keaType = kt_rsa; + break; ++ case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */ + case SEC_OID_X942_DIFFIE_HELMAN_KEY: + keaType = kt_dh; + break; +@@ -789,6 +803,11 @@ + goto loser; + } + } ++ if (kea == ssl_kea_dh || kea == ssl_kea_rsa) { ++ if (ssl3_SelectDHParams(ss) != SECSuccess) { ++ goto loser; ++ } ++ } + return SECSuccess; + + loser: +@@ -1177,11 +1196,8 @@ + int + ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) + { +- sslSecurityInfo *sec; + int rv = 0; + +- sec = &ss->sec; +- + if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { + PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); + return PR_FAILURE; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslsnce.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslsnce.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslsnce.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslsnce.c 2016-01-13 14:18:55.631954926 +0100 +@@ -120,14 +120,14 @@ + /* 2 */ ssl3CipherSuite cipherSuite; + /* 2 */ PRUint16 compression; /* SSLCompressionMethod */ + +-/* 52 */ ssl3SidKeys keys; /* keys, wrapped as needed. */ ++/* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */ + + /* 4 */ PRUint32 masterWrapMech; + /* 4 */ SSL3KEAType exchKeyType; + /* 4 */ PRInt32 certIndex; + /* 4 */ PRInt32 srvNameIndex; + /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */ +-/*104 */} ssl3; ++/*108 */} ssl3; + /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ + struct { + /*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */ +@@ -507,7 +507,6 @@ + to->sessionIDLength = from->u.ssl3.sessionIDLength; + to->u.ssl3.certIndex = -1; + to->u.ssl3.srvNameIndex = -1; +- + PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID, + to->sessionIDLength); + +@@ -637,7 +636,7 @@ + to->authKeyBits = from->authKeyBits; + to->keaType = from->keaType; + to->keaKeyBits = from->keaKeyBits; +- ++ + return to; + + loser: +@@ -1228,20 +1227,32 @@ + /* Fix pointers in our private copy of cache descriptor to point to + ** spaces in shared memory + */ +- ptr = (ptrdiff_t)cache->cacheMem; +- *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr; +- *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr; +- *(ptrdiff_t *)(&cache->certCacheLock) += ptr; +- *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr; +- *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr; +- *(ptrdiff_t *)(&cache->sidCacheData ) += ptr; +- *(ptrdiff_t *)(&cache->certCacheData) += ptr; +- *(ptrdiff_t *)(&cache->keyCacheData ) += ptr; +- *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr; +- *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr; +- *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr; +- *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr; +- *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr; ++ cache->sidCacheLocks = (sidCacheLock *) ++ (cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks); ++ cache->keyCacheLock = (sidCacheLock *) ++ (cache->cacheMem + (ptrdiff_t)cache->keyCacheLock); ++ cache->certCacheLock = (sidCacheLock *) ++ (cache->cacheMem + (ptrdiff_t)cache->certCacheLock); ++ cache->srvNameCacheLock = (sidCacheLock *) ++ (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock); ++ cache->sidCacheSets = (sidCacheSet *) ++ (cache->cacheMem + (ptrdiff_t)cache->sidCacheSets); ++ cache->sidCacheData = (sidCacheEntry *) ++ (cache->cacheMem + (ptrdiff_t)cache->sidCacheData); ++ cache->certCacheData = (certCacheEntry *) ++ (cache->cacheMem + (ptrdiff_t)cache->certCacheData); ++ cache->keyCacheData = (SSLWrappedSymWrappingKey *) ++ (cache->cacheMem + (ptrdiff_t)cache->keyCacheData); ++ cache->ticketKeyNameSuffix = (PRUint8 *) ++ (cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix); ++ cache->ticketEncKey = (encKeyCacheEntry *) ++ (cache->cacheMem + (ptrdiff_t)cache->ticketEncKey); ++ cache->ticketMacKey = (encKeyCacheEntry *) ++ (cache->cacheMem + (ptrdiff_t)cache->ticketMacKey); ++ cache->ticketKeysValid = (PRUint32 *) ++ (cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid); ++ cache->srvNameCacheData = (srvNameCacheEntry *) ++ (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData); + + /* initialize the locks */ + init_time = ssl_Time(); +@@ -1484,7 +1495,6 @@ + char * fmString = NULL; + char * myEnvString = NULL; + unsigned int decoLen; +- ptrdiff_t ptr; + inheritance inherit; + cacheDesc my; + #ifdef WINNT +@@ -1580,20 +1590,32 @@ + /* Fix pointers in our private copy of cache descriptor to point to + ** spaces in shared memory, whose address is now in "my". + */ +- ptr = (ptrdiff_t)my.cacheMem; +- *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr; +- *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr; +- *(ptrdiff_t *)(&cache->certCacheLock) += ptr; +- *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr; +- *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr; +- *(ptrdiff_t *)(&cache->sidCacheData ) += ptr; +- *(ptrdiff_t *)(&cache->certCacheData) += ptr; +- *(ptrdiff_t *)(&cache->keyCacheData ) += ptr; +- *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr; +- *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr; +- *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr; +- *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr; +- *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr; ++ cache->sidCacheLocks = (sidCacheLock *) ++ (my.cacheMem + (ptrdiff_t)cache->sidCacheLocks); ++ cache->keyCacheLock = (sidCacheLock *) ++ (my.cacheMem + (ptrdiff_t)cache->keyCacheLock); ++ cache->certCacheLock = (sidCacheLock *) ++ (my.cacheMem + (ptrdiff_t)cache->certCacheLock); ++ cache->srvNameCacheLock = (sidCacheLock *) ++ (my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock); ++ cache->sidCacheSets = (sidCacheSet *) ++ (my.cacheMem + (ptrdiff_t)cache->sidCacheSets); ++ cache->sidCacheData = (sidCacheEntry *) ++ (my.cacheMem + (ptrdiff_t)cache->sidCacheData); ++ cache->certCacheData = (certCacheEntry *) ++ (my.cacheMem + (ptrdiff_t)cache->certCacheData); ++ cache->keyCacheData = (SSLWrappedSymWrappingKey *) ++ (my.cacheMem + (ptrdiff_t)cache->keyCacheData); ++ cache->ticketKeyNameSuffix = (PRUint8 *) ++ (my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix); ++ cache->ticketEncKey = (encKeyCacheEntry *) ++ (my.cacheMem + (ptrdiff_t)cache->ticketEncKey); ++ cache->ticketMacKey = (encKeyCacheEntry *) ++ (my.cacheMem + (ptrdiff_t)cache->ticketMacKey); ++ cache->ticketKeysValid = (PRUint32 *) ++ (my.cacheMem + (ptrdiff_t)cache->ticketKeysValid); ++ cache->srvNameCacheData = (srvNameCacheEntry *) ++ (my.cacheMem + (ptrdiff_t)cache->srvNameCacheData); + + cache->cacheMemMap = my.cacheMemMap; + cache->cacheMem = my.cacheMem; +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslsock.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslsock.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslsock.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslsock.c 2016-01-13 14:18:55.632954931 +0100 +@@ -19,6 +19,7 @@ + #endif + #include "pk11pub.h" + #include "nss.h" ++#include "pk11pqg.h" + + /* This is a bodge to allow this code to be compiled against older NSS headers + * that don't contain the TLS 1.2 changes. */ +@@ -90,6 +91,8 @@ + PR_FALSE, /* enableALPN */ + PR_TRUE, /* reuseServerECDHEKey */ + PR_FALSE, /* enableFallbackSCSV */ ++ PR_TRUE, /* enableServerDhe */ ++ PR_FALSE, /* enableExtendedMS */ + PR_FALSE, /* enableSignedCertTimestamps */ + }; + +@@ -232,6 +235,24 @@ + PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers, + sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount); + ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount; ++ PORT_Memcpy(ss->ssl3.signatureAlgorithms, os->ssl3.signatureAlgorithms, ++ sizeof(ss->ssl3.signatureAlgorithms[0]) * ++ os->ssl3.signatureAlgorithmCount); ++ ss->ssl3.signatureAlgorithmCount = os->ssl3.signatureAlgorithmCount; ++ ++ ss->ssl3.dheWeakGroupEnabled = os->ssl3.dheWeakGroupEnabled; ++ ss->ssl3.numDHEGroups = os->ssl3.numDHEGroups; ++ if (os->ssl3.dheGroups) { ++ ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType, ++ os->ssl3.numDHEGroups); ++ if (!ss->ssl3.dheGroups) { ++ goto loser; ++ } ++ PORT_Memcpy(ss->ssl3.dheGroups, os->ssl3.dheGroups, ++ sizeof(SSLDHEGroupType) * os->ssl3.numDHEGroups); ++ } else { ++ ss->ssl3.dheGroups = NULL; ++ } + + if (os->cipherSpecs) { + ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs); +@@ -275,6 +296,10 @@ + ssl3_GetKeyPairRef(os->stepDownKeyPair); + ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL : + ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair); ++ ss->dheKeyPair = !os->dheKeyPair ? NULL : ++ ssl3_GetKeyPairRef(os->dheKeyPair); ++ ss->dheParams = os->dheParams; ++ + /* + * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL. + * XXX We should detect this, and not just march on with NULL pointers. +@@ -398,8 +423,11 @@ + ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); + ss->ephemeralECDHKeyPair = NULL; + } ++ if (ss->dheKeyPair) { ++ ssl3_FreeKeyPair(ss->dheKeyPair); ++ ss->dheKeyPair = NULL; ++ } + SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE); +- PORT_Assert(!ss->xtnData.sniNameArr); + if (ss->xtnData.sniNameArr) { + PORT_Free(ss->xtnData.sniNameArr); + ss->xtnData.sniNameArr = NULL; +@@ -808,6 +836,14 @@ + ss->opt.enableFallbackSCSV = on; + break; + ++ case SSL_ENABLE_SERVER_DHE: ++ ss->opt.enableServerDhe = on; ++ break; ++ ++ case SSL_ENABLE_EXTENDED_MASTER_SECRET: ++ ss->opt.enableExtendedMS = on; ++ break; ++ + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: + ss->opt.enableSignedCertTimestamps = on; + break; +@@ -887,6 +923,9 @@ + case SSL_REUSE_SERVER_ECDHE_KEY: + on = ss->opt.reuseServerECDHEKey; break; + case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break; ++ case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break; ++ case SSL_ENABLE_EXTENDED_MASTER_SECRET: ++ on = ss->opt.enableExtendedMS; break; + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: + on = ss->opt.enableSignedCertTimestamps; + break; +@@ -959,6 +998,12 @@ + case SSL_ENABLE_FALLBACK_SCSV: + on = ssl_defaults.enableFallbackSCSV; + break; ++ case SSL_ENABLE_SERVER_DHE: ++ on = ssl_defaults.enableServerDhe; ++ break; ++ case SSL_ENABLE_EXTENDED_MASTER_SECRET: ++ on = ssl_defaults.enableExtendedMS; ++ break; + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: + on = ssl_defaults.enableSignedCertTimestamps; + break; +@@ -1145,6 +1190,14 @@ + ssl_defaults.enableFallbackSCSV = on; + break; + ++ case SSL_ENABLE_SERVER_DHE: ++ ssl_defaults.enableServerDhe = on; ++ break; ++ ++ case SSL_ENABLE_EXTENDED_MASTER_SECRET: ++ ssl_defaults.enableExtendedMS = on; ++ break; ++ + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: + ssl_defaults.enableSignedCertTimestamps = on; + break; +@@ -1381,6 +1434,148 @@ + } + + SECStatus ++SSL_DHEGroupPrefSet(PRFileDesc *fd, ++ SSLDHEGroupType *groups, ++ PRUint16 num_groups) ++{ ++ sslSocket *ss; ++ ++ if ((num_groups && !groups) || (!num_groups && groups)) { ++ PORT_SetError(SEC_ERROR_INVALID_ARGS); ++ return SECFailure; ++ } ++ ++ ss = ssl_FindSocket(fd); ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DHEGroupPrefSet", SSL_GETPID(), fd)); ++ return SECFailure; ++ } ++ ++ if (ss->ssl3.dheGroups) { ++ PORT_Free(ss->ssl3.dheGroups); ++ ss->ssl3.dheGroups = NULL; ++ ss->ssl3.numDHEGroups = 0; ++ } ++ ++ if (groups) { ++ ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType, num_groups); ++ if (!ss->ssl3.dheGroups) { ++ PORT_SetError(SEC_ERROR_NO_MEMORY); ++ return SECFailure; ++ } ++ PORT_Memcpy(ss->ssl3.dheGroups, groups, ++ sizeof(SSLDHEGroupType) * num_groups); ++ } ++ return SECSuccess; ++} ++ ++ ++PRCallOnceType gWeakDHParamsRegisterOnce; ++int gWeakDHParamsRegisterError; ++ ++PRCallOnceType gWeakDHParamsOnce; ++int gWeakDHParamsError; ++/* As our code allocates type PQGParams, we'll keep it around, ++ * even though we only make use of it's parameters through gWeakDHParam. */ ++static PQGParams *gWeakParamsPQG; ++static ssl3DHParams *gWeakDHParams; ++ ++static PRStatus ++ssl3_CreateWeakDHParams(void) ++{ ++ PQGVerify *vfy; ++ SECStatus rv, passed; ++ ++ PORT_Assert(!gWeakDHParams && !gWeakParamsPQG); ++ ++ rv = PK11_PQG_ParamGenV2(1024, 160, 64 /*maximum seed that will work*/, ++ &gWeakParamsPQG, &vfy); ++ if (rv != SECSuccess) { ++ gWeakDHParamsError = PORT_GetError(); ++ return PR_FAILURE; ++ } ++ ++ rv = PK11_PQG_VerifyParams(gWeakParamsPQG, vfy, &passed); ++ if (rv != SECSuccess || passed != SECSuccess) { ++ SSL_DBG(("%d: PK11_PQG_VerifyParams failed in ssl3_CreateWeakDHParams", ++ SSL_GETPID())); ++ gWeakDHParamsError = PORT_GetError(); ++ return PR_FAILURE; ++ } ++ ++ gWeakDHParams = PORT_ArenaNew(gWeakParamsPQG->arena, ssl3DHParams); ++ if (!gWeakDHParams) { ++ gWeakDHParamsError = PORT_GetError(); ++ return PR_FAILURE; ++ } ++ ++ gWeakDHParams->prime.data = gWeakParamsPQG->prime.data; ++ gWeakDHParams->prime.len = gWeakParamsPQG->prime.len; ++ gWeakDHParams->base.data = gWeakParamsPQG->base.data; ++ gWeakDHParams->base.len = gWeakParamsPQG->base.len; ++ ++ PK11_PQG_DestroyVerify(vfy); ++ return PR_SUCCESS; ++} ++ ++static SECStatus ++ssl3_WeakDHParamsShutdown(void *appData, void *nssData) ++{ ++ if (gWeakParamsPQG) { ++ PK11_PQG_DestroyParams(gWeakParamsPQG); ++ gWeakParamsPQG = NULL; ++ gWeakDHParams = NULL; ++ } ++ return SECSuccess; ++} ++ ++static PRStatus ++ssl3_WeakDHParamsRegisterShutdown(void) ++{ ++ SECStatus rv; ++ rv = NSS_RegisterShutdown(ssl3_WeakDHParamsShutdown, NULL); ++ if (rv != SECSuccess) { ++ gWeakDHParamsRegisterError = PORT_GetError(); ++ } ++ return (PRStatus)rv; ++} ++ ++/* global init strategy inspired by ssl3_CreateECDHEphemeralKeys */ ++SECStatus ++SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled) ++{ ++ sslSocket *ss; ++ PRStatus status; ++ ++ if (enabled) { ++ status = PR_CallOnce(&gWeakDHParamsRegisterOnce, ++ ssl3_WeakDHParamsRegisterShutdown); ++ if (status != PR_SUCCESS) { ++ PORT_SetError(gWeakDHParamsRegisterError); ++ return SECFailure; ++ } ++ ++ status = PR_CallOnce(&gWeakDHParamsOnce, ssl3_CreateWeakDHParams); ++ if (status != PR_SUCCESS) { ++ PORT_SetError(gWeakDHParamsError); ++ return SECFailure; ++ } ++ } ++ ++ if (!fd) ++ return SECSuccess; ++ ++ ss = ssl_FindSocket(fd); ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DHEGroupPrefSet", SSL_GETPID(), fd)); ++ return SECFailure; ++ } ++ ++ ss->ssl3.dheWeakGroupEnabled = enabled; ++ return SECSuccess; ++} ++ ++SECStatus + SSL_GetChannelBinding(PRFileDesc *fd, + SSLChannelBindingType binding_type, + unsigned char *out, +@@ -1402,6 +1597,62 @@ + return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax); + } + ++#include "dhe-param.c" ++ ++static const SSLDHEGroupType ssl_default_dhe_groups[] = { ++ ssl_ff_dhe_2048_group ++}; ++ ++/* Keep this array synchronized with the index definitions in SSLDHEGroupType */ ++static const ssl3DHParams *all_ssl3DHParams[] = { ++ NULL, /* ssl_dhe_group_none */ ++ &ff_dhe_2048, ++ &ff_dhe_3072, ++ &ff_dhe_4096, ++ &ff_dhe_6144, ++ &ff_dhe_8192, ++}; ++ ++static SSLDHEGroupType ++selectDHEGroup(sslSocket *ss, const SSLDHEGroupType *groups, PRUint16 num_groups) ++{ ++ if (!groups || !num_groups) ++ return ssl_dhe_group_none; ++ ++ /* We don't have automatic group parameter selection yet ++ * (potentially) based on socket parameters, e.g. key sizes. ++ * For now, we return the first available group from the allowed list. */ ++ return groups[0]; ++} ++ ++/* Ensure DH parameters have been selected */ ++SECStatus ++ssl3_SelectDHParams(sslSocket *ss) ++{ ++ SSLDHEGroupType selectedGroup = ssl_dhe_group_none; ++ ++ if (ss->ssl3.dheWeakGroupEnabled) { ++ ss->dheParams = gWeakDHParams; ++ } else { ++ if (ss->ssl3.dheGroups) { ++ selectedGroup = selectDHEGroup(ss, ss->ssl3.dheGroups, ++ ss->ssl3.numDHEGroups); ++ } else { ++ size_t number_of_default_groups = PR_ARRAY_SIZE(ssl_default_dhe_groups); ++ selectedGroup = selectDHEGroup(ss, ssl_default_dhe_groups, ++ number_of_default_groups); ++ } ++ ++ if (selectedGroup == ssl_dhe_group_none || ++ selectedGroup >= ssl_dhe_group_max) { ++ return SECFailure; ++ } ++ ++ ss->dheParams = all_ssl3DHParams[selectedGroup]; ++ } ++ ++ return SECSuccess; ++} + + /* LOCKS ??? XXX */ + static PRFileDesc * +@@ -1699,6 +1950,10 @@ + PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers, + sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount); + ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount; ++ PORT_Memcpy(ss->ssl3.signatureAlgorithms, sm->ssl3.signatureAlgorithms, ++ sizeof(ss->ssl3.signatureAlgorithms[0]) * ++ sm->ssl3.signatureAlgorithmCount); ++ ss->ssl3.signatureAlgorithmCount = sm->ssl3.signatureAlgorithmCount; + + if (!ss->opt.useSecurity) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -3122,6 +3377,10 @@ + } + ss->requestedCertTypes = NULL; + ss->stepDownKeyPair = NULL; ++ ++ ss->dheParams = NULL; ++ ss->dheKeyPair = NULL; ++ + ss->dbHandle = CERT_GetDefaultCertDB(); + + /* Provide default implementation of hooks */ +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslt.h qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslt.h +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslt.h 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslt.h 2016-01-13 14:18:55.633954937 +0100 +@@ -1,3 +1,4 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /* + * This file contains prototypes for the public SSL functions. + * +@@ -68,13 +69,35 @@ + #define kt_ecdh ssl_kea_ecdh + #define kt_kea_size ssl_kea_size + ++ ++/* Values of this enum match the SignatureAlgorithm enum from ++ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ + typedef enum { +- ssl_sign_null = 0, ++ ssl_sign_null = 0, /* "anonymous" in TLS */ + ssl_sign_rsa = 1, + ssl_sign_dsa = 2, + ssl_sign_ecdsa = 3 + } SSLSignType; + ++/* Values of this enum match the HashAlgorithm enum from ++ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ ++typedef enum { ++ /* ssl_hash_none is used internally to mean the pre-1.2 combination of MD5 ++ * and SHA1. The other values are only used in TLS 1.2. */ ++ ssl_hash_none = 0, ++ ssl_hash_md5 = 1, ++ ssl_hash_sha1 = 2, ++ ssl_hash_sha224 = 3, ++ ssl_hash_sha256 = 4, ++ ssl_hash_sha384 = 5, ++ ssl_hash_sha512 = 6 ++} SSLHashType; ++ ++typedef struct SSLSignatureAndHashAlgStr { ++ SSLHashType hashAlg; ++ SSLSignType sigAlg; ++} SSLSignatureAndHashAlg; ++ + typedef enum { + ssl_auth_null = 0, + ssl_auth_rsa = 1, +@@ -136,8 +159,31 @@ + /* compression method info */ + const char * compressionMethodName; + SSLCompressionMethod compressionMethod; ++ ++ /* The following fields are added in NSS 3.21. ++ * This field only has meaning in TLS < 1.3 and will be set to ++ * PR_FALSE in TLS 1.3. ++ */ ++ PRBool extendedMasterSecretUsed; + } SSLChannelInfo; + ++/* Preliminary channel info */ ++#define ssl_preinfo_version (1U << 0) ++#define ssl_preinfo_cipher_suite (1U << 1) ++#define ssl_preinfo_all (ssl_preinfo_version|ssl_preinfo_cipher_suite) ++ ++typedef struct SSLPreliminaryChannelInfoStr { ++ /* This is set to the length of the struct. */ ++ PRUint32 length; ++ /* A bitfield over SSLPreliminaryValueSet that describes which ++ * preliminary values are set (see ssl_preinfo_*). */ ++ PRUint32 valuesSet; ++ /* Protocol version: test (valuesSet & ssl_preinfo_version) */ ++ PRUint16 protocolVersion; ++ /* Cipher suite: test (valuesSet & ssl_preinfo_cipher_suite) */ ++ PRUint16 cipherSuite; ++} SSLPreliminaryChannelInfo; ++ + typedef struct SSLCipherSuiteInfoStr { + PRUint16 length; + PRUint16 cipherSuite; +@@ -204,6 +250,7 @@ + ssl_app_layer_protocol_xtn = 16, + ssl_signed_certificate_timestamp_xtn = 18, /* RFC 6962 */ + ssl_padding_xtn = 21, ++ ssl_extended_master_secret_xtn = 23, + ssl_session_ticket_xtn = 35, + ssl_next_proto_nego_xtn = 13172, + ssl_channel_id_xtn = 30032, +@@ -211,6 +258,16 @@ + ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */ + } SSLExtensionType; + +-#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */ ++#define SSL_MAX_EXTENSIONS 14 /* doesn't include ssl_padding_xtn. */ ++ ++typedef enum { ++ ssl_dhe_group_none = 0, ++ ssl_ff_dhe_2048_group = 1, ++ ssl_ff_dhe_3072_group = 2, ++ ssl_ff_dhe_4096_group = 3, ++ ssl_ff_dhe_6144_group = 4, ++ ssl_ff_dhe_8192_group = 5, ++ ssl_dhe_group_max ++} SSLDHEGroupType; + + #endif /* __sslt_h_ */ +diff -ur qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslver.c qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslver.c +--- qtwebengine-opensource-src-5.6.0-beta/src/3rdparty/chromium/net/third_party/nss/ssl/sslver.c 2015-12-10 18:17:21.000000000 +0100 ++++ qtwebengine-opensource-src-5.6.0-beta-nss321/src/3rdparty/chromium/net/third_party/nss/ssl/sslver.c 2016-01-13 14:18:55.633954937 +0100 +@@ -12,20 +12,7 @@ + #define _DEBUG_STRING "" + #endif + +-#if defined(DONT_EMBED_BUILD_METADATA) && !defined(OFFICIAL_BUILD) +-#define _DATE_AND_TIME "Sep 02 2008 08:00:00" +-#else +-#define _DATE_AND_TIME __DATE__ " " __TIME__ +-#endif +- +- + /* +- * Version information for the 'ident' and 'what commands +- * +- * NOTE: the first component of the concatenated rcsid string +- * must not end in a '$' to prevent rcs keyword substitution. ++ * Version information + */ +-const char __nss_ssl_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING +- " " _DATE_AND_TIME " $"; +-const char __nss_ssl_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING +- " " _DATE_AND_TIME; ++const char __nss_ssl_version[] = "Version: NSS " NSS_VERSION _DEBUG_STRING;