From b3fb266937af1be90b2aa7cfe25333b4d6f7bb9a Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 24 Feb 2023 12:36:17 -0800
Subject: [PATCH] h2_ssl_cert_test: re-add to build files and fix so that it
 builds (#32444)

Looks like this was accidentally dropped from our build files in
https://github.com/grpc/grpc/pull/21929, which means that this test
hasn't actually been built or run in almost 3 years. Unsurprisingly
after all that time, I had to make some changes to the test to get it to
actually build.
---
 CMakeLists.txt                        | 44 +++++++++++++++
 build_autogenerated.yaml              | 19 +++++++
 test/core/end2end/BUILD               | 26 +++++++++
 test/core/end2end/h2_ssl_cert_test.cc | 78 +++++++++++++++------------
 tools/run_tests/generated/tests.json  | 24 +++++++++
 5 files changed, 157 insertions(+), 34 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 522a97172ec..feb37d1a7f1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -995,6 +995,7 @@ if(gRPC_BUILD_TESTS)
   if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     add_dependencies(buildtests_cxx grpclb_end2end_test)
   endif()
+  add_dependencies(buildtests_cxx h2_ssl_cert_test)
   add_dependencies(buildtests_cxx h2_ssl_session_reuse_test)
   if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     add_dependencies(buildtests_cxx handshake_server_with_readahead_handshaker_test)
@@ -13071,6 +13072,49 @@ endif()
 endif()
 if(gRPC_BUILD_TESTS)
 
+add_executable(h2_ssl_cert_test
+  test/core/end2end/cq_verifier.cc
+  test/core/end2end/data/client_certs.cc
+  test/core/end2end/data/server1_cert.cc
+  test/core/end2end/data/server1_key.cc
+  test/core/end2end/data/test_root_cert.cc
+  test/core/end2end/fixtures/local_util.cc
+  test/core/end2end/h2_ssl_cert_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+target_compile_features(h2_ssl_cert_test PUBLIC cxx_std_14)
+target_include_directories(h2_ssl_cert_test
+  PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+    ${_gRPC_RE2_INCLUDE_DIR}
+    ${_gRPC_SSL_INCLUDE_DIR}
+    ${_gRPC_UPB_GENERATED_DIR}
+    ${_gRPC_UPB_GRPC_GENERATED_DIR}
+    ${_gRPC_UPB_INCLUDE_DIR}
+    ${_gRPC_XXHASH_INCLUDE_DIR}
+    ${_gRPC_ZLIB_INCLUDE_DIR}
+    third_party/googletest/googletest/include
+    third_party/googletest/googletest
+    third_party/googletest/googlemock/include
+    third_party/googletest/googlemock
+    ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(h2_ssl_cert_test
+  ${_gRPC_BASELIB_LIBRARIES}
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ZLIB_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
 add_executable(h2_ssl_session_reuse_test
   test/core/end2end/cq_verifier.cc
   test/core/end2end/h2_ssl_session_reuse_test.cc
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index 513e151b4fc..838d3e2af14 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -8435,6 +8435,25 @@ targets:
   - linux
   - posix
   - mac
+- name: h2_ssl_cert_test
+  gtest: true
+  build: test
+  language: c++
+  headers:
+  - test/core/end2end/cq_verifier.h
+  - test/core/end2end/data/ssl_test_data.h
+  - test/core/end2end/end2end_tests.h
+  - test/core/end2end/fixtures/local_util.h
+  src:
+  - test/core/end2end/cq_verifier.cc
+  - test/core/end2end/data/client_certs.cc
+  - test/core/end2end/data/server1_cert.cc
+  - test/core/end2end/data/server1_key.cc
+  - test/core/end2end/data/test_root_cert.cc
+  - test/core/end2end/fixtures/local_util.cc
+  - test/core/end2end/h2_ssl_cert_test.cc
+  deps:
+  - grpc_test_util
 - name: h2_ssl_session_reuse_test
   gtest: true
   build: test
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index a1f0cb26910..e1326557902 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -257,6 +257,32 @@ grpc_cc_test(
 
 grpc_end2end_tests()
 
+grpc_cc_test(
+    name = "h2_ssl_cert_test",
+    srcs = [
+        "end2end_tests.h",
+        "h2_ssl_cert_test.cc",
+    ],
+    external_deps = [
+        "gtest",
+        "libcrypto",
+    ],
+    language = "C++",
+    deps = [
+        "cq_verifier",
+        "local_util",
+        "ssl_test_data",
+        "//:exec_ctx",
+        "//:gpr",
+        "//:grpc",
+        "//:grpc_public_hdrs",
+        "//:grpc_security_base",
+        "//:tsi_ssl_credentials",
+        "//src/core:channel_args",
+        "//test/core/util:grpc_test_util",
+    ],
+)
+
 grpc_cc_test(
     name = "h2_ssl_session_reuse_test",
     srcs = ["h2_ssl_session_reuse_test.cc"],
diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc
index dc0fadaea90..2d4f231297e 100644
--- a/test/core/end2end/h2_ssl_cert_test.cc
+++ b/test/core/end2end/h2_ssl_cert_test.cc
@@ -16,22 +16,31 @@
 //
 //
 
+#include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 
-#include <gtest/gtest.h>
+#include <string>
+
 #include <openssl/crypto.h>
 
+#include "gtest/gtest.h"
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/grpc_security_constants.h>
+#include <grpc/impl/propagation_bits.h>
+#include <grpc/slice.h>
+#include <grpc/status.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpcpp/support/string_ref.h>
+#include <grpc/support/time.h>
 
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/tmpfile.h"
-#include "src/core/lib/gprpp/crash.h"
+#include "src/core/lib/gprpp/global_config_generic.h"
 #include "src/core/lib/gprpp/host_port.h"
-#include "src/core/lib/security/credentials/credentials.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/security/security_connector/ssl_utils_config.h"
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/data/ssl_test_data.h"
@@ -49,7 +58,8 @@ struct fullstack_secure_fixture_data {
 };
 
 static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
-    grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
+    const grpc_channel_args* /*client_args*/,
+    const grpc_channel_args* /*server_args*/) {
   grpc_end2end_test_fixture f;
   int port = grpc_pick_unused_port_or_die();
   fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
@@ -72,7 +82,7 @@ static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
 }
 
 static void chttp2_init_client_secure_fullstack(
-    grpc_end2end_test_fixture* f, grpc_channel_args* client_args,
+    grpc_end2end_test_fixture* f, const grpc_channel_args* client_args,
     grpc_channel_credentials* creds) {
   fullstack_secure_fixture_data* ffd =
       static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
@@ -82,7 +92,7 @@ static void chttp2_init_client_secure_fullstack(
 }
 
 static void chttp2_init_server_secure_fullstack(
-    grpc_end2end_test_fixture* f, grpc_channel_args* server_args,
+    grpc_end2end_test_fixture* f, const grpc_channel_args* server_args,
     grpc_server_credentials* server_creds) {
   fullstack_secure_fixture_data* ffd =
       static_cast<fullstack_secure_fixture_data*>(f->fixture_data);
@@ -103,7 +113,7 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) {
   delete ffd;
 }
 
-static int fail_server_auth_check(grpc_channel_args* server_args) {
+static int fail_server_auth_check(const grpc_channel_args* server_args) {
   size_t i;
   if (server_args == nullptr) return 0;
   for (i = 0; i < server_args->num_args; i++) {
@@ -118,27 +128,27 @@ static int fail_server_auth_check(grpc_channel_args* server_args) {
 #define SERVER_INIT_NAME(REQUEST_TYPE) \
   chttp2_init_server_simple_ssl_secure_fullstack_##REQUEST_TYPE
 
-#define SERVER_INIT(REQUEST_TYPE)                                           \
-  static void SERVER_INIT_NAME(REQUEST_TYPE)(                               \
-      grpc_end2end_test_fixture * f, grpc_channel_args * server_args) {     \
-    grpc_ssl_pem_key_cert_pair pem_cert_key_pair;                           \
-    if (!test_server1_key_id.empty()) {                                     \
-      pem_cert_key_pair.private_key = test_server1_key_id.c_str();          \
-      pem_cert_key_pair.cert_chain = test_server1_cert;                     \
-    } else {                                                                \
-      pem_cert_key_pair.private_key = test_server1_key;                     \
-      pem_cert_key_pair.cert_chain = test_server1_cert;                     \
-    }                                                                       \
-    grpc_server_credentials* ssl_creds =                                    \
-        grpc_ssl_server_credentials_create_ex(                              \
-            test_root_cert, &pem_cert_key_pair, 1, REQUEST_TYPE, NULL);     \
-    if (fail_server_auth_check(server_args)) {                              \
-      grpc_auth_metadata_processor processor = {process_auth_failure, NULL, \
-                                                NULL};                      \
-      grpc_server_credentials_set_auth_metadata_processor(ssl_creds,        \
-                                                          processor);       \
-    }                                                                       \
-    chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);         \
+#define SERVER_INIT(REQUEST_TYPE)                                            \
+  static void SERVER_INIT_NAME(REQUEST_TYPE)(                                \
+      grpc_end2end_test_fixture * f, const grpc_channel_args* server_args) { \
+    grpc_ssl_pem_key_cert_pair pem_cert_key_pair;                            \
+    if (!test_server1_key_id.empty()) {                                      \
+      pem_cert_key_pair.private_key = test_server1_key_id.c_str();           \
+      pem_cert_key_pair.cert_chain = test_server1_cert;                      \
+    } else {                                                                 \
+      pem_cert_key_pair.private_key = test_server1_key;                      \
+      pem_cert_key_pair.cert_chain = test_server1_cert;                      \
+    }                                                                        \
+    grpc_server_credentials* ssl_creds =                                     \
+        grpc_ssl_server_credentials_create_ex(                               \
+            test_root_cert, &pem_cert_key_pair, 1, REQUEST_TYPE, NULL);      \
+    if (fail_server_auth_check(server_args)) {                               \
+      grpc_auth_metadata_processor processor = {process_auth_failure, NULL,  \
+                                                NULL};                       \
+      grpc_server_credentials_set_auth_metadata_processor(ssl_creds,         \
+                                                          processor);        \
+    }                                                                        \
+    chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);          \
   }
 
 SERVER_INIT(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE)
@@ -153,8 +163,8 @@ SERVER_INIT(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY)
 typedef enum { NONE, SELF_SIGNED, SIGNED, BAD_CERT_PAIR } certtype;
 
 #define CLIENT_INIT(cert_type)                                               \
-  static void CLIENT_INIT_NAME(cert_type)(grpc_end2end_test_fixture * f,     \
-                                          grpc_channel_args * client_args) { \
+  static void CLIENT_INIT_NAME(cert_type)(                                   \
+      grpc_end2end_test_fixture * f, const grpc_channel_args* client_args) { \
     grpc_channel_credentials* ssl_creds = NULL;                              \
     grpc_ssl_pem_key_cert_pair self_signed_client_key_cert_pair = {          \
         test_self_signed_client_key, test_self_signed_client_cert};          \
@@ -261,7 +271,7 @@ static grpc_end2end_test_config_wrapper configs[] = {
              BAD_CERT_PAIR, FAIL),
 };
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static gpr_timespec n_seconds_time(int n) {
   return grpc_timeout_seconds_to_deadline(n);
@@ -325,7 +335,7 @@ static void simple_request_body(grpc_end2end_test_fixture f,
                                 nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
-  CQ_EXPECT_COMPLETION(cqv, tag(1), expected_result == SUCCESS);
+  cqv.Expect(tag(1), expected_result == SUCCESS);
   cqv.Verify();
 
   grpc_call_unref(c);
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b28e728c9e6..6de701327e4 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3743,6 +3743,30 @@
     ],
     "uses_polling": true
   },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
+    "name": "h2_ssl_cert_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": true
+  },
   {
     "args": [],
     "benchmark": false,