[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Tue Jan 31 19:29:07 UTC 2017


The branch master has been updated
       via  f1adb0068fb04abbadf3ebbb105146bc75094197 (commit)
       via  6cbebb5516e0a505f7e4cfe286eb2ef0f0eca9a2 (commit)
       via  44b6318f4818af2ae5ec14905e55e996bbfb231a (commit)
       via  17ae384e4995f107f6743ffd61ccb28aed839e1b (commit)
       via  05b8486e47c50db658474f9a36eab91cd41d1a13 (commit)
       via  8f88cb53dd839610195d8bd58ecc790b4cd45728 (commit)
       via  2b4418ebd6a7b748b943f867eac0f3372a8dd5ea (commit)
       via  f742cda820cec70009ca914f8efbc725f3976b65 (commit)
      from  33d9341702813c0372bdb84e77a49c33142e3136 (commit)


- Log -----------------------------------------------------------------
commit f1adb0068fb04abbadf3ebbb105146bc75094197
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 22:02:11 2017 +0000

    Tidy up Suite B logic
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit 6cbebb5516e0a505f7e4cfe286eb2ef0f0eca9a2
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 18:10:17 2017 +0000

    Remove peer_md and use peer_sigalg instead.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit 44b6318f4818af2ae5ec14905e55e996bbfb231a
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 17:27:35 2017 +0000

    Simplify sigalgs code.
    
    Remove unnecessary lookup operations: use the indices and data in the
    lookup table directly.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit 17ae384e4995f107f6743ffd61ccb28aed839e1b
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 16:05:23 2017 +0000

    Add digest and key indices to table.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit 05b8486e47c50db658474f9a36eab91cd41d1a13
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 15:34:25 2017 +0000

    Don't check certificate type against ciphersuite for TLS 1.3
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit 8f88cb53dd839610195d8bd58ecc790b4cd45728
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 14:45:20 2017 +0000

    Add TLS 1.3 signing curve check
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit 2b4418ebd6a7b748b943f867eac0f3372a8dd5ea
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 13:53:54 2017 +0000

    Only allow PSS signatures with RSA keys and TLS 1.3
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

commit f742cda820cec70009ca914f8efbc725f3976b65
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 30 13:48:39 2017 +0000

    Store table entry to peer signature algorithm.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2324)

-----------------------------------------------------------------------

Summary of changes:
 ssl/s3_lib.c             |  16 +---
 ssl/ssl_locl.h           |  60 +++++++------
 ssl/statem/statem_clnt.c |  30 ++++---
 ssl/statem/statem_lib.c  |   2 +-
 ssl/t1_lib.c             | 223 ++++++++++++++++++++++-------------------------
 5 files changed, 161 insertions(+), 170 deletions(-)

diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 936a301..df9d0c7 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3177,20 +3177,10 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
 
     case SSL_CTRL_GET_PEER_SIGNATURE_NID:
-        if (SSL_USE_SIGALGS(s)) {
-            if (s->session) {
-                const EVP_MD *sig;
-                sig = s->s3->tmp.peer_md;
-                if (sig) {
-                    *(int *)parg = EVP_MD_type(sig);
-                    return 1;
-                }
-            }
-            return 0;
-        }
-        /* Might want to do something here for other versions */
-        else
+        if (s->s3->tmp.peer_sigalg == NULL)
             return 0;
+        *(int *)parg = s->s3->tmp.peer_sigalg->hash;
+        return 1;
 
     case SSL_CTRL_GET_SERVER_TMP_KEY:
 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 13be4f3..76e3a73 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -407,6 +407,12 @@
  */
 # define SSL_PKEY_GOST_EC SSL_PKEY_NUM+1
 
