Add the CA extension to client hello
If we have CA_names configured in the client,
make use of them and send the CA extension so
the client requests a cert with a matching
issuer.
Change-Id: I1f51a058b7a386915c198485915425727f15d002
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/71611
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/ssl/extensions.cc b/ssl/extensions.cc
index 0e001a6..c9424c9 100644
--- a/ssl/extensions.cc
+++ b/ssl/extensions.cc
@@ -2560,6 +2560,45 @@
}
+// Certificate Authorities.
+//
+// https://tools.ietf.org/html/rfc8446#section-4.2.4
+
+static bool ext_certificate_authorities_add_clienthello(
+ const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
+ ssl_client_hello_type_t type) {
+ if (ssl_has_CA_names(hs->config)) {
+ CBB ca_contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_authorities) || //
+ !CBB_add_u16_length_prefixed(out, &ca_contents) || //
+ !ssl_add_CA_names(hs, &ca_contents) || //
+ !CBB_flush(out)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool ext_certificate_authorities_parse_clienthello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return true;
+ }
+
+ if (CBS_len(contents) == 0) {
+ return false;
+ }
+
+ hs->ca_names = SSL_parse_CA_list(hs->ssl, out_alert, contents);
+ if (!hs->ca_names) {
+ return false;
+ }
+
+ return true;
+}
+
+
// QUIC Transport Parameters
static bool ext_quic_transport_params_add_clienthello_impl(
@@ -3285,6 +3324,13 @@
ignore_parse_clienthello,
ext_alps_add_serverhello_old,
},
+ {
+ TLSEXT_TYPE_certificate_authorities,
+ ext_certificate_authorities_add_clienthello,
+ forbid_parse_serverhello,
+ ext_certificate_authorities_parse_clienthello,
+ dont_add_serverhello,
+ },
};
#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
diff --git a/ssl/internal.h b/ssl/internal.h
index c34e9d9..a3b1ce0 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -2254,8 +2254,8 @@
// server when using a TLS 1.2 PSK key exchange.
UniquePtr<char> peer_psk_identity_hint;
- // ca_names, on the client, contains the list of CAs received in a
- // CertificateRequest message.
+ // ca_names contains the list of CAs received via the Certificate Authorities
+ // extension in our peer's CertificateRequest or ClientHello message
UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names;
// cached_x509_ca_names contains a cache of parsed versions of the elements of