[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Mon May 18 17:57:46 UTC 2015


The branch master has been updated
       via  6383d31645c6381817f26e2997b8bf58ec903edb (commit)
       via  d376e57d6826e56f4c922806e088a111c52f9e92 (commit)
       via  76106e60a827ddaefe1fee28a749018241d8f517 (commit)
      from  6c5b6cb035666d46495ccbe4a4f3d5e3a659cd40 (commit)


- Log -----------------------------------------------------------------
commit 6383d31645c6381817f26e2997b8bf58ec903edb
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Tue May 12 22:17:34 2015 +0100

    Move certificate validity flags out of CERT.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit d376e57d6826e56f4c922806e088a111c52f9e92
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Tue May 12 18:56:39 2015 +0100

    Move signing digest out of CERT.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 76106e60a827ddaefe1fee28a749018241d8f517
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Tue May 12 17:17:37 2015 +0100

    CERT tidy
    
    Move per-connection state out of the CERT structure: which should just be
    for shared configuration data (e.g. certificates to use).
    
    In particular move temporary premaster secret, raw ciphers, peer signature
    algorithms and shared signature algorithms.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

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

Summary of changes:
 ssl/s3_clnt.c  |  20 +++++-----
 ssl/s3_lib.c   |  13 ++++++-
 ssl/s3_srvr.c  |   8 ++--
 ssl/ssl_cert.c |  36 +-----------------
 ssl/ssl_lib.c  |  40 ++++++++------------
 ssl/ssl_locl.h |  50 +++++++++++++------------
 ssl/t1_lib.c   | 115 +++++++++++++++++++++++++++++++++------------------------
 7 files changed, 135 insertions(+), 147 deletions(-)

diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index c0dec1e..3b49fa4 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -2163,8 +2163,8 @@ int ssl3_get_certificate_request(SSL *s)
         }
         /* Clear certificate digests and validity flags */
         for (i = 0; i < SSL_PKEY_NUM; i++) {
-            s->cert->pkeys[i].digest = NULL;
-            s->cert->pkeys[i].valid_flags = 0;
+            s->s3->tmp.md[i] = NULL;
+            s->s3->tmp.valid_flags[i] = 0;
         }
         if ((llen & 1) || !tls1_save_sigalgs(s, p, llen)) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
@@ -3003,13 +3003,13 @@ int ssl3_send_client_key_exchange(SSL *s)
 #endif
         /* If we haven't written everything save PMS */
     if (n <= 0) {
-        s->cert->pms = pms;
-        s->cert->pmslen = pmslen;
+        s->s3->tmp.pms = pms;
+        s->s3->tmp.pmslen = pmslen;
     } else {
         /* If we don't have a PMS restore */
         if (pms == NULL) {
-            pms = s->cert->pms;
-            pmslen = s->cert->pmslen;
+            pms = s->s3->tmp.pms;
+            pmslen = s->s3->tmp.pmslen;
         }
         if (pms == NULL) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
@@ -3022,7 +3022,7 @@ int ssl3_send_client_key_exchange(SSL *s)
                                                         session->master_key,
                                                         pms, pmslen);
         OPENSSL_clear_free(pms, pmslen);
-        s->cert->pms = NULL;
+        s->s3->tmp.pms = NULL;
         if (s->session->master_key_length < 0) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
             SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
@@ -3035,7 +3035,7 @@ int ssl3_send_client_key_exchange(SSL *s)
     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
  err:
     OPENSSL_clear_free(pms, pmslen);
-    s->cert->pms = NULL;
+    s->s3->tmp.pms = NULL;
 #ifndef OPENSSL_NO_EC
     BN_CTX_free(bn_ctx);
     OPENSSL_free(encodedPoint);
@@ -3081,7 +3081,7 @@ int ssl3_send_client_verify(SSL *s)
         if (SSL_USE_SIGALGS(s)) {
             long hdatalen = 0;
             void *hdata;
-            const EVP_MD *md = s->cert->key->digest;
+            const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
             hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
             if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
@@ -3197,7 +3197,7 @@ static int ssl3_check_client_certificate(SSL *s)
     if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey)
         return 0;
     /* If no suitable signature algorithm can't use certificate */
