diff --git a/nss-check-policy-file.patch b/nss-check-policy-file.patch new file mode 100644 index 0000000..51db5bf --- /dev/null +++ b/nss-check-policy-file.patch @@ -0,0 +1,188 @@ +diff -up ./nss/lib/nss/config.mk.check_policy_file ./nss/lib/nss/config.mk +--- ./nss/lib/nss/config.mk.check_policy_file 2016-03-16 14:44:30.254078910 -0700 ++++ ./nss/lib/nss/config.mk 2016-03-16 14:44:30.290079522 -0700 +@@ -104,3 +104,7 @@ DEFINES += -DWIN32_NSS3_DLL_COMPAT + DLLFLAGS += -EXPORT:mktemp=nss_mktemp,PRIVATE + endif + endif ++ ++ifdef POLICY_FILE ++DEFINES += -DPOLICY_FILE=\"$(POLICY_FILE)\" -DPOLICY_PATH=\"$(POLICY_PATH)\" ++endif +diff -up ./nss/lib/nss/nssinit.c.check_policy_file ./nss/lib/nss/nssinit.c +--- ./nss/lib/nss/nssinit.c.check_policy_file 2016-02-26 12:51:11.000000000 -0800 ++++ ./nss/lib/nss/nssinit.c 2016-03-16 15:08:54.455301088 -0700 +@@ -335,7 +335,7 @@ nss_FindExternalRoot(const char *dbpath, + * set statics (from PKCS11_Configure, for instance), and uses it to kick off + * the loading of the various PKCS #11 modules. + */ +-static SECStatus ++static SECMODModule * + nss_InitModules(const char *configdir, const char *certPrefix, + const char *keyPrefix, const char *secmodName, + const char *updateDir, const char *updCertPrefix, +@@ -345,7 +345,7 @@ nss_InitModules(const char *configdir, c + PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace, + PRBool isContextInit) + { +- SECStatus rv = SECFailure; ++ SECMODModule *module = NULL; + char *moduleSpec = NULL; + char *flags = NULL; + char *lconfigdir = NULL; +@@ -360,12 +360,12 @@ nss_InitModules(const char *configdir, c + + if (NSS_InitializePRErrorTable() != SECSuccess) { + PORT_SetError(SEC_ERROR_NO_MEMORY); +- return rv; ++ return NULL; + } + + flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen, + pwRequired, optimizeSpace); +- if (flags == NULL) return rv; ++ if (flags == NULL) return NULL; + + /* + * configdir is double nested, and Windows uses the same character +@@ -432,14 +432,16 @@ loser: + if (lupdateName) PORT_Free(lupdateName); + + if (moduleSpec) { +- SECMODModule *module = SECMOD_LoadModule(moduleSpec,NULL,PR_TRUE); ++ module = SECMOD_LoadModule(moduleSpec,NULL,PR_TRUE); + PR_smprintf_free(moduleSpec); + if (module) { +- if (module->loaded) rv=SECSuccess; +- SECMOD_DestroyModule(module); ++ if (!module->loaded) { ++ SECMOD_DestroyModule(module); ++ module = NULL; ++ } + } + } +- return rv; ++ return module; + } + + /* +@@ -525,7 +527,7 @@ nss_Init(const char *configdir, const ch + PRBool allowAlreadyInitializedModules, + PRBool dontFinalizeModules) + { +- SECStatus rv = SECFailure; ++ SECMODModule *parent = NULL; + PKIX_UInt32 actualMinorVersion = 0; + PKIX_Error *pkixError = NULL; + PRBool isReallyInitted; +@@ -635,13 +637,13 @@ nss_Init(const char *configdir, const ch + /* Skip the module init if we are already initted and we are trying + * to init with noCertDB and noModDB */ + if (!(isReallyInitted && noCertDB && noModDB)) { +- rv = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName, ++ parent = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName, + updateDir, updCertPrefix, updKeyPrefix, updateID, + updateName, configName, configStrings, passwordRequired, + readOnly, noCertDB, noModDB, forceOpen, optimizeSpace, + (initContextPtr != NULL)); + +- if (rv != SECSuccess) { ++ if (parent == NULL) { + goto loser; + } + } +@@ -680,7 +682,24 @@ nss_Init(const char *configdir, const ch + } + } + } +- ++#ifdef POLICY_FILE ++ if (PR_Access(POLICY_PATH "/" POLICY_FILE, PR_ACCESS_READ_OK) == PR_SUCCESS ) { ++ SECMODModule *module = SECMOD_LoadModule( ++ "name=\"Policy File\" " ++ "parameters=\"configdir='sql:" POLICY_PATH "' " ++ "secmod='" POLICY_FILE "' " ++ "flags=readOnly,noCertDB,forceSecmodChoice,forceOpen\" " ++ "NSS=\"flags=internal,moduleDB,skipFirst,moduleDBOnly,critical\"", ++ parent, PR_TRUE); ++ if (module) { ++ PRBool isLoaded = module->loaded; ++ SECMOD_DestroyModule(module); ++ if (!isLoaded) { ++ goto loser; ++ } ++ } ++ } ++#endif + pk11sdr_Init(); + cert_CreateSubjectKeyIDHashTable(); + +@@ -721,6 +740,9 @@ nss_Init(const char *configdir, const ch + if (initContextPtr && configStrings) { + PR_smprintf_free(configStrings); + } ++ if (parent) { ++ SECMOD_DestroyModule(parent); ++ } + + return SECSuccess; + +@@ -737,6 +759,9 @@ loser: + /* We failed to init, allow one to move forward */ + PZ_NotifyCondVar(nssInitCondition); + PZ_Unlock(nssInitLock); ++ if (parent) { ++ SECMOD_DestroyModule(parent); ++ } + return SECFailure; + } + +diff -up ./nss/lib/pk11wrap/pk11pars.c.check_policy_file ./nss/lib/pk11wrap/pk11pars.c +--- ./nss/lib/pk11wrap/pk11pars.c.check_policy_file 2016-02-26 12:51:11.000000000 -0800 ++++ ./nss/lib/pk11wrap/pk11pars.c 2016-03-16 14:44:30.291079539 -0700 +@@ -110,6 +110,7 @@ secmod_NewModule(void) + *other flags are set */ + #define SECMOD_FLAG_MODULE_DB_SKIP_FIRST 0x02 + #define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04 ++#define SECMOD_FLAG_MODULE_DB_POLICY_ONLY 0x08 + + + /* private flags for internal (field in SECMODModule). */ +@@ -704,6 +705,9 @@ SECMOD_CreateModuleEx(const char *librar + if (NSSUTIL_ArgHasFlag("flags","defaultModDB",nssc)) { + flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB; + } ++ if (NSSUTIL_ArgHasFlag("flags","policyOnly",nssc)) { ++ flags |= SECMOD_FLAG_MODULE_DB_POLICY_ONLY; ++ } + /* additional moduleDB flags could be added here in the future */ + mod->isModuleDB = (PRBool) flags; + } +@@ -743,6 +747,14 @@ SECMOD_GetDefaultModDBFlag(SECMODModule + } + + PRBool ++secmod_PolicyOnly(SECMODModule *mod) ++{ ++ char flags = (char) mod->isModuleDB; ++ ++ return (flags & SECMOD_FLAG_MODULE_DB_POLICY_ONLY) ? PR_TRUE : PR_FALSE; ++} ++ ++PRBool + secmod_IsInternalKeySlot(SECMODModule *mod) + { + char flags = (char) mod->internal; +@@ -1526,6 +1538,12 @@ SECMOD_LoadModule(char *modulespec,SECMO + if (!module) { + goto loser; + } ++ ++ /* a policy only stanza doesn't actually get 'loaded'. policy has already ++ * been parsed as a side effect of the CreateModuleEx call */ ++ if (secmod_PolicyOnly(module)) { ++ return module; ++ } + if (parent) { + module->parent = SECMOD_ReferenceModule(parent); + if (module->internal && secmod_IsInternalKeySlot(parent)) { diff --git a/nss.spec b/nss.spec index b75d01b..9c606f9 100644 --- a/nss.spec +++ b/nss.spec @@ -21,7 +21,7 @@ Name: nss Version: 3.23.0 # for Rawhide, please always use release >= 2 # for Fedora release branches, please use release < 2 (1.0, 1.1, ...) -Release: 4%{?dist} +Release: 5%{?dist} License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Group: System Environment/Libraries @@ -97,6 +97,8 @@ Patch54: tstclnt-ssl2-off-by-default.patch Patch55: skip_stress_TLS_RC4_128_with_MD5.patch # Local patch for TLS_ECDHE_{ECDSA|RSA}_WITH_3DES_EDE_CBC_SHA ciphers Patch58: rhbz1185708-enable-ecc-3des-ciphers-by-default.patch +# TODO: file a bug usptream +Patch59: nss-check-policy-file.patch %description @@ -187,6 +189,7 @@ popd %patch54 -p0 -b .ssl2_off %patch55 -p1 -b .skip_stress_tls_rc4_128_with_md5 %patch58 -p0 -b .1185708_3des +%patch59 -p1 -b .check_policy_file ######################################################### # Higher-level libraries and test tools need access to @@ -301,6 +304,12 @@ export NSS_BLTEST_NOT_AVAILABLE=1 %{__make} -C ./nss/coreconf %{__make} -C ./nss/lib/dbm +# Set the policy file location +# if set NSS will always check for the policy file and load it if it exists +export POLICY_FILE="policy.cfg" +# location of the policy file +export POLICY_PATH="/etc/pki/nssdb" + # nss/nssinit.c, ssl/sslcon.c, smime/smimeutil.c and ckfw/builtins/binst.c # need nss/lib/util/verref.h which is which is exported privately, # copy the one we saved during prep so it they can find it. @@ -815,6 +824,10 @@ fi %changelog +* Thu Mar 24 2016 Elio Maldonado - 3.2 +- 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