Blame SOURCES/nss-softokn-3.16.allow_level1_init.patch

6fbbf4
diff -up ./nss/lib/softoken/fipstokn.c.allow_level1_init ./nss/lib/softoken/fipstokn.c
6fbbf4
--- ./nss/lib/softoken/fipstokn.c.allow_level1_init	2014-11-04 13:49:38.110171007 -0800
6fbbf4
+++ ./nss/lib/softoken/fipstokn.c	2014-11-04 14:22:55.241646058 -0800
6fbbf4
@@ -595,8 +595,14 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID,
6fbbf4
     CHECK_FORK();
6fbbf4
 
6fbbf4
     if (sftk_fatalError) return CKR_DEVICE_ERROR;
6fbbf4
-    if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
6fbbf4
+    /* NSC_InitPIN will only work once per database. We can either initialize
6fbbf4
+     * it to level1 (pin len == 0) or level2. If we initialize to level 2, then
6fbbf4
+     * we need to make sure the pin meets FIPS requirements */
6fbbf4
+    if ((ulPinLen== 0) || ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK)) {
6fbbf4
 	rv = NSC_InitPIN(hSession,pPin,ulPinLen);
6fbbf4
+	if (rv == CKR_OK) {
6fbbf4
+	    isLevel2 = (ulPinLen > 0) ? PR_TRUE : PR_FALSE;
6fbbf4
+	}
6fbbf4
     }
6fbbf4
     if (sftk_audit_enabled) {
6fbbf4
 	char msg[128];
6fbbf4
@@ -622,6 +628,12 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID,
6fbbf4
     if ((rv = sftk_fipsCheck()) == CKR_OK &&
6fbbf4
 	(rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
6fbbf4
 	rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
6fbbf4
+	if (rv == CKR_OK) {
6fbbf4
+	    /* if we set the password in level1 we now go
6fbbf4
+	     * to level2. NOTE: we don't allow the user to
6fbbf4
+	     * go from level2 to level1 */
6fbbf4
+	    isLevel2 = PR_TRUE; 
6fbbf4
+	}
6fbbf4
     }
6fbbf4
     if (sftk_audit_enabled) {
6fbbf4
 	char msg[128];
6fbbf4
diff -up ./nss/lib/softoken/pkcs11.c.allow_level1_init ./nss/lib/softoken/pkcs11.c
6fbbf4
--- ./nss/lib/softoken/pkcs11.c.allow_level1_init	2014-11-04 13:49:38.178172148 -0800
6fbbf4
+++ ./nss/lib/softoken/pkcs11.c	2014-11-04 14:21:06.712827288 -0800
6fbbf4
@@ -2444,7 +2444,12 @@ SFTK_SlotReInit(SFTKSlot *slot, char *co
6fbbf4
 	if ((slot->minimumPinLen == 0) && (params->pwRequired)) {
6fbbf4
 	    slot->minimumPinLen = 1;
6fbbf4
 	}
6fbbf4
-	if ((moduleIndex == NSC_FIPS_MODULE) &&
6fbbf4
+	/* Make sure the pin len is set to the Minimum allowed value for fips
6fbbf4
+  	 * when in FIPS mode. NOTE: we don't set it if the database has not
6fbbf4
+  	 * been initialized yet so that we can init into level1 mode if needed
6fbbf4
+  	 */
6fbbf4
+	if ((sftkdb_HasPasswordSet(slot->keyDB) == SECSuccess) && 
6fbbf4
+		(moduleIndex == NSC_FIPS_MODULE) &&
6fbbf4
 		(slot->minimumPinLen < FIPS_MIN_PIN)) {
6fbbf4
 	    slot->minimumPinLen = FIPS_MIN_PIN;
6fbbf4
 	}
6fbbf4
@@ -3576,6 +3581,14 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSes
6fbbf4
     /* Now update our local copy of the pin */
6fbbf4
     if (rv == SECSuccess) {
6fbbf4
 	if (ulPinLen == 0) slot->needLogin = PR_FALSE;
6fbbf4
+	/* database has been initialized, now force min password in FIPS
6fbbf4
+  	 * mode. NOTE: if we are in level1, we may not have a password, but
6fbbf4
+  	 * forcing it now will prevent an insufficient password from being set.
6fbbf4
+  	 */
6fbbf4
+	if ((sftk_GetModuleIndex(slot->slotID) == NSC_FIPS_MODULE) &&
6fbbf4
+		(slot->minimumPinLen < FIPS_MIN_PIN)) {
6fbbf4
+	    slot->minimumPinLen = FIPS_MIN_PIN;
6fbbf4
+	}
6fbbf4
 	return CKR_OK;
6fbbf4
     }
6fbbf4
     crv = CKR_PIN_INCORRECT;