summaryrefslogtreecommitdiff
path: root/security/nss/lib/pk11wrap
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/pk11wrap')
-rw-r--r--security/nss/lib/pk11wrap/Makefile4
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c134
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c109
-rw-r--r--security/nss/lib/pk11wrap/pk11cxt.c19
-rw-r--r--security/nss/lib/pk11wrap/pk11err.c2
-rw-r--r--security/nss/lib/pk11wrap/pk11kea.c76
-rw-r--r--security/nss/lib/pk11wrap/pk11mech.c4
-rw-r--r--security/nss/lib/pk11wrap/pk11nobj.c42
-rw-r--r--security/nss/lib/pk11wrap/pk11obj.c25
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c59
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c12
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.c8
-rw-r--r--security/nss/lib/pk11wrap/pk11priv.h2
-rw-r--r--security/nss/lib/pk11wrap/pk11pub.h8
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c179
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c4
-rw-r--r--security/nss/lib/pk11wrap/secmod.h5
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(&params);
+ length = SECKEY_ECParamsToBasePointOrderLen(&params);
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 */