Added the NSS_USE_ALG_IN_SSL_KX flag for NSS_G/SetAlgorithmPolicy, which specifies the allowed hash algorithms for SSL signatures. This is only relevant in TLS 1.2 which uses the SignatureAlgorithms extension. Older TLS versions have fixed signature algorithms and formats. --- lib/ssl/ssl3con.c | 8 ++++++++ lib/ssl/ssl3ext.c | 58 ++++++++++++++++++++++++++++++++++++++---------------- lib/util/secoid.c | 4 ++-- lib/util/secoidt.h | 1 + 4 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index d5a707f..4fc696b 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -8661,6 +8661,7 @@ ssl3_PickSignatureHashAlgorithm(sslSocket *ss, SSL3SignatureAndHashAlgorithm* out) { TLSSignatureAlgorithm sigAlg; + PRUint32 policy; unsigned int i, j; /* hashPreference expresses our preferences for hash algorithms, most * preferable first. */ @@ -8719,6 +8720,13 @@ ssl3_PickSignatureHashAlgorithm(sslSocket *ss, for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) { const SSL3SignatureAndHashAlgorithm* sh = &ss->ssl3.hs.clientSigAndHash[j]; + + if (NSS_GetAlgorithmPolicy(sh->hashAlg, &policy) != SECSuccess || + !(policy & NSS_USE_ALG_IN_SSL_KX)) { + /* We ignore hashes we don't support */ + continue; + } + if (sh->sigAlg == sigAlg && sh->hashAlg == hashPreference[i]) { out->hashAlg = sh->hashAlg; return SECSuccess; diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c index 607171c..0d56662 100644 --- a/lib/ssl/ssl3ext.c +++ b/lib/ssl/ssl3ext.c @@ -2190,6 +2190,7 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) /* We ignore formats that we don't understand. */ continue; } + /* tls_sig support will be checked later in * ssl3_PickSignatureHashAlgorithm. */ ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash; @@ -2212,32 +2213,55 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) { - static const unsigned char signatureAlgorithms[] = { - /* This block is the contents of our signature_algorithms extension, in - * wire format. See - * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ - tls_hash_sha256, tls_sig_rsa, - tls_hash_sha384, tls_sig_rsa, - tls_hash_sha1, tls_sig_rsa, -#ifndef NSS_DISABLE_ECC - tls_hash_sha256, tls_sig_ecdsa, - tls_hash_sha384, tls_sig_ecdsa, - tls_hash_sha1, tls_sig_ecdsa, -#endif - tls_hash_sha256, tls_sig_dsa, - tls_hash_sha1, tls_sig_dsa, - }; + unsigned char signatureAlgorithms[32]; PRInt32 extension_length; + PRUint32 policy; + unsigned pos = 0; if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { return 0; } + if (NSS_GetAlgorithmPolicy(SEC_OID_SHA256, &policy) == SECSuccess && + (policy & NSS_USE_ALG_IN_SSL_KX)) { + signatureAlgorithms[pos++] = tls_hash_sha256; + signatureAlgorithms[pos++] = tls_sig_rsa; + +#ifndef NSS_DISABLE_ECC + signatureAlgorithms[pos++] = tls_hash_sha256; + signatureAlgorithms[pos++] = tls_sig_ecdsa; +#endif + } + + if (NSS_GetAlgorithmPolicy(SEC_OID_SHA384, &policy) == SECSuccess && + (policy & NSS_USE_ALG_IN_SSL_KX)) { + signatureAlgorithms[pos++] = tls_hash_sha384; + signatureAlgorithms[pos++] = tls_sig_rsa; + +#ifndef NSS_DISABLE_ECC + signatureAlgorithms[pos++] = tls_hash_sha384; + signatureAlgorithms[pos++] = tls_sig_ecdsa; +#endif + } + + if (NSS_GetAlgorithmPolicy(SEC_OID_SHA1, &policy) == SECSuccess && + (policy & NSS_USE_ALG_IN_SSL_KX)) { + signatureAlgorithms[pos++] = tls_hash_sha1; + signatureAlgorithms[pos++] = tls_sig_rsa; + +#ifndef NSS_DISABLE_ECC + signatureAlgorithms[pos++] = tls_hash_sha1; + signatureAlgorithms[pos++] = tls_sig_ecdsa; +#endif + signatureAlgorithms[pos++] = tls_hash_sha1; + signatureAlgorithms[pos++] = tls_sig_dsa; + } + extension_length = 2 /* extension type */ + 2 /* extension length */ + 2 /* supported_signature_algorithms length */ + - sizeof(signatureAlgorithms); + pos; if (append && maxBytes >= extension_length) { SECStatus rv; @@ -2248,7 +2272,7 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) if (rv != SECSuccess) goto loser; rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms, - sizeof(signatureAlgorithms), 2); + pos, 2); if (rv != SECSuccess) goto loser; ss->xtnData.advertised[ss->xtnData.numAdvertised++] = diff --git a/lib/util/secoid.c b/lib/util/secoid.c index 5b1714a..9f121be 100644 --- a/lib/util/secoid.c +++ b/lib/util/secoid.c @@ -1896,14 +1896,14 @@ handleHashAlgSupport(char * envVal) *nextArg++ = '\0'; } } - notEnable = (*arg == '-') ? NSS_USE_ALG_IN_CERT_SIGNATURE : 0; + notEnable = (*arg == '-') ? (NSS_USE_ALG_IN_CERT_SIGNATURE|NSS_USE_ALG_IN_SSL_KX) : 0; if ((*arg == '+' || *arg == '-') && *++arg) { int i; for (i = 1; i < SEC_OID_TOTAL; i++) { if (oids[i].desc && strstr(arg, oids[i].desc)) { xOids[i].notPolicyFlags = notEnable | - (xOids[i].notPolicyFlags & ~NSS_USE_ALG_IN_CERT_SIGNATURE); + (xOids[i].notPolicyFlags & ~(NSS_USE_ALG_IN_CERT_SIGNATURE|NSS_USE_ALG_IN_SSL_KX)); } } } diff --git a/lib/util/secoidt.h b/lib/util/secoidt.h index ff0f527..747450e 100644 --- a/lib/util/secoidt.h +++ b/lib/util/secoidt.h @@ -476,6 +476,7 @@ struct SECOidDataStr { */ #define NSS_USE_ALG_IN_CERT_SIGNATURE 0x00000001 /* CRLs and OCSP, too */ #define NSS_USE_ALG_IN_CMS_SIGNATURE 0x00000002 /* used in S/MIME */ +#define NSS_USE_ALG_IN_SSL_KX 0x00000004 /* used in SSL key exchange */ #define NSS_USE_ALG_RESERVED 0xfffffffc /* may be used in future */ /* Code MUST NOT SET or CLEAR reserved bits, and must NOT depend on them -- 1.9.0 -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto