diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index 85b08364b5eb..652de8d5a24c 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_18_1_BETA1 +NSS_3_19_BETA2 diff --git a/security/nss/cmd/certutil/certext.c b/security/nss/cmd/certutil/certext.c index a87b4b1fa672..c36bc2d25e4a 100644 --- a/security/nss/cmd/certutil/certext.c +++ b/security/nss/cmd/certutil/certext.c @@ -987,10 +987,13 @@ AddNameConstraints(void *extHandle) GEN_BREAK(SECFailure); } - PrintChoicesAndGetAnswer("Type of Name Constraint?\n" + if (PrintChoicesAndGetAnswer("Type of Name Constraint?\n" "\t1 - permitted\n\t2 - excluded\n\tAny" "other number to finish\n\tChoice", - buffer, sizeof(buffer)); + buffer, sizeof(buffer)) != SECSuccess) { + GEN_BREAK(SECFailure); + } + intValue = PORT_Atoi(buffer); switch (intValue) { case 1: @@ -1826,11 +1829,13 @@ AddInfoAccess(void *extHandle, PRBool addSIAExt, PRBool isCACert) intValue = timeStamping; } } else { - PrintChoicesAndGetAnswer("Enter access method type " + if (PrintChoicesAndGetAnswer("Enter access method type " "for Authority Information Access extension:\n" "\t1 - CA Issuers\n\t2 - OCSP\n\tAny" "other number to finish\n\tChoice", - buffer, sizeof(buffer)); + buffer, sizeof(buffer)) != SECSuccess) { + GEN_BREAK (SECFailure); + } intValue = PORT_Atoi(buffer); } if (addSIAExt) { diff --git a/security/nss/cmd/checkcert/checkcert.c b/security/nss/cmd/checkcert/checkcert.c index 63beea5876ed..2a62a08ee53d 100644 --- a/security/nss/cmd/checkcert/checkcert.c +++ b/security/nss/cmd/checkcert/checkcert.c @@ -220,14 +220,12 @@ CERTCertificate *createEmptyCertificate(void) } return c; -} - - +} int main(int argc, char **argv) { - int rv, verbose=0, force=0; + int verbose=0, force=0; int ascii=0, issuerAscii=0; char *progName=0; PRFileDesc *inFile=0, *issuerCertFile=0; @@ -244,6 +242,7 @@ int main(int argc, char **argv) char *inFileName = NULL, *issuerCertFileName = NULL; PLOptState *optstate; PLOptStatus status; + SECStatus rv; PORT_Memset(&md5WithRSAEncryption, 0, sizeof(md5WithRSAEncryption)); PORT_Memset(&md2WithRSAEncryption, 0, sizeof(md2WithRSAEncryption)); @@ -405,17 +404,37 @@ int main(int argc, char **argv) printf("\n"); /* Check algorithms */ - SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption, + rv = SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption, SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, NULL); + if (rv) { + fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION.\n", + progName); + exit(1); + } - SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption, + rv = SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption, SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, NULL); + if (rv) { + fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION.\n", + progName); + exit(1); + } - SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption, + rv = SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption, SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, NULL); + if (rv) { + fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION.\n", + progName); + exit(1); + } - SECOID_SetAlgorithmID(arena, &rsaEncryption, + rv = SECOID_SetAlgorithmID(arena, &rsaEncryption, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL); + if (rv) { + fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_RSA_ENCRYPTION.\n", + progName); + exit(1); + } { int isMD5RSA = (SECOID_CompareAlgorithmID(&cert->signature, diff --git a/security/nss/cmd/modutil/install.c b/security/nss/cmd/modutil/install.c index 839cf4021ee9..283fc790ec6b 100644 --- a/security/nss/cmd/modutil/install.c +++ b/security/nss/cmd/modutil/install.c @@ -120,9 +120,10 @@ typedef struct StringNode_str { StringNode* StringNode_new() { StringNode* new_this; - new_this = (StringNode*)malloc(sizeof(StringNode)); - new_this->str=NULL; - new_this->next=NULL; + new_this = (StringNode*)PR_Malloc(sizeof(StringNode)); + PORT_Assert(new_this != NULL); + new_this->str = NULL; + new_this->next = NULL; return new_this; } diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfaeee3..5182f75552c8 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/external_tests/README b/security/nss/external_tests/README index 97f44e63c4cc..45d3b1f7066d 100644 --- a/security/nss/external_tests/README +++ b/security/nss/external_tests/README @@ -21,11 +21,11 @@ You should be able to run the unit tests manually as: ssl_gtest -d ${SSLGTESTDIR} -Where $SSLGTESTDIR the directory created by ./all.sh or a manually -created directory with a database containing a certificate called -server (with its private keys) +Where $SSLGTESTDIR is a directory with a database containing: + - an RSA certificate called server (with its private key) + - an ECDSA certificate called ecdsa (with its private key) +A directory like this is created by ./all.sh and can be found +in a directory named something like -There is a very trivial set of tests that demonstrate some -of the features. - + tests_results/security/${hostname}.${NUMBER}/ssl_gtests diff --git a/security/nss/external_tests/ssl_gtest/manifest.mn b/security/nss/external_tests/ssl_gtest/manifest.mn index 9b8669b3eebb..ee9f1c2abf69 100644 --- a/security/nss/external_tests/ssl_gtest/manifest.mn +++ b/security/nss/external_tests/ssl_gtest/manifest.mn @@ -9,6 +9,7 @@ MODULE = nss CPPSRCS = \ ssl_loopback_unittest.cc \ ssl_extension_unittest.cc \ + ssl_skip_unittest.cc \ ssl_gtest.cc \ test_io.cc \ tls_agent.cc \ diff --git a/security/nss/external_tests/ssl_gtest/ssl_extension_unittest.cc b/security/nss/external_tests/ssl_gtest/ssl_extension_unittest.cc index a11f905436a4..478cc0082408 100644 --- a/security/nss/external_tests/ssl_gtest/ssl_extension_unittest.cc +++ b/security/nss/external_tests/ssl_gtest/ssl_extension_unittest.cc @@ -268,8 +268,8 @@ class TlsExtensionTestBase : public TlsConnectTestBase { client_->SetPacketFilter(filter); } ConnectExpectFail(); - ASSERT_EQ(kTlsAlertFatal, alert_recorder->level()); - ASSERT_EQ(alert, alert_recorder->description()); + EXPECT_EQ(kTlsAlertFatal, alert_recorder->level()); + EXPECT_EQ(alert, alert_recorder->description()); } void ServerHelloErrorTest(PacketFilter* filter, @@ -280,8 +280,8 @@ class TlsExtensionTestBase : public TlsConnectTestBase { server_->SetPacketFilter(filter); } ConnectExpectFail(); - ASSERT_EQ(kTlsAlertFatal, alert_recorder->level()); - ASSERT_EQ(alert, alert_recorder->description()); + EXPECT_EQ(kTlsAlertFatal, alert_recorder->level()); + EXPECT_EQ(alert, alert_recorder->description()); } static void InitSimpleSni(DataBuffer* extension) { @@ -494,7 +494,7 @@ TEST_P(TlsExtensionTest12Plus, DISABLED_SignatureAlgorithmsSigUnsupported) { } TEST_P(TlsExtensionTestGeneric, SupportedCurvesShort) { - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); const uint8_t val[] = { 0x00, 0x01, 0x00 }; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(new TlsExtensionReplacer(ssl_elliptic_curves_xtn, @@ -502,7 +502,7 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesShort) { } TEST_P(TlsExtensionTestGeneric, SupportedCurvesBadLength) { - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); const uint8_t val[] = { 0x09, 0x99, 0x00, 0x00 }; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(new TlsExtensionReplacer(ssl_elliptic_curves_xtn, @@ -510,7 +510,7 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesBadLength) { } TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) { - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); const uint8_t val[] = { 0x00, 0x02, 0x00, 0x00, 0x00 }; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(new TlsExtensionReplacer(ssl_elliptic_curves_xtn, @@ -518,7 +518,7 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) { } TEST_P(TlsExtensionTestGeneric, SupportedPointsEmpty) { - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); const uint8_t val[] = { 0x00 }; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn, @@ -526,7 +526,7 @@ TEST_P(TlsExtensionTestGeneric, SupportedPointsEmpty) { } TEST_P(TlsExtensionTestGeneric, SupportedPointsBadLength) { - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); const uint8_t val[] = { 0x99, 0x00, 0x00 }; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn, @@ -534,7 +534,7 @@ TEST_P(TlsExtensionTestGeneric, SupportedPointsBadLength) { } TEST_P(TlsExtensionTestGeneric, SupportedPointsTrailingData) { - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); const uint8_t val[] = { 0x01, 0x00, 0x00 }; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn, diff --git a/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc b/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc index b372412f8520..8b3b84bf85ca 100644 --- a/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc +++ b/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc @@ -15,7 +15,7 @@ namespace nss_test { -class TlsServerKeyExchangeECDHE { +class TlsServerKeyExchangeEcdhe { public: bool Parse(const DataBuffer& buffer) { TlsParser parser(buffer); @@ -44,14 +44,15 @@ TEST_P(TlsConnectGeneric, SetupOnly) {} TEST_P(TlsConnectGeneric, Connect) { Connect(); - client_->CheckVersion(SSL_LIBRARY_VERSION_TLS_1_2); + client_->CheckVersion(std::get<1>(GetParam())); + client_->CheckAuthType(ssl_auth_rsa); } TEST_P(TlsConnectGeneric, ConnectResumed) { ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID); Connect(); - Reset(); + ResetRsa(); Connect(); CheckResumption(RESUME_SESSIONID); } @@ -59,7 +60,7 @@ TEST_P(TlsConnectGeneric, ConnectResumed) { TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) { ConfigureSessionCache(RESUME_NONE, RESUME_SESSIONID); Connect(); - Reset(); + ResetRsa(); Connect(); CheckResumption(RESUME_NONE); } @@ -67,7 +68,7 @@ TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) { TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) { ConfigureSessionCache(RESUME_SESSIONID, RESUME_NONE); Connect(); - Reset(); + ResetRsa(); Connect(); CheckResumption(RESUME_NONE); } @@ -75,7 +76,7 @@ TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) { TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) { ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); - Reset(); + ResetRsa(); Connect(); CheckResumption(RESUME_NONE); } @@ -85,7 +86,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeSupportBoth) { ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); Connect(); - Reset(); + ResetRsa(); ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); Connect(); CheckResumption(RESUME_TICKET); @@ -97,7 +98,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) { ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH); Connect(); - Reset(); + ResetRsa(); ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH); Connect(); CheckResumption(RESUME_NONE); @@ -108,7 +109,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicket) { ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); Connect(); - Reset(); + ResetRsa(); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); Connect(); CheckResumption(RESUME_TICKET); @@ -120,7 +121,7 @@ TEST_P(TlsConnectGeneric, ConnectClientServerTicketOnly) { ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); Connect(); - Reset(); + ResetRsa(); ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); Connect(); CheckResumption(RESUME_NONE); @@ -130,7 +131,7 @@ TEST_P(TlsConnectGeneric, ConnectClientBothServerNone) { ConfigureSessionCache(RESUME_BOTH, RESUME_NONE); Connect(); - Reset(); + ResetRsa(); ConfigureSessionCache(RESUME_BOTH, RESUME_NONE); Connect(); CheckResumption(RESUME_NONE); @@ -140,12 +141,32 @@ TEST_P(TlsConnectGeneric, ConnectClientNoneServerBoth) { ConfigureSessionCache(RESUME_NONE, RESUME_BOTH); Connect(); - Reset(); + ResetRsa(); ConfigureSessionCache(RESUME_NONE, RESUME_BOTH); Connect(); CheckResumption(RESUME_NONE); } +TEST_P(TlsConnectGeneric, ResumeWithHigherVersion) { + EnsureTlsSetup(); + ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_1); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_1); + Connect(); + + ResetRsa(); + EnsureTlsSetup(); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_2); + Connect(); + CheckResumption(RESUME_NONE); + client_->CheckVersion(SSL_LIBRARY_VERSION_TLS_1_2); +} + TEST_P(TlsConnectGeneric, ConnectAlpn) { EnableAlpn(); Connect(); @@ -153,65 +174,72 @@ TEST_P(TlsConnectGeneric, ConnectAlpn) { server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, "a"); } +TEST_P(TlsConnectGeneric, ConnectEcdsa) { + ResetEcdsa(); + Connect(); + client_->CheckVersion(std::get<1>(GetParam())); + client_->CheckAuthType(ssl_auth_ecdsa); +} + TEST_P(TlsConnectDatagram, ConnectSrtp) { EnableSrtp(); Connect(); CheckSrtp(); } -TEST_P(TlsConnectStream, ConnectECDHE) { - EnableSomeECDHECiphers(); +TEST_P(TlsConnectStream, ConnectEcdhe) { + EnableSomeEcdheCiphers(); Connect(); client_->CheckKEAType(ssl_kea_ecdh); } -TEST_P(TlsConnectStream, ConnectECDHETwiceReuseKey) { - EnableSomeECDHECiphers(); +TEST_P(TlsConnectStream, ConnectEcdheTwiceReuseKey) { + EnableSomeEcdheCiphers(); TlsInspectorRecordHandshakeMessage* i1 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); server_->SetPacketFilter(i1); Connect(); client_->CheckKEAType(ssl_kea_ecdh); - TlsServerKeyExchangeECDHE dhe1; - ASSERT_TRUE(dhe1.Parse(i1->buffer())); + TlsServerKeyExchangeEcdhe dhe1; + EXPECT_TRUE(dhe1.Parse(i1->buffer())); // Restart - Reset(); + ResetRsa(); TlsInspectorRecordHandshakeMessage* i2 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); server_->SetPacketFilter(i2); - EnableSomeECDHECiphers(); + EnableSomeEcdheCiphers(); ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); client_->CheckKEAType(ssl_kea_ecdh); - TlsServerKeyExchangeECDHE dhe2; - ASSERT_TRUE(dhe2.Parse(i2->buffer())); + TlsServerKeyExchangeEcdhe dhe2; + EXPECT_TRUE(dhe2.Parse(i2->buffer())); // Make sure they are the same. - ASSERT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len()); - ASSERT_TRUE(!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(), + EXPECT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len()); + EXPECT_TRUE(!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(), dhe1.public_key_.len())); } -TEST_P(TlsConnectStream, ConnectECDHETwiceNewKey) { - EnableSomeECDHECiphers(); +TEST_P(TlsConnectStream, ConnectEcdheTwiceNewKey) { + EnableSomeEcdheCiphers(); SECStatus rv = SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); TlsInspectorRecordHandshakeMessage* i1 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); server_->SetPacketFilter(i1); Connect(); client_->CheckKEAType(ssl_kea_ecdh); - TlsServerKeyExchangeECDHE dhe1; - ASSERT_TRUE(dhe1.Parse(i1->buffer())); + TlsServerKeyExchangeEcdhe dhe1; + EXPECT_TRUE(dhe1.Parse(i1->buffer())); // Restart - Reset(); - EnableSomeECDHECiphers(); + ResetRsa(); + EnableSomeEcdheCiphers(); rv = SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); TlsInspectorRecordHandshakeMessage* i2 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); server_->SetPacketFilter(i2); @@ -219,11 +247,11 @@ TEST_P(TlsConnectStream, ConnectECDHETwiceNewKey) { Connect(); client_->CheckKEAType(ssl_kea_ecdh); - TlsServerKeyExchangeECDHE dhe2; - ASSERT_TRUE(dhe2.Parse(i2->buffer())); + TlsServerKeyExchangeEcdhe dhe2; + EXPECT_TRUE(dhe2.Parse(i2->buffer())); // Make sure they are different. - ASSERT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) && + EXPECT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) && (!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(), dhe1.public_key_.len()))); } diff --git a/security/nss/external_tests/ssl_gtest/ssl_skip_unittest.cc b/security/nss/external_tests/ssl_gtest/ssl_skip_unittest.cc new file mode 100644 index 000000000000..5f6be9f239ed --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/ssl_skip_unittest.cc @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "sslerr.h" + +#include "tls_parser.h" +#include "tls_filter.h" +#include "tls_connect.h" + +/* + * The tests in this file test that the TLS state machine is robust against + * attacks that alter the order of handshake messages. + * + * See for a description of the problems + * that this sort of attack can enable. + */ +namespace nss_test { + +class TlsHandshakeSkipFilter : public TlsRecordFilter { + public: + // A TLS record filter that skips handshake messages of the identified type. + TlsHandshakeSkipFilter(uint8_t handshake_type) + : handshake_type_(handshake_type), + skipped_(false) {} + + protected: + // Takes a record; if it is a handshake record, it removes the first handshake + // message that is of handshake_type_ type. + virtual bool FilterRecord(uint8_t content_type, uint16_t version, + const DataBuffer& input, DataBuffer* output) { + if (content_type != kTlsHandshakeType) { + return false; + } + + size_t output_offset = 0U; + output->Allocate(input.len()); + + TlsParser parser(input); + while (parser.remaining()) { + size_t start = parser.consumed(); + uint8_t handshake_type; + if (!parser.Read(&handshake_type)) { + return false; + } + uint32_t length; + if (!TlsHandshakeFilter::ReadLength(&parser, version, &length)) { + return false; + } + + if (!parser.Skip(length)) { + return false; + } + + if (skipped_ || handshake_type != handshake_type_) { + size_t entire_length = parser.consumed() - start; + output->Write(output_offset, input.data() + start, + entire_length); + // DTLS sequence numbers need to be rewritten + if (skipped_ && IsDtls(version)) { + output->data()[start + 5] -= 1; + } + output_offset += entire_length; + } else { + std::cerr << "Dropping handshake: " + << static_cast(handshake_type_) << std::endl; + // We only need to report that the output contains changed data if we + // drop a handshake message. But once we've skipped one message, we + // have to modify all subsequent handshake messages so that they include + // the correct DTLS sequence numbers. + skipped_ = true; + } + } + output->Truncate(output_offset); + return skipped_; + } + + private: + // The type of handshake message to drop. + uint8_t handshake_type_; + // Whether this filter has ever skipped a handshake message. Track this so + // that sequence numbers on DTLS handshake messages can be rewritten in + // subsequent calls. + bool skipped_; +}; + +class TlsSkipTest + : public TlsConnectTestBase, + public ::testing::WithParamInterface> { + + protected: + TlsSkipTest() + : TlsConnectTestBase(TlsConnectTestBase::ToMode(std::get<0>(GetParam())), + std::get<1>(GetParam())) {} + + void ServerSkipTest(PacketFilter* filter, + uint8_t alert = kTlsAlertUnexpectedMessage) { + auto alert_recorder = new TlsAlertRecorder(); + client_->SetPacketFilter(alert_recorder); + if (filter) { + server_->SetPacketFilter(filter); + } + ConnectExpectFail(); + EXPECT_EQ(kTlsAlertFatal, alert_recorder->level()); + EXPECT_EQ(alert, alert_recorder->description()); + } +}; + +TEST_P(TlsSkipTest, SkipCertificate) { + ServerSkipTest(new TlsHandshakeSkipFilter(kTlsHandshakeCertificate)); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); +} + +TEST_P(TlsSkipTest, SkipCertificateEcdhe) { + EnableSomeEcdheCiphers(); + ServerSkipTest(new TlsHandshakeSkipFilter(kTlsHandshakeCertificate)); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); +} + +TEST_P(TlsSkipTest, SkipCertificateEcdsa) { + ResetEcdsa(); + ServerSkipTest(new TlsHandshakeSkipFilter(kTlsHandshakeCertificate)); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); +} + +TEST_P(TlsSkipTest, SkipServerKeyExchange) { + // Have to enable some ephemeral suites, or ServerKeyExchange doesn't appear. + EnableSomeEcdheCiphers(); + ServerSkipTest(new TlsHandshakeSkipFilter(kTlsHandshakeServerKeyExchange)); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); +} + +TEST_P(TlsSkipTest, SkipServerKeyExchangeEcdsa) { + ResetEcdsa(); + ServerSkipTest(new TlsHandshakeSkipFilter(kTlsHandshakeServerKeyExchange)); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); +} + +TEST_P(TlsSkipTest, SkipCertAndKeyExch) { + auto chain = new ChainedPacketFilter(); + chain->Add(new TlsHandshakeSkipFilter(kTlsHandshakeCertificate)); + chain->Add(new TlsHandshakeSkipFilter(kTlsHandshakeServerKeyExchange)); + ServerSkipTest(chain); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); +} + +TEST_P(TlsSkipTest, SkipCertAndKeyExchEcdsa) { + ResetEcdsa(); + auto chain = new ChainedPacketFilter(); + chain->Add(new TlsHandshakeSkipFilter(kTlsHandshakeCertificate)); + chain->Add(new TlsHandshakeSkipFilter(kTlsHandshakeServerKeyExchange)); + ServerSkipTest(chain); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); +} + +INSTANTIATE_TEST_CASE_P(SkipTls10, TlsSkipTest, + ::testing::Combine( + TlsConnectTestBase::kTlsModesStream, + TlsConnectTestBase::kTlsV10)); +INSTANTIATE_TEST_CASE_P(SkipVariants, TlsSkipTest, + ::testing::Combine( + TlsConnectTestBase::kTlsModesAll, + TlsConnectTestBase::kTlsV11V12)); + +} // namespace nss_test diff --git a/security/nss/external_tests/ssl_gtest/tls_agent.cc b/security/nss/external_tests/ssl_gtest/tls_agent.cc index 76e924574db3..7357412049e9 100644 --- a/security/nss/external_tests/ssl_gtest/tls_agent.cc +++ b/security/nss/external_tests/ssl_gtest/tls_agent.cc @@ -42,7 +42,7 @@ bool TlsAgent::EnsureTlsSetup() { EXPECT_NE(nullptr, priv); if (!priv) return false; // Leak cert. - SECStatus rv = SSL_ConfigSecureServer(ssl_fd_, cert, priv, kt_rsa); + SECStatus rv = SSL_ConfigSecureServer(ssl_fd_, cert, priv, kea_); EXPECT_EQ(SECSuccess, rv); if (rv != SECSuccess) return false; // Leak cert and key. @@ -71,40 +71,42 @@ bool TlsAgent::EnsureTlsSetup() { } void TlsAgent::StartConnect() { - ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_TRUE(EnsureTlsSetup()); SECStatus rv; rv = SSL_ResetHandshake(ssl_fd_, role_ == SERVER ? PR_TRUE : PR_FALSE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); SetState(CONNECTING); } -void TlsAgent::EnableSomeECDHECiphers() { - ASSERT_TRUE(EnsureTlsSetup()); +void TlsAgent::EnableSomeEcdheCiphers() { + EXPECT_TRUE(EnsureTlsSetup()); - const uint32_t EnabledCiphers[] = {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}; + const uint32_t EcdheCiphers[] = {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}; - for (size_t i = 0; i < PR_ARRAY_SIZE(EnabledCiphers); ++i) { - SECStatus rv = SSL_CipherPrefSet(ssl_fd_, EnabledCiphers[i], PR_TRUE); - ASSERT_EQ(SECSuccess, rv); + for (size_t i = 0; i < PR_ARRAY_SIZE(EcdheCiphers); ++i) { + SECStatus rv = SSL_CipherPrefSet(ssl_fd_, EcdheCiphers[i], PR_TRUE); + EXPECT_EQ(SECSuccess, rv); } } void TlsAgent::SetSessionTicketsEnabled(bool en) { - ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_TRUE(EnsureTlsSetup()); SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, en ? PR_TRUE : PR_FALSE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); } void TlsAgent::SetSessionCacheEnabled(bool en) { - ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_TRUE(EnsureTlsSetup()); SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, en ? PR_FALSE : PR_TRUE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); } void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) { @@ -113,25 +115,30 @@ void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) { if (ssl_fd_) { SECStatus rv = SSL_VersionRangeSet(ssl_fd_, &vrange_); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); } } void TlsAgent::CheckKEAType(SSLKEAType type) const { - ASSERT_EQ(CONNECTED, state_); - ASSERT_EQ(type, csinfo_.keaType); + EXPECT_EQ(CONNECTED, state_); + EXPECT_EQ(type, csinfo_.keaType); +} + +void TlsAgent::CheckAuthType(SSLAuthType type) const { + EXPECT_EQ(CONNECTED, state_); + EXPECT_EQ(type, csinfo_.authAlgorithm); } void TlsAgent::CheckVersion(uint16_t version) const { - ASSERT_EQ(CONNECTED, state_); - ASSERT_EQ(version, info_.protocolVersion); + EXPECT_EQ(CONNECTED, state_); + EXPECT_EQ(version, info_.protocolVersion); } void TlsAgent::EnableAlpn(const uint8_t* val, size_t len) { - ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_TRUE(EnsureTlsSetup()); - ASSERT_EQ(SECSuccess, SSL_OptionSet(ssl_fd_, SSL_ENABLE_ALPN, PR_TRUE)); - ASSERT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd_, val, len)); + EXPECT_EQ(SECSuccess, SSL_OptionSet(ssl_fd_, SSL_ENABLE_ALPN, PR_TRUE)); + EXPECT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd_, val, len)); } void TlsAgent::CheckAlpn(SSLNextProtoState expected_state, @@ -142,37 +149,41 @@ void TlsAgent::CheckAlpn(SSLNextProtoState expected_state, SECStatus rv = SSL_GetNextProto(ssl_fd_, &state, reinterpret_cast(chosen), &chosen_len, sizeof(chosen)); - ASSERT_EQ(SECSuccess, rv); - ASSERT_EQ(expected_state, state); - ASSERT_EQ(expected, std::string(chosen, chosen_len)); + EXPECT_EQ(SECSuccess, rv); + EXPECT_EQ(expected_state, state); + EXPECT_EQ(expected, std::string(chosen, chosen_len)); } void TlsAgent::EnableSrtp() { - ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_TRUE(EnsureTlsSetup()); const uint16_t ciphers[] = { SRTP_AES128_CM_HMAC_SHA1_80, SRTP_AES128_CM_HMAC_SHA1_32 }; - ASSERT_EQ(SECSuccess, SSL_SetSRTPCiphers(ssl_fd_, ciphers, + EXPECT_EQ(SECSuccess, SSL_SetSRTPCiphers(ssl_fd_, ciphers, PR_ARRAY_SIZE(ciphers))); } void TlsAgent::CheckSrtp() { uint16_t actual; - ASSERT_EQ(SECSuccess, SSL_GetSRTPCipher(ssl_fd_, &actual)); - ASSERT_EQ(SRTP_AES128_CM_HMAC_SHA1_80, actual); + EXPECT_EQ(SECSuccess, SSL_GetSRTPCipher(ssl_fd_, &actual)); + EXPECT_EQ(SRTP_AES128_CM_HMAC_SHA1_80, actual); } +void TlsAgent::CheckErrorCode(int32_t expected) const { + EXPECT_EQ(ERROR, state_); + EXPECT_EQ(expected, error_code_); +} void TlsAgent::Handshake() { SECStatus rv = SSL_ForceHandshake(ssl_fd_); if (rv == SECSuccess) { LOG("Handshake success"); SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &info_, sizeof(info_)); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); rv = SSL_GetCipherSuiteInfo(info_.cipherSuite, &csinfo_, sizeof(csinfo_)); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); SetState(CONNECTED); return; @@ -192,25 +203,26 @@ void TlsAgent::Handshake() { case SSL_ERROR_RX_MALFORMED_HANDSHAKE: default: LOG("Handshake failed with error " << err); + error_code_ = err; SetState(ERROR); return; } } void TlsAgent::ConfigureSessionCache(SessionResumptionMode mode) { - ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_TRUE(EnsureTlsSetup()); SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, mode & RESUME_SESSIONID ? PR_FALSE : PR_TRUE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, mode & RESUME_TICKET ? PR_TRUE : PR_FALSE); - ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(SECSuccess, rv); } diff --git a/security/nss/external_tests/ssl_gtest/tls_agent.h b/security/nss/external_tests/ssl_gtest/tls_agent.h index dd2a5e01b4d2..b3afeca4057f 100644 --- a/security/nss/external_tests/ssl_gtest/tls_agent.h +++ b/security/nss/external_tests/ssl_gtest/tls_agent.h @@ -33,14 +33,16 @@ class TlsAgent : public PollTarget { enum Role { CLIENT, SERVER }; enum State { INIT, CONNECTING, CONNECTED, ERROR }; - TlsAgent(const std::string& name, Role role, Mode mode) + TlsAgent(const std::string& name, Role role, Mode mode, SSLKEAType kea) : name_(name), mode_(mode), + kea_(kea), pr_fd_(nullptr), adapter_(nullptr), ssl_fd_(nullptr), role_(role), - state_(INIT) { + state_(INIT), + error_code_(0) { memset(&info_, 0, sizeof(info_)); memset(&csinfo_, 0, sizeof(csinfo_)); SECStatus rv = SSL_VersionRangeGetDefault(mode_ == STREAM ? @@ -78,10 +80,11 @@ class TlsAgent : public PollTarget { void StartConnect(); void CheckKEAType(SSLKEAType type) const; + void CheckAuthType(SSLAuthType type) const; void CheckVersion(uint16_t version) const; void Handshake(); - void EnableSomeECDHECiphers(); + void EnableSomeEcdheCiphers(); bool EnsureTlsSetup(); void ConfigureSessionCache(SessionResumptionMode mode); @@ -93,6 +96,7 @@ class TlsAgent : public PollTarget { const std::string& expected); void EnableSrtp(); void CheckSrtp(); + void CheckErrorCode(int32_t expected) const; State state() const { return state_; } @@ -172,6 +176,7 @@ class TlsAgent : public PollTarget { const std::string name_; Mode mode_; + SSLKEAType kea_; PRFileDesc* pr_fd_; DummyPrSocket* adapter_; PRFileDesc* ssl_fd_; @@ -180,6 +185,7 @@ class TlsAgent : public PollTarget { SSLChannelInfo info_; SSLCipherSuiteInfo csinfo_; SSLVersionRange vrange_; + int32_t error_code_; }; } // namespace nss_test diff --git a/security/nss/external_tests/ssl_gtest/tls_connect.cc b/security/nss/external_tests/ssl_gtest/tls_connect.cc index 6101b271a796..5200c39ee069 100644 --- a/security/nss/external_tests/ssl_gtest/tls_connect.cc +++ b/security/nss/external_tests/ssl_gtest/tls_connect.cc @@ -52,8 +52,8 @@ static std::string VersionString(uint16_t version) { TlsConnectTestBase::TlsConnectTestBase(Mode mode, uint16_t version) : mode_(mode), - client_(new TlsAgent("client", TlsAgent::CLIENT, mode_)), - server_(new TlsAgent("server", TlsAgent::SERVER, mode_)), + client_(new TlsAgent("client", TlsAgent::CLIENT, mode_, ssl_kea_rsa)), + server_(new TlsAgent("server", TlsAgent::SERVER, mode_, ssl_kea_rsa)), version_(version), session_ids_() { std::cerr << "Version: " << mode_ << " " << VersionString(version_) << std::endl; @@ -84,8 +84,8 @@ void TlsConnectTestBase::TearDown() { } void TlsConnectTestBase::Init() { - ASSERT_TRUE(client_->Init()); - ASSERT_TRUE(server_->Init()); + EXPECT_TRUE(client_->Init()); + EXPECT_TRUE(server_->Init()); client_->SetPeer(server_); server_->SetPeer(client_); @@ -96,19 +96,28 @@ void TlsConnectTestBase::Init() { } } -void TlsConnectTestBase::Reset() { +void TlsConnectTestBase::Reset(const std::string& server_name, SSLKEAType kea) { delete client_; delete server_; - client_ = new TlsAgent("client", TlsAgent::CLIENT, mode_); - server_ = new TlsAgent("server", TlsAgent::SERVER, mode_); + client_ = new TlsAgent("client", TlsAgent::CLIENT, mode_, kea); + server_ = new TlsAgent(server_name, TlsAgent::SERVER, mode_, kea); Init(); } +void TlsConnectTestBase::ResetRsa() { + Reset("server", ssl_kea_rsa); +} + +void TlsConnectTestBase::ResetEcdsa() { + Reset("ecdsa", ssl_kea_ecdh); + EnableSomeEcdheCiphers(); +} + void TlsConnectTestBase::EnsureTlsSetup() { - ASSERT_TRUE(client_->EnsureTlsSetup()); - ASSERT_TRUE(server_->EnsureTlsSetup()); + EXPECT_TRUE(client_->EnsureTlsSetup()); + EXPECT_TRUE(server_->EnsureTlsSetup()); } void TlsConnectTestBase::Handshake() { @@ -127,20 +136,20 @@ void TlsConnectTestBase::Connect() { Handshake(); // Check the version is as expected - ASSERT_EQ(client_->version(), server_->version()); - ASSERT_EQ(std::min(client_->max_version(), + EXPECT_EQ(client_->version(), server_->version()); + EXPECT_EQ(std::min(client_->max_version(), server_->max_version()), client_->version()); - ASSERT_EQ(TlsAgent::CONNECTED, client_->state()); - ASSERT_EQ(TlsAgent::CONNECTED, server_->state()); + EXPECT_EQ(TlsAgent::CONNECTED, client_->state()); + EXPECT_EQ(TlsAgent::CONNECTED, server_->state()); int16_t cipher_suite1, cipher_suite2; bool ret = client_->cipher_suite(&cipher_suite1); - ASSERT_TRUE(ret); + EXPECT_TRUE(ret); ret = server_->cipher_suite(&cipher_suite2); - ASSERT_TRUE(ret); - ASSERT_EQ(cipher_suite1, cipher_suite2); + EXPECT_TRUE(ret); + EXPECT_EQ(cipher_suite1, cipher_suite2); std::cerr << "Connected with version " << client_->version() << " cipher suite " << client_->cipher_suite_name() @@ -148,10 +157,10 @@ void TlsConnectTestBase::Connect() { // Check and store session ids. std::vector sid_c1 = client_->session_id(); - ASSERT_EQ(32U, sid_c1.size()); + EXPECT_EQ(32U, sid_c1.size()); std::vector sid_s1 = server_->session_id(); - ASSERT_EQ(32U, sid_s1.size()); - ASSERT_EQ(sid_c1, sid_s1); + EXPECT_EQ(32U, sid_s1.size()); + EXPECT_EQ(sid_c1, sid_s1); session_ids_.push_back(sid_c1); } @@ -162,9 +171,9 @@ void TlsConnectTestBase::ConnectExpectFail() { ASSERT_EQ(TlsAgent::ERROR, server_->state()); } -void TlsConnectTestBase::EnableSomeECDHECiphers() { - client_->EnableSomeECDHECiphers(); - server_->EnableSomeECDHECiphers(); +void TlsConnectTestBase::EnableSomeEcdheCiphers() { + client_->EnableSomeEcdheCiphers(); + server_->EnableSomeEcdheCiphers(); } @@ -175,22 +184,22 @@ void TlsConnectTestBase::ConfigureSessionCache(SessionResumptionMode client, } void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) { - ASSERT_NE(RESUME_BOTH, expected); + EXPECT_NE(RESUME_BOTH, expected); int resume_ct = expected ? 1 : 0; int stateless_ct = (expected & RESUME_TICKET) ? 1 : 0; SSL3Statistics* stats = SSL_GetStatistics(); - ASSERT_EQ(resume_ct, stats->hch_sid_cache_hits); - ASSERT_EQ(resume_ct, stats->hsh_sid_cache_hits); + EXPECT_EQ(resume_ct, stats->hch_sid_cache_hits); + EXPECT_EQ(resume_ct, stats->hsh_sid_cache_hits); - ASSERT_EQ(stateless_ct, stats->hch_sid_stateless_resumes); - ASSERT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes); + EXPECT_EQ(stateless_ct, stats->hch_sid_stateless_resumes); + EXPECT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes); if (resume_ct) { // Check that the last two session ids match. - ASSERT_GE(2U, session_ids_.size()); - ASSERT_EQ(session_ids_[session_ids_.size()-1], + EXPECT_GE(2U, session_ids_.size()); + EXPECT_EQ(session_ids_[session_ids_.size()-1], session_ids_[session_ids_.size()-2]); } } diff --git a/security/nss/external_tests/ssl_gtest/tls_connect.h b/security/nss/external_tests/ssl_gtest/tls_connect.h index a981399f683b..ae8605d474a7 100644 --- a/security/nss/external_tests/ssl_gtest/tls_connect.h +++ b/security/nss/external_tests/ssl_gtest/tls_connect.h @@ -39,8 +39,11 @@ class TlsConnectTestBase : public ::testing::Test { // Initialize client and server. void Init(); - // Re-initialize client and server. - void Reset(); + // Re-initialize client and server with the default RSA cert. + void ResetRsa(); + // Re-initialize client and server with an ECDSA cert on the server + // and some ECDHE suites. + void ResetEcdsa(); // Make sure TLS is configured for a connection. void EnsureTlsSetup(); @@ -51,7 +54,7 @@ class TlsConnectTestBase : public ::testing::Test { // Connect and expect it to fail. void ConnectExpectFail(); - void EnableSomeECDHECiphers(); + void EnableSomeEcdheCiphers(); void ConfigureSessionCache(SessionResumptionMode client, SessionResumptionMode server); void CheckResumption(SessionResumptionMode expected); @@ -65,6 +68,9 @@ class TlsConnectTestBase : public ::testing::Test { TlsAgent* server_; uint16_t version_; std::vector> session_ids_; + + private: + void Reset(const std::string& server_name, SSLKEAType kea); }; // A TLS-only test base. diff --git a/security/nss/external_tests/ssl_gtest/tls_filter.cc b/security/nss/external_tests/ssl_gtest/tls_filter.cc index 4ed74e4aa564..2430cfefda2d 100644 --- a/security/nss/external_tests/ssl_gtest/tls_filter.cc +++ b/security/nss/external_tests/ssl_gtest/tls_filter.cc @@ -67,7 +67,7 @@ size_t TlsRecordFilter::ApplyFilter(uint8_t content_type, uint16_t version, filtered.len() < 0x10000) { *changed = true; std::cerr << "record old: " << record << std::endl; - std::cerr << "record old: " << filtered << std::endl; + std::cerr << "record new: " << filtered << std::endl; source = &filtered; } @@ -96,11 +96,7 @@ bool TlsHandshakeFilter::FilterRecord(uint8_t content_type, uint16_t version, return false; // malformed } uint32_t length; - if (!parser.Read(&length, 3)) { - return false; // malformed - } - - if (IsDtls(version) && !CheckDtls(parser, length)) { + if (!ReadLength(&parser, version, &length)) { return false; } @@ -125,24 +121,32 @@ bool TlsHandshakeFilter::FilterRecord(uint8_t content_type, uint16_t version, return changed; } -bool TlsHandshakeFilter::CheckDtls(TlsParser& parser, size_t length) { +bool TlsHandshakeFilter::ReadLength(TlsParser* parser, uint16_t version, uint32_t *length) { + if (!parser->Read(length, 3)) { + return false; // malformed + } + + if (!IsDtls(version)) { + return true; // nothing left to do + } + // Read and check DTLS parameters - if (!parser.Skip(2)) { // sequence number + if (!parser->Skip(2)) { // sequence number return false; } uint32_t fragment_offset; - if (!parser.Read(&fragment_offset, 3)) { + if (!parser->Read(&fragment_offset, 3)) { return false; } uint32_t fragment_length; - if (!parser.Read(&fragment_length, 3)) { + if (!parser->Read(&fragment_length, 3)) { return false; } // All current tests where we are using this code don't fragment. - return (fragment_offset == 0 && fragment_length == length); + return (fragment_offset == 0 && fragment_length == *length); } size_t TlsHandshakeFilter::ApplyFilter( diff --git a/security/nss/external_tests/ssl_gtest/tls_filter.h b/security/nss/external_tests/ssl_gtest/tls_filter.h index 7ebd2c48220d..49593b363816 100644 --- a/security/nss/external_tests/ssl_gtest/tls_filter.h +++ b/security/nss/external_tests/ssl_gtest/tls_filter.h @@ -43,6 +43,10 @@ class TlsHandshakeFilter : public TlsRecordFilter { public: TlsHandshakeFilter() {} + // Reads the length from the record header. + // This also reads the DTLS fragment information and checks it. + static bool ReadLength(TlsParser* parser, uint16_t version, uint32_t *length); + protected: virtual bool FilterRecord(uint8_t content_type, uint16_t version, const DataBuffer& input, DataBuffer* output); @@ -50,7 +54,6 @@ class TlsHandshakeFilter : public TlsRecordFilter { const DataBuffer& input, DataBuffer* output) = 0; private: - bool CheckDtls(TlsParser& parser, size_t length); size_t ApplyFilter(uint16_t version, uint8_t handshake_type, const DataBuffer& record, DataBuffer* output, size_t length_offset, size_t value_offset, bool* changed); diff --git a/security/nss/external_tests/ssl_gtest/tls_parser.h b/security/nss/external_tests/ssl_gtest/tls_parser.h index 9ac4bdabea03..3e6ac24c68d0 100644 --- a/security/nss/external_tests/ssl_gtest/tls_parser.h +++ b/security/nss/external_tests/ssl_gtest/tls_parser.h @@ -15,23 +15,24 @@ namespace nss_test { -const uint8_t kTlsChangeCipherSpecType = 0x14; -const uint8_t kTlsAlertType = 0x15; -const uint8_t kTlsHandshakeType = 0x16; +const uint8_t kTlsChangeCipherSpecType = 20; +const uint8_t kTlsAlertType = 21; +const uint8_t kTlsHandshakeType = 22; -const uint8_t kTlsHandshakeClientHello = 0x01; -const uint8_t kTlsHandshakeServerHello = 0x02; -const uint8_t kTlsHandshakeCertificate = 0x0b; -const uint8_t kTlsHandshakeServerKeyExchange = 0x0c; +const uint8_t kTlsHandshakeClientHello = 1; +const uint8_t kTlsHandshakeServerHello = 2; +const uint8_t kTlsHandshakeCertificate = 11; +const uint8_t kTlsHandshakeServerKeyExchange = 12; const uint8_t kTlsAlertWarning = 1; const uint8_t kTlsAlertFatal = 2; -const uint8_t kTlsAlertHandshakeFailure = 0x28; -const uint8_t kTlsAlertIllegalParameter = 0x2f; -const uint8_t kTlsAlertDecodeError = 0x32; -const uint8_t kTlsAlertUnsupportedExtension = 0x6e; -const uint8_t kTlsAlertNoApplicationProtocol = 0x78; +const uint8_t kTlsAlertUnexpectedMessage = 10; +const uint8_t kTlsAlertHandshakeFailure = 40; +const uint8_t kTlsAlertIllegalParameter = 47; +const uint8_t kTlsAlertDecodeError = 50; +const uint8_t kTlsAlertUnsupportedExtension = 110; +const uint8_t kTlsAlertNoApplicationProtocol = 120; const uint8_t kTlsFakeChangeCipherSpec[] = { kTlsChangeCipherSpecType, // Type diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 6e0bdb0892fc..4564dc2ddecb 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -1172,6 +1172,20 @@ CERT_GetNextGeneralName(CERTGeneralName *current); extern CERTGeneralName * CERT_GetPrevGeneralName(CERTGeneralName *current); +/* + * Look up name constraints for some certs that do not include name constraints + * (Most importantly, root certificates) + * + * If a matching subject is found, |extensions| will be populated with a copy of the + * DER-encoded name constraints extension. The data in |extensions| will point to + * memory that the caller owns. + * + * There is no mechanism to configure imposed name constraints right now. All + * imposed name constraints are built into NSS. + */ +SECStatus +CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions); + CERTNameConstraint * CERT_GetNextNameConstraint(CERTNameConstraint *current); @@ -1543,6 +1557,9 @@ CERT_CheckNameSpace(PLArenaPool *arena, /* * Extract and allocate the name constraints extension from the CA cert. + * If the certificate contains no name constraints extension, but + * CERT_GetImposedNameConstraints returns a name constraints extension + * for the subject of the certificate, then that extension will be returned. */ extern SECStatus CERT_FindNameConstraintsExten(PLArenaPool *arena, diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h index 4f3c91166abb..d8b559c7f87b 100644 --- a/security/nss/lib/certdb/certt.h +++ b/security/nss/lib/certdb/certt.h @@ -186,7 +186,7 @@ struct CERTSubjectListStr { struct CERTCertificateStr { /* the arena is used to allocate any data structures that have the same * lifetime as the cert. This is all stuff that hangs off of the cert - * structure, and is all freed at the same time. I is used when the + * structure, and is all freed at the same time. It is used when the * cert is decoded, destroyed, and at some times when it changes * state */ diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c index 1b0cc9704894..e3bc11d59109 100644 --- a/security/nss/lib/certdb/genname.c +++ b/security/nss/lib/certdb/genname.c @@ -1556,76 +1556,98 @@ done: return rv; } -/* Add name constraints to certain certs that do not include name constraints - * This is the core of the implementation for bug 952572. +/* + * Here we define a list of name constraints to be imposed on + * certain certificates, most importantly root certificates. + * + * Each entry in the name constraints list is constructed with this + * macro. An entry contains two SECItems, which have names in + * specific forms to make the macro work: + * + * * ${CA}_SUBJECT_DN - The subject DN for which the constraints + * should be applied + * * ${CA}_NAME_CONSTRAINTS - The name constraints extension + * + * Entities subject to name constraints are identified by subject name + * so that we can cover all certificates for that entity, including, e.g., + * cross-certificates. We use subject rather than public key because + * calling methods often have easy access to that field (vs., say, a key ID), + * and in practice, subject names and public keys are usually in one-to-one + * correspondence anyway. + * */ -static SECStatus -getNameExtensionsBuiltIn(CERTCertificate *cert, - SECItem *extensions) +#define STRING_TO_SECITEM(str) \ +{ siBuffer, (unsigned char*) str, sizeof(str) - 1 } + +#define NAME_CONSTRAINTS_ENTRY(CA) \ + { \ + STRING_TO_SECITEM(CA ## _SUBJECT_DN), \ + STRING_TO_SECITEM(CA ## _NAME_CONSTRAINTS) \ + } + +/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ + +#define ANSSI_SUBJECT_DN \ + "\x30\x81\x85" \ + "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \ + "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \ + "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \ + "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \ + "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \ + "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \ + "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \ + "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \ + +#define ANSSI_NAME_CONSTRAINTS \ + "\x30\x5D\xA0\x5B" \ + "\x30\x05\x82\x03" ".fr" \ + "\x30\x05\x82\x03" ".gp" \ + "\x30\x05\x82\x03" ".gf" \ + "\x30\x05\x82\x03" ".mq" \ + "\x30\x05\x82\x03" ".re" \ + "\x30\x05\x82\x03" ".yt" \ + "\x30\x05\x82\x03" ".pm" \ + "\x30\x05\x82\x03" ".bl" \ + "\x30\x05\x82\x03" ".mf" \ + "\x30\x05\x82\x03" ".wf" \ + "\x30\x05\x82\x03" ".pf" \ + "\x30\x05\x82\x03" ".nc" \ + "\x30\x05\x82\x03" ".tf" \ + +static const SECItem builtInNameConstraints[][2] = { + NAME_CONSTRAINTS_ENTRY(ANSSI) +}; + +SECStatus +CERT_GetImposedNameConstraints(const SECItem *derSubject, + SECItem *extensions) { - const char constraintFranceGov[] = "\x30\x5D" /* sequence len = 93*/ - "\xA0\x5B" /* element len =91 */ - "\x30\x05" /* sequence len 5 */ - "\x82\x03" /* entry len 3 */ - ".fr" - "\x30\x05\x82\x03" /* sequence len5, entry len 3 */ - ".gp" - "\x30\x05\x82\x03" - ".gf" - "\x30\x05\x82\x03" - ".mq" - "\x30\x05\x82\x03" - ".re" - "\x30\x05\x82\x03" - ".yt" - "\x30\x05\x82\x03" - ".pm" - "\x30\x05\x82\x03" - ".bl" - "\x30\x05\x82\x03" - ".mf" - "\x30\x05\x82\x03" - ".wf" - "\x30\x05\x82\x03" - ".pf" - "\x30\x05\x82\x03" - ".nc" - "\x30\x05\x82\x03" - ".tf"; + size_t i; - /* The stringified value for the subject is: - E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR - */ - const char rawANSSISubject[] = "\x30\x81\x85\x31\x0B\x30\x09\x06\x03\x55\x04" - "\x06\x13\x02\x46\x52\x31\x0F\x30\x0D\x06\x03" - "\x55\x04\x08\x13\x06\x46\x72\x61\x6E\x63\x65" - "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" - "\x50\x61\x72\x69\x73\x31\x10\x30\x0E\x06\x03" - "\x55\x04\x0A\x13\x07\x50\x4D\x2F\x53\x47\x44" - "\x4E\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13" - "\x05\x44\x43\x53\x53\x49\x31\x0E\x30\x0C\x06" - "\x03\x55\x04\x03\x13\x05\x49\x47\x43\x2F\x41" - "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7" - "\x0D\x01\x09\x01\x16\x14\x69\x67\x63\x61\x40" - "\x73\x67\x64\x6E\x2E\x70\x6D\x2E\x67\x6F\x75" - "\x76\x2E\x66\x72"; + if (!extensions) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } - const SECItem anssi_subject = {0, (unsigned char *) rawANSSISubject, - sizeof(rawANSSISubject)-1}; - const SECItem permitFranceGovNC = {0, (unsigned char *) constraintFranceGov, - sizeof(constraintFranceGov)-1}; + for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) { + if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) { + return SECITEM_CopyItem(NULL, + extensions, + &builtInNameConstraints[i][1]); + } + } - if (SECITEM_ItemsAreEqual(&cert->derSubject, &anssi_subject)) { - SECStatus rv; - rv = SECITEM_CopyItem(NULL, extensions, &permitFranceGovNC); - return rv; - } - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); - return SECFailure; + PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); + return SECFailure; } -/* Extract the name constraints extension from the CA cert. */ +/* + * Extract the name constraints extension from the CA cert. + * If the certificate contains no name constraints extension, but + * CERT_GetImposedNameConstraints returns a name constraints extension + * for the subject of the certificate, then that extension will be returned. + */ SECStatus CERT_FindNameConstraintsExten(PLArenaPool *arena, CERTCertificate *cert, @@ -1643,7 +1665,8 @@ CERT_FindNameConstraintsExten(PLArenaPool *arena, if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { return rv; } - rv = getNameExtensionsBuiltIn(cert, &constraintsExtension); + rv = CERT_GetImposedNameConstraints(&cert->derSubject, + &constraintsExtension); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { return SECSuccess; diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index 004588633726..84b750489765 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -17340,149 +17340,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -# -# Certificate "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" -# -# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi,O=Elektronik Bilgi Guvenligi A.S.,C=TR -# Serial Number:44:99:8d:3c:c0:03:27:bd:9c:76:95:b9:ea:db:ac:b5 -# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi,O=Elektronik Bilgi Guvenligi A.S.,C=TR -# Not Valid Before: Thu Jan 04 11:32:48 2007 -# Not Valid After : Wed Jan 04 11:32:48 2017 -# Fingerprint (MD5): 3D:41:29:CB:1E:AA:11:74:CD:5D:B0:62:AF:B0:43:5B -# Fingerprint (SHA1): DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\165\061\013\060\011\006\003\125\004\006\023\002\124\122\061 -\050\060\046\006\003\125\004\012\023\037\105\154\145\153\164\162 -\157\156\151\153\040\102\151\154\147\151\040\107\165\166\145\156 -\154\151\147\151\040\101\056\123\056\061\074\060\072\006\003\125 -\004\003\023\063\145\055\107\165\166\145\156\040\113\157\153\040 -\105\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151 -\146\151\153\141\040\110\151\172\155\145\164\040\123\141\147\154 -\141\171\151\143\151\163\151 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\165\061\013\060\011\006\003\125\004\006\023\002\124\122\061 -\050\060\046\006\003\125\004\012\023\037\105\154\145\153\164\162 -\157\156\151\153\040\102\151\154\147\151\040\107\165\166\145\156 -\154\151\147\151\040\101\056\123\056\061\074\060\072\006\003\125 -\004\003\023\063\145\055\107\165\166\145\156\040\113\157\153\040 -\105\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151 -\146\151\153\141\040\110\151\172\155\145\164\040\123\141\147\154 -\141\171\151\143\151\163\151 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\104\231\215\074\300\003\047\275\234\166\225\271\352\333 -\254\265 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\266\060\202\002\236\240\003\002\001\002\002\020\104 -\231\215\074\300\003\047\275\234\166\225\271\352\333\254\265\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\165 -\061\013\060\011\006\003\125\004\006\023\002\124\122\061\050\060 -\046\006\003\125\004\012\023\037\105\154\145\153\164\162\157\156 -\151\153\040\102\151\154\147\151\040\107\165\166\145\156\154\151 -\147\151\040\101\056\123\056\061\074\060\072\006\003\125\004\003 -\023\063\145\055\107\165\166\145\156\040\113\157\153\040\105\154 -\145\153\164\162\157\156\151\153\040\123\145\162\164\151\146\151 -\153\141\040\110\151\172\155\145\164\040\123\141\147\154\141\171 -\151\143\151\163\151\060\036\027\015\060\067\060\061\060\064\061 -\061\063\062\064\070\132\027\015\061\067\060\061\060\064\061\061 -\063\062\064\070\132\060\165\061\013\060\011\006\003\125\004\006 -\023\002\124\122\061\050\060\046\006\003\125\004\012\023\037\105 -\154\145\153\164\162\157\156\151\153\040\102\151\154\147\151\040 -\107\165\166\145\156\154\151\147\151\040\101\056\123\056\061\074 -\060\072\006\003\125\004\003\023\063\145\055\107\165\166\145\156 -\040\113\157\153\040\105\154\145\153\164\162\157\156\151\153\040 -\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145\164 -\040\123\141\147\154\141\171\151\143\151\163\151\060\202\001\042 -\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 -\202\001\017\000\060\202\001\012\002\202\001\001\000\303\022\040 -\236\260\136\000\145\215\116\106\273\200\134\351\054\006\227\325 -\363\162\311\160\271\347\113\145\200\301\113\276\176\074\327\124 -\061\224\336\325\022\272\123\026\002\352\130\143\357\133\330\363 -\355\052\032\252\161\110\243\334\020\055\137\137\353\134\113\234 -\226\010\102\045\050\021\314\212\132\142\001\120\325\353\011\123 -\057\370\303\217\376\263\374\375\235\242\343\137\175\276\355\013 -\340\140\353\151\354\063\355\330\215\373\022\111\203\000\311\213 -\227\214\073\163\052\062\263\022\367\271\115\362\364\115\155\307 -\346\326\046\067\010\362\331\375\153\134\243\345\110\134\130\274 -\102\276\003\132\201\272\034\065\014\000\323\365\043\176\161\060 -\010\046\070\334\045\021\107\055\363\272\043\020\245\277\274\002 -\367\103\136\307\376\260\067\120\231\173\017\223\316\346\103\054 -\303\176\015\362\034\103\146\140\313\141\061\107\207\243\117\256 -\275\126\154\114\274\274\370\005\312\144\364\351\064\241\054\265 -\163\341\302\076\350\310\311\064\045\010\134\363\355\246\307\224 -\237\255\210\103\045\327\341\071\140\376\254\071\131\002\003\001 -\000\001\243\102\060\100\060\016\006\003\125\035\017\001\001\377 -\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377 -\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026 -\004\024\237\356\104\263\224\325\372\221\117\056\331\125\232\004 -\126\333\055\304\333\245\060\015\006\011\052\206\110\206\367\015 -\001\001\005\005\000\003\202\001\001\000\177\137\271\123\133\143 -\075\165\062\347\372\304\164\032\313\106\337\106\151\034\122\317 -\252\117\302\150\353\377\200\251\121\350\075\142\167\211\075\012 -\165\071\361\156\135\027\207\157\150\005\301\224\154\331\135\337 -\332\262\131\313\245\020\212\312\314\071\315\237\353\116\336\122 -\377\014\360\364\222\251\362\154\123\253\233\322\107\240\037\164 -\367\233\232\361\057\025\237\172\144\060\030\007\074\052\017\147 -\312\374\017\211\141\235\145\245\074\345\274\023\133\010\333\343 -\377\355\273\006\273\152\006\261\172\117\145\306\202\375\036\234 -\213\265\015\356\110\273\270\275\252\010\264\373\243\174\313\237 -\315\220\166\134\206\226\170\127\012\146\371\130\032\235\375\227 -\051\140\336\021\246\220\034\031\034\356\001\226\042\064\064\056 -\221\371\267\304\047\321\173\346\277\373\200\104\132\026\345\353 -\340\324\012\070\274\344\221\343\325\353\134\301\254\337\033\152 -\174\236\345\165\322\266\227\207\333\314\207\053\103\072\204\010 -\257\253\074\333\367\074\146\061\206\260\235\123\171\355\370\043 -\336\102\343\055\202\361\017\345\372\227 -END - -# Trust for Certificate "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" -# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi,O=Elektronik Bilgi Guvenligi A.S.,C=TR -# Serial Number:44:99:8d:3c:c0:03:27:bd:9c:76:95:b9:ea:db:ac:b5 -# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi,O=Elektronik Bilgi Guvenligi A.S.,C=TR -# Not Valid Before: Thu Jan 04 11:32:48 2007 -# Not Valid After : Wed Jan 04 11:32:48 2017 -# Fingerprint (MD5): 3D:41:29:CB:1E:AA:11:74:CD:5D:B0:62:AF:B0:43:5B -# Fingerprint (SHA1): DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\335\341\322\251\001\200\056\035\207\136\204\263\200\176\113\261 -\375\231\101\064 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\075\101\051\313\036\252\021\164\315\135\260\142\257\260\103\133 -END -CKA_ISSUER MULTILINE_OCTAL -\060\165\061\013\060\011\006\003\125\004\006\023\002\124\122\061 -\050\060\046\006\003\125\004\012\023\037\105\154\145\153\164\162 -\157\156\151\153\040\102\151\154\147\151\040\107\165\166\145\156 -\154\151\147\151\040\101\056\123\056\061\074\060\072\006\003\125 -\004\003\023\063\145\055\107\165\166\145\156\040\113\157\153\040 -\105\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151 -\146\151\153\141\040\110\151\172\155\145\164\040\123\141\147\154 -\141\171\151\143\151\163\151 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\104\231\215\074\300\003\047\275\234\166\225\271\352\333 -\254\265 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - # # Certificate "GlobalSign Root CA - R3" # diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h index e0131611cbf5..baa754707e87 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.h +++ b/security/nss/lib/ckfw/builtins/nssckbi.h @@ -45,8 +45,8 @@ * of the comment in the CK_VERSION type definition. */ #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2 -#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 3 -#define NSS_BUILTINS_LIBRARY_VERSION "2.3" +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 4 +#define NSS_BUILTINS_LIBRARY_VERSION "2.4" /* These version numbers detail the semantic changes to the ckfw engine. */ #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c index 4b5c54986c26..d619360aa094 100644 --- a/security/nss/lib/freebl/mpi/mpmontg.c +++ b/security/nss/lib/freebl/mpi/mpmontg.c @@ -883,8 +883,8 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, int expOff; mp_int accum1, accum2, accum[WEAVE_WORD_SIZE]; mp_int tmp; - unsigned char *powersArray; - unsigned char *powers; + unsigned char *powersArray = NULL; + unsigned char *powers = NULL; MP_DIGITS(&accum1) = 0; MP_DIGITS(&accum2) = 0; @@ -894,15 +894,6 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, MP_DIGITS(&accum[3]) = 0; MP_DIGITS(&tmp) = 0; - powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1)); - if (powersArray == NULL) { - res = MP_MEM; - goto CLEANUP; - } - - /* powers[i] = base ** (i); */ - powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); - /* grab the first window value. This allows us to preload accumulator1 * and save a conversion, some squares and a multiple*/ MP_CHECKOK( mpl_get_bits(exponent, @@ -911,7 +902,6 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) ); MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) ); - MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) ); /* build the first WEAVE_WORD powers inline */ /* if WEAVE_WORD_SIZE is not 4, this code will have to change */ @@ -925,6 +915,13 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, MP_CHECKOK( mp_copy(montBase, &accum[1]) ); SQR(montBase, &accum[2]); MUL_NOWEAVE(montBase, &accum[2], &accum[3]); + powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1)); + if (!powersArray) { + res = MP_MEM; + goto CLEANUP; + } + /* powers[i] = base ** (i); */ \ + powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); \ MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) ); if (first_window < 4) { MP_CHECKOK( mp_copy(&accum[first_window], &accum1) ); @@ -946,7 +943,10 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, * odd powers where k is the window size in the two other mp_modexpt * implementations in this file. We will get some of that * back by not needing the first 'k' squares and one multiply for the - * first window */ + * first window. + * Given the value of 4 for WEAVE_WORD_SIZE, this loop will only execute if + * num_powers > 2, in which case powers will have been allocated. + */ for (i = WEAVE_WORD_SIZE; i < num_powers; i++) { int acc_index = i & (WEAVE_WORD_SIZE-1); /* i % WEAVE_WORD_SIZE */ if ( i & 1 ) { @@ -993,6 +993,11 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, pa1 = &accum1; pa2 = &accum2; + /* tmp is not used if window_bits == 1. */ + if (window_bits != 1) { + MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) ); + } + for (expOff = bits_in_exponent - window_bits*2; expOff >= 0; expOff -= window_bits) { mp_size smallExp; MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) ); diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c index 697151548591..d459a4a7bae8 100644 --- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c @@ -1132,8 +1132,6 @@ pkix_pl_HttpDefaultClient_KeepAliveSession( PRPollDesc **pPollDesc, void *plContext) { - PKIX_PL_HttpDefaultClient *client = NULL; - PKIX_ENTER (HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_KeepAliveSession"); @@ -1145,8 +1143,6 @@ pkix_pl_HttpDefaultClient_KeepAliveSession( plContext), PKIX_SESSIONNOTANHTTPDEFAULTCLIENT); - client = (PKIX_PL_HttpDefaultClient *)session; - /* XXX Not implemented */ cleanup: diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c index 48d810feb449..2dfe9a9c2c8b 100644 --- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c @@ -211,7 +211,6 @@ pkix_pl_PublicKey_Hashcode( PKIX_UInt32 algOIDHash; PKIX_UInt32 algParamsHash; PKIX_UInt32 pubKeyHash; - PKIX_UInt32 fullHash; PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Hashcode"); PKIX_NULLCHECK_TWO(object, pHashcode); @@ -239,8 +238,6 @@ pkix_pl_PublicKey_Hashcode( (nssPubKey.data, nssPubKey.len, &pubKeyHash, plContext), PKIX_HASHFAILED); - fullHash = algOIDHash + algParamsHash + pubKeyHash; - *pHashcode = pubKeyHash; cleanup: diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index abe0604f5d95..fdc8a8a152aa 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1070,3 +1070,9 @@ SEC_GetCrlTimes; ;+ local: ;+ *; ;+}; +;+NSS_3.18.1 { # NSS 3.18.1 release +;+ global: +CERT_GetImposedNameConstraints; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index bb4d208154f2..31e4bce91389 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -33,10 +33,10 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.18.1" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta" +#define NSS_VERSION "3.19" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta" #define NSS_VMAJOR 3 -#define NSS_VMINOR 18 -#define NSS_VPATCH 1 +#define NSS_VMINOR 19 +#define NSS_VPATCH 0 #define NSS_VBUILD 0 #define NSS_BETA PR_TRUE diff --git a/security/nss/lib/smime/cmsmessage.c b/security/nss/lib/smime/cmsmessage.c index 72026e6ca924..a44fb0b5ce50 100644 --- a/security/nss/lib/smime/cmsmessage.c +++ b/security/nss/lib/smime/cmsmessage.c @@ -28,26 +28,26 @@ NSS_CMSMessage_Create(PLArenaPool *poolp) PRBool poolp_is_ours = PR_FALSE; if (poolp == NULL) { - poolp = PORT_NewArena (1024); /* XXX what is right value? */ - if (poolp == NULL) - return NULL; - poolp_is_ours = PR_TRUE; - } + poolp = PORT_NewArena (1024); /* XXX what is right value? */ + if (poolp == NULL) + return NULL; + poolp_is_ours = PR_TRUE; + } if (!poolp_is_ours) - mark = PORT_ArenaMark(poolp); + mark = PORT_ArenaMark(poolp); - cmsg = (NSSCMSMessage *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSMessage)); - if (cmsg == NULL) { - if (!poolp_is_ours) { - if (mark) { - PORT_ArenaRelease(poolp, mark); - } - } else - PORT_FreeArena(poolp, PR_FALSE); - return NULL; + cmsg = (NSSCMSMessage *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSMessage)); + if (cmsg == NULL || + NSS_CMSContentInfo_Private_Init(&(cmsg->contentInfo)) != SECSuccess) { + if (!poolp_is_ours) { + if (mark) { + PORT_ArenaRelease(poolp, mark); + } + } else + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } - NSS_CMSContentInfo_Private_Init(&(cmsg->contentInfo)); cmsg->poolp = poolp; cmsg->poolp_is_ours = poolp_is_ours; diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index 67075e613970..5643b0202403 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -25,10 +25,10 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.18.1" SOFTOKEN_ECC_STRING " Beta" +#define SOFTOKEN_VERSION "3.19" SOFTOKEN_ECC_STRING " Beta" #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 18 -#define SOFTOKEN_VPATCH 1 +#define SOFTOKEN_VMINOR 19 +#define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VBUILD 0 #define SOFTOKEN_BETA PR_TRUE diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 492b321fe252..163572c12b69 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -284,30 +284,30 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = { {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0}, }; -static const ssl3KEADef kea_defs[] = +static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */ - /* kea exchKeyType signKeyType is_limited limit tls_keygen */ - {kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE}, - {kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE}, - {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE}, - {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE}, - {kea_dh_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE}, - {kea_dh_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE}, - {kea_dh_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE}, - {kea_dh_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE}, - {kea_dhe_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE}, - {kea_dhe_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE}, - {kea_dhe_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE}, - {kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE}, - {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE}, - {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE}, - {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE }, + /* 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_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}, + {kea_dh_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_FALSE}, + {kea_dhe_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE, PR_TRUE}, + {kea_dhe_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE, PR_TRUE}, + {kea_dhe_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_TRUE}, + {kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_TRUE}, + {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE, PR_TRUE}, + {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE, PR_TRUE}, + {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE, PR_FALSE}, #ifndef NSS_DISABLE_ECC - {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE}, - {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE}, - {kea_ecdh_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE}, - {kea_ecdhe_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE}, - {kea_ecdh_anon, kt_ecdh, sign_null, PR_FALSE, 0, PR_FALSE}, + {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE, PR_FALSE}, + {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE, PR_TRUE}, + {kea_ecdh_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE}, + {kea_ecdhe_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_TRUE}, + {kea_ecdh_anon, kt_ecdh, sign_null, PR_FALSE, 0, PR_FALSE, PR_TRUE}, #endif /* NSS_DISABLE_ECC */ }; @@ -4987,23 +4987,17 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) sidOK = PR_FALSE; } - /* TLS 1.0 (RFC 2246) Appendix E says: - * Whenever a client already knows the highest protocol known to - * a server (for example, when resuming a session), it should - * initiate the connection in that native protocol. - * So we pass sid->version to ssl3_NegotiateVersion() here, except - * when renegotiating. - * - * Windows SChannel compares the client_version inside the RSA - * EncryptedPreMasterSecret of a renegotiation with the - * client_version of the initial ClientHello rather than the - * ClientHello in the renegotiation. To work around this bug, we - * continue to use the client_version used in the initial - * ClientHello when renegotiating. - */ if (sidOK) { + /* Set ss->version based on the session cache */ if (ss->firstHsDone) { /* + * Windows SChannel compares the client_version inside the RSA + * EncryptedPreMasterSecret of a renegotiation with the + * client_version of the initial ClientHello rather than the + * ClientHello in the renegotiation. To work around this bug, we + * continue to use the client_version used in the initial + * ClientHello when renegotiating. + * * The client_version of the initial ClientHello is still * available in ss->clientHelloVersion. Ensure that * sid->version is bounded within @@ -5017,10 +5011,22 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) sidOK = PR_FALSE; } } else { - if (ssl3_NegotiateVersion(ss, sid->version, - PR_FALSE) != SECSuccess) { + /* + * Check sid->version is OK first. + * Previously, we would cap the version based on sid->version, + * but that prevents negotiation of a higher version if the + * previous session was reduced (e.g., with version fallback) + */ + if (sid->version < ss->vrange.min || + sid->version > ss->vrange.max) { sidOK = PR_FALSE; - } + } else { + rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, + PR_TRUE); + if (rv != SECSuccess) { + return rv; /* error code was set */ + } + } } } @@ -6575,7 +6581,16 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len); ss->ssl3.hs.isResuming = PR_FALSE; - ss->ssl3.hs.ws = wait_server_cert; + 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. */ + 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; + } return SECSuccess; alert_loser: @@ -6634,16 +6649,10 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); - if (ss->ssl3.hs.ws != wait_server_key && - ss->ssl3.hs.ws != wait_server_cert) { - errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; - desc = unexpected_message; - goto alert_loser; - } - if (ss->sec.peerCert == NULL) { - errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; - desc = unexpected_message; - goto alert_loser; + if (ss->ssl3.hs.ws != wait_server_key) { + errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; + desc = unexpected_message; + goto alert_loser; } isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); @@ -6870,7 +6879,6 @@ no_memory: /* no-memory error has already been set. */ return SECFailure; } - /* * Returns the TLS signature algorithm for the client authentication key and * whether it is an RSA or DSA key that may be able to sign only SHA-1 hashes. @@ -6998,11 +7006,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); - if (ss->ssl3.hs.ws != wait_cert_request && - ss->ssl3.hs.ws != wait_server_key) { - desc = unexpected_message; - errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST; - goto alert_loser; + if (ss->ssl3.hs.ws != wait_cert_request) { + desc = unexpected_message; + errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST; + goto alert_loser; } PORT_Assert(ss->ssl3.clientCertChain == NULL); @@ -7251,9 +7258,8 @@ ssl3_HandleServerHelloDone(sslSocket *ss) PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); + /* Skipping CertificateRequest is always permitted. */ if (ws != wait_hello_done && - ws != wait_server_cert && - ws != wait_server_key && ws != wait_cert_request) { SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); @@ -7589,14 +7595,11 @@ ssl3_SendServerHelloSequence(sslSocket *ss) return rv; #endif } -#ifndef NSS_DISABLE_ECC - } else if ((kea_def->kea == kea_ecdhe_rsa) || - (kea_def->kea == kea_ecdhe_ecdsa)) { - rv = ssl3_SendServerKeyExchange(ss); - if (rv != SECSuccess) { - return rv; /* err code was set. */ - } -#endif /* NSS_DISABLE_ECC */ + } else if (kea_def->ephemeral) { + rv = ssl3_SendServerKeyExchange(ss); + if (rv != SECSuccess) { + return rv; /* err code was set. */ + } } if (ss->opt.requestCertificate) { @@ -7648,6 +7651,21 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert( ss->ssl3.initialized ); + if (!ss->sec.isServer || + (ss->ssl3.hs.ws != wait_client_hello && + ss->ssl3.hs.ws != idle_handshake)) { + desc = unexpected_message; + errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO; + goto alert_loser; + } + if (ss->ssl3.hs.ws == idle_handshake && + ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) { + desc = no_renegotiation; + level = alert_warning; + errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; + goto alert_loser; + } + /* Get peer name of client */ rv = ssl_GetPeerInfo(ss); if (rv != SECSuccess) { @@ -7674,20 +7692,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData)); ss->statelessResume = PR_FALSE; - if ((ss->ssl3.hs.ws != wait_client_hello) && - (ss->ssl3.hs.ws != idle_handshake)) { - desc = unexpected_message; - errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO; - goto alert_loser; - } - if (ss->ssl3.hs.ws == idle_handshake && - ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) { - desc = no_renegotiation; - level = alert_warning; - errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; - goto alert_loser; - } - if (IS_DTLS(ss)) { dtls_RehandshakeCleanup(ss); } @@ -9053,7 +9057,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); - if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) { + if (ss->ssl3.hs.ws != wait_cert_verify) { desc = unexpected_message; errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY; goto alert_loser; @@ -9839,11 +9843,11 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); - if ((ss->ssl3.hs.ws != wait_server_cert) && - (ss->ssl3.hs.ws != wait_client_cert)) { - desc = unexpected_message; - errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE; - goto alert_loser; + if ((isServer && ss->ssl3.hs.ws != wait_client_cert) || + (!isServer && ss->ssl3.hs.ws != wait_server_cert)) { + desc = unexpected_message; + errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE; + goto alert_loser; } if (ss->sec.peerCert != NULL) { @@ -10082,16 +10086,11 @@ ssl3_AuthCertificate(sslSocket *ss) pubKey = NULL; } - ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ - if (ss->ssl3.hs.kea_def->is_limited || - /* XXX OR server cert is signing only. */ -#ifndef NSS_DISABLE_ECC - ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || - ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || -#endif /* NSS_DISABLE_ECC */ - ss->ssl3.hs.kea_def->exchKeyType == kt_dh) { - ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */ - } + if (ss->ssl3.hs.kea_def->ephemeral) { + ss->ssl3.hs.ws = wait_server_key; /* require server_key_exchange */ + } else { + ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ + } } else { ss->ssl3.hs.ws = wait_client_key; } diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index 896d05a183f7..1b38a523674f 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -725,9 +725,15 @@ typedef struct { SSL3KeyExchangeAlgorithm kea; SSL3KEAType exchKeyType; SSL3SignType signKeyType; + /* For export cipher suites: + * 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; 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. */ + PRBool ephemeral; } ssl3KEADef; /* diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 90bc45729c96..282bb85c5737 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -89,7 +89,7 @@ static sslOptions ssl_defaults = { * default range of enabled SSL/TLS protocols */ static SSLVersionRange versions_defaults_stream = { - SSL_LIBRARY_VERSION_3_0, + SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2 }; diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index 05c2805d0591..a4231754cffa 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -19,10 +19,10 @@ * The format of the version string should be * ".[.[.]][ ]" */ -#define NSSUTIL_VERSION "3.18.1 Beta" +#define NSSUTIL_VERSION "3.19 Beta" #define NSSUTIL_VMAJOR 3 -#define NSSUTIL_VMINOR 18 -#define NSSUTIL_VPATCH 1 +#define NSSUTIL_VMINOR 19 +#define NSSUTIL_VPATCH 0 #define NSSUTIL_VBUILD 0 #define NSSUTIL_BETA PR_TRUE diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh index 8fbcd069b852..1170bc1bac83 100755 --- a/security/nss/tests/all.sh +++ b/security/nss/tests/all.sh @@ -302,7 +302,7 @@ fi # following test for modutil should check for that instead. # Exception: when building softoken only, shlibsign is the # last file created. -if [ ${NSS_BUILD_SOFTOKEN_ONLY} = "1" ]; then +if [ "${NSS_BUILD_SOFTOKEN_ONLY}" = "1" ]; then LAST_FILE_BUILT=shlibsign else LAST_FILE_BUILT=modutil diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh index 9f424ff5cc2f..93316257d205 100755 --- a/security/nss/tests/cert/cert.sh +++ b/security/nss/tests/cert/cert.sh @@ -958,8 +958,23 @@ cert_ssl_gtests() certu -N -d "${SSLGTESTDIR}" --empty-password 2>&1 # the ssl server used here is special: is a self-signed server # certificate with name server. - echo "$SCRIPTNAME: Creating server cert for ssl_gtests" - certu -S -z ${R_NOISE_FILE} -g 2048 -d ${SSLGTESTDIR} -n server -s "CN=server" -t C,C,C -x -m 1 -w -2 -v 120 -Z SHA256 -1 -2 <