diff --git a/lib/softoken/sftkpwd.c b/lib/softoken/sftkpwd.c --- a/lib/softoken/sftkpwd.c +++ b/lib/softoken/sftkpwd.c @@ -277,17 +277,19 @@ sftkdb_DecryptAttribute(SFTKDBHandle *ha *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value, PR_FALSE, NULL); if (*plain == NULL) { rv = SECFailure; goto loser; } /* If we are using aes 256, we need to check authentication as well.*/ - if ((type != CKT_INVALID_TYPE) && (cipherValue.alg == SEC_OID_AES_256_CBC)) { + if ((type != CKT_INVALID_TYPE) && + (cipherValue.alg == SEC_OID_PKCS5_PBES2) && + (cipherValue.param->encAlg == SEC_OID_AES_256_CBC)) { SECItem signature; unsigned char signData[SDB_MAX_META_DATA_LEN]; /* if we get here from the old legacy db, there is clearly an * error, don't return the plaintext */ if (handle == NULL) { rv = SECFailure; PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -299,17 +301,27 @@ sftkdb_DecryptAttribute(SFTKDBHandle *ha rv = sftkdb_GetAttributeSignature(handle, handle, id, type, &signature); if (rv != SECSuccess) { goto loser; } rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE, type, *plain, &signature); if (rv != SECSuccess) { - goto loser; + /* handle a bug where old versions of NSS misfiled the signature + * attribute on password update */ + id |= SFTK_KEYDB_TYPE|SFTK_TOKEN_TYPE; + signature.len = sizeof(signData); + rv = sftkdb_GetAttributeSignature(handle, handle, id, type, + &signature); + if (rv != SECSuccess) { + goto loser; + } + rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE, + type, *plain, &signature); } } loser: if (cipherValue.param) { nsspkcs5_DestroyPBEParameter(cipherValue.param); } if (cipherValue.arena) { @@ -1186,16 +1198,17 @@ sftk_updateEncrypted(PLArenaPool *arena, }; const CK_ULONG privAttrCount = sizeof(privAttrTypes) / sizeof(privAttrTypes[0]); // We don't know what attributes this object has, so we update them one at a // time. unsigned int i; for (i = 0; i < privAttrCount; i++) { // Read the old attribute in the clear. + CK_OBJECT_HANDLE sdbId = id & SFTK_OBJ_ID_MASK; CK_ATTRIBUTE privAttr = { privAttrTypes[i], NULL, 0 }; CK_RV crv = sftkdb_GetAttributeValue(keydb, id, &privAttr, 1); if (crv != CKR_OK) { continue; } if ((privAttr.ulValueLen == -1) || (privAttr.ulValueLen == 0)) { continue; } @@ -1210,30 +1223,29 @@ sftk_updateEncrypted(PLArenaPool *arena, if ((privAttr.ulValueLen == -1) || (privAttr.ulValueLen == 0)) { return CKR_GENERAL_ERROR; } SECItem plainText; SECItem *result; plainText.data = privAttr.pValue; plainText.len = privAttr.ulValueLen; if (sftkdb_EncryptAttribute(arena, keydb, keydb->db, newKey, - iterationCount, id, privAttr.type, + iterationCount, sdbId, privAttr.type, &plainText, &result) != SECSuccess) { return CKR_GENERAL_ERROR; } privAttr.pValue = result->data; privAttr.ulValueLen = result->len; // Clear sensitive data. PORT_Memset(plainText.data, 0, plainText.len); // Write the newly encrypted attributes out directly. - CK_OBJECT_HANDLE newId = id & SFTK_OBJ_ID_MASK; keydb->newKey = newKey; keydb->newDefaultIterationCount = iterationCount; - crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, newId, &privAttr, 1); + crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, sdbId, &privAttr, 1); keydb->newKey = NULL; if (crv != CKR_OK) { return crv; } } return CKR_OK; }