diff options
author | Robert Relyea <rrelyea@redhat.com> | 2020-10-23 16:14:36 -0700 |
---|---|---|
committer | Robert Relyea <rrelyea@redhat.com> | 2020-10-23 16:14:36 -0700 |
commit | 44e106bc6c51b4e21c7efac869cdda527d2494c1 (patch) | |
tree | 68a84ddf37dd0267db5e932332df25feba124c57 | |
parent | a709ad895bea3d3580f8a9ddee86fd7cebe1fcad (diff) | |
parent | 912b5170fc52869710c2ae8fb94f0ade7bb71353 (diff) | |
download | nss-hg-44e106bc6c51b4e21c7efac869cdda527d2494c1.tar.gz |
Bug 1670835 Crypto Policy Support needs to be updated with disable/enable support
Policy update
Current state of the nss policy system:
The initial policy patch focused on getting policy working well in handling ssl. The policy infrastructure used two existing NSS infrastructure:
1) Algorithm policies tied the OIDS and
2) the ssl policy constraints first created to handle export policy restrictions.
To make loadable policies work, we added a couple of new things:
1) a policy parser to the secmod infrastructure which allows us to set algorithm policies based on a config file. This file had two sections: disallow= and allow=. Disallow turned off policy bits, and allow turned them on. Disallow was always parsed first, so you could very strictly control your policy map by saying disallow=all allow={exclusive list of allowed algorithms}
2) a new NSS_Option() value that allowed the policy parser to set integer values (like minimum tls version) based on the data in the policy parser.
3) SSL code which is run at ssl_init time that reads the algorithm policies and maps the results to SSL policies.
The resulting loaded policy code, in general, sets the boundaries of what it possible, actually enable/disable of ssl cipher suites are still under program control, and the builtin NSS default values. The only consession to configuration is if a cipher is disallowed by policy, it is also disabled. Allowing a cipher suite by policy that wasn't already enabled, however, doesn't enable that policy by default. Inside the policy restrictions, applications can still make their own decisions on configuration and preference.
At the time the policy system was designed, there were 3 additional features, which were designed, but not specified: disable, enable, and lock.
disable and enable work just like disallow and allow, except the specify what the default settings are. This would allow the policy file to change the underlying default in the case where the application doesn't try to configure ssl on it's own.
lock would make either the policy or configuration 'locked' meaning once the lock has been executed, no further changes to those configurations would be allowed.
What is needed:
We have a need for the following additional features:
1) we want to turn more of the sha-1 hash function off by default. We still need sha-1 digest because it's used in many non-secure cases, but we do want to disable more sha-1 signature usage. Currently only CERT-SIGNATURE and various hmac usages in SSL ciphers can be controlled by policy. We want to disallow a greater range of signature (that is signature use in general).
2) we want to disable more ciphers by default, but need a way to have certain policies (like LEGACY) turn them back on, so that our shipped system is more secure by default.
What this patch provides:
1) A new policy flag NSS_USE_ALG_IN_ANY_SIGNATURE was added. The cryptohi code which exports the NSS sign/verify high level code now checks the hash and signing algorithm against this new policy flag and fails if the policy isn't available.
New key words were added to the policy parser for 'all-signature', which implies all signature flags at once, and 'signature', which maps to NSS_USE_ANY_SIGNATURE. NOTE: disable=all/signature and disable=all/all-signature are effective equivalent because cert-signatures eventually call the low level signature functions, but disable=all allow=rsa-pss/all-signature and disable=all allow=rsa-pss/signature are different in that the latter allows all rsa-pss signature and the latter allows rsa-pss signatures, but no on certificates (or on smime in the future)
Also new keywords were added for rsa-pkcs, rsa-pss, and ecdsa for signature algorithms (along with dsa).
2) This patch implements disable and enable. These functions only work on SSL configuration. In the future SMIME/CMS configuration could also be added. Because the policy system is parsed and handled by NSS, and SSL configuration is handled in SSL, we use the same Apply code we used to apply ssl policy to set the inital configuration. The configured enable/disable state is configured in the ALGORTHIM policy system, where one bit says the enable/disable value is active and another bit which gives it's state.
3) two locks have been implented, policy-lock and ssl-lock. These are specified in the parser as flags (flags=policy-lock,ssl-lock). The policy locks all the policy changes: ssl_policy, algorithm policy, and options. It is implemented by two new exported functions: NSS_IsPolicyLocked() and NSS_LockPolicy(). The first allows applications to test if the policy is locked without having to try changing the policy. The various policy set functions check the NSS_IsPolicyLocked() function and returns SEC_ERROR_POLICY_LOCK if it's true.
The ssl-lock changes the state of the policy to locked, and the state cannot be changed back without shutting down NSS. The second is implemented by setting a new Option called NSS_DEFAULT_LOCKS and the NSS_DEFAULT_SSL_LOCK flag. The idea is we can add an SMIME lock in the future. SSL checks the NSS_DEFAULT_SSL_LOCK flag before trying to set the cipher suite value, and blocks the change if it's set.
4) sslpolicy tests were updated to test the enable, disable, flags=policy-lock, flags=ssl-lock and the new signature primitives.
5) policy tests were updated to be able to run standalone (like all the other all.sh tests), as well as new tests to detect when no signing algorithms have been enabled.
What is not in the patch
1) S/MIME signature policy has been defined for a while, but never hooked up.
2) S/MIME export policy needs to be connected back to the algorithm policy system just like the ssl cipher suites already are.
3) S/MIME default configuration needs to be connected back to the policy system.
4) ECC Curve policy needs to be hooked up with the signature policy (probably should create a generic 'key meets policy' function and have every call it).
Differential Revision: https://phabricator.services.mozilla.com/D93697
-rw-r--r-- | automation/abi-check/expected-report-libnssutil3.so.txt | 6 | ||||
-rw-r--r-- | gtests/mozpkix_gtest/pkixcert_signature_algorithm_tests.cpp | 50 | ||||
-rw-r--r-- | gtests/mozpkix_gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp | 20 | ||||
-rw-r--r-- | lib/cryptohi/keyi.h | 3 | ||||
-rw-r--r-- | lib/cryptohi/secsign.c | 35 | ||||
-rw-r--r-- | lib/cryptohi/secvfy.c | 120 | ||||
-rw-r--r-- | lib/nss/nss.h | 2 | ||||
-rw-r--r-- | lib/nss/nssoptions.c | 17 | ||||
-rw-r--r-- | lib/pk11wrap/pk11pars.c | 205 | ||||
-rw-r--r-- | lib/ssl/ssl3con.c | 81 | ||||
-rw-r--r-- | lib/ssl/sslsock.c | 15 | ||||
-rw-r--r-- | lib/util/SECerrs.h | 6 | ||||
-rw-r--r-- | lib/util/nssutil.def | 7 | ||||
-rw-r--r-- | lib/util/secerr.h | 3 | ||||
-rw-r--r-- | lib/util/secoid.c | 24 | ||||
-rw-r--r-- | lib/util/secoid.h | 9 | ||||
-rw-r--r-- | lib/util/secoidt.h | 19 | ||||
-rw-r--r-- | tests/policy/crypto-policy.txt | 9 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/policy/policy.sh | 25 | ||||
-rwxr-xr-x | tests/ssl/ssl.sh | 31 | ||||
-rw-r--r-- | tests/ssl/sslpolicy.txt | 65 |
21 files changed, 614 insertions, 138 deletions
diff --git a/automation/abi-check/expected-report-libnssutil3.so.txt b/automation/abi-check/expected-report-libnssutil3.so.txt index e69de29bb..92961214f 100644 --- a/automation/abi-check/expected-report-libnssutil3.so.txt +++ b/automation/abi-check/expected-report-libnssutil3.so.txt @@ -0,0 +1,6 @@ + +2 Added functions: + + [A] 'function PRBool NSS_IsPolicyLocked()' {NSS_IsPolicyLocked@@NSSUTIL_3.59} + [A] 'function void NSS_LockPolicy()' {NSS_LockPolicy@@NSSUTIL_3.59} + diff --git a/gtests/mozpkix_gtest/pkixcert_signature_algorithm_tests.cpp b/gtests/mozpkix_gtest/pkixcert_signature_algorithm_tests.cpp index 5719d1045..685d4127c 100644 --- a/gtests/mozpkix_gtest/pkixcert_signature_algorithm_tests.cpp +++ b/gtests/mozpkix_gtest/pkixcert_signature_algorithm_tests.cpp @@ -7,9 +7,55 @@ #include "mozpkix/pkixder.h" +#include "secoid.h" + using namespace mozilla::pkix; using namespace mozilla::pkix::test; +/* These tests generate invalid certificates on the fly, We want to test + * validation of those certificates, not the generation, so we + * need to temporarily allow disallowed signature policies before + * we do the actual certificate or ocsp signing + */ +class HashAlgorithmPolicies +{ + static const int numberOfHashes = 4; /* sigh */ + static const SECOidTag hashOids[numberOfHashes]; + + PRUint32 savedPolicy[numberOfHashes]; + +public: + void EnableHashSignaturePolicy(void); + void RestoreHashSignaturePolicy(void); +}; + +const SECOidTag HashAlgorithmPolicies::hashOids[numberOfHashes] = { + SEC_OID_MD2, + SEC_OID_MD4, + SEC_OID_MD5, + SEC_OID_SHA1 }; + +void +HashAlgorithmPolicies::EnableHashSignaturePolicy(void) +{ + for (int i=0;i < numberOfHashes; i++) { + ASSERT_EQ(SECSuccess, + NSS_GetAlgorithmPolicy(hashOids[i], &savedPolicy[i])); + ASSERT_EQ(SECSuccess, + NSS_SetAlgorithmPolicy(hashOids[i], NSS_USE_ALG_IN_SIGNATURE, 0)); + } +} + +void +HashAlgorithmPolicies::RestoreHashSignaturePolicy(void) +{ + for (int i=0;i < numberOfHashes; i++) { + ASSERT_EQ(SECSuccess, + NSS_SetAlgorithmPolicy(hashOids[i], savedPolicy[i], + NSS_USE_ALG_IN_SIGNATURE)); + } +} + static ByteString CreateCert(const char* issuerCN, const char* subjectCN, @@ -35,16 +81,20 @@ CreateCert(const char* issuerCN, } ScopedTestKeyPair reusedKey(CloneReusedKeyPair()); + HashAlgorithmPolicies policies; + policies.EnableHashSignaturePolicy(); ByteString certDER(CreateEncodedCertificate(v3, signatureAlgorithm, serialNumber, issuerDER, oneDayBeforeNow, oneDayAfterNow, subjectDER, *reusedKey, extensions, *reusedKey, signatureAlgorithm)); + policies.RestoreHashSignaturePolicy(); EXPECT_FALSE(ENCODING_FAILED(certDER)); return certDER; } + class AlgorithmTestsTrustDomain final : public DefaultCryptoTrustDomain { public: diff --git a/gtests/mozpkix_gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/gtests/mozpkix_gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 3fe4e7b5a..81bee3367 100644 --- a/gtests/mozpkix_gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/gtests/mozpkix_gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -26,6 +26,8 @@ #include "mozpkix/pkixder.h" +#include "secoid.h" + using namespace mozilla::pkix; using namespace mozilla::pkix::test; @@ -338,6 +340,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, unknown) TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_unsupportedSignatureAlgorithm) { + PRUint32 policyMd5; + ASSERT_EQ(SECSuccess,NSS_GetAlgorithmPolicy(SEC_OID_MD5, &policyMd5)); + + /* our encode won't work if MD5 isn't allowed by policy */ + ASSERT_EQ(SECSuccess, + NSS_SetAlgorithmPolicy(SEC_OID_MD5, NSS_USE_ALG_IN_SIGNATURE, 0)); ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, byKey, @@ -347,6 +355,9 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, Input response; ASSERT_EQ(Success, response.Init(responseString.data(), responseString.length())); + /* now restore the existing policy */ + ASSERT_EQ(SECSuccess, + NSS_SetAlgorithmPolicy(SEC_OID_MD5, policyMd5, NSS_USE_ALG_IN_SIGNATURE)); bool expired; ASSERT_EQ(Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, @@ -930,14 +941,23 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, // Note that the algorithm ID (md5WithRSAEncryption) identifies the signature // algorithm that will be used to sign the certificate that issues the OCSP // responses, not the responses themselves. + PRUint32 policyMd5; + ASSERT_EQ(SECSuccess,NSS_GetAlgorithmPolicy(SEC_OID_MD5, &policyMd5)); + + /* our encode won't work if MD5 isn't allowed by policy */ + ASSERT_EQ(SECSuccess, + NSS_SetAlgorithmPolicy(SEC_OID_MD5, NSS_USE_ALG_IN_SIGNATURE, 0)); ByteString responseString( CreateEncodedIndirectOCSPSuccessfulResponse( "good_indirect_unsupportedSignatureAlgorithm", OCSPResponseContext::good, byKey, md5WithRSAEncryption())); Input response; + /* now restore the existing policy */ ASSERT_EQ(Success, response.Init(responseString.data(), responseString.length())); + ASSERT_EQ(SECSuccess, + NSS_SetAlgorithmPolicy(SEC_OID_MD5, policyMd5, NSS_USE_ALG_IN_SIGNATURE)); bool expired; ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT, VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(), diff --git a/lib/cryptohi/keyi.h b/lib/cryptohi/keyi.h index b746d3c8d..707e11ade 100644 --- a/lib/cryptohi/keyi.h +++ b/lib/cryptohi/keyi.h @@ -17,6 +17,9 @@ KeyType seckey_GetKeyType(SECOidTag pubKeyOid); SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg); +/* just get the 'encryption' oid from the combined signature oid */ +SECOidTag sec_GetEncAlgFromSigAlg(SECOidTag sigAlg); + /* extract the RSA-PSS hash algorithms and salt length from * parameters, taking into account of the default implications. * diff --git a/lib/cryptohi/secsign.c b/lib/cryptohi/secsign.c index 125dfd913..c46b2b1e4 100644 --- a/lib/cryptohi/secsign.c +++ b/lib/cryptohi/secsign.c @@ -31,6 +31,7 @@ sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key) SGNContext *cx; SECOidTag hashalg, signalg; KeyType keyType; + PRUint32 policyFlags; SECStatus rv; /* OK, map a PKCS #7 hash and encrypt algorithm into @@ -44,7 +45,7 @@ sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key) rv = sec_DecodeSigAlg(NULL, alg, params, &signalg, &hashalg); if (rv != SECSuccess) { PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return 0; + return NULL; } keyType = seckey_GetKeyType(signalg); @@ -53,7 +54,19 @@ sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key) !((key->keyType == dsaKey) && (keyType == fortezzaKey)) && !((key->keyType == rsaKey) && (keyType == rsaPssKey))) { PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return 0; + return NULL; + } + /* check the policy on the hash algorithm */ + if ((NSS_GetAlgorithmPolicy(hashalg, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { + PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); + return NULL; + } + /* check the policy on the encryption algorithm */ + if ((NSS_GetAlgorithmPolicy(signalg, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { + PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); + return NULL; } cx = (SGNContext *)PORT_ZAlloc(sizeof(SGNContext)); @@ -452,9 +465,27 @@ SGN_Digest(SECKEYPrivateKey *privKey, SECItem digder; PLArenaPool *arena = 0; SGNDigestInfo *di = 0; + SECOidTag enctag; + PRUint32 policyFlags; result->data = 0; + /* check the policy on the hash algorithm */ + if ((NSS_GetAlgorithmPolicy(algtag, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { + PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); + return SECFailure; + } + /* check the policy on the encryption algorithm */ + enctag = sec_GetEncAlgFromSigAlg( + SEC_GetSignatureAlgorithmOidTag(privKey->keyType, algtag)); + if ((enctag == SEC_OID_UNKNOWN) || + (NSS_GetAlgorithmPolicy(enctag, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { + PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); + return SECFailure; + } + if (privKey->keyType == rsaKey) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); diff --git a/lib/cryptohi/secvfy.c b/lib/cryptohi/secvfy.c index fc0a0c12b..2540a544c 100644 --- a/lib/cryptohi/secvfy.c +++ b/lib/cryptohi/secvfy.c @@ -217,6 +217,56 @@ const SEC_ASN1Template hashParameterTemplate[] = }; /* + * Get just the encryption algorithm from the signature algorithm + */ +SECOidTag +sec_GetEncAlgFromSigAlg(SECOidTag sigAlg) +{ + /* get the "encryption" algorithm */ + switch (sigAlg) { + case SEC_OID_PKCS1_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: + case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: + case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: + case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: + return SEC_OID_PKCS1_RSA_ENCRYPTION; + case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: + return SEC_OID_PKCS1_RSA_PSS_SIGNATURE; + + /* what about normal DSA? */ + case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: + case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: + case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: + case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: + return SEC_OID_ANSIX9_DSA_SIGNATURE; + case SEC_OID_MISSI_DSS: + case SEC_OID_MISSI_KEA_DSS: + case SEC_OID_MISSI_KEA_DSS_OLD: + case SEC_OID_MISSI_DSS_OLD: + return SEC_OID_MISSI_DSS; + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + return SEC_OID_ANSIX962_EC_PUBLIC_KEY; + /* we don't implement MD4 hashes */ + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + default: + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + break; + } + return SEC_OID_UNKNOWN; +} + +/* * Pulls the hash algorithm, signing algorithm, and key type out of a * composite algorithm. * @@ -229,15 +279,16 @@ const SEC_ASN1Template hashParameterTemplate[] = */ SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, - const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg) + const SECItem *param, SECOidTag *encalgp, SECOidTag *hashalg) { int len; PLArenaPool *arena; SECStatus rv; SECItem oid; + SECOidTag encalg; PR_ASSERT(hashalg != NULL); - PR_ASSERT(encalg != NULL); + PR_ASSERT(encalgp != NULL); switch (sigAlg) { /* We probably shouldn't be generating MD2 signatures either */ @@ -354,52 +405,13 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); return SECFailure; } - /* get the "encryption" algorithm */ - switch (sigAlg) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: - case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: - case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: - case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: - case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: - case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: - *encalg = SEC_OID_PKCS1_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: - *encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE; - break; - /* what about normal DSA? */ - case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: - case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: - *encalg = SEC_OID_ANSIX9_DSA_SIGNATURE; - break; - case SEC_OID_MISSI_DSS: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_DSS_OLD: - *encalg = SEC_OID_MISSI_DSS; - break; - case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: - *encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; - break; - /* we don't implement MD4 hashes */ - case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: - default: - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return SECFailure; + encalg = sec_GetEncAlgFromSigAlg(sigAlg); + if (encalg == SEC_OID_UNKNOWN) { + return SECFailure; } + *encalgp = encalg; + return SECSuccess; } @@ -423,6 +435,7 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, SECStatus rv; unsigned int sigLen; KeyType type; + PRUint32 policyFlags; /* make sure the encryption algorithm matches the key type */ /* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */ @@ -433,6 +446,13 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, return NULL; } + /* check the policy on the encryption algorithm */ + if ((NSS_GetAlgorithmPolicy(encAlg, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { + PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); + return NULL; + } + cx = (VFYContext *)PORT_ZAlloc(sizeof(VFYContext)); if (cx == NULL) { goto loser; @@ -493,6 +513,14 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, /* error set by HASH_GetHashTypeByOidTag */ goto loser; } + /* check the policy on the hash algorithm. Do this after + * the rsa decode because some uses of this function get hash implicitly + * from the RSA signature itself. */ + if ((NSS_GetAlgorithmPolicy(cx->hashAlg, &policyFlags) == SECFailure) || + !(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) { + PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED); + goto loser; + } if (hash) { *hash = cx->hashAlg; diff --git a/lib/nss/nss.h b/lib/nss/nss.h index 54ca3371f..76357aa49 100644 --- a/lib/nss/nss.h +++ b/lib/nss/nss.h @@ -299,6 +299,8 @@ SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); * old NSS versions. This option might be removed in the future NSS * releases; don't rely on it. */ #define __NSS_PKCS12_DECODE_FORCE_UNICODE 0x00c +#define NSS_DEFAULT_LOCKS 0x00d /* lock default values */ +#define NSS_DEFAULT_SSL_LOCK 1 /* lock the ssl default values */ /* * Set and get global options for the NSS library. diff --git a/lib/nss/nssoptions.c b/lib/nss/nssoptions.c index 1339cede8..f7225c414 100644 --- a/lib/nss/nssoptions.c +++ b/lib/nss/nssoptions.c @@ -14,6 +14,7 @@ #include "secoid.h" #include "nss.h" #include "nssoptions.h" +#include "secerr.h" struct nssOps { PRInt32 rsaMinKeySize; @@ -24,6 +25,7 @@ struct nssOps { PRInt32 dtlsVersionMinPolicy; PRInt32 dtlsVersionMaxPolicy; PRInt32 pkcs12DecodeForceUnicode; + PRInt32 defaultLocks; }; static struct nssOps nss_ops = { @@ -34,7 +36,8 @@ static struct nssOps nss_ops = { 0xffff, /* set TLS max to more than the largest legal SSL value */ 1, 0xffff, - PR_FALSE + PR_FALSE, + 0 }; SECStatus @@ -42,6 +45,11 @@ NSS_OptionSet(PRInt32 which, PRInt32 value) { SECStatus rv = SECSuccess; + if (NSS_IsPolicyLocked()) { + PORT_SetError(SEC_ERROR_POLICY_LOCKED); + return SECFailure; + } + switch (which) { case NSS_RSA_MIN_KEY_SIZE: nss_ops.rsaMinKeySize = value; @@ -67,7 +75,11 @@ NSS_OptionSet(PRInt32 which, PRInt32 value) case __NSS_PKCS12_DECODE_FORCE_UNICODE: nss_ops.pkcs12DecodeForceUnicode = value; break; + case NSS_DEFAULT_LOCKS: + nss_ops.defaultLocks = value; + break; default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; } @@ -104,6 +116,9 @@ NSS_OptionGet(PRInt32 which, PRInt32 *value) case __NSS_PKCS12_DECODE_FORCE_UNICODE: *value = nss_ops.pkcs12DecodeForceUnicode; break; + case NSS_DEFAULT_LOCKS: + *value = nss_ops.defaultLocks; + break; default: rv = SECFailure; } diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c index 0e823233d..68738b3d4 100644 --- a/lib/pk11wrap/pk11pars.c +++ b/lib/pk11wrap/pk11pars.c @@ -158,16 +158,17 @@ SECMOD_CreateModule(const char *library, const char *moduleName, * Disallow values are parsed first, then allow values, independent of the * order they appear. * - * Future key words (not yet implemented): + * flags: turn on the following flags: + * policy-lock: turn off the ability for applications to change policy with + * the call NSS_SetAlgorithmPolicy or the other system policy + * calls (SSL_SetPolicy, etc.) + * ssl-lock: turn off the ability to change the ssl defaults. + * + * The following only apply to ssl cipher suites (future smime) + * * enable: turn on ciphersuites by default. * disable: turn off ciphersuites by default without disallowing them by policy. - * flags: turn on the following flags: - * ssl-lock: turn off the ability for applications to change policy with - * the SSL_SetCipherPolicy (or SSL_SetPolicy). - * policy-lock: turn off the ability for applications to change policy with - * the call NSS_SetAlgorithmPolicy. - * ssl-default-lock: turn off the ability for applications to change cipher - * suite states with SSL_EnableCipher, SSL_DisableCipher. + * * */ @@ -323,21 +324,21 @@ static const oidValDef curveOptList[] = { static const oidValDef hashOptList[] = { /* Hashes */ { CIPHER_NAME("MD2"), SEC_OID_MD2, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("MD4"), SEC_OID_MD4, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("MD5"), SEC_OID_MD5, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("SHA1"), SEC_OID_SHA1, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("SHA224"), SEC_OID_SHA224, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("SHA256"), SEC_OID_SHA256, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("SHA384"), SEC_OID_SHA384, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("SHA512"), SEC_OID_SHA512, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE } }; static const oidValDef macOptList[] = { @@ -389,7 +390,13 @@ static const oidValDef kxOptList[] = { static const oidValDef signOptList[] = { /* Signatures */ { CIPHER_NAME("DSA"), SEC_OID_ANSIX9_DSA_SIGNATURE, - NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, + { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, + { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, + { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, }; typedef struct { @@ -405,7 +412,7 @@ static const algListsDef algOptLists[] = { { macOptList, PR_ARRAY_SIZE(macOptList), "MAC", PR_FALSE }, { cipherOptList, PR_ARRAY_SIZE(cipherOptList), "CIPHER", PR_FALSE }, { kxOptList, PR_ARRAY_SIZE(kxOptList), "OTHER-KX", PR_FALSE }, - { signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_TRUE }, + { signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_FALSE }, }; static const optionFreeDef sslOptList[] = { @@ -443,10 +450,19 @@ static const policyFlagDef policyFlagList[] = { /* add other key exhanges in the future */ { CIPHER_NAME("KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX }, { CIPHER_NAME("CERT-SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE }, - /* add other signatures in the future */ - { CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE }, - /* enable everything */ - { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, + { CIPHER_NAME("CMS-SIGNATURE"), NSS_USE_ALG_IN_CMS_SIGNATURE }, + { CIPHER_NAME("ALL-SIGNATURE"), NSS_USE_ALG_IN_SIGNATURE }, + /* sign turns off all signatures, but doesn't change the + * allowance for specific sigantures... for example: + * disallow=sha256/all allow=sha256/signature doesn't allow + * cert-sigantures, where disallow=sha256/all allow=sha256/all-signature + * does. + * however, disallow=sha356/signature and disallow=sha256/all-siganture are + * equivalent in effect */ + { CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_ANY_SIGNATURE }, + /* enable/disable everything */ + { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX | + NSS_USE_ALG_IN_SIGNATURE }, { CIPHER_NAME("NONE"), 0 } }; @@ -538,8 +554,82 @@ secmod_getPolicyOptValue(const char *policyValue, int policyValueLength, return SECFailure; } +/* Policy operations: + * Disallow: operation is disallowed by policy. Implies disabled. + * Allow: operation is allowed by policy (but could be disabled). + * Disable: operation is turned off by default (but could be allowed). + * Enable: operation is enabled by default. Implies allowed. + */ +typedef enum { + NSS_DISALLOW, + NSS_ALLOW, + NSS_DISABLE, + NSS_ENABLE +} NSSPolicyOperation; + +/* apply the operator specific policy */ +SECStatus +secmod_setPolicyOperation(SECOidTag oid, NSSPolicyOperation operation, + PRUint32 value) +{ + SECStatus rv = SECSuccess; + switch (operation) { + case NSS_DISALLOW: + /* clear the requested policy bits */ + rv = NSS_SetAlgorithmPolicy(oid, 0, value); + break; + case NSS_ALLOW: + /* set the requested policy bits */ + rv = NSS_SetAlgorithmPolicy(oid, value, 0); + break; + /* enable/disable only apply to SSL cipher suites (future S/MIME). + * Enable/disable is implemented by clearing the DEFAULT_NOT_VALID + * flag, then setting the NSS_USE_DEFAULT_SSL_ENABLE flag to the + * correct value. The ssl policy code will then sort out what to + * set based on ciphers and cipher suite values.*/ + case NSS_DISABLE: + if (value & (NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX)) { + /* clear not valid and enable */ + rv = NSS_SetAlgorithmPolicy(oid, 0, + NSS_USE_DEFAULT_NOT_VALID | + NSS_USE_DEFAULT_SSL_ENABLE); + } + break; + case NSS_ENABLE: + if (value & (NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX)) { + /* set enable, clear not valid. NOTE: enable implies allow! */ + rv = NSS_SetAlgorithmPolicy(oid, value | NSS_USE_DEFAULT_SSL_ENABLE, + NSS_USE_DEFAULT_NOT_VALID); + } + break; + default: + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + break; + } + return rv; +} + +const char * +secmod_getOperationString(NSSPolicyOperation operation) +{ + switch (operation) { + case NSS_DISALLOW: + return "disallow"; + case NSS_ALLOW: + return "allow"; + case NSS_DISABLE: + return "disable"; + case NSS_ENABLE: + return "enable"; + default: + break; + } + return "invalid"; +} + static SECStatus -secmod_applyCryptoPolicy(const char *policyString, PRBool allow, +secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation, PRBool printPolicyFeedback) { const char *cipher, *currentString; @@ -573,18 +663,10 @@ secmod_applyCryptoPolicy(const char *policyString, PRBool allow, 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); + secmod_setPolicyOperation(algOptList->list[j].oid, operation, value); } } continue; @@ -603,20 +685,12 @@ secmod_applyCryptoPolicy(const char *policyString, PRBool allow, 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); + rv = secmod_setPolicyOperation(algOptList->list[j].oid, operation, value); if (rv != SECSuccess) { /* could not enable option */ /* NSS_SetAlgorithPolicy should have set the error code */ @@ -666,7 +740,7 @@ secmod_applyCryptoPolicy(const char *policyString, PRBool allow, if (unknown && printPolicyFeedback) { PR_SetEnv("NSS_POLICY_FAIL=1"); fprintf(stderr, "NSS-POLICY-FAIL %s: unknown identifier: %.*s\n", - allow ? "allow" : "disallow", length, cipher); + secmod_getOperationString(operation), length, cipher); } } return rv; @@ -709,7 +783,8 @@ secmod_sanityCheckCryptoPolicy(void) 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)) { + if ((algOpt->val & NSS_USE_ALG_IN_CERT_SIGNATURE) && + ((value & NSS_USE_CERT_SIGNATURE_OK) == NSS_USE_CERT_SIGNATURE_OK)) { ++num_sig_enabled; anyEnabled = PR_TRUE; fprintf(stderr, "NSS-POLICY-INFO: %s is enabled for CERT-SIGNATURE\n", algOpt->name); @@ -740,7 +815,7 @@ secmod_sanityCheckCryptoPolicy(void) static SECStatus secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback) { - char *disallow, *allow; + char *args; SECStatus rv; if (policyConfig == NULL) { @@ -752,20 +827,46 @@ secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback) if (rv != SECSuccess) { return rv; } - disallow = NSSUTIL_ArgGetParamValue("disallow", policyConfig); - rv = secmod_applyCryptoPolicy(disallow, PR_FALSE, printPolicyFeedback); - if (disallow) - PORT_Free(disallow); + args = NSSUTIL_ArgGetParamValue("disallow", policyConfig); + rv = secmod_applyCryptoPolicy(args, NSS_DISALLOW, printPolicyFeedback); + if (args) + PORT_Free(args); + if (rv != SECSuccess) { + return rv; + } + args = NSSUTIL_ArgGetParamValue("allow", policyConfig); + rv = secmod_applyCryptoPolicy(args, NSS_ALLOW, printPolicyFeedback); + if (args) + PORT_Free(args); if (rv != SECSuccess) { return rv; } - allow = NSSUTIL_ArgGetParamValue("allow", policyConfig); - rv = secmod_applyCryptoPolicy(allow, PR_TRUE, printPolicyFeedback); - if (allow) - PORT_Free(allow); + args = NSSUTIL_ArgGetParamValue("disable", policyConfig); + rv = secmod_applyCryptoPolicy(args, NSS_DISABLE, printPolicyFeedback); + if (args) + PORT_Free(args); if (rv != SECSuccess) { return rv; } + args = NSSUTIL_ArgGetParamValue("enable", policyConfig); + rv = secmod_applyCryptoPolicy(args, NSS_ENABLE, printPolicyFeedback); + if (args) + PORT_Free(args); + if (rv != SECSuccess) { + return rv; + } + /* this has to be last. Everything after this will be a noop */ + if (NSSUTIL_ArgHasFlag("flags", "ssl-lock", policyConfig)) { + PRInt32 locks; + /* don't overwrite other (future) lock flags */ + rv = NSS_OptionGet(NSS_DEFAULT_LOCKS, &locks); + if (rv == SECSuccess) { + NSS_OptionSet(NSS_DEFAULT_LOCKS, locks | NSS_DEFAULT_SSL_LOCK); + } + } + if (NSSUTIL_ArgHasFlag("flags", "policy-lock", policyConfig)) { + NSS_LockPolicy(); + } if (printPolicyFeedback) { /* This helps to distinguish configurations that don't contain any * policy config= statement. */ diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index 5f22872f8..767ffc30f 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -13596,6 +13596,61 @@ ssl3_DestroySSL3Info(sslSocket *ss) tls13_DestroyPskList(&ss->ssl3.hs.psks); } +/* + * parse the policy value for a single algorithm in a cipher_suite, + * return TRUE if we disallow by the cipher suite by policy + * (we don't have to parse any more algorithm policies on this cipher suite), + * otherwise return FALSE. + * 1. If we don't have the required policy, disable by default, disallow by + * policy and return TRUE (no more processing needed). + * 2. If we have the required policy, and we are disabled, return FALSE, + * (if we are disabled, we only need to parse policy, not default). + * 3. If we have the required policy, and we aren't adjusting the defaults + * return FALSE. (only parsing the policy, not default). + * 4. We have the required policy and we are adjusting the defaults. + * If we are setting default = FALSE, set isDisabled to true so that + * we don't try to re-enable the cipher suite based on a different + * algorithm. + */ +PRBool +ssl_HandlePolicy(int cipher_suite, SECOidTag policyOid, + PRUint32 requiredPolicy, PRBool *isDisabled) +{ + PRUint32 policy; + SECStatus rv; + + /* first fetch the policy for this algorithm */ + rv = NSS_GetAlgorithmPolicy(policyOid, &policy); + if (rv != SECSuccess) { + return PR_FALSE; /* no policy value, continue to the next algorithm */ + } + /* first, are we allowed by policy, if not turn off allow and disable */ + if (!(policy & requiredPolicy)) { + ssl_CipherPrefSetDefault(cipher_suite, PR_FALSE); + ssl_CipherPolicySet(cipher_suite, SSL_NOT_ALLOWED); + return PR_TRUE; + } + /* If we are already disabled, or the policy isn't setting a default + * we are done processing this algorithm */ + if (*isDisabled || (policy & NSS_USE_DEFAULT_NOT_VALID)) { + return PR_FALSE; + } + /* set the default value for the cipher suite. If we disable the cipher + * suite, remember that so we don't process the next default. This has + * the effect of disabling the whole cipher suite if any of the + * algorithms it uses are disabled by default. We still have to + * process the upper level because the cipher suite is still allowed + * by policy, and we may still have to disallow it based on other + * algorithms in the cipher suite. */ + if (policy & NSS_USE_DEFAULT_SSL_ENABLE) { + ssl_CipherPrefSetDefault(cipher_suite, PR_TRUE); + } else { + *isDisabled = PR_TRUE; + ssl_CipherPrefSetDefault(cipher_suite, PR_FALSE); + } + return PR_FALSE; +} + #define MAP_NULL(x) (((x) != 0) ? (x) : SEC_OID_NULL_CIPHER) SECStatus @@ -13614,30 +13669,30 @@ ssl3_ApplyNSSPolicy(void) for (i = 1; i < PR_ARRAY_SIZE(cipher_suite_defs); ++i) { const ssl3CipherSuiteDef *suite = &cipher_suite_defs[i]; SECOidTag policyOid; + PRBool isDisabled = PR_FALSE; + /* if we haven't explicitly disabled it below enable by policy */ + ssl_CipherPolicySet(suite->cipher_suite, SSL_ALLOWED); + + /* now check the various key exchange, ciphers and macs and + * if we ever disallow by policy, we are done, go to the next cipher + */ policyOid = MAP_NULL(kea_defs[suite->key_exchange_alg].oid); - rv = NSS_GetAlgorithmPolicy(policyOid, &policy); - if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL_KX)) { - ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE); - ssl_CipherPolicySet(suite->cipher_suite, SSL_NOT_ALLOWED); + if (ssl_HandlePolicy(suite->cipher_suite, policyOid, + NSS_USE_ALG_IN_SSL_KX, &isDisabled)) { continue; } policyOid = MAP_NULL(ssl_GetBulkCipherDef(suite)->oid); - rv = NSS_GetAlgorithmPolicy(policyOid, &policy); - if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL)) { - ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE); - ssl_CipherPolicySet(suite->cipher_suite, SSL_NOT_ALLOWED); + if (ssl_HandlePolicy(suite->cipher_suite, policyOid, + NSS_USE_ALG_IN_SSL, &isDisabled)) { continue; } if (ssl_GetBulkCipherDef(suite)->type != type_aead) { policyOid = MAP_NULL(ssl_GetMacDefByAlg(suite->mac_alg)->oid); - rv = NSS_GetAlgorithmPolicy(policyOid, &policy); - if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL)) { - ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE); - ssl_CipherPolicySet(suite->cipher_suite, - SSL_NOT_ALLOWED); + if (ssl_HandlePolicy(suite->cipher_suite, policyOid, + NSS_USE_ALG_IN_SSL, &isDisabled)) { continue; } } diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c index 83372104e..695f39c50 100644 --- a/lib/ssl/sslsock.c +++ b/lib/ssl/sslsock.c @@ -1460,6 +1460,10 @@ SSL_CipherPolicySet(PRInt32 which, PRInt32 policy) if (rv != SECSuccess) { return rv; } + if (NSS_IsPolicyLocked()) { + PORT_SetError(SEC_ERROR_POLICY_LOCKED); + return SECFailure; + } return ssl_CipherPolicySet(which, policy); } @@ -1506,10 +1510,15 @@ SECStatus SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled) { SECStatus rv = ssl_Init(); + PRInt32 locks; if (rv != SECSuccess) { return rv; } + rv = NSS_OptionGet(NSS_DEFAULT_LOCKS, &locks); + if ((rv == SECSuccess) && (locks & NSS_DEFAULT_SSL_LOCK)) { + return SECSuccess; + } return ssl_CipherPrefSetDefault(which, enabled); } @@ -1535,11 +1544,17 @@ SECStatus SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled) { sslSocket *ss = ssl_FindSocket(fd); + PRInt32 locks; + SECStatus rv; if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd)); return SECFailure; } + rv = NSS_OptionGet(NSS_DEFAULT_LOCKS, &locks); + if ((rv == SECSuccess) && (locks & NSS_DEFAULT_SSL_LOCK)) { + return SECSuccess; + } if (ssl_IsRemovedCipherSuite(which)) return SECSuccess; return ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled); diff --git a/lib/util/SECerrs.h b/lib/util/SECerrs.h index d58813e46..4fb4afe40 100644 --- a/lib/util/SECerrs.h +++ b/lib/util/SECerrs.h @@ -552,3 +552,9 @@ ER3(SEC_ERROR_APPLICATION_CALLBACK_ERROR, (SEC_ERROR_BASE + 178), ER3(SEC_ERROR_INVALID_STATE, (SEC_ERROR_BASE + 179), "The attempted operation is invalid for the current state.") + +ER3(SEC_ERROR_POLICY_LOCKED, (SEC_ERROR_BASE + 180), + "Could not change the policy because the policy is now locked.") + +ER3(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED, (SEC_ERROR_BASE + 181), + "Could not create or verify a signature using a signature algorithm that is disabled because it is not secure.") diff --git a/lib/util/nssutil.def b/lib/util/nssutil.def index 8c233f7d3..2d61f53cd 100644 --- a/lib/util/nssutil.def +++ b/lib/util/nssutil.def @@ -334,3 +334,10 @@ NSSUTIL_AddNSSFlagToModuleSpec; ;+ local: ;+ *; ;+}; +;+NSSUTIL_3.59 { # NSS Utilities 3.59 release +;+ global: +NSS_IsPolicyLocked; +NSS_LockPolicy; +;+ local: +;+ *; +;+}; diff --git a/lib/util/secerr.h b/lib/util/secerr.h index 44bb5ee4a..7b205a71e 100644 --- a/lib/util/secerr.h +++ b/lib/util/secerr.h @@ -212,6 +212,9 @@ typedef enum { SEC_ERROR_INVALID_STATE = (SEC_ERROR_BASE + 179), + SEC_ERROR_POLICY_LOCKED = (SEC_ERROR_BASE + 180), + SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED = (SEC_ERROR_BASE + 181), + /* Add new error codes above here. */ SEC_ERROR_END_OF_LIST } SECErrorCodes; diff --git a/lib/util/secoid.c b/lib/util/secoid.c index d2bd8fd1f..b10f859fb 100644 --- a/lib/util/secoid.c +++ b/lib/util/secoid.c @@ -2244,6 +2244,8 @@ NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue) return SECSuccess; } +static PRBool nss_policy_locked = PR_FALSE; + /* The Set function modifies the stored value according to the following * algorithm: * policy[tag] = (policy[tag] & ~clearBits) | setBits; @@ -2255,6 +2257,11 @@ NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits) PRUint32 policyFlags; if (!pxo) return SECFailure; + + if (nss_policy_locked) { + PORT_SetError(SEC_ERROR_POLICY_LOCKED); + return SECFailure; + } /* The stored policy flags are the ones complement of the flags as * seen by the user. This is not atomic, but these changes should * be done rarely, e.g. at initialization time. @@ -2265,6 +2272,20 @@ NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits) return SECSuccess; } +/* Get the state of nss_policy_locked */ +PRBool +NSS_IsPolicyLocked(void) +{ + return nss_policy_locked; +} + +/* Once the policy is locked, it can't be unlocked */ +void +NSS_LockPolicy(void) +{ + nss_policy_locked = PR_TRUE; +} + /* --------- END OF opaque extended OID table accessor functions ---------*/ /* for now, this is only used in a single place, so it can remain static */ @@ -2326,6 +2347,9 @@ SECOID_Shutdown(void) dynOidEntriesAllocated = 0; dynOidEntriesUsed = 0; } + /* we are trashing the old policy state now, also reenable changing + * the policy as well */ + nss_policy_locked = PR_FALSE; memset(xOids, 0, sizeof xOids); return SECSuccess; } diff --git a/lib/util/secoid.h b/lib/util/secoid.h index e6eaa8ce9..20d4cf551 100644 --- a/lib/util/secoid.h +++ b/lib/util/secoid.h @@ -135,6 +135,15 @@ extern SECStatus NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue); extern SECStatus NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits); +/* Lock the policy so NSS_SetAlgorithmPolicy (and other policy functions) + * No longer function */ +void +NSS_LockPolicy(void); + +/* return true if policy changes are now locked out */ +PRBool +NSS_IsPolicyLocked(void); + SEC_END_PROTOS #endif /* _SECOID_H_ */ diff --git a/lib/util/secoidt.h b/lib/util/secoidt.h index 837972e2f..c73829ef8 100644 --- a/lib/util/secoidt.h +++ b/lib/util/secoidt.h @@ -538,7 +538,24 @@ struct SECOidDataStr { #define NSS_USE_ALG_IN_SSL_KX 0x00000004 /* used in SSL key exchange */ #define NSS_USE_ALG_IN_SSL 0x00000008 /* used in SSL record protocol */ #define NSS_USE_POLICY_IN_SSL 0x00000010 /* enable policy in SSL protocol */ -#define NSS_USE_ALG_RESERVED 0xfffffffc /* may be used in future */ +#define NSS_USE_ALG_IN_ANY_SIGNATURE 0x00000020 /* used in S/MIME */ +#define NSS_USE_DEFAULT_NOT_VALID 0x80000000 /* clear to make the default flag valid */ +#define NSS_USE_DEFAULT_SSL_ENABLE 0x40000000 /* default cipher suite setting 1=enable */ + +/* Combo policy bites */ +#define NSS_USE_ALG_RESERVED 0x3fffffc0 /* may be used in future */ +/* Alias of all the signature values. */ +#define NSS_USE_ALG_IN_SIGNATURE (NSS_USE_ALG_IN_CERT_SIGNATURE | \ + NSS_USE_ALG_IN_CMS_SIGNATURE | \ + NSS_USE_ALG_IN_ANY_SIGNATURE) +/* all the bits needed for a certificate signature + * and only the bits needed for a certificate signature */ +#define NSS_USE_CERT_SIGNATURE_OK (NSS_USE_ALG_IN_CERT_SIGNATURE | \ + NSS_USE_ALG_IN_ANY_SIGNATURE) +/* all the bits needed for an SMIME signature + * and only the bits needed for an SMIME signature */ +#define NSS_USE_CMS_SIGNATURE_OK (NSS_USE_ALG_IN_CMS_SIGNATURE | \ + NSS_USE_ALG_IN_ANY_SIGNATURE) /* Code MUST NOT SET or CLEAR reserved bits, and must NOT depend on them * being all zeros or having any other known value. The reserved bits diff --git a/tests/policy/crypto-policy.txt b/tests/policy/crypto-policy.txt index 9a8c0cd1b..c6de8824d 100644 --- a/tests/policy/crypto-policy.txt +++ b/tests/policy/crypto-policy.txt @@ -3,14 +3,15 @@ # 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 +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:rsa-pkcs:rsa-pss:ecdsa: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:rsa-pkcs:rsa-pss:ecdsa: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:rsa-pkcs:rsa-pss:ecdsa: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/signature NSS-POLICY-WARN.*NUMBER-OF-CERT-SIG disallow all signatures +1 disallow=ALL_allow=HMAC-SHA256:HMAC-SHA384:HMAC-SHA512:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:rsa-pkcs: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 diff --git a/tests/policy/policy.sh b/tests/policy/policy.sh index 50aee50ef..f3d16eb64 100644..100755 --- a/tests/policy/policy.sh +++ b/tests/policy/policy.sh @@ -12,6 +12,28 @@ # ######################################################################## +policy_init() +{ + SCRIPTNAME=policy.sh # sourced - $0 would point to all.sh + + if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for + CLEANUP="${SCRIPTNAME}" # cleaning this script will do it + fi + + if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then + cd ../common + . ./init.sh + fi + SCRIPTNAME=policy.sh + +} + +policy_cleanup() +{ + cd ${QADIR} + . common/cleanup.sh +} + ignore_blank_lines() { LC_ALL=C egrep -v '^[[:space:]]*(#|$)' "$1" @@ -53,6 +75,9 @@ NSS=flags=policyOnly,moduleDB html_msg $ret 0 "\"${testname}\" output is expected to match \"${match}\"" done + html "</TABLE><BR>" } +policy_init policy_run_tests +policy_cleanup diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh index d273a29b8..d63eb673c 100755 --- a/tests/ssl/ssl.sh +++ b/tests/ssl/ssl.sh @@ -886,6 +886,7 @@ ssl_policy_listsuites() cp ${P_R_CLIENTDIR}/pkcs11.txt ${P_R_CLIENTDIR}/pkcs11.txt.sav # Disallow all explicitly + testname="listsuites with all cipher disallowed by policy" setup_policy "disallow=all" ${P_R_CLIENTDIR} RET_EXP=1 list_enabled_suites | grep '^TLS_' @@ -894,6 +895,7 @@ ssl_policy_listsuites() "produced a returncode of $RET, expected is $RET_EXP" # Disallow RSA in key exchange explicitly + testname="listsuites with rsa cipher disallowed by policy" setup_policy "disallow=rsa/ssl-key-exchange" ${P_R_CLIENTDIR} RET_EXP=1 list_enabled_suites | grep '^TLS_RSA_' @@ -901,6 +903,34 @@ ssl_policy_listsuites() html_msg $RET $RET_EXP "${testname}" \ "produced a returncode of $RET, expected is $RET_EXP" + # allow by policy, but disable by default + testname="listsuites with all ciphers enabled by policy but disabled by default" + setup_policy "allow=all disable=all" ${P_R_CLIENTDIR} + RET_EXP=1 + list_enabled_suites | grep '^TLS_' + RET=$? + html_msg $RET $RET_EXP "${testname}" \ + "produced a returncode of $RET, expected is $RET_EXP" + + # allow by policy, but disable by default just rsa-kea + testname="listsuites with all ciphers enabled by policy but rsa disabled by default" + setup_policy "allow=all disable=rsa/ssl-key-exchange" ${P_R_CLIENTDIR} + RET_EXP=1 + list_enabled_suites | grep '^TLS_RSA_' + RET=$? + html_msg $RET $RET_EXP "${testname}" \ + "produced a returncode of $RET, expected is $RET_EXP" + + # list_enabled_suites tries to set a policy value explicitly, This will + # cause list_enabled_suites to fail if we lock the policy + testname="listsuites with policy locked" + setup_policy "allow=all flags=policy-lock" ${P_R_CLIENTDIR} + RET_EXP=1 + SSL_DIR="${P_R_CLIENTDIR}" ${BINDIR}/listsuites + RET=$? + html_msg $RET $RET_EXP "${testname}" \ + "produced a returncode of $RET, expected is $RET_EXP" + cp ${P_R_CLIENTDIR}/pkcs11.txt.sav ${P_R_CLIENTDIR}/pkcs11.txt html "</TABLE><BR>" @@ -925,6 +955,7 @@ ssl_policy_selfserv() cp ${P_R_SERVERDIR}/pkcs11.txt ${P_R_SERVERDIR}/pkcs11.txt.sav # Disallow RSA in key exchange explicitly + testname="Disallow RSA key exchange explicitly" setup_policy "disallow=rsa/ssl-key-exchange" ${P_R_SERVERDIR} SAVE_SERVER_OPTIONS=${SERVER_OPTIONS} diff --git a/tests/ssl/sslpolicy.txt b/tests/ssl/sslpolicy.txt index 844fd0e8f..f5e547185 100644 --- a/tests/ssl/sslpolicy.txt +++ b/tests/ssl/sslpolicy.txt @@ -7,8 +7,14 @@ # The policy string is set to the config= line in the pkcs11.txt # it currently has 2 keywords: # -# disallow= turn off the use of this algorithm by policy. +# disallow= turn off the use of this algorithm by policy. (implies disable) # allow= allow this algorithm to by used if selected by policy. +# disable= turn off the use of this algorithm even if allowed by policy +# (application can override) +# enable= turn off this algorithm by default (implies allow) +# flags= policy-lock: can't change policy with NSS_SetAlgorithmPolicy, +# NSS_SetOption, or SSL_SetCipherPolicy +# ssl-lock: can't change the cipher suite settings with the application. # # The syntax is disallow=algorithm{/uses}:algorithm{/uses} # where {} signifies an optional element @@ -76,6 +82,9 @@ # SECT571R1 # Signatures: # DSA +# RSA-PKCS +# RSA-PSS +# ECDSA # Hashes: # MD2 # MD4 @@ -137,7 +146,8 @@ # ssl-key-exchange # key-exchange (includes ssl-key-exchange) # cert-signature -# signature (includes cert-signature) +# all-signature (includes cert-signature) +# signature (all signatures off, some signature allowed based on other option) # all (includes all of the above) #----------------------------------------------- # In addition there are the following options: @@ -147,31 +157,48 @@ # they have the following syntax: # allow=min-rsa=512:min-dh=1024 # +# in the following tests, we use the cipher suite 'd': +# d SSL3 RSA WITH 3DES EDE CBC SHA (=:000a). +# NOTE: the certificates used in validation are rsa-pkcs1/sha256 signed. +# # Exp Enable Enable Cipher Config Policy Test Name # Ret EC TLS # turn on single cipher - 0 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Allowed by Narrow Policy - 0 noECC SSL3 d disallow=all_allow=hmac-sha1/ssl,ssl-key-exchange:sha256/cert-signature:rsa/ssl-key-exchange:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Allowed by Strict Policy - 0 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Allow All Explicitly - 1 noECC SSL3 d disallow=all Disallow All Explicitly. + 0 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:rsa:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Allowed by Narrow Policy + 0 noECC SSL3 d disallow=all_allow=hmac-sha1/ssl,ssl-key-exchange:sha256/all-signature:rsa-pkcs/all-signature:rsa/ssl-key-exchange:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Allowed by Strict Policy + 0 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:dsa/all:rsa-pss/all:ecdsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Allow All Explicitly + 1 noECC SSL3 d disallow=all Disallow All Explicitly # turn off signature only - 1 noECC SSL3 d disallow=sha256 Disallow SHA256 Signatures Explicitly. - 1 noECC SSL3 d disallow=all_allow=hmac-sha1:rsa/ssl-key-exchange:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow SHA256 Signatures Implicitly Narrow. - 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha384/all:sha512/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow SHA256 Signatures Implicitly. + 1 noECC SSL3 d disallow=all/signature Disallow all signatures with Explicitly + 1 noECC SSL3 d disallow=sha256 Disallow SHA256 Explicitly + 1 noECC SSL3 d disallow=sha256/cert-signature Disallow SHA256 Certificate signature Explicitly + 1 noECC SSL3 d disallow=sha256/signature Disallow All SHA256 signatures Explicitly + 1 noECC SSL3 d disallow=sha256/all-signature Disallow Any SHA256 signature Explicitly + 1 noECC SSL3 d disallow=all_allow=hmac-sha1:rsa/ssl-key-exchange:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow SHA256 Signatures Implicitly Narrow + 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:dsa/all:ecdsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow SHA256 Signatures Implicitly # turn off single cipher 1 noECC SSL3 d disallow=des-ede3-cbc Disallow Cipher Explicitly - 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa:des-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow Cipher Implicitly Narrow. - 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-verion-max=tls1.2 Disallow Cipher Implicitly. + 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:rsa:des-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow Cipher Implicitly Narrow + 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-verion-max=tls1.2 Disallow Cipher Implicitly # turn off H-Mac 1 noECC SSL3 d disallow=hmac-sha1 Disallow HMAC Explicitly - 1 noECC SSL3 d disallow=all_allow=md5:sha256:rsa:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow HMAC Implicitly Narrow. - 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow HMAC Signatures Implicitly. + 1 noECC SSL3 d disallow=all_allow=md5:sha256:rsa:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow HMAC Implicitly Narrow + 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow HMAC Signatures Implicitly # turn off key exchange - 1 noECC SSL3 d disallow=rsa/ssl-key-exchange Disallow Key Exchange Explicitly. - 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:dh-dss:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow Key Exchange Implicitly Narrow. - 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow Key Exchnage Signatures Implicitly. + 1 noECC SSL3 d disallow=rsa/ssl-key-exchange Disallow Key Exchange Explicitly + 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:dh-dss:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow Key Exchange Implicitly Narrow + 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow Key Exchange Signatures Implicitly # turn off version 1 noECC SSL3 d allow=tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Exlicitly - 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa:des-ede3-cbc:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly Narrow. - 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly. - 0 noECC SSL3 d disallow=dsa Disallow DSA Signatures Explicitly. + 1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:rsa:des-ede3-cbc:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly Narrow + 1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly + 0 noECC SSL3 d disallow=dsa Disallow DSA Signatures Explicitly + 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly +# test default settings +# NOTE: tstclient will attempt to overide the defaults, so we detect we +# were successful by locking in our settings + 0 noECC SSL3 d allow=all_disable=all Disable all by default, application override + 1 noECC SSL3 d allow=all_disable=all_flags=ssl-lock,policy-lock Disable all by default, prevent application from enabling + 0 noECC SSL3 d allow=all_disable=all_flags=policy-lock Disable all by default, lock policy (application can still change the ciphers) +# explicitly enable :002f RSA_AES_128_CBC_SHA1 and lock it in + 0 noECC SSL3 d allow=all_disable=all_enable=hmac-sha1:sha256:rsa-pkcs:rsa:aes128-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0_flags=ssl-lock Lock in a different ciphersuite that the one the application asks for |