From 1a4caffe99ad757b3d9ae337e481794cfdb8fe45 Mon Sep 17 00:00:00 2001 From: "relyea%netscape.com" Date: Sat, 18 Oct 2003 00:38:04 +0000 Subject: [PATCH] 221067 NSS needs to be able to create token symkeys from unwrap and derive. git-svn-id: svn://10.0.0.236/trunk@148092 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/nss/nss.def | 4 + mozilla/security/nss/lib/pk11wrap/pk11func.h | 48 ++++ mozilla/security/nss/lib/pk11wrap/pk11kea.c | 18 +- mozilla/security/nss/lib/pk11wrap/pk11skey.c | 237 ++++++++++++++----- mozilla/security/nss/lib/pk11wrap/secmodt.h | 2 + mozilla/security/nss/lib/softoken/pkcs11u.c | 2 +- 6 files changed, 246 insertions(+), 65 deletions(-) diff --git a/mozilla/security/nss/lib/nss/nss.def b/mozilla/security/nss/lib/nss/nss.def index b871e1cbfae..4990a8980fa 100644 --- a/mozilla/security/nss/lib/nss/nss.def +++ b/mozilla/security/nss/lib/nss/nss.def @@ -764,9 +764,13 @@ CERT_EncodeTimeChoice; DSAU_EncodeDerSigWithLen; DSAU_DecodeDerSigToLen; NSS_Get_CERT_TimeChoiceTemplate; +PK11_DeriveWithFlagsPerm; PK11_ExportEncryptedPrivKeyInfo; PK11_FindSlotsByAliases; +PK11_MoveKey; PK11_PubDeriveExtended; +PK11_PubUnwrapSymKeyWithFlagsPerm; +PK11_UnwrapSymKeyWithFlagsPerm; SEC_ASN1DecoderAbort; SEC_ASN1EncoderAbort; SEC_DupCrl; diff --git a/mozilla/security/nss/lib/pk11wrap/pk11func.h b/mozilla/security/nss/lib/pk11wrap/pk11func.h index d4f637de9e0..8eedbd25456 100644 --- a/mozilla/security/nss/lib/pk11wrap/pk11func.h +++ b/mozilla/security/nss/lib/pk11wrap/pk11func.h @@ -297,12 +297,32 @@ SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, PK11SymKey *symKey, SECItem *wrappedKey); SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params, PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey); +/* move a key to 'slot' optionally set the key attributes according to either + * operation or the flags and making the key permanent at the same time. + * If the key is moved to the same slot, operation and flags values are + * currently ignored */ +PK11SymKey *PK11_MoveKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, + CK_FLAGS flags, PRBool perm, PK11SymKey *symKey); +/* + * derive a new key from the base key. + * PK11_Derive returns a key which can do exactly one operation, and is + * ephemeral (session key). + * PK11_DeriveWithFlags is the same as PK11_Derive, except you can use + * CKF_ flags to enable more than one operation. + * PK11_DeriveWithFlagsPerm is the same as PK11_DeriveWithFlags except you can + * (optionally) make the key permanent (token key). + */ PK11SymKey *PK11_Derive(PK11SymKey *baseKey, CK_MECHANISM_TYPE mechanism, SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); PK11SymKey *PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags); +PK11SymKey * PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, + CK_MECHANISM_TYPE derive, + SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, + int keySize, CK_FLAGS flags, PRBool isPerm); + PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB, CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, @@ -312,6 +332,16 @@ PK11SymKey *PK11_PubDeriveExtended( SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx, CK_ULONG kdf, SECItem *sharedData); + +/* + * unwrap a new key with a symetric key. + * PK11_Unwrap returns a key which can do exactly one operation, and is + * ephemeral (session key). + * PK11_UnwrapWithFlags is the same as PK11_Unwrap, except you can use + * CKF_ flags to enable more than one operation. + * PK11_UnwrapWithFlagsPerm is the same as PK11_UnwrapWithFlags except you can + * (optionally) make the key permanent (token key). + */ PK11SymKey *PK11_UnwrapSymKey(PK11SymKey *key, CK_MECHANISM_TYPE wraptype, SECItem *param, SECItem *wrapppedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); @@ -319,8 +349,26 @@ PK11SymKey *PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags); +PK11SymKey * PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey, + CK_MECHANISM_TYPE wrapType, + SECItem *param, SECItem *wrappedKey, + CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, + int keySize, CK_FLAGS flags, PRBool isPerm); + +/* + * unwrap a new key with a private key. + * PK11_PubUnwrap returns a key which can do exactly one operation, and is + * ephemeral (session key). + * PK11_PubUnwrapWithFlagsPerm is the same as PK11_PubUnwrap except you can + * use * CKF_ flags to enable more than one operation, and optionally make + * the key permanent (token key). + */ PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); +PK11SymKey * PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, + SECItem *wrappedKey, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, + CK_FLAGS flags, PRBool isPerm); PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID, void *wincx); SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey,PRBool force); diff --git a/mozilla/security/nss/lib/pk11wrap/pk11kea.c b/mozilla/security/nss/lib/pk11wrap/pk11kea.c index d6046bd9907..a4cda1d2714 100644 --- a/mozilla/security/nss/lib/pk11wrap/pk11kea.c +++ b/mozilla/security/nss/lib/pk11wrap/pk11kea.c @@ -70,7 +70,8 @@ pk11_FindRSAPubKey(PK11SlotInfo *slot) PK11SymKey * pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) + CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, + PRBool isPerm, PK11SymKey *symKey) { PK11SymKey *newSymKey = NULL; SECStatus rv; @@ -101,7 +102,7 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, unsigned int symKeyLength = PK11_GetKeyLength(symKey); PK11RSAGenParams rsaParams; - if (symKeyLength > 60) /* bytes */ { + if (symKeyLength > 53) /* bytes */ { /* we'd have to generate an RSA key pair > 512 bits long, ** and that's too costly. Don't even try. */ @@ -109,7 +110,7 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, goto rsa_failed; } rsaParams.keySizeInBits = - (symKeyLength > 28 || symKeyLength == 0) ? 512 : 256; + (symKeyLength > 21 || symKeyLength == 0) ? 512 : 256; rsaParams.pe = 0x10001; privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx); @@ -137,8 +138,8 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, /* now wrap the keys in and out */ rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData); if (rv == SECSuccess) { - newSymKey = PK11_PubUnwrapSymKey(privKey,&wrapData,type,operation, - symKey->size); + newSymKey = PK11_PubUnwrapSymKeyWithFlagsPerm(privKey, + &wrapData,type,operation,0,flags,isPerm); } rsa_failed: if (wrapData.data != NULL) PORT_Free(wrapData.data); @@ -161,7 +162,7 @@ rsa_failed: SECItem Ra,wrap; /* can only exchange skipjack keys */ - if (type != CKM_SKIPJACK_CBC64) { + if ((type != CKM_SKIPJACK_CBC64) || (isPerm)) { PORT_SetError( SEC_ERROR_NO_MODULE ); goto kea_failed; } @@ -207,8 +208,9 @@ rsa_failed: rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap); if (rv == SECSuccess) { - newSymKey = PK11_UnwrapSymKey(tekTarget, CKM_SKIPJACK_WRAP, NULL, - &wrap, type, operation, symKey->size); + newSymKey = PK11_UnwrapSymKeyWithFlags(tekTarget, + CKM_SKIPJACK_WRAP, NULL, + &wrap, type, operation, flags, symKey->size); } PORT_Free(wrap.data); kea_failed: diff --git a/mozilla/security/nss/lib/pk11wrap/pk11skey.c b/mozilla/security/nss/lib/pk11wrap/pk11skey.c index b772c8885ec..764a85a172b 100644 --- a/mozilla/security/nss/lib/pk11wrap/pk11skey.c +++ b/mozilla/security/nss/lib/pk11wrap/pk11skey.c @@ -67,7 +67,7 @@ static const SECItem pk11_null_params = { 0 }; static PK11SymKey *pk11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_ATTRIBUTE *userAttr, - unsigned int numAttrs); + unsigned int numAttrs, PRBool isPerm); #ifdef NSS_ENABLE_ECC extern int SECKEY_ECParams2KeySize(SECItem *params); @@ -129,13 +129,11 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session, SECStatus rv = SECSuccess; rwsession = session; - if (rwsession == CK_INVALID_SESSION) { - if (token) { - rwsession = PK11_GetRWSession(slot); - } else { - rwsession = slot->session; - PK11_EnterSlotMonitor(slot); - } + if (token) { + rwsession = PK11_GetRWSession(slot); + } else if (rwsession == CK_INVALID_SESSION) { + rwsession = slot->session; + PK11_EnterSlotMonitor(slot); } crv = PK11_GETTAB(slot)->C_CreateObject(rwsession, theTemplate, count,objectID); @@ -143,13 +141,10 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session, PORT_SetError( PK11_MapError(crv) ); rv = SECFailure; } - - if (session == CK_INVALID_SESSION) { - if (token) { - PK11_RestoreROSession(slot, rwsession); - } else { - PK11_ExitSlotMonitor(slot); - } + if (token) { + PK11_RestoreROSession(slot, rwsession); + } else if (session == CK_INVALID_SESSION) { + PK11_ExitSlotMonitor(slot); } return rv; @@ -410,7 +405,7 @@ pk11_FlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue) static PK11SymKey * pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE *keyTemplate, + PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate, unsigned int templateCount, SECItem *key, void *wincx) { PK11SymKey * symKey; @@ -435,7 +430,7 @@ pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, /* import the keys */ rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate, - templateCount, PR_FALSE, &symKey->objectID); + templateCount, isToken, &symKey->objectID); if ( rv != SECSuccess) { PK11_FreeSymKey(symKey); return NULL; @@ -466,8 +461,8 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); keyType = PK11_GetKeyType(type,key->len); - symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, keyTemplate, - templateCount, key, wincx); + symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE, + keyTemplate, templateCount, key, wincx); return symKey; } @@ -491,15 +486,22 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; if (isPerm) { - PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(keyType) ); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++; + /* sigh some tokens think CKA_PRIVATE = false is a reasonable + * default for secret keys */ + PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue) ); attrs++; + } + attrs += pk11_FlagsToAttributes(flags, attrs, &cktrue); + if ((operation != CKA_FLAGS_ONLY) && + !pk11_FindAttrInTemplate(keyTemplate, attrs-keyTemplate, operation)) { + PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue)); attrs++; } templateCount = attrs - keyTemplate; - templateCount += pk11_FlagsToAttributes(flags, attrs, &cktrue); PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); keyType = PK11_GetKeyType(type,key->len); - symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, keyTemplate, - templateCount, key, wincx); + symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm, + keyTemplate, templateCount, key, wincx); if (symKey && isPerm) { symKey->owner = PR_FALSE; } @@ -1343,16 +1345,19 @@ PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject) PK11SymKey * pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey); + CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, + PRBool perm, PK11SymKey *symKey); + /* - * The next two utilities are to deal with the fact that a given operation + * The next three utilities are to deal with the fact that a given operation * may be a multi-slot affair. This creates a new key object that is copied * into the new slot. */ PK11SymKey * -pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) +pk11_CopyToSlotPerm(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, + CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, + PRBool isPerm, PK11SymKey *symKey) { SECStatus rv; PK11SymKey *newKey = NULL; @@ -1362,15 +1367,26 @@ pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, rv = PK11_ExtractKeyValue(symKey); /* KEY is sensitive, we're try key exchanging it. */ if (rv != SECSuccess) { - return pk11_KeyExchange(slot, type, operation, symKey); + return pk11_KeyExchange(slot, type, operation, + flags, isPerm, symKey); } } - newKey = PK11_ImportSymKey(slot, type, symKey->origin, operation, - &symKey->data, symKey->cx); - if (newKey == NULL) newKey = pk11_KeyExchange(slot,type,operation,symKey); + + newKey = PK11_ImportSymKeyWithFlags(slot, type, symKey->origin, + operation, &symKey->data, flags, isPerm, symKey->cx); + if (newKey == NULL) { + newKey = pk11_KeyExchange(slot, type, operation, flags, isPerm, symKey); + } return newKey; } +PK11SymKey * +pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, + CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) +{ + return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey); +} + /* * Make sure the slot we are in the correct slot for the operation */ @@ -1393,6 +1409,23 @@ pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type, return newKey; } +PK11SymKey * +PK11_MoveKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, + CK_FLAGS flags, PRBool perm, PK11SymKey *symKey) +{ + if (symKey->slot == slot) { + if (perm) { + return PK11_ConvertSessionSymKeyToTokenSymKey(symKey,symKey->cx); + } else { + return PK11_ReferenceSymKey(symKey); + } + } + + return pk11_CopyToSlotPerm(slot, symKey->type, + operation, flags, perm, symKey); +} + + /* * Use the token to Generate a key. keySize must be 'zero' for fixed key * length algorithms. NOTE: this means we can never generate a DES2 key @@ -2563,7 +2596,7 @@ PK11_Derive( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param, int keySize) { return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, - keySize, NULL, 0); + keySize, NULL, 0, PR_FALSE); } @@ -2578,7 +2611,27 @@ PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue); return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, - keySize, keyTemplate, templateCount); + keySize, keyTemplate, templateCount, PR_FALSE); +} + +PK11SymKey * +PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, + SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, + int keySize, CK_FLAGS flags, PRBool isPerm) +{ + CK_BBOOL cktrue = CK_TRUE; + CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS+1]; + CK_ATTRIBUTE *attrs; + unsigned int templateCount = 0; + + attrs = keyTemplate; + if (isPerm) { + PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++; + } + templateCount = attrs - keyTemplate; + templateCount += pk11_FlagsToAttributes(flags, keyTemplate, &cktrue); + return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, + keySize, keyTemplate, templateCount, isPerm); } static PRBool @@ -2596,7 +2649,8 @@ pk11_FindAttrInTemplate(CK_ATTRIBUTE * attr, static PK11SymKey * pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, - int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs) + int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, + PRBool isPerm) { PK11SlotInfo * slot = baseKey->slot; PK11SymKey * symKey; @@ -2609,6 +2663,7 @@ pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, CK_RV crv; CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; CK_ATTRIBUTE * attrs = keyTemplate; + CK_SESSION_HANDLE session; unsigned int templateCount; if (numAttrs > MAX_TEMPL_ATTRS) { @@ -2638,7 +2693,8 @@ pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen); attrs++; } - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { + if ((operation != CKA_FLAGS_ONLY) && + !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue); attrs++; } @@ -2679,10 +2735,19 @@ pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, } symKey->origin=PK11_OriginDerive; - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, + if (isPerm) { + session = PK11_GetRWSession(slot); + } else { + pk11_EnterKeyMonitor(symKey); + session = symKey->session; + } + crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism, baseKey->objectID, keyTemplate, templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); + if (isPerm) { + PK11_RestoreROSession(slot, session); + } else { + pk11_ExitKeyMonitor(symKey); + } if (newBaseKey) PK11_FreeSymKey(newBaseKey); if (crv != CKR_OK) { @@ -3025,7 +3090,7 @@ static PK11SymKey * pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, CK_MECHANISM *mech, SECItem *inKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE *keyTemplate, unsigned int templateCount, - int key_size, void * wincx, CK_RV *crvp) + int key_size, void * wincx, CK_RV *crvp, PRBool isPerm) { CK_ULONG len; SECItem outKey; @@ -3077,8 +3142,8 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, if (PK11_DoesMechanism(slot,target)) { symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap, - keyTemplate, templateCount, - &outKey, wincx); + isPerm, keyTemplate, + templateCount, &outKey, wincx); } else { slot = PK11_GetBestSlot(target,wincx); if (slot == NULL) { @@ -3088,8 +3153,8 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, return NULL; } symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap, - keyTemplate, templateCount, - &outKey, wincx); + isPerm, keyTemplate, + templateCount, &outKey, wincx); PK11_FreeSlot(slot); } PORT_Free(outKey.data); @@ -3107,7 +3172,7 @@ static PK11SymKey * pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, - void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs) + void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, PRBool isPerm) { PK11SymKey * symKey; SECItem * param_free = NULL; @@ -3116,6 +3181,7 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; CK_ULONG valueLen = 0; CK_MECHANISM mechanism; + CK_SESSION_HANDLE rwsession; CK_RV crv; CK_MECHANISM_INFO mechanism_info; CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; @@ -3143,7 +3209,8 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType ); attrs++; } - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { + if ((operation != CKA_FLAGS_ONLY) && + !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; } @@ -3195,7 +3262,7 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, && !PK11_DoesMechanism(slot,target)) { symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, target, keyTemplate, templateCount, keySize, - wincx, &crv); + wincx, &crv, isPerm); if (symKey) { if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); return symKey; @@ -3220,18 +3287,27 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, symKey->size = keySize; symKey->origin = PK11_OriginUnwrap; - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_UnwrapKey(symKey->session,&mechanism,wrappingKey, + if (isPerm) { + rwsession = PK11_GetRWSession(slot); + } else { + pk11_EnterKeyMonitor(symKey); + rwsession = symKey->session; + } + crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession,&mechanism,wrappingKey, wrappedKey->data, wrappedKey->len, keyTemplate, templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); + if (isPerm) { + PK11_RestoreROSession(slot, rwsession); + } else { + pk11_ExitKeyMonitor(symKey); + } if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); if ((crv != CKR_OK) && (crv != CKR_DEVICE_ERROR)) { /* try hand Unwrapping */ PK11_FreeSymKey(symKey); symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, target, keyTemplate, templateCount, keySize, - wincx, NULL); + wincx, NULL, isPerm); } return symKey; @@ -3246,7 +3322,7 @@ PK11_UnwrapSymKey( PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, { return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, wrapType, param, wrappedKey, target, operation, keySize, - wrappingKey->cx, NULL, 0); + wrappingKey->cx, NULL, 0, PR_FALSE); } /* use a symetric key to unwrap another symetric key */ @@ -3263,7 +3339,31 @@ PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue); return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, wrapType, param, wrappedKey, target, operation, keySize, - wrappingKey->cx, keyTemplate, templateCount); + wrappingKey->cx, keyTemplate, templateCount, PR_FALSE); +} + +PK11SymKey * +PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey, + CK_MECHANISM_TYPE wrapType, + SECItem *param, SECItem *wrappedKey, + CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, + int keySize, CK_FLAGS flags, PRBool isPerm) +{ + CK_BBOOL cktrue = CK_TRUE; + CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; + CK_ATTRIBUTE *attrs; + unsigned int templateCount; + + attrs = keyTemplate; + if (isPerm) { + PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++; + } + templateCount = attrs-keyTemplate; + templateCount += pk11_FlagsToAttributes(flags, keyTemplate, &cktrue); + + return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, + wrapType, param, wrappedKey, target, operation, keySize, + wrappingKey->cx, keyTemplate, templateCount, PR_TRUE); } @@ -3278,7 +3378,7 @@ PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, return pk11_AnyUnwrapKey(wrappingKey->pkcs11Slot, wrappingKey->pkcs11ID, wrapType, NULL, wrappedKey, target, operation, keySize, - wrappingKey->wincx, NULL, 0); + wrappingKey->wincx, NULL, 0, PR_FALSE); } /* unwrap a symetric key with a private key. */ @@ -3298,7 +3398,34 @@ PK11_PubUnwrapSymKeyWithFlags(SECKEYPrivateKey *wrappingKey, return pk11_AnyUnwrapKey(wrappingKey->pkcs11Slot, wrappingKey->pkcs11ID, wrapType, NULL, wrappedKey, target, operation, keySize, - wrappingKey->wincx, keyTemplate, templateCount); + wrappingKey->wincx, keyTemplate, templateCount, PR_FALSE); +} + +PK11SymKey * +PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, + SECItem *wrappedKey, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, + CK_FLAGS flags, PRBool isPerm) +{ + CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); + CK_BBOOL cktrue = CK_TRUE; + CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; + CK_ATTRIBUTE *attrs; + unsigned int templateCount; + + attrs = keyTemplate; + if (isPerm) { + PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++; + } + templateCount = attrs-keyTemplate; + + templateCount += pk11_FlagsToAttributes(flags, keyTemplate, &cktrue); + + PK11_HandlePasswordCheck(wrappingKey->pkcs11Slot,wrappingKey->wincx); + + return pk11_AnyUnwrapKey(wrappingKey->pkcs11Slot, wrappingKey->pkcs11ID, + wrapType, NULL, wrappedKey, target, operation, keySize, + wrappingKey->wincx, keyTemplate, templateCount, isPerm); } /* @@ -5507,7 +5634,6 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx) CK_BBOOL cktrue = CK_TRUE; CK_RV crv; CK_OBJECT_HANDLE newKeyID; - SECKEYPrivateKey *newKey=NULL; CK_SESSION_HANDLE rwsession; PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++; @@ -5536,7 +5662,6 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx) CK_BBOOL cktrue = CK_TRUE; CK_RV crv; CK_OBJECT_HANDLE newKeyID; - PK11SymKey *newKey=NULL; CK_SESSION_HANDLE rwsession; PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++; diff --git a/mozilla/security/nss/lib/pk11wrap/secmodt.h b/mozilla/security/nss/lib/pk11wrap/secmodt.h index 6fe534c4622..4d34e87c3d4 100644 --- a/mozilla/security/nss/lib/pk11wrap/secmodt.h +++ b/mozilla/security/nss/lib/pk11wrap/secmodt.h @@ -171,6 +171,8 @@ struct PK11DefaultArrayEntryStr { #define CKM_FAKE_RANDOM 0x80000efeL #define CKM_INVALID_MECHANISM 0xffffffffL #define CKA_DIGEST 0x81000000L +#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */ + /* Cryptographic module types */ #define SECMOD_EXTERNAL 0 /* external module */ diff --git a/mozilla/security/nss/lib/softoken/pkcs11u.c b/mozilla/security/nss/lib/softoken/pkcs11u.c index 22dadce7a73..f2447d6cf79 100644 --- a/mozilla/security/nss/lib/softoken/pkcs11u.c +++ b/mozilla/security/nss/lib/softoken/pkcs11u.c @@ -697,9 +697,9 @@ pk11_FindSecretKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type) case CKA_VERIFY: case CKA_WRAP: case CKA_UNWRAP: + case CKA_MODIFIABLE: return (PK11Attribute *) &pk11_StaticTrueAttr; case CKA_NEVER_EXTRACTABLE: - case CKA_MODIFIABLE: return (PK11Attribute *) &pk11_StaticFalseAttr; case CKA_LABEL: label = nsslowkey_FindKeyNicknameByPublicKey(object->obj.slot->keyDB,