| Index: nss/mozilla/security/nss/lib/softoken/sftkdb.c
|
| ===================================================================
|
| --- nss/mozilla/security/nss/lib/softoken/sftkdb.c (revision 55475)
|
| +++ nss/mozilla/security/nss/lib/softoken/sftkdb.c (working copy)
|
| @@ -509,18 +509,23 @@
|
| CK_ULONG count)
|
| {
|
| int i;
|
| + CK_RV crv;
|
| SFTKDBHandle *keyHandle = handle;
|
| SDB *keyTarget = NULL;
|
| + PRBool usingPeerDB = PR_FALSE;
|
| + PRBool inPeerDBTransaction = PR_FALSE;
|
|
|
| PORT_Assert(handle);
|
|
|
| if (handle->type != SFTK_KEYDB_TYPE) {
|
| keyHandle = handle->peerDB;
|
| + usingPeerDB = PR_TRUE;
|
| }
|
|
|
| /* no key DB defined? then no need to sign anything */
|
| if (keyHandle == NULL) {
|
| - return CKR_OK;
|
| + crv = CKR_OK;
|
| + goto loser;
|
| }
|
|
|
| /* When we are in a middle of an update, we have an update database set,
|
| @@ -532,9 +537,19 @@
|
|
|
| /* skip the the database does not support meta data */
|
| if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) {
|
| - return CKR_OK;
|
| + crv = CKR_OK;
|
| + goto loser;
|
| }
|
|
|
| + /* If we had to switch databases, we need to initialize a transaction. */
|
| + if (usingPeerDB) {
|
| + crv = (*keyTarget->sdb_Begin)(keyTarget);
|
| + if (crv != CKR_OK) {
|
| + goto loser;
|
| + }
|
| + inPeerDBTransaction = PR_TRUE;
|
| + }
|
| +
|
| for (i=0; i < count; i ++) {
|
| if (sftkdb_isAuthenticatedAttribute(template[i].type)) {
|
| SECStatus rv;
|
| @@ -546,23 +561,44 @@
|
| PZ_Lock(keyHandle->passwordLock);
|
| if (keyHandle->passwordKey.data == NULL) {
|
| PZ_Unlock(keyHandle->passwordLock);
|
| - return CKR_USER_NOT_LOGGED_IN;
|
| + crv = CKR_USER_NOT_LOGGED_IN;
|
| + goto loser;
|
| }
|
| rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey,
|
| objectID, template[i].type,
|
| &plainText, &signText);
|
| PZ_Unlock(keyHandle->passwordLock);
|
| if (rv != SECSuccess) {
|
| - return CKR_GENERAL_ERROR; /* better error code here? */
|
| + crv = CKR_GENERAL_ERROR; /* better error code here? */
|
| + goto loser;
|
| }
|
| rv = sftkdb_PutAttributeSignature(handle, keyTarget,
|
| objectID, template[i].type, signText);
|
| if (rv != SECSuccess) {
|
| - return CKR_GENERAL_ERROR; /* better error code here? */
|
| + crv = CKR_GENERAL_ERROR; /* better error code here? */
|
| + goto loser;
|
| }
|
| }
|
| }
|
| - return CKR_OK;
|
| + crv = CKR_OK;
|
| +
|
| + /* If necessary, commit the transaction */
|
| + if (inPeerDBTransaction) {
|
| + crv = (*keyTarget->sdb_Commit)(keyTarget);
|
| + if (crv != CKR_OK) {
|
| + goto loser;
|
| + }
|
| + inPeerDBTransaction = PR_FALSE;
|
| + }
|
| +
|
| +loser:
|
| + if (inPeerDBTransaction) {
|
| + /* The transaction must have failed. Abort. */
|
| + (*keyTarget->sdb_Abort)(keyTarget);
|
| + PORT_Assert(crv != CKR_OK);
|
| + if (crv == CKR_OK) crv = CKR_GENERAL_ERROR;
|
| + }
|
| + return crv;
|
| }
|
|
|
| static CK_RV
|
| @@ -766,6 +802,12 @@
|
| if (attr == NULL) {
|
| return CKR_TEMPLATE_INCOMPLETE;
|
| }
|
| + if (attr->ulValueLen == 0) {
|
| + /* key is too generic to determine that it's unique, usually
|
| + * happens in the key gen case */
|
| + return CKR_OBJECT_HANDLE_INVALID;
|
| + }
|
| +
|
| findTemplate[1] = *attr;
|
| count = 2;
|
| break;
|
| @@ -807,7 +849,7 @@
|
| }
|
|
|
| /*
|
| - * look to see if this object already exists and return it's object ID if
|
| + * look to see if this object already exists and return its object ID if
|
| * it does.
|
| */
|
| static CK_RV
|
| @@ -827,6 +869,13 @@
|
| }
|
| crv = sftkdb_getFindTemplate(objectType, objTypeData,
|
| findTemplate, &count, ptemplate, len);
|
| +
|
| + if (crv == CKR_OBJECT_HANDLE_INVALID) {
|
| + /* key is too generic to determine that it's unique, usually
|
| + * happens in the key gen case, tell the caller to go ahead
|
| + * and just create it */
|
| + return CKR_OK;
|
| + }
|
| if (crv != CKR_OK) {
|
| return crv;
|
| }
|
|
|