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

Reply via email to