diff options
author | wtchang%redhat.com <devnull@localhost> | 2006-05-05 20:35:37 +0000 |
---|---|---|
committer | wtchang%redhat.com <devnull@localhost> | 2006-05-05 20:35:37 +0000 |
commit | 51a1377bda540505683bfcaa4ab17c1745fb4d32 (patch) | |
tree | 9739573efbab11ed4c29e57cc26b8484ee872f1d | |
parent | 392ce013cfc043f1664f52f7d8b9b2dc1280cf18 (diff) | |
download | nss-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.c | 188 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11.c | 24 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11c.c | 21 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11i.h | 3 | ||||
-rw-r--r-- | security/nss/lib/softoken/softoken.h | 7 | ||||
-rw-r--r-- | security/nss/lib/softoken/softoknt.h | 9 |
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_ */ |