From 1abc8dffe800e82fc5fe7a729c6c24f079307021 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 7 Dec 2021 11:58:07 -0500 Subject: [PATCH] import nss-3.71.0-2.el9 --- .gitignore | 2 +- .nss.metadata | 2 +- SOURCES/nss-3.44-kbkdf-coverity.patch | 39 - SOURCES/nss-3.53.1-measure-fix.patch | 24 - SOURCES/nss-3.66-fix-gtest-parsing.patch | 16 - SOURCES/nss-3.66-no-small-primes.patch | 86 --- SOURCES/nss-3.67-fix-coverity-issues.patch | 45 -- SOURCES/nss-3.67-fix-private-key-mac.patch | 81 -- SOURCES/nss-3.67-fix-ssl-alerts.patch | 122 --- SOURCES/nss-3.71-fips-module-name.patch | 825 +++++++++++++++++++++ SOURCES/nss-3.71-ipv6-fix.patch | 36 + SOURCES/nss-539183.patch | 62 -- SOURCES/nss-fedora-btrf-sql-hack.patch | 18 - SPECS/nss.spec | 60 +- 14 files changed, 899 insertions(+), 519 deletions(-) delete mode 100644 SOURCES/nss-3.44-kbkdf-coverity.patch delete mode 100644 SOURCES/nss-3.53.1-measure-fix.patch delete mode 100644 SOURCES/nss-3.66-fix-gtest-parsing.patch delete mode 100644 SOURCES/nss-3.66-no-small-primes.patch delete mode 100644 SOURCES/nss-3.67-fix-coverity-issues.patch delete mode 100644 SOURCES/nss-3.67-fix-private-key-mac.patch delete mode 100644 SOURCES/nss-3.67-fix-ssl-alerts.patch create mode 100644 SOURCES/nss-3.71-fips-module-name.patch create mode 100644 SOURCES/nss-3.71-ipv6-fix.patch delete mode 100644 SOURCES/nss-539183.patch delete mode 100644 SOURCES/nss-fedora-btrf-sql-hack.patch diff --git a/.gitignore b/.gitignore index 33f2b3f..7c7da43 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ SOURCES/blank-key3.db SOURCES/blank-key4.db SOURCES/blank-secmod.db SOURCES/nspr-4.32.tar.gz -SOURCES/nss-3.67.tar.gz +SOURCES/nss-3.71.tar.gz diff --git a/.nss.metadata b/.nss.metadata index c1113a7..345574c 100644 --- a/.nss.metadata +++ b/.nss.metadata @@ -4,4 +4,4 @@ b5570125fbf6bfb410705706af48217a0817c03a SOURCES/blank-cert9.db f9c9568442386da370193474de1b25c3f68cdaf6 SOURCES/blank-key4.db bd748cf6e1465a1bbe6e751b72ffc0076aff0b50 SOURCES/blank-secmod.db 28e05ef5cbe6e7cde239d3cdcccabf571ec73f69 SOURCES/nspr-4.32.tar.gz -9cccf98f0476905c0d863a6b2cb08a1955482241 SOURCES/nss-3.67.tar.gz +b60e3e0a2765d4009347e08dc9792a4dc4aded03 SOURCES/nss-3.71.tar.gz diff --git a/SOURCES/nss-3.44-kbkdf-coverity.patch b/SOURCES/nss-3.44-kbkdf-coverity.patch deleted file mode 100644 index 1ef1d8d..0000000 --- a/SOURCES/nss-3.44-kbkdf-coverity.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff -up ./lib/softoken/kbkdf.c.coverity ./lib/softoken/kbkdf.c ---- ./lib/softoken/kbkdf.c.coverity 2019-12-03 15:33:43.047732312 -0800 -+++ ./lib/softoken/kbkdf.c 2019-12-03 15:39:40.982578357 -0800 -@@ -534,6 +534,10 @@ CK_RV kbkdf_CreateKey(CK_SESSION_HANDLE - PR_ASSERT(derived_key != NULL); - PR_ASSERT(derived_key->phKey != NULL); - -+ if (slot == NULL) { -+ return CKR_SESSION_HANDLE_INVALID; -+ } -+ - /* Create the new key object for this additional derived key. */ - key = sftk_NewObject(slot); - if (key == NULL) { -@@ -589,7 +593,9 @@ done: - sftk_FreeObject(key); - - /* Doesn't do anything. */ -- sftk_FreeSession(session); -+ if (session) { -+ sftk_FreeSession(session); -+ } - - return ret; - } -diff -up ./lib/softoken/sftkhmac.c.coverity ./lib/softoken/sftkhmac.c ---- ./lib/softoken/sftkhmac.c.coverity 2019-12-03 15:40:06.108848341 -0800 -+++ ./lib/softoken/sftkhmac.c 2019-12-03 15:41:04.919480267 -0800 -@@ -232,7 +232,9 @@ sftk_MAC_Init(sftk_MACCtx *ctx, CK_MECHA - keyval->attrib.ulValueLen, isFIPS); - - done: -- sftk_FreeAttribute(keyval); -+ if (keyval) { -+ sftk_FreeAttribute(keyval); -+ } - return ret; - } - diff --git a/SOURCES/nss-3.53.1-measure-fix.patch b/SOURCES/nss-3.53.1-measure-fix.patch deleted file mode 100644 index a312936..0000000 --- a/SOURCES/nss-3.53.1-measure-fix.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up ./coreconf/config.gypi.orig ./coreconf/config.gypi ---- ./coreconf/config.gypi.orig 2020-06-16 15:50:59.000000000 -0700 -+++ ./coreconf/config.gypi 2020-10-15 16:05:37.542761192 -0700 -@@ -363,7 +363,7 @@ - '_DEFAULT_SOURCE', # for functions, strdup, realpath, and getentropy - '_BSD_SOURCE', # for the above in glibc <= 2.19 - '_POSIX_SOURCE', # for -- 'SQL_MEASURE_USE_TEMP_DIR', # use tmpdir for the access calls -+ 'SDB_MEASURE_USE_TEMP_DIR', # use tmpdir for the access calls - ], - }], - [ 'OS=="dragonfly" or OS=="freebsd"', { -diff -up ./coreconf/Linux.mk.orig ./coreconf/Linux.mk ---- ./coreconf/Linux.mk.orig 2020-10-15 16:05:04.794591674 -0700 -+++ ./coreconf/Linux.mk 2020-10-15 16:05:37.543761197 -0700 -@@ -21,7 +21,7 @@ ifeq ($(USE_PTHREADS),1) - endif - - DEFAULT_COMPILER = gcc --DEFINES += -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -DSQL_MEASURE_USE_TEMP_DIR -+DEFINES += -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -DSDB_MEASURE_USE_TEMP_DIR - - ifeq ($(OS_TARGET),Android) - ifndef ANDROID_NDK diff --git a/SOURCES/nss-3.66-fix-gtest-parsing.patch b/SOURCES/nss-3.66-fix-gtest-parsing.patch deleted file mode 100644 index 7e5ff4b..0000000 --- a/SOURCES/nss-3.66-fix-gtest-parsing.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -up ./tests/common/parsegtestreport.sed.new_gtest ./tests/common/parsegtestreport.sed ---- ./tests/common/parsegtestreport.sed.new_gtest 2021-06-17 16:26:49.361035662 -0700 -+++ ./tests/common/parsegtestreport.sed 2021-06-17 16:49:08.512261136 -0700 -@@ -1,8 +1,11 @@ - /\len) { - case 1536 / PR_BITS_PER_BYTE: -+ /* don't accept 1536 bit primes in FIPS mode */ -+ if (isFIPS) { -+ break; -+ } - if (PORT_Memcmp(dhPrime->data, prime_ike_1536, - sizeof(prime_ike_1536)) == 0) { - return &subprime_ike_1536; diff --git a/SOURCES/nss-3.67-fix-coverity-issues.patch b/SOURCES/nss-3.67-fix-coverity-issues.patch deleted file mode 100644 index a68fa57..0000000 --- a/SOURCES/nss-3.67-fix-coverity-issues.patch +++ /dev/null @@ -1,45 +0,0 @@ -diff -up ./lib/pk11wrap/pk11cxt.c.coverity ./lib/pk11wrap/pk11cxt.c ---- ./lib/pk11wrap/pk11cxt.c.coverity 2021-06-18 09:36:19.499203028 -0700 -+++ ./lib/pk11wrap/pk11cxt.c 2021-06-18 09:37:57.993765299 -0700 -@@ -382,7 +382,7 @@ pk11_CreateNewContextInSlot(CK_MECHANISM - * of the connection.*/ - context->fortezzaHack = PR_FALSE; - if (type == CKM_SKIPJACK_CBC64) { -- if (symKey->origin == PK11_OriginFortezzaHack) { -+ if (symKey && (symKey->origin == PK11_OriginFortezzaHack)) { - context->fortezzaHack = PR_TRUE; - } - } -diff -up ./lib/pk11wrap/pk11hpke.c.coverity ./lib/pk11wrap/pk11hpke.c ---- ./lib/pk11wrap/pk11hpke.c.coverity 2021-06-18 13:40:05.410644464 -0700 -+++ ./lib/pk11wrap/pk11hpke.c 2021-06-18 13:42:40.627606469 -0700 -@@ -1164,8 +1164,6 @@ PK11_HPKE_Seal(HpkeContext *cx, const SE - unsigned char tagBuf[HASH_LENGTH_MAX]; - size_t tagLen; - unsigned int fixedBits; -- PORT_Assert(cx->baseNonce->len == sizeof(ivOut)); -- PORT_Memcpy(ivOut, cx->baseNonce->data, cx->baseNonce->len); - - /* aad may be NULL, PT may be zero-length but not NULL. */ - if (!cx || !cx->aeadContext || -@@ -1176,6 +1174,9 @@ PK11_HPKE_Seal(HpkeContext *cx, const SE - return SECFailure; - } - -+ PORT_Assert(cx->baseNonce->len == sizeof(ivOut)); -+ PORT_Memcpy(ivOut, cx->baseNonce->data, cx->baseNonce->len); -+ - tagLen = cx->aeadParams->tagLen; - maxOut = pt->len + tagLen; - fixedBits = (cx->baseNonce->len - 8) * 8; -diff -up ./lib/softoken/sftkike.c.coverity ./lib/softoken/sftkike.c ---- ./lib/softoken/sftkike.c.coverity 2021-06-18 09:33:59.633405513 -0700 -+++ ./lib/softoken/sftkike.c 2021-06-18 09:34:20.305523382 -0700 -@@ -1411,7 +1411,6 @@ sftk_fips_IKE_PowerUpSelfTests(void) - (outKeySize != sizeof(ike_known_sha256_prf_plus)) || - (PORT_Memcmp(outKeyData, ike_known_sha256_prf_plus, - sizeof(ike_known_sha256_prf_plus)) != 0)) { -- PORT_ZFree(outKeyData, outKeySize); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } diff --git a/SOURCES/nss-3.67-fix-private-key-mac.patch b/SOURCES/nss-3.67-fix-private-key-mac.patch deleted file mode 100644 index d211940..0000000 --- a/SOURCES/nss-3.67-fix-private-key-mac.patch +++ /dev/null @@ -1,81 +0,0 @@ -diff -up ./lib/softoken/sftkpwd.c.orig ./lib/softoken/sftkpwd.c ---- ./lib/softoken/sftkpwd.c.orig 2021-06-10 05:33:12.000000000 -0700 -+++ ./lib/softoken/sftkpwd.c 2021-07-01 14:04:34.068596942 -0700 -@@ -287,9 +287,12 @@ sftkdb_DecryptAttribute(SFTKDBHandle *ha - } - - /* If we are using aes 256, we need to check authentication as well.*/ -- if ((type != CKT_INVALID_TYPE) && (cipherValue.alg == SEC_OID_AES_256_CBC)) { -+ if ((type != CKT_INVALID_TYPE) && -+ (cipherValue.alg == SEC_OID_PKCS5_PBES2) && -+ (cipherValue.param->encAlg == SEC_OID_AES_256_CBC)) { - SECItem signature; - unsigned char signData[SDB_MAX_META_DATA_LEN]; -+ CK_RV crv; - - /* if we get here from the old legacy db, there is clearly an - * error, don't return the plaintext */ -@@ -301,15 +304,28 @@ sftkdb_DecryptAttribute(SFTKDBHandle *ha - - signature.data = signData; - signature.len = sizeof(signData); -- rv = sftkdb_GetAttributeSignature(handle, handle, id, type, -+ rv = SECFailure; -+ /* sign sftkdb_GetAttriibuteSignature returns a crv, not an rv */ -+ crv = sftkdb_GetAttributeSignature(handle, handle, id, type, - &signature); -- if (rv != SECSuccess) { -- goto loser; -+ if (crv == CKR_OK) { -+ rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE, -+ type, *plain, &signature); - } -- rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE, type, -- *plain, &signature); - if (rv != SECSuccess) { -- goto loser; -+ /* handle a bug where old versions of NSS misfiled the signature -+ * attribute on password update */ -+ id |= SFTK_KEYDB_TYPE|SFTK_TOKEN_TYPE; -+ signature.len = sizeof(signData); -+ crv = sftkdb_GetAttributeSignature(handle, handle, id, type, -+ &signature); -+ if (crv != CKR_OK) { -+ rv = SECFailure; -+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); -+ goto loser; -+ } -+ rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE, -+ type, *plain, &signature); - } - } - -@@ -1198,6 +1214,7 @@ sftk_updateEncrypted(PLArenaPool *arena, - unsigned int i; - for (i = 0; i < privAttrCount; i++) { - // Read the old attribute in the clear. -+ CK_OBJECT_HANDLE sdbId = id & SFTK_OBJ_ID_MASK; - CK_ATTRIBUTE privAttr = { privAttrTypes[i], NULL, 0 }; - CK_RV crv = sftkdb_GetAttributeValue(keydb, id, &privAttr, 1); - if (crv != CKR_OK) { -@@ -1222,7 +1239,7 @@ sftk_updateEncrypted(PLArenaPool *arena, - plainText.data = privAttr.pValue; - plainText.len = privAttr.ulValueLen; - if (sftkdb_EncryptAttribute(arena, keydb, keydb->db, newKey, -- iterationCount, id, privAttr.type, -+ iterationCount, sdbId, privAttr.type, - &plainText, &result) != SECSuccess) { - return CKR_GENERAL_ERROR; - } -@@ -1232,10 +1249,9 @@ sftk_updateEncrypted(PLArenaPool *arena, - PORT_Memset(plainText.data, 0, plainText.len); - - // Write the newly encrypted attributes out directly. -- CK_OBJECT_HANDLE newId = id & SFTK_OBJ_ID_MASK; - keydb->newKey = newKey; - keydb->newDefaultIterationCount = iterationCount; -- crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, newId, &privAttr, 1); -+ crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, sdbId, &privAttr, 1); - keydb->newKey = NULL; - if (crv != CKR_OK) { - return crv; diff --git a/SOURCES/nss-3.67-fix-ssl-alerts.patch b/SOURCES/nss-3.67-fix-ssl-alerts.patch deleted file mode 100644 index 10cdaf5..0000000 --- a/SOURCES/nss-3.67-fix-ssl-alerts.patch +++ /dev/null @@ -1,122 +0,0 @@ -diff -up ./lib/ssl/ssl3con.c.alert-fix ./lib/ssl/ssl3con.c ---- ./lib/ssl/ssl3con.c.alert-fix 2021-06-10 05:33:12.000000000 -0700 -+++ ./lib/ssl/ssl3con.c 2021-07-06 17:08:25.894018521 -0700 -@@ -4319,7 +4319,11 @@ ssl_SignatureSchemeValid(SSLSignatureSch - if (!ssl_IsSupportedSignatureScheme(scheme)) { - return PR_FALSE; - } -- if (!ssl_SignatureSchemeMatchesSpkiOid(scheme, spkiOid)) { -+ /* if we are purposefully passed SEC_OID_UNKOWN, it means -+ * we not checking the scheme against a potential key, so skip -+ * the call */ -+ if ((spkiOid != SEC_OID_UNKNOWN) && -+ !ssl_SignatureSchemeMatchesSpkiOid(scheme, spkiOid)) { - return PR_FALSE; - } - if (isTls13) { -@@ -4517,7 +4521,8 @@ ssl_CheckSignatureSchemeConsistency(sslS - } - - /* Verify that the signature scheme matches the signing key. */ -- if (!ssl_SignatureSchemeValid(scheme, spkiOid, isTLS13)) { -+ if ((spkiOid == SEC_OID_UNKNOWN) || -+ !ssl_SignatureSchemeValid(scheme, spkiOid, isTLS13)) { - PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); - return SECFailure; - } -@@ -4533,6 +4538,7 @@ ssl_CheckSignatureSchemeConsistency(sslS - PRBool - ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme) - { -+ PRBool isSupported = PR_FALSE; - switch (scheme) { - case ssl_sig_rsa_pkcs1_sha1: - case ssl_sig_rsa_pkcs1_sha256: -@@ -4552,7 +4558,8 @@ ssl_IsSupportedSignatureScheme(SSLSignat - case ssl_sig_dsa_sha384: - case ssl_sig_dsa_sha512: - case ssl_sig_ecdsa_sha1: -- return PR_TRUE; -+ isSupported = PR_TRUE; -+ break; - - case ssl_sig_rsa_pkcs1_sha1md5: - case ssl_sig_none: -@@ -4560,7 +4567,19 @@ ssl_IsSupportedSignatureScheme(SSLSignat - case ssl_sig_ed448: - return PR_FALSE; - } -- return PR_FALSE; -+ if (isSupported) { -+ SECOidTag hashOID = ssl3_HashTypeToOID(ssl_SignatureSchemeToHashType(scheme)); -+ PRUint32 policy; -+ const PRUint32 sigSchemePolicy= -+ NSS_USE_ALG_IN_SSL_KX|NSS_USE_ALG_IN_SIGNATURE; -+ /* check hash policy */ -+ if ((NSS_GetAlgorithmPolicy(hashOID, &policy) == SECSuccess) && -+ ((policy & sigSchemePolicy) != sigSchemePolicy)) { -+ return PR_FALSE; -+ } -+ /* check algorithm policy */ -+ } -+ return isSupported; - } - - PRBool -@@ -6533,6 +6552,9 @@ ssl_PickSignatureScheme(sslSocket *ss, - } - - spkiOid = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm); -+ if (spkiOid == SEC_OID_UNKNOWN) { -+ goto loser; -+ } - - /* Now we have to search based on the key type. Go through our preferred - * schemes in order and find the first that can be used. */ -@@ -6547,6 +6569,7 @@ ssl_PickSignatureScheme(sslSocket *ss, - } - } - -+loser: - PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); - return SECFailure; - } -@@ -7700,7 +7723,8 @@ ssl_ParseSignatureSchemes(const sslSocke - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } -- if (ssl_IsSupportedSignatureScheme((SSLSignatureScheme)tmp)) { -+ if (ssl_SignatureSchemeValid((SSLSignatureScheme)tmp, SEC_OID_UNKNOWN, -+ (PRBool)ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) {; - schemes[numSupported++] = (SSLSignatureScheme)tmp; - } - } -@@ -10286,7 +10310,12 @@ ssl3_HandleCertificateVerify(sslSocket * - PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_record); - rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme); - if (rv != SECSuccess) { -- goto loser; /* malformed or unsupported. */ -+ errCode = PORT_GetError(); -+ /* unsupported == illegal_parameter, others == handshake_failure. */ -+ if (errCode == SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM) { -+ desc = illegal_parameter; -+ } -+ goto alert_loser; - } - rv = ssl_CheckSignatureSchemeConsistency( - ss, sigScheme, &ss->sec.peerCert->subjectPublicKeyInfo); -diff -up ./gtests/ssl_gtest/ssl_extension_unittest.cc.alert-fix ./gtests/ssl_gtest/ssl_extension_unittest.cc ---- ./gtests/ssl_gtest/ssl_extension_unittest.cc.alert-fix 2021-07-07 11:32:11.634376932 -0700 -+++ ./gtests/ssl_gtest/ssl_extension_unittest.cc 2021-07-07 11:33:30.595841110 -0700 -@@ -428,7 +428,10 @@ TEST_P(TlsExtensionTest12Plus, Signature - } - - TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsTrailingData) { -- const uint8_t val[] = {0x00, 0x02, 0x04, 0x01, 0x00}; // sha-256, rsa -+ // make sure the test uses an algorithm that is legal for -+ // tls 1.3 (or tls 1.3 will through and illegalParameter -+ // instead of a decode error) -+ const uint8_t val[] = {0x00, 0x02, 0x08, 0x09, 0x00}; // sha-256, rsa-pss-pss - DataBuffer extension(val, sizeof(val)); - ClientHelloErrorTest(std::make_shared( - client_, ssl_signature_algorithms_xtn, extension)); diff --git a/SOURCES/nss-3.71-fips-module-name.patch b/SOURCES/nss-3.71-fips-module-name.patch new file mode 100644 index 0000000..a1ec103 --- /dev/null +++ b/SOURCES/nss-3.71-fips-module-name.patch @@ -0,0 +1,825 @@ +diff --git a/cmd/manifest.mn b/cmd/manifest.mn +--- a/cmd/manifest.mn ++++ b/cmd/manifest.mn +@@ -76,6 +76,7 @@ + symkeyutil \ + tests \ + tstclnt \ ++ validation \ + vfychain \ + vfyserv \ + modutil \ +diff --git a/cmd/validation/Makefile b/cmd/validation/Makefile +new file mode 100644 +--- /dev/null ++++ b/cmd/validation/Makefile +@@ -0,0 +1,48 @@ ++#! gmake ++# ++# 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/. ++ ++####################################################################### ++# (1) Include initial platform-independent assignments (MANDATORY). # ++####################################################################### ++ ++include manifest.mn ++ ++####################################################################### ++# (2) Include "global" configuration information. (OPTIONAL) # ++####################################################################### ++ ++include $(CORE_DEPTH)/coreconf/config.mk ++ ++####################################################################### ++# (3) Include "component" configuration information. (OPTIONAL) # ++####################################################################### ++ ++####################################################################### ++# (4) Include "local" platform-dependent assignments (OPTIONAL). # ++####################################################################### ++ ++include ../platlibs.mk ++ ++ ++####################################################################### ++# (5) Execute "global" rules. (OPTIONAL) # ++####################################################################### ++ ++include $(CORE_DEPTH)/coreconf/rules.mk ++ ++####################################################################### ++# (6) Execute "component" rules. (OPTIONAL) # ++####################################################################### ++ ++ ++ ++####################################################################### ++# (7) Execute "local" rules. (OPTIONAL). # ++####################################################################### ++ ++ ++include ../platrules.mk ++ +diff --git a/cmd/validation/manifest.mn b/cmd/validation/manifest.mn +new file mode 100644 +--- /dev/null ++++ b/cmd/validation/manifest.mn +@@ -0,0 +1,23 @@ ++# ++# 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/. ++ ++CORE_DEPTH = ../.. ++ ++DEFINES += -DNSPR20 ++ ++# MODULE public and private header directories are implicitly REQUIRED. ++MODULE = nss ++ ++CSRCS = \ ++ validation.c \ ++ $(NULL) ++ ++# The MODULE is always implicitly required. ++# Listing it here in REQUIRES makes it appear twice in the cc command line. ++REQUIRES = dbm seccmd ++ ++PROGRAM = validation ++ ++# USE_STATIC_LIBS = 1 +diff --git a/cmd/validation/validation.c b/cmd/validation/validation.c +new file mode 100644 +--- /dev/null ++++ b/cmd/validation/validation.c +@@ -0,0 +1,249 @@ ++/* 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/. */ ++ ++#ifdef _CRTDBG_MAP_ALLOC ++#include ++#include ++#endif ++ ++#include "nspr.h" ++#include "secutil.h" ++#include "pk11func.h" ++#include "nss.h" ++#include "secport.h" ++#include "secpkcs5.h" ++#include "sechash.h" ++#include "certdb.h" ++#include "secmod.h" ++ ++#define PKCS12_IN_BUFFER_SIZE 200 ++ ++static char *progName; ++PRBool debug = PR_FALSE; ++ ++#define ERR_USAGE 2 ++#define ERR_PK11GETSLOT 13 ++ ++static void ++Usage() ++{ ++#define FPS PR_fprintf(PR_STDERR, ++ FPS "Usage: %s [-d certdir] [-P dbprefix] [-h tokenname]\n", ++ progName); ++ FPS "\t\t [-k slotpwfile | -K slotpw] [-v]\n"); ++ ++ exit(ERR_USAGE); ++} ++ ++typedef enum { ++ tagULong, ++ tagVersion, ++ tagUtf8 ++} tagType; ++ ++typedef struct { ++ const char *attributeName; ++ tagType attributeStorageType; ++} attributeTag; ++ ++enum { ++ opt_CertDir = 0, ++ opt_TokenName, ++ opt_SlotPWFile, ++ opt_SlotPW, ++ opt_DBPrefix, ++ opt_Debug ++}; ++ ++static secuCommandFlag validation_options[] = ++ { ++ { /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE }, ++ { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE }, ++ { /* opt_SlotPWFile */ 'k', PR_TRUE, 0, PR_FALSE }, ++ { /* opt_SlotPW */ 'K', PR_TRUE, 0, PR_FALSE }, ++ { /* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE }, ++ { /* opt_Debug */ 'v', PR_FALSE, 0, PR_FALSE } ++ }; ++ ++void ++dump_Raw(char *label, CK_ATTRIBUTE *attr) ++{ ++ int i; ++ unsigned char *value = (unsigned char *)attr->pValue; ++ printf("0x"); ++ for (i = 0; i < attr->ulValueLen; i++) { ++ printf("%02x", value[i]); ++ } ++ printf("<%s>\n", label); ++} ++ ++SECStatus ++dump_validations(CK_OBJECT_CLASS objc, CK_ATTRIBUTE *template, int count, ++ attributeTag *tags, PK11SlotInfo *slot) ++{ ++ PK11GenericObject *objs, *obj; ++ ++ objs = PK11_FindGenericObjects(slot, objc); ++ ++ for (obj = objs; obj != NULL; obj = PK11_GetNextGenericObject(obj)) { ++ int i; ++ printf("Validation Object:\n"); ++ PK11_ReadRawAttributes(NULL, PK11_TypeGeneric, obj, template, count); ++ for (i = 0; i < count; i++) { ++ CK_ULONG ulong; ++ CK_VERSION version; ++ int len = template[i].ulValueLen; ++ printf(" %s: ", tags[i].attributeName); ++ if (len < 0) { ++ printf("\n"); ++ } else if (len == 0) { ++ printf("\n"); ++ } else ++ switch (tags[i].attributeStorageType) { ++ case tagULong: ++ if (len != sizeof(CK_ULONG)) { ++ dump_Raw("bad ulong", &template[i]); ++ break; ++ } ++ ulong = *(CK_ULONG *)template[i].pValue; ++ printf("%ld\n", ulong); ++ break; ++ case tagVersion: ++ if (len != sizeof(CK_VERSION)) { ++ dump_Raw("bad version", &template[i]); ++ break; ++ } ++ version = *(CK_VERSION *)template[i].pValue; ++ printf("%d.%d\n", version.major, version.minor); ++ break; ++ case tagUtf8: ++ printf("%.*s\n", len, (char *)template[i].pValue); ++ break; ++ default: ++ dump_Raw("unknown tag", &template[i]); ++ break; ++ } ++ PORT_Free(template[i].pValue); ++ template[i].pValue = NULL; ++ template[i].ulValueLen = 0; ++ } ++ } ++ PK11_DestroyGenericObjects(objs); ++ return SECSuccess; ++} ++ ++int ++main(int argc, char **argv) ++{ ++ secuPWData slotPw = { PW_NONE, NULL }; ++ secuPWData p12FilePw = { PW_NONE, NULL }; ++ PK11SlotInfo *slot; ++ char *slotname = NULL; ++ char *dbprefix = ""; ++ char *nssdir = NULL; ++ SECStatus rv; ++ secuCommand validation; ++ int local_errno = 0; ++ ++ CK_ATTRIBUTE validation_template[] = { ++ { CKA_NSS_VALIDATION_TYPE, NULL, 0 }, ++ { CKA_NSS_VALIDATION_VERSION, NULL, 0 }, ++ { CKA_NSS_VALIDATION_LEVEL, NULL, 0 }, ++ { CKA_NSS_VALIDATION_MODULE_ID, NULL, 0 } ++ }; ++ attributeTag validation_tags[] = { ++ { "Validation Type", tagULong }, ++ { "Validation Version", tagVersion }, ++ { "Validation Level", tagULong }, ++ { "Validation Module ID", tagUtf8 }, ++ }; ++ ++#ifdef _CRTDBG_MAP_ALLOC ++ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); ++#endif ++ ++ validation.numCommands = 0; ++ validation.commands = 0; ++ validation.numOptions = PR_ARRAY_SIZE(validation_options); ++ validation.options = validation_options; ++ ++ progName = strrchr(argv[0], '/'); ++ progName = progName ? progName + 1 : argv[0]; ++ ++ rv = SECU_ParseCommandLine(argc, argv, progName, &validation); ++ ++ if (rv != SECSuccess) ++ Usage(); ++ ++ debug = validation.options[opt_Debug].activated; ++ ++ slotname = SECU_GetOptionArg(&validation, opt_TokenName); ++ ++ if (validation.options[opt_SlotPWFile].activated) { ++ slotPw.source = PW_FROMFILE; ++ slotPw.data = PORT_Strdup(validation.options[opt_SlotPWFile].arg); ++ } ++ ++ if (validation.options[opt_SlotPW].activated) { ++ slotPw.source = PW_PLAINTEXT; ++ slotPw.data = PORT_Strdup(validation.options[opt_SlotPW].arg); ++ } ++ ++ if (validation.options[opt_CertDir].activated) { ++ nssdir = validation.options[opt_CertDir].arg; ++ } ++ if (validation.options[opt_DBPrefix].activated) { ++ dbprefix = validation.options[opt_DBPrefix].arg; ++ } ++ ++ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); ++ if (nssdir == NULL && NSS_NoDB_Init("") == SECSuccess) { ++ rv = SECSuccess; ++ /* if the system isn't already in FIPS mode, we need ++ * to switch to FIPS mode */ ++ if (!PK11_IsFIPS()) { ++ /* flip to FIPS mode */ ++ SECMODModule *module = SECMOD_GetInternalModule(); ++ rv = SECMOD_DeleteInternalModule(module->commonName); ++ } ++ } else { ++ rv = NSS_Initialize(nssdir, dbprefix, dbprefix, ++ "secmod.db", 0); ++ } ++ if (rv != SECSuccess) { ++ SECU_PrintPRandOSError(progName); ++ exit(-1); ++ } ++ ++ if (!slotname || PL_strcmp(slotname, "internal") == 0) ++ slot = PK11_GetInternalKeySlot(); ++ else ++ slot = PK11_FindSlotByName(slotname); ++ ++ if (!slot) { ++ SECU_PrintError(progName, "Invalid slot \"%s\"", slotname); ++ local_errno = ERR_PK11GETSLOT; ++ goto done; ++ } ++ ++ rv = dump_validations(CKO_NSS_VALIDATION, ++ validation_template, ++ PR_ARRAY_SIZE(validation_template), ++ validation_tags, ++ slot); ++ ++done: ++ if (slotPw.data != NULL) ++ PORT_ZFree(slotPw.data, PL_strlen(slotPw.data)); ++ if (p12FilePw.data != NULL) ++ PORT_ZFree(p12FilePw.data, PL_strlen(p12FilePw.data)); ++ if (slot) ++ PK11_FreeSlot(slot); ++ if (NSS_Shutdown() != SECSuccess) { ++ local_errno = 1; ++ } ++ PL_ArenaFinish(); ++ PR_Cleanup(); ++ return local_errno; ++} +diff --git a/cmd/validation/validation.gyp b/cmd/validation/validation.gyp +new file mode 100644 +--- /dev/null ++++ b/cmd/validation/validation.gyp +@@ -0,0 +1,30 @@ ++# 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/. ++{ ++ 'includes': [ ++ '../../coreconf/config.gypi', ++ '../../cmd/platlibs.gypi' ++ ], ++ 'targets': [ ++ { ++ 'target_name': 'validation', ++ 'type': 'executable', ++ 'sources': [ ++ 'validation.c' ++ ], ++ 'dependencies': [ ++ '<(DEPTH)/exports.gyp:dbm_exports', ++ '<(DEPTH)/exports.gyp:nss_exports' ++ ] ++ } ++ ], ++ 'target_defaults': { ++ 'defines': [ ++ 'NSPR20' ++ ] ++ }, ++ 'variables': { ++ 'module': 'nss' ++ } ++} +diff --git a/lib/softoken/config.mk b/lib/softoken/config.mk +--- a/lib/softoken/config.mk ++++ b/lib/softoken/config.mk +@@ -59,3 +59,7 @@ + DEFINES += -DNSS_ENABLE_FIPS_INDICATORS + endif + ++ifdef NSS_FIPS_MODULE_ID ++DEFINES += -DNSS_FIPS_MODULE_ID=\"${NSS_FIPS_MODULE_ID}\" ++endif ++ +diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c +--- a/lib/softoken/pkcs11.c ++++ b/lib/softoken/pkcs11.c +@@ -75,7 +75,6 @@ + * failure so that there are at most 60 login attempts per minute. + */ + static PRIntervalTime loginWaitTime; +-static PRUint32 minSessionObjectHandle = 1U; + + #define __PASTE(x, y) x##y + +@@ -1672,8 +1671,6 @@ + { + SFTKSlot *slot = session->slot; + SFTKAttribute *attribute; +- SFTKObject *duplicateObject = NULL; +- CK_OBJECT_HANDLE handle; + CK_BBOOL ckfalse = CK_FALSE; + CK_BBOOL cktrue = CK_TRUE; + CK_RV crv; +@@ -1711,30 +1708,13 @@ + * token objects and will have a token object handle assigned to + * them by a call to sftk_mkHandle in the handler for each object + * class, invoked below. +- * ++ * + * It may be helpful to note/remember that + * sftk_narrowToXxxObject uses sftk_isToken, + * sftk_isToken examines the sign bit of the object's handle, but + * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute. + */ +- do { +- PRUint32 wrappedAround; +- +- duplicateObject = NULL; +- PZ_Lock(slot->objectLock); +- wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK; +- handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK; +- if (!handle) /* don't allow zero handle */ +- handle = minSessionObjectHandle; +- slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround; +- /* Is there already a session object with this handle? */ +- if (wrappedAround) { +- sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, +- slot->sessObjHashSize); +- } +- PZ_Unlock(slot->objectLock); +- } while (duplicateObject != NULL); +- object->handle = handle; ++ object->handle = sftk_getNextHandle(slot); + + /* get the object class */ + attribute = sftk_FindAttribute(object, CKA_CLASS); +@@ -2875,10 +2855,15 @@ + goto mem_loser; + + slot->sessionIDCount = 0; +- slot->sessionObjectHandleCount = minSessionObjectHandle; ++ slot->sessionObjectHandleCount = NSC_MIN_SESSION_OBJECT_HANDLE; + slot->slotID = slotID; + sftk_setStringName(params->slotdes ? params->slotdes : sftk_getDefSlotName(slotID), slot->slotDescription, + sizeof(slot->slotDescription), PR_TRUE); ++ crv = sftk_InitSession(&slot->moduleObjects, slot, slotID, NULL, NULL, ++ CKF_SERIAL_SESSION); ++ if (crv != CKR_OK) { ++ goto loser; ++ } + + /* call the reinit code to set everything that changes between token + * init calls */ +@@ -2887,6 +2872,12 @@ + if (crv != CKR_OK) { + goto loser; + } ++ if (sftk_isFIPS(slotID)) { ++ crv = sftk_CreateValidationObjects(slot); ++ if (crv != CKR_OK) { ++ goto loser; ++ } ++ } + crv = sftk_RegisterSlot(slot, moduleIndex); + if (crv != CKR_OK) { + goto loser; +@@ -3032,6 +3023,8 @@ + + SFTK_ShutdownSlot(slot); + ++ sftk_ClearSession(&slot->moduleObjects); ++ + if (slot->tokObjHashTable) { + PL_HashTableDestroy(slot->tokObjHashTable); + slot->tokObjHashTable = NULL; +@@ -3262,6 +3255,7 @@ + CK_RV crv = CKR_OK; + SECStatus rv; + CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved; ++ PRBool destroy_freelist_on_error = PR_TRUE; + int i; + unsigned int moduleIndex = isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE; + +@@ -3341,7 +3335,14 @@ + "disabled FIPS mode"); + } + } ++ /* if we have a peer open, we don't want to destroy the freelist ++ * from under the peer if we fail, the free list will be ++ * destroyed in that case when the C_Finalize is called for ++ * the peer */ ++ destroy_freelist_on_error = PR_FALSE; + } ++ /* allow us to create objects in SFTK_SlotInit */ ++ sftk_InitFreeLists(); + + for (i = 0; i < paramStrings.token_count; i++) { + crv = SFTK_SlotInit(paramStrings.configdir, +@@ -3355,8 +3356,9 @@ + loser: + sftk_freeParams(¶mStrings); + } +- if (CKR_OK == crv) { +- sftk_InitFreeLists(); ++ if (destroy_freelist_on_error && (CKR_OK != crv)) { ++ /* idempotent. If the list are already freed, this is a noop */ ++ sftk_CleanupFreeLists(); + } + + #ifndef NO_FORK_CHECK +diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h +--- a/lib/softoken/pkcs11i.h ++++ b/lib/softoken/pkcs11i.h +@@ -49,6 +49,8 @@ + #define NSC_SEARCH_BLOCK_SIZE 5 + #define NSC_SLOT_LIST_BLOCK_SIZE 10 + ++#define NSC_MIN_SESSION_OBJECT_HANDLE 1U ++ + #define NSC_FIPS_MODULE 1 + #define NSC_NON_FIPS_MODULE 0 + +@@ -375,6 +377,9 @@ + char tokDescription[33]; /* per load */ + char updateTokDescription[33]; /* per load */ + char slotDescription[65]; /* invariant */ ++ SFTKSession moduleObjects; /* global session to hang module specific ++ * objects like profile objects or ++ * validation objects */ + }; + + /* +@@ -766,6 +771,7 @@ + extern void sftk_ReferenceObject(SFTKObject *object); + extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, + SFTKSession *session); ++extern CK_OBJECT_HANDLE sftk_getNextHandle(SFTKSlot *slot); + extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object); + extern void sftk_AddObject(SFTKSession *session, SFTKObject *object); + /* clear out all the existing object ID to database key mappings. +@@ -787,7 +793,11 @@ + extern CK_SLOT_ID sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle); + extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); + extern void sftk_FreeSession(SFTKSession *session); ++extern void sftk_ClearSession(SFTKSession *session); + extern void sftk_DestroySession(SFTKSession *session); ++extern CK_RV sftk_InitSession(SFTKSession *session, SFTKSlot *slot, ++ CK_SLOT_ID slotID, CK_NOTIFY notify, ++ CK_VOID_PTR pApplication, CK_FLAGS flags); + extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, + CK_VOID_PTR pApplication, CK_FLAGS flags); + extern void sftk_update_state(SFTKSlot *slot, SFTKSession *session); +@@ -955,6 +965,9 @@ + * FIPS security policy */ + PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, + CK_ATTRIBUTE_TYPE op, SFTKObject *source); ++/* add validation objects to the slot */ ++CK_RV sftk_CreateValidationObjects(SFTKSlot *slot); ++ + SEC_END_PROTOS + + #endif /* _PKCS11I_H_ */ +diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c +--- a/lib/softoken/pkcs11u.c ++++ b/lib/softoken/pkcs11u.c +@@ -14,6 +14,7 @@ + #include "sftkdb.h" + #include "softoken.h" + #include "secoid.h" ++#include "softkver.h" + + #if !defined(NSS_FIPS_DISABLED) && defined(NSS_ENABLE_FIPS_INDICATORS) + /* this file should be supplied by the vendor and include all the +@@ -1243,6 +1244,32 @@ + return SFTK_Busy; + } + ++/* find the next available object handle that isn't currently in use */ ++CK_OBJECT_HANDLE ++sftk_getNextHandle(SFTKSlot *slot) ++{ ++ CK_OBJECT_HANDLE handle; ++ SFTKObject *duplicateObject = NULL; ++ do { ++ PRUint32 wrappedAround; ++ ++ duplicateObject = NULL; ++ PZ_Lock(slot->objectLock); ++ wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK; ++ handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK; ++ if (!handle) /* don't allow zero handle */ ++ handle = NSC_MIN_SESSION_OBJECT_HANDLE; ++ slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround; ++ /* Is there already a session object with this handle? */ ++ if (wrappedAround) { ++ sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, ++ slot->sessObjHashSize); ++ } ++ PZ_Unlock(slot->objectLock); ++ } while (duplicateObject != NULL); ++ return handle; ++} ++ + /* + * add an object to a slot and session queue. These two functions + * adopt the object. +@@ -1848,23 +1875,13 @@ + } + + /* +- * create a new nession. NOTE: The session handle is not set, and the ++ * Init a new session. NOTE: The session handle is not set, and the + * session is not added to the slot's session queue. + */ +-SFTKSession * +-sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, +- CK_FLAGS flags) ++CK_RV ++sftk_InitSession(SFTKSession *session, SFTKSlot *slot, CK_SLOT_ID slotID, ++ CK_NOTIFY notify, CK_VOID_PTR pApplication, CK_FLAGS flags) + { +- SFTKSession *session; +- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); +- +- if (slot == NULL) +- return NULL; +- +- session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession)); +- if (session == NULL) +- return NULL; +- + session->next = session->prev = NULL; + session->enc_context = NULL; + session->hash_context = NULL; +@@ -1873,8 +1890,7 @@ + session->objectIDCount = 1; + session->objectLock = PZ_NewLock(nssILockObject); + if (session->objectLock == NULL) { +- PORT_Free(session); +- return NULL; ++ return CKR_HOST_MEMORY; + } + session->objects[0] = NULL; + +@@ -1887,12 +1903,38 @@ + sftk_update_state(slot, session); + /* no ops completed yet, so the last one couldn't be a FIPS op */ + session->lastOpWasFIPS = PR_FALSE; ++ return CKR_OK; ++} ++ ++/* ++ * Create a new session and init it. ++ */ ++SFTKSession * ++sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, ++ CK_FLAGS flags) ++{ ++ SFTKSession *session; ++ SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); ++ CK_RV crv; ++ ++ if (slot == NULL) ++ return NULL; ++ ++ session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession)); ++ if (session == NULL) ++ return NULL; ++ ++ crv = sftk_InitSession(session, slot, slotID, notify, pApplication, flags); ++ if (crv != CKR_OK) { ++ PORT_Free(session); ++ return NULL; ++ } + return session; + } + + /* free all the data associated with a session. */ + void +-sftk_DestroySession(SFTKSession *session) ++sftk_ClearSession(SFTKSession *session) + { + SFTKObjectList *op, *next; + +@@ -1918,6 +1960,13 @@ + if (session->search) { + sftk_FreeSearch(session->search); + } ++} ++ ++/* free the data associated with the session, and the session */ ++void ++sftk_DestroySession(SFTKSession *session) ++{ ++ sftk_ClearSession(session); + PORT_Free(session); + } + +@@ -2386,3 +2435,70 @@ + return PR_FALSE; + #endif + } ++ ++/* ++ * create the FIPS Validation objects. If the vendor ++ * doesn't supply an NSS_FIPS_MODULE_ID, at compile time, ++ * then we assumethis is an unvalidated module. ++ */ ++CK_RV ++sftk_CreateValidationObjects(SFTKSlot *slot) ++{ ++ const char *module_id; ++ int module_id_len; ++ CK_RV crv = CKR_OK; ++ /* we currently use vendor specific values until the validation ++ * objects are approved for PKCS #11 v3.2. */ ++ CK_OBJECT_CLASS cko_validation = CKO_NSS_VALIDATION; ++ CK_NSS_VALIDATION_TYPE ckv_fips = CKV_NSS_FIPS_140; ++ CK_VERSION fips_version = { 3, 0 }; /* FIPS-140-3 */ ++ CK_ULONG fips_level = 1; /* or 2 if you validated at level 2 */ ++ ++#ifndef NSS_FIPS_MODULE_ID ++#define NSS_FIPS_MODULE_ID "Generic NSS " SOFTOKEN_VERSION " Unvalidated" ++#endif ++ module_id = NSS_FIPS_MODULE_ID; ++ module_id_len = sizeof(NSS_FIPS_MODULE_ID) - 1; ++ SFTKObject *object; ++ ++ object = sftk_NewObject(slot); /* fill in the handle later */ ++ if (object == NULL) { ++ return CKR_HOST_MEMORY; ++ } ++ object->isFIPS = PR_FALSE; ++ ++ crv = sftk_AddAttributeType(object, CKA_CLASS, ++ &cko_validation, sizeof(cko_validation)); ++ if (crv != CKR_OK) { ++ goto loser; ++ } ++ crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_TYPE, ++ &ckv_fips, sizeof(ckv_fips)); ++ if (crv != CKR_OK) { ++ goto loser; ++ } ++ crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_VERSION, ++ &fips_version, sizeof(fips_version)); ++ if (crv != CKR_OK) { ++ goto loser; ++ } ++ crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_LEVEL, ++ &fips_level, sizeof(fips_level)); ++ if (crv != CKR_OK) { ++ goto loser; ++ } ++ crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_MODULE_ID, ++ module_id, module_id_len); ++ if (crv != CKR_OK) { ++ goto loser; ++ } ++ ++ /* future, fill in validation certificate information from a supplied ++ * pointer to a config file */ ++ object->handle = sftk_getNextHandle(slot); ++ object->slot = slot; ++ sftk_AddObject(&slot->moduleObjects, object); ++loser: ++ sftk_FreeObject(object); ++ return crv; ++} +diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h +--- a/lib/util/pkcs11n.h ++++ b/lib/util/pkcs11n.h +@@ -38,6 +38,9 @@ + #define CKO_NSS_BUILTIN_ROOT_LIST (CKO_NSS + 4) + #define CKO_NSS_NEWSLOT (CKO_NSS + 5) + #define CKO_NSS_DELSLOT (CKO_NSS + 6) ++#define CKO_NSS_VALIDATION (CKO_NSS + 7) ++ ++#define CKV_NSS_FIPS_140 (CKO_NSS + 1) + + /* + * NSS-defined key types +@@ -99,6 +102,11 @@ + #define CKA_NSS_SERVER_DISTRUST_AFTER (CKA_NSS + 35) + #define CKA_NSS_EMAIL_DISTRUST_AFTER (CKA_NSS + 36) + ++#define CKA_NSS_VALIDATION_TYPE (CKA_NSS + 36) ++#define CKA_NSS_VALIDATION_VERSION (CKA_NSS + 37) ++#define CKA_NSS_VALIDATION_LEVEL (CKA_NSS + 38) ++#define CKA_NSS_VALIDATION_MODULE_ID (CKA_NSS + 39) ++ + /* + * Trust attributes: + * +@@ -344,6 +352,9 @@ + #define CKR_NSS_CERTDB_FAILED (CKR_NSS + 1) + #define CKR_NSS_KEYDB_FAILED (CKR_NSS + 2) + ++/* NSS specific types */ ++typedef CK_ULONG CK_NSS_VALIDATION_TYPE; ++ + /* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms. + See RFC 5869. + +diff --git a/nss.gyp b/nss.gyp +--- a/nss.gyp ++++ b/nss.gyp +@@ -131,6 +131,7 @@ + 'cmd/smimetools/smimetools.gyp:cmsutil', + 'cmd/ssltap/ssltap.gyp:ssltap', + 'cmd/symkeyutil/symkeyutil.gyp:symkeyutil', ++ 'cmd/validation/validation.gyp:validation', + 'nss-tool/nss_tool.gyp:nss', + 'nss-tool/nss_tool.gyp:hw-support', + ], + diff --git a/SOURCES/nss-3.71-ipv6-fix.patch b/SOURCES/nss-3.71-ipv6-fix.patch new file mode 100644 index 0000000..b72c80f --- /dev/null +++ b/SOURCES/nss-3.71-ipv6-fix.patch @@ -0,0 +1,36 @@ +diff -up ./cmd/selfserv/selfserv.c.ipv6_fix ./cmd/selfserv/selfserv.c +--- ./cmd/selfserv/selfserv.c.ipv6_fix 2021-09-14 11:40:06.176408531 -0700 ++++ ./cmd/selfserv/selfserv.c 2021-09-14 11:49:46.361907308 -0700 +@@ -1717,14 +1717,28 @@ getBoundListenSocket(unsigned short port + PRNetAddr addr; + PRSocketOptionData opt; + +- addr.inet.family = PR_AF_INET; +- addr.inet.ip = PR_INADDR_ANY; +- addr.inet.port = PR_htons(port); ++ if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr) != PR_SUCCESS) { ++ errExit("PR_SetNetAddr"); ++ } + +- listen_sock = PR_NewTCPSocket(); ++ listen_sock = PR_OpenTCPSocket(PR_AF_INET6); + if (listen_sock == NULL) { + errExit("PR_NewTCPSocket"); + } ++ /* NSPR has a bug where set inheritable doesn't work unless it's a pure ++ * NSPR socket. If we have an IPV6 emulator on an IPV4 socket, it will fail. ++ * In that case just open an IPV4 socket instead */ ++ if (PR_NSPR_IO_LAYER != PR_GetLayersIdentity(listen_sock)) { ++ PR_Close(listen_sock); ++ addr.inet.family = PR_AF_INET; ++ addr.inet.ip = PR_INADDR_ANY; ++ addr.inet.port = PR_htons(port); ++ ++ listen_sock = PR_NewTCPSocket(); ++ if (listen_sock == NULL) { ++ errExit("PR_NewTCPSocket"); ++ } ++ } + + opt.option = PR_SockOpt_Nonblocking; + opt.value.non_blocking = PR_FALSE; diff --git a/SOURCES/nss-539183.patch b/SOURCES/nss-539183.patch deleted file mode 100644 index 267e71e..0000000 --- a/SOURCES/nss-539183.patch +++ /dev/null @@ -1,62 +0,0 @@ ---- nss/cmd/httpserv/httpserv.c.539183 2016-05-21 18:31:39.879585420 -0700 -+++ nss/cmd/httpserv/httpserv.c 2016-05-21 18:37:22.374464057 -0700 -@@ -953,23 +953,23 @@ - getBoundListenSocket(unsigned short port) - { - PRFileDesc *listen_sock; - int listenQueueDepth = 5 + (2 * maxThreads); - PRStatus prStatus; - PRNetAddr addr; - PRSocketOptionData opt; - -- addr.inet.family = PR_AF_INET; -- addr.inet.ip = PR_INADDR_ANY; -- addr.inet.port = PR_htons(port); -+ if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr) != PR_SUCCESS) { -+ errExit("PR_SetNetAddr"); -+ } - -- listen_sock = PR_NewTCPSocket(); -+ listen_sock = PR_OpenTCPSocket(PR_AF_INET6); - if (listen_sock == NULL) { -- errExit("PR_NewTCPSocket"); -+ errExit("PR_OpenTCPSockett"); - } - - opt.option = PR_SockOpt_Nonblocking; - opt.value.non_blocking = PR_FALSE; - prStatus = PR_SetSocketOption(listen_sock, &opt); - if (prStatus < 0) { - PR_Close(listen_sock); - errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)"); ---- nss/cmd/selfserv/selfserv.c.539183 2016-05-21 18:31:39.882585367 -0700 -+++ nss/cmd/selfserv/selfserv.c 2016-05-21 18:41:43.092801174 -0700 -@@ -1711,23 +1711,23 @@ - getBoundListenSocket(unsigned short port) - { - PRFileDesc *listen_sock; - int listenQueueDepth = 5 + (2 * maxThreads); - PRStatus prStatus; - PRNetAddr addr; - PRSocketOptionData opt; - -- addr.inet.family = PR_AF_INET; -- addr.inet.ip = PR_INADDR_ANY; -- addr.inet.port = PR_htons(port); -+ if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr) != PR_SUCCESS) { -+ errExit("PR_SetNetAddr"); -+ } - -- listen_sock = PR_NewTCPSocket(); -+ listen_sock = PR_OpenTCPSocket(PR_AF_INET6); - if (listen_sock == NULL) { -- errExit("PR_NewTCPSocket"); -+ errExit("PR_OpenTCPSocket error"); - } - - opt.option = PR_SockOpt_Nonblocking; - opt.value.non_blocking = PR_FALSE; - prStatus = PR_SetSocketOption(listen_sock, &opt); - if (prStatus < 0) { - PR_Close(listen_sock); - errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)"); diff --git a/SOURCES/nss-fedora-btrf-sql-hack.patch b/SOURCES/nss-fedora-btrf-sql-hack.patch deleted file mode 100644 index db60cc2..0000000 --- a/SOURCES/nss-fedora-btrf-sql-hack.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up ./lib/softoken/sdb.c.orig ./lib/softoken/sdb.c ---- ./lib/softoken/sdb.c.orig 2020-12-11 22:49:26.961726193 -0500 -+++ ./lib/softoken/sdb.c 2020-12-11 23:01:30.739122494 -0500 -@@ -690,8 +690,14 @@ sdb_openDB(const char *name, sqlite3 **s - openFlags = SQLITE_OPEN_READONLY; - } else { - openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; -+ /* btrfs and sqlite seem to incorrectly open readwrite. -+ * when the file is readonly explicitly reject that issue here */ -+ if ((_NSSUTIL_Access(name, PR_ACCESS_EXISTS) == PR_SUCCESS) && (_NSSUTIL_Access(name, PR_ACCESS_WRITE_OK) != PR_SUCCESS)) { -+ return SQLITE_READONLY; -+ } - } - -+ - /* Requires SQLite 3.5.0 or newer. */ - sqlerr = sqlite3_open_v2(name, sqlDB, openFlags, NULL); - if (sqlerr != SQLITE_OK) { diff --git a/SPECS/nss.spec b/SPECS/nss.spec index 04a14b6..84bdc0b 100644 --- a/SPECS/nss.spec +++ b/SPECS/nss.spec @@ -4,9 +4,9 @@ # - increment %%{nspr_version}, when updating the NSS part only # - put the nss_release number here next to nspr, as they both # need to be updated on a given release -%global nspr_release 2 -%global nss_release 13 -%global nss_version 3.67.0 +%global nss_release 2 +%global nspr_release %[%nss_release+2] +%global nss_version 3.71.0 # only need to update this as we added new # algorithms under nss policy control %global crypto_policies_version 20210118 @@ -111,7 +111,7 @@ Source100: nspr-%{nspr_archive_version}.tar.gz Source101: nspr-config.xml # Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=617723 -Patch2: nss-539183.patch +Patch2: nss-3.71-ipv6-fix.patch # This patch uses the GCC -iquote option documented at # http://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options # to give the in-tree headers a higher priority over the system headers, @@ -125,8 +125,6 @@ Patch2: nss-539183.patch # but it doesn't hurt to keep it. Patch4: iquote.patch Patch12: nss-signtool-format.patch -# can drop this patch when the underlying btrfs/sqlite issue is solved -Patch30: nss-fedora-btrf-sql-hack.patch # connect our shared library to the build root loader flags (needed for -relro) Patch31: nss-dso-ldflags.patch # keep RHEL 8 semantics of disabling md4 and md5 even if the env variable is set @@ -137,22 +135,8 @@ Patch32: nss-disable-md5.patch Patch33: nss-no-dbm-man-page.patch %endif -# Patches that should be upstreamed, and (hopefully) will disappear next -# rebase -# Need upstream bug -Patch50: nss-3.44-kbkdf-coverity.patch -# no upsteam bug yet -Patch51: nss-3.67-fix-private-key-mac.patch -# no upstream bug yet -Patch52: nss-3.53.1-measure-fix.patch -# no upstream bug yet -Patch53: nss-3.66-no-small-primes.patch -# no upstream bug yet -Patch54: nss-3.66-fix-gtest-parsing.patch -# no upstream bug yet -Patch55: nss-3.67-fix-coverity-issues.patch -# no upstream bug yet -Patch60: nss-3.67-fix-ssl-alerts.patch +# upstream bug https://bugzilla.mozilla.org/show_bug.cgi?id=1729550 +Patch50: nss-3.71-fips-module-name.patch Patch100: nspr-config-pc.patch Patch101: nspr-gcc-atomics.patch @@ -387,7 +371,26 @@ popd # uncomment if the iquote patch is activated export IN_TREE_FREEBL_HEADERS_FIRST=1 +# FIPS related defines export NSS_FORCE_FIPS=1 +export NSS_FIPS_VERSION="%{name}\ %{version}-$(date +%Y%m%d)" +%if %{defined rhel} +%if %{defined centos} + export NSS_FIPS_MODULE_ID="Centos\ %rhel\ ${NSS_FIPS_VERSION}\ unvalidated" +%else +if grep "Red Hat" /etc/system-release; then + export NSS_FIPS_MODULE_ID="Red\ Hat\ Enterprise\ Linux\ %rhel\ ${NSS_FIPS_VERSION}" +else + export NSS_FIPS_MODULE_ID="Generic\ Enterprise\ Linux\ %rhel\ ${NSS_FIPS_VERSION}\ unvalidated" +fi +%endif +%else +%if %{defined fedora} + export NSS_FIPS_MODULE_ID="Fedora\ %fedora\ ${NSS_FIPS_VERSION}\ unvalidated" +%else + export NSS_FIPS_MODULE_ID="Generic\ Linux\ ${NSS_FIPS_VERSION}\ unvalidated" +%endif +%endif # Enable compiler optimizations and disable debugging code export BUILD_OPT=1 @@ -719,7 +722,7 @@ do done # Copy the binaries we ship as unsupported -for file in bltest ecperf fbectest fipstest shlibsign atob btoa derdump listsuites ocspclnt pp selfserv signtool strsclnt symkeyutil tstclnt vfyserv vfychain +for file in bltest ecperf fbectest fipstest shlibsign atob btoa derdump listsuites ocspclnt pp selfserv signtool strsclnt symkeyutil tstclnt validation vfyserv vfychain do install -p -m 755 dist/*.OBJ/bin/$file $RPM_BUILD_ROOT/%{unsupported_tools_directory} done @@ -766,7 +769,7 @@ for f in nss-config setup-nsssysinit; do install -c -m 644 ${f}.1 $RPM_BUILD_ROOT%{_mandir}/man1/${f}.1 done # Copy the man pages for the nss tools -for f in certutil cmsutil crlutil derdump modutil pk12util signtool signver ssltap vfychain vfyserv; do +for f in certutil cmsutil crlutil derdump modutil nss-policy-check pk12util signtool signver ssltap vfychain vfyserv; do install -c -m 644 ./dist/docs/nroff/${f}.1 $RPM_BUILD_ROOT%{_mandir}/man1/${f}.1 done %if %{defined rhel} @@ -858,6 +861,7 @@ update-crypto-policies &> /dev/null || : %{unsupported_tools_directory}/strsclnt %{unsupported_tools_directory}/symkeyutil %{unsupported_tools_directory}/tstclnt +%{unsupported_tools_directory}/validation %{unsupported_tools_directory}/vfyserv %{unsupported_tools_directory}/vfychain # instead of %%{_mandir}/man*/* let's list them explicitly @@ -866,6 +870,7 @@ update-crypto-policies &> /dev/null || : %doc %{_mandir}/man1/cmsutil.1* %doc %{_mandir}/man1/crlutil.1* %doc %{_mandir}/man1/modutil.1* +%doc %{_mandir}/man1/nss-policy-check.1* %doc %{_mandir}/man1/pk12util.1* %doc %{_mandir}/man1/signver.1* # unsupported tools @@ -1076,6 +1081,13 @@ update-crypto-policies &> /dev/null || : %changelog +* Tue Oct 19 2021 Bob Relyea - 3.71.0-2 +- make sure validation is built +- fix syntax on FIPS module name + +* Tue Oct 5 2021 Bob Relyea - 3.71.0-1 +- rebase to NSS-3.71 + * Wed Aug 25 2021 Bob Relyea - 3.67.0-13 - rebuild to clear gating.yaml test