+/*
+ * TODO(TLS1.3) for now use RSA_SIGN keys for PSS
+ */
+
+#define SSL_PKEY_RSA_PSS_SIGN SSL_PKEY_RSA_SIGN
+
 /*-
  * SSL_kRSA <- RSA_ENC
  * SSL_kDH  <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
@@ -1180,6 +1186,29 @@ struct ssl_st {
     CRYPTO_RWLOCK *lock;
 };
 
+/*
+ * Structure containing table entry of values associated with the signature
+ * algorithms (signature scheme) extension
+*/
+typedef struct sigalg_lookup_st {
+    /* TLS 1.3 signature scheme name */
+    const char *name;
+    /* Raw value used in extension */
+    uint16_t sigalg;
+    /* NID of hash algorithm */
+    int hash;
+    /* Index of hash algorithm */
+    int hash_idx;
+    /* NID of signature algorithm */
+    int sig;
+    /* Index of signature algorithm */
+    int sig_idx;
+    /* Combined hash and signature NID, if any */
+    int sigandhash;
+    /* Required public key curve (ECDSA only) */
+    int curve;
+} SIGALG_LOOKUP;
+
 typedef struct ssl3_state_st {
     long flags;
     size_t read_mac_secret_size;
@@ -1269,10 +1298,8 @@ typedef struct ssl3_state_st {
         uint16_t *peer_sigalgs;
         /* Size of above array */
         size_t peer_sigalgslen;
-        /* Digest peer uses for signing */
-        const EVP_MD *peer_md;
-        /* Signature type: public key type or EVP_PKEY_RSA_PSS for PSS */
-        int peer_sigtype;
+        /* Sigalg peer actualy uses */
+        const SIGALG_LOOKUP *peer_sigalg;
         /* Array of digests used for signing */
         const EVP_MD *md[SSL_PKEY_NUM];
         /*
@@ -1509,25 +1536,6 @@ typedef struct {
     size_t meths_count;
 } custom_ext_methods;
 
-/*
- * Structure containing table entry of values associated with the signature
- * algorithms (signature scheme) extension
-*/
-typedef struct sigalg_lookup_st {
-    /* TLS 1.3 signature scheme name */
-    const char *name;
-    /* Raw value used in extension */
-    uint16_t sigalg;
-    /* NID of hash algorithm */
-    int hash;
-    /* NID of signature algorithm */
-    int sig;
-    /* Combined hash and signature NID, if any */
-    int sigandhash;
-    /* Required public key curve (ECDSA only) */
-    int curve;
-} SIGALG_LOOKUP;
-
 typedef struct cert_st {
     /* Current active set */
     /*
@@ -1750,7 +1758,8 @@ typedef enum tlsext_index_en {
 /* An invalid index into the TLSv1.3 PSK identities */
 #define TLSEXT_PSK_BAD_IDENTITY                                 -1
 
-#define SSL_USE_PSS(s) (s->s3->tmp.peer_sigtype == EVP_PKEY_RSA_PSS)
+#define SSL_USE_PSS(s) (s->s3->tmp.peer_sigalg != NULL && \
+                        s->s3->tmp.peer_sigalg->sig == EVP_PKEY_RSA_PSS)
 
 /* A dummy signature value not valid for TLSv1.2 signature algs */
 #define TLSEXT_signature_rsa_pss                                0x0101
@@ -2230,7 +2239,6 @@ __owur int tls_use_ticket(SSL *s);
 
 __owur int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk,
                                 const EVP_MD *md, int *ispss);
-__owur const EVP_MD *tls12_get_hash(int hash_nid);
 void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op);
 
 __owur int tls1_set_sigalgs_list(CERT *c, const char *str, int client);
@@ -2260,7 +2268,7 @@ __owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
 __owur int tls1_save_sigalgs(SSL *s, PACKET *pkt);
 __owur int tls1_process_sigalgs(SSL *s);
 __owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
-__owur int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey);
+__owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey);
 void ssl_set_client_disabled(SSL *s);
 __owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);
 
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 6bd7481..e5c60ae 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1562,17 +1562,23 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
                SSL_R_UNKNOWN_CERTIFICATE_TYPE);
         goto f_err;
     }
