summaryrefslogtreecommitdiff
path: root/security/nss/lib/pk11wrap
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/pk11wrap')
-rw-r--r--security/nss/lib/pk11wrap/pk11load.c3
-rw-r--r--security/nss/lib/pk11wrap/pk11merge.c6
-rw-r--r--security/nss/lib/pk11wrap/pk11obj.c39
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c3
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c19
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c23
-rw-r--r--security/nss/lib/pk11wrap/pk11pub.h4
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c4
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c5
-rw-r--r--security/nss/lib/pk11wrap/pk11util.c9
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h1
11 files changed, 88 insertions, 28 deletions
diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c
index 91339fad8f..d1f6ec442d 100644
--- a/security/nss/lib/pk11wrap/pk11load.c
+++ b/security/nss/lib/pk11wrap/pk11load.c
@@ -64,8 +64,7 @@ secmodUnlockMutext(CK_VOID_PTR mutext)
static SECMODModuleID nextModuleID = 1;
static const CK_C_INITIALIZE_ARGS secmodLockFunctions = {
secmodCreateMutext, secmodDestroyMutext, secmodLockMutext,
- secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS |
- CKF_OS_LOCKING_OK,
+ secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS | CKF_OS_LOCKING_OK,
NULL
};
static const CK_C_INITIALIZE_ARGS secmodNoLockArgs = {
diff --git a/security/nss/lib/pk11wrap/pk11merge.c b/security/nss/lib/pk11wrap/pk11merge.c
index 8c4c5129aa..b2101b8191 100644
--- a/security/nss/lib/pk11wrap/pk11merge.c
+++ b/security/nss/lib/pk11wrap/pk11merge.c
@@ -68,8 +68,11 @@ pk11_copyAttributes(PLArenaPool *arena,
copyTemplate, copyTemplateCount);
/* if we have missing attributes, just skip them and create the object */
if (crv == CKR_ATTRIBUTE_TYPE_INVALID) {
- int i, j;
+ CK_ULONG i, j;
newTemplate = PORT_NewArray(CK_ATTRIBUTE, copyTemplateCount);
+ if (!newTemplate) {
+ return SECFailure;
+ }
/* remove the unknown attributes. If we don't have enough attributes
* PK11_CreateNewObject() will fail */
for (i = 0, j = 0; i < copyTemplateCount; i++) {
@@ -1258,6 +1261,7 @@ pk11_newMergeLogNode(PLArenaPool *arena,
/* initialize it */
obj->slot = slot;
obj->objectID = id;
+ obj->owner = PR_FALSE;
newLog->object = obj;
newLog->error = error;
diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c
index 47c56154d4..b97caddd44 100644
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ b/security/nss/lib/pk11wrap/pk11obj.c
@@ -201,7 +201,6 @@ PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot,
/* make pedantic happy... note that it's only used arena != NULL */
void *mark = NULL;
CK_RV crv;
- PORT_Assert(slot->session != CK_INVALID_SESSION);
if (slot->session == CK_INVALID_SESSION)
return CKR_SESSION_HANDLE_INVALID;
@@ -1506,6 +1505,7 @@ PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass)
/* initialize it */
obj->slot = PK11_ReferenceSlot(slot);
obj->objectID = objectIDs[i];
+ obj->owner = PR_FALSE;
obj->next = NULL;
obj->prev = NULL;
@@ -1586,6 +1586,9 @@ PK11_DestroyGenericObject(PK11GenericObject *object)
PK11_UnlinkGenericObject(object);
if (object->slot) {
+ if (object->owner) {
+ PK11_DestroyObject(object->slot, object->objectID);
+ }
PK11_FreeSlot(object->slot);
}
PORT_Free(object);
@@ -1627,8 +1630,9 @@ PK11_DestroyGenericObjects(PK11GenericObject *objects)
* Hand Create a new object and return the Generic object for our new object.
*/
PK11GenericObject *
-PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
- int count, PRBool token)
+pk11_CreateGenericObjectHelper(PK11SlotInfo *slot,
+ const CK_ATTRIBUTE *pTemplate,
+ int count, PRBool token, PRBool owner)
{
CK_OBJECT_HANDLE objectID;
PK11GenericObject *obj;
@@ -1652,11 +1656,40 @@ PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
/* initialize it */
obj->slot = PK11_ReferenceSlot(slot);
obj->objectID = objectID;
+ obj->owner = owner;
obj->next = NULL;
obj->prev = NULL;
return obj;
}
+/* This is the classic interface. Applications would call this function to
+ * create new object that would not be destroyed later. This lead to resource
+ * leaks (and thus memory leaks in the PKCS #11 module). To solve this we have
+ * a new interface that automatically marks objects created on the fly to be
+ * destroyed later.
+ * The old interface is preserved because applications like Mozilla purposefully
+ * leak the reference to be found later with PK11_FindGenericObjects. New
+ * applications should use the new interface PK11_CreateManagedGenericObject */
+PK11GenericObject *
+PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
+ int count, PRBool token)
+{
+ return pk11_CreateGenericObjectHelper(slot, pTemplate, count, token,
+ PR_FALSE);
+}
+
+/* Use this interface. It will automatically destroy any temporary objects
+ * (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still
+ * need to be destroyed by hand with PK11_DestroyTokenObject.
+ */
+PK11GenericObject *
+PK11_CreateManagedGenericObject(PK11SlotInfo *slot,
+ const CK_ATTRIBUTE *pTemplate, int count, PRBool token)
+{
+ return pk11_CreateGenericObjectHelper(slot, pTemplate, count, token,
+ !token);
+}
+
/*
* Change an attribute on a raw object
*/
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
index ee20789cc0..fc30222b3d 100644
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -413,8 +413,7 @@ static const policyFlagDef policyFlagList[] = {
/* add other signatures in the future */
{ CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE },
/* enable everything */
- { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX |
- NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("NONE"), 0 }
};
diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c
index bea9333f62..5f68f399e5 100644
--- a/security/nss/lib/pk11wrap/pk11pbe.c
+++ b/security/nss/lib/pk11wrap/pk11pbe.c
@@ -367,7 +367,24 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId)
cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId);
if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) {
- length = sec_pkcs5v2_aes_key_length(cipherAlg);
+ /* Previously, the PKCS#12 files created with the old NSS
+ * releases encoded the maximum key size of AES (that is 32)
+ * in the keyLength field of PBKDF2-params. That resulted in
+ * always performing AES-256 even if AES-128-CBC or
+ * AES-192-CBC is specified in the encryptionScheme field of
+ * PBES2-params. This is wrong, but for compatibility reasons,
+ * check the keyLength field and use the value if it is 32.
+ */
+ if (p5_param.keyLength.data != NULL) {
+ length = DER_GetInteger(&p5_param.keyLength);
+ }
+ /* If the keyLength field is present and contains a value
+ * other than 32, that means the file is created outside of
+ * NSS, which we don't care about. Note that the following
+ * also handles the case when the field is absent. */
+ if (length != 32) {
+ length = sec_pkcs5v2_aes_key_length(cipherAlg);
+ }
} else if (p5_param.keyLength.data != NULL) {
length = DER_GetInteger(&p5_param.keyLength);
} else {
diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c
index d753b87e58..035143af80 100644
--- a/security/nss/lib/pk11wrap/pk11pk12.c
+++ b/security/nss/lib/pk11wrap/pk11pk12.c
@@ -153,7 +153,6 @@ const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) },
};
-#ifndef NSS_DISABLE_ECC
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
@@ -178,7 +177,6 @@ const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = {
SEC_ASN1_SUB(SEC_BitStringTemplate) },
{ 0 }
};
-#endif /* NSS_DISABLE_ECC */
const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
@@ -346,16 +344,13 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
switch (lpk->keyType) {
case rsaKey:
keyType = CKK_RSA;
- PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue
- : &ckfalse,
+ PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue : &ckfalse,
sizeof(CK_BBOOL));
attrs++;
- PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue
- : &ckfalse,
+ PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue : &ckfalse,
sizeof(CK_BBOOL));
attrs++;
- PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
- : &ckfalse,
+ PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse,
sizeof(CK_BBOOL));
attrs++;
PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
@@ -482,7 +477,6 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
lpk->u.dh.privateValue.len);
attrs++;
break;
-#ifndef NSS_DISABLE_ECC
case ecKey:
keyType = CKK_EC;
if (lpk->u.ec.publicValue.len == 0) {
@@ -494,8 +488,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
lpk->u.ec.publicValue.len);
attrs++;
}
- PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
- : &ckfalse,
+ PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse,
sizeof(CK_BBOOL));
attrs++;
PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
@@ -503,8 +496,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
: &ckfalse,
sizeof(CK_BBOOL));
attrs++;
- PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue
- : &ckfalse,
+ PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue : &ckfalse,
sizeof(CK_BBOOL));
attrs++;
ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue);
@@ -525,7 +517,6 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
lpk->u.ec.publicValue.len);
attrs++;
break;
-#endif /* NSS_DISABLE_ECC */
default:
PORT_SetError(SEC_ERROR_BAD_KEY);
goto loser;
@@ -606,7 +597,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
paramDest = NULL;
lpk->keyType = dhKey;
break;
-#ifndef NSS_DISABLE_ECC
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
prepare_ec_priv_key_export_for_asn1(lpk);
keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
@@ -614,7 +604,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
paramDest = NULL;
lpk->keyType = ecKey;
break;
-#endif /* NSS_DISABLE_ECC */
default:
keyTemplate = NULL;
@@ -633,7 +622,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
goto loser;
}
-#ifndef NSS_DISABLE_ECC
if (lpk->keyType == ecKey) {
/* Convert length in bits to length in bytes. */
lpk->u.ec.publicValue.len >>= 3;
@@ -645,7 +633,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
goto loser;
}
}
-#endif /* NSS_DISABLE_ECC */
if (paramDest && paramTemplate) {
rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h
index edfe82f5ae..dbd8da0923 100644
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -831,6 +831,10 @@ SECStatus PK11_LinkGenericObject(PK11GenericObject *list,
PK11GenericObject *object);
SECStatus PK11_DestroyGenericObjects(PK11GenericObject *object);
SECStatus PK11_DestroyGenericObject(PK11GenericObject *object);
+PK11GenericObject *PK11_CreateManagedGenericObject(PK11SlotInfo *slot,
+ const CK_ATTRIBUTE *pTemplate,
+ int count, PRBool token);
+/* deprecated */
PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot,
const CK_ATTRIBUTE *pTemplate,
int count, PRBool token);
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index 1ef53e1d76..cf2a40a2f1 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -182,6 +182,10 @@ PK11_FreeSymKey(PK11SymKey *symKey)
PK11SlotInfo *slot;
PRBool freeit = PR_TRUE;
+ if (!symKey) {
+ return;
+ }
+
if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) {
PK11SymKey *parent = symKey->parent;
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index 0a6ed6c087..c39abe17e6 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -1182,7 +1182,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
/* set the slot flags to the current token values */
slot->series++; /* allow other objects to detect that the
- * slot is different */
+ * slot is different */
slot->flags = slot->tokenInfo.flags;
slot->needLogin = ((slot->tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE);
slot->readOnly = ((slot->tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE);
@@ -1471,6 +1471,9 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
slot->hasRootCerts = PR_TRUE;
}
}
+ if ((slotInfo.flags & CKF_USER_PIN_INITIALIZED) != 0) {
+ slot->flags |= CKF_USER_PIN_INITIALIZED;
+ }
}
/*********************************************************************
diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c
index a962e9bb3d..e316f1f1a2 100644
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -437,6 +437,11 @@ SECMOD_DeleteInternalModule(const char *name)
return rv;
}
+#ifdef NSS_FIPS_DISABLED
+ PORT_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR);
+ return rv;
+#endif
+
SECMOD_GetWriteLock(moduleLock);
for (mlpp = &modules, mlp = modules;
mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
@@ -955,7 +960,11 @@ SECMOD_DestroyModuleList(SECMODModuleList *list)
PRBool
SECMOD_CanDeleteInternalModule(void)
{
+#ifdef NSS_FIPS_DISABLED
+ return PR_FALSE;
+#else
return (PRBool)(pendingModule == NULL);
+#endif
}
/*
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index 63c2079297..260e6387d7 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -175,6 +175,7 @@ struct PK11GenericObjectStr {
PK11GenericObject *next;
PK11SlotInfo *slot;
CK_OBJECT_HANDLE objectID;
+ PRBool owner;
};
#define MAX_TEMPL_ATTRS 16 /* maximum attributes in template */