diff options
Diffstat (limited to 'security/nss/lib/pk11wrap')
-rw-r--r-- | security/nss/lib/pk11wrap/Makefile | 4 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11akey.c | 134 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 109 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cxt.c | 19 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11err.c | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11kea.c | 76 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11mech.c | 4 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11nobj.c | 42 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11obj.c | 25 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pbe.c | 59 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pk12.c | 12 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pqg.c | 8 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11priv.h | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pub.h | 8 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11skey.c | 179 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11slot.c | 4 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/secmod.h | 5 |
17 files changed, 349 insertions, 343 deletions
diff --git a/security/nss/lib/pk11wrap/Makefile b/security/nss/lib/pk11wrap/Makefile index 95766f79e..0b3017de6 100644 --- a/security/nss/lib/pk11wrap/Makefile +++ b/security/nss/lib/pk11wrap/Makefile @@ -96,8 +96,8 @@ endif ifdef XP_OS2_VACPP $(OBJDIR)/pk11skey.obj: pk11skey.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) $(OBJDIR)/pk11slot.obj: pk11slot.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) endif diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c index a6189cf43..707989d9f 100644 --- a/security/nss/lib/pk11wrap/pk11akey.c +++ b/security/nss/lib/pk11wrap/pk11akey.c @@ -1313,68 +1313,6 @@ PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx) return NULL; } -static int -pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key) - -{ - CK_ATTRIBUTE rsaTemplate = { CKA_MODULUS, NULL, 0 }; - CK_ATTRIBUTE dsaTemplate = { CKA_PRIME, NULL, 0 }; - /* XXX We should normally choose an attribute such that - * factor times its size is enough to hold the private key. - * For EC keys, we have no choice but to use CKA_EC_PARAMS, - * CKA_VALUE is not available for token keys. But for named - * curves, the number of bytes needed to represent the params - * is quite small so we bump up factor from 10 to 15. - */ - CK_ATTRIBUTE ecTemplate = { CKA_EC_PARAMS, NULL, 0 }; - CK_ATTRIBUTE_PTR pTemplate; - CK_RV crv; - int length; - int factor = 10; - - if(!key) { - return -1; - } - - switch (key->keyType) { - case rsaKey: - pTemplate = &rsaTemplate; - break; - case dsaKey: - case dhKey: - pTemplate = &dsaTemplate; - break; - case ecKey: - pTemplate = &ecTemplate; - factor = 15; - break; - case fortezzaKey: - default: - pTemplate = NULL; - } - - if(!pTemplate) { - return -1; - } - - crv = PK11_GetAttributes(NULL, key->pkcs11Slot, key->pkcs11ID, - pTemplate, 1); - if(crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - - length = pTemplate->ulValueLen; - length *= factor; - - - if(pTemplate->pValue != NULL) { - PORT_Free(pTemplate->pValue); - } - - return length; -} - SECKEYEncryptedPrivateKeyInfo * PK11_ExportEncryptedPrivKeyInfo( PK11SlotInfo *slot, /* optional, encrypt key in this slot */ @@ -1390,14 +1328,12 @@ PK11_ExportEncryptedPrivKeyInfo( SECItem *pbe_param = NULL; PK11SymKey *key = NULL; SECStatus rv = SECSuccess; - int encryptBufLen; CK_RV crv; - CK_ULONG encBufLenPtr; + CK_ULONG encBufLen; CK_MECHANISM_TYPE mechanism; CK_MECHANISM pbeMech; CK_MECHANISM cryptoMech; SECItem crypto_param; - SECItem encryptedKey = {siBuffer, NULL, 0}; if (!pwitem || !pk) { PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -1461,20 +1397,6 @@ PK11_ExportEncryptedPrivKeyInfo( crypto_param.data = (unsigned char *)cryptoMech.pParameter; crypto_param.len = cryptoMech.ulParameterLen; - - encryptBufLen = pk11_private_key_encrypt_buffer_length(pk); - if(encryptBufLen == -1) { - rv = SECFailure; - goto loser; - } - encryptedKey.len = (unsigned int)encryptBufLen; - encBufLenPtr = (CK_ULONG) encryptBufLen; - encryptedKey.data = (unsigned char *)PORT_ZAlloc(encryptedKey.len); - if(!encryptedKey.data) { - rv = SECFailure; - goto loser; - } - /* If the key isn't in the private key slot, move it */ if (key->slot != pk->pkcs11Slot) { PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot, @@ -1488,30 +1410,40 @@ PK11_ExportEncryptedPrivKeyInfo( PK11_FreeSymKey(key); key = newkey; } - + /* we are extracting an encrypted privateKey structure. * which needs to be freed along with the buffer into which it is * returned. eventually, we should retrieve an encrypted key using * pkcs8/pkcs5. */ + encBufLen = 0; PK11_EnterSlotMonitor(pk->pkcs11Slot); crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, - &cryptoMech, key->objectID, pk->pkcs11ID, encryptedKey.data, - &encBufLenPtr); + &cryptoMech, key->objectID, pk->pkcs11ID, NULL, + &encBufLen); PK11_ExitSlotMonitor(pk->pkcs11Slot); - encryptedKey.len = (unsigned int) encBufLenPtr; - if(crv != CKR_OK) { + if (crv != CKR_OK) { rv = SECFailure; goto loser; } - - if(!encryptedKey.len) { + epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen); + if (!epki->encryptedData.data) { + rv = SECFailure; + goto loser; + } + PK11_EnterSlotMonitor(pk->pkcs11Slot); + crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, + &cryptoMech, key->objectID, pk->pkcs11ID, + epki->encryptedData.data, &encBufLen); + PK11_ExitSlotMonitor(pk->pkcs11Slot); + epki->encryptedData.len = (unsigned int) encBufLen; + if(crv != CKR_OK) { rv = SECFailure; goto loser; } - - rv = SECITEM_CopyItem(arena, &epki->encryptedData, &encryptedKey); - if(rv != SECSuccess) { + + if(!epki->encryptedData.len) { + rv = SECFailure; goto loser; } @@ -1739,18 +1671,17 @@ SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force) { CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey); + SECStatus rv = SECWouldBlock; - /* found a cert matching the private key?. */ - if (!force && cert != NULL) { - /* yes, don't delete the key */ - CERT_DestroyCertificate(cert); - SECKEY_DestroyPrivateKey(privKey); - return SECWouldBlock; + if (!cert || force) { + /* now, then it's safe for the key to go away */ + rv = PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); + } + if (cert) { + CERT_DestroyCertificate(cert); } - /* now, then it's safe for the key to go away */ - PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); SECKEY_DestroyPrivateKey(privKey); - return SECSuccess; + return rv; } /* @@ -1787,6 +1718,9 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) SECStatus rv = SECSuccess; SECKEYPrivateKey *privKey; pk11KeyCallback *keycb = (pk11KeyCallback *) arg; + if (!arg) { + return SECFailure; + } privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx); @@ -1794,7 +1728,7 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) return SECFailure; } - if (keycb && (keycb->callback)) { + if (keycb->callback) { rv = (*keycb->callback)(privKey,keycb->callbackArg); } @@ -2026,6 +1960,7 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname) keys = SECKEY_NewPublicKeyList(); if (keys == NULL) { PORT_Free(key_ids); + return NULL; } for (i=0; i < objCount ; i++) { @@ -2071,6 +2006,7 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) keys = SECKEY_NewPrivateKeyList(); if (keys == NULL) { PORT_Free(key_ids); + return NULL; } for (i=0; i < objCount ; i++) { diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 08c0af2db..eb1a358b1 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -273,7 +273,7 @@ static CERTCertificate } /* Create a PKI object from the cryptoki instance */ - pkio = nssPKIObject_Create(NULL, co, td, NULL); + pkio = nssPKIObject_Create(NULL, co, td, NULL, nssPKIMonitor); if (!pkio) { nssCryptokiObject_Destroy(co); return NULL; @@ -481,7 +481,7 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *), struct nss3_cert_cbstr pk11cb; /* authenticate to the tokens first */ - (void) pk11_TraverseAllSlots( NULL, NULL, wincx); + (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, wincx); fda.callback = callback; fda.arg = arg; @@ -702,7 +702,30 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) &status); nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); - nssList_Destroy(nameList); + + /* if it wasn't found, repeat the process for email address */ + if (nssPKIObjectCollection_Count(collection) == 0 && + PORT_Strchr(nickname, '@') != NULL) + { + char* lowercaseName = CERT_FixupEmailAddr(nickname); + if (lowercaseName) { + (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, + lowercaseName, + nameList); + transfer_token_certs_to_collection(nameList, token, collection); + instances = nssToken_FindCertificatesByEmail(token, + NULL, + lowercaseName, + tokenOnly, + 0, + &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); + PORT_Free(lowercaseName); + } + } + + nssList_Destroy(nameList); foundCerts = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL); nssPKIObjectCollection_Destroy(collection); @@ -796,6 +819,8 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, NSSToken *token = PK11Slot_GetNSSToken(slot); SECItem *keyID = pk11_mkcertKeyID(cert); char *emailAddr = NULL; + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; if (keyID == NULL) { goto loser; @@ -815,9 +840,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, if (c->object.cryptoContext) { /* Delete the temp instance */ NSSCryptoContext *cc = c->object.cryptoContext; - nssCertificateStore_Lock(cc->certStore); + nssCertificateStore_Lock(cc->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); c->object.cryptoContext = NULL; cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; @@ -925,6 +951,7 @@ pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert, SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx) { + int err; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_ATTRIBUTE theTemplate[] = { { CKA_VALUE, NULL, 0 }, @@ -935,6 +962,7 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, CK_OBJECT_HANDLE certh; CK_OBJECT_HANDLE keyh; CK_ATTRIBUTE *attrs = theTemplate; + PRBool needLogin; SECStatus rv; PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, @@ -953,10 +981,18 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, if (certh == CK_INVALID_HANDLE) { return NULL; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * PK11_MatchItem. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY); - if ((keyh == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot, wincx)) { + if ((keyh == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* try it again authenticated */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) { @@ -983,6 +1019,7 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, CK_OBJECT_HANDLE key; PK11SlotInfo *slot = NULL; SECStatus rv; + int err; keyID = pk11_mkcertKeyID(cert); /* get them all! */ @@ -995,10 +1032,18 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { + /* + * prevent a login race condition. If le->slot is logged in between + * our call to pk11_LoginStillRequired and the + * pk11_FindPrivateKeyFromCertID, the find will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + PRBool needLogin = pk11_LoginStillRequired(le->slot,wincx); key = pk11_FindPrivateKeyFromCertID(le->slot,keyID); - if ((key == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(le->slot,wincx)) { + if ((key == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* authenticate and try again */ rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; @@ -1084,7 +1129,6 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr, /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1159,7 +1203,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot, if (!instance) { goto loser; } - object = nssPKIObject_Create(NULL, instance, td, NULL); + object = nssPKIObject_Create(NULL, instance, td, NULL, nssPKIMonitor); if (!object) { goto loser; } @@ -1248,7 +1292,6 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1319,7 +1362,6 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr, /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1553,16 +1595,26 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx) CK_OBJECT_HANDLE keyHandle; PK11SlotInfo *slot = NULL; SECKEYPrivateKey *privKey = NULL; + PRBool needLogin; SECStatus rv; + int err; certHandle = PK11_FindObjectForCert(cert, wincx, &slot); if (certHandle == CK_INVALID_HANDLE) { return NULL; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * PK11_MatchItem. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY); - if ((keyHandle == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot,wincx)) { + if ((keyHandle == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err ) ) { /* authenticate and try again */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv == SECSuccess) { @@ -1947,6 +1999,8 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, SECItem *keyID; CK_OBJECT_HANDLE key; SECStatus rv; + PRBool needLogin; + int err; if((slot == NULL) || (cert == NULL)) { return CK_INVALID_HANDLE; @@ -1957,10 +2011,18 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, return CK_INVALID_HANDLE; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * pk11_FindPrivateKeyFromCerID. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); key = pk11_FindPrivateKeyFromCertID(slot, keyID); - if ((key == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot,wincx)) { + if ((key == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* authenticate and try again */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) goto loser; @@ -2284,7 +2346,7 @@ PK11_ListCerts(PK11CertListType type, void *pwarg) listCerts.certList = certList; /* authenticate to the slots */ - (void) pk11_TraverseAllSlots( NULL, NULL, pwarg); + (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, pwarg); NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback, &listCerts); return certList; @@ -2348,6 +2410,9 @@ listCertsCallback(CERTCertificate* cert, void*arg) NSSCertificate *c = STAN_GetNSSCertificate(cert); instances = nssPKIObject_GetInstances(&c->object); + if (!instances) { + return SECFailure; + } instance = NULL; for (ci = instances; *ci; ci++) { if ((*ci)->token->pk11slot == cdata->slot) { diff --git a/security/nss/lib/pk11wrap/pk11cxt.c b/security/nss/lib/pk11wrap/pk11cxt.c index 4428fda9b..d4ce2b68d 100644 --- a/security/nss/lib/pk11wrap/pk11cxt.c +++ b/security/nss/lib/pk11wrap/pk11cxt.c @@ -249,7 +249,7 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type, SECStatus rv; PORT_Assert(slot != NULL); - if (!slot) { + if (!slot || (!symKey && operation != CKA_DIGEST)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } @@ -325,15 +325,15 @@ __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, SECItem *param, void *wincx) { - PK11SymKey *symKey; - PK11Context *context; + PK11SymKey *symKey = NULL; + PK11Context *context = NULL; /* first get a slot */ if (slot == NULL) { slot = PK11_GetBestSlot(type,wincx); if (slot == NULL) { PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; + goto loser; } } else { PK11_ReferenceSlot(slot); @@ -341,12 +341,17 @@ __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, /* now import the key */ symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx); - if (symKey == NULL) return NULL; + if (symKey == NULL) goto loser; context = PK11_CreateContextBySymKey(type, operation, symKey, param); - PK11_FreeSymKey(symKey); - PK11_FreeSlot(slot); +loser: + if (symKey) { + PK11_FreeSymKey(symKey); + } + if (slot) { + PK11_FreeSlot(slot); + } return context; } diff --git a/security/nss/lib/pk11wrap/pk11err.c b/security/nss/lib/pk11wrap/pk11err.c index a63475636..588d6512c 100644 --- a/security/nss/lib/pk11wrap/pk11err.c +++ b/security/nss/lib/pk11wrap/pk11err.c @@ -113,7 +113,7 @@ PK11_MapError(CK_RV rv) { MAPERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY) MAPERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY) MAPERROR(CKR_USER_ALREADY_LOGGED_IN, 0) - MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_LIBRARY_FAILURE) /* XXXX */ + MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_TOKEN_NOT_LOGGED_IN) MAPERROR(CKR_USER_PIN_NOT_INITIALIZED, SEC_ERROR_NO_TOKEN) MAPERROR(CKR_USER_TYPE_INVALID, SEC_ERROR_LIBRARY_FAILURE) MAPERROR(CKR_WRAPPED_KEY_INVALID, SEC_ERROR_INVALID_KEY) diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c index a0db40729..7664d8071 100644 --- a/security/nss/lib/pk11wrap/pk11kea.c +++ b/security/nss/lib/pk11wrap/pk11kea.c @@ -152,82 +152,6 @@ rsa_failed: return newSymKey; } - /* KEA */ - if (PK11_DoesMechanism(symKey->slot, CKM_KEA_KEY_DERIVE) && - PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) { - CERTCertificate *certSource = NULL; - CERTCertificate *certTarget = NULL; - SECKEYPublicKey *pubKeySource = NULL; - SECKEYPublicKey *pubKeyTarget = NULL; - SECKEYPrivateKey *privKeySource = NULL; - SECKEYPrivateKey *privKeyTarget = NULL; - PK11SymKey *tekSource = NULL; - PK11SymKey *tekTarget = NULL; - SECItem Ra,wrap; - - /* can only exchange skipjack keys */ - if ((type != CKM_SKIPJACK_CBC64) || (isPerm)) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - /* find a pair of certs we can use */ - rv = PK11_GetKEAMatchedCerts(symKey->slot,slot,&certSource,&certTarget); - if (rv != SECSuccess) goto kea_failed; - - /* get all the key pairs */ - pubKeyTarget = CERT_ExtractPublicKey(certSource); - pubKeySource = CERT_ExtractPublicKey(certTarget); - privKeySource = - PK11_FindKeyByDERCert(symKey->slot,certSource,symKey->cx); - privKeyTarget = - PK11_FindKeyByDERCert(slot,certTarget,symKey->cx); - - if ((pubKeySource == NULL) || (pubKeyTarget == NULL) || - (privKeySource == NULL) || (privKeyTarget == NULL)) goto kea_failed; - - /* generate the wrapping TEK's */ - Ra.data = (unsigned char*)PORT_Alloc(128 /* FORTEZZA RA MAGIC */); - Ra.len = 128; - if (Ra.data == NULL) goto kea_failed; - - tekSource = PK11_PubDerive(privKeySource,pubKeyTarget,PR_TRUE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - tekTarget = PK11_PubDerive(privKeyTarget,pubKeySource,PR_FALSE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - PORT_Free(Ra.data); - - if ((tekSource == NULL) || (tekTarget == NULL)) { goto kea_failed; } - - /* wrap the key out of Source into target */ - wrap.data = (unsigned char*)PORT_Alloc(12); /* MAGIC SKIPJACK LEN */ - wrap.len = 12; - - /* paranoia to prevent infinite recursion on bugs */ - PORT_Assert(tekSource->slot == symKey->slot); - if (tekSource->slot != symKey->slot) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap); - if (rv == SECSuccess) { - newSymKey = PK11_UnwrapSymKeyWithFlags(tekTarget, - CKM_SKIPJACK_WRAP, NULL, - &wrap, type, operation, flags, symKey->size); - } - PORT_Free(wrap.data); -kea_failed: - if (certSource == NULL) CERT_DestroyCertificate(certSource); - if (certTarget == NULL) CERT_DestroyCertificate(certTarget); - if (pubKeySource == NULL) SECKEY_DestroyPublicKey(pubKeySource); - if (pubKeyTarget == NULL) SECKEY_DestroyPublicKey(pubKeyTarget); - if (privKeySource == NULL) SECKEY_DestroyPrivateKey(privKeySource); - if (privKeyTarget == NULL) SECKEY_DestroyPrivateKey(privKeyTarget); - if (tekSource == NULL) PK11_FreeSymKey(tekSource); - if (tekTarget == NULL) PK11_FreeSymKey(tekTarget); - return newSymKey; - } PORT_SetError( SEC_ERROR_NO_MODULE ); return NULL; } diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c index 1f8f2a372..fe106de50 100644 --- a/security/nss/lib/pk11wrap/pk11mech.c +++ b/security/nss/lib/pk11wrap/pk11mech.c @@ -823,7 +823,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) rc5_cbc_params = (CK_RC5_CBC_PARAMS *) PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0)); if (rc5_cbc_params == NULL) break; - if (iv && iv->data) { + if (iv && iv->data && iv->len) { rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS); PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len); @@ -832,7 +832,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) } else { rc5_cbc_params->ulWordsize = 4; rc5_cbc_params->pIv = NULL; - rc5_cbc_params->ulIvLen = iv->len; + rc5_cbc_params->ulIvLen = 0; } rc5_cbc_params->ulRounds = 16; param->data = (unsigned char *) rc5_cbc_params; diff --git a/security/nss/lib/pk11wrap/pk11nobj.c b/security/nss/lib/pk11wrap/pk11nobj.c index db9aa6ba9..3a88ef4ae 100644 --- a/security/nss/lib/pk11wrap/pk11nobj.c +++ b/security/nss/lib/pk11wrap/pk11nobj.c @@ -270,7 +270,7 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) { creater.findTemplate = theTemplate; creater.templateCount = (attrs - theTemplate); - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); + return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx); } struct crlOptionsStr { @@ -421,7 +421,7 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, creater.findTemplate = theTemplate; creater.templateCount = (attrs - theTemplate); - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); + return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx); } /* @@ -429,12 +429,15 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, */ SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, - SECItem *name, int type, char **url) + SECItem *name, int type, char **pUrl) { - NSSCRL **crls, **crlp, *crl; + NSSCRL **crls, **crlp, *crl = NULL; NSSDER subject; SECItem *rvItem; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); + char * url = NULL; + + PORT_SetError(0); NSSITEM_FROM_SECITEM(&subject, name); if (*slot) { nssCryptokiObject **instances; @@ -443,7 +446,7 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, NSSToken *token = PK11Slot_GetNSSToken(*slot); collection = nssCRLCollection_Create(td, NULL); if (!collection) { - return NULL; + goto loser; } instances = nssToken_FindCRLsBySubject(token, NULL, &subject, tokenOnly, 0, NULL); @@ -461,9 +464,8 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, if (NSS_GetError() == NSS_ERROR_NOT_FOUND) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } - return NULL; + goto loser; } - crl = NULL; for (crlp = crls; *crlp; crlp++) { if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) || ((*crlp)->isKRL && type != SEC_CRL_TYPE)) @@ -477,28 +479,34 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, /* CRL collection was found, but no interesting CRL's were on it. * Not an error */ PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); - return NULL; + goto loser; } if (crl->url) { - *url = PORT_Strdup(crl->url); - if (!*url) { - nssCRL_Destroy(crl); - return NULL; + url = PORT_Strdup(crl->url); + if (!url) { + goto loser; } - } else { - *url = NULL; } rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size); if (!rvItem) { - PORT_Free(*url); - nssCRL_Destroy(crl); - return NULL; + goto loser; } memcpy(rvItem->data, crl->encoding.data, crl->encoding.size); *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot); *crlHandle = crl->object.instances[0]->handle; + *pUrl = url; nssCRL_Destroy(crl); return rvItem; + +loser: + if (url) + PORT_Free(url); + if (crl) + nssCRL_Destroy(crl); + if (PORT_GetError() == 0) { + PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); + } + return NULL; } CK_OBJECT_HANDLE diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c index 65b47ef96..91a28321e 100644 --- a/security/nss/lib/pk11wrap/pk11obj.c +++ b/security/nss/lib/pk11wrap/pk11obj.c @@ -571,11 +571,14 @@ PK11_SignatureLen(SECKEYPrivateKey *key) if (theTemplate.pValue != NULL) { params.len = theTemplate.ulValueLen; params.data = (unsigned char *) theTemplate.pValue; - length = SECKEY_ECParamsToKeySize(¶ms); + length = SECKEY_ECParamsToBasePointOrderLen(¶ms); PORT_Free(theTemplate.pValue); + if (length == 0) { + return pk11_backupGetSignLength(key); + } + length = ((length + 7)/8) * 2; + return length; } - length = ((length + 7)/8) * 2; - return length; } break; default: @@ -948,7 +951,9 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, sizeof(cktrue)); attrs++; PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; + if (label && label->data) { + PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; + } PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); attrs++; for (i=0; i < usageCount; i++) { PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); attrs++; @@ -1568,8 +1573,8 @@ PK11_TraverseSlot(PK11SlotInfo *slot, void *arg) * Traverse all the objects in all slots. */ SECStatus -pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *arg,void *wincx) { +pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), + void *arg, PRBool forceLogin, void *wincx) { PK11SlotList *list; PK11SlotListElement *le; SECStatus rv; @@ -1580,9 +1585,11 @@ pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), /* look at each slot and authenticate as necessary */ for (le = list->head ; le; le = le->next) { - rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); - if (rv != SECSuccess) { - continue; + if (forceLogin) { + rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); + if (rv != SECSuccess) { + continue; + } } if (callback) { (*callback)(le->slot,arg); diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c index 1234af856..07ac7dff4 100644 --- a/security/nss/lib/pk11wrap/pk11pbe.c +++ b/security/nss/lib/pk11wrap/pk11pbe.c @@ -704,10 +704,10 @@ pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) { if (pbe_params) { if (pbe_params->pPassword) - PORT_ZFree(pbe_params->pPassword, PR_FALSE); + PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen); if (pbe_params->pSalt) - PORT_ZFree(pbe_params->pSalt, PR_FALSE); - PORT_ZFree(pbe_params, PR_TRUE); + PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen); + PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS)); } } @@ -716,30 +716,49 @@ PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations) { CK_PBE_PARAMS *pbe_params = NULL; SECItem *paramRV = NULL; - pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)); + + paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); + if (!paramRV ) { + goto loser; + } + /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */ + PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS)); + + pbe_params = (CK_PBE_PARAMS *)paramRV->data; pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); - if (pbe_params->pPassword != NULL) { - PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); - pbe_params->ulPasswordLen = pwd->len; - } else goto loser; + if (!pbe_params->pPassword) { + goto loser; + } + PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); + pbe_params->ulPasswordLen = pwd->len; + pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); - if (pbe_params->pSalt != NULL) { - PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); - pbe_params->ulSaltLen = salt->len; - } else goto loser; + if (!pbe_params->pSalt) { + goto loser; + } + PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); + pbe_params->ulSaltLen = salt->len; + pbe_params->ulIteration = (CK_ULONG)iterations; - paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); - paramRV->data = (unsigned char *)pbe_params; return paramRV; + loser: - pk11_destroy_ck_pbe_params(pbe_params); + if (pbe_params) + pk11_destroy_ck_pbe_params(pbe_params); + if (paramRV) + PORT_ZFree(paramRV, sizeof(SECItem)); return NULL; } void -PK11_DestroyPBEParams(SECItem *params) +PK11_DestroyPBEParams(SECItem *pItem) { - pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data); + if (pItem) { + CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data); + if (params) + pk11_destroy_ck_pbe_params(params); + PORT_ZFree(pItem, sizeof(SECItem)); + } } SECAlgorithmID * @@ -766,6 +785,9 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, } pbe_params = (CK_PBE_PARAMS *)mech->data; + if (!pbe_params) { + return NULL; + } pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwitem->len); if(pbe_params->pPassword != NULL) { PORT_Memcpy(pbe_params->pPassword, pwitem->data, pwitem->len); @@ -775,7 +797,8 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, return NULL; } - symKey = PK11_KeyGen(slot, type, mech, 0, wincx); + symKey = PK11_TokenKeyGenWithFlags(slot, type, mech, 0, NULL, + CKF_SIGN|CKF_ENCRYPT|CKF_DECRYPT|CKF_UNWRAP|CKF_WRAP, 0, wincx); PORT_ZFree(pbe_params->pPassword, pwitem->len); pbe_params->pPassword = NULL; diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c index 35a4cbc07..9c8afdf4e 100644 --- a/security/nss/lib/pk11wrap/pk11pk12.c +++ b/security/nss/lib/pk11wrap/pk11pk12.c @@ -250,7 +250,13 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, SECStatus rv = SECFailure; temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!temparena) + return rv; pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo); + if (!pki) { + PORT_FreeArena(temparena, PR_FALSE); + return rv; + } pki->arena = temparena; rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate, @@ -263,10 +269,8 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, publicValue, isPerm, isPrivate, keyUsage, privk, wincx); finish: - if( pki != NULL ) { - /* this zeroes the key and frees the arena */ - SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); - } + /* this zeroes the key and frees the arena */ + SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); return rv; } diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c index 62afc7756..711818639 100644 --- a/security/nss/lib/pk11wrap/pk11pqg.c +++ b/security/nss/lib/pk11wrap/pk11pqg.c @@ -119,6 +119,10 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, } parena = PORT_NewArena(60); + if (!parena) { + goto loser; + } + crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount); if (crv != CKR_OK) { PORT_SetError( PK11_MapError(crv) ); @@ -145,6 +149,10 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, varena = PORT_NewArena(60); + if (!varena) { + goto loser; + } + crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount); if (crv != CKR_OK) { PORT_SetError( PK11_MapError(crv) ); diff --git a/security/nss/lib/pk11wrap/pk11priv.h b/security/nss/lib/pk11wrap/pk11priv.h index 6d0b012b0..feef1959a 100644 --- a/security/nss/lib/pk11wrap/pk11priv.h +++ b/security/nss/lib/pk11wrap/pk11priv.h @@ -207,7 +207,7 @@ SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, /* private */ SECStatus pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *cbArg, void *pwArg); + void *cbArg, PRBool forceLogin, void *pwArg); /* fetch multiple CRLs for a specific issuer */ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h index 8a933cc93..4c674d48e 100644 --- a/security/nss/lib/pk11wrap/pk11pub.h +++ b/security/nss/lib/pk11wrap/pk11pub.h @@ -582,6 +582,14 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, /********************************************************************** * Sign/Verify **********************************************************************/ + +/* + * Return the length in bytes of a signature generated with the + * private key. + * + * Return 0 or -1 on failure. (XXX Should we fix it to always return + * -1 on failure?) + */ int PK11_SignatureLen(SECKEYPrivateKey *key); PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key); SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, SECItem *hash); diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index ce5cbd811..f7cb05411 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -929,6 +929,13 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, count = attrs - genTemplate; PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); + /* Initialize the Key Gen Mechanism */ + mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); + if (mechanism.mechanism == CKM_FAKE_RANDOM) { + PORT_SetError( SEC_ERROR_NO_MODULE ); + return NULL; + } + /* find a slot to generate the key into */ /* Only do slot management if this is not a token key */ if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) { @@ -951,13 +958,6 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, symKey->size = keySize; symKey->origin = PK11_OriginGenerated; - /* Initialize the Key Gen Mechanism */ - mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); - if (mechanism.mechanism == CKM_FAKE_RANDOM) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - /* Set the parameters for the key gen if provided */ mechanism.pParameter = NULL; mechanism.ulParameterLen = 0; @@ -1646,17 +1646,35 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, return NULL; } -PK11SymKey * -PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, - PRBool isSender, SECItem *randomA, SECItem *randomB, - CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize, - CK_ULONG kdf, SECItem *sharedData, void *wincx) +static PK11SymKey * +pk11_PubDeriveECKeyWithKDF( + SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, + PRBool isSender, SECItem *randomA, SECItem *randomB, + CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, + CK_ULONG kdf, SECItem *sharedData, void *wincx) { - PK11SlotInfo *slot = privKey->pkcs11Slot; - PK11SymKey *symKey; - CK_MECHANISM mechanism; - CK_RV crv; + PK11SlotInfo *slot = privKey->pkcs11Slot; + PK11SymKey *symKey; + CK_MECHANISM mechanism; + CK_RV crv; + CK_BBOOL cktrue = CK_TRUE; + CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; + CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; + CK_ULONG key_size = 0; + CK_ATTRIBUTE keyTemplate[4]; + int templateCount; + CK_ATTRIBUTE *attrs = keyTemplate; + CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; + + if (pubKey->keyType != ecKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return NULL; + } + if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } /* get our key Structure */ symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); @@ -1666,6 +1684,62 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, symKey->origin = PK11_OriginDerive; + PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; + PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; + PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; + PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++; + templateCount = attrs - keyTemplate; + PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); + + keyType = PK11_GetKeyType(target,keySize); + key_size = keySize; + symKey->size = keySize; + if (key_size == 0) + templateCount--; + + mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); + if (!mechParams) { + PK11_FreeSymKey(symKey); + return NULL; + } + mechParams->kdf = kdf; + if (sharedData == NULL) { + mechParams->ulSharedDataLen = 0; + mechParams->pSharedData = NULL; + } else { + mechParams->ulSharedDataLen = sharedData->len; + mechParams->pSharedData = sharedData->data; + } + mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; + mechParams->pPublicData = pubKey->u.ec.publicValue.data; + + mechanism.mechanism = derive; + mechanism.pParameter = mechParams; + mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); + + pk11_EnterKeyMonitor(symKey); + crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, + privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); + pk11_ExitKeyMonitor(symKey); + + PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); + + if (crv != CKR_OK) { + PK11_FreeSymKey(symKey); + symKey = NULL; + PORT_SetError( PK11_MapError(crv) ); + } + return symKey; +} + +PK11SymKey * +PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, + PRBool isSender, SECItem *randomA, SECItem *randomB, + CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, + CK_ULONG kdf, SECItem *sharedData, void *wincx) +{ + switch (privKey->keyType) { case rsaKey: case nullKey: @@ -1673,75 +1747,16 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, case keaKey: case fortezzaKey: case dhKey: - PK11_FreeSymKey(symKey); return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB, derive, target, operation, keySize, wincx); case ecKey: - { - CK_BBOOL cktrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_ULONG key_size = 0; - CK_ATTRIBUTE keyTemplate[4]; - int templateCount; - CK_ATTRIBUTE *attrs = keyTemplate; - CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; - - if (pubKey->keyType != ecKey) { - PORT_SetError(SEC_ERROR_BAD_KEY); - break; - } - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); - attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); - attrs++; - PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); - attrs++; - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - keyType = PK11_GetKeyType(target,keySize); - key_size = keySize; - symKey->size = keySize; - if (key_size == 0) templateCount--; - - mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); - if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - break; - } - mechParams->kdf = kdf; - if (sharedData == NULL) { - mechParams->ulSharedDataLen = 0; - mechParams->pSharedData = NULL; - } else { - mechParams->ulSharedDataLen = sharedData->len; - mechParams->pSharedData = sharedData->data; - } - mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; - mechParams->pPublicData = pubKey->u.ec.publicValue.data; - - mechanism.mechanism = derive; - mechanism.pParameter = mechParams; - mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); - - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, - &mechanism, privKey->pkcs11ID, keyTemplate, - templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - - PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); - - if (crv == CKR_OK) return symKey; - PORT_SetError( PK11_MapError(crv) ); - } - } + return pk11_PubDeriveECKeyWithKDF( privKey, pubKey, isSender, + randomA, randomB, derive, target, operation, keySize, + kdf, sharedData, wincx); + default: break; + } - PK11_FreeSymKey(symKey); - return NULL; + return NULL; } /* diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index a92fbf7df..94d4ffaba 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -354,7 +354,7 @@ PK11_NewSlotInfo(SECMODModule *mod) PZ_NewLock(nssILockSession) : mod->refLock; if (slot->sessionLock == NULL) { PORT_Free(slot); - return slot; + return NULL; } slot->freeListLock = PZ_NewLock(nssILockFreelist); if (slot->freeListLock == NULL) { @@ -362,7 +362,7 @@ PK11_NewSlotInfo(SECMODModule *mod) PZ_DestroyLock(slot->sessionLock); } PORT_Free(slot); - return slot; + return NULL; } slot->freeSymKeysWithSessionHead = NULL; slot->freeSymKeysHead = NULL; diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h index 83545f5e3..68ac59f27 100644 --- a/security/nss/lib/pk11wrap/secmod.h +++ b/security/nss/lib/pk11wrap/secmod.h @@ -55,6 +55,9 @@ #define PUBLIC_MECH_MD2_FLAG 0x00000400ul #define PUBLIC_MECH_SSL_FLAG 0x00000800ul #define PUBLIC_MECH_TLS_FLAG 0x00001000ul +#define PUBLIC_MECH_AES_FLAG 0x00002000ul +#define PUBLIC_MECH_SHA256_FLAG 0x00004000ul +#define PUBLIC_MECH_SHA512_FLAG 0x00008000ul #define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul #define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul @@ -62,7 +65,7 @@ #define PUBLIC_DISABLE_FLAG 0x40000000ul /* warning: reserved means reserved */ -#define PUBLIC_MECH_RESERVED_FLAGS 0x87FFE000ul +#define PUBLIC_MECH_RESERVED_FLAGS 0x87FF0000ul /* These cipher flags are visible to all other libraries, */ /* But they must be converted before used in functions */ |