summaryrefslogtreecommitdiffstats
path: root/security/nss/cmd
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2020-01-02 21:06:40 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2020-01-02 21:06:40 +0100
commitf4a12fc67689a830e9da1c87fd11afe5bc09deb3 (patch)
tree211ae0cd022a6c11b0026ecc7761a550c584583c /security/nss/cmd
parentf7d30133221896638f7bf4f66c504255c4b14f48 (diff)
downloadUXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.gz
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.lz
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.xz
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.zip
Issue #1338 - Part 2: Update NSS to 3.48-RTM
Diffstat (limited to 'security/nss/cmd')
-rw-r--r--security/nss/cmd/addbuiltin/addbuiltin.c89
-rw-r--r--security/nss/cmd/atob/atob.c36
-rw-r--r--security/nss/cmd/btoa/btoa.c37
-rw-r--r--security/nss/cmd/certutil/certext.c50
-rw-r--r--security/nss/cmd/certutil/certutil.c9
-rw-r--r--security/nss/cmd/fipstest/README1
-rw-r--r--security/nss/cmd/fipstest/aes.sh112
-rw-r--r--security/nss/cmd/fipstest/aesgcm.sh67
-rwxr-xr-xsecurity/nss/cmd/fipstest/dsa.sh71
-rw-r--r--security/nss/cmd/fipstest/ecdsa.sh60
-rw-r--r--security/nss/cmd/fipstest/fipstest.c1381
-rwxr-xr-xsecurity/nss/cmd/fipstest/hmac.sh36
-rw-r--r--security/nss/cmd/fipstest/kas.sh84
-rw-r--r--security/nss/cmd/fipstest/rng.sh34
-rw-r--r--security/nss/cmd/fipstest/rsa.sh50
-rw-r--r--security/nss/cmd/fipstest/runtest.sh14
-rw-r--r--security/nss/cmd/fipstest/sha.sh66
-rw-r--r--security/nss/cmd/fipstest/tdea.sh106
-rw-r--r--security/nss/cmd/fipstest/tls.sh34
-rw-r--r--security/nss/cmd/fipstest/validate1.sh30
-rw-r--r--security/nss/cmd/httpserv/httpserv.c2
-rw-r--r--security/nss/cmd/lib/Makefile1
-rw-r--r--security/nss/cmd/lib/derprint.c4
-rw-r--r--security/nss/cmd/lib/lib.gyp3
-rw-r--r--security/nss/cmd/lib/manifest.mn2
-rw-r--r--security/nss/cmd/lib/pk11table.c2
-rw-r--r--security/nss/cmd/lib/secpwd.c2
-rw-r--r--security/nss/cmd/lib/secutil.c236
-rw-r--r--security/nss/cmd/lib/secutil.h14
-rw-r--r--security/nss/cmd/manifest.mn1
-rw-r--r--security/nss/cmd/p7env/p7env.c4
-rw-r--r--security/nss/cmd/pk11importtest/Makefile43
-rw-r--r--security/nss/cmd/pk11importtest/manifest.mn (renamed from security/nss/cmd/fipstest/validate.sh)16
-rw-r--r--security/nss/cmd/pk11importtest/pk11importtest.c408
-rw-r--r--security/nss/cmd/pk11importtest/pk11importtest.gyp25
-rw-r--r--security/nss/cmd/pk11mode/pk11mode.c2
-rw-r--r--security/nss/cmd/pk12util/pk12util.c1
-rw-r--r--security/nss/cmd/platlibs.mk4
-rw-r--r--security/nss/cmd/selfserv/selfserv.c105
-rw-r--r--security/nss/cmd/shlibsign/shlibsign.c2
-rw-r--r--security/nss/cmd/ssltap/ssltap.c1
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c78
-rw-r--r--security/nss/cmd/symkeyutil/symkeyutil.c2
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c85
-rw-r--r--security/nss/cmd/vfyserv/vfyserv.c7
45 files changed, 2503 insertions, 914 deletions
diff --git a/security/nss/cmd/addbuiltin/addbuiltin.c b/security/nss/cmd/addbuiltin/addbuiltin.c
index 831672039..565588872 100644
--- a/security/nss/cmd/addbuiltin/addbuiltin.c
+++ b/security/nss/cmd/addbuiltin/addbuiltin.c
@@ -230,6 +230,8 @@ ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust,
hasPositiveTrust(trust->objectSigningFlags)) {
printf("CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE\n");
}
+ printf("CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE\n");
+ printf("CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE\n");
}
if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags) ==
@@ -306,19 +308,21 @@ printheader()
"#\n"
"# Certificates\n"
"#\n"
- "# -- Attribute -- -- type -- -- value --\n"
- "# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n"
- "# CKA_TOKEN CK_BBOOL CK_TRUE\n"
- "# CKA_PRIVATE CK_BBOOL CK_FALSE\n"
- "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"
- "# CKA_LABEL UTF8 (varies)\n"
- "# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n"
- "# CKA_SUBJECT DER+base64 (varies)\n"
- "# CKA_ID byte array (varies)\n"
- "# CKA_ISSUER DER+base64 (varies)\n"
- "# CKA_SERIAL_NUMBER DER+base64 (varies)\n"
- "# CKA_VALUE DER+base64 (varies)\n"
- "# CKA_NSS_EMAIL ASCII7 (unused here)\n"
+ "# -- Attribute -- -- type -- -- value --\n"
+ "# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n"
+ "# CKA_TOKEN CK_BBOOL CK_TRUE\n"
+ "# CKA_PRIVATE CK_BBOOL CK_FALSE\n"
+ "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"
+ "# CKA_LABEL UTF8 (varies)\n"
+ "# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n"
+ "# CKA_SUBJECT DER+base64 (varies)\n"
+ "# CKA_ID byte array (varies)\n"
+ "# CKA_ISSUER DER+base64 (varies)\n"
+ "# CKA_SERIAL_NUMBER DER+base64 (varies)\n"
+ "# CKA_VALUE DER+base64 (varies)\n"
+ "# CKA_NSS_EMAIL ASCII7 (unused here)\n"
+ "# CKA_NSS_SERVER_DISTRUST_AFTER DER+base64 (varies)\n"
+ "# CKA_NSS_EMAIL_DISTRUST_AFTER DER+base64 (varies)\n"
"#\n"
"# Trust\n"
"#\n"
@@ -392,6 +396,12 @@ Usage(char *progName)
fprintf(stderr, "%-15s a CRL entry number, as shown by \"crlutil -S\"\n", "-e");
fprintf(stderr, "%-15s input file to read (default stdin)\n", "-i file");
fprintf(stderr, "%-15s (pipe through atob if the cert is b64-encoded)\n", "");
+ fprintf(stderr, "%-15s convert a timestamp to DER, and output.\n", "-d timestamp");
+ fprintf(stderr, "%-15s useful to fill server and email distrust fields\n", "");
+ fprintf(stderr, "%-15s Example: %s -d 1561939200\n", "", progName);
+ fprintf(stderr, "%-15s NOTE: The informed timestamp are interpreted as seconds\n", "");
+ fprintf(stderr, "%-15s since unix epoch.\n", "");
+ fprintf(stderr, "%-15s TIP: date -d \"2019-07-01 00:00:00 UTC\" +%%s\n", "");
exit(-1);
}
@@ -403,20 +413,21 @@ enum {
opt_ExcludeCert,
opt_ExcludeHash,
opt_DistrustCRL,
- opt_CRLEnry
+ opt_CRLEntry,
+ opt_ConvertDate
};
-static secuCommandFlag addbuiltin_options[] =
- {
- { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
- { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
- { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE },
- { /* opt_Distrust */ 'D', PR_FALSE, 0, PR_FALSE },
- { /* opt_ExcludeCert */ 'c', PR_FALSE, 0, PR_FALSE },
- { /* opt_ExcludeHash */ 'h', PR_FALSE, 0, PR_FALSE },
- { /* opt_DistrustCRL */ 'C', PR_FALSE, 0, PR_FALSE },
- { /* opt_CRLEnry */ 'e', PR_TRUE, 0, PR_FALSE },
- };
+static secuCommandFlag addbuiltin_options[] = {
+ { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Distrust */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ExcludeCert */ 'c', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ExcludeHash */ 'h', PR_FALSE, 0, PR_FALSE },
+ { /* opt_DistrustCRL */ 'C', PR_FALSE, 0, PR_FALSE },
+ { /* opt_CRLEntry */ 'e', PR_TRUE, 0, PR_FALSE },
+ { /* opt_ConvertDate */ 'd', PR_TRUE, 0, PR_FALSE },
+};
int
main(int argc, char **argv)
@@ -444,6 +455,30 @@ main(int argc, char **argv)
if (rv != SECSuccess)
Usage(progName);
+ if (addbuiltin.options[opt_ConvertDate].activated) {
+ char *endPtr;
+ PRTime distrustTimestamp = strtol(addbuiltin.options[opt_ConvertDate].arg, &endPtr, 0) * PR_USEC_PER_SEC;
+ if (*endPtr != '\0' && distrustTimestamp > 0) {
+ Usage(progName);
+ exit(1);
+ }
+ SECItem encTime;
+ DER_EncodeTimeChoice(NULL, &encTime, distrustTimestamp);
+ SECU_PrintTimeChoice(stdout, &encTime, "The timestamp represents this date", 0);
+ printf("Locate the entry of the desired certificate in certdata.txt\n"
+ "Erase the CKA_NSS_[SERVER|EMAIL]_DISTRUST_AFTER CK_BBOOL CK_FALSE\n"
+ "And override with the following respective entry:\n\n");
+ SECU_PrintTimeChoice(stdout, &encTime, "# For Server Distrust After", 0);
+ printf("CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL\n");
+ dumpbytes(encTime.data, encTime.len);
+ printf("END\n");
+ SECU_PrintTimeChoice(stdout, &encTime, "# For Email Distrust After", 0);
+ printf("CKA_NSS_EMAIL_DISTRUST_AFTER MULTILINE_OCTAL\n");
+ dumpbytes(encTime.data, encTime.len);
+ printf("END\n");
+ exit(0);
+ }
+
if (addbuiltin.options[opt_Trust].activated)
++mutuallyExclusiveOpts;
if (addbuiltin.options[opt_Distrust].activated)
@@ -458,12 +493,12 @@ main(int argc, char **argv)
}
if (addbuiltin.options[opt_DistrustCRL].activated) {
- if (!addbuiltin.options[opt_CRLEnry].activated) {
+ if (!addbuiltin.options[opt_CRLEntry].activated) {
fprintf(stderr, "%s: you must specify the CRL entry number.\n",
progName);
Usage(progName);
} else {
- crlentry = atoi(addbuiltin.options[opt_CRLEnry].arg);
+ crlentry = atoi(addbuiltin.options[opt_CRLEntry].arg);
if (crlentry < 1) {
fprintf(stderr, "%s: The CRL entry number must be > 0.\n",
progName);
diff --git a/security/nss/cmd/atob/atob.c b/security/nss/cmd/atob/atob.c
index 115b0e9a0..3e15ceadb 100644
--- a/security/nss/cmd/atob/atob.c
+++ b/security/nss/cmd/atob/atob.c
@@ -105,7 +105,6 @@ Usage(char *progName)
"-i input");
fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
"-o output");
- exit(-1);
}
int
@@ -113,12 +112,12 @@ main(int argc, char **argv)
{
char *progName;
SECStatus rv;
- FILE *inFile, *outFile;
- PLOptState *optstate;
+ FILE *inFile = NULL, *outFile = NULL;
+ PRBool closeIn = PR_TRUE, closeOut = PR_TRUE;
+ PLOptState *optstate = NULL;
PLOptStatus status;
+ int exitCode = -1;
- inFile = 0;
- outFile = 0;
progName = strrchr(argv[0], '/');
progName = progName ? progName + 1 : argv[0];
@@ -129,6 +128,7 @@ main(int argc, char **argv)
case '?':
case 'h':
Usage(progName);
+ goto loser;
break;
case 'i':
@@ -136,7 +136,7 @@ main(int argc, char **argv)
if (!inFile) {
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
progName, optstate->value);
- return -1;
+ goto loser;
}
break;
@@ -145,13 +145,15 @@ main(int argc, char **argv)
if (!outFile) {
fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
progName, optstate->value);
- return -1;
+ goto loser;
}
break;
}
}
- if (!inFile)
+ if (!inFile) {
inFile = stdin;
+ closeIn = PR_FALSE;
+ }
if (!outFile) {
#if defined(WIN32)
int smrv = _setmode(_fileno(stdout), _O_BINARY);
@@ -159,16 +161,28 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: Cannot change stdout to binary mode. Use -o option instead.\n",
progName);
- return smrv;
+ goto loser;
}
#endif
outFile = stdout;
+ closeOut = PR_FALSE;
}
rv = decode_file(outFile, inFile);
if (rv != SECSuccess) {
fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
progName, PORT_GetError(), errno);
- return -1;
+ goto loser;
+ }
+ exitCode = 0;
+loser:
+ if (optstate) {
+ PL_DestroyOptState(optstate);
+ }
+ if (inFile && closeIn) {
+ fclose(inFile);
+ }
+ if (outFile && closeOut) {
+ fclose(outFile);
}
- return 0;
+ return exitCode;
}
diff --git a/security/nss/cmd/btoa/btoa.c b/security/nss/cmd/btoa/btoa.c
index 2a5e6d4c6..f82341325 100644
--- a/security/nss/cmd/btoa/btoa.c
+++ b/security/nss/cmd/btoa/btoa.c
@@ -99,7 +99,6 @@ Usage(char *progName)
"-w suffix");
fprintf(stderr, "%-20s (use \"c\" as a shortcut for suffix CERTIFICATE)\n",
"");
- exit(-1);
}
int
@@ -107,13 +106,13 @@ main(int argc, char **argv)
{
char *progName;
SECStatus rv;
- FILE *inFile, *outFile;
- PLOptState *optstate;
+ FILE *inFile = NULL, *outFile = NULL;
+ PRBool closeIn = PR_TRUE, closeOut = PR_TRUE;
+ PLOptState *optstate = NULL;
PLOptStatus status;
char *suffix = NULL;
+ int exitCode = -1;
- inFile = 0;
- outFile = 0;
progName = strrchr(argv[0], '/');
if (!progName)
progName = strrchr(argv[0], '\\');
@@ -121,10 +120,12 @@ main(int argc, char **argv)
/* Parse command line arguments */
optstate = PL_CreateOptState(argc, argv, "i:o:w:");
+ PORT_Assert(optstate);
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
default:
Usage(progName);
+ goto loser;
break;
case 'i':
@@ -132,7 +133,7 @@ main(int argc, char **argv)
if (!inFile) {
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
progName, optstate->value);
- return -1;
+ goto loser;
}
break;
@@ -141,7 +142,7 @@ main(int argc, char **argv)
if (!outFile) {
fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
progName, optstate->value);
- return -1;
+ goto loser;
}
break;
@@ -166,10 +167,11 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: Cannot change stdin to binary mode. Use -i option instead.\n",
progName);
- return smrv;
+ goto loser;
}
#endif
inFile = stdin;
+ closeIn = PR_FALSE;
}
if (!outFile) {
#if defined(WIN32)
@@ -182,10 +184,11 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: Cannot change stdout to binary mode. Use -o option instead.\n",
progName);
- return smrv;
+ goto loser;
}
#endif
outFile = stdout;
+ closeOut = PR_FALSE;
}
if (suffix) {
fprintf(outFile, "-----BEGIN %s-----\n", suffix);
@@ -194,10 +197,22 @@ main(int argc, char **argv)
if (rv != SECSuccess) {
fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
progName, PORT_GetError(), errno);
- return -1;
+ goto loser;
}
if (suffix) {
fprintf(outFile, "-----END %s-----\n", suffix);
}
- return 0;
+ exitCode = 0;
+loser:
+ PL_DestroyOptState(optstate);
+ if (inFile && closeIn) {
+ fclose(inFile);
+ }
+ if (outFile && closeOut) {
+ fclose(outFile);
+ }
+ if (suffix) {
+ PORT_Free(suffix);
+ }
+ return exitCode;
}
diff --git a/security/nss/cmd/certutil/certext.c b/security/nss/cmd/certutil/certext.c
index 0be3eb120..501608c85 100644
--- a/security/nss/cmd/certutil/certext.c
+++ b/security/nss/cmd/certutil/certext.c
@@ -497,6 +497,13 @@ static const char *const
"ocspResponder",
"stepUp",
"msTrustListSigning",
+ "x509Any",
+ "ipsecIKE",
+ "ipsecIKEEnd",
+ "ipsecIKEIntermediate",
+ "ipsecEnd",
+ "ipsecTunnel",
+ "ipsecUser",
NULL };
static SECStatus
@@ -517,6 +524,10 @@ AddExtKeyUsage(void *extHandle, const char *userSuppliedValue)
while (1) {
if (!userSuppliedValue) {
+ /*
+ * none of the 'new' extended key usage options work with the prompted menu. This is so
+ * old scripts can continue to work.
+ */
if (PrintChoicesAndGetAnswer(
"\t\t0 - Server Auth\n"
"\t\t1 - Client Auth\n"
@@ -572,6 +583,45 @@ AddExtKeyUsage(void *extHandle, const char *userSuppliedValue)
case 7:
rv = AddOidToSequence(os, SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING);
break;
+ /*
+ * These new usages can only be added explicitly by the userSuppliedValues. This allows old
+ * scripts which used '>7' as an exit value to continue to work.
+ */
+ case 8:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_X509_ANY_EXT_KEY_USAGE);
+ break;
+ case 9:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_IKE);
+ break;
+ case 10:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_IPSEC_IKE_END);
+ break;
+ case 11:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_IPSEC_IKE_INTERMEDIATE);
+ break;
+ case 12:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_END);
+ break;
+ case 13:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL);
+ break;
+ case 14:
+ if (!userSuppliedValue)
+ goto endloop;
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_USER);
+ break;
default:
goto endloop;
}
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c
index df02e4439..16a9bf16e 100644
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -1362,8 +1362,11 @@ luC(enum usage_level ul, const char *command)
"%-20s Create extended key usage extension. Possible keywords:\n"
"%-20s \"serverAuth\", \"clientAuth\",\"codeSigning\",\n"
"%-20s \"emailProtection\", \"timeStamp\",\"ocspResponder\",\n"
- "%-20s \"stepUp\", \"msTrustListSign\", \"critical\"\n",
- " -6 | --extKeyUsage keyword,keyword,...", "", "", "", "");
+ "%-20s \"stepUp\", \"msTrustListSign\", \"x509Any\",\n"
+ "%-20s \"ipsecIKE\", \"ipsecIKEEnd\", \"ipsecIKEIntermediate\",\n"
+ "%-20s \"ipsecEnd\", \"ipsecTunnel\", \"ipsecUser\",\n"
+ "%-20s \"critical\"\n",
+ " -6 | --extKeyUsage keyword,keyword,...", "", "", "", "", "", "", "");
FPS "%-20s Create an email subject alt name extension\n",
" -7 emailAddrs");
FPS "%-20s Create an dns subject alt name extension\n",
@@ -3120,7 +3123,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
PR_fprintf(PR_STDERR,
"%s -%c: specify a nickname (-n) or\n"
" a key ID (-k).\n",
- commandToRun, progName);
+ progName, commandToRun);
return 255;
}
diff --git a/security/nss/cmd/fipstest/README b/security/nss/cmd/fipstest/README
new file mode 100644
index 000000000..8f076587d
--- /dev/null
+++ b/security/nss/cmd/fipstest/README
@@ -0,0 +1 @@
+The scripts have been moved to tests/fips/cavs_scripts
diff --git a/security/nss/cmd/fipstest/aes.sh b/security/nss/cmd/fipstest/aes.sh
deleted file mode 100644
index 7e25e60d2..000000000
--- a/security/nss/cmd/fipstest/aes.sh
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-#
-# A Bourne shell script for running the NIST AES Algorithm Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/AES
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-cbc_kat_requests="
-CBCGFSbox128.req
-CBCGFSbox192.req
-CBCGFSbox256.req
-CBCKeySbox128.req
-CBCKeySbox192.req
-CBCKeySbox256.req
-CBCVarKey128.req
-CBCVarKey192.req
-CBCVarKey256.req
-CBCVarTxt128.req
-CBCVarTxt192.req
-CBCVarTxt256.req
-"
-
-cbc_mct_requests="
-CBCMCT128.req
-CBCMCT192.req
-CBCMCT256.req
-"
-
-cbc_mmt_requests="
-CBCMMT128.req
-CBCMMT192.req
-CBCMMT256.req
-"
-
-ecb_kat_requests="
-ECBGFSbox128.req
-ECBGFSbox192.req
-ECBGFSbox256.req
-ECBKeySbox128.req
-ECBKeySbox192.req
-ECBKeySbox256.req
-ECBVarKey128.req
-ECBVarKey192.req
-ECBVarKey256.req
-ECBVarTxt128.req
-ECBVarTxt192.req
-ECBVarTxt256.req
-"
-
-ecb_mct_requests="
-ECBMCT128.req
-ECBMCT192.req
-ECBMCT256.req
-"
-
-ecb_mmt_requests="
-ECBMMT128.req
-ECBMMT192.req
-ECBMMT256.req
-"
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do
- sh ./validate1.sh ${TESTDIR} $request
- done
- exit 0
-fi
-
-for request in $cbc_kat_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $cbc_mct_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $cbc_mmt_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $ecb_kat_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $ecb_mct_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $ecb_mmt_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
-done
diff --git a/security/nss/cmd/fipstest/aesgcm.sh b/security/nss/cmd/fipstest/aesgcm.sh
deleted file mode 100644
index 3b4dcf5e4..000000000
--- a/security/nss/cmd/fipstest/aesgcm.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST AES Algorithm Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/AES_GCM
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-gcm_decrypt_requests="
-gcmDecrypt128.req
-gcmDecrypt192.req
-gcmDecrypt256.req
-"
-
-gcm_encrypt_extiv_requests="
-gcmEncryptExtIV128.req
-gcmEncryptExtIV192.req
-gcmEncryptExtIV256.req
-"
-gcm_encrypt_intiv_requests="
-"
-
-#gcm_encrypt_intiv_requests="
-#gcmEncryptIntIV128.req
-#gcmEncryptIntIV192.req
-#gcmEncryptIntIV256.req
-#"
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do
- sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d'
- done
- for request in $gcm_encrypt_intiv_requests; do
- name=`basename $request .req`
- echo ">>>>> $name"
- fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL
- done
- exit 0
-fi
-
-for request in $gcm_decrypt_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $gcm_encrypt_intiv_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $gcm_encrypt_extiv_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response
-done
diff --git a/security/nss/cmd/fipstest/dsa.sh b/security/nss/cmd/fipstest/dsa.sh
deleted file mode 100755
index da18e1fa3..000000000
--- a/security/nss/cmd/fipstest/dsa.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST DSA Validation System
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/DSA2
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-
-#
-# several of the DSA tests do use known answer tests to verify the result.
-# in those cases, feed generated tests back into the fipstest tool and
-# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify
-# the dsa pqgver and dsa sigver functions, so we know they can detect errors
-# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
-#
-if [ ${COMMAND} = "verify" ]; then
-# verify generated keys
- name=KeyPair
- echo ">>>>> $name"
- fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify generated pqg values
- name=PQGGen
- echo ">>>>> $name"
- fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify PQGVer with known answer
-# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
-# verify signatures
- name=SigGen
- echo ">>>>> $name"
- fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify SigVer with known answer
- sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
- exit 0
-fi
-
-request=KeyPair.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=PQGGen.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=PQGVer1863.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=SigGen.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=SigVer.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff --git a/security/nss/cmd/fipstest/ecdsa.sh b/security/nss/cmd/fipstest/ecdsa.sh
deleted file mode 100644
index 9482160cc..000000000
--- a/security/nss/cmd/fipstest/ecdsa.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST ECDSA Validation System
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/ECDSA2
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-#
-# several of the ECDSA tests do not use known answer tests to verify the result.
-# In those cases, feed generated tests back into the fipstest tool and
-# see if we can verify those value. NOTE: PQGVer and SigVer tests verify
-# the dsa pqgver and dsa sigver functions, so we know they can detect errors
-# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
-#
-if [ ${COMMAND} = "verify" ]; then
-# verify generated keys
- name=KeyPair
- echo ">>>>> $name"
- fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
- sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
-# verify signatures
- name=SigGen
- echo ">>>>> $name"
- fipstest ecdsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify SigVer with known answer
- sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
- exit 0
-fi
-
-request=KeyPair.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=PKV.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=SigGen.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=SigVer.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c
index 5d00b3070..1a8008d59 100644
--- a/security/nss/cmd/fipstest/fipstest.c
+++ b/security/nss/cmd/fipstest/fipstest.c
@@ -34,6 +34,11 @@
#if 0
#include "../../lib/freebl/mpi/mpi.h"
#endif
+#define MATCH_OPENSSL 1
+/*#define MATCH_NIST 1 */
+#ifdef MATCH_NIST
+#define VERBOSE_REASON 1
+#endif
extern SECStatus
EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
@@ -3169,6 +3174,10 @@ ecdh_functional(char *reqfn, PRBool response)
fprintf(stderr, "generate key was compressed\n");
goto loser;
}
+ fputs("deIUT = ", ecdhresp);
+ to_hex_str(buf, ecpriv->privateValue.data, ecpriv->privateValue.len);
+ fputs(buf, ecdhresp);
+ fputc('\n', ecdhresp);
fputs("QeIUTx = ", ecdhresp);
to_hex_str(buf, &ecpriv->publicValue.data[1], uit_len);
fputs(buf, ecdhresp);
@@ -3215,7 +3224,6 @@ loser:
fclose(ecdhreq);
}
-#define MATCH_OPENSSL 1
/*
* Perform the ECDH Validity Test.
*
@@ -3408,9 +3416,10 @@ ecdh_verify(char *reqfn, PRBool response)
fputs(buf, ecdhresp);
continue;
}
- if (strncmp(buf, "CAVSHashZZ", 10) == 0) {
+ if ((strncmp(buf, "CAVSHashZZ", 10) == 0) ||
+ (strncmp(buf, "HashZZ", 6) == 0)) {
fputs(buf, ecdhresp);
- i = 10;
+ i = (buf[0] == 'C') ? 10 : 6;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
@@ -3421,10 +3430,10 @@ ecdh_verify(char *reqfn, PRBool response)
}
/* validate CAVS public key */
if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) {
-#ifdef MATCH_OPENSSL
- fprintf(ecdhresp, "Result = F\n");
-#else
+#ifdef VERBOSE_REASON
fprintf(ecdhresp, "Result = F # key didn't validate\n");
+#else
+ fprintf(ecdhresp, "Result = F\n");
#endif
continue;
}
@@ -3432,8 +3441,12 @@ ecdh_verify(char *reqfn, PRBool response)
/* ECDH */
if (ECDH_Derive(&pubkey, current_ecparams, &private_value,
PR_FALSE, &ZZ) != SECSuccess) {
- fprintf(stderr, "Derive failed\n");
- goto loser;
+#ifdef VERBOSE_REASON
+ fprintf(ecdhresp, "Result = F # derive failure\n");
+#else
+ fprintf(ecdhresp, "Result = F\n");
+#endif
+ continue;
}
/* output ZZ */
#ifndef MATCH_OPENSSL
@@ -3455,10 +3468,10 @@ ecdh_verify(char *reqfn, PRBool response)
fputc('\n', ecdhresp);
#endif
if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) {
-#ifdef MATCH_OPENSSL
- fprintf(ecdhresp, "Result = F\n");
-#else
+#ifdef VERBOSE_REASON
fprintf(ecdhresp, "Result = F # hash doesn't match\n");
+#else
+ fprintf(ecdhresp, "Result = F\n");
#endif
} else {
fprintf(ecdhresp, "Result = P\n");
@@ -3675,7 +3688,6 @@ loser:
fclose(dhreq);
}
-#define MATCH_OPENSSL 1
/*
* Perform the DH Validity Test.
*
@@ -3846,9 +3858,10 @@ dh_verify(char *reqfn, PRBool response)
continue;
}
/* CAVSHashZZ = ... */
- if (strncmp(buf, "CAVSHashZZ", 10) == 0) {
+ if ((strncmp(buf, "CAVSHashZZ", 10) == 0) ||
+ (strncmp(buf, "HashZZ", 6) == 0)) {
fputs(buf, dhresp);
- i = 10;
+ i = buf[0] == 'C' ? 10 : 6;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
@@ -3871,7 +3884,7 @@ dh_verify(char *reqfn, PRBool response)
goto loser;
}
SECITEM_FreeItem(&ZZ, PR_FALSE);
-#ifndef MATCH_NIST_
+#ifndef MATCH_NIST
fputs("IUTHashZZ = ", dhresp);
to_hex_str(buf, hashBuf, fips_hashLen(hash));
fputs(buf, dhresp);
@@ -6656,12 +6669,13 @@ tls(char *reqfn)
CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE, NULL, 0 };
CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE, NULL, 0 };
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
- CK_SSL3_KEY_MAT_PARAMS key_block_params;
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
+ CK_TLS12_KEY_MAT_PARAMS key_block_params;
CK_SSL3_KEY_MAT_OUT key_material;
CK_RV crv;
/* set up PKCS #11 parameters */
+ master_params.prfHashMechanism = CKM_SHA256;
master_params.pVersion = NULL;
master_params.RandomInfo.pClientRandom = clientHello_random;
master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random);
@@ -6669,6 +6683,7 @@ tls(char *reqfn)
master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random);
master_mech.pParameter = (void *)&master_params;
master_mech.ulParameterLen = sizeof(master_params);
+ key_block_params.prfHashMechanism = CKM_SHA256;
key_block_params.ulMacSizeInBits = 0;
key_block_params.ulKeySizeInBits = 0;
key_block_params.ulIVSizeInBits = 0;
@@ -6711,13 +6726,39 @@ tls(char *reqfn)
if (buf[0] == '[') {
if (strncmp(buf, "[TLS", 4) == 0) {
if (buf[7] == '0') {
+ /* CK_SSL3_MASTER_KEY_DERIVE_PARAMS is a subset of
+ * CK_TLS12_MASTER_KEY_DERIVE_PARAMS and
+ * CK_SSL3_KEY_MAT_PARAMS is a subset of
+ * CK_TLS12_KEY_MAT_PARAMS. The latter params have
+ * an extra prfHashMechanism field at the end. */
master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE;
key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE;
+ master_mech.ulParameterLen = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
+ key_block_mech.ulParameterLen = sizeof(CK_SSL3_KEY_MAT_PARAMS);
} else if (buf[7] == '2') {
- master_mech.mechanism =
- CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256;
- key_block_mech.mechanism =
- CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
+ if (strncmp(&buf[10], "SHA-1", 5) == 0) {
+ master_params.prfHashMechanism = CKM_SHA_1;
+ key_block_params.prfHashMechanism = CKM_SHA_1;
+ } else if (strncmp(&buf[10], "SHA-224", 7) == 0) {
+ master_params.prfHashMechanism = CKM_SHA224;
+ key_block_params.prfHashMechanism = CKM_SHA224;
+ } else if (strncmp(&buf[10], "SHA-256", 7) == 0) {
+ master_params.prfHashMechanism = CKM_SHA256;
+ key_block_params.prfHashMechanism = CKM_SHA256;
+ } else if (strncmp(&buf[10], "SHA-384", 7) == 0) {
+ master_params.prfHashMechanism = CKM_SHA384;
+ key_block_params.prfHashMechanism = CKM_SHA384;
+ } else if (strncmp(&buf[10], "SHA-512", 7) == 0) {
+ master_params.prfHashMechanism = CKM_SHA512;
+ key_block_params.prfHashMechanism = CKM_SHA512;
+ } else {
+ fprintf(tlsresp, "ERROR: Unable to find prf Hash type");
+ goto loser;
+ }
+ master_mech.mechanism = CKM_TLS12_MASTER_KEY_DERIVE;
+ key_block_mech.mechanism = CKM_TLS12_KEY_AND_MAC_DERIVE;
+ master_mech.ulParameterLen = sizeof(master_params);
+ key_block_mech.ulParameterLen = sizeof(key_block_params);
} else {
fprintf(stderr, "Unknown TLS type %x\n",
(unsigned int)buf[0]);
@@ -6900,6 +6941,1296 @@ loser:
fclose(tlsreq);
}
+void
+ikev1(char *reqfn)
+{
+ char buf[4096]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "g^xy = <2048 hex digits>\n".
+ */
+ unsigned char *gxy = NULL;
+ int gxy_len;
+ unsigned char *Ni = NULL;
+ int Ni_len;
+ unsigned char *Nr = NULL;
+ int Nr_len;
+ unsigned char CKYi[8];
+ int CKYi_len;
+ unsigned char CKYr[8];
+ int CKYr_len;
+ unsigned int i, j;
+ FILE *ikereq = NULL; /* input stream from the REQUEST file */
+ FILE *ikeresp; /* output stream to the RESPONSE file */
+
+ CK_SLOT_ID slotList[10];
+ CK_SLOT_ID slotID;
+ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
+ CK_ULONG count;
+ static const CK_C_INITIALIZE_ARGS pk11args = {
+ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS,
+ (void *)"flags=readOnly,noCertDB,noModDB", NULL
+ };
+ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY;
+ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET;
+ static CK_BBOOL ck_true = CK_TRUE;
+ static CK_ULONG keyLen = 1;
+ CK_ATTRIBUTE gxy_template[] = {
+ { CKA_VALUE, NULL, 0 }, /* must be first */
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ CK_ULONG gxy_template_count =
+ sizeof(gxy_template) / sizeof(gxy_template[0]);
+ CK_ATTRIBUTE derive_template[] = {
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, /* must be last */
+ };
+ CK_ULONG derive_template_count =
+ sizeof(derive_template) / sizeof(derive_template[0]);
+ CK_ATTRIBUTE skeyid_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE skeyid_d_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE skeyid_a_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE skeyid_e_template =
+ { CKA_VALUE, NULL, 0 };
+ unsigned char skeyid_secret[HASH_LENGTH_MAX];
+ unsigned char skeyid_d_secret[HASH_LENGTH_MAX];
+ unsigned char skeyid_a_secret[HASH_LENGTH_MAX];
+ unsigned char skeyid_e_secret[HASH_LENGTH_MAX];
+
+ CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 };
+ CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE, NULL, 0 };
+ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf;
+ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf;
+ CK_RV crv;
+
+ /* set up PKCS #11 parameters */
+ ike_prf.bDataAsKey = PR_TRUE;
+ ike_prf.bRekey = PR_FALSE;
+ ike_prf.hNewKey = CK_INVALID_HANDLE;
+ CKYi_len = sizeof(CKYi);
+ CKYr_len = sizeof(CKYr);
+ ike1_prf.pCKYi = CKYi;
+ ike1_prf.ulCKYiLen = CKYi_len;
+ ike1_prf.pCKYr = CKYr;
+ ike1_prf.ulCKYrLen = CKYr_len;
+ ike_mech.pParameter = &ike_prf;
+ ike_mech.ulParameterLen = sizeof(ike_prf);
+ ike1_mech.pParameter = &ike1_prf;
+ ike1_mech.ulParameterLen = sizeof(ike1_prf);
+ skeyid_template.pValue = skeyid_secret;
+ skeyid_template.ulValueLen = HASH_LENGTH_MAX;
+ skeyid_d_template.pValue = skeyid_d_secret;
+ skeyid_d_template.ulValueLen = HASH_LENGTH_MAX;
+ skeyid_a_template.pValue = skeyid_a_secret;
+ skeyid_a_template.ulValueLen = HASH_LENGTH_MAX;
+ skeyid_e_template.pValue = skeyid_e_secret;
+ skeyid_e_template.ulValueLen = HASH_LENGTH_MAX;
+
+ crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ count = slotListCount;
+ crv = NSC_GetSlotList(PR_TRUE, slotList, &count);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ if ((count > slotListCount) || count < 1) {
+ fprintf(stderr,
+ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
+ (int)count, (int)slotListCount);
+ goto loser;
+ }
+ slotID = slotList[0];
+ ikereq = fopen(reqfn, "r");
+ ikeresp = stdout;
+ while (fgets(buf, sizeof buf, ikereq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* [.....] */
+ if (buf[0] == '[') {
+ if (strncmp(buf, "[SHA-1]", 7) == 0) {
+ ike_prf.prfMechanism = CKM_SHA_1_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA_1_HMAC;
+ }
+ if (strncmp(buf, "[SHA-224]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA224_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA224_HMAC;
+ }
+ if (strncmp(buf, "[SHA-256]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA256_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA256_HMAC;
+ }
+ if (strncmp(buf, "[SHA-384]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA384_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA384_HMAC;
+ }
+ if (strncmp(buf, "[SHA-512]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA512_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA512_HMAC;
+ }
+ if (strncmp(buf, "[AES-XCBC", 9) == 0) {
+ ike_prf.prfMechanism = CKM_AES_XCBC_MAC;
+ ike1_prf.prfMechanism = CKM_AES_XCBC_MAC;
+ }
+ if (strncmp(buf, "[g^xy", 5) == 0) {
+ if (sscanf(buf, "[g^xy length = %d]",
+ &gxy_len) != 1) {
+ goto loser;
+ }
+ gxy_len = gxy_len / 8;
+ if (gxy)
+ free(gxy);
+ gxy = malloc(gxy_len);
+ gxy_template[0].pValue = gxy;
+ gxy_template[0].ulValueLen = gxy_len;
+ }
+ if (strncmp(buf, "[Ni", 3) == 0) {
+ if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) {
+ goto loser;
+ }
+ Ni_len = Ni_len / 8;
+ if (Ni)
+ free(Ni);
+ Ni = malloc(Ni_len);
+ ike_prf.pNi = Ni;
+ ike_prf.ulNiLen = Ni_len;
+ }
+ if (strncmp(buf, "[Nr", 3) == 0) {
+ if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) {
+ goto loser;
+ }
+ Nr_len = Nr_len / 8;
+ if (Nr)
+ free(Nr);
+ Nr = malloc(Nr_len);
+ ike_prf.pNr = Nr;
+ ike_prf.ulNrLen = Nr_len;
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(gxy, 0, gxy_len);
+ memset(Ni, 0, Ni_len);
+ memset(Nr, 0, Nr_len);
+ memset(CKYi, 0, CKYi_len);
+ memset(CKYr, 0, CKYr_len);
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* Ni = ... */
+ if (strncmp(buf, "Ni", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < Ni_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Ni[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* Nr = ... */
+ if (strncmp(buf, "Nr", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < Nr_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Nr[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* CKYi = ... */
+ if (strncmp(buf, "CKY_I", 5) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < CKYi_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &CKYi[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* CKYr = ... */
+ if (strncmp(buf, "CKY_R", 5) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < CKYr_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &CKYr[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* g^xy = ... */
+ if (strncmp(buf, "g^xy", 4) == 0) {
+ CK_SESSION_HANDLE session;
+ CK_OBJECT_HANDLE gxy_handle;
+ CK_OBJECT_HANDLE skeyid_handle;
+ CK_OBJECT_HANDLE skeyid_d_handle;
+ CK_OBJECT_HANDLE skeyid_a_handle;
+ CK_OBJECT_HANDLE skeyid_e_handle;
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < gxy_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &gxy[j]);
+ }
+ fputs(buf, ikeresp);
+ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_CreateObject(session, gxy_template,
+ gxy_template_count, &gxy_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_CreateObject failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ /* get the skeyid key */
+ crv = NSC_DeriveKey(session, &ike_mech, gxy_handle,
+ derive_template, derive_template_count - 1,
+ &skeyid_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ skeyid_template.ulValueLen = HASH_LENGTH_MAX;
+ crv = NSC_GetAttributeValue(session, skeyid_handle,
+ &skeyid_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ /* use the length of the skeyid to set the target length of all the
+ * other keys */
+ keyLen = skeyid_template.ulValueLen;
+ ike1_prf.hKeygxy = gxy_handle;
+ ike1_prf.bHasPrevKey = PR_FALSE;
+ ike1_prf.keyNumber = 0;
+ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
+ derive_template, derive_template_count,
+ &skeyid_d_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+
+ ike1_prf.hKeygxy = gxy_handle;
+ ike1_prf.bHasPrevKey = CK_TRUE;
+ ike1_prf.hPrevKey = skeyid_d_handle;
+ ike1_prf.keyNumber = 1;
+ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
+ derive_template, derive_template_count,
+ &skeyid_a_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ ike1_prf.hKeygxy = gxy_handle;
+ ike1_prf.bHasPrevKey = CK_TRUE;
+ ike1_prf.hPrevKey = skeyid_a_handle;
+ ike1_prf.keyNumber = 2;
+ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
+ derive_template, derive_template_count,
+ &skeyid_e_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID = ", ikeresp);
+ to_hex_str(buf, skeyid_secret, keyLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ skeyid_d_template.ulValueLen = keyLen;
+ crv = NSC_GetAttributeValue(session, skeyid_d_handle,
+ &skeyid_d_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID_d = ", ikeresp);
+ to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ skeyid_a_template.ulValueLen = keyLen;
+ crv = NSC_GetAttributeValue(session, skeyid_a_handle,
+ &skeyid_a_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID_a = ", ikeresp);
+ to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ skeyid_e_template.ulValueLen = keyLen;
+ crv = NSC_GetAttributeValue(session, skeyid_e_handle,
+ &skeyid_e_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID_e = ", ikeresp);
+ to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ crv = NSC_CloseSession(session);
+ continue;
+ }
+ }
+loser:
+ NSC_Finalize(NULL);
+ if (gxy)
+ free(gxy);
+ if (Ni)
+ free(Ni);
+ if (Nr)
+ free(Nr);
+ if (ikereq)
+ fclose(ikereq);
+}
+
+void
+ikev1_psk(char *reqfn)
+{
+ char buf[4096]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "g^xy = <2048 hex digits>\n".
+ */
+ unsigned char *gxy = NULL;
+ int gxy_len;
+ unsigned char *Ni = NULL;
+ int Ni_len;
+ unsigned char *Nr = NULL;
+ int Nr_len;
+ unsigned char CKYi[8];
+ int CKYi_len;
+ unsigned char CKYr[8];
+ int CKYr_len;
+ unsigned char *psk = NULL;
+ int psk_len;
+ unsigned int i, j;
+ FILE *ikereq = NULL; /* input stream from the REQUEST file */
+ FILE *ikeresp; /* output stream to the RESPONSE file */
+
+ CK_SLOT_ID slotList[10];
+ CK_SLOT_ID slotID;
+ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
+ CK_ULONG count;
+ static const CK_C_INITIALIZE_ARGS pk11args = {
+ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS,
+ (void *)"flags=readOnly,noCertDB,noModDB", NULL
+ };
+ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY;
+ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET;
+ static CK_BBOOL ck_true = CK_TRUE;
+ static CK_ULONG keyLen = 1;
+ CK_ATTRIBUTE gxy_template[] = {
+ { CKA_VALUE, NULL, 0 }, /* must be first */
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ CK_ULONG gxy_template_count =
+ sizeof(gxy_template) / sizeof(gxy_template[0]);
+ CK_ATTRIBUTE psk_template[] = {
+ { CKA_VALUE, NULL, 0 }, /* must be first */
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ CK_ULONG psk_template_count =
+ sizeof(psk_template) / sizeof(psk_template[0]);
+ CK_ATTRIBUTE derive_template[] = {
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, /* must be last */
+ };
+ CK_ULONG derive_template_count =
+ sizeof(derive_template) / sizeof(derive_template[0]);
+ CK_ATTRIBUTE skeyid_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE skeyid_d_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE skeyid_a_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE skeyid_e_template =
+ { CKA_VALUE, NULL, 0 };
+ unsigned char skeyid_secret[HASH_LENGTH_MAX];
+ unsigned char skeyid_d_secret[HASH_LENGTH_MAX];
+ unsigned char skeyid_a_secret[HASH_LENGTH_MAX];
+ unsigned char skeyid_e_secret[HASH_LENGTH_MAX];
+
+ CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 };
+ CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE, NULL, 0 };
+ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf;
+ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf;
+ CK_RV crv;
+
+ /* set up PKCS #11 parameters */
+ ike_prf.bDataAsKey = PR_FALSE;
+ ike_prf.bRekey = PR_FALSE;
+ ike_prf.hNewKey = CK_INVALID_HANDLE;
+ CKYi_len = 8;
+ CKYr_len = 8;
+ ike1_prf.pCKYi = CKYi;
+ ike1_prf.ulCKYiLen = CKYi_len;
+ ike1_prf.pCKYr = CKYr;
+ ike1_prf.ulCKYrLen = CKYr_len;
+ ike_mech.pParameter = &ike_prf;
+ ike_mech.ulParameterLen = sizeof(ike_prf);
+ ike1_mech.pParameter = &ike1_prf;
+ ike1_mech.ulParameterLen = sizeof(ike1_prf);
+ skeyid_template.pValue = skeyid_secret;
+ skeyid_template.ulValueLen = HASH_LENGTH_MAX;
+ skeyid_d_template.pValue = skeyid_d_secret;
+ skeyid_d_template.ulValueLen = HASH_LENGTH_MAX;
+ skeyid_a_template.pValue = skeyid_a_secret;
+ skeyid_a_template.ulValueLen = HASH_LENGTH_MAX;
+ skeyid_e_template.pValue = skeyid_e_secret;
+ skeyid_e_template.ulValueLen = HASH_LENGTH_MAX;
+
+ crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ count = slotListCount;
+ crv = NSC_GetSlotList(PR_TRUE, slotList, &count);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ if ((count > slotListCount) || count < 1) {
+ fprintf(stderr,
+ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
+ (int)count, (int)slotListCount);
+ goto loser;
+ }
+ slotID = slotList[0];
+ ikereq = fopen(reqfn, "r");
+ ikeresp = stdout;
+ while (fgets(buf, sizeof buf, ikereq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* [.....] */
+ if (buf[0] == '[') {
+ if (strncmp(buf, "[SHA-1]", 7) == 0) {
+ ike_prf.prfMechanism = CKM_SHA_1_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA_1_HMAC;
+ }
+ if (strncmp(buf, "[SHA-224]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA224_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA224_HMAC;
+ }
+ if (strncmp(buf, "[SHA-256]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA256_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA256_HMAC;
+ }
+ if (strncmp(buf, "[SHA-384]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA384_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA384_HMAC;
+ }
+ if (strncmp(buf, "[SHA-512]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA512_HMAC;
+ ike1_prf.prfMechanism = CKM_SHA512_HMAC;
+ }
+ if (strncmp(buf, "[AES-XCBC", 9) == 0) {
+ ike_prf.prfMechanism = CKM_AES_XCBC_MAC;
+ ike1_prf.prfMechanism = CKM_AES_XCBC_MAC;
+ }
+ if (strncmp(buf, "[g^xy", 5) == 0) {
+ if (sscanf(buf, "[g^xy length = %d]",
+ &gxy_len) != 1) {
+ goto loser;
+ }
+ gxy_len = gxy_len / 8;
+ if (gxy)
+ free(gxy);
+ gxy = malloc(gxy_len);
+ gxy_template[0].pValue = gxy;
+ gxy_template[0].ulValueLen = gxy_len;
+ }
+ if (strncmp(buf, "[pre-shared-key", 15) == 0) {
+ if (sscanf(buf, "[pre-shared-key length = %d]",
+ &psk_len) != 1) {
+ goto loser;
+ }
+ psk_len = psk_len / 8;
+ if (psk)
+ free(psk);
+ psk = malloc(psk_len);
+ psk_template[0].pValue = psk;
+ psk_template[0].ulValueLen = psk_len;
+ }
+ if (strncmp(buf, "[Ni", 3) == 0) {
+ if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) {
+ goto loser;
+ }
+ Ni_len = Ni_len / 8;
+ if (Ni)
+ free(Ni);
+ Ni = malloc(Ni_len);
+ ike_prf.pNi = Ni;
+ ike_prf.ulNiLen = Ni_len;
+ }
+ if (strncmp(buf, "[Nr", 3) == 0) {
+ if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) {
+ goto loser;
+ }
+ Nr_len = Nr_len / 8;
+ if (Nr)
+ free(Nr);
+ Nr = malloc(Nr_len);
+ ike_prf.pNr = Nr;
+ ike_prf.ulNrLen = Nr_len;
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(gxy, 0, gxy_len);
+ memset(Ni, 0, Ni_len);
+ memset(Nr, 0, Nr_len);
+ memset(CKYi, 0, CKYi_len);
+ memset(CKYr, 0, CKYr_len);
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* Ni = ... */
+ if (strncmp(buf, "Ni", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < Ni_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Ni[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* Nr = ... */
+ if (strncmp(buf, "Nr", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < Nr_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Nr[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* CKYi = ... */
+ if (strncmp(buf, "CKY_I", 5) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < CKYi_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &CKYi[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* CKYr = ... */
+ if (strncmp(buf, "CKY_R", 5) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < CKYr_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &CKYr[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* g^xy = ... */
+ if (strncmp(buf, "g^xy", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < gxy_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &gxy[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* pre-shared-key = ... */
+ if (strncmp(buf, "pre-shared-key", 14) == 0) {
+ CK_SESSION_HANDLE session;
+ CK_OBJECT_HANDLE gxy_handle;
+ CK_OBJECT_HANDLE psk_handle;
+ CK_OBJECT_HANDLE skeyid_handle;
+ CK_OBJECT_HANDLE skeyid_d_handle;
+ CK_OBJECT_HANDLE skeyid_a_handle;
+ CK_OBJECT_HANDLE skeyid_e_handle;
+ i = 14;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < psk_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &psk[j]);
+ }
+ fputs(buf, ikeresp);
+ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_CreateObject(session, psk_template,
+ psk_template_count, &psk_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_CreateObject(psk) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_CreateObject(session, gxy_template,
+ gxy_template_count, &gxy_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_CreateObject(gxy) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ /* get the skeyid key */
+ crv = NSC_DeriveKey(session, &ike_mech, psk_handle,
+ derive_template, derive_template_count - 1,
+ &skeyid_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ skeyid_template.ulValueLen = HASH_LENGTH_MAX;
+ crv = NSC_GetAttributeValue(session, skeyid_handle,
+ &skeyid_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ /* use the length of the skeyid to set the target length of all the
+ * other keys */
+ keyLen = skeyid_template.ulValueLen;
+ ike1_prf.hKeygxy = gxy_handle;
+ ike1_prf.bHasPrevKey = PR_FALSE;
+ ike1_prf.keyNumber = 0;
+ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
+ derive_template, derive_template_count,
+ &skeyid_d_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+
+ ike1_prf.hKeygxy = gxy_handle;
+ ike1_prf.bHasPrevKey = CK_TRUE;
+ ike1_prf.hPrevKey = skeyid_d_handle;
+ ike1_prf.keyNumber = 1;
+ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
+ derive_template, derive_template_count,
+ &skeyid_a_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ ike1_prf.hKeygxy = gxy_handle;
+ ike1_prf.bHasPrevKey = CK_TRUE;
+ ike1_prf.hPrevKey = skeyid_a_handle;
+ ike1_prf.keyNumber = 2;
+ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
+ derive_template, derive_template_count,
+ &skeyid_e_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID = ", ikeresp);
+ to_hex_str(buf, skeyid_secret, keyLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ skeyid_d_template.ulValueLen = keyLen;
+ crv = NSC_GetAttributeValue(session, skeyid_d_handle,
+ &skeyid_d_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID_d = ", ikeresp);
+ to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ skeyid_a_template.ulValueLen = keyLen;
+ crv = NSC_GetAttributeValue(session, skeyid_a_handle,
+ &skeyid_a_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID_a = ", ikeresp);
+ to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ skeyid_e_template.ulValueLen = keyLen;
+ crv = NSC_GetAttributeValue(session, skeyid_e_handle,
+ &skeyid_e_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYID_e = ", ikeresp);
+ to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ crv = NSC_CloseSession(session);
+ continue;
+ }
+ }
+loser:
+ NSC_Finalize(NULL);
+ if (psk)
+ free(psk);
+ if (gxy)
+ free(gxy);
+ if (Ni)
+ free(Ni);
+ if (Nr)
+ free(Nr);
+ if (ikereq)
+ fclose(ikereq);
+}
+
+void
+ikev2(char *reqfn)
+{
+ char buf[4096]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "g^xy = <2048 hex digits>\n".
+ */
+ unsigned char *gir = NULL;
+ unsigned char *gir_new = NULL;
+ int gir_len;
+ unsigned char *Ni = NULL;
+ int Ni_len;
+ unsigned char *Nr = NULL;
+ int Nr_len;
+ unsigned char *SPIi = NULL;
+ int SPIi_len = 8;
+ unsigned char *SPIr = NULL;
+ int SPIr_len = 8;
+ unsigned char *DKM = NULL;
+ int DKM_len;
+ unsigned char *DKM_child = NULL;
+ int DKM_child_len;
+ unsigned char *seed_data = NULL;
+ int seed_data_len = 0;
+ unsigned int i, j;
+ FILE *ikereq = NULL; /* input stream from the REQUEST file */
+ FILE *ikeresp; /* output stream to the RESPONSE file */
+
+ CK_SLOT_ID slotList[10];
+ CK_SLOT_ID slotID;
+ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
+ CK_ULONG count;
+ static const CK_C_INITIALIZE_ARGS pk11args = {
+ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS,
+ (void *)"flags=readOnly,noCertDB,noModDB", NULL
+ };
+ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY;
+ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET;
+ static CK_BBOOL ck_true = CK_TRUE;
+ static CK_ULONG keyLen = 1;
+ CK_ATTRIBUTE gir_template[] = {
+ { CKA_VALUE, NULL, 0 },
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ CK_ULONG gir_template_count =
+ sizeof(gir_template) / sizeof(gir_template[0]);
+ CK_ATTRIBUTE gir_new_template[] = {
+ { CKA_VALUE, NULL, 0 },
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ CK_ULONG gir_new_template_count =
+ sizeof(gir_new_template) / sizeof(gir_new_template[0]);
+ CK_ATTRIBUTE derive_template[] = {
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) },
+ };
+ CK_ULONG derive_template_count =
+ sizeof(derive_template) / sizeof(derive_template[0]);
+ CK_ATTRIBUTE skeyseed_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE dkm_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE dkm_child_template =
+ { CKA_VALUE, NULL, 0 };
+ unsigned char skeyseed_secret[HASH_LENGTH_MAX];
+
+ CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 };
+ CK_MECHANISM ike2_mech = { CKM_NSS_IKE_PRF_PLUS_DERIVE, NULL, 0 };
+ CK_MECHANISM subset_mech = { CKM_EXTRACT_KEY_FROM_KEY, NULL, 0 };
+ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf;
+ CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS ike2_prf;
+ CK_EXTRACT_PARAMS subset_params;
+ CK_RV crv;
+
+ /* set up PKCS #11 parameters */
+ ike_mech.pParameter = &ike_prf;
+ ike_mech.ulParameterLen = sizeof(ike_prf);
+ ike2_mech.pParameter = &ike2_prf;
+ ike2_mech.ulParameterLen = sizeof(ike2_prf);
+ subset_mech.pParameter = &subset_params;
+ subset_mech.ulParameterLen = sizeof(subset_params);
+ subset_params = 0;
+ skeyseed_template.pValue = skeyseed_secret;
+ skeyseed_template.ulValueLen = HASH_LENGTH_MAX;
+
+ crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ count = slotListCount;
+ crv = NSC_GetSlotList(PR_TRUE, slotList, &count);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ if ((count > slotListCount) || count < 1) {
+ fprintf(stderr,
+ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
+ (int)count, (int)slotListCount);
+ goto loser;
+ }
+ slotID = slotList[0];
+ ikereq = fopen(reqfn, "r");
+ ikeresp = stdout;
+ while (fgets(buf, sizeof buf, ikereq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* [.....] */
+ if (buf[0] == '[') {
+ if (strncmp(buf, "[SHA-1]", 7) == 0) {
+ ike_prf.prfMechanism = CKM_SHA_1_HMAC;
+ ike2_prf.prfMechanism = CKM_SHA_1_HMAC;
+ }
+ if (strncmp(buf, "[SHA-224]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA224_HMAC;
+ ike2_prf.prfMechanism = CKM_SHA224_HMAC;
+ }
+ if (strncmp(buf, "[SHA-256]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA256_HMAC;
+ ike2_prf.prfMechanism = CKM_SHA256_HMAC;
+ }
+ if (strncmp(buf, "[SHA-384]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA384_HMAC;
+ ike2_prf.prfMechanism = CKM_SHA384_HMAC;
+ }
+ if (strncmp(buf, "[SHA-512]", 9) == 0) {
+ ike_prf.prfMechanism = CKM_SHA512_HMAC;
+ ike2_prf.prfMechanism = CKM_SHA512_HMAC;
+ }
+ if (strncmp(buf, "[AES-XCBC", 9) == 0) {
+ ike_prf.prfMechanism = CKM_AES_XCBC_MAC;
+ ike2_prf.prfMechanism = CKM_AES_XCBC_MAC;
+ }
+ if (strncmp(buf, "[g^ir", 5) == 0) {
+ if (sscanf(buf, "[g^ir length = %d]",
+ &gir_len) != 1) {
+ goto loser;
+ }
+ gir_len = gir_len / 8;
+ if (gir)
+ free(gir);
+ if (gir_new)
+ free(gir_new);
+ gir = malloc(gir_len);
+ gir_new = malloc(gir_len);
+ gir_template[0].pValue = gir;
+ gir_template[0].ulValueLen = gir_len;
+ gir_new_template[0].pValue = gir_new;
+ gir_new_template[0].ulValueLen = gir_len;
+ }
+ if (strncmp(buf, "[Ni", 3) == 0) {
+ if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) {
+ goto loser;
+ }
+ Ni_len = Ni_len / 8;
+ }
+ if (strncmp(buf, "[Nr", 3) == 0) {
+ if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) {
+ goto loser;
+ }
+ Nr_len = Nr_len / 8;
+ }
+ if (strncmp(buf, "[DKM", 4) == 0) {
+ if (sscanf(buf, "[DKM length = %d]",
+ &DKM_len) != 1) {
+ goto loser;
+ }
+ DKM_len = DKM_len / 8;
+ if (DKM)
+ free(DKM);
+ DKM = malloc(DKM_len);
+ dkm_template.pValue = DKM;
+ dkm_template.ulValueLen = DKM_len;
+ }
+ if (strncmp(buf, "[Child SA DKM", 13) == 0) {
+ if (sscanf(buf, "[Child SA DKM length = %d]",
+ &DKM_child_len) != 1) {
+ goto loser;
+ }
+ DKM_child_len = DKM_child_len / 8;
+ if (DKM_child)
+ free(DKM_child);
+ DKM_child = malloc(DKM_child_len);
+ dkm_child_template.pValue = DKM_child;
+ dkm_child_template.ulValueLen = DKM_child_len;
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ int new_seed_len = Ni_len + Nr_len + SPIi_len + SPIr_len;
+ if (seed_data_len != new_seed_len) {
+ if (seed_data)
+ free(seed_data);
+ seed_data_len = new_seed_len;
+ seed_data = malloc(seed_data_len);
+ Ni = seed_data;
+ Nr = &seed_data[Ni_len];
+ SPIi = &seed_data[Ni_len + Nr_len];
+ SPIr = &seed_data[new_seed_len - SPIr_len];
+ ike_prf.pNi = Ni;
+ ike_prf.ulNiLen = Ni_len;
+ ike_prf.pNr = Nr;
+ ike_prf.ulNrLen = Nr_len;
+ ike2_prf.pSeedData = seed_data;
+ }
+ memset(gir, 0, gir_len);
+ memset(gir_new, 0, gir_len);
+ memset(seed_data, 0, seed_data_len);
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* Ni = ... */
+ if (strncmp(buf, "Ni", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < Ni_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Ni[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* Nr = ... */
+ if (strncmp(buf, "Nr", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < Nr_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Nr[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* g^ir (new) = ... */
+ if (strncmp(buf, "g^ir (new)", 10) == 0) {
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < gir_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &gir_new[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* g^ir = ... */
+ if (strncmp(buf, "g^ir", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < gir_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &gir[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* SPIi = ... */
+ if (strncmp(buf, "SPIi", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < SPIi_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &SPIi[j]);
+ }
+ fputs(buf, ikeresp);
+ continue;
+ }
+ /* SPIr = ... */
+ if (strncmp(buf, "SPIr", 4) == 0) {
+ CK_SESSION_HANDLE session;
+ CK_OBJECT_HANDLE gir_handle;
+ CK_OBJECT_HANDLE gir_new_handle;
+ CK_OBJECT_HANDLE skeyseed_handle;
+ CK_OBJECT_HANDLE sk_d_handle;
+ CK_OBJECT_HANDLE skeyseed_new_handle;
+ CK_OBJECT_HANDLE dkm_handle;
+ CK_OBJECT_HANDLE dkm_child_handle;
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < SPIr_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &SPIr[j]);
+ }
+ fputs(buf, ikeresp);
+ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_CreateObject(session, gir_template,
+ gir_template_count, &gir_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_CreateObject (g^ir) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_CreateObject(session, gir_new_template,
+ gir_new_template_count, &gir_new_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_CreateObject (g^ir new) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ /* get the SKEYSEED key */
+ ike_prf.bDataAsKey = CK_TRUE;
+ ike_prf.bRekey = CK_FALSE;
+ ike_prf.hNewKey = CK_INVALID_HANDLE;
+ crv = NSC_DeriveKey(session, &ike_mech, gir_handle,
+ derive_template, derive_template_count - 1,
+ &skeyseed_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ skeyseed_template.ulValueLen = HASH_LENGTH_MAX;
+ crv = NSC_GetAttributeValue(session, skeyseed_handle,
+ &skeyseed_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYSEED = ", ikeresp);
+ to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ /* get DKM */
+ keyLen = DKM_len;
+ ike2_prf.bHasSeedKey = CK_FALSE;
+ ike2_prf.hSeedKey = CK_INVALID_HANDLE;
+ ike2_prf.ulSeedDataLen = seed_data_len;
+ crv = NSC_DeriveKey(session, &ike2_mech, skeyseed_handle,
+ derive_template, derive_template_count,
+ &dkm_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(DKM) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_GetAttributeValue(session, dkm_handle,
+ &dkm_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(DKM) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("DKM = ", ikeresp);
+ to_hex_str(buf, DKM, DKM_len);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ /* get the sk_d from the DKM */
+ keyLen = skeyseed_template.ulValueLen;
+ crv = NSC_DeriveKey(session, &subset_mech, dkm_handle,
+ derive_template, derive_template_count,
+ &sk_d_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(sk_d) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+
+ /* get DKM child */
+ keyLen = DKM_child_len;
+ ike2_prf.bHasSeedKey = CK_FALSE;
+ ike2_prf.hSeedKey = CK_INVALID_HANDLE;
+ ike2_prf.ulSeedDataLen = Ni_len + Nr_len;
+ crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle,
+ derive_template, derive_template_count,
+ &dkm_child_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(DKM Child SA) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_GetAttributeValue(session, dkm_child_handle,
+ &dkm_child_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(DKM Child SA) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("DKM(Child SA) = ", ikeresp);
+ to_hex_str(buf, DKM_child, DKM_child_len);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ /* get DKM child D-H*/
+ keyLen = DKM_child_len;
+ ike2_prf.bHasSeedKey = CK_TRUE;
+ ike2_prf.hSeedKey = gir_new_handle;
+ ike2_prf.ulSeedDataLen = Ni_len + Nr_len;
+ crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle,
+ derive_template, derive_template_count,
+ &dkm_child_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(DKM Child SA D-H) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_GetAttributeValue(session, dkm_child_handle,
+ &dkm_child_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(DKM Child SA D-H) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("DKM(Child SA D-H) = ", ikeresp);
+ to_hex_str(buf, DKM_child, DKM_child_len);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ /* get SKEYSEED(rekey) */
+ ike_prf.bDataAsKey = CK_FALSE;
+ ike_prf.bRekey = CK_TRUE;
+ ike_prf.hNewKey = gir_new_handle;
+ crv = NSC_DeriveKey(session, &ike_mech, sk_d_handle,
+ derive_template, derive_template_count - 1,
+ &skeyseed_new_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(skeyid rekey) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ skeyseed_template.ulValueLen = HASH_LENGTH_MAX;
+ crv = NSC_GetAttributeValue(session, skeyseed_new_handle,
+ &skeyseed_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("SKEYSEED(rekey) = ", ikeresp);
+ to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen);
+ fputs(buf, ikeresp);
+ fputc('\n', ikeresp);
+
+ crv = NSC_CloseSession(session);
+ continue;
+ }
+ }
+loser:
+ NSC_Finalize(NULL);
+ if (gir)
+ free(gir);
+ if (gir_new)
+ free(gir_new);
+ if (seed_data)
+ free(seed_data);
+ if (DKM)
+ free(DKM);
+ if (DKM_child)
+ free(DKM_child);
+ if (ikereq)
+ fclose(ikereq);
+}
+
int
main(int argc, char **argv)
{
@@ -7071,6 +8402,14 @@ main(int argc, char **argv)
} else if (strcmp(argv[1], "ddrbg") == 0) {
debug = 1;
drbg(argv[2]);
+ } else if (strcmp(argv[1], "tls") == 0) {
+ tls(argv[2]);
+ } else if (strcmp(argv[1], "ikev1") == 0) {
+ ikev1(argv[2]);
+ } else if (strcmp(argv[1], "ikev1-psk") == 0) {
+ ikev1_psk(argv[2]);
+ } else if (strcmp(argv[1], "ikev2") == 0) {
+ ikev2(argv[2]);
}
return 0;
}
diff --git a/security/nss/cmd/fipstest/hmac.sh b/security/nss/cmd/fipstest/hmac.sh
deleted file mode 100755
index d29dbc27f..000000000
--- a/security/nss/cmd/fipstest/hmac.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/HMAC
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-hmac_requests="
-HMAC.req
-"
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $hmac_requests; do
- sh ./validate1.sh ${TESTDIR} $request
- done
- exit 0
-fi
-for request in $hmac_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response
-done
-
diff --git a/security/nss/cmd/fipstest/kas.sh b/security/nss/cmd/fipstest/kas.sh
deleted file mode 100644
index 9aa5387a8..000000000
--- a/security/nss/cmd/fipstest/kas.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST DSA Validation System
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/KAS
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-
-#
-if [ ${COMMAND} = "verify" ]; then
-#
-# need verify for KAS tests
-
-# verify generated keys
-# name=KeyPair
-# echo ">>>>> $name"
-# fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify generated pqg values
-# name=PQGGen
-# echo ">>>>> $name"
-# fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify PQGVer with known answer
-# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
-# verify signatures
-# name=SigGen
-# echo ">>>>> $name"
-# fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# verify SigVer with known answer
-# sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
- exit 0
-fi
-
-request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdh init-func ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdh resp-func ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdh init-verify ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest ecdh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dh init-func ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dh resp-func ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dh init-verify ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest dh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response
-
diff --git a/security/nss/cmd/fipstest/rng.sh b/security/nss/cmd/fipstest/rng.sh
deleted file mode 100644
index 1a313b422..000000000
--- a/security/nss/cmd/fipstest/rng.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST RNG Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/DRBG800-90A
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-drbg_requests="
-Hash_DRBG.req
-"
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $drbg_requests; do
- sh ./validate1.sh ${TESTDIR} $request
- done
- exit 0
-fi
-for request in $drbg_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response
-done
diff --git a/security/nss/cmd/fipstest/rsa.sh b/security/nss/cmd/fipstest/rsa.sh
deleted file mode 100644
index b86a73969..000000000
--- a/security/nss/cmd/fipstest/rsa.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST RSA Validation System
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/RSA2
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-if [ ${COMMAND} = "verify" ]; then
-#verify the signatures. The fax file does not have any known answers, so
-#use our own verify function.
- name=SigGen15_186-3
- echo ">>>>> $name"
- fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
-# fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F
-#The Fax file has the private exponent and the salt value, remove it
-#also remove the false reason
- sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;'
-#
-# currently don't have a way to verify the RSA keygen
-#
- exit 0
-fi
-
-request=SigGen15_186-3.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
-
-request=SigVer15_186-3.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
-
-#request=KeyGen_186-3.req
-request=KeyGen_RandomProbablyPrime3_3.req
-response=`echo $request | sed -e "s/req/rsp/"`
-echo $request $response
-fipstest rsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
diff --git a/security/nss/cmd/fipstest/runtest.sh b/security/nss/cmd/fipstest/runtest.sh
deleted file mode 100644
index fcb16348b..000000000
--- a/security/nss/cmd/fipstest/runtest.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-TESTDIR=${1-.}
-COMMAND=${2-run}
-TESTS="aes aesgcm dsa ecdsa hmac kas tls rng rsa sha tdea"
-for i in $TESTS
-do
- echo "********************Running $i tests"
- sh ./${i}.sh ${TESTDIR} ${COMMAND}
-done
diff --git a/security/nss/cmd/fipstest/sha.sh b/security/nss/cmd/fipstest/sha.sh
deleted file mode 100644
index ccc52d297..000000000
--- a/security/nss/cmd/fipstest/sha.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST SHA Algorithm Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/SHA
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-sha_ShortMsg_requests="
-SHA1ShortMsg.req
-SHA224ShortMsg.req
-SHA256ShortMsg.req
-SHA384ShortMsg.req
-SHA512ShortMsg.req
-"
-
-sha_LongMsg_requests="
-SHA1LongMsg.req
-SHA224LongMsg.req
-SHA256LongMsg.req
-SHA384LongMsg.req
-SHA512LongMsg.req
-"
-
-sha_Monte_requests="
-SHA1Monte.req
-SHA224Monte.req
-SHA256Monte.req
-SHA384Monte.req
-SHA512Monte.req
-"
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do
- sh ./validate1.sh ${TESTDIR} $request
- done
- exit 0
-fi
-
-for request in $sha_ShortMsg_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $sha_LongMsg_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $sha_Monte_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
-done
-
diff --git a/security/nss/cmd/fipstest/tdea.sh b/security/nss/cmd/fipstest/tdea.sh
deleted file mode 100644
index cbddad7d7..000000000
--- a/security/nss/cmd/fipstest/tdea.sh
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST tdea Algorithm Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/TDES
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-#CBC_Known_Answer_tests
-#Initial Permutation KAT
-#Permutation Operation KAT
-#Subsitution Table KAT
-#Variable Key KAT
-#Variable PlainText KAT
-cbc_kat_requests="
-TCBCinvperm.req
-TCBCpermop.req
-TCBCsubtab.req
-TCBCvarkey.req
-TCBCvartext.req
-"
-
-#CBC Monte Carlo KATs
-cbc_monte_requests="
-TCBCMonte1.req
-TCBCMonte2.req
-TCBCMonte3.req
-"
-#Multi-block Message KATs
-cbc_mmt_requests="
-TCBCMMT1.req
-TCBCMMT2.req
-TCBCMMT3.req
-"
-
-ecb_kat_requests="
-TECBinvperm.req
-TECBpermop.req
-TECBsubtab.req
-TECBvarkey.req
-TECBvartext.req
-"
-
-ecb_monte_requests="
-TECBMonte1.req
-TECBMonte2.req
-TECBMonte3.req
-"
-
-ecb_mmt_requests="
-TECBMMT1.req
-TECBMMT2.req
-TECBMMT3.req
-"
-
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests
- do
- sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d"
- done
- exit 0
-fi
-
-for request in $cbc_kat_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $cbc_mmt_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $cbc_monte_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $ecb_kat_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $ecb_mmt_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
-done
-for request in $ecb_monte_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
-done
diff --git a/security/nss/cmd/fipstest/tls.sh b/security/nss/cmd/fipstest/tls.sh
deleted file mode 100644
index 1c2824539..000000000
--- a/security/nss/cmd/fipstest/tls.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# A Bourne shell script for running the NIST RNG Validation Suite
-#
-# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
-# variables appropriately so that the fipstest command and the NSPR and NSS
-# shared libraries/DLLs are on the search path. Then run this script in the
-# directory where the REQUEST (.req) files reside. The script generates the
-# RESPONSE (.rsp) files in the same directory.
-BASEDIR=${1-.}
-TESTDIR=${BASEDIR}/KDF135
-COMMAND=${2-run}
-REQDIR=${TESTDIR}/req
-RSPDIR=${TESTDIR}/resp
-
-drbg_requests="
-tls.req
-"
-
-if [ ${COMMAND} = "verify" ]; then
- for request in $drbg_requests; do
- sh ./validate1.sh ${TESTDIR} $request
- done
- exit 0
-fi
-for request in $drbg_requests; do
- response=`echo $request | sed -e "s/req/rsp/"`
- echo $request $response
- fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response
-done
diff --git a/security/nss/cmd/fipstest/validate1.sh b/security/nss/cmd/fipstest/validate1.sh
deleted file mode 100644
index 1440af8fc..000000000
--- a/security/nss/cmd/fipstest/validate1.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-#
-# 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/.
-#
-# Validate1.sh is a helper shell script that each of the base test shell
-# scripts call to help validate that the generated response (response)
-# matches the known answer response (fax). Sometimes (depending on the
-# individual tests) there are extraneous output in either or both response
-# and fax files. These allow the caller to pass in additional sed commands
-# to clear out those extraneous outputs before we compare the two files.
-# The sed line always clears out Windows line endings, replaces tabs with
-# spaces, and removed comments.
-#
-TESTDIR=${1-.}
-request=${2}
-extraneous_response=${3}
-extraneous_fax=${4}
-name=`basename $request .req`
-echo ">>>>> $name"
-sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
-# if we didn't generate any output, flag that as an error
-size=`sum /tmp/y1 | awk '{ print $NF }'`
-if [ $size -eq 0 ]; then
- echo "${TESTDIR}/resp/${name}.rsp: empty"
- exit 1;
-fi
-sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2
-diff -i -w -B /tmp/y1 /tmp/y2
diff --git a/security/nss/cmd/httpserv/httpserv.c b/security/nss/cmd/httpserv/httpserv.c
index 71e2ab88d..c7277f3bd 100644
--- a/security/nss/cmd/httpserv/httpserv.c
+++ b/security/nss/cmd/httpserv/httpserv.c
@@ -463,7 +463,7 @@ handle_connection(
char *getData = NULL; /* inplace conversion */
SECItem postData;
PRBool isOcspRequest = PR_FALSE;
- PRBool isPost;
+ PRBool isPost = PR_FALSE;
postData.data = NULL;
postData.len = 0;
diff --git a/security/nss/cmd/lib/Makefile b/security/nss/cmd/lib/Makefile
index 0fb6c9058..6b53451ef 100644
--- a/security/nss/cmd/lib/Makefile
+++ b/security/nss/cmd/lib/Makefile
@@ -27,6 +27,7 @@ include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
include config.mk
+include ../platlibs.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
diff --git a/security/nss/cmd/lib/derprint.c b/security/nss/cmd/lib/derprint.c
index 08ef66d08..b86179e30 100644
--- a/security/nss/cmd/lib/derprint.c
+++ b/security/nss/cmd/lib/derprint.c
@@ -4,6 +4,8 @@
#include "secutil.h"
#include "secoid.h"
+#include <stdint.h>
+
#ifdef __sun
extern int fprintf(FILE *strm, const char *format, ... /* args */);
extern int fflush(FILE *stream);
@@ -509,7 +511,7 @@ prettyPrintItem(FILE *out, const unsigned char *data, const unsigned char *end,
/*
* Just quit now if slen more bytes puts us off the end.
*/
- if ((data + slen) > end) {
+ if (data > end || slen > (end - data)) {
PORT_SetError(SEC_ERROR_BAD_DER);
return -1;
}
diff --git a/security/nss/cmd/lib/lib.gyp b/security/nss/cmd/lib/lib.gyp
index 6b7da5810..c5835a869 100644
--- a/security/nss/cmd/lib/lib.gyp
+++ b/security/nss/cmd/lib/lib.gyp
@@ -27,7 +27,8 @@
],
'target_defaults': {
'defines': [
- 'NSPR20'
+ 'NSPR20',
+ 'NSS_USE_STATIC_LIBS'
]
},
'variables': {
diff --git a/security/nss/cmd/lib/manifest.mn b/security/nss/cmd/lib/manifest.mn
index 87440c052..b3c36b3a9 100644
--- a/security/nss/cmd/lib/manifest.mn
+++ b/security/nss/cmd/lib/manifest.mn
@@ -37,3 +37,5 @@ CSRCS = basicutil.c \
endif
NO_MD_RELEASE = 1
+
+USE_STATIC_LIBS = 1
diff --git a/security/nss/cmd/lib/pk11table.c b/security/nss/cmd/lib/pk11table.c
index 15c0a8d1e..ec5d88926 100644
--- a/security/nss/cmd/lib/pk11table.c
+++ b/security/nss/cmd/lib/pk11table.c
@@ -333,6 +333,8 @@ const Constant _consts[] = {
mkEntry(CKM_SHA512, Mechanism),
mkEntry(CKM_SHA512_HMAC_GENERAL, Mechanism),
mkEntry(CKM_SHA512_HMAC, Mechanism),
+ mkEntry(CKM_AES_CMAC, Mechanism),
+ mkEntry(CKM_AES_CMAC_GENERAL, Mechanism),
mkEntry(CKM_CAST_KEY_GEN, Mechanism),
mkEntry(CKM_CAST_ECB, Mechanism),
mkEntry(CKM_CAST_CBC, Mechanism),
diff --git a/security/nss/cmd/lib/secpwd.c b/security/nss/cmd/lib/secpwd.c
index 7e99b2757..e8ca792e8 100644
--- a/security/nss/cmd/lib/secpwd.c
+++ b/security/nss/cmd/lib/secpwd.c
@@ -66,7 +66,7 @@ SEC_GetPassword(FILE *input, FILE *output, char *prompt,
int infd = fileno(input);
int isTTY = isatty(infd);
#endif
- char phrase[200] = { '\0' }; /* ensure EOF doesn't return junk */
+ char phrase[500] = { '\0' }; /* ensure EOF doesn't return junk */
for (;;) {
/* Prompt for password */
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index 97c7f750a..703845e98 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -22,6 +22,7 @@
#include <stdarg.h>
#include <sys/stat.h>
#include <errno.h>
+#include <limits.h>
#ifdef XP_UNIX
#include <unistd.h>
@@ -1107,36 +1108,33 @@ typedef struct secuPBEParamsStr {
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
/* SECOID_PKCS5_PBKDF2 */
-const SEC_ASN1Template secuKDF2Params[] =
- {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
- { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
- { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
- { SEC_ASN1_INTEGER, offsetof(secuPBEParams, keyLength) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
- };
+const SEC_ASN1Template secuKDF2Params[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, keyLength) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { 0 }
+};
/* PKCS5v1 & PKCS12 */
-const SEC_ASN1Template secuPBEParamsTemp[] =
- {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
- { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
- { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
- { 0 }
- };
+const SEC_ASN1Template secuPBEParamsTemp[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
+ { 0 }
+};
/* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
-const SEC_ASN1Template secuPBEV2Params[] =
- {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, cipherAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
- };
+const SEC_ASN1Template secuPBEV2Params[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, cipherAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { 0 }
+};
void
secu_PrintRSAPSSParams(FILE *out, SECItem *value, char *m, int level)
@@ -2299,8 +2297,9 @@ SECU_PrintCertAttributes(FILE *out, CERTAttribute **attrs, char *m, int level)
return rv;
}
-int /* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
- SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
+/* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
+int
+SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
{
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
CERTCertificateRequest *cr;
@@ -3250,6 +3249,26 @@ SEC_PrintCertificateAndTrust(CERTCertificate *cert,
"Certificate Trust Flags", 1);
}
+ /* The distrust fields are hard-coded in nssckbi and read-only.
+ * If verifying some cert, with vfychain, for instance, the certificate may
+ * not have a defined slot if not imported. */
+ if (cert->slot != NULL && cert->distrust != NULL) {
+ const unsigned int kDistrustFieldSize = 13;
+ fprintf(stdout, "\n");
+ SECU_Indent(stdout, 1);
+ fprintf(stdout, "%s:\n", "Certificate Distrust Dates");
+ if (cert->distrust->serverDistrustAfter.len == kDistrustFieldSize) {
+ SECU_PrintTimeChoice(stdout,
+ &cert->distrust->serverDistrustAfter,
+ "Server Distrust After", 2);
+ }
+ if (cert->distrust->emailDistrustAfter.len == kDistrustFieldSize) {
+ SECU_PrintTimeChoice(stdout,
+ &cert->distrust->emailDistrustAfter,
+ "E-mail Distrust After", 2);
+ }
+ }
+
printf("\n");
return (SECSuccess);
@@ -3979,3 +3998,164 @@ done:
*enabledSigSchemes = schemes;
return SECSuccess;
}
+
+/* Parse the exporter spec in the form: LABEL[:OUTPUT-LENGTH[:CONTEXT]] */
+static SECStatus
+parseExporter(const char *arg,
+ secuExporter *exporter)
+{
+ SECStatus rv = SECSuccess;
+
+ char *str = PORT_Strdup(arg);
+ if (!str) {
+ rv = SECFailure;
+ goto done;
+ }
+
+ char *labelEnd = strchr(str, ':');
+ if (labelEnd) {
+ *labelEnd = '\0';
+ labelEnd++;
+
+ /* To extract CONTEXT, first skip OUTPUT-LENGTH */
+ char *outputEnd = strchr(labelEnd, ':');
+ if (outputEnd) {
+ *outputEnd = '\0';
+ outputEnd++;
+
+ exporter->hasContext = PR_TRUE;
+ exporter->context.data = (unsigned char *)PORT_Strdup(outputEnd);
+ exporter->context.len = strlen(outputEnd);
+ if (PORT_Strncasecmp((char *)exporter->context.data, "0x", 2) == 0) {
+ rv = SECU_SECItemHexStringToBinary(&exporter->context);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (labelEnd && *labelEnd != '\0') {
+ long int outputLength = strtol(labelEnd, NULL, 10);
+ if (!(outputLength > 0 && outputLength <= UINT_MAX)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ goto done;
+ }
+ exporter->outputLength = outputLength;
+ } else {
+ exporter->outputLength = 20;
+ }
+
+ char *label = PORT_Strdup(str);
+ exporter->label.data = (unsigned char *)label;
+ exporter->label.len = strlen(label);
+ if (PORT_Strncasecmp((char *)exporter->label.data, "0x", 2) == 0) {
+ rv = SECU_SECItemHexStringToBinary(&exporter->label);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ }
+
+done:
+ PORT_Free(str);
+
+ return rv;
+}
+
+SECStatus
+parseExporters(const char *arg,
+ const secuExporter **enabledExporters,
+ unsigned int *enabledExporterCount)
+{
+ secuExporter *exporters;
+ unsigned int numValues = 0;
+ unsigned int count = 0;
+
+ if (countItems(arg, &numValues) != SECSuccess) {
+ return SECFailure;
+ }
+ exporters = PORT_ZNewArray(secuExporter, numValues);
+ if (!exporters) {
+ return SECFailure;
+ }
+
+ /* Get exporter definitions. */
+ char *str = PORT_Strdup(arg);
+ if (!str) {
+ goto done;
+ }
+ char *p = strtok(str, ",");
+ while (p) {
+ SECStatus rv = parseExporter(p, &exporters[count++]);
+ if (rv != SECSuccess) {
+ count = 0;
+ goto done;
+ }
+ p = strtok(NULL, ",");
+ }
+
+done:
+ PORT_Free(str);
+ if (!count) {
+ PORT_Free(exporters);
+ return SECFailure;
+ }
+
+ *enabledExporterCount = count;
+ *enabledExporters = exporters;
+ return SECSuccess;
+}
+
+static SECStatus
+exportKeyingMaterial(PRFileDesc *fd, const secuExporter *exporter)
+{
+ SECStatus rv = SECSuccess;
+ unsigned char *out = PORT_Alloc(exporter->outputLength);
+
+ if (!out) {
+ fprintf(stderr, "Unable to allocate buffer for keying material\n");
+ return SECFailure;
+ }
+ rv = SSL_ExportKeyingMaterial(fd,
+ (char *)exporter->label.data,
+ exporter->label.len,
+ exporter->hasContext,
+ exporter->context.data,
+ exporter->context.len,
+ out,
+ exporter->outputLength);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ fprintf(stdout, "Exported Keying Material:\n");
+ secu_PrintRawString(stdout, (SECItem *)&exporter->label, "Label", 1);
+ if (exporter->hasContext) {
+ SECU_PrintAsHex(stdout, &exporter->context, "Context", 1);
+ }
+ SECU_Indent(stdout, 1);
+ fprintf(stdout, "Length: %u\n", exporter->outputLength);
+ SECItem temp = { siBuffer, out, exporter->outputLength };
+ SECU_PrintAsHex(stdout, &temp, "Keying Material", 1);
+
+done:
+ PORT_Free(out);
+ return rv;
+}
+
+SECStatus
+exportKeyingMaterials(PRFileDesc *fd,
+ const secuExporter *exporters,
+ unsigned int exporterCount)
+{
+ unsigned int i;
+
+ for (i = 0; i < exporterCount; i++) {
+ SECStatus rv = exportKeyingMaterial(fd, &exporters[i]);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+
+ return SECSuccess;
+}
diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h
index 90d763909..c6da961e7 100644
--- a/security/nss/cmd/lib/secutil.h
+++ b/security/nss/cmd/lib/secutil.h
@@ -409,6 +409,20 @@ SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
SECStatus parseSigSchemeList(const char *arg,
const SSLSignatureScheme **enabledSigSchemes,
unsigned int *enabledSigSchemeCount);
+typedef struct {
+ SECItem label;
+ PRBool hasContext;
+ SECItem context;
+ unsigned int outputLength;
+} secuExporter;
+
+SECStatus parseExporters(const char *arg,
+ const secuExporter **enabledExporters,
+ unsigned int *enabledExporterCount);
+
+SECStatus exportKeyingMaterials(PRFileDesc *fd,
+ const secuExporter *exporters,
+ unsigned int exporterCount);
/*
*
diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn
index be53d3c4e..695177c9d 100644
--- a/security/nss/cmd/manifest.mn
+++ b/security/nss/cmd/manifest.mn
@@ -56,6 +56,7 @@ NSS_SRCDIRS = \
p7sign \
p7verify \
pk12util \
+ pk11importtest \
pk11ectest \
pk11gcmtest \
pk11mode \
diff --git a/security/nss/cmd/p7env/p7env.c b/security/nss/cmd/p7env/p7env.c
index b35bf9a98..453cbee19 100644
--- a/security/nss/cmd/p7env/p7env.c
+++ b/security/nss/cmd/p7env/p7env.c
@@ -66,7 +66,7 @@ EncryptFile(FILE *outFile, FILE *inFile, struct recipient *recipients,
SEC_PKCS7ContentInfo *cinfo;
SEC_PKCS7EncoderContext *ecx;
struct recipient *rcpt;
- SECStatus rv;
+ SECStatus rv = SECFailure;
if (outFile == NULL || inFile == NULL || recipients == NULL)
return -1;
@@ -133,7 +133,7 @@ main(int argc, char **argv)
struct recipient *recipients, *rcpt;
PLOptState *optstate;
PLOptStatus status;
- SECStatus rv;
+ SECStatus rv = SECFailure;
progName = strrchr(argv[0], '/');
progName = progName ? progName + 1 : argv[0];
diff --git a/security/nss/cmd/pk11importtest/Makefile b/security/nss/cmd/pk11importtest/Makefile
new file mode 100644
index 000000000..fc8358d5a
--- /dev/null
+++ b/security/nss/cmd/pk11importtest/Makefile
@@ -0,0 +1,43 @@
+#! gmake
+#
+# 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/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
diff --git a/security/nss/cmd/fipstest/validate.sh b/security/nss/cmd/pk11importtest/manifest.mn
index d446dd587..5c40a8108 100644
--- a/security/nss/cmd/fipstest/validate.sh
+++ b/security/nss/cmd/pk11importtest/manifest.mn
@@ -1,7 +1,15 @@
-#!/bin/sh
-#
# 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/.
-#
-sh ./runtest.sh ${1-.} verify
+
+CORE_DEPTH = ../..
+
+MODULE = nss
+
+CSRCS = pk11importtest.c \
+ $(NULL)
+
+REQUIRES = seccmd
+
+PROGRAM = pk11importtest
+
diff --git a/security/nss/cmd/pk11importtest/pk11importtest.c b/security/nss/cmd/pk11importtest/pk11importtest.c
new file mode 100644
index 000000000..e8326594a
--- /dev/null
+++ b/security/nss/cmd/pk11importtest/pk11importtest.c
@@ -0,0 +1,408 @@
+/* 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 "secutil.h"
+#include "secmod.h"
+#include "cert.h"
+#include "secoid.h"
+#include "nss.h"
+#include "pk11pub.h"
+#include "pk11pqg.h"
+
+/* NSPR 2.0 header files */
+#include "prinit.h"
+#include "prprf.h"
+#include "prsystem.h"
+#include "prmem.h"
+/* Portable layer header files */
+#include "plstr.h"
+
+SECOidData *
+getCurveFromString(char *curve_name)
+{
+ SECOidTag tag = SEC_OID_SECG_EC_SECP256R1;
+
+ if (PORT_Strcasecmp(curve_name, "NISTP256") == 0) {
+ } else if (PORT_Strcasecmp(curve_name, "NISTP384") == 0) {
+ tag = SEC_OID_SECG_EC_SECP384R1;
+ } else if (PORT_Strcasecmp(curve_name, "NISTP521") == 0) {
+ tag = SEC_OID_SECG_EC_SECP521R1;
+ } else if (PORT_Strcasecmp(curve_name, "Curve25519") == 0) {
+ tag = SEC_OID_CURVE25519;
+ }
+ return SECOID_FindOIDByTag(tag);
+}
+
+void
+dumpItem(const char *label, const SECItem *item)
+{
+ int i;
+ printf("%s = [%d bytes] {", label, item->len);
+ for (i = 0; i < item->len; i++) {
+ if ((i & 0xf) == 0)
+ printf("\n ");
+ else
+ printf(", ");
+ printf("%02x", item->data[i]);
+ }
+ printf("};\n");
+}
+
+SECStatus
+handleEncryptedPrivateImportTest(char *progName, PK11SlotInfo *slot,
+ char *testname, CK_MECHANISM_TYPE genMech, void *params, void *pwArgs)
+{
+ SECStatus rv = SECSuccess;
+ SECItem privID = { 0 };
+ SECItem pubID = { 0 };
+ SECItem pubValue = { 0 };
+ SECItem pbePwItem = { 0 };
+ SECItem nickname = { 0 };
+ SECItem token = { 0 };
+ SECKEYPublicKey *pubKey = NULL;
+ SECKEYPrivateKey *privKey = NULL;
+ PK11GenericObject *objs = NULL;
+ PK11GenericObject *obj = NULL;
+ SECKEYEncryptedPrivateKeyInfo *epki = NULL;
+ PRBool keyFound = 0;
+ KeyType keyType;
+
+ fprintf(stderr, "Testing %s PrivateKeyImport ***********************\n",
+ testname);
+
+ /* generate a temp key */
+ privKey = PK11_GenerateKeyPair(slot, genMech, params, &pubKey,
+ PR_FALSE, PR_TRUE, pwArgs);
+ if (privKey == NULL) {
+ SECU_PrintError(progName, "PK11_GenerateKeyPair Failed");
+ goto cleanup;
+ }
+
+ /* wrap the temp key */
+ pbePwItem.data = (unsigned char *)"pw";
+ pbePwItem.len = 2;
+ epki = PK11_ExportEncryptedPrivKeyInfo(slot, SEC_OID_AES_256_CBC,
+ &pbePwItem, privKey, 1, NULL);
+ if (epki == NULL) {
+ SECU_PrintError(progName, "PK11_ExportEncryptedPrivKeyInfo Failed");
+ goto cleanup;
+ }
+
+ /* Save the public value, which we will need on import */
+ keyType = pubKey->keyType;
+ switch (keyType) {
+ case rsaKey:
+ SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.rsa.modulus);
+ break;
+ case dhKey:
+ SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.dh.publicValue);
+ break;
+ case dsaKey:
+ SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.dsa.publicValue);
+ break;
+ case ecKey:
+ SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.ec.publicValue);
+ break;
+ default:
+ fprintf(stderr, "Unknown keytype = %d\n", keyType);
+ goto cleanup;
+ }
+ if (pubValue.data == NULL) {
+ SECU_PrintError(progName, "Unable to allocate memory");
+ goto cleanup;
+ }
+ dumpItem("pubValue", &pubValue);
+
+ /* when Asymetric keys represent session keys, those session keys are
+ * destroyed when we destroy the Asymetric key representations */
+ SECKEY_DestroyPublicKey(pubKey);
+ pubKey = NULL;
+ SECKEY_DestroyPrivateKey(privKey);
+ privKey = NULL;
+
+ /* unwrap the temp key as a perm */
+ nickname.data = (unsigned char *)"testKey";
+ nickname.len = sizeof("testKey");
+ rv = PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(
+ slot, epki, &pbePwItem, &nickname, &pubValue,
+ PR_TRUE, PR_TRUE, keyType, 0, &privKey, NULL);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "PK11_ImportEncryptedPrivateKeyInfo Failed");
+ goto cleanup;
+ }
+
+ /* verify the public key exists */
+ rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey, CKA_ID, &privID);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "Couldn't read CKA_ID from pub key, checking next key");
+ goto cleanup;
+ }
+ dumpItem("privKey CKA_ID", &privID);
+ objs = PK11_FindGenericObjects(slot, CKO_PUBLIC_KEY);
+ for (obj = objs; obj; obj = PK11_GetNextGenericObject(obj)) {
+ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_ID, &pubID);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "Couldn't read CKA_ID from object, checking next key");
+ continue;
+ }
+ dumpItem("pubKey CKA_ID", &pubID);
+ if (!SECITEM_ItemsAreEqual(&privID, &pubID)) {
+ fprintf(stderr,
+ "CKA_ID does not match priv key, checking next key\n");
+ SECITEM_FreeItem(&pubID, PR_FALSE);
+ continue;
+ }
+ SECITEM_FreeItem(&pubID, PR_FALSE);
+ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_TOKEN, &token);
+ if (rv == SECSuccess) {
+ if (token.len == 1) {
+ keyFound = token.data[0];
+ }
+ SECITEM_FreeItem(&token, PR_FALSE);
+ }
+ if (keyFound) {
+ printf("matching public key found\n");
+ break;
+ }
+ printf("Matching key was not a token key, checking next key\n");
+ }
+
+cleanup:
+ if (objs) {
+ PK11_DestroyGenericObjects(objs);
+ }
+ SECITEM_FreeItem(&pubValue, PR_FALSE);
+ SECITEM_FreeItem(&privID, PR_FALSE);
+ if (epki && epki->arena) {
+ PORT_FreeArena(epki->arena, PR_TRUE);
+ }
+ SECKEY_DestroyPublicKey(pubKey);
+ SECKEY_DestroyPrivateKey(privKey);
+ fprintf(stderr, "%s PrivateKeyImport %s ***********************\n",
+ testname, keyFound ? "PASSED" : "FAILED");
+ return keyFound ? SECSuccess : SECFailure;
+}
+
+static const char *const usageInfo[] = {
+ "pk11import - test PK11_PrivateKeyImport()",
+ "Options:",
+ " -d certdir directory containing cert database",
+ " -k keysize size of the rsa, dh, and dsa key to test (default 1024)",
+ " -C ecc_curve ecc curve (default )",
+ " -f pwFile file to fetch the password from",
+ " -p pwString password",
+ " -r skip rsa test",
+ " -D skip dsa test",
+ " -h skip dh test",
+ " -e skip ec test",
+};
+static int nUsageInfo = sizeof(usageInfo) / sizeof(char *);
+
+static void
+Usage(char *progName, FILE *outFile)
+{
+ int i;
+ fprintf(outFile, "Usage: %s [ commands ] options\n", progName);
+ for (i = 0; i < nUsageInfo; i++)
+ fprintf(outFile, "%s\n", usageInfo[i]);
+ exit(-1);
+}
+
+enum {
+ opt_CertDir,
+ opt_KeySize,
+ opt_ECCurve,
+ opt_PWFile,
+ opt_PWString,
+ opt_NoRSA,
+ opt_NoDSA,
+ opt_NoEC,
+ opt_NoDH
+};
+
+static secuCommandFlag options[] =
+ {
+ { /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
+ { /* opt_KeySize */ 'k', PR_TRUE, 0, PR_FALSE },
+ { /* opt_ECCurve */ 'C', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PWFile */ 'f', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PWString */ 'p', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NORSA */ 'r', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NoDSA */ 'D', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NoDH */ 'h', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NoEC */ 'e', PR_TRUE, 0, PR_FALSE },
+ };
+
+int
+main(int argc, char **argv)
+{
+ char *progName;
+ SECStatus rv;
+ secuCommand args;
+ PK11SlotInfo *slot = NULL;
+ PRBool failed = PR_FALSE;
+ secuPWData pwArgs = { PW_NONE, 0 };
+ PRBool doRSA = PR_TRUE;
+ PRBool doDSA = PR_TRUE;
+ PRBool doDH = PR_FALSE; /* NSS currently can't export wrapped DH keys */
+ PRBool doEC = PR_TRUE;
+ PQGParams *pqgParams = NULL;
+ int keySize;
+
+ args.numCommands = 0;
+ args.numOptions = sizeof(options) / sizeof(secuCommandFlag);
+ args.commands = NULL;
+ args.options = options;
+
+#ifdef XP_PC
+ progName = strrchr(argv[0], '\\');
+#else
+ progName = strrchr(argv[0], '/');
+#endif
+ progName = progName ? progName + 1 : argv[0];
+
+ rv = SECU_ParseCommandLine(argc, argv, progName, &args);
+ if (SECSuccess != rv) {
+ Usage(progName, stderr);
+ }
+
+ /* Set the certdb directory (default is ~/.netscape) */
+ rv = NSS_InitReadWrite(SECU_ConfigDirectory(args.options[opt_CertDir].arg));
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ return 255;
+ }
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
+
+ /* below here, goto cleanup */
+ SECU_RegisterDynamicOids();
+
+ /* handle the arguments */
+ if (args.options[opt_PWFile].arg) {
+ pwArgs.source = PW_FROMFILE;
+ pwArgs.data = args.options[opt_PWFile].arg;
+ }
+ if (args.options[opt_PWString].arg) {
+ pwArgs.source = PW_PLAINTEXT;
+ pwArgs.data = args.options[opt_PWString].arg;
+ }
+ if (args.options[opt_NoRSA].activated) {
+ doRSA = PR_FALSE;
+ }
+ if (args.options[opt_NoDSA].activated) {
+ doDSA = PR_FALSE;
+ }
+ if (args.options[opt_NoDH].activated) {
+ doDH = PR_FALSE;
+ }
+ if (args.options[opt_NoEC].activated) {
+ doEC = PR_FALSE;
+ }
+
+ slot = PK11_GetInternalKeySlot();
+ if (slot == NULL) {
+ SECU_PrintError(progName, "Couldn't find the internal key slot\n");
+ return 255;
+ }
+ rv = PK11_Authenticate(slot, PR_TRUE, &pwArgs);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "Failed to log into slot");
+ PK11_FreeSlot(slot);
+ return 255;
+ }
+
+ keySize = 1024;
+ if (args.options[opt_KeySize].activated &&
+ args.options[opt_KeySize].arg) {
+ keySize = atoi(args.options[opt_KeySize].arg);
+ }
+
+ if (doDSA || doDH) {
+ PQGVerify *pqgVfy;
+ rv = PK11_PQG_ParamGenV2(keySize, 0, keySize / 16, &pqgParams, &pqgVfy);
+ if (rv == SECSuccess) {
+ PK11_PQG_DestroyVerify(pqgVfy);
+ } else {
+ SECU_PrintError(progName,
+ "PK11_PQG_ParamGenV2 failed, can't test DH or DSA");
+ doDSA = doDH = PR_FALSE;
+ failed = PR_TRUE;
+ }
+ }
+
+ if (doRSA) {
+ PK11RSAGenParams rsaParams;
+ rsaParams.keySizeInBits = keySize;
+ rsaParams.pe = 0x010001;
+ rv = handleEncryptedPrivateImportTest(progName, slot, "RSA",
+ CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaParams, &pwArgs);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Import Failed!\n");
+ failed = PR_TRUE;
+ }
+ }
+ if (doDSA) {
+ rv = handleEncryptedPrivateImportTest(progName, slot, "DSA",
+ CKM_DSA_KEY_PAIR_GEN, pqgParams, &pwArgs);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "DSA Import Failed!\n");
+ failed = PR_TRUE;
+ }
+ }
+ if (doDH) {
+ SECKEYDHParams dhParams;
+ dhParams.prime = pqgParams->prime;
+ dhParams.base = pqgParams->base;
+ rv = handleEncryptedPrivateImportTest(progName, slot, "DH",
+ CKM_DH_PKCS_KEY_PAIR_GEN, &dhParams, &pwArgs);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "DH Import Failed!\n");
+ failed = PR_TRUE;
+ }
+ }
+ if (doEC) {
+ SECKEYECParams ecParams;
+ SECOidData *curve = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
+ if (args.options[opt_ECCurve].activated &&
+ args.options[opt_ECCurve].arg) {
+ curve = getCurveFromString(args.options[opt_ECCurve].arg);
+ }
+ ecParams.data = PORT_Alloc(curve->oid.len + 2);
+ if (ecParams.data == NULL) {
+ rv = SECFailure;
+ goto ec_failed;
+ }
+ ecParams.data[0] = SEC_ASN1_OBJECT_ID;
+ ecParams.data[1] = (unsigned char)curve->oid.len;
+ PORT_Memcpy(&ecParams.data[2], curve->oid.data, curve->oid.len);
+ ecParams.len = curve->oid.len + 2;
+ rv = handleEncryptedPrivateImportTest(progName, slot, "ECC",
+ CKM_EC_KEY_PAIR_GEN, &ecParams, &pwArgs);
+ PORT_Free(ecParams.data);
+ ec_failed:
+ if (rv != SECSuccess) {
+ fprintf(stderr, "ECC Import Failed!\n");
+ failed = PR_TRUE;
+ }
+ }
+
+ if (pqgParams) {
+ PK11_PQG_DestroyParams(pqgParams);
+ }
+
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+
+ rv = NSS_Shutdown();
+ if (rv != SECSuccess) {
+ fprintf(stderr, "Shutdown failed\n");
+ SECU_PrintPRandOSError(progName);
+ return 255;
+ }
+
+ return failed ? 1 : 0;
+}
diff --git a/security/nss/cmd/pk11importtest/pk11importtest.gyp b/security/nss/cmd/pk11importtest/pk11importtest.gyp
new file mode 100644
index 000000000..4fce05962
--- /dev/null
+++ b/security/nss/cmd/pk11importtest/pk11importtest.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pk11importtest',
+ 'type': 'executable',
+ 'sources': [
+ 'pk11importtest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/security/nss/cmd/pk11mode/pk11mode.c b/security/nss/cmd/pk11mode/pk11mode.c
index 99891096c..16554536d 100644
--- a/security/nss/cmd/pk11mode/pk11mode.c
+++ b/security/nss/cmd/pk11mode/pk11mode.c
@@ -5229,7 +5229,7 @@ PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,
char *
PKM_FilePasswd(char *pwFile)
{
- unsigned char phrase[200];
+ unsigned char phrase[500];
PRFileDesc *fd;
PRInt32 nb;
int i;
diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c
index 5884713e3..794f17b39 100644
--- a/security/nss/cmd/pk12util/pk12util.c
+++ b/security/nss/cmd/pk12util/pk12util.c
@@ -644,6 +644,7 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
}
certlist = PK11_FindCertsFromNickname(nn, slotPw);
if (!certlist) {
+ PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
SECU_PrintError(progName, "find user certs from nickname failed");
pk12uErrno = PK12UERR_FINDCERTBYNN;
return;
diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk
index a59d03d06..640177882 100644
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -144,8 +144,8 @@ endif
ifeq ($(OS_ARCH), WINNT)
EXTRA_LIBS += \
- $(NSS_LIBS_1) \
$(SECTOOL_LIB) \
+ $(NSS_LIBS_1) \
$(NSS_LIBS_2) \
$(SOFTOKENLIB) \
$(CRYPTOLIB) \
@@ -161,8 +161,8 @@ EXTRA_LIBS += \
else
EXTRA_LIBS += \
- $(NSS_LIBS_1) \
$(SECTOOL_LIB) \
+ $(NSS_LIBS_1) \
$(NSS_LIBS_2) \
$(SOFTOKENLIB) \
$(NSS_LIBS_3) \
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index 1784c9ee3..03e39d67b 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -233,7 +233,15 @@ PrintParameterUsage()
" ecdsa_secp521r1_sha512,\n"
" rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
" rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
- "-Z enable 0-RTT (for TLS 1.3; also use -u)\n",
+ "-Z enable 0-RTT (for TLS 1.3; also use -u)\n"
+ "-E enable post-handshake authentication\n"
+ " (for TLS 1.3; only has an effect with 3 or more -r options)\n"
+ "-x Export and print keying material after successful handshake\n"
+ " The argument is a comma separated list of exporters in the form:\n"
+ " LABEL[:OUTPUT-LENGTH[:CONTEXT]]\n"
+ " where LABEL and CONTEXT can be either a free-form string or\n"
+ " a hex string if it is preceded by \"0x\"; OUTPUT-LENGTH\n"
+ " is a decimal integer.\n",
stderr);
}
@@ -803,11 +811,15 @@ PRBool enableSessionTickets = PR_FALSE;
PRBool failedToNegotiateName = PR_FALSE;
PRBool enableExtendedMasterSecret = PR_FALSE;
PRBool zeroRTT = PR_FALSE;
+SSLAntiReplayContext *antiReplay = NULL;
PRBool enableALPN = PR_FALSE;
+PRBool enablePostHandshakeAuth = PR_FALSE;
SSLNamedGroup *enabledGroups = NULL;
unsigned int enabledGroupsCount = 0;
const SSLSignatureScheme *enabledSigSchemes = NULL;
unsigned int enabledSigSchemeCount = 0;
+const secuExporter *enabledExporters = NULL;
+unsigned int enabledExporterCount = 0;
static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
static int virtServerNameIndex = 1;
@@ -1431,15 +1443,28 @@ handle_connection(PRFileDesc *tcp_sock, PRFileDesc *model_sock)
errWarn("second SSL_OptionSet SSL_REQUIRE_CERTIFICATE");
break;
}
- rv = SSL_ReHandshake(ssl_sock, PR_TRUE);
- if (rv != 0) {
- errWarn("SSL_ReHandshake");
- break;
- }
- rv = SSL_ForceHandshake(ssl_sock);
- if (rv < 0) {
- errWarn("SSL_ForceHandshake");
- break;
+ if (enablePostHandshakeAuth) {
+ rv = SSL_SendCertificateRequest(ssl_sock);
+ if (rv != SECSuccess) {
+ errWarn("SSL_SendCertificateRequest");
+ break;
+ }
+ rv = SSL_ForceHandshake(ssl_sock);
+ if (rv != SECSuccess) {
+ errWarn("SSL_ForceHandshake");
+ break;
+ }
+ } else {
+ rv = SSL_ReHandshake(ssl_sock, PR_TRUE);
+ if (rv != 0) {
+ errWarn("SSL_ReHandshake");
+ break;
+ }
+ rv = SSL_ForceHandshake(ssl_sock);
+ if (rv < 0) {
+ errWarn("SSL_ForceHandshake");
+ break;
+ }
}
}
}
@@ -1805,6 +1830,15 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
SECITEM_FreeItem(hostInfo, PR_TRUE);
}
}
+ if (enabledExporters) {
+ SECStatus rv = exportKeyingMaterials(fd, enabledExporters, enabledExporterCount);
+ if (rv != SECSuccess) {
+ PRErrorCode err = PR_GetError();
+ fprintf(stderr,
+ "couldn't export keying material: %s\n",
+ SECU_Strerror(err));
+ }
+ }
}
void
@@ -1909,7 +1943,7 @@ server_main(
for (i = 0; i < certNicknameIndex; i++) {
if (cert[i] != NULL) {
const SSLExtraServerCertData ocspData = {
- ssl_auth_null, NULL, certStatus[i], NULL
+ ssl_auth_null, NULL, certStatus[i], NULL, NULL, NULL
};
secStatus = SSL_ConfigServerCert(model_sock, cert[i],
@@ -1938,7 +1972,7 @@ server_main(
if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
errExit("You tried enabling 0RTT without enabling TLS 1.3!");
}
- rv = SSL_SetupAntiReplay(10 * PR_USEC_PER_SEC, 7, 14);
+ rv = SSL_SetAntiReplayContext(model_sock, antiReplay);
if (rv != SECSuccess) {
errExit("error configuring anti-replay ");
}
@@ -1948,6 +1982,16 @@ server_main(
}
}
+ if (enablePostHandshakeAuth) {
+ if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
+ errExit("You tried enabling post-handshake auth without enabling TLS 1.3!");
+ }
+ rv = SSL_OptionSet(model_sock, SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE);
+ if (rv != SECSuccess) {
+ errExit("error enabling post-handshake auth");
+ }
+ }
+
if (enableALPN) {
PRUint8 alpnVal[] = { 0x08,
0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 };
@@ -1985,7 +2029,7 @@ server_main(
errExit("SSL_CipherPrefSetDefault:TLS_RSA_WITH_NULL_MD5");
}
- if (expectedHostNameVal) {
+ if (expectedHostNameVal || enabledExporters) {
SSL_HandshakeCallback(model_sock, handshakeCallback,
(void *)expectedHostNameVal);
}
@@ -2219,11 +2263,11 @@ main(int argc, char **argv)
/* please keep this list of options in ASCII collating sequence.
** numbers, then capital letters, then lower case, alphabetical.
- ** XXX: 'B', 'E', 'q', and 'x' were used in the past but removed
+ ** XXX: 'B', and 'q' were used in the past but removed
** in 3.28, please leave some time before resuing those.
** 'z' was removed in 3.39. */
optstate = PL_CreateOptState(argc, argv,
- "2:A:C:DGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y");
+ "2:A:C:DEGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:x:y");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
++optionsFound;
switch (optstate->option) {
@@ -2243,6 +2287,11 @@ main(int argc, char **argv)
case 'D':
noDelay = PR_TRUE;
break;
+
+ case 'E':
+ enablePostHandshakeAuth = PR_TRUE;
+ break;
+
case 'H':
configureDHE = (PORT_Atoi(optstate->value) != 0);
break;
@@ -2464,6 +2513,17 @@ main(int argc, char **argv)
}
break;
+ case 'x':
+ rv = parseExporters(optstate->value,
+ &enabledExporters, &enabledExporterCount);
+ if (rv != SECSuccess) {
+ PL_DestroyOptState(optstate);
+ fprintf(stderr, "Bad exporter specified.\n");
+ fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
+ exit(5);
+ }
+ break;
+
default:
case '?':
fprintf(stderr, "Unrecognized or bad option specified.\n");
@@ -2653,8 +2713,10 @@ main(int argc, char **argv)
}
if (cipher > 0) {
rv = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
- if (rv != SECSuccess)
- SECU_PrintError(progName, "SSL_CipherPrefSet()");
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "SSL_CipherPrefSetDefault()");
+ exit(9);
+ }
} else {
fprintf(stderr,
"Invalid cipher specification (-c arg).\n");
@@ -2692,6 +2754,12 @@ main(int argc, char **argv)
}
fprintf(stderr, "selfserv: Done creating dynamic weak DH parameters\n");
}
+ if (zeroRTT) {
+ rv = SSL_CreateAntiReplayContext(PR_Now(), 10L * PR_USEC_PER_SEC, 7, 14, &antiReplay);
+ if (rv != SECSuccess) {
+ errExit("Unable to create anti-replay context for 0-RTT.");
+ }
+ }
/* allocate the array of thread slots, and launch the worker threads. */
rv = launch_threads(&jobLoop, 0, 0, useLocalThreads);
@@ -2767,6 +2835,9 @@ cleanup:
if (enabledGroups) {
PORT_Free(enabledGroups);
}
+ if (antiReplay) {
+ SSL_ReleaseAntiReplayContext(antiReplay);
+ }
if (NSS_Shutdown() != SECSuccess) {
SECU_PrintError(progName, "NSS_Shutdown");
if (loggerThread) {
diff --git a/security/nss/cmd/shlibsign/shlibsign.c b/security/nss/cmd/shlibsign/shlibsign.c
index 221d1e67e..b0a7512ab 100644
--- a/security/nss/cmd/shlibsign/shlibsign.c
+++ b/security/nss/cmd/shlibsign/shlibsign.c
@@ -614,7 +614,7 @@ cleanup:
static char *
filePasswd(char *pwFile)
{
- unsigned char phrase[200];
+ unsigned char phrase[500];
PRFileDesc *fd;
PRInt32 nb;
int i;
diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c
index a2471884e..2283cdb52 100644
--- a/security/nss/cmd/ssltap/ssltap.c
+++ b/security/nss/cmd/ssltap/ssltap.c
@@ -2260,7 +2260,6 @@ print_hex(int amt, unsigned char *buf)
void
Usage(void)
{
- PR_fprintf(PR_STDERR, "SSLTAP (C) 1997, 1998 Netscape Communications Corporation.\n");
PR_fprintf(PR_STDERR, "Usage: ssltap [-vhfsxl] [-p port] hostname:port\n");
PR_fprintf(PR_STDERR, " -v [prints version string]\n");
PR_fprintf(PR_STDERR, " -h [outputs hex instead of ASCII]\n");
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index bba53efac..3d9fc4f78 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -121,6 +121,9 @@ static PRBool enableCertStatus = PR_FALSE;
PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
+static const SSLSignatureScheme *enabledSigSchemes = NULL;
+static unsigned int enabledSigSchemeCount = 0;
+
char *progName;
secuPWData pwdata = { PW_NONE, 0 };
@@ -143,7 +146,8 @@ Usage(void)
"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n"
" [-BDNovqs] [-f filename] [-N | -P percentage]\n"
" [-w dbpasswd] [-C cipher(s)] [-t threads] [-W pwfile]\n"
- " [-V [min-version]:[max-version]] [-a sniHostName] hostname\n"
+ " [-V [min-version]:[max-version]] [-a sniHostName]\n"
+ " [-J signatureschemes] hostname\n"
" where -v means verbose\n"
" -o flag is interpreted as follows:\n"
" 1 -o means override the result of server certificate validation.\n"
@@ -161,7 +165,20 @@ Usage(void)
" -T enable the cert_status extension (OCSP stapling)\n"
" -u enable TLS Session Ticket extension\n"
" -z enable compression\n"
- " -g enable false start\n",
+ " -g enable false start\n"
+ " -4 Enforce using an IPv4 destination address\n"
+ " -6 Enforce using an IPv6 destination address\n"
+ " Note: Default behavior is both IPv4 and IPv6 enabled\n"
+ " -J enable signature schemes\n"
+ " This takes a comma separated list of signature schemes in preference\n"
+ " order.\n"
+ " Possible values are:\n"
+ " rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
+ " ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n"
+ " ecdsa_secp521r1_sha512,\n"
+ " rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
+ " rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
+ " dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n",
progName);
exit(1);
}
@@ -1047,7 +1064,9 @@ client_main(
int connections,
cert_and_key *Cert_And_Key,
const char *hostName,
- const char *sniHostName)
+ const char *sniHostName,
+ PRBool allowIPv4,
+ PRBool allowIPv6)
{
PRFileDesc *model_sock = NULL;
int i;
@@ -1069,11 +1088,15 @@ client_main(
SECU_PrintError(progName, "error looking up host");
return;
}
- do {
+ for (;;) {
enumPtr = PR_EnumerateAddrInfo(enumPtr, addrInfo, port, &addr);
- } while (enumPtr != NULL &&
- addr.raw.family != PR_AF_INET &&
- addr.raw.family != PR_AF_INET6);
+ if (enumPtr == NULL)
+ break;
+ if (addr.raw.family == PR_AF_INET && allowIPv4)
+ break;
+ if (addr.raw.family == PR_AF_INET6 && allowIPv6)
+ break;
+ }
PR_FreeAddrInfo(addrInfo);
if (enumPtr == NULL) {
SECU_PrintError(progName, "error looking up host address");
@@ -1158,6 +1181,14 @@ client_main(
errExit("error setting SSL/TLS version range ");
}
+ if (enabledSigSchemes) {
+ rv = SSL_SignatureSchemePrefSet(model_sock, enabledSigSchemes,
+ enabledSigSchemeCount);
+ if (rv < 0) {
+ errExit("SSL_SignatureSchemePrefSet");
+ }
+ }
+
if (bigBuf.data) { /* doing FDX */
rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1);
if (rv < 0) {
@@ -1297,6 +1328,8 @@ main(int argc, char **argv)
int connections = 1;
int exitVal;
int tmpInt;
+ PRBool allowIPv4 = PR_TRUE;
+ PRBool allowIPv6 = PR_TRUE;
unsigned short port = 443;
SECStatus rv;
PLOptState *optstate;
@@ -1316,9 +1349,25 @@ main(int argc, char **argv)
/* XXX: 'B' was used in the past but removed in 3.28,
* please leave some time before resuing it. */
optstate = PL_CreateOptState(argc, argv,
- "C:DNP:TUV:W:a:c:d:f:gin:op:qst:uvw:z");
+ "46C:DJ:NP:TUV:W:a:c:d:f:gin:op:qst:uvw:z");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
+ case '4':
+ if (!allowIPv4) {
+ fprintf(stderr, "Only one of [-4, -6] can be specified.\n");
+ Usage();
+ }
+ allowIPv6 = PR_FALSE;
+ break;
+
+ case '6':
+ if (!allowIPv6) {
+ fprintf(stderr, "Only one of [-4, -6] can be specified.\n");
+ Usage();
+ }
+ allowIPv4 = PR_FALSE;
+ break;
+
case 'C':
cipherString = optstate->value;
break;
@@ -1330,6 +1379,15 @@ main(int argc, char **argv)
case 'I': /* reserved for OCSP multi-stapling */
break;
+ case 'J':
+ rv = parseSigSchemeList(optstate->value, &enabledSigSchemes, &enabledSigSchemeCount);
+ if (rv != SECSuccess) {
+ PL_DestroyOptState(optstate);
+ fprintf(stderr, "Bad signature scheme specified.\n");
+ Usage();
+ }
+ break;
+
case 'N':
NoReuse = 1;
break;
@@ -1492,7 +1550,7 @@ main(int argc, char **argv)
}
client_main(port, connections, &Cert_And_Key, hostName,
- sniHostName);
+ sniHostName, allowIPv4, allowIPv6);
/* clean up */
if (Cert_And_Key.cert) {
@@ -1516,6 +1574,8 @@ main(int argc, char **argv)
PL_strfree(hostName);
+ PORT_Free((SSLSignatureScheme *)enabledSigSchemes);
+
/* some final stats. */
printf(
"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
diff --git a/security/nss/cmd/symkeyutil/symkeyutil.c b/security/nss/cmd/symkeyutil/symkeyutil.c
index 31ab4dda4..630433823 100644
--- a/security/nss/cmd/symkeyutil/symkeyutil.c
+++ b/security/nss/cmd/symkeyutil/symkeyutil.c
@@ -254,7 +254,7 @@ HexToBuf(char *inString, SECItem *outbuf)
int trueLen = 0;
outbuf->data = PORT_Alloc(outlen);
- if (outbuf->data) {
+ if (!outbuf->data) {
return -1;
}
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index 520eeff64..6fa154106 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -213,6 +213,9 @@ printSecurityInfo(PRFileDesc *fd)
" %u\n",
scts->len);
}
+ if (channel.peerDelegCred) {
+ fprintf(stderr, "Received a Delegated Credential\n");
+ }
}
static void
@@ -221,7 +224,7 @@ PrintUsageHeader()
fprintf(stderr,
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
" [-D | -d certdir] [-C] [-b | -R root-module] \n"
- " [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n"
+ " [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z] [-E]\n"
" [-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
" [-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n"
" [-I groups] [-J signatureschemes]\n"
@@ -272,6 +275,7 @@ PrintParameterUsage()
fprintf(stderr, "%-20s Enable false start.\n", "-g");
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
fprintf(stderr, "%-20s Enable the signed_certificate_timestamp extension.\n", "-U");
+ fprintf(stderr, "%-20s Enable the delegated credentials extension.\n", "-B");
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
"%-20s -F once means: require for server cert only\n"
"%-20s -F twice means: require for intermediates, too\n"
@@ -311,6 +315,16 @@ PrintParameterUsage()
fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}");
fprintf(stderr, "%-20s Exit after handshake\n", "-Q");
fprintf(stderr, "%-20s Encrypted SNI Keys\n", "-N");
+ fprintf(stderr, "%-20s Enable post-handshake authentication\n"
+ "%-20s for TLS 1.3; need to specify -n\n",
+ "-E", "");
+ fprintf(stderr, "%-20s Export and print keying material after successful handshake.\n"
+ "%-20s The argument is a comma separated list of exporters in the form:\n"
+ "%-20s LABEL[:OUTPUT-LENGTH[:CONTEXT]]\n"
+ "%-20s where LABEL and CONTEXT can be either a free-form string or\n"
+ "%-20s a hex string if it is preceded by \"0x\"; OUTPUT-LENGTH\n"
+ "%-20s is a decimal integer.\n",
+ "-x", "", "", "", "", "");
}
static void
@@ -917,7 +931,7 @@ restartHandshakeAfterServerCertIfNeeded(PRFileDesc *fd,
PRBool override)
{
SECStatus rv;
- PRErrorCode error;
+ PRErrorCode error = 0;
if (!serverCertAuth->isPaused)
return SECSuccess;
@@ -989,6 +1003,10 @@ PRBool requestToExit = PR_FALSE;
char *versionString = NULL;
PRBool handshakeComplete = PR_FALSE;
char *encryptedSNIKeys = NULL;
+PRBool enablePostHandshakeAuth = PR_FALSE;
+PRBool enableDelegatedCredentials = PR_FALSE;
+const secuExporter *enabledExporters = NULL;
+unsigned int enabledExporterCount = 0;
static int
writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb)
@@ -1084,6 +1102,18 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
requestToExit = PR_TRUE;
}
handshakeComplete = PR_TRUE;
+
+ if (enabledExporters) {
+ SECStatus rv;
+
+ rv = exportKeyingMaterials(fd, enabledExporters, enabledExporterCount);
+ if (rv != SECSuccess) {
+ PRErrorCode err = PR_GetError();
+ FPRINTF(stderr,
+ "couldn't export keying material: %s\n",
+ SECU_Strerror(err));
+ }
+ }
}
static SECStatus
@@ -1304,8 +1334,11 @@ run()
}
if (cipher > 0) {
rv = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
- if (rv != SECSuccess)
+ if (rv != SECSuccess) {
SECU_PrintError(progName, "SSL_CipherPrefSet()");
+ error = 1;
+ goto done;
+ }
} else {
Usage();
}
@@ -1361,6 +1394,14 @@ run()
goto done;
}
+ /* enable negotiation of delegated credentials (draft-ietf-tls-subcerts) */
+ rv = SSL_OptionSet(s, SSL_ENABLE_DELEGATED_CREDENTIALS, enableDelegatedCredentials);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "error enabling delegated credentials");
+ error = 1;
+ goto done;
+ }
+
/* enable extended master secret mode */
if (enableExtendedMasterSecret) {
rv = SSL_OptionSet(s, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
@@ -1410,6 +1451,15 @@ run()
goto done;
}
+ if (enablePostHandshakeAuth) {
+ rv = SSL_OptionSet(s, SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "error enabling post-handshake auth");
+ error = 1;
+ goto done;
+ }
+ }
+
if (enabledGroups) {
rv = SSL_NamedGroupConfig(s, enabledGroups, enabledGroupsCount);
if (rv < 0) {
@@ -1702,12 +1752,11 @@ main(int argc, char **argv)
}
}
- /* Note: 'B' was used in the past but removed in 3.28
- * 'z' was removed in 3.39
+ /* Note: 'z' was removed in 3.39
* Please leave some time before reusing these.
*/
optstate = PL_CreateOptState(argc, argv,
- "46A:CDFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
+ "46A:BCDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:x:");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@@ -1730,6 +1779,10 @@ main(int argc, char **argv)
requestFile = PORT_Strdup(optstate->value);
break;
+ case 'B':
+ enableDelegatedCredentials = PR_TRUE;
+ break;
+
case 'C':
++dumpServerChain;
break;
@@ -1738,6 +1791,10 @@ main(int argc, char **argv)
openDB = PR_FALSE;
break;
+ case 'E':
+ enablePostHandshakeAuth = PR_TRUE;
+ break;
+
case 'F':
if (serverCertAuth.testFreshStatusFromSideChannel) {
/* parameter given twice or more */
@@ -1947,6 +2004,17 @@ main(int argc, char **argv)
Usage();
}
break;
+
+ case 'x':
+ rv = parseExporters(optstate->value,
+ &enabledExporters,
+ &enabledExporterCount);
+ if (rv != SECSuccess) {
+ PL_DestroyOptState(optstate);
+ fprintf(stderr, "Bad exporter specified.\n");
+ Usage();
+ }
+ break;
}
}
PL_DestroyOptState(optstate);
@@ -1988,6 +2056,11 @@ main(int argc, char **argv)
exit(1);
}
+ if (enablePostHandshakeAuth && !nickname) {
+ fprintf(stderr, "%s: -E requires the use of -n\n", progName);
+ exit(1);
+ }
+
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
PK11_SetPasswordFunc(SECU_GetModulePassword);
diff --git a/security/nss/cmd/vfyserv/vfyserv.c b/security/nss/cmd/vfyserv/vfyserv.c
index 4234ecd09..3c6d01481 100644
--- a/security/nss/cmd/vfyserv/vfyserv.c
+++ b/security/nss/cmd/vfyserv/vfyserv.c
@@ -544,7 +544,12 @@ main(int argc, char **argv)
}
}
if (cipher > 0) {
- SSL_CipherPrefSetDefault(cipher, PR_TRUE);
+ SECStatus rv = SSL_CipherPrefSetDefault(cipher, PR_TRUE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "error setting cipher default preference");
+ goto cleanup;
+ }
} else {
Usage(progName);
}