diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/nss/lib/softoken/config.mk | 5 | ||||
-rw-r--r-- | security/nss/lib/softoken/dbinit.c | 24 | ||||
-rw-r--r-- | security/nss/lib/softoken/keydb.c | 26 | ||||
-rw-r--r-- | security/nss/lib/softoken/lowcert.c | 55 | ||||
-rw-r--r-- | security/nss/lib/softoken/pcertdb.c | 35 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11.c | 157 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11c.c | 11 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11i.h | 13 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11u.c | 39 | ||||
-rw-r--r-- | security/nss/lib/softoken/softokn.rc | 4 |
10 files changed, 226 insertions, 143 deletions
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk index de85f1d0a..f59687af5 100644 --- a/security/nss/lib/softoken/config.mk +++ b/security/nss/lib/softoken/config.mk @@ -41,6 +41,11 @@ #IMPORT_LIBRARY = #PROGRAM = + +ifdef MOZILLA_CLIENT +DEFINES += -DMOZ_CLIENT +endif + # can't do this in manifest.mn because OS_ARCH isn't defined there. ifeq ($(OS_ARCH), WINNT) diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c index daf0ca176..87dc9676c 100644 --- a/security/nss/lib/softoken/dbinit.c +++ b/security/nss/lib/softoken/dbinit.c @@ -209,24 +209,18 @@ loser: } -#ifdef notdef void -pk11_Shutdown(void) +pk11_DBShutdown(NSSLOWCERTCertDBHandle *certHandle, + NSSLOWKEYDBHandle *keyHandle) { - NSSLOWCERTCertDBHandle *certHandle; - NSSLOWKEYDBHandle *keyHandle; - - PR_FREEIF(secmodname); - certHandle = nsslowcert_GetDefaultCertDB(); - if (certHandle) + if (certHandle) { nsslowcert_ClosePermCertDB(certHandle); - nsslowcert_SetDefaultCertDB(NULL); + PORT_Free(certHandle); + certHandle= NULL; + } - keyHandle = nsslowkey_GetDefaultKeyDB(); - if (keyHandle) + if (keyHandle) { nsslowkey_CloseKeyDB(keyHandle); - nsslowkey_SetDefaultKeyDB(NULL); - - isInitialized = PR_FALSE; + keyHandle= NULL; + } } -#endif diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c index ceeb36ba6..059115741 100644 --- a/security/nss/lib/softoken/keydb.c +++ b/security/nss/lib/softoken/keydb.c @@ -1093,13 +1093,14 @@ void nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle) { if (handle != NULL) { - if (handle == nsslowkey_GetDefaultKeyDB()) { - nsslowkey_SetDefaultKeyDB(NULL); - } if (handle->db != NULL) { (* handle->db->close)(handle->db); } if (handle->dbname) PORT_Free(handle->dbname); + if (handle->global_salt) { + SECITEM_FreeItem(handle->global_salt,PR_TRUE); + } + PORT_Free(handle); } } @@ -1114,25 +1115,6 @@ nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle) } /* - * Allow use of default key database, so that apps (such as mozilla) do - * not have to pass the handle all over the place. - */ - -static NSSLOWKEYDBHandle *sec_default_key_db = NULL; - -void -nsslowkey_SetDefaultKeyDB(NSSLOWKEYDBHandle *handle) -{ - sec_default_key_db = handle; -} - -NSSLOWKEYDBHandle * -nsslowkey_GetDefaultKeyDB(void) -{ - return sec_default_key_db; -} - -/* * Delete a private key that was stored in the database */ SECStatus diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c index 0cea4e396..917eb4e5d 100644 --- a/security/nss/lib/softoken/lowcert.c +++ b/security/nss/lib/softoken/lowcert.c @@ -118,44 +118,6 @@ const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = { }; -static PZLock *pcertRefCountLock = NULL; - -/* - * Acquire the cert reference count lock - * There is currently one global lock for all certs, but I'm putting a cert - * arg here so that it will be easy to make it per-cert in the future if - * that turns out to be necessary. - */ -void -nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert) -{ - if ( pcertRefCountLock == NULL ) { - nss_InitLock(&pcertRefCountLock, nssILockRefLock); - PORT_Assert(pcertRefCountLock != NULL); - } - - PZ_Lock(pcertRefCountLock); - return; -} - -/* - * Free the cert reference count lock - */ -void -nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(pcertRefCountLock != NULL); - - prstat = PZ_Unlock(pcertRefCountLock); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - - NSSLOWCERTCertificate * nsslowcert_DupCertificate(NSSLOWCERTCertificate *c) { @@ -319,23 +281,6 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, cert->dbEntry = NULL; cert ->trust = NULL; -#ifdef notdef - /* these fields are used by client GUI code to keep track of ssl sockets - * that are blocked waiting on GUI feedback related to this cert. - * XXX - these should be moved into some sort of application specific - * data structure. They are only used by the browser right now. - */ - struct SECSocketNode *socketlist; - int socketcount; - struct SECSocketNode *authsocketlist; - int authsocketcount; - - /* This is PKCS #11 stuff. */ - PK11SlotInfo *slot; /*if this cert came of a token, which is it*/ - CK_OBJECT_HANDLE pkcs11ID; /*and which object on that token is it */ - PRBool ownSlot; /*true if the cert owns the slot reference */ -#endif - /* generate and save the database key for the cert */ rv = nsslowcert_KeyFromDERCert(arena, &cert->derCert, &cert->certKey); if ( rv ) { diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c index 61d6f193e..8d62ffd5e 100644 --- a/security/nss/lib/softoken/pcertdb.c +++ b/security/nss/lib/softoken/pcertdb.c @@ -117,7 +117,7 @@ static PZLock *certRefCountLock = NULL; * arg here so that it will be easy to make it per-cert in the future if * that turns out to be necessary. */ -static void +void nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert) { if ( certRefCountLock == NULL ) { @@ -132,7 +132,7 @@ nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert) /* * Free the cert reference count lock */ -static void +void nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert) { PRStatus prstat; @@ -3898,23 +3898,21 @@ nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle, * Close the database */ void -__nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle) +nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle) { if ( handle ) { if ( handle->permCertDB ) { certdb_Close( handle->permCertDB ); - handle->permCertDB = 0; + handle->permCertDB = NULL; + } + if (handle->dbMon) { + PZ_DestroyMonitor(handle->dbMon); + handle->dbMon = NULL; } } return; } -void -nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle) -{ - __nsslowcert_ClosePermCertDB(handle); -} - /* * Get the trust attributes from a certificate */ @@ -4455,3 +4453,20 @@ loser: } return(rv); } + +void +nsslowcert_DestroyGlobalLocks() +{ + if (dbLock) { + PZ_DestroyLock(dbLock); + dbLock = NULL; + } + if (certRefCountLock) { + PZ_DestroyLock(certRefCountLock); + certRefCountLock = NULL; + } + if (certTrustLock) { + PZ_DestroyLock(certTrustLock); + certTrustLock = NULL; + } +} diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index d0a9acd9d..7e2622b0f 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -70,26 +70,6 @@ static char *manufacturerID = "mozilla.org "; static char manufacturerID_space[33]; static char *libraryDescription = "NSS Internal Crypto Services "; static char libraryDescription_space[33]; -#ifdef notdef -static char *tokDescription = "NSS Generic Crypto Services "; -static char tokDescription_space[33]; -static char *privTokDescription = "NSS Certificate DB "; -static char privTokDescription_space[33]; -/* The next two strings must be exactly 64 characters long, with the - first 32 characters meaningful */ -static char *slotDescription = - "NSS Internal Cryptographic Services Version 3.2 "; -static char slotDescription_space[65]; -static char *privSlotDescription = - "NSS User Private Key and Certificate Services "; -static char privSlotDescription_space[65]; -/* The next two strings must be exactly 64 characters long, with the - first 32 characters meaningful */ -static char *slotDescription = - "Netscape Internal FIPS-140-1 Cryptographic Services "; -static char *privSlotDescription = - "Netscape FIPS-140-1 User Private Key Services "; -#endif #define __PASTE(x,y) x##y @@ -178,7 +158,7 @@ static const desKey pk11_desWeakTable[] = { { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e }, { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 }, - { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe }, + { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe }, { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 } #endif }; @@ -417,7 +397,7 @@ static const struct mechanismList mechanisms[] = { static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); static char * -pk11_setStringName(char *inString, char *buffer, int buffer_length) { +pk11_setStringName(const char *inString, char *buffer, int buffer_length) { int full_length, string_length; full_length = buffer_length -1; @@ -425,14 +405,14 @@ pk11_setStringName(char *inString, char *buffer, int buffer_length) { if (string_length > full_length) string_length = full_length; PORT_Memset(buffer,' ',full_length); buffer[full_length] = 0; - PORT_Memcpy(buffer,inString,full_length); + PORT_Memcpy(buffer,inString,string_length); return buffer; } /* * Configuration utils */ static CK_RV -pk11_configure(char *man, char *libdes) +pk11_configure(const char *man, const char *libdes) { /* make sure the internationalization was done correctly... */ @@ -1138,6 +1118,8 @@ pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE &ckfalse,sizeof(CK_BBOOL)); if (crv != CKR_OK) return crv; + /* should we check the non-token RSA private keys? */ + if (pk11_isTrue(object,CKA_TOKEN)) { PK11Slot *slot = session->slot; NSSLOWKEYPrivateKey *privKey; @@ -1165,9 +1147,17 @@ pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE PORT_Memcpy(pubKey.data,buf,sizeof(buf)); pubKey.len = sizeof(buf); } + + if (key_type == CKK_RSA) { + rv = RSA_PrivateKeyCheck(&privKey->u.rsa); + if (rv == SECFailure) { + goto fail; + } + } rv = nsslowkey_StoreKeyByPublicKey(object->slot->keyDB, privKey, &pubKey, label, object->slot->password); +fail: if (label) PORT_Free(label); object->handle = pk11_mkHandle(slot,&pubKey,PK11_TOKEN_TYPE_PRIV); if (pubKey.data) PORT_Free(pubKey.data); @@ -1863,7 +1853,7 @@ pk11_HashNumber(const void *key) * just go with the info in the slot. This is one place, however, * where it might be a little difficult. */ -char * +const char * pk11_getDefTokName(CK_SLOT_ID slotID) { static char buf[33]; @@ -1882,7 +1872,7 @@ pk11_getDefTokName(CK_SLOT_ID slotID) return buf; } -char * +const char * pk11_getDefSlotName(CK_SLOT_ID slotID) { static char buf[65]; @@ -1916,8 +1906,7 @@ static PLHashTable *nscSlotHashTable = NULL; PK11Slot * pk11_SlotFromID(CK_SLOT_ID slotID) { - return (PK11Slot *)PL_HashTableLookupConst(nscSlotHashTable, - (void *)slotID); + return (PK11Slot *)PL_HashTableLookup(nscSlotHashTable, (void *)slotID); } PK11Slot * @@ -2061,6 +2050,54 @@ PK11_SlotInit(char *configdir,pk11_token_parameters *params) return CKR_OK; } +static PRIntn +pk11_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg) +{ + SECItem *item = (SECItem *)entry->value; + + SECITEM_FreeItem(item, PR_TRUE); + return HT_ENUMERATE_NEXT; +} + +/* + * initialize one of the slot structures. figure out which by the ID + */ +CK_RV +PK11_DestroySlot(PK11Slot *slot) +{ + int i; + +#ifdef PKCS11_USE_THREADS + if (slot->sessionLock) { + PZ_DestroyLock(slot->sessionLock); + slot->sessionLock = NULL; + } + if (slot->objectLock) { + PZ_DestroyLock(slot->objectLock); + slot->objectLock = NULL; + } +#endif + + PL_HashTableEnumerateEntries(slot->tokenHashTable,pk11_freeHashItem,NULL); + PL_HashTableDestroy(slot->tokenHashTable); + + for(i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) { + PK11Object *object = slot->tokObjects[i]; + slot->tokObjects[i] = NULL; + pk11_FreeObject(object); + } + + for(i=0; i < SESSION_HASH_SIZE; i++) { + PK11Session *session = slot->head[i]; + slot->head[i] = NULL; + pk11_FreeSession(session); + } + pk11_DBShutdown(slot->certDB,slot->keyDB); + + PORT_Free(slot); + return CKR_OK; +} + /* * handle the SECMOD.db */ @@ -2087,16 +2124,16 @@ NSC_ModuleDBFunc(unsigned long function,char *parameters, char *args) } +static PRBool nsc_init = PR_FALSE; /* NSC_Initialize initializes the Cryptoki library. */ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) { - static PRBool init = PR_FALSE; CK_RV crv = CKR_OK; SECStatus rv; CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved; int i; - if (init) { + if (nsc_init) { return crv; } @@ -2122,7 +2159,7 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) pk11_parameters paramStrings; crv = secmod_parseParameters - ((char *)init_args->LibraryParameters,¶mStrings, isFIPS); + ((char *)init_args->LibraryParameters, ¶mStrings, isFIPS); if (crv != CKR_OK) { return crv; } @@ -2133,13 +2170,13 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) for (i=0; i < paramStrings.token_count; i++) { crv = - PK11_SlotInit(paramStrings.configdir,¶mStrings.tokens[i]); + PK11_SlotInit(paramStrings.configdir, ¶mStrings.tokens[i]); if (crv != CKR_OK) break; } loser: secmod_freeParams(¶mStrings); } - init = (PRBool) (crv == CKR_OK); + nsc_init = (PRBool) (crv == CKR_OK); return crv; } @@ -2153,6 +2190,60 @@ CK_RV NSC_Initialize(CK_VOID_PTR pReserved) * Cryptoki library.*/ CK_RV NSC_Finalize (CK_VOID_PTR pReserved) { + PK11Slot *slot = NULL; + CK_SLOT_ID slotID; + int i; + + if (!nsc_init) { + return CKR_OK; + } + + /* free all the slots */ + if (nscSlotList) { + CK_ULONG tmpSlotCount = nscSlotCount; + CK_ULONG tmpSlotListSize = nscSlotListSize; + CK_SLOT_ID_PTR tmpSlotList = nscSlotList; + PLHashTable *tmpSlotHashTable = nscSlotHashTable; + + /* now clear out the statics */ + nscSlotList = NULL; + nscSlotCount = 0; + nscSlotHashTable = NULL; + nscSlotListSize = 0; + + for (i=0; i < tmpSlotCount; i++) { + slotID = tmpSlotList[i]; + slot = (PK11Slot *) + PL_HashTableLookup(tmpSlotHashTable, (void *)slotID); + PORT_Assert(slot); + if (!slot) continue; + PK11_DestroySlot(slot); + PL_HashTableRemove(tmpSlotHashTable, (void *)slotID); + } + PORT_Free(tmpSlotList); + PL_HashTableDestroy(tmpSlotHashTable); + } + + 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. + */ + RNG_RNGShutdown(); +#endif + + pk11_CleanupFreeLists(); + /* tell freeBL to clean up after itself */ + BL_Cleanup(); + nsc_init = PR_FALSE; + return CKR_OK; } diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index b4e769d06..997002c71 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -923,8 +923,11 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, if (rv == SECSuccess) { unsigned int padSize = (unsigned int) pLastPart[context->blockSize-1]; - - *pulLastPartLen = outlen - padSize; + if ((padSize > context->blockSize) || (padSize == 0)) { + rv = SECFailure; + } else { + *pulLastPartLen = outlen - padSize; + } } } } @@ -3881,7 +3884,7 @@ pk11_DeriveSensitiveCheck(PK11Object *baseKey,PK11Object *destKey) { hasSensitive = PR_FALSE; att = pk11_FindAttribute(destKey,CKA_SENSITIVE); if (att) { - hasSensitive = PR_FALSE; + hasSensitive = PR_TRUE; sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue; pk11_FreeAttribute(att); } @@ -3889,7 +3892,7 @@ pk11_DeriveSensitiveCheck(PK11Object *baseKey,PK11Object *destKey) { hasExtractable = PR_FALSE; att = pk11_FindAttribute(destKey,CKA_EXTRACTABLE); if (att) { - hasExtractable = PR_FALSE; + hasExtractable = PR_TRUE; extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue; pk11_FreeAttribute(att); } diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index c09b2635e..5056cc035 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -92,12 +92,25 @@ /* these are data base storage hashes, not cryptographic hashes.. The define * the effective size of the various object hash tables */ +#ifdef MOZ_CLIENT +/* clients care more about memory usage than lookup performance on + * cyrptographic objects. Clients also have less objects around to play with */ + * + * we eventually should make this configurable at runtime! Especially now that + * NSS is a shared library. + */ +#define ATTRIBUTE_HASH_SIZE 32 +#define SESSION_OBJECT_HASH_SIZE 16 +#define TOKEN_OBJECT_HASH_SIZE 32 +#define SESSION_HASH_SIZE 32 +#else #define ATTRIBUTE_HASH_SIZE 32 #define SESSION_OBJECT_HASH_SIZE 32 #define TOKEN_OBJECT_HASH_SIZE 1024 #define SESSION_HASH_SIZE 512 #define MAX_OBJECT_LIST_SIZE 800 /* how many objects to keep on the free list * before we start freeing them */ +#endif #define MAX_KEY_LEN 256 diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index c9a65d648..1ad205a2c 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -1662,8 +1662,7 @@ pk11_deleteTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle) SECItem *item; PRBool rem; - item = (SECItem *)PL_HashTableLookupConst(slot->tokenHashTable, - (void *)handle); + item = (SECItem *)PL_HashTableLookup(slot->tokenHashTable, (void *)handle); if (item) { SECITEM_FreeItem(item,PR_TRUE); } @@ -1692,8 +1691,7 @@ pk11_addTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle, SECItem *key) static SECItem * pk11_lookupTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle) { - return (SECItem *)PL_HashTableLookupConst(slot->tokenHashTable, - (void *)handle); + return (SECItem *)PL_HashTableLookup(slot->tokenHashTable, (void *)handle); } /* @@ -1764,6 +1762,39 @@ pk11_PutObjectToList(PK11SessionObject *object) { PORT_Free(object); } +static PK11Object * +pk11_freeObjectData(PK11Object *object) { + PK11Object *next = object->next; + + PORT_Free(object); + return next; +} + +void +pk11_CleanupFreeLists() +{ +#ifdef MAX_OBJECT_LIST_SIZE + PK11Object *object; + + if (!objectLock) { + return; + } + PK11_USE_THREADS(PZ_Lock(objectLock)); + for (object= objectFreeList; object != NULL; + object = pk11_freeObjectData(object)) { +#ifdef PKCS11_USE_THREADS + PZ_DestroyLock(object->refLock); + PZ_DestroyLock(((PK11SessionObject *)object)->attributeLock); +#endif + } + object_count = 0; + objectFreeList = NULL; + PK11_USE_THREADS(PZ_Unlock(objectLock)); + PZ_DestroyLock(objectLock); + objectLock = NULL; +#endif +} + /* * Create a new object diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc index 31bdb2272..5f54d2b0a 100644 --- a/security/nss/lib/softoken/softokn.rc +++ b/security/nss/lib/softoken/softokn.rc @@ -35,7 +35,11 @@ #include <winver.h> #define MY_LIBNAME "softoken" +#ifdef MOZ_CLIENT +#define MY_FILEDESCRIPTION "NSS Builtin Crypto PKCS #11 Library for Clients" +#else #define MY_FILEDESCRIPTION "NSS Builtin Crypto PKCS #11 Library" +#endif #define STRINGIZE(x) #x #define STRINGIZE2(x) STRINGIZE(x) |