-
-    exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
-    if (exp_idx >= 0 && i != exp_idx
-        && (exp_idx != SSL_PKEY_GOST_EC ||
-            (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256
-             && i != SSL_PKEY_GOST01))) {
-        x = NULL;
-        al = SSL_AD_ILLEGAL_PARAMETER;
-        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
-               SSL_R_WRONG_CERTIFICATE_TYPE);
-        goto f_err;
+    /*
+     * Check certificate type is consistent with ciphersuite. For TLS 1.3
+     * skip check since TLS 1.3 ciphersuites can be used with any certificate
+     * type.
+     */
+    if (!SSL_IS_TLS13(s)) {
+        exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
+        if (exp_idx >= 0 && i != exp_idx
+            && (exp_idx != SSL_PKEY_GOST_EC ||
+                (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256
+                 && i != SSL_PKEY_GOST01))) {
+            x = NULL;
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+                   SSL_R_WRONG_CERTIFICATE_TYPE);
+            goto f_err;
+        }
     }
     s->session->peer_type = i;
 
@@ -1975,7 +1981,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
                 al = SSL_AD_DECODE_ERROR;
                 goto err;
             }
-            md = s->s3->tmp.peer_md;
+            md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx);
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index a05b67f..e21a102 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -340,7 +340,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
-            md = s->s3->tmp.peer_md;
+            md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx);
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index c906061..0b90048 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -708,47 +708,66 @@ static const uint16_t suiteb_sigalgs[] = {
 static const SIGALG_LOOKUP sigalg_lookup_tbl[] = {
 #ifndef OPENSSL_NO_EC
     {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
-     NID_sha256, EVP_PKEY_EC, NID_ecdsa_with_SHA256, NID_X9_62_prime256v1},
+     NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
+     NID_ecdsa_with_SHA256, NID_X9_62_prime256v1},
     {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
-     NID_sha384, EVP_PKEY_EC, NID_ecdsa_with_SHA384, NID_secp384r1},
+     NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
+     NID_ecdsa_with_SHA384, NID_secp384r1},
     {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
-     NID_sha512, EVP_PKEY_EC, NID_ecdsa_with_SHA512, NID_secp521r1},
+     NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
+     NID_ecdsa_with_SHA512, NID_secp521r1},
     {NULL, TLSEXT_SIGALG_ecdsa_sha1,
-     NID_sha1, EVP_PKEY_EC, NID_ecdsa_with_SHA1, NID_undef},
+     NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
+     NID_ecdsa_with_SHA1, NID_undef},
 #endif
     {"rsa_pss_sha256", TLSEXT_SIGALG_rsa_pss_sha256,
-     NID_sha256, EVP_PKEY_RSA_PSS, NID_undef, NID_undef},
+     NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
+     NID_undef, NID_undef},
     {"rsa_pss_sha384", TLSEXT_SIGALG_rsa_pss_sha384,
-     NID_sha384, EVP_PKEY_RSA_PSS, NID_undef, NID_undef},
+     NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
+     NID_undef, NID_undef},
     {"rsa_pss_sha512", TLSEXT_SIGALG_rsa_pss_sha512,
-     NID_sha512, EVP_PKEY_RSA_PSS, NID_undef, NID_undef},
+     NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
+     NID_undef, NID_undef},
     {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256,
-     NID_sha256, EVP_PKEY_RSA, NID_sha256WithRSAEncryption, NID_undef},
+     NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+     NID_sha256WithRSAEncryption, NID_undef},
     {"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384,
-     NID_sha384, EVP_PKEY_RSA, NID_sha384WithRSAEncryption, NID_undef},
+     NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+     NID_sha384WithRSAEncryption, NID_undef},
     {"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512,
-     NID_sha512, EVP_PKEY_RSA, NID_sha512WithRSAEncryption, NID_undef},
+     NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+     NID_sha512WithRSAEncryption, NID_undef},
     {"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1,
-     NID_sha1, EVP_PKEY_RSA, NID_sha1WithRSAEncryption, NID_undef},
+     NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+     NID_sha1WithRSAEncryption, NID_undef},
 #ifndef OPENSSL_NO_DSA
     {NULL, TLSEXT_SIGALG_dsa_sha256,
-     NID_sha256, EVP_PKEY_DSA, NID_dsa_with_SHA256, NID_undef},
+     NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
+     NID_dsa_with_SHA256, NID_undef},
     {NULL, TLSEXT_SIGALG_dsa_sha384,
-     NID_sha384, EVP_PKEY_DSA, NID_undef, NID_undef},
+     NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
+     NID_undef, NID_undef},
     {NULL, TLSEXT_SIGALG_dsa_sha512,
-     NID_sha512, EVP_PKEY_DSA, NID_undef, NID_undef},
+     NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
+     NID_undef, NID_undef},
     {NULL, TLSEXT_SIGALG_dsa_sha1,
-     NID_sha1, EVP_PKEY_DSA, NID_dsaWithSHA1, NID_undef},
+     NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
+     NID_dsaWithSHA1, NID_undef},
 #endif
 #ifndef OPENSSL_NO_GOST
     {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
-     NID_id_GostR3411_2012_256, NID_id_GostR3410_2012_256, NID_undef,
-     NID_undef},
+     NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
+     NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
+     NID_undef, NID_undef},
     {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
-     NID_id_GostR3411_2012_512, NID_id_GostR3410_2012_512, NID_undef,
-     NID_undef},
+     NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
+     NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
+     NID_undef, NID_undef},
     {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411,
-     NID_id_GostR3411_94, NID_id_GostR3410_2001, NID_undef, NID_undef}
+     NID_id_GostR3411_94, SSL_MD_GOST94_IDX,
+     NID_id_GostR3410_2001, SSL_PKEY_GOST01,
+     NID_undef, NID_undef}
 #endif
 };
 
