diff --git a/Bug-872838-fix-pk11wrap-locking.patch b/Bug-872838-fix-pk11wrap-locking.patch new file mode 100644 index 0000000..977d8a9 --- /dev/null +++ b/Bug-872838-fix-pk11wrap-locking.patch @@ -0,0 +1,393 @@ +Index: ./mozilla/security/nss/lib/cryptohi/keythi.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/cryptohi/keythi.h,v +retrieving revision 1.17 +diff -u -p -r1.17 keythi.h +--- ./mozilla/security/nss/lib/cryptohi/keythi.h 16 May 2012 12:34:15 -0000 1.17 ++++ ./mozilla/security/nss/lib/cryptohi/keythi.h 2 Nov 2012 18:09:53 -0000 +@@ -214,7 +214,12 @@ typedef struct SECKEYPublicKeyStr SECKEY + #define SECKEY_HAS_ATTRIBUTE_SET(key,attribute) \ + (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? \ + (0 != (key->staticflags & SECKEY_##attribute)) : \ +- PK11_HasAttributeSet(key->pkcs11Slot,key->pkcs11ID,attribute) ++ PK11_HasAttributeSet(key->pkcs11Slot,key->pkcs11ID,attribute, PR_FALSE) ++ ++#define SECKEY_HAS_ATTRIBUTE_SET_LOCK(key,attribute, haslock) \ ++ (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? \ ++ (0 != (key->staticflags & SECKEY_##attribute)) : \ ++ PK11_HasAttributeSet(key->pkcs11Slot,key->pkcs11ID,attribute, haslock) + + /* + ** A generic key structure +Index: ./mozilla/security/nss/lib/cryptohi/seckey.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/cryptohi/seckey.c,v +retrieving revision 1.68 +diff -u -p -r1.68 seckey.c +--- ./mozilla/security/nss/lib/cryptohi/seckey.c 25 Jun 2012 21:48:39 -0000 1.68 ++++ ./mozilla/security/nss/lib/cryptohi/seckey.c 2 Nov 2012 18:09:53 -0000 +@@ -1918,7 +1918,7 @@ loser: + } + + #define SECKEY_CacheAttribute(key, attribute) \ +- if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute)) { \ ++ if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, PR_FALSE)) { \ + key->staticflags |= SECKEY_##attribute; \ + } else { \ + key->staticflags &= (~SECKEY_##attribute); \ +Index: ./mozilla/security/nss/lib/pk11wrap/pk11akey.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/pk11wrap/pk11akey.c,v +retrieving revision 1.36 +diff -u -p -r1.36 pk11akey.c +--- ./mozilla/security/nss/lib/pk11wrap/pk11akey.c 25 Apr 2012 14:50:04 -0000 1.36 ++++ ./mozilla/security/nss/lib/pk11wrap/pk11akey.c 2 Nov 2012 18:09:54 -0000 +@@ -740,7 +740,7 @@ PK11_MakePrivKey(PK11SlotInfo *slot, Key + CK_KEY_TYPE pk11Type = CKK_RSA; + + pk11Type = PK11_ReadULongAttribute(slot,privID,CKA_KEY_TYPE); +- isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN); ++ isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN,PR_FALSE); + switch (pk11Type) { + case CKK_RSA: keyType = rsaKey; break; + case CKK_DSA: keyType = dsaKey; break; +@@ -754,7 +754,7 @@ PK11_MakePrivKey(PK11SlotInfo *slot, Key + + /* 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); ++ isPrivate = (PRBool)PK11_HasAttributeSet(slot,privID,CKA_PRIVATE,PR_FALSE); + if (isPrivate) { + rv = PK11_Authenticate(slot, PR_TRUE, wincx); + if (rv != SECSuccess) { +@@ -1432,7 +1432,7 @@ PK11_GenerateKeyPairWithOpFlags(PK11Slot + + /* set the ID to the public key so we can find it again */ + cka_id = pk11_MakeIDFromPublicKey(*pubKey); +- pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN); ++ pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN,PR_FALSE); + + PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len); + +Index: ./mozilla/security/nss/lib/pk11wrap/pk11auth.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/pk11wrap/pk11auth.c,v +retrieving revision 1.16 +diff -u -p -r1.16 pk11auth.c +--- ./mozilla/security/nss/lib/pk11wrap/pk11auth.c 16 May 2012 12:34:19 -0000 1.16 ++++ ./mozilla/security/nss/lib/pk11wrap/pk11auth.c 2 Nov 2012 18:09:54 -0000 +@@ -45,8 +45,9 @@ static struct PK11GlobalStruct { + * Check the user's password. Log into the card if it's correct. + * succeed if the user is already logged in. + */ +-SECStatus +-pk11_CheckPassword(PK11SlotInfo *slot,char *pw,PRBool contextSpecific) ++static SECStatus ++pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session, ++ char *pw, PRBool alreadyLocked, PRBool contextSpecific) + { + int len = 0; + CK_RV crv; +@@ -66,13 +67,13 @@ pk11_CheckPassword(PK11SlotInfo *slot,ch + } + + do { +- PK11_EnterSlotMonitor(slot); +- crv = PK11_GETTAB(slot)->C_Login(slot->session, ++ if (!alreadyLocked) PK11_EnterSlotMonitor(slot); ++ crv = PK11_GETTAB(slot)->C_Login(session, + contextSpecific ? CKU_CONTEXT_SPECIFIC : CKU_USER, + (unsigned char *)pw,len); + slot->lastLoginCheck = 0; + mustRetry = PR_FALSE; +- PK11_ExitSlotMonitor(slot); ++ if (!alreadyLocked) PK11_ExitSlotMonitor(slot); + switch (crv) { + /* if we're already logged in, we're good to go */ + case CKR_OK: +@@ -91,10 +92,19 @@ pk11_CheckPassword(PK11SlotInfo *slot,ch + * if the token is still there. */ + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_CLOSED: ++ if (session != slot->session) { ++ /* don't bother retrying, we were in a middle of an operation, ++ * which is now lost. Just fail. */ ++ PORT_SetError(PK11_MapError(crv)); ++ rv = SECFailure; ++ break; ++ } + if (retry++ == 0) { + rv = PK11_InitToken(slot,PR_FALSE); + if (rv == SECSuccess) { + if (slot->session != CK_INVALID_SESSION) { ++ session = slot->session; /* we should have ++ * a new session now */ + mustRetry = PR_TRUE; + } else { + PORT_SetError(PK11_MapError(crv)); +@@ -242,7 +252,8 @@ PK11_HandlePasswordCheck(PK11SlotInfo *s + NeedAuth = PR_TRUE; + } + } +- if (NeedAuth) PK11_DoPassword(slot,PR_TRUE,wincx,PR_FALSE); ++ if (NeedAuth) PK11_DoPassword(slot, slot->session, PR_TRUE, ++ wincx, PR_FALSE, PR_FALSE); + } + + void +@@ -301,7 +312,8 @@ pk11_LoginStillRequired(PK11SlotInfo *sl + SECStatus + PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx) { + if (pk11_LoginStillRequired(slot,wincx)) { +- return PK11_DoPassword(slot,loadCerts,wincx,PR_FALSE); ++ return PK11_DoPassword(slot, slot->session, loadCerts, wincx, ++ PR_FALSE, PR_FALSE); + } + return SECSuccess; + } +@@ -532,7 +544,8 @@ PK11_SetIsLoggedInFunc(PK11IsLoggedInFun + * of the PKCS 11 module. + */ + SECStatus +-PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx, ++PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session, ++ PRBool loadCerts, void *wincx, PRBool alreadyLocked, + PRBool contextSpecific) + { + SECStatus rv = SECFailure; +@@ -602,7 +615,8 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBo + break; + } + } +- rv = pk11_CheckPassword(slot,password,contextSpecific); ++ rv = pk11_CheckPassword(slot, session, password, ++ alreadyLocked, contextSpecific); + PORT_Memset(password, 0, PORT_Strlen(password)); + PORT_Free(password); + if (rv != SECWouldBlock) break; +Index: ./mozilla/security/nss/lib/pk11wrap/pk11merge.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/pk11wrap/pk11merge.c,v +retrieving revision 1.10 +diff -u -p -r1.10 pk11merge.c +--- ./mozilla/security/nss/lib/pk11wrap/pk11merge.c 25 Apr 2012 14:50:05 -0000 1.10 ++++ ./mozilla/security/nss/lib/pk11wrap/pk11merge.c 2 Nov 2012 18:09:54 -0000 +@@ -169,15 +169,15 @@ pk11_getPrivateKeyUsage(PK11SlotInfo *sl + { + unsigned int usage = 0; + +- if ((PK11_HasAttributeSet(slot, id, CKA_UNWRAP) || +- PK11_HasAttributeSet(slot,id, CKA_DECRYPT))) { ++ if ((PK11_HasAttributeSet(slot, id, CKA_UNWRAP,PR_FALSE) || ++ PK11_HasAttributeSet(slot,id, CKA_DECRYPT,PR_FALSE))) { + usage |= KU_KEY_ENCIPHERMENT; + } +- if (PK11_HasAttributeSet(slot, id, CKA_DERIVE)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) { + usage |= KU_KEY_AGREEMENT; + } +- if ((PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER) || +- PK11_HasAttributeSet(slot, id, CKA_SIGN))) { ++ if ((PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE) || ++ PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE))) { + usage |= KU_DIGITAL_SIGNATURE; + } + return usage; +@@ -373,31 +373,31 @@ pk11_getSecretKeyFlags(PK11SlotInfo *slo + { + CK_FLAGS flags = 0; + +- if (PK11_HasAttributeSet(slot, id, CKA_UNWRAP)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_UNWRAP, PR_FALSE)) { + flags |= CKF_UNWRAP; + } +- if (PK11_HasAttributeSet(slot, id, CKA_WRAP)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_WRAP, PR_FALSE)) { + flags |= CKF_WRAP; + } +- if (PK11_HasAttributeSet(slot, id, CKA_ENCRYPT)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_ENCRYPT, PR_FALSE)) { + flags |= CKF_ENCRYPT; + } +- if (PK11_HasAttributeSet(slot, id, CKA_DECRYPT)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_DECRYPT, PR_FALSE)) { + flags |= CKF_DECRYPT; + } +- if (PK11_HasAttributeSet(slot, id, CKA_DERIVE)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) { + flags |= CKF_DERIVE; + } +- if (PK11_HasAttributeSet(slot, id, CKA_SIGN)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE)) { + flags |= CKF_SIGN; + } +- if (PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE)) { + flags |= CKF_SIGN_RECOVER; + } +- if (PK11_HasAttributeSet(slot, id, CKA_VERIFY)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_VERIFY, PR_FALSE)) { + flags |= CKF_VERIFY; + } +- if (PK11_HasAttributeSet(slot, id, CKA_VERIFY_RECOVER)) { ++ if (PK11_HasAttributeSet(slot, id, CKA_VERIFY_RECOVER, PR_FALSE)) { + flags |= CKF_VERIFY_RECOVER; + } + return flags; +Index: ./mozilla/security/nss/lib/pk11wrap/pk11obj.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/pk11wrap/pk11obj.c,v +retrieving revision 1.27 +diff -u -p -r1.27 pk11obj.c +--- ./mozilla/security/nss/lib/pk11wrap/pk11obj.c 29 Jun 2012 17:46:25 -0000 1.27 ++++ ./mozilla/security/nss/lib/pk11wrap/pk11obj.c 2 Nov 2012 18:09:54 -0000 +@@ -146,7 +146,7 @@ PK11_ReadULongAttribute(PK11SlotInfo *sl + */ + CK_BBOOL + PK11_HasAttributeSet( PK11SlotInfo *slot, CK_OBJECT_HANDLE id, +- CK_ATTRIBUTE_TYPE type ) ++ CK_ATTRIBUTE_TYPE type, PRBool haslock ) + { + CK_BBOOL ckvalue = CK_FALSE; + CK_ATTRIBUTE theTemplate; +@@ -156,10 +156,10 @@ PK11_HasAttributeSet( PK11SlotInfo *slot + PK11_SETATTRS( &theTemplate, type, &ckvalue, sizeof( CK_BBOOL ) ); + + /* Retrieve attribute value. */ +- PK11_EnterSlotMonitor(slot); ++ if (!haslock) PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB( slot )->C_GetAttributeValue( slot->session, id, + &theTemplate, 1 ); +- PK11_ExitSlotMonitor(slot); ++ if (!haslock) PK11_ExitSlotMonitor(slot); + if( crv != CKR_OK ) { + PORT_SetError( PK11_MapError( crv ) ); + return CK_FALSE; +@@ -254,7 +254,7 @@ PK11_GetAttributes(PRArenaPool *arena,PK + PRBool + PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle) + { +- return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN); ++ return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE); + } + + char * +@@ -735,6 +735,7 @@ PK11_Sign(SECKEYPrivateKey *key, SECItem + CK_MECHANISM mech = {0, NULL, 0 }; + PRBool owner = PR_TRUE; + CK_SESSION_HANDLE session; ++ PRBool haslock = PR_FALSE; + CK_ULONG len; + CK_RV crv; + +@@ -745,24 +746,27 @@ PK11_Sign(SECKEYPrivateKey *key, SECItem + } + + session = pk11_GetNewSession(slot,&owner); +- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); ++ haslock = (!owner || !(slot->isThreadSafe)); ++ if (haslock) PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); + if (crv != CKR_OK) { +- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); ++ if (haslock) PK11_ExitSlotMonitor(slot); + pk11_CloseSession(slot,session,owner); + PORT_SetError( PK11_MapError(crv) ); + return SECFailure; + } +- /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then +- * do C_Login with CKU_CONTEXT_SPECIFIC +- * between C_SignInit and C_Sign */ +- if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_ALWAYS_AUTHENTICATE)) { +- PK11_DoPassword(slot, PR_FALSE, key->wincx, PR_TRUE); +- } ++ ++ /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then ++ * do C_Login with CKU_CONTEXT_SPECIFIC ++ * between C_SignInit and C_Sign */ ++ if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { ++ PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); ++ } ++ + len = sig->len; + crv = PK11_GETTAB(slot)->C_Sign(session,hash->data, + hash->len, sig->data, &len); +- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); ++ if (haslock) PK11_ExitSlotMonitor(slot); + pk11_CloseSession(slot,session,owner); + sig->len = len; + if (crv != CKR_OK) { +@@ -788,6 +792,7 @@ pk11_PrivDecryptRaw(SECKEYPrivateKey *ke + CK_ULONG out = maxLen; + PRBool owner = PR_TRUE; + CK_SESSION_HANDLE session; ++ PRBool haslock = PR_FALSE; + CK_RV crv; + + if (key->keyType != rsaKey) { +@@ -803,23 +808,26 @@ pk11_PrivDecryptRaw(SECKEYPrivateKey *ke + PK11_HandlePasswordCheck(slot, key->wincx); + } + session = pk11_GetNewSession(slot,&owner); +- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); ++ haslock = (!owner || !(slot->isThreadSafe)); ++ if (haslock) PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID); + if (crv != CKR_OK) { +- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); ++ if (haslock) PK11_ExitSlotMonitor(slot); + pk11_CloseSession(slot,session,owner); + PORT_SetError( PK11_MapError(crv) ); + return SECFailure; + } +- /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then +- * do C_Login with CKU_CONTEXT_SPECIFIC +- * between C_DecryptInit and C_Decrypt */ +- /* But see note above about servers */ +- if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_ALWAYS_AUTHENTICATE)) { +- PK11_DoPassword(slot, PR_FALSE, key->wincx, PR_TRUE); +- } ++ ++ /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then ++ * do C_Login with CKU_CONTEXT_SPECIFIC ++ * between C_DecryptInit and C_Decrypt ++ * ... But see note above about servers */ ++ if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { ++ PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); ++ } ++ + crv = PK11_GETTAB(slot)->C_Decrypt(session,enc, encLen, data, &out); +- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); ++ if (haslock) PK11_ExitSlotMonitor(slot); + pk11_CloseSession(slot,session,owner); + *outLen = out; + if (crv != CKR_OK) { +Index: ./mozilla/security/nss/lib/pk11wrap/pk11priv.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/./mozilla/security/nss/lib/pk11wrap/pk11priv.h,v +retrieving revision 1.18 +diff -u -p -r1.18 pk11priv.h +--- ./mozilla/security/nss/lib/pk11wrap/pk11priv.h 16 May 2012 12:34:20 -0000 1.18 ++++ ./mozilla/security/nss/lib/pk11wrap/pk11priv.h 2 Nov 2012 18:09:55 -0000 +@@ -59,8 +59,9 @@ void PK11_CleanKeyList(PK11SlotInfo *slo + /************************************************************ + * Slot Password Management + ************************************************************/ +-SECStatus PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx, +- PRBool contextSpecific); ++SECStatus PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session, ++ PRBool loadCerts, void *wincx, PRBool alreadyLocked, ++ PRBool contextSpecific); + SECStatus PK11_VerifyPW(PK11SlotInfo *slot,char *pw); + void PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx); + void PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func); +@@ -121,7 +122,8 @@ CK_OBJECT_HANDLE PK11_MatchItem(PK11Slot + CK_OBJECT_CLASS o_class); + CK_BBOOL PK11_HasAttributeSet( PK11SlotInfo *slot, + CK_OBJECT_HANDLE id, +- CK_ATTRIBUTE_TYPE type ); ++ CK_ATTRIBUTE_TYPE type, ++ PRBool haslock ); + CK_RV PK11_GetAttributes(PLArenaPool *arena,PK11SlotInfo *slot, + CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count); + int PK11_NumberCertsForCertSubject(CERTCertificate *cert); diff --git a/nss.spec b/nss.spec index d2d9366..b7343d4 100644 --- a/nss.spec +++ b/nss.spec @@ -7,7 +7,7 @@ Summary: Network Security Services Name: nss Version: 3.14 -Release: 7%{?dist} +Release: 8%{?dist} License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Group: System Environment/Libraries @@ -67,6 +67,9 @@ Patch29: nss-ssl-cbc-random-iv-off-by-default.patch # TODO: Remove this patch when the ocsp test are fixed Patch40: nss-3.14.0.0-disble-ocsp-test.patch +# upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=357025 +Patch41: Bug-872838-fix-pk11wrap-locking.patch + %description Network Security Services (NSS) is a set of libraries designed to support cross-platform development of security-enabled client and @@ -148,6 +151,7 @@ low level services. # activate for stable and beta branches #%patch29 -p0 -b .770682 %patch40 -p1 -b .noocsptest +%patch41 -p0 -b .872838 %build @@ -580,6 +584,11 @@ rm -f $RPM_BUILD_ROOT/%{_includedir}/nss3/nsslowhash.h %changelog +* Sun Nov 04 2012 Elio Maldonado - 3.14-8 +- Fix pk11wrap locking to fix 'fedpkg new-sources' and 'fedpkg update' hangs +- Bug 87838 - nss-3.14 causes fedpkg new-sources breakage +- Fix should be considered preliminary since the patch may change upon upstream approval + * Thu Nov 01 2012 Elio Maldonado - 3.14-7 - Add a dummy source file for testing /preventing fedpkg breakage - Helps test the fedpkg new-sources and upload commands for breakage by nss updates