/* 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/. */ /* * The following handles the loading, unloading and management of * various PCKS #11 modules
*/
/* private flags for isModuleDB (field in SECMODModule). */ /* The meaing of these flags is as follows: * * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the * database of other modules to load. Module DBs are loadable modules that * tells NSS which PKCS #11 modules to load and when. These module DBs are * chainable. That is, one module DB can load another one. NSS system init * design takes advantage of this feature. In system NSS, a fixed system * module DB loads the system defined libraries, then chains out to the * traditional module DBs to load any system or user configured modules * (like smart cards). This bit is the same as the already existing meaning * of isModuleDB = PR_TRUE. None of the other module db flags should be set * if this flag isn't on. * * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first * PKCS #11 module presented by a module DB. This allows the OS to load a * softoken from the system module, then ask the existing module DB code to * load the other PKCS #11 modules in that module DB (skipping it's request * to load softoken). This gives the system init finer control over the * configuration of that softoken module. * * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a * different module DB as the 'default' module DB (the one in which * 'Add module' changes will go). Without this flag NSS takes the first * module as the default Module DB, but in system NSS, that first module * is the system module, which is likely read only (at least to the user). * This allows system NSS to delegate those changes to the user's module DB, * preserving the user's ability to load new PKCS #11 modules (which only * affect him), from existing applications like Firefox.
*/ #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 - This is a marks the the module is * the internal module (that is, softoken). This bit is the same as the * already existing meaning of internal = PR_TRUE. None of the other * internal flags should be set if this flag isn't on. * * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary' * slot defined by this module will be the new internal key slot.
*/ #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
/* * for 3.4 we continue to use the old SECMODModule structure
*/
SECMODModule *
SECMOD_CreateModule(constchar *library, constchar *moduleName, constchar *parameters, constchar *nss)
{ return SECMOD_CreateModuleEx(library, moduleName, parameters, nss, NULL);
}
/* * NSS config options format: * * The specified ciphers will be allowed by policy, but an application * may allow more by policy explicitly: * config="allow=curve1:curve2:hash1:hash2:rsa-1024..." * * Only the specified hashes and curves will be allowed: * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1" * * Only the specified hashes and curves will be allowed, and * RSA keys of 2048 or more will be accepted, and DH key exchange * with 1024-bit primes or more: * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1:min-rsa=2048:min-dh=1024" * * A policy that enables the AES ciphersuites and the SECP256/384 curves: * config="allow=aes128-cbc:aes128-gcm:TLS1.0:TLS1.2:TLS1.1:HMAC-SHA1:SHA1:SHA256:SHA384:RSA:ECDHE-RSA:SECP256R1:SECP384R1" * * Disallow values are parsed first, then allow values, independent of the * order they appear. * * flags: turn on the following flags: * policy-lock: turn off the ability for applications to change policy with * the call NSS_SetAlgorithmPolicy or the other system policy * calls (SSL_SetPolicy, etc.) * ssl-lock: turn off the ability to change the ssl defaults. * * The following only apply to ssl cipher suites (future smime) * * enable: turn on ciphersuites by default. * disable: turn off ciphersuites by default without disallowing them by policy. * *
*/
/* 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 }, /* constraints on DTLS Protocols */
{ CIPHER_NAME("DTLS-VERSION-MIN"), NSS_DTLS_VERSION_MIN_POLICY },
{ CIPHER_NAME("DTLS-VERSION-MAX"), NSS_DTLS_VERSION_MAX_POLICY }
};
staticconst policyFlagDef policyFlagList[] = {
{ CIPHER_NAME("SSL"), NSS_USE_ALG_IN_SSL },
{ CIPHER_NAME("SSL-KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX }, /* add other key exhanges in the future */
{ CIPHER_NAME("KEY-EXCHANGE"), NSS_USE_ALG_IN_KEY_EXCHANGE },
{ CIPHER_NAME("CERT-SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("CMS-SIGNATURE"), NSS_USE_ALG_IN_SMIME_SIGNATURE },
{ CIPHER_NAME("SMIME-SIGNATURE"), NSS_USE_ALG_IN_SMIME_SIGNATURE },
{ CIPHER_NAME("ALL-SIGNATURE"), NSS_USE_ALG_IN_SIGNATURE },
{ CIPHER_NAME("PKCS12"), NSS_USE_ALG_IN_PKCS12 }, /* only use in allow */
{ CIPHER_NAME("PKCS12-LEGACY"), NSS_USE_ALG_IN_PKCS12_DECRYPT }, /* only use in disallow */
{ CIPHER_NAME("PKCS12-ENCRYPT"), NSS_USE_ALG_IN_PKCS12_ENCRYPT },
{ CIPHER_NAME("SMIME"), NSS_USE_ALG_IN_SMIME }, /* only use in allow, enable */
{ CIPHER_NAME("SMIME-LEGACY"), NSS_USE_ALG_IN_SMIME_LEGACY }, /* only use in disallow, disable */
{ CIPHER_NAME("SMIME-ENCRYPT"), NSS_USE_ALG_IN_SMIME_ENCRYPT },
{ CIPHER_NAME("SMIME-KEY-EXCHANGE"), NSS_USE_ALG_IN_SMIME_KX }, /* only use in allow */
{ CIPHER_NAME("SMIME-KEY-EXCHANGE-LEGACY"), NSS_USE_ALG_IN_SMIME_KX_LEGACY }, /* only use in disallow */
{ CIPHER_NAME("SMIME-KEY-EXCHANGE-ENCRYPT"), NSS_USE_ALG_IN_SMIME_KX_ENCRYPT }, /* sign turns off all signatures, but doesn't change the * allowance for specific signatures... for example: * disallow=sha256/all allow=sha256/signature * doesn't allow cert-signatures or sime-signatures, where * disallow=sha256/all allow=sha256/all-signature * does. however, * disallow=sha256/signature * and * disallow=sha256/all-signature
* are equivalent in effect */
{ CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_ANY_SIGNATURE }, /* enable/allow algorithms for legacy (read/verify)operations */
{ CIPHER_NAME("LEGACY"), NSS_USE_ALG_IN_PKCS12_DECRYPT |
NSS_USE_ALG_IN_SMIME_LEGACY |
NSS_USE_ALG_IN_SMIME_KX_LEGACY }, /* enable/disable everything */
{ CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX |
NSS_USE_ALG_IN_PKCS12 | NSS_USE_ALG_IN_SMIME |
NSS_USE_ALG_IN_SIGNATURE |
NSS_USE_ALG_IN_SMIME_KX },
{ CIPHER_NAME("NONE"), 0 }
};
/* * Get the next cipher on the list. point to the next one in 'next'. * return the length;
*/ staticconstchar *
secmod_ArgGetSubValue(constchar *cipher, char sep1, char sep2, int *len, constchar **next)
{ constchar *start = cipher;
/* 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;
}
/* Policy operations: * Disallow: operation is disallowed by policy. Implies disabled. * Allow: operation is allowed by policy (but could be disabled). * Disable: operation is turned off by default (but could be allowed). * Enable: operation is enabled by default. Implies allowed.
*/ typedefenum {
NSS_DISALLOW,
NSS_ALLOW,
NSS_DISABLE,
NSS_ENABLE
} NSSPolicyOperation;
/* Enable/Disable only apply to SSL cipher suites and S/MIME symetric algorithms. * Enable/Disable is implemented by clearing the DEFAULT_NOT_VALID * flag, then setting the NSS_USE_DEFAULT_SSL_ENABLE and * NSS_USE_DEFAULT_SMIME_ENABLE flags to the correct value. The ssl * policy code will then sort out what to set based on ciphers and * cipher suite values and the smime policy code will sort
* 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 * clear any of the other bits we aren't actually setting as well.
*/
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";
}
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 * so we overload the isModuleDB PRBool with additional flags. * These flags are only valid if mod->isModuleDB is already set. * NOTE: this depends on the fact that PRBool is at least a char on * all platforms. These flags are only valid if moduleDB is set, 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;
/* * copy desc and value into target. Target is known to be big enough to * hold desc +2 +value, which is good because the result of this will be * *desc"*value". We may, however, have to add some escapes for special * characters imbedded into value (rare). This string potentially comes from * a user, so we don't want the user overflowing the target buffer by using * excessive escapes. To prevent this we count the escapes we need to add and * try to expand the buffer with Realloc.
*/ staticchar *
secmod_doDescCopy(char *target, char **base, int *baseLen, constchar *desc, int descLen, char *value)
{ int diff, esc_len;
esc_len = NSSUTIL_EscapeSize(value, '\"') - 1;
diff = esc_len - strlen(value); if (diff > 0) { /* we need to escape... expand newSpecPtr as well to make sure
* we don't overflow it */ int offset = target - *base; char *newPtr = PORT_Realloc(*base, *baseLen + diff); if (!newPtr) { return target; /* not enough space, just drop the whole copy */
}
*baseLen += diff;
target = newPtr + offset;
*base = newPtr;
value = NSSUTIL_Escape(value, '\"'); if (value == NULL) { return target; /* couldn't escape value, just drop the copy */
}
}
PORT_Memcpy(target, desc, descLen);
target += descLen;
*target++ = '\"';
PORT_Memcpy(target, value, esc_len);
target += esc_len;
*target++ = '\"'; if (diff > 0) {
PORT_Free(value);
} return target;
}
#define SECMOD_SPEC_COPY(new, start, end) \ if (end > start) { \ int _cnt = end - start; \
PORT_Memcpy(new, start, _cnt); \ new += _cnt; \
} #define SECMOD_TOKEN_DESCRIPTION "tokenDescription=" #define SECMOD_SLOT_DESCRIPTION "slotDescription="
/* * Find any tokens= values in the module spec. * Always return a new spec which does not have any tokens= arguments. * If tokens= arguments are found, Split the the various tokens defined into * an array of child specs to return. * * Caller is responsible for freeing the child spec and the new token * spec.
*/ char *
secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS, constchar *moduleSpec, char ***children,
CK_SLOT_ID **ids)
{ int newSpecLen = PORT_Strlen(moduleSpec) + 2; char *newSpec = PORT_Alloc(newSpecLen); char *newSpecPtr = newSpec; constchar *modulePrev = moduleSpec; char *target = NULL; char *tmp = NULL; char **childArray = NULL; constchar *tokenIndex;
CK_SLOT_ID *idArray = NULL; int tokenCount = 0; int i;
/* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening * a new softoken module takes the following parameters to name the * various tokens: * * cryptoTokenDescription: name of the non-fips crypto token. * cryptoSlotDescription: name of the non-fips crypto slot. * dbTokenDescription: name of the non-fips db token. * dbSlotDescription: name of the non-fips db slot. * FIPSTokenDescription: name of the fips db/crypto token. * FIPSSlotDescription: name of the fips db/crypto slot. * * if we are opening a new slot, we need to have the following * parameters: * tokenDescription: name of the token. * slotDescription: name of the slot. * * * The convert flag tells us to drop the unnecessary *TokenDescription * and *SlotDescription arguments and convert the appropriate pair * (either db or FIPS based on the isFIPS flag) to tokenDescription and * slotDescription).
*/ /* * walk down the list. if we find a tokens= argument, save it, * otherise copy the argument.
*/ while (*moduleSpec) { int next;
modulePrev = moduleSpec;
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",
modulePrev = moduleSpec; /* skip copying */)
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "cryptoTokenDescription=", if (convert) { modulePrev = moduleSpec; })
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "cryptoSlotDescription=", if (convert) { modulePrev = moduleSpec; })
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "dbTokenDescription=", if (convert) {
modulePrev = moduleSpec; if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_TOKEN_DESCRIPTION, sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "dbSlotDescription=", if (convert) {
modulePrev = moduleSpec; /* skip copying */ if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_SLOT_DESCRIPTION, sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "FIPSTokenDescription=", if (convert) {
modulePrev = moduleSpec; /* skip copying */ if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_TOKEN_DESCRIPTION, sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "FIPSSlotDescription=", if (convert) {
modulePrev = moduleSpec; /* skip copying */ if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_SLOT_DESCRIPTION, sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_FINAL_ARG(moduleSpec)
SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
} if (tmp) {
PORT_Free(tmp);
tmp = NULL;
}
*newSpecPtr = 0;
/* 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;
/* * determine if we are trying to open an old dbm database. For this test * RDB databases should return PR_FALSE.
*/ static PRBool
secmod_configIsDBM(char *configDir)
{ char *env;
/* explicit dbm open */ if (strncmp(configDir, "dbm:", 4) == 0) { return PR_TRUE;
} /* explicit open of a non-dbm database */ if ((strncmp(configDir, "sql:", 4) == 0) ||
(strncmp(configDir, "rdb:", 4) == 0) ||
(strncmp(configDir, "extern:", 7) == 0)) { return PR_FALSE;
}
env = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE"); /* implicit dbm open */ if ((env == NULL) || (strcmp(env, "dbm") == 0)) { return PR_TRUE;
} /* implicit non-dbm open */ return PR_FALSE;
}
/* * match two prefixes. prefix may be NULL. NULL patches '\0'
*/ static PRBool
secmod_matchPrefix(char *prefix1, char *prefix2)
{ if ((prefix1 == NULL) || (*prefix1 == 0)) { if ((prefix2 == NULL) || (*prefix2 == 0)) { return PR_TRUE;
} return PR_FALSE;
} if (strcmp(prefix1, prefix2) == 0) { return PR_TRUE;
} return PR_FALSE;
}
/* do two config paramters match? Not all callers are compariing * SECMODConfigLists directly, so this function breaks them out to their
* 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: * "Why not allow them to match if they are both NULL?" * 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, * than any open will suffice, but if we requested it read/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;
}
/* * return true if we are requesting a database that is already openned.
*/
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 * twice from two different locations, then we can corrupt our database * (the cache will be inconsistent). Protect against this by claiming * for comparison only that we are always openning dbm databases read only.
*/ 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;
}
/* * Find the slot id from the module spec. If the slot is the database slot, we * can get the slot id from the default database slot.
*/
CK_SLOT_ID
secmod_GetSlotIDFromModuleSpec(constchar *moduleSpec, SECMODModule *module)
{ char *tmp_spec = NULL; char **children, **thisChild;
CK_SLOT_ID *ids, *thisID, slotID = -1; char *inConfig = NULL, *thisConfig = NULL; char *inCertPrefix = NULL, *thisCertPrefix = NULL; char *inKeyPrefix = NULL, *thisKeyPrefix = NULL;
PRBool inReadOnly, thisReadOnly;
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.32 Sekunden
(vorverarbeitet)
¤
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.