@@ -766,13 +785,6 @@ static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg)
     return NULL;
 }
 
-static int tls_sigalg_get_hash(uint16_t sigalg)
-{
-    const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
-
-    return r != NULL ? r->hash : 0;
-}
-
 static int tls_sigalg_get_sig(uint16_t sigalg)
 {
     const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
@@ -823,57 +835,77 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
  * algorithms and if so set relevant digest and signature scheme in
  * s.
  */
-int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
+int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
 {
     const uint16_t *sent_sigs;
     const EVP_MD *md = NULL;
     char sigalgstr[2];
     size_t sent_sigslen, i;
     int pkeyid = EVP_PKEY_id(pkey);
-    int peer_sigtype;
+    const SIGALG_LOOKUP *lu;
 
     /* Should never happen */
     if (pkeyid == -1)
         return -1;
-    /* Check key type is consistent with signature */
-    peer_sigtype = tls_sigalg_get_sig(sig);
-    /* RSA keys can be used for RSA-PSS */
-    if (pkeyid != peer_sigtype
-        && (peer_sigtype != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA)) {
+    /* Only allow PSS for TLS 1.3 */
+    if (SSL_IS_TLS13(s) && pkeyid == EVP_PKEY_RSA)
+        pkeyid = EVP_PKEY_RSA_PSS;
+    lu = tls1_lookup_sigalg(sig);
+    /*
+     * Check sigalgs is known and key type is consistent with signature:
+     * RSA keys can be used for RSA-PSS
+     */
+    if (lu == NULL || (pkeyid != lu->sig
+        && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
 #ifndef OPENSSL_NO_EC
     if (pkeyid == EVP_PKEY_EC) {
-        unsigned char curve_id[2], comp_id;
-        /* Check compression and curve matches extensions */
-        if (!tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey)))
-            return 0;
-        if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
-            SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
-            return 0;
-        }
-        /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
-        if (tls1_suiteb(s)) {
-            if (curve_id[0])
+        EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+        int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+
+        if (SSL_IS_TLS13(s)) {
+            /* For TLS 1.3 check curve matches signature algorithm */
+
+            if (curve != lu->curve) {
+                SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
+                return 0;
+            }
+        } else {
+            unsigned char curve_id[2], comp_id;
+
+            /* Check compression and curve matches extensions */
+            if (!tls1_set_ec_id(curve_id, &comp_id, ec))
                 return 0;
-            if (curve_id[1] == TLSEXT_curve_P_256) {
-                if (tls_sigalg_get_hash(sig) != NID_sha256) {
+            if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
+                SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
+                return 0;
+            }
+            if (tls1_suiteb(s)) {
+                /* Check sigalg matches a permissible Suite B value */
+                if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256
+                    && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) {
                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
-                           SSL_R_ILLEGAL_SUITEB_DIGEST);
+                           SSL_R_WRONG_SIGNATURE_TYPE);
                     return 0;
                 }
-            } else if (curve_id[1] == TLSEXT_curve_P_384) {
-                if (tls_sigalg_get_hash(sig) != NID_sha384) {
+                /*
+                 * Suite B also requires P-256+SHA256 and P-384+SHA384:
+                 * this matches the TLS 1.3 requirements so we can just
+                 * check the curve is the expected TLS 1.3 value.
+                 * If this fails an inappropriate digest is being used.
+                 */
+                if (curve != lu->curve) {
                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
                            SSL_R_ILLEGAL_SUITEB_DIGEST);
                     return 0;
                 }
-            } else
-                return 0;
+            }
         }
-    } else if (tls1_suiteb(s))
+    } else if (tls1_suiteb(s)) {
         return 0;
+    }
 #endif
 
     /* Check signature matches a type we sent */
