Check CA names during the handshake.
Rather than store CA names and only find out that they're unparsable
when we're asked for a |STACK_OF(X509_NAME)|, check that we can parse
them all during the handshake. This avoids changing the semantics with
the previous change that kept CA names as |CRYPTO_BUFFER|s.
Change-Id: I0fc7a4e6ab01685347e7a5be0d0579f45b8a4818
Reviewed-on: https://boringssl-review.googlesource.com/13969
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_x509.c b/ssl/ssl_x509.c
index 8a132ff..81d2642 100644
--- a/ssl/ssl_x509.c
+++ b/ssl/ssl_x509.c
@@ -331,6 +331,23 @@
cert->x509_chain = NULL;
}
+static int ssl_crypto_x509_check_client_CA_list(
+ STACK_OF(CRYPTO_BUFFER) *names) {
+ for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(names); i++) {
+ const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(names, i);
+ const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
+ X509_NAME *name = d2i_X509_NAME(NULL, &inp, CRYPTO_BUFFER_len(buffer));
+ const int ok = name != NULL && inp == CRYPTO_BUFFER_data(buffer) +
+ CRYPTO_BUFFER_len(buffer);
+ X509_NAME_free(name);
+ if (!ok) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static void ssl_crypto_x509_clear(CERT *cert) {
ssl_crypto_x509_flush_cached_leaf(cert);
ssl_crypto_x509_flush_cached_chain(cert);
@@ -427,6 +444,7 @@
}
const SSL_X509_METHOD ssl_crypto_x509_method = {
+ ssl_crypto_x509_check_client_CA_list,
ssl_crypto_x509_clear,
ssl_crypto_x509_flush_cached_chain,
ssl_crypto_x509_flush_cached_leaf,