mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 18:07:31 +09:00
Replace NSS with Pale Moon's
This commit is contained in:
parent
ff1e5e48bf
commit
8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions
|
|
@ -6,6 +6,8 @@
|
|||
* Interfaces.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secmod.h"
|
||||
#include "nssilock.h"
|
||||
|
|
@ -73,11 +75,11 @@ pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession)
|
|||
* session could be invalid if the token has been removed or because
|
||||
* we got it from the non-owner free list */
|
||||
if ((symKey->series != slot->series) ||
|
||||
(symKey->session == CK_INVALID_SESSION)) {
|
||||
(symKey->session == CK_INVALID_HANDLE)) {
|
||||
symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
|
||||
}
|
||||
PORT_Assert(symKey->session != CK_INVALID_SESSION);
|
||||
if (symKey->session != CK_INVALID_SESSION)
|
||||
PORT_Assert(symKey->session != CK_INVALID_HANDLE);
|
||||
if (symKey->session != CK_INVALID_HANDLE)
|
||||
return symKey;
|
||||
PK11_FreeSymKey(symKey);
|
||||
/* if we are here, we need a session, but couldn't get one, it's
|
||||
|
|
@ -94,13 +96,13 @@ pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession)
|
|||
symKey->next = NULL;
|
||||
if (needSession) {
|
||||
symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
|
||||
PORT_Assert(symKey->session != CK_INVALID_SESSION);
|
||||
if (symKey->session == CK_INVALID_SESSION) {
|
||||
PORT_Assert(symKey->session != CK_INVALID_HANDLE);
|
||||
if (symKey->session == CK_INVALID_HANDLE) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
symKey = NULL;
|
||||
}
|
||||
} else {
|
||||
symKey->session = CK_INVALID_SESSION;
|
||||
symKey->session = CK_INVALID_HANDLE;
|
||||
}
|
||||
return symKey;
|
||||
}
|
||||
|
|
@ -148,7 +150,7 @@ pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
|||
/* if needSession was specified, make sure we have a valid session.
|
||||
* callers which specify needSession as false should do their own
|
||||
* check of the session before returning the symKey */
|
||||
if (needSession && symKey->session == CK_INVALID_SESSION) {
|
||||
if (needSession && symKey->session == CK_INVALID_HANDLE) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return NULL;
|
||||
|
|
@ -213,16 +215,16 @@ PK11_FreeSymKey(PK11SymKey *symKey)
|
|||
* session must be valid.
|
||||
* freeSymKeysHead contain a list of SymKey structures without
|
||||
* valid session.
|
||||
* session must be CK_INVALID_SESSION.
|
||||
* session must be CK_INVALID_HANDLE.
|
||||
* though sessionOwner is false, callers should not depend on
|
||||
* this fact.
|
||||
*/
|
||||
if (symKey->sessionOwner) {
|
||||
PORT_Assert(symKey->session != CK_INVALID_SESSION);
|
||||
PORT_Assert(symKey->session != CK_INVALID_HANDLE);
|
||||
symKey->next = slot->freeSymKeysWithSessionHead;
|
||||
slot->freeSymKeysWithSessionHead = symKey;
|
||||
} else {
|
||||
symKey->session = CK_INVALID_SESSION;
|
||||
symKey->session = CK_INVALID_HANDLE;
|
||||
symKey->next = slot->freeSymKeysHead;
|
||||
slot->freeSymKeysHead = symKey;
|
||||
}
|
||||
|
|
@ -345,8 +347,8 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
|
|||
/* This is the only case where pk11_CreateSymKey does not explicitly
|
||||
* check symKey->session. We need to assert here to make sure.
|
||||
* the session isn't invalid. */
|
||||
PORT_Assert(parent->session != CK_INVALID_SESSION);
|
||||
if (parent->session == CK_INVALID_SESSION) {
|
||||
PORT_Assert(parent->session != CK_INVALID_HANDLE);
|
||||
if (parent->session == CK_INVALID_HANDLE) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return NULL;
|
||||
|
|
@ -366,6 +368,7 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
|
|||
int series, void *wincx)
|
||||
{
|
||||
PK11SymKey *symKey = NULL;
|
||||
CK_OBJECT_HANDLE keyHandle;
|
||||
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
if (slot->series != series ||
|
||||
|
|
@ -378,9 +381,10 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
|
|||
type = slot->wrapMechanism;
|
||||
}
|
||||
|
||||
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
|
||||
slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
|
||||
keyHandle = slot->refKeys[wrap];
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
|
||||
slot->wrapMechanism, keyHandle, PR_FALSE, wincx);
|
||||
return symKey;
|
||||
}
|
||||
|
||||
|
|
@ -401,15 +405,19 @@ void
|
|||
PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey)
|
||||
{
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
if (wrap < PR_ARRAY_SIZE(slot->refKeys) &&
|
||||
slot->refKeys[wrap] == CK_INVALID_HANDLE) {
|
||||
/* save the handle and mechanism for the wrapping key */
|
||||
/* mark the key and session as not owned by us so they don't get freed
|
||||
* when the key goes way... that lets us reuse the key later */
|
||||
slot->refKeys[wrap] = wrapKey->objectID;
|
||||
wrapKey->owner = PR_FALSE;
|
||||
wrapKey->sessionOwner = PR_FALSE;
|
||||
slot->wrapMechanism = wrapKey->type;
|
||||
if (wrap >= 0) {
|
||||
size_t uwrap = (size_t)wrap;
|
||||
if (uwrap < PR_ARRAY_SIZE(slot->refKeys) &&
|
||||
slot->refKeys[uwrap] == CK_INVALID_HANDLE) {
|
||||
/* save the handle and mechanism for the wrapping key */
|
||||
/* mark the key and session as not owned by us so they don't get
|
||||
* freed when the key goes way... that lets us reuse the key
|
||||
* later */
|
||||
slot->refKeys[uwrap] = wrapKey->objectID;
|
||||
wrapKey->owner = PR_FALSE;
|
||||
wrapKey->sessionOwner = PR_FALSE;
|
||||
slot->wrapMechanism = wrapKey->type;
|
||||
}
|
||||
}
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
}
|
||||
|
|
@ -477,6 +485,15 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
|||
CK_ATTRIBUTE keyTemplate[5];
|
||||
CK_ATTRIBUTE *attrs = keyTemplate;
|
||||
|
||||
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
|
||||
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
|
||||
* it as a real attribute */
|
||||
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
|
||||
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
|
||||
* etc. Strip out the real attribute here */
|
||||
operation &= ~CKA_NSS_MESSAGE_MASK;
|
||||
}
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
|
||||
|
|
@ -491,10 +508,37 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
|||
keyTemplate, templateCount, key, wincx);
|
||||
return symKey;
|
||||
}
|
||||
/* Import a PKCS #11 data object and return it as a key. This key is
|
||||
* only useful in a limited number of mechanisms, such as HKDF. */
|
||||
PK11SymKey *
|
||||
PK11_ImportDataKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin,
|
||||
CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx)
|
||||
{
|
||||
CK_OBJECT_CLASS ckoData = CKO_DATA;
|
||||
CK_ATTRIBUTE template[2] = { { CKA_CLASS, (CK_BYTE_PTR)&ckoData, sizeof(ckoData) },
|
||||
{ CKA_VALUE, (CK_BYTE_PTR)key->data, key->len } };
|
||||
CK_OBJECT_HANDLE handle;
|
||||
PK11GenericObject *genObject;
|
||||
|
||||
/*
|
||||
* turn key bits into an appropriate key object
|
||||
*/
|
||||
genObject = PK11_CreateGenericObject(slot, template, PR_ARRAY_SIZE(template), PR_FALSE);
|
||||
if (genObject == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
handle = PK11_GetObjectHandle(PK11_TypeGeneric, genObject, NULL);
|
||||
if (handle == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
/* A note about ownership of the PKCS #11 handle:
|
||||
* PK11_CreateGenericObject() will not destroy the object it creates
|
||||
* on Free, For that you want PK11_CreateManagedGenericObject().
|
||||
* Below we import the handle into the symKey structure. We pass
|
||||
* PR_TRUE as the owner so that the symKey will destroy the object
|
||||
* once it's freed. This is way it's safe to free now. */
|
||||
PK11_DestroyGenericObject(genObject);
|
||||
return PK11_SymKeyFromHandle(slot, NULL, origin, type, handle, PR_TRUE, wincx);
|
||||
}
|
||||
|
||||
/* turn key bits into an appropriate key object */
|
||||
PK11SymKey *
|
||||
PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
|
||||
|
|
@ -508,6 +552,15 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
|||
CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
|
||||
CK_ATTRIBUTE *attrs = keyTemplate;
|
||||
|
||||
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
|
||||
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
|
||||
* it as a real attribute */
|
||||
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
|
||||
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
|
||||
* etc. Strip out the real attribute here */
|
||||
operation &= ~CKA_NSS_MESSAGE_MASK;
|
||||
}
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
|
||||
|
|
@ -546,7 +599,7 @@ PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
|
|||
CK_ATTRIBUTE *attrs;
|
||||
CK_BBOOL ckTrue = CK_TRUE;
|
||||
CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
|
||||
int tsize = 0;
|
||||
size_t tsize = 0;
|
||||
CK_OBJECT_HANDLE key_id;
|
||||
|
||||
attrs = findTemp;
|
||||
|
|
@ -1157,10 +1210,10 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
|||
symKey->owner = PR_FALSE;
|
||||
} else {
|
||||
session = symKey->session;
|
||||
if (session != CK_INVALID_SESSION)
|
||||
if (session != CK_INVALID_HANDLE)
|
||||
pk11_EnterKeyMonitor(symKey);
|
||||
}
|
||||
if (session == CK_INVALID_SESSION) {
|
||||
if (session == CK_INVALID_HANDLE) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return NULL;
|
||||
|
|
@ -1207,7 +1260,7 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
|
|||
|
||||
PK11_Authenticate(slot, PR_TRUE, wincx);
|
||||
rwsession = PK11_GetRWSession(slot);
|
||||
if (rwsession == CK_INVALID_SESSION) {
|
||||
if (rwsession == CK_INVALID_HANDLE) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1224,13 +1277,23 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
|
|||
symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function does a straight public key wrap (which only RSA can do).
|
||||
* Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and
|
||||
* Diffie-Hellman Ciphers. */
|
||||
/* This function does a straight public key wrap with the CKM_RSA_PKCS
|
||||
* mechanism. */
|
||||
SECStatus
|
||||
PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
|
||||
PK11SymKey *symKey, SECItem *wrappedKey)
|
||||
{
|
||||
CK_MECHANISM_TYPE inferred = pk11_mapWrapKeyType(pubKey->keyType);
|
||||
return PK11_PubWrapSymKeyWithMechanism(pubKey, inferred, NULL, symKey,
|
||||
wrappedKey);
|
||||
}
|
||||
|
||||
/* This function wraps a symmetric key with a public key, such as with the
|
||||
* CKM_RSA_PKCS and CKM_RSA_PKCS_OAEP mechanisms. */
|
||||
SECStatus
|
||||
PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey,
|
||||
CK_MECHANISM_TYPE mechType, SECItem *param,
|
||||
PK11SymKey *symKey, SECItem *wrappedKey)
|
||||
{
|
||||
PK11SlotInfo *slot;
|
||||
CK_ULONG len = wrappedKey->len;
|
||||
|
|
@ -1247,7 +1310,7 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
|
|||
}
|
||||
|
||||
/* if this slot doesn't support the mechanism, go to a slot that does */
|
||||
newKey = pk11_ForceSlot(symKey, type, CKA_ENCRYPT);
|
||||
newKey = pk11_ForceSlot(symKey, mechType, CKA_ENCRYPT);
|
||||
if (newKey != NULL) {
|
||||
symKey = newKey;
|
||||
}
|
||||
|
|
@ -1258,9 +1321,15 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
|
|||
}
|
||||
|
||||
slot = symKey->slot;
|
||||
mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType);
|
||||
mechanism.pParameter = NULL;
|
||||
mechanism.ulParameterLen = 0;
|
||||
|
||||
mechanism.mechanism = mechType;
|
||||
if (param == NULL) {
|
||||
mechanism.pParameter = NULL;
|
||||
mechanism.ulParameterLen = 0;
|
||||
} else {
|
||||
mechanism.pParameter = param->data;
|
||||
mechanism.ulParameterLen = param->len;
|
||||
}
|
||||
|
||||
id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
|
||||
if (id == CK_INVALID_HANDLE) {
|
||||
|
|
@ -1354,16 +1423,124 @@ pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* helper function which moves two keys into a new slot based on the
|
||||
* desired mechanism.
|
||||
*/
|
||||
static SECStatus
|
||||
pk11_moveTwoKeys(CK_MECHANISM_TYPE mech,
|
||||
CK_ATTRIBUTE_TYPE preferedOperation,
|
||||
CK_ATTRIBUTE_TYPE movingOperation,
|
||||
PK11SymKey *preferedKey, PK11SymKey *movingKey,
|
||||
PK11SymKey **newPreferedKey, PK11SymKey **newMovingKey)
|
||||
{
|
||||
PK11SlotInfo *newSlot;
|
||||
*newMovingKey = NULL;
|
||||
*newPreferedKey = NULL;
|
||||
|
||||
newSlot = PK11_GetBestSlot(mech, preferedKey->cx);
|
||||
if (newSlot == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
*newMovingKey = pk11_CopyToSlot(newSlot, movingKey->type,
|
||||
movingOperation, movingKey);
|
||||
if (*newMovingKey == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
*newPreferedKey = pk11_CopyToSlot(newSlot, preferedKey->type,
|
||||
preferedOperation, preferedKey);
|
||||
if (*newPreferedKey == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PK11_FreeSlot(newSlot);
|
||||
return SECSuccess;
|
||||
loser:
|
||||
PK11_FreeSlot(newSlot);
|
||||
PK11_FreeSymKey(*newMovingKey);
|
||||
PK11_FreeSymKey(*newPreferedKey);
|
||||
*newMovingKey = NULL;
|
||||
*newPreferedKey = NULL;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* To do joint operations, we often need two keys in the same slot.
|
||||
* Usually the PKCS #11 wrappers handle this correctly (like for PK11_WrapKey),
|
||||
* but sometimes the wrappers don't know about mechanism specific keys in
|
||||
* the Mechanism params. This function makes sure the two keys are in the
|
||||
* same slot by copying one or both of the keys into a common slot. This
|
||||
* functions makes sure the slot can handle the target mechanism. If the copy
|
||||
* is warranted, this function will prefer to move the movingKey first, then
|
||||
* the preferedKey. If the keys are moved, the new keys are returned in
|
||||
* newMovingKey and/or newPreferedKey. The application is responsible
|
||||
* for freeing those keys once the operation is complete.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_SymKeysToSameSlot(CK_MECHANISM_TYPE mech,
|
||||
CK_ATTRIBUTE_TYPE preferedOperation,
|
||||
CK_ATTRIBUTE_TYPE movingOperation,
|
||||
PK11SymKey *preferedKey, PK11SymKey *movingKey,
|
||||
PK11SymKey **newPreferedKey, PK11SymKey **newMovingKey)
|
||||
{
|
||||
/* usually don't return new keys */
|
||||
*newMovingKey = NULL;
|
||||
*newPreferedKey = NULL;
|
||||
if (movingKey->slot == preferedKey->slot) {
|
||||
|
||||
/* this should be the most common case */
|
||||
if ((preferedKey->slot != NULL) &&
|
||||
PK11_DoesMechanism(preferedKey->slot, mech)) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* we are in the same slot, but it doesn't do the operation,
|
||||
* move both keys to an appropriate target slot */
|
||||
return pk11_moveTwoKeys(mech, preferedOperation, movingOperation,
|
||||
preferedKey, movingKey,
|
||||
newPreferedKey, newMovingKey);
|
||||
}
|
||||
|
||||
/* keys are in different slot, try moving the moving key to the prefered
|
||||
* key's slot */
|
||||
if ((preferedKey->slot != NULL) &&
|
||||
PK11_DoesMechanism(preferedKey->slot, mech)) {
|
||||
*newMovingKey = pk11_CopyToSlot(preferedKey->slot, movingKey->type,
|
||||
movingOperation, movingKey);
|
||||
if (*newMovingKey != NULL) {
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
/* couldn't moving the moving key to the prefered slot, try moving
|
||||
* the prefered key */
|
||||
if ((movingKey->slot != NULL) &&
|
||||
PK11_DoesMechanism(movingKey->slot, mech)) {
|
||||
*newPreferedKey = pk11_CopyToSlot(movingKey->slot, preferedKey->type,
|
||||
preferedOperation, preferedKey);
|
||||
if (*newPreferedKey != NULL) {
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
/* Neither succeeded, but that could be that they were not in slots that
|
||||
* supported the operation, try moving both keys into a common slot that
|
||||
* can do the operation. */
|
||||
return pk11_moveTwoKeys(mech, preferedOperation, movingOperation,
|
||||
preferedKey, movingKey,
|
||||
newPreferedKey, newMovingKey);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function does a symetric based wrap.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
|
||||
PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey)
|
||||
PK11SymKey *wrappingKey, PK11SymKey *symKey,
|
||||
SECItem *wrappedKey)
|
||||
{
|
||||
PK11SlotInfo *slot;
|
||||
CK_ULONG len = wrappedKey->len;
|
||||
PK11SymKey *newKey = NULL;
|
||||
PK11SymKey *newSymKey = NULL;
|
||||
PK11SymKey *newWrappingKey = NULL;
|
||||
SECItem *param_save = NULL;
|
||||
CK_MECHANISM mechanism;
|
||||
PRBool owner = PR_TRUE;
|
||||
|
|
@ -1371,44 +1548,32 @@ PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
|
|||
CK_RV crv;
|
||||
SECStatus rv;
|
||||
|
||||
/* if this slot doesn't support the mechanism, go to a slot that does */
|
||||
/* Force symKey and wrappingKey into the same slot */
|
||||
if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) {
|
||||
/* first try copying the wrapping Key to the symKey slot */
|
||||
if (symKey->slot && PK11_DoesMechanism(symKey->slot, type)) {
|
||||
newKey = pk11_CopyToSlot(symKey->slot, type, CKA_WRAP, wrappingKey);
|
||||
}
|
||||
/* Nope, try it the other way */
|
||||
if (newKey == NULL) {
|
||||
if (wrappingKey->slot) {
|
||||
newKey = pk11_CopyToSlot(wrappingKey->slot,
|
||||
symKey->type, CKA_ENCRYPT, symKey);
|
||||
/* force the keys into same slot */
|
||||
rv = PK11_SymKeysToSameSlot(type, CKA_ENCRYPT, CKA_WRAP,
|
||||
symKey, wrappingKey,
|
||||
&newSymKey, &newWrappingKey);
|
||||
if (rv != SECSuccess) {
|
||||
/* Couldn't move the keys as desired, try to hand unwrap if possible */
|
||||
if (symKey->data.data == NULL) {
|
||||
rv = PK11_ExtractKeyValue(symKey);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_NO_MODULE);
|
||||
return SECFailure;
|
||||
}
|
||||
/* just not playing... one last thing, can we get symKey's data?
|
||||
* If it's possible, we it should already be in the
|
||||
* symKey->data.data pointer because pk11_CopyToSlot would have
|
||||
* tried to put it there. */
|
||||
if (newKey == NULL) {
|
||||
/* Can't get symKey's data: Game Over */
|
||||
if (symKey->data.data == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MODULE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (param == NULL) {
|
||||
param_save = param = PK11_ParamFromIV(type, NULL);
|
||||
}
|
||||
rv = pk11_HandWrap(wrappingKey, param, type,
|
||||
&symKey->data, wrappedKey);
|
||||
if (param_save)
|
||||
SECITEM_FreeItem(param_save, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
/* we successfully moved the sym Key */
|
||||
symKey = newKey;
|
||||
} else {
|
||||
/* we successfully moved the wrapping Key */
|
||||
wrappingKey = newKey;
|
||||
}
|
||||
if (param == NULL) {
|
||||
param_save = param = PK11_ParamFromIV(type, NULL);
|
||||
}
|
||||
rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data, wrappedKey);
|
||||
if (param_save)
|
||||
SECITEM_FreeItem(param_save, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
if (newSymKey) {
|
||||
symKey = newSymKey;
|
||||
}
|
||||
if (newWrappingKey) {
|
||||
wrappingKey = newWrappingKey;
|
||||
}
|
||||
|
||||
/* at this point both keys are in the same token */
|
||||
|
|
@ -1452,8 +1617,8 @@ PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
|
|||
} else {
|
||||
wrappedKey->len = len;
|
||||
}
|
||||
if (newKey)
|
||||
PK11_FreeSymKey(newKey);
|
||||
PK11_FreeSymKey(newSymKey);
|
||||
PK11_FreeSymKey(newWrappingKey);
|
||||
if (param_save)
|
||||
SECITEM_FreeItem(param_save, PR_TRUE);
|
||||
return rv;
|
||||
|
|
@ -1532,6 +1697,14 @@ PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
|
|||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
|
||||
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
|
||||
* it as a real attribute */
|
||||
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
|
||||
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
|
||||
* etc. Strip out the real attribute here */
|
||||
operation &= ~CKA_NSS_MESSAGE_MASK;
|
||||
}
|
||||
|
||||
/* first copy caller attributes in. */
|
||||
for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
|
||||
|
|
@ -1606,7 +1779,7 @@ PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
|
|||
pk11_EnterKeyMonitor(symKey);
|
||||
session = symKey->session;
|
||||
}
|
||||
if (session == CK_INVALID_SESSION) {
|
||||
if (session == CK_INVALID_HANDLE) {
|
||||
if (!isPerm)
|
||||
pk11_ExitKeyMonitor(symKey);
|
||||
crv = CKR_SESSION_HANDLE_INVALID;
|
||||
|
|
@ -1759,6 +1932,11 @@ pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
|
|||
else
|
||||
SharedInfoLen = sharedData->len;
|
||||
|
||||
if (SharedInfoLen > PR_UINT32_MAX - 4) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bufferLen = SharedInfoLen + 4;
|
||||
|
||||
/* Populate buffer with Counter || sharedData
|
||||
|
|
@ -1916,6 +2094,15 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
|
||||
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
|
||||
* it as a real attribute */
|
||||
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
|
||||
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
|
||||
* etc. Strip out the real attribute here */
|
||||
operation &= ~CKA_NSS_MESSAGE_MASK;
|
||||
}
|
||||
|
||||
symKey->origin = PK11_OriginDerive;
|
||||
|
||||
switch (privKey->keyType) {
|
||||
|
|
@ -2189,6 +2376,14 @@ pk11_PubDeriveECKeyWithKDF(
|
|||
if (symKey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
|
||||
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
|
||||
* it as a real attribute */
|
||||
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
|
||||
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
|
||||
* etc. Strip out the real attribute here */
|
||||
operation &= ~CKA_NSS_MESSAGE_MASK;
|
||||
}
|
||||
|
||||
symKey->origin = PK11_OriginDerive;
|
||||
|
||||
|
|
@ -2235,7 +2430,7 @@ pk11_PubDeriveECKeyWithKDF(
|
|||
key_size = SHA512_LENGTH;
|
||||
break;
|
||||
default:
|
||||
PORT_Assert(!"Invalid CKD");
|
||||
PORT_AssertNotReached("Invalid CKD");
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2511,6 +2706,14 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
|
|||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
|
||||
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
|
||||
* it as a real attribute */
|
||||
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
|
||||
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
|
||||
* etc. Strip out the real attribute here */
|
||||
operation &= ~CKA_NSS_MESSAGE_MASK;
|
||||
}
|
||||
|
||||
/* first copy caller attributes in. */
|
||||
for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
|
||||
|
|
@ -2619,8 +2822,8 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
|
|||
pk11_EnterKeyMonitor(symKey);
|
||||
rwsession = symKey->session;
|
||||
}
|
||||
PORT_Assert(rwsession != CK_INVALID_SESSION);
|
||||
if (rwsession == CK_INVALID_SESSION)
|
||||
PORT_Assert(rwsession != CK_INVALID_HANDLE);
|
||||
if (rwsession == CK_INVALID_HANDLE)
|
||||
crv = CKR_SESSION_HANDLE_INVALID;
|
||||
else
|
||||
crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism, wrappingKey,
|
||||
|
|
@ -2628,7 +2831,7 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
|
|||
keyTemplate, templateCount,
|
||||
&symKey->objectID);
|
||||
if (isPerm) {
|
||||
if (rwsession != CK_INVALID_SESSION)
|
||||
if (rwsession != CK_INVALID_HANDLE)
|
||||
PK11_RestoreROSession(slot, rwsession);
|
||||
} else {
|
||||
pk11_ExitKeyMonitor(symKey);
|
||||
|
|
@ -2703,20 +2906,33 @@ PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
|
|||
wrappingKey->cx, keyTemplate, templateCount, isPerm);
|
||||
}
|
||||
|
||||
/* unwrap a symetric key with a private key. */
|
||||
/* unwrap a symmetric key with a private key. Only supports CKM_RSA_PKCS. */
|
||||
PK11SymKey *
|
||||
PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey,
|
||||
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize)
|
||||
{
|
||||
CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
|
||||
|
||||
return PK11_PubUnwrapSymKeyWithMechanism(wrappingKey, wrapType, NULL,
|
||||
wrappedKey, target, operation,
|
||||
keySize);
|
||||
}
|
||||
|
||||
/* unwrap a symmetric key with a private key with the given parameters. */
|
||||
PK11SymKey *
|
||||
PK11_PubUnwrapSymKeyWithMechanism(SECKEYPrivateKey *wrappingKey,
|
||||
CK_MECHANISM_TYPE mechType, SECItem *param,
|
||||
SECItem *wrappedKey, CK_MECHANISM_TYPE target,
|
||||
CK_ATTRIBUTE_TYPE operation, int keySize)
|
||||
{
|
||||
PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
|
||||
|
||||
if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) {
|
||||
PK11_HandlePasswordCheck(slot, wrappingKey->wincx);
|
||||
}
|
||||
|
||||
return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
|
||||
wrapType, NULL, wrappedKey, target, operation, keySize,
|
||||
return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, mechType, param,
|
||||
wrappedKey, target, operation, keySize,
|
||||
wrappingKey->wincx, NULL, 0, PR_FALSE);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue