From 74cabf7948b2597f5b6a67d6910c844fd1a88ff6 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sat, 15 Dec 2018 01:42:53 +0100 Subject: Update NSS to 3.41 --- security/nss/cmd/certutil/certutil.c | 168 +++- security/nss/cmd/crlutil/crlutil.c | 16 +- security/nss/cmd/crmf-cgi/crmfcgi.c | 2 +- security/nss/cmd/crmftest/testcrmf.c | 2 +- security/nss/cmd/dbck/dbrecover.c | 3 +- security/nss/cmd/fipstest/fipstest.c | 1034 +++++++++++++++++++- security/nss/cmd/fipstest/kas.sh | 84 ++ security/nss/cmd/fipstest/runtest.sh | 2 +- security/nss/cmd/lib/secutil.c | 116 ++- security/nss/cmd/lib/secutil.h | 6 +- security/nss/cmd/manifest.mn | 1 + security/nss/cmd/modutil/error.h | 1 + security/nss/cmd/modutil/modutil.c | 28 +- security/nss/cmd/modutil/modutil.h | 1 + security/nss/cmd/modutil/pk11.c | 49 + security/nss/cmd/nss-policy-check/Makefile | 47 + security/nss/cmd/nss-policy-check/manifest.mn | 15 + .../nss/cmd/nss-policy-check/nss-policy-check.c | 206 ++++ .../nss/cmd/nss-policy-check/nss-policy-check.gyp | 24 + security/nss/cmd/ocspclnt/ocspclnt.c | 5 + security/nss/cmd/p7verify/p7verify.c | 1 + security/nss/cmd/rsaperf/rsaperf.c | 8 +- security/nss/cmd/selfserv/selfserv.c | 51 +- security/nss/cmd/smimetools/cmsutil.c | 1 + security/nss/cmd/tests/nonspr10.c | 2 - security/nss/cmd/tstclnt/Makefile | 2 +- security/nss/cmd/tstclnt/tstclnt.c | 134 ++- security/nss/cmd/vfychain/vfychain.c | 3 +- security/nss/cmd/vfyserv/vfyserv.h | 2 +- 29 files changed, 1837 insertions(+), 177 deletions(-) create mode 100644 security/nss/cmd/fipstest/kas.sh create mode 100644 security/nss/cmd/nss-policy-check/Makefile create mode 100644 security/nss/cmd/nss-policy-check/manifest.mn create mode 100644 security/nss/cmd/nss-policy-check/nss-policy-check.c create mode 100644 security/nss/cmd/nss-policy-check/nss-policy-check.gyp (limited to 'security/nss/cmd') diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index dbb93c922..df02e4439 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -741,6 +741,9 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date, case 'V': usage = certificateUsageSSLServer; break; + case 'I': + usage = certificateUsageIPsec; + break; case 'S': usage = certificateUsageEmailSigner; break; @@ -856,41 +859,59 @@ SECItemToHex(const SECItem *item, char *dst) } static const char *const keyTypeName[] = { - "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec", "rsaPss" + "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec", "rsaPss", "rsaOaep" }; #define MAX_CKA_ID_BIN_LEN 20 #define MAX_CKA_ID_STR_LEN 40 -/* print key number, key ID (in hex or ASCII), key label (nickname) */ -static SECStatus -PrintKey(PRFileDesc *out, const char *nickName, int count, - SECKEYPrivateKey *key, void *pwarg) +/* output human readable key ID in buffer, which should have at least + * MAX_CKA_ID_STR_LEN + 3 octets (quotations and a null terminator) */ +static void +formatPrivateKeyID(SECKEYPrivateKey *privkey, char *buffer) { SECItem *ckaID; - char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; - pwarg = NULL; - ckaID = PK11_GetLowLevelKeyIDForPrivateKey(key); + ckaID = PK11_GetLowLevelKeyIDForPrivateKey(privkey); if (!ckaID) { - strcpy(ckaIDbuf, "(no CKA_ID)"); + strcpy(buffer, "(no CKA_ID)"); } else if (ItemIsPrintableASCII(ckaID)) { int len = PR_MIN(MAX_CKA_ID_STR_LEN, ckaID->len); - ckaIDbuf[0] = '"'; - memcpy(ckaIDbuf + 1, ckaID->data, len); - ckaIDbuf[1 + len] = '"'; - ckaIDbuf[2 + len] = '\0'; + buffer[0] = '"'; + memcpy(buffer + 1, ckaID->data, len); + buffer[1 + len] = '"'; + buffer[2 + len] = '\0'; } else { /* print ckaid in hex */ SECItem idItem = *ckaID; if (idItem.len > MAX_CKA_ID_BIN_LEN) idItem.len = MAX_CKA_ID_BIN_LEN; - SECItemToHex(&idItem, ckaIDbuf); + SECItemToHex(&idItem, buffer); } + SECITEM_ZfreeItem(ckaID, PR_TRUE); +} + +/* print key number, key ID (in hex or ASCII), key label (nickname) */ +static SECStatus +PrintKey(PRFileDesc *out, const char *nickName, int count, + SECKEYPrivateKey *key, void *pwarg) +{ + char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; + CERTCertificate *cert; + KeyType keyType; + + pwarg = NULL; + formatPrivateKeyID(key, ckaIDbuf); + cert = PK11_GetCertFromPrivateKey(key); + if (cert) { + keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo); + CERT_DestroyCertificate(cert); + } else { + keyType = key->keyType; + } PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count, - keyTypeName[key->keyType], ckaIDbuf, nickName); - SECITEM_ZfreeItem(ckaID, PR_TRUE); + keyTypeName[keyType], ckaIDbuf, nickName); return SECSuccess; } @@ -1002,7 +1023,7 @@ ListKeys(PK11SlotInfo *slot, const char *nickName, int index, } static SECStatus -DeleteKey(char *nickname, secuPWData *pwdata) +DeleteCertAndKey(char *nickname, secuPWData *pwdata) { SECStatus rv; CERTCertificate *cert; @@ -1031,6 +1052,61 @@ DeleteKey(char *nickname, secuPWData *pwdata) return rv; } +static SECKEYPrivateKey * +findPrivateKeyByID(PK11SlotInfo *slot, const char *ckaID, secuPWData *pwarg) +{ + PORTCheapArenaPool arena; + SECItem ckaIDItem = { 0 }; + SECKEYPrivateKey *privkey = NULL; + SECStatus rv; + + if (PK11_NeedLogin(slot)) { + rv = PK11_Authenticate(slot, PR_TRUE, pwarg); + if (rv != SECSuccess) { + SECU_PrintError(progName, "could not authenticate to token %s.", + PK11_GetTokenName(slot)); + return NULL; + } + } + + if (0 == PL_strncasecmp("0x", ckaID, 2)) { + ckaID += 2; /* skip leading "0x" */ + } + PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE); + if (SECU_HexString2SECItem(&arena.arena, &ckaIDItem, ckaID)) { + privkey = PK11_FindKeyByKeyID(slot, &ckaIDItem, pwarg); + } + PORT_DestroyCheapArena(&arena); + return privkey; +} + +static SECStatus +DeleteKey(SECKEYPrivateKey *privkey, secuPWData *pwarg) +{ + SECStatus rv; + PK11SlotInfo *slot; + + slot = PK11_GetSlotFromPrivateKey(privkey); + if (PK11_NeedLogin(slot)) { + rv = PK11_Authenticate(slot, PR_TRUE, pwarg); + if (rv != SECSuccess) { + SECU_PrintError(progName, "could not authenticate to token %s.", + PK11_GetTokenName(slot)); + return SECFailure; + } + } + + rv = PK11_DeleteTokenPrivateKey(privkey, PR_TRUE); + if (rv != SECSuccess) { + char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; + formatPrivateKeyID(privkey, ckaIDbuf); + SECU_PrintError("problem deleting private key \"%s\"\n", ckaIDbuf); + } + + PK11_FreeSlot(slot); + return rv; +} + /* * L i s t M o d u l e s * @@ -1100,7 +1176,9 @@ PrintSyntax() "\t\t [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", progName); - FPS "\t%s -F -n nickname [-d certdir] [-P dbprefix]\n", + FPS "\t%s -F -n cert-name [-d certdir] [-P dbprefix]\n", + progName); + FPS "\t%s -F -k key-id [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -G -n key-name [-h token-name] [-k rsa] [-g key-size] [-y exp]\n" "\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); @@ -1390,6 +1468,8 @@ luF(enum usage_level ul, const char *command) return; FPS "%-20s The nickname of the key to delete\n", " -n cert-name"); + FPS "%-20s The key id of the key to delete, obtained using -K\n", + " -k key-id"); FPS "%-20s Cert database directory (default is ~/.netscape)\n", " -d certdir"); FPS "%-20s Cert & Key database prefix\n", @@ -1629,6 +1709,7 @@ luV(enum usage_level ul, const char *command) FPS "%-20s Specify certificate usage:\n", " -u certusage"); FPS "%-25s C \t SSL Client\n", ""); FPS "%-25s V \t SSL Server\n", ""); + FPS "%-25s I \t IPsec\n", ""); FPS "%-25s L \t SSL CA\n", ""); FPS "%-25s A \t Any CA\n", ""); FPS "%-25s Y \t Verify CA\n", ""); @@ -2944,10 +3025,9 @@ certutil_main(int argc, char **argv, PRBool initialize) readOnly = !certutil.options[opt_RW].activated; } - /* -A, -D, -F, -M, -S, -V, and all require -n */ + /* -A, -D, -M, -S, -V, and all require -n */ if ((certutil.commands[cmd_AddCert].activated || certutil.commands[cmd_DeleteCert].activated || - certutil.commands[cmd_DeleteKey].activated || certutil.commands[cmd_DumpChain].activated || certutil.commands[cmd_ModifyCertTrust].activated || certutil.commands[cmd_CreateAndAddCert].activated || @@ -3034,6 +3114,16 @@ certutil_main(int argc, char **argv, PRBool initialize) return 255; } + /* Delete needs a nickname or a key ID */ + if (certutil.commands[cmd_DeleteKey].activated && + !(certutil.options[opt_Nickname].activated || keysource)) { + PR_fprintf(PR_STDERR, + "%s -%c: specify a nickname (-n) or\n" + " a key ID (-k).\n", + commandToRun, progName); + return 255; + } + /* Upgrade/Merge needs a source database and a upgrade id. */ if (certutil.commands[cmd_UpgradeMerge].activated && !(certutil.options[opt_SourceDir].activated && @@ -3396,7 +3486,19 @@ certutil_main(int argc, char **argv, PRBool initialize) } /* Delete key (-F) */ if (certutil.commands[cmd_DeleteKey].activated) { - rv = DeleteKey(name, &pwdata); + if (certutil.options[opt_Nickname].activated) { + rv = DeleteCertAndKey(name, &pwdata); + } else { + privkey = findPrivateKeyByID(slot, keysource, &pwdata); + if (!privkey) { + SECU_PrintError(progName, "%s is not a key-id", keysource); + rv = SECFailure; + } else { + rv = DeleteKey(privkey, &pwdata); + /* already destroyed by PK11_DeleteTokenPrivateKey */ + privkey = NULL; + } + } goto shutdown; } /* Modify trust attribute for cert (-M) */ @@ -3468,30 +3570,8 @@ certutil_main(int argc, char **argv, PRBool initialize) if (keycert) { privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata); } else { - PLArenaPool *arena = NULL; - SECItem keyidItem = { 0 }; - char *keysourcePtr = keysource; /* Interpret keysource as CKA_ID */ - if (PK11_NeedLogin(slot)) { - rv = PK11_Authenticate(slot, PR_TRUE, &pwdata); - if (rv != SECSuccess) { - SECU_PrintError(progName, "could not authenticate to token %s.", - PK11_GetTokenName(slot)); - return SECFailure; - } - } - if (0 == PL_strncasecmp("0x", keysource, 2)) { - keysourcePtr = keysource + 2; // skip leading "0x" - } - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - SECU_PrintError(progName, "unable to allocate arena"); - return SECFailure; - } - if (SECU_HexString2SECItem(arena, &keyidItem, keysourcePtr)) { - privkey = PK11_FindKeyByKeyID(slot, &keyidItem, &pwdata); - } - PORT_FreeArena(arena, PR_FALSE); + privkey = findPrivateKeyByID(slot, keysource, &pwdata); } if (!privkey) { diff --git a/security/nss/cmd/crlutil/crlutil.c b/security/nss/cmd/crlutil/crlutil.c index c5527fc93..be2e47a6c 100644 --- a/security/nss/cmd/crlutil/crlutil.c +++ b/security/nss/cmd/crlutil/crlutil.c @@ -232,10 +232,6 @@ ImportCRL(CERTCertDBHandle *certHandle, char *url, int type, SECItem crlDER; PK11SlotInfo *slot = NULL; int rv; -#if defined(DEBUG_jp96085) - PRIntervalTime starttime, endtime, elapsed; - PRUint32 mins, secs, msecs; -#endif crlDER.data = NULL; @@ -256,19 +252,9 @@ ImportCRL(CERTCertDBHandle *certHandle, char *url, int type, goto loser; } -#if defined(DEBUG_jp96085) - starttime = PR_IntervalNow(); -#endif crl = PK11_ImportCRL(slot, &crlDER, url, type, NULL, importOptions, NULL, decodeOptions); -#if defined(DEBUG_jp96085) - endtime = PR_IntervalNow(); - elapsed = endtime - starttime; - mins = PR_IntervalToSeconds(elapsed) / 60; - secs = PR_IntervalToSeconds(elapsed) % 60; - msecs = PR_IntervalToMilliseconds(elapsed) % 1000; - printf("Elapsed : %2d:%2d.%3d\n", mins, secs, msecs); -#endif + if (!crl) { const char *errString; diff --git a/security/nss/cmd/crmf-cgi/crmfcgi.c b/security/nss/cmd/crmf-cgi/crmfcgi.c index 07b81f233..9f6174383 100644 --- a/security/nss/cmd/crmf-cgi/crmfcgi.c +++ b/security/nss/cmd/crmf-cgi/crmfcgi.c @@ -4,7 +4,7 @@ #include "seccomon.h" #include "nss.h" -#include "key.h" +#include "keyhi.h" #include "cert.h" #include "pk11func.h" #include "secmod.h" diff --git a/security/nss/cmd/crmftest/testcrmf.c b/security/nss/cmd/crmftest/testcrmf.c index 1c1359b1b..3fe5725bf 100644 --- a/security/nss/cmd/crmftest/testcrmf.c +++ b/security/nss/cmd/crmftest/testcrmf.c @@ -66,7 +66,7 @@ #include "crmf.h" #include "secerr.h" #include "pk11func.h" -#include "key.h" +#include "keyhi.h" #include "cmmf.h" #include "plgetopt.h" #include "secutil.h" diff --git a/security/nss/cmd/dbck/dbrecover.c b/security/nss/cmd/dbck/dbrecover.c index 74d21d85e..5b7e0549d 100644 --- a/security/nss/cmd/dbck/dbrecover.c +++ b/security/nss/cmd/dbck/dbrecover.c @@ -288,7 +288,8 @@ addCertToDB(certDBEntryCert *certEntry, dbRestoreInfo *info, /* If user chooses so, ignore expired certificates. */ allowOverride = (PRBool)((oldCert->keyUsage == certUsageSSLServer) || - (oldCert->keyUsage == certUsageSSLServerWithStepUp)); + (oldCert->keyUsage == certUsageSSLServerWithStepUp) || + (oldCert->keyUsage == certUsageIPsec)); validity = CERT_CheckCertValidTimes(oldCert, PR_Now(), allowOverride); /* If cert expired and user wants to delete it, ignore it. */ if ((validity != secCertTimeValid) && diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c index 061f3dde0..5d00b3070 100644 --- a/security/nss/cmd/fipstest/fipstest.c +++ b/security/nss/cmd/fipstest/fipstest.c @@ -2335,6 +2335,34 @@ sha_get_hashType(int hashbits) return hashType; } +HASH_HashType +hash_string_to_hashType(const char *src) +{ + HASH_HashType shaAlg = HASH_AlgNULL; + if (strncmp(src, "SHA-1", 5) == 0) { + shaAlg = HASH_AlgSHA1; + } else if (strncmp(src, "SHA-224", 7) == 0) { + shaAlg = HASH_AlgSHA224; + } else if (strncmp(src, "SHA-256", 7) == 0) { + shaAlg = HASH_AlgSHA256; + } else if (strncmp(src, "SHA-384", 7) == 0) { + shaAlg = HASH_AlgSHA384; + } else if (strncmp(src, "SHA-512", 7) == 0) { + shaAlg = HASH_AlgSHA512; + } else if (strncmp(src, "SHA1", 4) == 0) { + shaAlg = HASH_AlgSHA1; + } else if (strncmp(src, "SHA224", 6) == 0) { + shaAlg = HASH_AlgSHA224; + } else if (strncmp(src, "SHA256", 6) == 0) { + shaAlg = HASH_AlgSHA256; + } else if (strncmp(src, "SHA384", 6) == 0) { + shaAlg = HASH_AlgSHA384; + } else if (strncmp(src, "SHA512", 6) == 0) { + shaAlg = HASH_AlgSHA512; + } + return shaAlg; +} + /* * Perform the ECDSA Key Pair Generation Test. * @@ -2628,17 +2656,8 @@ ecdsa_siggen_test(char *reqfn) *dst = '\0'; src++; /* skip the comma */ /* set the SHA Algorithm */ - if (strncmp(src, "SHA-1", 5) == 0) { - shaAlg = HASH_AlgSHA1; - } else if (strncmp(src, "SHA-224", 7) == 0) { - shaAlg = HASH_AlgSHA224; - } else if (strncmp(src, "SHA-256", 7) == 0) { - shaAlg = HASH_AlgSHA256; - } else if (strncmp(src, "SHA-384", 7) == 0) { - shaAlg = HASH_AlgSHA384; - } else if (strncmp(src, "SHA-512", 7) == 0) { - shaAlg = HASH_AlgSHA512; - } else { + shaAlg = hash_string_to_hashType(src); + if (shaAlg == HASH_AlgNULL) { fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type"); goto loser; } @@ -2798,17 +2817,8 @@ ecdsa_sigver_test(char *reqfn) *dst = '\0'; src++; /* skip the comma */ /* set the SHA Algorithm */ - if (strncmp(src, "SHA-1", 5) == 0) { - shaAlg = HASH_AlgSHA1; - } else if (strncmp(src, "SHA-224", 7) == 0) { - shaAlg = HASH_AlgSHA224; - } else if (strncmp(src, "SHA-256", 7) == 0) { - shaAlg = HASH_AlgSHA256; - } else if (strncmp(src, "SHA-384", 7) == 0) { - shaAlg = HASH_AlgSHA384; - } else if (strncmp(src, "SHA-512", 7) == 0) { - shaAlg = HASH_AlgSHA512; - } else { + shaAlg = hash_string_to_hashType(src); + if (shaAlg == HASH_AlgNULL) { fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type"); goto loser; } @@ -2956,6 +2966,932 @@ loser: fclose(ecdsareq); } +/* + * Perform the ECDH Functional Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +#define MAX_ECC_PARAMS 256 +void +ecdh_functional(char *reqfn, PRBool response) +{ + char buf[256]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "Qx = <144 hex digits>\n". + */ + FILE *ecdhreq; /* input stream from the REQUEST file */ + FILE *ecdhresp; /* output stream to the RESPONSE file */ + char curve[16]; /* "nistxddd" */ + unsigned char hashBuf[HASH_LENGTH_MAX]; + ECParams *ecparams[MAX_ECC_PARAMS] = { NULL }; + ECPrivateKey *ecpriv = NULL; + ECParams *current_ecparams = NULL; + SECItem pubkey; + SECItem ZZ; + unsigned int i; + unsigned int len = 0; + unsigned int uit_len = 0; + int current_curve = -1; + HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */ + + ecdhreq = fopen(reqfn, "r"); + ecdhresp = stdout; + strcpy(curve, "nist"); + pubkey.data = NULL; + while (fgets(buf, sizeof buf, ecdhreq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { + fputs(buf, ecdhresp); + continue; + } + if (buf[0] == '[') { + /* [Ex] */ + if (buf[1] == 'E' && buf[3] == ']') { + current_curve = buf[2] - 'A'; + fputs(buf, ecdhresp); + continue; + } + /* [Curve selected: x-nnn */ + if (strncmp(buf, "[Curve ", 7) == 0) { + const char *src; + char *dst; + SECItem *encodedparams; + + if ((current_curve < 0) || (current_curve > MAX_ECC_PARAMS)) { + fprintf(stderr, "No curve type defined\n"); + goto loser; + } + + src = &buf[1]; + /* skip passed the colon */ + while (*src && *src != ':') + src++; + if (*src != ':') { + fprintf(stderr, + "No colon in curve selected statement\n%s", buf); + goto loser; + } + src++; + /* skip to the first non-space */ + while (*src && *src == ' ') + src++; + dst = &curve[4]; + *dst++ = tolower(*src); + src += 2; /* skip the hyphen */ + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst = '\0'; + if (ecparams[current_curve] != NULL) { + PORT_FreeArena(ecparams[current_curve]->arena, PR_FALSE); + ecparams[current_curve] = NULL; + } + encodedparams = getECParams(curve); + if (encodedparams == NULL) { + fprintf(stderr, "Unknown curve %s.", curve); + goto loser; + } + if (EC_DecodeParams(encodedparams, &ecparams[current_curve]) != SECSuccess) { + fprintf(stderr, "Curve %s not supported.\n", curve); + goto loser; + } + SECITEM_FreeItem(encodedparams, PR_TRUE); + fputs(buf, ecdhresp); + continue; + } + /* [Ex - SHAxxx] */ + if (buf[1] == 'E' && buf[3] == ' ') { + const char *src; + current_curve = buf[2] - 'A'; + if ((current_curve < 0) || (current_curve > 256)) { + fprintf(stderr, "bad curve type defined (%c)\n", buf[2]); + goto loser; + } + current_ecparams = ecparams[current_curve]; + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined for type %c defined\n", + buf[2]); + goto loser; + } + /* skip passed the colon */ + src = &buf[1]; + while (*src && *src != '-') + src++; + if (*src != '-') { + fprintf(stderr, + "No data in curve selected statement\n%s", buf); + goto loser; + } + src++; + /* skip to the first non-space */ + while (*src && *src == ' ') + src++; + hash = hash_string_to_hashType(src); + if (hash == HASH_AlgNULL) { + fprintf(ecdhresp, "ERROR: Unable to find SHAAlg type"); + goto loser; + } + fputs(buf, ecdhresp); + continue; + } + fputs(buf, ecdhresp); + continue; + } + /* COUNT = ... */ + if (strncmp(buf, "COUNT", 5) == 0) { + fputs(buf, ecdhresp); + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined for type %c defined\n", + buf[2]); + goto loser; + } + len = (current_ecparams->fieldID.size + 7) >> 3; + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + pubkey.data = NULL; + } + SECITEM_AllocItem(NULL, &pubkey, EC_GetPointSize(current_ecparams)); + if (pubkey.data == NULL) { + goto loser; + } + pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED; + continue; + } + /* QeCAVSx = ... */ + if (strncmp(buf, "QeCAVSx", 7) == 0) { + fputs(buf, ecdhresp); + i = 7; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(&pubkey.data[1], len, &buf[i]); + continue; + } + /* QeCAVSy = ... */ + if (strncmp(buf, "QeCAVSy", 7) == 0) { + fputs(buf, ecdhresp); + i = 7; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(&pubkey.data[1 + len], len, &buf[i]); + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined\n"); + goto loser; + } + /* validate CAVS public key */ + if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) { + fprintf(stderr, "BAD key detected\n"); + goto loser; + } + + /* generate ECC key pair */ + if (EC_NewKey(current_ecparams, &ecpriv) != SECSuccess) { + fprintf(stderr, "Failed to generate new key\n"); + goto loser; + } + /* validate UIT generated public key */ + if (EC_ValidatePublicKey(current_ecparams, &ecpriv->publicValue) != + SECSuccess) { + fprintf(stderr, "generate key did not validate\n"); + goto loser; + } + /* output UIT public key */ + uit_len = ecpriv->publicValue.len; + if (uit_len % 2 == 0) { + fprintf(stderr, "generate key had invalid public value len\n"); + goto loser; + } + uit_len = (uit_len - 1) / 2; + if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) { + fprintf(stderr, "generate key was compressed\n"); + goto loser; + } + fputs("QeIUTx = ", ecdhresp); + to_hex_str(buf, &ecpriv->publicValue.data[1], uit_len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); + fputs("QeIUTy = ", ecdhresp); + to_hex_str(buf, &ecpriv->publicValue.data[1 + uit_len], uit_len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); + /* ECDH */ + if (ECDH_Derive(&pubkey, current_ecparams, &ecpriv->privateValue, + PR_FALSE, &ZZ) != SECSuccess) { + fprintf(stderr, "Derive failed\n"); + goto loser; + } + /* output hash of ZZ */ + if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) { + fprintf(stderr, "hash of derived key failed\n"); + goto loser; + } + SECITEM_FreeItem(&ZZ, PR_FALSE); + fputs("HashZZ = ", ecdhresp); + to_hex_str(buf, hashBuf, fips_hashLen(hash)); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); + fputc('\n', ecdhresp); + PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE); + ecpriv = NULL; + continue; + } + } +loser: + if (ecpriv != NULL) { + PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE); + } + for (i = 0; i < MAX_ECC_PARAMS; i++) { + if (ecparams[i] != NULL) { + PORT_FreeArena(ecparams[i]->arena, PR_FALSE); + ecparams[i] = NULL; + } + } + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + } + fclose(ecdhreq); +} + +#define MATCH_OPENSSL 1 +/* + * Perform the ECDH Validity Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +ecdh_verify(char *reqfn, PRBool response) +{ + char buf[256]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "Qx = <144 hex digits>\n". + */ + FILE *ecdhreq; /* input stream from the REQUEST file */ + FILE *ecdhresp; /* output stream to the RESPONSE file */ + char curve[16]; /* "nistxddd" */ + unsigned char hashBuf[HASH_LENGTH_MAX]; + unsigned char cavsHashBuf[HASH_LENGTH_MAX]; + unsigned char private_data[MAX_ECKEY_LEN]; + ECParams *ecparams[MAX_ECC_PARAMS] = { NULL }; + ECParams *current_ecparams = NULL; + SECItem pubkey; + SECItem ZZ; + SECItem private_value; + unsigned int i; + unsigned int len = 0; + int current_curve = -1; + HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */ + + ecdhreq = fopen(reqfn, "r"); + ecdhresp = stdout; + strcpy(curve, "nist"); + pubkey.data = NULL; + while (fgets(buf, sizeof buf, ecdhreq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { + fputs(buf, ecdhresp); + continue; + } + if (buf[0] == '[') { + /* [Ex] */ + if (buf[1] == 'E' && buf[3] == ']') { + current_curve = buf[2] - 'A'; + fputs(buf, ecdhresp); + continue; + } + /* [Curve selected: x-nnn */ + if (strncmp(buf, "[Curve ", 7) == 0) { + const char *src; + char *dst; + SECItem *encodedparams; + + if ((current_curve < 0) || (current_curve > MAX_ECC_PARAMS)) { + fprintf(stderr, "No curve type defined\n"); + goto loser; + } + + src = &buf[1]; + /* skip passed the colon */ + while (*src && *src != ':') + src++; + if (*src != ':') { + fprintf(stderr, + "No colon in curve selected statement\n%s", buf); + goto loser; + } + src++; + /* skip to the first non-space */ + while (*src && *src == ' ') + src++; + dst = &curve[4]; + *dst++ = tolower(*src); + src += 2; /* skip the hyphen */ + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst = '\0'; + if (ecparams[current_curve] != NULL) { + PORT_FreeArena(ecparams[current_curve]->arena, PR_FALSE); + ecparams[current_curve] = NULL; + } + encodedparams = getECParams(curve); + if (encodedparams == NULL) { + fprintf(stderr, "Unknown curve %s.\n", curve); + goto loser; + } + if (EC_DecodeParams(encodedparams, &ecparams[current_curve]) != SECSuccess) { + fprintf(stderr, "Curve %s not supported.\n", curve); + goto loser; + } + SECITEM_FreeItem(encodedparams, PR_TRUE); + fputs(buf, ecdhresp); + continue; + } + /* [Ex - SHAxxx] */ + if (buf[1] == 'E' && buf[3] == ' ') { + const char *src; + current_curve = buf[2] - 'A'; + if ((current_curve < 0) || (current_curve > 256)) { + fprintf(stderr, "bad curve type defined (%c)\n", buf[2]); + goto loser; + } + current_ecparams = ecparams[current_curve]; + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined for type %c defined\n", + buf[2]); + goto loser; + } + /* skip passed the colon */ + src = &buf[1]; + while (*src && *src != '-') + src++; + if (*src != '-') { + fprintf(stderr, + "No data in curve selected statement\n%s", buf); + goto loser; + } + src++; + /* skip to the first non-space */ + while (*src && *src == ' ') + src++; + hash = hash_string_to_hashType(src); + if (hash == HASH_AlgNULL) { + fprintf(ecdhresp, "ERROR: Unable to find SHAAlg type"); + goto loser; + } + fputs(buf, ecdhresp); + continue; + } + fputs(buf, ecdhresp); + continue; + } + /* COUNT = ... */ + if (strncmp(buf, "COUNT", 5) == 0) { + fputs(buf, ecdhresp); + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined for type %c defined\n", + buf[2]); + goto loser; + } + len = (current_ecparams->fieldID.size + 7) >> 3; + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + pubkey.data = NULL; + } + SECITEM_AllocItem(NULL, &pubkey, EC_GetPointSize(current_ecparams)); + if (pubkey.data == NULL) { + goto loser; + } + pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED; + continue; + } + /* QeCAVSx = ... */ + if (strncmp(buf, "QeCAVSx", 7) == 0) { + fputs(buf, ecdhresp); + i = 7; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(&pubkey.data[1], len, &buf[i]); + continue; + } + /* QeCAVSy = ... */ + if (strncmp(buf, "QeCAVSy", 7) == 0) { + fputs(buf, ecdhresp); + i = 7; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(&pubkey.data[1 + len], len, &buf[i]); + continue; + } + if (strncmp(buf, "deIUT", 5) == 0) { + fputs(buf, ecdhresp); + i = 5; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(private_data, len, &buf[i]); + private_value.data = private_data; + private_value.len = len; + continue; + } + if (strncmp(buf, "QeIUTx", 6) == 0) { + fputs(buf, ecdhresp); + continue; + } + if (strncmp(buf, "QeIUTy", 6) == 0) { + fputs(buf, ecdhresp); + continue; + } + if (strncmp(buf, "CAVSHashZZ", 10) == 0) { + fputs(buf, ecdhresp); + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]); + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined for type defined\n"); + goto loser; + } + /* validate CAVS public key */ + if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) { +#ifdef MATCH_OPENSSL + fprintf(ecdhresp, "Result = F\n"); +#else + fprintf(ecdhresp, "Result = F # key didn't validate\n"); +#endif + continue; + } + + /* ECDH */ + if (ECDH_Derive(&pubkey, current_ecparams, &private_value, + PR_FALSE, &ZZ) != SECSuccess) { + fprintf(stderr, "Derive failed\n"); + goto loser; + } +/* output ZZ */ +#ifndef MATCH_OPENSSL + fputs("Z = ", ecdhresp); + to_hex_str(buf, ZZ.data, ZZ.len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); +#endif + + if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) { + fprintf(stderr, "hash of derived key failed\n"); + goto loser; + } + SECITEM_FreeItem(&ZZ, PR_FALSE); +#ifndef MATCH_NIST + fputs("IUTHashZZ = ", ecdhresp); + to_hex_str(buf, hashBuf, fips_hashLen(hash)); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); +#endif + if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) { +#ifdef MATCH_OPENSSL + fprintf(ecdhresp, "Result = F\n"); +#else + fprintf(ecdhresp, "Result = F # hash doesn't match\n"); +#endif + } else { + fprintf(ecdhresp, "Result = P\n"); + } +#ifndef MATCH_OPENSSL + fputc('\n', ecdhresp); +#endif + continue; + } + } +loser: + for (i = 0; i < MAX_ECC_PARAMS; i++) { + if (ecparams[i] != NULL) { + PORT_FreeArena(ecparams[i]->arena, PR_FALSE); + ecparams[i] = NULL; + } + } + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + } + fclose(ecdhreq); +} + +/* + * Perform the DH Functional Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +#define MAX_ECC_PARAMS 256 +void +dh_functional(char *reqfn, PRBool response) +{ + char buf[1024]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "YephCAVS = <512 hex digits>\n". + */ + FILE *dhreq; /* input stream from the REQUEST file */ + FILE *dhresp; /* output stream to the RESPONSE file */ + unsigned char hashBuf[HASH_LENGTH_MAX]; + DSAPrivateKey *dsapriv = NULL; + PQGParams pqg = { 0 }; + unsigned char pubkeydata[DSA_MAX_P_BITS / 8]; + SECItem pubkey; + SECItem ZZ; + unsigned int i, j; + unsigned int pgySize; + HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */ + + dhreq = fopen(reqfn, "r"); + dhresp = stdout; + while (fgets(buf, sizeof buf, dhreq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { + fputs(buf, dhresp); + continue; + } + if (buf[0] == '[') { + /* [Fx - SHAxxx] */ + if (buf[1] == 'F' && buf[3] == ' ') { + const char *src; + /* skip passed the colon */ + src = &buf[1]; + while (*src && *src != '-') + src++; + if (*src != '-') { + fprintf(stderr, "No hash specified\n%s", buf); + goto loser; + } + src++; + /* skip to the first non-space */ + while (*src && *src == ' ') + src++; + hash = hash_string_to_hashType(src); + if (hash == HASH_AlgNULL) { + fprintf(dhresp, "ERROR: Unable to find SHAAlg type"); + goto loser; + } + /* clear the PQG parameters */ + if (pqg.prime.data) { /* P */ + SECITEM_ZfreeItem(&pqg.prime, PR_FALSE); + } + if (pqg.subPrime.data) { /* Q */ + SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE); + } + if (pqg.base.data) { /* G */ + SECITEM_ZfreeItem(&pqg.base, PR_FALSE); + } + pgySize = DSA_MAX_P_BITS / 8; /* change if more key sizes are supported in CAVS */ + SECITEM_AllocItem(NULL, &pqg.prime, pgySize); + SECITEM_AllocItem(NULL, &pqg.base, pgySize); + pqg.prime.len = pqg.base.len = pgySize; + + /* set q to the max allows */ + SECITEM_AllocItem(NULL, &pqg.subPrime, DSA_MAX_Q_BITS / 8); + pqg.subPrime.len = DSA_MAX_Q_BITS / 8; + fputs(buf, dhresp); + continue; + } + fputs(buf, dhresp); + continue; + } + if (buf[0] == 'P') { + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < pqg.prime.len; i += 2, j++) { + if (!isxdigit(buf[i])) { + pqg.prime.len = j; + break; + } + hex_to_byteval(&buf[i], &pqg.prime.data[j]); + } + + fputs(buf, dhresp); + continue; + } + + /* Q = ... */ + if (buf[0] == 'Q') { + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < pqg.subPrime.len; i += 2, j++) { + if (!isxdigit(buf[i])) { + pqg.subPrime.len = j; + break; + } + hex_to_byteval(&buf[i], &pqg.subPrime.data[j]); + } + + fputs(buf, dhresp); + continue; + } + + /* G = ... */ + if (buf[0] == 'G') { + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < pqg.base.len; i += 2, j++) { + if (!isxdigit(buf[i])) { + pqg.base.len = j; + break; + } + hex_to_byteval(&buf[i], &pqg.base.data[j]); + } + + fputs(buf, dhresp); + continue; + } + + /* COUNT = ... */ + if (strncmp(buf, "COUNT", 5) == 0) { + fputs(buf, dhresp); + continue; + } + + /* YephemCAVS = ... */ + if (strncmp(buf, "YephemCAVS", 10) == 0) { + fputs(buf, dhresp); + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(pubkeydata, pqg.prime.len, &buf[i]); + pubkey.data = pubkeydata; + pubkey.len = pqg.prime.len; + + /* generate FCC key pair, nist uses pqg rather then pg, + * so use DSA to generate the key */ + if (DSA_NewKey(&pqg, &dsapriv) != SECSuccess) { + fprintf(stderr, "Failed to generate new key\n"); + goto loser; + } + fputs("XephemIUT = ", dhresp); + to_hex_str(buf, dsapriv->privateValue.data, dsapriv->privateValue.len); + fputs(buf, dhresp); + fputc('\n', dhresp); + fputs("YephemIUT = ", dhresp); + to_hex_str(buf, dsapriv->publicValue.data, dsapriv->publicValue.len); + fputs(buf, dhresp); + fputc('\n', dhresp); + /* DH */ + if (DH_Derive(&pubkey, &pqg.prime, &dsapriv->privateValue, + &ZZ, pqg.prime.len) != SECSuccess) { + fprintf(stderr, "Derive failed\n"); + goto loser; + } + /* output hash of ZZ */ + if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) { + fprintf(stderr, "hash of derived key failed\n"); + goto loser; + } + SECITEM_FreeItem(&ZZ, PR_FALSE); + fputs("HashZZ = ", dhresp); + to_hex_str(buf, hashBuf, fips_hashLen(hash)); + fputs(buf, dhresp); + fputc('\n', dhresp); + fputc('\n', dhresp); + PORT_FreeArena(dsapriv->params.arena, PR_TRUE); + dsapriv = NULL; + continue; + } + } +loser: + if (dsapriv != NULL) { + PORT_FreeArena(dsapriv->params.arena, PR_TRUE); + } + fclose(dhreq); +} + +#define MATCH_OPENSSL 1 +/* + * Perform the DH Validity Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +dh_verify(char *reqfn, PRBool response) +{ + char buf[1024]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "YephCAVS = <512 hex digits>\n". + */ + FILE *dhreq; /* input stream from the REQUEST file */ + FILE *dhresp; /* output stream to the RESPONSE file */ + unsigned char hashBuf[HASH_LENGTH_MAX]; + unsigned char cavsHashBuf[HASH_LENGTH_MAX]; + PQGParams pqg = { 0 }; + unsigned char pubkeydata[DSA_MAX_P_BITS / 8]; + unsigned char privkeydata[DSA_MAX_P_BITS / 8]; + SECItem pubkey; + SECItem privkey; + SECItem ZZ; + unsigned int i, j; + unsigned int pgySize; + HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */ + + dhreq = fopen(reqfn, "r"); + dhresp = stdout; + while (fgets(buf, sizeof buf, dhreq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { + fputs(buf, dhresp); + continue; + } + if (buf[0] == '[') { + /* [Fx - SHAxxx] */ + if (buf[1] == 'F' && buf[3] == ' ') { + const char *src; + /* skip passed the colon */ + src = &buf[1]; + while (*src && *src != '-') + src++; + if (*src != '-') { + fprintf(stderr, "No hash specified\n%s", buf); + goto loser; + } + src++; + /* skip to the first non-space */ + while (*src && *src == ' ') + src++; + hash = hash_string_to_hashType(src); + if (hash == HASH_AlgNULL) { + fprintf(dhresp, "ERROR: Unable to find SHAAlg type"); + goto loser; + } + /* clear the PQG parameters */ + if (pqg.prime.data) { /* P */ + SECITEM_ZfreeItem(&pqg.prime, PR_FALSE); + } + if (pqg.subPrime.data) { /* Q */ + SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE); + } + if (pqg.base.data) { /* G */ + SECITEM_ZfreeItem(&pqg.base, PR_FALSE); + } + pgySize = DSA_MAX_P_BITS / 8; /* change if more key sizes are supported in CAVS */ + SECITEM_AllocItem(NULL, &pqg.prime, pgySize); + SECITEM_AllocItem(NULL, &pqg.base, pgySize); + pqg.prime.len = pqg.base.len = pgySize; + + /* set q to the max allows */ + SECITEM_AllocItem(NULL, &pqg.subPrime, DSA_MAX_Q_BITS / 8); + pqg.subPrime.len = DSA_MAX_Q_BITS / 8; + fputs(buf, dhresp); + continue; + } + fputs(buf, dhresp); + continue; + } + if (buf[0] == 'P') { + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < pqg.prime.len; i += 2, j++) { + if (!isxdigit(buf[i])) { + pqg.prime.len = j; + break; + } + hex_to_byteval(&buf[i], &pqg.prime.data[j]); + } + + fputs(buf, dhresp); + continue; + } + + /* Q = ... */ + if (buf[0] == 'Q') { + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < pqg.subPrime.len; i += 2, j++) { + if (!isxdigit(buf[i])) { + pqg.subPrime.len = j; + break; + } + hex_to_byteval(&buf[i], &pqg.subPrime.data[j]); + } + + fputs(buf, dhresp); + continue; + } + + /* G = ... */ + if (buf[0] == 'G') { + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < pqg.base.len; i += 2, j++) { + if (!isxdigit(buf[i])) { + pqg.base.len = j; + break; + } + hex_to_byteval(&buf[i], &pqg.base.data[j]); + } + + fputs(buf, dhresp); + continue; + } + + /* COUNT = ... */ + if (strncmp(buf, "COUNT", 5) == 0) { + fputs(buf, dhresp); + continue; + } + + /* YephemCAVS = ... */ + if (strncmp(buf, "YephemCAVS", 10) == 0) { + fputs(buf, dhresp); + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(pubkeydata, pqg.prime.len, &buf[i]); + pubkey.data = pubkeydata; + pubkey.len = pqg.prime.len; + continue; + } + /* XephemUIT = ... */ + if (strncmp(buf, "XephemIUT", 9) == 0) { + fputs(buf, dhresp); + i = 9; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(privkeydata, pqg.subPrime.len, &buf[i]); + privkey.data = privkeydata; + privkey.len = pqg.subPrime.len; + continue; + } + /* YephemUIT = ... */ + if (strncmp(buf, "YephemIUT", 9) == 0) { + fputs(buf, dhresp); + continue; + } + /* CAVSHashZZ = ... */ + if (strncmp(buf, "CAVSHashZZ", 10) == 0) { + fputs(buf, dhresp); + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]); + /* do the DH operation*/ + if (DH_Derive(&pubkey, &pqg.prime, &privkey, + &ZZ, pqg.prime.len) != SECSuccess) { + fprintf(stderr, "Derive failed\n"); + goto loser; + } +/* output ZZ */ +#ifndef MATCH_OPENSSL + fputs("Z = ", dhresp); + to_hex_str(buf, ZZ.data, ZZ.len); + fputs(buf, dhresp); + fputc('\n', dhresp); +#endif + if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) { + fprintf(stderr, "hash of derived key failed\n"); + goto loser; + } + SECITEM_FreeItem(&ZZ, PR_FALSE); +#ifndef MATCH_NIST_ + fputs("IUTHashZZ = ", dhresp); + to_hex_str(buf, hashBuf, fips_hashLen(hash)); + fputs(buf, dhresp); + fputc('\n', dhresp); +#endif + if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) { + fprintf(dhresp, "Result = F\n"); + } else { + fprintf(dhresp, "Result = P\n"); + } +#ifndef MATCH_OPENSSL + fputc('\n', dhresp); +#endif + continue; + } + } +loser: + fclose(dhreq); +} + PRBool isblankline(char *b) { @@ -5342,17 +6278,8 @@ rsa_siggen_test(char *reqfn) i++; } /* set the SHA Algorithm */ - if (strncmp(&buf[i], "SHA1", 4) == 0) { - shaAlg = HASH_AlgSHA1; - } else if (strncmp(&buf[i], "SHA224", 6) == 0) { - shaAlg = HASH_AlgSHA224; - } else if (strncmp(&buf[i], "SHA256", 6) == 0) { - shaAlg = HASH_AlgSHA256; - } else if (strncmp(&buf[i], "SHA384", 6) == 0) { - shaAlg = HASH_AlgSHA384; - } else if (strncmp(&buf[i], "SHA512", 6) == 0) { - shaAlg = HASH_AlgSHA512; - } else { + shaAlg = hash_string_to_hashType(&buf[i]); + if (shaAlg == HASH_AlgNULL) { fprintf(rsaresp, "ERROR: Unable to find SHAAlg type"); goto loser; } @@ -5537,17 +6464,8 @@ rsa_sigver_test(char *reqfn) i++; } /* set the SHA Algorithm */ - if (strncmp(&buf[i], "SHA1", 4) == 0) { - shaAlg = HASH_AlgSHA1; - } else if (strncmp(&buf[i], "SHA224", 6) == 0) { - shaAlg = HASH_AlgSHA224; - } else if (strncmp(&buf[i], "SHA256", 6) == 0) { - shaAlg = HASH_AlgSHA256; - } else if (strncmp(&buf[i], "SHA384", 6) == 0) { - shaAlg = HASH_AlgSHA384; - } else if (strncmp(&buf[i], "SHA512", 6) == 0) { - shaAlg = HASH_AlgSHA512; - } else { + shaAlg = hash_string_to_hashType(&buf[i]); + if (shaAlg == HASH_AlgNULL) { fprintf(rsaresp, "ERROR: Unable to find SHAAlg type"); goto loser; } @@ -6108,6 +7026,34 @@ main(int argc, char **argv) ecdsa_sigver_test(argv[3]); } /*************/ + /* ECDH */ + /*************/ + } else if (strcmp(argv[1], "ecdh") == 0) { + /* argv[2]={init|resp}-{func|verify} argv[3]=.req */ + if (strcmp(argv[2], "init-func") == 0) { + ecdh_functional(argv[3], 0); + } else if (strcmp(argv[2], "resp-func") == 0) { + ecdh_functional(argv[3], 1); + } else if (strcmp(argv[2], "init-verify") == 0) { + ecdh_verify(argv[3], 0); + } else if (strcmp(argv[2], "resp-verify") == 0) { + ecdh_verify(argv[3], 1); + } + /*************/ + /* DH */ + /*************/ + } else if (strcmp(argv[1], "dh") == 0) { + /* argv[2]={init|resp}-{func|verify} argv[3]=.req */ + if (strcmp(argv[2], "init-func") == 0) { + dh_functional(argv[3], 0); + } else if (strcmp(argv[2], "resp-func") == 0) { + dh_functional(argv[3], 1); + } else if (strcmp(argv[2], "init-verify") == 0) { + dh_verify(argv[3], 0); + } else if (strcmp(argv[2], "resp-verify") == 0) { + dh_verify(argv[3], 1); + } + /*************/ /* RNG */ /*************/ } else if (strcmp(argv[1], "rng") == 0) { diff --git a/security/nss/cmd/fipstest/kas.sh b/security/nss/cmd/fipstest/kas.sh new file mode 100644 index 000000000..9aa5387a8 --- /dev/null +++ b/security/nss/cmd/fipstest/kas.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# A Bourne shell script for running the NIST DSA Validation System +# +# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment +# variables appropriately so that the fipstest command and the NSPR and NSS +# shared libraries/DLLs are on the search path. Then run this script in the +# directory where the REQUEST (.req) files reside. The script generates the +# RESPONSE (.rsp) files in the same directory. +BASEDIR=${1-.} +TESTDIR=${BASEDIR}/KAS +COMMAND=${2-run} +REQDIR=${TESTDIR}/req +RSPDIR=${TESTDIR}/resp + + +# +if [ ${COMMAND} = "verify" ]; then +# +# need verify for KAS tests + +# verify generated keys +# name=KeyPair +# echo ">>>>> $name" +# fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F +# verify generated pqg values +# name=PQGGen +# echo ">>>>> $name" +# fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F +# verify PQGVer with known answer +# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;' +# verify signatures +# name=SigGen +# echo ">>>>> $name" +# fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F +# verify SigVer with known answer +# sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;' + exit 0 +fi + +request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdh init-func ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdh resp-func ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdh init-verify ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest dh init-func ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest dh resp-func ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest dh init-verify ${REQDIR}/$request > ${RSPDIR}/$response + +request=KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest dh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response + diff --git a/security/nss/cmd/fipstest/runtest.sh b/security/nss/cmd/fipstest/runtest.sh index 5f8e66a08..fcb16348b 100644 --- a/security/nss/cmd/fipstest/runtest.sh +++ b/security/nss/cmd/fipstest/runtest.sh @@ -6,7 +6,7 @@ # TESTDIR=${1-.} COMMAND=${2-run} -TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea" +TESTS="aes aesgcm dsa ecdsa hmac kas tls rng rsa sha tdea" 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 6be2df432..97c7f750a 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -3799,7 +3799,7 @@ SECU_ParseSSLVersionRangeString(const char *input, return SECSuccess; } -SSLNamedGroup +static SSLNamedGroup groupNameToNamedGroup(char *name) { if (PL_strlen(name) == 4) { @@ -3837,6 +3837,23 @@ groupNameToNamedGroup(char *name) return ssl_grp_none; } +static SECStatus +countItems(const char *arg, unsigned int *numItems) +{ + char *str = PORT_Strdup(arg); + if (!str) { + return SECFailure; + } + char *p = strtok(str, ","); + while (p) { + ++(*numItems); + p = strtok(NULL, ","); + } + PORT_Free(str); + str = NULL; + return SECSuccess; +} + SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, unsigned int *enabledGroupsCount) @@ -3847,21 +3864,12 @@ parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, unsigned int numValues = 0; unsigned int count = 0; - /* Count the number of groups. */ - str = PORT_Strdup(arg); - if (!str) { + if (countItems(arg, &numValues) != SECSuccess) { return SECFailure; } - p = strtok(str, ","); - while (p) { - ++numValues; - p = strtok(NULL, ","); - } - PORT_Free(str); - str = NULL; groups = PORT_ZNewArray(SSLNamedGroup, numValues); if (!groups) { - goto done; + return SECFailure; } /* Get group names. */ @@ -3881,9 +3889,7 @@ parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, } done: - if (str) { - PORT_Free(str); - } + PORT_Free(str); if (!count) { PORT_Free(groups); return SECFailure; @@ -3893,3 +3899,83 @@ done: *enabledGroups = groups; return SECSuccess; } + +SSLSignatureScheme +schemeNameToScheme(const char *name) +{ +#define compareScheme(x) \ + do { \ + if (!PORT_Strncmp(name, #x, PORT_Strlen(#x))) { \ + return ssl_sig_##x; \ + } \ + } while (0) + + compareScheme(rsa_pkcs1_sha1); + compareScheme(rsa_pkcs1_sha256); + compareScheme(rsa_pkcs1_sha384); + compareScheme(rsa_pkcs1_sha512); + compareScheme(ecdsa_sha1); + compareScheme(ecdsa_secp256r1_sha256); + compareScheme(ecdsa_secp384r1_sha384); + compareScheme(ecdsa_secp521r1_sha512); + compareScheme(rsa_pss_rsae_sha256); + compareScheme(rsa_pss_rsae_sha384); + compareScheme(rsa_pss_rsae_sha512); + compareScheme(ed25519); + compareScheme(ed448); + compareScheme(rsa_pss_pss_sha256); + compareScheme(rsa_pss_pss_sha384); + compareScheme(rsa_pss_pss_sha512); + compareScheme(dsa_sha1); + compareScheme(dsa_sha256); + compareScheme(dsa_sha384); + compareScheme(dsa_sha512); + +#undef compareScheme + + return ssl_sig_none; +} + +SECStatus +parseSigSchemeList(const char *arg, const SSLSignatureScheme **enabledSigSchemes, + unsigned int *enabledSigSchemeCount) +{ + SSLSignatureScheme *schemes; + unsigned int numValues = 0; + unsigned int count = 0; + + if (countItems(arg, &numValues) != SECSuccess) { + return SECFailure; + } + schemes = PORT_ZNewArray(SSLSignatureScheme, numValues); + if (!schemes) { + return SECFailure; + } + + /* Get group names. */ + char *str = PORT_Strdup(arg); + if (!str) { + goto done; + } + char *p = strtok(str, ","); + while (p) { + SSLSignatureScheme scheme = schemeNameToScheme(p); + if (scheme == ssl_sig_none) { + count = 0; + goto done; + } + schemes[count++] = scheme; + p = strtok(NULL, ","); + } + +done: + PORT_Free(str); + if (!count) { + PORT_Free(schemes); + return SECFailure; + } + + *enabledSigSchemeCount = count; + *enabledSigSchemes = schemes; + return SECSuccess; +} diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h index fe07aca60..90d763909 100644 --- a/security/nss/cmd/lib/secutil.h +++ b/security/nss/cmd/lib/secutil.h @@ -9,7 +9,7 @@ #include "secport.h" #include "prerror.h" #include "base64.h" -#include "key.h" +#include "keyhi.h" #include "secpkcs7.h" #include "secasn1.h" #include "secder.h" @@ -406,7 +406,9 @@ SECU_ParseSSLVersionRangeString(const char *input, SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, unsigned int *enabledGroupsCount); -SSLNamedGroup groupNameToNamedGroup(char *name); +SECStatus parseSigSchemeList(const char *arg, + const SSLSignatureScheme **enabledSigSchemes, + unsigned int *enabledSigSchemeCount); /* * diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn index 567c6bb9d..be53d3c4e 100644 --- a/security/nss/cmd/manifest.mn +++ b/security/nss/cmd/manifest.mn @@ -47,6 +47,7 @@ NSS_SRCDIRS = \ listsuites \ makepqg \ multinit \ + nss-policy-check \ ocspclnt \ ocspresp \ oidcalc \ diff --git a/security/nss/cmd/modutil/error.h b/security/nss/cmd/modutil/error.h index d9f06592f..33ed7bde7 100644 --- a/security/nss/cmd/modutil/error.h +++ b/security/nss/cmd/modutil/error.h @@ -131,6 +131,7 @@ typedef enum { UNDEFAULT_SUCCESS_MSG, BROWSER_RUNNING_MSG, ABORTING_MSG, + P11_KIT_ENABLED_MSG, LAST_MSG /* must be last */ } Message; diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c index c1b44be53..f04ad3d92 100644 --- a/security/nss/cmd/modutil/modutil.c +++ b/security/nss/cmd/modutil/modutil.c @@ -138,7 +138,11 @@ char* msgStrings[] = { "\ncorruption of your security databases. If the browser is currently running," "\nyou should exit browser before continuing this operation. Type " "\n'q ' to abort, or to continue: ", - "\nAborting...\n" + "\nAborting...\n", + "\nWARNING: Manually adding a module while p11-kit is enabled could cause" + "\nduplicate module registration in your security database. It is suggested " + "\nto configure the module through p11-kit configuration file instead.\n" + "\nType 'q ' to abort, or to continue: " }; /* Increment i if doing so would have i still be less than j. If you @@ -856,6 +860,28 @@ main(int argc, char* argv[]) goto loser; } + /* Warn if we are adding a module while p11-kit is enabled in the + * database. */ + if ((command == ADD_COMMAND || command == RAW_ADD_COMMAND) && + IsP11KitEnabled()) { + char* response; + + PR_fprintf(PR_STDOUT, msgStrings[P11_KIT_ENABLED_MSG]); + if (!PR_fgets(stdinbuf, STDINBUF_SIZE, PR_STDIN)) { + PR_fprintf(PR_STDERR, errStrings[STDIN_READ_ERR]); + errcode = STDIN_READ_ERR; + goto loser; + } + if ((response = strtok(stdinbuf, " \r\n\t"))) { + if (!PL_strcasecmp(response, "q")) { + PR_fprintf(PR_STDOUT, msgStrings[ABORTING_MSG]); + errcode = SUCCESS; + goto loser; + } + } + PR_fprintf(PR_STDOUT, "\n"); + } + /* Execute the command */ switch (command) { case ADD_COMMAND: diff --git a/security/nss/cmd/modutil/modutil.h b/security/nss/cmd/modutil/modutil.h index 04aa908c8..1981fec7b 100644 --- a/security/nss/cmd/modutil/modutil.h +++ b/security/nss/cmd/modutil/modutil.h @@ -36,6 +36,7 @@ Error RawAddModule(char *dbmodulespec, char *modulespec); Error RawListModule(char *modulespec); Error SetDefaultModule(char *moduleName, char *slotName, char *mechanisms); Error UnsetDefaultModule(char *moduleName, char *slotName, char *mechanisms); +PRBool IsP11KitEnabled(void); void out_of_memory(void); #endif /*MODUTIL_H*/ diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c index 1efc1895c..6d17a3365 100644 --- a/security/nss/cmd/modutil/pk11.c +++ b/security/nss/cmd/modutil/pk11.c @@ -259,6 +259,55 @@ getStringFromFlags(unsigned long flags, const MaskString array[], int elements) return buf; } +static PRBool +IsP11KitProxyModule(SECMODModule *module) +{ + CK_INFO modinfo; + static const char p11KitManufacturerID[33] = + "PKCS#11 Kit "; + static const char p11KitLibraryDescription[33] = + "PKCS#11 Kit Proxy Module "; + + if (PK11_GetModInfo(module, &modinfo) == SECSuccess && + PORT_Memcmp(modinfo.manufacturerID, + p11KitManufacturerID, + sizeof(modinfo.manufacturerID)) == 0 && + PORT_Memcmp(modinfo.libraryDescription, + p11KitLibraryDescription, + sizeof(modinfo.libraryDescription)) == 0) { + return PR_TRUE; + } + + return PR_FALSE; +} + +PRBool +IsP11KitEnabled(void) +{ + SECMODListLock *lock; + SECMODModuleList *mlp; + PRBool found = PR_FALSE; + + lock = SECMOD_GetDefaultModuleListLock(); + if (!lock) { + PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]); + return found; + } + + SECMOD_GetReadLock(lock); + + mlp = SECMOD_GetDefaultModuleList(); + for (; mlp != NULL; mlp = mlp->next) { + if (IsP11KitProxyModule(mlp->module)) { + found = PR_TRUE; + break; + } + } + + SECMOD_ReleaseReadLock(lock); + return found; +} + /********************************************************************** * * A d d M o d u l e diff --git a/security/nss/cmd/nss-policy-check/Makefile b/security/nss/cmd/nss-policy-check/Makefile new file mode 100644 index 000000000..6e1d4ecdf --- /dev/null +++ b/security/nss/cmd/nss-policy-check/Makefile @@ -0,0 +1,47 @@ +#! gmake +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include ../platlibs.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +include ../platrules.mk + diff --git a/security/nss/cmd/nss-policy-check/manifest.mn b/security/nss/cmd/nss-policy-check/manifest.mn new file mode 100644 index 000000000..8fb9abf00 --- /dev/null +++ b/security/nss/cmd/nss-policy-check/manifest.mn @@ -0,0 +1,15 @@ +# +# 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/. + +CORE_DEPTH = ../.. + +MODULE = nss + +CSRCS = nss-policy-check.c + +REQUIRES = seccmd + +PROGRAM = nss-policy-check + diff --git a/security/nss/cmd/nss-policy-check/nss-policy-check.c b/security/nss/cmd/nss-policy-check/nss-policy-check.c new file mode 100644 index 000000000..b83003874 --- /dev/null +++ b/security/nss/cmd/nss-policy-check/nss-policy-check.c @@ -0,0 +1,206 @@ +/* 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/. */ + +/* This program can be used to check the validity of a NSS crypto policy + * configuration file, specified using a config= line. + * + * Exit codes: + * failure: 2 + * warning: 1 + * success: 0 + */ + +#include +#include +#include +#include "utilparst.h" +#include "nss.h" +#include "secport.h" +#include "secutil.h" +#include "secmod.h" +#include "ssl.h" +#include "prenv.h" + +const char *sWarn = "WARN"; +const char *sInfo = "INFO"; + +void +get_tls_info(SSLProtocolVariant protocolVariant, const char *display) +{ + SSLVersionRange vrange_supported, vrange_enabled; + unsigned num_enabled = 0; + PRBool failed = PR_FALSE; + + /* We assume SSL v2 is inactive, and therefore SSL_VersionRangeGetDefault + * gives complete information. */ + if ((SSL_VersionRangeGetSupported(protocolVariant, &vrange_supported) != SECSuccess) || + (SSL_VersionRangeGetDefault(protocolVariant, &vrange_enabled) != SECSuccess) || + !vrange_enabled.min || + !vrange_enabled.max || + vrange_enabled.max < vrange_supported.min || + vrange_enabled.min > vrange_supported.max) { + failed = PR_TRUE; + } else { + if (vrange_enabled.min < vrange_supported.min) { + vrange_enabled.min = vrange_supported.min; + } + if (vrange_enabled.max > vrange_supported.max) { + vrange_enabled.max = vrange_supported.max; + } + if (vrange_enabled.min > vrange_enabled.max) { + failed = PR_TRUE; + } + } + if (failed) { + num_enabled = 0; + } else { + num_enabled = vrange_enabled.max - vrange_enabled.min + 1; + } + fprintf(stderr, "NSS-POLICY-%s: NUMBER-OF-%s-VERSIONS: %u\n", + num_enabled ? sInfo : sWarn, display, num_enabled); + if (!num_enabled) { + PR_SetEnv("NSS_POLICY_WARN=1"); + } +} + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +int +main(int argc, char **argv) +{ + const PRUint16 *cipherSuites = SSL_ImplementedCiphers; + int i; + SECStatus rv; + SECMODModule *module = NULL; + char path[PATH_MAX]; + const char *filename; + char moduleSpec[1024 + PATH_MAX]; + unsigned num_enabled = 0; + int result = 0; + int fullPathLen; + + if (argc != 2) { + fprintf(stderr, "Syntax: nss-policy-check \n"); + result = 2; + goto loser_no_shutdown; + } + + fullPathLen = strlen(argv[1]); + + if (!fullPathLen || PR_Access(argv[1], PR_ACCESS_READ_OK) != PR_SUCCESS) { + fprintf(stderr, "Error: cannot read file %s\n", argv[1]); + result = 2; + goto loser_no_shutdown; + } + + if (fullPathLen >= PATH_MAX) { + fprintf(stderr, "Error: filename parameter is too long\n"); + result = 2; + goto loser_no_shutdown; + } + + path[0] = 0; + filename = argv[1] + fullPathLen - 1; + while ((filename > argv[1]) && (*filename != NSSUTIL_PATH_SEPARATOR[0])) { + filename--; + } + + if (filename == argv[1]) { + PORT_Strcpy(path, "."); + } else { + filename++; /* Go past the path separator. */ + PORT_Strncat(path, argv[1], (filename - argv[1])); + } + + PR_SetEnv("NSS_IGNORE_SYSTEM_POLICY=1"); + rv = NSS_NoDB_Init(NULL); + if (rv != SECSuccess) { + fprintf(stderr, "NSS_Init failed: %s\n", PORT_ErrorToString(PR_GetError())); + result = 2; + goto loser_no_shutdown; + } + + PR_SetEnv("NSS_POLICY_LOADED=0"); + PR_SetEnv("NSS_POLICY_FAIL=0"); + PR_SetEnv("NSS_POLICY_WARN=0"); + + sprintf(moduleSpec, + "name=\"Policy File\" " + "parameters=\"configdir='sql:%s' " + "secmod='%s' " + "flags=readOnly,noCertDB,forceSecmodChoice,forceOpen\" " + "NSS=\"flags=internal,moduleDB,skipFirst,moduleDBOnly,critical,printPolicyFeedback\"", + path, filename); + + module = SECMOD_LoadModule(moduleSpec, NULL, PR_TRUE); + if (!module || !module->loaded || atoi(PR_GetEnvSecure("NSS_POLICY_LOADED")) != 1) { + fprintf(stderr, "Error: failed to load policy file\n"); + result = 2; + goto loser; + } + + rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); + if (rv != SECSuccess) { + fprintf(stderr, "enable SSL_SECURITY failed: %s\n", PORT_ErrorToString(PR_GetError())); + result = 2; + goto loser; + } + + for (i = 0; i < SSL_NumImplementedCiphers; i++) { + PRUint16 suite = cipherSuites[i]; + PRBool enabled; + SSLCipherSuiteInfo info; + + rv = SSL_CipherPrefGetDefault(suite, &enabled); + if (rv != SECSuccess) { + fprintf(stderr, + "SSL_CipherPrefGetDefault didn't like value 0x%04x (i = %d): %s\n", + suite, i, PORT_ErrorToString(PR_GetError())); + continue; + } + rv = SSL_GetCipherSuiteInfo(suite, &info, (int)(sizeof info)); + if (rv != SECSuccess) { + fprintf(stderr, + "SSL_GetCipherSuiteInfo didn't like value 0x%04x (i = %d): %s\n", + suite, i, PORT_ErrorToString(PR_GetError())); + continue; + } + if (enabled) { + ++num_enabled; + fprintf(stderr, "NSS-POLICY-INFO: ciphersuite %s is enabled\n", info.cipherSuiteName); + } + } + fprintf(stderr, "NSS-POLICY-%s: NUMBER-OF-CIPHERSUITES: %u\n", num_enabled ? sInfo : sWarn, num_enabled); + if (!num_enabled) { + PR_SetEnv("NSS_POLICY_WARN=1"); + } + + get_tls_info(ssl_variant_stream, "TLS"); + get_tls_info(ssl_variant_datagram, "DTLS"); + + if (atoi(PR_GetEnvSecure("NSS_POLICY_FAIL")) != 0) { + result = 2; + } else if (atoi(PR_GetEnvSecure("NSS_POLICY_WARN")) != 0) { + result = 1; + } + +loser: + if (module) { + SECMOD_DestroyModule(module); + } + rv = NSS_Shutdown(); + if (rv != SECSuccess) { + fprintf(stderr, "NSS_Shutdown failed: %s\n", PORT_ErrorToString(PR_GetError())); + result = 2; + } +loser_no_shutdown: + if (result == 2) { + fprintf(stderr, "NSS-POLICY-FAIL\n"); + } else if (result == 1) { + fprintf(stderr, "NSS-POLICY-WARN\n"); + } + return result; +} diff --git a/security/nss/cmd/nss-policy-check/nss-policy-check.gyp b/security/nss/cmd/nss-policy-check/nss-policy-check.gyp new file mode 100644 index 000000000..877a5bc06 --- /dev/null +++ b/security/nss/cmd/nss-policy-check/nss-policy-check.gyp @@ -0,0 +1,24 @@ +# 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': 'nss-policy-check', + 'type': 'executable', + 'sources': [ + 'nss-policy-check.c' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports' + ] + } + ], + 'variables': { + 'module': 'nss' + } +} \ No newline at end of file diff --git a/security/nss/cmd/ocspclnt/ocspclnt.c b/security/nss/cmd/ocspclnt/ocspclnt.c index 0927f8ef6..359dbc217 100644 --- a/security/nss/cmd/ocspclnt/ocspclnt.c +++ b/security/nss/cmd/ocspclnt/ocspclnt.c @@ -133,6 +133,8 @@ long_usage(char *progname) "%-17s c SSL Client\n", ""); PR_fprintf(pr_stderr, "%-17s s SSL Server\n", ""); + PR_fprintf(pr_stderr, + "%-17s I IPsec\n", ""); PR_fprintf(pr_stderr, "%-17s e Email Recipient\n", ""); PR_fprintf(pr_stderr, @@ -908,6 +910,9 @@ cert_usage_from_char(const char *cert_usage_str, SECCertUsage *cert_usage) case 's': *cert_usage = certUsageSSLServer; break; + case 'I': + *cert_usage = certUsageIPsec; + break; case 'e': *cert_usage = certUsageEmailRecipient; break; diff --git a/security/nss/cmd/p7verify/p7verify.c b/security/nss/cmd/p7verify/p7verify.c index ba38e1158..5cbb4dcae 100644 --- a/security/nss/cmd/p7verify/p7verify.c +++ b/security/nss/cmd/p7verify/p7verify.c @@ -117,6 +117,7 @@ Usage(char *progName) fprintf(stderr, "%-25s 9 - certUsageProtectedObjectSigner\n", " "); fprintf(stderr, "%-25s 10 - certUsageStatusResponder\n", " "); fprintf(stderr, "%-25s 11 - certUsageAnyCA\n", " "); + fprintf(stderr, "%-25s 12 - certUsageIPsec\n", " "); exit(-1); } diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c index 7762a465b..292b40b0f 100644 --- a/security/nss/cmd/rsaperf/rsaperf.c +++ b/security/nss/cmd/rsaperf/rsaperf.c @@ -21,8 +21,8 @@ #define DEFAULT_THREADS 1 #define DEFAULT_EXPONENT 0x10001 -extern NSSLOWKEYPrivateKey *getDefaultRSAPrivateKey(void); -extern NSSLOWKEYPublicKey *getDefaultRSAPublicKey(void); +extern NSSLOWKEYPrivateKey *getDefaultRSAPrivateKey(int); +extern NSSLOWKEYPublicKey *getDefaultRSAPublicKey(int); secuPWData pwData = { PW_NONE, NULL }; @@ -580,9 +580,9 @@ main(int argc, char **argv) /* use a hardcoded key */ printf("Using hardcoded %ld bits key.\n", keybits); if (doPub) { - pubKey = getDefaultRSAPublicKey(); + pubKey = getDefaultRSAPublicKey(keybits); } else { - privKey = getDefaultRSAPrivateKey(); + privKey = getDefaultRSAPrivateKey(keybits); } } diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index c372ec9b8..1784c9ee3 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -165,9 +165,8 @@ PrintUsageHeader(const char *progName) " [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n" " [-V [min-version]:[max-version]] [-a sni_name]\n" " [ T ] [-A ca]\n" - " [-C SSLCacheEntries] [-S dsa_nickname] -Q [-I groups]" - " [-e ec_nickname]" - "\n" + " [-C SSLCacheEntries] [-S dsa_nickname] [-Q]\n" + " [-I groups] [-J signatureschemes] [-e ec_nickname]\n" " -U [0|1] -H [0|1|2] -W [0|1]\n" "\n", progName); @@ -179,7 +178,7 @@ PrintParameterUsage() fputs( "-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n" " All versions are enabled by default.\n" - " Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n" + " Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2 tls1.3\n" " Example: \"-V ssl3:\" enables SSL 3 and newer.\n" "-D means disable Nagle delays in TCP\n" "-R means disable detection of rollback from TLS to SSL3\n" @@ -195,7 +194,6 @@ PrintParameterUsage() "-s means disable SSL socket locking for performance\n" "-u means enable Session Ticket extension for TLS.\n" "-v means verbose output\n" - "-z means enable compression.\n" "-L seconds means log statistics every 'seconds' seconds (default=30).\n" "-M maxProcs tells how many processes to run in a multi-process server\n" "-N means do NOT use the server session cache. Incompatible with -M.\n" @@ -228,6 +226,13 @@ PrintParameterUsage() "-I comma separated list of enabled groups for TLS key exchange.\n" " The following values are valid:\n" " P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n" + "-J comma separated list of enabled signature schemes in preference order.\n" + " The following values are valid:\n" + " rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n" + " ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n" + " ecdsa_secp521r1_sha512,\n" + " rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n" + " rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n" "-Z enable 0-RTT (for TLS 1.3; also use -u)\n", stderr); } @@ -795,13 +800,14 @@ PRBool NoReuse = PR_FALSE; PRBool hasSidCache = PR_FALSE; PRBool disableLocking = PR_FALSE; PRBool enableSessionTickets = PR_FALSE; -PRBool enableCompression = PR_FALSE; PRBool failedToNegotiateName = PR_FALSE; PRBool enableExtendedMasterSecret = PR_FALSE; PRBool zeroRTT = PR_FALSE; PRBool enableALPN = PR_FALSE; SSLNamedGroup *enabledGroups = NULL; unsigned int enabledGroupsCount = 0; +const SSLSignatureScheme *enabledSigSchemes = NULL; +unsigned int enabledSigSchemeCount = 0; static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX]; static int virtServerNameIndex = 1; @@ -1857,13 +1863,6 @@ server_main( } } - if (enableCompression) { - rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE); - if (rv != SECSuccess) { - errExit("error enabling compression "); - } - } - if (virtServerNameIndex > 1) { rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig, (void *)&virtServerNameArray); @@ -1970,6 +1969,13 @@ server_main( } } + if (enabledSigSchemes) { + rv = SSL_SignatureSchemePrefSet(model_sock, enabledSigSchemes, enabledSigSchemeCount); + if (rv < 0) { + errExit("SSL_SignatureSchemePrefSet failed"); + } + } + /* This cipher is not on by default. The Acceptance test * would like it to be. Turn this cipher on. */ @@ -2214,9 +2220,10 @@ main(int argc, char **argv) /* please keep this list of options in ASCII collating sequence. ** numbers, then capital letters, then lower case, alphabetical. ** XXX: 'B', 'E', 'q', and 'x' were used in the past but removed - ** in 3.28, please leave some time before resuing those. */ + ** in 3.28, please leave some time before resuing those. + ** 'z' was removed in 3.39. */ optstate = PL_CreateOptState(argc, argv, - "2:A:C:DGH:I:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:yz"); + "2:A:C:DGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { ++optionsFound; switch (optstate->option) { @@ -2429,10 +2436,6 @@ main(int argc, char **argv) debugCache = PR_TRUE; break; - case 'z': - enableCompression = PR_TRUE; - break; - case 'Z': zeroRTT = PR_TRUE; break; @@ -2451,6 +2454,16 @@ main(int argc, char **argv) } break; + case 'J': + rv = parseSigSchemeList(optstate->value, &enabledSigSchemes, &enabledSigSchemeCount); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad signature scheme specified.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + exit(5); + } + break; + default: case '?': fprintf(stderr, "Unrecognized or bad option specified.\n"); diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c index 7106521c1..9106d9955 100644 --- a/security/nss/cmd/smimetools/cmsutil.c +++ b/security/nss/cmd/smimetools/cmsutil.c @@ -115,6 +115,7 @@ Usage(void) fprintf(stderr, "%-25s 9 - certUsageProtectedObjectSigner\n", " "); fprintf(stderr, "%-25s 10 - certUsageStatusResponder\n", " "); fprintf(stderr, "%-25s 11 - certUsageAnyCA\n", " "); + fprintf(stderr, "%-25s 12 - certUsageIPsec\n", " "); exit(-1); } diff --git a/security/nss/cmd/tests/nonspr10.c b/security/nss/cmd/tests/nonspr10.c index 295484a1c..fc700407a 100644 --- a/security/nss/cmd/tests/nonspr10.c +++ b/security/nss/cmd/tests/nonspr10.c @@ -26,9 +26,7 @@ #include "cryptoht.h" #include "ecl-exp.h" #include "hasht.h" -#include "key.h" #include "keyhi.h" -#include "keyt.h" #include "keythi.h" #include "nss.h" #include "nssb64.h" diff --git a/security/nss/cmd/tstclnt/Makefile b/security/nss/cmd/tstclnt/Makefile index a27a3ce97..aae7b445c 100644 --- a/security/nss/cmd/tstclnt/Makefile +++ b/security/nss/cmd/tstclnt/Makefile @@ -1,5 +1,5 @@ #! gmake -# +# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 6f5a43146..520eeff64 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -28,6 +28,7 @@ #include "prio.h" #include "prnetdb.h" #include "nss.h" +#include "nssb64.h" #include "ocsp.h" #include "ssl.h" #include "sslproto.h" @@ -106,6 +107,45 @@ secuPWData pwdata = { PW_NONE, 0 }; SSLNamedGroup *enabledGroups = NULL; unsigned int enabledGroupsCount = 0; +const SSLSignatureScheme *enabledSigSchemes = NULL; +unsigned int enabledSigSchemeCount = 0; + +const char * +signatureSchemeName(SSLSignatureScheme scheme) +{ + switch (scheme) { +#define strcase(x) \ + case ssl_sig_##x: \ + return #x + strcase(none); + strcase(rsa_pkcs1_sha1); + strcase(rsa_pkcs1_sha256); + strcase(rsa_pkcs1_sha384); + strcase(rsa_pkcs1_sha512); + strcase(ecdsa_sha1); + strcase(ecdsa_secp256r1_sha256); + strcase(ecdsa_secp384r1_sha384); + strcase(ecdsa_secp521r1_sha512); + strcase(rsa_pss_rsae_sha256); + strcase(rsa_pss_rsae_sha384); + strcase(rsa_pss_rsae_sha512); + strcase(ed25519); + strcase(ed448); + strcase(rsa_pss_pss_sha256); + strcase(rsa_pss_pss_sha384); + strcase(rsa_pss_pss_sha512); + strcase(dsa_sha1); + strcase(dsa_sha256); + strcase(dsa_sha384); + strcase(dsa_sha512); +#undef strcase + case ssl_sig_rsa_pkcs1_sha1md5: + return "RSA PKCS#1 SHA1+MD5"; + default: + break; + } + return "Unknown Scheme"; +} void printSecurityInfo(PRFileDesc *fd) @@ -132,11 +172,13 @@ printSecurityInfo(PRFileDesc *fd) suite.macBits, suite.macAlgorithmName); FPRINTF(stderr, "tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" - " Compression: %s, Extended Master Secret: %s\n", + " Compression: %s, Extended Master Secret: %s\n" + " Signature Scheme: %s\n", channel.authKeyBits, suite.authAlgorithmName, channel.keaKeyBits, suite.keaTypeName, channel.compressionMethodName, - channel.extendedMasterSecretUsed ? "Yes" : "No"); + channel.extendedMasterSecretUsed ? "Yes" : "No", + signatureSchemeName(channel.signatureScheme)); } } cert = SSL_RevealCert(fd); @@ -178,11 +220,13 @@ PrintUsageHeader() { fprintf(stderr, "Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n" - "[-D | -d certdir] [-C] [-b | -R root-module] \n" - "[-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n" - "[-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] [-P {client,server}] [-Q]\n" + " [-D | -d certdir] [-C] [-b | -R root-module] \n" + " [-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]]\n" + " [-I groups] [-J signatureschemes]\n" + " [-A requestfile] [-L totalconnections] [-P {client,server}]\n" + " [-N encryptedSniKeys] [-Q]\n" "\n", progName); } @@ -225,7 +269,6 @@ PrintParameterUsage() fprintf(stderr, "%-20s Timeout for server ping (default: no timeout).\n", "-t seconds"); fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N"); fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u"); - fprintf(stderr, "%-20s Enable compression.\n", "-z"); fprintf(stderr, "%-20s Enable false start.\n", "-g"); fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T"); fprintf(stderr, "%-20s Enable the signed_certificate_timestamp extension.\n", "-U"); @@ -255,9 +298,19 @@ PrintParameterUsage() "%-20s The following values are valid:\n" "%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n", "-I", "", ""); + fprintf(stderr, "%-20s Comma separated list of signature schemes in preference order.\n" + "%-20s The following values are valid:\n" + "%-20s rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n" + "%-20s ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n" + "%-20s ecdsa_secp521r1_sha512,\n" + "%-20s rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n" + "%-20s rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n" + "%-20s dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n", + "-J", "", "", "", "", "", "", ""); 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"); + fprintf(stderr, "%-20s Encrypted SNI Keys\n", "-N"); } static void @@ -906,7 +959,6 @@ int multiplier = 0; SSLVersionRange enabledVersions; int disableLocking = 0; int enableSessionTickets = 0; -int enableCompression = 0; int enableFalseStart = 0; int enableCertStatus = 0; int enableSignedCertTimestamps = 0; @@ -936,6 +988,7 @@ PRBool stopAfterHandshake = PR_FALSE; PRBool requestToExit = PR_FALSE; char *versionString = NULL; PRBool handshakeComplete = PR_FALSE; +char *encryptedSNIKeys = NULL; static int writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb) @@ -1283,14 +1336,6 @@ run() goto done; } - /* enable compression. */ - rv = SSL_OptionSet(s, SSL_ENABLE_DEFLATE, enableCompression); - if (rv != SECSuccess) { - SECU_PrintError(progName, "error enabling compression"); - error = 1; - goto done; - } - /* enable false start. */ rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart); if (rv != SECSuccess) { @@ -1374,6 +1419,35 @@ run() } } + if (enabledSigSchemes) { + rv = SSL_SignatureSchemePrefSet(s, enabledSigSchemes, enabledSigSchemeCount); + if (rv < 0) { + SECU_PrintError(progName, "SSL_SignatureSchemePrefSet failed"); + error = 1; + goto done; + } + } + + if (encryptedSNIKeys) { + SECItem esniKeysBin = { siBuffer, NULL, 0 }; + + if (!NSSBase64_DecodeBuffer(NULL, &esniKeysBin, encryptedSNIKeys, + strlen(encryptedSNIKeys))) { + SECU_PrintError(progName, "ESNIKeys record is invalid base64"); + error = 1; + goto done; + } + + rv = SSL_EnableESNI(s, esniKeysBin.data, esniKeysBin.len, + "dummy.invalid"); + SECITEM_FreeItem(&esniKeysBin, PR_FALSE); + if (rv < 0) { + SECU_PrintError(progName, "SSL_EnableESNI failed"); + error = 1; + goto done; + } + } + serverCertAuth.dbHandle = CERT_GetDefaultCertDB(); SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth); @@ -1628,10 +1702,12 @@ main(int argc, char **argv) } } - /* XXX: 'B' was used in the past but removed in 3.28, - * please leave some time before resuing it. */ + /* Note: 'B' was used in the past but removed in 3.28 + * 'z' was removed in 3.39 + * Please leave some time before reusing these. + */ optstate = PL_CreateOptState(argc, argv, - "46A:CDFGHI:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z"); + "46A:CDFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -1708,6 +1784,10 @@ main(int argc, char **argv) }; break; + case 'N': + encryptedSNIKeys = PORT_Strdup(optstate->value); + break; + case 'P': useDTLS = PR_TRUE; if (!strcmp(optstate->value, "server")) { @@ -1850,10 +1930,6 @@ main(int argc, char **argv) pwdata.data = PORT_Strdup(optstate->value); break; - case 'z': - enableCompression = 1; - break; - case 'I': rv = parseGroupList(optstate->value, &enabledGroups, &enabledGroupsCount); if (rv != SECSuccess) { @@ -1862,6 +1938,15 @@ main(int argc, char **argv) Usage(); } break; + + case 'J': + rv = parseSigSchemeList(optstate->value, &enabledSigSchemes, &enabledSigSchemeCount); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad signature scheme specified.\n"); + Usage(); + } + break; } } PL_DestroyOptState(optstate); @@ -2051,6 +2136,7 @@ done: PORT_Free(pwdata.data); PORT_Free(host); PORT_Free(zeroRttData); + PORT_Free(encryptedSNIKeys); if (enabledGroups) { PORT_Free(enabledGroups); diff --git a/security/nss/cmd/vfychain/vfychain.c b/security/nss/cmd/vfychain/vfychain.c index d42274c12..c01cdd08e 100644 --- a/security/nss/cmd/vfychain/vfychain.c +++ b/security/nss/cmd/vfychain/vfychain.c @@ -64,7 +64,8 @@ Usage(const char *progName) "\t-t\t\t Following cert is explicitly trusted (overrides db trust).\n" "\t-u usage \t 0=SSL client, 1=SSL server, 2=SSL StepUp, 3=SSL CA,\n" "\t\t\t 4=Email signer, 5=Email recipient, 6=Object signer,\n" - "\t\t\t 9=ProtectedObjectSigner, 10=OCSP responder, 11=Any CA\n" + "\t\t\t 9=ProtectedObjectSigner, 10=OCSP responder, 11=Any CA,\n" + "\t\t\t 12=IPsec\n" "\t-T\t\t Trust both explicit trust anchors (-t) and the database.\n" "\t\t\t (Default is to only trust certificates marked -t, if there are any,\n" "\t\t\t or to trust the database if there are certificates marked -t.)\n" diff --git a/security/nss/cmd/vfyserv/vfyserv.h b/security/nss/cmd/vfyserv/vfyserv.h index 00afc8049..5bcc51a50 100644 --- a/security/nss/cmd/vfyserv/vfyserv.h +++ b/security/nss/cmd/vfyserv/vfyserv.h @@ -24,7 +24,7 @@ #include "certt.h" #include "nss.h" #include "secder.h" -#include "key.h" +#include "keyhi.h" #include "sslproto.h" /* Custom header files */ -- cgit v1.2.3