Remove hard coded ecdsaWithSHA1 hack in ssl routines and check for RSA
authorDr. Stephen Henson <steve@openssl.org>
Sun, 14 Aug 2011 13:45:19 +0000 (13:45 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 14 Aug 2011 13:45:19 +0000 (13:45 +0000)
using OBJ xref utilities instead of string comparison with OID name.

This removes the arbitrary restriction on using SHA1 only with some ECC
ciphersuites.

CHANGES
ssl/ssl_lib.c

diff --git a/CHANGES b/CHANGES
index 011df12db373725680e7382f1017fcbeaa87bfdc..65bbce6c39b96f0eacfabfef6d7b5161a94f3022 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 
  Changes between 1.0.0d and 1.0.0e [xx XXX xxxx]
 
 
  Changes between 1.0.0d and 1.0.0e [xx XXX xxxx]
 
+  *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check
+     signature public key algorithm by using OID xref utilities instead.
+     Before this you could only use some ECC ciphersuites with SHA1 only.
+     [Steve Henson]
+
   *) Add protection against ECDSA timing attacks as mentioned in the paper
      by Billy Bob Brumley and Nicola Tuveri, see:
 
   *) Add protection against ECDSA timing attacks as mentioned in the paper
      by Billy Bob Brumley and Nicola Tuveri, see:
 
index 6ed9ca51c004ba08a8ee99dd34f50d53fb4433a4..22039fb1680bc418a6ddcb87696790551cdac1f0 100644 (file)
@@ -1996,7 +1996,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
 #endif
        X509 *x = NULL;
        EVP_PKEY *ecc_pkey = NULL;
 #endif
        X509 *x = NULL;
        EVP_PKEY *ecc_pkey = NULL;
-       int signature_nid = 0;
+       int signature_nid = 0, pk_nid = 0, md_nid = 0;
 
        if (c == NULL) return;
 
 
        if (c == NULL) return;
 
@@ -2126,18 +2126,15 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
                    EVP_PKEY_bits(ecc_pkey) : 0;
                EVP_PKEY_free(ecc_pkey);
                if ((x->sig_alg) && (x->sig_alg->algorithm))
                    EVP_PKEY_bits(ecc_pkey) : 0;
                EVP_PKEY_free(ecc_pkey);
                if ((x->sig_alg) && (x->sig_alg->algorithm))
+                       {
                        signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
                        signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
+                       OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
+                       }
 #ifndef OPENSSL_NO_ECDH
                if (ecdh_ok)
                        {
 #ifndef OPENSSL_NO_ECDH
                if (ecdh_ok)
                        {
-                       const char *sig = OBJ_nid2ln(signature_nid);
-                       if (sig == NULL)
-                               {
-                               ERR_clear_error();
-                               sig = "unknown";
-                               }
-                               
-                       if (strstr(sig, "WithRSA"))
+
+                       if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa)
                                {
                                mask_k|=SSL_kECDHr;
                                mask_a|=SSL_aECDH;
                                {
                                mask_k|=SSL_kECDHr;
                                mask_a|=SSL_aECDH;
@@ -2148,7 +2145,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
                                        }
                                }
 
                                        }
                                }
 
-                       if (signature_nid == NID_ecdsa_with_SHA1)
+                       if (pk_nid == NID_X9_62_id_ecPublicKey)
                                {
                                mask_k|=SSL_kECDHe;
                                mask_a|=SSL_aECDH;
                                {
                                mask_k|=SSL_kECDHe;
                                mask_a|=SSL_aECDH;
@@ -2202,7 +2199,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
        unsigned long alg_k, alg_a;
        EVP_PKEY *pkey = NULL;
        int keysize = 0;
        unsigned long alg_k, alg_a;
        EVP_PKEY *pkey = NULL;
        int keysize = 0;
-       int signature_nid = 0;
+       int signature_nid = 0, md_nid = 0, pk_nid = 0;
        const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
 
        alg_k = cs->algorithm_mkey;
        const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
 
        alg_k = cs->algorithm_mkey;
@@ -2221,7 +2218,10 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
        /* This call populates the ex_flags field correctly */
        X509_check_purpose(x, -1, 0);
        if ((x->sig_alg) && (x->sig_alg->algorithm))
        /* This call populates the ex_flags field correctly */
        X509_check_purpose(x, -1, 0);
        if ((x->sig_alg) && (x->sig_alg->algorithm))
+               {
                signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
                signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
+               OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
+               }
        if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr)
                {
                /* key usage, if present, must allow key agreement */
        if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr)
                {
                /* key usage, if present, must allow key agreement */
@@ -2233,7 +2233,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
                if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION)
                        {
                        /* signature alg must be ECDSA */
                if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION)
                        {
                        /* signature alg must be ECDSA */
-                       if (signature_nid != NID_ecdsa_with_SHA1)
+                       if (pk_nid != NID_X9_62_id_ecPublicKey)
                                {
                                SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
                                return 0;
                                {
                                SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
                                return 0;
@@ -2243,13 +2243,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
                        {
                        /* signature alg must be RSA */
 
                        {
                        /* signature alg must be RSA */
 
-                       const char *sig = OBJ_nid2ln(signature_nid);
-                       if (sig == NULL)
-                               {
-                               ERR_clear_error();
-                               sig = "unknown";
-                               }
-                       if (strstr(sig, "WithRSA") == NULL)
+                       if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa)
                                {
                                SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
                                return 0;
                                {
                                SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
                                return 0;