From fbc2eaacd679f0c484993ffe23d786fd06da22c3 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 26 Jun 2019 15:13:18 +0200 Subject: Update NSS to 3.41.1 (custom) This resolves #82 --- old-configure.in | 3 +- security/nss/lib/nss/nss.h | 4 +- security/nss/lib/softoken/legacydb/keydb.c | 33 ++++- security/nss/lib/softoken/lgglue.c | 12 +- security/nss/lib/softoken/pkcs11.c | 4 +- security/nss/lib/softoken/sftkdb.c | 4 +- security/nss/lib/softoken/sftkdb.h | 1 + security/nss/lib/softoken/sftkdbti.h | 7 +- security/nss/lib/softoken/sftkpwd.c | 193 ++++++++++++++++++++++++----- 9 files changed, 215 insertions(+), 46 deletions(-) diff --git a/old-configure.in b/old-configure.in index 6a7bc701f..1ee90b4cf 100644 --- a/old-configure.in +++ b/old-configure.in @@ -2045,7 +2045,8 @@ MOZ_ARG_WITH_BOOL(system-nss, _USE_SYSTEM_NSS=1 ) if test -n "$_USE_SYSTEM_NSS"; then - AM_PATH_NSS(3.41, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) + AC_MSG_ERROR([Building with system-nss is currently not supported]) +dnl AM_PATH_NSS(3.41.1, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) fi if test -z "$MOZ_SYSTEM_NSS"; then diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 49c545ecc..0a235941f 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -22,10 +22,10 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.41" _NSS_CUSTOMIZED +#define NSS_VERSION "3.41.1" _NSS_CUSTOMIZED #define NSS_VMAJOR 3 #define NSS_VMINOR 41 -#define NSS_VPATCH 0 +#define NSS_VPATCH 1 #define NSS_VBUILD 0 #define NSS_BETA PR_FALSE diff --git a/security/nss/lib/softoken/legacydb/keydb.c b/security/nss/lib/softoken/legacydb/keydb.c index b4aa7754b..c8c4d07ba 100644 --- a/security/nss/lib/softoken/legacydb/keydb.c +++ b/security/nss/lib/softoken/legacydb/keydb.c @@ -1213,6 +1213,8 @@ nsslowkey_EncodePW(SECOidTag alg, const SECItem *salt, SECItem *data) unsigned char one = 1; SECItem *epw = NULL; SECItem *encParam; + int iterLen = 0; + int saltLen; SECStatus rv; param.salt = *salt; @@ -1221,6 +1223,17 @@ nsslowkey_EncodePW(SECOidTag alg, const SECItem *salt, SECItem *data) param.iter.len = 1; edi.encryptedData = *data; + iterLen = salt->len > 1 ? salt->data[salt->len - 1] : 2; + saltLen = (salt->len - iterLen) - 1; + /* if the resulting saltLen is a sha hash length, then assume that + * the iteration count is tacked on the end of the buffer */ + if ((saltLen == SHA1_LENGTH) || (saltLen == SHA256_LENGTH) || (saltLen == SHA384_LENGTH) || (saltLen == SHA224_LENGTH) || + (saltLen == SHA512_LENGTH)) { + param.iter.data = &salt->data[saltLen]; + param.iter.len = iterLen; + param.salt.len = saltLen; + } + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { return NULL; @@ -1270,9 +1283,23 @@ nsslowkey_DecodePW(const SECItem *derData, SECOidTag *alg, SECItem *salt) if (rv != SECSuccess) { goto loser; } - rv = SECITEM_CopyItem(NULL, salt, ¶m.salt); - if (rv != SECSuccess) { - goto loser; + /* if the iteration count isn't one, tack it at the end of the salt */ + if (!((param.iter.len == 1) && (param.iter.data[0] == 1))) { + int total_len = param.salt.len + param.iter.len + 1; + salt->data = PORT_Alloc(total_len); + if (salt->data == NULL) { + goto loser; + } + PORT_Memcpy(salt->data, param.salt.data, param.salt.len); + PORT_Memcpy(&salt->data[param.salt.len], param.iter.data, + param.iter.len); + salt->data[total_len - 1] = param.iter.len; + salt->len = total_len; + } else { + rv = SECITEM_CopyItem(NULL, salt, ¶m.salt); + if (rv != SECSuccess) { + goto loser; + } } pwe = SECITEM_DupItem(&edi.encryptedData); diff --git a/security/nss/lib/softoken/lgglue.c b/security/nss/lib/softoken/lgglue.c index 94f054129..67f17943b 100644 --- a/security/nss/lib/softoken/lgglue.c +++ b/security/nss/lib/softoken/lgglue.c @@ -171,6 +171,8 @@ sftkdb_encrypt_stub(PLArenaPool *arena, SDB *sdb, SECItem *plainText, { SFTKDBHandle *handle = sdb->app_private; SECStatus rv; + SECItem *key; + int iterationCount; if (handle == NULL) { return SECFailure; @@ -192,9 +194,15 @@ sftkdb_encrypt_stub(PLArenaPool *arena, SDB *sdb, SECItem *plainText, /* PORT_SetError */ return SECFailure; } + if (handle->newKey) { + key = handle->newKey; + iterationCount = handle->newDefaultIterationCount; + } else { + key = &handle->passwordKey; + iterationCount = handle->defaultIterationCount; + } - rv = sftkdb_EncryptAttribute(arena, - handle->newKey ? handle->newKey : &handle->passwordKey, + rv = sftkdb_EncryptAttribute(arena, key, iterationCount, plainText, cipherText); PZ_Unlock(handle->passwordLock); diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 34f25a9d0..7dd4f7ee9 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -617,7 +617,7 @@ sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb) pwenabled = PR_FALSE; if (sftkdb_HasPasswordSet(keydb) == SECSuccess) { PRBool tokenRemoved = PR_FALSE; - SECStatus rv = sftkdb_CheckPassword(keydb, "", &tokenRemoved); + SECStatus rv = sftkdb_CheckPasswordNull(keydb, &tokenRemoved); if (tokenRemoved) { sftk_CloseAllSessions(slot, PR_FALSE); } @@ -3812,7 +3812,7 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, PZ_Unlock(slot->slotLock); tokenRemoved = PR_FALSE; - rv = sftkdb_CheckPassword(handle, "", &tokenRemoved); + rv = sftkdb_CheckPasswordNull(handle, &tokenRemoved); if (tokenRemoved) { sftk_CloseAllSessions(slot, PR_FALSE); } diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c index 409c910f4..21796bbbb 100644 --- a/security/nss/lib/softoken/sftkdb.c +++ b/security/nss/lib/softoken/sftkdb.c @@ -530,6 +530,7 @@ sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle, goto loser; } rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey, + keyHandle->defaultIterationCount, objectID, template[i].type, &plainText, &signText); PZ_Unlock(keyHandle->passwordLock); @@ -663,6 +664,7 @@ sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object, break; } rv = sftkdb_EncryptAttribute(arena, &handle->passwordKey, + handle->defaultIterationCount, &plainText, &cipherText); PZ_Unlock(handle->passwordLock); if (rv == SECSuccess) { @@ -2759,7 +2761,7 @@ sftk_DBInit(const char *configdir, const char *certPrefix, (sftkdb_HasPasswordSet(*keyDB) == SECSuccess) ? PR_TRUE : PR_FALSE; /* if the password on the key db is NULL, kick off our update * chain of events */ - sftkdb_CheckPassword((*keyDB), "", &tokenRemoved); + sftkdb_CheckPasswordNull((*keyDB), &tokenRemoved); } else { /* we don't have a key DB, update the certificate DB now */ sftkdb_Update(*certDB, NULL); diff --git a/security/nss/lib/softoken/sftkdb.h b/security/nss/lib/softoken/sftkdb.h index a47c89670..e30f3a237 100644 --- a/security/nss/lib/softoken/sftkdb.h +++ b/security/nss/lib/softoken/sftkdb.h @@ -25,6 +25,7 @@ CK_RV sftkdb_closeDB(SFTKDBHandle *handle); SECStatus sftkdb_PWIsInitialized(SFTKDBHandle *keydb); SECStatus sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved); +SECStatus sftkdb_CheckPasswordNull(SFTKDBHandle *keydb, PRBool *tokenRemoved); SECStatus sftkdb_PWCached(SFTKDBHandle *keydb); SECStatus sftkdb_HasPasswordSet(SFTKDBHandle *keydb); SECStatus sftkdb_ResetKeyDB(SFTKDBHandle *keydb); diff --git a/security/nss/lib/softoken/sftkdbti.h b/security/nss/lib/softoken/sftkdbti.h index 7b1db4560..22655de56 100644 --- a/security/nss/lib/softoken/sftkdbti.h +++ b/security/nss/lib/softoken/sftkdbti.h @@ -13,7 +13,9 @@ struct SFTKDBHandleStr { PRInt32 ref; CK_OBJECT_HANDLE type; SECItem passwordKey; + int defaultIterationCount; SECItem *newKey; + int newDefaultIterationCount; SECItem *oldKey; SECItem *updatePasswordKey; PZLock *passwordLock; @@ -39,9 +41,10 @@ struct SFTKDBHandleStr { SECStatus sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plainText); SECStatus sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, - SECItem *plainText, SECItem **cipherText); + int iterationCount, SECItem *plainText, + SECItem **cipherText); SECStatus sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, - CK_OBJECT_HANDLE objectID, + int iterationCount, CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, SECItem *plainText, SECItem **sigText); SECStatus sftkdb_VerifyAttribute(SECItem *passKey, diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c index 9834d3ba0..745e724f0 100644 --- a/security/nss/lib/softoken/sftkpwd.c +++ b/security/nss/lib/softoken/sftkpwd.c @@ -34,6 +34,14 @@ #include "secerr.h" #include "softoken.h" +const int NSS_DEFAULT_ITERATION_COUNT = +#ifdef DEBUG + 1000 +#else + 60000 +#endif + ; + /****************************************************************** * * Key DB password handling functions @@ -132,7 +140,7 @@ const SEC_ASN1Template sftkdb_EncryptedDataInfoTemplate[] = { * to data in cipherText, if cipherText is freed, cipherValue will be invalid. */ static SECStatus -sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue) +sftkdb_decodeCipherText(const SECItem *cipherText, sftkCipherValue *cipherValue) { PLArenaPool *arena = NULL; SFTKDBEncryptedDataInfo edi; @@ -225,7 +233,8 @@ loser: * with SECITEM_FreeItem by the caller. */ SECStatus -sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain) +sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, + SECItem **plain) { SECStatus rv; sftkCipherValue cipherValue; @@ -261,7 +270,8 @@ loser: */ SECStatus sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, - SECItem *plainText, SECItem **cipherText) + int iterationCount, SECItem *plainText, + SECItem **cipherText) { SECStatus rv; sftkCipherValue cipherValue; @@ -275,7 +285,7 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len); param = nsspkcs5_NewParam(cipherValue.alg, HASH_AlgSHA1, &cipherValue.salt, - 1); + iterationCount); if (param == NULL) { rv = SECFailure; goto loser; @@ -413,7 +423,8 @@ loser: */ SECStatus sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, + int iterationCount, CK_OBJECT_HANDLE objectID, + CK_ATTRIBUTE_TYPE attrType, SECItem *plainText, SECItem **signature) { SECStatus rv; @@ -446,7 +457,8 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, RNG_GenerateGlobalRandomBytes(saltData, prfLength); /* initialize our pkcs5 parameter */ - param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 1); + param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, + iterationCount); if (param == NULL) { rv = SECFailure; goto loser; @@ -491,7 +503,7 @@ loser: * and sftkdb_DecryptAttribute calls. */ static void -sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey) +sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey, int iterationCount) { unsigned char *data; int len; @@ -507,6 +519,7 @@ sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey) len = keydb->passwordKey.len; keydb->passwordKey.data = passKey->data; keydb->passwordKey.len = passKey->len; + keydb->defaultIterationCount = iterationCount; passKey->data = data; passKey->len = len; SKIP_AFTER_FORK(PZ_Unlock(keydb->passwordLock)); @@ -660,6 +673,90 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb) return (crv == CKR_OK) ? SECSuccess : SECFailure; } +/* pull out the common final part of checking a password */ +SECStatus +sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, + const char *pw, SECItem *value, + PRBool *tokenRemoved); + +/* + * check to see if we have the NULL password set. + * We special case the NULL password so that if you have no password set, you + * don't do thousands of hash rounds. This allows us to startup and get + * webpages without slowdown in normal mode. + */ +SECStatus +sftkdb_CheckPasswordNull(SFTKDBHandle *keydb, PRBool *tokenRemoved) +{ + /* just like sftkdb_CheckPassowd, we get the salt and value, and + * create a dbkey */ + SECStatus rv; + SECItem salt, value; + unsigned char saltData[SDB_MAX_META_DATA_LEN]; + unsigned char valueData[SDB_MAX_META_DATA_LEN]; + SECItem key; + SDB *db; + CK_RV crv; + sftkCipherValue cipherValue; + + cipherValue.param = NULL; + cipherValue.arena = NULL; + + if (keydb == NULL) { + return SECFailure; + } + + db = sftk_getPWSDB(keydb); + if (db == NULL) { + return SECFailure; + } + + key.data = NULL; + key.len = 0; + + /* get the entry from the database */ + salt.data = saltData; + salt.len = sizeof(saltData); + value.data = valueData; + value.len = sizeof(valueData); + crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); + if (crv != CKR_OK) { + rv = SECFailure; + goto done; + } + + /* get our intermediate key based on the entry salt value */ + rv = sftkdb_passwordToKey(keydb, &salt, "", &key); + if (rv != SECSuccess) { + goto done; + } + + /* First get the cipher type */ + rv = sftkdb_decodeCipherText(&value, &cipherValue); + if (rv != SECSuccess) { + goto done; + } + + if (cipherValue.param->iter != 1) { + rv = SECFailure; + goto done; + } + + rv = sftkdb_finishPasswordCheck(keydb, &key, "", &value, tokenRemoved); + +done: + if (key.data) { + PORT_ZFree(key.data, key.len); + } + if (cipherValue.param) { + nsspkcs5_DestroyPBEParameter(cipherValue.param); + } + if (cipherValue.arena) { + PORT_FreeArena(cipherValue.arena, PR_FALSE); + } + return rv; +} + #define SFTK_PW_CHECK_STRING "password-check" #define SFTK_PW_CHECK_LEN 14 @@ -674,7 +771,6 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) unsigned char saltData[SDB_MAX_META_DATA_LEN]; unsigned char valueData[SDB_MAX_META_DATA_LEN]; SECItem key; - SECItem *result = NULL; SDB *db; CK_RV crv; @@ -710,8 +806,30 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) goto done; } + rv = sftkdb_finishPasswordCheck(keydb, &key, pw, &value, tokenRemoved); + +done: + if (key.data) { + PORT_ZFree(key.data, key.len); + } + return rv; +} + +/* we need to pass iterationCount in case we are updating a new database + * and from an old one. */ +SECStatus +sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, const char *pw, + SECItem *value, PRBool *tokenRemoved) +{ + SECItem *result = NULL; + SECStatus rv; + int iterationCount = NSS_DEFAULT_ITERATION_COUNT; + + if (*pw == 0) { + iterationCount = 1; + } /* decrypt the entry value */ - rv = sftkdb_DecryptAttribute(&key, &value, &result); + rv = sftkdb_DecryptAttribute(key, value, &result); if (rv != SECSuccess) { goto done; } @@ -752,7 +870,7 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) * as well as changing which database is returned from * SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword() * and sftkdb_HasPasswordSet()) */ - keydb->updatePasswordKey = SECITEM_DupItem(&key); + keydb->updatePasswordKey = SECITEM_DupItem(key); PZ_Unlock(keydb->passwordLock); if (keydb->updatePasswordKey == NULL) { /* PORT_Error set by SECITEM_DupItem */ @@ -787,7 +905,7 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) * are good to go */ goto done; } - sftkdb_CheckPassword(keydb, "", tokenRemoved); + sftkdb_CheckPasswordNull(keydb, tokenRemoved); /* * Important 'NULL' code here. At this point either we @@ -821,15 +939,15 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) PZ_Unlock(keydb->passwordLock); } /* load the keys, so the keydb can parse it's key set */ - sftkdb_switchKeys(keydb, &key); + sftkdb_switchKeys(keydb, key, iterationCount); /* we need to update, do it now */ if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) { /* update the peer certdb if it exists */ if (keydb->peerDB) { - sftkdb_Update(keydb->peerDB, &key); + sftkdb_Update(keydb->peerDB, key); } - sftkdb_Update(keydb, &key); + sftkdb_Update(keydb, key); } } else { rv = SECFailure; @@ -837,9 +955,6 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) } done: - if (key.data) { - PORT_ZFree(key.data, key.len); - } if (result) { SECITEM_FreeItem(result, PR_TRUE); } @@ -857,7 +972,7 @@ sftkdb_PWCached(SFTKDBHandle *keydb) static CK_RV sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, - CK_OBJECT_HANDLE id, SECItem *newKey) + CK_OBJECT_HANDLE id, SECItem *newKey, int iterationCount) { CK_ATTRIBUTE authAttrs[] = { { CKA_MODULUS, NULL, 0 }, @@ -937,7 +1052,7 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, plainText.data = authAttrs[i].pValue; plainText.len = authAttrs[i].ulValueLen; - rv = sftkdb_SignAttribute(arena, newKey, id, + rv = sftkdb_SignAttribute(arena, newKey, iterationCount, id, authAttrs[i].type, &plainText, &signText); if (rv != SECSuccess) { return CKR_GENERAL_ERROR; @@ -954,7 +1069,7 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, static CK_RV sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, - CK_OBJECT_HANDLE id, SECItem *newKey) + CK_OBJECT_HANDLE id, SECItem *newKey, int iterationCount) { CK_RV crv = CKR_OK; CK_RV crv2; @@ -1041,7 +1156,8 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, plainText.data = first[i].pValue; plainText.len = first[i].ulValueLen; - rv = sftkdb_EncryptAttribute(arena, newKey, &plainText, &result); + rv = sftkdb_EncryptAttribute(arena, newKey, iterationCount, + &plainText, &result); if (rv != SECSuccess) { return CKR_GENERAL_ERROR; } @@ -1056,6 +1172,7 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, */ id &= SFTK_OBJ_ID_MASK; keydb->newKey = newKey; + keydb->newDefaultIterationCount = iterationCount; crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, id, first, count); keydb->newKey = NULL; @@ -1063,8 +1180,8 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, } static CK_RV -sftk_convertAttributes(SFTKDBHandle *handle, - CK_OBJECT_HANDLE id, SECItem *newKey) +sftk_convertAttributes(SFTKDBHandle *handle, CK_OBJECT_HANDLE id, + SECItem *newKey, int iterationCount) { CK_RV crv = CKR_OK; PLArenaPool *arena = NULL; @@ -1078,13 +1195,14 @@ sftk_convertAttributes(SFTKDBHandle *handle, /* * first handle the MACS */ - crv = sftk_updateMacs(arena, handle, id, newKey); + crv = sftk_updateMacs(arena, handle, id, newKey, iterationCount); if (crv != CKR_OK) { goto loser; } if (handle->type == SFTK_KEYDB_TYPE) { - crv = sftk_updateEncrypted(arena, handle, id, newKey); + crv = sftk_updateEncrypted(arena, handle, id, newKey, + iterationCount); if (crv != CKR_OK) { goto loser; } @@ -1106,7 +1224,7 @@ loser: */ CK_RV sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template, - CK_ULONG count, SECItem *newKey) + CK_ULONG count, SECItem *newKey, int iterationCount) { SDBFind *find = NULL; CK_ULONG idCount = SFTK_MAX_IDS; @@ -1122,7 +1240,8 @@ sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template, while ((crv == CKR_OK) && (idCount == SFTK_MAX_IDS)) { crv = sftkdb_FindObjects(handle, find, ids, SFTK_MAX_IDS, &idCount); for (i = 0; (crv == CKR_OK) && (i < idCount); i++) { - crv = sftk_convertAttributes(handle, ids[i], newKey); + crv = sftk_convertAttributes(handle, ids[i], newKey, + iterationCount); } } crv2 = sftkdb_FindObjectsFinal(handle, find); @@ -1147,6 +1266,7 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, SFTKDBHandle *certdb; unsigned char saltData[SDB_MAX_META_DATA_LEN]; unsigned char valueData[SDB_MAX_META_DATA_LEN]; + int iterationCount = NSS_DEFAULT_ITERATION_COUNT; CK_RV crv; SDB *db; @@ -1182,6 +1302,10 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, RNG_GenerateGlobalRandomBytes(salt.data, salt.len); } + if (newPin && *newPin == 0) { + iterationCount = 1; + } + rv = sftkdb_passwordToKey(keydb, &salt, newPin, &newKey); if (rv != SECSuccess) { goto loser; @@ -1190,7 +1314,7 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, /* * convert encrypted entries here. */ - crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey); + crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey, iterationCount); if (crv != CKR_OK) { rv = SECFailure; goto loser; @@ -1202,13 +1326,15 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, CK_OBJECT_CLASS myClass = CKO_NETSCAPE_TRUST; objectType.pValue = &myClass; - crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); + crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey, + iterationCount); if (crv != CKR_OK) { rv = SECFailure; goto loser; } myClass = CKO_PUBLIC_KEY; - crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); + crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey, + iterationCount); if (crv != CKR_OK) { rv = SECFailure; goto loser; @@ -1218,7 +1344,8 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, plainText.data = (unsigned char *)SFTK_PW_CHECK_STRING; plainText.len = SFTK_PW_CHECK_LEN; - rv = sftkdb_EncryptAttribute(NULL, &newKey, &plainText, &result); + rv = sftkdb_EncryptAttribute(NULL, &newKey, iterationCount, + &plainText, &result); if (rv != SECSuccess) { goto loser; } @@ -1237,7 +1364,7 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, keydb->newKey = NULL; - sftkdb_switchKeys(keydb, &newKey); + sftkdb_switchKeys(keydb, &newKey, iterationCount); loser: if (newKey.data) { @@ -1262,7 +1389,7 @@ sftkdb_ClearPassword(SFTKDBHandle *keydb) SECItem oldKey; oldKey.data = NULL; oldKey.len = 0; - sftkdb_switchKeys(keydb, &oldKey); + sftkdb_switchKeys(keydb, &oldKey, 1); if (oldKey.data) { PORT_ZFree(oldKey.data, oldKey.len); } -- cgit v1.2.3