Resolves: RHEL-127696
- Fix regression in private key lifecycle
This commit is contained in:
parent
ee702100d1
commit
e57288c6ae
@ -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);
|
||||
|
||||
5
nss.spec
5
nss.spec
@ -1,6 +1,6 @@
|
||||
%global nss_version 3.112.0
|
||||
%global nspr_version 4.36.0
|
||||
%global baserelease 6
|
||||
%global baserelease 7
|
||||
%global nss_release %baserelease
|
||||
# NOTE: To avoid NVR clashes of nspr* packages:
|
||||
# use "%%global nspr_release %%[%%baserelease+n]" to handle offsets when
|
||||
@ -1204,6 +1204,9 @@ update-crypto-policies &> /dev/null || :
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Jan 16 2026 Bob Relyea <rrelyea@redhat.com> - 3.112.0-7
|
||||
- fix gregression 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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user