Decide whether or not to request client certificates early.

This allows us to merge two of the ssl3_digest_cached_records calls which were
almost, but not completely, redundant. Also catches a missing case: the buffer
may be discarded if doing session resumption but otherwise enabling client
authentication.

BUG=492371

Change-Id: I78e9a4a9cca665e89899ef97b815454c6f5c7e02
Reviewed-on: https://boringssl-review.googlesource.com/4885
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2015-05-26 16:59:43 -04:00 committed by Adam Langley
parent 4b30b28def
commit 5c1ce2925d
2 changed files with 26 additions and 34 deletions

View File

@ -273,25 +273,17 @@ int dtls1_accept(SSL *s) {
case SSL3_ST_SW_CERT_REQ_A:
case SSL3_ST_SW_CERT_REQ_B:
if (/* don't request cert unless asked for it: */
!(s->verify_mode & SSL_VERIFY_PEER) ||
/* With normal PSK Certificates and
* Certificate Requests are omitted */
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
/* no cert request */
skip = 1;
s->s3->tmp.cert_request = 0;
s->state = SSL3_ST_SW_SRVR_DONE_A;
} else {
s->s3->tmp.cert_request = 1;
if (s->s3->tmp.cert_request) {
dtls1_start_timer(s);
ret = ssl3_send_certificate_request(s);
if (ret <= 0) {
goto end;
}
s->state = SSL3_ST_SW_SRVR_DONE_A;
s->init_num = 0;
} else {
skip = 1;
}
s->state = SSL3_ST_SW_SRVR_DONE_A;
s->init_num = 0;
break;
case SSL3_ST_SW_SRVR_DONE_A:

View File

@ -337,31 +337,16 @@ int ssl3_accept(SSL *s) {
case SSL3_ST_SW_CERT_REQ_A:
case SSL3_ST_SW_CERT_REQ_B:
if (/* don't request cert unless asked for it: */
!(s->verify_mode & SSL_VERIFY_PEER) ||
/* Don't request a certificate if an obc was presented */
((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
s->s3->tlsext_channel_id_valid) ||
/* With normal PSK Certificates and
* Certificate Requests are omitted */
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
/* no cert request */
skip = 1;
s->s3->tmp.cert_request = 0;
s->state = SSL3_ST_SW_SRVR_DONE_A;
if (s->s3->handshake_buffer &&
!ssl3_digest_cached_records(s, free_handshake_buffer)) {
return -1;
}
} else {
s->s3->tmp.cert_request = 1;
if (s->s3->tmp.cert_request) {
ret = ssl3_send_certificate_request(s);
if (ret <= 0) {
goto end;
}
s->state = SSL3_ST_SW_SRVR_DONE_A;
s->init_num = 0;
} else {
skip = 1;
}
s->state = SSL3_ST_SW_SRVR_DONE_A;
s->init_num = 0;
break;
case SSL3_ST_SW_SRVR_DONE_A:
@ -1069,12 +1054,27 @@ int ssl3_get_client_hello(SSL *s) {
goto f_err;
}
s->s3->tmp.new_cipher = c;
/* Determine whether to request a client certificate. */
s->s3->tmp.cert_request = !!(s->verify_mode & SSL_VERIFY_PEER);
/* Only request a certificate if Channel ID isn't negotiated. */
if ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
s->s3->tlsext_channel_id_valid) {
s->s3->tmp.cert_request = 0;
}
/* Plain PSK forbids Certificate and CertificateRequest. */
if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) {
s->s3->tmp.cert_request = 0;
}
} else {
/* Session-id reuse */
s->s3->tmp.new_cipher = s->session->cipher;
s->s3->tmp.cert_request = 0;
}
if ((!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) &&
/* In TLS 1.2, client authentication requires hashing the handshake transcript
* under a different hash. Otherwise, release the handshake buffer. */
if ((!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) &&
!ssl3_digest_cached_records(s, free_handshake_buffer)) {
goto f_err;
}