Use cert_index and sigalg
authorDr. Stephen Henson <steve@openssl.org>
Mon, 13 Feb 2017 16:32:06 +0000 (16:32 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 15 Feb 2017 02:23:54 +0000 (02:23 +0000)
Now the certificate and signature algorithm is set in one place we
can use it directly insetad of recalculating it. The old functions
ssl_get_server_send_pkey() and ssl_get_server_cert_index() are no
longer required.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2623)

ssl/s3_lib.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/statem/statem_clnt.c
ssl/statem/statem_lib.c
ssl/statem/statem_srvr.c
ssl/t1_lib.c

index 8065e15..ac2e858 100644 (file)
@@ -3137,12 +3137,11 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 
     case SSL_CTRL_SET_CURRENT_CERT:
         if (larg == SSL_CERT_SET_SERVER) {
-            CERT_PKEY *cpk;
             const SSL_CIPHER *cipher;
             if (!s->server)
                 return 0;
             cipher = s->s3->tmp.new_cipher;
-            if (!cipher)
+            if (cipher == NULL)
                 return 0;
             /*
              * No certificate for unauthenticated ciphersuites or using SRP
@@ -3150,10 +3149,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
              */
             if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
                 return 2;
-            cpk = ssl_get_server_send_pkey(s);
-            if (!cpk)
+            if (s->s3->tmp.cert_idx == -1)
                 return 0;
-            s->cert->key = cpk;
+            s->cert->key = &s->cert->pkeys[s->s3->tmp.cert_idx];
             return 1;
         }
         return ssl_cert_set_current(s->cert, larg);
index c92875f..5bc4c40 100644 (file)
@@ -2833,80 +2833,6 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
 
 #endif
 
-static int ssl_get_server_cert_index(const SSL *s)
-{
-    int idx;
-
-    if (SSL_IS_TLS13(s)) {
-        if (s->s3->tmp.sigalg == NULL) {
-            SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR);
-            return -1;
-        }
-        return s->s3->tmp.cert_idx;
-    }
-
-    idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
-    if (idx == SSL_PKEY_GOST_EC) {
-        if (s->cert->pkeys[SSL_PKEY_GOST12_512].x509)
-            idx = SSL_PKEY_GOST12_512;
-        else if (s->cert->pkeys[SSL_PKEY_GOST12_256].x509)
-            idx = SSL_PKEY_GOST12_256;
-        else if (s->cert->pkeys[SSL_PKEY_GOST01].x509)
-            idx = SSL_PKEY_GOST01;
-        else
-            idx = -1;
-    }
-    if (idx == -1)
-        SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR);
-    return idx;
-}
-
-CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
-{
-    CERT *c;
-    int i;
-
-    c = s->cert;
-    if (!s->s3 || !s->s3->tmp.new_cipher)
-        return NULL;
-    ssl_set_masks(s);
-
-    i = ssl_get_server_cert_index(s);
-
-    /* This may or may not be an error. */
-    if (i < 0)
-        return NULL;
-
-    /* May be NULL. */
-    return &c->pkeys[i];
-}
-
-EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher,
-                            const EVP_MD **pmd)
-{
-    unsigned long alg_a;
-    CERT *c;
-    int idx = -1;
-
-    alg_a = cipher->algorithm_auth;
-    c = s->cert;
-
-    if (alg_a & SSL_aDSS && c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)
-        idx = SSL_PKEY_DSA_SIGN;
-    else if (alg_a & SSL_aRSA && c->pkeys[SSL_PKEY_RSA].privatekey != NULL)
-            idx = SSL_PKEY_RSA;
-    else if (alg_a & SSL_aECDSA &&
-             c->pkeys[SSL_PKEY_ECC].privatekey != NULL)
-        idx = SSL_PKEY_ECC;
-    if (idx == -1) {
-        SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR);
-        return (NULL);
-    }
-    if (pmd)
-        *pmd = s->s3->tmp.md[idx];
-    return c->pkeys[idx].privatekey;
-}
-
 int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
                                    size_t *serverinfo_length)
 {
@@ -2915,7 +2841,7 @@ int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
     *serverinfo_length = 0;
 
     c = s->cert;
-    i = ssl_get_server_cert_index(s);
+    i = s->s3->tmp.cert_idx;
 
     if (i == -1)
         return 0;
index 6311413..09bfed6 100644 (file)
@@ -2012,12 +2012,9 @@ __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
 int ssl_undefined_function(SSL *s);
 __owur int ssl_undefined_void_function(void);
 __owur int ssl_undefined_const_function(const SSL *s);
-__owur CERT_PKEY *ssl_get_server_send_pkey(SSL *s);
 __owur int ssl_get_server_cert_serverinfo(SSL *s,
                                           const unsigned char **serverinfo,
                                           size_t *serverinfo_length);
-__owur EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c,
-                                   const EVP_MD **pmd);
 __owur int ssl_cert_type(const X509 *x, const EVP_PKEY *pkey);
 void ssl_set_masks(SSL *s);
 __owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
