diff --git a/security/nss/automation/abi-check/expected-report-libnss3.so.txt b/security/nss/automation/abi-check/expected-report-libnss3.so.txt index e69de29bb..a4c767310 100644 --- a/security/nss/automation/abi-check/expected-report-libnss3.so.txt +++ b/security/nss/automation/abi-check/expected-report-libnss3.so.txt @@ -0,0 +1,5 @@ + +1 Added function: + + 'function SECOidTag HASH_GetHashOidTagByHashType(HASH_HashType)' {HASH_GetHashOidTagByHashType@@NSS_3.43} + diff --git a/security/nss/automation/release/nspr-version.txt b/security/nss/automation/release/nspr-version.txt index 102def16d..b91871c6e 100644 --- a/security/nss/automation/release/nspr-version.txt +++ b/security/nss/automation/release/nspr-version.txt @@ -1,4 +1,4 @@ -4.20 +4.21 # The first line of this file must contain the human readable NSPR # version number, which is the minimum required version of NSPR diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c index a2471884e..2283cdb52 100644 --- a/security/nss/cmd/ssltap/ssltap.c +++ b/security/nss/cmd/ssltap/ssltap.c @@ -2260,7 +2260,6 @@ print_hex(int amt, unsigned char *buf) void Usage(void) { - PR_fprintf(PR_STDERR, "SSLTAP (C) 1997, 1998 Netscape Communications Corporation.\n"); PR_fprintf(PR_STDERR, "Usage: ssltap [-vhfsxl] [-p port] hostname:port\n"); PR_fprintf(PR_STDERR, " -v [prints version string]\n"); PR_fprintf(PR_STDERR, " -h [outputs hex instead of ASCII]\n"); diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 5182f7555..590d1bfae 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,3 +10,4 @@ */ #error "Do not include this header file." + diff --git a/security/nss/gtests/pk11_gtest/pk11_import_unittest.cc b/security/nss/gtests/pk11_gtest/pk11_import_unittest.cc new file mode 100644 index 000000000..a155bbd73 --- /dev/null +++ b/security/nss/gtests/pk11_gtest/pk11_import_unittest.cc @@ -0,0 +1,334 @@ +/* -*- 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 +#include "nss.h" +#include "pk11pub.h" +#include "pk11pqg.h" +#include "prerror.h" +#include "secoid.h" + +#include "cpputil.h" +#include "nss_scoped_ptrs.h" +#include "gtest/gtest.h" +#include "databuffer.h" + +namespace nss_test { + +// This deleter deletes a set of objects, unlike the deleter on +// ScopedPK11GenericObject, which only deletes one. +struct PK11GenericObjectsDeleter { + void operator()(PK11GenericObject* objs) { + if (objs) { + PK11_DestroyGenericObjects(objs); + } + } +}; + +class Pk11KeyImportTestBase : public ::testing::Test { + public: + Pk11KeyImportTestBase(CK_MECHANISM_TYPE mech) : mech_(mech) {} + virtual ~Pk11KeyImportTestBase() = default; + + void SetUp() override { + slot_.reset(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot_); + + static const uint8_t pw[] = "pw"; + SECItem pwItem = {siBuffer, toUcharPtr(pw), sizeof(pw)}; + password_.reset(SECITEM_DupItem(&pwItem)); + } + + void Test() { + // Generate a key and export it. + KeyType key_type; + ScopedSECKEYEncryptedPrivateKeyInfo key_info; + ScopedSECItem public_value; + GenerateAndExport(&key_type, &key_info, &public_value); + ASSERT_NE(nullptr, key_info); + ASSERT_NE(nullptr, public_value); + + // Now import the encrypted key. + static const uint8_t nick[] = "nick"; + SECItem nickname = {siBuffer, toUcharPtr(nick), sizeof(nick)}; + SECKEYPrivateKey* priv_tmp; + SECStatus rv = PK11_ImportEncryptedPrivateKeyInfoAndReturnKey( + slot_.get(), key_info.get(), password_.get(), &nickname, + public_value.get(), PR_TRUE, PR_TRUE, key_type, 0, &priv_tmp, NULL); + ASSERT_EQ(SECSuccess, rv) << "PK11_ImportEncryptedPrivateKeyInfo failed " + << PORT_ErrorToName(PORT_GetError()); + ScopedSECKEYPrivateKey priv_key(priv_tmp); + ASSERT_NE(nullptr, priv_key); + + CheckForPublicKey(priv_key, public_value.get()); + } + + protected: + class ParamHolder { + public: + virtual ~ParamHolder() = default; + virtual void* get() = 0; + }; + + virtual std::unique_ptr MakeParams() = 0; + + CK_MECHANISM_TYPE mech_; + + private: + void CheckForPublicKey(const ScopedSECKEYPrivateKey& priv_key, + const SECItem* expected_public) { + // Verify the public key exists. + StackSECItem priv_id; + SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, priv_key.get(), + CKA_ID, &priv_id); + ASSERT_EQ(SECSuccess, rv) << "Couldn't read CKA_ID from private key: " + << PORT_ErrorToName(PORT_GetError()); + + CK_ATTRIBUTE_TYPE value_type = CKA_VALUE; + switch (SECKEY_GetPrivateKeyType(priv_key.get())) { + case rsaKey: + value_type = CKA_MODULUS; + break; + + case dhKey: + case dsaKey: + value_type = CKA_VALUE; + break; + + case ecKey: + value_type = CKA_EC_POINT; + break; + + default: + FAIL() << "unknown key type"; + } + + std::unique_ptr objs( + PK11_FindGenericObjects(slot_.get(), CKO_PUBLIC_KEY)); + ASSERT_NE(nullptr, objs); + for (PK11GenericObject* obj = objs.get(); obj != nullptr; + obj = PK11_GetNextGenericObject(obj)) { + StackSECItem pub_id; + rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_ID, &pub_id); + if (rv != SECSuccess) { + // Can't read CKA_ID from object. + continue; + } + if (!SECITEM_ItemsAreEqual(&priv_id, &pub_id)) { + // This isn't the object we're looking for. + continue; + } + + StackSECItem token; + rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_TOKEN, &token); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(1U, token.len); + ASSERT_NE(0, token.data[0]); + + StackSECItem value; + rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, value_type, &value); + ASSERT_EQ(SECSuccess, rv); + + // CKA_EC_POINT isn't stable, see Bug 1520649. + if (value_type == CKA_EC_POINT) { + continue; + } + + ASSERT_TRUE(SECITEM_ItemsAreEqual(expected_public, &value)) + << "expected: " + << DataBuffer(expected_public->data, expected_public->len) + << std::endl + << "actual: " << DataBuffer(value.data, value.len) << std::endl; + } + } + + void GenerateAndExport(KeyType* key_type, + ScopedSECKEYEncryptedPrivateKeyInfo* key_info, + ScopedSECItem* public_value) { + auto params = MakeParams(); + ASSERT_NE(nullptr, params); + + SECKEYPublicKey* pub_tmp; + ScopedSECKEYPrivateKey priv_key( + PK11_GenerateKeyPair(slot_.get(), mech_, params->get(), &pub_tmp, + PR_FALSE, PR_TRUE, nullptr)); + ASSERT_NE(nullptr, priv_key) << "PK11_GenerateKeyPair failed: " + << PORT_ErrorToName(PORT_GetError()); + ScopedSECKEYPublicKey pub_key(pub_tmp); + ASSERT_NE(nullptr, pub_key); + + // Wrap and export the key. + ScopedSECKEYEncryptedPrivateKeyInfo epki(PK11_ExportEncryptedPrivKeyInfo( + slot_.get(), SEC_OID_AES_256_CBC, password_.get(), priv_key.get(), 1, + nullptr)); + ASSERT_NE(nullptr, epki) << "PK11_ExportEncryptedPrivKeyInfo failed: " + << PORT_ErrorToName(PORT_GetError()); + + // Save the public value, which we will need on import */ + SECItem* pub_val; + KeyType t = SECKEY_GetPublicKeyType(pub_key.get()); + switch (t) { + case rsaKey: + pub_val = &pub_key->u.rsa.modulus; + break; + case dhKey: + pub_val = &pub_key->u.dh.publicValue; + break; + case dsaKey: + pub_val = &pub_key->u.dsa.publicValue; + break; + case ecKey: + pub_val = &pub_key->u.ec.publicValue; + break; + default: + FAIL() << "Unknown key type"; + } + + CheckForPublicKey(priv_key, pub_val); + + *key_type = t; + key_info->swap(epki); + public_value->reset(SECITEM_DupItem(pub_val)); + } + + ScopedPK11SlotInfo slot_; + ScopedSECItem password_; +}; + +class Pk11KeyImportTest + : public Pk11KeyImportTestBase, + public ::testing::WithParamInterface { + public: + Pk11KeyImportTest() : Pk11KeyImportTestBase(GetParam()) {} + virtual ~Pk11KeyImportTest() = default; + + protected: + std::unique_ptr MakeParams() override { + switch (mech_) { + case CKM_RSA_PKCS_KEY_PAIR_GEN: + return std::unique_ptr(new RsaParamHolder()); + + case CKM_DSA_KEY_PAIR_GEN: + case CKM_DH_PKCS_KEY_PAIR_GEN: { + PQGParams* pqg_params = nullptr; + PQGVerify* pqg_verify = nullptr; + const unsigned int key_size = 1024; + SECStatus rv = PK11_PQG_ParamGenV2(key_size, 0, key_size / 16, + &pqg_params, &pqg_verify); + if (rv != SECSuccess) { + ADD_FAILURE() << "PK11_PQG_ParamGenV2 failed"; + return nullptr; + } + EXPECT_NE(nullptr, pqg_verify); + EXPECT_NE(nullptr, pqg_params); + PK11_PQG_DestroyVerify(pqg_verify); + if (mech_ == CKM_DSA_KEY_PAIR_GEN) { + return std::unique_ptr(new PqgParamHolder(pqg_params)); + } + return std::unique_ptr(new DhParamHolder(pqg_params)); + } + + default: + ADD_FAILURE() << "unknown OID " << mech_; + } + return nullptr; + } + + private: + class RsaParamHolder : public ParamHolder { + public: + RsaParamHolder() + : params_({/*.keySizeInBits = */ 1024, /*.pe = */ 0x010001}) {} + ~RsaParamHolder() = default; + + void* get() override { return ¶ms_; } + + private: + PK11RSAGenParams params_; + }; + + class PqgParamHolder : public ParamHolder { + public: + PqgParamHolder(PQGParams* params) : params_(params) {} + ~PqgParamHolder() = default; + + void* get() override { return params_.get(); } + + private: + ScopedPQGParams params_; + }; + + class DhParamHolder : public PqgParamHolder { + public: + DhParamHolder(PQGParams* params) + : PqgParamHolder(params), + params_({/*.arena = */ nullptr, + /*.prime = */ params->prime, + /*.base = */ params->base}) {} + ~DhParamHolder() = default; + + void* get() override { return ¶ms_; } + + private: + SECKEYDHParams params_; + }; +}; + +TEST_P(Pk11KeyImportTest, GenerateExportImport) { Test(); } + +INSTANTIATE_TEST_CASE_P(Pk11KeyImportTest, Pk11KeyImportTest, + ::testing::Values(CKM_RSA_PKCS_KEY_PAIR_GEN, + CKM_DSA_KEY_PAIR_GEN)); +// Note: NSS is currently unable export wrapped DH keys, so this doesn't test +// CKM_DH_PKCS_KEY_PAIR_GEN. + +class Pk11KeyImportTestEC : public Pk11KeyImportTestBase, + public ::testing::WithParamInterface { + public: + Pk11KeyImportTestEC() : Pk11KeyImportTestBase(CKM_EC_KEY_PAIR_GEN) {} + virtual ~Pk11KeyImportTestEC() = default; + + protected: + std::unique_ptr MakeParams() override { + return std::unique_ptr(new EcParamHolder(GetParam())); + } + + private: + class EcParamHolder : public ParamHolder { + public: + EcParamHolder(SECOidTag curve_oid) { + SECOidData* curve = SECOID_FindOIDByTag(curve_oid); + EXPECT_NE(nullptr, curve); + + size_t plen = curve->oid.len + 2; + extra_.reset(new uint8_t[plen]); + extra_[0] = SEC_ASN1_OBJECT_ID; + extra_[1] = static_cast(curve->oid.len); + memcpy(&extra_[2], curve->oid.data, curve->oid.len); + + ec_params_ = {/*.type = */ siBuffer, + /*.data = */ extra_.get(), + /*.len = */ static_cast(plen)}; + } + ~EcParamHolder() = default; + + void* get() override { return &ec_params_; } + + private: + SECKEYECParams ec_params_; + std::unique_ptr extra_; + }; +}; + +TEST_P(Pk11KeyImportTestEC, GenerateExportImport) { Test(); } + +INSTANTIATE_TEST_CASE_P(Pk11KeyImportTestEC, Pk11KeyImportTestEC, + ::testing::Values(SEC_OID_SECG_EC_SECP256R1, + SEC_OID_SECG_EC_SECP384R1, + SEC_OID_SECG_EC_SECP521R1, + SEC_OID_CURVE25519)); + +} // namespace nss_test diff --git a/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc b/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc index ed0573027..2024a525f 100644 --- a/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc +++ b/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc @@ -93,6 +93,20 @@ TEST_F(Pkcs11RsaPssTest, GenerateAndSignAndVerify) { EXPECT_EQ(rv, SECFailure); } +TEST_F(Pkcs11RsaPssTest, NoLeakWithInvalidExponent) { + // Attempt to generate an RSA key with a public exponent of 1. This should + // fail, but it shouldn't leak memory. + PK11RSAGenParams rsaGenParams = {1024, 0x01}; + + // Generate RSA key pair. + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + SECKEYPublicKey* pubKey = nullptr; + SECKEYPrivateKey* privKey = + PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaGenParams, + &pubKey, false, false, nullptr); + EXPECT_FALSE(privKey); + EXPECT_FALSE(pubKey); +} class Pkcs11RsaPssVectorTest : public Pkcs11RsaPssTest, public ::testing::WithParamInterface {}; diff --git a/security/nss/gtests/util_gtest/manifest.mn b/security/nss/gtests/util_gtest/manifest.mn index a90e8431e..c09146c83 100644 --- a/security/nss/gtests/util_gtest/manifest.mn +++ b/security/nss/gtests/util_gtest/manifest.mn @@ -3,29 +3,30 @@ # 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/. CORE_DEPTH = ../.. -DEPTH = ../.. +DEPTH = ../.. MODULE = nss CPPSRCS = \ - util_utf8_unittest.cc \ - util_b64_unittest.cc \ - util_pkcs11uri_unittest.cc \ - util_aligned_malloc_unittest.cc \ - util_memcmpzero_unittest.cc \ - $(NULL) + util_aligned_malloc_unittest.cc \ + util_b64_unittest.cc \ + util_gtests.cc \ + util_memcmpzero_unittest.cc \ + util_pkcs11uri_unittest.cc \ + util_utf8_unittest.cc \ + $(NULL) INCLUDES += \ - -I$(CORE_DEPTH)/gtests/google_test/gtest/include \ - -I$(CORE_DEPTH)/gtests/common \ - -I$(CORE_DEPTH)/cpputil \ - $(NULL) + -I$(CORE_DEPTH)/gtests/google_test/gtest/include \ + -I$(CORE_DEPTH)/gtests/common \ + -I$(CORE_DEPTH)/cpputil \ + $(NULL) REQUIRES = nspr gtest PROGRAM = util_gtest EXTRA_LIBS = \ - $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \ - $(DIST)/lib/$(LIB_PREFIX)nssutil.$(LIB_SUFFIX) \ - $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) \ - $(NULL) + $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)nssutil.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) \ + $(NULL) diff --git a/security/nss/gtests/util_gtest/util_gtest.gyp b/security/nss/gtests/util_gtest/util_gtest.gyp index 1c54329b2..ab803b761 100644 --- a/security/nss/gtests/util_gtest/util_gtest.gyp +++ b/security/nss/gtests/util_gtest/util_gtest.gyp @@ -11,27 +11,17 @@ 'target_name': 'util_gtest', 'type': 'executable', 'sources': [ - 'util_utf8_unittest.cc', - 'util_b64_unittest.cc', - 'util_pkcs11uri_unittest.cc', 'util_aligned_malloc_unittest.cc', + 'util_b64_unittest.cc', + 'util_gtests.cc', 'util_memcmpzero_unittest.cc', - '<(DEPTH)/gtests/common/gtests.cc', + 'util_pkcs11uri_unittest.cc', + 'util_utf8_unittest.cc', ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports', '<(DEPTH)/gtests/google_test/google_test.gyp:gtest', '<(DEPTH)/lib/util/util.gyp:nssutil', - '<(DEPTH)/lib/nss/nss.gyp:nss_static', - '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static', - '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi', - '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi', - '<(DEPTH)/lib/certdb/certdb.gyp:certdb', - '<(DEPTH)/lib/base/base.gyp:nssb', - '<(DEPTH)/lib/dev/dev.gyp:nssdev', - '<(DEPTH)/lib/pki/pki.gyp:nsspki', - '<(DEPTH)/lib/ssl/ssl.gyp:ssl', - '<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix', ], 'conditions': [ [ 'OS=="win"', { diff --git a/security/nss/gtests/util_gtest/util_gtests.cc b/security/nss/gtests/util_gtest/util_gtests.cc new file mode 100644 index 000000000..77e663f3c --- /dev/null +++ b/security/nss/gtests/util_gtest/util_gtests.cc @@ -0,0 +1,9 @@ +#include + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/security/nss/lib/cryptohi/sechash.c b/security/nss/lib/cryptohi/sechash.c index b12621100..474fdfff9 100644 --- a/security/nss/lib/cryptohi/sechash.c +++ b/security/nss/lib/cryptohi/sechash.c @@ -202,13 +202,46 @@ HASH_GetHashTypeByOidTag(SECOidTag hashOid) ht = HASH_AlgSHA512; break; default: - ht = HASH_AlgNULL; PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); break; } return ht; } +SECOidTag +HASH_GetHashOidTagByHashType(HASH_HashType type) +{ + SECOidTag oid = SEC_OID_UNKNOWN; + + switch (type) { + case HASH_AlgMD2: + oid = SEC_OID_MD2; + break; + case HASH_AlgMD5: + oid = SEC_OID_MD5; + break; + case HASH_AlgSHA1: + oid = SEC_OID_SHA1; + break; + case HASH_AlgSHA224: + oid = SEC_OID_SHA224; + break; + case HASH_AlgSHA256: + oid = SEC_OID_SHA256; + break; + case HASH_AlgSHA384: + oid = SEC_OID_SHA384; + break; + case HASH_AlgSHA512: + oid = SEC_OID_SHA512; + break; + default: + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + break; + } + return oid; +} + SECOidTag HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid) { diff --git a/security/nss/lib/cryptohi/sechash.h b/security/nss/lib/cryptohi/sechash.h index 94ff7ed3d..16e8b6713 100644 --- a/security/nss/lib/cryptohi/sechash.h +++ b/security/nss/lib/cryptohi/sechash.h @@ -53,6 +53,8 @@ extern HASH_HashType HASH_GetHashTypeByOidTag(SECOidTag hashOid); extern SECOidTag HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid); extern SECOidTag HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid); +extern SECOidTag HASH_GetHashOidTagByHashType(HASH_HashType type); + SEC_END_PROTOS #endif /* _HASH_H_ */ diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c index 7c9430d3c..28f21a6c2 100644 --- a/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c +++ b/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c @@ -168,6 +168,9 @@ pkix_NameConstraintsChecker_Check( PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL; PKIX_Boolean selfIssued = PKIX_FALSE; PKIX_Boolean lastCert = PKIX_FALSE; + PKIX_Boolean treatCommonNameAsDNSName = PKIX_FALSE; + PKIX_List *extKeyUsageList = NULL; + PKIX_PL_OID *serverAuthOID = NULL; PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check"); PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); @@ -185,11 +188,38 @@ pkix_NameConstraintsChecker_Check( PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext), PKIX_ISCERTSELFISSUEDFAILED); + if (lastCert) { + /* For the last cert, treat the CN as a DNS name for name + * constraint check. But only if EKU has id-kp-serverAuth + * or EKU is absent. It does not make sense to treat CN + * as a DNS name for an OCSP signing certificate, for example. + */ + PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage + (cert, &extKeyUsageList, plContext), + PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); + if (extKeyUsageList == NULL) { + treatCommonNameAsDNSName = PKIX_TRUE; + } else { + PKIX_CHECK(PKIX_PL_OID_Create + (PKIX_KEY_USAGE_SERVER_AUTH_OID, + &serverAuthOID, + plContext), + PKIX_OIDCREATEFAILED); + + PKIX_CHECK(pkix_List_Contains + (extKeyUsageList, + (PKIX_PL_Object *) serverAuthOID, + &treatCommonNameAsDNSName, + plContext), + PKIX_LISTCONTAINSFAILED); + } + } + /* Check on non self-issued and if so only for last cert */ if (selfIssued == PKIX_FALSE || (selfIssued == PKIX_TRUE && lastCert)) { PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints - (cert, state->nameConstraints, lastCert, + (cert, state->nameConstraints, treatCommonNameAsDNSName, plContext), PKIX_CERTCHECKNAMECONSTRAINTSFAILED); } @@ -241,6 +271,8 @@ pkix_NameConstraintsChecker_Check( cleanup: PKIX_DECREF(state); + PKIX_DECREF(extKeyUsageList); + PKIX_DECREF(serverAuthOID); PKIX_RETURN(CERTCHAINCHECKER); } diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index 8a9b3b030..d589fd30e 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1139,3 +1139,9 @@ CERT_GetCertKeyType; ;+ local: ;+ *; ;+}; +;+NSS_3.43 { # NSS 3.43 release +;+ global: +HASH_GetHashOidTagByHashType; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 7eec3d7ee..4caa18e43 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -4838,6 +4838,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len); if (bitSize < 2) { crv = CKR_ATTRIBUTE_VALUE_INVALID; + PORT_Free(pubExp.data); break; } crv = sftk_AddAttributeType(privateKey, CKA_PUBLIC_EXPONENT, diff --git a/security/nss/lib/sysinit/nsssysinit.c b/security/nss/lib/sysinit/nsssysinit.c index 2572141a3..bd0fac2f4 100644 --- a/security/nss/lib/sysinit/nsssysinit.c +++ b/security/nss/lib/sysinit/nsssysinit.c @@ -15,11 +15,10 @@ * of pkcs11 modules common to all applications. */ -/* - * OS Specific function to get where the NSS user database should reside. - */ +#ifndef LINUX +#error __FILE__ only builds on Linux. +#endif -#ifdef XP_UNIX #include #include #include @@ -150,44 +149,6 @@ userCanModifySystemDB() return (access(NSS_DEFAULT_SYSTEM, W_OK) == 0); } -#else -#ifdef XP_WIN -static char * -getUserDB(void) -{ - /* use the registry to find the user's NSS_DIR. if no entry exists, create - * one in the users Appdir location */ - return NULL; -} - -static char * -getSystemDB(void) -{ - /* use the registry to find the system's NSS_DIR. if no entry exists, create - * one based on the windows system data area */ - return NULL; -} - -static PRBool -userIsRoot() -{ - /* use the registry to find if the user is the system administrator. */ - return PR_FALSE; -} - -static PRBool -userCanModifySystemDB() -{ - /* use the registry to find if the user has administrative privilege - * to modify the system's nss database. */ - return PR_FALSE; -} - -#else -#error "Need to write getUserDB, SystemDB, userIsRoot, and userCanModifySystemDB functions" -#endif -#endif - static PRBool getFIPSEnv(void) { @@ -203,7 +164,6 @@ getFIPSEnv(void) } return PR_FALSE; } -#ifdef XP_LINUX static PRBool getFIPSMode(void) @@ -228,14 +188,6 @@ getFIPSMode(void) return PR_TRUE; } -#else -static PRBool -getFIPSMode(void) -{ - return getFIPSEnv(); -} -#endif - #define NSS_DEFAULT_FLAGS "flags=readonly" /* configuration flags according to diff --git a/security/nss/nss.gyp b/security/nss/nss.gyp index ba48c4bbf..3cc3d7b6d 100644 --- a/security/nss/nss.gyp +++ b/security/nss/nss.gyp @@ -29,6 +29,10 @@ [ 'OS=="linux"', { 'dependencies': [ 'lib/freebl/freebl.gyp:freeblpriv3', + ], + }], + [ 'OS=="linux" and mozilla_client==0', { + 'dependencies': [ 'lib/sysinit/sysinit.gyp:nsssysinit', ], }], @@ -68,7 +72,7 @@ 'lib/util/util.gyp:nssutil', ], 'conditions': [ - [ 'OS=="linux"', { + [ 'OS=="linux" and mozilla_client==0', { 'dependencies': [ 'lib/sysinit/sysinit.gyp:nsssysinit_static', ], @@ -199,6 +203,10 @@ [ 'OS=="linux"', { 'dependencies': [ 'cmd/lowhashtest/lowhashtest.gyp:lowhashtest', + ], + }], + [ 'OS=="linux" and mozilla_client==0', { + 'dependencies': [ 'gtests/sysinit_gtest/sysinit_gtest.gyp:sysinit_gtest', ], }], diff --git a/security/nss/tests/chains/scenarios/nameconstraints.cfg b/security/nss/tests/chains/scenarios/nameconstraints.cfg index 6eda441ce..4a149032b 100644 --- a/security/nss/tests/chains/scenarios/nameconstraints.cfg +++ b/security/nss/tests/chains/scenarios/nameconstraints.cfg @@ -10,6 +10,7 @@ import NameConstraints.ca:x:CT,C,C # Name Constrained CA: Name constrained to permited DNSName ".example" import NameConstraints.ncca:x:CT,C,C import NameConstraints.dcisscopy:x:CT,C,C +import NameConstraints.ipaca:x:CT,C,C # Intermediate 1: Name constrained to permited DNSName ".example" @@ -158,4 +159,12 @@ verify NameConstraints.dcissblocked:x verify NameConstraints.dcissallowed:x result pass +# Subject: "O = IPA.LOCAL 201901211552, CN = OCSP Subsystem" +# +# This tests that a non server certificate (i.e. id-kp-serverAuth +# not present in EKU) does *NOT* have CN treated as dnsName for +# purposes of Name Constraints validation +verify NameConstraints.ocsp1:x + usage 10 + result pass diff --git a/security/nss/tests/libpkix/certs/NameConstraints.ipaca.cert b/security/nss/tests/libpkix/certs/NameConstraints.ipaca.cert new file mode 100644 index 000000000..6c7d68c77 Binary files /dev/null and b/security/nss/tests/libpkix/certs/NameConstraints.ipaca.cert differ diff --git a/security/nss/tests/libpkix/certs/NameConstraints.ocsp1.cert b/security/nss/tests/libpkix/certs/NameConstraints.ocsp1.cert new file mode 100644 index 000000000..ce7325fca Binary files /dev/null and b/security/nss/tests/libpkix/certs/NameConstraints.ocsp1.cert differ