From d376e57d6826e56f4c922806e088a111c52f9e92 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 12 May 2015 18:56:39 +0100 Subject: [PATCH] Move signing digest out of CERT. Reviewed-by: Rich Salz --- ssl/s3_clnt.c | 6 +++--- ssl/s3_lib.c | 2 +- ssl/ssl_cert.c | 21 ------------------- ssl/ssl_lib.c | 2 +- ssl/ssl_locl.h | 7 ++++--- ssl/t1_lib.c | 56 ++++++++++++++++++++++++++++++++------------------ 6 files changed, 45 insertions(+), 49 deletions(-) diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 3486b944d4..9b83a0541e 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -2163,7 +2163,7 @@ 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->s3->tmp.md[i] = NULL; s->cert->pkeys[i].valid_flags = 0; } if ((llen & 1) || !tls1_save_sigalgs(s, p, llen)) { @@ -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 72c47d6473..c38d3e1efc 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3326,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; diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index fd7a9a60c1..45e2c021f8 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; @@ -306,11 +290,6 @@ 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); /* Configured sigalgs copied across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e143bc991e..8929ea0b9c 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2269,7 +2269,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; } diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 28a120158d..72971c48b1 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1291,6 +1291,10 @@ typedef struct ssl3_state_st { 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]; } tmp; /* Connection binding to prevent renegotiation attacks */ @@ -1439,8 +1443,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 @@ -1870,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); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 0df324dbde..1ee7afb64a 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; } @@ -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,7 +2693,7 @@ 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->s3->tmp.md[i] = NULL; s->cert->pkeys[i].valid_flags = 0; } @@ -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); @@ -3434,6 +3449,7 @@ int tls1_process_sigalgs(SSL *s) int idx; size_t i; const EVP_MD *md; + const EVP_MD **pmd = s->s3->tmp.md; CERT *c = s->cert; TLS_SIGALGS *sigptr; if (!tls1_set_shared_sigalgs(s)) @@ -3453,12 +3469,12 @@ 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; + pmd[idx] = md; c->pkeys[idx].valid_flags = 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; + pmd[SSL_PKEY_RSA_ENC] = md; } } } @@ -3467,14 +3483,14 @@ 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; + pmd[idx] = md; c->pkeys[idx].valid_flags = 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; + pmd[SSL_PKEY_RSA_ENC] = md; } } @@ -3489,18 +3505,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; @@ -4086,7 +4102,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (TLS1_get_version(s) >= TLS1_2_VERSION) { if (cpk->valid_flags & 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; -- GitLab