summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtchang%redhat.com <devnull@localhost>2006-05-05 20:35:37 +0000
committerwtchang%redhat.com <devnull@localhost>2006-05-05 20:35:37 +0000
commit51a1377bda540505683bfcaa4ab17c1745fb4d32 (patch)
tree9739573efbab11ed4c29e57cc26b8484ee872f1d
parent392ce013cfc043f1664f52f7d8b9b2dc1280cf18 (diff)
downloadnss-hg-51a1377bda540505683bfcaa4ab17c1745fb4d32.tar.gz
Bugzilla Bug 298506: implemented FIPS 140-2 Security Level 2 audit
requirements. r=glen.beasley. Modified Files: Tag: NSS_3_11_BRANCH fipstokn.c pkcs11.c pkcs11c.c pkcs11i.h softoken.h softoknt.h
-rw-r--r--security/nss/lib/softoken/fipstokn.c188
-rw-r--r--security/nss/lib/softoken/pkcs11.c24
-rw-r--r--security/nss/lib/softoken/pkcs11c.c21
-rw-r--r--security/nss/lib/softoken/pkcs11i.h3
-rw-r--r--security/nss/lib/softoken/softoken.h7
-rw-r--r--security/nss/lib/softoken/softoknt.h9
6 files changed, 218 insertions, 34 deletions
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
index 9ef144cb8..73ec4b597 100644
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -55,9 +55,17 @@
#include "pcert.h"
#include "pkcs11.h"
#include "pkcs11i.h"
+#include "prenv.h"
+#include "prprf.h"
#include <ctype.h>
+#ifdef XP_UNIX
+#define NSS_AUDIT_WITH_SYSLOG 1
+#include <syslog.h>
+#include <unistd.h>
+#endif
+
/*
* ******************** Password Utilities *******************************
@@ -251,6 +259,58 @@ fips_login_if_key_object(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
return rv;
}
+/**********************************************************************
+ *
+ * FIPS 140 auditable event logging
+ *
+ **********************************************************************/
+
+PRBool sftk_audit_enabled = PR_FALSE;
+
+/*
+ * Each audit record must have the following information:
+ * - Date and time of the event
+ * - Type of event
+ * - user (subject) identity
+ * - outcome (success or failure) of the event
+ * - process ID
+ * - name (ID) of the object
+ * - for changes to data (except for authentication data and CSPs), the new
+ * and old values of the data
+ * - for authentication attempts, the origin of the attempt (e.g., terminal
+ * identifier)
+ * - for assuming a role, the type of role, and the location of the request
+ */
+void
+sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg)
+{
+#ifdef NSS_AUDIT_WITH_SYSLOG
+ SFTKSlot *slot = sftk_SlotFromID(FIPS_SLOT_ID, PR_FALSE);
+ const char *tokenLabel =
+ slot ? slot->tokDescription : sftk_getDefTokName(FIPS_SLOT_ID);
+ int level;
+
+ switch (severity) {
+ case NSS_AUDIT_ERROR:
+ level = LOG_ERR;
+ break;
+ case NSS_AUDIT_WARNING:
+ level = LOG_WARNING;
+ break;
+ default:
+ level = LOG_INFO;
+ break;
+ }
+ /* timestamp is provided by syslog in the message header */
+ /* tokenLabel points to a 32-byte label, which is not null-terminated */
+ syslog(level | LOG_USER /* facility */,
+ "%.32s[pid=%d uid=%d]: %s",
+ tokenLabel, (int)getpid(), (int)getuid(), msg);
+#else
+ /* do nothing */
+#endif
+}
+
/**********************************************************************
*
@@ -268,12 +328,17 @@ PRBool nsf_init = PR_FALSE;
/* FC_Initialize initializes the PKCS #11 library. */
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
+ const char *envp;
CK_RV crv;
if (nsf_init) {
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
+ if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
+ sftk_audit_enabled = (atoi(envp) == 1);
+ }
+
crv = nsc_CommonInitialize(pReserved, PR_TRUE);
/* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
@@ -288,6 +353,14 @@ CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
if (crv != CKR_OK) {
nsc_CommonFinalize(NULL, PR_TRUE);
fatalError = PR_TRUE;
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_Initialize()=0x%08lX "
+ "self-test: cryptographic algorithm test failed",
+ (PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
return crv;
}
nsf_init = PR_TRUE;
@@ -321,15 +394,7 @@ CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
-
- CK_RV crv;
-
- crv = NSC_GetSlotInfo(slotID,pInfo);
- if (crv != CKR_OK) {
- return crv;
- }
-
- return CKR_OK;
+ return NSC_GetSlotInfo(slotID,pInfo);
}
@@ -369,7 +434,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FC_InitToken initializes a token. */
CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
- return NSC_InitToken(slotID,pPin,usPinLen,pLabel);
+ CK_RV crv;
+
+ crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel);
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity = (crv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ /* pLabel points to a 32-byte label, which is not null-terminated */
+ PR_snprintf(msg,sizeof msg,
+ "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX",
+ (PRUint32)slotID,pLabel,(PRUint32)crv);
+ sftk_LogAuditMessage(severity, msg);
+ }
+ return crv;
}
@@ -377,9 +455,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
CK_RV rv;
- SFTK_FIPSFATALCHECK();
- if ((rv = sftk_newPinCheck(pPin,ulPinLen)) != CKR_OK) return rv;
- return NSC_InitPIN(hSession,pPin,ulPinLen);
+ if (fatalError) return CKR_DEVICE_ERROR;
+ if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
+ rv = NSC_InitPIN(hSession,pPin,ulPinLen);
+ }
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_InitPIN(hSession=%lu)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+ }
+ return rv;
}
@@ -388,9 +477,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
CK_RV rv;
- if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
- if ((rv = sftk_newPinCheck(pNewPin,usNewLen)) != CKR_OK) return rv;
- return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
+ if ((rv = sftk_fipsCheck()) == CKR_OK &&
+ (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
+ rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
+ }
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_SetPIN(hSession=%lu)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+ }
+ return rv;
}
/* FC_OpenSession opens a session between an application and a token. */
@@ -435,7 +535,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
CK_RV rv;
- SFTK_FIPSFATALCHECK();
+ if (fatalError) return CKR_DEVICE_ERROR;
rv = NSC_Login(hSession,userType,pPin,usPinLen);
if (rv == CKR_OK)
isLoggedIn = PR_TRUE;
@@ -443,22 +543,50 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
{
isLoggedIn = PR_TRUE;
- /* Provide FIPS PUB 140-1 power-up self-tests on demand. */
+ /* Provide FIPS PUB 140-2 power-up self-tests on demand. */
rv = sftk_fipsPowerUpSelfTest();
if (rv == CKR_OK)
- return CKR_USER_ALREADY_LOGGED_IN;
+ rv = CKR_USER_ALREADY_LOGGED_IN;
else
fatalError = PR_TRUE;
}
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity;
+ if (fatalError) {
+ severity = NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_Login(hSession=%lu, userType=%lu)=0x%08lX ",
+ "self-test: cryptographic algorithm test failed",
+ (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
+ } else {
+ severity = (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_Login(hSession=%lu, userType=%lu)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
+ }
+ sftk_LogAuditMessage(severity, msg);
+ }
return rv;
}
/* FC_Logout logs a user out from a token. */
CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
- SFTK_FIPSCHECK();
-
- rv = NSC_Logout(hSession);
- isLoggedIn = PR_FALSE;
+ CK_RV rv;
+ if ((rv = sftk_fipsCheck()) == CKR_OK) {
+ rv = NSC_Logout(hSession);
+ isLoggedIn = PR_FALSE;
+ }
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_Logout(hSession=%lu)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+ }
return rv;
}
@@ -982,13 +1110,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FC_GenerateRandom generates random data. */
CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen) {
+ CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) {
CK_RV crv;
SFTK_FIPSFATALCHECK();
- crv = NSC_GenerateRandom(hSession,pRandomData,usRandomLen);
+ crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
if (crv != CKR_OK) {
fatalError = PR_TRUE;
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_GenerateRandom(hSession=%lu, pRandomData=%p, "
+ "ulRandomLen=%lu)=0x%08lX "
+ "self-test: continuous RNG test failed",
+ (PRUint32)hSession,pRandomData,
+ (PRUint32)ulRandomLen,(PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
}
return crv;
}
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 6e3919328..2439e55bb 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -2355,7 +2355,7 @@ sftk_getDefTokName(CK_SLOT_ID slotID)
case PRIVATE_KEY_SLOT_ID:
return "NSS Certificate DB ";
case FIPS_SLOT_ID:
- return "NSS FIPS-140-1 Certificate DB ";
+ return "NSS FIPS 140-2 Certificate DB ";
default:
break;
}
@@ -2377,7 +2377,7 @@ sftk_getDefSlotName(CK_SLOT_ID slotID)
"NSS User Private Key and Certificate Services ";
case FIPS_SLOT_ID:
return
- "Netscape FIPS-140-1 User Private Key Services ";
+ "NSS FIPS 140-2 User Private Key Services ";
default:
break;
}
@@ -2410,6 +2410,9 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
{
SFTKSlot *slot;
int index = sftk_GetModuleIndex(slotID);
+ if (nscSlotHashTable[index] == NULL) {
+ return NULL;
+ }
slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
(void *)slotID);
/* cleared slots shouldn't 'show up' */
@@ -2981,6 +2984,14 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
if (!BLAPI_VerifySelf(NULL) ||
!BLAPI_SHVerify(SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_closePeer)) {
crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_Initialize()=0x%08lX "
+ "self-test: software/firmware integrity test failed",
+ (PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
return crv;
}
@@ -3052,6 +3063,13 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
* don't clobber each other. */
if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
sftk_closePeer(isFIPS);
+ if (sftk_audit_enabled) {
+ if (isFIPS && nsc_init) {
+ sftk_LogAuditMessage(NSS_AUDIT_INFO, "enabled FIPS mode");
+ } else {
+ sftk_LogAuditMessage(NSS_AUDIT_INFO, "disabled FIPS mode");
+ }
+ }
}
for (i=0; i < paramStrings.token_count; i++) {
@@ -3581,7 +3599,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
sftk_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */
}
if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index ca893afa3..76c79df25 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -73,6 +73,7 @@
#include "pcert.h"
#include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */
+#include "prprf.h"
#define __PASTE(x,y) x##y
@@ -3770,6 +3771,16 @@ ecgn_done:
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession,privateKey->handle);
sftk_FreeObject(privateKey);
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_GenerateKeyPair(hSession=%lu, "
+ "pMechanism->mechanism=0x%08lX)=0x%08lX "
+ "self-test: pair-wise consistency test failed",
+ (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
+ (PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
return crv;
}
@@ -5547,11 +5558,11 @@ key_and_mac_derive_fail:
}
/*
- * if keySize is supplied, then we are generating a key of a specific length.
- * This is done by taking the least significant 'keySize' bytes from the unsigned
- * value calculated by ECDH. Note: this may mean padding temp with extra leading
- * zeros from what ECDH_Derive already returned (which itself may contain leading
- * zeros).
+ * if keySize is supplied, then we are generating a key of a specific
+ * length. This is done by taking the least significant 'keySize'
+ * bytes from the unsigned value calculated by ECDH. Note: this may
+ * mean padding temp with extra leading zeros from what ECDH_Derive
+ * already returned (which itself may contain leading zeros).
*/
if (keySize) {
if (secretlen < keySize) {
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index 0eaf5bf37..1bd62b93c 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -555,7 +555,7 @@ typedef struct sftk_parametersStr {
SEC_BEGIN_PROTOS
-/* shared functions between PKCS11.c and SFTKFIPS.c */
+/* shared functions between pkcs11.c and fipstokn.c */
extern int nsf_init;
extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
@@ -635,6 +635,7 @@ extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle);
extern void sftk_FreeSession(SFTKSession *session);
extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
CK_VOID_PTR pApplication, CK_FLAGS flags);
+extern const char *sftk_getDefTokName(CK_SLOT_ID slotID);
extern void sftk_update_state(SFTKSlot *slot,SFTKSession *session);
extern void sftk_update_all_states(SFTKSlot *slot);
extern void sftk_FreeContext(SFTKSessionContext *context);
diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h
index 2f03e1990..9a06be831 100644
--- a/security/nss/lib/softoken/softoken.h
+++ b/security/nss/lib/softoken/softoken.h
@@ -177,6 +177,13 @@ extern CK_RV sftk_fipsPowerUpSelfTest( void );
*/
unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
+/*
+** FIPS 140-2 auditing
+*/
+extern PRBool sftk_audit_enabled;
+
+extern void sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg);
+
SEC_END_PROTOS
#endif /* _SOFTOKEN_H_ */
diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h
index b499eb6b0..3af94e286 100644
--- a/security/nss/lib/softoken/softoknt.h
+++ b/security/nss/lib/softoken/softoknt.h
@@ -61,4 +61,13 @@ typedef enum {
#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
+/*
+ * FIPS 140-2 auditing
+ */
+typedef enum {
+ NSS_AUDIT_ERROR = 3, /* errors */
+ NSS_AUDIT_WARNING = 2, /* warning messages */
+ NSS_AUDIT_INFO = 1 /* informational messages */
+} NSSAuditSeverity;
+
#endif /* _SOFTOKNT_H_ */