commit 20685f0bae4027f63c880b5e00bae5cb839c4795 Author: CentOS Sources Date: Wed Mar 15 09:49:21 2023 +0000 import nss-3.79.0-11.el8_7 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4befa78 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +SOURCES/blank-cert8.db +SOURCES/blank-cert9.db +SOURCES/blank-key3.db +SOURCES/blank-key4.db +SOURCES/blank-secmod.db +SOURCES/nss-3.79.tar.gz diff --git a/.nss.metadata b/.nss.metadata new file mode 100644 index 0000000..b374a5a --- /dev/null +++ b/.nss.metadata @@ -0,0 +1,6 @@ +d272a7b58364862613d44261c5744f7a336bf177 SOURCES/blank-cert8.db +b5570125fbf6bfb410705706af48217a0817c03a SOURCES/blank-cert9.db +7f78b5bcecdb5005e7b803604b2ec9d1a9df2fb5 SOURCES/blank-key3.db +f9c9568442386da370193474de1b25c3f68cdaf6 SOURCES/blank-key4.db +bd748cf6e1465a1bbe6e751b72ffc0076aff0b50 SOURCES/blank-secmod.db +3719dd97c8ec9cb04aa61e6aca41b129b4adc004 SOURCES/nss-3.79.tar.gz diff --git a/SOURCES/cert8.db.xml b/SOURCES/cert8.db.xml new file mode 100644 index 0000000..e82948d --- /dev/null +++ b/SOURCES/cert8.db.xml @@ -0,0 +1,59 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + cert8.db + 5 + + + + cert8.db + Legacy NSS certificate database + + + + Description + cert8.db is an NSS certificate database. + This certificate database is in the legacy database format. Consider migrating to cert9.db and key4.db which are the new sqlite-based shared database format with support for concurrent access. + + + + + Files + /etc/pki/nssdb/cert8.db + + + + See also + cert9.db(5), key4.db(5), pkcs11.txt(5), + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + + diff --git a/SOURCES/cert9.db.xml b/SOURCES/cert9.db.xml new file mode 100644 index 0000000..815d3f9 --- /dev/null +++ b/SOURCES/cert9.db.xml @@ -0,0 +1,59 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + cert9.db + 5 + + + + cert9.db + NSS certificate database + + + + Description + cert9.db is an NSS certificate database. + This certificate database is the sqlite-based shared database with support for concurrent access. + + + + + Files + /etc/pki/nssdb/cert9.db + + + + See also + pkcs11.txt(5) + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + + diff --git a/SOURCES/cve-2023-0767.patch b/SOURCES/cve-2023-0767.patch new file mode 100644 index 0000000..fc5d4fa --- /dev/null +++ b/SOURCES/cve-2023-0767.patch @@ -0,0 +1,92 @@ +diff --git a/lib/pkcs12/p12d.c b/lib/pkcs12/p12d.c +--- a/lib/pkcs12/p12d.c ++++ b/lib/pkcs12/p12d.c +@@ -335,35 +335,42 @@ + sec_PKCS12SafeContentsContext *safeContentsCtx = + (sec_PKCS12SafeContentsContext *)arg; + SEC_PKCS12DecoderContext *p12dcx; + SECStatus rv; + +- /* make sure that we are not skipping the current safeBag, +- * and that there are no errors. If so, just return rather +- * than continuing to process. +- */ +- if (!safeContentsCtx || !safeContentsCtx->p12dcx || +- safeContentsCtx->p12dcx->error || safeContentsCtx->skipCurrentSafeBag) { ++ if (!safeContentsCtx || !safeContentsCtx->p12dcx || !safeContentsCtx->currentSafeBagA1Dcx) { + return; + } + p12dcx = safeContentsCtx->p12dcx; + ++ /* make sure that there are no errors and we are not skipping the current safeBag */ ++ if (p12dcx->error || safeContentsCtx->skipCurrentSafeBag) { ++ goto loser; ++ } ++ + rv = SEC_ASN1DecoderUpdate(safeContentsCtx->currentSafeBagA1Dcx, data, len); + if (rv != SECSuccess) { + p12dcx->errorValue = PORT_GetError(); ++ p12dcx->error = PR_TRUE; ++ goto loser; ++ } ++ ++ /* The update may have set safeContentsCtx->skipCurrentSafeBag, and we ++ * may not get another opportunity to clean up the decoder context. ++ */ ++ if (safeContentsCtx->skipCurrentSafeBag) { + goto loser; + } + + return; + + loser: +- /* set the error, and finish the decoder context. because there ++ /* Finish the decoder context. Because there + * is not a way of returning an error message, it may be worth + * while to do a check higher up and finish any decoding contexts + * that are still open. + */ +- p12dcx->error = PR_TRUE; + SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx); + safeContentsCtx->currentSafeBagA1Dcx = NULL; + return; + } + +diff --git a/lib/pkcs12/p12t.h b/lib/pkcs12/p12t.h +--- a/lib/pkcs12/p12t.h ++++ b/lib/pkcs12/p12t.h +@@ -71,10 +71,11 @@ + SECKEYEncryptedPrivateKeyInfo *pkcs8ShroudedKeyBag; + sec_PKCS12CertBag *certBag; + sec_PKCS12CRLBag *crlBag; + sec_PKCS12SecretBag *secretBag; + sec_PKCS12SafeContents *safeContents; ++ SECItem *unknownBag; + } safeBagContent; + + sec_PKCS12Attribute **attribs; + + /* used locally */ +diff --git a/lib/pkcs12/p12tmpl.c b/lib/pkcs12/p12tmpl.c +--- a/lib/pkcs12/p12tmpl.c ++++ b/lib/pkcs12/p12tmpl.c +@@ -28,16 +28,16 @@ + + safeBag = (sec_PKCS12SafeBag *)src_or_dest; + + oiddata = SECOID_FindOID(&safeBag->safeBagType); + if (oiddata == NULL) { +- return SEC_ASN1_GET(SEC_AnyTemplate); ++ return SEC_ASN1_GET(SEC_PointerToAnyTemplate); + } + + switch (oiddata->offset) { + default: +- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); ++ theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); + break; + case SEC_OID_PKCS12_V1_KEY_BAG_ID: + theTemplate = SEC_ASN1_GET(SECKEY_PointerToPrivateKeyInfoTemplate); + break; + case SEC_OID_PKCS12_V1_CERT_BAG_ID: + diff --git a/SOURCES/iquote.patch b/SOURCES/iquote.patch new file mode 100644 index 0000000..6e4adcd --- /dev/null +++ b/SOURCES/iquote.patch @@ -0,0 +1,13 @@ +diff -up nss/coreconf/location.mk.iquote nss/coreconf/location.mk +--- nss/coreconf/location.mk.iquote 2017-07-27 16:09:32.000000000 +0200 ++++ nss/coreconf/location.mk 2017-09-06 13:23:14.633611555 +0200 +@@ -75,4 +75,9 @@ ifndef SQLITE_LIB_NAME + SQLITE_LIB_NAME = sqlite3 + endif + ++# Prefer in-tree headers over system headers ++ifdef IN_TREE_FREEBL_HEADERS_FIRST ++ INCLUDES += -iquote $(DIST)/../public/nss -iquote $(DIST)/../private/nss ++endif ++ + MK_LOCATION = included diff --git a/SOURCES/key3.db.xml b/SOURCES/key3.db.xml new file mode 100644 index 0000000..444d7aa --- /dev/null +++ b/SOURCES/key3.db.xml @@ -0,0 +1,59 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + key3.db + 5 + + + + key3.db + Legacy NSS certificate database + + + + Description + key3.db is an NSS certificate database. + This is a key database in the legacy database format. Consider migrating to cert9.db and key4.db which which are the new sqlite-based shared database format with support for concurrent access. + + + + + Files + /etc/pki/nssdb/key3.db + + + + See also + cert9.db(5), key4.db(5), pkcs11.txt(5), + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + + diff --git a/SOURCES/key4.db.xml b/SOURCES/key4.db.xml new file mode 100644 index 0000000..9b65f41 --- /dev/null +++ b/SOURCES/key4.db.xml @@ -0,0 +1,59 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + key4.db + 5 + + + + key4.db + NSS certificate database + + + + Description + key4.db is an NSS key database. + This key database is the sqlite-based shared database format with support for concurrent access. + + + + + Files + /etc/pki/nssdb/key4.db + + + + See also + pkcs11.txt(5) + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + + diff --git a/SOURCES/nss-3.66-disable-external-host-test.patch b/SOURCES/nss-3.66-disable-external-host-test.patch new file mode 100644 index 0000000..7f04502 --- /dev/null +++ b/SOURCES/nss-3.66-disable-external-host-test.patch @@ -0,0 +1,14 @@ +diff -up ./tests/ssl/ssl.sh.brew ./tests/ssl/ssl.sh +--- ./tests/ssl/ssl.sh.brew 2021-06-12 11:37:46.153265942 -0700 ++++ ./tests/ssl/ssl.sh 2021-06-12 11:39:43.069925034 -0700 +@@ -1641,7 +1641,9 @@ ssl_run_tests() + if [ "${TEST_MODE}" = "SHARED_DB" ] ; then + ssl_policy_listsuites + ssl_policy_selfserv +- ssl_policy_pkix_ocsp ++ # requires access to external servers, which fails ++ # when running in brew ++ #ssl_policy_pkix_ocsp + ssl_policy + fi + ;; diff --git a/SOURCES/nss-3.66-disable-signature-policies.patch b/SOURCES/nss-3.66-disable-signature-policies.patch new file mode 100644 index 0000000..3329634 --- /dev/null +++ b/SOURCES/nss-3.66-disable-signature-policies.patch @@ -0,0 +1,42 @@ +diff -up ./lib/pk11wrap/pk11pars.c.no_signature_policy ./lib/pk11wrap/pk11pars.c +--- ./lib/pk11wrap/pk11pars.c.no_signature_policy 2021-06-03 10:08:49.988118880 -0700 ++++ ./lib/pk11wrap/pk11pars.c 2021-06-03 10:16:26.059935708 -0700 +@@ -391,12 +391,9 @@ static const oidValDef signOptList[] = { + /* Signatures */ + { CIPHER_NAME("DSA"), SEC_OID_ANSIX9_DSA_SIGNATURE, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, +- { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION, +- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, +- { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE, +- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, +- { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, +- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, ++ { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION, 0}, ++ { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0}, ++ { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, 0}, + }; + + typedef struct { +@@ -412,7 +409,7 @@ static const algListsDef algOptLists[] = + { macOptList, PR_ARRAY_SIZE(macOptList), "MAC", PR_FALSE }, + { cipherOptList, PR_ARRAY_SIZE(cipherOptList), "CIPHER", PR_FALSE }, + { kxOptList, PR_ARRAY_SIZE(kxOptList), "OTHER-KX", PR_FALSE }, +- { signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_FALSE }, ++ { signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_TRUE }, + }; + + static const optionFreeDef sslOptList[] = { +diff -up ./tests/ssl/sslpolicy.txt.policy_revert ./tests/ssl/sslpolicy.txt +--- ./tests/ssl/sslpolicy.txt.policy_revert 2020-11-04 10:31:20.837715397 -0800 ++++ ./tests/ssl/sslpolicy.txt 2020-11-04 10:33:19.598357223 -0800 +@@ -193,7 +193,9 @@ + 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:rsa:des-ede3-cbc:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly Narrow + 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly + 0 noECC SSL3 d disallow=dsa Disallow DSA Signatures Explicitly +- 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly ++# rsa-pkcs, rsa-pss, and ecdsa policy checking reverted in rhel8 for binary ++# compatibility reasons ++# 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly + # test default settings + # NOTE: tstclient will attempt to overide the defaults, so we detect we + # were successful by locking in our settings diff --git a/SOURCES/nss-3.66-restore-old-pkcs12-default.patch b/SOURCES/nss-3.66-restore-old-pkcs12-default.patch new file mode 100644 index 0000000..54f020c --- /dev/null +++ b/SOURCES/nss-3.66-restore-old-pkcs12-default.patch @@ -0,0 +1,44 @@ +diff -up ./cmd/pk12util/pk12util.c.orig ./cmd/pk12util/pk12util.c +--- ./cmd/pk12util/pk12util.c.orig 2021-05-28 02:50:43.000000000 -0700 ++++ ./cmd/pk12util/pk12util.c 2021-06-15 17:05:37.200262345 -0700 +@@ -1031,9 +1031,11 @@ main(int argc, char **argv) + char *export_file = NULL; + char *dbprefix = ""; + SECStatus rv; +- SECOidTag cipher = SEC_OID_AES_256_CBC; +- SECOidTag hash = SEC_OID_SHA256; +- SECOidTag certCipher = SEC_OID_AES_128_CBC; ++ SECOidTag cipher = ++ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC; ++ SECOidTag hash = SEC_OID_SHA1; ++ SECOidTag certCipher = ++ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC; + int keyLen = 0; + int certKeyLen = 0; + secuCommand pk12util; +@@ -1147,6 +1149,9 @@ main(int argc, char **argv) + } + } + ++ if (PK11_IsFIPS()) { ++ certCipher = SEC_OID_UNKNOWN; ++ } + if (pk12util.options[opt_CertCipher].activated) { + char *cipherString = pk12util.options[opt_CertCipher].arg; + +diff -up ./tests/tools/tools.sh.orig ./tests/tools/tools.sh +--- ./tests/tools/tools.sh.orig 2021-06-15 17:06:27.650564449 -0700 ++++ ./tests/tools/tools.sh 2021-06-15 17:07:59.934117192 -0700 +@@ -47,9 +47,9 @@ + "PKCS #5 Password Based Encryption with SHA-1 and DES-CBC" + + # if we change the defaults in pk12util, update these variables +- export CERT_ENCRYPTION_DEFAULT="AES-128-CBC" +- export KEY_ENCRYPTION_DEFAULT="AES-256-CBC" +- export HASH_DEFAULT="SHA-256" ++ export CERT_ENCRYPTION_DEFAULT=${pkcs12v2pbeWithSha1And40BitRc2Cbc} ++ export KEY_ENCRYPTION_DEFAULT=${pkcs12v2pbeWithSha1AndTripleDESCBC} ++ export HASH_DEFAULT="SHA-1" + + export PKCS5v1_PBE_CIPHERS="${pkcs5pbeWithMD2AndDEScbc},\ + ${pkcs5pbeWithMD5AndDEScbc},\ diff --git a/SOURCES/nss-3.79-dbtool.patch b/SOURCES/nss-3.79-dbtool.patch new file mode 100644 index 0000000..b61942b --- /dev/null +++ b/SOURCES/nss-3.79-dbtool.patch @@ -0,0 +1,3411 @@ +diff --git a/cmd/dbtool/Makefile b/cmd/dbtool/Makefile +new file mode 100644 +--- /dev/null ++++ b/cmd/dbtool/Makefile +@@ -0,0 +1,46 @@ ++#! 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) # ++####################################################################### ++ ++#include ../platlibs.mk ++ ++####################################################################### ++# (7) Execute "local" rules. (OPTIONAL). # ++####################################################################### ++ ++include ../platrules.mk ++ +diff --git a/cmd/dbtool/dbtool.c b/cmd/dbtool/dbtool.c +new file mode 100644 +--- /dev/null ++++ b/cmd/dbtool/dbtool.c +@@ -0,0 +1,806 @@ ++/* 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/. */ ++ ++/* ++** dbtool.c ++** ++** tool to dump the underlying encoding of a database. This tool duplicates ++** some private functions in softoken. It uses libsec and libutil, but no ++** other portions of NSS. It currently only works on sqlite databases. For ++** an even more primitive dump, use sqlite3 on the individual files. ++** ++** TODO: dump the meta data for the databases. ++** optionally dump more PKCS5 information (KDF/salt/iterations) ++** take a password and decode encrypted attributes/verify signed ++** attributes. ++*/ ++#include ++#include ++ ++#if defined(WIN32) ++#include "fcntl.h" ++#include "io.h" ++#endif ++ ++#include "secutil.h" ++#include "pk11pub.h" ++ ++#if defined(XP_UNIX) ++#include ++#endif ++ ++#include "nspr.h" ++#include "prtypes.h" ++#include "certdb.h" ++#include "nss.h" ++#include "../modutil/modutil.h" ++#include "pk11table.h" ++#include "sftkdbt.h" ++#include "sdb.h" ++#include "secoid.h" ++ ++#include "plgetopt.h" ++ ++static char *progName; ++ ++char *dbDir = NULL; ++ ++static void ++Usage() ++{ ++ printf("Usage: %s [-c certprefix] [-k keyprefix] " ++ "[-V certversion] [-v keyversion]\n" ++ " [-d dbdir]\n", ++ progName); ++ printf("%-20s Directory with cert database (default is .)\n", ++ "-d certdir"); ++ printf("%-20s prefix for the cert database (default is \"\")\n", ++ "-c certprefix"); ++ printf("%-20s prefix for the key database (default is \"\")\n", ++ "-k keyprefix"); ++ printf("%-20s version of the cert database (default is 9)\n", ++ "-V certversion"); ++ printf("%-20s version of the key database (default is 4)\n", ++ "-v keyversion"); ++ exit(1); ++} ++#define SFTK_KEYDB_TYPE 0x40000000 ++#define SFTK_TOKEN_TYPE 0x80000000 ++ ++/* ++ * known attributes ++ */ ++static const CK_ATTRIBUTE_TYPE known_attributes[] = { ++ CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION, ++ CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER, ++ CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED, ++ CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL, ++ CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY, ++ CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE, ++ CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER, ++ CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE, ++ CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT, ++ CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT, ++ CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS, ++ CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE, ++ CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, ++ CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS, ++ CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, ++ CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE, ++ CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, ++ CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS, ++ CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS, ++ CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE, ++ CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES, ++ CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NSS_URL, CKA_NSS_EMAIL, ++ CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP, ++ CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES, ++ CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED, ++ CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC, ++ CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION, ++ CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT, ++ CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN, ++ CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING, ++ CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM, ++ CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING, ++ CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, ++ CKA_NSS_DB, CKA_NSS_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS, ++ CKA_PUBLIC_KEY_INFO ++}; ++ ++static unsigned int known_attributes_size = sizeof(known_attributes) / ++ sizeof(known_attributes[0]); ++ ++PRBool ++isULONGAttribute(CK_ATTRIBUTE_TYPE type) ++{ ++ switch (type) { ++ case CKA_CERTIFICATE_CATEGORY: ++ case CKA_CERTIFICATE_TYPE: ++ case CKA_CLASS: ++ case CKA_JAVA_MIDP_SECURITY_DOMAIN: ++ case CKA_KEY_GEN_MECHANISM: ++ case CKA_KEY_TYPE: ++ case CKA_MECHANISM_TYPE: ++ case CKA_MODULUS_BITS: ++ case CKA_PRIME_BITS: ++ case CKA_SUBPRIME_BITS: ++ case CKA_VALUE_BITS: ++ case CKA_VALUE_LEN: ++ ++ case CKA_TRUST_DIGITAL_SIGNATURE: ++ case CKA_TRUST_NON_REPUDIATION: ++ case CKA_TRUST_KEY_ENCIPHERMENT: ++ case CKA_TRUST_DATA_ENCIPHERMENT: ++ case CKA_TRUST_KEY_AGREEMENT: ++ case CKA_TRUST_KEY_CERT_SIGN: ++ case CKA_TRUST_CRL_SIGN: ++ ++ case CKA_TRUST_SERVER_AUTH: ++ case CKA_TRUST_CLIENT_AUTH: ++ case CKA_TRUST_CODE_SIGNING: ++ case CKA_TRUST_EMAIL_PROTECTION: ++ case CKA_TRUST_IPSEC_END_SYSTEM: ++ case CKA_TRUST_IPSEC_TUNNEL: ++ case CKA_TRUST_IPSEC_USER: ++ case CKA_TRUST_TIME_STAMPING: ++ case CKA_TRUST_STEP_UP_APPROVED: ++ return PR_TRUE; ++ default: ++ break; ++ } ++ return PR_FALSE; ++} ++ ++/* are the attributes private? */ ++static PRBool ++isPrivateAttribute(CK_ATTRIBUTE_TYPE type) ++{ ++ switch (type) { ++ case CKA_VALUE: ++ case CKA_PRIVATE_EXPONENT: ++ case CKA_PRIME_1: ++ case CKA_PRIME_2: ++ case CKA_EXPONENT_1: ++ case CKA_EXPONENT_2: ++ case CKA_COEFFICIENT: ++ return PR_TRUE; ++ default: ++ break; ++ } ++ return PR_FALSE; ++} ++ ++/* These attributes must be authenticated with an hmac. */ ++static PRBool ++isAuthenticatedAttribute(CK_ATTRIBUTE_TYPE type) ++{ ++ switch (type) { ++ case CKA_MODULUS: ++ case CKA_PUBLIC_EXPONENT: ++ case CKA_CERT_SHA1_HASH: ++ case CKA_CERT_MD5_HASH: ++ case CKA_TRUST_SERVER_AUTH: ++ case CKA_TRUST_CLIENT_AUTH: ++ case CKA_TRUST_EMAIL_PROTECTION: ++ case CKA_TRUST_CODE_SIGNING: ++ case CKA_TRUST_STEP_UP_APPROVED: ++ case CKA_NSS_OVERRIDE_EXTENSIONS: ++ return PR_TRUE; ++ default: ++ break; ++ } ++ return PR_FALSE; ++} ++ ++/* ++ * convert a database ulong back to a native ULONG. (reverse of the above ++ * function. ++ */ ++static CK_ULONG ++sdbULong2ULong(unsigned char *data) ++{ ++ int i; ++ CK_ULONG value = 0; ++ ++ for (i = 0; i < SDB_ULONG_SIZE; i++) { ++ value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE - 1 - i) ++ * PR_BITS_PER_BYTE); ++ } ++ return value; ++} ++ ++/* PBE defines and functions */ ++ ++typedef struct EncryptedDataInfoStr { ++ SECAlgorithmID algorithm; ++ SECItem encryptedData; ++} EncryptedDataInfo; ++ ++static const SEC_ASN1Template encryptedDataInfoTemplate[] = { ++ { SEC_ASN1_SEQUENCE, ++ 0, NULL, sizeof(EncryptedDataInfo) }, ++ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, ++ offsetof(EncryptedDataInfo, algorithm), ++ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, ++ { SEC_ASN1_OCTET_STRING, ++ offsetof(EncryptedDataInfo, encryptedData) }, ++ { 0 } ++}; ++ ++typedef struct PBEParameterStr { ++ SECAlgorithmID prfAlg; ++ SECItem salt; ++ SECItem iteration; ++ SECItem keyLength; ++} PBEParameter; ++ ++static const SEC_ASN1Template pkcs5V1PBEParameterTemplate[] = ++ { ++ { SEC_ASN1_SEQUENCE, ++ 0, NULL, sizeof(PBEParameter) }, ++ { SEC_ASN1_OCTET_STRING, ++ offsetof(PBEParameter, salt) }, ++ { SEC_ASN1_INTEGER, ++ offsetof(PBEParameter, iteration) }, ++ { 0 } ++ }; ++ ++static const SEC_ASN1Template pkcs12V2PBEParameterTemplate[] = ++ { ++ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PBEParameter) }, ++ { SEC_ASN1_OCTET_STRING, offsetof(PBEParameter, salt) }, ++ { SEC_ASN1_INTEGER, offsetof(PBEParameter, iteration) }, ++ { 0 } ++ }; ++ ++ ++static const SEC_ASN1Template pkcs5V2PBEParameterTemplate[] = ++ { ++ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PBEParameter) }, ++ /* this is really a choice, but since we don't understand any other ++ * choice, just inline it. */ ++ { SEC_ASN1_OCTET_STRING, offsetof(PBEParameter, salt) }, ++ { SEC_ASN1_INTEGER, offsetof(PBEParameter, iteration) }, ++ { SEC_ASN1_INTEGER, offsetof(PBEParameter, keyLength) }, ++ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, ++ offsetof(PBEParameter, prfAlg), ++ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, ++ { 0 } ++ }; ++ ++typedef struct Pkcs5v2PBEParameterStr { ++ SECAlgorithmID keyParams; /* parameters of the key generation */ ++ SECAlgorithmID algParams; /* parameters for the encryption or mac op */ ++} Pkcs5v2PBEParameter; ++ ++static const SEC_ASN1Template pkcs5v2PBES2ParameterTemplate[] = { ++ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(Pkcs5v2PBEParameter) }, ++ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, ++ offsetof(Pkcs5v2PBEParameter, keyParams), ++ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, ++ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, ++ offsetof(Pkcs5v2PBEParameter, algParams), ++ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, ++ { 0 } ++}; ++ ++static inline PRBool ++isPKCS12PBE(SECOidTag alg) { ++ switch (alg) { ++ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: ++ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: ++ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: ++ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: ++ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: ++ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: ++ return PR_TRUE; ++ default: ++ break; ++ } ++ return PR_FALSE; ++} ++ ++ ++/* helper functions */ ++ ++/* output an NSS specific attribute or name that wasn't found in our ++ * pkcs #11 table */ ++const char * ++makeNSSVendorName(CK_ATTRIBUTE_TYPE attribute, const char *nameType) ++{ ++ static char nss_name[256]; ++ const char *name = NULL; ++ if ((attribute >= CKA_NSS) && (attribute <= 0xffffffff)) { ++ sprintf(nss_name,"%s+%d", nameType, (int)(attribute-CKA_NSS)); ++ name = nss_name; ++ } ++ return name; ++} ++ ++/* turn and attribute into a name */ ++const char * ++AttributeName(CK_ATTRIBUTE_TYPE attribute) ++{ ++ const char *name = getNameFromAttribute(attribute); ++ if (!name) { ++ name = makeNSSVendorName(attribute, "CKA_NSS"); ++ } ++ ++ return name ? name : "UNKNOWN_ATTRIBUTE_TYPE"; ++} ++ ++/* turn and error code into a name */ ++const char * ++ErrorName(CK_RV crv) ++{ ++ const char *error = getName(crv, ConstResult); ++ if (!error) { ++ error = makeNSSVendorName(crv, "CKR_NSS"); ++ } ++ return error ? error : "UNKNOWN_ERROR"; ++} ++ ++/* turn an oud tag into a string */ ++const char * ++oid2string(SECOidTag alg) ++{ ++ const char *oidstring = SECOID_FindOIDTagDescription(alg); ++ const char *def="Invalid oid tag"; /* future build a dotted oid string value here */ ++ return oidstring ? oidstring : def; ++} ++ ++/* dump an arbitary data blob. Dump it has hex with ascii on the side */ ++#define ASCCHAR(val) ((val) >= ' ' && (val) <= 0x7e ? (val) : '.') ++#define LINE_LENGTH 16 ++void ++dumpValue(const unsigned char *v, int len) ++{ ++ int i, next = 0; ++ char string[LINE_LENGTH+1]; ++ char space[LINE_LENGTH*2+1]; ++ char *nl = ""; ++ char *sp = ""; ++ PORT_Memset(string, 0, sizeof(string)); ++ ++ for (i=0; i < len; i++) { ++ if ((i % LINE_LENGTH) == 0) { ++ printf("%s%s%s ", sp, string, nl); ++ PORT_Memset(string, 0, sizeof(string)); ++ next = 0; ++ nl = "\n"; ++ sp = " "; ++ } ++ printf("%02x", v[i]); ++ string[next++] = ASCCHAR(v[i]); ++ } ++ PORT_Memset(space, 0, sizeof(space)); ++ i = LINE_LENGTH - (len % LINE_LENGTH); ++ if (i != LINE_LENGTH) { ++ int j; ++ for (j=0 ; j < i; j++) { ++ space[j*2] = ' '; ++ space[j*2+1] = ' '; ++ } ++ } ++ printf("%s%s%s%s", space, sp, string, nl); ++} ++ ++/* dump a PKCS5/12 PBE blob */ ++void ++dumpPKCS(unsigned char *val, CK_ULONG len, PRBool *hasSig) ++{ ++ EncryptedDataInfo edi; ++ SECStatus rv; ++ SECItem data; ++ PLArenaPool *arena; ++ SECOidTag alg, prfAlg; ++ PBEParameter pbeParam; ++ unsigned char zero = 0; ++ const SEC_ASN1Template *template = pkcs5V1PBEParameterTemplate; ++ int iter, keyLen, i; ++ ++ if (hasSig) { *hasSig = PR_FALSE; } ++ ++ ++ data.data = val; ++ data.len = len; ++ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); ++ if (arena == NULL) { ++ printf("Couldn't allocate arena\n"); ++ return; ++ } ++ ++ /* initialize default values */ ++ PORT_Memset(&pbeParam, 0, sizeof(pbeParam)); ++ pbeParam.keyLength.data = &zero; ++ pbeParam.keyLength.len = sizeof(zero); ++ SECOID_SetAlgorithmID(arena, &pbeParam.prfAlg, SEC_OID_SHA1, NULL); ++ ++ /* first crack the encrypted data from the PBE algorithm ID */ ++ rv = SEC_QuickDERDecodeItem(arena, &edi, encryptedDataInfoTemplate, &data); ++ if (rv != SECSuccess) { ++ printf("Encrypted Data, failed to decode\n"); ++ dumpValue(val,len); ++ PORT_FreeArena(arena, PR_FALSE); ++ return; ++ } ++ /* now use the pbe secalg to dump info on the pbe */ ++ alg = SECOID_GetAlgorithmTag(&edi.algorithm); ++ if ((alg == SEC_OID_PKCS5_PBES2) || (alg == SEC_OID_PKCS5_PBMAC1)){ ++ Pkcs5v2PBEParameter param; ++ SECOidTag palg; ++ const char *typeName = (alg == SEC_OID_PKCS5_PBES2) ? ++ "Encrypted Data PBES2" : ++ "Mac Data PBMAC1"; ++ ++ rv = SEC_QuickDERDecodeItem(arena, ¶m, ++ pkcs5v2PBES2ParameterTemplate, ++ &edi.algorithm.parameters); ++ if (rv != SECSuccess) { ++ printf("%s, failed to decode\n", typeName); ++ dumpValue(val,len); ++ PORT_FreeArena(arena, PR_FALSE); ++ return; ++ } ++ palg = SECOID_GetAlgorithmTag(¶m.algParams); ++ printf("%s alg=%s ", typeName, oid2string(palg)); ++ if (hasSig && palg == SEC_OID_AES_256_CBC) { ++ *hasSig = PR_TRUE; ++ } ++ template = pkcs5V2PBEParameterTemplate; ++ edi.algorithm.parameters = param.keyParams.parameters; ++ } else { ++ printf("Encrypted Data alg=%s ", oid2string(alg)); ++ if (alg == SEC_OID_PKCS5_PBKDF2) { ++ template = pkcs5V2PBEParameterTemplate; ++ } else if (isPKCS12PBE(alg)) { ++ template = pkcs12V2PBEParameterTemplate; ++ } else { ++ template = pkcs5V1PBEParameterTemplate; ++ } ++ } ++ rv = SEC_QuickDERDecodeItem(arena, &pbeParam, ++ template, ++ &edi.algorithm.parameters); ++ if (rv != SECSuccess) { ++ printf("( failed to decode params)\n"); ++ PORT_FreeArena(arena, PR_FALSE); ++ return; ++ } ++ /* dump the pbe parmeters */ ++ iter = DER_GetInteger(&pbeParam.iteration); ++ keyLen = DER_GetInteger(&pbeParam.keyLength); ++ prfAlg = SECOID_GetAlgorithmTag(&pbeParam.prfAlg); ++ printf("(prf=%s iter=%d keyLen=%d salt=0x", ++ oid2string(prfAlg), iter, keyLen); ++ for(i=0;i < pbeParam.salt.len; i++) printf("%02x",pbeParam.salt.data[i]); ++ printf(")\n"); ++ /* finally dump the raw encrypted data */ ++ dumpValue(edi.encryptedData.data, edi.encryptedData.len); ++ PORT_FreeArena(arena, PR_FALSE); ++} ++ ++/* dump a long attribute, convert to an unsigned long. PKCS #11 Longs are ++ * limited to 32 bits by the spec, even if the CK_ULONG is longer */ ++void ++dumpLongAttribute(CK_ATTRIBUTE_TYPE type, CK_ULONG value) ++{ ++ const char *nameType = "CK_NSS"; ++ ConstType constType = ConstNone; ++ const char *valueName = NULL; ++ ++ switch (type) { ++ case CKA_CLASS: ++ nameType = "CKO_NSS"; ++ constType = ConstObject; ++ break; ++ case CKA_CERTIFICATE_TYPE: ++ nameType = "CKC_NSS"; ++ constType = ConstCertType; ++ break; ++ case CKA_KEY_TYPE: ++ nameType = "CKK_NSS"; ++ constType = ConstKeyType; ++ break; ++ case CKA_MECHANISM_TYPE: ++ nameType = "CKM_NSS"; ++ constType = ConstMechanism; ++ break; ++ case CKA_TRUST_SERVER_AUTH: ++ case CKA_TRUST_CLIENT_AUTH: ++ case CKA_TRUST_CODE_SIGNING: ++ case CKA_TRUST_EMAIL_PROTECTION: ++ case CKA_TRUST_IPSEC_END_SYSTEM: ++ case CKA_TRUST_IPSEC_TUNNEL: ++ case CKA_TRUST_IPSEC_USER: ++ case CKA_TRUST_TIME_STAMPING: ++ nameType = "CKT_NSS"; ++ constType = ConstTrust; ++ break; ++ default: ++ break; ++ } ++ /* if value has a symbolic name, use it */ ++ if (constType != ConstNone) { ++ valueName = getName(value, constType); ++ } ++ if (!valueName) { ++ valueName = makeNSSVendorName(value, nameType); ++ } ++ if (!valueName) { ++ printf("%d (0x%08x)\n", (int) value, (int)value); ++ } else { ++ printf("%s (0x%08x)\n", valueName, (int)value); ++ } ++} ++ ++/* dump a signature for an object */ ++static const char META_SIG_TEMPLATE[] = "sig_%s_%08x_%08x"; ++void ++dumpSignature(CK_ATTRIBUTE_TYPE attribute, SDB *keydb, PRBool isKey, ++ CK_OBJECT_HANDLE objectID, PRBool force) ++{ ++ char id[30]; ++ CK_RV crv; ++ SECItem signText; ++ unsigned char signData[SDB_MAX_META_DATA_LEN]; ++ ++ if (!force && !isAuthenticatedAttribute(attribute)) { ++ return; ++ } ++ sprintf(id, META_SIG_TEMPLATE, ++ isKey ? "key" : "cert", ++ (unsigned int)objectID, (unsigned int)attribute); ++ printf(" Signature %s:",id); ++ signText.data = signData; ++ signText.len = sizeof(signData); ++ ++ ++ crv = (*keydb->sdb_GetMetaData)(keydb, id, &signText, NULL); ++ if ((crv != CKR_OK) && isKey) { ++ sprintf(id, META_SIG_TEMPLATE, ++ isKey ? "key" : "cert", (unsigned int) ++ (objectID | SFTK_KEYDB_TYPE | SFTK_TOKEN_TYPE), ++ (unsigned int)attribute); ++ crv = (*keydb->sdb_GetMetaData)(keydb, id, &signText, NULL); ++ } ++ if (crv != CKR_OK) { ++ printf(" FAILED %s with %s (0x%08x)\n", id, ErrorName(crv), (int) crv); ++ return; ++ } ++ dumpPKCS(signText.data, signText.len, NULL); ++ return; ++} ++ ++/* dump an attribute. use the helper functions above */ ++void ++dumpAttribute(CK_ATTRIBUTE *template, SDB *keydb, PRBool isKey, ++ CK_OBJECT_HANDLE id) ++{ ++ CK_ATTRIBUTE_TYPE attribute = template->type; ++ printf(" %s(0x%08x): ", AttributeName(attribute), (int)attribute); ++ if (template->pValue == NULL) { ++ printf("NULL (%d)\n", (int)template->ulValueLen); ++ return; ++ } ++ if (template->ulValueLen == SDB_ULONG_SIZE ++ && isULONGAttribute(attribute)) { ++ CK_ULONG value=sdbULong2ULong(template->pValue); ++ dumpLongAttribute(attribute, value); ++ return; ++ } ++ if (template->ulValueLen == 1) { ++ unsigned char val = *(unsigned char *)template->pValue; ++ switch (val) { ++ case 0: ++ printf("CK_FALSE\n"); ++ break; ++ case 1: ++ printf("CK_TRUE\n"); ++ break; ++ default: ++ printf("%d 0x%02x %c\n", val, val, ASCCHAR(val)); ++ break; ++ } ++ return; ++ } ++ if (isKey && isPrivateAttribute(attribute)) { ++ PRBool hasSig = PR_FALSE; ++ dumpPKCS(template->pValue, template->ulValueLen, &hasSig); ++ if (hasSig) { ++ dumpSignature(attribute, keydb, isKey, id, PR_TRUE); ++ } ++ return; ++ } ++ if (template->ulValueLen == 0) { printf("empty"); } ++ printf("\n"); ++ dumpValue(template->pValue, template->ulValueLen); ++} ++ ++/* dump all the attributes in an object */ ++void ++dumpObject(CK_OBJECT_HANDLE id, SDB *db, SDB *keydb, PRBool isKey) ++{ ++ CK_RV crv; ++ int i; ++ CK_ATTRIBUTE template; ++ char buffer[2048]; ++ char * alloc = NULL; ++ ++ printf(" Object 0x%08x:\n", (int)id); ++ for (i = 0; i < known_attributes_size; i++) { ++ CK_ATTRIBUTE_TYPE attribute = known_attributes[i]; ++ template.type = attribute; ++ template.pValue = NULL; ++ template.ulValueLen = 0; ++ crv = (*db->sdb_GetAttributeValue)(db, id, &template, 1); ++ ++ if (crv != CKR_OK) { ++ if (crv != CKR_ATTRIBUTE_TYPE_INVALID) { ++ PR_fprintf(PR_STDERR, " " ++ "Get Attribute %s (0x%08x):FAILED\"%s\"(0x%08x)\n", ++ AttributeName(attribute), (int)attribute, ++ ErrorName(crv), (int)crv); ++ } ++ continue; ++ } ++ ++ if (template.ulValueLen < sizeof(buffer)) { ++ template.pValue = buffer; ++ } else { ++ alloc = PORT_Alloc(template.ulValueLen); ++ template.pValue = alloc; ++ } ++ if (template.pValue == NULL) { ++ PR_fprintf(PR_STDERR, " " ++ "Could allocate %d bytes for Attribute %s (0x%08x)\n", ++ (int) template.ulValueLen, ++ AttributeName(attribute), (int)attribute); ++ continue; ++ } ++ crv = (*db->sdb_GetAttributeValue)(db, id, &template, 1); ++ ++ if (crv != CKR_OK) { ++ if (crv != CKR_ATTRIBUTE_TYPE_INVALID) { ++ PR_fprintf(PR_STDERR, " " ++ "Get Attribute %s (0x%08x):FAILED\"%s\"(0x%08x)\n", ++ AttributeName(attribute), (int)attribute, ++ ErrorName(crv), (int)crv); ++ } ++ if (alloc) { ++ PORT_Free(alloc); ++ alloc = NULL; ++ } ++ continue; ++ } ++ ++ dumpAttribute(&template, keydb, isKey, id); ++ dumpSignature(template.type, keydb, isKey, id, PR_FALSE); ++ if (alloc) { ++ PORT_Free(alloc); ++ alloc = NULL; ++ } ++ } ++} ++ ++/* dump all the objects in a database */ ++void ++dumpDB(SDB *db, const char *name, SDB *keydb, PRBool isKey) ++{ ++ SDBFind *findHandle= NULL; ++ CK_BBOOL isTrue = 1; ++ CK_ATTRIBUTE allObjectTemplate = {CKA_TOKEN, NULL, 1 }; ++ CK_ULONG allObjectTemplateCount = 1; ++ PRBool recordFound = PR_FALSE; ++ CK_RV crv = CKR_OK; ++ CK_ULONG objectCount = 0; ++ printf("%s:\n",name); ++ ++ allObjectTemplate.pValue = &isTrue; ++ crv = (*db->sdb_FindObjectsInit)(db, &allObjectTemplate, ++ allObjectTemplateCount, &findHandle); ++ do { ++ CK_OBJECT_HANDLE id; ++ recordFound = PR_FALSE; ++ crv =(*db->sdb_FindObjects)(db, findHandle, &id, 1, &objectCount); ++ if ((crv == CKR_OK) && (objectCount == 1)) { ++ recordFound = PR_TRUE; ++ dumpObject(id, db, keydb, isKey); ++ } ++ } while (recordFound); ++ if (crv != CKR_OK) { ++ PR_fprintf(PR_STDERR, ++ "Last record return PKCS #11 error = %s (0x%08x)\n", ++ ErrorName(crv), (int)crv); ++ } ++ (*db->sdb_FindObjectsFinal)(db,findHandle); ++} ++ ++int ++main(int argc, char **argv) ++{ ++ PLOptState *optstate; ++ PLOptStatus optstatus; ++ char *certPrefix="", *keyPrefix=""; ++ int cert_version = 9; ++ int key_version = 4; ++ SDB *certdb = NULL; ++ SDB *keydb = NULL; ++ PRBool isNew = PR_FALSE; ++ ++ CK_RV crv; ++ ++ progName = strrchr(argv[0], '/'); ++ if (!progName) ++ progName = strrchr(argv[0], '\\'); ++ progName = progName ? progName + 1 : argv[0]; ++ ++ optstate = PL_CreateOptState(argc, argv, "d:c:k:v:V:h"); ++ ++ while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { ++ switch (optstate->option) { ++ case 'h': ++ default: ++ Usage(); ++ break; ++ ++ case 'd': ++ dbDir = PORT_Strdup(optstate->value); ++ break; ++ ++ case 'c': ++ certPrefix = PORT_Strdup(optstate->value); ++ break; ++ ++ case 'k': ++ keyPrefix = PORT_Strdup(optstate->value); ++ break; ++ ++ case 'v': ++ key_version = atoi(optstate->value); ++ break; ++ ++ case 'V': ++ cert_version = atoi(optstate->value); ++ break; ++ ++ } ++ } ++ PL_DestroyOptState(optstate); ++ if (optstatus == PL_OPT_BAD) ++ Usage(); ++ ++ if (dbDir) { ++ char *tmp = dbDir; ++ dbDir = SECU_ConfigDirectory(tmp); ++ PORT_Free(tmp); ++ } else { ++ /* Look in $SSL_DIR */ ++ dbDir = SECU_ConfigDirectory(SECU_DefaultSSLDir()); ++ } ++ PR_fprintf(PR_STDERR, "dbdir selected is %s\n\n", dbDir); ++ ++ if (dbDir[0] == '\0') { ++ PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir); ++ return 1; ++ } ++ ++ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); ++ SECOID_Init(); ++ ++ crv = s_open(dbDir, certPrefix, keyPrefix, cert_version, key_version, ++ SDB_RDONLY, &certdb, &keydb, &isNew); ++ if (crv != CKR_OK) { ++ PR_fprintf(PR_STDERR, ++ "Couldn't open databased in %s, error=%s (0x%08x)\n", ++ dbDir, ErrorName(crv), (int)crv); ++ return 1; ++ } ++ ++ /* now dump the objects in the cert database */ ++ dumpDB(certdb, "CertDB", keydb, PR_FALSE); ++ dumpDB(keydb, "KeyDB", keydb, PR_TRUE); ++ return 0; ++} +diff --git a/cmd/dbtool/dbtool.gyp b/cmd/dbtool/dbtool.gyp +new file mode 100644 +--- /dev/null ++++ b/cmd/dbtool/dbtool.gyp +@@ -0,0 +1,25 @@ ++# 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': 'dbtest', ++ 'type': 'executable', ++ 'sources': [ ++ 'dbtest.c' ++ ], ++ 'dependencies': [ ++ '<(DEPTH)/exports.gyp:dbm_exports', ++ '<(DEPTH)/exports.gyp:nss_exports' ++ ] ++ } ++ ], ++ 'variables': { ++ 'module': 'nss' ++ } ++} +\ No newline at end of file +diff --git a/cmd/dbtool/manifest.mn b/cmd/dbtool/manifest.mn +new file mode 100644 +--- /dev/null ++++ b/cmd/dbtool/manifest.mn +@@ -0,0 +1,18 @@ ++# ++# 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 = ../.. ++ ++# MODULE public and private header directories are implicitly REQUIRED. ++MODULE = nss ++ ++USE_STATIC_LIBS = 1 ++ ++# DIRS = ++ ++CSRCS = dbtool.c sdb.c ++ ++PROGRAM = dbtool ++ +diff --git a/cmd/dbtool/sdb.c b/cmd/dbtool/sdb.c +new file mode 100644 +--- /dev/null ++++ b/cmd/dbtool/sdb.c +@@ -0,0 +1,2469 @@ ++/* 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/. */ ++/* ++ * This file implements PKCS 11 on top of our existing security modules ++ * ++ * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. ++ * This implementation has two slots: ++ * slot 1 is our generic crypto support. It does not require login. ++ * It supports Public Key ops, and all they bulk ciphers and hashes. ++ * It can also support Private Key ops for imported Private keys. It does ++ * not have any token storage. ++ * slot 2 is our private key support. It requires a login before use. It ++ * can store Private Keys and Certs as token objects. Currently only private ++ * keys and their associated Certificates are saved on the token. ++ * ++ * In this implementation, session objects are only visible to the session ++ * that created or generated them. ++ */ ++ ++#include "sdb.h" ++#include "pkcs11t.h" ++#include "seccomon.h" ++#include ++#include "prthread.h" ++#include "prio.h" ++#include ++#include "secport.h" ++#include "prmon.h" ++#include "prenv.h" ++#include "prprf.h" ++#include "prsystem.h" /* for PR_GetDirectorySeparator() */ ++#include ++#if defined(_WIN32) ++#include ++#include ++#elif defined(XP_UNIX) ++#include ++#endif ++#if defined(LINUX) && !defined(ANDROID) ++#include ++#include ++#endif ++#include "utilpars.h" ++ ++#ifdef SQLITE_UNSAFE_THREADS ++#include "prlock.h" ++/* ++ * SQLite can be compiled to be thread safe or not. ++ * turn on SQLITE_UNSAFE_THREADS if the OS does not support ++ * a thread safe version of sqlite. ++ */ ++static PRLock *sqlite_lock = NULL; ++ ++#define LOCK_SQLITE() PR_Lock(sqlite_lock); ++#define UNLOCK_SQLITE() PR_Unlock(sqlite_lock); ++#else ++#define LOCK_SQLITE() ++#define UNLOCK_SQLITE() ++#endif ++ ++typedef enum { ++ SDB_CERT = 1, ++ SDB_KEY = 2 ++} sdbDataType; ++ ++/* ++ * defines controlling how long we wait to acquire locks. ++ * ++ * SDB_SQLITE_BUSY_TIMEOUT specifies how long (in milliseconds) ++ * sqlite will wait on lock. If that timeout expires, sqlite will ++ * return SQLITE_BUSY. ++ * SDB_BUSY_RETRY_TIME specifies how many seconds the sdb_ code waits ++ * after receiving a busy before retrying. ++ * SDB_MAX_BUSY_RETRIES specifies how many times the sdb_ will retry on ++ * a busy condition. ++ * ++ * SDB_SQLITE_BUSY_TIMEOUT affects all opertions, both manual ++ * (prepare/step/reset/finalize) and automatic (sqlite3_exec()). ++ * SDB_BUSY_RETRY_TIME and SDB_MAX_BUSY_RETRIES only affect manual operations ++ * ++ * total wait time for automatic operations: ++ * 1 second (SDB_SQLITE_BUSY_TIMEOUT/1000). ++ * total wait time for manual operations: ++ * (1 second + SDB_BUSY_RETRY_TIME) * 30 = 30 seconds. ++ * (SDB_SQLITE_BUSY_TIMEOUT/1000 + SDB_BUSY_RETRY_TIME)*SDB_MAX_BUSY_RETRIES ++ */ ++#define SDB_SQLITE_BUSY_TIMEOUT 1000 /* milliseconds */ ++#define SDB_BUSY_RETRY_TIME 5 /* 'ticks', varies by platforms */ ++#define SDB_MAX_BUSY_RETRIES 30 ++ ++/* ++ * known attributes ++ */ ++static const CK_ATTRIBUTE_TYPE known_attributes[] = { ++ CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION, ++ CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER, ++ CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED, ++ CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL, ++ CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY, ++ CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE, ++ CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER, ++ CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE, ++ CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT, ++ CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT, ++ CKA_PUBLIC_KEY_INFO, CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS, ++ CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE, ++ CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, ++ CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS, ++ CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, ++ CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_HW_FEATURE_TYPE, ++ CKA_RESET_ON_INIT, CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, ++ CKA_RESOLUTION, CKA_CHAR_ROWS, CKA_CHAR_COLUMNS, CKA_COLOR, ++ CKA_BITS_PER_PIXEL, CKA_CHAR_SETS, CKA_ENCODING_METHODS, CKA_MIME_TYPES, ++ CKA_MECHANISM_TYPE, CKA_REQUIRED_CMS_ATTRIBUTES, ++ CKA_DEFAULT_CMS_ATTRIBUTES, CKA_SUPPORTED_CMS_ATTRIBUTES, ++ CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE, CKA_NSS_TRUST, CKA_NSS_URL, ++ CKA_NSS_EMAIL, CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP, ++ CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES, ++ CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED, ++ CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC, ++ CKA_NSS_OVERRIDE_EXTENSIONS, CKA_NSS_SERVER_DISTRUST_AFTER, ++ CKA_NSS_EMAIL_DISTRUST_AFTER, CKA_TRUST_DIGITAL_SIGNATURE, ++ CKA_TRUST_NON_REPUDIATION, CKA_TRUST_KEY_ENCIPHERMENT, ++ CKA_TRUST_DATA_ENCIPHERMENT, CKA_TRUST_KEY_AGREEMENT, ++ CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN, CKA_TRUST_SERVER_AUTH, ++ CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION, ++ CKA_TRUST_IPSEC_END_SYSTEM, CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, ++ CKA_TRUST_TIME_STAMPING, CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, ++ CKA_CERT_MD5_HASH, CKA_NSS_DB ++}; ++ ++static const int known_attributes_size = PR_ARRAY_SIZE(known_attributes); ++ ++/* ++ * Note on use of sqlReadDB: Only one thread at a time may have an actual ++ * operation going on given sqlite3 * database. An operation is defined as ++ * the time from a sqlite3_prepare() until the sqlite3_finalize(). ++ * Multiple sqlite3 * databases can be open and have simultaneous operations ++ * going. We use the sqlXactDB for all write operations. This database ++ * is only opened when we first create a transaction and closed when the ++ * transaction is complete. sqlReadDB is open when we first opened the database ++ * and is used for all read operation. It's use is protected by a monitor. This ++ * is because an operation can span the use of FindObjectsInit() through the ++ * call to FindObjectsFinal(). In the intermediate time it is possible to call ++ * other operations like NSC_GetAttributeValue */ ++ ++struct SDBPrivateStr { ++ char *sqlDBName; /* invariant, path to this database */ ++ sqlite3 *sqlXactDB; /* access protected by dbMon, use protected ++ * by the transaction. Current transaction db*/ ++ PRThread *sqlXactThread; /* protected by dbMon, ++ * current transaction thread */ ++ sqlite3 *sqlReadDB; /* use protected by dbMon, value invariant */ ++ PRIntervalTime lastUpdateTime; /* last time the cache was updated */ ++ PRIntervalTime updateInterval; /* how long the cache can go before it ++ * must be updated again */ ++ sdbDataType type; /* invariant, database type */ ++ char *table; /* invariant, SQL table which contains the db */ ++ char *cacheTable; /* invariant, SQL table cache of db */ ++ PRMonitor *dbMon; /* invariant, monitor to protect ++ * sqlXact* fields, and use of the sqlReadDB */ ++ CK_ATTRIBUTE_TYPE *schemaAttrs; /* Attribute columns that exist in the table. */ ++ unsigned int numSchemaAttrs; ++}; ++ ++typedef struct SDBPrivateStr SDBPrivate; ++ ++/* Magic for an explicit NULL. NOTE: ideally this should be ++ * out of band data. Since it's not completely out of band, pick ++ * a value that has no meaning to any existing PKCS #11 attributes. ++ * This value is 1) not a valid string (imbedded '\0'). 2) not a U_LONG ++ * or a normal key (too short). 3) not a bool (too long). 4) not an RSA ++ * public exponent (too many bits). ++ */ ++const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a }; ++#define SQLITE_EXPLICIT_NULL_LEN 3 ++ ++/* ++ * determine when we've completed our tasks ++ */ ++static int ++sdb_done(int err, int *count) ++{ ++ /* allow as many rows as the database wants to give */ ++ if (err == SQLITE_ROW) { ++ *count = 0; ++ return 0; ++ } ++ if (err != SQLITE_BUSY) { ++ return 1; ++ } ++ /* err == SQLITE_BUSY, Dont' retry forever in this case */ ++ if (++(*count) >= SDB_MAX_BUSY_RETRIES) { ++ return 1; ++ } ++ return 0; ++} ++ ++#if defined(_WIN32) ++/* ++ * NSPR functions and narrow CRT functions do not handle UTF-8 file paths that ++ * sqlite3 expects. ++ */ ++ ++static int ++sdb_chmod(const char *filename, int pmode) ++{ ++ int result; ++ ++ if (!filename) { ++ return -1; ++ } ++ ++ wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename); ++ if (!filenameWide) { ++ return -1; ++ } ++ result = _wchmod(filenameWide, pmode); ++ PORT_Free(filenameWide); ++ ++ return result; ++} ++#else ++#define sdb_chmod(filename, pmode) chmod((filename), (pmode)) ++#endif ++ ++/* ++ * find out where sqlite stores the temp tables. We do this by replicating ++ * the logic from sqlite. ++ */ ++#if defined(_WIN32) ++static char * ++sdb_getFallbackTempDir(void) ++{ ++ /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have ++ * access to sqlite3_temp_directory because it is not exported from ++ * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and ++ * sqlite3_temp_directory is NULL. ++ */ ++ char path[MAX_PATH]; ++ DWORD rv; ++ size_t len; ++ ++ rv = GetTempPathA(MAX_PATH, path); ++ if (rv > MAX_PATH || rv == 0) ++ return NULL; ++ len = strlen(path); ++ if (len == 0) ++ return NULL; ++ /* The returned string ends with a backslash, for example, "C:\TEMP\". */ ++ if (path[len - 1] == '\\') ++ path[len - 1] = '\0'; ++ return PORT_Strdup(path); ++} ++#elif defined(XP_UNIX) ++static char * ++sdb_getFallbackTempDir(void) ++{ ++ const char *azDirs[] = { ++ NULL, ++ NULL, ++ "/var/tmp", ++ "/usr/tmp", ++ "/tmp", ++ NULL /* List terminator */ ++ }; ++ unsigned int i; ++ struct stat buf; ++ const char *zDir = NULL; ++ ++ azDirs[0] = sqlite3_temp_directory; ++ azDirs[1] = PR_GetEnvSecure("TMPDIR"); ++ ++ for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) { ++ zDir = azDirs[i]; ++ if (zDir == NULL) ++ continue; ++ if (stat(zDir, &buf)) ++ continue; ++ if (!S_ISDIR(buf.st_mode)) ++ continue; ++ if (access(zDir, 07)) ++ continue; ++ break; ++ } ++ ++ if (zDir == NULL) ++ return NULL; ++ return PORT_Strdup(zDir); ++} ++#else ++#error "sdb_getFallbackTempDir not implemented" ++#endif ++ ++#ifndef SQLITE_FCNTL_TEMPFILENAME ++/* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */ ++#define SQLITE_FCNTL_TEMPFILENAME 16 ++#endif ++ ++static char * ++sdb_getTempDir(sqlite3 *sqlDB) ++{ ++ int sqlrv; ++ char *result = NULL; ++ char *tempName = NULL; ++ char *foundSeparator = NULL; ++ ++ /* Obtain temporary filename in sqlite's directory for temporary tables */ ++ sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME, ++ (void *)&tempName); ++ if (sqlrv == SQLITE_NOTFOUND) { ++ /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using ++ * an older SQLite. */ ++ return sdb_getFallbackTempDir(); ++ } ++ if (sqlrv != SQLITE_OK) { ++ return NULL; ++ } ++ ++ /* We'll extract the temporary directory from tempName */ ++ foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator()); ++ if (foundSeparator) { ++ /* We shorten the temp filename string to contain only ++ * the directory name (including the trailing separator). ++ * We know the byte after the foundSeparator position is ++ * safe to use, in the shortest scenario it contains the ++ * end-of-string byte. ++ * By keeping the separator at the found position, it will ++ * even work if tempDir consists of the separator, only. ++ * (In this case the toplevel directory will be used for ++ * access speed testing). */ ++ ++foundSeparator; ++ *foundSeparator = 0; ++ ++ /* Now we copy the directory name for our caller */ ++ result = PORT_Strdup(tempName); ++ } ++ ++ sqlite3_free(tempName); ++ return result; ++} ++ ++/* ++ * Map SQL_LITE errors to PKCS #11 errors as best we can. ++ */ ++static CK_RV ++sdb_mapSQLError(sdbDataType type, int sqlerr) ++{ ++ switch (sqlerr) { ++ /* good matches */ ++ case SQLITE_OK: ++ case SQLITE_DONE: ++ return CKR_OK; ++ case SQLITE_NOMEM: ++ return CKR_HOST_MEMORY; ++ case SQLITE_READONLY: ++ return CKR_TOKEN_WRITE_PROTECTED; ++ /* close matches */ ++ case SQLITE_AUTH: ++ case SQLITE_PERM: ++ /*return CKR_USER_NOT_LOGGED_IN; */ ++ case SQLITE_CANTOPEN: ++ case SQLITE_NOTFOUND: ++ /* NSS distiguishes between failure to open the cert and the key db */ ++ return type == SDB_CERT ? CKR_NSS_CERTDB_FAILED : CKR_NSS_KEYDB_FAILED; ++ case SQLITE_IOERR: ++ return CKR_DEVICE_ERROR; ++ default: ++ break; ++ } ++ return CKR_GENERAL_ERROR; ++} ++ ++/* ++ * build up database name from a directory, prefix, name, version and flags. ++ */ ++static char * ++sdb_BuildFileName(const char *directory, ++ const char *prefix, const char *type, ++ int version) ++{ ++ char *dbname = NULL; ++ /* build the full dbname */ ++ dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory, ++ (int)(unsigned char)PR_GetDirectorySeparator(), ++ prefix, type, version); ++ return dbname; ++} ++ ++/* ++ * find out how expensive the access system call is for non-existant files ++ * in the given directory. Return the number of operations done in 33 ms. ++ */ ++static PRUint32 ++sdb_measureAccess(const char *directory) ++{ ++ PRUint32 i; ++ PRIntervalTime time; ++ PRIntervalTime delta; ++ PRIntervalTime duration = PR_MillisecondsToInterval(33); ++ const char *doesntExistName = "_dOeSnotExist_.db"; ++ char *temp, *tempStartOfFilename; ++ size_t maxTempLen, maxFileNameLen, directoryLength, tmpdirLength = 0; ++#ifdef SDB_MEASURE_USE_TEMP_DIR ++ /* ++ * on some OS's and Filesystems, creating a bunch of files and deleting ++ * them messes up the systems's caching, but if we create the files in ++ * a temp directory which we later delete, then the cache gets cleared ++ * up. This code uses several OS dependent calls, and it's not clear ++ * that temp directory use won't mess up other filesystems and OS caching, ++ * so if you need this for your OS, you can turn on the ++ * 'SDB_MEASURE_USE_TEMP_DIR' define in coreconf ++ */ ++ const char template[] = "dbTemp.XXXXXX"; ++ tmpdirLength = sizeof(template); ++#endif ++ /* no directory, just return one */ ++ if (directory == NULL) { ++ return 1; ++ } ++ ++ /* our calculation assumes time is a 4 bytes == 32 bit integer */ ++ PORT_Assert(sizeof(time) == 4); ++ ++ directoryLength = strlen(directory); ++ ++ maxTempLen = directoryLength + 1 /* dirname + / */ ++ + tmpdirLength /* tmpdirname includes / */ ++ + strlen(doesntExistName) /* filename base */ ++ + 11 /* max chars for 32 bit int plus potential sign */ ++ + 1; /* zero terminator */ ++ ++ temp = PORT_ZAlloc(maxTempLen); ++ if (!temp) { ++ return 1; ++ } ++ ++ /* We'll copy directory into temp just once, then ensure it ends ++ * with the directory separator. */ ++ ++ strcpy(temp, directory); ++ if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) { ++ temp[directoryLength++] = PR_GetDirectorySeparator(); ++ } ++ ++#ifdef SDB_MEASURE_USE_TEMP_DIR ++ /* add the template for a temporary subdir, and create it */ ++ strcat(temp, template); ++ if (!mkdtemp(temp)) { ++ PORT_Free(temp); ++ return 1; ++ } ++ /* and terminate that tmp subdir with a / */ ++ strcat(temp, "/"); ++#endif ++ ++ /* Remember the position after the last separator, and calculate the ++ * number of remaining bytes. */ ++ tempStartOfFilename = temp + directoryLength + tmpdirLength; ++ maxFileNameLen = maxTempLen - directoryLength; ++ ++ /* measure number of Access operations that can be done in 33 milliseconds ++ * (1/30'th of a second), or 10000 operations, which ever comes first. ++ */ ++ time = PR_IntervalNow(); ++ for (i = 0; i < 10000u; i++) { ++ PRIntervalTime next; ++ ++ /* We'll use the variable part first in the filename string, just in ++ * case it's longer than assumed, so if anything gets cut off, it ++ * will be cut off from the constant part. ++ * This code assumes the directory name at the beginning of ++ * temp remains unchanged during our loop. */ ++ PR_snprintf(tempStartOfFilename, maxFileNameLen, ++ ".%lu%s", (PRUint32)(time + i), doesntExistName); ++ PR_Access(temp, PR_ACCESS_EXISTS); ++ next = PR_IntervalNow(); ++ delta = next - time; ++ if (delta >= duration) ++ break; ++ } ++ ++#ifdef SDB_MEASURE_USE_TEMP_DIR ++ /* turn temp back into our tmpdir path by removing doesntExistName, and ++ * remove the tmp dir */ ++ *tempStartOfFilename = '\0'; ++ (void)rmdir(temp); ++#endif ++ PORT_Free(temp); ++ ++ /* always return 1 or greater */ ++ return i ? i : 1u; ++} ++ ++/* ++ * some file sytems are very slow to run sqlite3 on, particularly if the ++ * access count is pretty high. On these filesystems is faster to create ++ * a temporary database on the local filesystem and access that. This ++ * code uses a temporary table to create that cache. Temp tables are ++ * automatically cleared when the database handle it was created on ++ * Is freed. ++ */ ++static const char DROP_CACHE_CMD[] = "DROP TABLE %s"; ++static const char CREATE_CACHE_CMD[] = ++ "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s"; ++static const char CREATE_ISSUER_INDEX_CMD[] = ++ "CREATE INDEX issuer ON %s (a81)"; ++static const char CREATE_SUBJECT_INDEX_CMD[] = ++ "CREATE INDEX subject ON %s (a101)"; ++static const char CREATE_LABEL_INDEX_CMD[] = "CREATE INDEX label ON %s (a3)"; ++static const char CREATE_ID_INDEX_CMD[] = "CREATE INDEX ckaid ON %s (a102)"; ++ ++static CK_RV ++sdb_buildCache(sqlite3 *sqlDB, sdbDataType type, ++ const char *cacheTable, const char *table) ++{ ++ char *newStr; ++ int sqlerr = SQLITE_OK; ++ ++ newStr = sqlite3_mprintf(CREATE_CACHE_CMD, cacheTable, table); ++ if (newStr == NULL) { ++ return CKR_HOST_MEMORY; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) { ++ return sdb_mapSQLError(type, sqlerr); ++ } ++ /* failure to create the indexes is not an issue */ ++ newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, cacheTable); ++ if (newStr == NULL) { ++ return CKR_OK; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, cacheTable); ++ if (newStr == NULL) { ++ return CKR_OK; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, cacheTable); ++ if (newStr == NULL) { ++ return CKR_OK; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, cacheTable); ++ if (newStr == NULL) { ++ return CKR_OK; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ return CKR_OK; ++} ++ ++/* ++ * update the cache and the data records describing it. ++ * The cache is updated by dropping the temp database and recreating it. ++ */ ++static CK_RV ++sdb_updateCache(SDBPrivate *sdb_p) ++{ ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ char *newStr; ++ ++ /* drop the old table */ ++ newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable); ++ if (newStr == NULL) { ++ return CKR_HOST_MEMORY; ++ } ++ sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR)) { ++ /* something went wrong with the drop, don't try to refresh... ++ * NOTE: SQLITE_ERROR is returned if the table doesn't exist. In ++ * that case, we just continue on and try to reload it */ ++ return sdb_mapSQLError(sdb_p->type, sqlerr); ++ } ++ ++ /* set up the new table */ ++ error = sdb_buildCache(sdb_p->sqlReadDB, sdb_p->type, ++ sdb_p->cacheTable, sdb_p->table); ++ if (error == CKR_OK) { ++ /* we have a new cache! */ ++ sdb_p->lastUpdateTime = PR_IntervalNow(); ++ } ++ return error; ++} ++ ++/* ++ * The sharing of sqlite3 handles across threads is tricky. Older versions ++ * couldn't at all, but newer ones can under strict conditions. Basically ++ * no 2 threads can use the same handle while another thread has an open ++ * stmt running. Once the sqlite3_stmt is finalized, another thread can then ++ * use the database handle. ++ * ++ * We use monitors to protect against trying to use a database before ++ * it's sqlite3_stmt is finalized. This is preferable to the opening and ++ * closing the database each operation because there is significant overhead ++ * in the open and close. Also continually opening and closing the database ++ * defeats the cache code as the cache table is lost on close (thus ++ * requiring us to have to reinitialize the cache every operation). ++ * ++ * An execption to the shared handle is transations. All writes happen ++ * through a transaction. When we are in a transaction, we must use the ++ * same database pointer for that entire transation. In this case we save ++ * the transaction database and use it for all accesses on the transaction ++ * thread. Other threads use the common database. ++ * ++ * There can only be once active transaction on the database at a time. ++ * ++ * sdb_openDBLocal() provides us with a valid database handle for whatever ++ * state we are in (reading or in a transaction), and acquires any locks ++ * appropriate to that state. It also decides when it's time to refresh ++ * the cache before we start an operation. Any database handle returned ++ * just eventually be closed with sdb_closeDBLocal(). ++ * ++ * The table returned either points to the database's physical table, or ++ * to the cached shadow. Tranactions always return the physical table ++ * and read operations return either the physical table or the cache ++ * depending on whether or not the cache exists. ++ */ ++static CK_RV ++sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table) ++{ ++ *sqlDB = NULL; ++ ++ PR_EnterMonitor(sdb_p->dbMon); ++ ++ if (table) { ++ *table = sdb_p->table; ++ } ++ ++ /* We're in a transaction, use the transaction DB */ ++ if ((sdb_p->sqlXactDB) && (sdb_p->sqlXactThread == PR_GetCurrentThread())) { ++ *sqlDB = sdb_p->sqlXactDB; ++ /* only one thread can get here, safe to unlock */ ++ PR_ExitMonitor(sdb_p->dbMon); ++ return CKR_OK; ++ } ++ ++ /* ++ * if we are just reading from the table, we may have the table ++ * cached in a temporary table (especially if it's on a shared FS). ++ * In that case we want to see updates to the table, the the granularity ++ * is on order of human scale, not computer scale. ++ */ ++ if (table && sdb_p->cacheTable) { ++ PRIntervalTime now = PR_IntervalNow(); ++ if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) { ++ sdb_updateCache(sdb_p); ++ } ++ *table = sdb_p->cacheTable; ++ } ++ ++ *sqlDB = sdb_p->sqlReadDB; ++ ++ /* leave holding the lock. only one thread can actually use a given ++ * database connection at once */ ++ ++ return CKR_OK; ++} ++ ++/* closing the local database currenly means unlocking the monitor */ ++static CK_RV ++sdb_closeDBLocal(SDBPrivate *sdb_p, sqlite3 *sqlDB) ++{ ++ if (sdb_p->sqlXactDB != sqlDB) { ++ /* if we weren't in a transaction, we got a lock */ ++ PR_ExitMonitor(sdb_p->dbMon); ++ } ++ return CKR_OK; ++} ++ ++/* ++ * wrapper to sqlite3_open which also sets the busy_timeout ++ */ ++static int ++sdb_openDB(const char *name, sqlite3 **sqlDB, int flags) ++{ ++ int sqlerr; ++ int openFlags; ++ ++ *sqlDB = NULL; ++ ++ if (flags & SDB_RDONLY) { ++ openFlags = SQLITE_OPEN_READONLY; ++ } else { ++ openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; ++ /* sqlite 3.34 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) { ++ return sqlerr; ++ } ++ ++ sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT); ++ if (sqlerr != SQLITE_OK) { ++ sqlite3_close(*sqlDB); ++ *sqlDB = NULL; ++ return sqlerr; ++ } ++ return SQLITE_OK; ++} ++ ++/* Sigh, if we created a new table since we opened the database, ++ * the database handle will not see the new table, we need to close this ++ * database and reopen it. Caller must be in a transaction or holding ++ * the dbMon. sqlDB is changed on success. */ ++static int ++sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB) ++{ ++ sqlite3 *newDB; ++ int sqlerr; ++ ++ /* open a new database */ ++ sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY); ++ if (sqlerr != SQLITE_OK) { ++ return sqlerr; ++ } ++ ++ /* if we are in a transaction, we may not be holding the monitor. ++ * grab it before we update the transaction database. This is ++ * safe since are using monitors. */ ++ PR_EnterMonitor(sdb_p->dbMon); ++ /* update our view of the database */ ++ if (sdb_p->sqlReadDB == *sqlDB) { ++ sdb_p->sqlReadDB = newDB; ++ } else if (sdb_p->sqlXactDB == *sqlDB) { ++ sdb_p->sqlXactDB = newDB; ++ } ++ PR_ExitMonitor(sdb_p->dbMon); ++ ++ /* close the old one */ ++ sqlite3_close(*sqlDB); ++ ++ *sqlDB = newDB; ++ return SQLITE_OK; ++} ++ ++struct SDBFindStr { ++ sqlite3 *sqlDB; ++ sqlite3_stmt *findstmt; ++}; ++ ++static const char FIND_OBJECTS_CMD[] = "SELECT ALL id FROM %s WHERE %s;"; ++static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL id FROM %s;"; ++CK_RV ++sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count, ++ SDBFind **find) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ const char *table; ++ char *newStr, *findStr = NULL; ++ sqlite3_stmt *findstmt = NULL; ++ char *join = ""; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ unsigned int i; ++ ++ LOCK_SQLITE() ++ *find = NULL; ++ error = sdb_openDBLocal(sdb_p, &sqlDB, &table); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ ++ findStr = sqlite3_mprintf(""); ++ for (i = 0; findStr && i < count; i++) { ++ newStr = sqlite3_mprintf("%s%sa%x=$DATA%d", findStr, join, ++ template[i].type, i); ++ join = " AND "; ++ sqlite3_free(findStr); ++ findStr = newStr; ++ } ++ ++ if (findStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ ++ if (count == 0) { ++ newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table); ++ } else { ++ newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr); ++ } ++ sqlite3_free(findStr); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &findstmt, NULL); ++ sqlite3_free(newStr); ++ for (i = 0; sqlerr == SQLITE_OK && i < count; i++) { ++ const void *blobData = template[i].pValue; ++ unsigned int blobSize = template[i].ulValueLen; ++ if (blobSize == 0) { ++ blobSize = SQLITE_EXPLICIT_NULL_LEN; ++ blobData = SQLITE_EXPLICIT_NULL; ++ } ++ sqlerr = sqlite3_bind_blob(findstmt, i + 1, blobData, blobSize, ++ SQLITE_TRANSIENT); ++ } ++ if (sqlerr == SQLITE_OK) { ++ *find = PORT_New(SDBFind); ++ if (*find == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ (*find)->findstmt = findstmt; ++ (*find)->sqlDB = sqlDB; ++ UNLOCK_SQLITE() ++ return CKR_OK; ++ } ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ ++loser: ++ if (findstmt) { ++ sqlite3_reset(findstmt); ++ sqlite3_finalize(findstmt); ++ } ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ UNLOCK_SQLITE() ++ return error; ++} ++ ++CK_RV ++sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object, ++ CK_ULONG arraySize, CK_ULONG *count) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3_stmt *stmt = sdbFind->findstmt; ++ int sqlerr = SQLITE_OK; ++ int retry = 0; ++ ++ *count = 0; ++ ++ if (arraySize == 0) { ++ return CKR_OK; ++ } ++ LOCK_SQLITE() ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ if (sqlerr == SQLITE_ROW) { ++ /* only care about the id */ ++ *object++ = sqlite3_column_int(stmt, 0); ++ arraySize--; ++ (*count)++; ++ } ++ } while (!sdb_done(sqlerr, &retry) && (arraySize > 0)); ++ ++ /* we only have some of the objects, there is probably more, ++ * set the sqlerr to an OK value so we return CKR_OK */ ++ if (sqlerr == SQLITE_ROW && arraySize == 0) { ++ sqlerr = SQLITE_DONE; ++ } ++ UNLOCK_SQLITE() ++ ++ return sdb_mapSQLError(sdb_p->type, sqlerr); ++} ++ ++CK_RV ++sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3_stmt *stmt = sdbFind->findstmt; ++ sqlite3 *sqlDB = sdbFind->sqlDB; ++ int sqlerr = SQLITE_OK; ++ ++ LOCK_SQLITE() ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlerr = sqlite3_finalize(stmt); ++ } ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ PORT_Free(sdbFind); ++ ++ UNLOCK_SQLITE() ++ return sdb_mapSQLError(sdb_p->type, sqlerr); ++} ++ ++static CK_RV ++sdb_GetValidAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id, ++ CK_ATTRIBUTE *template, CK_ULONG count) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ sqlite3_stmt *stmt = NULL; ++ const char *table = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ int found = 0; ++ int retry = 0; ++ unsigned int i; ++ ++ if (count == 0) { ++ error = CKR_OBJECT_HANDLE_INVALID; ++ goto loser; ++ } ++ ++ /* open a new db if necessary */ ++ error = sdb_openDBLocal(sdb_p, &sqlDB, &table); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ ++ char *columns = NULL; ++ for (i = 0; i < count; i++) { ++ char *newColumns; ++ if (columns) { ++ newColumns = sqlite3_mprintf("%s, a%x", columns, template[i].type); ++ sqlite3_free(columns); ++ columns = NULL; ++ } else { ++ newColumns = sqlite3_mprintf("a%x", template[i].type); ++ } ++ if (!newColumns) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ columns = newColumns; ++ } ++ ++ PORT_Assert(columns); ++ ++ char *statement = sqlite3_mprintf("SELECT DISTINCT %s FROM %s where id=$ID LIMIT 1;", ++ columns, table); ++ sqlite3_free(columns); ++ columns = NULL; ++ if (!statement) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ ++ sqlerr = sqlite3_prepare_v2(sqlDB, statement, -1, &stmt, NULL); ++ sqlite3_free(statement); ++ statement = NULL; ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ ++ // NB: indices in sqlite3_bind_int are 1-indexed ++ sqlerr = sqlite3_bind_int(stmt, 1, object_id); ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ if (sqlerr == SQLITE_ROW) { ++ PORT_Assert(!found); ++ for (i = 0; i < count; i++) { ++ unsigned int blobSize; ++ const char *blobData; ++ ++ // NB: indices in sqlite_column_{bytes,blob} are 0-indexed ++ blobSize = sqlite3_column_bytes(stmt, i); ++ blobData = sqlite3_column_blob(stmt, i); ++ if (blobData == NULL) { ++ /* PKCS 11 requires that get attributes process all the ++ * attributes in the template, marking the attributes with ++ * issues with -1. Mark the error but continue */ ++ template[i].ulValueLen = -1; ++ error = CKR_ATTRIBUTE_TYPE_INVALID; ++ continue; ++ } ++ /* If the blob equals our explicit NULL value, then the ++ * attribute is a NULL. */ ++ if ((blobSize == SQLITE_EXPLICIT_NULL_LEN) && ++ (PORT_Memcmp(blobData, SQLITE_EXPLICIT_NULL, ++ SQLITE_EXPLICIT_NULL_LEN) == 0)) { ++ blobSize = 0; ++ } ++ if (template[i].pValue) { ++ if (template[i].ulValueLen < blobSize) { ++ /* like CKR_ATTRIBUTE_TYPE_INVALID, continue processing */ ++ template[i].ulValueLen = -1; ++ error = CKR_BUFFER_TOO_SMALL; ++ continue; ++ } ++ PORT_Memcpy(template[i].pValue, blobData, blobSize); ++ } ++ template[i].ulValueLen = blobSize; ++ } ++ found = 1; ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ stmt = NULL; ++ ++loser: ++ /* fix up the error if necessary */ ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ if (!found && error == CKR_OK) { ++ error = CKR_OBJECT_HANDLE_INVALID; ++ } ++ } ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ /* if we had to open a new database, free it now */ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ return error; ++} ++ ++/* NOTE: requires sdb_p->schemaAttrs to be sorted asc. */ ++inline static PRBool ++sdb_attributeExists(SDB *sdb, CK_ATTRIBUTE_TYPE attr) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ int first = 0; ++ int last = (int)sdb_p->numSchemaAttrs - 1; ++ while (last >= first) { ++ int mid = first + (last - first) / 2; ++ if (sdb_p->schemaAttrs[mid] == attr) { ++ return PR_TRUE; ++ } ++ if (attr > sdb_p->schemaAttrs[mid]) { ++ first = mid + 1; ++ } else { ++ last = mid - 1; ++ } ++ } ++ ++ return PR_FALSE; ++} ++ ++CK_RV ++sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, ++ CK_ATTRIBUTE *template, CK_ULONG count) ++{ ++ CK_RV crv = CKR_OK; ++ unsigned int tmplIdx; ++ unsigned int resIdx = 0; ++ unsigned int validCount = 0; ++ unsigned int i; ++ ++ if (count == 0) { ++ return crv; ++ } ++ ++ CK_ATTRIBUTE *validTemplate; ++ PRBool invalidExists = PR_FALSE; ++ for (tmplIdx = 0; tmplIdx < count; tmplIdx++) { ++ if (!sdb_attributeExists(sdb, template[tmplIdx].type)) { ++ template[tmplIdx].ulValueLen = -1; ++ crv = CKR_ATTRIBUTE_TYPE_INVALID; ++ invalidExists = PR_TRUE; ++ break; ++ } ++ } ++ ++ if (!invalidExists) { ++ validTemplate = template; ++ validCount = count; ++ } else { ++ /* Create a new template containing only the valid subset of ++ * input |template|, and query with that. */ ++ validCount = tmplIdx; ++ validTemplate = malloc(sizeof(CK_ATTRIBUTE) * count); ++ if (!validTemplate) { ++ return CKR_HOST_MEMORY; ++ } ++ /* Copy in what we already know is valid. */ ++ for (i = 0; i < validCount; i++) { ++ validTemplate[i] = template[i]; ++ } ++ ++ /* tmplIdx was left at the index of the first invalid ++ * attribute, which has been handled. We only need to ++ * deal with the remainder. */ ++ tmplIdx++; ++ for (; tmplIdx < count; tmplIdx++) { ++ if (sdb_attributeExists(sdb, template[tmplIdx].type)) { ++ validTemplate[validCount++] = template[tmplIdx]; ++ } else { ++ template[tmplIdx].ulValueLen = -1; ++ } ++ } ++ } ++ ++ if (validCount) { ++ LOCK_SQLITE() ++ CK_RV crv2 = sdb_GetValidAttributeValueNoLock(sdb, object_id, validTemplate, validCount); ++ UNLOCK_SQLITE() ++ ++ /* If an invalid attribute was removed above, let ++ * the caller know. Any other error from the actual ++ * query should propogate. */ ++ crv = (crv2 == CKR_OK) ? crv : crv2; ++ } ++ ++ if (invalidExists) { ++ /* Copy out valid lengths. */ ++ tmplIdx = 0; ++ for (resIdx = 0; resIdx < validCount; resIdx++) { ++ for (; tmplIdx < count; tmplIdx++) { ++ if (template[tmplIdx].type != validTemplate[resIdx].type) { ++ continue; ++ } ++ template[tmplIdx].ulValueLen = validTemplate[resIdx].ulValueLen; ++ tmplIdx++; ++ break; ++ } ++ } ++ free(validTemplate); ++ } ++ ++ return crv; ++} ++ ++static const char SET_ATTRIBUTE_CMD[] = "UPDATE %s SET %s WHERE id=$ID;"; ++CK_RV ++sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, ++ const CK_ATTRIBUTE *template, CK_ULONG count) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ sqlite3_stmt *stmt = NULL; ++ char *setStr = NULL; ++ char *newStr = NULL; ++ int sqlerr = SQLITE_OK; ++ int retry = 0; ++ CK_RV error = CKR_OK; ++ unsigned int i; ++ ++ if ((sdb->sdb_flags & SDB_RDONLY) != 0) { ++ return CKR_TOKEN_WRITE_PROTECTED; ++ } ++ ++ if (count == 0) { ++ return CKR_OK; ++ } ++ ++ LOCK_SQLITE() ++ setStr = sqlite3_mprintf(""); ++ for (i = 0; setStr && i < count; i++) { ++ if (i == 0) { ++ sqlite3_free(setStr); ++ setStr = sqlite3_mprintf("a%x=$VALUE%d", ++ template[i].type, i); ++ continue; ++ } ++ newStr = sqlite3_mprintf("%s,a%x=$VALUE%d", setStr, ++ template[i].type, i); ++ sqlite3_free(setStr); ++ setStr = newStr; ++ } ++ newStr = NULL; ++ ++ if (setStr == NULL) { ++ return CKR_HOST_MEMORY; ++ } ++ newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr); ++ sqlite3_free(setStr); ++ if (newStr == NULL) { ++ UNLOCK_SQLITE() ++ return CKR_HOST_MEMORY; ++ } ++ error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ for (i = 0; i < count; i++) { ++ if (template[i].ulValueLen != 0) { ++ sqlerr = sqlite3_bind_blob(stmt, i + 1, template[i].pValue, ++ template[i].ulValueLen, SQLITE_STATIC); ++ } else { ++ sqlerr = sqlite3_bind_blob(stmt, i + 1, SQLITE_EXPLICIT_NULL, ++ SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC); ++ } ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ } ++ sqlerr = sqlite3_bind_int(stmt, i + 1, object_id); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++loser: ++ if (newStr) { ++ sqlite3_free(newStr); ++ } ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ } ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ ++ UNLOCK_SQLITE() ++ return error; ++} ++ ++/* ++ * check to see if a candidate object handle already exists. ++ */ ++static PRBool ++sdb_objectExists(SDB *sdb, CK_OBJECT_HANDLE candidate) ++{ ++ CK_RV crv; ++ CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 }; ++ ++ crv = sdb_GetValidAttributeValueNoLock(sdb, candidate, &template, 1); ++ if (crv == CKR_OBJECT_HANDLE_INVALID) { ++ return PR_FALSE; ++ } ++ return PR_TRUE; ++} ++ ++/* ++ * if we're here, we are in a transaction, so it's safe ++ * to examine the current state of the database ++ */ ++static CK_OBJECT_HANDLE ++sdb_getObjectId(SDB *sdb) ++{ ++ CK_OBJECT_HANDLE candidate; ++ static CK_OBJECT_HANDLE next_obj = CK_INVALID_HANDLE; ++ int count; ++ /* ++ * get an initial object handle to use ++ */ ++ if (next_obj == CK_INVALID_HANDLE) { ++ PRTime time; ++ time = PR_Now(); ++ ++ next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL); ++ } ++ candidate = next_obj++; ++ /* detect that we've looped through all the handles... */ ++ for (count = 0; count < 0x40000000; count++, candidate = next_obj++) { ++ /* mask off excess bits */ ++ candidate &= 0x3fffffff; ++ /* if we hit zero, go to the next entry */ ++ if (candidate == CK_INVALID_HANDLE) { ++ continue; ++ } ++ /* make sure we aren't already using */ ++ if (!sdb_objectExists(sdb, candidate)) { ++ /* this one is free */ ++ return candidate; ++ } ++ } ++ ++ /* no handle is free, fail */ ++ return CK_INVALID_HANDLE; ++} ++ ++CK_RV ++sdb_GetNewObjectID(SDB *sdb, CK_OBJECT_HANDLE *object) ++{ ++ CK_OBJECT_HANDLE id; ++ ++ id = sdb_getObjectId(sdb); ++ if (id == CK_INVALID_HANDLE) { ++ return CKR_DEVICE_MEMORY; /* basically we ran out of resources */ ++ } ++ *object = id; ++ return CKR_OK; ++} ++ ++static const char CREATE_CMD[] = "INSERT INTO %s (id%s) VALUES($ID%s);"; ++CK_RV ++sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id, ++ const CK_ATTRIBUTE *template, CK_ULONG count) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ sqlite3_stmt *stmt = NULL; ++ char *columnStr = NULL; ++ char *valueStr = NULL; ++ char *newStr = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ CK_OBJECT_HANDLE this_object = CK_INVALID_HANDLE; ++ int retry = 0; ++ unsigned int i; ++ ++ if ((sdb->sdb_flags & SDB_RDONLY) != 0) { ++ return CKR_TOKEN_WRITE_PROTECTED; ++ } ++ ++ LOCK_SQLITE() ++ if ((*object_id != CK_INVALID_HANDLE) && ++ !sdb_objectExists(sdb, *object_id)) { ++ this_object = *object_id; ++ } else { ++ this_object = sdb_getObjectId(sdb); ++ } ++ if (this_object == CK_INVALID_HANDLE) { ++ UNLOCK_SQLITE(); ++ return CKR_HOST_MEMORY; ++ } ++ columnStr = sqlite3_mprintf(""); ++ valueStr = sqlite3_mprintf(""); ++ *object_id = this_object; ++ for (i = 0; columnStr && valueStr && i < count; i++) { ++ newStr = sqlite3_mprintf("%s,a%x", columnStr, template[i].type); ++ sqlite3_free(columnStr); ++ columnStr = newStr; ++ newStr = sqlite3_mprintf("%s,$VALUE%d", valueStr, i); ++ sqlite3_free(valueStr); ++ valueStr = newStr; ++ } ++ newStr = NULL; ++ if ((columnStr == NULL) || (valueStr == NULL)) { ++ if (columnStr) { ++ sqlite3_free(columnStr); ++ } ++ if (valueStr) { ++ sqlite3_free(valueStr); ++ } ++ UNLOCK_SQLITE() ++ return CKR_HOST_MEMORY; ++ } ++ newStr = sqlite3_mprintf(CREATE_CMD, sdb_p->table, columnStr, valueStr); ++ sqlite3_free(columnStr); ++ sqlite3_free(valueStr); ++ error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ sqlerr = sqlite3_bind_int(stmt, 1, *object_id); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ for (i = 0; i < count; i++) { ++ if (template[i].ulValueLen) { ++ sqlerr = sqlite3_bind_blob(stmt, i + 2, template[i].pValue, ++ template[i].ulValueLen, SQLITE_STATIC); ++ } else { ++ sqlerr = sqlite3_bind_blob(stmt, i + 2, SQLITE_EXPLICIT_NULL, ++ SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC); ++ } ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ } ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++loser: ++ if (newStr) { ++ sqlite3_free(newStr); ++ } ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ } ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ UNLOCK_SQLITE() ++ ++ return error; ++} ++ ++/* ++ * Generic destroy that can destroy metadata or objects ++ */ ++static const char DESTROY_CMD[] = "DELETE FROM %s WHERE (id=$ID);"; ++CK_RV ++sdb_destroyAnyObject(SDB *sdb, const char *table, ++ CK_OBJECT_HANDLE object_id, const char *string_id) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ sqlite3_stmt *stmt = NULL; ++ char *newStr = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ int retry = 0; ++ ++ if ((sdb->sdb_flags & SDB_RDONLY) != 0) { ++ return CKR_TOKEN_WRITE_PROTECTED; ++ } ++ ++ LOCK_SQLITE() ++ error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ newStr = sqlite3_mprintf(DESTROY_CMD, table); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ if (string_id == NULL) { ++ sqlerr = sqlite3_bind_int(stmt, 1, object_id); ++ } else { ++ sqlerr = sqlite3_bind_text(stmt, 1, string_id, ++ PORT_Strlen(string_id), SQLITE_STATIC); ++ } ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++loser: ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ } ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ ++ UNLOCK_SQLITE() ++ return error; ++} ++ ++CK_RV ++sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ return sdb_destroyAnyObject(sdb, sdb_p->table, object_id, NULL); ++} ++ ++CK_RV ++sdb_DestroyMetaData(SDB *sdb, const char *id) ++{ ++ return sdb_destroyAnyObject(sdb, "metaData", 0, id); ++} ++ ++static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;"; ++ ++/* ++ * start a transaction. ++ * ++ * We need to open a new database, then store that new database into ++ * the private data structure. We open the database first, then use locks ++ * to protect storing the data to prevent deadlocks. ++ */ ++CK_RV ++sdb_Begin(SDB *sdb) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ sqlite3_stmt *stmt = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ int retry = 0; ++ ++ if ((sdb->sdb_flags & SDB_RDONLY) != 0) { ++ return CKR_TOKEN_WRITE_PROTECTED; ++ } ++ ++ LOCK_SQLITE() ++ ++ /* get a new version that we will use for the entire transaction */ ++ sqlerr = sdb_openDB(sdb_p->sqlDBName, &sqlDB, SDB_RDWR); ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ ++ sqlerr = sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL); ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ /* don't retry BEGIN transaction*/ ++ retry = 0; ++ } while (!sdb_done(sqlerr, &retry)); ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++loser: ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ ++ /* we are starting a new transaction, ++ * and if we succeeded, then save this database for the rest of ++ * our transaction */ ++ if (error == CKR_OK) { ++ /* we hold a 'BEGIN TRANSACTION' and a sdb_p->lock. At this point ++ * sdb_p->sqlXactDB MUST be null */ ++ PR_EnterMonitor(sdb_p->dbMon); ++ PORT_Assert(sdb_p->sqlXactDB == NULL); ++ sdb_p->sqlXactDB = sqlDB; ++ sdb_p->sqlXactThread = PR_GetCurrentThread(); ++ PR_ExitMonitor(sdb_p->dbMon); ++ } else { ++ /* we failed to start our transaction, ++ * free any databases we opened. */ ++ if (sqlDB) { ++ sqlite3_close(sqlDB); ++ } ++ } ++ ++ UNLOCK_SQLITE() ++ return error; ++} ++ ++/* ++ * Complete a transaction. Basically undo everything we did in begin. ++ * There are 2 flavors Abort and Commit. Basically the only differerence between ++ * these 2 are what the database will show. (no change in to former, change in ++ * the latter). ++ */ ++static CK_RV ++sdb_complete(SDB *sdb, const char *cmd) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ sqlite3_stmt *stmt = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ int retry = 0; ++ ++ if ((sdb->sdb_flags & SDB_RDONLY) != 0) { ++ return CKR_TOKEN_WRITE_PROTECTED; ++ } ++ ++ /* We must have a transation database, or we shouldn't have arrived here */ ++ PR_EnterMonitor(sdb_p->dbMon); ++ PORT_Assert(sdb_p->sqlXactDB); ++ if (sdb_p->sqlXactDB == NULL) { ++ PR_ExitMonitor(sdb_p->dbMon); ++ return CKR_GENERAL_ERROR; /* shouldn't happen */ ++ } ++ PORT_Assert(sdb_p->sqlXactThread == PR_GetCurrentThread()); ++ if (sdb_p->sqlXactThread != PR_GetCurrentThread()) { ++ PR_ExitMonitor(sdb_p->dbMon); ++ return CKR_GENERAL_ERROR; /* shouldn't happen */ ++ } ++ sqlDB = sdb_p->sqlXactDB; ++ sdb_p->sqlXactDB = NULL; /* no one else can get to this DB, ++ * safe to unlock */ ++ sdb_p->sqlXactThread = NULL; ++ PR_ExitMonitor(sdb_p->dbMon); ++ ++ sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL); ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++ /* Pending BEGIN TRANSACTIONS Can move forward at this point. */ ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ /* we we have a cached DB image, update it as well */ ++ if (sdb_p->cacheTable) { ++ PR_EnterMonitor(sdb_p->dbMon); ++ sdb_updateCache(sdb_p); ++ PR_ExitMonitor(sdb_p->dbMon); ++ } ++ ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ ++ /* We just finished a transaction. ++ * Free the database, and remove it from the list */ ++ sqlite3_close(sqlDB); ++ ++ return error; ++} ++ ++static const char COMMIT_CMD[] = "COMMIT TRANSACTION;"; ++CK_RV ++sdb_Commit(SDB *sdb) ++{ ++ CK_RV crv; ++ LOCK_SQLITE() ++ crv = sdb_complete(sdb, COMMIT_CMD); ++ UNLOCK_SQLITE() ++ return crv; ++} ++ ++static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;"; ++CK_RV ++sdb_Abort(SDB *sdb) ++{ ++ CK_RV crv; ++ LOCK_SQLITE() ++ crv = sdb_complete(sdb, ROLLBACK_CMD); ++ UNLOCK_SQLITE() ++ return crv; ++} ++ ++static int tableExists(sqlite3 *sqlDB, const char *tableName); ++ ++static const char GET_PW_CMD[] = "SELECT ALL * FROM metaData WHERE id=$ID;"; ++CK_RV ++sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = sdb_p->sqlXactDB; ++ sqlite3_stmt *stmt = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ int found = 0; ++ int retry = 0; ++ ++ LOCK_SQLITE() ++ error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ ++ /* handle 'test' versions of the sqlite db */ ++ sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL); ++ /* Sigh, if we created a new table since we opened the database, ++ * the database handle will not see the new table, we need to close this ++ * database and reopen it. This is safe because we are holding the lock ++ * still. */ ++ if (sqlerr == SQLITE_SCHEMA) { ++ sqlerr = sdb_reopenDBLocal(sdb_p, &sqlDB); ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL); ++ } ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC); ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ if (sqlerr == SQLITE_ROW) { ++ const char *blobData; ++ unsigned int len = item1->len; ++ item1->len = sqlite3_column_bytes(stmt, 1); ++ if (item1->len > len) { ++ error = CKR_BUFFER_TOO_SMALL; ++ continue; ++ } ++ blobData = sqlite3_column_blob(stmt, 1); ++ PORT_Memcpy(item1->data, blobData, item1->len); ++ if (item2) { ++ len = item2->len; ++ item2->len = sqlite3_column_bytes(stmt, 2); ++ if (item2->len > len) { ++ error = CKR_BUFFER_TOO_SMALL; ++ continue; ++ } ++ blobData = sqlite3_column_blob(stmt, 2); ++ PORT_Memcpy(item2->data, blobData, item2->len); ++ } ++ found = 1; ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++loser: ++ /* fix up the error if necessary */ ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ if (!found && error == CKR_OK) { ++ error = CKR_OBJECT_HANDLE_INVALID; ++ } ++ } ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ UNLOCK_SQLITE() ++ ++ return error; ++} ++ ++static const char PW_CREATE_TABLE_CMD[] = ++ "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);"; ++static const char PW_CREATE_CMD[] = ++ "INSERT INTO metaData (id,item1,item2) VALUES($ID,$ITEM1,$ITEM2);"; ++static const char MD_CREATE_CMD[] = ++ "INSERT INTO metaData (id,item1) VALUES($ID,$ITEM1);"; ++ ++CK_RV ++sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1, ++ const SECItem *item2) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = sdb_p->sqlXactDB; ++ sqlite3_stmt *stmt = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ int retry = 0; ++ const char *cmd = PW_CREATE_CMD; ++ ++ if ((sdb->sdb_flags & SDB_RDONLY) != 0) { ++ return CKR_TOKEN_WRITE_PROTECTED; ++ } ++ ++ LOCK_SQLITE() ++ error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ ++ if (!tableExists(sqlDB, "metaData")) { ++ sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ } ++ if (item2 == NULL) { ++ cmd = MD_CREATE_CMD; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ sqlerr = sqlite3_bind_blob(stmt, 2, item1->data, item1->len, SQLITE_STATIC); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ if (item2) { ++ sqlerr = sqlite3_bind_blob(stmt, 3, item2->data, ++ item2->len, SQLITE_STATIC); ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ } ++ ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++loser: ++ /* fix up the error if necessary */ ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ } ++ ++ if (stmt) { ++ sqlite3_reset(stmt); ++ sqlite3_finalize(stmt); ++ } ++ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ UNLOCK_SQLITE() ++ ++ return error; ++} ++ ++static const char RESET_CMD[] = "DELETE FROM %s;"; ++CK_RV ++sdb_Reset(SDB *sdb) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ sqlite3 *sqlDB = NULL; ++ char *newStr; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ ++ /* only Key databases can be reset */ ++ if (sdb_p->type != SDB_KEY) { ++ return CKR_OBJECT_HANDLE_INVALID; ++ } ++ ++ LOCK_SQLITE() ++ error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ ++ if (tableExists(sqlDB, sdb_p->table)) { ++ /* delete the contents of the key table */ ++ newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ ++ if (sqlerr != SQLITE_OK) ++ goto loser; ++ } ++ ++ /* delete the password entry table */ ++ sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;", ++ NULL, 0, NULL); ++ ++loser: ++ /* fix up the error if necessary */ ++ if (error == CKR_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ } ++ ++ if (sqlDB) { ++ sdb_closeDBLocal(sdb_p, sqlDB); ++ } ++ ++ UNLOCK_SQLITE() ++ return error; ++} ++ ++CK_RV ++sdb_Close(SDB *sdb) ++{ ++ SDBPrivate *sdb_p = sdb->private; ++ int sqlerr = SQLITE_OK; ++ sdbDataType type = sdb_p->type; ++ ++ sqlerr = sqlite3_close(sdb_p->sqlReadDB); ++ PORT_Free(sdb_p->sqlDBName); ++ if (sdb_p->cacheTable) { ++ sqlite3_free(sdb_p->cacheTable); ++ } ++ if (sdb_p->dbMon) { ++ PR_DestroyMonitor(sdb_p->dbMon); ++ } ++ free(sdb_p->schemaAttrs); ++ free(sdb_p); ++ free(sdb); ++ return sdb_mapSQLError(type, sqlerr); ++} ++ ++/* ++ * functions to support open ++ */ ++ ++static const char CHECK_TABLE_CMD[] = "SELECT ALL * FROM %s LIMIT 0;"; ++ ++/* return 1 if sqlDB contains table 'tableName */ ++static int ++tableExists(sqlite3 *sqlDB, const char *tableName) ++{ ++ char *cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName); ++ int sqlerr = SQLITE_OK; ++ ++ if (cmd == NULL) { ++ return 0; ++ } ++ ++ sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0); ++ sqlite3_free(cmd); ++ ++ return (sqlerr == SQLITE_OK) ? 1 : 0; ++} ++ ++void ++sdb_SetForkState(PRBool forked) ++{ ++ /* XXXright now this is a no-op. The global fork state in the softokn3 ++ * shared library is already taken care of at the PKCS#11 level. ++ * If and when we add fork state to the sqlite shared library and extern ++ * interface, we will need to set it and reset it from here */ ++} ++ ++static int ++sdb_attributeComparator(const void *a, const void *b) ++{ ++ if (*(CK_ATTRIBUTE_TYPE *)a < *(CK_ATTRIBUTE_TYPE *)b) { ++ return -1; ++ } ++ if (*(CK_ATTRIBUTE_TYPE *)a > *(CK_ATTRIBUTE_TYPE *)b) { ++ return 1; ++ } ++ return 0; ++} ++ ++/* ++ * initialize a single database ++ */ ++static const char INIT_CMD[] = ++ "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)"; ++ ++CK_RV ++sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, ++ int *newInit, int inFlags, PRUint32 accessOps, SDB **pSdb) ++{ ++ int i; ++ char *initStr = NULL; ++ char *newStr; ++ char *queryStr = NULL; ++ int inTransaction = 0; ++ SDB *sdb = NULL; ++ SDBPrivate *sdb_p = NULL; ++ sqlite3 *sqlDB = NULL; ++ int sqlerr = SQLITE_OK; ++ CK_RV error = CKR_OK; ++ char *cacheTable = NULL; ++ PRIntervalTime now = 0; ++ char *env; ++ PRBool enableCache = PR_FALSE; ++ PRBool checkFSType = PR_FALSE; ++ PRBool measureSpeed = PR_FALSE; ++ PRBool create; ++ int flags = inFlags & 0x7; ++ ++ *pSdb = NULL; ++ *inUpdate = 0; ++ ++ /* sqlite3 doesn't have a flag to specify that we want to ++ * open the database read only. If the db doesn't exist, ++ * sqlite3 will always create it. ++ */ ++ LOCK_SQLITE(); ++ create = (_NSSUTIL_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS); ++ if ((flags == SDB_RDONLY) && create) { ++ error = sdb_mapSQLError(type, SQLITE_CANTOPEN); ++ goto loser; ++ } ++ sqlerr = sdb_openDB(dbname, &sqlDB, flags); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ ++ /* ++ * SQL created the file, but it doesn't set appropriate modes for ++ * a database. ++ * ++ * NO NSPR call for chmod? :( ++ */ ++ if (create && sdb_chmod(dbname, 0600) != 0) { ++ error = sdb_mapSQLError(type, SQLITE_CANTOPEN); ++ goto loser; ++ } ++ ++ if (flags != SDB_RDONLY) { ++ sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ inTransaction = 1; ++ } ++ if (!tableExists(sqlDB, table)) { ++ *newInit = 1; ++ if (flags != SDB_CREATE) { ++ error = sdb_mapSQLError(type, SQLITE_CANTOPEN); ++ goto loser; ++ } ++ initStr = sqlite3_mprintf(""); ++ for (i = 0; initStr && i < known_attributes_size; i++) { ++ newStr = sqlite3_mprintf("%s, a%x", initStr, known_attributes[i]); ++ sqlite3_free(initStr); ++ initStr = newStr; ++ } ++ if (initStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ ++ newStr = sqlite3_mprintf(INIT_CMD, table, initStr); ++ sqlite3_free(initStr); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ ++ newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ ++ newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ ++ newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ ++ newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table); ++ if (newStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); ++ sqlite3_free(newStr); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(type, sqlerr); ++ goto loser; ++ } ++ } ++ /* ++ * detect the case where we have created the database, but have ++ * not yet updated it. ++ * ++ * We only check the Key database because only the key database has ++ * a metaData table. The metaData table is created when a password ++ * is set, or in the case of update, when a password is supplied. ++ * If no key database exists, then the update would have happened immediately ++ * on noticing that the cert database didn't exist (see newInit set above). ++ */ ++ if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) { ++ *newInit = 1; ++ } ++ ++ /* access to network filesystems are significantly slower than local ones ++ * for database operations. In those cases we need to create a cached copy ++ * of the database in a temporary location on the local disk. SQLITE ++ * already provides a way to create a temporary table and initialize it, ++ * so we use it for the cache (see sdb_buildCache for how it's done).*/ ++ ++ /* ++ * we decide whether or not to use the cache based on the following input. ++ * ++ * NSS_SDB_USE_CACHE environment variable is set to anything other than ++ * "yes" or "no" (for instance, "auto"): NSS will measure the performance ++ * of access to the temp database versus the access to the user's ++ * passed-in database location. If the temp database location is ++ * "significantly" faster we will use the cache. ++ * ++ * NSS_SDB_USE_CACHE environment variable is nonexistent or set to "no": ++ * cache will not be used. ++ * ++ * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will ++ * always be used. ++ * ++ * It is expected that most applications will not need this feature, and ++ * thus it is disabled by default. ++ */ ++ ++ env = PR_GetEnvSecure("NSS_SDB_USE_CACHE"); ++ ++ /* Variables enableCache, checkFSType, measureSpeed are PR_FALSE by default, ++ * which is the expected behavior for NSS_SDB_USE_CACHE="no". ++ * We don't need to check for "no" here. */ ++ if (!env) { ++ /* By default, with no variable set, we avoid expensive measuring for ++ * most FS types. We start with inexpensive FS type checking, and ++ * might perform measuring for some types. */ ++ checkFSType = PR_TRUE; ++ } else if (PORT_Strcasecmp(env, "yes") == 0) { ++ enableCache = PR_TRUE; ++ } else if (PORT_Strcasecmp(env, "no") != 0) { /* not "no" => "auto" */ ++ measureSpeed = PR_TRUE; ++ } ++ ++ if (checkFSType) { ++#if defined(LINUX) && !defined(ANDROID) ++ struct statfs statfs_s; ++ if (statfs(dbname, &statfs_s) == 0) { ++ switch (statfs_s.f_type) { ++ case SMB_SUPER_MAGIC: ++ case 0xff534d42: /* CIFS_MAGIC_NUMBER */ ++ case NFS_SUPER_MAGIC: ++ /* We assume these are slow. */ ++ enableCache = PR_TRUE; ++ break; ++ case CODA_SUPER_MAGIC: ++ case 0x65735546: /* FUSE_SUPER_MAGIC */ ++ case NCP_SUPER_MAGIC: ++ /* It's uncertain if this FS is fast or slow. ++ * It seems reasonable to perform slow measuring for users ++ * with questionable FS speed. */ ++ measureSpeed = PR_TRUE; ++ break; ++ case AFS_SUPER_MAGIC: /* Already implements caching. */ ++ default: ++ break; ++ } ++ } ++#endif ++ } ++ ++ if (measureSpeed) { ++ char *tempDir = NULL; ++ PRUint32 tempOps = 0; ++ /* ++ * Use PR_Access to determine how expensive it ++ * is to check for the existance of a local file compared to the same ++ * check in the temp directory. If the temp directory is faster, cache ++ * the database there. */ ++ tempDir = sdb_getTempDir(sqlDB); ++ if (tempDir) { ++ tempOps = sdb_measureAccess(tempDir); ++ PORT_Free(tempDir); ++ ++ /* There is a cost to continually copying the database. ++ * Account for that cost with the arbitrary factor of 10 */ ++ enableCache = (PRBool)(tempOps > accessOps * 10); ++ } ++ } ++ ++ if (enableCache) { ++ /* try to set the temp store to memory.*/ ++ sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL); ++ /* Failure to set the temp store to memory is not fatal, ++ * ignore the error */ ++ ++ cacheTable = sqlite3_mprintf("%sCache", table); ++ if (cacheTable == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ /* build the cache table */ ++ error = sdb_buildCache(sqlDB, type, cacheTable, table); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ /* initialize the last cache build time */ ++ now = PR_IntervalNow(); ++ } ++ ++ sdb = (SDB *)malloc(sizeof(SDB)); ++ if (!sdb) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sdb_p = (SDBPrivate *)malloc(sizeof(SDBPrivate)); ++ if (!sdb_p) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ ++ /* Cache the attributes that are held in the table, so we can later check ++ * that queried attributes actually exist. We don't assume the schema ++ * to be exactly |known_attributes|, as it may change over time. */ ++ sdb_p->schemaAttrs = NULL; ++ if (!PORT_Strcmp("nssPublic", table) || ++ !PORT_Strcmp("nssPrivate", table)) { ++ sqlite3_stmt *stmt = NULL; ++ int retry = 0; ++ unsigned int backedAttrs = 0; ++ ++ /* Can't bind parameters to a PRAGMA. */ ++ queryStr = sqlite3_mprintf("PRAGMA table_info(%s);", table); ++ if (queryStr == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ sqlerr = sqlite3_prepare_v2(sqlDB, queryStr, -1, &stmt, NULL); ++ sqlite3_free(queryStr); ++ queryStr = NULL; ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ unsigned int schemaAttrsCapacity = known_attributes_size; ++ sdb_p->schemaAttrs = malloc(schemaAttrsCapacity * sizeof(CK_ATTRIBUTE_TYPE)); ++ if (!sdb_p->schemaAttrs) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ do { ++ sqlerr = sqlite3_step(stmt); ++ if (sqlerr == SQLITE_BUSY) { ++ PR_Sleep(SDB_BUSY_RETRY_TIME); ++ } ++ if (sqlerr == SQLITE_ROW) { ++ if (backedAttrs == schemaAttrsCapacity) { ++ schemaAttrsCapacity += known_attributes_size; ++ sdb_p->schemaAttrs = realloc(sdb_p->schemaAttrs, ++ schemaAttrsCapacity * sizeof(CK_ATTRIBUTE_TYPE)); ++ if (!sdb_p->schemaAttrs) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ } ++ /* Record the ULONG attribute value. */ ++ char *val = (char *)sqlite3_column_text(stmt, 1); ++ if (val && val[0] == 'a') { ++ CK_ATTRIBUTE_TYPE attr = strtoul(&val[1], NULL, 16); ++ sdb_p->schemaAttrs[backedAttrs++] = attr; ++ } ++ } ++ } while (!sdb_done(sqlerr, &retry)); ++ ++ if (sqlerr != SQLITE_DONE) { ++ goto loser; ++ } ++ sqlerr = sqlite3_reset(stmt); ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ sqlerr = sqlite3_finalize(stmt); ++ if (sqlerr != SQLITE_OK) { ++ goto loser; ++ } ++ ++ sdb_p->numSchemaAttrs = backedAttrs; ++ ++ /* Sort these once so we can shortcut invalid attribute searches. */ ++ qsort(sdb_p->schemaAttrs, sdb_p->numSchemaAttrs, ++ sizeof(CK_ATTRIBUTE_TYPE), sdb_attributeComparator); ++ } ++ ++ /* invariant fields */ ++ sdb_p->sqlDBName = PORT_Strdup(dbname); ++ sdb_p->type = type; ++ sdb_p->table = table; ++ sdb_p->cacheTable = cacheTable; ++ sdb_p->lastUpdateTime = now; ++ /* set the cache delay time. This is how long we will wait before we ++ * decide the existing cache is stale. Currently set to 10 sec */ ++ sdb_p->updateInterval = PR_SecondsToInterval(10); ++ sdb_p->dbMon = PR_NewMonitor(); ++ /* these fields are protected by the lock */ ++ sdb_p->sqlXactDB = NULL; ++ sdb_p->sqlXactThread = NULL; ++ sdb->private = sdb_p; ++ sdb->version = 1; ++ sdb->sdb_flags = inFlags | SDB_HAS_META; ++ sdb->app_private = NULL; ++ sdb->sdb_FindObjectsInit = sdb_FindObjectsInit; ++ sdb->sdb_FindObjects = sdb_FindObjects; ++ sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal; ++ sdb->sdb_GetAttributeValue = sdb_GetAttributeValue; ++ sdb->sdb_SetAttributeValue = sdb_SetAttributeValue; ++ sdb->sdb_CreateObject = sdb_CreateObject; ++ sdb->sdb_DestroyObject = sdb_DestroyObject; ++ sdb->sdb_GetMetaData = sdb_GetMetaData; ++ sdb->sdb_PutMetaData = sdb_PutMetaData; ++ sdb->sdb_DestroyMetaData = sdb_DestroyMetaData; ++ sdb->sdb_Begin = sdb_Begin; ++ sdb->sdb_Commit = sdb_Commit; ++ sdb->sdb_Abort = sdb_Abort; ++ sdb->sdb_Reset = sdb_Reset; ++ sdb->sdb_Close = sdb_Close; ++ sdb->sdb_SetForkState = sdb_SetForkState; ++ sdb->sdb_GetNewObjectID = sdb_GetNewObjectID; ++ ++ if (inTransaction) { ++ sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL); ++ if (sqlerr != SQLITE_OK) { ++ error = sdb_mapSQLError(sdb_p->type, sqlerr); ++ goto loser; ++ } ++ inTransaction = 0; ++ } ++ ++ sdb_p->sqlReadDB = sqlDB; ++ ++ *pSdb = sdb; ++ UNLOCK_SQLITE(); ++ return CKR_OK; ++ ++loser: ++ /* lots of stuff to do */ ++ if (inTransaction) { ++ sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL); ++ } ++ if (sdb) { ++ free(sdb); ++ } ++ if (sdb_p) { ++ if (sdb_p->schemaAttrs) { ++ free(sdb_p->schemaAttrs); ++ } ++ free(sdb_p); ++ } ++ if (sqlDB) { ++ sqlite3_close(sqlDB); ++ } ++ UNLOCK_SQLITE(); ++ return error; ++} ++ ++/* sdbopen */ ++CK_RV ++s_open(const char *directory, const char *certPrefix, const char *keyPrefix, ++ int cert_version, int key_version, int flags, ++ SDB **certdb, SDB **keydb, int *newInit) ++{ ++ char *cert = sdb_BuildFileName(directory, certPrefix, ++ "cert", cert_version); ++ char *key = sdb_BuildFileName(directory, keyPrefix, ++ "key", key_version); ++ CK_RV error = CKR_OK; ++ int inUpdate; ++ PRUint32 accessOps; ++ ++ if (certdb) ++ *certdb = NULL; ++ if (keydb) ++ *keydb = NULL; ++ *newInit = 0; ++ ++#ifdef SQLITE_UNSAFE_THREADS ++ if (sqlite_lock == NULL) { ++ sqlite_lock = PR_NewLock(); ++ if (sqlite_lock == NULL) { ++ error = CKR_HOST_MEMORY; ++ goto loser; ++ } ++ } ++#endif ++ ++ /* how long does it take to test for a non-existant file in our working ++ * directory? Allows us to test if we may be on a network file system */ ++ accessOps = 1; ++ { ++ char *env; ++ env = PR_GetEnvSecure("NSS_SDB_USE_CACHE"); ++ /* If the environment variable is undefined or set to yes or no, ++ * sdb_init() will ignore the value of accessOps, and we can skip the ++ * measuring.*/ ++ if (env && PORT_Strcasecmp(env, "no") != 0 && ++ PORT_Strcasecmp(env, "yes") != 0) { ++ accessOps = sdb_measureAccess(directory); ++ } ++ } ++ ++ /* ++ * open the cert data base ++ */ ++ if (certdb) { ++ /* initialize Certificate database */ ++ error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate, ++ newInit, flags, accessOps, certdb); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ } ++ ++ /* ++ * open the key data base: ++ * NOTE:if we want to implement a single database, we open ++ * the same database file as the certificate here. ++ * ++ * cert an key db's have different tables, so they will not ++ * conflict. ++ */ ++ if (keydb) { ++ /* initialize the Key database */ ++ error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate, ++ newInit, flags, accessOps, keydb); ++ if (error != CKR_OK) { ++ goto loser; ++ } ++ } ++ ++loser: ++ if (cert) { ++ sqlite3_free(cert); ++ } ++ if (key) { ++ sqlite3_free(key); ++ } ++ ++ if (error != CKR_OK) { ++ /* currently redundant, but could be necessary if more code is added ++ * just before loser */ ++ if (keydb && *keydb) { ++ sdb_Close(*keydb); ++ } ++ if (certdb && *certdb) { ++ sdb_Close(*certdb); ++ } ++ } ++ ++ return error; ++} ++ ++CK_RV ++s_shutdown() ++{ ++#ifdef SQLITE_UNSAFE_THREADS ++ if (sqlite_lock) { ++ PR_DestroyLock(sqlite_lock); ++ sqlite_lock = NULL; ++ } ++#endif ++ return CKR_OK; ++} +diff --git a/cmd/manifest.mn b/cmd/manifest.mn +--- a/cmd/manifest.mn ++++ b/cmd/manifest.mn +@@ -36,16 +36,17 @@ NSS_SRCDIRS = \ + addbuiltin \ + atob \ + btoa \ + certutil \ + chktest \ + crlutil \ + crmftest \ + dbtest \ ++ dbtool \ + derdump \ + digest \ + httpserv \ + listsuites \ + makepqg \ + multinit \ + nss-policy-check \ + ocspclnt \ diff --git a/SOURCES/nss-3.79-dont-verify-default.patch b/SOURCES/nss-3.79-dont-verify-default.patch new file mode 100644 index 0000000..6c747b6 --- /dev/null +++ b/SOURCES/nss-3.79-dont-verify-default.patch @@ -0,0 +1,170 @@ +diff --git a/lib/softoken/legacydb/pcertdb.c b/lib/softoken/legacydb/pcertdb.c +--- a/lib/softoken/legacydb/pcertdb.c ++++ b/lib/softoken/legacydb/pcertdb.c +@@ -4272,16 +4272,17 @@ CreateTrust(void) + { + NSSLOWCERTTrust *trust = NULL; + + nsslowcert_LockFreeList(); + trust = trustListHead; + if (trust) { + trustListCount--; + trustListHead = trust->next; ++ trust->next = NULL; + } + PORT_Assert(trustListCount >= 0); + nsslowcert_UnlockFreeList(); + if (trust) { + return trust; + } + + return PORT_ZNew(NSSLOWCERTTrust); +@@ -5155,19 +5156,21 @@ done: + } + + PRBool + nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust) + { + if (trust == NULL) { + return PR_FALSE; + } +- return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) && +- (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) && +- (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN)); ++ /* if we only have CERTDB__USER and CERTDB_TRUSTED_UNKNOWN bits, then ++ * we don't have a trust record. */ ++ return !(((trust->sslFlags & ~(CERTDB_USER|CERTDB_TRUSTED_UNKNOWN)) == 0) && ++ ((trust->emailFlags & ~(CERTDB_USER|CERTDB_TRUSTED_UNKNOWN)) == 0) && ++ ((trust->objectSigningFlags & ~(CERTDB_USER|CERTDB_TRUSTED_UNKNOWN)) == 0)); + } + + /* + * This function has the logic that decides if another person's cert and + * email profile from an S/MIME message should be saved. It can deal with + * the case when there is no profile. + */ + static SECStatus +diff --git a/lib/softoken/sftkdb.c b/lib/softoken/sftkdb.c +--- a/lib/softoken/sftkdb.c ++++ b/lib/softoken/sftkdb.c +@@ -119,47 +119,79 @@ sftkdb_isAuthenticatedAttribute(CK_ATTRI + case CKA_TRUST_STEP_UP_APPROVED: + case CKA_NSS_OVERRIDE_EXTENSIONS: + return PR_TRUE; + default: + break; + } + return PR_FALSE; + } +- + /* + * convert a native ULONG to a database ulong. Database ulong's + * are all 4 byte big endian values. + */ + void + sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value) + { + int i; + + for (i = 0; i < SDB_ULONG_SIZE; i++) { + data[i] = (value >> (SDB_ULONG_SIZE - 1 - i) * BBP) & 0xff; + } + } + + /* + * convert a database ulong back to a native ULONG. (reverse of the above +- * function. ++ * function). + */ + static CK_ULONG + sftk_SDBULong2ULong(unsigned char *data) + { + int i; + CK_ULONG value = 0; + + for (i = 0; i < SDB_ULONG_SIZE; i++) { + value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE - 1 - i) * BBP); + } + return value; + } + ++/* certain trust records are default values, which are the values ++ * returned if the signature check fails anyway. ++ * In those cases, we can skip the signature check. */ ++PRBool ++sftkdb_isNullTrust(const CK_ATTRIBUTE *template) ++{ ++ switch (template->type) { ++ case CKA_TRUST_SERVER_AUTH: ++ case CKA_TRUST_CLIENT_AUTH: ++ case CKA_TRUST_EMAIL_PROTECTION: ++ case CKA_TRUST_CODE_SIGNING: ++ if (template->ulValueLen != SDB_ULONG_SIZE) { ++ break; ++ } ++ if (sftk_SDBULong2ULong(template->pValue) == ++ CKT_NSS_TRUST_UNKNOWN) { ++ return PR_TRUE; ++ } ++ break; ++ case CKA_TRUST_STEP_UP_APPROVED: ++ if (template->ulValueLen != 1) { ++ break; ++ } ++ if (*((unsigned char *)(template->pValue)) == 0) { ++ return PR_TRUE; ++ } ++ break; ++ default: ++ break; ++ } ++ return PR_FALSE; ++} ++ + /* + * fix up the input templates. Our fixed up ints are stored in data and must + * be freed by the caller. The new template must also be freed. If there are no + * CK_ULONG attributes, the orignal template is passed in as is. + */ + static CK_ATTRIBUTE * + sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count, + unsigned char **dataOut, int *dataOutSize) +@@ -410,17 +442,18 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *te + } + + /* copy the plain text back into the template */ + PORT_Memcpy(template[i].pValue, plainText->data, plainText->len); + template[i].ulValueLen = plainText->len; + SECITEM_ZfreeItem(plainText, PR_TRUE); + } + /* make sure signed attributes are valid */ +- if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) { ++ if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type) ++ && !sftkdb_isNullTrust(&ntemplate[i])) { + SECStatus rv; + CK_RV local_crv; + SECItem signText; + SECItem plainText; + unsigned char signData[SDB_MAX_META_DATA_LEN]; + + signText.data = signData; + signText.len = sizeof(signData); +@@ -2387,16 +2420,18 @@ sftkdb_mergeObject(SFTKDBHandle *handle, + crv = (*source->sdb_GetAttributeValue)(source, id, + ptemplate, max_attributes); + if (crv != CKR_OK) { + goto loser; + } + + objectType = sftkdb_getULongFromTemplate(CKA_CLASS, ptemplate, + max_attributes); ++/*printf(" - merging object Type 0x%08lx id=0x%08lx updateID=%s\n", objectType, id, ++ handle->updateID?handle->updateID: "");*/ + + /* + * Update Object updates the object template if necessary then returns + * whether or not we need to actually write the object out to our target + * database. + */ + if (!handle->updateID) { + crv = sftkdb_CreateObject(arena, handle, target, &newID, diff --git a/SOURCES/nss-3.79-enable-POST-rerun.patch b/SOURCES/nss-3.79-enable-POST-rerun.patch new file mode 100644 index 0000000..47c1ff8 --- /dev/null +++ b/SOURCES/nss-3.79-enable-POST-rerun.patch @@ -0,0 +1,522 @@ +diff --git a/cmd/bltest/blapitest.c b/cmd/bltest/blapitest.c +--- a/cmd/bltest/blapitest.c ++++ b/cmd/bltest/blapitest.c +@@ -3870,17 +3870,17 @@ main(int argc, char **argv) + rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff, + encrypt, decrypt); + PORT_Free(cipherInfo); + return rv == SECSuccess ? 0 : 1; + } + + /* Do FIPS self-test */ + if (bltest.commands[cmd_FIPS].activated) { +- CK_RV ckrv = sftk_FIPSEntryOK(); ++ CK_RV ckrv = sftk_FIPSEntryOK(PR_FALSE); + fprintf(stdout, "CK_RV: %ld.\n", ckrv); + PORT_Free(cipherInfo); + if (ckrv == CKR_OK) + return SECSuccess; + return SECFailure; + } + + /* +diff --git a/cmd/pk11mode/pk11mode.c b/cmd/pk11mode/pk11mode.c +--- a/cmd/pk11mode/pk11mode.c ++++ b/cmd/pk11mode/pk11mode.c +@@ -318,23 +318,25 @@ static PRBool verbose = PR_FALSE; + + int + main(int argc, char **argv) + { + CK_C_GetFunctionList pC_GetFunctionList; + CK_FUNCTION_LIST_PTR pFunctionList; + CK_RV crv = CKR_OK; + CK_C_INITIALIZE_ARGS_NSS initArgs; ++ CK_C_INITIALIZE_ARGS_NSS initArgsRerun; /* rerun selftests */ + CK_SLOT_ID *pSlotList = NULL; + CK_TOKEN_INFO tokenInfo; + CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */ + + CK_UTF8CHAR *pwd = NULL; + CK_ULONG pwdLen = 0; + char *moduleSpec = NULL; ++ char *moduleSpecRerun = NULL; + char *configDir = NULL; + char *dbPrefix = NULL; + char *disableUnload = NULL; + PRBool doForkTests = PR_TRUE; + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:Fd:p:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { +@@ -458,18 +460,23 @@ main(int argc, char **argv) + initArgs.CreateMutex = NULL; + initArgs.DestroyMutex = NULL; + initArgs.LockMutex = NULL; + initArgs.UnlockMutex = NULL; + initArgs.flags = CKF_OS_LOCKING_OK; + moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' " + "keyPrefix='%s' secmod='secmod.db' flags= ", + configDir, dbPrefix, dbPrefix); ++ moduleSpecRerun = PR_smprintf("configdir='%s' certPrefix='%s' " ++ "keyPrefix='%s' secmod='secmod.db' flags=forcePOST ", ++ configDir, dbPrefix, dbPrefix); + initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec; + initArgs.pReserved = NULL; ++ initArgsRerun = initArgs; ++ initArgsRerun.LibraryParameters = (CK_CHAR_PTR *)moduleSpecRerun; + + /*DebugBreak();*/ + /* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */ + /* NSS cryptographic module library initialization for the FIPS */ + /* Approved mode when FC_Initialize is envoked will perfom */ + /* software integrity test, and power-up self-tests before */ + /* FC_Initialize returns */ + crv = pFunctionList->C_Initialize(&initArgs); +@@ -705,17 +712,17 @@ main(int argc, char **argv) + PKM_Error("PKM_HybridMode failed with 0x%08X, %-26s\n", crv, + PKM_CK_RVtoStr(crv)); + goto cleanup; + } + + if (doForkTests) { + /* testing one more C_Initialize / C_Finalize to exercise getpid() + * fork check code */ +- crv = pFunctionList->C_Initialize(&initArgs); ++ crv = pFunctionList->C_Initialize(&initArgsRerun); + if (crv == CKR_OK) { + PKM_LogIt("C_Initialize succeeded\n"); + } else { + PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv, + PKM_CK_RVtoStr(crv)); + goto cleanup; + } + crv = pFunctionList->C_Finalize(NULL); +@@ -741,16 +748,19 @@ cleanup: + free(configDir); + } + if (dbPrefix) { + free(dbPrefix); + } + if (moduleSpec) { + PR_smprintf_free(moduleSpec); + } ++ if (moduleSpecRerun) { ++ PR_smprintf_free(moduleSpecRerun); ++ } + + #ifdef _WIN32 + FreeLibrary(hModule); + #else + disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD"); + if (!disableUnload) { + PR_UnloadLibrary(lib); + } +diff --git a/lib/freebl/blapii.h b/lib/freebl/blapii.h +--- a/lib/freebl/blapii.h ++++ b/lib/freebl/blapii.h +@@ -24,17 +24,17 @@ typedef SECStatus (*freeblAeadFunc)(void + void *params, unsigned int paramsLen, + const unsigned char *aad, unsigned int aadLen, + unsigned int blocksize); + typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit); + + SEC_BEGIN_PROTOS + + #ifndef NSS_FIPS_DISABLED +-SECStatus BL_FIPSEntryOK(PRBool freeblOnly); ++SECStatus BL_FIPSEntryOK(PRBool freeblOnly, PRBool rerun); + PRBool BL_POSTRan(PRBool freeblOnly); + #endif + + #if defined(XP_UNIX) && !defined(NO_FORK_CHECK) + + extern PRBool bl_parentForkedAfterC_Initialize; + + #define SKIP_AFTER_FORK(x) \ +diff --git a/lib/freebl/blapit.h b/lib/freebl/blapit.h +--- a/lib/freebl/blapit.h ++++ b/lib/freebl/blapit.h +@@ -223,16 +223,21 @@ typedef int __BLAPI_DEPRECATED __attribu + * + * If we arbitrarily set p = 10^-18 (1 chance in trillion trillion operation) + * we get GCMIV_RANDOM_BIRTHDAY_BITS = -(-18)/.301 -1 = 59 (.301 = log10 2) + * GCMIV_RANDOM_BIRTHDAY_BITS should be at least 59, call it a round 64. NOTE: + * the variable IV size for TLS is 64 bits, which explains why it's not safe + * to use a random value for the nonce in TLS. */ + #define GCMIV_RANDOM_BIRTHDAY_BITS 64 + ++/* flag to tell BLAPI_Verify* to rerun the post and integrity tests */ ++#define BLAPI_FIPS_RERUN_FLAG '\377' /* 0xff, 255 invalide code for UFT8/ASCII */ ++#define BLAPI_FIPS_RERUN_FLAG_STRING "\377" /* The above as a C string */ ++ ++ + /*************************************************************************** + ** Opaque objects + */ + + struct DESContextStr; + struct RC2ContextStr; + struct RC4ContextStr; + struct RC5ContextStr; +diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c +--- a/lib/freebl/fipsfreebl.c ++++ b/lib/freebl/fipsfreebl.c +@@ -2211,29 +2211,37 @@ bl_startup_tests(void) + } + + /* + * this is called from the freebl init entry points that controll access to + * all other freebl functions. This prevents freebl from operating if our + * power on selftest failed. + */ + SECStatus +-BL_FIPSEntryOK(PRBool freebl_only) ++BL_FIPSEntryOK(PRBool freebl_only, PRBool rerun) + { + #ifdef NSS_NO_INIT_SUPPORT + /* this should only be set on platforms that can't handle one of the INIT + * schemes. This code allows those platforms to continue to function, + * though they don't meet the strict NIST requirements. If NSS_NO_INIT_SUPPORT + * is not set, and init support has not been properly enabled, freebl + * will always fail because of the test below + */ + if (!self_tests_freebl_ran) { + bl_startup_tests(); + } + #endif ++ if (rerun) { ++ /* reset the flags */ ++ self_tests_freebl_ran = PR_FALSE; ++ self_tests_success = PR_FALSE; ++ self_tests_success = PR_FALSE; ++ self_tests_freebl_success = PR_FALSE; ++ bl_startup_tests(); ++ } + /* if the general self tests succeeded, we're done */ + if (self_tests_success) { + return SECSuccess; + } + /* standalone freebl can initialize */ + if (freebl_only && self_tests_freebl_success) { + return SECSuccess; + } +diff --git a/lib/freebl/nsslowhash.c b/lib/freebl/nsslowhash.c +--- a/lib/freebl/nsslowhash.c ++++ b/lib/freebl/nsslowhash.c +@@ -55,17 +55,17 @@ NSSLOW_Init(void) + #ifdef FREEBL_NO_DEPEND + (void)FREEBL_InitStubs(); + #endif + + #ifndef NSS_FIPS_DISABLED + /* make sure the FIPS product is installed if we are trying to + * go into FIPS mode */ + if (nsslow_GetFIPSEnabled()) { +- if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) { ++ if (BL_FIPSEntryOK(PR_TRUE, PR_FALSE) != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + post_failed = PR_TRUE; + return NULL; + } + } + #endif + post_failed = PR_FALSE; + +diff --git a/lib/freebl/shvfy.c b/lib/freebl/shvfy.c +--- a/lib/freebl/shvfy.c ++++ b/lib/freebl/shvfy.c +@@ -282,52 +282,62 @@ readItem(PRFileDesc *fd, SECItem *item) + PORT_Free(item->data); + item->data = NULL; + item->len = 0; + return SECFailure; + } + return SECSuccess; + } + +-static PRBool blapi_SHVerifyFile(const char *shName, PRBool self); ++static PRBool blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun); + + static PRBool +-blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self) ++blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self, PRBool rerun) + { + PRBool result = PR_FALSE; /* if anything goes wrong, + * the signature does not verify */ + /* find our shared library name */ + char *shName = PR_GetLibraryFilePathname(name, addr); + if (!shName) { + goto loser; + } +- result = blapi_SHVerifyFile(shName, self); ++ result = blapi_SHVerifyFile(shName, self, rerun); + + loser: + if (shName != NULL) { + PR_Free(shName); + } + + return result; + } + + PRBool + BLAPI_SHVerify(const char *name, PRFuncPtr addr) + { +- return blapi_SHVerify(name, addr, PR_FALSE); ++ PRBool rerun = PR_FALSE; ++ if (name && *name == BLAPI_FIPS_RERUN_FLAG) { ++ name++; ++ rerun = PR_TRUE; ++ } ++ return blapi_SHVerify(name, addr, PR_FALSE, rerun); + } + + PRBool + BLAPI_SHVerifyFile(const char *shName) + { +- return blapi_SHVerifyFile(shName, PR_FALSE); ++ PRBool rerun = PR_FALSE; ++ if (shName && *shName == BLAPI_FIPS_RERUN_FLAG) { ++ shName++; ++ rerun = PR_TRUE; ++ } ++ return blapi_SHVerifyFile(shName, PR_FALSE, rerun); + } + + static PRBool +-blapi_SHVerifyFile(const char *shName, PRBool self) ++blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun) + { + char *checkName = NULL; + PRFileDesc *checkFD = NULL; + PRFileDesc *shFD = NULL; + void *hashcx = NULL; + const SECHashObject *hashObj = NULL; + SECItem signature = { 0, NULL, 0 }; + SECItem hash; +@@ -346,17 +356,17 @@ blapi_SHVerifyFile(const char *shName, P + unsigned char hashBuf[HASH_LENGTH_MAX]; + + PORT_Memset(&key, 0, sizeof(key)); + hash.data = hashBuf; + hash.len = sizeof(hashBuf); + + /* If our integrity check was never ran or failed, fail any other + * integrity checks to prevent any token going into FIPS mode. */ +- if (!self && (BL_FIPSEntryOK(PR_FALSE) != SECSuccess)) { ++ if (!self && (BL_FIPSEntryOK(PR_FALSE, rerun) != SECSuccess)) { + return PR_FALSE; + } + + if (!shName) { + goto loser; + } + + /* figure out the name of our check file */ +@@ -536,17 +546,17 @@ BLAPI_VerifySelf(const char *name) + { + if (name == NULL) { + /* + * If name is NULL, freebl is statically linked into softoken. + * softoken will call BLAPI_SHVerify next to verify itself. + */ + return PR_TRUE; + } +- return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE); ++ return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE, PR_FALSE); + } + + #else /* NSS_FIPS_DISABLED */ + + PRBool + BLAPI_SHVerifyFile(const char *shName) + { + return PR_FALSE; +diff --git a/lib/softoken/fipstest.c b/lib/softoken/fipstest.c +--- a/lib/softoken/fipstest.c ++++ b/lib/softoken/fipstest.c +@@ -684,22 +684,25 @@ sftk_fips_HKDF_PowerUpSelfTest(void) + + static PRBool sftk_self_tests_ran = PR_FALSE; + static PRBool sftk_self_tests_success = PR_FALSE; + + /* + * This function is called at dll load time, the code tha makes this + * happen is platform specific on defined above. + */ +-static void +-sftk_startup_tests(void) ++void sftk_startup_tests_with_rerun(PRBool rerun) + { + SECStatus rv; +- const char *libraryName = SOFTOKEN_LIB_NAME; +- ++ /*const char *nlibraryName = SOFTOKEN_LIB_NAME; ++ const char *rlibraryName = BLAPI_FIPS_RERUN_FLAG_STRING SOFTOKEN_LIB_NAME; */ ++ const char *libraryName = rerun ? ++ BLAPI_FIPS_RERUN_FLAG_STRING SOFTOKEN_LIB_NAME : ++ SOFTOKEN_LIB_NAME; ++ + PORT_Assert(!sftk_self_tests_ran); + PORT_Assert(!sftk_self_tests_success); + sftk_self_tests_ran = PR_TRUE; + sftk_self_tests_success = PR_FALSE; /* just in case */ + + /* need to initiallize the oid library before the RSA tests */ + rv = SECOID_Init(); + if (rv != SECSuccess) { +@@ -746,35 +749,46 @@ sftk_startup_tests(void) + rv = sftk_fips_pbkdf_PowerUpSelfTests(); + if (rv != SECSuccess) { + return; + } + + sftk_self_tests_success = PR_TRUE; + } + ++static void ++sftk_startup_tests(void) ++{ ++ sftk_startup_tests_with_rerun(PR_FALSE); ++} ++ + /* + * this is called from nsc_Common_Initizialize entry points that gates access + * to * all other pkcs11 functions. This prevents softoken operation if our + * power on selftest failed. + */ + CK_RV +-sftk_FIPSEntryOK() ++sftk_FIPSEntryOK(PRBool rerun) + { + #ifdef NSS_NO_INIT_SUPPORT + /* this should only be set on platforms that can't handle one of the INIT + * schemes. This code allows those platforms to continue to function, + * though they don't meet the strict NIST requirements. If NSS_NO_INIT_SUPPORT + * is not set, and init support has not been properly enabled, softken + * will always fail because of the test below + */ + if (!sftk_self_tests_ran) { + sftk_startup_tests(); + } + #endif ++ if (rerun) { ++ sftk_self_tests_ran = PR_FALSE; ++ sftk_self_tests_success = PR_FALSE; ++ sftk_startup_tests_with_rerun(PR_TRUE); ++ } + if (!sftk_self_tests_success) { + return CKR_DEVICE_ERROR; + } + return CKR_OK; + } + #else + #include "pkcs11t.h" + CK_RV +diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c +--- a/lib/softoken/fipstokn.c ++++ b/lib/softoken/fipstokn.c +@@ -524,25 +524,32 @@ fc_log_init_error(CK_RV crv) + } + + /* FC_Initialize initializes the PKCS #11 library. */ + CK_RV + FC_Initialize(CK_VOID_PTR pReserved) + { + const char *envp; + CK_RV crv; ++ PRBool rerun; + + if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { + sftk_audit_enabled = (atoi(envp) == 1); + } + ++ /* if we have the forcePOST flag on, rerun the integrity checks */ ++ /* we need to know this before we fully parse the arguments in ++ * nsc_CommonInitialize, so read it now */ ++ rerun = sftk_RawArgHasFlag("flags", "forcePost", pReserved); ++ + /* At this point we should have already done post and integrity checks. + * if we haven't, it probably means the FIPS product has not been installed +- * or the tests failed. Don't let an application try to enter FIPS mode */ +- crv = sftk_FIPSEntryOK(); ++ * or the tests failed. Don't let an application try to enter FIPS mode. This ++ * also forces the tests to be rerun if forcePOST is set. */ ++ crv = sftk_FIPSEntryOK(rerun); + if (crv != CKR_OK) { + sftk_fatalError = PR_TRUE; + fc_log_init_error(crv); + return crv; + } + + sftk_ForkReset(pReserved, &crv); + +diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h +--- a/lib/softoken/pkcs11i.h ++++ b/lib/softoken/pkcs11i.h +@@ -869,16 +869,17 @@ extern CK_RV sftk_MechAllowsOperation(CK + * acquiring a reference to the keydb from the slot */ + NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey); + + /* + * parameter parsing functions + */ + CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS); + void sftk_freeParams(sftk_parameters *params); ++PRBool sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved); + + /* + * narrow objects + */ + SFTKSessionObject *sftk_narrowToSessionObject(SFTKObject *); + SFTKTokenObject *sftk_narrowToTokenObject(SFTKObject *); + + /* +diff --git a/lib/softoken/sftkpars.c b/lib/softoken/sftkpars.c +--- a/lib/softoken/sftkpars.c ++++ b/lib/softoken/sftkpars.c +@@ -244,8 +244,21 @@ sftk_freeParams(sftk_parameters *params) + FREE_CLEAR(params->configdir); + FREE_CLEAR(params->secmodName); + FREE_CLEAR(params->man); + FREE_CLEAR(params->libdes); + FREE_CLEAR(params->tokens); + FREE_CLEAR(params->updatedir); + FREE_CLEAR(params->updateID); + } ++ ++PRBool ++sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved) ++{ ++ CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved; ++ ++ /* if we don't have any params, the flag isn't set */ ++ if ((!init_args || !init_args->LibraryParameters)) { ++ return PR_FALSE; ++ } ++ ++ return NSSUTIL_ArgHasFlag(entry, flag, (const char *)init_args->LibraryParameters); ++} +diff --git a/lib/softoken/softoken.h b/lib/softoken/softoken.h +--- a/lib/softoken/softoken.h ++++ b/lib/softoken/softoken.h +@@ -52,17 +52,17 @@ extern unsigned char *CBC_PadBuffer(PLAr + unsigned int inlen, unsigned int *outlen, + int blockSize); + + /****************************************/ + /* + ** Power-Up selftests are required for FIPS. + */ + /* make sure Power-up selftests have been run. */ +-extern CK_RV sftk_FIPSEntryOK(void); ++extern CK_RV sftk_FIPSEntryOK(PRBool rerun); + + /* + ** make known fixed PKCS #11 key types to their sizes in bytes + */ + unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType); + + /* + ** FIPS 140-2 auditing diff --git a/SOURCES/nss-3.79-fips.patch b/SOURCES/nss-3.79-fips.patch new file mode 100644 index 0000000..eadcb26 --- /dev/null +++ b/SOURCES/nss-3.79-fips.patch @@ -0,0 +1,742 @@ +diff --git a/lib/freebl/config.mk b/lib/freebl/config.mk +--- a/lib/freebl/config.mk ++++ b/lib/freebl/config.mk +@@ -85,9 +85,13 @@ EXTRA_SHARED_LIBS += \ + $(NULL) + endif + endif + + ifeq ($(OS_ARCH), Darwin) + EXTRA_SHARED_LIBS += -dylib_file @executable_path/libplc4.dylib:$(DIST)/lib/libplc4.dylib -dylib_file @executable_path/libplds4.dylib:$(DIST)/lib/libplds4.dylib + endif + ++ifdef NSS_FIPS_140_3 ++DEFINES += -DNSS_FIPS_140_3 + endif ++ ++endif +diff --git a/lib/freebl/unix_urandom.c b/lib/freebl/unix_urandom.c +--- a/lib/freebl/unix_urandom.c ++++ b/lib/freebl/unix_urandom.c +@@ -20,53 +20,110 @@ RNG_SystemInfoForRNG(void) + if (!numBytes) { + /* error is set */ + return; + } + RNG_RandomUpdate(bytes, numBytes); + PORT_Memset(bytes, 0, sizeof bytes); + } + ++#ifdef NSS_FIPS_140_3 ++#include ++#include "prinit.h" ++ ++static int rng_grndFlags= 0; ++static PRCallOnceType rng_KernelFips; ++ ++static PRStatus ++rng_getKernelFips() ++{ ++#ifdef LINUX ++ FILE *f; ++ char d; ++ size_t size; ++ ++ f = fopen("/proc/sys/crypto/fips_enabled", "r"); ++ if (!f) ++ return PR_FAILURE; ++ ++ size = fread(&d, 1, 1, f); ++ fclose(f); ++ if (size != 1) ++ return PR_SUCCESS; ++ if (d != '1') ++ return PR_SUCCESS; ++ /* if the kernel is in FIPS mode, set the GRND_RANDOM flag */ ++ rng_grndFlags = GRND_RANDOM; ++#endif /* LINUX */ ++ return PR_SUCCESS; ++} ++#endif ++ + size_t + RNG_SystemRNG(void *dest, size_t maxLen) + { ++ size_t fileBytes = 0; ++ unsigned char *buffer = dest; ++#ifndef NSS_FIPS_140_3 + int fd; + int bytes; +- size_t fileBytes = 0; +- unsigned char *buffer = dest; ++#else ++ PR_CallOnce(&rng_KernelFips, rng_getKernelFips); ++#endif + + #if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(LINUX) && defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))) + int result; +- + while (fileBytes < maxLen) { + size_t getBytes = maxLen - fileBytes; + if (getBytes > GETENTROPY_MAX_BYTES) { + getBytes = GETENTROPY_MAX_BYTES; + } ++#ifdef NSS_FIPS_140_3 ++ /* FIP 140-3 requires full kernel reseeding for chained entropy sources ++ * so we need to use getrandom with GRND_RANDOM. ++ * getrandom returns -1 on failure, otherwise returns ++ * the number of bytes, which can be less than getBytes */ ++ result = getrandom(buffer, getBytes, rng_grndFlags); ++ if (result < 0) { ++ break; ++ } ++ fileBytes += result; ++ buffer += result; ++#else ++ /* get entropy returns 0 on success and always return ++ * getBytes on success */ + result = getentropy(buffer, getBytes); + if (result == 0) { /* success */ + fileBytes += getBytes; + buffer += getBytes; + } else { + break; + } ++#endif + } + if (fileBytes == maxLen) { /* success */ + return maxLen; + } ++#ifdef NSS_FIPS_140_3 ++ /* in FIPS 104-3 we don't fallback, just fail */ ++ PORT_SetError(SEC_ERROR_NEED_RANDOM); ++ return 0; ++#else + /* If we failed with an error other than ENOSYS, it means the destination + * buffer is not writeable. We don't need to try writing to it again. */ + if (errno != ENOSYS) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } ++#endif /*!NSS_FIPS_140_3 */ ++#endif /* platorm has getentropy */ ++#ifndef NSS_FIPS_140_3 + /* ENOSYS means the kernel doesn't support getentropy()/getrandom(). + * Reset the number of bytes to get and fall back to /dev/urandom. */ + fileBytes = 0; +-#endif + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } + while (fileBytes < maxLen) { + bytes = read(fd, buffer, maxLen - fileBytes); + if (bytes <= 0) { +@@ -76,9 +133,10 @@ RNG_SystemRNG(void *dest, size_t maxLen) + buffer += bytes; + } + (void)close(fd); + if (fileBytes != maxLen) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } + return fileBytes; ++#endif + } +diff --git a/lib/softoken/config.mk b/lib/softoken/config.mk +--- a/lib/softoken/config.mk ++++ b/lib/softoken/config.mk +@@ -58,8 +58,12 @@ endif + ifdef NSS_ENABLE_FIPS_INDICATORS + DEFINES += -DNSS_ENABLE_FIPS_INDICATORS + endif + + ifdef NSS_FIPS_MODULE_ID + DEFINES += -DNSS_FIPS_MODULE_ID=\"${NSS_FIPS_MODULE_ID}\" + endif + ++ifdef NSS_FIPS_140_3 ++DEFINES += -DNSS_FIPS_140_3 ++endif ++ +diff --git a/lib/softoken/fips_algorithms.h b/lib/softoken/fips_algorithms.h +--- a/lib/softoken/fips_algorithms.h ++++ b/lib/softoken/fips_algorithms.h +@@ -49,33 +49,46 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] + #define CKF_KEK (CKF_WRAP | CKF_UNWRAP) + #define CKF_KEA CKF_DERIVE + #define CKF_KDF CKF_DERIVE + #define CKF_HSH CKF_DIGEST + #define CK_MAX 0xffffffffUL + /* mechanisms using the same key types share the same key type + * limits */ + #define RSA_FB_KEY 2048, 4096 /* min, max */ +-#define RSA_FB_STEP 1024 ++#define RSA_FB_STEP 1 ++#define RSA_LEGACY_FB_KEY 1024, 1792 /* min, max */ ++#define RSA_LEGACY_FB_STEP 256 ++ + #define DSA_FB_KEY 2048, 4096 /* min, max */ + #define DSA_FB_STEP 1024 + #define DH_FB_KEY 2048, 4096 /* min, max */ + #define DH_FB_STEP 1024 + #define EC_FB_KEY 256, 521 /* min, max */ + #define EC_FB_STEP 1 /* key limits handled by special operation */ + #define AES_FB_KEY 128, 256 + #define AES_FB_STEP 64 + { CKM_RSA_PKCS_KEY_PAIR_GEN, { RSA_FB_KEY, CKF_KPG }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_RSA_PKCS_OAEP, { RSA_FB_KEY, CKF_ENC }, RSA_FB_STEP, SFTKFIPSNone }, ++ { CKM_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ + /* -------------- RSA Multipart Signing Operations -------------------- */ + { CKM_SHA224_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA256_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA384_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA512_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA224_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA256_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA384_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA512_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA224_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA256_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA384_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA512_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, + { CKM_SHA224_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA256_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA384_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA512_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + /* ------------------------- DSA Operations --------------------------- */ + { CKM_DSA_KEY_PAIR_GEN, { DSA_FB_KEY, CKF_KPG }, DSA_FB_STEP, SFTKFIPSNone }, + { CKM_DSA, { DSA_FB_KEY, CKF_SGN }, DSA_FB_STEP, SFTKFIPSNone }, + { CKM_DSA_PARAMETER_GEN, { DSA_FB_KEY, CKF_KPG }, DSA_FB_STEP, SFTKFIPSNone }, +@@ -95,76 +108,73 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] + { CKM_ECDSA_SHA256, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC }, + { CKM_ECDSA_SHA384, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC }, + { CKM_ECDSA_SHA512, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC }, + /* ------------------------- RC2 Operations --------------------------- */ + /* ------------------------- AES Operations --------------------------- */ + { CKM_AES_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_ECB, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CBC, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, +- { CKM_AES_MAC, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, +- { CKM_AES_MAC_GENERAL, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CMAC, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CMAC_GENERAL, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CBC_PAD, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CTS, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CTR, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_GCM, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSAEAD }, + { CKM_AES_KEY_WRAP, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_KEY_WRAP_PAD, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_KEY_WRAP_KWP, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, +- { CKM_AES_XCBC_MAC_96, { 96, 96, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_AES_XCBC_MAC, { 128, 128, CKF_SGN }, 1, SFTKFIPSNone }, + /* ------------------------- Hashing Operations ----------------------- */ + { CKM_SHA224, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, + { CKM_SHA224_HMAC, { 112, 224, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA224_HMAC_GENERAL, { 112, 224, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA256, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, +- { CKM_SHA256_HMAC, { 128, 256, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_SHA256_HMAC_GENERAL, { 128, 256, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA256_HMAC, { 112, 256, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA256_HMAC_GENERAL, { 112, 256, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA384, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, +- { CKM_SHA384_HMAC, { 192, 384, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_SHA384_HMAC_GENERAL, { 192, 384, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA384_HMAC, { 112, 384, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA384_HMAC_GENERAL, { 112, 384, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA512, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, +- { CKM_SHA512_HMAC, { 256, 512, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_SHA512_HMAC_GENERAL, { 256, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA512_HMAC, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA512_HMAC_GENERAL, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, + /* --------------------- Secret Key Operations ------------------------ */ +- { CKM_GENERIC_SECRET_KEY_GEN, { 8, 256, CKF_GEN }, 1, SFTKFIPSNone }, ++ { CKM_GENERIC_SECRET_KEY_GEN, { 112, 256, CKF_GEN }, 1, SFTKFIPSNone }, + /* ---------------------- SSL/TLS operations ------------------------- */ + { CKM_SHA224_KEY_DERIVATION, { 112, 224, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SHA256_KEY_DERIVATION, { 128, 256, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SHA384_KEY_DERIVATION, { 192, 284, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SHA512_KEY_DERIVATION, { 256, 512, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SHA256_KEY_DERIVATION, { 112, 256, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SHA384_KEY_DERIVATION, { 112, 284, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SHA512_KEY_DERIVATION, { 112, 512, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SSL3_PRE_MASTER_KEY_GEN, { 384, 384, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_TLS12_MASTER_KEY_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_TLS12_MASTER_KEY_DERIVE_DH, { DH_FB_KEY, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_TLS12_KEY_AND_MAC_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_TLS_PRF_GENERAL, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_TLS_MAC, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_TLS_PRF_GENERAL, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_TLS_MAC, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, + /* sigh, is this algorithm really tested. ssl doesn't seem to have a + * way of turning the extension off */ + { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, { 192, 1024, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH, { 192, 1024, CKF_DERIVE }, 1, SFTKFIPSNone }, + + /* ------------------------- HKDF Operations -------------------------- */ +- { CKM_HKDF_DERIVE, { 8, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_HKDF_DATA, { 8, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_HKDF_DERIVE, { 112, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_HKDF_DATA, { 112, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_HKDF_KEY_GEN, { 160, 224, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_HKDF_KEY_GEN, { 256, 512, CKF_GEN }, 128, SFTKFIPSNone }, + /* ------------------ NIST 800-108 Key Derivations ------------------- */ +- { CKM_SP800_108_COUNTER_KDF, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SP800_108_FEEDBACK_KDF, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SP800_108_DOUBLE_PIPELINE_KDF, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SP800_108_COUNTER_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SP800_108_FEEDBACK_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SP800_108_DOUBLE_PIPELINE_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, + /* --------------------IPSEC ----------------------- */ +- { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 8, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 8, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE_PRF_DERIVE, { 112, 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE1_PRF_DERIVE, { 112, 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, + /* ------------------ PBE Key Derivations ------------------- */ +- { CKM_PKCS5_PBKD2, { 1, 256, CKF_GEN }, 1, SFTKFIPSNone }, ++ { CKM_PKCS5_PBKD2, { 112, 256, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, { 224, 224, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, { 256, 256, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, { 384, 384, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, { 512, 512, CKF_GEN }, 1, SFTKFIPSNone } + }; + const int SFTK_NUMBER_FIPS_ALGORITHMS = PR_ARRAY_SIZE(sftk_fips_mechs); +diff --git a/lib/softoken/lowpbe.c b/lib/softoken/lowpbe.c +--- a/lib/softoken/lowpbe.c ++++ b/lib/softoken/lowpbe.c +@@ -1765,27 +1765,29 @@ SECStatus + sftk_fips_pbkdf_PowerUpSelfTests(void) + { + SECItem *result; + SECItem inKey; + NSSPKCS5PBEParameter pbe_params; + unsigned char iteration_count = 5; + unsigned char keyLen = 64; + char *inKeyData = TEST_KEY; +- static const unsigned char saltData[] = +- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; ++ static const unsigned char saltData[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f ++ }; + static const unsigned char pbkdf_known_answer[] = { +- 0x31, 0xf0, 0xe5, 0x39, 0x9f, 0x39, 0xb9, 0x29, +- 0x68, 0xac, 0xf2, 0xe9, 0x53, 0x9b, 0xb4, 0x9c, +- 0x28, 0x59, 0x8b, 0x5c, 0xd8, 0xd4, 0x02, 0x37, +- 0x18, 0x22, 0xc1, 0x92, 0xd0, 0xfa, 0x72, 0x90, +- 0x2c, 0x8d, 0x19, 0xd4, 0x56, 0xfb, 0x16, 0xfa, +- 0x8d, 0x5c, 0x06, 0x33, 0xd1, 0x5f, 0x17, 0xb1, +- 0x22, 0xd9, 0x9c, 0xaf, 0x5e, 0x3f, 0xf3, 0x66, +- 0xc6, 0x14, 0xfe, 0x83, 0xfa, 0x1a, 0x2a, 0xc5 ++ 0x73, 0x8c, 0xfa, 0x02, 0xe8, 0xdb, 0x43, 0xe4, ++ 0x99, 0xc5, 0xfd, 0xd9, 0x4d, 0x8e, 0x3e, 0x7b, ++ 0xc4, 0xda, 0x22, 0x1b, 0xe1, 0xae, 0x23, 0x7a, ++ 0x21, 0x27, 0xbd, 0xcc, 0x78, 0xc4, 0xe6, 0xc5, ++ 0x33, 0x38, 0x35, 0xe0, 0x68, 0x1a, 0x1e, 0x06, ++ 0xad, 0xaf, 0x7f, 0xd7, 0x3f, 0x0e, 0xc0, 0x90, ++ 0x17, 0x97, 0x73, 0x75, 0x7b, 0x88, 0x49, 0xd8, ++ 0x6f, 0x78, 0x5a, 0xde, 0x50, 0x20, 0x55, 0x33 + }; + + sftk_PBELockInit(); + + inKey.data = (unsigned char *)inKeyData; + inKey.len = sizeof(TEST_KEY) - 1; + + pbe_params.salt.data = (unsigned char *)saltData; +diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c +--- a/lib/softoken/pkcs11c.c ++++ b/lib/softoken/pkcs11c.c +@@ -4609,16 +4609,17 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi + goto loser; + } + + /* make sure we don't have any class, key_type, or value fields */ + sftk_DeleteAttributeType(key, CKA_CLASS); + sftk_DeleteAttributeType(key, CKA_KEY_TYPE); + sftk_DeleteAttributeType(key, CKA_VALUE); + ++ + /* Now Set up the parameters to generate the key (based on mechanism) */ + key_gen_type = nsc_bulk; /* bulk key by default */ + switch (pMechanism->mechanism) { + case CKM_CDMF_KEY_GEN: + case CKM_DES_KEY_GEN: + case CKM_DES2_KEY_GEN: + case CKM_DES3_KEY_GEN: + checkWeak = PR_TRUE; +@@ -4812,16 +4813,19 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi + crv = sftk_handleObject(key, session); + sftk_FreeSession(session); + if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) { + crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL)); + } + if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) { + crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL)); + } ++ /* we need to do this check at the end, so we can check the generated key length against ++ * fips requirements */ ++ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key); + if (crv == CKR_OK) { + *phKey = key->handle; + } + loser: + PORT_Memset(buf, 0, sizeof buf); + sftk_FreeObject(key); + return crv; + } +@@ -5780,16 +5784,19 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS + + if (crv != CKR_OK) { + NSC_DestroyObject(hSession, publicKey->handle); + sftk_FreeObject(publicKey); + NSC_DestroyObject(hSession, privateKey->handle); + sftk_FreeObject(privateKey); + return crv; + } ++ /* we need to do this check at the end to make sure the generated key meets the key length requirements */ ++ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey); ++ publicKey->isFIPS = privateKey->isFIPS; + + *phPrivateKey = privateKey->handle; + *phPublicKey = publicKey->handle; + sftk_FreeObject(publicKey); + sftk_FreeObject(privateKey); + + return CKR_OK; + } +@@ -6990,16 +6997,17 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_ + } + + /* HKDF-Extract(salt, base key value) */ + if (params->bExtract) { + CK_BYTE *salt; + CK_ULONG saltLen; + HMACContext *hmac; + unsigned int bufLen; ++ SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT; + + switch (params->ulSaltType) { + case CKF_HKDF_SALT_NULL: + saltLen = hashLen; + salt = hashbuf; + memset(salt, 0, saltLen); + break; + case CKF_HKDF_SALT_DATA: +@@ -7026,29 +7034,54 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_ + if (isFIPS && (key->isFIPS == 0) && (saltKey->isFIPS == 1)) { + CK_MECHANISM mech; + mech.mechanism = CKM_HKDF_DERIVE; + mech.pParameter = params; + mech.ulParameterLen = sizeof(*params); + key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech, + CKA_DERIVE, saltKey); + } ++ saltKeySource = saltKey->source; + saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE); + if (saltKey_att == NULL) { + sftk_FreeObject(saltKey); + return CKR_KEY_HANDLE_INVALID; + } + /* save the resulting salt */ + salt = saltKey_att->attrib.pValue; + saltLen = saltKey_att->attrib.ulValueLen; + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + break; + } ++ /* only TLS style usage is FIPS approved, ++ * turn off the FIPS indicator for other usages */ ++ if (isFIPS && key && sourceKey) { ++ PRBool fipsOK = PR_FALSE; ++ /* case one: mix the kea with a previous or default ++ * salt */ ++ if ((sourceKey->source == SFTK_SOURCE_KEA) && ++ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) && ++ (saltLen == rawHash->length)) { ++ fipsOK = PR_TRUE; ++ } ++ /* case two: restart, remix the previous secret as a salt */ ++ if ((sourceKey->objclass == CKO_DATA) && ++ (NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) && ++ (sourceKeyLen == rawHash->length) && ++ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) && ++ (saltLen == rawHash->length)) { ++ fipsOK = PR_TRUE; ++ } ++ if (!fipsOK) { ++ key->isFIPS = PR_FALSE; ++ } ++ } ++ if (key) key->source = SFTK_SOURCE_HKDF_EXTRACT; + + hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS); + if (saltKey_att) { + sftk_FreeAttribute(saltKey_att); + } + if (saltKey) { + sftk_FreeObject(saltKey); + } +@@ -7076,16 +7109,40 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_ + /* T(1) = HMAC-Hash(prk, "" | info | 0x01) + * T(n) = HMAC-Hash(prk, T(n-1) | info | n + * key material = T(1) | ... | T(n) + */ + HMACContext *hmac; + CK_BYTE bi; + unsigned iterations; + ++ /* only TLS style usage is FIPS approved, ++ * turn off the FIPS indicator for other usages */ ++ if (isFIPS && key && key->isFIPS && sourceKey) { ++ unsigned char *info=¶ms->pInfo[3]; ++ /* only one case, ++ * 1) Expand only ++ * 2) with a key whose source was ++ * SFTK_SOURCE_HKDF_EXPAND or SFTK_SOURCE_HKDF_EXTRACT ++ * 3) source key length == rawHash->length ++ * 4) Info has tls or dtls ++ * If any of those conditions aren't met, then we turn ++ * off the fips indicator */ ++ if (params->bExtract || ++ ((sourceKey->source != SFTK_SOURCE_HKDF_EXTRACT) && ++ (sourceKey->source != SFTK_SOURCE_HKDF_EXPAND)) || ++ (sourceKeyLen != rawHash->length) || ++ (params->ulInfoLen < 7) || ++ ((PORT_Memcmp(info,"tls",3) != 0) && ++ (PORT_Memcmp(info,"dtls",4) != 0))) { ++ key->isFIPS = PR_FALSE; ++ } ++ } ++ if (key) key->source = SFTK_SOURCE_HKDF_EXPAND; ++ + genLen = PR_ROUNDUP(keySize, hashLen); + iterations = genLen / hashLen; + + if (genLen > sizeof(keyBlock)) { + keyBlockAlloc = PORT_Alloc(genLen); + if (keyBlockAlloc == NULL) { + return CKR_HOST_MEMORY; + } +@@ -8434,16 +8491,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + + /* calculate private value - oct */ + rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); + + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); + SECITEM_ZfreeItem(&dhValue, PR_FALSE); + + if (rv == SECSuccess) { ++ key->source = SFTK_SOURCE_KEA; + sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len); + SECITEM_ZfreeItem(&derived, PR_FALSE); + crv = CKR_OK; + } else + crv = CKR_HOST_MEMORY; + + break; + } +@@ -8564,16 +8622,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + } + PORT_Memcpy(&keyData[keySize - secretlen], secret, secretlen); + secret = keyData; + } else { + secret += (secretlen - keySize); + } + secretlen = keySize; + } ++ key->source = SFTK_SOURCE_KEA; + + sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); + PORT_ZFree(tmp.data, tmp.len); + if (keyData) { + PORT_ZFree(keyData, keySize); + } + break; + +diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h +--- a/lib/softoken/pkcs11i.h ++++ b/lib/softoken/pkcs11i.h +@@ -147,16 +147,26 @@ typedef enum { + */ + typedef enum { + SFTK_DestroyFailure, + SFTK_Destroyed, + SFTK_Busy + } SFTKFreeStatus; + + /* ++ * Source of various objects ++ */ ++typedef enum { ++ SFTK_SOURCE_DEFAULT=0, ++ SFTK_SOURCE_KEA, ++ SFTK_SOURCE_HKDF_EXPAND, ++ SFTK_SOURCE_HKDF_EXTRACT ++} SFTKSource; ++ ++/* + * attribute values of an object. + */ + struct SFTKAttributeStr { + SFTKAttribute *next; + SFTKAttribute *prev; + PRBool freeAttr; + PRBool freeData; + /*must be called handle to make sftkqueue_find work */ +@@ -189,16 +199,17 @@ struct SFTKObjectStr { + CK_OBJECT_CLASS objclass; + CK_OBJECT_HANDLE handle; + int refCount; + PZLock *refLock; + SFTKSlot *slot; + void *objectInfo; + SFTKFree infoFree; + PRBool isFIPS; ++ SFTKSource source; + }; + + struct SFTKTokenObjectStr { + SFTKObject obj; + SECItem dbKey; + }; + + struct SFTKSessionObjectStr { +diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c +--- a/lib/softoken/pkcs11u.c ++++ b/lib/softoken/pkcs11u.c +@@ -1090,16 +1090,17 @@ sftk_NewObject(SFTKSlot *slot) + sessObject->attrList[i].freeData = PR_FALSE; + } + sessObject->optimizeSpace = slot->optimizeSpace; + + object->handle = 0; + object->next = object->prev = NULL; + object->slot = slot; + object->isFIPS = sftk_isFIPS(slot->slotID); ++ object->source = SFTK_SOURCE_DEFAULT; + + object->refCount = 1; + sessObject->sessionList.next = NULL; + sessObject->sessionList.prev = NULL; + sessObject->sessionList.parent = object; + sessObject->session = NULL; + sessObject->wasDerived = PR_FALSE; + if (!hasLocks) +@@ -1674,16 +1675,17 @@ fail: + CK_RV + sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject) + { + SFTKAttribute *attribute; + SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject); + unsigned int i; + + destObject->isFIPS = srcObject->isFIPS; ++ destObject->source = srcObject->source; + if (src_so == NULL) { + return sftk_CopyTokenObject(destObject, srcObject); + } + + PZ_Lock(src_so->attributeLock); + for (i = 0; i < src_so->hashSize; i++) { + attribute = src_so->head[i]; + do { +@@ -2059,16 +2061,17 @@ sftk_NewTokenObject(SFTKSlot *slot, SECI + /* every object must have a class, if we can't get it, the object + * doesn't exist */ + crv = handleToClass(slot, handle, &object->objclass); + if (crv != CKR_OK) { + goto loser; + } + object->slot = slot; + object->isFIPS = sftk_isFIPS(slot->slotID); ++ object->source = SFTK_SOURCE_DEFAULT; + object->objectInfo = NULL; + object->infoFree = NULL; + if (!hasLocks) { + object->refLock = PZ_NewLock(nssILockRefLock); + } + if (object->refLock == NULL) { + goto loser; + } +@@ -2225,16 +2228,25 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE + break; + case CKA_DERIVE: + flags = CKF_DERIVE; + break; + /* fake attribute to select digesting */ + case CKA_DIGEST: + flags = CKF_DIGEST; + break; ++ /* fake attribute to select key gen */ ++ case CKA_NSS_GENERATE: ++ flags = CKF_GENERATE; ++ break; ++ /* fake attribute to select key pair gen */ ++ case CKA_NSS_GENERATE_KEY_PAIR: ++ flags = CKF_GENERATE_KEY_PAIR; ++ break; ++ /* fake attributes to to handle MESSAGE* flags */ + case CKA_NSS_MESSAGE | CKA_ENCRYPT: + flags = CKF_MESSAGE_ENCRYPT; + break; + case CKA_NSS_MESSAGE | CKA_DECRYPT: + flags = CKF_MESSAGE_DECRYPT; + break; + case CKA_NSS_MESSAGE | CKA_SIGN: + flags = CKF_MESSAGE_SIGN; +@@ -2278,17 +2290,17 @@ sftk_quickGetECCCurveOid(SFTKObject *sou + } + + /* This function currently only returns valid lengths for + * FIPS approved ECC curves. If we want to make this generic + * in the future, that Curve determination can be done in + * the sftk_handleSpecial. Since it's currently only used + * in FIPS indicators, it's currently only compiled with + * the FIPS indicator code */ +-static int ++static CK_ULONG + sftk_getKeyLength(SFTKObject *source) + { + CK_KEY_TYPE keyType = CK_INVALID_HANDLE; + CK_ATTRIBUTE_TYPE keyAttribute; + CK_ULONG keyLength = 0; + SFTKAttribute *attribute; + CK_RV crv; + +diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h +--- a/lib/util/pkcs11n.h ++++ b/lib/util/pkcs11n.h +@@ -58,16 +58,18 @@ + /* + * NSS-defined certificate types + * + */ + #define CKC_NSS (CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS) + + /* FAKE PKCS #11 defines */ + #define CKA_DIGEST 0x81000000L ++#define CKA_NSS_GENERATE 0x81000001L ++#define CKA_NSS_GENERATE_KEY_PAIR 0x81000002L + #define CKA_NSS_MESSAGE 0x82000000L + #define CKA_NSS_MESSAGE_MASK 0xff000000L + #define CKA_FLAGS_ONLY 0 /* CKA_CLASS */ + + /* + * NSS-defined object attributes + * + */ diff --git a/SOURCES/nss-3.79-fix-client-cert-crash.patch b/SOURCES/nss-3.79-fix-client-cert-crash.patch new file mode 100644 index 0000000..2d752e4 --- /dev/null +++ b/SOURCES/nss-3.79-fix-client-cert-crash.patch @@ -0,0 +1,23 @@ +diff --git a/lib/ssl/authcert.c b/lib/ssl/authcert.c +--- a/lib/ssl/authcert.c ++++ b/lib/ssl/authcert.c +@@ -201,16 +201,19 @@ NSS_GetClientAuthData(void *arg, + + /* otherwise look through the cache based on usage + * if chosenNickname is set, we ignore the expiration date */ + if (certList == NULL) { + certList = CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), + certUsageSSLClient, + PR_FALSE, chosenNickName == NULL, + pw_arg); ++ if (certList == NULL) { ++ return SECFailure; ++ } + /* filter only the certs that meet the nickname requirements */ + if (chosenNickName) { + rv = CERT_FilterCertListByNickname(certList, chosenNickName, + pw_arg); + } else { + int nnames = 0; + char **names = ssl_DistNamesToStrings(caNames, &nnames); + rv = CERT_FilterCertListByCANames(certList, nnames, names, diff --git a/SOURCES/nss-3.79-increase-pbe-cache.patch b/SOURCES/nss-3.79-increase-pbe-cache.patch new file mode 100644 index 0000000..e175766 --- /dev/null +++ b/SOURCES/nss-3.79-increase-pbe-cache.patch @@ -0,0 +1,22 @@ +diff --git a/lib/softoken/lowpbe.c b/lib/softoken/lowpbe.c +--- a/lib/softoken/lowpbe.c ++++ b/lib/softoken/lowpbe.c +@@ -565,17 +565,17 @@ struct KDFCacheItemStr { + int iterations; + int keyLen; + }; + typedef struct KDFCacheItemStr KDFCacheItem; + + /* Bug 1606992 - Cache the hash result for the common case that we're + * asked to repeatedly compute the key for the same password item, + * hash, iterations and salt. */ +-#define KDF2_CACHE_COUNT 3 ++#define KDF2_CACHE_COUNT 150 + static struct { + PZLock *lock; + struct { + KDFCacheItem common; + int ivLen; + PRBool faulty3DES; + } cacheKDF1; + struct { diff --git a/SOURCES/nss-3.79-pkcs12-fips-defaults.patch b/SOURCES/nss-3.79-pkcs12-fips-defaults.patch new file mode 100644 index 0000000..fd8cb4d --- /dev/null +++ b/SOURCES/nss-3.79-pkcs12-fips-defaults.patch @@ -0,0 +1,25 @@ +diff -up ./cmd/pk12util/pk12util.c.pkcs12_fips_defaults ./cmd/pk12util/pk12util.c +--- ./cmd/pk12util/pk12util.c.pkcs12_fips_defaults 2022-07-20 13:40:24.152212683 -0700 ++++ ./cmd/pk12util/pk12util.c 2022-07-20 13:42:40.031094190 -0700 +@@ -1146,6 +1146,11 @@ main(int argc, char **argv) + goto done; + } + ++ if (PK11_IsFIPS()) { ++ cipher = SEC_OID_AES_256_CBC; ++ certCipher = SEC_OID_AES_128_CBC; ++ } ++ + if (pk12util.options[opt_Cipher].activated) { + char *cipherString = pk12util.options[opt_Cipher].arg; + +@@ -1160,9 +1165,6 @@ main(int argc, char **argv) + } + } + +- if (PK11_IsFIPS()) { +- certCipher = SEC_OID_UNKNOWN; +- } + if (pk12util.options[opt_CertCipher].activated) { + char *cipherString = pk12util.options[opt_CertCipher].arg; + diff --git a/SOURCES/nss-3.79-pkcs12-fix-null-password.patch b/SOURCES/nss-3.79-pkcs12-fix-null-password.patch new file mode 100644 index 0000000..1195e5c --- /dev/null +++ b/SOURCES/nss-3.79-pkcs12-fix-null-password.patch @@ -0,0 +1,21 @@ +diff -up ./lib/pkcs12/p12local.c.fix_null_password ./lib/pkcs12/p12local.c +--- ./lib/pkcs12/p12local.c.fix_null_password 2022-07-20 14:15:45.081009438 -0700 ++++ ./lib/pkcs12/p12local.c 2022-07-20 14:19:40.856546963 -0700 +@@ -968,15 +968,14 @@ sec_pkcs12_convert_item_to_unicode(PLAre + if (zeroTerm) { + /* unicode adds two nulls at the end */ + if (toUnicode) { +- if ((dest->len >= 2) && +- (dest->data[dest->len - 1] || dest->data[dest->len - 2])) { ++ if ((dest->len < 2) || dest->data[dest->len - 1] || dest->data[dest->len - 2]) { + /* we've already allocated space for these new NULLs */ + PORT_Assert(dest->len + 2 <= bufferSize); + dest->len += 2; + dest->data[dest->len - 1] = dest->data[dest->len - 2] = 0; + } + /* ascii/utf-8 adds just 1 */ +- } else if ((dest->len >= 1) && dest->data[dest->len - 1]) { ++ } else if (!dest->len || dest->data[dest->len - 1]) { + PORT_Assert(dest->len + 1 <= bufferSize); + dest->len++; + dest->data[dest->len - 1] = 0; diff --git a/SOURCES/nss-3.79-revert-distrusted-certs.patch b/SOURCES/nss-3.79-revert-distrusted-certs.patch new file mode 100644 index 0000000..8a607a3 --- /dev/null +++ b/SOURCES/nss-3.79-revert-distrusted-certs.patch @@ -0,0 +1,335 @@ +diff -up ./lib/ckfw/builtins/certdata.txt.revert-distrusted ./lib/ckfw/builtins/certdata.txt +--- ./lib/ckfw/builtins/certdata.txt.revert-distrusted 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/ckfw/builtins/certdata.txt 2022-06-24 10:51:32.035207662 -0700 +@@ -7668,6 +7668,187 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_ + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + + # ++# Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2" ++# ++# Issuer: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL ++# Serial Number: 268435455 (0xfffffff) ++# Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL ++# Not Valid Before: Wed May 12 08:51:39 2010 ++# Not Valid After : Mon Mar 23 09:50:05 2020 ++# Fingerprint (MD5): 2E:61:A2:D1:78:CE:EE:BF:59:33:B0:23:14:0F:94:1C ++# Fingerprint (SHA1): D5:F2:57:A9:BF:2D:D0:3F:8B:46:57:F9:2B:C9:A4:C6:92:E1:42:42 ++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 "Explicitly Distrusted DigiNotar PKIoverheid G2" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157 ++\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004 ++\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111 ++\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141 ++\156\151\163\141\164\151\145\040\055\040\107\062 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157 ++\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004 ++\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111 ++\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141 ++\156\151\163\141\164\151\145\040\055\040\107\062 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\017\377\377\377 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\006\225\060\202\004\175\240\003\002\001\002\002\004\017 ++\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\013 ++\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116 ++\114\061\027\060\025\006\003\125\004\012\014\016\104\151\147\151 ++\116\157\164\141\162\040\102\056\126\056\061\062\060\060\006\003 ++\125\004\003\014\051\104\151\147\151\116\157\164\141\162\040\120 ++\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117\162 ++\147\141\156\151\163\141\164\151\145\040\055\040\107\062\060\036 ++\027\015\061\060\060\065\061\062\060\070\065\061\063\071\132\027 ++\015\062\060\060\063\062\063\060\071\065\060\060\065\132\060\132 ++\061\013\060\011\006\003\125\004\006\023\002\116\114\061\027\060 ++\025\006\003\125\004\012\014\016\104\151\147\151\116\157\164\141 ++\162\040\102\056\126\056\061\062\060\060\006\003\125\004\003\014 ++\051\104\151\147\151\116\157\164\141\162\040\120\113\111\157\166 ++\145\162\150\145\151\144\040\103\101\040\117\162\147\141\156\151 ++\163\141\164\151\145\040\055\040\107\062\060\202\002\042\060\015 ++\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 ++\017\000\060\202\002\012\002\202\002\001\000\261\023\031\017\047 ++\346\154\324\125\206\113\320\354\211\212\105\221\170\254\107\275 ++\107\053\344\374\105\353\117\264\046\163\133\067\323\303\177\366 ++\343\336\327\243\370\055\150\305\010\076\113\224\326\344\207\045 ++\066\153\204\265\030\164\363\050\130\163\057\233\152\317\274\004 ++\036\366\336\335\257\374\113\252\365\333\146\142\045\001\045\202 ++\336\362\227\132\020\156\335\135\251\042\261\004\251\043\163\072 ++\370\161\255\035\317\204\104\353\107\321\257\155\310\174\050\253 ++\307\362\067\172\164\137\137\305\002\024\212\243\132\343\033\154 ++\001\343\135\216\331\150\326\364\011\033\062\334\221\265\054\365 ++\040\353\214\003\155\046\111\270\223\304\205\135\330\322\233\257 ++\126\152\314\005\063\314\240\102\236\064\125\104\234\153\240\324 ++\022\320\053\124\315\267\211\015\345\366\353\350\373\205\001\063 ++\117\172\153\361\235\162\063\226\016\367\262\204\245\245\047\304 ++\047\361\121\163\051\167\272\147\156\376\114\334\264\342\241\241 ++\201\057\071\111\215\103\070\023\316\320\245\134\302\207\072\000 ++\147\145\102\043\361\066\131\012\035\243\121\310\274\243\224\052 ++\061\337\343\074\362\235\032\074\004\260\357\261\012\060\023\163 ++\266\327\363\243\114\001\165\024\205\170\300\327\212\071\130\205 ++\120\372\056\346\305\276\317\213\077\257\217\066\324\045\011\055 ++\322\017\254\162\223\362\277\213\324\120\263\371\025\120\233\231 ++\365\024\331\373\213\221\243\062\046\046\240\370\337\073\140\201 ++\206\203\171\133\053\353\023\075\051\072\301\155\335\275\236\216 ++\207\326\112\256\064\227\005\356\024\246\366\334\070\176\112\351 ++\044\124\007\075\227\150\067\106\153\015\307\250\041\257\023\124 ++\344\011\152\361\115\106\012\311\135\373\233\117\275\336\373\267 ++\124\313\270\070\234\247\071\373\152\055\300\173\215\253\245\247 ++\127\354\112\222\212\063\305\341\040\134\163\330\220\222\053\200 ++\325\017\206\030\151\174\071\117\204\206\274\367\114\133\363\325 ++\264\312\240\302\360\067\042\312\171\122\037\123\346\252\363\220 ++\260\073\335\362\050\375\254\353\305\006\044\240\311\324\057\017 ++\130\375\265\236\354\017\317\262\131\320\242\004\172\070\152\256 ++\162\373\275\360\045\142\224\011\247\005\013\002\003\001\000\001 ++\243\202\001\141\060\202\001\135\060\110\006\003\125\035\040\004 ++\101\060\077\060\075\006\004\125\035\040\000\060\065\060\063\006 ++\010\053\006\001\005\005\007\002\001\026\047\150\164\164\160\072 ++\057\057\167\167\167\056\144\151\147\151\156\157\164\141\162\056 ++\156\154\057\143\160\163\057\160\153\151\157\166\145\162\150\145 ++\151\144\060\017\006\003\125\035\023\001\001\377\004\005\060\003 ++\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003 ++\002\001\006\060\201\205\006\003\125\035\043\004\176\060\174\200 ++\024\071\020\213\111\222\134\333\141\022\040\315\111\235\032\216 ++\332\234\147\100\271\241\136\244\134\060\132\061\013\060\011\006 ++\003\125\004\006\023\002\116\114\061\036\060\034\006\003\125\004 ++\012\014\025\123\164\141\141\164\040\144\145\162\040\116\145\144 ++\145\162\154\141\156\144\145\156\061\053\060\051\006\003\125\004 ++\003\014\042\123\164\141\141\164\040\144\145\162\040\116\145\144 ++\145\162\154\141\156\144\145\156\040\122\157\157\164\040\103\101 ++\040\055\040\107\062\202\004\000\230\226\364\060\111\006\003\125 ++\035\037\004\102\060\100\060\076\240\074\240\072\206\070\150\164 ++\164\160\072\057\057\143\162\154\056\160\153\151\157\166\145\162 ++\150\145\151\144\056\156\154\057\104\157\155\117\162\147\141\156 ++\151\163\141\164\151\145\114\141\164\145\163\164\103\122\114\055 ++\107\062\056\143\162\154\060\035\006\003\125\035\016\004\026\004 ++\024\274\135\224\073\331\253\173\003\045\163\141\302\333\055\356 ++\374\253\217\145\241\060\015\006\011\052\206\110\206\367\015\001 ++\001\013\005\000\003\202\002\001\000\217\374\055\114\267\331\055 ++\325\037\275\357\313\364\267\150\027\165\235\116\325\367\335\234 ++\361\052\046\355\237\242\266\034\003\325\123\263\354\010\317\064 ++\342\343\303\364\265\026\057\310\303\276\327\323\163\253\000\066 ++\371\032\112\176\326\143\351\136\106\272\245\266\216\025\267\243 ++\052\330\103\035\357\135\310\037\201\205\263\213\367\377\074\364 ++\331\364\106\010\077\234\274\035\240\331\250\114\315\045\122\116 ++\012\261\040\367\037\351\103\331\124\106\201\023\232\300\136\164 ++\154\052\230\062\352\374\167\273\015\245\242\061\230\042\176\174 ++\174\347\332\244\255\354\267\056\032\031\161\370\110\120\332\103 ++\217\054\204\335\301\100\047\343\265\360\025\116\226\324\370\134 ++\343\206\051\106\053\327\073\007\353\070\177\310\206\127\227\323 ++\357\052\063\304\027\120\325\144\151\153\053\153\105\136\135\057 ++\027\312\132\116\317\303\327\071\074\365\073\237\106\271\233\347 ++\016\111\227\235\326\325\343\033\017\352\217\001\116\232\023\224 ++\131\012\002\007\110\113\032\140\253\177\117\355\013\330\125\015 ++\150\157\125\234\151\145\025\102\354\300\334\335\154\254\303\026 ++\316\013\035\126\233\244\304\304\322\056\340\017\342\104\047\053 ++\120\151\244\334\142\350\212\041\051\102\154\314\000\072\226\166 ++\233\357\100\300\244\136\167\204\062\154\046\052\071\146\256\135 ++\343\271\271\262\054\150\037\036\232\220\003\071\360\252\263\244 ++\314\111\213\030\064\351\067\311\173\051\307\204\174\157\104\025 ++\057\354\141\131\004\311\105\313\242\326\122\242\174\177\051\222 ++\326\112\305\213\102\250\324\376\352\330\307\207\043\030\344\235 ++\172\175\163\100\122\230\240\256\156\343\005\077\005\017\340\245 ++\306\155\115\355\203\067\210\234\307\363\334\102\232\152\266\327 ++\041\111\066\167\362\357\030\117\305\160\331\236\351\336\267\053 ++\213\364\274\176\050\337\015\100\311\205\134\256\235\305\061\377 ++\320\134\016\265\250\176\360\351\057\272\257\210\256\345\265\321 ++\130\245\257\234\161\247\051\001\220\203\151\067\202\005\272\374 ++\011\301\010\156\214\170\073\303\063\002\200\077\104\205\010\035 ++\337\125\126\010\255\054\205\055\135\261\003\341\256\252\164\305 ++\244\363\116\272\067\230\173\202\271 ++END ++ ++# Trust for Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2" ++# Issuer: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL ++# Serial Number: 268435455 (0xfffffff) ++# Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL ++# Not Valid Before: Wed May 12 08:51:39 2010 ++# Not Valid After : Mon Mar 23 09:50:05 2020 ++# Fingerprint (MD5): 2E:61:A2:D1:78:CE:EE:BF:59:33:B0:23:14:0F:94:1C ++# Fingerprint (SHA1): D5:F2:57:A9:BF:2D:D0:3F:8B:46:57:F9:2B:C9:A4:C6:92:E1:42:42 ++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 "Explicitly Distrusted DigiNotar PKIoverheid G2" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\325\362\127\251\277\055\320\077\213\106\127\371\053\311\244\306 ++\222\341\102\102 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\056\141\242\321\170\316\356\277\131\063\260\043\024\017\224\034 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157 ++\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004 ++\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111 ++\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141 ++\156\151\163\141\164\151\145\040\055\040\107\062 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\017\377\377\377 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# + # Certificate "Security Communication RootCA2" + # + # Issuer: OU=Security Communication RootCA2,O="SECOM Trust Systems CO.,LTD.",C=JP +@@ -8161,6 +8342,68 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_ + CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + ++# Explicitly Distrust "MITM subCA 1 issued by Trustwave", Bug 724929 ++# Issuer: E=ca@trustwave.com,CN="Trustwave Organization Issuing CA, Level 2",O="Trustwave Holdings, Inc.",L=Chicago,ST=Illinois,C=US ++# Serial Number: 1800000005 (0x6b49d205) ++# Not Before: Apr 7 15:37:15 2011 GMT ++# Not After : Apr 4 15:37:15 2021 GMT ++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 "MITM subCA 1 issued by Trustwave" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\253\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\021\060\017\006\003\125\004\010\023\010\111\154\154\151\156 ++\157\151\163\061\020\060\016\006\003\125\004\007\023\007\103\150 ++\151\143\141\147\157\061\041\060\037\006\003\125\004\012\023\030 ++\124\162\165\163\164\167\141\166\145\040\110\157\154\144\151\156 ++\147\163\054\040\111\156\143\056\061\063\060\061\006\003\125\004 ++\003\023\052\124\162\165\163\164\167\141\166\145\040\117\162\147 ++\141\156\151\172\141\164\151\157\156\040\111\163\163\165\151\156 ++\147\040\103\101\054\040\114\145\166\145\154\040\062\061\037\060 ++\035\006\011\052\206\110\206\367\015\001\011\001\026\020\143\141 ++\100\164\162\165\163\164\167\141\166\145\056\143\157\155 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\153\111\322\005 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# Explicitly Distrust "MITM subCA 2 issued by Trustwave", Bug 724929 ++# Issuer: E=ca@trustwave.com,CN="Trustwave Organization Issuing CA, Level 2",O="Trustwave Holdings, Inc.",L=Chicago,ST=Illinois,C=US ++# Serial Number: 1800000006 (0x6b49d206) ++# Not Before: Apr 18 21:09:30 2011 GMT ++# Not After : Apr 15 21:09:30 2021 GMT ++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 "MITM subCA 2 issued by Trustwave" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\253\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\021\060\017\006\003\125\004\010\023\010\111\154\154\151\156 ++\157\151\163\061\020\060\016\006\003\125\004\007\023\007\103\150 ++\151\143\141\147\157\061\041\060\037\006\003\125\004\012\023\030 ++\124\162\165\163\164\167\141\166\145\040\110\157\154\144\151\156 ++\147\163\054\040\111\156\143\056\061\063\060\061\006\003\125\004 ++\003\023\052\124\162\165\163\164\167\141\166\145\040\117\162\147 ++\141\156\151\172\141\164\151\157\156\040\111\163\163\165\151\156 ++\147\040\103\101\054\040\114\145\166\145\154\040\062\061\037\060 ++\035\006\011\052\206\110\206\367\015\001\011\001\026\020\143\141 ++\100\164\162\165\163\164\167\141\166\145\056\143\157\155 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\153\111\322\006 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ + # + # Certificate "Actalis Authentication Root CA" + # +@@ -8804,6 +9047,74 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_ + CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + ++# Explicitly Distrust "TURKTRUST Mis-issued Intermediate CA 1", Bug 825022 ++# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,C=TR,CN=T..RKTRUST Elektronik Sunucu Sertifikas.. Hizmetleri ++# Serial Number: 2087 (0x827) ++# Subject: CN=*.EGO.GOV.TR,OU=EGO BILGI ISLEM,O=EGO,L=ANKARA,ST=ANKARA,C=TR ++# Not Valid Before: Mon Aug 08 07:07:51 2011 ++# Not Valid After : Tue Jul 06 07:07:51 2021 ++# Fingerprint (MD5): F8:F5:25:FF:0C:31:CF:85:E1:0C:86:17:C1:CE:1F:8E ++# Fingerprint (SHA1): C6:9F:28:C8:25:13:9E:65:A6:46:C4:34:AC:A5:A1:D2:00:29:5D:B1 ++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 "TURKTRUST Mis-issued Intermediate CA 1" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\254\061\075\060\073\006\003\125\004\003\014\064\124\303 ++\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157 ++\156\151\153\040\123\165\156\165\143\165\040\123\145\162\164\151 ++\146\151\153\141\163\304\261\040\110\151\172\155\145\164\154\145 ++\162\151\061\013\060\011\006\003\125\004\006\023\002\124\122\061 ++\136\060\134\006\003\125\004\012\014\125\124\303\234\122\113\124 ++\122\125\123\124\040\102\151\154\147\151\040\304\260\154\145\164 ++\151\305\237\151\155\040\166\145\040\102\151\154\151\305\237\151 ++\155\040\107\303\274\166\145\156\154\151\304\237\151\040\110\151 ++\172\155\145\164\154\145\162\151\040\101\056\305\236\056\040\050 ++\143\051\040\113\141\163\304\261\155\040\040\062\060\060\065 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\002\010\047 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# Explicitly Distrust "TURKTRUST Mis-issued Intermediate CA 2", Bug 825022 ++# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,C=TR,CN=T..RKTRUST Elektronik Sunucu Sertifikas.. Hizmetleri ++# Serial Number: 2148 (0x864) ++# Subject: E=ileti@kktcmerkezbankasi.org,CN=e-islem.kktcmerkezbankasi.org,O=KKTC Merkez Bankasi,L=Lefkosa,ST=Lefkosa,C=TR ++# Not Valid Before: Mon Aug 08 07:07:51 2011 ++# Not Valid After : Thu Aug 05 07:07:51 2021 ++# Fingerprint (MD5): BF:C3:EC:AD:0F:42:4F:B4:B5:38:DB:35:BF:AD:84:A2 ++# Fingerprint (SHA1): F9:2B:E5:26:6C:C0:5D:B2:DC:0D:C3:F2:DC:74:E0:2D:EF:D9:49:CB ++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 "TURKTRUST Mis-issued Intermediate CA 2" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\254\061\075\060\073\006\003\125\004\003\014\064\124\303 ++\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157 ++\156\151\153\040\123\165\156\165\143\165\040\123\145\162\164\151 ++\146\151\153\141\163\304\261\040\110\151\172\155\145\164\154\145 ++\162\151\061\013\060\011\006\003\125\004\006\023\002\124\122\061 ++\136\060\134\006\003\125\004\012\014\125\124\303\234\122\113\124 ++\122\125\123\124\040\102\151\154\147\151\040\304\260\154\145\164 ++\151\305\237\151\155\040\166\145\040\102\151\154\151\305\237\151 ++\155\040\107\303\274\166\145\156\154\151\304\237\151\040\110\151 ++\172\155\145\164\154\145\162\151\040\101\056\305\236\056\040\050 ++\143\051\040\113\141\163\304\261\155\040\040\062\060\060\065 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\002\010\144 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ + # + # Certificate "D-TRUST Root Class 3 CA 2 2009" + # diff --git a/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch b/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch new file mode 100644 index 0000000..f2692c0 --- /dev/null +++ b/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch @@ -0,0 +1,685 @@ +diff -up ./cmd/crmftest/testcrmf.c.sign_policy ./cmd/crmftest/testcrmf.c +--- ./cmd/crmftest/testcrmf.c.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./cmd/crmftest/testcrmf.c 2022-06-20 16:47:35.023785628 -0700 +@@ -85,7 +85,7 @@ + #include "sechash.h" + #endif + +-#define MAX_KEY_LEN 512 ++#define MAX_KEY_LEN 1024 + #define PATH_LEN 150 + #define BUFF_SIZE 150 + #define UID_BITS 800 +diff -up ./gtests/pk11_gtest/pk11_rsapkcs1_unittest.cc.sign_policy ./gtests/pk11_gtest/pk11_rsapkcs1_unittest.cc +--- ./gtests/pk11_gtest/pk11_rsapkcs1_unittest.cc.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./gtests/pk11_gtest/pk11_rsapkcs1_unittest.cc 2022-06-20 16:47:35.024785635 -0700 +@@ -16,6 +16,7 @@ + #include "secerr.h" + #include "sechash.h" + #include "pk11_signature_test.h" ++#include "blapit.h" + + #include "testvectors/rsa_signature_2048_sha224-vectors.h" + #include "testvectors/rsa_signature_2048_sha256-vectors.h" +@@ -109,7 +110,11 @@ class Pkcs11RsaPkcs1WycheproofTest + * Use 6 as the invalid value since modLen % 16 must be zero. + */ + TEST(RsaPkcs1Test, Pkcs1MinimumPadding) { +- const size_t kRsaShortKeyBits = 736; ++#define RSA_SHORT_KEY_LENGTH 736 ++/* if our minimum supported key length is big enough to handle ++ * our largest Hash function, we can't test a short length */ ++#if RSA_MIN_MODULUS_BITS < RSA_SHORT_KEY_LENGTH ++ const size_t kRsaShortKeyBits = RSA_SHORT_KEY_LENGTH; + const size_t kRsaKeyBits = 752; + static const std::vector kMsg{'T', 'E', 'S', 'T'}; + static const std::vector kSha512DigestInfo{ +@@ -209,6 +214,9 @@ TEST(RsaPkcs1Test, Pkcs1MinimumPadding) + SEC_OID_PKCS1_RSA_ENCRYPTION, SEC_OID_SHA512, + nullptr); + EXPECT_EQ(SECSuccess, rv); ++#else ++ GTEST_SKIP(); ++#endif + } + + TEST(RsaPkcs1Test, RequireNullParameter) { +diff -up ./gtests/ssl_gtest/tls_subcerts_unittest.cc.sign_policy ./gtests/ssl_gtest/tls_subcerts_unittest.cc +--- ./gtests/ssl_gtest/tls_subcerts_unittest.cc.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./gtests/ssl_gtest/tls_subcerts_unittest.cc 2022-06-20 16:47:35.024785635 -0700 +@@ -9,6 +9,8 @@ + #include "prtime.h" + #include "secerr.h" + #include "ssl.h" ++#include "nss.h" ++#include "blapit.h" + + #include "gtest_utils.h" + #include "tls_agent.h" +@@ -348,9 +350,14 @@ static void GenerateWeakRsaKey(ScopedSEC + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + ASSERT_TRUE(slot); + PK11RSAGenParams rsaparams; +- // The absolute minimum size of RSA key that we can use with SHA-256 is +- // 256bit (hash) + 256bit (salt) + 8 (start byte) + 8 (end byte) = 528. ++// The absolute minimum size of RSA key that we can use with SHA-256 is ++// 256bit (hash) + 256bit (salt) + 8 (start byte) + 8 (end byte) = 528. ++#define RSA_WEAK_KEY 528 ++#if RSA_MIN_MODULUS_BITS < RSA_WEAK_KEY + rsaparams.keySizeInBits = 528; ++#else ++ rsaparams.keySizeInBits = RSA_MIN_MODULUS_BITS + 1; ++#endif + rsaparams.pe = 65537; + + // Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient +@@ -390,6 +397,18 @@ TEST_P(TlsConnectTls13, DCWeakKey) { + ssl_sig_rsa_pss_pss_sha256}; + client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes)); + server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes)); ++#if RSA_MIN_MODULUS_BITS > RSA_WEAK_KEY ++ // save the MIN POLICY length. ++ PRInt32 minRsa; ++ ++ ASSERT_EQ(SECSuccess, NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minRsa)); ++#if RSA_MIN_MODULUS_BITS >= 2048 ++ ASSERT_EQ(SECSuccess, ++ NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, RSA_MIN_MODULUS_BITS + 1024)); ++#else ++ ASSERT_EQ(SECSuccess, NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 2048)); ++#endif ++#endif + + ScopedSECKEYPrivateKey dc_priv; + ScopedSECKEYPublicKey dc_pub; +@@ -412,6 +431,9 @@ TEST_P(TlsConnectTls13, DCWeakKey) { + auto cfilter = MakeTlsFilter( + client_, ssl_delegated_credentials_xtn); + ConnectExpectAlert(client_, kTlsAlertInsufficientSecurity); ++#if RSA_MIN_MODULUS_BITS > RSA_WEAK_KEY ++ ASSERT_EQ(SECSuccess, NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, minRsa)); ++#endif + } + + class ReplaceDCSigScheme : public TlsHandshakeFilter { +diff -up ./lib/cryptohi/keyhi.h.sign_policy ./lib/cryptohi/keyhi.h +--- ./lib/cryptohi/keyhi.h.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/cryptohi/keyhi.h 2022-06-20 16:47:35.024785635 -0700 +@@ -53,6 +53,11 @@ extern unsigned SECKEY_PublicKeyStrength + extern unsigned SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk); + + /* ++** Return the strength of the private key in bits ++*/ ++extern unsigned SECKEY_PrivateKeyStrengthInBits(const SECKEYPrivateKey *privk); ++ ++/* + ** Return the length of the signature in bytes + */ + extern unsigned SECKEY_SignatureLen(const SECKEYPublicKey *pubk); +diff -up ./lib/cryptohi/keyi.h.sign_policy ./lib/cryptohi/keyi.h +--- ./lib/cryptohi/keyi.h.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/cryptohi/keyi.h 2022-06-20 16:47:35.024785635 -0700 +@@ -4,6 +4,7 @@ + + #ifndef _KEYI_H_ + #define _KEYI_H_ ++#include "secerr.h" + + SEC_BEGIN_PROTOS + /* NSS private functions */ +@@ -36,6 +37,9 @@ SECStatus sec_DecodeRSAPSSParamsToMechan + const SECItem *params, + CK_RSA_PKCS_PSS_PARAMS *mech); + ++/* make sure the key length matches the policy for keyType */ ++SECStatus seckey_EnforceKeySize(KeyType keyType, unsigned keyLength, ++ SECErrorCodes error); + SEC_END_PROTOS + + #endif /* _KEYHI_H_ */ +diff -up ./lib/cryptohi/seckey.c.sign_policy ./lib/cryptohi/seckey.c +--- ./lib/cryptohi/seckey.c.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/cryptohi/seckey.c 2022-06-20 16:47:35.025785641 -0700 +@@ -14,6 +14,7 @@ + #include "secdig.h" + #include "prtime.h" + #include "keyi.h" ++#include "nss.h" + + SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) + SEC_ASN1_MKSUB(SEC_IntegerTemplate) +@@ -1042,6 +1043,62 @@ SECKEY_PublicKeyStrengthInBits(const SEC + return bitSize; + } + ++unsigned ++SECKEY_PrivateKeyStrengthInBits(const SECKEYPrivateKey *privk) ++{ ++ unsigned bitSize = 0; ++ CK_ATTRIBUTE_TYPE attribute = CKT_INVALID_TYPE; ++ SECItem params; ++ SECStatus rv; ++ ++ if (!privk) { ++ PORT_SetError(SEC_ERROR_INVALID_KEY); ++ return 0; ++ } ++ ++ /* interpret modulus length as key strength */ ++ switch (privk->keyType) { ++ case rsaKey: ++ case rsaPssKey: ++ case rsaOaepKey: ++ /* some tokens don't export CKA_MODULUS on the private key, ++ * PK11_SignatureLen works around this if necessary */ ++ bitSize = PK11_SignatureLen((SECKEYPrivateKey *)privk) * PR_BITS_PER_BYTE; ++ if (bitSize == -1) { ++ bitSize = 0; ++ } ++ return bitSize; ++ case dsaKey: ++ case fortezzaKey: ++ case dhKey: ++ case keaKey: ++ attribute = CKA_PRIME; ++ break; ++ case ecKey: ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, ++ CKA_EC_PARAMS, NULL, ¶ms); ++ if ((rv != SECSuccess) || (params.data == NULL)) { ++ return 0; ++ } ++ bitSize = SECKEY_ECParamsToKeySize(¶ms); ++ PORT_Free(params.data); ++ return bitSize; ++ default: ++ PORT_SetError(SEC_ERROR_INVALID_KEY); ++ return 0; ++ } ++ PORT_Assert(attribute != CKT_INVALID_TYPE); ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, ++ attribute, NULL, ¶ms); ++ if ((rv != SECSuccess) || (params.data == NULL)) { ++ PORT_SetError(SEC_ERROR_INVALID_KEY); ++ return 0; ++ } ++ bitSize = SECKEY_BigIntegerBitLength(¶ms); ++ PORT_Free(params.data); ++ return bitSize; ++} ++ + /* returns signature length in bytes (not bits) */ + unsigned + SECKEY_SignatureLen(const SECKEYPublicKey *pubk) +@@ -1212,6 +1269,51 @@ SECKEY_CopyPublicKey(const SECKEYPublicK + } + + /* ++ * Check that a given key meets the policy limits for the given key ++ * size. ++ */ ++SECStatus ++seckey_EnforceKeySize(KeyType keyType, unsigned keyLength, SECErrorCodes error) ++{ ++ PRInt32 opt = -1; ++ PRInt32 optVal; ++ SECStatus rv; ++ ++ switch (keyType) { ++ case rsaKey: ++ case rsaPssKey: ++ case rsaOaepKey: ++ opt = NSS_RSA_MIN_KEY_SIZE; ++ break; ++ case dsaKey: ++ case fortezzaKey: ++ opt = NSS_DSA_MIN_KEY_SIZE; ++ break; ++ case dhKey: ++ case keaKey: ++ opt = NSS_DH_MIN_KEY_SIZE; ++ break; ++ case ecKey: ++ opt = NSS_ECC_MIN_KEY_SIZE; ++ break; ++ case nullKey: ++ default: ++ PORT_SetError(SEC_ERROR_INVALID_KEY); ++ return SECFailure; ++ } ++ PORT_Assert(opt != -1); ++ rv = NSS_OptionGet(opt, &optVal); ++ if (rv != SECSuccess) { ++ return rv; ++ } ++ if (optVal < keyLength) { ++ PORT_SetError(error); ++ return SECFailure; ++ } ++ return SECSuccess; ++} ++ ++/* + * Use the private key to find a public key handle. The handle will be on + * the same slot as the private key. + */ +diff -up ./lib/cryptohi/secsign.c.sign_policy ./lib/cryptohi/secsign.c +--- ./lib/cryptohi/secsign.c.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/cryptohi/secsign.c 2022-06-20 16:47:35.025785641 -0700 +@@ -15,6 +15,7 @@ + #include "pk11func.h" + #include "secerr.h" + #include "keyi.h" ++#include "nss.h" + + struct SGNContextStr { + SECOidTag signalg; +@@ -32,6 +33,7 @@ sgn_NewContext(SECOidTag alg, SECItem *p + SECOidTag hashalg, signalg; + KeyType keyType; + PRUint32 policyFlags; ++ PRInt32 optFlags; + SECStatus rv; + + /* OK, map a PKCS #7 hash and encrypt algorithm into +@@ -56,6 +58,16 @@ sgn_NewContext(SECOidTag alg, SECItem *p + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } ++ if (NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optFlags) != SECFailure) { ++ if (optFlags & NSS_KEY_SIZE_POLICY_SIGN_FLAG) { ++ rv = seckey_EnforceKeySize(key->keyType, ++ SECKEY_PrivateKeyStrengthInBits(key), ++ SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); ++ if (rv != SECSuccess) { ++ return NULL; ++ } ++ } ++ } + /* check the policy on the hash algorithm */ + if ((NSS_GetAlgorithmPolicy(hashalg, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { +@@ -467,9 +479,20 @@ SGN_Digest(SECKEYPrivateKey *privKey, + SGNDigestInfo *di = 0; + SECOidTag enctag; + PRUint32 policyFlags; ++ PRInt32 optFlags; + + result->data = 0; + ++ if (NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optFlags) != SECFailure) { ++ if (optFlags & NSS_KEY_SIZE_POLICY_SIGN_FLAG) { ++ rv = seckey_EnforceKeySize(privKey->keyType, ++ SECKEY_PrivateKeyStrengthInBits(privKey), ++ SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } ++ } ++ } + /* check the policy on the hash algorithm */ + if ((NSS_GetAlgorithmPolicy(algtag, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { +diff -up ./lib/cryptohi/secvfy.c.sign_policy ./lib/cryptohi/secvfy.c +--- ./lib/cryptohi/secvfy.c.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/cryptohi/secvfy.c 2022-06-20 16:47:35.025785641 -0700 +@@ -16,6 +16,7 @@ + #include "secdig.h" + #include "secerr.h" + #include "keyi.h" ++#include "nss.h" + + /* + ** Recover the DigestInfo from an RSA PKCS#1 signature. +@@ -467,6 +468,7 @@ vfy_CreateContext(const SECKEYPublicKey + unsigned int sigLen; + KeyType type; + PRUint32 policyFlags; ++ PRInt32 optFlags; + + /* make sure the encryption algorithm matches the key type */ + /* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */ +@@ -476,7 +478,16 @@ vfy_CreateContext(const SECKEYPublicKey + PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH); + return NULL; + } +- ++ if (NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optFlags) != SECFailure) { ++ if (optFlags & NSS_KEY_SIZE_POLICY_VERIFY_FLAG) { ++ rv = seckey_EnforceKeySize(key->keyType, ++ SECKEY_PublicKeyStrengthInBits(key), ++ SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); ++ if (rv != SECSuccess) { ++ return NULL; ++ } ++ } ++ } + /* check the policy on the encryption algorithm */ + if ((NSS_GetAlgorithmPolicy(encAlg, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { +diff -up ./lib/freebl/blapit.h.sign_policy ./lib/freebl/blapit.h +--- ./lib/freebl/blapit.h.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/freebl/blapit.h 2022-06-20 16:47:35.025785641 -0700 +@@ -135,7 +135,7 @@ typedef int __BLAPI_DEPRECATED __attribu + * These values come from the initial key size limits from the PKCS #11 + * module. They may be arbitrarily adjusted to any value freebl supports. + */ +-#define RSA_MIN_MODULUS_BITS 128 ++#define RSA_MIN_MODULUS_BITS 1023 /* 128 */ + #define RSA_MAX_MODULUS_BITS 16384 + #define RSA_MAX_EXPONENT_BITS 64 + #define DH_MIN_P_BITS 128 +diff -up ./lib/nss/nss.h.sign_policy ./lib/nss/nss.h +--- ./lib/nss/nss.h.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/nss/nss.h 2022-06-20 16:47:35.026785647 -0700 +@@ -302,6 +302,28 @@ SECStatus NSS_UnregisterShutdown(NSS_Shu + #define NSS_DEFAULT_LOCKS 0x00d /* lock default values */ + #define NSS_DEFAULT_SSL_LOCK 1 /* lock the ssl default values */ + ++/* NSS_KEY_SIZE_POLICY controls what kinds of operations are subject to ++ * the NSS_XXX_MIN_KEY_SIZE values. ++ * NSS_KEY_SIZE_POLICY_FLAGS sets and clears all the flags to the input ++ * value ++ * On get it returns all the flags ++ * NSS_KEY_SIZE_POLICY_SET_FLAGS sets only the flags=1 in theinput value and ++ * does not affect the other flags ++ * On get it returns all the flags ++ * NSS_KEY_SIZE_POLICY_CLEAR_FLAGS clears only the flags=1 in the input ++ * value and does not affect the other flags ++ * On get it returns all the compliment of all the flags ++ * (cleared flags == 1) */ ++#define NSS_KEY_SIZE_POLICY_FLAGS 0x00e ++#define NSS_KEY_SIZE_POLICY_SET_FLAGS 0x00f ++#define NSS_KEY_SIZE_POLICY_CLEAR_FLAGS 0x010 ++/* currently defined flags */ ++#define NSS_KEY_SIZE_POLICY_SSL_FLAG 1 ++#define NSS_KEY_SIZE_POLICY_VERIFY_FLAG 2 ++#define NSS_KEY_SIZE_POLICY_SIGN_FLAG 4 ++ ++#define NSS_ECC_MIN_KEY_SIZE 0x011 ++ + /* + * Set and get global options for the NSS library. + */ +diff -up ./lib/nss/nssoptions.c.sign_policy ./lib/nss/nssoptions.c +--- ./lib/nss/nssoptions.c.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/nss/nssoptions.c 2022-06-20 16:47:35.026785647 -0700 +@@ -26,6 +26,8 @@ struct nssOps { + PRInt32 dtlsVersionMaxPolicy; + PRInt32 pkcs12DecodeForceUnicode; + PRInt32 defaultLocks; ++ PRInt32 keySizePolicyFlags; ++ PRInt32 eccMinKeySize; + }; + + static struct nssOps nss_ops = { +@@ -37,7 +39,9 @@ static struct nssOps nss_ops = { + 1, + 0xffff, + PR_FALSE, +- 0 ++ 0, ++ NSS_KEY_SIZE_POLICY_SSL_FLAG, ++ SSL_ECC_MIN_CURVE_BITS + }; + + SECStatus +@@ -78,6 +82,18 @@ NSS_OptionSet(PRInt32 which, PRInt32 val + case NSS_DEFAULT_LOCKS: + nss_ops.defaultLocks = value; + break; ++ case NSS_KEY_SIZE_POLICY_FLAGS: ++ nss_ops.keySizePolicyFlags = value; ++ break; ++ case NSS_KEY_SIZE_POLICY_SET_FLAGS: ++ nss_ops.keySizePolicyFlags |= value; ++ break; ++ case NSS_KEY_SIZE_POLICY_CLEAR_FLAGS: ++ nss_ops.keySizePolicyFlags &= ~value; ++ break; ++ case NSS_ECC_MIN_KEY_SIZE: ++ nss_ops.eccMinKeySize = value; ++ break; + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; +@@ -119,6 +135,16 @@ NSS_OptionGet(PRInt32 which, PRInt32 *va + case NSS_DEFAULT_LOCKS: + *value = nss_ops.defaultLocks; + break; ++ case NSS_KEY_SIZE_POLICY_FLAGS: ++ case NSS_KEY_SIZE_POLICY_SET_FLAGS: ++ *value = nss_ops.keySizePolicyFlags; ++ break; ++ case NSS_KEY_SIZE_POLICY_CLEAR_FLAGS: ++ *value = ~nss_ops.keySizePolicyFlags; ++ break; ++ case NSS_ECC_MIN_KEY_SIZE: ++ *value = nss_ops.eccMinKeySize; ++ break; + default: + rv = SECFailure; + } +diff -up ./lib/nss/nssoptions.h.sign_policy ./lib/nss/nssoptions.h +--- ./lib/nss/nssoptions.h.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/nss/nssoptions.h 2022-06-20 16:47:35.026785647 -0700 +@@ -18,3 +18,5 @@ + * happens because NSS used to count bit lengths incorrectly. */ + #define SSL_DH_MIN_P_BITS 1023 + #define SSL_DSA_MIN_P_BITS 1023 ++/* not really used by SSL, but define it here for consistency */ ++#define SSL_ECC_MIN_CURVE_BITS 256 +diff -up ./lib/pk11wrap/pk11kea.c.sign_policy ./lib/pk11wrap/pk11kea.c +--- ./lib/pk11wrap/pk11kea.c.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./lib/pk11wrap/pk11kea.c 2022-06-20 16:47:35.026785647 -0700 +@@ -78,15 +78,14 @@ pk11_KeyExchange(PK11SlotInfo *slot, CK_ + if (privKeyHandle == CK_INVALID_HANDLE) { + PK11RSAGenParams rsaParams; + +- if (symKeyLength > 53) /* bytes */ { +- /* we'd have to generate an RSA key pair > 512 bits long, ++ if (symKeyLength > 120) /* bytes */ { ++ /* we'd have to generate an RSA key pair > 1024 bits long, + ** and that's too costly. Don't even try. + */ + PORT_SetError(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY); + goto rsa_failed; + } +- rsaParams.keySizeInBits = +- (symKeyLength > 21 || symKeyLength == 0) ? 512 : 256; ++ rsaParams.keySizeInBits = 1024; + rsaParams.pe = 0x10001; + privKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, + &rsaParams, &pubKey, PR_FALSE, PR_TRUE, symKey->cx); +diff -up ./lib/pk11wrap/pk11pars.c.sign_policy ./lib/pk11wrap/pk11pars.c +--- ./lib/pk11wrap/pk11pars.c.sign_policy 2022-06-20 16:47:35.004785510 -0700 ++++ ./lib/pk11wrap/pk11pars.c 2022-06-20 16:47:35.026785647 -0700 +@@ -427,12 +427,21 @@ static const optionFreeDef sslOptList[] + { CIPHER_NAME("DTLS1.3"), 0x304 }, + }; + ++static const optionFreeDef keySizeFlagsList[] = { ++ { CIPHER_NAME("KEY-SIZE-SSL"), NSS_KEY_SIZE_POLICY_SSL_FLAG }, ++ { CIPHER_NAME("KEY-SIZE-SIGN"), NSS_KEY_SIZE_POLICY_SIGN_FLAG }, ++ { CIPHER_NAME("KEY-SIZE-VERIFY"), NSS_KEY_SIZE_POLICY_VERIFY_FLAG }, ++}; ++ + static const optionFreeDef freeOptList[] = { + + /* Restrictions for asymetric keys */ + { CIPHER_NAME("RSA-MIN"), NSS_RSA_MIN_KEY_SIZE }, + { CIPHER_NAME("DH-MIN"), NSS_DH_MIN_KEY_SIZE }, + { CIPHER_NAME("DSA-MIN"), NSS_DSA_MIN_KEY_SIZE }, ++ { CIPHER_NAME("ECC-MIN"), NSS_ECC_MIN_KEY_SIZE }, ++ /* what operations doe the key size apply to */ ++ { CIPHER_NAME("KEY-SIZE-FLAGS"), NSS_KEY_SIZE_POLICY_FLAGS }, + /* constraints on SSL Protocols */ + { CIPHER_NAME("TLS-VERSION-MIN"), NSS_TLS_VERSION_MIN_POLICY }, + { CIPHER_NAME("TLS-VERSION-MAX"), NSS_TLS_VERSION_MAX_POLICY }, +@@ -540,6 +549,7 @@ secmod_getPolicyOptValue(const char *pol + *result = val; + return SECSuccess; + } ++ /* handle any ssl strings */ + for (i = 0; i < PR_ARRAY_SIZE(sslOptList); i++) { + if (policyValueLength == sslOptList[i].name_size && + PORT_Strncasecmp(sslOptList[i].name, policyValue, +@@ -548,7 +558,29 @@ secmod_getPolicyOptValue(const char *pol + return SECSuccess; + } + } +- return SECFailure; ++ /* handle key_size flags. Each flag represents a bit, which ++ * gets or'd together. They can be separated by , | or + */ ++ val = 0; ++ while (*policyValue) { ++ PRBool found = PR_FALSE; ++ for (i = 0; i < PR_ARRAY_SIZE(keySizeFlagsList); i++) { ++ if (PORT_Strncasecmp(keySizeFlagsList[i].name, policyValue, ++ keySizeFlagsList[i].name_size) == 0) { ++ val |= keySizeFlagsList[i].option; ++ found = PR_TRUE; ++ policyValue += keySizeFlagsList[i].name_size; ++ break; ++ } ++ } ++ if (!found) { ++ return SECFailure; ++ } ++ if (*policyValue == ',' || *policyValue == '|' || *policyValue == '+') { ++ policyValue++; ++ } ++ } ++ *result = val; ++ return SECSuccess; + } + + /* Policy operations: +diff -up ./lib/ssl/ssl3con.c.sign_policy ./lib/ssl/ssl3con.c +--- ./lib/ssl/ssl3con.c.sign_policy 2022-06-20 16:47:34.998785473 -0700 ++++ ./lib/ssl/ssl3con.c 2022-06-20 16:47:35.028785660 -0700 +@@ -7409,6 +7409,8 @@ ssl_HandleDHServerKeyExchange(sslSocket + unsigned dh_p_bits; + unsigned dh_g_bits; + PRInt32 minDH; ++ PRInt32 optval; ++ PRBool usePolicyLength = PR_FALSE; + + SSL3Hashes hashes; + SECItem signature = { siBuffer, NULL, 0 }; +@@ -7419,8 +7421,13 @@ ssl_HandleDHServerKeyExchange(sslSocket + if (rv != SECSuccess) { + goto loser; /* malformed. */ + } ++ rv = NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optval); ++ if (rv == SECSuccess) { ++ usePolicyLength = (PRBool)((optval & NSS_KEY_SIZE_POLICY_SSL_FLAG) == NSS_KEY_SIZE_POLICY_SSL_FLAG); ++ } + +- rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH); ++ rv = usePolicyLength ? NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH) ++ : SECFailure; + if (rv != SECSuccess || minDH <= 0) { + minDH = SSL_DH_MIN_P_BITS; + } +@@ -11411,13 +11418,20 @@ ssl_SetAuthKeyBits(sslSocket *ss, const + SECStatus rv; + PRUint32 minKey; + PRInt32 optval; ++ PRBool usePolicyLength = PR_TRUE; ++ ++ rv = NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optval); ++ if (rv == SECSuccess) { ++ usePolicyLength = (PRBool)((optval & NSS_KEY_SIZE_POLICY_SSL_FLAG) == NSS_KEY_SIZE_POLICY_SSL_FLAG); ++ } + + ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey); + switch (SECKEY_GetPublicKeyType(pubKey)) { + case rsaKey: + case rsaPssKey: + case rsaOaepKey: +- rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &optval); ++ rv = usePolicyLength ? NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &optval) ++ : SECFailure; + if (rv == SECSuccess && optval > 0) { + minKey = (PRUint32)optval; + } else { +@@ -11426,7 +11440,8 @@ ssl_SetAuthKeyBits(sslSocket *ss, const + break; + + case dsaKey: +- rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &optval); ++ rv = usePolicyLength ? NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &optval) ++ : SECFailure; + if (rv == SECSuccess && optval > 0) { + minKey = (PRUint32)optval; + } else { +@@ -11435,7 +11450,8 @@ ssl_SetAuthKeyBits(sslSocket *ss, const + break; + + case dhKey: +- rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &optval); ++ rv = usePolicyLength ? NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &optval) ++ : SECFailure; + if (rv == SECSuccess && optval > 0) { + minKey = (PRUint32)optval; + } else { +@@ -11444,9 +11460,15 @@ ssl_SetAuthKeyBits(sslSocket *ss, const + break; + + case ecKey: +- /* Don't check EC strength here on the understanding that we only +- * support curves we like. */ +- minKey = ss->sec.authKeyBits; ++ rv = usePolicyLength ? NSS_OptionGet(NSS_ECC_MIN_KEY_SIZE, &optval) ++ : SECFailure; ++ if (rv == SECSuccess && optval > 0) { ++ minKey = (PRUint32)optval; ++ } else { ++ /* Don't check EC strength here on the understanding that we ++ * only support curves we like. */ ++ minKey = ss->sec.authKeyBits; ++ } + break; + + default: +diff -up ./tests/policy/crypto-policy.txt.sign_policy ./tests/policy/crypto-policy.txt +--- ./tests/policy/crypto-policy.txt.sign_policy 2022-05-26 02:54:33.000000000 -0700 ++++ ./tests/policy/crypto-policy.txt 2022-06-20 16:47:35.028785660 -0700 +@@ -6,6 +6,8 @@ + 0 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA1:HMAC-SHA384:HMAC-SHA512:SECP256R1:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:aes256-cbc:camellia256-cbc:aes128-gcm:aes128-cbc:camellia128-cbc:SHA256:SHA384:SHA512:SHA1:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:rsa-pkcs:rsa-pss:ecdsa:tls-version-min=tls1.0:dtls-version-min=dtls1.0:DH-MIN=1023:DSA-MIN=2048:RSA-MIN=2048 NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Standard policy + 0 disallow=ALL_allow=HMAC-SHA1:HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP256R1:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:aes256-cbc:camellia256-cbc:aes128-gcm:aes128-cbc:camellia128-cbc:des-ede3-cbc:rc4:SHA256:SHA384:SHA512:SHA1:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:DHE-DSS:rsa-pkcs:rsa-pss:ecdsa:tls-version-min=tls1.0:dtls-version-min=tls1.0:DH-MIN=1023:DSA-MIN=1023:RSA-MIN=1023 NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Legacy policy + 0 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:SHA384:SHA512:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:rsa-pkcs:rsa-pss:ecdsa:tls-version-min=tls1.2:dtls-version-min=dtls1.2:DH-MIN=3072:DSA-MIN=3072:RSA-MIN=3072 NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Reduced policy ++0 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:SHA384:SHA512:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:rsa-pkcs:rsa-pss:ecdsa:tls-version-min=tls1.2:dtls-version-min=dtls1.2:DH-MIN=3072:DSA-MIN=3072:RSA-MIN=3072:KEY-SIZE-FLAGS=KEY-SIZE-SSL,KEY-SIZE-SIGN,KEY-SIZE-VERIFY NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Valid key size ++2 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:SHA384:SHA512:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:rsa-pkcs:rsa-pss:ecdsa:tls-version-min=tls1.2:dtls-version-min=dtls1.2:DH-MIN=3072:DSA-MIN=3072:RSA-MIN=3072:KEY-SIZE-FLAGS=UNKNOWN,KEY-SIZE-SIGN,KEY-SIZE-VERIFY NSS-POLICY-FAIL.*unknown.* Invalid key size + 2 disallow=ALL_allow=dtls-version-min=:dtls-version-max= NSS-POLICY-FAIL Missing value + 2 disallow=ALL_allow=RSA-MIN=whatever NSS-POLICY-FAIL Invalid value + 2 disallow=ALL_allow=flower NSS-POLICY-FAIL Invalid identifier +diff -up ./tests/ssl/sslpolicy.txt.sign_policy ./tests/ssl/sslpolicy.txt +--- ./tests/ssl/sslpolicy.txt.sign_policy 2022-06-20 16:47:35.028785660 -0700 ++++ ./tests/ssl/sslpolicy.txt 2022-06-20 16:50:08.958742135 -0700 +@@ -196,6 +196,11 @@ + # rsa-pkcs, rsa-pss, and ecdsa policy checking reverted in rhel8 for binary + # compatibility reasons + # 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly ++ 1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-verify Restrict RSA keys on signature verification ++ 1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-sign Restrict RSA keys on signing ++ 1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-ssl Restrict RSA keys when used in SSL ++ 0 noECC SSL3 d allow=rsa-min=1023 Restrict RSA keys when used in SSL ++ + # test default settings + # NOTE: tstclient will attempt to overide the defaults, so we detect we + # were successful by locking in our settings +diff -up ./tests/dbupgrade/dbupgrade.sh.sign_policy ./tests/dbupgrade/dbupgrade.sh +--- ./tests/dbupgrade/dbupgrade.sh.sign_policy 2022-06-22 08:43:55.905407738 -0700 ++++ ./tests/dbupgrade/dbupgrade.sh 2022-06-22 08:43:58.837426779 -0700 +@@ -69,7 +69,7 @@ dbupgrade_main() + echo $i + if [ -d $i ]; then + echo "upgrading db $i" +- ${BINDIR}/certutil -G -g 512 -d sql:$i -f ${PWFILE} -z ${NOISE_FILE} 2>&1 ++ ${BINDIR}/certutil -G -g 1024 -d sql:$i -f ${PWFILE} -z ${NOISE_FILE} 2>&1 + html_msg $? 0 "Upgrading $i" + else + echo "skipping db $i" diff --git a/SOURCES/nss-config.in b/SOURCES/nss-config.in new file mode 100644 index 0000000..f8f893e --- /dev/null +++ b/SOURCES/nss-config.in @@ -0,0 +1,145 @@ +#!/bin/sh + +prefix=@prefix@ + +major_version=@MOD_MAJOR_VERSION@ +minor_version=@MOD_MINOR_VERSION@ +patch_version=@MOD_PATCH_VERSION@ + +usage() +{ + cat <&2 +fi + +lib_ssl=yes +lib_smime=yes +lib_nss=yes +lib_nssutil=yes + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + ;; + --prefix) + echo_prefix=yes + ;; + --exec-prefix=*) + exec_prefix=$optarg + ;; + --exec-prefix) + echo_exec_prefix=yes + ;; + --includedir=*) + includedir=$optarg + ;; + --includedir) + echo_includedir=yes + ;; + --libdir=*) + libdir=$optarg + ;; + --libdir) + echo_libdir=yes + ;; + --version) + echo ${major_version}.${minor_version}.${patch_version} + ;; + --cflags) + echo_cflags=yes + ;; + --libs) + echo_libs=yes + ;; + ssl) + lib_ssl=yes + ;; + smime) + lib_smime=yes + ;; + nss) + lib_nss=yes + ;; + nssutil) + lib_nssutil=yes + ;; + *) + usage 1 1>&2 + ;; + esac + shift +done + +# Set variables that may be dependent upon other variables +if test -z "$exec_prefix"; then + exec_prefix=`pkg-config --variable=exec_prefix nss` +fi +if test -z "$includedir"; then + includedir=`pkg-config --variable=includedir nss` +fi +if test -z "$libdir"; then + libdir=`pkg-config --variable=libdir nss` +fi + +if test "$echo_prefix" = "yes"; then + echo $prefix +fi + +if test "$echo_exec_prefix" = "yes"; then + echo $exec_prefix +fi + +if test "$echo_includedir" = "yes"; then + echo $includedir +fi + +if test "$echo_libdir" = "yes"; then + echo $libdir +fi + +if test "$echo_cflags" = "yes"; then + echo -I$includedir +fi + +if test "$echo_libs" = "yes"; then + libdirs="-Wl,-rpath-link,$libdir -L$libdir" + if test -n "$lib_ssl"; then + libdirs="$libdirs -lssl${major_version}" + fi + if test -n "$lib_smime"; then + libdirs="$libdirs -lsmime${major_version}" + fi + if test -n "$lib_nss"; then + libdirs="$libdirs -lnss${major_version}" + fi + if test -n "$lib_nssutil"; then + libdirs="$libdirs -lnssutil${major_version}" + fi + echo $libdirs +fi + diff --git a/SOURCES/nss-config.xml b/SOURCES/nss-config.xml new file mode 100644 index 0000000..f9518c9 --- /dev/null +++ b/SOURCES/nss-config.xml @@ -0,0 +1,132 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + nss-config + 1 + + + + nss-config + Return meta information about nss libraries + + + + + nss-config + + + + + + + + + + + + Description + + nss-config is a shell scrip + tool which can be used to obtain gcc options for building client pacakges of nspt. + + + + + Options + + + + + Returns the top level system directory under which the nss libraries are installed. + + + + + returns the top level system directory under which any nss binaries would be installed. + + + + count + returns the path to the directory were the nss libraries are installed. + + + + + returns the upstream version of nss in the form major_version-minor_version-patch_version. + + + + + returns the compiler linking flags. + + + + + returns the compiler include flags. + + + + + returns the path to the directory were the nss libraries are installed. + + + + + + + Examples + + The following example will query for both include path and linkage flags: + + + /usr/bin/nss-config --cflags --libs + + + + + + + + + Files + + /usr/bin/nss-config + + + + + See also + pkg-config(1) + + + + Authors + The nss liraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + + LICENSE + Licensed under 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/. + + + + + diff --git a/SOURCES/nss-disable-dc.patch b/SOURCES/nss-disable-dc.patch new file mode 100644 index 0000000..6eae5e4 --- /dev/null +++ b/SOURCES/nss-disable-dc.patch @@ -0,0 +1,32 @@ +diff -up ./gtests/ssl_gtest/manifest.mn.orig ./gtests/ssl_gtest/manifest.mn +--- ./gtests/ssl_gtest/manifest.mn.orig 2021-06-02 15:40:48.677355426 -0700 ++++ ./gtests/ssl_gtest/manifest.mn 2021-06-02 15:42:31.248977261 -0700 +@@ -57,7 +57,6 @@ CPPSRCS = \ + tls_filter.cc \ + tls_protect.cc \ + tls_psk_unittest.cc \ +- tls_subcerts_unittest.cc \ + tls_ech_unittest.cc \ + $(SSLKEYLOGFILE_FILES) \ + $(NULL) +diff -up ./lib/ssl/sslsock.c.orig ./lib/ssl/sslsock.c +--- ./lib/ssl/sslsock.c.orig 2021-05-28 02:50:43.000000000 -0700 ++++ ./lib/ssl/sslsock.c 2021-06-02 15:40:48.676355420 -0700 +@@ -819,7 +819,7 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh + break; + + case SSL_ENABLE_DELEGATED_CREDENTIALS: +- ss->opt.enableDelegatedCredentials = val; ++ /* disable it for now */ + break; + + case SSL_ENABLE_NPN: +@@ -1337,7 +1337,7 @@ SSL_OptionSetDefault(PRInt32 which, PRIn + break; + + case SSL_ENABLE_DELEGATED_CREDENTIALS: +- ssl_defaults.enableDelegatedCredentials = val; ++ /* disable it for now */ + break; + + case SSL_ENABLE_NPN: diff --git a/SOURCES/nss-disable-md5.patch b/SOURCES/nss-disable-md5.patch new file mode 100644 index 0000000..827928f --- /dev/null +++ b/SOURCES/nss-disable-md5.patch @@ -0,0 +1,41 @@ +diff -r 699541a7793b lib/pk11wrap/pk11pars.c +--- a/lib/pk11wrap/pk11pars.c 2021-04-16 14:43:41.668835607 -0700 ++++ b/lib/pk11wrap/pk11pars.c 2021-04-16 14:43:50.585888411 -0700 +@@ -324,11 +324,11 @@ static const oidValDef curveOptList[] = + static const oidValDef hashOptList[] = { + /* Hashes */ + { CIPHER_NAME("MD2"), SEC_OID_MD2, +- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, ++ 0 }, + { CIPHER_NAME("MD4"), SEC_OID_MD4, +- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, ++ 0 }, + { CIPHER_NAME("MD5"), SEC_OID_MD5, +- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, ++ 0 }, + { CIPHER_NAME("SHA1"), SEC_OID_SHA1, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, + { CIPHER_NAME("SHA224"), SEC_OID_SHA224, +diff -r 699541a7793b lib/util/secoid.c +--- a/lib/util/secoid.c Tue Jun 16 23:03:22 2020 +0000 ++++ b/lib/util/secoid.c Thu Jun 25 14:33:09 2020 +0200 +@@ -2042,6 +2042,19 @@ + int i; + + for (i = 1; i < SEC_OID_TOTAL; i++) { ++ switch (i) { ++ case SEC_OID_MD2: ++ case SEC_OID_MD4: ++ case SEC_OID_MD5: ++ case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: ++ case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: ++ continue; ++ default: ++ break; ++ } + if (oids[i].desc && strstr(arg, oids[i].desc)) { + xOids[i].notPolicyFlags = notEnable | + (xOids[i].notPolicyFlags & ~(DEF_FLAGS)); diff --git a/SOURCES/nss-dso-ldflags.patch b/SOURCES/nss-dso-ldflags.patch new file mode 100644 index 0000000..d5485ae --- /dev/null +++ b/SOURCES/nss-dso-ldflags.patch @@ -0,0 +1,13 @@ +Index: nss/coreconf/Linux.mk +=================================================================== +--- nss.orig/coreconf/Linux.mk ++++ nss/coreconf/Linux.mk +@@ -144,7 +144,7 @@ ifdef USE_PTHREADS + endif + + DSO_CFLAGS = -fPIC +-DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections ++DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections $(DSO_LDFLAGS) + # The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8) + # incorrectly reports undefined references in the libraries we link with, so + # we don't use -z defs there. diff --git a/SOURCES/nss-gcm-param-default-pkcs11v2.patch b/SOURCES/nss-gcm-param-default-pkcs11v2.patch new file mode 100644 index 0000000..2d6cba8 --- /dev/null +++ b/SOURCES/nss-gcm-param-default-pkcs11v2.patch @@ -0,0 +1,21 @@ +diff -up ./lib/util/pkcs11n.h.aes_gcm_pkcs11_v2 ./lib/util/pkcs11n.h +--- ./lib/util/pkcs11n.h.aes_gcm_pkcs11_v2 2020-05-13 13:44:11.312405744 -0700 ++++ ./lib/util/pkcs11n.h 2020-05-13 13:45:23.951723660 -0700 +@@ -605,7 +605,7 @@ typedef struct CK_NSS_GCM_PARAMS { + typedef CK_NSS_GCM_PARAMS CK_PTR CK_NSS_GCM_PARAMS_PTR; + + /* deprecated #defines. Drop in future NSS releases */ +-#ifdef NSS_PKCS11_2_0_COMPAT ++#ifndef NSS_PKCS11_3_0_STRICT + + /* defines that were changed between NSS's PKCS #11 and the Oasis headers */ + #define CKF_EC_FP CKF_EC_F_P +@@ -664,7 +664,7 @@ typedef CK_NSS_GCM_PARAMS CK_PTR CK_GCM_ + #define CKT_NETSCAPE_VALID CKT_NSS_VALID + #define CKT_NETSCAPE_VALID_DELEGATOR CKT_NSS_VALID_DELEGATOR + #else +-/* use the new CK_GCM_PARAMS if NSS_PKCS11_2_0_COMPAT is not defined */ ++/* use the new CK_GCM_PARAMS if NSS_PKCS11_3_0_STRICT is defined */ + typedef struct CK_GCM_PARAMS_V3 CK_GCM_PARAMS; + typedef CK_GCM_PARAMS_V3 CK_PTR CK_GCM_PARAMS_PTR; + #endif diff --git a/SOURCES/nss-p11-kit.config b/SOURCES/nss-p11-kit.config new file mode 100644 index 0000000..0ebf073 --- /dev/null +++ b/SOURCES/nss-p11-kit.config @@ -0,0 +1,4 @@ +name=p11-kit-proxy +library=p11-kit-proxy.so + + diff --git a/SOURCES/nss-skip-sysinit-gtests.patch b/SOURCES/nss-skip-sysinit-gtests.patch new file mode 100644 index 0000000..0a80e48 --- /dev/null +++ b/SOURCES/nss-skip-sysinit-gtests.patch @@ -0,0 +1,12 @@ +Index: nss/gtests/manifest.mn +=================================================================== +--- nss.orig/gtests/manifest.mn ++++ nss/gtests/manifest.mn +@@ -31,7 +31,6 @@ NSS_SRCDIRS = \ + smime_gtest \ + softoken_gtest \ + ssl_gtest \ +- $(SYSINIT_GTEST) \ + nss_bogo_shim \ + pkcs11testmodule \ + $(NULL) diff --git a/SOURCES/nss-softokn-config.in b/SOURCES/nss-softokn-config.in new file mode 100644 index 0000000..c7abe29 --- /dev/null +++ b/SOURCES/nss-softokn-config.in @@ -0,0 +1,116 @@ +#!/bin/sh + +prefix=@prefix@ + +major_version=@MOD_MAJOR_VERSION@ +minor_version=@MOD_MINOR_VERSION@ +patch_version=@MOD_PATCH_VERSION@ + +usage() +{ + cat <&2 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + ;; + --prefix) + echo_prefix=yes + ;; + --exec-prefix=*) + exec_prefix=$optarg + ;; + --exec-prefix) + echo_exec_prefix=yes + ;; + --includedir=*) + includedir=$optarg + ;; + --includedir) + echo_includedir=yes + ;; + --libdir=*) + libdir=$optarg + ;; + --libdir) + echo_libdir=yes + ;; + --version) + echo ${major_version}.${minor_version}.${patch_version} + ;; + --cflags) + echo_cflags=yes + ;; + --libs) + echo_libs=yes + ;; + *) + usage 1 1>&2 + ;; + esac + shift +done + +# Set variables that may be dependent upon other variables +if test -z "$exec_prefix"; then + exec_prefix=`pkg-config --variable=exec_prefix nss-softokn` +fi +if test -z "$includedir"; then + includedir=`pkg-config --variable=includedir nss-softokn` +fi +if test -z "$libdir"; then + libdir=`pkg-config --variable=libdir nss-softokn` +fi + +if test "$echo_prefix" = "yes"; then + echo $prefix +fi + +if test "$echo_exec_prefix" = "yes"; then + echo $exec_prefix +fi + +if test "$echo_includedir" = "yes"; then + echo $includedir +fi + +if test "$echo_libdir" = "yes"; then + echo $libdir +fi + +if test "$echo_cflags" = "yes"; then + echo -I$includedir +fi + +if test "$echo_libs" = "yes"; then + libdirs="-Wl,-rpath-link,$libdir -L$libdir" + echo $libdirs +fi + diff --git a/SOURCES/nss-softokn-dracut-module-setup.sh b/SOURCES/nss-softokn-dracut-module-setup.sh new file mode 100644 index 0000000..010ec18 --- /dev/null +++ b/SOURCES/nss-softokn-dracut-module-setup.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +check() { + return 255 +} + +depends() { + return 0 +} + +install() { + local _dir + + inst_libdir_file libfreeblpriv3.so libfreeblpriv3.chk \ + libfreebl3.so +} diff --git a/SOURCES/nss-softokn-dracut.conf b/SOURCES/nss-softokn-dracut.conf new file mode 100644 index 0000000..2d9232e --- /dev/null +++ b/SOURCES/nss-softokn-dracut.conf @@ -0,0 +1,3 @@ +# turn on nss-softokn module + +add_dracutmodules+=" nss-softokn " diff --git a/SOURCES/nss-softokn.pc.in b/SOURCES/nss-softokn.pc.in new file mode 100644 index 0000000..022ebbf --- /dev/null +++ b/SOURCES/nss-softokn.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: NSS-SOFTOKN +Description: Network Security Services Softoken PKCS #11 Module +Version: %SOFTOKEN_VERSION% +Requires: nspr >= %NSPR_VERSION%, nss-util >= %NSSUTIL_VERSION% +Libs: -L${libdir} -lfreebl3 -lnssdbm3 -lsoftokn3 +Cflags: -I${includedir} diff --git a/SOURCES/nss-sysinit-userdb.patch b/SOURCES/nss-sysinit-userdb.patch new file mode 100644 index 0000000..7347260 --- /dev/null +++ b/SOURCES/nss-sysinit-userdb.patch @@ -0,0 +1,106 @@ +Index: nss/lib/sysinit/nsssysinit.c +=================================================================== +--- nss.orig/lib/sysinit/nsssysinit.c ++++ nss/lib/sysinit/nsssysinit.c +@@ -36,41 +36,9 @@ testdir(char *dir) + return S_ISDIR(buf.st_mode); + } + +-/** +- * Append given @dir to @path and creates the directory with mode @mode. +- * Returns 0 if successful, -1 otherwise. +- * Assumes that the allocation for @path has sufficient space for @dir +- * to be added. +- */ +-static int +-appendDirAndCreate(char *path, char *dir, mode_t mode) +-{ +- PORT_Strcat(path, dir); +- if (!testdir(path)) { +- if (mkdir(path, mode)) { +- return -1; +- } +- } +- return 0; +-} +- +-#define XDG_NSS_USER_PATH1 "/.local" +-#define XDG_NSS_USER_PATH2 "/share" +-#define XDG_NSS_USER_PATH3 "/pki" +- + #define NSS_USER_PATH1 "/.pki" + #define NSS_USER_PATH2 "/nssdb" +- +-/** +- * Return the path to user's NSS database. +- * We search in the following dirs in order: +- * (1) $HOME/.pki/nssdb; +- * (2) $XDG_DATA_HOME/pki/nssdb if XDG_DATA_HOME is set; +- * (3) $HOME/.local/share/pki/nssdb (default XDG_DATA_HOME value). +- * If (1) does not exist, then the returned dir will be set to either +- * (2) or (3), depending if XDG_DATA_HOME is set. +- */ +-char * ++static char * + getUserDB(void) + { + char *userdir = PR_GetEnvSecure("HOME"); +@@ -81,47 +49,22 @@ getUserDB(void) + } + + nssdir = PORT_Alloc(strlen(userdir) + sizeof(NSS_USER_PATH1) + sizeof(NSS_USER_PATH2)); ++ if (nssdir == NULL) { ++ return NULL; ++ } + PORT_Strcpy(nssdir, userdir); +- PORT_Strcat(nssdir, NSS_USER_PATH1 NSS_USER_PATH2); +- if (testdir(nssdir)) { +- /* $HOME/.pki/nssdb exists */ +- return nssdir; +- } else { +- /* either $HOME/.pki or $HOME/.pki/nssdb does not exist */ ++ /* verify it exists */ ++ if (!testdir(nssdir)) { + PORT_Free(nssdir); +- } +- int size = 0; +- char *xdguserdatadir = PR_GetEnvSecure("XDG_DATA_HOME"); +- if (xdguserdatadir) { +- size = strlen(xdguserdatadir); +- } else { +- size = strlen(userdir) + sizeof(XDG_NSS_USER_PATH1) + sizeof(XDG_NSS_USER_PATH2); +- } +- size += sizeof(XDG_NSS_USER_PATH3) + sizeof(NSS_USER_PATH2); +- +- nssdir = PORT_Alloc(size); +- if (nssdir == NULL) { + return NULL; + } +- +- if (xdguserdatadir) { +- PORT_Strcpy(nssdir, xdguserdatadir); +- if (!testdir(nssdir)) { +- PORT_Free(nssdir); +- return NULL; +- } +- +- } else { +- PORT_Strcpy(nssdir, userdir); +- if (appendDirAndCreate(nssdir, XDG_NSS_USER_PATH1, 0755) || +- appendDirAndCreate(nssdir, XDG_NSS_USER_PATH2, 0755)) { +- PORT_Free(nssdir); +- return NULL; +- } ++ PORT_Strcat(nssdir, NSS_USER_PATH1); ++ if (!testdir(nssdir) && mkdir(nssdir, 0760)) { ++ PORT_Free(nssdir); ++ return NULL; + } +- /* ${XDG_DATA_HOME:-$HOME/.local/share}/pki/nssdb */ +- if (appendDirAndCreate(nssdir, XDG_NSS_USER_PATH3, 0760) || +- appendDirAndCreate(nssdir, NSS_USER_PATH2, 0760)) { ++ PORT_Strcat(nssdir, NSS_USER_PATH2); ++ if (!testdir(nssdir) && mkdir(nssdir, 0760)) { + PORT_Free(nssdir); + return NULL; + } diff --git a/SOURCES/nss-util-config.in b/SOURCES/nss-util-config.in new file mode 100644 index 0000000..532abbe --- /dev/null +++ b/SOURCES/nss-util-config.in @@ -0,0 +1,118 @@ +#!/bin/sh + +prefix=@prefix@ + +major_version=@MOD_MAJOR_VERSION@ +minor_version=@MOD_MINOR_VERSION@ +patch_version=@MOD_PATCH_VERSION@ + +usage() +{ + cat <&2 +fi + +lib_nssutil=yes + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + ;; + --prefix) + echo_prefix=yes + ;; + --exec-prefix=*) + exec_prefix=$optarg + ;; + --exec-prefix) + echo_exec_prefix=yes + ;; + --includedir=*) + includedir=$optarg + ;; + --includedir) + echo_includedir=yes + ;; + --libdir=*) + libdir=$optarg + ;; + --libdir) + echo_libdir=yes + ;; + --version) + echo ${major_version}.${minor_version}.${patch_version} + ;; + --cflags) + echo_cflags=yes + ;; + --libs) + echo_libs=yes + ;; + *) + usage 1 1>&2 + ;; + esac + shift +done + +# Set variables that may be dependent upon other variables +if test -z "$exec_prefix"; then + exec_prefix=`pkg-config --variable=exec_prefix nss-util` +fi +if test -z "$includedir"; then + includedir=`pkg-config --variable=includedir nss-util` +fi +if test -z "$libdir"; then + libdir=`pkg-config --variable=libdir nss-util` +fi + +if test "$echo_prefix" = "yes"; then + echo $prefix +fi + +if test "$echo_exec_prefix" = "yes"; then + echo $exec_prefix +fi + +if test "$echo_includedir" = "yes"; then + echo $includedir +fi + +if test "$echo_libdir" = "yes"; then + echo $libdir +fi + +if test "$echo_cflags" = "yes"; then + echo -I$includedir +fi + +if test "$echo_libs" = "yes"; then + libdirs="-Wl,-rpath-link,$libdir -L$libdir" + if test -n "$lib_nssutil"; then + libdirs="$libdirs -lnssutil${major_version}" + fi + echo $libdirs +fi + diff --git a/SOURCES/nss-util.pc.in b/SOURCES/nss-util.pc.in new file mode 100644 index 0000000..1310248 --- /dev/null +++ b/SOURCES/nss-util.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: NSS-UTIL +Description: Network Security Services Utility Library +Version: %NSSUTIL_VERSION% +Requires: nspr >= %NSPR_VERSION% +Libs: -L${libdir} -lnssutil3 +Cflags: -I${includedir} diff --git a/SOURCES/nss.pc.in b/SOURCES/nss.pc.in new file mode 100644 index 0000000..69823cb --- /dev/null +++ b/SOURCES/nss.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: NSS +Description: Network Security Services +Version: %NSS_VERSION% +Requires: nspr >= %NSPR_VERSION%, nss-util >= %NSSUTIL_VERSION% +Libs: -L${libdir} -lssl3 -lsmime3 -lnss3 +Cflags: -I${includedir} diff --git a/SOURCES/pkcs11.txt.xml b/SOURCES/pkcs11.txt.xml new file mode 100644 index 0000000..d30e469 --- /dev/null +++ b/SOURCES/pkcs11.txt.xml @@ -0,0 +1,56 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + pkcs11.txt + 5 + + + + pkcs11.txt + NSS PKCS #11 module configuration file + + + + Description + +The pkcs11.txt file is used to configure initialization parameters for the nss security module and optionally other pkcs #11 modules. + + +For full documentation visit PKCS #11 Module Specs. + + + + + Files + /etc/pki/nssdb/pkcs11.txt + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + diff --git a/SOURCES/rhbz1185708-enable-ecc-3des-ciphers-by-default.patch b/SOURCES/rhbz1185708-enable-ecc-3des-ciphers-by-default.patch new file mode 100644 index 0000000..970c84e --- /dev/null +++ b/SOURCES/rhbz1185708-enable-ecc-3des-ciphers-by-default.patch @@ -0,0 +1,14 @@ +diff -up nss/lib/ssl/ssl3con.c.1185708_3des nss/lib/ssl/ssl3con.c +--- nss/lib/ssl/ssl3con.c.1185708_3des 2018-12-11 18:28:06.736592552 +0100 ++++ nss/lib/ssl/ssl3con.c 2018-12-11 18:29:06.273314692 +0100 +@@ -106,8 +106,8 @@ static ssl3CipherSuiteCfg cipherSuites[s + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + diff --git a/SOURCES/secmod.db.xml b/SOURCES/secmod.db.xml new file mode 100644 index 0000000..afc9dce --- /dev/null +++ b/SOURCES/secmod.db.xml @@ -0,0 +1,63 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + secmod.db + 5 + + + + secmod.db + Legacy NSS security modules database + + + + Description + secmod.db is an NSS security modules database. + The security modules database is used to keep track of the NSS security modules. The NSS security modules export their services via the PKCS #11 API which NSS uses as its Services Provider Interface. + + The command line utility modutil is used for managing PKCS #11 module information both within secmod.db files and within hardware tokens. + + For new applications the recommended way of tracking security modules is via the pkcs11.txt configuration file used in conjunction the new sqlite-based shared database format for certificate and key databases. + + + + + Files + /etc/pki/nssdb/secmod.db + + + + See also + modutil(1), cert8.db(5), cert9.db(5), key3.db(5), key4.db(5), pkcs11.txt(5) + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + + diff --git a/SOURCES/setup-nsssysinit.sh b/SOURCES/setup-nsssysinit.sh new file mode 100755 index 0000000..8e1f5f7 --- /dev/null +++ b/SOURCES/setup-nsssysinit.sh @@ -0,0 +1,68 @@ +#!/bin/sh +# +# Turns on or off the nss-sysinit module db by editing the +# global PKCS #11 congiguration file. Displays the status. +# +# This script can be invoked by the user as super user. +# It is invoked at nss-sysinit post install time with argument on. +# +usage() +{ + cat <&2 +fi + +# the system-wide configuration file +p11conf="/etc/pki/nssdb/pkcs11.txt" +# must exist, otherwise report it and exit with failure +if [ ! -f $p11conf ]; then + echo "Could not find ${p11conf}" + exit 1 +fi + +# check if nsssysinit is currently enabled or disabled +sysinit_enabled() +{ + grep -q '^library=libnsssysinit' ${p11conf} +} + +umask 022 +case "$1" in + on | ON ) + if sysinit_enabled; then + exit 0 + fi + cat ${p11conf} | \ + sed -e 's/^library=$/library=libnsssysinit.so/' \ + -e '/^NSS/s/\(Flags=internal\)\(,[^m]\)/\1,moduleDBOnly\2/' > \ + ${p11conf}.on + mv ${p11conf}.on ${p11conf} + ;; + off | OFF ) + if ! sysinit_enabled; then + exit 0 + fi + cat ${p11conf} | \ + sed -e 's/^library=libnsssysinit.so/library=/' \ + -e '/^NSS/s/Flags=internal,moduleDBOnly/Flags=internal/' > \ + ${p11conf}.off + mv ${p11conf}.off ${p11conf} + ;; + status ) + echo -n 'NSS sysinit is ' + sysinit_enabled && echo 'enabled' || echo 'disabled' + ;; + * ) + usage 1 1>&2 + ;; +esac diff --git a/SOURCES/setup-nsssysinit.xml b/SOURCES/setup-nsssysinit.xml new file mode 100644 index 0000000..5b9827f --- /dev/null +++ b/SOURCES/setup-nsssysinit.xml @@ -0,0 +1,106 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + setup-nsssysinit + 1 + + + + setup-nsssysinit + Query or enable the nss-sysinit module + + + + + setup-nsssysinit + + + + + + + + Description + setup-nsssysinit is a shell script to query the status of the nss-sysinit module and when run with root priviledge it can enable or disable it. + Turns on or off the nss-sysinit module db by editing the global PKCS #11 configuration file. Displays the status. This script can be invoked by the user as super user. It is invoked at nss-sysinit post install time with argument on. + + + + + Options + + + + + Turn on nss-sysinit. + + + + + Turn on nss-sysinit. + + + + + returns whether nss-syinit is enabled or not. + + + + + + + Examples + + The following example will query for the status of nss-sysinit: + + /usr/bin/setup-nsssysinit status + + + + The following example, when run as superuser, will turn on nss-sysinit: + + /usr/bin/setup-nsssysinit on + + + + + + + Files + /usr/bin/setup-nsssysinit + + + + See also + pkg-config(1) + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + diff --git a/SOURCES/system-pkcs11.txt b/SOURCES/system-pkcs11.txt new file mode 100644 index 0000000..c2f5704 --- /dev/null +++ b/SOURCES/system-pkcs11.txt @@ -0,0 +1,5 @@ +library=libnsssysinit.so +name=NSS Internal PKCS #11 Module +parameters=configdir='sql:/etc/pki/nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' +NSS=Flags=internal,moduleDBOnly,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) + diff --git a/SPECS/nss.spec b/SPECS/nss.spec new file mode 100644 index 0000000..0efdf0a --- /dev/null +++ b/SPECS/nss.spec @@ -0,0 +1,2529 @@ +%global nspr_build_version 4.34.0-3 +%global nspr_release -3 +%global nspr_version 4.34.0 +%global nss_version 3.79.0 +%global unsupported_tools_directory %{_libdir}/nss/unsupported-tools +%global saved_files_dir %{_libdir}/nss/saved +%global dracutlibdir %{_prefix}/lib/dracut +%global dracut_modules_dir %{dracutlibdir}/modules.d/05nss-softokn/ +%global dracut_conf_dir %{dracutlibdir}/dracut.conf.d + +# The timestamp of our downstream manual pages, e.g., nss-config.1 +%global manual_date "Nov 13 2013" + +%bcond_without tests + +# Produce .chk files for the final stripped binaries +# +# NOTE: The LD_LIBRARY_PATH line guarantees shlibsign links +# against the freebl that we just built. This is necessary +# because the signing algorithm changed on 3.14 to DSA2 with SHA256 +# whereas we previously signed with DSA and SHA1. We must Keep this line +# until all mock platforms have been updated. +# After %%{__os_install_post} we would add +# export LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%%{_libdir} +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libsoftokn3.so \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libfreeblpriv3.so \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libfreebl3.so \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libnssdbm3.so \ +%{nil} + +# The upstream omits the trailing ".0", while we need it for +# consistency with the pkg-config version: +# https://bugzilla.redhat.com/show_bug.cgi?id=1578106 +%{lua: +rpm.define(string.format("nss_archive_version %s", + string.gsub(rpm.expand("%nss_version"), "(.*)%.0$", "%1"))) +} + +%{lua: +rpm.define(string.format("nss_release_tag NSS_%s_RTM", + string.gsub(rpm.expand("%nss_archive_version"), "%.", "_"))) +} + +# This is taken from gnutls.spec +%define srpmhash() %{lua: +local files = rpm.expand("%_specdir/nss.spec") +for i, p in ipairs(patches) do + files = files.." "..p +end +for i, p in ipairs(sources) do + files = files.." "..p +end +local sha256sum = assert(io.popen("cat "..files.."| sha256sum")) +local hash = sha256sum:read("*a") +sha256sum:close() +print(string.sub(hash, 0, 16)) +} + +Summary: Network Security Services +Name: nss +Version: %{nss_version} +Release: 11%{?dist} +License: MPLv2.0 +URL: http://www.mozilla.org/projects/security/pki/nss/ +Requires: nspr >= %{nspr_version}%{nspr_release} +Requires: nss-util >= %{nss_version} +# TODO: revert to same version as nss once we are done with the merge +Requires: nss-softokn%{_isa} >= %{nss_version} +Requires: nss-system-init +Requires: p11-kit-trust +Requires: /usr/bin/update-crypto-policies +BuildRequires: nspr-devel >= %{nspr_build_version} +# for shlibsign +BuildRequires: nss-softokn +BuildRequires: sqlite-devel +BuildRequires: zlib-devel +BuildRequires: pkgconfig +BuildRequires: gawk +BuildRequires: psmisc +BuildRequires: perl-interpreter +BuildRequires: gcc-c++ + +Source0: https://ftp.mozilla.org/pub/security/nss/releases/%{nss_release_tag}/src/%{name}-%{nss_archive_version}.tar.gz +Source1: nss-util.pc.in +Source2: nss-util-config.in +Source3: nss-softokn.pc.in +Source4: nss-softokn-config.in +Source6: nss-softokn-dracut-module-setup.sh +Source7: nss-softokn-dracut.conf +Source8: nss.pc.in +Source9: nss-config.in +Source10: blank-cert8.db +Source11: blank-key3.db +Source12: blank-secmod.db +Source13: blank-cert9.db +Source14: blank-key4.db +Source15: system-pkcs11.txt +Source16: setup-nsssysinit.sh +Source20: nss-config.xml +Source21: setup-nsssysinit.xml +Source22: pkcs11.txt.xml +Source23: cert8.db.xml +Source24: cert9.db.xml +Source25: key3.db.xml +Source26: key4.db.xml +Source27: secmod.db.xml +Source28: nss-p11-kit.config + +# To inject hardening flags for DSO +Patch1: nss-dso-ldflags.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, +# when they are included through the quote form (#include "file.h"). +# +# This ensures a build even when system headers are older. Such is the +# case when starting an update with API changes or even private export +# changes. +# +# Once the buildroot aha been bootstrapped the patch may be removed +# but it doesn't hurt to keep it. +Patch4: iquote.patch +# To revert the change in: +# https://bugzilla.mozilla.org/show_bug.cgi?id=818686 +Patch9: nss-sysinit-userdb.patch +# Disable nss-sysinit test which is solely to test the above change +Patch10: nss-skip-sysinit-gtests.patch + +# For compatibility reasons, we stick with the old PKCS #11 2.40 +# definition of CK_GCM_PARAMS: +%if 0%{?fedora} < 34 +%if 0%{?rhel} < 9 +Patch20: nss-gcm-param-default-pkcs11v2.patch +%endif +%endif +# Local patch: disable MD5 (also MD2 and MD4) completely +# https://bugzilla.redhat.com/show_bug.cgi?id=1849938 +Patch25: nss-disable-md5.patch +# Local patch for TLS_ECDHE_{ECDSA|RSA}_WITH_3DES_EDE_CBC_SHA ciphers +Patch30: rhbz1185708-enable-ecc-3des-ciphers-by-default.patch +# Local patch: disable Delegated Credentials +Patch35: nss-disable-dc.patch +# Local patch: ignore rsa, rsa-pss, ecdsa policies until crypto-policies +# is updated. +Patch40: nss-3.66-disable-signature-policies.patch +# Local patch: disable tests that require external reference so brew completes +Patch45: nss-3.66-disable-external-host-test.patch +# Local patch: restore old pkcs 12 defaults on old version of rhel +Patch50: nss-3.66-restore-old-pkcs12-default.patch +# Local Patch: restore expired distrusted certs for now +Patch51: nss-3.79-revert-distrusted-certs.patch +# Local Patch: update fipsdefaults to AES +Patch52: nss-3.79-pkcs12-fips-defaults.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1774659 +Patch60: nss-3.79-dbtool.patch +Patch61: nss-3.79-dont-verify-default.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1774654 +Patch63: nss-3.79-fix-client-cert-crash.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1767883 +Patch64: nss-3.79-rhel-8-fips-signature-policy.patch +Patch65: nss-3.79-enable-POST-rerun.patch +Patch66: nss-3.79-increase-pbe-cache.patch +Patch67: nss-3.79-pkcs12-fix-null-password.patch +Patch68: nss-3.79-fips.patch +# cve 2023-0767, remove on rebase to nss 3.88.1 or later +# https://bugzilla.mozilla.org/show_bug.cgi?id=1804640 +Patch70: cve-2023-0767.patch + +%description +Network Security Services (NSS) is a set of libraries designed to +support cross-platform development of security-enabled client and +server applications. Applications built with NSS can support SSL v2 +and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 +v3 certificates, and other security standards. + +%package tools +Summary: Tools for the Network Security Services +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tools +Network Security Services (NSS) is a set of libraries designed to +support cross-platform development of security-enabled client and +server applications. Applications built with NSS can support SSL v2 +and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 +v3 certificates, and other security standards. + +Install the nss-tools package if you need command-line tools to +manipulate the NSS certificate and key database. + +%package sysinit +Summary: System NSS Initialization +# providing nss-system-init without version so that it can +# be replaced by a better one, e.g. supplied by the os vendor +Provides: nss-system-init +Requires: nss%{?_isa} = %{version}-%{release} +Requires(post): coreutils, sed + +%description sysinit +Default Operating System module that manages applications loading +NSS globally on the system. This module loads the system defined +PKCS #11 modules for NSS and chains with other NSS modules to load +any system or user configured modules. + +%package devel +Summary: Development libraries for Network Security Services +Provides: nss-static = %{version}-%{release} +Requires: nss%{?_isa} = %{version}-%{release} +Requires: nss-util-devel +Requires: nss-softokn-devel +Requires: nspr-devel >= %{nspr_version}%{nspr_release} +Requires: pkgconfig +BuildRequires: xmlto + +%description devel +Header and Library files for doing development with Network Security Services. + + +%package pkcs11-devel +Summary: Development libraries for PKCS #11 (Cryptoki) using NSS +Provides: nss-pkcs11-devel-static = %{version}-%{release} +Requires: nss-devel = %{version}-%{release} +Requires: nss-softokn-freebl-devel = %{version}-%{release} + +%description pkcs11-devel +Library files for developing PKCS #11 modules using basic NSS +low level services. + + +%package util +Summary: Network Security Services Utilities Library +Requires: nspr >= %{nspr_version}%{nspr_release} + +%description util +Utilities for Network Security Services and the Softoken module + +%package util-devel +Summary: Development libraries for Network Security Services Utilities +Requires: nss-util%{?_isa} = %{version}-%{release} +Requires: nspr-devel >= %{nspr_version}%{nspr_release} +Requires: pkgconfig + +%description util-devel +Header and library files for doing development with Network Security Services. + + +%package softokn +Summary: Network Security Services Softoken Module +Requires: nspr >= %{nspr_version}%{nspr_release} +Requires: nss-util >= %{version}-%{release} +Requires: nss-softokn-freebl%{_isa} >= %{version}-%{release} + +%description softokn +Network Security Services Softoken Cryptographic Module + +%package softokn-freebl +Summary: Freebl library for the Network Security Services +# For PR_GetEnvSecure() from nspr >= 4.12 +Requires: nspr >= 4.12 +# For NSS_SecureMemcmpZero() from nss-util >= 3.33 +Requires: nss-util >= 3.33 +Conflicts: nss < 3.12.2.99.3-5 +Conflicts: filesystem < 3 + +%description softokn-freebl +NSS Softoken Cryptographic Module Freebl Library + +Install the nss-softokn-freebl package if you need the freebl library. + +%package softokn-freebl-devel +Summary: Header and Library files for doing development with the Freebl library for NSS +Provides: nss-softokn-freebl-static = %{version}-%{release} +Requires: nss-softokn-freebl%{?_isa} = %{version}-%{release} + +%description softokn-freebl-devel +NSS Softoken Cryptographic Module Freebl Library Development Tools +This package supports special needs of some PKCS #11 module developers and +is otherwise considered private to NSS. As such, the programming interfaces +may change and the usual NSS binary compatibility commitments do not apply. +Developers should rely only on the officially supported NSS public API. + +%package softokn-devel +Summary: Development libraries for Network Security Services +Requires: nss-softokn%{?_isa} = %{version}-%{release} +Requires: nss-softokn-freebl-devel%{?_isa} = %{version}-%{release} +Requires: nspr-devel >= %{nspr_version}%{nspr_release} +Requires: nss-util-devel >= %{version}-%{release} +Requires: pkgconfig +BuildRequires: nspr-devel >= %{nspr_build_version} + +%description softokn-devel +Header and library files for doing development with Network Security Services. + + +%prep +%autosetup -N -n %{name}-%{nss_archive_version} +pushd nss +%autopatch -p1 +popd + +# https://bugzilla.redhat.com/show_bug.cgi?id=1247353 +find nss/lib/libpkix -perm /u+x -type f -exec chmod -x {} \; + +%build + +export FREEBL_NO_DEPEND=1 + +# Must export FREEBL_LOWHASH=1 for nsslowhash.h so that it gets +# copied to dist and the rpm install phase can find it +# This due of the upstream changes to fix +# https://bugzilla.mozilla.org/show_bug.cgi?id=717906 +export FREEBL_LOWHASH=1 + +# 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}-%{srpmhash}" +eval $(sed -n 's/^\(\(NAME\|VERSION_ID\)=.*\)/OS_\1/p' /etc/os-release | sed -e 's/ /\\ /g') +export FIPS_MODULE_OS="$OS_NAME\ ${OS_VERSION_ID%%.*}" +export NSS_FIPS_MODULE_ID="${FIPS_MODULE_OS}\ ${NSS_FIPS_VERSION}" +export NSS_FIPS_140_3=1 +export NSS_ENABLE_FIPS_INDICATORS=1 + +# Enable compiler optimizations and disable debugging code +export BUILD_OPT=1 + +# Uncomment to disable optimizations +#RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed -e 's/-O2/-O0/g'` +#export RPM_OPT_FLAGS + +# Generate symbolic info for debuggers +export XCFLAGS=$RPM_OPT_FLAGS + +export LDFLAGS=$RPM_LD_FLAGS + +export DSO_LDFLAGS=$RPM_LD_FLAGS + +export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 +export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 + +export NSPR_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nspr | sed 's/-I//'` +export NSPR_LIB_DIR=%{_libdir} + +export NSS_USE_SYSTEM_SQLITE=1 + +export NSS_ALLOW_SSLKEYLOGFILE=1 + +export NSS_SEED_ONLY_DEV_URANDOM=1 + +%ifnarch noarch +%if 0%{__isa_bits} == 64 +export USE_64=1 +%endif +%endif + +# Set the policy file location +# if set NSS will always check for the policy file and load if it exists +export POLICY_FILE="nss.config" +# location of the policy file +export POLICY_PATH="/etc/crypto-policies/back-ends" + +%{__make} -C ./nss all +%{__make} -C ./nss latest + +# build the man pages clean +pushd ./nss/doc +rm -rf ./nroff +make clean +echo -n %{manual_date} > date.xml +echo -n %{version} > version.xml +make +popd + +# and copy them to the dist directory for %%install to find them +mkdir -p ./dist/docs/nroff +cp ./nss/doc/nroff/* ./dist/docs/nroff + +# Set up our package files +mkdir -p ./dist/pkgconfig + +cat %{SOURCE1} | sed -e "s,%%libdir%%,%{_libdir},g" \ + -e "s,%%prefix%%,%{_prefix},g" \ + -e "s,%%exec_prefix%%,%{_prefix},g" \ + -e "s,%%includedir%%,%{_includedir}/nss3,g" \ + -e "s,%%NSPR_VERSION%%,%{nspr_version},g" \ + -e "s,%%NSSUTIL_VERSION%%,%{version},g" > \ + ./dist/pkgconfig/nss-util.pc + +NSSUTIL_VMAJOR=`cat nss/lib/util/nssutil.h | grep "#define.*NSSUTIL_VMAJOR" | awk '{print $3}'` +NSSUTIL_VMINOR=`cat nss/lib/util/nssutil.h | grep "#define.*NSSUTIL_VMINOR" | awk '{print $3}'` +NSSUTIL_VPATCH=`cat nss/lib/util/nssutil.h | grep "#define.*NSSUTIL_VPATCH" | awk '{print $3}'` + +cat %{SOURCE2} | sed -e "s,@libdir@,%{_libdir},g" \ + -e "s,@prefix@,%{_prefix},g" \ + -e "s,@exec_prefix@,%{_prefix},g" \ + -e "s,@includedir@,%{_includedir}/nss3,g" \ + -e "s,@MOD_MAJOR_VERSION@,$NSSUTIL_VMAJOR,g" \ + -e "s,@MOD_MINOR_VERSION@,$NSSUTIL_VMINOR,g" \ + -e "s,@MOD_PATCH_VERSION@,$NSSUTIL_VPATCH,g" \ + > ./dist/pkgconfig/nss-util-config + +chmod 755 ./dist/pkgconfig/nss-util-config + +cat %{SOURCE3} | sed -e "s,%%libdir%%,%{_libdir},g" \ + -e "s,%%prefix%%,%{_prefix},g" \ + -e "s,%%exec_prefix%%,%{_prefix},g" \ + -e "s,%%includedir%%,%{_includedir}/nss3,g" \ + -e "s,%%NSPR_VERSION%%,%{nspr_version},g" \ + -e "s,%%NSSUTIL_VERSION%%,%{nss_version},g" \ + -e "s,%%SOFTOKEN_VERSION%%,%{version},g" > \ + ./dist/pkgconfig/nss-softokn.pc + +SOFTOKEN_VMAJOR=`cat nss/lib/softoken/softkver.h | grep "#define.*SOFTOKEN_VMAJOR" | awk '{print $3}'` +SOFTOKEN_VMINOR=`cat nss/lib/softoken/softkver.h | grep "#define.*SOFTOKEN_VMINOR" | awk '{print $3}'` +SOFTOKEN_VPATCH=`cat nss/lib/softoken/softkver.h | grep "#define.*SOFTOKEN_VPATCH" | awk '{print $3}'` + +cat %{SOURCE4} | sed -e "s,@libdir@,%{_libdir},g" \ + -e "s,@prefix@,%{_prefix},g" \ + -e "s,@exec_prefix@,%{_prefix},g" \ + -e "s,@includedir@,%{_includedir}/nss3,g" \ + -e "s,@MOD_MAJOR_VERSION@,$SOFTOKEN_VMAJOR,g" \ + -e "s,@MOD_MINOR_VERSION@,$SOFTOKEN_VMINOR,g" \ + -e "s,@MOD_PATCH_VERSION@,$SOFTOKEN_VPATCH,g" \ + > ./dist/pkgconfig/nss-softokn-config + +chmod 755 ./dist/pkgconfig/nss-softokn-config + +cat %{SOURCE8} | sed -e "s,%%libdir%%,%{_libdir},g" \ + -e "s,%%prefix%%,%{_prefix},g" \ + -e "s,%%exec_prefix%%,%{_prefix},g" \ + -e "s,%%includedir%%,%{_includedir}/nss3,g" \ + -e "s,%%NSS_VERSION%%,%{version},g" \ + -e "s,%%NSPR_VERSION%%,%{nspr_version},g" \ + -e "s,%%NSSUTIL_VERSION%%,%{nss_version},g" \ + -e "s,%%SOFTOKEN_VERSION%%,%{nss_version},g" > \ + ./dist/pkgconfig/nss.pc + +NSS_VMAJOR=`cat nss/lib/nss/nss.h | grep "#define.*NSS_VMAJOR" | awk '{print $3}'` +NSS_VMINOR=`cat nss/lib/nss/nss.h | grep "#define.*NSS_VMINOR" | awk '{print $3}'` +NSS_VPATCH=`cat nss/lib/nss/nss.h | grep "#define.*NSS_VPATCH" | awk '{print $3}'` + +cat %{SOURCE9} | sed -e "s,@libdir@,%{_libdir},g" \ + -e "s,@prefix@,%{_prefix},g" \ + -e "s,@exec_prefix@,%{_prefix},g" \ + -e "s,@includedir@,%{_includedir}/nss3,g" \ + -e "s,@MOD_MAJOR_VERSION@,$NSS_VMAJOR,g" \ + -e "s,@MOD_MINOR_VERSION@,$NSS_VMINOR,g" \ + -e "s,@MOD_PATCH_VERSION@,$NSS_VPATCH,g" \ + > ./dist/pkgconfig/nss-config + +chmod 755 ./dist/pkgconfig/nss-config + +cat %{SOURCE16} > ./dist/pkgconfig/setup-nsssysinit.sh +chmod 755 ./dist/pkgconfig/setup-nsssysinit.sh + +cp ./nss/lib/ckfw/nssck.api ./dist/private/nss/ + +date +"%e %B %Y" | tr -d '\n' > date.xml +echo -n %{version} > version.xml + +# configuration files and setup script +for m in %{SOURCE20} %{SOURCE21} %{SOURCE22}; do + cp ${m} . +done +for m in nss-config.xml setup-nsssysinit.xml pkcs11.txt.xml; do + xmlto man ${m} +done + +# nss databases considered to be configuration files +for m in %{SOURCE23} %{SOURCE24} %{SOURCE25} %{SOURCE26} %{SOURCE27}; do + cp ${m} . +done +for m in cert8.db.xml cert9.db.xml key3.db.xml key4.db.xml secmod.db.xml; do + xmlto man ${m} +done + + +%check +%if %{with tests} +# Begin -- copied from the build section + +export FREEBL_NO_DEPEND=1 + +export BUILD_OPT=1 + +%ifnarch noarch +%if 0%{__isa_bits} == 64 +export USE_64=1 +%endif +%endif + +# End -- copied from the build section + +# This is necessary because the test suite tests algorithms that are +# disabled by the system policy. +export NSS_IGNORE_SYSTEM_POLICY=1 + +# enable the following line to force a test failure +# find ./nss -name \*.chk | xargs rm -f + +# Run test suite. +# In order to support multiple concurrent executions of the test suite +# (caused by concurrent RPM builds) on a single host, +# we'll use a random port. Also, we want to clean up any stuck +# selfserv processes. If process name "selfserv" is used everywhere, +# we can't simply do a "killall selfserv", because it could disturb +# concurrent builds. Therefore we'll do a search and replace and use +# a different process name. +# Using xargs doesn't mix well with spaces in filenames, in order to +# avoid weird quoting we'll require that no spaces are being used. + +SPACEISBAD=`find ./nss/tests | grep -c ' '` ||: +if [ $SPACEISBAD -ne 0 ]; then + echo "error: filenames containing space are not supported (xargs)" + exit 1 +fi +MYRAND=`perl -e 'print 9000 + int rand 1000'`; echo $MYRAND ||: +RANDSERV=selfserv_${MYRAND}; echo $RANDSERV ||: +DISTBINDIR=`ls -d ./dist/*.OBJ/bin`; echo $DISTBINDIR ||: +pushd "$DISTBINDIR" +ln -s selfserv $RANDSERV +popd +# man perlrun, man perlrequick +# replace word-occurrences of selfserv with selfserv_$MYRAND +find ./nss/tests -type f |\ + grep -v "\.db$" |grep -v "\.crl$" | grep -v "\.crt$" |\ + grep -vw CVS |xargs grep -lw selfserv |\ + xargs -l perl -pi -e "s/\bselfserv\b/$RANDSERV/g" ||: + +killall $RANDSERV || : + +rm -rf ./tests_results +pushd nss/tests +# all.sh is the test suite script + +# don't need to run all the tests when testing packaging +export NSS_DEFAULT_DB_TYPE=dbm #in RHEL 8, the default db is sql, but we want + # standard to test dbm, or upgradedb will fail +%define nss_cycles "standard pkix upgradedb sharedb threadunsafe" +# the full list from all.sh is: +# "cipher lowhash libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests" +%define nss_tests "libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests" +# nss_ssl_tests: crl bypass_normal normal_bypass normal_fips fips_normal iopr policy +# nss_ssl_run: cov auth stapling stress +# +# Uncomment these lines if you need to temporarily +# disable some test suites for faster test builds +# % define nss_ssl_tests "normal_fips" +# % define nss_ssl_run "cov" + +HOST=localhost DOMSUF=localdomain PORT=$MYRAND NSS_CYCLES=%{?nss_cycles} NSS_TESTS=%{?nss_tests} NSS_SSL_TESTS=%{?nss_ssl_tests} NSS_SSL_RUN=%{?nss_ssl_run} ./all.sh +popd + +%endif + +%install + +# There is no make install target so we'll do it ourselves. + +mkdir -p $RPM_BUILD_ROOT/%{_includedir}/nss3 +mkdir -p $RPM_BUILD_ROOT/%{_includedir}/nss3/templates +mkdir -p $RPM_BUILD_ROOT/%{_bindir} +mkdir -p $RPM_BUILD_ROOT/%{_libdir} +mkdir -p $RPM_BUILD_ROOT/%{unsupported_tools_directory} +mkdir -p $RPM_BUILD_ROOT/%{_libdir}/pkgconfig +mkdir -p $RPM_BUILD_ROOT/%{saved_files_dir} +mkdir -p $RPM_BUILD_ROOT/%{dracut_modules_dir} +mkdir -p $RPM_BUILD_ROOT/%{dracut_conf_dir} +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/crypto-policies/local.d +%if %{defined rhel} +# not needed for rhel and its derivatives only fedora +%else +# because of the pp.1 conflict with perl-PAR-Packer +mkdir -p $RPM_BUILD_ROOT%{_datadir}/doc/nss-tools +%endif + +install -m 755 %{SOURCE6} $RPM_BUILD_ROOT/%{dracut_modules_dir}/module-setup.sh +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT/%{dracut_conf_dir}/50-nss-softokn.conf + +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man5 + +# Copy the binary libraries we want +for file in libnssutil3.so libsoftokn3.so libnssdbm3.so libfreebl3.so libfreeblpriv3.so libnss3.so libnsssysinit.so libsmime3.so libssl3.so +do + install -p -m 755 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir} +done + +# Install the empty NSS db files +# Legacy db +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb +install -p -m 644 %{SOURCE10} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/cert8.db +install -p -m 644 %{SOURCE11} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/key3.db +install -p -m 644 %{SOURCE12} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/secmod.db +# Shared db +install -p -m 644 %{SOURCE13} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/cert9.db +install -p -m 644 %{SOURCE14} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/key4.db +install -p -m 644 %{SOURCE15} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/pkcs11.txt + +# Copy the development libraries we want +for file in libcrmf.a libnssb.a libnssckfw.a +do + install -p -m 644 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir} +done + +# Copy the binaries we want +for file in certutil cmsutil crlutil modutil nss-policy-check pk12util signver ssltap +do + install -p -m 755 dist/*.OBJ/bin/$file $RPM_BUILD_ROOT/%{_bindir} +done + +# Copy the binaries we ship as unsupported +for file in bltest dbtool 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 + +# Copy the include files we want +for file in dist/public/nss/*.h +do + install -p -m 644 $file $RPM_BUILD_ROOT/%{_includedir}/nss3 +done + +# Copy some freebl include files we also want +for file in blapi.h alghmac.h cmac.h +do + install -p -m 644 dist/private/nss/$file $RPM_BUILD_ROOT/%{_includedir}/nss3 +done + +# Copy the static freebl library +for file in libfreebl.a +do +install -p -m 644 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir} +done + +# Copy the template files we want +for file in dist/private/nss/templates.c dist/private/nss/nssck.api +do + install -p -m 644 $file $RPM_BUILD_ROOT/%{_includedir}/nss3/templates +done + +# Copy the package configuration files +install -p -m 644 ./dist/pkgconfig/nss-util.pc $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/nss-util.pc +install -p -m 755 ./dist/pkgconfig/nss-util-config $RPM_BUILD_ROOT/%{_bindir}/nss-util-config +install -p -m 644 ./dist/pkgconfig/nss-softokn.pc $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/nss-softokn.pc +install -p -m 755 ./dist/pkgconfig/nss-softokn-config $RPM_BUILD_ROOT/%{_bindir}/nss-softokn-config +install -p -m 644 ./dist/pkgconfig/nss.pc $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/nss.pc +install -p -m 755 ./dist/pkgconfig/nss-config $RPM_BUILD_ROOT/%{_bindir}/nss-config +# Copy the pkcs #11 configuration script +install -p -m 755 ./dist/pkgconfig/setup-nsssysinit.sh $RPM_BUILD_ROOT/%{_bindir}/setup-nsssysinit.sh +# install a symbolic link to it, without the ".sh" suffix, +# that matches the man page documentation +ln -r -s -f $RPM_BUILD_ROOT/%{_bindir}/setup-nsssysinit.sh $RPM_BUILD_ROOT/%{_bindir}/setup-nsssysinit + +# Copy the man pages for scripts +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 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} +install -c -m 644 ./dist/docs/nroff/pp.1 $RPM_BUILD_ROOT%{_mandir}/man1/pp.1 +%else +install -c -m 644 ./dist/docs/nroff/pp.1 $RPM_BUILD_ROOT%{_datadir}/doc/nss-tools/pp.1 +%endif + +# Copy the man pages for the configuration files +for f in pkcs11.txt; do + install -c -m 644 ${f}.5 $RPM_BUILD_ROOT%{_mandir}/man5/${f}.5 +done +# Copy the man pages for the nss databases +for f in cert8.db cert9.db key3.db key4.db secmod.db; do + install -c -m 644 ${f}.5 $RPM_BUILD_ROOT%{_mandir}/man5/${f}.5 +done + +# Copy the crypto-policies configuration file +install -p -m 644 %{SOURCE28} $RPM_BUILD_ROOT/%{_sysconfdir}/crypto-policies/local.d + +%triggerpostun -n nss-sysinit -- nss-sysinit < 3.12.8-3 +# Reverse unwanted disabling of sysinit by faulty preun sysinit scriplet +# from previous versions of nss.spec +/usr/bin/setup-nsssysinit.sh on + +%posttrans +update-crypto-policies --no-reload &> /dev/null || : + + +%files +%{!?_licensedir:%global license %%doc} +%license nss/COPYING +%{_libdir}/libnss3.so +%{_libdir}/libssl3.so +%{_libdir}/libsmime3.so +%dir %{_sysconfdir}/pki/nssdb +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/cert8.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/key3.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/secmod.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/cert9.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/key4.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/pkcs11.txt +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/crypto-policies/local.d/nss-p11-kit.config +%doc %{_mandir}/man5/cert8.db.5* +%doc %{_mandir}/man5/key3.db.5* +%doc %{_mandir}/man5/secmod.db.5* +%doc %{_mandir}/man5/cert9.db.5* +%doc %{_mandir}/man5/key4.db.5* +%doc %{_mandir}/man5/pkcs11.txt.5* + +%files sysinit +%{_libdir}/libnsssysinit.so +%{_bindir}/setup-nsssysinit.sh +# symbolic link to setup-nsssysinit.sh +%{_bindir}/setup-nsssysinit +%doc %{_mandir}/man1/setup-nsssysinit.1* + +%files tools +%{_bindir}/certutil +%{_bindir}/cmsutil +%{_bindir}/crlutil +%{_bindir}/modutil +%{_bindir}/nss-policy-check +%{_bindir}/pk12util +%{_bindir}/signver +%{_bindir}/ssltap +%{unsupported_tools_directory}/atob +%{unsupported_tools_directory}/btoa +%{unsupported_tools_directory}/derdump +%{unsupported_tools_directory}/listsuites +%{unsupported_tools_directory}/ocspclnt +%{unsupported_tools_directory}/pp +%{unsupported_tools_directory}/selfserv +%{unsupported_tools_directory}/signtool +%{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 +# supported tools +%doc %{_mandir}/man1/certutil.1* +%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 +%doc %{_mandir}/man1/derdump.1* +%doc %{_mandir}/man1/signtool.1* +%if %{defined rhel} +%doc %{_mandir}/man1/pp.1* +%else +%dir %{_datadir}/doc/nss-tools +%doc %{_datadir}/doc/nss-tools/pp.1 +%endif +%doc %{_mandir}/man1/ssltap.1* +%doc %{_mandir}/man1/vfychain.1* +%doc %{_mandir}/man1/vfyserv.1* + +%files devel +%{_libdir}/libcrmf.a +%{_libdir}/pkgconfig/nss.pc +%{_bindir}/nss-config +%doc %{_mandir}/man1/nss-config.1* + +%dir %{_includedir}/nss3 +%{_includedir}/nss3/cert.h +%{_includedir}/nss3/certdb.h +%{_includedir}/nss3/certt.h +%{_includedir}/nss3/cmmf.h +%{_includedir}/nss3/cmmft.h +%{_includedir}/nss3/cms.h +%{_includedir}/nss3/cmsreclist.h +%{_includedir}/nss3/cmst.h +%{_includedir}/nss3/crmf.h +%{_includedir}/nss3/crmft.h +%{_includedir}/nss3/cryptohi.h +%{_includedir}/nss3/cryptoht.h +%{_includedir}/nss3/sechash.h +%{_includedir}/nss3/jar-ds.h +%{_includedir}/nss3/jar.h +%{_includedir}/nss3/jarfile.h +%{_includedir}/nss3/key.h +%{_includedir}/nss3/keyhi.h +%{_includedir}/nss3/keyt.h +%{_includedir}/nss3/keythi.h +%{_includedir}/nss3/nss.h +%{_includedir}/nss3/nssckbi.h +%{_includedir}/nss3/ocsp.h +%{_includedir}/nss3/ocspt.h +%{_includedir}/nss3/p12.h +%{_includedir}/nss3/p12plcy.h +%{_includedir}/nss3/p12t.h +%{_includedir}/nss3/pk11func.h +%{_includedir}/nss3/pk11hpke.h +%{_includedir}/nss3/pk11pqg.h +%{_includedir}/nss3/pk11priv.h +%{_includedir}/nss3/pk11pub.h +%{_includedir}/nss3/pk11sdr.h +%{_includedir}/nss3/pkcs12.h +%{_includedir}/nss3/pkcs12t.h +%{_includedir}/nss3/pkcs7t.h +%{_includedir}/nss3/preenc.h +%{_includedir}/nss3/secmime.h +%{_includedir}/nss3/secmod.h +%{_includedir}/nss3/secmodt.h +%{_includedir}/nss3/secpkcs5.h +%{_includedir}/nss3/secpkcs7.h +%{_includedir}/nss3/smime.h +%{_includedir}/nss3/ssl.h +%{_includedir}/nss3/sslerr.h +%{_includedir}/nss3/sslexp.h +%{_includedir}/nss3/sslproto.h +%{_includedir}/nss3/sslt.h + +%files pkcs11-devel +%{_includedir}/nss3/nssbase.h +%{_includedir}/nss3/nssbaset.h +%{_includedir}/nss3/nssckepv.h +%{_includedir}/nss3/nssckft.h +%{_includedir}/nss3/nssckfw.h +%{_includedir}/nss3/nssckfwc.h +%{_includedir}/nss3/nssckfwt.h +%{_includedir}/nss3/nssckg.h +%{_includedir}/nss3/nssckmdt.h +%{_includedir}/nss3/nssckt.h +%{_includedir}/nss3/templates/nssck.api +%{_libdir}/libnssb.a +%{_libdir}/libnssckfw.a + +%files util +%{!?_licensedir:%global license %%doc} +%license nss/COPYING +%{_libdir}/libnssutil3.so + +%files util-devel +# package configuration files +%{_libdir}/pkgconfig/nss-util.pc +%{_bindir}/nss-util-config + +# co-owned with nss +%dir %{_includedir}/nss3 +# these are marked as public export in nss/lib/util/manifest.mk +%{_includedir}/nss3/base64.h +%{_includedir}/nss3/ciferfam.h +%{_includedir}/nss3/eccutil.h +%{_includedir}/nss3/hasht.h +%{_includedir}/nss3/nssb64.h +%{_includedir}/nss3/nssb64t.h +%{_includedir}/nss3/nsslocks.h +%{_includedir}/nss3/nssilock.h +%{_includedir}/nss3/nssilckt.h +%{_includedir}/nss3/nssrwlk.h +%{_includedir}/nss3/nssrwlkt.h +%{_includedir}/nss3/nssutil.h +%{_includedir}/nss3/pkcs1sig.h +%{_includedir}/nss3/pkcs11.h +%{_includedir}/nss3/pkcs11f.h +%{_includedir}/nss3/pkcs11n.h +%{_includedir}/nss3/pkcs11p.h +%{_includedir}/nss3/pkcs11t.h +%{_includedir}/nss3/pkcs11u.h +%{_includedir}/nss3/pkcs11uri.h +%{_includedir}/nss3/portreg.h +%{_includedir}/nss3/secasn1.h +%{_includedir}/nss3/secasn1t.h +%{_includedir}/nss3/seccomon.h +%{_includedir}/nss3/secder.h +%{_includedir}/nss3/secdert.h +%{_includedir}/nss3/secdig.h +%{_includedir}/nss3/secdigt.h +%{_includedir}/nss3/secerr.h +%{_includedir}/nss3/secitem.h +%{_includedir}/nss3/secoid.h +%{_includedir}/nss3/secoidt.h +%{_includedir}/nss3/secport.h +%{_includedir}/nss3/utilmodt.h +%{_includedir}/nss3/utilpars.h +%{_includedir}/nss3/utilparst.h +%{_includedir}/nss3/utilrename.h +%{_includedir}/nss3/templates/templates.c + +%files softokn +%{_libdir}/libnssdbm3.so +%{_libdir}/libnssdbm3.chk +%{_libdir}/libsoftokn3.so +%{_libdir}/libsoftokn3.chk +# shared with nss-tools +%dir %{_libdir}/nss +%dir %{saved_files_dir} +%dir %{unsupported_tools_directory} +%{unsupported_tools_directory}/bltest +%{unsupported_tools_directory}/dbtool +%{unsupported_tools_directory}/ecperf +%{unsupported_tools_directory}/fbectest +%{unsupported_tools_directory}/fipstest +%{unsupported_tools_directory}/shlibsign + +%files softokn-freebl +%{!?_licensedir:%global license %%doc} +%license nss/COPYING +%{_libdir}/libfreebl3.so +%{_libdir}/libfreebl3.chk +%{_libdir}/libfreeblpriv3.so +%{_libdir}/libfreeblpriv3.chk +#shared +%dir %{dracut_modules_dir} +%{dracut_modules_dir}/module-setup.sh +%{dracut_conf_dir}/50-nss-softokn.conf + +%files softokn-freebl-devel +%{_libdir}/libfreebl.a +%{_includedir}/nss3/blapi.h +%{_includedir}/nss3/blapit.h +%{_includedir}/nss3/alghmac.h +%{_includedir}/nss3/cmac.h +%{_includedir}/nss3/lowkeyi.h +%{_includedir}/nss3/lowkeyti.h + +%files softokn-devel +%{_libdir}/pkgconfig/nss-softokn.pc +%{_bindir}/nss-softokn-config + +# co-owned with nss +%dir %{_includedir}/nss3 +# +# The following headers are those exported public in +# nss/lib/freebl/manifest.mn and +# nss/lib/softoken/manifest.mn +# +# The following list is short because many headers, such as +# the pkcs #11 ones, have been provided by nss-util-devel +# which installed them before us. +# +%{_includedir}/nss3/ecl-exp.h +%{_includedir}/nss3/nsslowhash.h +%{_includedir}/nss3/shsign.h + + +%changelog +* Wed Mar 8 2023 Bob Relyea - 3.79.0-11 +- Fix CVE-2023-0767 + +* Thu Aug 11 2022 Bob Relyea - 3.79.0-10 +- Fix QA found failures: +- remove extra '+' from sslpolicy.txt file causing test error values +- only use GRND_RANDOM if the kernel is in FIPS mode. + +* Fri Aug 5 2022 Bob Relyea - 3.79.0-9 +- FIPS 140-3 changes + +* Wed Jul 13 2022 Bob Relyea - 3.79.0-8 +- Update fips default for pk12util to AES rather than TDES +- Fix bug in pkcs12 files with null passwords + +* Wed Jul 6 2022 Bob Relyea - 3.79.0-7 +- Better fix for test regressions + +* Mon Jun 27 2022 Bob Relyea - 3.79.0-6 +- fix nss.spec so it works in a rhel-8.1.0 buildroot + +* Mon Jun 20 2022 Bob Relyea - 3.79.0-5 +- FIPS 140-3 changes +- Reject Small RSA keys, 1024 bit keys are marked as FIP OK when verifying, reject + signature keys by policy +- Allow applications to retrigger selftests on demand. + +* Fri Jun 17 2022 Bob Relyea - 3.79.0-4 +- Fix pkgconfig output + +* Wed Jun 15 2022 Bob Relyea - 3.79.0-3 +- NSR Coverity fix changed selfserv from passive to active, change it back + +* Sat Jun 11 2022 Bob Relyea - 3.79.0-2 +- Fix regressions found in test suites. + +* Thu Jun 2 2022 Bob Relyea - 3.79.0-1 +- Rebase to NSS 3.79 +- Set FIPS Module ID +- skip attribute verification on attributes with default values +- don't export trust objects if they are default trust objects from dbm +- add dbtool to nss-tools + +* Thu Nov 18 2021 Bob Relyea - 3.67.0-7 +- Fix CVE 2021 43527 + +* Tue Jul 6 2021 Bob Relyea - 3.67.0-6 +- Fix ssl alert issue + +* Thu Jul 1 2021 Bob Relyea - 3.67.0-5 +- Fix issue with reading databases that were updated using + unpatched versions of nss + +* Tue Jun 29 2021 Bob Relyea - 3.67.0-4 +- Better fix for the sdb timeout. The issue wasn't a race, it was + the sqlite timeout waiting to begin a transaction under heavy + thread usage. + +* Mon Jun 28 2021 Bob Relyea - 3.67.0-3 +- Fix sdb race condition + +* Fri Jun 18 2021 Bob Relyea - 3.67.0-2 +- Fix coverity issues + +* Thu Jun 17 2021 Bob Relyea - 3.67.0-1 +- Rebase to NSS 3.67 + +* Tue Jun 15 2021 Bob Relyea - 3.66.0-2 +- Restore old pkcs12 defaults. + +* Mon Jun 14 2021 Bob Relyea - 3.66.0-1.1 +- build nss for older nspr so we can pass gating with + the new nspr in the build root + +* Wed Jun 2 2021 Bob Relyea - 3.66.0-1 +- Rebase to NSS 3.66 + +* Thu Dec 3 2020 Bob Relyea - 3.53.1-17 +- Fix various corner cases with ike v1 app b support. + +* Thu Nov 19 2020 Bob Relyea - 3.53.1-16 +- Fix the following CVE +- CVE-2020-12403 chacha-poly issues +- CVE-2020-12400 constant time ECC. +- CVE-2020-6829 constant time ECC. + +* Wed Nov 4 2020 Bob Relyea - 3.53.1-15 +- Revert some policy changes the generate ABI runtime issues. + +* Thu Oct 29 2020 Bob Relyea - 3.53.1-14 +- Add support for enable/disable in policy. Now if your policy + file has disallow=x enable=y it will act just like our other + libraries. + +* Mon Oct 26 2020 Bob Relyea - 3.53.1-13 +- Add OAEP interface so applications can wrap keys with RSA-OAEP + rather than RSA-PKCS-1. + +* Mon Oct 19 2020 Bob Relyea - 3.53.1-12 +- fips need to reject small primes even if they are approved +- code to autodetect whether or not to use the cache needs to do so + in a way that doesn't mess with filesystem negative file caching. +- add kdf selftests + +* Thu Jul 30 2020 Bob Relyea - 3.53.1-11 +- Fix issue with upgradedb where upgradedb expects standard to + generate dbm databases, not sql databases (default in RHEL8) + +* Thu Jul 30 2020 Bob Relyea - 3.53.1-10 +- Disable dh timing test because it's unreliable on s390 + +* Thu Jul 30 2020 Daiki Ueno - 3.53.1-9 +- Explicitly enable upgradedb/sharedb test cycles + +* Wed Jul 29 2020 Daiki Ueno - 3.53.1-8 +- Disable Delegated Credentials for TLS + +* Fri Jul 24 2020 Bob Relyea - 3.53.1-7 +- Fix attribute decryption issue where the private key components + integrity check on private attributes where not being checked. + +* Mon Jul 13 2020 Daiki Ueno - 3.53.1-6 +- Update nss-rsa-pkcs1-sigalgs.patch to the upstream version + +* Sat Jul 11 2020 Bob Relyea - 3.53.1-5 +- Include required checks for dh and ecdh key generation in FIPS mode. + +* Wed Jul 8 2020 Bob Relyea - 3.53.1-4 +- Add better checks for dh derive operations in FIPS mode. + +* Thu Jun 25 2020 Daiki Ueno - 3.53.1-3 +- Disable NSS_HASH_ALG_SUPPORT as well for MD5 (#1849938) +- Adjust for update-crypto-policies packaging change (#1848649) +- Fix compilation with -Werror=strict-prototypes (#1843417) + +* Wed Jun 24 2020 Daiki Ueno - 3.53.1-2 +- Fix regression in MD5 disablement (#1849938) +- Include rsa_pkcs1_* in signature_algorithms extension (#1847945) + +* Mon Jun 22 2020 Daiki Ueno - 3.53.1-1 +- Update to NSS 3.53.1 + +* Sat Jun 6 2020 Daiki Ueno - 3.53.0-1 +- Update to NSS 3.53 + +* Fri Jan 31 2020 Bob Relyea - 3.44.0-15 +- Fix swapped CMAC PKCS #11 values. +- Fix data alignment crash in CMAC. + +* Tue Dec 3 2019 Bob Relyea - 3.44.0-14 +- Fix coverify scan issue + +* Mon Dec 2 2019 Bob Relyea - 3.44.0-13 +- Fix endian problem in SP-800 108 code. + +* Thu Nov 28 2019 Daiki Ueno - 3.44.0-12 +- Install cmac.h required by blapi.h (#1764513) +- Fix out-of-bounds write in NSC_EncryptUpdate (#1775913) + +* Wed Nov 27 2019 Bob Relyea - 3.44.0-11 +- Add SP-800 108 Generalized kdf + +* Mon Nov 11 2019 Daiki Ueno - 3.44.0-10 +- Check policy against hash algorithms used for ServerKeyExchange (#1730039) + +* Wed Nov 6 2019 Bob Relyea - 3.44.0-9 +- Add CMAC + +* Thu Aug 8 2019 Bob Relyea - 3.44.0-8 +- CKM_NSS_IKE1_APP_B_PRF_DERIVE was missing from the mechanism list, preventing + PK11_Derive*() from using it. Add gtests for the PK11_Derive interface for + all the CKM_NSS_IKE*_DERIVE mechanism. + +* Wed Jul 3 2019 Daiki Ueno - 3.44.0-7 +- Backport fixes from 3.44.1 + +* Wed Jun 26 2019 Daiki Ueno - 3.44.0-6 +- Add continuous RNG test required by FIPS +- fipstest: use CKM_TLS12_MASTER_KEY_DERIVE instead of vendor specific mechanism + +* Mon Jun 10 2019 Daiki Ueno - 3.44.0-5 +- Rebuild with the correct build target + +*Fri Jun 7 2019 Bob Relyea - 3.44.0-4.1 +- rebuild to try to retrigger CI tests + +*Wed Jun 5 2019 Bob Relyea - 3.44.0-4 +- Fix certutil man page +- Fix extracting a public key from a private key for dh, ec, and dsa + +* Thu May 30 2019 Daiki Ueno - 3.44.0-3 +- Disable TLS 1.3 under FIPS mode +- Disable RSASSA-PKCS1-v1_5 in TLS 1.3 +- Fix post-handshake auth transcript calculation if + SSL_ENABLE_SESSION_TICKETS is set +- Revert the change to use XDG basedirs (mozilla#818686) + +* Fri May 24 2019 Bob Relyea - 3.44.0-2 +- Add ike mechanisms in softokn +- Add FIPS checks in softoken + +* Fri May 24 2019 Daiki Ueno - 3.44.0-1 +- Update to NSS 3.44 +- Define NSS_SEED_ONLY_DEV_URANDOM=1 to exclusively use getentropy +- Use %%autosetup +- Clean up manual pages generation +- Clean up %%check +- Remove prelink dependency, which is not available in RHEL-8 +- Remove upstreamed patches + +* Mon Dec 17 2018 Daiki Ueno - 3.41.0-5 +- Update manual pages to reflect recent changes in commands + +* Fri Dec 14 2018 Bob Relyea - 3.41.0-4 +- Make sure corresponding public keys are created when importing private keys. + +* Thu Dec 13 2018 Daiki Ueno - 3.41.0-3 +- Fix the last change +- Add --no-reload option to update-crypto-policies to avoid + unnecessary restart of daemons + +* Thu Dec 13 2018 Daiki Ueno - 3.41.0-2 +- Restore LDFLAGS injection when linking DSO + +* Mon Dec 10 2018 Daiki Ueno - 3.41.0-1 +- Update to NSS 3.41 +- Consolidate nss-util, nss-softokn, and nss into a single source package + +* Fri Dec 7 2018 Daiki Ueno - 3.39.0-1.5 +- Fix the last commit + +* Tue Dec 4 2018 Bob Relyea - 3.39.0-1.4 +- Support for IKE/IPsec typical PKIX usage so libreswan can use nss + without rejecting certs based on EKU + +* Thu Nov 29 2018 Daiki Ueno - 3.39.0-1.3 +- Backport upstream fixes for rhbz#1649026, rhbz#1608895, rhbz#1644854 +- Document PKCS #11 URI +- Add warning when adding module with modutil while p11-kit is enabled + +* Tue Nov 13 2018 Daiki Ueno - 3.39.0-1.2 +- Update nss-dsa.patch to not advertise DSA signature algorithm +- Update PayPal test certs for testing + +* Thu Oct 18 2018 Daiki Ueno - 3.39.0-1.1 +- Backport "DSA" keyword in crypto-policies + +* Tue Sep 25 2018 Daiki Ueno - 3.39.0-1.0 +- Update to NSS 3.39 + +* Fri Sep 14 2018 Daiki Ueno - 3.38.0-1.2 +- Fix LDFLAGS injection when linking DSO + +* Tue Jul 24 2018 Daiki Ueno - 3.38.0-1.1 +- Install crypto-policies configuration file for + https://fedoraproject.org/wiki/Changes/NSSLoadP11KitModules +- Port enable-fips-when-system-is-in-fips-mode.patch from RHEL-7 +- Use %%ldconfig_scriptlets +- Remove needless use of %defattr, by Jason Tibbitts + +* Wed Jul 18 2018 Daiki Ueno - 3.38.0-1.0 +- Update to NSS 3.38 + +* Tue Jul 17 2018 Kai Engert - 3.36.1-1.2 +- Backport upstream addition of nss-policy-check utility, rhbz#1428746, + includes required fixes for mozbz#1296263 and mozbz#1474875 + +* Fri May 25 2018 Daiki Ueno - 3.36.1-1.1 +- Switch the default DB type to SQL +- Enable SSLKEYLOGFILE + +* Wed Apr 11 2018 Daiki Ueno - 3.36.1-1.0 +- Update to NSS 3.36.1 +- Remove nss-3.14.0.0-disble-ocsp-test.patch +- Fix partial injection of LDFLAGS +- Remove NSS_NO_PKCS11_BYPASS, which is no-op in upstream + +* Fri Mar 9 2018 Daiki Ueno - 3.36.0-1.0 +- Update to NSS 3.36.0 +- Add gcc-c++ to BuildRequires (C++ is needed for gtests) +- Make test failure detection robuster + +* Thu Feb 08 2018 Fedora Release Engineering - 3.35.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Jan 29 2018 Kai Engert - 3.35.0-4 +- Fix a compiler error with gcc 8, mozbz#1434070 +- Set NSS_FORCE_FIPS=1 at %%build time, and remove from %%check. + +* Mon Jan 29 2018 Kai Engert - 3.35.0-3 +- Stop pulling in nss-pem automatically, packages that need it should + depend on it, rhbz#1539401 + +* Tue Jan 23 2018 Daiki Ueno - 3.35.0-2 +- Update to NSS 3.35.0 + +* Tue Nov 14 2017 Daiki Ueno - 3.34.0-2 +- Update to NSS 3.34.0 + +* Fri Nov 10 2017 Daiki Ueno - 3.33.0-6 +- Make sure 32bit nss-pem always be installed with 32bit nss in + multlib environment, patch by Kamil Dudka + +* Wed Nov 8 2017 Kai Engert - 3.33.0-5 +- Fix test script + +* Tue Nov 7 2017 Kai Engert - 3.33.0-4 +- Update tests to be compatible with default NSS DB changed to sql + (the default was changed in the nss-util package). + +* Tue Oct 24 2017 Kai Engert - 3.33.0-3 +- rhbz#1505487, backport upstream fixes required for rhbz#1496560 + +* Tue Oct 3 2017 Daiki Ueno - 3.33.0-2 +- Update to NSS 3.33.0 + +* Fri Sep 15 2017 Daiki Ueno - 3.32.1-2 +- Update to NSS 3.32.1 + +* Wed Sep 6 2017 Daiki Ueno - 3.32.0-4 +- Update iquote.patch to really prefer in-tree headers over system headers + +* Wed Aug 23 2017 Kai Engert - 3.32.0-3 +- NSS libnssckbi.so has already been obsoleted by p11-kit-trust, rhbz#1484449 + +* Mon Aug 7 2017 Daiki Ueno - 3.32.0-2 +- Update to NSS 3.32.0 + +* Thu Aug 03 2017 Fedora Release Engineering - 3.31.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 3.31.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jul 18 2017 Daiki Ueno - 3.31.0-4 +- Backport mozbz#1381784 to avoid deadlock in dnf + +* Thu Jul 13 2017 Daiki Ueno - 3.31.0-3 +- Move signtool to %%_libdir/nss/unsupported-tools, for: + https://fedoraproject.org/wiki/Changes/NSSSigntoolDeprecation + +* Wed Jun 21 2017 Daiki Ueno - 3.31.0-2 +- Rebase to NSS 3.31.0 + +* Fri Jun 2 2017 Daiki Ueno - 3.30.2-3 +- Enable gtests + +* Mon Apr 24 2017 Daiki Ueno - 3.30.2-2 +- Rebase to NSS 3.30.2 +- Enable TLS 1.3 + +* Thu Mar 30 2017 Kai Engert - 3.30.0-3 +- Backport upstream mozbz#1328318 to support crypto policy FUTURE. + +* Tue Mar 21 2017 Daiki Ueno - 3.30.0-2 +- Rebase to NSS 3.30.0 +- Remove upstreamed patches + +* Thu Mar 02 2017 Kai Engert - 3.29.1-3 +- Backport mozbz#1334976 and mozbz#1336487. + +* Fri Feb 17 2017 Daiki Ueno - 3.29.1-2 +- Rebase to NSS 3.29.1 + +* Thu Feb 9 2017 Daiki Ueno - 3.29.0-3 +- Disable TLS 1.3, following the upstream change + +* Wed Feb 8 2017 Daiki Ueno - 3.29.0-2 +- Rebase to NSS 3.29.0 +- Suppress -Werror=int-in-bool-context warnings with GCC7 + +* Mon Jan 23 2017 Daiki Ueno - 3.28.1-6 +- Work around pkgconfig -> pkgconf transition issue (releng#6597) + +* Fri Jan 20 2017 Daiki Ueno - 3.28.1-5 +- Disable TLS 1.3 +- Add "Conflicts" with packages using older Mozilla codebase, which is + not compatible with NSS 3.28.1 +- Remove NSS_ECC_MORE_THAN_SUITE_B setting, as it was removed in upstream + +* Tue Jan 17 2017 Daiki Ueno - 3.28.1-4 +- Add "Conflicts" with older firefox packages which don't have support + for smaller curves added in NSS 3.28.1 + +* Fri Jan 13 2017 Daiki Ueno - 3.28.1-3 +- Fix incorrect version specification in %%nss_{util,softokn}_version, + pointed by Elio Maldonado + +* Fri Jan 6 2017 Daiki Ueno - 3.28.1-2 +- Rebase to NSS 3.28.1 +- Remove upstreamed patch for disabling RSA-PSS +- Re-enable TLS 1.3 + +* Wed Nov 30 2016 Daiki Ueno - 3.27.2-2 +- Rebase to NSS 3.27.2 + +* Tue Nov 15 2016 Daiki Ueno - 3.27.0-5 +- Revert the previous fix for RSA-PSS and use the upstream fix instead + +* Wed Nov 02 2016 Kai Engert - 3.27.0-4 +- Disable the use of RSA-PSS with SSL/TLS. #1383809 + +* Sun Oct 2 2016 Daiki Ueno - 3.27.0-3 +- Disable TLS 1.3 for now, to avoid reported regression with TLS to + version intolerant servers + +* Thu Sep 29 2016 Daiki Ueno - 3.27.0-2 +- Rebase to NSS 3.27.0 +- Remove upstreamed ectest patch + +* Mon Aug 8 2016 Daiki Ueno - 3.26.0-2 +- Rebase to NSS 3.26.0 +- Update check policy file patch to better match what was upstreamed +- Remove conditionally ignore system policy patch as it has been upstreamed +- Skip ectest as well as ecperf, which are built as part of nss-softokn +- Fix rpmlint error regarding %%define usage + +* Thu Jul 14 2016 Elio Maldonado - 3.25.0-6 +- Incorporate some changes requested in upstream review and commited upstream (#1157720) + +* Fri Jul 01 2016 Elio Maldonado - 3.25.0-5 +- Add support for conditionally ignoring the system policy (#1157720) +- Remove unneeded test scripts patches in order to run more tests +- Remove unneeded test data modifications from the spec file + +* Tue Jun 28 2016 Elio Maldonado - 3.25.0-4 +- Remove obsolete patch and spurious lines from the spec file (#1347336) + +* Sun Jun 26 2016 Elio Maldonado - 3.25.0-3 +- Cleanup spec file and patches and add references to bugs filed upstream + +* Fri Jun 24 2016 Elio Maldonado - 3.25.0-2 +- Rebase to nss 3.25 + +* Thu Jun 16 2016 Kamil Dudka - 3.24.0-3 +- decouple nss-pem from the nss package (#1347336) + +* Fri Jun 03 2016 Elio Maldonado - 3.24.0-2.3 +- Apply the patch that was last introduced +- Renumber and reorder some of the patches +- Resolves: Bug 1342158 + +* Thu Jun 02 2016 Elio Maldonado - 3.24.0-2.2 +- Allow application requests to disable SSL v2 to succeed +- Resolves: Bug 1342158 - nss-3.24 does no longer support ssl V2, installation of IPA fails because nss init fails + +* Sun May 29 2016 Elio Maldonado - 3.24.0-2.1 +- Rebase to NSS 3.24.0 +- Restore setting the policy file location +- Make ssl tests scripts aware of policy +- Ajust tests data expected result for policy + +* Tue May 24 2016 Elio Maldonado - 3.24.0-2.0 +- Bootstrap build to rebase to NSS 3.24.0 +- Temporarily not setting the policy file location + +* Thu May 12 2016 Elio Maldonado - 3.23.0-9 +- Change POLICY_FILE to "nss.config" + +* Fri Apr 22 2016 Elio Maldonado - 3.23.0-8 +- Change POLICY_FILE to "nss.cfg" + +* Wed Apr 20 2016 Elio Maldonado - 3.23.0-7 +- Change the POLICY_PATH to "/etc/crypto-policies/back-ends" +- Regenerate the check policy patch with hg to provide more context + +* Thu Apr 14 2016 Elio Maldonado - 3.23.0-6 +- Fix typo in the last %%changelog entry + +* Thu Mar 24 2016 Elio Maldonado - 3.23.0-5 +- Load policy file if /etc/pki/nssdb/policy.cfg exists +- Resolves: Bug 1157720 - NSS should enforce the system-wide crypto policy + +* Tue Mar 08 2016 Elio Maldonado - 3.23.0-4 +- Remove unused patch rendered obsolete by pem update + +* Tue Mar 08 2016 Elio Maldonado - 3.23.0-3 +- Update pem sources to latest from nss-pem upstream +- Resolves: Bug 1300652 - [PEM] insufficient input validity checking while loading a private key + +* Sat Mar 05 2016 Elio Maldonado - 3.23.0-2 +- Rebase to NSS 3.23 + +* Sat Feb 27 2016 Elio Maldonado - 3.22.2-2 +- Rebase to NSS 3.22.2 + +* Tue Feb 23 2016 Elio Maldonado - 3.22.1-3 +- Fix ssl2/exp test disabling to run all the required tests + +* Sun Feb 21 2016 Elio Maldonado - 3.22.1-1 +- Rebase to NSS 3.22.1 + +* Mon Feb 08 2016 Elio Maldonado - 3.22.0-3 +- Update .gitignore as part of updating to nss 3.22 + +* Mon Feb 08 2016 Elio Maldonado - 3.22.0-2 +- Update to NSS 3.22 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.21.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Fri Jan 15 2016 Elio Maldonado - 3.21.0-6 +- Resolves: Bug 1299040 - Enable ssl_gtests upstream test suite +- Remove 'export NSS_DISABLE_GTESTS=1' go ssl_gtests are built +- Use %%define when specifying the nss_tests to run + +* Wed Dec 30 2015 Michal Toman - 3.21.0-5 +- Add 64-bit MIPS to multilib arches + +* Fri Nov 20 2015 Elio Maldonado - 3.21.0-4 +- Update %%{nss_util_version} and %%{nss_softokn_version} to 3.21.0 +- Resolves: Bug 1284095 - all https fails with sec_error_no_token + +* Sun Nov 15 2015 Elio Maldonado - 3.21.0-3 +- Add references to bugs filed upstream + +* Fri Nov 13 2015 Elio Maldonado Batiz - 3.21.1-2 +- Update to NSS 3.21 +- Package listsuites as part of the unsupported tools set +- Resolves: Bug 1279912 - nss-3.21 is available +- Resolves: Bug 1258425 - Use __isa_bits macro instead of list of 64-bit +- Resolves: Bug 1280032 - Package listsuites as part of the nss unsupported tools set + +* Fri Oct 30 2015 Elio Maldonado - 3.20.1-2 +- Update to NSS 3.20.1 + +* Wed Sep 30 2015 Elio Maldonado - 3.20.0-6 +- Enable ECC cipher-suites by default [hrbz#1185708] +- Split the enabling patch in two for easier maintenance +- Remove unused patches rendered obsolete by prior rebase + +* Wed Sep 16 2015 Elio Maldonado - 3.20.0-5 +- Enable ECC cipher-suites by default [hrbz#1185708] +- Implement corrections requested in code review + +* Tue Sep 15 2015 Elio Maldonado - 3.20.0-4 +- Enable ECC cipher-suites by default [hrbz#1185708] + +* Mon Sep 14 2015 Elio Maldonado - 3.20.0-3 +- Fix patches that disable ssl2 and export cipher suites support +- Fix libssl patch that disable ssl2 & export cipher suites to not disable RSA_WITH_NULL ciphers +- Fix syntax errors in patch to skip ssl2 and export cipher suite tests +- Turn ssl2 off by default in the tstclnt tool +- Disable ssl stress tests containing TLS RC4 128 with MD5 + +* Thu Aug 20 2015 Elio Maldonado - 3.20.0-2 +- Update to NSS 3.20 + +* Sat Aug 08 2015 Elio Maldonado - 3.19.3-2 +- Update to NSS 3.19.3 + +* Fri Jun 26 2015 Elio Maldonado - 3.19.2-3 +- Create on the fly versions of sslcov.txt and sslstress.txt that disable tests for SSL2 and EXPORT ciphers + +* Wed Jun 17 2015 Kai Engert - 3.19.2-2 +- Update to NSS 3.19.2 + +* Thu May 28 2015 Kai Engert - 3.19.1-2 +- Update to NSS 3.19.1 + +* Tue May 19 2015 Kai Engert - 3.19.0-2 +- Update to NSS 3.19 + +* Fri May 15 2015 Kai Engert - 3.18.0-2 +- Replace expired test certificates, upstream bug 1151037 + +* Thu Mar 19 2015 Elio Maldonado - 3.18.0-1 +- Update to nss-3.18.0 +- Resolves: Bug 1203689 - nss-3.18 is available + +* Tue Mar 03 2015 Elio Maldonado - 3.17.4-5 +- Disable export suites and SSL2 support at build time +- Fix syntax errors in various shell scripts +- Resolves: Bug 1189952 - Disable SSL2 and the export cipher suites + +* Sat Feb 21 2015 Till Maas - 3.17.4-4 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Tue Feb 10 2015 Elio Maldonado - 3.17.4-3 +- Commented out the export NSS_NO_SSL2=1 line to not disable ssl2 +- Backing out from disabling ssl2 until the patches are fixed + +* Mon Feb 09 2015 Elio Maldonado - 3.17.4-2 +- Disable SSL2 support at build time +- Fix syntax errors in various shell scripts +- Resolves: Bug 1189952 - Disable SSL2 and the export cipher suites + +* Wed Jan 28 2015 Elio Maldonado - 3.17.4-1 +- Update to nss-3.17.4 + +* Sat Jan 24 2015 Ville Skyttä - 3.17.3-4 +- Own the %%{_datadir}/doc/nss-tools dir + +* Tue Dec 16 2014 Elio Maldonado - 3.17.3-3 +- Resolves: Bug 987189 - nss-tools RPM conflicts with perl-PAR-Packer +- Install pp man page in %%{_datadir}/doc/nss-tools/pp.1 +- Use %%{_mandir} instead of /usr/share/man as more generic + +* Mon Dec 15 2014 Elio Maldonado - 3.17.3-2 +- Install pp man page in alternative location +- Resolves: Bug 987189 - nss-tools RPM conflicts with perl-PAR-Packer + +* Fri Dec 05 2014 Elio Maldonado - 3.17.3-1 +- Update to nss-3.17.3 +- Resolves: Bug 1171012 - nss-3.17.3 is available + +* Thu Oct 16 2014 Elio Maldonado - 3.17.2-2 +- Resolves: Bug 994599 - Enable TLS 1.2 by default + +* Sun Oct 12 2014 Elio Maldonado - 3.17.2-1 +- Update to nss-3.17.2 + +* Wed Sep 24 2014 Kai Engert - 3.17.1-1 +- Update to nss-3.17.1 +- Add a mechanism to skip test suite execution during development work + +* Thu Aug 21 2014 Kevin Fenzi - 3.17.0-2 +- Rebuild for rpm bug 1131960 + +* Tue Aug 19 2014 Elio Maldonado - 3.17.0-1 +- Update to nss-3.17.0 + +* Sun Aug 17 2014 Fedora Release Engineering - 3.16.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Jul 30 2014 Elio Maldonado - 3.16.2-3 +- Replace expired PayPal test cert with current one to prevent build failure + +* Fri Jul 18 2014 Tom Callaway - 3.16.2-2 +- fix license handling + +* Sun Jun 29 2014 Elio Maldonado - 3.16.2-1 +- Update to nss-3.16.2 + +* Sun Jun 15 2014 Elio Maldonado - 3.16.1-4 +- Remove unwanted source directories at end of %%prep so it truly does it +- Skip the cipher suite already run as part of the nss-softokn build + +* Sat Jun 07 2014 Fedora Release Engineering - 3.16.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon May 12 2014 Jaromir Capik - 3.16.1-2 +- Replacing ppc64 and ppc64le with the power64 macro +- Related: Bug 1052545 - Trivial change for ppc64le in nss spec + +* Tue May 06 2014 Elio Maldonado - 3.16.1-1 +- Update to nss-3.16.1 +- Update the iquote patch on account of the rebase +- Improve error detection in the %%section +- Resolves: Bug 1094702 - nss-3.16.1 is available + +* Tue Mar 18 2014 Elio Maldonado - 3.16.0-1 +- Update to nss-3.16.0 +- Cleanup the copying of the tools man pages +- Update the iquote.patch on account of the rebase + +* Tue Mar 04 2014 Elio Maldonado - 3.15.5-2 +- Restore requiring nss_softokn_version >= 3.15.5 + +* Wed Feb 19 2014 Elio Maldonado - 3.15.5-1 +- Update to nss-3.15.5 +- Temporarily requiring only nss_softokn_version >= 3.15.4 +- Fix location of sharedb files and their manpages +- Move cert9.db, key4.db, and pkcs11.txt to the main package +- Move nss-sysinit manpages tar archives to the main package +- Resolves: Bug 1066877 - nss-3.15.5 is available +- Resolves: Bug 1067091 - Move sharedb files to the %%files section + +* Thu Feb 06 2014 Elio Maldonado - 3.15.4-5 +- Revert previous change that moved some sysinit manpages +- Restore nss-sysinit manpages tar archives to %%files sysinit +- Removing spurious wildcard entry was the only change needed + +* Mon Jan 27 2014 Elio Maldonado - 3.15.4-4 +- Add explanatory comments for iquote.patch as was done on f20 + +* Sat Jan 25 2014 Elio Maldonado - 3.15.4-3 +- Update pem sources to latest from nss-pem upstream +- Pick up pem fixes verified on RHEL and applied upstream +- Fix a problem where same files in two rpms created rpm conflict +- Move some nss-sysinit manpages tar archives to the %%files the +- All man pages are listed by name so there shouldn't be wildcard inclusion +- Add support for ppc64le, Resolves: Bug 1052545 + +* Mon Jan 20 2014 Peter Robinson 3.15.4-2 +- ARM tests pass so remove ARM conditional + +* Tue Jan 07 2014 Elio Maldonado - 3.15.4-1 +- Update to nss-3.15.4 (hg tag NSS_3_15_4_RTM) +- Resolves: Bug 1049229 - nss-3.15.4 is available +- Update pem sources to latest from the interim upstream for pem +- Remove no longer needed patches +- Update pem/rsawrapr.c patch on account of upstream changes to freebl/softoken +- Update iquote.patch on account of upstream changes + +* Wed Dec 11 2013 Elio Maldonado - 3.15.3.1-1 +- Update to nss-3.15.3.1 (hg tag NSS_3_15_3_1_RTM) +- Resolves: Bug 1040282 - nss: Mis-issued ANSSI/DCSSI certificate (MFSA 2013-117) +- Resolves: Bug 1040192 - nss-3.15.3.1 is available + +* Tue Dec 03 2013 Elio Maldonado - 3.15.3-2 +- Bump the release tag + +* Sun Nov 24 2013 Elio Maldonado - 3.15.3-1 +- Update to NSS_3_15_3_RTM +- Resolves: Bug 1031897 - CVE-2013-5605 CVE-2013-5606 CVE-2013-1741 nss: various flaws +- Fix option descriptions for setup-nsssysinit manpage +- Fix man page of nss-sysinit wrong path and other flaws +- Document email option for certutil manpage +- Remove unused patches + +* Sun Oct 27 2013 Elio Maldonado - 3.15.2-3 +- Revert one change from last commit to preserve full nss pluggable ecc supprt [1019245] + +* Wed Oct 23 2013 Elio Maldonado - 3.15.2-2 +- Use the full sources from upstream +- Bug 1019245 - ECDHE in openssl available -> NSS needs too for Firefox/Thunderbird + +* Thu Sep 26 2013 Elio Maldonado - 3.15.2-1 +- Update to NSS_3_15_2_RTM +- Update iquote.patch on account of modified prototype on cert.h installed by nss-devel + +* Wed Aug 28 2013 Elio Maldonado - 3.15.1-7 +- Update pem sources to pick up a patch applied upstream which a faulty merge had missed +- The pem module should not require unique file basenames + +* Tue Aug 27 2013 Elio Maldonado - 3.15.1-6 +- Update pem sources to the latest from interim upstream + +* Mon Aug 19 2013 Elio Maldonado - 3.15.1-5 +- Resolves: rhbz#996639 - Minor bugs in nss man pages +- Fix some typos and improve description and see also sections + +* Sun Aug 11 2013 Elio Maldonado - 3.15.1-4 +- Cleanup spec file to address most rpmlint errors and warnings +- Using double percent symbols to fix macro-in-comment warnings +- Ignore unversioned-explicit-provides nss-system-init per spec comments +- Ignore invalid-url Source0 as it comes from the git lookaside cache +- Ignore invalid-url Source12 as it comes from the git lookaside cache + +* Thu Jul 25 2013 Elio Maldonado - 3.15.1-3 +- Add man page for pkcs11.txt configuration file and cert and key databases +- Resolves: rhbz#985114 - Provide man pages for the nss configuration files + +* Fri Jul 19 2013 Elio Maldonado - 3.15.1-2 +- Fix errors in the man pages +- Resolves: rhbz#984106 - Add missing option descriptions to man pages for {cert|cms|crl}util +- Resolves: rhbz#982856 - Fix path to script in man page for nss-sysinit + +* Tue Jul 02 2013 Elio Maldonado - 3.15.1-1 +- Update to NSS_3_15_1_RTM +- Enable the iquote.patch to access newly introduced types + +* Wed Jun 19 2013 Elio Maldonado - 3.15-5 +- Install man pages for nss-tools and the nss-config and setup-nsssysinit scripts +- Resolves: rhbz#606020 - nss security tools lack man pages + +* Tue Jun 18 2013 emaldona - 3.15-4 +- Build nss without softoken or util sources in the tree +- Resolves: rhbz#689918 + +* Mon Jun 17 2013 emaldona - 3.15-3 +- Update ssl-cbc-random-iv-by-default.patch + +* Sun Jun 16 2013 Elio Maldonado - 3.15-2 +- Fix generation of NSS_VMAJOR, NSS_VMINOR, and NSS_VPATCH for nss-config + +* Sat Jun 15 2013 Elio Maldonado - 3.15-1 +- Update to NSS_3_15_RTM + +* Wed Apr 24 2013 Elio Maldonado - 3.15-0.1.beta1.2 +- Fix incorrect path that hid failed test from view +- Add ocsp to the test suites to run but ... +- Temporarily disable the ocsp stapling tests +- Do not treat failed attempts at ssl pkcs11 bypass as fatal errors + +* Thu Apr 04 2013 Elio Maldonado - 3.15-0.1.beta1.1 +- Update to NSS_3_15_BETA1 +- Update spec file, patches, and helper scripts on account of a shallower source tree + +* Sun Mar 24 2013 Kai Engert - 3.14.3-12 +- Update expired test certificates (fixed in upstream bug 852781) + +* Fri Mar 08 2013 Kai Engert - 3.14.3-10 +- Fix incorrect post/postun scripts. Fix broken links in posttrans. + +* Wed Mar 06 2013 Kai Engert - 3.14.3-9 +- Configure libnssckbi.so to use the alternatives system + in order to prepare for a drop in replacement. + +* Fri Feb 15 2013 Elio Maldonado - 3.14.3-1 +- Update to NSS_3_14_3_RTM +- sync up pem rsawrapr.c with softoken upstream changes for nss-3.14.3 +- Resolves: rhbz#908257 - CVE-2013-1620 nss: TLS CBC padding timing attack +- Resolves: rhbz#896651 - PEM module trashes private keys if login fails +- Resolves: rhbz#909775 - specfile support for AArch64 +- Resolves: rhbz#910584 - certutil -a does not produce ASCII output + +* Mon Feb 04 2013 Elio Maldonado - 3.14.2-2 +- Allow building nss against older system sqlite + +* Fri Feb 01 2013 Elio Maldonado - 3.14.2-1 +- Update to NSS_3_14_2_RTM + +* Wed Jan 02 2013 Kai Engert - 3.14.1-3 +- Update to NSS_3_14_1_WITH_CKBI_1_93_RTM + +* Sat Dec 22 2012 Elio Maldonado - 3.14.1-2 +- Require nspr >= 4.9.4 +- Fix changelog invalid dates + +* Mon Dec 17 2012 Elio Maldonado - 3.14.1-1 +- Update to NSS_3_14_1_RTM + +* Wed Dec 12 2012 Elio Maldonado - 3.14-12 +- Bug 879978 - Install the nssck.api header template where mod_revocator can access it +- Install nssck.api in /usr/includes/nss3/templates + +* Tue Nov 27 2012 Elio Maldonado - 3.14-11 +- Bug 879978 - Install the nssck.api header template in a place where mod_revocator can access it +- Install nssck.api in /usr/includes/nss3 + +* Mon Nov 19 2012 Elio Maldonado - 3.14-10 +- Bug 870864 - Add support in NSS for Secure Boot + +* Sat Nov 10 2012 Elio Maldonado - 3.14-9 +- Disable bypass code at build time and return failure on attempts to enable at runtime +- Bug 806588 - Disable SSL PKCS #11 bypass at build time + +* Sun Nov 04 2012 Elio Maldonado - 3.14-8 +- Fix pk11wrap locking which fixes 'fedpkg new-sources' and 'fedpkg update' hangs +- Bug 872124 - nss-3.14 breaks fedpkg new-sources +- Fix should be considered preliminary since the patch may change upon upstream approval + +* Thu Nov 01 2012 Elio Maldonado - 3.14-7 +- Add a dummy source file for testing /preventing fedpkg breakage +- Helps test the fedpkg new-sources and upload commands for breakage by nss updates +- Related to Bug 872124 - nss 3.14 breaks fedpkg new-sources + +* Thu Nov 01 2012 Elio Maldonado - 3.14-6 +- Fix a previous unwanted merge from f18 +- Update the SS_SSL_CBC_RANDOM_IV patch to match new sources while +- Keeping the patch disabled while we are still in rawhide and +- State in comment that patch is needed for both stable and beta branches +- Update .gitignore to download only the new sources + +* Wed Oct 31 2012 Elio Maldonado - 3.14-5 +- Fix the spec file so sechash.h gets installed +- Resolves: rhbz#871882 - missing header: sechash.h in nss 3.14 + +* Sat Oct 27 2012 Elio Maldonado - 3.14-4 +- Update the license to MPLv2.0 + +* Wed Oct 24 2012 Elio Maldonado - 3.14-3 +- Use only -f when removing unwanted headers + +* Tue Oct 23 2012 Elio Maldonado - 3.14-2 +- Add secmodt.h to the headers installed by nss-devel +- nss-devel must install secmodt.h which moved from softoken to pk11wrap with nss-3.14 + +* Mon Oct 22 2012 Elio Maldonado - 3.14-1 +- Update to NSS_3_14_RTM + +* Sun Oct 21 2012 Elio Maldonado - 3.14-0.1.rc.1 +- Update to NSS_3_14_RC1 +- update nss-589636.patch to apply to httpdserv +- turn off ocsp tests for now +- remove no longer needed patches +- remove headers shipped by nss-util + +* Fri Oct 05 2012 Kai Engert - 3.13.6-1 +- Update to NSS_3_13_6_RTM + +* Mon Aug 27 2012 Elio Maldonado - 3.13.5-8 +- Rebase pem sources to fedora-hosted upstream to pick up two fixes from rhel-6.3 +- Resolves: rhbz#847460 - Fix invalid read and free on invalid cert load +- Resolves: rhbz#847462 - PEM module may attempt to free uninitialized pointer +- Remove unneeded fix gcc 4.7 c++ issue in secmodt.h that actually undoes the upstream fix + +* Mon Aug 13 2012 Elio Maldonado - 3.13.5-7 +- Fix pluggable ecc support + +* Fri Jul 20 2012 Fedora Release Engineering - 3.13.5-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sun Jul 01 2012 Elio Maldonado - 3.13.5-5 +- Fix checkin comment to prevent unwanted expansions of percents + +* Sun Jul 01 2012 Elio Maldonado - 3.13.5-4 +- Resolves: Bug 830410 - Missing Requires %%{?_isa} +- Use Requires: %%{name}%%{?_isa} = %%{version}-%%{release} on tools +- Drop zlib requires which rpmlint reports as error E: explicit-lib-dependency zlib +- Enable sha224 portion of powerup selftest when running test suites +- Require nspr 4.9.1 + +* Wed Jun 20 2012 Elio Maldonado - 3.13.5-3 +- Resolves: rhbz#833529 - revert unwanted change to nss.pc.in + +* Tue Jun 19 2012 Elio Maldonado - 3.13.5-2 +- Resolves: rhbz#833529 - Remove unwanted space from the Libs: line on nss.pc.in + +* Mon Jun 18 2012 Elio Maldonado - 3.13.5-1 +- Update to NSS_3_13_5_RTM + +* Fri Apr 13 2012 Elio Maldonado - 3.13.4-3 +- Resolves: Bug 812423 - nss_Init leaks memory, fix from RHEL 6.3 + +* Sun Apr 08 2012 Elio Maldonado - 3.13.4-2 +- Resolves: Bug 805723 - Library needs partial RELRO support added +- Patch coreconf/Linux.mk as done on RHEL 6.2 + +* Fri Apr 06 2012 Elio Maldonado - 3.13.4-1 +- Update to NSS_3_13_4_RTM +- Update the nss-pem source archive to the latest version +- Remove no longer needed patches +- Resolves: Bug 806043 - use pem files interchangeably in a single process +- Resolves: Bug 806051 - PEM various flaws detected by Coverity +- Resolves: Bug 806058 - PEM pem_CreateObject leaks memory given a non-existing file name + +* Wed Mar 21 2012 Elio Maldonado - 3.13.3-4 +- Resolves: Bug 805723 - Library needs partial RELRO support added + +* Fri Mar 09 2012 Elio Maldonado - 3.13.3-3 +- Cleanup of the spec file +- Add references to the upstream bugs +- Fix typo in Summary for sysinit + +* Thu Mar 08 2012 Elio Maldonado - 3.13.3-2 +- Pick up fixes from RHEL +- Resolves: rhbz#800674 - Unable to contact LDAP Server during winsync +- Resolves: rhbz#800682 - Qpid AMQP daemon fails to load after nss update +- Resolves: rhbz#800676 - NSS workaround for freebl bug that causes openswan to drop connections + +* Thu Mar 01 2012 Elio Maldonado - 3.13.3-1 +- Update to NSS_3_13_3_RTM + +* Mon Jan 30 2012 Tom Callaway - 3.13.1-13 +- fix issue with gcc 4.7 in secmodt.h and C++11 user-defined literals + +* Thu Jan 26 2012 Elio Maldonado - 3.13.1-12 +- Resolves: Bug 784672 - nss should protect against being called before nss_Init + +* Fri Jan 13 2012 Fedora Release Engineering - 3.13.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Jan 06 2012 Elio Maldonado - 3.13.1-11 +- Deactivate a patch currently meant for stable branches only + +* Fri Jan 06 2012 Elio Maldonado - 3.13.1-10 +- Resolves: Bug 770682 - nss update breaks pidgin-sipe connectivity +- NSS_SSL_CBC_RANDOM_IV set to 0 by default and changed to 1 on user request + +* Tue Dec 13 2011 elio maldonado - 3.13.1-9 +- Revert to using current nss_softokn_version +- Patch to deal with lack of sha224 is no longer needed + +* Tue Dec 13 2011 Elio Maldonado - 3.13.1-8 +- Resolves: Bug 754771 - [PEM] an unregistered callback causes a SIGSEGV + +* Mon Dec 12 2011 Elio Maldonado - 3.13.1-7 +- Resolves: Bug 750376 - nss 3.13 breaks sssd TLS +- Fix how pem is built so that nss-3.13.x works with nss-softokn-3.12.y +- Only patch blapitest for the lack of sha224 on system freebl +- Completed the patch to make pem link against system freebl + +* Mon Dec 05 2011 Elio Maldonado - 3.13.1-6 +- Removed unwanted /usr/include/nss3 in front of the normal cflags include path +- Removed unnecessary patch dealing with CERTDB_TERMINAL_RECORD, it's visible + +* Sun Dec 04 2011 Elio Maldonado - 3.13.1-5 +- Statically link the pem module against system freebl found in buildroot +- Disabling sha224-related powerup selftest until we update softokn +- Disable sha224 and pss tests which nss-softokn 3.12.x doesn't support + +* Fri Dec 02 2011 Elio Maldonado Batiz - 3.13.1-4 +- Rebuild with nss-softokn from 3.12 in the buildroot +- Allows the pem module to statically link against 3.12.x freebl +- Required for using nss-3.13.x with nss-softokn-3.12.y for a merge inrto rhel git repo +- Build will be temprarily placed on buildroot override but not pushed in bodhi + +* Fri Nov 04 2011 Elio Maldonado - 3.13.1-2 +- Fix broken dependencies by updating the nss-util and nss-softokn versions + +* Thu Nov 03 2011 Elio Maldonado - 3.13.1-1 +- Update to NSS_3_13_1_RTM +- Update builtin certs to those from NSSCKBI_1_88_RTM + +* Sat Oct 15 2011 Elio Maldonado - 3.13-1 +- Update to NSS_3_13_RTM + +* Sat Oct 08 2011 Elio Maldonado - 3.13-0.1.rc0.1 +- Update to NSS_3_13_RC0 + +* Wed Sep 14 2011 Elio Maldonado - 3.12.11-3 +- Fix attempt to free initilized pointer (#717338) +- Fix leak on pem_CreateObject when given non-existing file name (#734760) +- Fix pem_Initialize to return CKR_CANT_LOCK on multi-treaded calls (#736410) + +* Tue Sep 06 2011 Kai Engert - 3.12.11-2 +- Update builtins certs to those from NSSCKBI_1_87_RTM + +* Tue Aug 09 2011 Elio Maldonado - 3.12.11-1 +- Update to NSS_3_12_11_RTM + +* Sat Jul 23 2011 Elio Maldonado - 3.12.10-6 +- Indicate the provenance of stripped source tarball (#688015) + +* Mon Jun 27 2011 Michael Schwendt - 3.12.10-5 +- Provide virtual -static package to meet guidelines (#609612). + +* Fri Jun 10 2011 Elio Maldonado - 3.12.10-4 +- Enable pluggable ecc support (#712556) +- Disable the nssdb write-access-on-read-only-dir tests when user is root (#646045) + +* Fri May 20 2011 Dennis Gilmore - 3.12.10-3 +- make the testsuite non fatal on arm arches + +* Tue May 17 2011 Elio Maldonado - 3.12.10-2 +- Fix crmf hard-coded maximum size for wrapped private keys (#703656) + +* Fri May 06 2011 Elio Maldonado - 3.12.10-1 +- Update to NSS_3_12_10_RTM + +* Wed Apr 27 2011 Elio Maldonado - 3.12.10-0.1.beta1 +- Update to NSS_3_12_10_BETA1 + +* Mon Apr 11 2011 Elio Maldonado - 3.12.9-15 +- Implement PEM logging using NSPR's own (#695011) + +* Wed Mar 23 2011 Elio Maldonado - 3.12.9-14 +- Update to NSS_3.12.9_WITH_CKBI_1_82_RTM + +* Thu Feb 24 2011 Elio Maldonado - 3.12.9-13 +- Short-term fix for ssl test suites hangs on ipv6 type connections (#539183) + +* Fri Feb 18 2011 Elio Maldonado - 3.12.9-12 +- Add a missing requires for pkcs11-devel (#675196) + +* Tue Feb 15 2011 Elio Maldonado - 3.12.9-11 +- Run the test suites in the check section (#677809) + +* Thu Feb 10 2011 Elio Maldonado - 3.12.9-10 +- Fix cms headers to not use c++ reserved words (#676036) +- Reenabling Bug 499444 patches +- Fix to swap internal key slot on fips mode switches + +* Tue Feb 08 2011 Elio Maldonado - 3.12.9-9 +- Revert patches for 499444 until all c++ reserved words are found and extirpated + +* Tue Feb 08 2011 Fedora Release Engineering - 3.12.9-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Feb 08 2011 Elio Maldonado - 3.12.9-7 +- Fix cms header to not use c++ reserved word (#676036) +- Reenable patches for bug 499444 + +* Tue Feb 08 2011 Christopher Aillon - 3.12.9-6 +- Revert patches for 499444 as they use a C++ reserved word and + cause compilation of Firefox to fail + +* Fri Feb 04 2011 Elio Maldonado - 3.12.9-5 +- Fix the earlier infinite recursion patch (#499444) +- Remove a header that now nss-softokn-freebl-devel ships + +* Tue Feb 01 2011 Elio Maldonado - 3.12.9-4 +- Fix infinite recursion when encoding NSS enveloped/digested data (#499444) + +* Mon Jan 31 2011 Elio Maldonado - 3.12.9-3 +- Update the cacert trust patch per upstream review requests (#633043) + +* Wed Jan 19 2011 Elio Maldonado - 3.12.9-2 +- Fix to honor the user's cert trust preferences (#633043) +- Remove obsoleted patch + +* Wed Jan 12 2011 Elio Maldonado - 3.12.9-1 +- Update to 3.12.9 + +* Mon Dec 27 2010 Elio Maldonado - 3.12.9-0.1.beta2 +- Rebuilt according to fedora pre-release package naming guidelines + +* Fri Dec 10 2010 Elio Maldonado - 3.12.8.99.2-1 +- Update to NSS_3_12_9_BETA2 +- Fix libpnsspem crash when cacert dir contains other directories (#642433) + +* Wed Dec 08 2010 Elio Maldonado - 3.12.8.99.1-1 +- Update to NSS_3_12_9_BETA1 + +* Thu Nov 25 2010 Elio Maldonado - 3.12.8-9 +- Update pem source tar with fixes for 614532 and 596674 +- Remove no longer needed patches + +* Fri Nov 05 2010 Elio Maldonado - 3.12.8-8 +- Update PayPalEE.cert test certificate which had expired + +* Sun Oct 31 2010 Elio Maldonado - 3.12.8-7 +- Tell rpm not to verify md5, size, and modtime of configurations file + +* Mon Oct 18 2010 Elio Maldonado - 3.12.8-6 +- Fix certificates trust order (#643134) +- Apply nss-sysinit-userdb-first.patch last + +* Wed Oct 06 2010 Elio Maldonado - 3.12.8-5 +- Move triggerpostun -n nss-sysinit script ahead of the other ones (#639248) + +* Tue Oct 05 2010 Elio Maldonado - 3.12.8-4 +- Fix invalid %%postun scriptlet (#639248) + +* Wed Sep 29 2010 Elio Maldonado - 3.12.8-3 +- Replace posttrans sysinit scriptlet with a triggerpostun one (#636787) +- Fix and cleanup the setup-nsssysinit.sh script (#636792, #636801) + +* Mon Sep 27 2010 Elio Maldonado - 3.12.8-2 +- Add posttrans scriptlet (#636787) + +* Thu Sep 23 2010 Elio Maldonado - 3.12.8-1 +- Update to 3.12.8 +- Prevent disabling of nss-sysinit on package upgrade (#636787) +- Create pkcs11.txt with correct permissions regardless of umask (#636792) +- Setup-nsssysinit.sh reports whether nss-sysinit is turned on or off (#636801) +- Added provides pkcs11-devel-static to comply with packaging guidelines (#609612) + +* Sat Sep 18 2010 Elio Maldonado - 3.12.7.99.4-1 +- NSS 3.12.8 RC0 + +* Sun Sep 05 2010 Elio Maldonado - 3.12.7.99.3-2 +- Fix nss-util_version and nss_softokn_version required to be 3.12.7.99.3 + +* Sat Sep 04 2010 Elio Maldonado - 3.12.7.99.3-1 +- NSS 3.12.8 Beta3 +- Fix unclosed comment in renegotiate-transitional.patch + +* Sat Aug 28 2010 Elio Maldonado - 3.12.7-3 +- Change BuildRequries to available version of nss-util-devel + +* Sat Aug 28 2010 Elio Maldonado - 3.12.7-2 +- Define NSS_USE_SYSTEM_SQLITE and remove unneeded patch +- Add comments regarding an unversioned provides which triggers rpmlint warning +- Build requires nss-softokn-devel >= 3.12.7 + +* Mon Aug 16 2010 Elio Maldonado - 3.12.7-1 +- Update to 3.12.7 + +* Sat Aug 14 2010 Elio Maldonado - 3.12.6-12 +- Apply the patches to fix rhbz#614532 + +* Mon Aug 09 2010 Elio Maldonado - 3.12.6-11 +- Removed pem sourecs as they are in the cache + +* Mon Aug 09 2010 Elio Maldonado - 3.12.6-10 +- Add support for PKCS#8 encoded PEM RSA private key files (#614532) + +* Sat Jul 31 2010 Elio Maldonado - 3.12.6-9 +- Fix nsssysinit to return userdb ahead of systemdb (#603313) + +* Tue Jun 08 2010 Dennis Gilmore - 3.12.6-8 +- Require and BuildRequire >= the listed version not = + +* Tue Jun 08 2010 Elio Maldonado - 3.12.6-7 +- Require nss-softoken 3.12.6 + +* Sun Jun 06 2010 Elio Maldonado - 3.12.6-6 +- Fix SIGSEGV within CreateObject (#596674) + +* Mon Apr 12 2010 Elio Maldonado - 3.12.6-5 +- Update pem source tar to pick up the following bug fixes: +- PEM - Allow collect objects to search through all objects +- PEM - Make CopyObject return a new shallow copy +- PEM - Fix memory leak in pem_mdCryptoOperationRSAPriv + +* Wed Apr 07 2010 Elio Maldonado - 3.12.6-4 +- Update the test cert in the setup phase + +* Wed Apr 07 2010 Elio Maldonado - 3.12.6-3 +- Add sed to sysinit requires as setup-nsssysinit.sh requires it (#576071) +- Update PayPalEE test cert with unexpired one (#580207) + +* Thu Mar 18 2010 Elio Maldonado - 3.12.6-2 +- Fix ns.spec to not require nss-softokn (#575001) + +* Sat Mar 06 2010 Elio Maldonado - 3.12.6-1.2 +- rebuilt with all tests enabled + +* Sat Mar 06 2010 Elio Maldonado - 3.12.6-1.1 +- Using SSL_RENEGOTIATE_TRANSITIONAL as default while on transition period +- Disabling ssl tests suites until bug 539183 is resolved + +* Sat Mar 06 2010 Elio Maldonado - 3.12.6-1 +- Update to 3.12.6 +- Reactivate all tests +- Patch tools to validate command line options arguments + +* Mon Jan 25 2010 Elio Maldonado - 3.12.5-8 +- Fix curl related regression and general patch code clean up + +* Wed Jan 13 2010 Elio Maldonado - 3.12.5-5 +- retagging + +* Tue Jan 12 2010 Elio Maldonado - 3.12.5-1.1 +- Fix SIGSEGV on call of NSS_Initialize (#553638) + +* Wed Jan 06 2010 Elio Maldonado - 3.12.5-1.13.2 +- New version of patch to allow root to modify ystem database (#547860) + +* Thu Dec 31 2009 Elio Maldonado - 3.12.5-1.13.1 +- Temporarily disabling the ssl tests + +* Sat Dec 26 2009 Elio Maldonado - 3.12.5-1.13 +- Fix nsssysinit to allow root to modify the nss system database (#547860) + +* Fri Dec 25 2009 Elio Maldonado - 3.12.5-1.11 +- Fix an error introduced when adapting the patch for rhbz #546211 + +* Sat Dec 19 2009 Elio maldonado - 3.12.5-1.9 +- Remove left over trace statements from nsssysinit patching + +* Fri Dec 18 2009 Elio Maldonado - 3.12.5-2.7 +- Fix a misconstructed patch + +* Thu Dec 17 2009 Elio Maldonado - 3.12.5-1.6 +- Fix nsssysinit to enable apps to use system cert store, patch contributed by David Woodhouse (#546221) +- Fix spec so sysinit requires coreutils for post install scriplet (#547067) +- Fix segmentation fault when listing keys or certs in the database, patch contributed by Kamil Dudka (#540387) + +* Thu Dec 10 2009 Elio Maldonado - 3.12.5-1.5 +- Fix nsssysinit to set the default flags on the crypto module (#545779) +- Remove redundant header from the pem module + +* Wed Dec 09 2009 Elio Maldonado - 3.12.5-1.1 +- Remove unneeded patch + +* Thu Dec 03 2009 Elio Maldonado - 3.12.5-1.1 +- Retagging to include missing patch + +* Thu Dec 03 2009 Elio Maldonado - 3.12.5-1 +- Update to 3.12.5 +- Patch to allow ssl/tls clients to interoperate with servers that require renogiation + +* Fri Nov 20 2009 Elio Maldonado - 3.12.4-14.1 +- Retagging + +* Tue Oct 20 2009 Elio Maldonado - 3.12.4-13.1 +- Require nss-softoken of same architecture as nss (#527867) +- Merge setup-nsssysinit.sh improvements from F-12 (#527051) + +* Sat Oct 03 2009 Elio Maldonado - 3.12.4-13 +- User no longer prompted for a password when listing keys an empty system db (#527048) +- Fix setup-nsssysinit to handle more general formats (#527051) + +* Sun Sep 27 2009 Elio Maldonado - 3.12.4-12 +- Fix syntax error in setup-nsssysinit.sh + +* Sun Sep 27 2009 Elio Maldonado - 3.12.4-11 +- Fix sysinit to be under mozilla/security/nss/lib + +* Sat Sep 26 2009 Elio Maldonado - 3.12.4-10 +- Add nss-sysinit activation/deactivation script + +* Fri Sep 18 2009 Elio Maldonado - 3.12.4-8 +- Restoring nssutil and -rpath-link to nss-config for now - 522477 + +* Tue Sep 08 2009 Elio Maldonado - 3.12.4-6 +- Installing shared libraries to %%{_libdir} + +* Mon Sep 07 2009 Elio Maldonado - 3.12.4-5 +- Retagging to pick up new sources + +* Mon Sep 07 2009 Elio Maldonado - 3.12.4-4 +- Update pem enabling source tar with latest fixes (509705, 51209) + +* Sun Sep 06 2009 Elio Maldonado - 3.12.4-3 +- PEM module implements memory management for internal objects - 509705 +- PEM module doesn't crash when processing malformed key files - 512019 + +* Sat Sep 05 2009 Elio Maldonado - 3.12.4-2 +- Remove symbolic links to shared libraries from devel - 521155 +- No rpath-link in nss-softokn-config + +* Tue Sep 01 2009 Elio Maldonado - 3.12.4-1 +- Update to 3.12.4 + +* Mon Aug 31 2009 Elio Maldonado - 3.12.3.99.3-30 +- Fix FORTIFY_SOURCE buffer overflows in test suite on ppc and ppc64 - bug 519766 +- Fixed requires and buildrequires as per recommendations in spec file review + +* Sun Aug 30 2009 Elio Maldonado - 3.12.3.99.3-29 +- Restoring patches 2 and 7 as we still compile all sources +- Applying the nss-nolocalsql.patch solves nss-tools sqlite dependency problems + +* Sun Aug 30 2009 Elio Maldonado - 3.12.3.99.3-28 +- restore require sqlite + +* Sat Aug 29 2009 Elio Maldonado - 3.12.3.99.3-27 +- Don't require sqlite for nss + +* Sat Aug 29 2009 Elio Maldonado - 3.12.3.99.3-26 +- Ensure versions in the requires match those used when creating nss.pc + +* Fri Aug 28 2009 Elio Maldonado - 3.12.3.99.3-25 +- Remove nss-prelink.conf as signed all shared libraries moved to nss-softokn +- Add a temprary hack to nss.pc.in to unblock builds + +* Fri Aug 28 2009 Warren Togami - 3.12.3.99.3-24 +- caolan's nss.pc patch + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-23 +- Bump the release number for a chained build of nss-util, nss-softokn and nss + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-22 +- Fix nss-config not to include nssutil +- Add BuildRequires on nss-softokn and nss-util since build also runs the test suite + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-21 +- disabling all tests while we investigate a buffer overflow bug + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-20 +- disabling some tests while we investigate a buffer overflow bug - 519766 + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-19 +- remove patches that are now in nss-softokn and +- remove spurious exec-permissions for nss.pc per rpmlint +- single requires line in nss.pc.in + +* Wed Aug 26 2009 Elio Maldonado - 3.12.3.99.3-18 +- Fix BuildRequires: nss-softokn-devel release number + +* Wed Aug 26 2009 Elio Maldonado - 3.12.3.99.3-16 +- cleanups for softokn + +* Tue Aug 25 2009 Dennis Gilmore - 3.12.3.99.3-15 +- remove the softokn subpackages + +* Mon Aug 24 2009 Dennis Gilmore - 3.12.3.99.3-14 +- don install the nss-util pkgconfig bits + +* Mon Aug 24 2009 Dennis Gilmore - 3.12.3.99.3-13 +- remove from -devel the 3 headers that ship in nss-util-devel + +* Mon Aug 24 2009 Dennis Gilmore - 3.12.3.99.3-12 +- kill off the nss-util nss-util-devel subpackages + +* Sun Aug 23 2009 Elio Maldonado+emaldona@redhat.com - 3.12.3.99.3-11 +- split off nss-softokn and nss-util as subpackages with their own rpms +- first phase of splitting nss-softokn and nss-util as their own packages + +* Thu Aug 20 2009 Elio Maldonado - 3.12.3.99.3-10 +- must install libnssutil3.since nss-util is untagged at the moment +- preserve time stamps when installing various files + +* Thu Aug 20 2009 Dennis Gilmore - 3.12.3.99.3-9 +- dont install libnssutil3.so since its now in nss-util + +* Thu Aug 06 2009 Elio Maldonado - 3.12.3.99.3-7.1 +- Fix spec file problems uncovered by Fedora_12_Mass_Rebuild + +* Sat Jul 25 2009 Fedora Release Engineering - 3.12.3.99.3-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jun 22 2009 Elio Maldonado - 3.12.3.99.3-6 +- removed two patch files which are no longer needed and fixed previous change log number +* Mon Jun 22 2009 Elio Maldonado - 3.12.3.99.3-5 +- updated pem module incorporates various patches +- fix off-by-one error when computing size to reduce memory leak. (483855) +- fix data type to work on x86_64 systems. (429175) +- fix various memory leaks and free internal objects on module unload. (501080) +- fix to not clone internal objects in collect_objects(). (501118) +- fix to not bypass initialization if module arguments are omitted. (501058) +- fix numerous gcc warnings. (500815) +- fix to support arbitrarily long password while loading a private key. (500180) +- fix memory leak in make_key and memory leaks and return values in pem_mdSession_Login (501191) +* Mon Jun 08 2009 Elio Maldonado - 3.12.3.99.3-4 +- add patch for bug 502133 upstream bug 496997 +* Fri Jun 05 2009 Kai Engert - 3.12.3.99.3-3 +- rebuild with higher release number for upgrade sanity +* Fri Jun 05 2009 Kai Engert - 3.12.3.99.3-2 +- updated to NSS_3_12_4_FIPS1_WITH_CKBI_1_75 +* Thu May 07 2009 Kai Engert - 3.12.3-7 +- re-enable test suite +- add patch for upstream bug 488646 and add newer paypal + certs in order to make the test suite pass +* Wed May 06 2009 Kai Engert - 3.12.3-4 +- add conflicts info in order to fix bug 499436 +* Tue Apr 14 2009 Kai Engert - 3.12.3-3 +- ship .chk files instead of running shlibsign at install time +- include .chk file in softokn-freebl subpackage +- add patch for upstream nss bug 488350 +* Tue Apr 14 2009 Kai Engert - 3.12.3-2 +- Update to NSS 3.12.3 +* Mon Apr 06 2009 Kai Engert - 3.12.2.99.3-7 +- temporarily disable the test suite because of bug 494266 +* Mon Apr 06 2009 Kai Engert - 3.12.2.99.3-6 +- fix softokn-freebl dependency for multilib (bug 494122) +* Thu Apr 02 2009 Kai Engert - 3.12.2.99.3-5 +- introduce separate nss-softokn-freebl package +* Thu Apr 02 2009 Kai Engert - 3.12.2.99.3-4 +- disable execstack when building freebl +* Tue Mar 31 2009 Kai Engert - 3.12.2.99.3-3 +- add upstream patch to fix bug 483855 +* Tue Mar 31 2009 Kai Engert - 3.12.2.99.3-2 +- build nspr-less freebl library +* Tue Mar 31 2009 Kai Engert - 3.12.2.99.3-1 +- Update to NSS_3_12_3_BETA4 + +* Wed Feb 25 2009 Fedora Release Engineering - 3.12.2.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Oct 22 2008 Kai Engert - 3.12.2.0-3 +- update to NSS_3_12_2_RC1 +- use system zlib +* Tue Sep 30 2008 Dennis Gilmore - 3.12.1.1-4 +- add sparc64 to the list of 64 bit arches + +* Wed Sep 24 2008 Kai Engert - 3.12.1.1-3 +- bug 456847, move pkgconfig requirement to devel package +* Fri Sep 05 2008 Kai Engert - 3.12.1.1-2 +- Update to NSS_3_12_1_RC2 +* Fri Aug 22 2008 Kai Engert - 3.12.1.0-2 +- NSS 3.12.1 RC1 +* Fri Aug 15 2008 Kai Engert - 3.12.0.3-7 +- fix bug bug 429175 in libpem module +* Tue Aug 05 2008 Kai Engert - 3.12.0.3-6 +- bug 456847, add Requires: pkgconfig +* Tue Jun 24 2008 Kai Engert - 3.12.0.3-3 +- nss package should own /etc/prelink.conf.d folder, rhbz#452062 +- use upstream patch to fix test suite abort +* Mon Jun 02 2008 Kai Engert - 3.12.0.3-2 +- Update to NSS_3_12_RC4 +* Mon Apr 14 2008 Kai Engert - 3.12.0.1-1 +- Update to NSS_3_12_RC2 +* Thu Mar 20 2008 Jesse Keating - 3.11.99.5-2 +- Zapping old Obsoletes/Provides. No longer needed, causes multilib headache. +* Mon Mar 17 2008 Kai Engert - 3.11.99.5-1 +- Update to NSS_3_12_BETA3 +* Fri Feb 22 2008 Kai Engert - 3.11.99.4-1 +- NSS 3.12 Beta 2 +- Use /usr/lib{64} as devel libdir, create symbolic links. +* Sat Feb 16 2008 Kai Engert - 3.11.99.3-6 +- Apply upstream patch for bug 417664, enable test suite on pcc. +* Fri Feb 15 2008 Kai Engert - 3.11.99.3-5 +- Support concurrent runs of the test suite on a single build host. +* Thu Feb 14 2008 Kai Engert - 3.11.99.3-4 +- disable test suite on ppc +* Thu Feb 14 2008 Kai Engert - 3.11.99.3-3 +- disable test suite on ppc64 + +* Thu Feb 14 2008 Kai Engert - 3.11.99.3-2 +- Build against gcc 4.3.0, use workaround for bug 432146 +- Run the test suite after the build and abort on failures. + +* Thu Jan 24 2008 Kai Engert - 3.11.99.3-1 +* NSS 3.12 Beta 1 + +* Mon Jan 07 2008 Kai Engert - 3.11.99.2b-3 +- move .so files to /lib + +* Wed Dec 12 2007 Kai Engert - 3.11.99.2b-2 +- NSS 3.12 alpha 2b + +* Mon Dec 03 2007 Kai Engert - 3.11.99.2-2 +- upstream patches to avoid calling netstat for random data + +* Wed Nov 07 2007 Kai Engert - 3.11.99.2-1 +- NSS 3.12 alpha 2 + +* Wed Oct 10 2007 Kai Engert - 3.11.7-10 +- Add /etc/prelink.conf.d/nss-prelink.conf in order to blacklist + our signed libraries and protect them from modification. + +* Thu Sep 06 2007 Rob Crittenden - 3.11.7-9 +- Fix off-by-one error in the PEM module + +* Thu Sep 06 2007 Kai Engert - 3.11.7-8 +- fix a C++ mode compilation error + +* Wed Sep 05 2007 Bob Relyea - 3.11.7-7 +- Add 3.12 ckfw and libnsspem + +* Tue Aug 28 2007 Kai Engert - 3.11.7-6 +- Updated license tag + +* Wed Jul 11 2007 Kai Engert - 3.11.7-5 +- Ensure the workaround for mozilla bug 51429 really get's built. + +* Mon Jun 18 2007 Kai Engert - 3.11.7-4 +- Better approach to ship freebl/softokn based on 3.11.5 +- Remove link time dependency on softokn + +* Sun Jun 10 2007 Kai Engert - 3.11.7-3 +- Fix unowned directories, rhbz#233890 + +* Fri Jun 01 2007 Kai Engert - 3.11.7-2 +- Update to 3.11.7, but freebl/softokn remain at 3.11.5. +- Use a workaround to avoid mozilla bug 51429. + +* Fri Mar 02 2007 Kai Engert - 3.11.5-2 +- Fix rhbz#230545, failure to enable FIPS mode +- Fix rhbz#220542, make NSS more tolerant of resets when in the + middle of prompting for a user password. + +* Sat Feb 24 2007 Kai Engert - 3.11.5-1 +- Update to 3.11.5 +- This update fixes two security vulnerabilities with SSL 2 +- Do not use -rpath link option +- Added several unsupported tools to tools package + +* Tue Jan 9 2007 Bob Relyea - 3.11.4-4 +- disable ECC, cleanout dead code + +* Tue Nov 28 2006 Kai Engert - 3.11.4-1 +- Update to 3.11.4 + +* Thu Sep 14 2006 Kai Engert - 3.11.3-2 +- Revert the attempt to require latest NSPR, as it is not yet available + in the build infrastructure. + +* Thu Sep 14 2006 Kai Engert - 3.11.3-1 +- Update to 3.11.3 + +* Thu Aug 03 2006 Kai Engert - 3.11.2-2 +- Add /etc/pki/nssdb + +* Wed Jul 12 2006 Jesse Keating - 3.11.2-1.1 +- rebuild + +* Fri Jun 30 2006 Kai Engert - 3.11.2-1 +- Update to 3.11.2 +- Enable executable bit on shared libs, also fixes debug info. + +* Wed Jun 14 2006 Kai Engert - 3.11.1-2 +- Enable Elliptic Curve Cryptography (ECC) + +* Fri May 26 2006 Kai Engert - 3.11.1-1 +- Update to 3.11.1 +- Include upstream patch to limit curves + +* Wed Feb 15 2006 Kai Engert - 3.11-4 +- add --noexecstack when compiling assembler on x86_64 + +* Fri Feb 10 2006 Jesse Keating - 3.11-3.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 3.11-3.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Jan 19 2006 Ray Strode 3.11-3 +- rebuild + +* Fri Dec 16 2005 Christopher Aillon 3.11-2 +- Update file list for the devel packages + +* Thu Dec 15 2005 Christopher Aillon 3.11-1 +- Update to 3.11 + +* Thu Dec 15 2005 Christopher Aillon 3.11-0.cvs.2 +- Add patch to allow building on ppc* +- Update the pkgconfig file to Require nspr + +* Thu Dec 15 2005 Christopher Aillon 3.11-0.cvs +- Initial import into Fedora Core, based on a CVS snapshot of + the NSS_3_11_RTM tag +- Fix up the pkcs11-devel subpackage to contain the proper headers +- Build with RPM_OPT_FLAGS +- No need to have rpath of /usr/lib in the pc file + +* Thu Dec 15 2005 Kai Engert +- Adressed review comments by Wan-Teh Chang, Bob Relyea, + Christopher Aillon. + +* Sat Jul 9 2005 Rob Crittenden 3.10-1 +- Initial build