diff options
author | Matt Caswell <matt@openssl.org> | 2018-10-11 17:01:06 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2018-10-30 12:08:42 +0000 |
commit | e45620140fce22c3251440063bc17440289d730c (patch) | |
tree | 3d2a409735c08e86cd550797e0350e76f145bb82 /ssl/statem/statem_lib.c | |
parent | 828b52951cf182d5f9cf159804419230b27840c9 (diff) |
Don't call the client_cert_cb immediately in TLSv1.3
In TLSv1.2 and below a CertificateRequest is sent after the Certificate
from the server. This means that by the time the client_cert_cb is called
on receipt of the CertificateRequest a call to SSL_get_peer_certificate()
will return the server certificate as expected. In TLSv1.3 a
CertificateRequest is sent before a Certificate message so calling
SSL_get_peer_certificate() returns NULL.
To workaround this we delay calling the client_cert_cb until after we
have processed the CertificateVerify message, when we are doing TLSv1.3.
Fixes #7384
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/7413)
Diffstat (limited to 'ssl/statem/statem_lib.c')
-rw-r--r-- | ssl/statem/statem_lib.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index e6e61f7876..75cf321b98 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -495,7 +495,18 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) } } - ret = MSG_PROCESS_CONTINUE_READING; + /* + * In TLSv1.3 on the client side we make sure we prepare the client + * certificate after the CertVerify instead of when we get the + * CertificateRequest. This is because in TLSv1.3 the CertificateRequest + * comes *before* the Certificate message. In TLSv1.2 it comes after. We + * want to make sure that SSL_get_peer_certificate() will return the actual + * server certificate from the client_cert_cb callback. + */ + if (!s->server && SSL_IS_TLS13(s) && s->s3->tmp.cert_req == 1) + ret = MSG_PROCESS_CONTINUE_PROCESSING; + else + ret = MSG_PROCESS_CONTINUE_READING; err: BIO_free(s->s3->handshake_buffer); s->s3->handshake_buffer = NULL; |