-    if (SSL_USE_SIGALGS(s) && !s->cert->key->digest)
+    if (SSL_USE_SIGALGS(s) && !s->s3->tmp.md[s->cert->key - s->cert->pkeys])
         return 0;
     /*
      * If strict mode check suitability of chain before using it. This also
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 1a67e4e..c28c447 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2902,6 +2902,9 @@ void ssl3_free(SSL *s)
 #endif
 
     sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
     BIO_free(s->s3->handshake_buffer);
     if (s->s3->handshake_dgst)
         ssl3_free_digest_list(s);
@@ -2922,6 +2925,12 @@ void ssl3_clear(SSL *s)
 
     ssl3_cleanup_key_block(s);
     sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    s->s3->tmp.ciphers_raw = NULL;
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    s->s3->tmp.pms = NULL;
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = NULL;
 
 #ifndef OPENSSL_NO_DH
     DH_free(s->s3->tmp.dh);
@@ -3317,7 +3326,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         if (SSL_USE_SIGALGS(s)) {
             if (s->session && s->session->sess_cert) {
                 const EVP_MD *sig;
-                sig = s->session->sess_cert->peer_key->digest;
+                sig = s->s3->tmp.peer_md;
                 if (sig) {
                     *(int *)parg = EVP_MD_type(sig);
                     return 1;
@@ -3883,7 +3892,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
         if ((c->algorithm_ssl & SSL_TLSV1_2) && !SSL_USE_TLS1_2_CIPHERS(s))
             continue;
 
-        ssl_set_cert_masks(cert, c);
+        ssl_set_masks(s, c);
         mask_k = cert->mask_k;
         mask_a = cert->mask_a;
         emask_k = cert->export_mask_k;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index ce092a7..6bc80d5 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -3572,13 +3572,13 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
         sk_SSL_CIPHER_zero(sk);
     }
 
-    OPENSSL_free(s->cert->ciphers_raw);
-    s->cert->ciphers_raw = BUF_memdup(p, num);
-    if (s->cert->ciphers_raw == NULL) {
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    s->s3->tmp.ciphers_raw = BUF_memdup(p, num);
+    if (s->s3->tmp.ciphers_raw == NULL) {
         SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
         goto err;
     }
-    s->cert->ciphers_rawlen = (size_t)num;
+    s->s3->tmp.ciphers_rawlen = (size_t)num;
 
     for (i = 0; i < num; i += n) {
         /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index d8b47e6..14c0c16 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -165,21 +165,6 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void)
     return ssl_x509_store_ctx_idx;
 }
 
-void ssl_cert_set_default_md(CERT *cert)
-{
-    /* Set digest values to defaults */
-#ifndef OPENSSL_NO_DSA
-    cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
-#endif
-#ifndef OPENSSL_NO_RSA
-    cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
-    cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
-#endif
-#ifndef OPENSSL_NO_EC
-    cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
-#endif
-}
-
 CERT *ssl_cert_new(void)
 {
     CERT *ret = OPENSSL_malloc(sizeof(*ret));
@@ -192,7 +177,6 @@ CERT *ssl_cert_new(void)
 
     ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
     ret->references = 1;
-    ssl_cert_set_default_md(ret);
     ret->sec_cb = ssl_security_default_callback;
     ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL;
     ret->sec_ex = NULL;
@@ -286,7 +270,6 @@ CERT *ssl_cert_dup(CERT *cert)
                 goto err;
             }
         }
-        rpk->valid_flags = 0;
 #ifndef OPENSSL_NO_TLSEXT
         if (cert->pkeys[i].serverinfo != NULL) {
             /* Just copy everything. */
@@ -306,16 +289,7 @@ CERT *ssl_cert_dup(CERT *cert)
     }
 
     ret->references = 1;
