From 9d4b719a04dc69685e59c293f06270e6534505dd Mon Sep 17 00:00:00 2001 From: Benjamin Beurdouche Date: Thu, 18 Nov 2021 18:55:20 +0000 Subject: [PATCH] Bug 1738222 - land NSS 4b8ce9641338 UPGRADE_NSS_RELEASE, r=jschanck Differential Revision: https://phabricator.services.mozilla.com/D131519 --- build/moz.configure/nss.configure | 2 +- security/nss/TAG-INFO | 2 +- .../automation/abi-check/previous-nss-release | 2 +- .../taskcluster/docker-fuzz/Dockerfile | 2 +- .../taskcluster/graph/src/extend.js | 27 -- .../automation/taskcluster/graph/src/index.js | 6 - .../taskcluster/graph/src/try_syntax.js | 2 +- .../taskcluster/scripts/run_coverity.sh | 21 -- security/nss/cmd/manifest.mn | 1 + security/nss/cmd/validation/Makefile | 48 +++ security/nss/cmd/validation/manifest.mn | 23 ++ security/nss/cmd/validation/validation.c | 251 +++++++++++++++ security/nss/cmd/validation/validation.gyp | 30 ++ security/nss/coreconf/coreconf.dep | 1 - .../nss/lib/libpkix/pkix/util/pkix_tools.c | 1 + security/nss/lib/nss/nss.h | 6 +- security/nss/lib/softoken/config.mk | 4 + security/nss/lib/softoken/pkcs11.c | 52 +-- security/nss/lib/softoken/pkcs11i.h | 13 + security/nss/lib/softoken/pkcs11u.c | 154 ++++++++- security/nss/lib/softoken/softkver.h | 6 +- security/nss/lib/util/nssutil.h | 6 +- security/nss/lib/util/pkcs11n.h | 11 + security/nss/mach | 296 ------------------ security/nss/nss.gyp | 1 + 25 files changed, 561 insertions(+), 407 deletions(-) delete mode 100755 security/nss/automation/taskcluster/scripts/run_coverity.sh create mode 100644 security/nss/cmd/validation/Makefile create mode 100644 security/nss/cmd/validation/manifest.mn create mode 100644 security/nss/cmd/validation/validation.c create mode 100644 security/nss/cmd/validation/validation.gyp diff --git a/build/moz.configure/nss.configure b/build/moz.configure/nss.configure index 0ac5dbbc1c66..fa04f1519519 100644 --- a/build/moz.configure/nss.configure +++ b/build/moz.configure/nss.configure @@ -9,7 +9,7 @@ system_lib_option("--with-system-nss", help="Use system NSS") imply_option("--with-system-nspr", True, when="--with-system-nss") nss_pkg = pkg_check_modules( - "NSS", "nss >= 3.72", when="--with-system-nss", config=False + "NSS", "nss >= 3.73", when="--with-system-nss", config=False ) set_config("MOZ_SYSTEM_NSS", True, when="--with-system-nss") diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index f4bb0484c54e..34d092f3b3cf 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_72_RTM \ No newline at end of file +4b8ce9641338 \ No newline at end of file diff --git a/security/nss/automation/abi-check/previous-nss-release b/security/nss/automation/abi-check/previous-nss-release index 5ae7de053ee9..979308c94021 100644 --- a/security/nss/automation/abi-check/previous-nss-release +++ b/security/nss/automation/abi-check/previous-nss-release @@ -1 +1 @@ -NSS_3_71_BRANCH +NSS_3_72_BRANCH diff --git a/security/nss/automation/taskcluster/docker-fuzz/Dockerfile b/security/nss/automation/taskcluster/docker-fuzz/Dockerfile index 00964b42f355..d7e7fa918d99 100644 --- a/security/nss/automation/taskcluster/docker-fuzz/Dockerfile +++ b/security/nss/automation/taskcluster/docker-fuzz/Dockerfile @@ -1,5 +1,5 @@ # Dockerfile for running fuzzing tests. -# Used for ASAN and Coverity based static-analysis. +# Used for ASAN. # Note that when running this, you need to add `--cap-add SYS_PTRACE` to the # docker invocation or ASAN won't work. # On taskcluster for ASAN use `features: ["allowPtrace"]`. diff --git a/security/nss/automation/taskcluster/graph/src/extend.js b/security/nss/automation/taskcluster/graph/src/extend.js index 58b89dc70751..ee3710555e4b 100644 --- a/security/nss/automation/taskcluster/graph/src/extend.js +++ b/security/nss/automation/taskcluster/graph/src/extend.js @@ -1148,33 +1148,6 @@ async function scheduleTools() { ] })); - queue.scheduleTask(merge(base, { - symbol: "coverity", - name: "coverity", - image: FUZZ_IMAGE, - tags: ['code-review'], - env: { - USE_64: "1", - CC: "clang", - CCC: "clang++", - NSS_AUTOMATION: "1" - }, - features: ["taskclusterProxy"], - scopes: ["secrets:get:project/relman/coverity-nss"], - artifacts: { - "public/code-review/coverity.json": { - expires: 24 * 7, - type: "file", - path: "/home/worker/nss/coverity/coverity.json" - } - }, - command: [ - "/bin/bash", - "-c", - "bin/checkout.sh && nss/automation/taskcluster/scripts/run_coverity.sh" - ] - })); - queue.scheduleTask(merge(base, { symbol: "hacl", name: "hacl", diff --git a/security/nss/automation/taskcluster/graph/src/index.js b/security/nss/automation/taskcluster/graph/src/index.js index 2c7f5eb502c0..78f4af8e48ab 100644 --- a/security/nss/automation/taskcluster/graph/src/index.js +++ b/security/nss/automation/taskcluster/graph/src/index.js @@ -10,12 +10,6 @@ const main = async () => { // Init try syntax filter. if (process.env.TC_PROJECT == "nss-try") { await try_syntax.initFilter(); - } else { - // Coverity should not be run on landings, only by request (typically - // by Phabricator). - queue.filter(task => { - return task.symbol != "coverity"; - }); } // Extend the task graph. diff --git a/security/nss/automation/taskcluster/graph/src/try_syntax.js b/security/nss/automation/taskcluster/graph/src/try_syntax.js index 0d2e84c59b0f..4629ff4b26ec 100644 --- a/security/nss/automation/taskcluster/graph/src/try_syntax.js +++ b/security/nss/automation/taskcluster/graph/src/try_syntax.js @@ -57,7 +57,7 @@ function parseOptions(opts) { } // Parse tools. - let allTools = ["clang-format", "scan-build", "coverity", "hacl", "saw", "abi", "coverage"]; + let allTools = ["clang-format", "scan-build", "hacl", "saw", "abi", "coverage"]; let tools = intersect(opts.tools.split(/\s*,\s*/), allTools); // If the given value is "all" run all tools. diff --git a/security/nss/automation/taskcluster/scripts/run_coverity.sh b/security/nss/automation/taskcluster/scripts/run_coverity.sh deleted file mode 100755 index 4b09f53983e2..000000000000 --- a/security/nss/automation/taskcluster/scripts/run_coverity.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -source $(dirname "$0")/tools.sh - -# Clone NSPR if needed. -if [ ! -d "nspr" ]; then - hg_clone https://hg.mozilla.org/projects/nspr ./nspr default - - if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then - pushd nspr - cat ../nss/nspr.patch | patch -p1 - popd - fi -fi - -# Build and run Coverity -cd nss -./mach static-analysis - -# Return the exit code of the Coverity Analysis -exit $? diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn index bb5319a0f56e..aafcf86fdbf5 100644 --- a/security/nss/cmd/manifest.mn +++ b/security/nss/cmd/manifest.mn @@ -76,6 +76,7 @@ NSS_SRCDIRS = \ symkeyutil \ tests \ tstclnt \ + validation \ vfychain \ vfyserv \ modutil \ diff --git a/security/nss/cmd/validation/Makefile b/security/nss/cmd/validation/Makefile new file mode 100644 index 000000000000..d7c879aec286 --- /dev/null +++ b/security/nss/cmd/validation/Makefile @@ -0,0 +1,48 @@ +#! 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/validation/manifest.mn b/security/nss/cmd/validation/manifest.mn new file mode 100644 index 000000000000..98fbe341d206 --- /dev/null +++ b/security/nss/cmd/validation/manifest.mn @@ -0,0 +1,23 @@ +# +# 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 = ../.. + +DEFINES += -DNSPR20 + +# MODULE public and private header directories are implicitly REQUIRED. +MODULE = nss + +CSRCS = \ + validation.c \ + $(NULL) + +# The MODULE is always implicitly required. +# Listing it here in REQUIRES makes it appear twice in the cc command line. +REQUIRES = dbm seccmd + +PROGRAM = validation + +# USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/validation/validation.c b/security/nss/cmd/validation/validation.c new file mode 100644 index 000000000000..f7b32a6f8cc6 --- /dev/null +++ b/security/nss/cmd/validation/validation.c @@ -0,0 +1,251 @@ +/* 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/. */ + +#ifdef _CRTDBG_MAP_ALLOC +#include +#include +#endif + +#include "nspr.h" +#include "secutil.h" +#include "pk11func.h" +#include "nss.h" +#include "secport.h" +#include "secpkcs5.h" +#include "sechash.h" +#include "certdb.h" +#include "secmod.h" + +static char *progName; +PRBool debug = PR_FALSE; + +#define ERR_USAGE 2 +#define ERR_PK11GETSLOT 13 + +static void +Usage() +{ +#define FPS PR_fprintf(PR_STDERR, + FPS "Usage: %s [-d certdir] [-P dbprefix] [-h tokenname]\n", + progName); + FPS "\t\t [-k slotpwfile | -K slotpw] [-v]\n"); + + exit(ERR_USAGE); +} + +typedef enum { + tagULong, + tagVersion, + tagUtf8 +} tagType; + +typedef struct { + const char *attributeName; + tagType attributeStorageType; +} attributeTag; + +enum { + opt_CertDir = 0, + opt_TokenName, + opt_SlotPWFile, + opt_SlotPW, + opt_DBPrefix, + opt_Debug +}; + +static secuCommandFlag validation_options[] = + { + { /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE }, + { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE }, + { /* opt_SlotPWFile */ 'k', PR_TRUE, 0, PR_FALSE }, + { /* opt_SlotPW */ 'K', PR_TRUE, 0, PR_FALSE }, + { /* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE }, + { /* opt_Debug */ 'v', PR_FALSE, 0, PR_FALSE } + }; + +void +dump_Raw(char *label, CK_ATTRIBUTE *attr) +{ + int i; + unsigned char *value = (unsigned char *)attr->pValue; + printf("0x"); + for (i = 0; i < attr->ulValueLen; i++) { + printf("%02x", value[i]); + } + printf("<%s>\n", label); +} + +SECStatus +dump_validations(CK_OBJECT_CLASS objc, CK_ATTRIBUTE *template, int count, + attributeTag *tags, PK11SlotInfo *slot) +{ + PK11GenericObject *objs, *obj; + + objs = PK11_FindGenericObjects(slot, objc); + + for (obj = objs; obj != NULL; obj = PK11_GetNextGenericObject(obj)) { + int i; + printf("Validation Object:\n"); + PK11_ReadRawAttributes(NULL, PK11_TypeGeneric, obj, template, count); + for (i = 0; i < count; i++) { + CK_ULONG ulong; + CK_VERSION version; + int len = template[i].ulValueLen; + printf(" %s: ", tags[i].attributeName); + if (len < 0) { + printf("\n"); + } else if (len == 0) { + printf("\n"); + } else + switch (tags[i].attributeStorageType) { + case tagULong: + if (len != sizeof(CK_ULONG)) { + dump_Raw("bad ulong", &template[i]); + break; + } + ulong = *(CK_ULONG *)template[i].pValue; + printf("%ld\n", ulong); + break; + case tagVersion: + if (len != sizeof(CK_VERSION)) { + dump_Raw("bad version", &template[i]); + break; + } + version = *(CK_VERSION *)template[i].pValue; + printf("%d.%d\n", version.major, version.minor); + break; + case tagUtf8: + printf("%.*s\n", len, (char *)template[i].pValue); + break; + default: + dump_Raw("unknown tag", &template[i]); + break; + } + PORT_Free(template[i].pValue); + template[i].pValue = NULL; + template[i].ulValueLen = 0; + } + } + PK11_DestroyGenericObjects(objs); + return SECSuccess; +} + +int +main(int argc, char **argv) +{ + secuPWData slotPw = { PW_NONE, NULL }; + secuPWData p12FilePw = { PW_NONE, NULL }; + PK11SlotInfo *slot = NULL; + char *slotname = NULL; + char *dbprefix = ""; + char *nssdir = NULL; + SECStatus rv; + secuCommand validation; + int local_errno = 0; + + CK_ATTRIBUTE validation_template[] = { + { CKA_NSS_VALIDATION_TYPE, NULL, 0 }, + { CKA_NSS_VALIDATION_VERSION, NULL, 0 }, + { CKA_NSS_VALIDATION_LEVEL, NULL, 0 }, + { CKA_NSS_VALIDATION_MODULE_ID, NULL, 0 } + }; + attributeTag validation_tags[] = { + { "Validation Type", tagULong }, + { "Validation Version", tagVersion }, + { "Validation Level", tagULong }, + { "Validation Module ID", tagUtf8 }, + }; + +#ifdef _CRTDBG_MAP_ALLOC + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif + + validation.numCommands = 0; + validation.commands = 0; + validation.numOptions = PR_ARRAY_SIZE(validation_options); + validation.options = validation_options; + + progName = strrchr(argv[0], '/'); + progName = progName ? progName + 1 : argv[0]; + + rv = SECU_ParseCommandLine(argc, argv, progName, &validation); + + if (rv != SECSuccess) + Usage(); + + debug = validation.options[opt_Debug].activated; + + slotname = SECU_GetOptionArg(&validation, opt_TokenName); + + if (validation.options[opt_SlotPWFile].activated) { + slotPw.source = PW_FROMFILE; + slotPw.data = PORT_Strdup(validation.options[opt_SlotPWFile].arg); + } + + if (validation.options[opt_SlotPW].activated) { + slotPw.source = PW_PLAINTEXT; + slotPw.data = PORT_Strdup(validation.options[opt_SlotPW].arg); + } + + if (validation.options[opt_CertDir].activated) { + nssdir = validation.options[opt_CertDir].arg; + } + if (validation.options[opt_DBPrefix].activated) { + dbprefix = validation.options[opt_DBPrefix].arg; + } + + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + if (nssdir == NULL && NSS_NoDB_Init("") == SECSuccess) { + rv = SECSuccess; + /* if the system isn't already in FIPS mode, we need + * to switch to FIPS mode */ + if (!PK11_IsFIPS()) { + /* flip to FIPS mode */ + SECMODModule *module = SECMOD_GetInternalModule(); + rv = SECMOD_DeleteInternalModule(module->commonName); + } + } else if (nssdir != NULL) { + rv = NSS_Initialize(nssdir, dbprefix, dbprefix, "secmod.db", 0); + } + if (rv != SECSuccess) { + SECU_PrintPRandOSError(progName); + local_errno = -1; + goto done; + } + + if (!slotname || PL_strcmp(slotname, "internal") == 0) + slot = PK11_GetInternalKeySlot(); + else + slot = PK11_FindSlotByName(slotname); + + if (!slot) { + SECU_PrintError(progName, "Invalid slot \"%s\"", + slotname ? "internal" : slotname); + local_errno = ERR_PK11GETSLOT; + goto done; + } + + rv = dump_validations(CKO_NSS_VALIDATION, + validation_template, + PR_ARRAY_SIZE(validation_template), + validation_tags, + slot); + +done: + if (slotPw.data != NULL) + PORT_ZFree(slotPw.data, PL_strlen(slotPw.data)); + if (p12FilePw.data != NULL) + PORT_ZFree(p12FilePw.data, PL_strlen(p12FilePw.data)); + if (slotname) { + PORT_Free(slotname); + } + if (slot) + PK11_FreeSlot(slot); + if (NSS_Shutdown() != SECSuccess) { + local_errno = 1; + } + PL_ArenaFinish(); + PR_Cleanup(); + return local_errno; +} diff --git a/security/nss/cmd/validation/validation.gyp b/security/nss/cmd/validation/validation.gyp new file mode 100644 index 000000000000..32edd30a4a11 --- /dev/null +++ b/security/nss/cmd/validation/validation.gyp @@ -0,0 +1,30 @@ +# 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': 'validation', + 'type': 'executable', + 'sources': [ + 'validation.c' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:dbm_exports', + '<(DEPTH)/exports.gyp:nss_exports' + ] + } + ], + 'target_defaults': { + 'defines': [ + 'NSPR20' + ] + }, + 'variables': { + 'module': 'nss' + } +} diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfaeee3..5182f75552c8 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/lib/libpkix/pkix/util/pkix_tools.c b/security/nss/lib/libpkix/pkix/util/pkix_tools.c index d354a766a06e..4c01f8da1444 100755 --- a/security/nss/lib/libpkix/pkix/util/pkix_tools.c +++ b/security/nss/lib/libpkix/pkix/util/pkix_tools.c @@ -1073,6 +1073,7 @@ pkix_CacheCert_Lookup( (PKIX_PL_Object *)cert, plContext), PKIX_LISTAPPENDITEMFAILED); + *pFound = PKIX_TRUE; } else { PKIX_DECREF(selectorError); } diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 3ff29c54a2df..30e8bfaee2a4 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -22,12 +22,12 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.72" _NSS_CUSTOMIZED +#define NSS_VERSION "3.73" _NSS_CUSTOMIZED " Beta" #define NSS_VMAJOR 3 -#define NSS_VMINOR 72 +#define NSS_VMINOR 73 #define NSS_VPATCH 0 #define NSS_VBUILD 0 -#define NSS_BETA PR_FALSE +#define NSS_BETA PR_TRUE #ifndef RC_INVOKED diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk index 771b93a3fab7..339f804938c9 100644 --- a/security/nss/lib/softoken/config.mk +++ b/security/nss/lib/softoken/config.mk @@ -59,3 +59,7 @@ ifdef NSS_ENABLE_FIPS_INDICATORS DEFINES += -DNSS_ENABLE_FIPS_INDICATORS endif +ifdef NSS_FIPS_MODULE_ID +DEFINES += -DNSS_FIPS_MODULE_ID=\"${NSS_FIPS_MODULE_ID}\" +endif + diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 3f49333f86ca..dcb0c729dac5 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -75,7 +75,6 @@ static char libraryDescription_space[33]; * failure so that there are at most 60 login attempts per minute. */ static PRIntervalTime loginWaitTime; -static PRUint32 minSessionObjectHandle = 1U; #define __PASTE(x, y) x##y @@ -1672,8 +1671,6 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session) { SFTKSlot *slot = session->slot; SFTKAttribute *attribute; - SFTKObject *duplicateObject = NULL; - CK_OBJECT_HANDLE handle; CK_BBOOL ckfalse = CK_FALSE; CK_BBOOL cktrue = CK_TRUE; CK_RV crv; @@ -1711,30 +1708,13 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session) * token objects and will have a token object handle assigned to * them by a call to sftk_mkHandle in the handler for each object * class, invoked below. - * + * * It may be helpful to note/remember that * sftk_narrowToXxxObject uses sftk_isToken, * sftk_isToken examines the sign bit of the object's handle, but * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute. */ - do { - PRUint32 wrappedAround; - - duplicateObject = NULL; - PZ_Lock(slot->objectLock); - wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK; - handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK; - if (!handle) /* don't allow zero handle */ - handle = minSessionObjectHandle; - slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround; - /* Is there already a session object with this handle? */ - if (wrappedAround) { - sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, - slot->sessObjHashSize); - } - PZ_Unlock(slot->objectLock); - } while (duplicateObject != NULL); - object->handle = handle; + object->handle = sftk_getNextHandle(slot); /* get the object class */ attribute = sftk_FindAttribute(object, CKA_CLASS); @@ -2875,10 +2855,15 @@ SFTK_SlotInit(char *configdir, char *updatedir, char *updateID, goto mem_loser; slot->sessionIDCount = 0; - slot->sessionObjectHandleCount = minSessionObjectHandle; + slot->sessionObjectHandleCount = NSC_MIN_SESSION_OBJECT_HANDLE; slot->slotID = slotID; sftk_setStringName(params->slotdes ? params->slotdes : sftk_getDefSlotName(slotID), slot->slotDescription, sizeof(slot->slotDescription), PR_TRUE); + crv = sftk_InitSession(&slot->moduleObjects, slot, slotID, NULL, NULL, + CKF_SERIAL_SESSION); + if (crv != CKR_OK) { + goto loser; + } /* call the reinit code to set everything that changes between token * init calls */ @@ -2887,6 +2872,12 @@ SFTK_SlotInit(char *configdir, char *updatedir, char *updateID, if (crv != CKR_OK) { goto loser; } + if (sftk_isFIPS(slotID)) { + crv = sftk_CreateValidationObjects(slot); + if (crv != CKR_OK) { + goto loser; + } + } crv = sftk_RegisterSlot(slot, moduleIndex); if (crv != CKR_OK) { goto loser; @@ -3032,6 +3023,8 @@ SFTK_DestroySlotData(SFTKSlot *slot) SFTK_ShutdownSlot(slot); + sftk_ClearSession(&slot->moduleObjects); + if (slot->tokObjHashTable) { PL_HashTableDestroy(slot->tokObjHashTable); slot->tokObjHashTable = NULL; @@ -3262,6 +3255,7 @@ nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) CK_RV crv = CKR_OK; SECStatus rv; CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved; + PRBool destroy_freelist_on_error = PR_TRUE; int i; unsigned int moduleIndex = isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE; @@ -3341,7 +3335,14 @@ nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) "disabled FIPS mode"); } } + /* if we have a peer open, we don't want to destroy the freelist + * from under the peer if we fail, the free list will be + * destroyed in that case when the C_Finalize is called for + * the peer */ + destroy_freelist_on_error = PR_FALSE; } + /* allow us to create objects in SFTK_SlotInit */ + sftk_InitFreeLists(); for (i = 0; i < paramStrings.token_count; i++) { crv = SFTK_SlotInit(paramStrings.configdir, @@ -3355,8 +3356,9 @@ nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) loser: sftk_freeParams(¶mStrings); } - if (CKR_OK == crv) { - sftk_InitFreeLists(); + if (destroy_freelist_on_error && (CKR_OK != crv)) { + /* idempotent. If the list are already freed, this is a noop */ + sftk_CleanupFreeLists(); } #ifndef NO_FORK_CHECK diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index 032e85fee2f1..4365a115c285 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -49,6 +49,8 @@ #define NSC_SEARCH_BLOCK_SIZE 5 #define NSC_SLOT_LIST_BLOCK_SIZE 10 +#define NSC_MIN_SESSION_OBJECT_HANDLE 1U + #define NSC_FIPS_MODULE 1 #define NSC_NON_FIPS_MODULE 0 @@ -375,6 +377,9 @@ struct SFTKSlotStr { char tokDescription[33]; /* per load */ char updateTokDescription[33]; /* per load */ char slotDescription[65]; /* invariant */ + SFTKSession moduleObjects; /* global session to hang module specific + * objects like profile objects or + * validation objects */ }; /* @@ -766,6 +771,7 @@ extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object); extern void sftk_ReferenceObject(SFTKObject *object); extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session); +extern CK_OBJECT_HANDLE sftk_getNextHandle(SFTKSlot *slot); extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object); extern void sftk_AddObject(SFTKSession *session, SFTKObject *object); /* clear out all the existing object ID to database key mappings. @@ -787,7 +793,11 @@ extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle); extern CK_SLOT_ID sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle); extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); extern void sftk_FreeSession(SFTKSession *session); +extern void sftk_ClearSession(SFTKSession *session); extern void sftk_DestroySession(SFTKSession *session); +extern CK_RV sftk_InitSession(SFTKSession *session, SFTKSlot *slot, + CK_SLOT_ID slotID, CK_NOTIFY notify, + CK_VOID_PTR pApplication, CK_FLAGS flags); extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, CK_FLAGS flags); extern void sftk_update_state(SFTKSlot *slot, SFTKSession *session); @@ -955,6 +965,9 @@ CK_FLAGS sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE op); * FIPS security policy */ PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, CK_ATTRIBUTE_TYPE op, SFTKObject *source); +/* add validation objects to the slot */ +CK_RV sftk_CreateValidationObjects(SFTKSlot *slot); + SEC_END_PROTOS #endif /* _PKCS11I_H_ */ diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index f37aab92f7e5..5299a700adaa 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -14,6 +14,7 @@ #include "sftkdb.h" #include "softoken.h" #include "secoid.h" +#include "softkver.h" #if !defined(NSS_FIPS_DISABLED) && defined(NSS_ENABLE_FIPS_INDICATORS) /* this file should be supplied by the vendor and include all the @@ -1243,6 +1244,36 @@ sftk_FreeObject(SFTKObject *object) return SFTK_Busy; } +/* find the next available object handle that isn't currently in use */ +/* NOTE: This function could loop forever if we've exhausted all + * 3^31-1 handles. This is highly unlikely (NSS has been running for + * decades with this code) uless we start increasing the size of the + * SFTK_TOKEN_MASK (which is just the high bit currently). */ +CK_OBJECT_HANDLE +sftk_getNextHandle(SFTKSlot *slot) +{ + CK_OBJECT_HANDLE handle; + SFTKObject *duplicateObject = NULL; + do { + PRUint32 wrappedAround; + + duplicateObject = NULL; + PZ_Lock(slot->objectLock); + wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK; + handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK; + if (!handle) /* don't allow zero handle */ + handle = NSC_MIN_SESSION_OBJECT_HANDLE; + slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround; + /* Is there already a session object with this handle? */ + if (wrappedAround) { + sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, + slot->sessObjHashSize); + } + PZ_Unlock(slot->objectLock); + } while (duplicateObject != NULL); + return handle; +} + /* * add an object to a slot and session queue. These two functions * adopt the object. @@ -1848,23 +1879,13 @@ sftk_FreeContext(SFTKSessionContext *context) } /* - * create a new nession. NOTE: The session handle is not set, and the + * Init a new session. NOTE: The session handle is not set, and the * session is not added to the slot's session queue. */ -SFTKSession * -sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, - CK_FLAGS flags) +CK_RV +sftk_InitSession(SFTKSession *session, SFTKSlot *slot, CK_SLOT_ID slotID, + CK_NOTIFY notify, CK_VOID_PTR pApplication, CK_FLAGS flags) { - SFTKSession *session; - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); - - if (slot == NULL) - return NULL; - - session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession)); - if (session == NULL) - return NULL; - session->next = session->prev = NULL; session->enc_context = NULL; session->hash_context = NULL; @@ -1873,8 +1894,7 @@ sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, session->objectIDCount = 1; session->objectLock = PZ_NewLock(nssILockObject); if (session->objectLock == NULL) { - PORT_Free(session); - return NULL; + return CKR_HOST_MEMORY; } session->objects[0] = NULL; @@ -1887,12 +1907,38 @@ sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, sftk_update_state(slot, session); /* no ops completed yet, so the last one couldn't be a FIPS op */ session->lastOpWasFIPS = PR_FALSE; + return CKR_OK; +} + +/* + * Create a new session and init it. + */ +SFTKSession * +sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, + CK_FLAGS flags) +{ + SFTKSession *session; + SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); + CK_RV crv; + + if (slot == NULL) + return NULL; + + session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession)); + if (session == NULL) + return NULL; + + crv = sftk_InitSession(session, slot, slotID, notify, pApplication, flags); + if (crv != CKR_OK) { + PORT_Free(session); + return NULL; + } return session; } /* free all the data associated with a session. */ void -sftk_DestroySession(SFTKSession *session) +sftk_ClearSession(SFTKSession *session) { SFTKObjectList *op, *next; @@ -1918,6 +1964,13 @@ sftk_DestroySession(SFTKSession *session) if (session->search) { sftk_FreeSearch(session->search); } +} + +/* free the data associated with the session, and the session */ +void +sftk_DestroySession(SFTKSession *session) +{ + sftk_ClearSession(session); PORT_Free(session); } @@ -2386,3 +2439,70 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, CK_ATTRIBUTE_TYPE op, return PR_FALSE; #endif } + +/* + * create the FIPS Validation objects. If the vendor + * doesn't supply an NSS_FIPS_MODULE_ID, at compile time, + * then we assumethis is an unvalidated module. + */ +CK_RV +sftk_CreateValidationObjects(SFTKSlot *slot) +{ + const char *module_id; + int module_id_len; + CK_RV crv = CKR_OK; + /* we currently use vendor specific values until the validation + * objects are approved for PKCS #11 v3.2. */ + CK_OBJECT_CLASS cko_validation = CKO_NSS_VALIDATION; + CK_NSS_VALIDATION_TYPE ckv_fips = CKV_NSS_FIPS_140; + CK_VERSION fips_version = { 3, 0 }; /* FIPS-140-3 */ + CK_ULONG fips_level = 1; /* or 2 if you validated at level 2 */ + +#ifndef NSS_FIPS_MODULE_ID +#define NSS_FIPS_MODULE_ID "Generic NSS " SOFTOKEN_VERSION " Unvalidated" +#endif + module_id = NSS_FIPS_MODULE_ID; + module_id_len = sizeof(NSS_FIPS_MODULE_ID) - 1; + SFTKObject *object; + + object = sftk_NewObject(slot); /* fill in the handle later */ + if (object == NULL) { + return CKR_HOST_MEMORY; + } + object->isFIPS = PR_FALSE; + + crv = sftk_AddAttributeType(object, CKA_CLASS, + &cko_validation, sizeof(cko_validation)); + if (crv != CKR_OK) { + goto loser; + } + crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_TYPE, + &ckv_fips, sizeof(ckv_fips)); + if (crv != CKR_OK) { + goto loser; + } + crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_VERSION, + &fips_version, sizeof(fips_version)); + if (crv != CKR_OK) { + goto loser; + } + crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_LEVEL, + &fips_level, sizeof(fips_level)); + if (crv != CKR_OK) { + goto loser; + } + crv = sftk_AddAttributeType(object, CKA_NSS_VALIDATION_MODULE_ID, + module_id, module_id_len); + if (crv != CKR_OK) { + goto loser; + } + + /* future, fill in validation certificate information from a supplied + * pointer to a config file */ + object->handle = sftk_getNextHandle(slot); + object->slot = slot; + sftk_AddObject(&slot->moduleObjects, object); +loser: + sftk_FreeObject(object); + return crv; +} diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index 68137ac87362..d34d58b32633 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -17,11 +17,11 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.72" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.73" SOFTOKEN_ECC_STRING " Beta" #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 72 +#define SOFTOKEN_VMINOR 73 #define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VBUILD 0 -#define SOFTOKEN_BETA PR_FALSE +#define SOFTOKEN_BETA PR_TRUE #endif /* _SOFTKVER_H_ */ diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index 361c50600e6f..f798af90e90d 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -19,12 +19,12 @@ * The format of the version string should be * ".[.[.]][ ]" */ -#define NSSUTIL_VERSION "3.72" +#define NSSUTIL_VERSION "3.73 Beta" #define NSSUTIL_VMAJOR 3 -#define NSSUTIL_VMINOR 72 +#define NSSUTIL_VMINOR 73 #define NSSUTIL_VPATCH 0 #define NSSUTIL_VBUILD 0 -#define NSSUTIL_BETA PR_FALSE +#define NSSUTIL_BETA PR_TRUE SEC_BEGIN_PROTOS diff --git a/security/nss/lib/util/pkcs11n.h b/security/nss/lib/util/pkcs11n.h index 9a8126a82823..cb7672048a6e 100644 --- a/security/nss/lib/util/pkcs11n.h +++ b/security/nss/lib/util/pkcs11n.h @@ -38,6 +38,9 @@ #define CKO_NSS_BUILTIN_ROOT_LIST (CKO_NSS + 4) #define CKO_NSS_NEWSLOT (CKO_NSS + 5) #define CKO_NSS_DELSLOT (CKO_NSS + 6) +#define CKO_NSS_VALIDATION (CKO_NSS + 7) + +#define CKV_NSS_FIPS_140 (CKO_NSS + 1) /* * NSS-defined key types @@ -99,6 +102,11 @@ #define CKA_NSS_SERVER_DISTRUST_AFTER (CKA_NSS + 35) #define CKA_NSS_EMAIL_DISTRUST_AFTER (CKA_NSS + 36) +#define CKA_NSS_VALIDATION_TYPE (CKA_NSS + 36) +#define CKA_NSS_VALIDATION_VERSION (CKA_NSS + 37) +#define CKA_NSS_VALIDATION_LEVEL (CKA_NSS + 38) +#define CKA_NSS_VALIDATION_MODULE_ID (CKA_NSS + 39) + /* * Trust attributes: * @@ -344,6 +352,9 @@ typedef struct CK_NSS_AEAD_PARAMS { #define CKR_NSS_CERTDB_FAILED (CKR_NSS + 1) #define CKR_NSS_KEYDB_FAILED (CKR_NSS + 2) +/* NSS specific types */ +typedef CK_ULONG CK_NSS_VALIDATION_TYPE; + /* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms. See RFC 5869. diff --git a/security/nss/mach b/security/nss/mach index 7c45990f0f65..a3ef38dac410 100755 --- a/security/nss/mach +++ b/security/nss/mach @@ -41,277 +41,6 @@ def run_tests(test, cycles="standard", env={}, silent=False): subprocess.check_call(command, env=os_env, stdout=stdout, stderr=stderr) -class coverityAction(argparse.Action): - - def get_coverity_remote_cfg(self): - secret_name = 'project/relman/coverity-nss' - secrets_url = 'http://taskcluster/secrets/v1/secret/{}'.format(secret_name) - - print('Using symbol upload token from the secrets service: "{}"'. - format(secrets_url)) - - import requests - res = requests.get(secrets_url) - res.raise_for_status() - secret = res.json() - cov_config = secret['secret'] if 'secret' in secret else None - - if cov_config is None: - print('Ill formatted secret for Coverity. Aborting analysis.') - return None - - return cov_config - - def get_coverity_local_cfg(self, path): - try: - import yaml - file_handler = open(path) - config = yaml.safe_load(file_handler) - except Exception: - print('Unable to load coverity config from {}'.format(path)) - return None - return config - - def get_cov_config(self, path): - cov_config = None - if self.local_config: - cov_config = self.get_coverity_local_cfg(path) - else: - cov_config = self.get_coverity_remote_cfg() - - if cov_config is None: - print('Unable to load Coverity config.') - return 1 - - self.cov_analysis_url = cov_config.get('package_url') - self.cov_package_name = cov_config.get('package_name') - self.cov_url = cov_config.get('server_url') - self.cov_port = cov_config.get('server_port') - self.cov_auth = cov_config.get('auth_key') - self.cov_package_ver = cov_config.get('package_ver') - self.cov_full_stack = cov_config.get('full_stack', False) - - return 0 - - def download_coverity(self): - if self.cov_url is None or self.cov_port is None or self.cov_analysis_url is None or self.cov_auth is None: - print('Missing Coverity config options!') - return 1 - - COVERITY_CONFIG = ''' - { - "type": "Coverity configuration", - "format_version": 1, - "settings": { - "server": { - "host": "%s", - "port": %s, - "ssl" : true, - "on_new_cert" : "trust", - "auth_key_file": "%s" - }, - "stream": "NSS", - "cov_run_desktop": { - "build_cmd": ["%s"], - "clean_cmd": ["%s", "-cc"], - } - } - } - ''' - # Generate the coverity.conf and auth files - build_cmd = os.path.join(cwd, 'build.sh') - cov_auth_path = os.path.join(self.cov_state_path, 'auth') - cov_setup_path = os.path.join(self.cov_state_path, 'coverity.conf') - cov_conf = COVERITY_CONFIG % (self.cov_url, self.cov_port, cov_auth_path, build_cmd, build_cmd) - - def download(artifact_url, target): - import requests - resp = requests.get(artifact_url, verify=False, stream=True) - resp.raise_for_status() - - # Extract archive into destination - with tarfile.open(fileobj=io.BytesIO(resp.content)) as tar: - tar.extractall(target) - - download(self.cov_analysis_url, self.cov_state_path) - - with open(cov_auth_path, 'w') as f: - f.write(self.cov_auth) - - # Modify it's permission to 600 - os.chmod(cov_auth_path, 0o600) - - with open(cov_setup_path, 'a') as f: - f.write(cov_conf) - - def setup_coverity(self, config_path, storage_path=None, force_download=True): - rc = self.get_cov_config(config_path) - - if rc != 0: - return rc - - if storage_path is None: - # If storage_path is None we set the context of the coverity into the cwd. - storage_path = cwd - - self.cov_state_path = os.path.join(storage_path, "coverity") - - if force_download is True or not os.path.exists(self.cov_state_path): - shutil.rmtree(self.cov_state_path, ignore_errors=True) - os.mkdir(self.cov_state_path) - - # Download everything that we need for Coverity from out private instance - self.download_coverity() - - self.cov_path = os.path.join(self.cov_state_path, self.cov_package_name) - self.cov_run_desktop = os.path.join(self.cov_path, 'bin', 'cov-run-desktop') - self.cov_translate = os.path.join(self.cov_path, 'bin', 'cov-translate') - self.cov_configure = os.path.join(self.cov_path, 'bin', 'cov-configure') - self.cov_work_path = os.path.join(self.cov_state_path, 'data-coverity') - self.cov_idir_path = os.path.join(self.cov_work_path, self.cov_package_ver, 'idir') - - if not os.path.exists(self.cov_path) or \ - not os.path.exists(self.cov_run_desktop) or \ - not os.path.exists(self.cov_translate) or \ - not os.path.exists(self.cov_configure): - print('Missing Coverity in {}'.format(self.cov_path)) - return 1 - - return 0 - - def run_process(self, args, cwd=cwd): - proc = subprocess.Popen(args, cwd=cwd) - status = None - while status is None: - try: - status = proc.wait() - except KeyboardInterrupt: - pass - return status - - def cov_is_file_in_source(self, abs_path): - if os.path.islink(abs_path): - abs_path = os.path.realpath(abs_path) - return abs_path - - def dump_cov_artifact(self, cov_results, source, output): - import json - - def relpath(path): - '''Build path relative to repository root''' - if path.startswith(cwd): - return os.path.relpath(path, cwd) - return path - - # Parse Coverity json into structured issues - with open(cov_results) as f: - result = json.load(f) - - # Parse the issues to a standard json format - issues_dict = {'files': {}} - - files_list = issues_dict['files'] - - def build_element(issue): - # We look only for main event - event_path = next((event for event in issue['events'] if event['main'] is True), None) - - dict_issue = { - 'line': issue['mainEventLineNumber'], - 'flag': issue['checkerName'], - 'message': event_path['eventDescription'], - 'extra': { - 'category': issue['checkerProperties']['category'], - 'stateOnServer': issue['stateOnServer'], - 'stack': [] - } - } - - # Embed all events into extra message - for event in issue['events']: - dict_issue['extra']['stack'].append({'file_path': relpath(event['strippedFilePathname']), - 'line_number': event['lineNumber'], - 'path_type': event['eventTag'], - 'description': event['eventDescription']}) - - return dict_issue - - for issue in result['issues']: - path = self.cov_is_file_in_source(issue['strippedMainEventFilePathname']) - if path is None: - # Since we skip a result we should log it - print('Skipping CID: {0} from file: {1} since it\'s not related with the current patch.'.format( - issue['stateOnServer']['cid'], issue['strippedMainEventFilePathname'])) - continue - # If path does not start with `cwd` skip it - if not path.startswith(cwd): - continue - path = relpath(path) - if path in files_list: - files_list[path]['warnings'].append(build_element(issue)) - else: - files_list[path] = {'warnings': [build_element(issue)]} - - with open(output, 'w') as f: - json.dump(issues_dict, f) - - def mutate_paths(self, paths): - for index in xrange(len(paths)): - paths[index] = os.path.abspath(paths[index]) - - def __call__(self, parser, args, paths, option_string=None): - self.local_config = True - config_path = args.config - storage_path = args.storage - - have_paths = True - if len(paths) == 0: - have_paths = False - print('No files have been specified for analysis, running Coverity on the entire project.') - - self.mutate_paths(paths) - - if config_path is None: - self.local_config = False - print('No coverity config path has been specified, so running in automation.') - if 'NSS_AUTOMATION' not in os.environ: - print('Coverity based static-analysis cannot be ran outside automation.') - return 1 - - rc = self.setup_coverity(config_path, storage_path, args.force) - if rc != 0: - return 1 - - # First run cov-run-desktop --setup in order to setup the analysis env - cmd = [self.cov_run_desktop, '--setup'] - print('Running {} --setup'.format(self.cov_run_desktop)) - - rc = self.run_process(args=cmd, cwd=self.cov_path) - - if rc != 0: - print('Running {} --setup failed!'.format(self.cov_run_desktop)) - return rc - - cov_result = os.path.join(self.cov_state_path, 'cov-results.json') - - # Once the capture is performed we need to do the actual Coverity Desktop analysis - if have_paths: - cmd = [self.cov_run_desktop, '--json-output-v6', cov_result] + paths - else: - cmd = [self.cov_run_desktop, '--json-output-v6', cov_result, '--analyze-captured-source'] - - print('Running Coverity Analysis for {}'.format(cmd)) - - rc = self.run_process(cmd, cwd=self.cov_state_path) - - if rc != 0: - print('Coverity Analysis failed!') - - # On automation, like try, we want to build an artifact with the results. - if 'NSS_AUTOMATION' in os.environ: - self.dump_cov_artifact(cov_result, cov_result, "/home/worker/nss/coverity/coverity.json") - - class cfAction(argparse.Action): docker_command = None restorecon = None @@ -535,31 +264,6 @@ def parse_arguments(): help="Specify files or directories to run clang-format on", action=cfAction) - parser_sa = subparsers.add_parser( - 'static-analysis', - help=""" - Run static-analysis tools based on coverity. - - By default this runs only on automation and provides a list of issues that - are only present locally. - """) - parser_sa.add_argument( - '--config', help='Path to Coverity config file. Only used for local runs.', - default=None) - parser_sa.add_argument( - '--storage', help=""" - Path where to store Coverity binaries and results. If none, the base repository will be used. - """, - default=None) - parser_sa.add_argument( - '--force', help='Force the re-download of the coverity artefact.', - action='store_true') - parser_sa.add_argument( - '', - nargs='*', - help="Specify files to run Coverity on. If no files are specified the analysis will check the entire project.", - action=coverityAction) - parser_test = subparsers.add_parser( 'tests', help='Run tests through tests/all.sh.') tests = [ diff --git a/security/nss/nss.gyp b/security/nss/nss.gyp index 1b917386c029..dfc723259cdc 100644 --- a/security/nss/nss.gyp +++ b/security/nss/nss.gyp @@ -131,6 +131,7 @@ 'cmd/smimetools/smimetools.gyp:cmsutil', 'cmd/ssltap/ssltap.gyp:ssltap', 'cmd/symkeyutil/symkeyutil.gyp:symkeyutil', + 'cmd/validation/validation.gyp:validation', 'nss-tool/nss_tool.gyp:nss', 'nss-tool/nss_tool.gyp:hw-support', ],