Replace NSS with Pale Moon's

This commit is contained in:
wuggy 2026-06-29 21:29:25 +01:00
commit 8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions

View file

@ -92,6 +92,11 @@ sftkdb_passwordToKey(SFTKDBHandle *keydb, SECItem *salt,
SHA1Context *cx = NULL;
SECStatus rv = SECFailure;
if (!pw) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
key->data = PORT_Alloc(SHA1_LENGTH);
if (key->data == NULL) {
goto loser;
@ -247,7 +252,7 @@ sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue,
loser:
if (localArena) {
PORT_FreeArena(localArena, PR_FALSE);
PORT_FreeArena(localArena, PR_TRUE);
}
return rv;
@ -260,18 +265,19 @@ loser:
* with SECITEM_FreeItem by the caller.
*/
SECStatus
sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText,
SECItem **plain)
sftkdb_DecryptAttribute(SFTKDBHandle *handle, SECItem *passKey,
CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type,
SECItem *cipherText, SECItem **plain)
{
SECStatus rv;
sftkCipherValue cipherValue;
/* First get the cipher type */
*plain = NULL;
rv = sftkdb_decodeCipherText(cipherText, &cipherValue);
if (rv != SECSuccess) {
goto loser;
}
/* fprintf(stderr, "sftkdb_DecryptAttribute iteration: %d\n", cipherValue.param->iter); */
*plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value,
PR_FALSE, NULL);
@ -280,6 +286,49 @@ sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText,
goto loser;
}
/* If we are using aes 256, we need to check authentication as well.*/
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];
CK_RV crv;
/* 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);
goto loser;
}
signature.data = signData;
signature.len = sizeof(signData);
rv = SECFailure;
/* sign sftkdb_GetAttriibuteSignature returns a crv, not an rv */
crv = sftkdb_GetAttributeSignature(handle, handle, id, type,
&signature);
if (crv == CKR_OK) {
rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE,
type, *plain, &signature);
}
if (rv != SECSuccess) {
/* handle bug 1720226 where old versions of NSS misfiled the signature
* attribute on password update */
id |= SFTK_KEYDB_TYPE | SFTK_TOKEN_TYPE;
signature.len = sizeof(signData);
crv = sftkdb_GetAttributeSignature(handle, handle, id, type,
&signature);
if (crv != CKR_OK) {
rv = SECFailure;
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto loser;
}
rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE,
type, *plain, &signature);
}
}
loser:
if (cipherValue.param) {
nsspkcs5_DestroyPBEParameter(cipherValue.param);
@ -287,9 +336,36 @@ loser:
if (cipherValue.arena) {
PORT_FreeArena(cipherValue.arena, PR_FALSE);
}
/* Item decrypted, but failed integrity, clear it out */
if (*plain && rv != SECSuccess) {
SECITEM_ZfreeItem(*plain, PR_TRUE);
*plain = NULL;
}
return rv;
}
/* If the database can't store the integrity check, it's a non-FIPS database
* and we use the old encryption scheme for it */
static PRBool
sftkdb_useLegacyEncryption(SFTKDBHandle *handle, SDB *db)
{
if ((handle == NULL) || (db == NULL)) {
/* this is the case where the legacy db is calling back to us to
* encrypt or decrypt attributes inside the lower level db code.
* This is because the legacy db stored keys as pkcs #8 encrypted
* blobs rather than individual encrypted attributes */
return PR_TRUE;
}
/* currently, only the legacy db can't store meta data, but if we
* add a new db that also can't store meta data, then it to wouldn't
* be able to do the integrity checks. In both cases use the old encryption
* algorithms. */
if ((db->sdb_flags & SDB_HAS_META) == 0) {
return PR_TRUE;
}
return PR_FALSE;
}
/*
* encrypt a block. This function returned the encrypted ciphertext which
* the caller must free. If the caller provides an arena, cipherText will
@ -297,22 +373,32 @@ loser:
* salt automatically.
*/
SECStatus
sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
int iterationCount, SECItem *plainText,
SECItem **cipherText)
sftkdb_EncryptAttribute(PLArenaPool *arena, SFTKDBHandle *handle, SDB *db,
SECItem *passKey, int iterationCount,
CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type,
SECItem *plainText, SECItem **cipherText)
{
SECStatus rv;
sftkCipherValue cipherValue;
SECItem *cipher = NULL;
NSSPKCS5PBEParameter *param = NULL;
unsigned char saltData[HASH_LENGTH_MAX];
SECItem *signature = NULL;
HASH_HashType hashType = HASH_AlgNULL;
cipherValue.alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
cipherValue.salt.len = SHA1_LENGTH;
if (sftkdb_useLegacyEncryption(handle, db)) {
cipherValue.alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
cipherValue.salt.len = SHA1_LENGTH;
hashType = HASH_AlgSHA1;
} else {
cipherValue.alg = SEC_OID_AES_256_CBC;
cipherValue.salt.len = SHA256_LENGTH;
hashType = HASH_AlgSHA256;
}
cipherValue.salt.data = saltData;
RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len);
param = nsspkcs5_NewParam(cipherValue.alg, HASH_AlgSHA1, &cipherValue.salt,
param = nsspkcs5_NewParam(cipherValue.alg, hashType, &cipherValue.salt,
iterationCount);
if (param == NULL) {
rv = SECFailure;
@ -331,7 +417,26 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
goto loser;
}
/* If we are using aes 256, we need to add authentication as well */
if ((type != CKT_INVALID_TYPE) &&
(cipherValue.param->encAlg == SEC_OID_AES_256_CBC)) {
rv = sftkdb_SignAttribute(arena, handle, db, passKey, iterationCount,
CK_INVALID_HANDLE, type, plainText,
&signature);
if (rv != SECSuccess) {
goto loser;
}
rv = sftkdb_PutAttributeSignature(handle, db, id, type,
signature);
if (rv != SECSuccess) {
goto loser;
}
}
loser:
if ((arena == NULL) && signature) {
SECITEM_ZfreeItem(signature, PR_TRUE);
}
if (cipher) {
SECITEM_FreeItem(cipher, PR_TRUE);
}
@ -397,7 +502,7 @@ loser:
HMAC_Destroy(hashCx, PR_TRUE);
}
if (key) {
SECITEM_FreeItem(key, PR_TRUE);
SECITEM_ZfreeItem(key, PR_TRUE);
}
return rv;
}
@ -408,7 +513,8 @@ loser:
* plainText is the plainText of the attribute.
*/
SECStatus
sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID,
sftkdb_VerifyAttribute(SFTKDBHandle *handle,
SECItem *passKey, CK_OBJECT_HANDLE objectID,
CK_ATTRIBUTE_TYPE attrType,
SECItem *plainText, SECItem *signText)
{
@ -436,11 +542,12 @@ sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID,
}
loser:
PORT_Memset(signData, 0, sizeof signData);
if (signValue.param) {
nsspkcs5_DestroyPBEParameter(signValue.param);
}
if (signValue.arena) {
PORT_FreeArena(signValue.arena, PR_FALSE);
PORT_FreeArena(signValue.arena, PR_TRUE);
}
return rv;
}
@ -450,8 +557,9 @@ loser:
* attribute. The signText is a PKCS 5 v2 pbe.
*/
SECStatus
sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
int iterationCount, CK_OBJECT_HANDLE objectID,
sftkdb_SignAttribute(PLArenaPool *arena, SFTKDBHandle *keyDB, SDB *db,
SECItem *passKey, int iterationCount,
CK_OBJECT_HANDLE objectID,
CK_ATTRIBUTE_TYPE attrType,
SECItem *plainText, SECItem **signature)
{
@ -517,6 +625,7 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
}
loser:
PORT_Memset(signData, 0, sizeof signData);
if (param) {
nsspkcs5_DestroyPBEParameter(param);
}
@ -860,7 +969,8 @@ sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, const char *pw,
}
/* decrypt the entry value */
rv = sftkdb_DecryptAttribute(key, value, &result);
rv = sftkdb_DecryptAttribute(keydb, key, CK_INVALID_HANDLE,
CKT_INVALID_TYPE, value, &result);
if (rv != SECSuccess) {
goto done;
}
@ -987,7 +1097,7 @@ sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, const char *pw,
done:
if (result) {
SECITEM_FreeItem(result, PR_TRUE);
SECITEM_ZfreeItem(result, PR_TRUE);
}
return rv;
}
@ -1074,9 +1184,9 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle,
SECItem plainText;
plainText.data = authAttr.pValue;
plainText.len = authAttr.ulValueLen;
if (sftkdb_SignAttribute(arena, newKey, iterationCount, id,
authAttr.type, &plainText,
&signText) != SECSuccess) {
if (sftkdb_SignAttribute(arena, handle, keyTarget, newKey,
iterationCount, id, authAttr.type,
&plainText, &signText) != SECSuccess) {
return CKR_GENERAL_ERROR;
}
if (sftkdb_PutAttributeSignature(handle, keyTarget, id, authAttr.type,
@ -1108,6 +1218,7 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
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) {
@ -1131,7 +1242,8 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
SECItem *result;
plainText.data = privAttr.pValue;
plainText.len = privAttr.ulValueLen;
if (sftkdb_EncryptAttribute(arena, newKey, iterationCount,
if (sftkdb_EncryptAttribute(arena, keydb, keydb->db, newKey,
iterationCount, sdbId, privAttr.type,
&plainText, &result) != SECSuccess) {
return CKR_GENERAL_ERROR;
}
@ -1141,10 +1253,9 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
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;
@ -1184,8 +1295,7 @@ sftk_convertAttributes(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
}
/* free up our mess */
/* NOTE: at this point we know we've cleared out any unencrypted data */
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
return CKR_OK;
loser:
@ -1300,7 +1410,7 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
certdb = keydb->peerDB;
if (certdb) {
CK_ATTRIBUTE objectType = { CKA_CLASS, 0, sizeof(CK_OBJECT_CLASS) };
CK_OBJECT_CLASS myClass = CKO_NETSCAPE_TRUST;
CK_OBJECT_CLASS myClass = CKO_NSS_TRUST;
objectType.pValue = &myClass;
crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey,
@ -1321,8 +1431,9 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
plainText.data = (unsigned char *)SFTK_PW_CHECK_STRING;
plainText.len = SFTK_PW_CHECK_LEN;
rv = sftkdb_EncryptAttribute(NULL, &newKey, iterationCount,
&plainText, &result);
rv = sftkdb_EncryptAttribute(NULL, keydb, keydb->db, &newKey,
iterationCount, CK_INVALID_HANDLE,
CKT_INVALID_TYPE, &plainText, &result);
if (rv != SECSuccess) {
goto loser;
}