diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 8065e15cb6..ac2e858e76 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -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); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index c92875f2d9..5bc4c404ce 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 6311413935..09bfed6f79 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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); diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 152600ba45..8ca3c4cc1d 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -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; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 3a03ada93a..31156fdcc8 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -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; diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 245277b433..94a7caf31b 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -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 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index d0e54d91d8..0ae41cd71e 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -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); }