/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* *Thefollowinghandlestheloading,unloadingandmanagementof *variousPCKS#11modules
*/
/* private flags for isModuleDB (field in SECMODModule). */ /* The meaing of these flags is as follows: * *SECMOD_FLAG_MODULE_DB_IS_MODULE_DB-Thisisamodulethataccessesthe *databaseofothermodulestoload.ModuleDBsareloadablemodulesthat *tellsNSSwhichPKCS#11modulestoloadandwhen.ThesemoduleDBsare *chainable.Thatis,onemoduleDBcanloadanotherone.NSSsysteminit *designtakesadvantageofthisfeature.InsystemNSS,afixedsystem *moduleDBloadsthesystemdefinedlibraries,thenchainsouttothe *traditionalmoduleDBstoloadanysystemoruserconfiguredmodules *(likesmartcards).Thisbitisthesameasthealreadyexistingmeaning *ofisModuleDB=PR_TRUE.Noneoftheothermoduledbflagsshouldbeset *ifthisflagisn'ton. * *SECMOD_FLAG_MODULE_DB_SKIP_FIRST-ThisflagtellsNSStoskipthefirst *PKCS#11modulepresentedbyamoduleDB.ThisallowstheOStoloada *softokenfromthesystemmodule,thenasktheexistingmoduleDBcodeto *loadtheotherPKCS#11modulesinthatmoduleDB(skippingit'srequest *toloadsoftoken).Thisgivesthesysteminitfinercontroloverthe *configurationofthatsoftokenmodule. * *SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB-Thisflagallowssysteminittomarka *differentmoduleDBasthe'default'moduleDB(theoneinwhich *'Addmodule'changeswillgo).WithoutthisflagNSStakesthefirst *moduleasthedefaultModuleDB,butinsystemNSS,thatfirstmodule *isthesystemmodule,whichislikelyreadonly(atleasttotheuser). *ThisallowssystemNSStodelegatethosechangestotheuser'smoduleDB, *preservingtheuser'sabilitytoloadnewPKCS#11modules(whichonly *affecthim),fromexistingapplicationslikeFirefox.
*/ #define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB 0x01 /* must be set if any of the \
*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). */ /* The meaing of these flags is as follows: * *SECMOD_FLAG_INTERNAL_IS_INTERNAL-Thisisamarksthethemoduleis *theinternalmodule(thatis,softoken).Thisbitisthesameasthe *alreadyexistingmeaningofinternal=PR_TRUE.Noneoftheother *internalflagsshouldbesetifthisflagisn'ton. * *SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT-Thisflagallowssysteminittomark *adifferentslotreturnedbytPK11_GetInternalKeySlot().The'primary' *slotdefinedbythismodulewillbethenewinternalkeyslot.
*/ #define SECMOD_FLAG_INTERNAL_IS_INTERNAL 0x01 /* must be set if any of \
*the other flags are set */ #define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02
/* allow symbolic names for values. The only ones currently defines or
* SSL protocol versions. */ static SECStatus
secmod_getPolicyOptValue(constchar *policyValue, int policyValueLength,
PRInt32 *result)
{
PRInt32 val = atoi(policyValue); int i;
if ((val != 0) || (*policyValue == '0')) {
*result = val; return SECSuccess;
} if (policyValueLength == 0) { return SECFailure;
} /* 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,
sslOptList[i].name_size) == 0) {
*result = sslOptList[i].option; return SECSuccess;
}
} /* handle key_size flags. Each flag represents a bit, which
* gets or'd together. They can be separated by , | or + */
val = 0; while (policyValueLength > 0) {
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;
policyValueLength -= keySizeFlagsList[i].name_size; break;
}
} if (!found) { return SECFailure;
} if (*policyValue == ',' || *policyValue == '|' || *policyValue == '+') {
policyValue++;
policyValueLength--;
}
}
*result = val; return SECSuccess;
}
/* Enable/Disable only apply to SSL cipher suites and S/MIME symetric algorithms. *Enable/DisableisimplementedbyclearingtheDEFAULT_NOT_VALID *flag,thensettingtheNSS_USE_DEFAULT_SSL_ENABLEand *NSS_USE_DEFAULT_SMIME_ENABLEflagstothecorrectvalue.Thessl *policycodewillthensortoutwhattosetbasedonciphersand *ciphersuitevaluesandthesmimepolicycodewillsort
* out which ciphers to include in capabilities based on these values */ static SECStatus
secmod_setDefault(SECOidTag oid, NSSPolicyOperation operation,
PRUint32 value)
{
SECStatus rv = SECSuccess;
PRUint32 policy;
PRUint32 useDefault = 0;
PRUint32 set = 0; /* we always clear the default not valid flag as this operation will
* make the defaults valid */
PRUint32 clear = NSS_USE_DEFAULT_NOT_VALID;
/* what values are we trying to change */ /* if either SSL or SSL_KX is set, enable SSL */ if (value & (NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX)) {
useDefault |= NSS_USE_DEFAULT_SSL_ENABLE;
} /* only bulk ciphers are configured as enable in S/MIME, only
* enable them if both SMIME bits are set */ if ((value & NSS_USE_ALG_IN_SMIME) == NSS_USE_ALG_IN_SMIME) {
useDefault |= NSS_USE_DEFAULT_SMIME_ENABLE;
}
/* on disable we clear, on enable we set */ if (operation == NSS_DISABLE) {
clear |= useDefault;
} else { /* we also turn the cipher on by policy if we enable it,
* so include the policy bits */
set |= value | useDefault;
}
/* if we haven't set the not valid flag yet, then we need to *clearanyoftheotherbitswearen'tactuallysettingaswell.
*/
rv = NSS_GetAlgorithmPolicy(oid, &policy); if (rv != SECSuccess) { return rv;
} if (policy & NSS_USE_DEFAULT_NOT_VALID) {
clear |= ((NSS_USE_DEFAULT_SSL_ENABLE | NSS_USE_DEFAULT_SMIME_ENABLE) &
~set);
} return NSS_SetAlgorithmPolicy(oid, set, clear);
}
/* apply the operator specific policy */
SECStatus
secmod_setPolicyOperation(SECOidTag oid, NSSPolicyOperation operation,
PRUint32 value)
{
SECStatus rv = SECSuccess; switch (operation) { case NSS_DISALLOW: /* clear the requested policy bits */
rv = NSS_SetAlgorithmPolicy(oid, 0, value); break; case NSS_ALLOW: /* set the requested policy bits */
rv = NSS_SetAlgorithmPolicy(oid, value, 0); break; case NSS_DISABLE: case NSS_ENABLE:
rv = secmod_setDefault(oid, operation, value); break; default:
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure; break;
} return rv;
}
constchar *
secmod_getOperationString(NSSPolicyOperation operation)
{ switch (operation) { case NSS_DISALLOW: return"disallow"; case NSS_ALLOW: return"allow"; case NSS_DISABLE: return"disable"; case NSS_ENABLE: return"enable"; default: break;
} return"invalid";
}
/* Allow external applications fetch the policy oid based on the internal *stringmappingusedbytheconfigurationsystem.Thesearchcanbe *narrowedbysupplyingthenameofthetable(list)thatthepolicy
* is on. The value 'Any' allows the policy to be searched on all lists */
SECOidTag
SECMOD_PolicyStringToOid(constchar *policy, constchar *list)
{
PRBool any = (PORT_Strcasecmp(list, "Any") == 0) ? PR_TRUE : PR_FALSE; int len = PORT_Strlen(policy); int i, j;
for (i = 0; i < PR_ARRAY_SIZE(algOptLists); i++) { const algListsDef *algOptList = &algOptLists[i]; if (any || (PORT_Strcasecmp(algOptList->description, list) == 0)) { for (j = 0; j < algOptList->entries; j++) { const oidValDef *algOpt = &algOptList->list[j]; unsigned name_size = algOpt->name_size; if (len == name_size &&
PORT_Strcasecmp(algOpt->name, policy) == 0) { return algOpt->oid;
}
}
}
} return SEC_OID_UNKNOWN;
}
/* Allow external applications fetch the NSS option based on the internal
* string mapping used by the configuration system. */
PRUint32
SECMOD_PolicyStringToOpt(constchar *policy)
{ int len = PORT_Strlen(policy); int i;
for (i = 0; i < PR_ARRAY_SIZE(freeOptList); i++) { const optionFreeDef *freeOpt = &freeOptList[i]; unsigned name_size = freeOpt->name_size; if (len == name_size &&
PORT_Strcasecmp(freeOpt->name, policy) == 0) { return freeOpt->option;
}
} return0;
}
/* Allow external applications map policy flags to their string equivalance. *Somestringsrepresentmorethanoneflag.Ifmorethanoneflagisincluded *thereturnedstringisthestringthatcontainsanyofthe *suppliedflagsunlessexactisspecified.Ifexactisspecified,thenthe *returnedvaluematchesalltheincludedflagsandonlythoseflags.For *Example:'ALL-SIGNATURE'hasthebitsNSS_USE_ALG_IN_CERTSIGNATURE| *NSS_USE_ALG_IN_SMIME_SIGNATURE|NSS_USE_ALG_IN_ANY_SIGNATURE.Ifyouaskfor *NSS_USE_ALG_IN_CERT_SIGNATURE|NSS_USE_ALG_IN_SMIME_SIGNATUREanddon'tset *exact,thisfunctionwillreturn'ALL-SIGNATURE'ifyoudosetexact,youmust
* include all three bits in value to get 'All-SIGNATURE'*/ constchar *
SECMOD_FlagsToPolicyString(PRUint32 val, PRBool exact)
{ int i;
for (i = 0; i < PR_ARRAY_SIZE(policyFlagList); i++) { const policyFlagDef *policy = &policyFlagList[i]; if (exact && (policy->flag == val)) { return policy->name;
} if (!exact && ((policy->flag & val) == policy->flag)) { return policy->name;
}
} return NULL;
}
if (policyConfig == NULL) { return SECSuccess; /* no policy given */
} /* make sure we initialize the oid table and set all the default policy
* values first so we can override them here */
rv = SECOID_Init(); if (rv != SECSuccess) { return rv;
}
args = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_DISALLOW, printPolicyFeedback,
policyCheckFlags); if (args)
PORT_Free(args); if (rv != SECSuccess) { return rv;
}
args = NSSUTIL_ArgGetParamValue("allow", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_ALLOW, printPolicyFeedback,
policyCheckFlags); if (args)
PORT_Free(args); if (rv != SECSuccess) { return rv;
}
args = NSSUTIL_ArgGetParamValue("disable", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_DISABLE, printPolicyFeedback,
policyCheckFlags); if (args)
PORT_Free(args); if (rv != SECSuccess) { return rv;
}
args = NSSUTIL_ArgGetParamValue("enable", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_ENABLE, printPolicyFeedback,
policyCheckFlags); if (args)
PORT_Free(args); if (rv != SECSuccess) { return rv;
} /* this has to be last. Everything after this will be a noop */ if (NSSUTIL_ArgHasFlag("flags", "ssl-lock", policyConfig)) {
PRInt32 locks; /* don't overwrite other (future) lock flags */
rv = NSS_OptionGet(NSS_DEFAULT_LOCKS, &locks); if (rv == SECSuccess) {
rv = NSS_OptionSet(NSS_DEFAULT_LOCKS, locks | NSS_DEFAULT_SSL_LOCK);
} if (rv != SECSuccess) { return rv;
}
} if (NSSUTIL_ArgHasFlag("flags", "policy-lock", policyConfig)) {
NSS_LockPolicy();
} if (printPolicyFeedback) { /* This helps to distinguish configurations that don't contain any
* policy config= statement. */
PR_SetEnv("NSS_POLICY_LOADED=1");
fprintf(stderr, "NSS-POLICY-INFO: LOADED-SUCCESSFULLY\n");
secmod_sanityCheckCryptoPolicy();
} return rv;
}
/* do not load the module if policy parsing fails */ if (rv != SECSuccess) { if (printPolicyFeedback) {
PR_SetEnv("NSS_POLICY_FAIL=1");
fprintf(stderr, "NSS-POLICY-FAIL: policy config parsing failed, not loading module %s\n", moduleName);
} return NULL;
}
mod = secmod_NewModule(); if (mod == NULL) return NULL;
mod->commonName = PORT_ArenaStrdup(mod->arena, moduleName ? moduleName : ""); if (library) {
mod->dllName = PORT_ArenaStrdup(mod->arena, library);
} /* new field */ if (parameters) {
mod->libraryParams = PORT_ArenaStrdup(mod->arena, parameters);
}
mod->internal = NSSUTIL_ArgHasFlag("flags", "internal", nss);
mod->isFIPS = NSSUTIL_ArgHasFlag("flags", "FIPS", nss); /* if the system FIPS mode is enabled, force FIPS to be on */ if (SECMOD_GetSystemFIPSEnabled()) {
mod->isFIPS = PR_TRUE;
}
mod->isCritical = NSSUTIL_ArgHasFlag("flags", "critical", nss);
slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena, slotParams,
&mod->slotInfoCount); if (slotParams)
PORT_Free(slotParams); /* new field */
mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nss,
NSSUTIL_DEFAULT_TRUST_ORDER, NULL); /* new field */
mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder", nss,
NSSUTIL_DEFAULT_CIPHER_ORDER, NULL); /* new field */
mod->isModuleDB = NSSUTIL_ArgHasFlag("flags", "moduleDB", nss);
mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags", "moduleDBOnly", nss); if (mod->moduleDBOnly)
mod->isModuleDB = PR_TRUE;
/* we need more bits, but we also want to preserve binary compatibility *soweoverloadtheisModuleDBPRBoolwithadditionalflags. *Theseflagsareonlyvalidifmod->isModuleDBisalreadyset. *NOTE:thisdependsonthefactthatPRBoolisatleastacharon *allplatforms.TheseflagsareonlyvalidifmoduleDBisset,so
* code checking if (mod->isModuleDB) will continue to work correctly. */ if (mod->isModuleDB) { char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB; if (NSSUTIL_ArgHasFlag("flags", "skipFirst", nss)) {
flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST;
} if (NSSUTIL_ArgHasFlag("flags", "defaultModDB", nss)) {
flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB;
} if (NSSUTIL_ArgHasFlag("flags", "policyOnly", nss)) {
flags |= SECMOD_FLAG_MODULE_DB_POLICY_ONLY;
} /* additional moduleDB flags could be added here in the future */
mod->isModuleDB = (PRBool)flags;
}
if (mod->internal) { char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL;
/* no target found, return the newSpec */ if (target == NULL) { return newSpec;
}
/* now build the child array from target */ /*first count them */ for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex;
tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
tokenCount++;
}
childArray = PORT_NewArray(char *, tokenCount + 1); if (childArray == NULL) { /* just return the spec as is then */
PORT_Free(target); return newSpec;
} if (ids) {
idArray = PORT_NewArray(CK_SLOT_ID, tokenCount + 1); if (idArray == NULL) {
PORT_Free(childArray);
PORT_Free(target); return newSpec;
}
}
/* now fill them in */ for (tokenIndex = NSSUTIL_ArgStrip(target), i = 0;
*tokenIndex && (i < tokenCount);
tokenIndex = NSSUTIL_ArgStrip(tokenIndex)) { int next; char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
tokenIndex += next;
if (idArray) {
idArray[i] = NSSUTIL_ArgDecodeNumber(name);
}
PORT_Free(name); /* drop the explicit number */
/* if anything is left, copy the args to the child array */ if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next);
tokenIndex += next;
}
}
/* return it */
*children = childArray; if (ids) {
*ids = idArray;
} return newSpec;
}
/* get the database and flags from the spec */ staticchar *
secmod_getConfigDir(constchar *spec, char **certPrefix, char **keyPrefix,
PRBool *readOnly)
{ char *config = NULL;
/* do two config paramters match? Not all callers are compariing *SECMODConfigListsdirectly,sothisfunctionbreaksthemouttotheir
* components. */ static PRBool
secmod_matchConfig(char *configDir1, char *configDir2, char *certPrefix1, char *certPrefix2, char *keyPrefix1, char *keyPrefix2,
PRBool isReadOnly1, PRBool isReadOnly2)
{ /* TODO: Document the answer to the question: *"WhynotallowthemtomatchiftheyarebothNULL?" *See:https://bugzilla.mozilla.org/show_bug.cgi?id=1318633#c1
*/ if ((configDir1 == NULL) || (configDir2 == NULL)) { return PR_FALSE;
} if (strcmp(configDir1, configDir2) != 0) { return PR_FALSE;
} if (!secmod_matchPrefix(certPrefix1, certPrefix2)) { return PR_FALSE;
} if (!secmod_matchPrefix(keyPrefix1, keyPrefix2)) { return PR_FALSE;
} /* these last test -- if we just need the DB open read only, *thananyopenwillsuffice,butifwerequesteditread/write
* and it's only open read only, we need to open it again */ if (isReadOnly1) { return PR_TRUE;
} if (isReadOnly2) { /* isReadonly1 == PR_FALSE */ return PR_FALSE;
} return PR_TRUE;
}
/* *returntrueifwearerequestingadatabasethatisalreadyopenned.
*/
PRBool
secmod_MatchConfigList(constchar *spec, SECMODConfigList *conflist, int count)
{ char *config; char *certPrefix; char *keyPrefix;
PRBool isReadOnly;
PRBool ret = PR_FALSE; int i;
/* NOTE: we dbm isn't multiple open safe. If we open the same database *twicefromtwodifferentlocations,thenwecancorruptourdatabase *(thecachewillbeinconsistent).Protectagainstthisbyclaiming *forcomparisononlythatwearealwaysopenningdbmdatabasesreadonly.
*/ if (secmod_configIsDBM(config)) {
isReadOnly = 1;
} for (i = 0; i < count; i++) { if (secmod_matchConfig(config, conflist[i].config, certPrefix,
conflist[i].certPrefix, keyPrefix,
conflist[i].keyPrefix, isReadOnly,
conflist[i].isReadOnly)) {
ret = PR_TRUE; goto done;
}
}
ret = PR_FALSE;
done:
PORT_Free(config);
PORT_Free(certPrefix);
PORT_Free(keyPrefix); return ret;
}
/* first check to see if the parent is the database */
thisConfig = secmod_getConfigDir(tmp_spec, &thisCertPrefix, &thisKeyPrefix,
&thisReadOnly); if (!thisConfig) { goto done;
} if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) { /* yup it's the default key slot, get the id for it */
PK11SlotInfo *slot = PK11_GetInternalKeySlot(); if (slot) {
slotID = slot->slotID;
PK11_FreeSlot(slot);
} goto done;
}
/* find id of the token */ for (thisChild = children, thisID = ids; thisChild && *thisChild; thisChild++, thisID++) {
PORT_Free(thisConfig);
PORT_Free(thisCertPrefix);
PORT_Free(thisKeyPrefix);
thisConfig = secmod_getConfigDir(*thisChild, &thisCertPrefix,
&thisKeyPrefix, &thisReadOnly); if (thisConfig == NULL) { continue;
} if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
slotID = *thisID; break;
}
}
void
secmod_FreeConfigList(SECMODConfigList *conflist, int count)
{ int i; for (i = 0; i < count; i++) {
PORT_Free(conflist[i].config);
PORT_Free(conflist[i].certPrefix);
PORT_Free(conflist[i].keyPrefix);
}
PORT_Free(conflist);
}
char *
secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
{ char *rawParam = NULL; /* oldParam with tokens stripped off */ char *newParam = NULL; /* space for the return parameter */ char *nextParam = NULL; /* current end of the new parameter */ char **oldChildren = NULL;
CK_SLOT_ID *oldIds = NULL; void *mark = NULL; /* mark the arena pool in case we need
* to release it */ int length, i, tmpLen;
SECStatus rv;
/* first strip out and save the old tokenlist */
rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE, PR_FALSE,
oldParam, &oldChildren, &oldIds); if (!rawParam) { goto loser;
}
/* now calculate the total length of the new buffer */ /* First the 'fixed stuff', length of rawparam (does not include a NULL),
* length of the token string (does include the NULL), closing bracket */
length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1; /* now add then length of all the old children */ for (i = 0; oldChildren && oldChildren[i]; i++) {
length += secmod_getChildLength(oldChildren[i], oldIds[i]);
}
/* add the new token */
length += secmod_getChildLength(newToken, newID);
/* and it's new children */ for (i = 0; children && children[i]; i++) { if (ids[i] == -1) { continue;
}
length += secmod_getChildLength(children[i], ids[i]);
}
/* now allocate and build the string */
mark = PORT_ArenaMark(arena); if (!mark) { goto loser;
}
newParam = PORT_ArenaAlloc(arena, length); if (!newParam) { goto loser;
}
for (i = 0; children && children[i]; i++) { if (ids[i] == -1) { continue;
}
rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]); if (rv != SECSuccess) { goto loser;
}
}
if (length < 2) { goto loser;
}
*nextParam++ = ']';
*nextParam++ = 0;
/* we are going to return newParam now, don't release the mark */
PORT_ArenaUnmark(arena, mark);
mark = NULL;
loser: if (mark) {
PORT_ArenaRelease(arena, mark);
newParam = NULL; /* if the mark is still active,
* don't return the param */
} if (rawParam) {
PORT_Free(rawParam);
} if (oldChildren) {
secmod_FreeChildren(oldChildren, oldIds);
} return newParam;
}
if (library)
PORT_Free(library); if (moduleName)
PORT_Free(moduleName); if (parameters)
PORT_Free(parameters); if (nss)
PORT_Free(nss); if (config)
PORT_Free(config); 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)) {
module->internal = parent->internal;
}
}
/* load it */
rv = secmod_LoadPKCS11Module(module, &oldModule); if (rv != SECSuccess) { goto loser;
}
/* if we just reload an old module, no need to add it to any lists.
* we simple release all our references */ if (oldModule) { /* This module already exists, don't link it anywhere. This
* will probably destroy this module */
SECMOD_DestroyModule(module); return oldModule;
}
if (recurse && module->isModuleDB) { char **moduleSpecList;
PORT_SetError(0);
moduleSpecList = SECMOD_GetModuleSpecList(module); if (moduleSpecList) { char **index;
index = moduleSpecList; if (*index && SECMOD_GetSkipFirstFlag(module)) {
index++;
}
module->commonName = PORT_ArenaStrdup(module->arena, moduleName ? moduleName : "");
module->internal = PR_FALSE;
module->isFIPS = PR_FALSE; /* if the system FIPS mode is enabled, force FIPS to be on */ if (SECMOD_GetSystemFIPSEnabled()) {
module->isFIPS = PR_TRUE;
}
module->isCritical = PR_FALSE; /* new field */
module->trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER; /* new field */
module->cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER; /* new field */
module->isModuleDB = PR_FALSE;
module->moduleDBOnly = PR_FALSE;
module->ssl[0] = 0;
module->ssl[1] = 0;
secmod_PrivateModuleCount++;
/* load it */
rv = secmod_LoadPKCS11ModuleFromFunction(module, &oldModule, fentry); if (rv != SECSuccess) { goto loser;
}
/* if we just reload an old module, no need to add it to any lists.
* we simple release all our references */ if (oldModule) { /* This module already exists, don't link it anywhere. This
* will probably destroy this module */
SECMOD_DestroyModule(module); return oldModule;
}
SECMOD_AddModuleToList(module); /* handle any additional work here */ return module;
loser: if (module) { if (module->loaded) {
SECMOD_UnloadModule(module);
}
SECMOD_AddModuleToUnloadList(module);
} return module;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.