951 lines
37 KiB
Diff
951 lines
37 KiB
Diff
# HG changeset patch
|
|
# User Kai Engert <kaie@kuix.de>
|
|
# Date 1531823374 -7200
|
|
# Tue Jul 17 12:29:34 2018 +0200
|
|
# Node ID a6d6a56b6e39558e9b6b0b32009a46ea78040bfd
|
|
# Parent 1f58a4995451ac0bdb79b5e3117b365edec3af2d
|
|
Bug 1474887, nss-policy-check: a tool to check a NSS policy configuration for errors, r=rrelyea
|
|
|
|
diff --git a/automation/abi-check/expected-report-libnssutil3.so.txt b/automation/abi-check/expected-report-libnssutil3.so.txt
|
|
--- a/automation/abi-check/expected-report-libnssutil3.so.txt
|
|
+++ b/automation/abi-check/expected-report-libnssutil3.so.txt
|
|
@@ -0,0 +1,5 @@
|
|
+
|
|
+1 Added function:
|
|
+
|
|
+ 'function char* NSSUTIL_AddNSSFlagToModuleSpec(char*, char*)' {NSSUTIL_AddNSSFlagToModuleSpec@@NSSUTIL_3.39}
|
|
+
|
|
diff --git a/automation/taskcluster/graph/src/extend.js b/automation/taskcluster/graph/src/extend.js
|
|
--- a/automation/taskcluster/graph/src/extend.js
|
|
+++ b/automation/taskcluster/graph/src/extend.js
|
|
@@ -928,6 +928,9 @@ function scheduleTests(task_build, task_
|
|
queue.scheduleTask(merge(no_cert_base, {
|
|
name: "SDR tests", symbol: "SDR", tests: "sdr"
|
|
}));
|
|
+ queue.scheduleTask(merge(no_cert_base, {
|
|
+ name: "Policy tests", symbol: "Policy", tests: "policy"
|
|
+ }));
|
|
|
|
// Schedule tests that need certificates.
|
|
let cert_base = merge(test_base, {parent: task_cert});
|
|
diff --git a/automation/taskcluster/graph/src/try_syntax.js b/automation/taskcluster/graph/src/try_syntax.js
|
|
--- a/automation/taskcluster/graph/src/try_syntax.js
|
|
+++ b/automation/taskcluster/graph/src/try_syntax.js
|
|
@@ -37,7 +37,7 @@ function parseOptions(opts) {
|
|
let aliases = {"gtests": "gtest"};
|
|
let allUnitTests = ["bogo", "crmf", "chains", "cipher", "db", "ec", "fips",
|
|
"gtest", "interop", "lowhash", "merge", "sdr", "smime", "tools",
|
|
- "ssl", "mpi", "scert", "spki"];
|
|
+ "ssl", "mpi", "scert", "spki", "policy"];
|
|
let unittests = intersect(opts.unittests.split(/\s*,\s*/).map(t => {
|
|
return aliases[t] || t;
|
|
}), allUnitTests);
|
|
diff --git a/cmd/manifest.mn b/cmd/manifest.mn
|
|
--- a/cmd/manifest.mn
|
|
+++ b/cmd/manifest.mn
|
|
@@ -47,6 +47,7 @@ NSS_SRCDIRS = \
|
|
listsuites \
|
|
makepqg \
|
|
multinit \
|
|
+ nss-policy-check \
|
|
ocspclnt \
|
|
ocspresp \
|
|
oidcalc \
|
|
diff --git a/cmd/nss-policy-check/Makefile b/cmd/nss-policy-check/Makefile
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/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/cmd/nss-policy-check/manifest.mn b/cmd/nss-policy-check/manifest.mn
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/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/cmd/nss-policy-check/nss-policy-check.c b/cmd/nss-policy-check/nss-policy-check.c
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/cmd/nss-policy-check/nss-policy-check.c
|
|
@@ -0,0 +1,205 @@
|
|
+/* 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;
|
|
+ }
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ if (fullPathLen >= PATH_MAX) {
|
|
+ fprintf(stderr, "Error: filename parameter is too long\n");
|
|
+ result = 2;
|
|
+ goto loser;
|
|
+ }
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+ if (result == 2) {
|
|
+ fprintf(stderr, "NSS-POLICY-FAIL\n");
|
|
+ } else if (result == 1) {
|
|
+ fprintf(stderr, "NSS-POLICY-WARN\n");
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
diff --git a/cmd/nss-policy-check/nss-policy-check.gyp b/cmd/nss-policy-check/nss-policy-check.gyp
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/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/lib/nss/nssinit.c b/lib/nss/nssinit.c
|
|
--- a/lib/nss/nssinit.c
|
|
+++ b/lib/nss/nssinit.c
|
|
@@ -54,7 +54,7 @@ nss_mktemp(char *path)
|
|
|
|
#define NSS_MAX_FLAG_SIZE sizeof("readOnly") + sizeof("noCertDB") + \
|
|
sizeof("noModDB") + sizeof("forceOpen") + sizeof("passwordRequired") + \
|
|
- sizeof("optimizeSpace")
|
|
+ sizeof("optimizeSpace") + sizeof("printPolicyFeedback")
|
|
#define NSS_DEFAULT_MOD_NAME "NSS Internal Module"
|
|
|
|
static char *
|
|
diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c
|
|
--- a/lib/pk11wrap/pk11pars.c
|
|
+++ b/lib/pk11wrap/pk11pars.c
|
|
@@ -194,7 +194,7 @@ typedef struct {
|
|
* This table should be merged with the SECOID table.
|
|
*/
|
|
#define CIPHER_NAME(x) x, (sizeof(x) - 1)
|
|
-static const oidValDef algOptList[] = {
|
|
+static const oidValDef curveOptList[] = {
|
|
/* Curves */
|
|
{ CIPHER_NAME("PRIME192V1"), SEC_OID_ANSIX962_EC_PRIME192V1,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
@@ -316,7 +316,9 @@ static const oidValDef algOptList[] = {
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
{ CIPHER_NAME("SECT571R1"), SEC_OID_SECG_EC_SECT571R1,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
+};
|
|
|
|
+static const oidValDef hashOptList[] = {
|
|
/* Hashes */
|
|
{ CIPHER_NAME("MD2"), SEC_OID_MD2,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
@@ -334,7 +336,9 @@ static const oidValDef algOptList[] = {
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
{ CIPHER_NAME("SHA512"), SEC_OID_SHA512,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
+};
|
|
|
|
+static const oidValDef macOptList[] = {
|
|
/* MACs */
|
|
{ CIPHER_NAME("HMAC-SHA1"), SEC_OID_HMAC_SHA1, NSS_USE_ALG_IN_SSL },
|
|
{ CIPHER_NAME("HMAC-SHA224"), SEC_OID_HMAC_SHA224, NSS_USE_ALG_IN_SSL },
|
|
@@ -342,7 +346,9 @@ static const oidValDef algOptList[] = {
|
|
{ CIPHER_NAME("HMAC-SHA384"), SEC_OID_HMAC_SHA384, NSS_USE_ALG_IN_SSL },
|
|
{ CIPHER_NAME("HMAC-SHA512"), SEC_OID_HMAC_SHA512, NSS_USE_ALG_IN_SSL },
|
|
{ CIPHER_NAME("HMAC-MD5"), SEC_OID_HMAC_MD5, NSS_USE_ALG_IN_SSL },
|
|
+};
|
|
|
|
+static const oidValDef cipherOptList[] = {
|
|
/* Ciphers */
|
|
{ CIPHER_NAME("AES128-CBC"), SEC_OID_AES_128_CBC, NSS_USE_ALG_IN_SSL },
|
|
{ CIPHER_NAME("AES192-CBC"), SEC_OID_AES_192_CBC, NSS_USE_ALG_IN_SSL },
|
|
@@ -362,7 +368,9 @@ static const oidValDef algOptList[] = {
|
|
{ CIPHER_NAME("RC2"), SEC_OID_RC2_CBC, NSS_USE_ALG_IN_SSL },
|
|
{ CIPHER_NAME("RC4"), SEC_OID_RC4, NSS_USE_ALG_IN_SSL },
|
|
{ CIPHER_NAME("IDEA"), SEC_OID_IDEA_CBC, NSS_USE_ALG_IN_SSL },
|
|
+};
|
|
|
|
+static const oidValDef kxOptList[] = {
|
|
/* Key exchange */
|
|
{ CIPHER_NAME("RSA"), SEC_OID_TLS_RSA, NSS_USE_ALG_IN_SSL_KX },
|
|
{ CIPHER_NAME("RSA-EXPORT"), SEC_OID_TLS_RSA_EXPORT, NSS_USE_ALG_IN_SSL_KX },
|
|
@@ -376,6 +384,20 @@ static const oidValDef algOptList[] = {
|
|
{ CIPHER_NAME("ECDH-RSA"), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX },
|
|
};
|
|
|
|
+typedef struct {
|
|
+ const oidValDef *list;
|
|
+ PRUint32 entries;
|
|
+ const char *description;
|
|
+} algListsDef;
|
|
+
|
|
+static const algListsDef algOptLists[] = {
|
|
+ { curveOptList, PR_ARRAY_SIZE(curveOptList), "ECC" },
|
|
+ { hashOptList, PR_ARRAY_SIZE(hashOptList), "HASH" },
|
|
+ { macOptList, PR_ARRAY_SIZE(macOptList), "MAC" },
|
|
+ { cipherOptList, PR_ARRAY_SIZE(cipherOptList), "CIPHER" },
|
|
+ { kxOptList, PR_ARRAY_SIZE(kxOptList), "OTHER-KX" },
|
|
+};
|
|
+
|
|
static const optionFreeDef sslOptList[] = {
|
|
/* Versions */
|
|
{ CIPHER_NAME("SSL2.0"), 0x002 },
|
|
@@ -447,7 +469,8 @@ secmod_ArgGetSubValue(const char *cipher
|
|
}
|
|
|
|
static PRUint32
|
|
-secmod_parsePolicyValue(const char *policyFlags, int policyLength)
|
|
+secmod_parsePolicyValue(const char *policyFlags, int policyLength,
|
|
+ PRBool printPolicyFeedback)
|
|
{
|
|
const char *flag, *currentString;
|
|
PRUint32 flags = 0;
|
|
@@ -456,6 +479,7 @@ secmod_parsePolicyValue(const char *poli
|
|
for (currentString = policyFlags; currentString &&
|
|
currentString < policyFlags + policyLength;) {
|
|
int length;
|
|
+ PRBool unknown = PR_TRUE;
|
|
flag = secmod_ArgGetSubValue(currentString, ',', ':', &length,
|
|
¤tString);
|
|
if (length == 0) {
|
|
@@ -467,41 +491,49 @@ secmod_parsePolicyValue(const char *poli
|
|
if ((policy->name_size == length) &&
|
|
PORT_Strncasecmp(policy->name, flag, name_size) == 0) {
|
|
flags |= policy->flag;
|
|
+ unknown = PR_FALSE;
|
|
break;
|
|
}
|
|
}
|
|
+ if (unknown && printPolicyFeedback) {
|
|
+ PR_SetEnv("NSS_POLICY_FAIL=1");
|
|
+ fprintf(stderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
|
|
+ policyLength, policyFlags, length, flag);
|
|
+ }
|
|
}
|
|
return flags;
|
|
}
|
|
|
|
/* allow symbolic names for values. The only ones currently defines or
|
|
* SSL protocol versions. */
|
|
-static PRInt32
|
|
-secmod_getPolicyOptValue(const char *policyValue, int policyValueLength)
|
|
+static SECStatus
|
|
+secmod_getPolicyOptValue(const char *policyValue, int policyValueLength,
|
|
+ PRInt32 *result)
|
|
{
|
|
PRInt32 val = atoi(policyValue);
|
|
int i;
|
|
|
|
if ((val != 0) || (*policyValue == '0')) {
|
|
- return val;
|
|
+ *result = val;
|
|
+ return SECSuccess;
|
|
}
|
|
for (i = 0; i < PR_ARRAY_SIZE(sslOptList); i++) {
|
|
if (policyValueLength == sslOptList[i].name_size &&
|
|
PORT_Strncasecmp(sslOptList[i].name, policyValue,
|
|
sslOptList[i].name_size) == 0) {
|
|
- val = sslOptList[i].option;
|
|
- break;
|
|
+ *result = sslOptList[i].option;
|
|
+ return SECSuccess;
|
|
}
|
|
}
|
|
- return val;
|
|
+ return SECFailure;
|
|
}
|
|
|
|
static SECStatus
|
|
-secmod_applyCryptoPolicy(const char *policyString,
|
|
- PRBool allow)
|
|
+secmod_applyCryptoPolicy(const char *policyString, PRBool allow,
|
|
+ PRBool printPolicyFeedback)
|
|
{
|
|
const char *cipher, *currentString;
|
|
- unsigned i;
|
|
+ unsigned i, j;
|
|
SECStatus rv = SECSuccess;
|
|
PRBool unknown;
|
|
|
|
@@ -526,56 +558,63 @@ secmod_applyCryptoPolicy(const char *pol
|
|
/* disable or enable all options by default */
|
|
PRUint32 value = 0;
|
|
if (newValue) {
|
|
- value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1);
|
|
+ value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1, printPolicyFeedback);
|
|
}
|
|
- for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
|
|
- PRUint32 enable, disable;
|
|
- if (!newValue) {
|
|
- value = algOptList[i].val;
|
|
+ for (i = 0; i < PR_ARRAY_SIZE(algOptLists); i++) {
|
|
+ const algListsDef *algOptList = &algOptLists[i];
|
|
+ for (j = 0; j < algOptList->entries; j++) {
|
|
+ PRUint32 enable, disable;
|
|
+ if (!newValue) {
|
|
+ value = algOptList->list[j].val;
|
|
+ }
|
|
+ if (allow) {
|
|
+ enable = value;
|
|
+ disable = 0;
|
|
+ } else {
|
|
+ enable = 0;
|
|
+ disable = value;
|
|
+ }
|
|
+ NSS_SetAlgorithmPolicy(algOptList->list[j].oid, enable, disable);
|
|
}
|
|
- if (allow) {
|
|
- enable = value;
|
|
- disable = 0;
|
|
- } else {
|
|
- enable = 0;
|
|
- disable = value;
|
|
- }
|
|
- NSS_SetAlgorithmPolicy(algOptList[i].oid, enable, disable);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
- for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
|
|
- const oidValDef *algOpt = &algOptList[i];
|
|
- unsigned name_size = algOpt->name_size;
|
|
- PRBool newOption = PR_FALSE;
|
|
+ for (i = 0; i < PR_ARRAY_SIZE(algOptLists); i++) {
|
|
+ const algListsDef *algOptList = &algOptLists[i];
|
|
+ for (j = 0; j < algOptList->entries; j++) {
|
|
+ const oidValDef *algOpt = &algOptList->list[j];
|
|
+ unsigned name_size = algOpt->name_size;
|
|
+ PRBool newOption = PR_FALSE;
|
|
|
|
- if ((length >= name_size) && (cipher[name_size] == '/')) {
|
|
- newOption = PR_TRUE;
|
|
- }
|
|
- if ((newOption || algOpt->name_size == length) &&
|
|
- PORT_Strncasecmp(algOpt->name, cipher, name_size) == 0) {
|
|
- PRUint32 value = algOpt->val;
|
|
- PRUint32 enable, disable;
|
|
- if (newOption) {
|
|
- value = secmod_parsePolicyValue(&cipher[name_size] + 1,
|
|
- length - name_size - 1);
|
|
+ if ((length >= name_size) && (cipher[name_size] == '/')) {
|
|
+ newOption = PR_TRUE;
|
|
}
|
|
- if (allow) {
|
|
- enable = value;
|
|
- disable = 0;
|
|
- } else {
|
|
- enable = 0;
|
|
- disable = value;
|
|
+ if ((newOption || algOpt->name_size == length) &&
|
|
+ PORT_Strncasecmp(algOpt->name, cipher, name_size) == 0) {
|
|
+ PRUint32 value = algOpt->val;
|
|
+ PRUint32 enable, disable;
|
|
+ if (newOption) {
|
|
+ value = secmod_parsePolicyValue(&cipher[name_size] + 1,
|
|
+ length - name_size - 1,
|
|
+ printPolicyFeedback);
|
|
+ }
|
|
+ if (allow) {
|
|
+ enable = value;
|
|
+ disable = 0;
|
|
+ } else {
|
|
+ enable = 0;
|
|
+ disable = value;
|
|
+ }
|
|
+ rv = NSS_SetAlgorithmPolicy(algOpt->oid, enable, disable);
|
|
+ if (rv != SECSuccess) {
|
|
+ /* could not enable option */
|
|
+ /* NSS_SetAlgorithPolicy should have set the error code */
|
|
+ return SECFailure;
|
|
+ }
|
|
+ unknown = PR_FALSE;
|
|
+ break;
|
|
}
|
|
- rv = NSS_SetAlgorithmPolicy(algOpt->oid, enable, disable);
|
|
- if (rv != SECSuccess) {
|
|
- /* could not enable option */
|
|
- /* NSS_SetAlgorithPolicy should have set the error code */
|
|
- return SECFailure;
|
|
- }
|
|
- unknown = PR_FALSE;
|
|
- break;
|
|
}
|
|
}
|
|
if (!unknown) {
|
|
@@ -588,9 +627,19 @@ secmod_applyCryptoPolicy(const char *pol
|
|
|
|
if ((length > name_size) && cipher[name_size] == '=' &&
|
|
PORT_Strncasecmp(freeOpt->name, cipher, name_size) == 0) {
|
|
- PRInt32 val = secmod_getPolicyOptValue(&cipher[name_size + 1],
|
|
- length - name_size - 1);
|
|
-
|
|
+ PRInt32 val;
|
|
+ const char *policyValue = &cipher[name_size + 1];
|
|
+ int policyValueLength = length - name_size - 1;
|
|
+ rv = secmod_getPolicyOptValue(policyValue, policyValueLength,
|
|
+ &val);
|
|
+ if (rv != SECSuccess) {
|
|
+ if (printPolicyFeedback) {
|
|
+ PR_SetEnv("NSS_POLICY_FAIL=1");
|
|
+ fprintf(stderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
|
|
+ length, cipher, policyValueLength, policyValue);
|
|
+ }
|
|
+ return SECFailure;
|
|
+ }
|
|
rv = NSS_OptionSet(freeOpt->option, val);
|
|
if (rv != SECSuccess) {
|
|
/* could not enable option */
|
|
@@ -603,12 +652,83 @@ secmod_applyCryptoPolicy(const char *pol
|
|
break;
|
|
}
|
|
}
|
|
+
|
|
+ if (unknown && printPolicyFeedback) {
|
|
+ PR_SetEnv("NSS_POLICY_FAIL=1");
|
|
+ fprintf(stderr, "NSS-POLICY-FAIL %s: unknown identifier: %.*s\n",
|
|
+ allow ? "allow" : "disallow", length, cipher);
|
|
+ }
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
+static void
|
|
+secmod_sanityCheckCryptoPolicy(void)
|
|
+{
|
|
+ unsigned i, j;
|
|
+ SECStatus rv = SECSuccess;
|
|
+ unsigned num_kx_enabled = 0;
|
|
+ unsigned num_ssl_enabled = 0;
|
|
+ unsigned num_sig_enabled = 0;
|
|
+ unsigned enabledCount[PR_ARRAY_SIZE(algOptLists)];
|
|
+ const char *sWarn = "WARN";
|
|
+ const char *sInfo = "INFO";
|
|
+ PRBool haveWarning = PR_FALSE;
|
|
+
|
|
+ for (i = 0; i < PR_ARRAY_SIZE(algOptLists); i++) {
|
|
+ const algListsDef *algOptList = &algOptLists[i];
|
|
+ enabledCount[i] = 0;
|
|
+ for (j = 0; j < algOptList->entries; j++) {
|
|
+ const oidValDef *algOpt = &algOptList->list[j];
|
|
+ PRUint32 value;
|
|
+ PRBool anyEnabled = PR_FALSE;
|
|
+ rv = NSS_GetAlgorithmPolicy(algOpt->oid, &value);
|
|
+ if (rv != SECSuccess) {
|
|
+ PR_SetEnv("NSS_POLICY_FAIL=1");
|
|
+ fprintf(stderr, "NSS-POLICY-FAIL: internal failure with NSS_GetAlgorithmPolicy at %u\n", i);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if ((algOpt->val & NSS_USE_ALG_IN_SSL_KX) && (value & NSS_USE_ALG_IN_SSL_KX)) {
|
|
+ ++num_kx_enabled;
|
|
+ anyEnabled = PR_TRUE;
|
|
+ fprintf(stderr, "NSS-POLICY-INFO: %s is enabled for KX\n", algOpt->name);
|
|
+ }
|
|
+ if ((algOpt->val & NSS_USE_ALG_IN_SSL) && (value & NSS_USE_ALG_IN_SSL)) {
|
|
+ ++num_ssl_enabled;
|
|
+ anyEnabled = PR_TRUE;
|
|
+ fprintf(stderr, "NSS-POLICY-INFO: %s is enabled for SSL\n", algOpt->name);
|
|
+ }
|
|
+ if ((algOpt->val & NSS_USE_ALG_IN_CERT_SIGNATURE) && (value & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
|
|
+ ++num_sig_enabled;
|
|
+ anyEnabled = PR_TRUE;
|
|
+ fprintf(stderr, "NSS-POLICY-INFO: %s is enabled for CERT-SIGNATURE\n", algOpt->name);
|
|
+ }
|
|
+ if (anyEnabled) {
|
|
+ ++enabledCount[i];
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ fprintf(stderr, "NSS-POLICY-%s: NUMBER-OF-SSL-ALG-KX: %u\n", num_kx_enabled ? sInfo : sWarn, num_kx_enabled);
|
|
+ fprintf(stderr, "NSS-POLICY-%s: NUMBER-OF-SSL-ALG: %u\n", num_ssl_enabled ? sInfo : sWarn, num_ssl_enabled);
|
|
+ fprintf(stderr, "NSS-POLICY-%s: NUMBER-OF-CERT-SIG: %u\n", num_sig_enabled ? sInfo : sWarn, num_sig_enabled);
|
|
+ if (!num_kx_enabled || !num_ssl_enabled || !num_sig_enabled) {
|
|
+ haveWarning = PR_TRUE;
|
|
+ }
|
|
+ for (i = 0; i < PR_ARRAY_SIZE(algOptLists); i++) {
|
|
+ const algListsDef *algOptList = &algOptLists[i];
|
|
+ fprintf(stderr, "NSS-POLICY-%s: NUMBER-OF-%s: %u\n", enabledCount[i] ? sInfo : sWarn, algOptList->description, enabledCount[i]);
|
|
+ if (!enabledCount[i]) {
|
|
+ haveWarning = PR_TRUE;
|
|
+ }
|
|
+ }
|
|
+ if (haveWarning) {
|
|
+ PR_SetEnv("NSS_POLICY_WARN=1");
|
|
+ }
|
|
+}
|
|
+
|
|
static SECStatus
|
|
-secmod_parseCryptoPolicy(const char *policyConfig)
|
|
+secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback)
|
|
{
|
|
char *disallow, *allow;
|
|
SECStatus rv;
|
|
@@ -623,16 +743,26 @@ secmod_parseCryptoPolicy(const char *pol
|
|
return rv;
|
|
}
|
|
disallow = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
|
|
- rv = secmod_applyCryptoPolicy(disallow, PR_FALSE);
|
|
+ rv = secmod_applyCryptoPolicy(disallow, PR_FALSE, printPolicyFeedback);
|
|
if (disallow)
|
|
PORT_Free(disallow);
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
allow = NSSUTIL_ArgGetParamValue("allow", policyConfig);
|
|
- rv = secmod_applyCryptoPolicy(allow, PR_TRUE);
|
|
+ rv = secmod_applyCryptoPolicy(allow, PR_TRUE, printPolicyFeedback);
|
|
if (allow)
|
|
PORT_Free(allow);
|
|
+ if (rv != SECSuccess) {
|
|
+ return rv;
|
|
+ }
|
|
+ if (printPolicyFeedback) {
|
|
+ /* This helps to distinguish configurations that don't contain any
|
|
+ * policy config= statement. */
|
|
+ PR_SetEnv("NSS_POLICY_LOADED=1");
|
|
+ fprintf(stderr, "NSS-POLICY-INFO: LOADED-SUCCESSFULLY\n");
|
|
+ secmod_sanityCheckCryptoPolicy();
|
|
+ }
|
|
return rv;
|
|
}
|
|
|
|
@@ -649,11 +779,16 @@ SECMOD_CreateModuleEx(const char *librar
|
|
char *slotParams, *ciphers;
|
|
/* pk11pars.h still does not have const char * interfaces */
|
|
char *nssc = (char *)nss;
|
|
+ PRBool printPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nssc);
|
|
|
|
- rv = secmod_parseCryptoPolicy(config);
|
|
+ rv = secmod_parseCryptoPolicy(config, printPolicyFeedback);
|
|
|
|
/* do not load the module if policy parsing fails */
|
|
if (rv != SECSuccess) {
|
|
+ if (printPolicyFeedback) {
|
|
+ PR_SetEnv("NSS_POLICY_FAIL=1");
|
|
+ fprintf(stderr, "NSS-POLICY-FAIL: policy config parsing failed, not loading module %s\n", moduleName);
|
|
+ }
|
|
return NULL;
|
|
}
|
|
|
|
@@ -1647,6 +1782,7 @@ SECMOD_LoadModule(char *modulespec, SECM
|
|
SECMODModule *module = NULL;
|
|
SECMODModule *oldModule = NULL;
|
|
SECStatus rv;
|
|
+ PRBool forwardPolicyFeedback = PR_FALSE;
|
|
|
|
/* initialize the underlying module structures */
|
|
SECMOD_Init();
|
|
@@ -1659,6 +1795,7 @@ SECMOD_LoadModule(char *modulespec, SECM
|
|
}
|
|
|
|
module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config);
|
|
+ forwardPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
|
|
if (library)
|
|
PORT_Free(library);
|
|
if (moduleName)
|
|
@@ -1721,7 +1858,15 @@ SECMOD_LoadModule(char *modulespec, SECM
|
|
rv = SECFailure;
|
|
break;
|
|
}
|
|
- child = SECMOD_LoadModule(*index, module, PR_TRUE);
|
|
+ if (!forwardPolicyFeedback) {
|
|
+ child = SECMOD_LoadModule(*index, module, PR_TRUE);
|
|
+ } else {
|
|
+ /* Add printPolicyFeedback to the nss flags */
|
|
+ char *specWithForwards =
|
|
+ NSSUTIL_AddNSSFlagToModuleSpec(*index, "printPolicyFeedback");
|
|
+ child = SECMOD_LoadModule(specWithForwards, module, PR_TRUE);
|
|
+ PORT_Free(specWithForwards);
|
|
+ }
|
|
if (!child)
|
|
break;
|
|
if (child->isCritical && !child->loaded) {
|
|
diff --git a/nss.gyp b/nss.gyp
|
|
--- a/nss.gyp
|
|
+++ b/nss.gyp
|
|
@@ -135,6 +135,7 @@
|
|
'cmd/listsuites/listsuites.gyp:listsuites',
|
|
'cmd/makepqg/makepqg.gyp:makepqg',
|
|
'cmd/multinit/multinit.gyp:multinit',
|
|
+ 'cmd/nss-policy-check/nss-policy-check.gyp:nss-policy-check',
|
|
'cmd/ocspclnt/ocspclnt.gyp:ocspclnt',
|
|
'cmd/ocspresp/ocspresp.gyp:ocspresp',
|
|
'cmd/oidcalc/oidcalc.gyp:oidcalc',
|
|
diff --git a/readme.md b/readme.md
|
|
--- a/readme.md
|
|
+++ b/readme.md
|
|
@@ -97,7 +97,7 @@ e.g. `NSS_TESTS=ssl_gtests ./all.sh` or
|
|
and running the bash script there `cd ssl_gtests && ./ssl_gtests.sh`. The
|
|
following tests are available:
|
|
|
|
- cipher lowhash libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests bogo
|
|
+ cipher lowhash libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests bogo policy
|
|
|
|
To make tests run faster it's recommended to set `NSS_CYCLES=standard` to run
|
|
only the standard cycle.
|
|
diff --git a/tests/all.sh b/tests/all.sh
|
|
--- a/tests/all.sh
|
|
+++ b/tests/all.sh
|
|
@@ -37,6 +37,7 @@
|
|
# memleak.sh - memory leak testing (optional)
|
|
# ssl_gtests.sh- Gtest based unit tests for ssl
|
|
# gtests.sh - Gtest based unit tests for everything else
|
|
+# policy.sh - Crypto Policy tests
|
|
# bogo.sh - Bogo interop tests (disabled by default)
|
|
# https://boringssl.googlesource.com/boringssl/+/master/ssl/test/PORTING.md
|
|
# interop.sh - Interoperability tests (disabled by default)
|
|
@@ -300,7 +301,7 @@ if [ $NO_INIT_SUPPORT -eq 0 ]; then
|
|
RUN_FIPS="fips"
|
|
fi
|
|
|
|
-tests="cipher lowhash libpkix cert dbtests tools $RUN_FIPS sdr crmf smime ssl ocsp merge pkits ec gtests ssl_gtests"
|
|
+tests="cipher lowhash libpkix cert dbtests tools $RUN_FIPS sdr crmf smime ssl ocsp merge pkits ec gtests ssl_gtests policy"
|
|
# Don't run chains tests when we have a gyp build.
|
|
if [ "$OBJDIR" != "Debug" -a "$OBJDIR" != "Release" ]; then
|
|
tests="$tests chains"
|
|
diff --git a/tests/policy/crypto-policy.txt b/tests/policy/crypto-policy.txt
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/tests/policy/crypto-policy.txt
|
|
@@ -0,0 +1,19 @@
|
|
+# col 1: expected return value of nss-policy-check
|
|
+# col 2: policy config statement, using _ instead of space
|
|
+# col 3: an extended regular expression, expected to match the output
|
|
+# col 4: description of the test
|
|
+#
|
|
+0 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA1:HMAC-SHA384:HMAC-SHA512:SECP256R1:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:aes256-cbc:camellia256-cbc:aes128-gcm:aes128-cbc:camellia128-cbc:SHA256:SHA384:SHA512:SHA1:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:tls-version-min=tls1.0:dtls-version-min=dtls1.0:DH-MIN=1023:DSA-MIN=2048:RSA-MIN=2048 NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Standard policy
|
|
+0 disallow=ALL_allow=HMAC-SHA1:HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP256R1:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:aes256-cbc:camellia256-cbc:aes128-gcm:aes128-cbc:camellia128-cbc:des-ede3-cbc:rc4:SHA256:SHA384:SHA512:SHA1:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:DHE-DSS:tls-version-min=tls1.0:dtls-version-min=tls1.0:DH-MIN=1023:DSA-MIN=1023:RSA-MIN=1023 NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Legacy policy
|
|
+0 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:SHA384:SHA512:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:tls-version-min=tls1.2:dtls-version-min=dtls1.2:DH-MIN=3072:DSA-MIN=3072:RSA-MIN=3072 NSS-POLICY-INFO.*LOADED-SUCCESSFULLY Reduced policy
|
|
+2 disallow=ALL_allow=dtls-version-min=:dtls-version-max= NSS-POLICY-FAIL Missing value
|
|
+2 disallow=ALL_allow=RSA-MIN=whatever NSS-POLICY-FAIL Invalid value
|
|
+2 disallow=ALL_allow=flower NSS-POLICY-FAIL Invalid identifier
|
|
+1 disallow=all NSS-POLICY-WARN.*NUMBER-OF-CERT-SIG disallow all
|
|
+1 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:tls-version-min=tls1.2:dtls-version-min=dtls1.2:DH-MIN=3072:DSA-MIN=3072:RSA-MIN=3072 NSS-POLICY-WARN.*NUMBER-OF-HASH No Hashes
|
|
+1 disallow=ALL_allow=tls-version-min=0:tls-version-max=0 NSS-POLICY-WARN.*NUMBER-OF-TLS-VERSIONS All TLS versions disabled
|
|
+1 disallow=ALL_allow=dtls-version-min=0:dtls-version-max=0 NSS-POLICY-WARN.*NUMBER-OF-DTLS-VERSIONS All DTLS versions disabled
|
|
+1 disallow=ALL_allow=tls-version-min=tls1.2:tls-version-max=tls1.1 NSS-POLICY-WARN.*NUMBER-OF-TLS-VERSIONS Invalid range of TLS versions
|
|
+1 disallow=ALL_allow=dtls-version-min=tls1.2:dtls-version-max=tls1.1 NSS-POLICY-WARN.*NUMBER-OF-DTLS-VERSIONS Invalid range of DTLS versions
|
|
+1 disallow=ALL_allow=tls-version-min=tls1.1:tls-version-max=tls1.2 NSS-POLICY-INFO.*NUMBER-OF-TLS-VERSIONS Valid range of TLS versions
|
|
+1 disallow=ALL_allow=dtls-version-min=tls1.1:dtls-version-max=tls1.2 NSS-POLICY-INFO.*NUMBER-OF-DTLS-VERSIONS Valid range of DTLS versions
|
|
diff --git a/tests/policy/policy.sh b/tests/policy/policy.sh
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/tests/policy/policy.sh
|
|
@@ -0,0 +1,58 @@
|
|
+#! /bin/bash
|
|
+#
|
|
+# 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/.
|
|
+
|
|
+########################################################################
|
|
+#
|
|
+# mozilla/security/nss/tests/policy/policy.sh
|
|
+#
|
|
+# Script to test NSS crypto policy code
|
|
+#
|
|
+########################################################################
|
|
+
|
|
+ignore_blank_lines()
|
|
+{
|
|
+ LC_ALL=C grep -v '^[[:space:]]*\(#\|$\)' "$1"
|
|
+}
|
|
+
|
|
+policy_run_tests()
|
|
+{
|
|
+ html_head "CRYPTO-POLICY"
|
|
+
|
|
+ POLICY_INPUT=${QADIR}/policy/crypto-policy.txt
|
|
+
|
|
+ ignore_blank_lines ${POLICY_INPUT} | \
|
|
+ while read value policy match testname
|
|
+ do
|
|
+ echo "$SCRIPTNAME: running \"$testname\" ----------------------------"
|
|
+ policy=`echo ${policy} | sed -e 's;_; ;g'`
|
|
+ match=`echo ${match} | sed -e 's;_; ;g'`
|
|
+ POLICY_FILE="${TMP}/nss-policy"
|
|
+
|
|
+ echo "$SCRIPTNAME: policy: \"$policy\""
|
|
+
|
|
+ cat > "$POLICY_FILE" << ++EOF++
|
|
+library=
|
|
+name=Policy
|
|
+NSS=flags=policyOnly,moduleDB
|
|
+++EOF++
|
|
+ echo "config=\"${policy}\"" >> "$POLICY_FILE"
|
|
+ echo "" >> "$POLICY_FILE"
|
|
+
|
|
+ nss-policy-check "$POLICY_FILE" >${TMP}/$HOST.tmp.$$ 2>&1
|
|
+ ret=$?
|
|
+ cat ${TMP}/$HOST.tmp.$$
|
|
+
|
|
+ html_msg $ret $value "\"${testname}\"" \
|
|
+ "produced a returncode of $ret, expected is $value"
|
|
+
|
|
+ egrep "${match}" ${TMP}/$HOST.tmp.$$
|
|
+ ret=$?
|
|
+ html_msg $ret 0 "\"${testname}\" output is expected to match \"${match}\""
|
|
+
|
|
+ done
|
|
+}
|
|
+
|
|
+policy_run_tests
|