Return null from SSL_get0_peer_certificates if unauthenticated.
SSL_get0_peer_certificates is documented to return NULL if the peer was
anonymous, but it actually returns a non-NULL empty list (except in SSL
3.0 where the Certificate message and thus ssl_parse_cert_chain is
skipped).
Make the implementation match the documentation.
Change-Id: Ib3e25d2155f316cc5e9eb3ab7f74b78e08b8a86b
Reviewed-on: https://boringssl-review.googlesource.com/18226
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc
index 338975b..627f038 100644
--- a/ssl/tls13_both.cc
+++ b/ssl/tls13_both.cc
@@ -196,7 +196,9 @@
CBS cbs, context, certificate_list;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
if (!CBS_get_u8_length_prefixed(&cbs, &context) ||
- CBS_len(&context) != 0) {
+ CBS_len(&context) != 0 ||
+ !CBS_get_u24_length_prefixed(&cbs, &certificate_list) ||
+ CBS_len(&cbs) != 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return 0;
@@ -209,12 +211,6 @@
return 0;
}
- if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- return 0;
- }
-
const bool retain_sha256 =
ssl->server && ssl->retain_only_sha256_of_client_certs;
UniquePtr<EVP_PKEY> pkey;
@@ -326,10 +322,10 @@
}
}
- if (CBS_len(&cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return 0;
+ /* Store a null certificate list rather than an empty one if the peer didn't
+ * send certificates. */
+ if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) {
+ certs.reset();
}
hs->peer_pubkey = std::move(pkey);