Add an API to record use of delegated credential

Change-Id: Ie964dee5ff9f8c6d43208dd1d3947d9b427ea27d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/36424
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 4586bdb..34b354c 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -3100,6 +3100,10 @@
     SSL *ssl, CRYPTO_BUFFER *dc, EVP_PKEY *pkey,
     const SSL_PRIVATE_KEY_METHOD *key_method);
 
+// SSL_delegated_credential_used returns one if a delegated credential was used
+// and zero otherwise.
+OPENSSL_EXPORT int SSL_delegated_credential_used(const SSL *ssl);
+
 
 // QUIC integration.
 //
diff --git a/ssl/internal.h b/ssl/internal.h
index c7f6a5e..f03271e 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -2221,6 +2221,10 @@
   // session_reused indicates whether a session was resumed.
   bool session_reused : 1;
 
+  // delegated_credential_used is whether we presented a delegated credential to
+  // the peer.
+  bool delegated_credential_used : 1;
+
   bool send_connection_binding : 1;
 
   // In a client, this means that the server supported Channel ID and that a
diff --git a/ssl/s3_lib.cc b/ssl/s3_lib.cc
index 0e0770c..b6d905d 100644
--- a/ssl/s3_lib.cc
+++ b/ssl/s3_lib.cc
@@ -172,6 +172,7 @@
       has_message(false),
       initial_handshake_complete(false),
       session_reused(false),
+      delegated_credential_used(false),
       send_connection_binding(false),
       channel_id_valid(false),
       key_update_pending(false),
diff --git a/ssl/ssl_cert.cc b/ssl/ssl_cert.cc
index 54df38f..b565a35 100644
--- a/ssl/ssl_cert.cc
+++ b/ssl/ssl_cert.cc
@@ -1010,3 +1010,7 @@
 
   return cert_set_dc(ssl->config->cert.get(), dc, pkey, key_method);
 }
+
+int SSL_delegated_credential_used(const SSL *ssl) {
+  return ssl->s3->delegated_credential_used;
+}
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 89b4ba5..98da2ec 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -665,6 +665,13 @@
     return false;
   }
 
+  if (config->expect_delegated_credential_used !=
+      !!SSL_delegated_credential_used(ssl)) {
+    fprintf(stderr,
+            "Got %s delegated credential usage, but wanted opposite. \n",
+            SSL_delegated_credential_used(ssl) ? "" : "no");
+    return false;
+  }
   return true;
 }
 
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 7dd0def..ee09faf 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -15480,6 +15480,7 @@
 		},
 		flags: []string{
 			"-delegated-credential", ecdsaFlagValue,
+			"-expect-delegated-credential-used",
 		},
 	})
 
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 4a25b1a..98e0440 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -148,6 +148,8 @@
     {"-server-preference", &TestConfig::server_preference},
     {"-export-traffic-secrets", &TestConfig::export_traffic_secrets},
     {"-key-update", &TestConfig::key_update},
+    {"-expect-delegated-credential-used",
+     &TestConfig::expect_delegated_credential_used},
 };
 
 const Flag<std::string> kStringFlags[] = {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 195ffc9..fc2dded 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -173,6 +173,7 @@
   bool server_preference = false;
   bool export_traffic_secrets = false;
   bool key_update = false;
+  bool expect_delegated_credential_used = false;
   std::string delegated_credential;
   std::string expect_early_data_reason;
 
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc
index bd0bb4f..2a290f4 100644
--- a/ssl/tls13_both.cc
+++ b/ssl/tls13_both.cc
@@ -497,6 +497,7 @@
       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
       return 0;
     }
+    ssl->s3->delegated_credential_used = true;
   }
 
   for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain.get()); i++) {