diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:06:40 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:06:40 +0100 |
commit | f4a12fc67689a830e9da1c87fd11afe5bc09deb3 (patch) | |
tree | 211ae0cd022a6c11b0026ecc7761a550c584583c /security/nss/cmd | |
parent | f7d30133221896638f7bf4f66c504255c4b14f48 (diff) | |
download | UXP-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')
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); } |