# HG changeset patch # User Daiki Ueno # Date 1542120846 -3600 # Tue Nov 13 15:54:06 2018 +0100 # Node ID 5046749fa8a56a99c251bc1cdd1b3302f43947d2 # Parent 0d97145d524ab35b8bc2a4a8aea60a83bd244f14 Bug 1493936, add a new "DSA" policy keyword Summary: This adds a new policy keyword "DSA" to explicitly disable DSA in TLS 1.2 or earlier. We could make this a bit more generic, e.g., by adding "ECDSA", "RSA-PSS" etc. However, considering the current use of policy in [fedora-crypto-policies](https://gitlab.com/redhat-crypto/fedora-crypto-policies), I realized that adding new keywords may cause compatibility problems; because the Fedora configuration has `disallow=ALL`, all new keywords would be disabled by default. I think it's okay for DSA, though. Reviewers: kaie Reviewed By: kaie Bug #: 1493936 Differential Revision: https://phabricator.services.mozilla.com/D6777 diff --git a/lib/certhigh/certvfy.c b/lib/certhigh/certvfy.c --- a/lib/certhigh/certvfy.c +++ b/lib/certhigh/certvfy.c @@ -37,7 +37,7 @@ CERT_CertTimesValid(CERTCertificate *c) return (valid == secCertTimeValid) ? SECSuccess : SECFailure; } -SECStatus +static SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key) { SECStatus rv; @@ -47,6 +47,12 @@ checkKeyParams(const SECAlgorithmID *sig PRInt32 minLen, len; sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm); + rv = NSS_GetAlgorithmPolicy(sigAlg, &policyFlags); + if (rv == SECSuccess && + !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { + PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + return SECFailure; + } switch (sigAlg) { case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c --- a/lib/pk11wrap/pk11pars.c +++ b/lib/pk11wrap/pk11pars.c @@ -384,18 +384,26 @@ static const oidValDef kxOptList[] = { { CIPHER_NAME("ECDH-RSA"), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX }, }; +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 }, +}; + typedef struct { const oidValDef *list; PRUint32 entries; const char *description; + PRBool allowEmpty; } 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" }, + { curveOptList, PR_ARRAY_SIZE(curveOptList), "ECC", PR_FALSE }, + { hashOptList, PR_ARRAY_SIZE(hashOptList), "HASH", PR_FALSE }, + { 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 }, }; static const optionFreeDef sslOptList[] = { @@ -718,7 +726,7 @@ secmod_sanityCheckCryptoPolicy(void) 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]) { + if (!enabledCount[i] && !algOptList->allowEmpty) { haveWarning = PR_TRUE; } } diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -64,6 +64,7 @@ static SECStatus ssl3_FlushHandshakeMess static CK_MECHANISM_TYPE ssl3_GetHashMechanismByHashType(SSLHashType hashType); static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash); PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme); +PRBool ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme); const PRUint8 ssl_hello_retry_random[] = { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, @@ -4309,6 +4310,22 @@ ssl_IsRsaPssSignatureScheme(SSLSignature return PR_FALSE; } +PRBool +ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme) +{ + switch (scheme) { + case ssl_sig_dsa_sha256: + case ssl_sig_dsa_sha384: + case ssl_sig_dsa_sha512: + case ssl_sig_dsa_sha1: + return PR_TRUE; + + default: + return PR_FALSE; + } + return PR_FALSE; +} + SSLAuthType ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme) { @@ -6017,6 +6034,13 @@ ssl_CanUseSignatureScheme(SSLSignatureSc return PR_FALSE; } + if (ssl_IsDsaSignatureScheme(scheme) && + (NSS_GetAlgorithmPolicy(SEC_OID_ANSIX9_DSA_SIGNATURE, &policy) == + SECSuccess) && + !(policy & NSS_USE_ALG_IN_SSL_KX)) { + return PR_FALSE; + } + hashType = ssl_SignatureSchemeToHashType(scheme); if (requireSha1 && (hashType != ssl_hash_sha1)) { return PR_FALSE; @@ -9490,6 +9514,14 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, continue; } + /* Skip DSA scheme if it is disabled by policy. */ + if (ssl_IsDsaSignatureScheme(ss->ssl3.signatureSchemes[i]) && + (NSS_GetAlgorithmPolicy(SEC_OID_ANSIX9_DSA_SIGNATURE, &policy) == + SECSuccess) && + !(policy & NSS_USE_ALG_IN_SSL_KX)) { + continue; + } + if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess) || (policy & NSS_USE_ALG_IN_SSL_KX)) { rv = sslBuffer_AppendNumber(buf, ss->ssl3.signatureSchemes[i], 2); diff --git a/tests/ssl/sslpolicy.txt b/tests/ssl/sslpolicy.txt --- a/tests/ssl/sslpolicy.txt +++ b/tests/ssl/sslpolicy.txt @@ -74,6 +74,8 @@ # SECT409R1 # SECT571K1 # SECT571R1 +# Signatures: +# DSA # Hashes: # MD2 # MD4 @@ -172,3 +174,4 @@ 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.