Account for EVP_PKEY capabilities in selecting hash functions.
tls1_process_sigalgs now only determines the intersection between the peer
algorithms and those configured locally. That list is queried later to
determine the hash algorithm to use when signing CertificateVerify or
ServerKeyExchange.
This is needed to support client auth on Windows where smartcards or CAPI may
not support all hash functions.
As a bonus, this does away with more connection-global state. This avoids the
current situation where digests are chosen before keys are known (for
CertificateVerify) or for slots that don't exist.
Change-Id: Iec3619a103d691291d8ebe08ef77d574f2faf0e8
Reviewed-on: https://boringssl-review.googlesource.com/2280
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 7f20b84..083e2f4 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -425,8 +425,6 @@
{
X509 *x509;
EVP_PKEY *privatekey;
- /* Digest to use when signing */
- const EVP_MD *digest;
/* Chain for this certificate */
STACK_OF(X509) *chain;
} CERT_PKEY;
@@ -759,7 +757,6 @@
int ssl_clear_bad_session(SSL *s);
CERT *ssl_cert_new(void);
CERT *ssl_cert_dup(CERT *cert);
-void ssl_cert_set_default_md(CERT *cert);
int ssl_cert_inst(CERT **o);
void ssl_cert_clear_certs(CERT *c);
void ssl_cert_free(CERT *c);
@@ -806,7 +803,7 @@
int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s);
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
-EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd);
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c);
int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
/* ssl_get_compatible_server_ciphers determines the key exchange and
@@ -1095,6 +1092,11 @@
int ssl_parse_clienthello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert);
long ssl_get_algorithm2(SSL *s);
int tls1_process_sigalgs(SSL *s, const CBS *sigalgs);
+
+/* tls1_choose_signing_digest returns a digest for use with |pkey| based on the
+ * peer's preferences recorded for |s| and the digests supported by |pkey|. */
+const EVP_MD *tls1_choose_signing_digest(SSL *s, EVP_PKEY *pkey);
+
size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs);
int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
CBS *cbs, EVP_PKEY *pkey);