Blob Blame History Raw
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);