summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Relyea <rrelyea@redhat.com>2023-04-12 08:19:35 -0700
committerRobert Relyea <rrelyea@redhat.com>2023-04-12 08:19:35 -0700
commit2386c64d2cf4194c8f63ae2e8d5b9e83544679eb (patch)
treeab0536e1141042e65242d1257534a8ae3f28f6ff
parentaf6cccfbf3d14f62f86e322ea56b4c3a4e3fd5df (diff)
downloadnss-hg-2386c64d2cf4194c8f63ae2e8d5b9e83544679eb.tar.gz
Bug 1806010 FIPS-104-3 requires we restart post programmatically
FIPS -140-3 requires that we give applications a way to restart the Power On Self-Tests programmatically. Unloading the shared library is insufficient. Shutting down softoken and restarting it with a special flag is. This path accomplishes this task by: 1) adding a new startup flag init argument flag called forcePost which is parsed at FC_Initialize time. 2) Code which checks if the post ran properly takes a new Bool which tells the function whether or not to rerun the post operations. If post operations are to be rerun, all test flags are set to unknown or fail and the tests are rerun. The results are returned. 3) Public facing functions to verify integrity looks for a special non-valid character flag as the first character of the filename and uses that to decide if we should rerun post or not. Callers add the flag if post should be rerun. 4) pk11mode, the general FIPS test program makes sure we can turn on the forcePost flag. Differential Revision: https://phabricator.services.mozilla.com/D165050
-rw-r--r--cmd/bltest/blapitest.c8
-rw-r--r--cmd/httpserv/httpserv.c5
-rw-r--r--cmd/lib/secutil.c6
-rw-r--r--cmd/nss-policy-check/nss-policy-check.c12
-rw-r--r--cmd/pk11mode/pk11mode.c12
-rw-r--r--cmd/selfserv/selfserv.c4
-rw-r--r--cmd/signtool/certgen.c22
-rw-r--r--lib/freebl/blapii.h2
-rw-r--r--lib/freebl/blapit.h4
-rw-r--r--lib/freebl/fipsfreebl.c10
-rw-r--r--lib/freebl/nsslowhash.c2
-rw-r--r--lib/freebl/shvfy.c351
-rw-r--r--lib/pki/tdcache.c6
-rw-r--r--lib/softoken/fipstest.c19
-rw-r--r--lib/softoken/fipstokn.c11
-rw-r--r--lib/softoken/pkcs11.c4
-rw-r--r--lib/softoken/pkcs11i.h1
-rw-r--r--lib/softoken/sftkdb.c12
-rw-r--r--lib/softoken/sftkpars.c13
-rw-r--r--lib/softoken/sftkpars.h14
-rw-r--r--lib/softoken/softoken.h2
-rw-r--r--lib/util/secport.h1
22 files changed, 285 insertions, 236 deletions
diff --git a/cmd/bltest/blapitest.c b/cmd/bltest/blapitest.c
index f0e3d3dff..0b86075b7 100644
--- a/cmd/bltest/blapitest.c
+++ b/cmd/bltest/blapitest.c
@@ -3047,7 +3047,7 @@ get_params(PLArenaPool *arena, bltestParams *params,
snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "key", j);
load_file_data(arena, &params->sk.key, filename, bltestBinary);
snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr,
- "params", j);
+ "params", j);
file = fopen(filename, "r");
if (!file)
return;
@@ -3255,12 +3255,12 @@ blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
}
for (j = 0; j < numtests; j++) {
snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr,
- "plaintext", j);
+ "plaintext", j);
load_file_data(arena, &pt, filename,
is_sigCipher(mode) ? bltestBase64Encoded
: bltestBinary);
snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr,
- "ciphertext", j);
+ "ciphertext", j);
load_file_data(arena, &ct, filename, bltestBase64Encoded);
get_params(arena, params, mode, j);
@@ -3871,7 +3871,7 @@ main(int argc, char **argv)
/* Do FIPS self-test */
if (bltest.commands[cmd_FIPS].activated) {
- CK_RV ckrv = sftk_FIPSEntryOK();
+ CK_RV ckrv = sftk_FIPSEntryOK(PR_FALSE);
fprintf(stdout, "CK_RV: %ld.\n", ckrv);
PORT_Free(cipherInfo);
if (ckrv == CKR_OK)
diff --git a/cmd/httpserv/httpserv.c b/cmd/httpserv/httpserv.c
index b4e4736ff..58014ac50 100644
--- a/cmd/httpserv/httpserv.c
+++ b/cmd/httpserv/httpserv.c
@@ -37,7 +37,6 @@
#include "ocspti.h"
#include "ocspi.h"
-
#ifndef PORT_Strstr
#define PORT_Strstr strstr
#endif
@@ -816,14 +815,14 @@ handle_connection(
numIOVs++;
} else if (reqLen <= 0) { /* hit eof */
snprintf(msgBuf, sizeof(msgBuf), "Get or Post incomplete after %d bytes.\r\n",
- bufDat);
+ bufDat);
iovs[numIOVs].iov_base = msgBuf;
iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
numIOVs++;
} else if (reqLen < bufDat) {
snprintf(msgBuf, sizeof(msgBuf), "Discarded %d characters.\r\n",
- bufDat - reqLen);
+ bufDat - reqLen);
iovs[numIOVs].iov_base = msgBuf;
iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
diff --git a/cmd/lib/secutil.c b/cmd/lib/secutil.c
index a290b8f7a..de10ce918 100644
--- a/cmd/lib/secutil.c
+++ b/cmd/lib/secutil.c
@@ -234,14 +234,14 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
switch (pwdata->source) {
case PW_NONE:
snprintf(prompt, sizeof(prompt), "Enter Password or Pin for \"%s\":",
- PK11_GetTokenName(slot));
+ PK11_GetTokenName(slot));
return SECU_GetPasswordString(NULL, prompt);
case PW_FROMFILE:
return SECU_FilePasswd(slot, retry, pwdata->data);
case PW_EXTERNAL:
snprintf(prompt, sizeof(prompt),
- "Press Enter, then enter PIN for \"%s\" on external device.\n",
- PK11_GetTokenName(slot));
+ "Press Enter, then enter PIN for \"%s\" on external device.\n",
+ PK11_GetTokenName(slot));
char *pw = SECU_GetPasswordString(NULL, prompt);
PORT_Free(pw);
/* Fall Through */
diff --git a/cmd/nss-policy-check/nss-policy-check.c b/cmd/nss-policy-check/nss-policy-check.c
index 0a77d7c7a..b806dfba6 100644
--- a/cmd/nss-policy-check/nss-policy-check.c
+++ b/cmd/nss-policy-check/nss-policy-check.c
@@ -221,12 +221,12 @@ breakout:
}
snprintf(moduleSpec, sizeof(moduleSpec),
- "name=\"Policy File\" "
- "parameters=\"configdir='sql:%s' "
- "secmod='%s' "
- "flags=readOnly,noCertDB,forceSecmodChoice,forceOpen\" "
- "NSS=\"flags=%s\"",
- path, filename, flags);
+ "name=\"Policy File\" "
+ "parameters=\"configdir='sql:%s' "
+ "secmod='%s' "
+ "flags=readOnly,noCertDB,forceSecmodChoice,forceOpen\" "
+ "NSS=\"flags=%s\"",
+ path, filename, flags);
module = SECMOD_LoadModule(moduleSpec, NULL, PR_TRUE);
if (!module || !module->loaded || atoi(PR_GetEnvSecure("NSS_POLICY_LOADED")) != 1) {
diff --git a/cmd/pk11mode/pk11mode.c b/cmd/pk11mode/pk11mode.c
index e761d5e65..caf1f90a8 100644
--- a/cmd/pk11mode/pk11mode.c
+++ b/cmd/pk11mode/pk11mode.c
@@ -322,6 +322,7 @@ main(int argc, char **argv)
CK_FUNCTION_LIST_PTR pFunctionList;
CK_RV crv = CKR_OK;
CK_C_INITIALIZE_ARGS_NSS initArgs;
+ CK_C_INITIALIZE_ARGS_NSS initArgsRerun; /* rerun selftests */
CK_SLOT_ID *pSlotList = NULL;
CK_TOKEN_INFO tokenInfo;
CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */
@@ -329,6 +330,7 @@ main(int argc, char **argv)
CK_UTF8CHAR *pwd = NULL;
CK_ULONG pwdLen = 0;
char *moduleSpec = NULL;
+ char *moduleSpecRerun = NULL;
char *configDir = NULL;
char *dbPrefix = NULL;
char *disableUnload = NULL;
@@ -462,8 +464,13 @@ main(int argc, char **argv)
moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
"keyPrefix='%s' secmod='secmod.db' flags= ",
configDir, dbPrefix, dbPrefix);
+ moduleSpecRerun = PR_smprintf("configdir='%s' certPrefix='%s' "
+ "keyPrefix='%s' secmod='secmod.db' flags=forcePOST ",
+ configDir, dbPrefix, dbPrefix);
initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec;
initArgs.pReserved = NULL;
+ initArgsRerun = initArgs;
+ initArgsRerun.LibraryParameters = (CK_CHAR_PTR *)moduleSpecRerun;
/*DebugBreak();*/
/* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */
@@ -709,7 +716,7 @@ main(int argc, char **argv)
if (doForkTests) {
/* testing one more C_Initialize / C_Finalize to exercise getpid()
* fork check code */
- crv = pFunctionList->C_Initialize(&initArgs);
+ crv = pFunctionList->C_Initialize(&initArgsRerun);
if (crv == CKR_OK) {
PKM_LogIt("C_Initialize succeeded\n");
} else {
@@ -745,6 +752,9 @@ cleanup:
if (moduleSpec) {
PR_smprintf_free(moduleSpec);
}
+ if (moduleSpecRerun) {
+ PR_smprintf_free(moduleSpecRerun);
+ }
#ifdef _WIN32
FreeLibrary(hModule);
diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c
index e41bbe3a8..7ad899a77 100644
--- a/cmd/selfserv/selfserv.c
+++ b/cmd/selfserv/selfserv.c
@@ -1532,14 +1532,14 @@ handle_connection(PRFileDesc *tcp_sock, PRFileDesc *model_sock)
}
} else if (reqLen <= 0) { /* hit eof */
snprintf(msgBuf, sizeof(msgBuf), "Get or Post incomplete after %d bytes.\r\n",
- bufDat);
+ bufDat);
iovs[numIOVs].iov_base = msgBuf;
iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
numIOVs++;
} else if (reqLen < bufDat) {
snprintf(msgBuf, sizeof(msgBuf), "Discarded %d characters.\r\n",
- bufDat - reqLen);
+ bufDat - reqLen);
iovs[numIOVs].iov_base = msgBuf;
iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
diff --git a/cmd/signtool/certgen.c b/cmd/signtool/certgen.c
index 442b0d616..a2d03f7c3 100644
--- a/cmd/signtool/certgen.c
+++ b/cmd/signtool/certgen.c
@@ -130,7 +130,7 @@ GetSubjectFromUser(unsigned long serial)
cp = chop(buf);
if (*cp == '\0') {
snprintf(common_name_buf, sizeof(common_name_buf), "%s (%lu)", DEFAULT_COMMON_NAME,
- serial);
+ serial);
cp = common_name_buf;
}
common_name = PORT_ZAlloc(strlen(cp) + 6);
@@ -261,7 +261,7 @@ GetSubjectFromUser(unsigned long serial)
if (!email) {
out_of_memory();
}
- snprintf(email,strlen(cp) + 5, "E=%s,", cp);
+ snprintf(email, strlen(cp) + 5, "E=%s,", cp);
subjectlen += strlen(email);
}
@@ -273,13 +273,13 @@ GetSubjectFromUser(unsigned long serial)
}
snprintf(subject, subjectlen, "%s%s%s%s%s%s%s",
- common_name ? common_name : "",
- org ? org : "",
- orgunit ? orgunit : "",
- state ? state : "",
- country ? country : "",
- uid ? uid : "",
- email ? email : "");
+ common_name ? common_name : "",
+ org ? org : "",
+ orgunit ? orgunit : "",
+ state ? state : "",
+ country ? country : "",
+ uid ? uid : "",
+ email ? email : "");
if ((strlen(subject) > 1) && (subject[strlen(subject) - 1] == ' ')) {
subject[strlen(subject) - 2] = '\0';
}
@@ -662,7 +662,7 @@ output_ca_cert(CERTCertificate *cert, CERTCertDBHandle *db)
if (!filename)
out_of_memory();
- snprintf(filename, strlen(DEFAULT_X509_BASENAME) + 8,"%s.raw", DEFAULT_X509_BASENAME);
+ snprintf(filename, strlen(DEFAULT_X509_BASENAME) + 8, "%s.raw", DEFAULT_X509_BASENAME);
if ((out = fopen(filename, "wb")) == NULL) {
PR_fprintf(errorFD, "%s: Can't open %s output file\n", PROGRAM_NAME,
filename);
@@ -691,7 +691,7 @@ output_ca_cert(CERTCertificate *cert, CERTCertDBHandle *db)
/* and the cooked */
- snprintf(filename,strlen(DEFAULT_X509_BASENAME) + 8, "%s.cacert", DEFAULT_X509_BASENAME);
+ snprintf(filename, strlen(DEFAULT_X509_BASENAME) + 8, "%s.cacert", DEFAULT_X509_BASENAME);
if ((out = fopen(filename, "wb")) == NULL) {
PR_fprintf(errorFD, "%s: Can't open %s output file\n", PROGRAM_NAME,
filename);
diff --git a/lib/freebl/blapii.h b/lib/freebl/blapii.h
index 7db57cdb0..a373b84d3 100644
--- a/lib/freebl/blapii.h
+++ b/lib/freebl/blapii.h
@@ -29,7 +29,7 @@ typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit);
SEC_BEGIN_PROTOS
#ifndef NSS_FIPS_DISABLED
-SECStatus BL_FIPSEntryOK(PRBool freeblOnly);
+SECStatus BL_FIPSEntryOK(PRBool freeblOnly, PRBool rerun);
PRBool BL_POSTRan(PRBool freeblOnly);
#endif
diff --git a/lib/freebl/blapit.h b/lib/freebl/blapit.h
index 0054e17b8..ff0d66639 100644
--- a/lib/freebl/blapit.h
+++ b/lib/freebl/blapit.h
@@ -228,6 +228,10 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
* to use a random value for the nonce in TLS. */
#define GCMIV_RANDOM_BIRTHDAY_BITS 64
+/* flag to tell BLAPI_Verify* to rerun the post and integrity tests */
+#define BLAPI_FIPS_RERUN_FLAG '\377' /* 0xff, 255 invalide code for UFT8/ASCII */
+#define BLAPI_FIPS_RERUN_FLAG_STRING "\377" /* The above as a C string */
+
/***************************************************************************
** Opaque objects
*/
diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c
index f05e31b92..6d24372d6 100644
--- a/lib/freebl/fipsfreebl.c
+++ b/lib/freebl/fipsfreebl.c
@@ -2216,7 +2216,7 @@ bl_startup_tests(void)
* power on selftest failed.
*/
SECStatus
-BL_FIPSEntryOK(PRBool freebl_only)
+BL_FIPSEntryOK(PRBool freebl_only, PRBool rerun)
{
#ifdef NSS_NO_INIT_SUPPORT
/* this should only be set on platforms that can't handle one of the INIT
@@ -2229,6 +2229,14 @@ BL_FIPSEntryOK(PRBool freebl_only)
bl_startup_tests();
}
#endif
+ if (rerun) {
+ /* reset the flags */
+ self_tests_freebl_ran = PR_FALSE;
+ self_tests_success = PR_FALSE;
+ self_tests_success = PR_FALSE;
+ self_tests_freebl_success = PR_FALSE;
+ bl_startup_tests();
+ }
/* if the general self tests succeeded, we're done */
if (self_tests_success) {
return SECSuccess;
diff --git a/lib/freebl/nsslowhash.c b/lib/freebl/nsslowhash.c
index e950e0865..7a22a357e 100644
--- a/lib/freebl/nsslowhash.c
+++ b/lib/freebl/nsslowhash.c
@@ -67,7 +67,7 @@ NSSLOW_Init(void)
/* make sure the FIPS product is installed if we are trying to
* go into FIPS mode */
if (nsslow_GetFIPSEnabled()) {
- if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
+ if (BL_FIPSEntryOK(PR_TRUE, PR_FALSE) != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
post_failed = PR_TRUE;
return NULL;
diff --git a/lib/freebl/shvfy.c b/lib/freebl/shvfy.c
index e713f64b0..15fde72b5 100644
--- a/lib/freebl/shvfy.c
+++ b/lib/freebl/shvfy.c
@@ -288,10 +288,10 @@ readItem(PRFileDesc *fd, SECItem *item)
return SECSuccess;
}
-static PRBool blapi_SHVerifyFile(const char *shName, PRBool self);
+static PRBool blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun);
static PRBool
-blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self)
+blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self, PRBool rerun)
{
PRBool result = PR_FALSE; /* if anything goes wrong,
* the signature does not verify */
@@ -300,7 +300,7 @@ blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self)
if (!shName) {
goto loser;
}
- result = blapi_SHVerifyFile(shName, self);
+ result = blapi_SHVerifyFile(shName, self, rerun);
loser:
if (shName != NULL) {
@@ -313,13 +313,23 @@ loser:
PRBool
BLAPI_SHVerify(const char *name, PRFuncPtr addr)
{
- return blapi_SHVerify(name, addr, PR_FALSE);
+ PRBool rerun = PR_FALSE;
+ if (name && *name == BLAPI_FIPS_RERUN_FLAG) {
+ name++;
+ rerun = PR_TRUE;
+ }
+ return blapi_SHVerify(name, addr, PR_FALSE, rerun);
}
PRBool
BLAPI_SHVerifyFile(const char *shName)
{
- return blapi_SHVerifyFile(shName, PR_FALSE);
+ PRBool rerun = PR_FALSE;
+ if (shName && *shName == BLAPI_FIPS_RERUN_FLAG) {
+ shName++;
+ rerun = PR_TRUE;
+ }
+ return blapi_SHVerifyFile(shName, PR_FALSE, rerun);
}
#ifndef NSS_STRICT_INTEGRITY
@@ -392,112 +402,113 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD, const SECHashObject *hashObj,
#ifdef NSS_STRICT_INTEGRITY
if (!blapi_HashAllowed(hashObj)) {
return PR_FALSE;
+ }
#endif
- hash.type = siBuffer;
- hash.data = hashBuf;
- hash.len = hashObj->length;
+ hash.type = siBuffer;
+ hash.data = hashBuf;
+ hash.len = hashObj->length;
- /* create an hmac for the library file */
- hmaccx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE);
- if (hmaccx == NULL) {
- return PR_FALSE;
- }
- HMAC_Begin(hmaccx);
+ /* create an hmac for the library file */
+ hmaccx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE);
+ if (hmaccx == NULL) {
+ return PR_FALSE;
+ }
+ HMAC_Begin(hmaccx);
- while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
- HMAC_Update(hmaccx, buf, bytesRead);
- }
- rv = HMAC_Finish(hmaccx, hash.data, &hash.len, hash.len);
+ while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
+ HMAC_Update(hmaccx, buf, bytesRead);
+ }
+ rv = HMAC_Finish(hmaccx, hash.data, &hash.len, hash.len);
- HMAC_Destroy(hmaccx, PR_TRUE);
+ HMAC_Destroy(hmaccx, PR_TRUE);
- /* verify the hmac against the check file */
- if (rv == SECSuccess) {
- result = SECITEM_ItemsAreEqual(signature, &hash);
- }
- PORT_Memset(hashBuf, 0, sizeof hashBuf);
- return result;
- }
-
- static PRBool
- blapi_SHVerifyFile(const char *shName, PRBool self)
- {
- char *checkName = NULL;
- PRFileDesc *checkFD = NULL;
- PRFileDesc *shFD = NULL;
- const SECHashObject *hashObj = NULL;
- SECItem signature = { 0, NULL, 0 };
- int bytesRead, offset, type;
- SECStatus rv;
- SECItem hmacKey = { 0, NULL, 0 };
+ /* verify the hmac against the check file */
+ if (rv == SECSuccess) {
+ result = SECITEM_ItemsAreEqual(signature, &hash);
+ }
+ PORT_Memset(hashBuf, 0, sizeof hashBuf);
+ return result;
+}
+
+static PRBool
+blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun)
+{
+ char *checkName = NULL;
+ PRFileDesc *checkFD = NULL;
+ PRFileDesc *shFD = NULL;
+ const SECHashObject *hashObj = NULL;
+ SECItem signature = { 0, NULL, 0 };
+ int bytesRead, offset, type;
+ SECStatus rv;
+ SECItem hmacKey = { 0, NULL, 0 };
#ifdef FREEBL_USE_PRELINK
- int pid = 0;
+ int pid = 0;
#endif
- PRBool result = PR_FALSE; /* if anything goes wrong,
- * the signature does not verify */
- NSSSignChkHeader header;
+ PRBool result = PR_FALSE; /* if anything goes wrong,
+ * the signature does not verify */
+ NSSSignChkHeader header;
#ifndef NSS_STRICT_INTEGRITY
- DSAPublicKey key;
+ DSAPublicKey key;
- PORT_Memset(&key, 0, sizeof(key));
+ PORT_Memset(&key, 0, sizeof(key));
#endif
- /* If our integrity check was never ran or failed, fail any other
+ /* If our integrity check was never ran or failed, fail any other
* integrity checks to prevent any token going into FIPS mode. */
- if (!self && (BL_FIPSEntryOK(PR_FALSE) != SECSuccess)) {
- return PR_FALSE;
- }
+ if (!self && (BL_FIPSEntryOK(PR_FALSE, rerun) != SECSuccess)) {
+ return PR_FALSE;
+ }
- if (!shName) {
- goto loser;
- }
+ if (!shName) {
+ goto loser;
+ }
- /* figure out the name of our check file */
- checkName = mkCheckFileName(shName);
- if (!checkName) {
- goto loser;
- }
+ /* figure out the name of our check file */
+ checkName = mkCheckFileName(shName);
+ if (!checkName) {
+ goto loser;
+ }
- /* open the check File */
- checkFD = PR_Open(checkName, PR_RDONLY, 0);
- if (checkFD == NULL) {
+ /* open the check File */
+ checkFD = PR_Open(checkName, PR_RDONLY, 0);
+ if (checkFD == NULL) {
#ifdef DEBUG_SHVERIFY
- fprintf(stderr, "Failed to open the check file %s: (%d, %d)\n",
- checkName, (int)PR_GetError(), (int)PR_GetOSError());
+ fprintf(stderr, "Failed to open the check file %s: (%d, %d)\n",
+ checkName, (int)PR_GetError(), (int)PR_GetOSError());
#endif /* DEBUG_SHVERIFY */
- goto loser;
- }
+ goto loser;
+ }
- /* read and Verify the headerthe header */
- bytesRead = PR_Read(checkFD, &header, sizeof(header));
- if (bytesRead != sizeof(header)) {
- goto loser;
- }
- if ((header.magic1 != NSS_SIGN_CHK_MAGIC1) ||
- (header.magic2 != NSS_SIGN_CHK_MAGIC2)) {
- goto loser;
- }
- /* we've bumped the version number so that newly signed .check
+ /* read and Verify the headerthe header */
+ bytesRead = PR_Read(checkFD, &header, sizeof(header));
+ if (bytesRead != sizeof(header)) {
+ goto loser;
+ }
+ if ((header.magic1 != NSS_SIGN_CHK_MAGIC1) ||
+ (header.magic2 != NSS_SIGN_CHK_MAGIC2)) {
+ goto loser;
+ }
+ /* we've bumped the version number so that newly signed .check
* files will fail nicely on old version of nss */
- if (header.majorVersion > NSS_SIGN_CHK_MAJOR_VERSION) {
- goto loser;
- }
- if (header.minorVersion < NSS_SIGN_CHK_MINOR_VERSION) {
- goto loser;
- }
- type = decodeInt(header.type);
+ if (header.majorVersion > NSS_SIGN_CHK_MAJOR_VERSION) {
+ goto loser;
+ }
+ if (header.minorVersion < NSS_SIGN_CHK_MINOR_VERSION) {
+ goto loser;
+ }
+ type = decodeInt(header.type);
- /* seek past any future header extensions */
- offset = decodeInt(header.offset);
- if (PR_Seek(checkFD, offset, PR_SEEK_SET) < 0) {
- goto loser;
- }
+ /* seek past any future header extensions */
+ offset = decodeInt(header.offset);
+ if (PR_Seek(checkFD, offset, PR_SEEK_SET) < 0) {
+ goto loser;
+ }
- switch (type) {
- case CKK_DSA:
+ switch (type) {
+ case CKK_DSA:
#ifdef NSS_STRICT_INTEGRITY
- goto loser;
+ goto loser;
#else
/* accept old dsa check files if NSS_STRICT_INTEGRITY is not set*/
/* read the key */
@@ -525,112 +536,112 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD, const SECHashObject *hashObj,
hashObj = HASH_GetRawHashObject(PQG_GetHashType(&key.params));
break;
#endif
- default:
- if ((type & NSS_SIGN_CHK_TYPE_FLAGS) != NSS_SIGN_CHK_FLAG_HMAC) {
- goto loser;
- }
- /* read the HMAC Key */
- rv = readItem(checkFD, &hmacKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* read the siganture */
- rv = readItem(checkFD, &signature);
- if (rv != SECSuccess) {
- goto loser;
- }
- hashObj = HASH_GetRawHashObject(type & ~NSS_SIGN_CHK_TYPE_FLAGS);
- }
+ default:
+ if ((type & NSS_SIGN_CHK_TYPE_FLAGS) != NSS_SIGN_CHK_FLAG_HMAC) {
+ goto loser;
+ }
+ /* read the HMAC Key */
+ rv = readItem(checkFD, &hmacKey);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ /* read the siganture */
+ rv = readItem(checkFD, &signature);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ hashObj = HASH_GetRawHashObject(type & ~NSS_SIGN_CHK_TYPE_FLAGS);
+ }
- /* done with the check file */
- PR_Close(checkFD);
- checkFD = NULL;
+ /* done with the check file */
+ PR_Close(checkFD);
+ checkFD = NULL;
- if (hashObj == NULL) {
- goto loser;
- }
+ if (hashObj == NULL) {
+ goto loser;
+ }
/* open our library file */
#ifdef FREEBL_USE_PRELINK
- shFD = bl_OpenUnPrelink(shName, &pid);
+ shFD = bl_OpenUnPrelink(shName, &pid);
#else
shFD = PR_Open(shName, PR_RDONLY, 0);
#endif
- if (shFD == NULL) {
+ if (shFD == NULL) {
#ifdef DEBUG_SHVERIFY
- fprintf(stderr, "Failed to open the library file %s: (%d, %d)\n",
- shName, (int)PR_GetError(), (int)PR_GetOSError());
+ fprintf(stderr, "Failed to open the library file %s: (%d, %d)\n",
+ shName, (int)PR_GetError(), (int)PR_GetOSError());
#endif /* DEBUG_SHVERIFY */
- goto loser;
- }
+ goto loser;
+ }
- switch (type) {
- case CKK_DSA:
+ switch (type) {
+ case CKK_DSA:
#ifndef NSS_STRICT_INTEGRITY
- result = blapi_SHVerifyDSACheck(shFD, hashObj, &key, &signature);
+ result = blapi_SHVerifyDSACheck(shFD, hashObj, &key, &signature);
#endif
+ break;
+ default:
+ if ((type & NSS_SIGN_CHK_TYPE_FLAGS) != NSS_SIGN_CHK_FLAG_HMAC) {
break;
- default:
- if ((type & NSS_SIGN_CHK_TYPE_FLAGS) != NSS_SIGN_CHK_FLAG_HMAC) {
- break;
- }
- result = blapi_SHVerifyHMACCheck(shFD, hashObj, &hmacKey, &signature);
- break;
- }
+ }
+ result = blapi_SHVerifyHMACCheck(shFD, hashObj, &hmacKey, &signature);
+ break;
+ }
#ifdef FREEBL_USE_PRELINK
- bl_CloseUnPrelink(shFD, pid);
+ bl_CloseUnPrelink(shFD, pid);
#else
PR_Close(shFD);
#endif
- shFD = NULL;
+ shFD = NULL;
- loser:
- PORT_Memset(&header, 0, sizeof header);
- if (checkName != NULL) {
- PORT_Free(checkName);
- }
- if (checkFD != NULL) {
- PR_Close(checkFD);
- }
- if (shFD != NULL) {
- PR_Close(shFD);
- }
- if (hmacKey.data != NULL) {
- SECITEM_ZfreeItem(&hmacKey, PR_FALSE);
- }
- if (signature.data != NULL) {
- SECITEM_ZfreeItem(&signature, PR_FALSE);
- }
+loser:
+ PORT_Memset(&header, 0, sizeof header);
+ if (checkName != NULL) {
+ PORT_Free(checkName);
+ }
+ if (checkFD != NULL) {
+ PR_Close(checkFD);
+ }
+ if (shFD != NULL) {
+ PR_Close(shFD);
+ }
+ if (hmacKey.data != NULL) {
+ SECITEM_ZfreeItem(&hmacKey, PR_FALSE);
+ }
+ if (signature.data != NULL) {
+ SECITEM_ZfreeItem(&signature, PR_FALSE);
+ }
#ifndef NSS_STRICT_INTEGRITY
- if (key.params.prime.data != NULL) {
- SECITEM_ZfreeItem(&key.params.prime, PR_FALSE);
- }
- if (key.params.subPrime.data != NULL) {
- SECITEM_ZfreeItem(&key.params.subPrime, PR_FALSE);
- }
- if (key.params.base.data != NULL) {
- SECITEM_ZfreeItem(&key.params.base, PR_FALSE);
- }
- if (key.publicValue.data != NULL) {
- SECITEM_ZfreeItem(&key.publicValue, PR_FALSE);
- }
-#endif
- return result;
+ if (key.params.prime.data != NULL) {
+ SECITEM_ZfreeItem(&key.params.prime, PR_FALSE);
+ }
+ if (key.params.subPrime.data != NULL) {
+ SECITEM_ZfreeItem(&key.params.subPrime, PR_FALSE);
+ }
+ if (key.params.base.data != NULL) {
+ SECITEM_ZfreeItem(&key.params.base, PR_FALSE);
}
+ if (key.publicValue.data != NULL) {
+ SECITEM_ZfreeItem(&key.publicValue, PR_FALSE);
+ }
+#endif
+ return result;
+}
- PRBool
- BLAPI_VerifySelf(const char *name)
- {
- if (name == NULL) {
- /*
- * If name is NULL, freebl is statically linked into softoken.
- * softoken will call BLAPI_SHVerify next to verify itself.
- */
- return PR_TRUE;
- }
- return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE);
+PRBool
+BLAPI_VerifySelf(const char *name)
+{
+ if (name == NULL) {
+ /*
+ * If name is NULL, freebl is statically linked into softoken.
+ * softoken will call BLAPI_SHVerify next to verify itself.
+ */
+ return PR_TRUE;
}
+ return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE, PR_FALSE);
+}
#else /* NSS_FIPS_DISABLED */
diff --git a/lib/pki/tdcache.c b/lib/pki/tdcache.c
index 8738ded9a..14cc563c4 100644
--- a/lib/pki/tdcache.c
+++ b/lib/pki/tdcache.c
@@ -41,13 +41,13 @@ log_item_dump(const char *msg, NSSItem *it)
char buf[33];
int i, j;
for (i = 0; i < 10 && i < it->size; i++) {
- snprintf(&buf[2 * i], sizeof(buf)-2*i, "%02X", ((PRUint8 *)it->data)[i]);
+ snprintf(&buf[2 * i], sizeof(buf) - 2 * i, "%02X", ((PRUint8 *)it->data)[i]);
}
if (it->size > 10) {
- snprintf(&buf[2 * i], sizeof(buf)-2*i, "..");
+ snprintf(&buf[2 * i], sizeof(buf) - 2 * i, "..");
i += 1;
for (j = it->size - 1; i <= 16 && j > 10; i++, j--) {
- snprintf(&buf[2 * i], sizeof(buf)-2*i, "%02X", ((PRUint8 *)it->data)[j]);
+ snprintf(&buf[2 * i], sizeof(buf) - 2 * i, "%02X", ((PRUint8 *)it->data)[j]);
}
}
PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg, buf));
diff --git a/lib/softoken/fipstest.c b/lib/softoken/fipstest.c
index 01d66427c..6010a50d6 100644
--- a/lib/softoken/fipstest.c
+++ b/lib/softoken/fipstest.c
@@ -690,11 +690,11 @@ static PRBool sftk_self_tests_success = PR_FALSE;
* This function is called at dll load time, the code tha makes this
* happen is platform specific on defined above.
*/
-static void
-sftk_startup_tests(void)
+void
+sftk_startup_tests_with_rerun(PRBool rerun)
{
SECStatus rv;
- const char *libraryName = SOFTOKEN_LIB_NAME;
+ const char *libraryName = rerun ? BLAPI_FIPS_RERUN_FLAG_STRING SOFTOKEN_LIB_NAME : SOFTOKEN_LIB_NAME;
PORT_Assert(!sftk_self_tests_ran);
PORT_Assert(!sftk_self_tests_success);
@@ -752,13 +752,19 @@ sftk_startup_tests(void)
sftk_self_tests_success = PR_TRUE;
}
+static void
+sftk_startup_tests(void)
+{
+ sftk_startup_tests_with_rerun(PR_FALSE);
+}
+
/*
* this is called from nsc_Common_Initizialize entry points that gates access
* to * all other pkcs11 functions. This prevents softoken operation if our
* power on selftest failed.
*/
CK_RV
-sftk_FIPSEntryOK()
+sftk_FIPSEntryOK(PRBool rerun)
{
#ifdef NSS_NO_INIT_SUPPORT
/* this should only be set on platforms that can't handle one of the INIT
@@ -771,6 +777,11 @@ sftk_FIPSEntryOK()
sftk_startup_tests();
}
#endif
+ if (rerun) {
+ sftk_self_tests_ran = PR_FALSE;
+ sftk_self_tests_success = PR_FALSE;
+ sftk_startup_tests_with_rerun(PR_TRUE);
+ }
if (!sftk_self_tests_success) {
return CKR_DEVICE_ERROR;
}
diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c
index 43e8c3847..cf5d73ce7 100644
--- a/lib/softoken/fipstokn.c
+++ b/lib/softoken/fipstokn.c
@@ -529,15 +529,22 @@ FC_Initialize(CK_VOID_PTR pReserved)
{
const char *envp;
CK_RV crv;
+ PRBool rerun;
if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
sftk_audit_enabled = (atoi(envp) == 1);
}
+ /* if we have the forcePOST flag on, rerun the integrity checks */
+ /* we need to know this before we fully parse the arguments in
+ * nsc_CommonInitialize, so read it now */
+ rerun = sftk_RawArgHasFlag("flags", "forcePost", pReserved);
+
/* At this point we should have already done post and integrity checks.
* if we haven't, it probably means the FIPS product has not been installed
- * or the tests failed. Don't let an application try to enter FIPS mode */
- crv = sftk_FIPSEntryOK();
+ * or the tests failed. Don't let an application try to enter FIPS mode. This
+ * also forces the tests to be rerun if forcePOST is set. */
+ crv = sftk_FIPSEntryOK(rerun);
if (crv != CKR_OK) {
sftk_fatalError = PR_TRUE;
fc_log_init_error(crv);
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
index e9dc09acf..a730ba397 100644
--- a/lib/softoken/pkcs11.c
+++ b/lib/softoken/pkcs11.c
@@ -2588,8 +2588,8 @@ sftk_getDefSlotName(CK_SLOT_ID slotID)
break;
}
snprintf(buf, sizeof(buf),
- "NSS Application Slot %08x ",
- (unsigned int)slotID);
+ "NSS Application Slot %08x ",
+ (unsigned int)slotID);
return buf;
}
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
index 3116de831..e4719a8ee 100644
--- a/lib/softoken/pkcs11i.h
+++ b/lib/softoken/pkcs11i.h
@@ -874,6 +874,7 @@ NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey);
*/
CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS);
void sftk_freeParams(sftk_parameters *params);
+PRBool sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved);
/*
* narrow objects
diff --git a/lib/softoken/sftkdb.c b/lib/softoken/sftkdb.c
index 90d49304d..8542a2d56 100644
--- a/lib/softoken/sftkdb.c
+++ b/lib/softoken/sftkdb.c
@@ -256,8 +256,8 @@ sftkdb_getRawAttributeSignature(SFTKDBHandle *handle, SDB *db,
CK_RV crv;
snprintf(id, sizeof(id), SFTKDB_META_SIG_TEMPLATE,
- sftkdb_TypeString(handle),
- (unsigned int)objectID, (unsigned int)type);
+ sftkdb_TypeString(handle),
+ (unsigned int)objectID, (unsigned int)type);
crv = (*db->sdb_GetMetaData)(db, id, signText, NULL);
return crv;
@@ -281,8 +281,8 @@ sftkdb_DestroyAttributeSignature(SFTKDBHandle *handle, SDB *db,
CK_RV crv;
snprintf(id, sizeof(id), SFTKDB_META_SIG_TEMPLATE,
- sftkdb_TypeString(handle),
- (unsigned int)objectID, (unsigned int)type);
+ sftkdb_TypeString(handle),
+ (unsigned int)objectID, (unsigned int)type);
crv = (*db->sdb_DestroyMetaData)(db, id);
return crv;
@@ -307,8 +307,8 @@ sftkdb_PutAttributeSignature(SFTKDBHandle *handle, SDB *keyTarget,
CK_RV crv;
snprintf(id, sizeof(id), SFTKDB_META_SIG_TEMPLATE,
- sftkdb_TypeString(handle),
- (unsigned int)objectID, (unsigned int)type);
+ sftkdb_TypeString(handle),
+ (unsigned int)objectID, (unsigned int)type);
crv = (*keyTarget->sdb_PutMetaData)(keyTarget, id, signText, NULL);
return crv;
diff --git a/lib/softoken/sftkpars.c b/lib/softoken/sftkpars.c
index 9c953b307..fdd08648f 100644
--- a/lib/softoken/sftkpars.c
+++ b/lib/softoken/sftkpars.c
@@ -253,3 +253,16 @@ sftk_freeParams(sftk_parameters *params)
FREE_CLEAR(params->updatedir);
FREE_CLEAR(params->updateID);
}
+
+PRBool
+sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved)
+{
+ CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved;
+
+ /* if we don't have any params, the flag isn't set */
+ if ((!init_args || !init_args->LibraryParameters)) {
+ return PR_FALSE;
+ }
+
+ return NSSUTIL_ArgHasFlag(entry, flag, (const char *)init_args->LibraryParameters);
+}
diff --git a/lib/softoken/sftkpars.h b/lib/softoken/sftkpars.h
deleted file mode 100644
index a7707fc2b..000000000
--- a/lib/softoken/sftkpars.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "pkcs11i.h"
-#include "sftkdbt.h"
-
-/* parsing functions */
-char *sftk_argFetchValue(char *string, int *pcount);
-char *sftk_getSecmodName(char *param, SDBType *dbType, char **appName, char **filename, PRBool *rw);
-char *sftk_argStrip(char *c);
-CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS);
-void sftk_freeParams(sftk_parameters *params);
-const char *sftk_EvaluateConfigDir(const char *configdir, SDBType *dbType, char **app);
-char *sftk_argGetParamValue(char *paramName, char *parameters);
diff --git a/lib/softoken/softoken.h b/lib/softoken/softoken.h
index 30586fcf4..dfb42b4e0 100644
--- a/lib/softoken/softoken.h
+++ b/lib/softoken/softoken.h
@@ -57,7 +57,7 @@ extern unsigned char *CBC_PadBuffer(PLArenaPool *arena, unsigned char *inbuf,
** Power-Up selftests are required for FIPS.
*/
/* make sure Power-up selftests have been run. */
-extern CK_RV sftk_FIPSEntryOK(void);
+extern CK_RV sftk_FIPSEntryOK(PRBool rerun);
/*
** make known fixed PKCS #11 key types to their sizes in bytes
diff --git a/lib/util/secport.h b/lib/util/secport.h
index c4d9b8183..fc1e1f538 100644
--- a/lib/util/secport.h
+++ b/lib/util/secport.h
@@ -197,7 +197,6 @@ SEC_END_PROTOS
#define PORT_Strstr strstr
#define PORT_Strtok strtok
-
#define PORT_Tolower tolower
typedef PRBool(PR_CALLBACK *PORTCharConversionWSwapFunc)(PRBool toUnicode,