diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-06-06 21:27:04 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-06-06 21:27:04 +0200 |
commit | 4a71b30364a4b6d1eaf16fcfdc8e873e6697f293 (patch) | |
tree | a47014077c14579249859ad34afcc5a8f2f0730a /security/nss/cmd | |
parent | d7da72799521386c110dbba73b1e483b00a0a56a (diff) | |
parent | 2dad0ec41d0b69c0a815012e6ea4bdde81b2875b (diff) | |
download | UXP-4a71b30364a4b6d1eaf16fcfdc8e873e6697f293.tar UXP-4a71b30364a4b6d1eaf16fcfdc8e873e6697f293.tar.gz UXP-4a71b30364a4b6d1eaf16fcfdc8e873e6697f293.tar.lz UXP-4a71b30364a4b6d1eaf16fcfdc8e873e6697f293.tar.xz UXP-4a71b30364a4b6d1eaf16fcfdc8e873e6697f293.zip |
Merge branch 'NSS-335'
Diffstat (limited to 'security/nss/cmd')
30 files changed, 931 insertions, 477 deletions
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c index a3a162da1..ca3d6f314 100644 --- a/security/nss/cmd/bltest/blapitest.c +++ b/security/nss/cmd/bltest/blapitest.c @@ -20,16 +20,14 @@ #include "secport.h" #include "secoid.h" #include "nssutil.h" +#include "ecl-curve.h" #include "pkcs1_vectors.h" -#ifndef NSS_DISABLE_ECC -#include "ecl-curve.h" SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif char *progName; char *testdir = NULL; @@ -135,18 +133,14 @@ Usage() PRINTUSAGE(progName, "-S -m mode", "Sign a buffer"); PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]"); PRINTUSAGE("", "", "[-b bufsize]"); -#ifndef NSS_DISABLE_ECC PRINTUSAGE("", "", "[-n curvename]"); -#endif PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]"); PRINTUSAGE("", "-m", "cipher mode to use"); PRINTUSAGE("", "-i", "file which contains input buffer"); PRINTUSAGE("", "-o", "file for signature"); PRINTUSAGE("", "-k", "file which contains key"); -#ifndef NSS_DISABLE_ECC PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:"); PRINTUSAGE("", "", " nistp256, nistp384, nistp521"); -#endif PRINTUSAGE("", "-p", "do performance test"); PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); @@ -369,7 +363,6 @@ dsakey_from_filedata(PLArenaPool *arena, SECItem *filedata) return key; } -#ifndef NSS_DISABLE_ECC static ECPrivateKey * eckey_from_filedata(PLArenaPool *arena, SECItem *filedata) { @@ -519,7 +512,6 @@ getECParams(const char *curve) return ecparams; } -#endif /* NSS_DISABLE_ECC */ static void dump_pqg(PQGParams *pqg) @@ -537,7 +529,6 @@ dump_dsakey(DSAPrivateKey *key) SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0); } -#ifndef NSS_DISABLE_ECC static void dump_ecp(ECParams *ecp) { @@ -552,7 +543,6 @@ dump_eckey(ECPrivateKey *key) SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0); SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0); } -#endif static void dump_rsakey(RSAPrivateKey *key) @@ -638,17 +628,15 @@ typedef enum { bltestRSA, /* Public Key Ciphers */ bltestRSA_OAEP, /* . (Public Key Enc.) */ bltestRSA_PSS, /* . (Public Key Sig.) */ -#ifndef NSS_DISABLE_ECC - bltestECDSA, /* . (Public Key Sig.) */ -#endif - bltestDSA, /* . (Public Key Sig.) */ - bltestMD2, /* Hash algorithms */ - bltestMD5, /* . */ - bltestSHA1, /* . */ - bltestSHA224, /* . */ - bltestSHA256, /* . */ - bltestSHA384, /* . */ - bltestSHA512, /* . */ + bltestECDSA, /* . (Public Key Sig.) */ + bltestDSA, /* . (Public Key Sig.) */ + bltestMD2, /* Hash algorithms */ + bltestMD5, /* . */ + bltestSHA1, /* . */ + bltestSHA224, /* . */ + bltestSHA256, /* . */ + bltestSHA384, /* . */ + bltestSHA512, /* . */ NUMMODES } bltestCipherMode; @@ -678,9 +666,7 @@ static char *mode_strings[] = "rsa", "rsa_oaep", "rsa_pss", -#ifndef NSS_DISABLE_ECC "ecdsa", -#endif /*"pqg",*/ "dsa", "md2", @@ -732,13 +718,11 @@ typedef struct PQGParams *pqg; } bltestDSAParams; -#ifndef NSS_DISABLE_ECC typedef struct { char *curveName; bltestIO sigseed; } bltestECDSAParams; -#endif typedef struct { @@ -751,9 +735,7 @@ typedef struct union { bltestRSAParams rsa; bltestDSAParams dsa; -#ifndef NSS_DISABLE_ECC bltestECDSAParams ecdsa; -#endif } cipherParams; } bltestAsymKeyParams; @@ -1310,7 +1292,6 @@ dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input) return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input); } -#ifndef NSS_DISABLE_ECC SECStatus ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input) { @@ -1331,7 +1312,6 @@ ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input) bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input); } -#endif SECStatus bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt) @@ -1811,7 +1791,6 @@ bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) return SECSuccess; } -#ifndef NSS_DISABLE_ECC SECStatus bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) { @@ -1877,7 +1856,6 @@ bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) } return SECSuccess; } -#endif /* XXX unfortunately, this is not defined in blapi.h */ SECStatus @@ -2169,11 +2147,7 @@ finish: SECStatus pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, -#ifndef NSS_DISABLE_ECC int keysize, int exponent, char *curveName) -#else - int keysize, int exponent) -#endif { int i; SECStatus rv = SECSuccess; @@ -2182,12 +2156,10 @@ pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, RSAPrivateKey **rsaKey = NULL; bltestDSAParams *dsap; DSAPrivateKey **dsaKey = NULL; -#ifndef NSS_DISABLE_ECC SECItem *tmpECParamsDER; ECParams *tmpECParams = NULL; SECItem ecSerialize[3]; ECPrivateKey **ecKey = NULL; -#endif switch (cipherInfo->mode) { case bltestRSA: case bltestRSA_PSS: @@ -2224,7 +2196,6 @@ pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, dsap->keysize = (*dsaKey)->params.prime.len * 8; } break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: ecKey = (ECPrivateKey **)&asymk->privKey; if (curveName != NULL) { @@ -2254,7 +2225,6 @@ pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, *ecKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf); } break; -#endif default: return SECFailure; } @@ -2341,7 +2311,6 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) } return bltest_dsa_init(cipherInfo, encrypt); break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: if (encrypt) { SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, @@ -2349,7 +2318,6 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) } return bltest_ecdsa_init(cipherInfo, encrypt); break; -#endif case bltestMD2: restart = cipherInfo->params.hash.restart; SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, @@ -2644,9 +2612,7 @@ cipherFinish(bltestCipherInfo *cipherInfo) case bltestRSA_PSS: /* will be freed with it. */ case bltestRSA_OAEP: case bltestDSA: -#ifndef NSS_DISABLE_ECC case bltestECDSA: -#endif case bltestMD2: /* hash contexts are ephemeral */ case bltestMD5: case bltestSHA1: @@ -2822,7 +2788,6 @@ print_td: fprintf(stdout, "%8d", info->params.asymk.cipherParams.dsa.keysize); } break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: if (td) { fprintf(stdout, "%12s", "ec_curve"); @@ -2833,7 +2798,6 @@ print_td: ecCurve_map[curveName] ? ecCurve_map[curveName]->text : "Unsupported curve"); } break; -#endif case bltestMD2: case bltestMD5: case bltestSHA1: @@ -3063,7 +3027,6 @@ get_params(PLArenaPool *arena, bltestParams *params, sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j); load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); load_file_data(arena, ¶ms->asymk.key, filename, bltestBase64Encoded); @@ -3075,7 +3038,6 @@ get_params(PLArenaPool *arena, bltestParams *params, sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j); load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); break; -#endif case bltestMD2: case bltestMD5: case bltestSHA1: @@ -3297,13 +3259,11 @@ dump_file(bltestCipherMode mode, char *filename) load_file_data(arena, &keydata, filename, bltestBase64Encoded); key = dsakey_from_filedata(arena, &keydata.buf); dump_dsakey(key); -#ifndef NSS_DISABLE_ECC } else if (mode == bltestECDSA) { ECPrivateKey *key; load_file_data(arena, &keydata, filename, bltestBase64Encoded); key = eckey_from_filedata(arena, &keydata.buf); dump_eckey(key); -#endif } PORT_FreeArena(arena, PR_FALSE); return SECFailure; @@ -3590,9 +3550,7 @@ enum { opt_Key, opt_HexWSpc, opt_Mode, -#ifndef NSS_DISABLE_ECC opt_CurveName, -#endif opt_Output, opt_Repetitions, opt_ZeroBuf, @@ -3644,9 +3602,7 @@ static secuCommandFlag bltest_options[] = { /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE }, { /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE }, { /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE }, -#ifndef NSS_DISABLE_ECC { /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE }, -#endif { /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE }, { /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE }, { /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE }, @@ -3679,9 +3635,7 @@ main(int argc, char **argv) bltestCipherInfo *cipherInfoListHead, *cipherInfo = NULL; bltestIOMode ioMode; int bufsize, exponent, curThrdNum; -#ifndef NSS_DISABLE_ECC char *curveName = NULL; -#endif int i, commandsEntered; int inoff, outoff; int threads = 1; @@ -3917,12 +3871,10 @@ main(int argc, char **argv) else exponent = 65537; -#ifndef NSS_DISABLE_ECC if (bltest.options[opt_CurveName].activated) curveName = PORT_Strdup(bltest.options[opt_CurveName].arg); else curveName = NULL; -#endif if (bltest.commands[cmd_Verify].activated && !bltest.options[opt_SigFile].activated) { @@ -4008,11 +3960,7 @@ main(int argc, char **argv) file = PR_Open("tmp.key", PR_WRONLY | PR_CREATE_FILE, 00660); } params->key.mode = bltestBase64Encoded; -#ifndef NSS_DISABLE_ECC pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName); -#else - pubkeyInitKey(cipherInfo, file, keysize, exponent); -#endif PR_Close(file); } diff --git a/security/nss/cmd/certcgi/certcgi.c b/security/nss/cmd/certcgi/certcgi.c index 35409e250..4d1a1061a 100644 --- a/security/nss/cmd/certcgi/certcgi.c +++ b/security/nss/cmd/certcgi/certcgi.c @@ -233,8 +233,7 @@ make_datastruct(char *data, int len) if (remaining == 1) { remaining += fields; fields = fields * 2; - datastruct = (Pair *)PORT_Realloc(datastruct, fields * - sizeof(Pair)); + datastruct = (Pair *)PORT_Realloc(datastruct, fields * sizeof(Pair)); if (datastruct == NULL) { error_allocate(); } diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index fbc752c1b..03f4478b7 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -194,6 +194,8 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, PLArenaPool *arena; void *extHandle; SECItem signedReq = { siBuffer, NULL, 0 }; + SECAlgorithmID signAlg; + SECItem *params = NULL; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { @@ -211,11 +213,26 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, /* Change cert type to RSA-PSS, if desired. */ if (pssCertificate) { + params = SEC_CreateSignatureAlgorithmParameters(arena, + NULL, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + hashAlgTag, + NULL, + privk); + if (!params) { + PORT_FreeArena(arena, PR_FALSE); + SECKEY_DestroySubjectPublicKeyInfo(spki); + SECU_PrintError(progName, "unable to create RSA-PSS parameters"); + return SECFailure; + } + spki->algorithm.parameters.data = NULL; rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, - SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0); + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + hashAlgTag == SEC_OID_UNKNOWN ? NULL : params); if (rv != SECSuccess) { PORT_FreeArena(arena, PR_FALSE); + SECKEY_DestroySubjectPublicKeyInfo(spki); SECU_PrintError(progName, "unable to set algorithm ID"); return SECFailure; } @@ -256,16 +273,34 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, return SECFailure; } - /* Sign the request */ - signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); - if (signAlgTag == SEC_OID_UNKNOWN) { - PORT_FreeArena(arena, PR_FALSE); - SECU_PrintError(progName, "unknown Key or Hash type"); - return SECFailure; + PORT_Memset(&signAlg, 0, sizeof(signAlg)); + if (pssCertificate) { + rv = SECOID_SetAlgorithmID(arena, &signAlg, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, params); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + SECU_PrintError(progName, "unable to set algorithm ID"); + return SECFailure; + } + } else { + signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); + if (signAlgTag == SEC_OID_UNKNOWN) { + PORT_FreeArena(arena, PR_FALSE); + SECU_PrintError(progName, "unknown Key or Hash type"); + return SECFailure; + } + rv = SECOID_SetAlgorithmID(arena, &signAlg, signAlgTag, 0); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + SECU_PrintError(progName, "unable to set algorithm ID"); + return SECFailure; + } } - rv = SEC_DerSignData(arena, &signedReq, encoding->data, encoding->len, - privk, signAlgTag); + /* Sign the request */ + rv = SEC_DerSignDataWithAlgorithmID(arena, &signedReq, + encoding->data, encoding->len, + privk, &signAlg); if (rv) { PORT_FreeArena(arena, PR_FALSE); SECU_PrintError(progName, "signing of data failed"); @@ -365,7 +400,7 @@ ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot, CERTCertificate *cert; CERTCertTrust *trust; - cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata); if (!cert) { SECU_PrintError(progName, "could not find certificate named \"%s\"", name); @@ -591,6 +626,10 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, char *email, { SECStatus rv; + if (slot && PK11_NeedUserInit(slot)) { + printf("\nDatabase needs user init\n"); + } + if (!ascii && !raw && !nickname && !email) { PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n", "Certificate Nickname", "Trust Attributes", "", @@ -614,12 +653,12 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, char *email, } static SECStatus -DeleteCert(CERTCertDBHandle *handle, char *name) +DeleteCert(CERTCertDBHandle *handle, char *name, void *pwdata) { SECStatus rv; CERTCertificate *cert; - cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata); if (!cert) { SECU_PrintError(progName, "could not find certificate named \"%s\"", name); @@ -635,12 +674,12 @@ DeleteCert(CERTCertDBHandle *handle, char *name) } static SECStatus -RenameCert(CERTCertDBHandle *handle, char *name, char *newName) +RenameCert(CERTCertDBHandle *handle, char *name, char *newName, void *pwdata) { SECStatus rv; CERTCertificate *cert; - cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata); if (!cert) { SECU_PrintError(progName, "could not find certificate named \"%s\"", name); @@ -1015,6 +1054,18 @@ ListModules(void) } static void +PrintBuildFlags() +{ +#ifdef NSS_FIPS_DISABLED + PR_fprintf(PR_STDOUT, "NSS_FIPS_DISABLED\n"); +#endif +#ifdef NSS_NO_INIT_SUPPORT + PR_fprintf(PR_STDOUT, "NSS_NO_INIT_SUPPORT\n"); +#endif + exit(0); +} + +static void PrintSyntax(char *progName) { #define FPS fprintf(stderr, @@ -1044,15 +1095,10 @@ PrintSyntax(char *progName) "\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -G [-h token-name] -k dsa [-q pqgfile -g key-size] [-f pwfile]\n" "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); -#ifndef NSS_DISABLE_ECC FPS "\t%s -G [-h token-name] -k ec -q curve [-f pwfile]\n" "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|ec|rsa|all]\n", progName); -#else - FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|rsa|all]\n", - progName); -#endif /* NSS_DISABLE_ECC */ FPS "\t\t [-f pwfile] [-X] [-d certdir] [-P dbprefix]\n"); FPS "\t%s --upgrade-merge --source-dir upgradeDir --upgrade-id uniqueID\n", progName); @@ -1066,6 +1112,7 @@ PrintSyntax(char *progName) FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n", progName); FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n"); + FPS "\t%s --build-flags\n", progName); FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName); @@ -1184,6 +1231,8 @@ luC(enum usage_level ul, const char *command) " -o output-cert"); FPS "%-20s Self sign\n", " -x"); + FPS "%-20s Sign the certificate with RSA-PSS (the issuer key must be rsa)\n", + " --pss-sign"); FPS "%-20s Cert serial number\n", " -m serial-number"); FPS "%-20s Time Warp\n", @@ -1244,17 +1293,10 @@ luG(enum usage_level ul, const char *command) return; FPS "%-20s Name of token in which to generate key (default is internal)\n", " -h token-name"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", " -k key-type"); FPS "%-20s Key size in bits, (min %d, max %d, default %d) (not for ec)\n", " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); -#else - FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", - " -k key-type"); - FPS "%-20s Key size in bits, (min %d, max %d, default %d)\n", - " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); -#endif /* NSS_DISABLE_ECC */ FPS "%-20s Set the public exponent value (3, 17, 65537) (rsa only)\n", " -y exp"); FPS "%-20s Specify the password file\n", @@ -1263,7 +1305,6 @@ luG(enum usage_level ul, const char *command) " -z noisefile"); FPS "%-20s read PQG value from pqgfile (dsa only)\n", " -q pqgfile"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Elliptic curve name (ec only)\n", " -q curve-name"); FPS "%-20s One of nistp256, nistp384, nistp521, curve25519.\n", ""); @@ -1285,7 +1326,6 @@ luG(enum usage_level ul, const char *command) FPS "%-20s c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, \n", ""); FPS "%-20s secp112r2, secp128r1, secp128r2, sect113r1, sect113r2\n", ""); FPS "%-20s sect131r1, sect131r2\n", ""); -#endif FPS "%-20s Key database directory (default is ~/.netscape)\n", " -d keydir"); FPS "%-20s Cert & Key database prefix\n", @@ -1375,9 +1415,7 @@ luK(enum usage_level ul, const char *command) " -h token-name "); FPS "%-20s Key type (\"all\" (default), \"dsa\"," -#ifndef NSS_DISABLE_ECC " \"ec\"," -#endif " \"rsa\")\n", " -k key-type"); FPS "%-20s The nickname of the key or associated certificate\n", @@ -1520,11 +1558,7 @@ luR(enum usage_level ul, const char *command) " -s subject"); FPS "%-20s Output the cert request to this file\n", " -o output-req"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", -#else - FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", -#endif /* NSS_DISABLE_ECC */ " -k key-type-or-id"); FPS "%-20s or nickname of the cert key to use \n", ""); @@ -1532,14 +1566,14 @@ luR(enum usage_level ul, const char *command) " -h token-name"); FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n", " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); + FPS "%-20s Create a certificate request restricted to RSA-PSS (rsa only)\n", + " --pss"); FPS "%-20s Name of file containing PQG parameters (dsa only)\n", " -q pqgfile"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Elliptic curve name (ec only)\n", " -q curve-name"); FPS "%-20s See the \"-G\" option for a full list of supported names.\n", ""); -#endif /* NSS_DISABLE_ECC */ FPS "%-20s Specify the password file\n", " -f pwfile"); FPS "%-20s Key database directory (default is ~/.netscape)\n", @@ -1705,26 +1739,24 @@ luS(enum usage_level ul, const char *command) " -c issuer-name"); FPS "%-20s Set the certificate trust attributes (see -A above)\n", " -t trustargs"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", -#else - FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", -#endif /* NSS_DISABLE_ECC */ " -k key-type-or-id"); FPS "%-20s Name of token in which to generate key (default is internal)\n", " -h token-name"); FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n", " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); + FPS "%-20s Create a certificate restricted to RSA-PSS (rsa only)\n", + " --pss"); FPS "%-20s Name of file containing PQG parameters (dsa only)\n", " -q pqgfile"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Elliptic curve name (ec only)\n", " -q curve-name"); FPS "%-20s See the \"-G\" option for a full list of supported names.\n", ""); -#endif /* NSS_DISABLE_ECC */ FPS "%-20s Self sign\n", " -x"); + FPS "%-20s Sign the certificate with RSA-PSS (the issuer key must be rsa)\n", + " --pss-sign"); FPS "%-20s Cert serial number\n", " -m serial-number"); FPS "%-20s Time Warp\n", @@ -1794,6 +1826,18 @@ luS(enum usage_level ul, const char *command) } static void +luBuildFlags(enum usage_level ul, const char *command) +{ + int is_my_command = (command && 0 == strcmp(command, "build-flags")); + if (ul == usage_all || !command || is_my_command) + FPS "%-15s Print enabled build flags relevant for NSS test execution\n", + "--build-flags"); + if (ul == usage_selected && !is_my_command) + return; + FPS "\n"); +} + +static void LongUsage(char *progName, enum usage_level ul, const char *command) { luA(ul, command); @@ -1807,6 +1851,7 @@ LongUsage(char *progName, enum usage_level ul, const char *command) luU(ul, command); luK(ul, command); luL(ul, command); + luBuildFlags(ul, command); luM(ul, command); luN(ul, command); luT(ul, command); @@ -1889,46 +1934,119 @@ MakeV1Cert(CERTCertDBHandle *handle, } static SECStatus +SetSignatureAlgorithm(PLArenaPool *arena, + SECAlgorithmID *signAlg, + SECAlgorithmID *spkiAlg, + SECOidTag hashAlgTag, + SECKEYPrivateKey *privKey, + PRBool pssSign) +{ + SECStatus rv; + + if (pssSign || + SECOID_GetAlgorithmTag(spkiAlg) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + SECItem *srcParams; + SECItem *params; + + if (SECOID_GetAlgorithmTag(spkiAlg) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + srcParams = &spkiAlg->parameters; + } else { + /* If the issuer's public key is RSA, the parameter field + * of the SPKI should be NULL, which can't be used as a + * basis of RSA-PSS parameters. */ + srcParams = NULL; + } + params = SEC_CreateSignatureAlgorithmParameters(arena, + NULL, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + hashAlgTag, + srcParams, + privKey); + if (!params) { + SECU_PrintError(progName, "Could not create RSA-PSS parameters"); + return SECFailure; + } + rv = SECOID_SetAlgorithmID(arena, signAlg, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + params); + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set signature algorithm id."); + return rv; + } + } else { + KeyType keyType = SECKEY_GetPrivateKeyType(privKey); + SECOidTag algID; + + algID = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); + if (algID == SEC_OID_UNKNOWN) { + SECU_PrintError(progName, "Unknown key or hash type for issuer."); + return SECFailure; + } + rv = SECOID_SetAlgorithmID(arena, signAlg, algID, 0); + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set signature algorithm id."); + return rv; + } + } + return SECSuccess; +} + +static SECStatus SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, SECOidTag hashAlgTag, SECKEYPrivateKey *privKey, char *issuerNickName, - int certVersion, void *pwarg) + int certVersion, PRBool pssSign, void *pwarg) { SECItem der; SECKEYPrivateKey *caPrivateKey = NULL; SECStatus rv; PLArenaPool *arena; - SECOidTag algID; + CERTCertificate *issuer; void *dummy; - if (!selfsign) { - CERTCertificate *issuer = PK11_FindCertFromNickname(issuerNickName, pwarg); + arena = cert->arena; + + if (selfsign) { + issuer = cert; + } else { + issuer = PK11_FindCertFromNickname(issuerNickName, pwarg); if ((CERTCertificate *)NULL == issuer) { SECU_PrintError(progName, "unable to find issuer with nickname %s", issuerNickName); - return SECFailure; + rv = SECFailure; + goto done; } - privKey = caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg); - CERT_DestroyCertificate(issuer); if (caPrivateKey == NULL) { SECU_PrintError(progName, "unable to retrieve key %s", issuerNickName); - return SECFailure; + rv = SECFailure; + CERT_DestroyCertificate(issuer); + goto done; } } - arena = cert->arena; - - algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlgTag); - if (algID == SEC_OID_UNKNOWN) { - fprintf(stderr, "Unknown key or hash type for issuer."); + if (pssSign && + (SECKEY_GetPrivateKeyType(privKey) != rsaKey && + SECKEY_GetPrivateKeyType(privKey) != rsaPssKey)) { + SECU_PrintError(progName, "unable to create RSA-PSS signature with key %s", + issuerNickName); rv = SECFailure; + if (!selfsign) { + CERT_DestroyCertificate(issuer); + } goto done; } - rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0); + rv = SetSignatureAlgorithm(arena, + &cert->signature, + &issuer->subjectPublicKeyInfo.algorithm, + hashAlgTag, + privKey, + pssSign); + if (!selfsign) { + CERT_DestroyCertificate(issuer); + } if (rv != SECSuccess) { - fprintf(stderr, "Could not set signature algorithm id."); goto done; } @@ -1947,7 +2065,8 @@ SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + rv = SECFailure; + goto done; } der.len = 0; @@ -1960,7 +2079,8 @@ SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, goto done; } - rv = SEC_DerSignData(arena, &cert->derCert, der.data, der.len, privKey, algID); + rv = SEC_DerSignDataWithAlgorithmID(arena, &cert->derCert, der.data, der.len, + privKey, &cert->signature); if (rv != SECSuccess) { fprintf(stderr, "Could not sign encoded certificate data.\n"); /* result allocated out of the arena, it will be freed @@ -1993,6 +2113,7 @@ CreateCert( certutilExtnList extnList, const char *extGeneric, int certVersion, + PRBool pssSign, SECItem *certDER) { void *extHandle = NULL; @@ -2053,7 +2174,7 @@ CreateCert( rv = SignCert(handle, subjectCert, selfsign, hashAlgTag, *selfsignprivkey, issuerNickName, - certVersion, pwarg); + certVersion, pssSign, pwarg); if (rv != SECSuccess) break; @@ -2306,6 +2427,7 @@ enum { cmd_Merge, cmd_UpgradeMerge, /* test only */ cmd_Rename, + cmd_BuildFlags, max_cmd }; @@ -2376,6 +2498,7 @@ enum certutilOpts { opt_GenericExtensions, opt_NewNickname, opt_Pss, + opt_PssSign, opt_Help }; @@ -2407,7 +2530,9 @@ static const secuCommandFlag commands_init[] = { /* cmd_UpgradeMerge */ 0, PR_FALSE, 0, PR_FALSE, "upgrade-merge" }, { /* cmd_Rename */ 0, PR_FALSE, 0, PR_FALSE, - "rename" } + "rename" }, + { /* cmd_BuildFlags */ 0, PR_FALSE, 0, PR_FALSE, + "build-flags" } }; #define NUM_COMMANDS ((sizeof commands_init) / (sizeof commands_init[0])) @@ -2496,6 +2621,8 @@ static const secuCommandFlag options_init[] = "new-n" }, { /* opt_Pss */ 0, PR_FALSE, 0, PR_FALSE, "pss" }, + { /* opt_PssSign */ 0, PR_FALSE, 0, PR_FALSE, + "pss-sign" }, }; #define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0])) @@ -2592,6 +2719,10 @@ certutil_main(int argc, char **argv, PRBool initialize) exit(1); } + if (certutil.commands[cmd_BuildFlags].activated) { + PrintBuildFlags(); + } + if (certutil.options[opt_PasswordFile].arg) { pwdata.source = PW_FROMFILE; pwdata.data = certutil.options[opt_PasswordFile].arg; @@ -2621,12 +2752,10 @@ certutil_main(int argc, char **argv, PRBool initialize) progName, MIN_KEY_BITS, MAX_KEY_BITS); return 255; } -#ifndef NSS_DISABLE_ECC if (keytype == ecKey) { PR_fprintf(PR_STDERR, "%s -g: Not for ec keys.\n", progName); return 255; } -#endif /* NSS_DISABLE_ECC */ } /* -h specify token name */ @@ -2655,10 +2784,8 @@ certutil_main(int argc, char **argv, PRBool initialize) keytype = rsaKey; } else if (PL_strcmp(arg, "dsa") == 0) { keytype = dsaKey; -#ifndef NSS_DISABLE_ECC } else if (PL_strcmp(arg, "ec") == 0) { keytype = ecKey; -#endif /* NSS_DISABLE_ECC */ } else if (PL_strcmp(arg, "all") == 0) { keytype = nullKey; } else { @@ -2711,16 +2838,10 @@ certutil_main(int argc, char **argv, PRBool initialize) /* -q PQG file or curve name */ if (certutil.options[opt_PQGFile].activated) { -#ifndef NSS_DISABLE_ECC if ((keytype != dsaKey) && (keytype != ecKey)) { PR_fprintf(PR_STDERR, "%s -q: specifies a PQG file for DSA keys" " (-k dsa) or a named curve for EC keys (-k ec)\n)", progName); -#else /* } */ - if (keytype != dsaKey) { - PR_fprintf(PR_STDERR, "%s -q: PQG file is for DSA key (-k dsa).\n)", - progName); -#endif /* NSS_DISABLE_ECC */ return 255; } } @@ -3032,11 +3153,43 @@ certutil_main(int argc, char **argv, PRBool initialize) /* If creating new database, initialize the password. */ if (certutil.commands[cmd_NewDBs].activated) { - if (certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot))) - PK11_InitPin(slot, (char *)NULL, ""); - else - SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, - certutil.options[opt_NewPasswordFile].arg); + if (certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot))) { + rv = PK11_InitPin(slot, (char *)NULL, ""); + } else { + rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, + certutil.options[opt_NewPasswordFile].arg); + } + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set password for the slot"); + goto shutdown; + } + } + + /* if we are going to modify the cert database, + * make sure it's initialized */ + if (certutil.commands[cmd_ModifyCertTrust].activated || + certutil.commands[cmd_CreateAndAddCert].activated || + certutil.commands[cmd_AddCert].activated || + certutil.commands[cmd_AddEmailCert].activated) { + if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) { + char *password = NULL; + /* fetch the password from the command line or the file + * if no password is supplied, initialize the password to NULL */ + if (pwdata.source == PW_FROMFILE) { + password = SECU_FilePasswd(slot, PR_FALSE, pwdata.data); + } else if (pwdata.source == PW_PLAINTEXT) { + password = PL_strdup(pwdata.data); + } + rv = PK11_InitPin(slot, (char *)NULL, password ? password : ""); + if (password) { + PORT_Memset(password, 0, PL_strlen(password)); + PORT_Free(password); + } + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set password for the slot"); + goto shutdown; + } + } } /* walk through the upgrade merge if necessary. @@ -3214,12 +3367,12 @@ certutil_main(int argc, char **argv, PRBool initialize) } /* Delete cert (-D) */ if (certutil.commands[cmd_DeleteCert].activated) { - rv = DeleteCert(certHandle, name); + rv = DeleteCert(certHandle, name, &pwdata); goto shutdown; } /* Rename cert (--rename) */ if (certutil.commands[cmd_Rename].activated) { - rv = RenameCert(certHandle, name, newName); + rv = RenameCert(certHandle, name, newName, &pwdata); goto shutdown; } /* Delete key (-F) */ @@ -3237,7 +3390,10 @@ certutil_main(int argc, char **argv, PRBool initialize) if (certutil.commands[cmd_ChangePassword].activated) { rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, certutil.options[opt_NewPasswordFile].arg); - goto shutdown; + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set password for the slot"); + goto shutdown; + } } /* Reset the a token */ if (certutil.commands[cmd_TokenReset].activated) { @@ -3362,6 +3518,25 @@ certutil_main(int argc, char **argv, PRBool initialize) } } + /* --pss-sign is to sign a certificate with RSA-PSS, even if the + * issuer's key is an RSA key. If the key is an RSA-PSS key, the + * generated signature is always RSA-PSS. */ + if (certutil.options[opt_PssSign].activated) { + if (!certutil.commands[cmd_CreateNewCert].activated && + !certutil.commands[cmd_CreateAndAddCert].activated) { + PR_fprintf(PR_STDERR, + "%s -%c: --pss-sign only works with -C or -S.\n", + progName, commandToRun); + return 255; + } + if (keytype != rsaKey) { + PR_fprintf(PR_STDERR, + "%s -%c: --pss-sign only works with RSA keys.\n", + progName, commandToRun); + return 255; + } + } + /* If we need a list of extensions convert the flags into list format */ if (certutil.commands[cmd_CertReq].activated || certutil.commands[cmd_CreateAndAddCert].activated || @@ -3499,6 +3674,7 @@ certutil_main(int argc, char **argv, PRBool initialize) (certutil.options[opt_GenericExtensions].activated ? certutil.options[opt_GenericExtensions].arg : NULL), certVersion, + certutil.options[opt_PssSign].activated, &certDER); if (rv) goto shutdown; diff --git a/security/nss/cmd/certutil/keystuff.c b/security/nss/cmd/certutil/keystuff.c index 2878e3765..330284c61 100644 --- a/security/nss/cmd/certutil/keystuff.c +++ b/security/nss/cmd/certutil/keystuff.c @@ -380,7 +380,6 @@ CERTUTIL_FileForRNG(const char *noise) return SECSuccess; } -#ifndef NSS_DISABLE_ECC typedef struct curveNameTagPairStr { char *curveName; SECOidTag curveOidTag; @@ -495,9 +494,9 @@ getECParams(const char *curve) ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len)); - /* + /* * ecparams->data needs to contain the ASN encoding of an object ID (OID) - * representing the named curve. The actual OID is in + * representing the named curve. The actual OID is in * oidData->oid.data so we simply prepend 0x06 and OID length */ ecparams->data[0] = SEC_ASN1_OBJECT_ID; @@ -506,7 +505,6 @@ getECParams(const char *curve) return ecparams; } -#endif /* NSS_DISABLE_ECC */ SECKEYPrivateKey * CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, @@ -564,14 +562,12 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, params = (void *)&default_pqg_params; } break; -#ifndef NSS_DISABLE_ECC case ecKey: mechanism = CKM_EC_KEY_PAIR_GEN; /* For EC keys, PQGFile determines EC parameters */ if ((params = (void *)getECParams(pqgFile)) == NULL) return NULL; break; -#endif /* NSS_DISABLE_ECC */ default: return NULL; } @@ -580,8 +576,7 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, fprintf(stderr, "Generating key. This may take a few moments...\n\n"); privKey = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubkeyp, - attrFlags, opFlagsOn, opFlagsOn | - opFlagsOff, + attrFlags, opFlagsOn, opFlagsOn | opFlagsOff, pwdata /*wincx*/); /* free up the params */ switch (keytype) { @@ -589,11 +584,9 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, if (dsaparams) CERTUTIL_DestroyParamsPQG(dsaparams); break; -#ifndef NSS_DISABLE_ECC case ecKey: SECITEM_FreeItem((SECItem *)params, PR_TRUE); break; -#endif default: /* nothing to free */ break; } diff --git a/security/nss/cmd/crlutil/crlgen.c b/security/nss/cmd/crlutil/crlgen.c index 1f9dc4b43..fce5e2a60 100644 --- a/security/nss/cmd/crlutil/crlgen.c +++ b/security/nss/cmd/crlutil/crlgen.c @@ -616,8 +616,7 @@ crlgen_CreateInvalidityDate(PLArenaPool *arena, const char **dataArr, goto loser; } - PORT_Memcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) * - sizeof(char)); + PORT_Memcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) * sizeof(char)); *extCode = SEC_OID_X509_INVALID_DATE; return encodedItem; diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c index ab73e42a5..061f3dde0 100644 --- a/security/nss/cmd/fipstest/fipstest.c +++ b/security/nss/cmd/fipstest/fipstest.c @@ -35,13 +35,11 @@ #include "../../lib/freebl/mpi/mpi.h" #endif -#ifndef NSS_DISABLE_ECC extern SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); extern SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif #define ENCRYPT 1 #define DECRYPT 0 @@ -2094,7 +2092,6 @@ get_next_line(FILE *req, char *key, char *val, FILE *rsp) return (c == EOF) ? -1 : ignore; } -#ifndef NSS_DISABLE_ECC typedef struct curveNameTagPairStr { char *curveName; SECOidTag curveOidTag; @@ -2958,7 +2955,6 @@ loser: } fclose(ecdsareq); } -#endif /* NSS_DISABLE_ECC */ PRBool isblankline(char *b) @@ -5926,8 +5922,7 @@ tls(char *reqfn) goto loser; } crv = NSC_DeriveKey(session, &master_mech, pms_handle, - derive_template, derive_template_count - - 1, + derive_template, derive_template_count - 1, &master_handle); if (crv != CKR_OK) { fprintf(stderr, "NSC_DeriveKey(master) failed crv=0x%x\n", @@ -6094,7 +6089,6 @@ main(int argc, char **argv) /* Signature Verification Test */ dsa_sigver_test(argv[3]); } -#ifndef NSS_DISABLE_ECC /*************/ /* ECDSA */ /*************/ @@ -6113,7 +6107,6 @@ main(int argc, char **argv) /* Signature Verification Test */ ecdsa_sigver_test(argv[3]); } -#endif /* NSS_DISABLE_ECC */ /*************/ /* RNG */ /*************/ diff --git a/security/nss/cmd/fipstest/runtest.sh b/security/nss/cmd/fipstest/runtest.sh index 99cefed77..5f8e66a08 100644 --- a/security/nss/cmd/fipstest/runtest.sh +++ b/security/nss/cmd/fipstest/runtest.sh @@ -7,9 +7,6 @@ TESTDIR=${1-.} COMMAND=${2-run} TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea" -if [ ${NSS_ENABLE_ECC}x = 1x ]; then - TESTS=${TESTS} ecdsa -fi for i in $TESTS do echo "********************Running $i tests" diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index cb4752df9..2b33f8963 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -54,6 +54,10 @@ static char consoleName[] = { static PRBool utf8DisplayEnabled = PR_FALSE; +/* The minimum password/pin length (in Unicode characters) in FIPS mode, + * defined in lib/softoken/pkcs11i.h. */ +#define FIPS_MIN_PIN 7 + void SECU_EnableUtf8Display(PRBool enable) { @@ -236,7 +240,8 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) sprintf(prompt, "Press Enter, then enter PIN for \"%s\" on external device.\n", PK11_GetTokenName(slot)); - (void)SECU_GetPasswordString(NULL, prompt); + char *pw = SECU_GetPasswordString(NULL, prompt); + PORT_Free(pw); /* Fall Through */ case PW_PLAINTEXT: return PL_strdup(pwdata->data); @@ -276,10 +281,25 @@ secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg) } /* we have no password, so initialize database with one */ - PR_fprintf(PR_STDERR, - "Enter a password which will be used to encrypt your keys.\n" - "The password should be at least 8 characters long,\n" - "and should contain at least one non-alphabetic character.\n\n"); + if (PK11_IsFIPS()) { + PR_fprintf(PR_STDERR, + "Enter a password which will be used to encrypt your keys.\n" + "The password should be at least %d characters long,\n" + "and should consist of at least three character classes.\n" + "The available character classes are: digits (0-9), ASCII\n" + "lowercase letters, ASCII uppercase letters, ASCII\n" + "non-alphanumeric characters, and non-ASCII characters.\n\n" + "If an ASCII uppercase letter appears at the beginning of\n" + "the password, it is not counted toward its character class.\n" + "Similarly, if a digit appears at the end of the password,\n" + "it is not counted toward its character class.\n\n", + FIPS_MIN_PIN); + } else { + PR_fprintf(PR_STDERR, + "Enter a password which will be used to encrypt your keys.\n" + "The password should be at least 8 characters long,\n" + "and should contain at least one non-alphabetic character.\n\n"); + } output = fopen(consoleName, "w"); if (output == NULL) { @@ -465,48 +485,6 @@ SECU_ConfigDirectory(const char *base) return buf; } -/*Turn off SSL for now */ -/* This gets called by SSL when server wants our cert & key */ -int -SECU_GetClientAuthData(void *arg, PRFileDesc *fd, - struct CERTDistNamesStr *caNames, - struct CERTCertificateStr **pRetCert, - struct SECKEYPrivateKeyStr **pRetKey) -{ - SECKEYPrivateKey *key; - CERTCertificate *cert; - int errsave; - - if (arg == NULL) { - fprintf(stderr, "no key/cert name specified for client auth\n"); - return -1; - } - cert = PK11_FindCertFromNickname(arg, NULL); - errsave = PORT_GetError(); - if (!cert) { - if (errsave == SEC_ERROR_BAD_PASSWORD) - fprintf(stderr, "Bad password\n"); - else if (errsave > 0) - fprintf(stderr, "Unable to read cert (error %d)\n", errsave); - else if (errsave == SEC_ERROR_BAD_DATABASE) - fprintf(stderr, "Unable to get cert from database (%d)\n", errsave); - else - fprintf(stderr, "SECKEY_FindKeyByName: internal error %d\n", errsave); - return -1; - } - - key = PK11_FindKeyByAnyCert(arg, NULL); - if (!key) { - fprintf(stderr, "Unable to get key (%d)\n", PORT_GetError()); - return -1; - } - - *pRetCert = cert; - *pRetKey = key; - - return 0; -} - SECStatus SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii, PRBool warnOnPrivateKeyInAsciiFile) @@ -991,7 +969,7 @@ secu_PrintUniversalString(FILE *out, const SECItem *i, const char *m, int level) for (s = my.data, d = tmp.data; len > 0; len--) { PRUint32 bmpChar = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; s += 4; - if (!isprint(bmpChar)) + if (!isprint(bmpChar & 0xFF)) goto loser; *d++ = (unsigned char)bmpChar; } @@ -1215,7 +1193,7 @@ secu_PrintRSAPSSParams(FILE *out, SECItem *value, char *m, int level) SECU_Indent(out, level + 1); fprintf(out, "Salt length: default, %i (0x%2X)\n", 20, 20); } else { - SECU_PrintInteger(out, ¶m.saltLength, "Salt Length", level + 1); + SECU_PrintInteger(out, ¶m.saltLength, "Salt length", level + 1); } } else { SECU_Indent(out, level + 1); @@ -1335,15 +1313,12 @@ SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level) return; } - if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { - secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1); - return; - } - if (a->parameters.len == 0 || (a->parameters.len == 2 && PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) { /* No arguments or NULL argument */ + } else if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1); } else { /* Print args to algorithm */ SECU_PrintAsHex(out, &a->parameters, "Args", level + 1); @@ -1390,7 +1365,6 @@ secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level) } } -#ifndef NSS_DISABLE_ECC static void secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) { @@ -1409,7 +1383,6 @@ secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) SECU_PrintObjectID(out, &curveOID, "Curve", level + 1); } } -#endif /* NSS_DISABLE_ECC */ void SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) @@ -1457,11 +1430,9 @@ secu_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena, SECU_PrintDSAPublicKey(out, pk, "DSA Public Key", level + 1); break; -#ifndef NSS_DISABLE_ECC case ecKey: secu_PrintECPublicKey(out, pk, "EC Public Key", level + 1); break; -#endif case dhKey: case fortezzaKey: @@ -3614,44 +3585,6 @@ loser: return rv; } -#if 0 - -/* we need access to the private function cert_FindExtension for this code to work */ - -CERTAuthKeyID * -SECU_FindCRLAuthKeyIDExten (PLArenaPool *arena, CERTSignedCrl *scrl) -{ - SECItem encodedExtenValue; - SECStatus rv; - CERTAuthKeyID *ret; - CERTCrl* crl; - - if (!scrl) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - crl = &scrl->crl; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(crl->extensions, SEC_OID_X509_AUTH_KEY_ID, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (NULL); - } - - ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); - - PORT_Free(encodedExtenValue.data); - encodedExtenValue.data = NULL; - - return(ret); -} - -#endif - /* * Find the issuer of a Crl. Use the authorityKeyID if it exists. */ @@ -3725,7 +3658,7 @@ SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle, void *pwarg) { CERTCertificate *the_cert; - the_cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + the_cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwarg); if (the_cert) { return the_cert; } diff --git a/security/nss/cmd/libpkix/pkix/util/test_list2.c b/security/nss/cmd/libpkix/pkix/util/test_list2.c index 7e4114e52..b802ff0e6 100644 --- a/security/nss/cmd/libpkix/pkix/util/test_list2.c +++ b/security/nss/cmd/libpkix/pkix/util/test_list2.c @@ -78,16 +78,14 @@ test_list2(int argc, char *argv[]) for (i = 0; i < size; i++) for (j = 9; j > i; j--) { PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j, &obj, plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j - - 1, + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j - 1, &obj2, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Compare(obj, obj2, &cmpResult, plContext)); if (cmpResult < 0) { /* Exchange the items */ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j, obj2, plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j - - 1, + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j - 1, obj, plContext)); } /* DecRef objects */ diff --git a/security/nss/cmd/listsuites/listsuites.c b/security/nss/cmd/listsuites/listsuites.c index 458130e5e..8eb2c3553 100644 --- a/security/nss/cmd/listsuites/listsuites.c +++ b/security/nss/cmd/listsuites/listsuites.c @@ -10,7 +10,9 @@ #include <errno.h> #include <stdio.h> +#include "nss.h" #include "secport.h" +#include "secutil.h" #include "ssl.h" int @@ -19,6 +21,43 @@ main(int argc, char **argv) const PRUint16 *cipherSuites = SSL_ImplementedCiphers; int i; int errCount = 0; + SECStatus rv; + PRErrorCode err; + char *certDir = NULL; + + /* load policy from $SSL_DIR/pkcs11.txt, for testing */ + certDir = SECU_DefaultSSLDir(); + if (certDir) { + rv = NSS_Init(certDir); + } else { + rv = NSS_NoDB_Init(NULL); + } + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "NSS_Init failed: %s\n", PORT_ErrorToString(err)); + goto out; + } + + /* apply policy */ + rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0); + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "NSS_SetAlgorithmPolicy failed: %s\n", + PORT_ErrorToString(err)); + goto out; + } + + /* update the default cipher suites according to the policy */ + rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "SSL_OptionSetDefault failed: %s\n", + PORT_ErrorToString(err)); + goto out; + } fputs("This version of libSSL supports these cipher suites:\n\n", stdout); @@ -58,5 +97,14 @@ main(int argc, char **argv) info.isFIPS ? "FIPS" : "", info.nonStandard ? "nonStandard" : ""); } + +out: + rv = NSS_Shutdown(); + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "NSS_Shutdown failed: %s\n", PORT_ErrorToString(err)); + } + return errCount; } diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn index 153384ce1..f5e6bc236 100644 --- a/security/nss/cmd/manifest.mn +++ b/security/nss/cmd/manifest.mn @@ -63,6 +63,7 @@ NSS_SRCDIRS = \ pp \ pwdecrypt \ rsaperf \ + rsapoptst \ sdrtest \ selfserv \ signtool \ diff --git a/security/nss/cmd/modutil/error.h b/security/nss/cmd/modutil/error.h index b328afebc..d9f06592f 100644 --- a/security/nss/cmd/modutil/error.h +++ b/security/nss/cmd/modutil/error.h @@ -57,6 +57,7 @@ typedef enum { UNSPECIFIED_ERR, NOCERTDB_MISUSE_ERR, NSS_INITIALIZE_FAILED_ERR, + INITPW_FAILED_ERR, LAST_ERR /* must be last */ } Error; @@ -109,8 +110,9 @@ static char *errStrings[] = { "ERROR: Failed to change default.\n", "ERROR: Unable to read from standard input.\n", "ERROR: Unknown error occurred.\n", - "ERROR: -nocertdb option can only be used with the -jar command.\n" - "ERROR: NSS_Initialize() failed.\n" + "ERROR: -nocertdb option can only be used with the -jar command.\n", + "ERROR: NSS_Initialize() failed.\n", + "ERROR: Unable to set initial password on the database.\n" }; typedef enum { diff --git a/security/nss/cmd/modutil/install-ds.c b/security/nss/cmd/modutil/install-ds.c index c8fef7897..030568762 100644 --- a/security/nss/cmd/modutil/install-ds.c +++ b/security/nss/cmd/modutil/install-ds.c @@ -975,8 +975,7 @@ Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad) printf("Doesn't use equiv\n"); } PAD(pad); - printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile - : "<NULL>"); + printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile : "<NULL>"); PAD(pad); printf("mechFlags: %lx\n", _this->mechFlags); PAD(pad); diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c index 02972f7b4..c1b44be53 100644 --- a/security/nss/cmd/modutil/modutil.c +++ b/security/nss/cmd/modutil/modutil.c @@ -865,7 +865,7 @@ main(int argc, char* argv[]) errcode = ChangePW(tokenName, pwFile, newpwFile); break; case CREATE_COMMAND: - /* The work was already done in init_crypto() */ + errcode = InitPW(); break; case DEFAULT_COMMAND: errcode = SetDefaultModule(moduleName, slotName, mechanisms); diff --git a/security/nss/cmd/modutil/modutil.h b/security/nss/cmd/modutil/modutil.h index 127d0d0da..04aa908c8 100644 --- a/security/nss/cmd/modutil/modutil.h +++ b/security/nss/cmd/modutil/modutil.h @@ -29,6 +29,7 @@ Error AddModule(char *moduleName, char *libFile, char *ciphers, Error DeleteModule(char *moduleName); Error ListModule(char *moduleName); Error ListModules(); +Error InitPW(void); Error ChangePW(char *tokenName, char *pwFile, char *newpwFile); Error EnableModule(char *moduleName, char *slotName, PRBool enable); Error RawAddModule(char *dbmodulespec, char *modulespec); diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c index 834469af1..1efc1895c 100644 --- a/security/nss/cmd/modutil/pk11.c +++ b/security/nss/cmd/modutil/pk11.c @@ -670,6 +670,39 @@ loser: /************************************************************************ * + * I n i t P W + */ +Error +InitPW(void) +{ + PK11SlotInfo *slot; + Error ret = UNSPECIFIED_ERR; + + slot = PK11_GetInternalKeySlot(); + if (!slot) { + PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], "internal"); + return NO_SUCH_TOKEN_ERR; + } + + /* Set the initial password to empty */ + if (PK11_NeedUserInit(slot)) { + if (PK11_InitPin(slot, NULL, "") != SECSuccess) { + PR_fprintf(PR_STDERR, errStrings[INITPW_FAILED_ERR]); + ret = INITPW_FAILED_ERR; + goto loser; + } + } + + ret = SUCCESS; + +loser: + PK11_FreeSlot(slot); + + return ret; +} + +/************************************************************************ + * * C h a n g e P W */ Error @@ -695,7 +728,7 @@ ChangePW(char *tokenName, char *pwFile, char *newpwFile) ret = BAD_PW_ERR; goto loser; } - } else { + } else if (PK11_NeedLogin(slot)) { for (matching = PR_FALSE; !matching;) { oldpw = SECU_GetPasswordString(NULL, "Enter old password: "); if (PK11_CheckUserPassword(slot, oldpw) == SECSuccess) { diff --git a/security/nss/cmd/multinit/multinit.c b/security/nss/cmd/multinit/multinit.c index a57c4819f..874263e56 100644 --- a/security/nss/cmd/multinit/multinit.c +++ b/security/nss/cmd/multinit/multinit.c @@ -502,8 +502,7 @@ do_list_certs(const char *progName, int log) SECU_PrintCertNickname(node, stderr); if (log) { - fprintf(stderr, "* Slot=%s*\n", cert->slot ? PK11_GetTokenName(cert->slot) - : "none"); + fprintf(stderr, "* Slot=%s*\n", cert->slot ? PK11_GetTokenName(cert->slot) : "none"); fprintf(stderr, "* Nickname=%s*\n", cert->nickname); fprintf(stderr, "* Subject=<%s>*\n", cert->subjectName); fprintf(stderr, "* Issuer=<%s>*\n", cert->issuerName); diff --git a/security/nss/cmd/pk11mode/pk11mode.c b/security/nss/cmd/pk11mode/pk11mode.c index 2f1fa374e..99891096c 100644 --- a/security/nss/cmd/pk11mode/pk11mode.c +++ b/security/nss/cmd/pk11mode/pk11mode.c @@ -2169,36 +2169,22 @@ PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList, PKM_LogIt(" ulMinKeySize = %lu\n", minfo.ulMinKeySize); PKM_LogIt(" ulMaxKeySize = %lu\n", minfo.ulMaxKeySize); PKM_LogIt(" flags = 0x%08x\n", minfo.flags); - PKM_LogIt(" -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> SIGN_RECOVER = %s\n", minfo.flags & - CKF_SIGN_RECOVER - ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE"); + PKM_LogIt(" -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE"); + PKM_LogIt(" -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE"); + PKM_LogIt(" -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE"); + PKM_LogIt(" -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE"); + PKM_LogIt(" -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE"); + PKM_LogIt(" -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE"); PKM_LogIt(" -> VERIFY_RECOVER = %s\n", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE"); - PKM_LogIt(" -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE"); PKM_LogIt(" -> GENERATE_KEY_PAIR = %s\n", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE"); - PKM_LogIt(" -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE"); + PKM_LogIt(" -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE"); + PKM_LogIt(" -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE"); + PKM_LogIt(" -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE"); PKM_LogIt("\n"); } @@ -3604,24 +3590,12 @@ PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList, PKM_LogIt(" state = %lu\n", sinfo.state); PKM_LogIt(" flags = 0x%08x\n", sinfo.flags); #ifdef CKF_EXCLUSIVE_SESSION - PKM_LogIt(" -> EXCLUSIVE SESSION = %s\n", sinfo.flags & - CKF_EXCLUSIVE_SESSION - ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE"); #endif /* CKF_EXCLUSIVE_SESSION */ - PKM_LogIt(" -> RW SESSION = %s\n", sinfo.flags & - CKF_RW_SESSION - ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> SERIAL SESSION = %s\n", sinfo.flags & - CKF_SERIAL_SESSION - ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE"); + PKM_LogIt(" -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE"); #ifdef CKF_INSERTION_CALLBACK - PKM_LogIt(" -> INSERTION CALLBACK = %s\n", sinfo.flags & - CKF_INSERTION_CALLBACK - ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE"); #endif /* CKF_INSERTION_CALLBACK */ PKM_LogIt(" ulDeviceError = %lu\n", sinfo.ulDeviceError); PKM_LogIt("\n"); diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c index 0ac1ba00e..70454a0d8 100644 --- a/security/nss/cmd/pk12util/pk12util.c +++ b/security/nss/cmd/pk12util/pk12util.c @@ -23,6 +23,7 @@ static char *progName; PRBool pk12_debugging = PR_FALSE; PRBool dumpRawFile; +static PRBool pk12uForceUnicode; PRIntn pk12uErrno = 0; @@ -357,6 +358,7 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, SECItem p12file = { 0 }; SECStatus rv = SECFailure; PRBool swapUnicode = PR_FALSE; + PRBool forceUnicode = pk12uForceUnicode; PRBool trypw; int error; @@ -424,6 +426,18 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, SEC_PKCS12DecoderFinish(p12dcx); uniPwp->len = 0; trypw = PR_TRUE; + } else if (forceUnicode == pk12uForceUnicode) { + /* try again with a different password encoding */ + forceUnicode = !pk12uForceUnicode; + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, + forceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decoding failed to set option"); + pk12uErrno = PK12UERR_DECODEVERIFY; + break; + } + SEC_PKCS12DecoderFinish(p12dcx); + trypw = PR_TRUE; } else { SECU_PrintError(progName, "PKCS12 decode not verified"); pk12uErrno = PK12UERR_DECODEVERIFY; @@ -431,6 +445,15 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, } } } while (trypw == PR_TRUE); + + /* revert the option setting */ + if (forceUnicode != pk12uForceUnicode) { + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, pk12uForceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decoding failed to set option"); + pk12uErrno = PK12UERR_DECODEVERIFY; + } + } /* rv has been set at this point */ done: @@ -470,6 +493,8 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, { SEC_PKCS12DecoderContext *p12dcx = NULL; SECItem uniPwitem = { 0 }; + PRBool forceUnicode = pk12uForceUnicode; + PRBool trypw; SECStatus rv = SECFailure; rv = P12U_InitSlot(slot, slotPw); @@ -480,31 +505,62 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, return rv; } - rv = SECFailure; - p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw); + do { + trypw = PR_FALSE; /* normally we do this once */ + rv = SECFailure; + p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw); - if (p12dcx == NULL) { - goto loser; - } + if (p12dcx == NULL) { + goto loser; + } - /* make sure the bags are okey dokey -- nicknames correct, etc. */ - rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) { - pk12uErrno = PK12UERR_CERTALREADYEXISTS; - } else { - pk12uErrno = PK12UERR_DECODEVALIBAGS; + /* make sure the bags are okey dokey -- nicknames correct, etc. */ + rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback); + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) { + pk12uErrno = PK12UERR_CERTALREADYEXISTS; + } else { + pk12uErrno = PK12UERR_DECODEVALIBAGS; + } + SECU_PrintError(progName, "PKCS12 decode validate bags failed"); + goto loser; } - SECU_PrintError(progName, "PKCS12 decode validate bags failed"); - goto loser; - } - /* stuff 'em in */ - rv = SEC_PKCS12DecoderImportBags(p12dcx); - if (rv != SECSuccess) { - SECU_PrintError(progName, "PKCS12 decode import bags failed"); - pk12uErrno = PK12UERR_DECODEIMPTBAGS; - goto loser; + /* stuff 'em in */ + if (forceUnicode != pk12uForceUnicode) { + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, + forceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decode set option failed"); + pk12uErrno = PK12UERR_DECODEIMPTBAGS; + goto loser; + } + } + rv = SEC_PKCS12DecoderImportBags(p12dcx); + if (rv != SECSuccess) { + if (PR_GetError() == SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY && + forceUnicode == pk12uForceUnicode) { + /* try again with a different password encoding */ + forceUnicode = !pk12uForceUnicode; + SEC_PKCS12DecoderFinish(p12dcx); + SECITEM_ZfreeItem(&uniPwitem, PR_FALSE); + trypw = PR_TRUE; + } else { + SECU_PrintError(progName, "PKCS12 decode import bags failed"); + pk12uErrno = PK12UERR_DECODEIMPTBAGS; + goto loser; + } + } + } while (trypw); + + /* revert the option setting */ + if (forceUnicode != pk12uForceUnicode) { + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, pk12uForceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decode set option failed"); + pk12uErrno = PK12UERR_DECODEIMPTBAGS; + goto loser; + } } fprintf(stdout, "%s: PKCS12 IMPORT SUCCESSFUL\n", progName); @@ -947,6 +1003,7 @@ main(int argc, char **argv) int keyLen = 0; int certKeyLen = 0; secuCommand pk12util; + PRInt32 forceUnicode; #ifdef _CRTDBG_MAP_ALLOC _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); @@ -978,6 +1035,14 @@ main(int argc, char **argv) Usage(progName); } + rv = NSS_OptionGet(__NSS_PKCS12_DECODE_FORCE_UNICODE, &forceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, + "Failed to get NSS_PKCS12_DECODE_FORCE_UNICODE option"); + Usage(progName); + } + pk12uForceUnicode = forceUnicode; + slotname = SECU_GetOptionArg(&pk12util, opt_TokenName); import_file = (pk12util.options[opt_List].activated) ? SECU_GetOptionArg(&pk12util, opt_List) diff --git a/security/nss/cmd/pp/pp.c b/security/nss/cmd/pp/pp.c index 9f33d10a4..d6e276834 100644 --- a/security/nss/cmd/pp/pp.c +++ b/security/nss/cmd/pp/pp.c @@ -84,6 +84,8 @@ main(int argc, char **argv) if (!inFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); + PORT_Free(typeTag); + PL_DestroyOptState(optstate); return -1; } break; @@ -93,6 +95,8 @@ main(int argc, char **argv) if (!outFile) { fprintf(stderr, "%s: unable to open \"%s\" for writing\n", progName, optstate->value); + PORT_Free(typeTag); + PL_DestroyOptState(optstate); return -1; } break; diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c index 556030f6a..2bb23856e 100644 --- a/security/nss/cmd/rsaperf/rsaperf.c +++ b/security/nss/cmd/rsaperf/rsaperf.c @@ -671,8 +671,7 @@ main(int argc, char **argv) printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx)); - printf("%.2f operations/s .\n", ((double)(iters) * (double)1000000.0) / - (double)timeCtx->interval); + printf("%.2f operations/s .\n", ((double)(iters) * (double)1000000.0) / (double)timeCtx->interval); TimingDivide(timeCtx, iters); printf("one operation every %s\n", TimingGenerateString(timeCtx)); diff --git a/security/nss/cmd/rsapoptst/rsapoptst.c b/security/nss/cmd/rsapoptst/rsapoptst.c index 81ddcd6c4..d9468e6d6 100644 --- a/security/nss/cmd/rsapoptst/rsapoptst.c +++ b/security/nss/cmd/rsapoptst/rsapoptst.c @@ -23,7 +23,7 @@ static const struct test_args test_array[] = { { "d_n_q", 0x02, "private exponent, modulus, prime2" }, { "d_p_q", 0x04, "private exponent, prime1, prime2" }, { "e_d_q", 0x08, "public exponent, private exponent, prime2" }, - { "e_d_n", 0x10, "public exponent, private exponent, moduls" } + { "e_d_n", 0x10, "public exponent, private exponent, modulus" } }; static const int test_array_size = (sizeof(test_array) / sizeof(struct test_args)); @@ -58,6 +58,7 @@ const static CK_ATTRIBUTE rsaTemplate[] = { { CKA_TOKEN, NULL, 0 }, { CKA_SENSITIVE, NULL, 0 }, { CKA_PRIVATE, NULL, 0 }, + { CKA_ID, NULL, 0 }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, @@ -123,46 +124,77 @@ fail: #define ATTR_STRING(x) getNameFromAttribute(x) +static void +dumphex(FILE *file, const unsigned char *cpval, int start, int end) +{ + int i; + for (i = start; i < end; i++) { + if ((i % 16) == 0) + fprintf(file, "\n "); + fprintf(file, " %02x", cpval[i]); + } + return; +} + void -dumpTemplate(CK_ATTRIBUTE *template, int start, int end) +dumpTemplate(FILE *file, const CK_ATTRIBUTE *template, int start, int end) { - int i, j; - for (i = 0; i < end; i++) { + int i; + for (i = start; i < end; i++) { unsigned char cval; CK_ULONG ulval; - unsigned char *cpval; + const unsigned char *cpval; - fprintf(stderr, "%s:", ATTR_STRING(template[i].type)); + fprintf(file, "%s:", ATTR_STRING(template[i].type)); switch (template[i].ulValueLen) { case 1: cval = *(unsigned char *)template[i].pValue; switch (cval) { case 0: - fprintf(stderr, " false"); + fprintf(file, " false"); break; case 1: - fprintf(stderr, " true"); + fprintf(file, " true"); break; default: - fprintf(stderr, " %d (=0x%02x,'%c')", cval, cval, cval); + fprintf(file, " %d (=0x%02x,'%c')", cval, cval, cval); break; } break; case sizeof(CK_ULONG): ulval = *(CK_ULONG *)template[i].pValue; - fprintf(stderr, " %ld (=0x%04lx)", ulval, ulval); + fprintf(file, " %ld (=0x%04lx)", ulval, ulval); break; default: - cpval = (unsigned char *)template[i].pValue; - for (j = 0; j < template[i].ulValueLen; j++) { - if ((j % 16) == 0) - fprintf(stderr, "\n "); - fprintf(stderr, " %02x", cpval[j]); - } + cpval = (const unsigned char *)template[i].pValue; + dumphex(file, cpval, 0, template[i].ulValueLen); break; } - fprintf(stderr, "\n"); + fprintf(file, "\n"); + } +} + +void +dumpItem(FILE *file, const SECItem *item) +{ + const unsigned char *cpval; + + if (item == NULL) { + fprintf(file, " pNULL "); + return; + } + if (item->data == NULL) { + fprintf(file, " NULL "); + return; } + if (item->len == 0) { + fprintf(file, " Empty "); + return; + } + cpval = item->data; + dumphex(file, cpval, 0, item->len); + fprintf(file, " "); + return; } PRBool @@ -184,13 +216,16 @@ rsaKeysAreEqual(PK11ObjectType srcType, void *src, printf("Could read source key\n"); return PR_FALSE; } - readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES); + rv = readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES); if (rv != SECSuccess) { printf("Could read dest key\n"); return PR_FALSE; } for (i = 0; i < RSA_ATTRIBUTES; i++) { + if (srcTemplate[i].type == CKA_ID) { + continue; /* we purposefully make the CKA_ID different */ + } if (srcTemplate[i].ulValueLen != destTemplate[i].ulValueLen) { printf("key->%s not equal src_len = %ld, dest_len=%ld\n", ATTR_STRING(srcTemplate[i].type), @@ -204,18 +239,22 @@ rsaKeysAreEqual(PK11ObjectType srcType, void *src, } if (!areEqual) { fprintf(stderr, "original key:\n"); - dumpTemplate(srcTemplate, 0, RSA_ATTRIBUTES); + dumpTemplate(stderr, srcTemplate, 0, RSA_ATTRIBUTES); fprintf(stderr, "created key:\n"); - dumpTemplate(destTemplate, 0, RSA_ATTRIBUTES); + dumpTemplate(stderr, destTemplate, 0, RSA_ATTRIBUTES); } + resetTemplate(srcTemplate, 0, RSA_ATTRIBUTES); + resetTemplate(destTemplate, 0, RSA_ATTRIBUTES); return areEqual; } static int exp_exp_prime_fail_count = 0; +#define LEAK_ID 0xf + static int doRSAPopulateTest(unsigned int keySize, unsigned long exponent, - int mask, void *pwarg) + int mask, int round, void *pwarg) { SECKEYPrivateKey *rsaPrivKey; SECKEYPublicKey *rsaPubKey; @@ -227,7 +266,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; CK_KEY_TYPE key_type = CKK_RSA; CK_BBOOL ck_false = CK_FALSE; + CK_BYTE cka_id[2] = { 0, 0 }; int failed = 0; + int leak_found; /* did we find the expected leak */ + int expect_leak = 0; /* are we expecting a leak? */ rsaParams.pe = exponent; rsaParams.keySizeInBits = keySize; @@ -259,11 +301,15 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, tstTemplate[3].ulValueLen = sizeof(ck_false); tstTemplate[4].pValue = &ck_false; tstTemplate[4].ulValueLen = sizeof(ck_false); - tstHeaderCount = 5; + tstTemplate[5].pValue = &cka_id[0]; + tstTemplate[5].ulValueLen = sizeof(cka_id); + tstHeaderCount = 6; + cka_id[0] = round; if (mask & 1) { printf("%s\n", test_array[1].description); resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 0; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PUBLIC_EXPONENT); copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, @@ -271,10 +317,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount + 2, CKA_PRIME_1); - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: pubExp mod p\n"); failed = 1; @@ -290,6 +336,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, printf("%s\n", test_array[2].description); /* test the basic2 case, public exponent, modulus, prime2 */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 1; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PUBLIC_EXPONENT); copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, @@ -299,10 +346,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, /* test with q in the prime1 position */ tstTemplate[tstHeaderCount + 2].type = CKA_PRIME_1; - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: pubExp mod q\n"); failed = 1; @@ -318,6 +365,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, printf("%s\n", test_array[3].description); /* test the medium case, private exponent, prime1, prime2 */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 2; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PRIVATE_EXPONENT); @@ -329,10 +377,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, tstTemplate[tstHeaderCount + 2].type = CKA_PRIME_1; tstTemplate[tstHeaderCount + 1].type = CKA_PRIME_2; - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: privExp p q\n"); failed = 1; @@ -348,6 +396,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, printf("%s\n", test_array[4].description); /* test the advanced case, public exponent, private exponent, prime2 */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 3; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PRIVATE_EXPONENT); copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, @@ -355,10 +404,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount + 2, CKA_PRIME_2); - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: pubExp privExp q\n"); fprintf(stderr, " this is expected periodically. It means we\n"); @@ -373,11 +422,12 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); } - if (mask & 16) { + if (mask & 0x10) { printf("%s\n", test_array[5].description); /* test the advanced case2, public exponent, private exponent, modulus */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = LEAK_ID; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PRIVATE_EXPONENT); @@ -386,6 +436,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount + 2, CKA_MODULUS); + /* purposefully use the old version. This will create a leak */ tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, tstHeaderCount + 3, @@ -398,9 +449,59 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n"); failed = 1; } + expect_leak = 1; if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); } + resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + SECKEY_DestroyPrivateKey(rsaPrivKey); + SECKEY_DestroyPublicKey(rsaPubKey); + + /* make sure we didn't leak */ + leak_found = 0; + tstPrivKey = PK11_FindGenericObjects(slot, CKO_PRIVATE_KEY); + if (tstPrivKey) { + SECStatus rv; + PK11GenericObject *thisKey; + int i; + + fprintf(stderr, "Leaking keys...\n"); + for (i = 0, thisKey = tstPrivKey; thisKey; i++, + thisKey = PK11_GetNextGenericObject(thisKey)) { + SECItem id = { 0, NULL, 0 }; + + rv = PK11_ReadRawAttribute(PK11_TypeGeneric, thisKey, + CKA_ID, &id); + if (rv != SECSuccess) { + fprintf(stderr, "Key %d: couldn't read CKA_ID: %s\n", + i, PORT_ErrorToString(PORT_GetError())); + continue; + } + fprintf(stderr, "id = { "); + dumpItem(stderr, &id); + fprintf(stderr, "};"); + if (id.data[1] == LEAK_ID) { + fprintf(stderr, " ---> leak expected\n"); + if (id.data[0] == round) + leak_found = 1; + } else { + if (id.len != sizeof(cka_id)) { + fprintf(stderr, + " ---> ERROR unexpected leak in generated key\n"); + } else { + fprintf(stderr, + " ---> ERROR unexpected leak in constructed key\n"); + } + failed = 1; + } + SECITEM_FreeItem(&id, PR_FALSE); + } + PK11_DestroyGenericObjects(tstPrivKey); + } + if (expect_leak && !leak_found) { + fprintf(stderr, "ERROR expected leak not found\n"); + failed = 1; + } PK11_FreeSlot(slot); return failed ? -1 : 0; @@ -517,7 +618,7 @@ main(int argc, char **argv) exp_exp_prime_fail_count = 0; for (i = 0; i < repeat; i++) { printf("Running RSA Populate test run %d\n", i); - ret = doRSAPopulateTest(keySize, exponent, mask, NULL); + ret = doRSAPopulateTest(keySize, exponent, mask, i, NULL); if (ret != 0) { i++; break; @@ -531,5 +632,9 @@ main(int argc, char **argv) exp_exp_prime_fail_count, i, (((double)exp_exp_prime_fail_count) * 100.0) / (double)i); } + if (NSS_Shutdown() != SECSuccess) { + fprintf(stderr, "Shutdown failed\n"); + ret = -1; + } return ret; } diff --git a/security/nss/cmd/rsapoptst/rsapoptst.gyp b/security/nss/cmd/rsapoptst/rsapoptst.gyp new file mode 100644 index 000000000..325a10909 --- /dev/null +++ b/security/nss/cmd/rsapoptst/rsapoptst.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': 'rsapoptst', + 'type': 'executable', + 'sources': [ + 'rsapoptst.c' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:dbm_exports', + '<(DEPTH)/exports.gyp:nss_exports', + ] + } + ], + 'variables': { + 'module': 'nss', + } +} diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index 65b1ee304..fac428e10 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -38,6 +38,7 @@ #include "nss.h" #include "ssl.h" #include "sslproto.h" +#include "sslexp.h" #include "cert.h" #include "certt.h" #include "ocsp.h" @@ -165,9 +166,7 @@ PrintUsageHeader(const char *progName) " [-V [min-version]:[max-version]] [-a sni_name]\n" " [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n" " [-C SSLCacheEntries] [-S dsa_nickname] -Q [-I groups]" -#ifndef NSS_DISABLE_ECC " [-e ec_nickname]" -#endif /* NSS_DISABLE_ECC */ "\n" " -U [0|1] -H [0|1|2] -W [0|1]\n" "\n", @@ -1955,6 +1954,10 @@ 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); + if (rv != SECSuccess) { + errExit("error configuring anti-replay "); + } rv = SSL_OptionSet(model_sock, SSL_ENABLE_0RTT_DATA, PR_TRUE); if (rv != SECSuccess) { errExit("error enabling 0RTT "); @@ -2343,7 +2346,6 @@ main(int argc, char **argv) dir = optstate->value; break; -#ifndef NSS_DISABLE_ECC case 'e': if (certNicknameIndex >= MAX_CERT_NICKNAME_ARRAY_INDEX) { Usage(progName); @@ -2351,7 +2353,6 @@ main(int argc, char **argv) } certNicknameArray[certNicknameIndex++] = PORT_Strdup(optstate->value); break; -#endif /* NSS_DISABLE_ECC */ case 'f': pwdata.source = PW_FROMFILE; @@ -2553,6 +2554,14 @@ main(int argc, char **argv) tmp = PR_GetEnvSecure("TMPDIR"); if (!tmp) tmp = PR_GetEnvSecure("TEMP"); + + /* Call the NSS initialization routines */ + rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); + if (rv != SECSuccess) { + fputs("NSS_Init failed.\n", stderr); + exit(8); + } + if (envString) { /* we're one of the children in a multi-process server. */ listen_sock = PR_GetInheritedFD(inheritableSockName); @@ -2607,13 +2616,6 @@ main(int argc, char **argv) /* set our password function */ PK11_SetPasswordFunc(SECU_GetModulePassword); - /* Call the NSS initialization routines */ - rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); - if (rv != SECSuccess) { - fputs("NSS_Init failed.\n", stderr); - exit(8); - } - /* all SSL3 cipher suites are enabled by default. */ if (cipherString) { char *cstringSaved = cipherString; @@ -2681,9 +2683,7 @@ main(int argc, char **argv) certNicknameArray[i]); exit(11); } -#ifdef NSS_DISABLE_ECC if (privKey[i]->keyType != ecKey) -#endif setupCertStatus(certStatusArena, ocspStaplingMode, cert[i], i, &pwdata); } diff --git a/security/nss/cmd/signtool/javascript.c b/security/nss/cmd/signtool/javascript.c index 746f724f8..ffff2db59 100644 --- a/security/nss/cmd/signtool/javascript.c +++ b/security/nss/cmd/signtool/javascript.c @@ -1115,8 +1115,7 @@ extract_js(char *filename) textStart = 0; startLine = 0; - while (linenum = FB_GetLineNum(fb), (curchar = FB_GetChar(fb)) != - EOF) { + while (linenum = FB_GetLineNum(fb), (curchar = FB_GetChar(fb)) != EOF) { switch (state) { case TEXT_HTML_STATE: if (curchar == '<') { diff --git a/security/nss/cmd/signtool/signtool.c b/security/nss/cmd/signtool/signtool.c index 51857d638..915a00fbc 100644 --- a/security/nss/cmd/signtool/signtool.c +++ b/security/nss/cmd/signtool/signtool.c @@ -1033,9 +1033,7 @@ main(int argc, char *argv[]) if (errorCount > 0 || warningCount > 0) { PR_fprintf(outputFD, "%d error%s, %d warning%s.\n", errorCount, - errorCount == 1 ? "" : "s", warningCount, warningCount == 1 - ? "" - : "s"); + errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s"); } else { PR_fprintf(outputFD, "Directory %s signed successfully.\n", jartree); diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c index 10e743c6b..fe17f26a4 100644 --- a/security/nss/cmd/smimetools/cmsutil.c +++ b/security/nss/cmd/smimetools/cmsutil.c @@ -1572,10 +1572,7 @@ main(int argc, char **argv) { unsigned int j; for (j = 0; j < input.len; j++) - fprintf(stderr, "%2x%c", input.data[j], (j > 0 && - j % 35 == 0) - ? '\n' - : ' '); + fprintf(stderr, "%2x%c", input.data[j], (j > 0 && j % 35 == 0) ? '\n' : ' '); } } if (input.len > 0) { /* skip if certs-only (or other zero content) */ diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c index 197b1942d..a2471884e 100644 --- a/security/nss/cmd/ssltap/ssltap.c +++ b/security/nss/cmd/ssltap/ssltap.c @@ -1637,8 +1637,7 @@ print_ssl3_handshake(unsigned char *recordBuf, PR_snprintf(certFileName, sizeof certFileName, "cert.%03d", ++certFileNumber); cfd = - PR_Open(certFileName, PR_WRONLY | - PR_CREATE_FILE | PR_TRUNCATE, + PR_Open(certFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); if (!cfd) { PR_fprintf(PR_STDOUT, @@ -1722,8 +1721,7 @@ print_ssl3_handshake(unsigned char *recordBuf, 0 && sslhexparse) { PR_fprintf(PR_STDOUT, " = {\n"); - print_hex(dnLen, hsdata + - pos); + print_hex(dnLen, hsdata + pos); PR_fprintf(PR_STDOUT, " }\n"); } else { PR_fprintf(PR_STDOUT, "\n"); @@ -1796,8 +1794,7 @@ print_ssl3_handshake(unsigned char *recordBuf, PR_snprintf(ocspFileName, sizeof ocspFileName, "ocsp.%03d", ++ocspFileNumber); - ofd = PR_Open(ocspFileName, PR_WRONLY | - PR_CREATE_FILE | PR_TRUNCATE, + ofd = PR_Open(ocspFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); if (!ofd) { PR_fprintf(PR_STDOUT, @@ -2167,8 +2164,7 @@ print_ssl(DataBufferList *s, int length, unsigned char *buffer) break; case 22: /* handshake */ - print_ssl3_handshake(recordBuf, recordLen - - s->hMACsize, + print_ssl3_handshake(recordBuf, recordLen - s->hMACsize, &sr, s); break; diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c index f65e31913..7d259bd0a 100644 --- a/security/nss/cmd/strsclnt/strsclnt.c +++ b/security/nss/cmd/strsclnt/strsclnt.c @@ -886,8 +886,10 @@ PRBool LoggedIn(CERTCertificate *cert, SECKEYPrivateKey *key) { if ((cert->slot) && (key->pkcs11Slot) && - (PR_TRUE == PK11_IsLoggedIn(cert->slot, NULL)) && - (PR_TRUE == PK11_IsLoggedIn(key->pkcs11Slot, NULL))) { + (!PK11_NeedLogin(cert->slot) || + PR_TRUE == PK11_IsLoggedIn(cert->slot, NULL)) && + (!PK11_NeedLogin(key->pkcs11Slot) || + PR_TRUE == PK11_IsLoggedIn(key->pkcs11Slot, NULL))) { return PR_TRUE; } diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 959afec59..1ad99502b 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -31,6 +31,7 @@ #include "ocsp.h" #include "ssl.h" #include "sslproto.h" +#include "sslexp.h" #include "pk11func.h" #include "secmod.h" #include "plgetopt.h" @@ -95,6 +96,7 @@ PRBool verbose; int dumpServerChain = 0; int renegotiationsToDo = 0; int renegotiationsDone = 0; +PRBool initializedServerSessionCache = PR_FALSE; static char *progName; @@ -178,7 +180,7 @@ PrintUsageHeader(const char *progName) "[-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n" "[-V [min-version]:[max-version]] [-K] [-T] [-U]\n" "[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]] [-I groups]\n" - "[-A requestfile] [-L totalconnections]\n" + "[-A requestfile] [-L totalconnections] [-P {client,server}] [-Q]\n" "\n", progName); } @@ -202,7 +204,7 @@ PrintParameterUsage(void) fprintf(stderr, "%-20s Print certificate chain information\n", "-C"); fprintf(stderr, "%-20s (use -C twice to print more certificate details)\n", ""); fprintf(stderr, "%-20s (use -C three times to include PEM format certificate dumps)\n", ""); - fprintf(stderr, "%-20s Nickname of key and cert for client auth\n", + fprintf(stderr, "%-20s Nickname of key and cert\n", "-n nickname"); fprintf(stderr, "%-20s Restricts the set of enabled SSL/TLS protocols versions.\n" @@ -251,6 +253,9 @@ PrintParameterUsage(void) "%-20s The following values are valid:\n" "%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n", "-I", "", ""); + fprintf(stderr, "%-20s Enable alternative TLS 1.3 handshake\n", "-X alt-server-hello"); + fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}"); + fprintf(stderr, "%-20s Exit after handshake\n", "-Q"); } static void @@ -914,6 +919,12 @@ char *requestString = NULL; PRInt32 requestStringLen = 0; PRBool requestSent = PR_FALSE; PRBool enableZeroRtt = PR_FALSE; +PRBool enableAltServerHello = PR_FALSE; +PRBool useDTLS = PR_FALSE; +PRBool actAsServer = PR_FALSE; +PRBool stopAfterHandshake = PR_FALSE; +PRBool requestToExit = PR_FALSE; +char *versionString = NULL; static int writeBytesToServer(PRFileDesc *s, const char *buf, int nb) @@ -996,12 +1007,129 @@ handshakeCallback(PRFileDesc *fd, void *client_data) writeBytesToServer(fd, requestString, requestStringLen); } } + if (stopAfterHandshake) { + requestToExit = PR_TRUE; + } } #define REQUEST_WAITING (requestString && !requestSent) +static SECStatus +installServerCertificate(PRFileDesc *s, char *nickname) +{ + CERTCertificate *cert; + SECKEYPrivateKey *privKey = NULL; + + if (!nickname) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + cert = PK11_FindCertFromNickname(nickname, &pwdata); + if (cert == NULL) { + return SECFailure; + } + + privKey = PK11_FindKeyByAnyCert(cert, &pwdata); + if (privKey == NULL) { + return SECFailure; + } + if (SSL_ConfigServerCert(s, cert, privKey, NULL, 0) != SECSuccess) { + return SECFailure; + } + SECKEY_DestroyPrivateKey(privKey); + CERT_DestroyCertificate(cert); + + return SECSuccess; +} + +static SECStatus +bindToClient(PRFileDesc *s) +{ + PRStatus status; + status = PR_Bind(s, &addr); + if (status != PR_SUCCESS) { + return SECFailure; + } + + for (;;) { + /* Bind the remote address on first packet. This must happen + * before we SSL-ize the socket because we need to get the + * peer's address before SSLizing. Recvfrom gives us that + * while not consuming any data. */ + unsigned char tmp; + PRNetAddr remote; + int nb; + + nb = PR_RecvFrom(s, &tmp, 1, PR_MSG_PEEK, + &remote, PR_INTERVAL_NO_TIMEOUT); + if (nb != 1) + continue; + + status = PR_Connect(s, &remote, PR_INTERVAL_NO_TIMEOUT); + if (status != PR_SUCCESS) { + SECU_PrintError(progName, "server bind to remote end failed"); + return SECFailure; + } + return SECSuccess; + } + + /* Unreachable. */ +} + +static SECStatus +connectToServer(PRFileDesc *s, PRPollDesc *pollset) +{ + PRStatus status; + PRInt32 filesReady; + + status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT); + if (status != PR_SUCCESS) { + if (PR_GetError() == PR_IN_PROGRESS_ERROR) { + if (verbose) + SECU_PrintError(progName, "connect"); + milliPause(50 * multiplier); + pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + pollset[SSOCK_FD].out_flags = 0; + pollset[SSOCK_FD].fd = s; + while (1) { + FPRINTF(stderr, + "%s: about to call PR_Poll for connect completion!\n", + progName); + filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT); + if (filesReady < 0) { + SECU_PrintError(progName, "unable to connect (poll)"); + return SECFailure; + } + FPRINTF(stderr, + "%s: PR_Poll returned 0x%02x for socket out_flags.\n", + progName, pollset[SSOCK_FD].out_flags); + if (filesReady == 0) { /* shouldn't happen! */ + SECU_PrintError(progName, "%s: PR_Poll returned zero!\n"); + return SECFailure; + } + status = PR_GetConnectStatus(pollset); + if (status == PR_SUCCESS) { + break; + } + if (PR_GetError() != PR_IN_PROGRESS_ERROR) { + SECU_PrintError(progName, "unable to connect (poll)"); + return SECFailure; + } + SECU_PrintError(progName, "poll"); + milliPause(50 * multiplier); + } + } else { + SECU_PrintError(progName, "unable to connect"); + return SECFailure; + } + } + + return SECSuccess; +} + static int -run_client(void) +run(void) { int headerSeparatorPtrnId = 0; int error = 0; @@ -1017,13 +1145,23 @@ run_client(void) requestSent = PR_FALSE; /* Create socket */ - s = PR_OpenTCPSocket(addr.raw.family); + if (useDTLS) { + s = PR_OpenUDPSocket(addr.raw.family); + } else { + s = PR_OpenTCPSocket(addr.raw.family); + } + if (s == NULL) { SECU_PrintError(progName, "error creating socket"); error = 1; goto done; } + if (actAsServer) { + if (bindToClient(s) != SECSuccess) { + return 1; + } + } opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_TRUE; /* default */ if (serverCertAuth.testFreshStatusFromSideChannel) { @@ -1036,13 +1174,16 @@ run_client(void) goto done; } - s = SSL_ImportFD(NULL, s); + if (useDTLS) { + s = DTLS_ImportFD(NULL, s); + } else { + s = SSL_ImportFD(NULL, s); + } if (s == NULL) { SECU_PrintError(progName, "error importing socket"); error = 1; goto done; } - SSL_SetPKCS11PinArg(s, &pwdata); rv = SSL_OptionSet(s, SSL_SECURITY, 1); @@ -1052,7 +1193,7 @@ run_client(void) goto done; } - rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, 1); + rv = SSL_OptionSet(s, actAsServer ? SSL_HANDSHAKE_AS_SERVER : SSL_HANDSHAKE_AS_CLIENT, 1); if (rv != SECSuccess) { SECU_PrintError(progName, "error enabling client handshake"); error = 1; @@ -1178,6 +1319,16 @@ run_client(void) } } + /* Alternate ServerHello content type (TLS 1.3 only) */ + if (enableAltServerHello) { + rv = SSL_UseAltServerHelloType(s, PR_TRUE); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error enabling alternate ServerHello type"); + error = 1; + goto done; + } + } + /* require the use of fixed finite-field DH groups */ if (requireDHNamedGroups) { rv = SSL_OptionSet(s, SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); @@ -1212,7 +1363,21 @@ run_client(void) if (override) { SSL_BadCertHook(s, ownBadCertHandler, NULL); } - SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname); + if (actAsServer) { + rv = installServerCertificate(s, nickname); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error installing server cert"); + return 1; + } + rv = SSL_ConfigServerSessionIDCache(1024, 0, 0, "."); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error configuring session cache"); + return 1; + } + initializedServerSessionCache = PR_TRUE; + } else { + SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname); + } SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName); if (hs1SniHostName) { SSL_SetURL(s, hs1SniHostName); @@ -1220,56 +1385,27 @@ run_client(void) SSL_SetURL(s, host); } - /* Try to connect to the server */ - status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT); - if (status != PR_SUCCESS) { - if (PR_GetError() == PR_IN_PROGRESS_ERROR) { - if (verbose) - SECU_PrintError(progName, "connect"); - milliPause(50 * multiplier); - pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - pollset[SSOCK_FD].out_flags = 0; - pollset[SSOCK_FD].fd = s; - while (1) { - FPRINTF(stderr, - "%s: about to call PR_Poll for connect completion!\n", - progName); - filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT); - if (filesReady < 0) { - SECU_PrintError(progName, "unable to connect (poll)"); - error = 1; - goto done; - } - FPRINTF(stderr, - "%s: PR_Poll returned 0x%02x for socket out_flags.\n", - progName, pollset[SSOCK_FD].out_flags); - if (filesReady == 0) { /* shouldn't happen! */ - FPRINTF(stderr, "%s: PR_Poll returned zero!\n", progName); - error = 1; - goto done; - } - status = PR_GetConnectStatus(pollset); - if (status == PR_SUCCESS) { - break; - } - if (PR_GetError() != PR_IN_PROGRESS_ERROR) { - SECU_PrintError(progName, "unable to connect (poll)"); - error = 1; - goto done; - } - SECU_PrintError(progName, "poll"); - milliPause(50 * multiplier); - } - } else { - SECU_PrintError(progName, "unable to connect"); + if (actAsServer) { + rv = SSL_ResetHandshake(s, PR_TRUE /* server */); + if (rv != SECSuccess) { + return 1; + } + } else { + /* Try to connect to the server */ + rv = connectToServer(s, pollset); + if (rv != SECSuccess) { + ; error = 1; goto done; } } pollset[SSOCK_FD].fd = s; - pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT | - (clientSpeaksFirst ? 0 : PR_POLL_READ); + pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT; + if (!actAsServer) + pollset[SSOCK_FD].in_flags |= (clientSpeaksFirst ? 0 : PR_POLL_READ); + else + pollset[SSOCK_FD].in_flags |= PR_POLL_READ; pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput); if (!REQUEST_WAITING) { pollset[STDIN_FD].in_flags = PR_POLL_READ; @@ -1319,9 +1455,11 @@ run_client(void) ** Select on stdin and on the socket. Write data from stdin to ** socket, read data from socket and write to stdout. */ + requestToExit = PR_FALSE; FPRINTF(stderr, "%s: ready...\n", progName); - while ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) || - REQUEST_WAITING) { + while (!requestToExit && + ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) || + REQUEST_WAITING)) { char buf[4000]; /* buffer for stdin */ int nb; /* num bytes read from stdin. */ @@ -1507,12 +1645,10 @@ main(int argc, char **argv) } } - SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions); - /* XXX: 'B' was used in the past but removed in 3.28, * please leave some time before resuing it. */ optstate = PL_CreateOptState(argc, argv, - "46A:CDFGHI:KL:M:OR:STUV:W:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z"); + "46A:CDFGHI:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -1593,6 +1729,21 @@ main(int argc, char **argv) }; break; + case 'P': + useDTLS = PR_TRUE; + if (!strcmp(optstate->value, "server")) { + actAsServer = 1; + } else { + if (strcmp(optstate->value, "client")) { + Usage(progName); + } + } + break; + + case 'Q': + stopAfterHandshake = PR_TRUE; + break; + case 'R': rootModule = PORT_Strdup(optstate->value); break; @@ -1610,14 +1761,16 @@ main(int argc, char **argv) break; case 'V': - if (SECU_ParseSSLVersionRangeString(optstate->value, - enabledVersions, &enabledVersions) != - SECSuccess) { - fprintf(stderr, "Bad version specified.\n"); + versionString = PORT_Strdup(optstate->value); + break; + + case 'X': + if (!strcmp(optstate->value, "alt-server-hello")) { + enableAltServerHello = PR_TRUE; + } else { Usage(progName); } break; - case 'Y': PrintCipherUsage(progName); exit(0); @@ -1727,9 +1880,20 @@ main(int argc, char **argv) break; } } - PL_DestroyOptState(optstate); + SSL_VersionRangeGetSupported(useDTLS ? ssl_variant_datagram : ssl_variant_stream, &enabledVersions); + + if (versionString) { + if (SECU_ParseSSLVersionRangeString(versionString, + enabledVersions, &enabledVersions) != + SECSuccess) { + fprintf(stderr, "Bad version specified.\n"); + Usage(progName); + } + PORT_Free(versionString); + } + if (optstatus == PL_OPT_BAD) { Usage(progName); } @@ -1758,7 +1922,7 @@ main(int argc, char **argv) PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PK11_SetPasswordFunc(SECU_GetModulePassword); - + memset(&addr, 0, sizeof(addr)); status = PR_StringToNetAddr(host, &addr); if (status == PR_SUCCESS) { addr.inet.port = PR_htons(portno); @@ -1770,6 +1934,7 @@ main(int argc, char **argv) addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC, PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME); if (!addrInfo) { + fprintf(stderr, "HOSTNAME=%s\n", host); SECU_PrintError(progName, "error looking up host"); error = 1; goto done; @@ -1884,7 +2049,7 @@ main(int argc, char **argv) } while (numConnections--) { - error = run_client(); + error = run(); if (error) { goto done; } @@ -1915,6 +2080,12 @@ done: } if (NSS_IsInitialized()) { SSL_ClearSessionCache(); + if (initializedServerSessionCache) { + if (SSL_ShutdownServerSessionIDCache() != SECSuccess) { + error = 1; + } + } + if (NSS_Shutdown() != SECSuccess) { error = 1; } |