-    /*
-     * Set digests to defaults. NB: we don't copy existing values as they
-     * will be set during handshake.
-     */
-    ssl_cert_set_default_md(ret);
-    /* Peer sigalgs set to NULL as we get these from handshake too */
-    ret->peer_sigalgs = NULL;
-    ret->peer_sigalgslen = 0;
-    /* Configured sigalgs however we copy across */
-
+    /* Configured sigalgs copied across */
     if (cert->conf_sigalgs) {
         ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
         if (!ret->conf_sigalgs)
@@ -361,8 +335,6 @@ CERT *ssl_cert_dup(CERT *cert)
         ret->chain_store = cert->chain_store;
     }
 
-    ret->ciphers_raw = NULL;
-
     ret->sec_cb = cert->sec_cb;
     ret->sec_level = cert->sec_level;
     ret->sec_ex = cert->sec_ex;
@@ -402,8 +374,6 @@ void ssl_cert_clear_certs(CERT *c)
         cpk->serverinfo = NULL;
         cpk->serverinfo_length = 0;
 #endif
-        /* Clear all flags apart from explicit sign */
-        cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
     }
 }
 
@@ -438,20 +408,16 @@ void ssl_cert_free(CERT *c)
 #endif
 
     ssl_cert_clear_certs(c);
-    OPENSSL_free(c->peer_sigalgs);
     OPENSSL_free(c->conf_sigalgs);
     OPENSSL_free(c->client_sigalgs);
     OPENSSL_free(c->shared_sigalgs);
     OPENSSL_free(c->ctypes);
     X509_STORE_free(c->verify_store);
     X509_STORE_free(c->chain_store);
-    OPENSSL_free(c->ciphers_raw);
 #ifndef OPENSSL_NO_TLSEXT
     custom_exts_free(&c->cli_ext);
     custom_exts_free(&c->srv_ext);
 #endif
-    OPENSSL_clear_free(c->pms, c->pmslen);
-    c->pms = NULL;
     OPENSSL_free(c);
 }
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index b9ae025..b44cb19 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1076,10 +1076,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
 
     case SSL_CTRL_GET_RAW_CIPHERLIST:
         if (parg) {
-            if (s->cert->ciphers_raw == NULL)
+            if (s->s3->tmp.ciphers_raw == NULL)
                 return 0;
-            *(unsigned char **)parg = s->cert->ciphers_raw;
-            return (int)s->cert->ciphers_rawlen;
+            *(unsigned char **)parg = s->s3->tmp.ciphers_raw;
+            return (int)s->s3->tmp.ciphers_rawlen;
         } else
             return ssl_put_cipher_by_char(s, NULL, NULL);
     case SSL_CTRL_GET_EXTMS_SUPPORT:
@@ -1933,9 +1933,11 @@ void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg)
     ssl_cert_set_cert_cb(s->cert, cb, arg);
 }
 
-void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
+void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
 {
     CERT_PKEY *cpk;
+    CERT *c = s->cert;
+    int *pvalid = s->s3->tmp.valid_flags;
     int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign;
     int rsa_enc_export, dh_rsa_export, dh_dsa_export;
     int rsa_tmp_export, dh_tmp_export, kl;
@@ -1972,22 +1974,21 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
     have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto);
 #endif
     cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]);
-    rsa_enc = cpk->valid_flags & CERT_PKEY_VALID;
+    rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID;
     rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
     cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]);
-    rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN;
+    rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN;
     cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]);
-    dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN;
+    dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN;
     cpk = &(c->pkeys[SSL_PKEY_DH_RSA]);
-    dh_rsa = cpk->valid_flags & CERT_PKEY_VALID;
+    dh_rsa = pvalid[SSL_PKEY_DH_RSA] & CERT_PKEY_VALID;
     dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
     cpk = &(c->pkeys[SSL_PKEY_DH_DSA]);
-/* FIX THIS EAY EAY EAY */
-    dh_dsa = cpk->valid_flags & CERT_PKEY_VALID;
+    dh_dsa = pvalid[SSL_PKEY_DH_DSA] & CERT_PKEY_VALID;
     dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
     cpk = &(c->pkeys[SSL_PKEY_ECC]);
 #ifndef OPENSSL_NO_EC
-    have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID;
+    have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
 #endif
     mask_k = 0;
     mask_a = 0;
