diff options
Diffstat (limited to 'security/nss/cmd')
47 files changed, 2198 insertions, 516 deletions
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c index ca3d6f314..ef8fdd802 100644 --- a/security/nss/cmd/bltest/blapitest.c +++ b/security/nss/cmd/bltest/blapitest.c @@ -3724,7 +3724,7 @@ main(int argc, char **argv) /* test the RSA_PopulatePrivateKey function */ if (bltest.commands[cmd_RSAPopulate].activated) { unsigned int keySize = 1024; - unsigned long exponent = 65537; + unsigned long keyExponent = 65537; int rounds = 1; int ret = -1; @@ -3735,12 +3735,12 @@ main(int argc, char **argv) rounds = PORT_Atoi(bltest.options[opt_Rounds].arg); } if (bltest.options[opt_Exponent].activated) { - exponent = PORT_Atoi(bltest.options[opt_Exponent].arg); + keyExponent = PORT_Atoi(bltest.options[opt_Exponent].arg); } for (i = 0; i < rounds; i++) { printf("Running RSA Populate test round %d\n", i); - ret = doRSAPopulateTest(keySize, exponent); + ret = doRSAPopulateTest(keySize, keyExponent); if (ret != 0) { break; } diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index 20722ae78..df02e4439 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -36,9 +36,11 @@ #include "certdb.h" #include "nss.h" #include "certutil.h" +#include "basicutil.h" +#include "ssl.h" #define MIN_KEY_BITS 512 -/* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */ +/* MAX_KEY_BITS should agree with RSA_MAX_MODULUS_BITS in freebl */ #define MAX_KEY_BITS 8192 #define DEFAULT_KEY_BITS 2048 @@ -447,7 +449,8 @@ ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot, } static SECStatus -DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii) +DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii, + PRBool simpleSelfSigned) { CERTCertificate *the_cert; CERTCertificateList *chain; @@ -458,6 +461,14 @@ DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii) SECU_PrintError(progName, "Could not find: %s\n", name); return SECFailure; } + if (simpleSelfSigned && + SECEqual == SECITEM_CompareItem(&the_cert->derIssuer, + &the_cert->derSubject)) { + printf("\"%s\" [%s]\n\n", the_cert->nickname, the_cert->subjectName); + CERT_DestroyCertificate(the_cert); + return SECSuccess; + } + chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE); CERT_DestroyCertificate(the_cert); if (!chain) { @@ -730,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; @@ -782,17 +796,17 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date, fprintf(stdout, "%s: certificate is valid\n", progName); GEN_BREAK(SECSuccess) } else { - char *name; + char *nick; CERTVerifyLogNode *node; node = log->head; while (node) { if (node->cert->nickname != NULL) { - name = node->cert->nickname; + nick = node->cert->nickname; } else { - name = node->cert->subjectName; + nick = node->cert->subjectName; } - fprintf(stderr, "%s : %s\n", name, + fprintf(stderr, "%s : %s\n", nick, SECU_Strerror(node->error)); CERT_DestroyCertificate(node->cert); node = node->next; @@ -845,41 +859,59 @@ SECItemToHex(const SECItem *item, char *dst) } static const char *const keyTypeName[] = { - "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec" + "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; } @@ -991,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; @@ -999,7 +1031,7 @@ DeleteKey(char *nickname, secuPWData *pwdata) slot = PK11_GetInternalKeySlot(); if (PK11_NeedLogin(slot)) { - SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwdata); + rv = PK11_Authenticate(slot, PR_TRUE, pwdata); if (rv != SECSuccess) { SECU_PrintError(progName, "could not authenticate to token %s.", PK11_GetTokenName(slot)); @@ -1020,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 * @@ -1066,7 +1153,7 @@ PrintBuildFlags() } static void -PrintSyntax(char *progName) +PrintSyntax() { #define FPS fprintf(stderr, FPS "Type %s -H for more detailed descriptions\n", progName); @@ -1089,7 +1176,9 @@ PrintSyntax(char *progName) "\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); @@ -1115,7 +1204,9 @@ PrintSyntax(char *progName) 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); + FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n" + "\t\t [--simple-self-signed]\n", + progName); FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n" "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n" "\t\t [-g key-size] [-Z hashAlg]\n", @@ -1377,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", @@ -1542,6 +1635,8 @@ luO(enum usage_level ul, const char *command) " -P dbprefix"); FPS "%-20s force the database to open R/W\n", " -X"); + FPS "%-20s don't search for a chain if issuer name equals subject name\n", + " --simple-self-signed"); FPS "\n"); } @@ -1560,7 +1655,7 @@ luR(enum usage_level ul, const char *command) " -o output-req"); FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", " -k key-type-or-id"); - FPS "%-20s or nickname of the cert key to use \n", + FPS "%-20s or nickname of the cert key to use, or key id obtained using -K\n", ""); FPS "%-20s Name of token in which to generate key (default is internal)\n", " -h token-name"); @@ -1614,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", ""); @@ -1838,7 +1934,7 @@ luBuildFlags(enum usage_level ul, const char *command) } static void -LongUsage(char *progName, enum usage_level ul, const char *command) +LongUsage(enum usage_level ul, const char *command) { luA(ul, command); luB(ul, command); @@ -1866,14 +1962,14 @@ LongUsage(char *progName, enum usage_level ul, const char *command) } static void -Usage(char *progName) +Usage() { PR_fprintf(PR_STDERR, "%s - Utility to manipulate NSS certificate databases\n\n" "Usage: %s <command> -d <database-directory> <options>\n\n" "Valid commands:\n", progName, progName); - LongUsage(progName, usage_selected, NULL); + LongUsage(usage_selected, NULL); PR_fprintf(PR_STDERR, "\n" "%s -H <command> : Print available options for the given command\n" "%s -H : Print complete help output of all commands and options\n" @@ -2269,10 +2365,10 @@ flagArray opFlagsArray[] = { NAME_SIZE(verify_recover), CKF_VERIFY_RECOVER }, { NAME_SIZE(wrap), CKF_WRAP }, { NAME_SIZE(unwrap), CKF_UNWRAP }, - { NAME_SIZE(derive), CKF_DERIVE }, + { NAME_SIZE(derive), CKF_DERIVE } }; -int opFlagsCount = sizeof(opFlagsArray) / sizeof(flagArray); +int opFlagsCount = PR_ARRAY_SIZE(opFlagsArray); flagArray attrFlagsArray[] = { @@ -2286,14 +2382,13 @@ flagArray attrFlagsArray[] = { NAME_SIZE(insensitive), PK11_ATTR_INSENSITIVE }, { NAME_SIZE(extractable), PK11_ATTR_EXTRACTABLE }, { NAME_SIZE(unextractable), PK11_ATTR_UNEXTRACTABLE } - }; -int attrFlagsCount = sizeof(attrFlagsArray) / sizeof(flagArray); +int attrFlagsCount = PR_ARRAY_SIZE(attrFlagsArray); #define MAX_STRING 30 CK_ULONG -GetFlags(char *flagsString, flagArray *flagArray, int count) +GetFlags(char *flagsString, flagArray *flags, int count) { CK_ULONG flagsValue = strtol(flagsString, NULL, 0); int i; @@ -2303,10 +2398,10 @@ GetFlags(char *flagsString, flagArray *flagArray, int count) } while (*flagsString) { for (i = 0; i < count; i++) { - if (strncmp(flagsString, flagArray[i].name, flagArray[i].nameSize) == + if (strncmp(flagsString, flags[i].name, flags[i].nameSize) == 0) { - flagsValue |= flagArray[i].value; - flagsString += flagArray[i].nameSize; + flagsValue |= flags[i].value; + flagsString += flags[i].nameSize; if (*flagsString != 0) { flagsString++; } @@ -2499,6 +2594,7 @@ enum certutilOpts { opt_NewNickname, opt_Pss, opt_PssSign, + opt_SimpleSelfSigned, opt_Help }; @@ -2623,6 +2719,8 @@ static const secuCommandFlag options_init[] = "pss" }, { /* opt_PssSign */ 0, PR_FALSE, 0, PR_FALSE, "pss-sign" }, + { /* opt_SimpleSelfSigned */ 0, PR_FALSE, 0, PR_FALSE, + "simple-self-signed" }, }; #define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0])) @@ -2691,14 +2789,13 @@ certutil_main(int argc, char **argv, PRBool initialize) rv = SECU_ParseCommandLine(argc, argv, progName, &certutil); if (rv != SECSuccess) - Usage(progName); + Usage(); if (certutil.commands[cmd_PrintSyntax].activated) { - PrintSyntax(progName); + PrintSyntax(); } if (certutil.commands[cmd_PrintHelp].activated) { - int i; char buf[2]; const char *command = NULL; for (i = 0; i < max_cmd; i++) { @@ -2715,7 +2812,7 @@ certutil_main(int argc, char **argv, PRBool initialize) break; } } - LongUsage(progName, (command ? usage_selected : usage_all), command); + LongUsage((command ? usage_selected : usage_all), command); exit(1); } @@ -2823,7 +2920,7 @@ certutil_main(int argc, char **argv, PRBool initialize) if (certutil.options[opt_DBPrefix].arg) { certPrefix = certutil.options[opt_DBPrefix].arg; } else { - Usage(progName); + Usage(); } } @@ -2832,7 +2929,7 @@ certutil_main(int argc, char **argv, PRBool initialize) if (certutil.options[opt_SourcePrefix].arg) { srcCertPrefix = certutil.options[opt_SourcePrefix].arg; } else { - Usage(progName); + Usage(); } } @@ -2916,7 +3013,7 @@ certutil_main(int argc, char **argv, PRBool initialize) return 255; } if (commandsEntered == 0) { - Usage(progName); + Usage(); } if (certutil.commands[cmd_ListCerts].activated || @@ -2928,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 || @@ -3018,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 && @@ -3124,6 +3230,8 @@ certutil_main(int argc, char **argv, PRBool initialize) } initialized = PR_TRUE; SECU_RegisterDynamicOids(); + /* Ensure the SSL error code table has been registered. Bug 1460284. */ + SSL_OptionSetDefault(-1, 0); } certHandle = CERT_GetDefaultCertDB(); @@ -3350,7 +3458,8 @@ certutil_main(int argc, char **argv, PRBool initialize) } if (certutil.commands[cmd_DumpChain].activated) { rv = DumpChain(certHandle, name, - certutil.options[opt_ASCIIForIO].activated); + certutil.options[opt_ASCIIForIO].activated, + certutil.options[opt_SimpleSelfSigned].activated); goto shutdown; } /* XXX needs work */ @@ -3377,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) */ @@ -3444,37 +3565,58 @@ certutil_main(int argc, char **argv, PRBool initialize) keycert = CERT_FindCertByNicknameOrEmailAddr(certHandle, keysource); if (!keycert) { keycert = PK11_FindCertFromNickname(keysource, NULL); - if (!keycert) { - SECU_PrintError(progName, - "%s is neither a key-type nor a nickname", keysource); - return SECFailure; - } } - privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata); - if (privkey) - pubkey = CERT_ExtractPublicKey(keycert); + + if (keycert) { + privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata); + } else { + /* Interpret keysource as CKA_ID */ + privkey = findPrivateKeyByID(slot, keysource, &pwdata); + } + + if (!privkey) { + SECU_PrintError( + progName, + "%s is neither a key-type nor a nickname nor a key-id", keysource); + return SECFailure; + } + + pubkey = SECKEY_ConvertToPublicKey(privkey); if (!pubkey) { SECU_PrintError(progName, "Could not get keys from cert %s", keysource); + if (keycert) { + CERT_DestroyCertificate(keycert); + } rv = SECFailure; - CERT_DestroyCertificate(keycert); goto shutdown; } keytype = privkey->keyType; + /* On CertReq for renewal if no subject has been * specified obtain it from the certificate. */ if (certutil.commands[cmd_CertReq].activated && !subject) { - subject = CERT_AsciiToName(keycert->subjectName); - if (!subject) { - SECU_PrintError(progName, - "Could not get subject from certificate %s", keysource); - CERT_DestroyCertificate(keycert); + if (keycert) { + subject = CERT_AsciiToName(keycert->subjectName); + if (!subject) { + SECU_PrintError( + progName, + "Could not get subject from certificate %s", + keysource); + CERT_DestroyCertificate(keycert); + rv = SECFailure; + goto shutdown; + } + } else { + SECU_PrintError(progName, "Subject name not provided"); rv = SECFailure; goto shutdown; } } - CERT_DestroyCertificate(keycert); + if (keycert) { + CERT_DestroyCertificate(keycert); + } } else { privkey = CERTUTIL_GeneratePrivateKey(keytype, slot, keysize, @@ -3537,6 +3679,14 @@ certutil_main(int argc, char **argv, PRBool initialize) } } + if (certutil.options[opt_SimpleSelfSigned].activated && + !certutil.commands[cmd_DumpChain].activated) { + PR_fprintf(PR_STDERR, + "%s -%c: --simple-self-signed only works with -O.\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 || diff --git a/security/nss/cmd/crlutil/crlutil.c b/security/nss/cmd/crlutil/crlutil.c index c008ecc01..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; @@ -770,7 +756,7 @@ loser: } static void -Usage(char *progName) +Usage() { fprintf(stderr, "Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n" @@ -908,7 +894,7 @@ main(int argc, char **argv) while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': - Usage(progName); + Usage(); break; case 'T': @@ -1038,17 +1024,17 @@ main(int argc, char **argv) } if (deleteCRL && !nickName) - Usage(progName); + Usage(); if (importCRL && !inFile) - Usage(progName); + Usage(); if (showFileCRL && !inFile) - Usage(progName); + Usage(); if ((generateCRL && !nickName) || (modifyCRL && !inFile && !nickName)) - Usage(progName); + Usage(); if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL || modifyCRL || test || erase)) - Usage(progName); + Usage(); if (listCRL || showFileCRL) { readonly = PR_TRUE; 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 cbc680b08..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" @@ -577,7 +577,6 @@ Decode(void) printf("WARNING: The DER contained %d messages.\n", numMsgs); } for (i = 0; i < numMsgs; i++) { - SECStatus rv; printf("crmftest: Processing cert request %d\n", i); certReqMsg = CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqMsgs, i); if (certReqMsg == NULL) { 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/dbtest/dbtest.c b/security/nss/cmd/dbtest/dbtest.c index 9a6a034a6..11713c23f 100644 --- a/security/nss/cmd/dbtest/dbtest.c +++ b/security/nss/cmd/dbtest/dbtest.c @@ -58,7 +58,7 @@ getPassword(PK11SlotInfo *slot, PRBool retry, void *arg) } static void -Usage(const char *progName) +Usage() { printf("Usage: %s [-r] [-f] [-i] [-d dbdir ] \n", progName); @@ -96,7 +96,7 @@ main(int argc, char **argv) switch (optstate->option) { case 'h': default: - Usage(progName); + Usage(); break; case 'r': @@ -122,7 +122,7 @@ main(int argc, char **argv) } PL_DestroyOptState(optstate); if (optstatus == PL_OPT_BAD) - Usage(progName); + Usage(); if (dbDir) { char *tmp = dbDir; @@ -181,7 +181,6 @@ main(int argc, char **argv) ret = SUCCESS; if (doInitTest) { PK11SlotInfo *slot = PK11_GetInternalKeySlot(); - SECStatus rv; int passwordSuccess = 0; int type = CKM_DES3_CBC; SECItem keyid = { 0, NULL, 0 }; 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]=<test name>.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]=<test name>.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/httpserv/httpserv.c b/security/nss/cmd/httpserv/httpserv.c index 7cf28c65a..71e2ab88d 100644 --- a/security/nss/cmd/httpserv/httpserv.c +++ b/security/nss/cmd/httpserv/httpserv.c @@ -682,6 +682,7 @@ handle_connection( } if (arena) { PORT_FreeArena(arena, PR_FALSE); + arena = NULL; } if (!request || !request->tbsRequest || !request->tbsRequest->requestList || @@ -753,11 +754,11 @@ handle_connection( { PRTime now = PR_Now(); - PLArenaPool *arena = NULL; CERTOCSPSingleResponse *sr; CERTOCSPSingleResponse **singleResponses; SECItem *ocspResponse; + PORT_Assert(!arena); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (unknown) { @@ -787,8 +788,8 @@ handle_connection( } else { PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader)); PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len); - PORT_FreeArena(arena, PR_FALSE); } + PORT_FreeArena(arena, PR_FALSE); } CERT_DestroyOCSPRequest(request); break; @@ -1357,7 +1358,6 @@ main(int argc, char **argv) caRevoIter = &caRevoInfos->link; do { PRFileDesc *inFile; - int rv = SECFailure; SECItem crlDER; crlDER.data = NULL; @@ -1413,11 +1413,9 @@ main(int argc, char **argv) if (provideOcsp) { if (caRevoInfos) { - PRCList *caRevoIter; - caRevoIter = &caRevoInfos->link; do { - caRevoInfo *revoInfo = (caRevoInfo *)caRevoIter; + revoInfo = (caRevoInfo *)caRevoIter; if (revoInfo->nickname) PORT_Free(revoInfo->nickname); if (revoInfo->crlFilename) diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index 2b33f8963..97c7f750a 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -1528,9 +1528,9 @@ SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m, unsigned int i; for (i = 0; i < c->serialNumber.len; ++i) { unsigned char *chardata = (unsigned char *)(c->serialNumber.data); - unsigned char c = *(chardata + i); + unsigned char ch = *(chardata + i); - fprintf(out, "\\x%02x", c); + fprintf(out, "\\x%02x", ch); } fprintf(out, "\" }\n"); } @@ -3137,7 +3137,7 @@ typedef enum { static int secu_PrintSignedDataSigOpt(FILE *out, SECItem *der, const char *m, int level, SECU_PPFunc inner, - SignatureOptionType withSignature) + SignatureOptionType signatureOption) { PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); CERTSignedData *sd; @@ -3164,7 +3164,7 @@ secu_PrintSignedDataSigOpt(FILE *out, SECItem *der, const char *m, } rv = (*inner)(out, &sd->data, "Data", level + 1); - if (withSignature) { + if (signatureOption == withSignature) { SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm", level + 1); DER_ConvertBitString(&sd->signature); @@ -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/listsuites/listsuites.c b/security/nss/cmd/listsuites/listsuites.c index 8eb2c3553..b49f2d8cf 100644 --- a/security/nss/cmd/listsuites/listsuites.c +++ b/security/nss/cmd/listsuites/listsuites.c @@ -64,9 +64,7 @@ main(int argc, char **argv) /* disable all the SSL3 cipher suites */ for (i = 0; i < SSL_NumImplementedCiphers; i++) { PRUint16 suite = cipherSuites[i]; - SECStatus rv; PRBool enabled; - PRErrorCode err; SSLCipherSuiteInfo info; rv = SSL_CipherPrefGetDefault(suite, &enabled); diff --git a/security/nss/cmd/lowhashtest/lowhashtest.c b/security/nss/cmd/lowhashtest/lowhashtest.c index 29d6ff4fd..fcc06a86e 100644 --- a/security/nss/cmd/lowhashtest/lowhashtest.c +++ b/security/nss/cmd/lowhashtest/lowhashtest.c @@ -390,7 +390,7 @@ testSHA512(NSSLOWInitContext *initCtx) } static void -Usage(char *progName) +Usage() { fprintf(stderr, "Usage: %s [algorithm]\n", progName); @@ -436,7 +436,7 @@ main(int argc, char **argv) rv += testSHA512(initCtx); } else { SECU_PrintError(progName, "Unsupported hash type %s\n", argv[0]); - Usage(progName); + Usage(); } NSSLOW_Shutdown(initCtx); 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/install-ds.c b/security/nss/cmd/modutil/install-ds.c index 030568762..576839f8f 100644 --- a/security/nss/cmd/modutil/install-ds.c +++ b/security/nss/cmd/modutil/install-ds.c @@ -88,11 +88,11 @@ static const char* errString[] = { static char* PR_Strdup(const char* str); -#define PAD(x) \ - { \ - int i; \ - for (i = 0; i < x; i++) \ - printf(" "); \ +#define PAD(x) \ + { \ + int pad_i; \ + for (pad_i = 0; pad_i < (x); pad_i++) \ + printf(" "); \ } #define PADINC 4 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 <enter>' to abort, or <enter> 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 <enter>' to abort, or <enter> 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/mpitests/mpi-test.c b/security/nss/cmd/mpitests/mpi-test.c index 3a1f5d6c2..b7953b6f6 100644 --- a/security/nss/cmd/mpitests/mpi-test.c +++ b/security/nss/cmd/mpitests/mpi-test.c @@ -375,14 +375,14 @@ void reason(char *fmt, ...); char g_intbuf[4096]; /* buffer for integer comparison */ char a_intbuf[4096]; /* buffer for integer comparison */ int g_verbose = 1; /* print out reasons for failure? */ -int res; - -#define IFOK(x) \ - { \ - if (MP_OKAY > (res = (x))) { \ - reason("test %s failed: error %d\n", #x, res); \ - return 1; \ - } \ + +#define IFOK(x) \ + { \ + int ifok_res = (x); \ + if (MP_OKAY > ifok_res) { \ + reason("test %s failed: error %d\n", #x, ifok_res); \ + return 1; \ + } \ } int 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 <limits.h> +#include <errno.h> +#include <stdio.h> +#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 <path-to-policy-file>\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 afcb7e13f..359dbc217 100644 --- a/security/nss/cmd/ocspclnt/ocspclnt.c +++ b/security/nss/cmd/ocspclnt/ocspclnt.c @@ -38,7 +38,7 @@ char *program_name; static void -synopsis(char *program_name) +synopsis(char *progname) { PRFileDesc *pr_stderr; @@ -46,44 +46,44 @@ synopsis(char *program_name) PR_fprintf(pr_stderr, "Usage:"); PR_fprintf(pr_stderr, "\t%s -p [-d <dir>]\n", - program_name); + progname); PR_fprintf(pr_stderr, "\t%s -P [-d <dir>]\n", - program_name); + progname); PR_fprintf(pr_stderr, "\t%s -r <name> [-a] [-L] [-s <name>] [-d <dir>]\n", - program_name); + progname); PR_fprintf(pr_stderr, "\t%s -R <name> [-a] [-l <location>] [-s <name>] [-d <dir>]\n", - program_name); + progname); PR_fprintf(pr_stderr, "\t%s -S <name> [-a] [-l <location> -t <name>]\n", - program_name); + progname); PR_fprintf(pr_stderr, "\t\t [-s <name>] [-w <time>] [-d <dir>]\n"); PR_fprintf(pr_stderr, "\t%s -V <name> [-a] -u <usage> [-l <location> -t <name>]\n", - program_name); + progname); PR_fprintf(pr_stderr, "\t\t [-s <name>] [-w <time>] [-d <dir>]\n"); } static void -short_usage(char *program_name) +short_usage(char *progname) { PR_fprintf(PR_STDERR, "Type %s -H for more detailed descriptions\n", - program_name); - synopsis(program_name); + progname); + synopsis(progname); } static void -long_usage(char *program_name) +long_usage(char *progname) { PRFileDesc *pr_stderr; pr_stderr = PR_STDERR; - synopsis(program_name); + synopsis(progname); PR_fprintf(pr_stderr, "\nCommands (must specify exactly one):\n"); PR_fprintf(pr_stderr, " %-13s Pretty-print a binary request read from stdin\n", @@ -134,6 +134,8 @@ long_usage(char *program_name) 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, "%-17s E Email Signer\n", ""); @@ -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/ocspresp/ocspresp.c b/security/nss/cmd/ocspresp/ocspresp.c index 632623c97..d18d32e18 100644 --- a/security/nss/cmd/ocspresp/ocspresp.c +++ b/security/nss/cmd/ocspresp/ocspresp.c @@ -194,8 +194,8 @@ main(int argc, char **argv) &obtainedSignerCert, caCert)); #ifdef DEBUG { - SECStatus rv = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid, - obtainedSignerCert, now); + rv = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid, + obtainedSignerCert, now); PORT_Assert(rv == SECFailure); PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE); } @@ -211,7 +211,7 @@ main(int argc, char **argv) decodedFail = CERT_DecodeOCSPResponse(encodedFail); #ifdef DEBUG { - SECStatus rv = CERT_GetOCSPResponseStatus(decodedFail); + rv = CERT_GetOCSPResponseStatus(decodedFail); PORT_Assert(rv == SECFailure); PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER); } 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/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c index 70454a0d8..5884713e3 100644 --- a/security/nss/cmd/pk12util/pk12util.c +++ b/security/nss/cmd/pk12util/pk12util.c @@ -28,7 +28,7 @@ static PRBool pk12uForceUnicode; PRIntn pk12uErrno = 0; static void -Usage(char *progName) +Usage() { #define FPS PR_fprintf(PR_STDERR, FPS "Usage: %s -i importfile [-d certdir] [-P dbprefix] [-h tokenname]\n", @@ -1020,26 +1020,26 @@ main(int argc, char **argv) rv = SECU_ParseCommandLine(argc, argv, progName, &pk12util); if (rv != SECSuccess) - Usage(progName); + Usage(); pk12_debugging = pk12util.options[opt_Debug].activated; if ((pk12util.options[opt_Import].activated + pk12util.options[opt_Export].activated + pk12util.options[opt_List].activated) != 1) { - Usage(progName); + Usage(); } if (pk12util.options[opt_Export].activated && !pk12util.options[opt_Nickname].activated) { - Usage(progName); + Usage(); } 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); + Usage(); } pk12uForceUnicode = forceUnicode; @@ -1144,7 +1144,7 @@ main(int argc, char **argv) P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw); } else { - Usage(progName); + Usage(); pk12uErrno = PK12UERR_USAGE; } diff --git a/security/nss/cmd/pk1sign/pk1sign.c b/security/nss/cmd/pk1sign/pk1sign.c index 085aa1659..d5524c149 100644 --- a/security/nss/cmd/pk1sign/pk1sign.c +++ b/security/nss/cmd/pk1sign/pk1sign.c @@ -178,7 +178,7 @@ loser: SECKEY_DestroyPrivateKey(privKey); } if (data) { - PORT_Free(data); + PR_Free(data); } PORT_FreeArena(arena, PR_FALSE); diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c index 2bb23856e..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 }; @@ -313,7 +313,7 @@ main(int argc, char **argv) char *slotname = NULL; long keybits = 0; RSAOp fn; - void *rsaKey = NULL; + void *rsaKeyPtr = NULL; PLOptState *optstate; PLOptStatus optstatus; long iters = DEFAULT_ITERS; @@ -464,7 +464,7 @@ main(int argc, char **argv) if (doPub) { /* do public key ops */ fn = (RSAOp)PK11_PublicKeyOp; - rsaKey = (void *)pubHighKey; + rsaKeyPtr = (void *)pubHighKey; kh = PK11_ImportPublicKey(cert->slot, pubHighKey, PR_FALSE); if (CK_INVALID_HANDLE == kh) { @@ -489,7 +489,7 @@ main(int argc, char **argv) fn = (RSAOp)PK11_PrivateKeyOp; keys.privKey = privHighKey; keys.pubKey = pubHighKey; - rsaKey = (void *)&keys; + rsaKeyPtr = (void *)&keys; printf("Using PKCS#11 for RSA decryption with token %s.\n", PK11_GetTokenName(privHighKey->pkcs11Slot)); } @@ -537,13 +537,13 @@ main(int argc, char **argv) if (doPub) { /* do public key operations */ fn = (RSAOp)PK11_PublicKeyOp; - rsaKey = (void *)pubHighKey; + rsaKeyPtr = (void *)pubHighKey; } else { /* do private key operations */ fn = (RSAOp)PK11_PrivateKeyOp; keys.privKey = privHighKey; keys.pubKey = pubHighKey; - rsaKey = (void *)&keys; + rsaKeyPtr = (void *)&keys; } } else @@ -574,46 +574,46 @@ main(int argc, char **argv) pe.data = &pubEx[0]; pe.type = siBuffer; - rsaKey = RSA_NewKey(keybits, &pe); + rsaKeyPtr = RSA_NewKey(keybits, &pe); fprintf(stderr, "Keygen completed.\n"); } else { /* 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); } } if (doPub) { /* do public key operations */ fn = (RSAOp)RSA_PublicKeyOp; - if (rsaKey) { + if (rsaKeyPtr) { /* convert the RSAPrivateKey to RSAPublicKey */ pubKeyStr.arena = NULL; - pubKeyStr.modulus = ((RSAPrivateKey *)rsaKey)->modulus; + pubKeyStr.modulus = ((RSAPrivateKey *)rsaKeyPtr)->modulus; pubKeyStr.publicExponent = - ((RSAPrivateKey *)rsaKey)->publicExponent; - rsaKey = &pubKeyStr; + ((RSAPrivateKey *)rsaKeyPtr)->publicExponent; + rsaKeyPtr = &pubKeyStr; } else { /* convert NSSLOWKeyPublicKey to RSAPublicKey */ - rsaKey = (void *)(&pubKey->u.rsa); + rsaKeyPtr = (void *)(&pubKey->u.rsa); } - PORT_Assert(rsaKey); + PORT_Assert(rsaKeyPtr); } else { /* do private key operations */ fn = (RSAOp)RSA_PrivateKeyOp; if (privKey) { /* convert NSSLOWKeyPrivateKey to RSAPrivateKey */ - rsaKey = (void *)(&privKey->u.rsa); + rsaKeyPtr = (void *)(&privKey->u.rsa); } - PORT_Assert(rsaKey); + PORT_Assert(rsaKeyPtr); } } memset(buf, 1, sizeof buf); - rv = fn(rsaKey, buf2, buf); + rv = fn(rsaKeyPtr, buf2, buf); if (rv != SECSuccess) { PRErrorCode errNum; const char *errStr = NULL; @@ -638,7 +638,7 @@ main(int argc, char **argv) runDataArr[i]->fn = fn; runDataArr[i]->buf = buf; runDataArr[i]->doIters = &doIters; - runDataArr[i]->rsaKey = rsaKey; + runDataArr[i]->rsaKey = rsaKeyPtr; runDataArr[i]->seconds = seconds; runDataArr[i]->iters = iters; threadsArr[i] = diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index fac428e10..1784c9ee3 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -57,7 +57,7 @@ int NumSidCacheEntries = 1024; -static int handle_connection(PRFileDesc *, PRFileDesc *, int); +static int handle_connection(PRFileDesc *, PRFileDesc *); static const char envVarName[] = { SSL_ENV_VAR_NAME }; static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" }; @@ -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 <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-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); } @@ -509,7 +514,6 @@ typedef struct jobStr { PRCList link; PRFileDesc *tcp_sock; PRFileDesc *model_sock; - int requestCert; } JOB; static PZLock *qLock; /* this lock protects all data immediately below */ @@ -541,7 +545,7 @@ setupJobs(int maxJobs) return SECSuccess; } -typedef int startFn(PRFileDesc *a, PRFileDesc *b, int c); +typedef int startFn(PRFileDesc *a, PRFileDesc *b); typedef enum { rs_idle = 0, rs_running = 1, @@ -550,7 +554,6 @@ typedef enum { rs_idle = 0, typedef struct perThreadStr { PRFileDesc *a; PRFileDesc *b; - int c; int rv; startFn *startFunc; PRThread *prThread; @@ -564,7 +567,7 @@ thread_wrapper(void *arg) { perThread *slot = (perThread *)arg; - slot->rv = (*slot->startFunc)(slot->a, slot->b, slot->c); + slot->rv = (*slot->startFunc)(slot->a, slot->b); /* notify the thread exit handler. */ PZ_Lock(qLock); @@ -575,7 +578,7 @@ thread_wrapper(void *arg) } int -jobLoop(PRFileDesc *a, PRFileDesc *b, int c) +jobLoop(PRFileDesc *a, PRFileDesc *b) { PRCList *myLink = 0; JOB *myJob; @@ -595,8 +598,7 @@ jobLoop(PRFileDesc *a, PRFileDesc *b, int c) /* myJob will be null when stopping is true and jobQ is empty */ if (!myJob) break; - handle_connection(myJob->tcp_sock, myJob->model_sock, - myJob->requestCert); + handle_connection(myJob->tcp_sock, myJob->model_sock); PZ_Lock(qLock); PR_APPEND_LINK(myLink, &freeJobs); PZ_NotifyCondVar(freeListNotEmptyCv); @@ -609,7 +611,6 @@ launch_threads( startFn *startFunc, PRFileDesc *a, PRFileDesc *b, - int c, PRBool local) { int i; @@ -645,7 +646,6 @@ launch_threads( slot->state = rs_running; slot->a = a; slot->b = b; - slot->c = c; slot->startFunc = startFunc; slot->prThread = PR_CreateThread(PR_USER_THREAD, thread_wrapper, slot, PR_PRIORITY_NORMAL, @@ -800,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; @@ -893,8 +894,7 @@ int /* returns count */ int do_writes( PRFileDesc *ssl_sock, - PRFileDesc *model_sock, - int requestCert) + PRFileDesc *model_sock) { int sent = 0; int count = 0; @@ -925,8 +925,7 @@ do_writes( static int handle_fdx_connection( PRFileDesc *tcp_sock, - PRFileDesc *model_sock, - int requestCert) + PRFileDesc *model_sock) { PRFileDesc *ssl_sock = NULL; SECStatus result; @@ -960,8 +959,7 @@ handle_fdx_connection( lockedVars_AddToCount(&lv, 1); /* Attempt to launch the writer thread. */ - result = launch_thread(do_writes, ssl_sock, (PRFileDesc *)&lv, - requestCert); + result = launch_thread(do_writes, ssl_sock, (PRFileDesc *)&lv); if (result == SECSuccess) do { @@ -1093,7 +1091,7 @@ makeCorruptedOCSPResponse(PLArenaPool *arena) } SECItemArray * -makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, +makeSignedOCSPResponse(PLArenaPool *arena, CERTCertificate *cert, secuPWData *pwdata) { SECItemArray *result = NULL; @@ -1117,7 +1115,7 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, nextUpdate = now + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /* plus 1 day */ - switch (osm) { + switch (ocspStaplingMode) { case osm_good: case osm_badsig: sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, @@ -1150,7 +1148,7 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, singleResponses[1] = NULL; ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena, - (osm == osm_badsig) + (ocspStaplingMode == osm_badsig) ? NULL : ca, ocspResponderID_byName, now, singleResponses, @@ -1175,7 +1173,7 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, } void -setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode, +setupCertStatus(PLArenaPool *arena, CERTCertificate *cert, int index, secuPWData *pwdata) { if (ocspStaplingMode == osm_random) { @@ -1213,7 +1211,7 @@ setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode, case osm_unknown: case osm_badsig: multiOcspResponses = - makeSignedOCSPResponse(arena, ocspStaplingMode, cert, + makeSignedOCSPResponse(arena, cert, pwdata); break; case osm_corrupted: @@ -1236,10 +1234,7 @@ setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode, } int -handle_connection( - PRFileDesc *tcp_sock, - PRFileDesc *model_sock, - int requestCert) +handle_connection(PRFileDesc *tcp_sock, PRFileDesc *model_sock) { PRFileDesc *ssl_sock = NULL; PRFileDesc *local_file_fd = NULL; @@ -1272,7 +1267,6 @@ handle_connection( VLOG(("selfserv: handle_connection: starting\n")); if (useModelSocket && model_sock) { - SECStatus rv; ssl_sock = SSL_ImportFD(model_sock, tcp_sock); if (!ssl_sock) { errWarn("SSL_ImportFD with model"); @@ -1588,8 +1582,7 @@ sigusr1_handler(int sig) SECStatus do_accepts( PRFileDesc *listen_sock, - PRFileDesc *model_sock, - int requestCert) + PRFileDesc *model_sock) { PRNetAddr addr; PRErrorCode perr; @@ -1659,7 +1652,6 @@ do_accepts( JOB *myJob = (JOB *)myLink; myJob->tcp_sock = tcp_sock; myJob->model_sock = model_sock; - myJob->requestCert = requestCert; } PR_APPEND_LINK(myLink, &jobQ); @@ -1818,7 +1810,6 @@ handshakeCallback(PRFileDesc *fd, void *client_data) void server_main( PRFileDesc *listen_sock, - int requestCert, SECKEYPrivateKey **privKey, CERTCertificate **cert, const char *expectedHostNameVal) @@ -1872,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); @@ -1985,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. */ @@ -2021,7 +2012,7 @@ server_main( /* end of ssl configuration. */ /* Now, do the accepting, here in the main thread. */ - rv = do_accepts(listen_sock, model_sock, requestCert); + rv = do_accepts(listen_sock, model_sock); terminateWorkerThreads(); @@ -2229,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) { @@ -2444,10 +2436,6 @@ main(int argc, char **argv) debugCache = PR_TRUE; break; - case 'z': - enableCompression = PR_TRUE; - break; - case 'Z': zeroRTT = PR_TRUE; break; @@ -2466,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"); @@ -2654,9 +2652,8 @@ main(int argc, char **argv) } } if (cipher > 0) { - SECStatus status; - status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED); - if (status != SECSuccess) + rv = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED); + if (rv != SECSuccess) SECU_PrintError(progName, "SSL_CipherPrefSet()"); } else { fprintf(stderr, @@ -2684,7 +2681,7 @@ main(int argc, char **argv) exit(11); } if (privKey[i]->keyType != ecKey) - setupCertStatus(certStatusArena, ocspStaplingMode, cert[i], i, &pwdata); + setupCertStatus(certStatusArena, cert[i], i, &pwdata); } if (configureWeakDHE > 0) { @@ -2697,7 +2694,7 @@ main(int argc, char **argv) } /* allocate the array of thread slots, and launch the worker threads. */ - rv = launch_threads(&jobLoop, 0, 0, requestCert, useLocalThreads); + rv = launch_threads(&jobLoop, 0, 0, useLocalThreads); if (rv == SECSuccess && logStats) { loggerThread = PR_CreateThread(PR_SYSTEM_THREAD, @@ -2712,7 +2709,7 @@ main(int argc, char **argv) } if (rv == SECSuccess) { - server_main(listen_sock, requestCert, privKey, cert, + server_main(listen_sock, privKey, cert, expectedHostNameVal); } @@ -2731,7 +2728,6 @@ cleanup: } { - int i; for (i = 0; i < certNicknameIndex; i++) { if (cert[i]) { CERT_DestroyCertificate(cert[i]); diff --git a/security/nss/cmd/shlibsign/shlibsign.c b/security/nss/cmd/shlibsign/shlibsign.c index d93fc422d..221d1e67e 100644 --- a/security/nss/cmd/shlibsign/shlibsign.c +++ b/security/nss/cmd/shlibsign/shlibsign.c @@ -148,7 +148,7 @@ writeItem(PRFileDesc *fd, CK_VOID_PTR pValue, return PR_FAILURE; } bytesWritten = PR_Write(fd, pValue, ulValueLen); - if (bytesWritten != ulValueLen) { + if (bytesWritten < 0 || (CK_ULONG)bytesWritten != ulValueLen) { lperror(file); return PR_FAILURE; } diff --git a/security/nss/cmd/signtool/javascript.c b/security/nss/cmd/signtool/javascript.c index ffff2db59..58869aa61 100644 --- a/security/nss/cmd/signtool/javascript.c +++ b/security/nss/cmd/signtool/javascript.c @@ -1300,7 +1300,6 @@ extract_js(char *filename) * Now we have a stream of tags and text. Go through and deal with each. */ for (curitem = head; curitem; curitem = curitem->next) { - TagItem *tagp = NULL; AVPair *pairp = NULL; char *src = NULL, *id = NULL, *codebase = NULL; PRBool hasEventHandler = PR_FALSE; @@ -1669,11 +1668,14 @@ loser: * Returns PR_SUCCESS if the directory is present, PR_FAILURE otherwise. */ static PRStatus -ensureExists(char *base, char *path) +ensureExists(char *basepath, char *path) { char fn[FNSIZE]; PRDir *dir; - sprintf(fn, "%s/%s", base, path); + int c = snprintf(fn, sizeof(fn), "%s/%s", basepath, path); + if (c >= sizeof(fn)) { + return PR_FAILURE; + } /*PR_fprintf(outputFD, "Trying to open directory %s.\n", fn);*/ diff --git a/security/nss/cmd/signtool/sign.c b/security/nss/cmd/signtool/sign.c index 6f8e43946..534530947 100644 --- a/security/nss/cmd/signtool/sign.c +++ b/security/nss/cmd/signtool/sign.c @@ -175,16 +175,16 @@ typedef struct { * */ int -SignAllArc(char *jartree, char *keyName, int javascript, char *metafile, - char *install_script, int optimize, PRBool recurse) +SignAllArc(char *jartree, char *keyName, int javascript, char *metafilename, + char *install_script, int optimize_level, PRBool recurse) { SignArcInfo info; info.keyName = keyName; info.javascript = javascript; - info.metafile = metafile; + info.metafile = metafilename; info.install_script = install_script; - info.optimize = optimize; + info.optimize = optimize_level; return foreach (jartree, "", sign_all_arc_fn, recurse, PR_TRUE /*include dirs*/, (void *)&info); @@ -194,7 +194,7 @@ static int sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename, void *arg) { - char *zipfile = NULL; + char *zipfilename = NULL; char *arc = NULL, *archive = NULL; int retval = 0; SignArcInfo *infop = (SignArcInfo *)arg; @@ -212,8 +212,8 @@ sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename, } archive = PR_smprintf("%s/%s", basedir, relpath); - zipfile = PL_strdup(archive); - arc = PORT_Strrchr(zipfile, '.'); + zipfilename = PL_strdup(archive); + arc = PORT_Strrchr(zipfilename, '.'); if (arc == NULL) { PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME); @@ -225,17 +225,17 @@ sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename, PL_strcpy(arc, ".jar"); if (verbosity >= 0) { - PR_fprintf(outputFD, "\nsigning: %s\n", zipfile); + PR_fprintf(outputFD, "\nsigning: %s\n", zipfilename); } - retval = SignArchive(archive, infop->keyName, zipfile, + retval = SignArchive(archive, infop->keyName, zipfilename, infop->javascript, infop->metafile, infop->install_script, infop->optimize, PR_TRUE /* recurse */); } finish: if (archive) PR_Free(archive); - if (zipfile) - PR_Free(zipfile); + if (zipfilename) + PR_Free(zipfilename); return retval; } @@ -707,8 +707,8 @@ SignFile(FILE *outFile, FILE *inFile, CERTCertificate *cert) static int generate_SF_file(char *manifile, char *who) { - FILE *sf; - FILE *mf; + FILE *sfFile; + FILE *mfFile; long r1, r2, r3; char whofile[FNSIZE]; char *buf, *name = NULL; @@ -718,12 +718,12 @@ generate_SF_file(char *manifile, char *who) strcpy(whofile, who); - if ((mf = fopen(manifile, "rb")) == NULL) { + if ((mfFile = fopen(manifile, "rb")) == NULL) { perror(manifile); exit(ERRX); } - if ((sf = fopen(whofile, "wb")) == NULL) { + if ((sfFile = fopen(whofile, "wb")) == NULL) { perror(who); exit(ERRX); } @@ -736,11 +736,11 @@ generate_SF_file(char *manifile, char *who) if (buf == NULL || name == NULL) out_of_memory(); - fprintf(sf, "Signature-Version: 1.0\n"); - fprintf(sf, "Created-By: %s\n", CREATOR); - fprintf(sf, "Comments: %s\n", BREAKAGE); + fprintf(sfFile, "Signature-Version: 1.0\n"); + fprintf(sfFile, "Created-By: %s\n", CREATOR); + fprintf(sfFile, "Comments: %s\n", BREAKAGE); - if (fgets(buf, BUFSIZ, mf) == NULL) { + if (fgets(buf, BUFSIZ, mfFile) == NULL) { PR_fprintf(errorFD, "%s: empty manifest file!\n", PROGRAM_NAME); errorCount++; exit(ERRX); @@ -752,15 +752,15 @@ generate_SF_file(char *manifile, char *who) exit(ERRX); } - fseek(mf, 0L, SEEK_SET); + fseek(mfFile, 0L, SEEK_SET); /* Process blocks of headers, and calculate their hashen */ while (1) { /* Beginning range */ - r1 = ftell(mf); + r1 = ftell(mfFile); - if (fgets(name, BUFSIZ, mf) == NULL) + if (fgets(name, BUFSIZ, mfFile) == NULL) break; line++; @@ -774,46 +774,46 @@ generate_SF_file(char *manifile, char *who) } r2 = r1; - while (fgets(buf, BUFSIZ, mf)) { + while (fgets(buf, BUFSIZ, mfFile)) { if (*buf == 0 || *buf == '\n' || *buf == '\r') break; line++; /* Ending range for hashing */ - r2 = ftell(mf); + r2 = ftell(mfFile); } - r3 = ftell(mf); + r3 = ftell(mfFile); if (r1) { - fprintf(sf, "\n"); - fprintf(sf, "%s", name); + fprintf(sfFile, "\n"); + fprintf(sfFile, "%s", name); } - calculate_MD5_range(mf, r1, r2, &dig); + calculate_MD5_range(mfFile, r1, r2, &dig); if (optimize == 0) { - fprintf(sf, "Digest-Algorithms: MD5 SHA1\n"); + fprintf(sfFile, "Digest-Algorithms: MD5 SHA1\n"); md5 = BTOA_DataToAscii(dig.md5, MD5_LENGTH); - fprintf(sf, "MD5-Digest: %s\n", md5); + fprintf(sfFile, "MD5-Digest: %s\n", md5); PORT_Free(md5); } sha1 = BTOA_DataToAscii(dig.sha1, SHA1_LENGTH); - fprintf(sf, "SHA1-Digest: %s\n", sha1); + fprintf(sfFile, "SHA1-Digest: %s\n", sha1); PORT_Free(sha1); /* restore normalcy after changing offset position */ - fseek(mf, r3, SEEK_SET); + fseek(mfFile, r3, SEEK_SET); } PORT_Free(buf); PORT_Free(name); - fclose(sf); - fclose(mf); + fclose(sfFile); + fclose(mfFile); return 0; } diff --git a/security/nss/cmd/signtool/zip.c b/security/nss/cmd/signtool/zip.c index 35d5f5733..aeb5d6c54 100644 --- a/security/nss/cmd/signtool/zip.c +++ b/security/nss/cmd/signtool/zip.c @@ -129,7 +129,7 @@ handle_zerror(int err, char *msg) * been opened with JzipOpen. */ int -JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level) +JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int lvl) { ZIPentry *entry; PRFileDesc *readfp; @@ -319,7 +319,7 @@ JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level) * It causes zlib to leave out its headers and footers, which don't * work in PKZIP files. */ - err = deflateInit2(&zstream, compression_level, Z_DEFLATED, + err = deflateInit2(&zstream, lvl, Z_DEFLATED, -MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY); if (err != Z_OK) { handle_zerror(err, zstream.msg); diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c index fe17f26a4..9106d9955 100644 --- a/security/nss/cmd/smimetools/cmsutil.c +++ b/security/nss/cmd/smimetools/cmsutil.c @@ -68,7 +68,7 @@ DigestFile(PLArenaPool *poolp, SECItem ***digests, SECItem *input, } static void -Usage(char *progName) +Usage(void) { fprintf(stderr, "Usage: %s [-C|-D|-E|-O|-S] [<options>] [-d dbdir] [-u certusage]\n" @@ -115,6 +115,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); } @@ -280,7 +281,6 @@ decode(FILE *out, SECItem *input, const struct decodeOptionsStr *decodeOptions) ** or might be an invalid message, such as a QA test message ** or a message from an attacker. */ - SECStatus rv; rv = NSS_CMSSignedData_VerifyCertsOnly(sigd, decodeOptions->options->certHandle, decodeOptions->options->certUsage); @@ -1127,7 +1127,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -G only supported with option -S.\n", progName); - Usage(progName); + Usage(); exit(1); } signOptions.signingTime = PR_TRUE; @@ -1137,7 +1137,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -H only supported with option -S.\n", progName); - Usage(progName); + Usage(); exit(1); } decodeOptions.suppressContent = PR_TRUE; @@ -1167,7 +1167,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -N only supported with option -S.\n", progName); - Usage(progName); + Usage(); exit(1); } signOptions.nickname = PORT_Strdup(optstate->value); @@ -1180,7 +1180,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -P only supported with option -S.\n", progName); - Usage(progName); + Usage(); exit(1); } signOptions.smimeProfile = PR_TRUE; @@ -1193,7 +1193,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -T only supported with option -S.\n", progName); - Usage(progName); + Usage(); exit(1); } signOptions.detached = PR_TRUE; @@ -1203,7 +1203,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -Y only supported with option -S.\n", progName); - Usage(progName); + Usage(); exit(1); } signOptions.encryptionKeyPreferenceNick = strdup(optstate->value); @@ -1214,7 +1214,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -b only supported with option -D.\n", progName); - Usage(progName); + Usage(); exit(1); } batch = PR_TRUE; @@ -1225,7 +1225,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -c only supported with option -D.\n", progName); - Usage(progName); + Usage(); exit(1); } contentFile = PR_Open(optstate->value, PR_RDONLY, 006600); @@ -1261,7 +1261,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -h only supported with option -D.\n", progName); - Usage(progName); + Usage(); exit(1); } decodeOptions.headerLevel = atoi(optstate->value); @@ -1288,7 +1288,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -k only supported with option -D.\n", progName); - Usage(progName); + Usage(); exit(1); } decodeOptions.keepCerts = PR_TRUE; @@ -1299,7 +1299,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: option -n only supported with option -D.\n", progName); - Usage(progName); + Usage(); exit(1); } decodeOptions.suppressContent = PR_TRUE; @@ -1315,7 +1315,7 @@ main(int argc, char **argv) case 'p': if (!optstate->value) { fprintf(stderr, "%s: option -p must have a value.\n", progName); - Usage(progName); + Usage(); exit(1); } @@ -1325,7 +1325,7 @@ main(int argc, char **argv) case 'f': if (!optstate->value) { fprintf(stderr, "%s: option -f must have a value.\n", progName); - Usage(progName); + Usage(); exit(1); } @@ -1335,7 +1335,7 @@ main(int argc, char **argv) case 'r': if (!optstate->value) { fprintf(stderr, "%s: option -r must have a value.\n", progName); - Usage(progName); + Usage(); exit(1); } envelopeOptions.recipients = ptrarray; @@ -1368,11 +1368,11 @@ main(int argc, char **argv) } } if (status == PL_OPT_BAD) - Usage(progName); + Usage(); PL_DestroyOptState(optstate); if (mode == UNKNOWN) - Usage(progName); + Usage(); if (mode != CERTSONLY && !batch) { rv = SECU_FileToItem(&input, inFile); @@ -1529,7 +1529,7 @@ main(int argc, char **argv) break; default: fprintf(stderr, "One of options -D, -S or -E must be set.\n"); - Usage(progName); + Usage(); exitstatus = 1; } diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c index 7d259bd0a..bba53efac 100644 --- a/security/nss/cmd/strsclnt/strsclnt.c +++ b/security/nss/cmd/strsclnt/strsclnt.c @@ -137,7 +137,7 @@ SECItem bigBuf; fprintf static void -Usage(const char *progName) +Usage(void) { fprintf(stderr, "Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n" @@ -260,7 +260,6 @@ void printSecurityInfo(PRFileDesc *fd) { CERTCertificate *cert = NULL; - SSL3Statistics *ssl3stats = SSL_GetStatistics(); SECStatus result; SSLChannelInfo channel; SSLCipherSuiteInfo suite; @@ -1095,7 +1094,6 @@ client_main( while (0 != (ndx = *cipherString)) { const char *startCipher = cipherString++; int cipher = 0; - SECStatus rv; if (ndx == ':') { cipher = hexchar_to_int(*cipherString++); @@ -1353,7 +1351,7 @@ main(int argc, char **argv) enabledVersions, &enabledVersions) != SECSuccess) { fprintf(stderr, "Bad version specified.\n"); - Usage(progName); + Usage(); } break; @@ -1431,27 +1429,27 @@ main(int argc, char **argv) case 0: /* positional parameter */ if (hostName) { - Usage(progName); + Usage(); } hostName = PL_strdup(optstate->value); break; default: case '?': - Usage(progName); + Usage(); break; } } PL_DestroyOptState(optstate); if (!hostName || status == PL_OPT_BAD) - Usage(progName); + Usage(); if (fullhs != NO_FULLHS_PERCENTAGE && (fullhs < 0 || fullhs > 100 || NoReuse)) - Usage(progName); + Usage(); if (port == 0) - Usage(progName); + Usage(); if (fileName) readBigFile(fileName); diff --git a/security/nss/cmd/symkeyutil/symkeyutil.c b/security/nss/cmd/symkeyutil/symkeyutil.c index 444456808..31ab4dda4 100644 --- a/security/nss/cmd/symkeyutil/symkeyutil.c +++ b/security/nss/cmd/symkeyutil/symkeyutil.c @@ -1034,10 +1034,10 @@ main(int argc, char **argv) char *targetName = symKeyUtil.options[opt_TargetToken].arg; PK11SymKey *newKey; PK11SymKey *symKey = FindKey(slot, name, &keyID, &pwdata); - char *keyName = PK11_GetSymKeyNickname(symKey); + char *keyName; if (!symKey) { - char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name); + keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name); PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n", progName, keyName, PK11_GetTokenName(slot)); PORT_Free(keyName); @@ -1061,6 +1061,7 @@ main(int argc, char **argv) PR_fprintf(PR_STDERR, "%s: Couldn't move the key \n", progName); goto shutdown; } + keyName = PK11_GetSymKeyNickname(symKey); if (keyName) { rv = PK11_SetSymKeyNickname(newKey, keyName); if (rv != SECSuccess) { 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 1ad99502b..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" @@ -51,6 +52,7 @@ #define MAX_WAIT_FOR_SERVER 600 #define WAIT_INTERVAL 100 +#define ZERO_RTT_MAX (2 << 16) #define EXIT_CODE_HANDSHAKE_FAILED 254 @@ -99,11 +101,51 @@ int renegotiationsDone = 0; PRBool initializedServerSessionCache = PR_FALSE; static char *progName; +static const char *requestFile; 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) @@ -130,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); @@ -172,21 +216,23 @@ printSecurityInfo(PRFileDesc *fd) } static void -PrintUsageHeader(const char *progName) +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); } static void -PrintParameterUsage(void) +PrintParameterUsage() { fprintf(stderr, "%-20s Send different SNI name. 1st_hs_name - at first\n" "%-20s handshake, 2nd_hs_name - at second handshake.\n" @@ -223,7 +269,6 @@ PrintParameterUsage(void) 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"); @@ -253,23 +298,33 @@ PrintParameterUsage(void) "%-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 -Usage(const char *progName) +Usage() { - PrintUsageHeader(progName); + PrintUsageHeader(); PrintParameterUsage(); exit(1); } static void -PrintCipherUsage(const char *progName) +PrintCipherUsage() { - PrintUsageHeader(progName); + PrintUsageHeader(); fprintf(stderr, "%-20s Letter(s) chosen from the following list\n", "-c ciphers"); fprintf(stderr, @@ -303,7 +358,7 @@ milliPause(PRUint32 milli) } void -disableAllSSLCiphers(void) +disableAllSSLCiphers() { const PRUint16 *cipherSuites = SSL_GetImplementedCiphers(); int i = SSL_GetNumImplementedCiphers(); @@ -711,12 +766,18 @@ void thread_main(void *arg) { PRFileDesc *ps = (PRFileDesc *)arg; - PRFileDesc *std_in = PR_GetSpecialFD(PR_StandardInput); + PRFileDesc *std_in; int wc, rc; char buf[256]; + if (requestFile) { + std_in = PR_Open(requestFile, PR_RDONLY, 0); + } else { + std_in = PR_GetSpecialFD(PR_StandardInput); + } + #ifdef WIN32 - { + if (!requestFile) { /* Put stdin into O_BINARY mode ** or else incoming \r\n's will become \n's. */ @@ -737,6 +798,9 @@ thread_main(void *arg) wc = PR_Send(ps, buf, rc, 0, maxInterval); } while (wc == rc); PR_Close(ps); + if (requestFile) { + PR_Close(std_in); + } } #endif @@ -844,7 +908,7 @@ separateReqHeader(const PRFileDesc *outFd, const char *buf, const int nb, } else if (((c) >= 'A') && ((c) <= 'F')) { \ i = (c) - 'A' + 10; \ } else { \ - Usage(progName); \ + Usage(); \ } static SECStatus @@ -895,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; @@ -915,22 +978,23 @@ char *hs1SniHostName = NULL; char *hs2SniHostName = NULL; PRUint16 portno = 443; int override = 0; -char *requestString = NULL; -PRInt32 requestStringLen = 0; -PRBool requestSent = PR_FALSE; PRBool enableZeroRtt = PR_FALSE; +PRUint8 *zeroRttData; +unsigned int zeroRttLen = 0; PRBool enableAltServerHello = PR_FALSE; PRBool useDTLS = PR_FALSE; PRBool actAsServer = PR_FALSE; PRBool stopAfterHandshake = PR_FALSE; PRBool requestToExit = PR_FALSE; char *versionString = NULL; +PRBool handshakeComplete = PR_FALSE; +char *encryptedSNIKeys = NULL; static int -writeBytesToServer(PRFileDesc *s, const char *buf, int nb) +writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb) { SECStatus rv; - const char *bufp = buf; + const PRUint8 *bufp = buf; PRPollDesc pollDesc; pollDesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; @@ -944,12 +1008,20 @@ writeBytesToServer(PRFileDesc *s, const char *buf, int nb) if (cc < 0) { PRErrorCode err = PR_GetError(); if (err != PR_WOULD_BLOCK_ERROR) { - SECU_PrintError(progName, - "write to SSL socket failed"); + SECU_PrintError(progName, "write to SSL socket failed"); return 254; } cc = 0; } + FPRINTF(stderr, "%s: %d bytes written\n", progName, cc); + if (enableZeroRtt && !handshakeComplete) { + if (zeroRttLen + cc > ZERO_RTT_MAX) { + SECU_PrintError(progName, "too much early data to save"); + return -1; + } + PORT_Memcpy(zeroRttData + zeroRttLen, bufp, cc); + zeroRttLen += cc; + } bufp += cc; nb -= cc; if (nb <= 0) @@ -969,8 +1041,7 @@ writeBytesToServer(PRFileDesc *s, const char *buf, int nb) progName); cc = PR_Poll(&pollDesc, 1, PR_INTERVAL_NO_TIMEOUT); if (cc < 0) { - SECU_PrintError(progName, - "PR_Poll failed"); + SECU_PrintError(progName, "PR_Poll failed"); return -1; } FPRINTF(stderr, @@ -993,7 +1064,7 @@ handshakeCallback(PRFileDesc *fd, void *client_data) SSL_ReHandshake(fd, (renegotiationsToDo < 2)); ++renegotiationsDone; } - if (requestString && requestSent) { + if (zeroRttLen) { /* This data was sent in 0-RTT. */ SSLChannelInfo info; SECStatus rv; @@ -1003,29 +1074,30 @@ handshakeCallback(PRFileDesc *fd, void *client_data) return; if (!info.earlyDataAccepted) { - FPRINTF(stderr, "Early data rejected. Re-sending\n"); - writeBytesToServer(fd, requestString, requestStringLen); + FPRINTF(stderr, "Early data rejected. Re-sending %d bytes\n", + zeroRttLen); + writeBytesToServer(fd, zeroRttData, zeroRttLen); + zeroRttLen = 0; } } if (stopAfterHandshake) { requestToExit = PR_TRUE; } + handshakeComplete = PR_TRUE; } -#define REQUEST_WAITING (requestString && !requestSent) - static SECStatus -installServerCertificate(PRFileDesc *s, char *nickname) +installServerCertificate(PRFileDesc *s, char *nick) { CERTCertificate *cert; SECKEYPrivateKey *privKey = NULL; - if (!nickname) { + if (!nick) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - cert = PK11_FindCertFromNickname(nickname, &pwdata); + cert = PK11_FindCertFromNickname(nick, &pwdata); if (cert == NULL) { return SECFailure; } @@ -1129,20 +1201,19 @@ connectToServer(PRFileDesc *s, PRPollDesc *pollset) } static int -run(void) +run() { int headerSeparatorPtrnId = 0; int error = 0; SECStatus rv; PRStatus status; PRInt32 filesReady; - int npds; PRFileDesc *s = NULL; PRFileDesc *std_out; - PRPollDesc pollset[2]; + PRPollDesc pollset[2] = { { 0 }, { 0 } }; PRBool wrStarted = PR_FALSE; - requestSent = PR_FALSE; + handshakeComplete = PR_FALSE; /* Create socket */ if (useDTLS) { @@ -1225,19 +1296,18 @@ run(void) cipherString++; } else { if (!isalpha(ndx)) - Usage(progName); + Usage(); ndx = tolower(ndx) - 'a'; if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) { cipher = ssl3CipherSuites[ndx]; } } if (cipher > 0) { - SECStatus status; - status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED); - if (status != SECSuccess) + rv = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED); + if (rv != SECSuccess) SECU_PrintError(progName, "SSL_CipherPrefSet()"); } else { - Usage(progName); + Usage(); } } PORT_Free(cstringSaved); @@ -1266,14 +1336,6 @@ run(void) 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) { @@ -1357,6 +1419,35 @@ run(void) } } + 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); @@ -1394,7 +1485,6 @@ run(void) /* Try to connect to the server */ rv = connectToServer(s, pollset); if (rv != SECSuccess) { - ; error = 1; goto done; } @@ -1406,13 +1496,18 @@ run(void) 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; - npds = 2; + if (requestFile) { + pollset[STDIN_FD].fd = PR_Open(requestFile, PR_RDONLY, 0); + if (!pollset[STDIN_FD].fd) { + fprintf(stderr, "%s: unable to open input file: %s\n", + progName, requestFile); + error = 1; + goto done; + } } else { - npds = 1; + pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput); } + pollset[STDIN_FD].in_flags = PR_POLL_READ; std_out = PR_GetSpecialFD(PR_StandardOutput); #if defined(WIN32) || defined(OS2) @@ -1458,10 +1553,9 @@ run(void) requestToExit = PR_FALSE; FPRINTF(stderr, "%s: ready...\n", progName); 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. */ + (pollset[SSOCK_FD].in_flags || pollset[STDIN_FD].in_flags)) { + PRUint8 buf[4000]; /* buffer for stdin */ + int nb; /* num bytes read from stdin. */ rv = restartHandshakeAfterServerCertIfNeeded(s, &serverCertAuth, override); @@ -1475,7 +1569,8 @@ run(void) pollset[STDIN_FD].out_flags = 0; FPRINTF(stderr, "%s: about to call PR_Poll !\n", progName); - filesReady = PR_Poll(pollset, npds, PR_INTERVAL_NO_TIMEOUT); + filesReady = PR_Poll(pollset, PR_ARRAY_SIZE(pollset), + PR_INTERVAL_NO_TIMEOUT); if (filesReady < 0) { SECU_PrintError(progName, "select failed"); error = 1; @@ -1497,14 +1592,6 @@ run(void) "%s: PR_Poll returned 0x%02x for socket out_flags.\n", progName, pollset[SSOCK_FD].out_flags); } - if (REQUEST_WAITING) { - error = writeBytesToServer(s, requestString, requestStringLen); - if (error) { - goto done; - } - requestSent = PR_TRUE; - pollset[SSOCK_FD].in_flags = PR_POLL_READ; - } if (pollset[STDIN_FD].out_flags & PR_POLL_READ) { /* Read from stdin and write to socket */ nb = PR_Read(pollset[STDIN_FD].fd, buf, sizeof(buf)); @@ -1518,6 +1605,8 @@ run(void) } else if (nb == 0) { /* EOF on stdin, stop polling stdin for read. */ pollset[STDIN_FD].in_flags = 0; + if (actAsServer) + requestToExit = PR_TRUE; } else { error = writeBytesToServer(s, buf, nb); if (error) { @@ -1532,12 +1621,12 @@ run(void) "%s: PR_Poll returned 0x%02x for socket out_flags.\n", progName, pollset[SSOCK_FD].out_flags); } - if ((pollset[SSOCK_FD].out_flags & PR_POLL_READ) || - (pollset[SSOCK_FD].out_flags & PR_POLL_ERR) #ifdef PR_POLL_HUP - || (pollset[SSOCK_FD].out_flags & PR_POLL_HUP) +#define POLL_RECV_FLAGS (PR_POLL_READ | PR_POLL_ERR | PR_POLL_HUP) +#else +#define POLL_RECV_FLAGS (PR_POLL_READ | PR_POLL_ERR) #endif - ) { + if (pollset[SSOCK_FD].out_flags & POLL_RECV_FLAGS) { /* Read from socket and write to stdout */ nb = PR_Recv(pollset[SSOCK_FD].fd, buf, sizeof buf, 0, maxInterval); FPRINTF(stderr, "%s: Read from server %d bytes\n", progName, nb); @@ -1554,7 +1643,7 @@ run(void) if (skipProtoHeader != PR_TRUE || wrStarted == PR_TRUE) { PR_Write(std_out, buf, nb); } else { - separateReqHeader(std_out, buf, nb, &wrStarted, + separateReqHeader(std_out, (char *)buf, nb, &wrStarted, &headerSeparatorPtrnId); } if (verbose) @@ -1568,42 +1657,10 @@ done: if (s) { PR_Close(s); } - - return error; -} - -PRInt32 -ReadFile(const char *filename, char **data) -{ - char *ret = NULL; - char buf[8192]; - unsigned int len = 0; - PRStatus rv; - - PRFileDesc *fd = PR_Open(filename, PR_RDONLY, 0); - if (!fd) - return -1; - - for (;;) { - rv = PR_Read(fd, buf, sizeof(buf)); - if (rv < 0) { - PR_Free(ret); - return rv; - } - - if (!rv) - break; - - ret = PR_Realloc(ret, len + rv); - if (!ret) { - return -1; - } - PORT_Memcpy(ret + len, buf, rv); - len += rv; + if (requestFile && pollset[STDIN_FD].fd) { + PR_Close(pollset[STDIN_FD].fd); } - - *data = ret; - return len; + return error; } int @@ -1645,34 +1702,32 @@ 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 '?': default: - Usage(progName); + Usage(); break; case '4': allowIPv6 = PR_FALSE; if (!allowIPv4) - Usage(progName); + Usage(); break; case '6': allowIPv4 = PR_FALSE; if (!allowIPv6) - Usage(progName); + Usage(); break; case 'A': - requestStringLen = ReadFile(optstate->value, &requestString); - if (requestStringLen < 0) { - fprintf(stderr, "Couldn't read file %s\n", optstate->value); - exit(1); - } + requestFile = PORT_Strdup(optstate->value); break; case 'C': @@ -1729,13 +1784,17 @@ main(int argc, char **argv) }; break; + case 'N': + encryptedSNIKeys = PORT_Strdup(optstate->value); + break; + case 'P': useDTLS = PR_TRUE; if (!strcmp(optstate->value, "server")) { actAsServer = 1; } else { if (strcmp(optstate->value, "client")) { - Usage(progName); + Usage(); } } break; @@ -1768,16 +1827,21 @@ main(int argc, char **argv) if (!strcmp(optstate->value, "alt-server-hello")) { enableAltServerHello = PR_TRUE; } else { - Usage(progName); + Usage(); } break; case 'Y': - PrintCipherUsage(progName); + PrintCipherUsage(); exit(0); break; case 'Z': enableZeroRtt = PR_TRUE; + zeroRttData = PORT_ZAlloc(ZERO_RTT_MAX); + if (!zeroRttData) { + fprintf(stderr, "Unable to allocate buffer for 0-RTT\n"); + exit(1); + } break; case 'a': @@ -1786,7 +1850,7 @@ main(int argc, char **argv) } else if (!hs2SniHostName) { hs2SniHostName = PORT_Strdup(optstate->value); } else { - Usage(progName); + Usage(); } break; @@ -1866,16 +1930,21 @@ 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) { PL_DestroyOptState(optstate); fprintf(stderr, "Bad group specified.\n"); - Usage(progName); + 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; } @@ -1889,18 +1958,18 @@ main(int argc, char **argv) enabledVersions, &enabledVersions) != SECSuccess) { fprintf(stderr, "Bad version specified.\n"); - Usage(progName); + Usage(); } PORT_Free(versionString); } if (optstatus == PL_OPT_BAD) { - Usage(progName); + Usage(); } if (!host || !portno) { fprintf(stderr, "%s: parameters -h and -p are mandatory\n", progName); - Usage(progName); + Usage(); } if (serverCertAuth.testFreshStatusFromSideChannel && @@ -2060,20 +2129,14 @@ done: PR_Close(s); } - if (hs1SniHostName) { - PORT_Free(hs1SniHostName); - } - if (hs2SniHostName) { - PORT_Free(hs2SniHostName); - } - if (nickname) { - PORT_Free(nickname); - } - if (pwdata.data) { - PORT_Free(pwdata.data); - } + PORT_Free((void *)requestFile); + PORT_Free(hs1SniHostName); + PORT_Free(hs2SniHostName); + PORT_Free(nickname); + PORT_Free(pwdata.data); PORT_Free(host); - PORT_Free(requestString); + 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.c b/security/nss/cmd/vfyserv/vfyserv.c index aa648ad8c..4234ecd09 100644 --- a/security/nss/cmd/vfyserv/vfyserv.c +++ b/security/nss/cmd/vfyserv/vfyserv.c @@ -327,9 +327,7 @@ do_connects(void *a, int connection) } void -client_main(unsigned short port, - int connections, - const char *hostName) +client_main(int connections) { int i; SECStatus secStatus; @@ -553,7 +551,7 @@ main(int argc, char **argv) } } - client_main(port, connections, hostName); + client_main(connections); cleanup: if (doOcspCheck) { 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 */ diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c index 2f1b53262..d3d8a206e 100644 --- a/security/nss/cmd/vfyserv/vfyutil.c +++ b/security/nss/cmd/vfyserv/vfyutil.c @@ -310,13 +310,13 @@ myHandshakeCallback(PRFileDesc *socket, void *arg) void disableAllSSLCiphers(void) { - const PRUint16 *cipherSuites = SSL_ImplementedCiphers; + const PRUint16 *allSuites = SSL_ImplementedCiphers; int i = SSL_NumImplementedCiphers; SECStatus rv; /* disable all the SSL3 cipher suites */ while (--i >= 0) { - PRUint16 suite = cipherSuites[i]; + PRUint16 suite = allSuites[i]; rv = SSL_CipherPrefSetDefault(suite, PR_FALSE); if (rv != SECSuccess) { fprintf(stderr, |