@@ -883,13 +915,12 @@ int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
             break;
     }
     /* Allow fallback to SHA1 if not strict mode */
-    if (i == sent_sigslen
-        && (tls_sigalg_get_hash(sig) != NID_sha1
-            || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
+    if (i == sent_sigslen && (lu->hash != NID_sha1
+        || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
-    md = tls12_get_hash(tls_sigalg_get_hash(sig));
+    md = ssl_md(lu->hash_idx);
     if (md == NULL) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
         return 0;
@@ -906,19 +937,16 @@ int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
-    /*
-     * Store the digest used so applications can retrieve it if they wish.
-     */
-    s->s3->tmp.peer_md = md;
-    s->s3->tmp.peer_sigtype = peer_sigtype;
+    /* Store the sigalg the peer uses */
+    s->s3->tmp.peer_sigalg = lu;
     return 1;
 }
 
 int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid)
 {
-    if (s->s3->tmp.peer_sigtype == NID_undef)
+    if (s->s3->tmp.peer_sigalg == NULL)
         return 0;
-    *pnid = s->s3->tmp.peer_sigtype;
+    *pnid = s->s3->tmp.peer_sigalg->sig;
     return 1;
 }
 
@@ -1325,49 +1353,6 @@ int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk,
     return 0;
 }
 
-typedef struct {
-    int nid;
-    int secbits;
-    int md_idx;
-} tls12_hash_info;
-
-static const tls12_hash_info tls12_md_info[] = {
-    {NID_md5, 64, SSL_MD_MD5_IDX},
-    {NID_sha1, 80, SSL_MD_SHA1_IDX},
-    {NID_sha224, 112, SSL_MD_SHA224_IDX},
-    {NID_sha256, 128, SSL_MD_SHA256_IDX},
-    {NID_sha384, 192, SSL_MD_SHA384_IDX},
-    {NID_sha512, 256, SSL_MD_SHA512_IDX},
-    {NID_id_GostR3411_94, 128, SSL_MD_GOST94_IDX},
-    {NID_id_GostR3411_2012_256, 128, SSL_MD_GOST12_256_IDX},
-    {NID_id_GostR3411_2012_512, 256, SSL_MD_GOST12_512_IDX},
-};
-
-static const tls12_hash_info *tls12_get_hash_info(int hash_nid)
-{
-    unsigned int i;
-    if (hash_nid == NID_undef)
-        return NULL;
-
-    for (i = 0; i < OSSL_NELEM(tls12_md_info); i++) {
-        if (tls12_md_info[i].nid == hash_nid)
-            return tls12_md_info + i;
-    }
-
-    return NULL;
-}
-
-const EVP_MD *tls12_get_hash(int hash_nid)
-{
-    const tls12_hash_info *inf;
-    if (hash_nid == NID_md5 && FIPS_mode())
-        return NULL;
-    inf = tls12_get_hash_info(hash_nid);
-    if (!inf)
-        return NULL;
-    return ssl_md(inf->md_idx);
-}
-
 static int tls12_get_pkey_idx(int sig_nid)
 {
     switch (sig_nid) {
@@ -1404,22 +1389,24 @@ static int tls12_get_pkey_idx(int sig_nid)
 }
 
 /* Check to see if a signature algorithm is allowed */
-static int tls12_sigalg_allowed(SSL *s, int op, unsigned int ptmp)
+static int tls12_sigalg_allowed(SSL *s, int op, uint16_t ptmp)
 {
-    /* See if we have an entry in the hash table and it is enabled */
-    const tls12_hash_info *hinf
-        = tls12_get_hash_info(tls_sigalg_get_hash(ptmp));
+    const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(ptmp);
     unsigned char sigalgstr[2];
+    int secbits;
 
-    if (hinf == NULL || ssl_md(hinf->md_idx) == NULL)
+    /* See if sigalgs is recognised and if hash is enabled */
+    if (lu == NULL || ssl_md(lu->hash_idx) == NULL)
         return 0;
     /* See if public key algorithm allowed */
-    if (tls12_get_pkey_idx(tls_sigalg_get_sig(ptmp)) == -1)
+    if (tls12_get_pkey_idx(lu->sig) == -1)
         return 0;
+    /* Security bits: half digest bits */
+    secbits = EVP_MD_size(ssl_md(lu->hash_idx)) * 4;
     /* Finally see if security callback allows it */
     sigalgstr[0] = (ptmp >> 8) & 0xff;
     sigalgstr[1] = ptmp & 0xff;
-    return ssl_security(s, op, hinf->secbits, hinf->nid, (void *)sigalgstr);
+    return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
 }
 
 /*
@@ -1615,7 +1602,7 @@ int tls1_process_sigalgs(SSL *s)
             continue;
         idx = tls12_get_pkey_idx(sigptr->sig);
         if (idx > 0 && pmd[idx] == NULL) {
-            md = tls12_get_hash(sigptr->hash);
+            md = ssl_md(sigptr->hash_idx);
             pmd[idx] = md;
             pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
             if (idx == SSL_PKEY_RSA_SIGN) {
@@ -1623,7 +1610,6 @@ int tls1_process_sigalgs(SSL *s)
                 pmd[SSL_PKEY_RSA_ENC] = md;
             }
         }
-
     }
     /*
      * In strict mode or TLS1.3 leave unset digests as NULL to indicate we can't
@@ -2002,8 +1988,9 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
             size_t j;
             const uint16_t *p = c->conf_sigalgs;
             for (j = 0; j < c->conf_sigalgslen; j++, p++) {
-                if (tls_sigalg_get_hash(*p) == NID_sha1
-                        && tls_sigalg_get_sig(*p) == rsign)
+                const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*p);
+
+                if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign)
                     break;
             }
             if (j == c->conf_sigalgslen) {


More information about the openssl-commits mailing list