@@ -2063,7 +2064,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
             (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
         ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
             (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
-        if (!(cpk->valid_flags & CERT_PKEY_SIGN))
+        if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
             ecdsa_ok = 0;
         ecc_pkey = X509_get_pubkey(x);
         ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0;
@@ -2204,7 +2205,7 @@ static int ssl_get_server_cert_index(const SSL *s)
     return idx;
 }
 
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
+CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
 {
     CERT *c;
     int i;
@@ -2212,7 +2213,7 @@ CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
     c = s->cert;
     if (!s->s3 || !s->s3->tmp.new_cipher)
         return NULL;
-    ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
+    ssl_set_masks(s, s->s3->tmp.new_cipher);
 
 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
     /*
@@ -2269,7 +2270,7 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher,
         return (NULL);
     }
     if (pmd)
-        *pmd = c->pkeys[idx].digest;
+        *pmd = s->s3->tmp.md[idx];
     return c->pkeys[idx].privatekey;
 }
 
@@ -2826,15 +2827,6 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
     if (new_cert == NULL) {
         return NULL;
     }
-    /* Preserve any already negotiated parameters */
-    if (ssl->server) {
-        new_cert->peer_sigalgs = ssl->cert->peer_sigalgs;
-        new_cert->peer_sigalgslen = ssl->cert->peer_sigalgslen;
-        ssl->cert->peer_sigalgs = NULL;
-        new_cert->ciphers_raw = ssl->cert->ciphers_raw;
-        new_cert->ciphers_rawlen = ssl->cert->ciphers_rawlen;
-        ssl->cert->ciphers_raw = NULL;
-    }
     ssl_cert_free(ssl->cert);
     ssl->cert = new_cert;
 
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 91eb119..d2ee634 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1277,6 +1277,30 @@ typedef struct ssl3_state_st {
         char *new_compression;
 #  endif
         int cert_request;
+        /* Raw values of the cipher list from a client */
+        unsigned char *ciphers_raw;
+        size_t ciphers_rawlen;
+        /* Temporary storage for premaster secret */
+        unsigned char *pms;
+        size_t pmslen;
+        /*
+         * signature algorithms peer reports: e.g. supported signature
+         * algorithms extension for server or as part of a certificate
+         * request for client.
+         */
+        unsigned char *peer_sigalgs;
+        /* Size of above array */
+        size_t peer_sigalgslen;
+        /* Digest peer uses for signing */
+        const EVP_MD *peer_md;
+        /* Array of digests used for signing */
+        const EVP_MD *md[SSL_PKEY_NUM];
+        /*
+         * Set if corresponding CERT_PKEY can be used with current
+         * SSL session: e.g. appropriate curve, signature algorithms etc.
+         * If zero it can't be used at all.
+         */
+        int valid_flags[SSL_PKEY_NUM];
     } tmp;
 
     /* Connection binding to prevent renegotiation attacks */
@@ -1425,8 +1449,6 @@ typedef struct dtls1_state_st {
 typedef struct cert_pkey_st {
     X509 *x509;
     EVP_PKEY *privatekey;
-    /* Digest to use when signing */
-    const EVP_MD *digest;
     /* Chain for this certificate */
     STACK_OF(X509) *chain;
 # ifndef OPENSSL_NO_TLSEXT
@@ -1440,12 +1462,6 @@ typedef struct cert_pkey_st {
     unsigned char *serverinfo;
     size_t serverinfo_length;
 # endif
-    /*
-     * Set if CERT_PKEY can be used with current SSL session: e.g.
-     * appropriate curve, signature algorithms etc. If zero it can't be used
-     * at all.
-     */
-    int valid_flags;
 } CERT_PKEY;
 /* Retrieve Suite B flags */
 # define tls1_suiteb(s)  (s->cert->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS)
@@ -1531,16 +1547,6 @@ typedef struct cert_st {
      */
     unsigned char *ctypes;
     size_t ctype_num;
-    /* Temporary storage for premaster secret */
-    unsigned char *pms;
-    size_t pmslen;
-    /*
-     * signature algorithms peer reports: e.g. supported signature algorithms
-     * extension for server or as part of a certificate request for client.
-     */
-    unsigned char *peer_sigalgs;
-    /* Size of above array */
-    size_t peer_sigalgslen;
     /*
      * suppported signature algorithms. When set on a client this is sent in
      * the client hello as the supported signature algorithms extension. For
@@ -1580,9 +1586,6 @@ typedef struct cert_st {
      */
     X509_STORE *chain_store;
     X509_STORE *verify_store;
-    /* Raw values of the cipher list from a client */
-    unsigned char *ciphers_raw;
-    size_t ciphers_rawlen;
     /* Custom extension methods for server and client */
     custom_ext_methods cli_ext;
     custom_ext_methods srv_ext;
@@ -1869,7 +1872,6 @@ void ssl_clear_cipher_ctx(SSL *s);
 int ssl_clear_bad_session(SSL *s);
 __owur CERT *ssl_cert_new(void);
 __owur CERT *ssl_cert_dup(CERT *cert);
-void ssl_cert_set_default_md(CERT *cert);
 void ssl_cert_clear_certs(CERT *c);
 void ssl_cert_free(CERT *c);
 __owur SESS_CERT *ssl_sess_cert_new(void);
@@ -1914,14 +1916,14 @@ __owur int ssl_ctx_security(SSL_CTX *ctx, int op, int bits, int nid, void *other
 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(const SSL *s);
+__owur CERT_PKEY *ssl_get_server_send_pkey(SSL *s);
 #  ifndef OPENSSL_NO_TLSEXT
 __owur int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
                                    size_t *serverinfo_length);
 #  endif
 __owur EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd);
 __owur int ssl_cert_type(X509 *x, EVP_PKEY *pkey);
-void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
+void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher);
 __owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 __owur int ssl_verify_alarm_type(long type);
 void ssl_load_ciphers(void);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index af0be02..5291574 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -795,9 +795,9 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
             return 0;
         if (set_ee_md == 2) {
             if (check_md == NID_ecdsa_with_SHA256)
-                c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256();
+                s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha256();
             else
-                c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384();
+                s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha384();
         }
     }
     return rv;
@@ -1036,8 +1036,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
     /*
      * Store the digest used so applications can retrieve it if they wish.
      */
-    if (s->session && s->session->sess_cert)
-        s->session->sess_cert->peer_key->digest = *pmd;
+    s->s3->tmp.peer_md = *pmd;
     return 1;
 }
 
@@ -1889,8 +1888,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
 # endif                         /* !OPENSSL_NO_EC */
 
     /* Clear any signature algorithms extension received */
-    OPENSSL_free(s->cert->peer_sigalgs);
-    s->cert->peer_sigalgs = NULL;
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = NULL;
 # ifdef TLSEXT_TYPE_encrypt_then_mac
     s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
 # endif
@@ -2107,7 +2106,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
             }
         } else if (type == TLSEXT_TYPE_signature_algorithms) {
             int dsize;
-            if (s->cert->peer_sigalgs || size < 2) {
+            if (s->s3->tmp.peer_sigalgs || size < 2) {
                 *al = SSL_AD_DECODE_ERROR;
                 return 0;
             }
@@ -2668,6 +2667,21 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
         return 1;
     }
 }