index 152600b..8ca3c4c 100644 (file)
@@ -2058,16 +2058,16 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
                 al = SSL_AD_DECODE_ERROR;
                 goto err;
             }
-            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
-        } else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
-            md = EVP_md5_sha1();
-        } else {
-            md = EVP_sha1();
+        } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) {
+            al = SSL_AD_INTERNAL_ERROR;
+            goto err;
         }
 
+        md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx);
+
         if (!PACKET_get_length_prefixed_2(pkt, &signature)
             || PACKET_remaining(pkt) != 0) {
             al = SSL_AD_DECODE_ERROR;
index 3a03ada..31156fd 100644 (file)
@@ -331,21 +331,16 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
-            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
-        } else {
-            /* Use default digest for this key type */
-            int idx = ssl_cert_type(NULL, pkey);
-            if (idx >= 0)
-                md = s->s3->tmp.md[idx];
-            if (md == NULL) {
+        } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) {
                 al = SSL_AD_INTERNAL_ERROR;
                 goto f_err;
-            }
         }
 
+        md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx);
+
         if (!PACKET_get_net_2(pkt, &len)) {
             SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
index 245277b..94a7caf 100644 (file)
@@ -1759,15 +1759,14 @@ static int tls_handle_status_request(SSL *s, int *al)
     if (s->ext.status_type != TLSEXT_STATUSTYPE_nothing && s->ctx != NULL
             && s->ctx->ext.status_cb != NULL) {
         int ret;
-        CERT_PKEY *certpkey = ssl_get_server_send_pkey(s);
 
         /* If no certificate can't return certificate status */
-        if (certpkey != NULL) {
+        if (s->s3->tmp.cert_idx != -1) {
             /*
              * Set current certificate to one we will use so SSL_get_certificate
              * et al can pick it up.
              */
-            s->cert->key = certpkey;
+            s->cert->key = &s->cert->pkeys[s->s3->tmp.cert_idx];
             ret = s->ctx->ext.status_cb(s, s->ctx->ext.status_arg);
             switch (ret) {
                 /* We don't want to send a status request response */
@@ -2157,11 +2156,12 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
 
     if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
         && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) {
-        if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md))
-            == NULL) {
+        if (s->s3->tmp.cert_idx == -1 || s->s3->tmp.sigalg == NULL) {
             al = SSL_AD_DECODE_ERROR;
             goto f_err;
         }
+        pkey = s->cert->pkeys[s->s3->tmp.cert_idx].privatekey;
+        md = ssl_md(s->s3->tmp.sigalg->hash_idx);
     } else {
         pkey = NULL;
     }
@@ -3214,11 +3214,11 @@ int tls_construct_server_certificate(SSL *s, WPACKET *pkt)
     CERT_PKEY *cpk;
     int al = SSL_AD_INTERNAL_ERROR;
 
-    cpk = ssl_get_server_send_pkey(s);
-    if (cpk == NULL) {
+    if (s->s3->tmp.cert_idx == -1) {
         SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
         return 0;
     }
+    cpk = &s->cert->pkeys[s->s3->tmp.cert_idx];
 
     /*
      * In TLSv1.3 the certificate chain is always preceded by a 0 length context
index d0e54d9..0ae41cd 100644 (file)
@@ -2201,7 +2201,10 @@ DH *ssl_get_auto_dh(SSL *s)
         else
             dh_secbits = 80;
     } else {
-        CERT_PKEY *cpk = ssl_get_server_send_pkey(s);
+        CERT_PKEY *cpk;
+        if (s->s3->tmp.cert_idx == -1)
+            return NULL;
+        cpk = &s->cert->pkeys[s->s3->tmp.cert_idx];
         dh_secbits = EVP_PKEY_security_bits(cpk->privatekey);
     }