summaryrefslogtreecommitdiff
path: root/security/nss/lib/softoken/pkcs11.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/softoken/pkcs11.c')
-rw-r--r--security/nss/lib/softoken/pkcs11.c143
1 files changed, 96 insertions, 47 deletions
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 10a7bcfb7..f913735a4 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -67,9 +67,8 @@
#include "keydbi.h"
-#ifdef NSS_ENABLE_ECC
-extern SECStatus EC_FillParams(PRArenaPool *arena,
- const SECItem *encodedParams, ECParams *params);
+#ifdef DEBUG
+#include "cdbhdl.h"
#endif
/*
@@ -77,7 +76,7 @@ extern SECStatus EC_FillParams(PRArenaPool *arena,
*/
/* The next three strings must be exactly 32 characters long */
-static char *manufacturerID = "mozilla.org ";
+static char *manufacturerID = "Mozilla Foundation ";
static char manufacturerID_space[33];
static char *libraryDescription = "NSS Internal Crypto Services ";
static char libraryDescription_space[33];
@@ -1228,6 +1227,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
+ CK_BBOOL sign = CK_FALSE;
CK_BBOOL recover = CK_TRUE;
CK_BBOOL wrap = CK_TRUE;
CK_BBOOL derive = CK_FALSE;
@@ -1268,15 +1268,18 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
sftk_item_expand(&mod));
if (mod.data) PORT_Free(mod.data);
if (crv != CKR_OK) return crv;
-
+
+ sign = CK_TRUE;
break;
case CKK_DSA:
if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) {
return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
+ if (sftk_isTrue(object,CKA_TOKEN) &&
+ !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ sign = CK_TRUE;
/* fall through */
case CKK_DH:
if ( !sftk_hasAttribute(object, CKA_PRIME)) {
@@ -1300,10 +1303,12 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
if ( !sftk_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
+ if (sftk_isTrue(object,CKA_TOKEN) &&
+ !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
return CKR_TEMPLATE_INCOMPLETE;
}
encrypt = CK_FALSE;
+ sign = CK_TRUE;
recover = CK_FALSE;
wrap = CK_FALSE;
derive = CK_TRUE;
@@ -1320,7 +1325,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
if (crv != CKR_OK) return crv;
crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
+ crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover,
sizeof(CK_BBOOL));
@@ -1532,6 +1537,9 @@ sftk_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
(++retries <= SFTK_KEY_MAX_RETRIES));
if ((rv != SECSuccess) || (retries > SFTK_KEY_MAX_RETRIES)) {
+ if (rv != SECSuccess) {
+ sftk_fatalError = PR_TRUE;
+ }
crv = CKR_DEVICE_ERROR; /* random number generator is bad */
PORT_Free(id->data);
id->data = NULL;
@@ -1644,6 +1652,9 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
/* get the key type */
attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
+ if (!attribute) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
@@ -1750,6 +1761,9 @@ sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
/* get the key type */
attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
+ if (!attribute) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
@@ -1952,7 +1966,10 @@ NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,CK_KEY_TYPE key_type,
* based on the encoded params
*/
if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding,
- &pubKey->u.ec.ecParams) != SECSuccess) break;
+ &pubKey->u.ec.ecParams) != SECSuccess) {
+ crv = CKR_DOMAIN_PARAMS_INVALID;
+ break;
+ }
crv = sftk_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue,
object,CKA_EC_POINT);
@@ -2045,9 +2062,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.publicValue,
- object,CKA_NETSCAPE_DB);
- /* can't set the public value.... */
+ if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) {
+ crv = sftk_Attribute2SSecItem(arena, &privKey->u.dsa.publicValue,
+ object,CKA_NETSCAPE_DB);
+ /* privKey was zero'd so public value is already set to NULL, 0
+ * if we don't set it explicitly */
+ }
break;
case CKK_DH:
@@ -2061,8 +2081,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.publicValue,
- object,CKA_NETSCAPE_DB);
+ if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) {
+ crv = sftk_Attribute2SSecItem(arena, &privKey->u.dh.publicValue,
+ object,CKA_NETSCAPE_DB);
+ /* privKey was zero'd so public value is already set to NULL, 0
+ * if we don't set it explicitly */
+ }
break;
#ifdef NSS_ENABLE_ECC
@@ -2077,13 +2101,20 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
* based on the encoded params
*/
if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
- &privKey->u.ec.ecParams) != SECSuccess) break;
+ &privKey->u.ec.ecParams) != SECSuccess) {
+ crv = CKR_DOMAIN_PARAMS_INVALID;
+ break;
+ }
crv = sftk_Attribute2SSecItem(arena,&privKey->u.ec.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
+ if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) {
+ crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) break;
+ if (crv != CKR_OK) break;
+ /* privKey was zero'd so public value is already set to NULL, 0
+ * if we don't set it explicitly */
+ }
rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
@@ -2333,7 +2364,7 @@ sftk_getDefTokName(CK_SLOT_ID slotID)
case PRIVATE_KEY_SLOT_ID:
return "NSS Certificate DB ";
case FIPS_SLOT_ID:
- return "NSS FIPS-140-1 Certificate DB ";
+ return "NSS FIPS 140-2 Certificate DB ";
default:
break;
}
@@ -2355,7 +2386,7 @@ sftk_getDefSlotName(CK_SLOT_ID slotID)
"NSS User Private Key and Certificate Services ";
case FIPS_SLOT_ID:
return
- "Netscape FIPS-140-1 User Private Key Services ";
+ "NSS FIPS 140-2 User Private Key Services ";
default:
break;
}
@@ -2388,6 +2419,8 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
{
SFTKSlot *slot;
int index = sftk_GetModuleIndex(slotID);
+
+ if (nscSlotHashTable[index] == NULL) return NULL;
slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
(void *)slotID);
/* cleared slots shouldn't 'show up' */
@@ -2756,9 +2789,11 @@ sftk_DBShutdown(SFTKSlot *slot)
slot->keyDB = NULL;
PZ_Unlock(slot->slotLock);
if (certHandle) {
+ PORT_Assert(certHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID);
sftk_freeCertDB(certHandle);
}
if (keyHandle) {
+ PORT_Assert(keyHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID);
sftk_freeKeyDB(keyHandle);
}
}
@@ -2953,13 +2988,6 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
if (isFIPS) {
- /* make sure that our check file signatures are OK */
- if (!BLAPI_VerifySelf(NULL) ||
- !BLAPI_SHVerify(SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_closePeer)) {
- crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
- return crv;
- }
-
loginWaitTime = PR_SecondsToInterval(1);
}
@@ -2976,6 +3004,12 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
}
RNG_SystemInfoForRNG();
+ rv = nsslowcert_InitLocks();
+ if (rv != SECSuccess) {
+ crv = CKR_DEVICE_ERROR;
+ return crv;
+ }
+
/* NOTE:
* we should be getting out mutexes from this list, not statically binding
@@ -3022,6 +3056,13 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
* don't clobber each other. */
if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
sftk_closePeer(isFIPS);
+ if (sftk_audit_enabled) {
+ if (isFIPS && nsc_init) {
+ sftk_LogAuditMessage(NSS_AUDIT_INFO, "enabled FIPS mode");
+ } else {
+ sftk_LogAuditMessage(NSS_AUDIT_INFO, "disabled FIPS mode");
+ }
+ }
}
for (i=0; i < paramStrings.token_count; i++) {
@@ -3076,21 +3117,13 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
nsslowcert_DestroyFreeLists();
nsslowcert_DestroyGlobalLocks();
-#ifdef LEAK_TEST
- /*
- * do we really want to throw away all our hard earned entropy here!!?
- * No we don't! Not calling RNG_RNGShutdown only 'leaks' data on the
- * initial call to RNG_Init(). So the only reason to call this is to clean
- * up leak detection warnings on shutdown. In many cases we *don't* want
- * to free up the global RNG context because the application has Finalized
- * simply to swap profiles. We don't want to loose the entropy we've
- * already collected.
- */
+ /* This function does not discard all our previously aquired entropy. */
RNG_RNGShutdown();
-#endif
/* tell freeBL to clean up after itself */
BL_Cleanup();
+ /* unload freeBL shared library from memory */
+ BL_Unload();
/* clean up the default OID table */
SECOID_Shutdown();
nsc_init = PR_FALSE;
@@ -3178,7 +3211,6 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
return CKR_OK;
}
-#define CKF_THREAD_SAFE 0x8000 /* for now */
/*
* check the current state of the 'needLogin' flag in case the database has
* been changed underneath us.
@@ -3206,14 +3238,17 @@ sftk_checkNeedLogin(SFTKSlot *slot, NSSLOWKEYDBHandle *keyHandle)
* the system. */
CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
{
- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
+ SFTKSlot *slot;
NSSLOWKEYDBHandle *handle;
+ if (!nsc_init && !nsf_init) return CKR_CRYPTOKI_NOT_INITIALIZED;
+ slot = sftk_SlotFromID(slotID, PR_FALSE);
if (slot == NULL) return CKR_SLOT_ID_INVALID;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
PORT_Memcpy(pInfo->model,"NSS 3 ",16);
PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16);
+ PORT_Memcpy(pInfo->utcTime,"0000000000000000",16);
pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
pInfo->ulSessionCount = slot->sessionCount;
pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */
@@ -3222,8 +3257,9 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->firmwareVersion.minor = 0;
PORT_Memcpy(pInfo->label,slot->tokDescription,32);
handle = sftk_getKeyDB(slot);
+ pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS;
if (handle == NULL) {
- pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE;
+ pInfo->flags |= CKF_WRITE_PROTECTED;
pInfo->ulMaxPinLen = 0;
pInfo->ulMinPinLen = 0;
pInfo->ulTotalPublicMemory = 0;
@@ -3243,12 +3279,11 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
* we will need to prompt for it.
*/
if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) {
- pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED;
+ pInfo->flags |= CKF_LOGIN_REQUIRED;
} else if (!sftk_checkNeedLogin(slot,handle)) {
- pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED;
+ pInfo->flags |= CKF_USER_PIN_INITIALIZED;
} else {
- pInfo->flags = CKF_THREAD_SAFE |
- CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
+ pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
}
pInfo->ulMaxPinLen = SFTK_MAX_PIN;
pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
@@ -3260,6 +3295,18 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->hardwareVersion.minor = handle->version;
sftk_freeKeyDB(handle);
}
+ /*
+ * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED
+ * should be set
+ * 0 0 1
+ * 1 0 0
+ * 0 1 1
+ * 1 1 1
+ */
+ if (!(pInfo->flags & CKF_LOGIN_REQUIRED) ||
+ (pInfo->flags & CKF_USER_PIN_INITIALIZED)) {
+ pInfo->flags |= CKF_TOKEN_INITIALIZED;
+ }
return CKR_OK;
}
@@ -3551,7 +3598,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
sftk_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */
}
if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
@@ -3927,7 +3974,7 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
if (attribute == NULL) {
return CKR_TEMPLATE_INCOMPLETE;
}
- paramString = (unsigned char *)attribute->attrib.pValue;
+ paramString = (char *)attribute->attrib.pValue;
crv = secmod_parseParameters(paramString, &paramStrings, isFIPS);
if (crv != CKR_OK) {
goto loser;
@@ -3990,7 +4037,9 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
SFTKSession *session;
SFTKObject *object;
- CK_OBJECT_CLASS class;
+ /* make sure class isn't randomly CKO_NETSCAPE_NEWSLOT or
+ * CKO_NETSCPE_DELSLOT. */
+ CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED;
CK_RV crv;
int i;