+/* Initialise digests to default values */
+static void ssl_set_default_md(SSL *s)
+{
+    const EVP_MD **pmd = s->s3->tmp.md;
+#ifndef OPENSSL_NO_DSA
+    pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_RSA
+    pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1();
+    pmd[SSL_PKEY_RSA_ENC] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_EC
+    pmd[SSL_PKEY_ECC] = EVP_sha1();
+#endif
+}
 
 int tls1_set_server_sigalgs(SSL *s)
 {
@@ -2679,12 +2693,12 @@ int tls1_set_server_sigalgs(SSL *s)
     s->cert->shared_sigalgslen = 0;
     /* Clear certificate digests and validity flags */
     for (i = 0; i < SSL_PKEY_NUM; i++) {
-        s->cert->pkeys[i].digest = NULL;
-        s->cert->pkeys[i].valid_flags = 0;
+        s->s3->tmp.md[i] = NULL;
+        s->s3->tmp.valid_flags[i] = 0;
     }
 
     /* If sigalgs received process it. */
-    if (s->cert->peer_sigalgs) {
+    if (s->s3->tmp.peer_sigalgs) {
         if (!tls1_process_sigalgs(s)) {
             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
             al = SSL_AD_INTERNAL_ERROR;
@@ -2697,8 +2711,9 @@ int tls1_set_server_sigalgs(SSL *s)
             al = SSL_AD_ILLEGAL_PARAMETER;
             goto err;
         }
-    } else
-        ssl_cert_set_default_md(s->cert);
+    } else {
+        ssl_set_default_md(s);
+    }
     return 1;
  err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -3386,13 +3401,13 @@ static int tls1_set_shared_sigalgs(SSL *s)
     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
         pref = conf;
         preflen = conflen;
-        allow = c->peer_sigalgs;
-        allowlen = c->peer_sigalgslen;
+        allow = s->s3->tmp.peer_sigalgs;
+        allowlen = s->s3->tmp.peer_sigalgslen;
     } else {
         allow = conf;
         allowlen = conflen;
-        pref = c->peer_sigalgs;
-        preflen = c->peer_sigalgslen;
+        pref = s->s3->tmp.peer_sigalgs;
+        preflen = s->s3->tmp.peer_sigalgslen;
     }
     nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
     if (nmatch) {
@@ -3420,12 +3435,12 @@ int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
     if (!c)
         return 0;
 
-    OPENSSL_free(c->peer_sigalgs);
-    c->peer_sigalgs = OPENSSL_malloc(dsize);
-    if (!c->peer_sigalgs)
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = OPENSSL_malloc(dsize);
+    if (s->s3->tmp.peer_sigalgs == NULL)
         return 0;
-    c->peer_sigalgslen = dsize;
-    memcpy(c->peer_sigalgs, data, dsize);
+    s->s3->tmp.peer_sigalgslen = dsize;
+    memcpy(s->s3->tmp.peer_sigalgs, data, dsize);
     return 1;
 }
 
