Resolves: RHEL-127691

- Fix regression in private key lifecycle
- fix a null in ml-dsa pkcs12 decode
- fix return code in ml-kem pct
This commit is contained in:
Robert Relyea 2026-01-20 13:50:25 -08:00
parent 29ff4c3b89
commit 23b99ddc44
3 changed files with 367 additions and 28 deletions

View File

@ -0,0 +1,202 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1767992040 28800
# Fri Jan 09 12:54:00 2026 -0800
# Branch RHEL10
# Node ID 15f1129c29c037cce7913eb62c0eca06b5aa51d1
# Parent 4bfb87c6e863957fc933e6dd5af8eae8a5cd0469
nss-3.112-pkcs12-ml-dsa-crash-fix.patch
diff --git a/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc b/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
--- a/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
+++ b/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
@@ -7,16 +7,17 @@
#include <climits>
#include <memory>
#include "nss.h"
#include "pk11pub.h"
#include "secutil.h"
#include "gtest/gtest.h"
#include "nss_scoped_ptrs.h"
+#define SEC_OID_ML_DSA_44 SEC_OID_PRIVATE_3
namespace nss_test {
const std::vector<uint8_t> kValidP256Key = {
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
0xc9, 0xaf, 0xa9, 0xd8, 0x45, 0xba, 0x75, 0x16, 0x6b, 0x5c, 0x21, 0x57,
@@ -133,16 +134,69 @@ class DERPrivateKeyImportTest : public :
// no cert. This is expected, so clear it.
if (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) {
PORT_SetError(0);
}
}
return rv == SECSuccess;
}
+
+ SECStatus BuildPrivateKeyInfoAndImportIt(SECOidTag algTag) {
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ EXPECT_TRUE(slot);
+ if (!slot) {
+ return SECFailure;
+ }
+
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ EXPECT_TRUE(arena);
+ if (!arena) {
+ return SECFailure;
+ }
+
+ SECKEYPrivateKeyInfo* pki = (SECKEYPrivateKeyInfo*)PORT_ArenaZAlloc(
+ arena.get(), sizeof(SECKEYPrivateKeyInfo));
+ EXPECT_TRUE(pki);
+ if (!pki) {
+ return SECFailure;
+ }
+
+ pki->version.data = (unsigned char*)PORT_ArenaAlloc(arena.get(), 1);
+ EXPECT_TRUE(pki->version.data);
+ if (!pki->version.data) {
+ return SECFailure;
+ }
+
+ pki->version.data[0] = 0x00;
+ pki->version.len = 1;
+
+ EXPECT_EQ(
+ SECOID_SetAlgorithmID(arena.get(), &pki->algorithm, algTag, nullptr),
+ SECSuccess);
+
+ // Empty private key
+ pki->privateKey.data = (unsigned char*)PORT_ArenaAlloc(arena.get(), 1);
+ EXPECT_TRUE(pki->privateKey.data);
+ if (!pki->privateKey.data) {
+ return SECFailure;
+ }
+ pki->privateKey.len = 0;
+
+ SECKEYPrivateKey* privk = nullptr;
+ PORT_SetError(0);
+ SECStatus rv = PK11_ImportPrivateKeyInfoAndReturnKey(
+ slot.get(), pki, nullptr, nullptr, PR_FALSE, PR_FALSE, KU_ALL, &privk,
+ nullptr);
+
+ if (privk) {
+ SECKEY_DestroyPrivateKey(privk);
+ }
+ return rv;
+ }
};
TEST_F(DERPrivateKeyImportTest, ImportPrivateRSAKey) {
EXPECT_TRUE(ParsePrivateKey(kValidRSAKey, true));
EXPECT_FALSE(PORT_GetError()) << PORT_GetError();
}
TEST_F(DERPrivateKeyImportTest, ImportEcdsaKey) {
@@ -155,9 +209,15 @@ TEST_F(DERPrivateKeyImportTest, ImportIn
EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_DER) << PORT_GetError();
}
TEST_F(DERPrivateKeyImportTest, ImportZeroLengthPrivateKey) {
EXPECT_FALSE(ParsePrivateKey(kInvalidZeroLengthKey, false));
EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_KEY) << PORT_GetError();
}
+TEST_F(DERPrivateKeyImportTest,
+ ImportZeroLengthMLDSAPrivateKey) {
+ EXPECT_EQ(BuildPrivateKeyInfoAndImportIt(SEC_OID_ML_DSA_44), SECFailure);
+ EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_KEY);
+}
+
} // namespace nss_test
diff --git a/lib/pk11wrap/pk11pk12.c b/lib/pk11wrap/pk11pk12.c
--- a/lib/pk11wrap/pk11pk12.c
+++ b/lib/pk11wrap/pk11pk12.c
@@ -323,17 +323,17 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey
derPKI);
if (rv != SECSuccess) {
/* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
* validity of the data in pki. The best we can do is free the arena
* and return. */
PORT_FreeArena(temparena, PR_TRUE);
return rv;
}
- if (pki->privateKey.data == NULL) {
+ if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
/* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
* is a zero-length octet string, free the arena and return a failure
* to avoid trying to zero the corresponding SECItem in
* SECKEY_DestroyPrivateKeyInfo(). */
PORT_FreeArena(temparena, PR_TRUE);
PORT_SetError(SEC_ERROR_BAD_KEY);
return SECFailure;
}
@@ -753,16 +753,20 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK
keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
paramTemplate = NULL;
paramDest = NULL;
lpk->keyType = ecKey;
break;
case SEC_OID_ML_DSA_44:
case SEC_OID_ML_DSA_65:
case SEC_OID_ML_DSA_87:
+ if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ goto loser;
+ }
/* choice */
switch (pki->privateKey.data[0]) {
case SEC_ASN1_CONTEXT_SPECIFIC|0:
keyTemplate = SECKEY_MLDSAPrivateKeySeedExportTemplate;
break;
case SEC_ASN1_OCTET_STRING:
keyTemplate = SECKEY_MLDSAPrivateKeyKeyExportTemplate;
break;
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -5815,17 +5815,17 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
}
crv = NSC_Decapsulate(hSession, &mech, privateKey->handle,
cipher_text, cipher_text_length, &template, 1,
&key2);
if (crv != CKR_OK) {
goto kem_done;
}
if (!sftk_compareKeysEqual(hSession, key1, key2)) {
- crv = CKR_DEVICE_ERROR;
+ crv = CKR_GENERAL_ERROR;
goto kem_done;
}
kem_done:
/* PORT_Free already checks for NULL */
PORT_Free(cipher_text);
if (key1 != CK_INVALID_HANDLE) {
NSC_DestroyObject(hSession, key1);
}
@@ -7105,16 +7105,20 @@ sftk_unwrapPrivateKey(SFTKObject *key, S
paramSet = CKP_ML_DSA_44;
goto mldsa_next;
case SEC_OID_ML_DSA_65:
paramSet = CKP_ML_DSA_65;
goto mldsa_next;
case SEC_OID_ML_DSA_87:
paramSet = CKP_ML_DSA_87;
mldsa_next:
+ if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ goto loser;
+ }
switch (pki->privateKey.data[0]) {
case SEC_ASN1_CONTEXT_SPECIFIC|0:
keyTemplate = nsslowkey_PQSeedTemplate;
break;
case SEC_ASN1_OCTET_STRING:
keyTemplate = nsslowkey_PQPrivateKeyTemplate;
break;
case SEC_ASN1_CONSTRUCTED|SEC_ASN1_SEQUENCE:

View File

@ -2,32 +2,42 @@
# User Robert Relyea <rrelyea@redhat.com>
# Date 1762542092 28800
# Fri Nov 07 11:01:32 2025 -0800
# Branch RHEL10
# Node ID 6949dbcd6631ec0db3f53b3cf8957fac3a80da25
# Parent 3e2ea63bf062fef47334b69723db7eac95daaa2a
# Branch RHEL_8
# Node ID 5b6833262609c6a2567d234a645be532bde27ef7
# Parent 04ad729ed140ac94ab37d012dd2fec6c575bba2b
nss-3.112-update-fixes.patch
diff --git a/lib/cryptohi/keythi.h b/lib/cryptohi/keythi.h
--- a/lib/cryptohi/keythi.h
+++ b/lib/cryptohi/keythi.h
@@ -240,16 +240,17 @@ typedef struct SECKEYPublicKeyStr SECKEY
struct SECKEYPrivateKeyStr {
PLArenaPool *arena;
KeyType keyType;
@@ -243,16 +243,27 @@ struct SECKEYPrivateKeyStr {
PK11SlotInfo *pkcs11Slot; /* pkcs11 slot this key lives in */
CK_OBJECT_HANDLE pkcs11ID; /* ID of pkcs11 object */
PRBool pkcs11IsTemp; /* temp pkcs11 object, delete it when done */
void *wincx; /* context for errors and pw prompts */
PRUint32 staticflags; /* bit flag of cached PKCS#11 attributes */
+ PRBool pkcs11IsOwner; /* the pkcs11ID is owned by this SECKEY */
};
typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey;
+#define SECKEYPRIVATEKEY_IS_TEMP_FLAG 0x01
+#define SECKEYPRIVATEKEY_IS_OWNED_FLAG 0x02
+#define SECKEYPRIVATEKEY_IS_TEMP(key) \
+ ((PRBool)((key)->pkcs11IsTemp&SECKEYPRIVATEKEY_IS_TEMP_FLAG)==SECKEYPRIVATEKEY_IS_TEMP_FLAG)
+#define SECKEYPRIVATEKEY_IS_OWNED(key) \
+ ((PRBool)((key)->pkcs11IsTemp&SECKEYPRIVATEKEY_IS_OWNED_FLAG)==SECKEYPRIVATEKEY_IS_OWNED_FLAG)
+#define SECKEYPRIVATEKEY_SET_TEMP(key,isTemp) (key)->pkcs11IsTemp = ((key)->pkcs11IsTemp & ~SECKEYPRIVATEKEY_IS_TEMP_FLAG) | \
+ ((isTemp) ? SECKEYPRIVATEKEY_IS_TEMP_FLAG : 0)
+#define SECKEYPRIVATEKEY_SET_OWNED(key,isOwned) (key)->pkcs11IsTemp = ((key)->pkcs11IsTemp & ~SECKEYPRIVATEKEY_IS_OWNED_FLAG) | \
+ ((isOwned) ? SECKEYPRIVATEKEY_IS_OWNED_FLAG : 0)
+
typedef struct {
PRCList links;
SECKEYPrivateKey *key;
} SECKEYPrivateKeyListNode;
typedef struct {
PRCList list;
PLArenaPool *arena;
diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
--- a/lib/cryptohi/seckey.c
+++ b/lib/cryptohi/seckey.c
@ -41,7 +51,7 @@ diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
if (privk) {
if (privk->pkcs11Slot) {
- if (privk->pkcs11IsTemp) {
+ if (privk->pkcs11IsOwner) {
+ if (SECKEYPRIVATEKEY_IS_OWNED(privk)) {
PK11_DestroyObject(privk->pkcs11Slot, privk->pkcs11ID);
}
PK11_FreeSlot(privk->pkcs11Slot);
@ -50,16 +60,33 @@ diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
PORT_FreeArena(privk->arena, PR_TRUE);
}
}
@@ -1429,16 +1429,17 @@ SECKEY_CopyPrivateKey(const SECKEYPrivat
@@ -1418,27 +1418,31 @@ SECKEY_CopyPrivateKey(const SECKEYPrivat
copyk = (SECKEYPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
if (copyk) {
copyk->arena = arena;
copyk->keyType = privk->keyType;
/* copy the PKCS #11 parameters */
copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
/* if the key we're referencing was a temparary key we have just
- * created, that we want to go away when we're through, we need
+ * it may go away when we're through, we need
* to make a copy of it */
- if (privk->pkcs11IsTemp) {
+ copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
+ if (SECKEYPRIVATEKEY_IS_TEMP(privk)) {
copyk->pkcs11ID =
PK11_CopyKey(privk->pkcs11Slot, privk->pkcs11ID);
if (copyk->pkcs11ID == CK_INVALID_HANDLE)
goto fail;
+ /* since we made a copy, we own that copy (even if we
+ * didn't own the original */
+ SECKEYPRIVATEKEY_SET_OWNED(copyk, PR_TRUE);
} else {
copyk->pkcs11ID = privk->pkcs11ID;
+ SECKEYPRIVATEKEY_SET_OWNED(copyk, PR_FALSE);
}
copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
+ copyk->pkcs11IsOwner = privk->pkcs11IsOwner;
- copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
copyk->wincx = privk->wincx;
copyk->staticflags = privk->staticflags;
return copyk;
@ -118,7 +145,7 @@ diff --git a/lib/freebl/leancrypto/lc_sha3.h b/lib/freebl/leancrypto/lc_sha3.h
diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
--- a/lib/pk11wrap/pk11akey.c
+++ b/lib/pk11wrap/pk11akey.c
@@ -1002,22 +1002,23 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
@@ -1002,34 +1002,39 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
return pubKey;
}
@ -143,7 +170,24 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
pk11Type = PK11_ReadULongAttribute(slot, privID, CKA_KEY_TYPE);
isTemp = (PRBool)!PK11_HasAttributeSet(slot, privID, CKA_TOKEN, PR_FALSE);
keyType = pk11_GetKeyTypeFromPKCS11KeyType(pk11Type);
@@ -1048,16 +1049,17 @@ PK11_MakePrivKey(PK11SlotInfo *slot, Key
if (keyType == nullKey) {
return NULL;
}
}
+ /* we can never own a perm key, make sure we don't set owner */
+ if (!isTemp) {
+ isOwner = PR_FALSE;
+ }
/* if the key is private, make sure we are authenticated to the
* token before we try to use it */
isPrivate = (PRBool)PK11_HasAttributeSet(slot, privID, CKA_PRIVATE, PR_FALSE);
if (isPrivate) {
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
return NULL;
@@ -1047,17 +1052,19 @@ PK11_MakePrivKey(PK11SlotInfo *slot, Key
PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
@ -151,8 +195,10 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
privKey->keyType = keyType;
privKey->pkcs11Slot = PK11_ReferenceSlot(slot);
privKey->pkcs11ID = privID;
privKey->pkcs11IsTemp = isTemp;
+ privKey->pkcs11IsOwner = isOwner;
- privKey->pkcs11IsTemp = isTemp;
+ privKey->pkcs11IsTemp = 0;
+ SECKEYPRIVATEKEY_SET_TEMP(privKey, isTemp);
+ SECKEYPRIVATEKEY_SET_OWNED(privKey, isOwner);
privKey->wincx = wincx;
return privKey;
@ -161,7 +207,7 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
PK11SlotInfo *
PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key)
{
@@ -2635,17 +2637,17 @@ PK11_CopyTokenPrivKeyToSessionPrivKey(PK
@@ -2635,17 +2642,17 @@ PK11_CopyTokenPrivKeyToSessionPrivKey(PK
1, &newKeyID);
PK11_ExitSlotMonitor(destSlot);
@ -180,7 +226,7 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
{
PK11SlotInfo *slot = privk->pkcs11Slot;
CK_ATTRIBUTE template[1];
@@ -2668,17 +2670,17 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey
@@ -2668,17 +2675,17 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey
template, 1, &newKeyID);
PK11_RestoreROSession(slot, rwsession);
@ -199,7 +245,7 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
* this function also frees the privKey structure.
*/
SECStatus
@@ -2731,17 +2733,17 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJEC
@@ -2731,17 +2738,17 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJEC
{
SECStatus rv = SECSuccess;
SECKEYPrivateKey *privKey;
@ -218,7 +264,7 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
if (keycb->callback) {
rv = (*keycb->callback)(privKey, keycb->callbackArg);
}
@@ -2823,17 +2825,17 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot,
@@ -2823,17 +2830,17 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot,
{
CK_OBJECT_HANDLE keyHandle;
SECKEYPrivateKey *privKey;
@ -237,7 +283,7 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
* from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make
* smart cards happy.
*/
@@ -3011,15 +3013,15 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *sl
@@ -3011,15 +3018,15 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *sl
keys = SECKEY_NewPrivateKeyList();
if (keys == NULL) {
PORT_Free(key_ids);
@ -254,6 +300,89 @@ diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
PORT_Free(key_ids);
return keys;
}
diff --git a/lib/pk11wrap/pk11cert.c b/lib/pk11wrap/pk11cert.c
--- a/lib/pk11wrap/pk11cert.c
+++ b/lib/pk11wrap/pk11cert.c
@@ -1313,17 +1313,18 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo
if (rv != SECSuccess) {
return NULL;
}
keyh = PK11_MatchItem(slot, certh, CKO_PRIVATE_KEY);
}
if (keyh == CK_INVALID_HANDLE) {
return NULL;
}
- return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);
+
+ return PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyh, wincx);
}
/*
* import a cert for a private key we have already generated. Set the label
* on both to be the nickname. This is for the Key Gen, orphaned key case.
*/
PK11SlotInfo *
PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
@@ -2085,17 +2086,17 @@ PK11_FindKeyByAnyCert(CERTCertificate *c
SEC_ERROR_TOKEN_NOT_LOGGED_IN == err)) {
/* authenticate and try again */
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
if (rv == SECSuccess) {
keyHandle = PK11_MatchItem(slot, certHandle, CKO_PRIVATE_KEY);
}
}
if (keyHandle != CK_INVALID_HANDLE) {
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyHandle, wincx);
}
if (slot) {
PK11_FreeSlot(slot);
}
return privKey;
}
CK_OBJECT_HANDLE
@@ -2492,17 +2493,17 @@ PK11_FindKeyByDERCert(PK11SlotInfo *slot
return NULL;
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
if (keyHandle == CK_INVALID_HANDLE) {
return NULL;
}
- return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
+ return PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyHandle, wincx);
}
SECStatus
PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
char *nickname,
PRBool addCertUsage, void *wincx)
{
CK_OBJECT_HANDLE keyHandle;
diff --git a/lib/pk11wrap/pk11kea.c b/lib/pk11wrap/pk11kea.c
--- a/lib/pk11wrap/pk11kea.c
+++ b/lib/pk11wrap/pk11kea.c
@@ -86,17 +86,17 @@ pk11_KeyExchange(PK11SlotInfo *slot, CK_
goto rsa_failed;
}
rsaParams.keySizeInBits = 1024;
rsaParams.pe = 0x10001;
privKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
&rsaParams, &pubKey, PR_FALSE, PR_TRUE, symKey->cx);
} else {
/* if keys exist, build SECKEY data structures for them */
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, privKeyHandle,
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyHandle,
symKey->cx);
if (privKey != NULL) {
pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle);
if (pubKey && pubKey->pkcs11Slot) {
PK11_FreeSlot(pubKey->pkcs11Slot);
pubKey->pkcs11Slot = NULL;
pubKey->pkcs11ID = CK_INVALID_HANDLE;
}
diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c
--- a/lib/pk11wrap/pk11skey.c
+++ b/lib/pk11wrap/pk11skey.c
@ -423,7 +552,7 @@ diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
--- a/lib/softoken/pkcs11.c
+++ b/lib/softoken/pkcs11.c
@@ -1033,36 +1033,40 @@ sftk_handleCrlObject(SFTKSession *sessio
@@ -1031,36 +1031,40 @@ sftk_handleCrlObject(SFTKSession *sessio
/*
* check the consistancy and initialize a Public Key Object
@ -468,7 +597,7 @@ diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
return crv;
}
crv = sftk_ConstrainAttribute(object, CKA_PRIME,
@@ -1073,92 +1077,73 @@ sftk_handlePublicKeyObject(SFTKSession *
@@ -1071,92 +1075,73 @@ sftk_handlePublicKeyObject(SFTKSession *
crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DSA_MAX_P_BITS, 0);
if (crv != CKR_OK) {
return crv;
@ -562,7 +691,7 @@ diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
/* make sure the required fields exist */
crv = sftk_defaultAttribute(object, CKA_SUBJECT, NULL, 0);
@@ -1226,21 +1211,21 @@ sftk_verifyRSAPrivateKey(SFTKObject *obj
@@ -1224,21 +1209,21 @@ sftk_verifyRSAPrivateKey(SFTKObject *obj
/*
* check the consistancy and initialize a Private Key Object
@ -588,7 +717,7 @@ diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
int missing_rsa_mod_component = 0;
int missing_rsa_exp_component = 0;
int missing_rsa_crt_component = 0;
@@ -1302,71 +1287,74 @@ sftk_handlePrivateKeyObject(SFTKSession
@@ -1300,71 +1285,74 @@ sftk_handlePrivateKeyObject(SFTKSession
crv = sftk_forceAttribute(object, CKA_NSS_DB,
sftk_item_expand(&mod));
if (mod.data)
@ -673,7 +802,7 @@ diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
#endif
case CKK_NSS_ML_KEM:
case CKK_ML_KEM:
@@ -1376,17 +1364,16 @@ sftk_handlePrivateKeyObject(SFTKSession
@@ -1374,17 +1362,16 @@ sftk_handlePrivateKeyObject(SFTKSession
if (!sftk_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
@ -691,7 +820,7 @@ diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
return CKR_TEMPLATE_INCOMPLETE;
}
/* make sure we have a CKA_PARAMETER_SET */
@@ -1454,17 +1441,16 @@ sftk_handlePrivateKeyObject(SFTKSession
@@ -1452,17 +1439,16 @@ sftk_handlePrivateKeyObject(SFTKSession
}
}
sftk_DeleteAttributeType(object, CKA_NSS_SEED_OK);

View File

@ -63,7 +63,7 @@ print(string.sub(hash, 0, 16))
Summary: Network Security Services
Name: nss
Version: %{nss_version}
Release: 5%{?dist}
Release: 7%{?dist}
License: MPLv2.0
URL: http://www.mozilla.org/projects/security/pki/nss/
Requires: nspr >= %{nspr_version}%{nspr_release}
@ -198,6 +198,7 @@ Patch88: nss-3.112-fix-get-interface.patch
Patch89: nss-3.112-update-fixes.patch
Patch90: nss-3.112-mlkem-fips-update.patch
Patch91: nss-3.112-partial-pub-key-validate.patch
Patch92: nss-3.112-pkcs12-ml-dsa-crash-fix.patch
%description
Network Security Services (NSS) is a set of libraries designed to
@ -1000,6 +1001,13 @@ update-crypto-policies --no-reload &> /dev/null || :
%changelog
* Fri Jan 16 2026 Bob Relyea <rrelyea@redhat.com> - 3.112.0-7
- fix regression in -5 bug fix
* Fri Jan 9 2026 Bob Relyea <rrelyea@redhat.com> - 3.112.0-6
- fix a null in ml-dsa pkcs12 decode
- fix return code in ml-kem pct
* Tue Nov 11 2025 Bob Relyea <rrelyea@redhat.com> - 3.112.0-5
- fips update
- Fix indicators for the new post-quantum algorithms