@@ -3434,6 +3449,8 @@ int tls1_process_sigalgs(SSL *s)
     int idx;
     size_t i;
     const EVP_MD *md;
+    const EVP_MD **pmd = s->s3->tmp.md;
+    int *pvalid = s->s3->tmp.valid_flags;
     CERT *c = s->cert;
     TLS_SIGALGS *sigptr;
     if (!tls1_set_shared_sigalgs(s))
@@ -3453,12 +3470,11 @@ int tls1_process_sigalgs(SSL *s)
         if (sigs) {
             idx = tls12_get_pkey_idx(sigs[1]);
             md = tls12_get_hash(sigs[0]);
-            c->pkeys[idx].digest = md;
-            c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
+            pmd[idx] = md;
+            pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
             if (idx == SSL_PKEY_RSA_SIGN) {
-                c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
-                    CERT_PKEY_EXPLICIT_SIGN;
-                c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
+                pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN;
+                pmd[SSL_PKEY_RSA_ENC] = md;
             }
         }
     }
@@ -3467,14 +3483,13 @@ int tls1_process_sigalgs(SSL *s)
     for (i = 0, sigptr = c->shared_sigalgs;
          i < c->shared_sigalgslen; i++, sigptr++) {
         idx = tls12_get_pkey_idx(sigptr->rsign);
-        if (idx > 0 && c->pkeys[idx].digest == NULL) {
+        if (idx > 0 && pmd[idx] == NULL) {
             md = tls12_get_hash(sigptr->rhash);
-            c->pkeys[idx].digest = md;
-            c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
+            pmd[idx] = md;
+            pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
             if (idx == SSL_PKEY_RSA_SIGN) {
-                c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
-                    CERT_PKEY_EXPLICIT_SIGN;
-                c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
+                pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN;
+                pmd[SSL_PKEY_RSA_ENC] = md;
             }
         }
 
@@ -3489,18 +3504,18 @@ int tls1_process_sigalgs(SSL *s)
          * supported it stays as NULL.
          */
 # ifndef OPENSSL_NO_DSA
-        if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
-            c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
+        if (pmd[SSL_PKEY_DSA_SIGN] == NULL)
+            pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
 # endif
 # ifndef OPENSSL_NO_RSA
-        if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
-            c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
-            c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
+        if (pmd[SSL_PKEY_RSA_SIGN] == NULL) {
+            pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1();
+            pmd[SSL_PKEY_RSA_ENC] = EVP_sha1();
         }
 # endif
 # ifndef OPENSSL_NO_EC
-        if (!c->pkeys[SSL_PKEY_ECC].digest)
-            c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
+        if (pmd[SSL_PKEY_ECC] == NULL)
+            pmd[SSL_PKEY_ECC] = EVP_sha1();
 # endif
     }
     return 1;
@@ -3510,12 +3525,12 @@ int SSL_get_sigalgs(SSL *s, int idx,
                     int *psign, int *phash, int *psignhash,
                     unsigned char *rsig, unsigned char *rhash)
 {
-    const unsigned char *psig = s->cert->peer_sigalgs;
+    const unsigned char *psig = s->s3->tmp.peer_sigalgs;
     if (psig == NULL)
         return 0;
     if (idx >= 0) {
         idx <<= 1;
-        if (idx >= (int)s->cert->peer_sigalgslen)
+        if (idx >= (int)s->s3->tmp.peer_sigalgslen)
             return 0;
         psig += idx;
         if (rhash)
@@ -3524,7 +3539,7 @@ int SSL_get_sigalgs(SSL *s, int idx,
             *rsig = psig[1];
         tls1_lookup_sigalg(phash, psign, psignhash, psig);
     }
-    return s->cert->peer_sigalgslen / 2;
+    return s->s3->tmp.peer_sigalgslen / 2;
 }
 
 int SSL_get_shared_sigalgs(SSL *s, int idx,
@@ -3866,6 +3881,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
     int check_flags = 0, strict_mode;
     CERT_PKEY *cpk = NULL;
     CERT *c = s->cert;
+    int *pvalid;
     unsigned int suiteb_flags = tls1_suiteb(s);
     /* idx == -1 means checking server chains */
     if (idx != -1) {
@@ -3875,6 +3891,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
             idx = cpk - c->pkeys;
         } else
             cpk = c->pkeys + idx;
+        pvalid = s->s3->tmp.valid_flags + idx;
         x = cpk->x509;
         pk = cpk->privatekey;
         chain = cpk->chain;
@@ -3887,7 +3904,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
         if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
             rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN |
                 CERT_PKEY_VALID | CERT_PKEY_SIGN;
-            cpk->valid_flags = rv;
+            *pvalid = rv;
             return rv;
         }
 # endif
@@ -3898,6 +3915,8 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
         if (idx == -1)
             return 0;
         cpk = c->pkeys + idx;
+        pvalid = s->s3->tmp.valid_flags + idx;
+
         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
             check_flags = CERT_PKEY_STRICT_FLAGS;
         else
@@ -3923,7 +3942,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
     if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
         int default_nid;
         unsigned char rsign = 0;
-        if (c->peer_sigalgs)
+        if (s->s3->tmp.peer_sigalgs)
             default_nid = 0;
         /* If no sigalgs extension use defaults from RFC5246 */
         else {
@@ -4084,9 +4103,9 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
  end:
 
     if (TLS1_get_version(s) >= TLS1_2_VERSION) {
-        if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN)
+        if (*pvalid & CERT_PKEY_EXPLICIT_SIGN)
             rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
-        else if (cpk->digest)
+        else if (s->s3->tmp.md[idx] != NULL)
             rv |= CERT_PKEY_SIGN;
     } else
         rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
@@ -4097,10 +4116,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
      */
     if (!check_flags) {
         if (rv & CERT_PKEY_VALID)
-            cpk->valid_flags = rv;
+            *pvalid = rv;
         else {
             /* Preserve explicit sign flag, clear rest */
-            cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
+            *pvalid &= CERT_PKEY_EXPLICIT_SIGN;
             return 0;
         }
     }


More information about the openssl-commits mailing list