aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuwei Ge <lwge@google.com>2023-11-03 14:17:28 -0700
committerGitHub <noreply@github.com>2023-11-03 14:17:28 -0700
commiteaa72802a0df7503d3aa79f82bbf03ae9afa21e2 (patch)
tree8a5b26b4ccc2155aa8315291bfa547e9c02fedbe
parent0d4e1ef5df0751393003d1745cd4de184ab494ed (diff)
downloadgrpc-grpc-eaa72802a0df7503d3aa79f82bbf03ae9afa21e2.tar.gz
[security] Support a list of SSL ECs (#34867)
Addresses #23235
-rw-r--r--CMakeLists.txt35
-rw-r--r--build_autogenerated.yaml12
-rw-r--r--src/core/tsi/ssl_transport_security.cc16
-rw-r--r--src/core/tsi/test_creds/BUILD19
-rw-r--r--src/core/tsi/test_creds/README24
-rw-r--r--src/core/tsi/test_creds/ca_p256.key5
-rw-r--r--src/core/tsi/test_creds/ca_p256.pem13
-rw-r--r--src/core/tsi/test_creds/ca_p384.key6
-rw-r--r--src/core/tsi/test_creds/ca_p384.pem14
-rw-r--r--src/core/tsi/test_creds/ca_p521.key8
-rw-r--r--src/core/tsi/test_creds/ca_p521.pem16
-rw-r--r--src/core/tsi/test_creds/client_p256.key5
-rw-r--r--src/core/tsi/test_creds/client_p256.pem11
-rw-r--r--src/core/tsi/test_creds/client_p384.key6
-rw-r--r--src/core/tsi/test_creds/client_p384.pem13
-rw-r--r--src/core/tsi/test_creds/client_p521.key8
-rw-r--r--src/core/tsi/test_creds/client_p521.pem14
-rw-r--r--src/core/tsi/test_creds/server1_p256.key5
-rw-r--r--src/core/tsi/test_creds/server1_p256.pem15
-rw-r--r--src/core/tsi/test_creds/server1_p384.key6
-rw-r--r--src/core/tsi/test_creds/server1_p384.pem17
-rw-r--r--src/core/tsi/test_creds/server1_p521.key8
-rw-r--r--src/core/tsi/test_creds/server1_p521.pem18
-rw-r--r--test/core/end2end/BUILD38
-rw-r--r--test/core/end2end/h2_ssl_certs_curves_test.cc378
-rw-r--r--tools/run_tests/generated/tests.json24
26 files changed, 722 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac4f4aa385..fb91c5ee66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1073,6 +1073,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx grpclb_end2end_test)
endif()
add_dependencies(buildtests_cxx h2_ssl_cert_test)
+ add_dependencies(buildtests_cxx h2_ssl_certs_curves_test)
add_dependencies(buildtests_cxx h2_ssl_session_reuse_test)
add_dependencies(buildtests_cxx h2_tls_peer_property_external_verifier_test)
add_dependencies(buildtests_cxx handle_tests)
@@ -13707,6 +13708,40 @@ target_link_libraries(h2_ssl_cert_test
endif()
if(gRPC_BUILD_TESTS)
+add_executable(h2_ssl_certs_curves_test
+ test/core/end2end/cq_verifier.cc
+ test/core/end2end/h2_ssl_certs_curves_test.cc
+)
+target_compile_features(h2_ssl_certs_curves_test PUBLIC cxx_std_14)
+target_include_directories(h2_ssl_certs_curves_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_certs_curves_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gtest
+ 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 d81f2a7791..7749a8349b 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -9596,6 +9596,18 @@ targets:
deps:
- gtest
- grpc_test_util
+- name: h2_ssl_certs_curves_test
+ gtest: true
+ build: test
+ language: c++
+ headers:
+ - test/core/end2end/cq_verifier.h
+ src:
+ - test/core/end2end/cq_verifier.cc
+ - test/core/end2end/h2_ssl_certs_curves_test.cc
+ deps:
+ - gtest
+ - grpc_test_util
- name: h2_ssl_session_reuse_test
gtest: true
build: test
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index 6acda5eaab..b14b3ad316 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -153,9 +153,8 @@ static int g_ssl_ex_verified_root_cert_index = -1;
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE)
static const char kSslEnginePrefix[] = "engine:";
#endif
-#if OPENSSL_VERSION_NUMBER >= 0x30000000
-static const int kSslEcCurveNames[] = {NID_X9_62_prime256v1};
-#endif
+static const int kSslEcCurveNames[] = {NID_X9_62_prime256v1, NID_secp384r1,
+ NID_secp521r1};
#if OPENSSL_VERSION_NUMBER < 0x10100000
static gpr_mu* g_openssl_mutexes = nullptr;
@@ -800,17 +799,16 @@ static tsi_result populate_ssl_context(
return TSI_INVALID_ARGUMENT;
}
{
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
- EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
- if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) {
+#if OPENSSL_VERSION_NUMBER < 0x10101000L
+ if (!SSL_CTX_set1_curves(context, kSslEcCurveNames,
+ ((sizeof(kSslEcCurveNames) / sizeof(int))))) {
gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key.");
- EC_KEY_free(ecdh);
return TSI_INTERNAL_ERROR;
}
SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
- EC_KEY_free(ecdh);
#else
- if (!SSL_CTX_set1_groups(context, kSslEcCurveNames, 1)) {
+ if (!SSL_CTX_set1_groups(context, kSslEcCurveNames,
+ ((sizeof(kSslEcCurveNames) / sizeof(int))))) {
gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key.");
return TSI_INTERNAL_ERROR;
}
diff --git a/src/core/tsi/test_creds/BUILD b/src/core/tsi/test_creds/BUILD
index f6072bc552..d887a71fbd 100644
--- a/src/core/tsi/test_creds/BUILD
+++ b/src/core/tsi/test_creds/BUILD
@@ -16,14 +16,29 @@ licenses(["notice"])
exports_files([
"ca.pem",
- "server1.key",
- "server1.pem",
+ "ca_p256.pem",
+ "ca_p384.pem",
+ "ca_p521.pem",
"server0.key",
"server0.pem",
+ "server1.key",
+ "server1.pem",
+ "server1_p256.key",
+ "server1_p256.pem",
+ "server1_p384.key",
+ "server1_p384.pem",
+ "server1_p521.key",
+ "server1_p521.pem",
"client.key",
"client.pem",
"client-with-spiffe.key",
"client-with-spiffe.pem",
+ "client_p256.key",
+ "client_p256.pem",
+ "client_p384.key",
+ "client_p384.pem",
+ "client_p521.key",
+ "client_p521.pem",
"badserver.key",
"badserver.pem",
"badclient.key",
diff --git a/src/core/tsi/test_creds/README b/src/core/tsi/test_creds/README
index f3a6679e39..61d74bc935 100644
--- a/src/core/tsi/test_creds/README
+++ b/src/core/tsi/test_creds/README
@@ -16,7 +16,7 @@ common name which is set to badserver.test.google.com.
Valid test credentials:
=======================
-The ca is self-signed:
+The ca is self-signed with RSA:
----------------------
$ openssl req -x509 -new -newkey rsa:2048 -nodes -keyout ca.key -out ca.pem \
@@ -128,7 +128,29 @@ $ openssl req -key leaf_signed_by_intermediate.key -new -out temp.csr -config le
$ openssl x509 -req -days 3650 -in temp.csr -CA intermediate_ca.pem -CAkey intermediate_ca.key -CAcreateserial -out leaf_signed_by_intermediate.pem -extfile leaf_signed_by_intermediate.cnf -extensions 'v3_req'
$ cat leaf_signed_by_intermediate.pem intermediate_ca.pem > leaf_and_intermediate_chain.pem
+ECDSA CAs and certs/keys
+------------------------
+For P256, P384 or P521 curves, assign $NAME to prime256v1, secp384r1 or secp521r1 and $SUFFIX to p256, p384 or p521 respectively.
+
+$ openssl ecparam -name $NAME -genkey -noout -out temp.pem
+$ openssl pkcs8 -topk8 -in temp.pem -out ca_${SUFFIX}.key -nocrypt
+$ rm temp.pem
+$ openssl req -x509 -days 3650 -new -key ca_${SUFFIX}.key -nodes -out ca_${SUFFIX}.pem -config ca-openssl.cnf -extensions 'v3_req'
+
+Sign client certs (with common name testclient) with the above CAs:
+$ openssl ecparam -name $NAME -genkey -noout -out temp.pem
+$ openssl pkcs8 -topk8 -in temp.pem -out client_${SUFFIX}.key -nocrypt
+$ rm temp.pem
+$ openssl req -key client_${SUFFIX}.key -new -out temp.csr
+$ openssl x509 -req -days 3650 -in temp.csr -CA ca_${SUFFIX}.pem -CAkey ca_${SUFFIX}.key -CAcreateserial -out client_${SUFFIX}.pem
+
+Sign server certs (with common name *.test.google.com) with the above CAs:
+$ openssl ecparam -name $NAME -genkey -noout -out temp.pem
+$ openssl pkcs8 -topk8 -in temp.pem -out server1_${SUFFIX}.key -nocrypt
+$ rm temp.pem
+$ openssl req -key server1_${SUFFIX}.key -new -out temp.csr -config server1-openssl.cnf
+$ openssl x509 -req -days 3650 -in temp.csr -CA ca_${SUFFIX}.pem -CAkey ca_${SUFFIX}.key -CAcreateserial -out server1_${SUFFIX}.pem -extensions 'v3_req' -extfile server1-openssl.cnf
Clean up:
---------
diff --git a/src/core/tsi/test_creds/ca_p256.key b/src/core/tsi/test_creds/ca_p256.key
new file mode 100644
index 0000000000..ec679aaee4
--- /dev/null
+++ b/src/core/tsi/test_creds/ca_p256.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGXLU0TtzErcyGDE/
+fhbphpw2Zdhw3iZmUvnxsFG08iKhRANCAAR1Y4rj/7GFUANxiV8QcKvYC8pdbIsy
+jfe1qgcyL6gwxxbqokJllnvfTGdcH65l9M4xCSKWe+PeghI+i9NTu7R0
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/ca_p256.pem b/src/core/tsi/test_creds/ca_p256.pem
new file mode 100644
index 0000000000..6e8aa6e24a
--- /dev/null
+++ b/src/core/tsi/test_creds/ca_p256.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB7TCCAZOgAwIBAgIUPLuUtYXNndWg+lpfpgmhpyGhLF8wCgYIKoZIzj0EAwIw
+VjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIzMTEw
+MzE2MjcwMFoXDTMzMTAzMTE2MjcwMFowVjELMAkGA1UEBhMCQVUxEzARBgNVBAgM
+ClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEP
+MA0GA1UEAwwGdGVzdGNhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdWOK4/+x
+hVADcYlfEHCr2AvKXWyLMo33taoHMi+oMMcW6qJCZZZ730xnXB+uZfTOMQkilnvj
+3oISPovTU7u0dKM/MD0wDAYDVR0TBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwHQYD
+VR0OBBYEFAwTlsQiF6A70bdNxAl4Y1x+3uVlMAoGCCqGSM49BAMCA0gAMEUCIQC+
+T4oowHyHutdr+Iu1X0wNoJ3Hodxp+ihtgou95+Tw8gIgFW4DMB0mATGgi8zIXREx
+1yXBQ+a2DYE6lSUUPChRUB8=
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/ca_p384.key b/src/core/tsi/test_creds/ca_p384.key
new file mode 100644
index 0000000000..c24f0c055a
--- /dev/null
+++ b/src/core/tsi/test_creds/ca_p384.key
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBS37qQ3DuoihlwFOS2
+zwN9egL1Vi+tpeBXElrm7/+7A/SA2OENZfXeQnb1HpqcgaOhZANiAATy4kYuJN4L
+27TvhbEY/dXD3MuZm71pQQOjqES1aghcPTFR04WDWIIVmzTuUUjz4XAcrOf1CsTu
+T1NEXZnHX/8A99OYsw/nlPRhvjAhPZ/kK5KH7NWK9+N7suf7QFP0PJU=
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/ca_p384.pem b/src/core/tsi/test_creds/ca_p384.pem
new file mode 100644
index 0000000000..7d09f86a28
--- /dev/null
+++ b/src/core/tsi/test_creds/ca_p384.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICKjCCAbCgAwIBAgIUQ5u1l9zc4BdSXdyGzv369f5bg48wCgYIKoZIzj0EAwIw
+VjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIzMTEw
+MzE2MzA0NloXDTMzMTAzMTE2MzA0NlowVjELMAkGA1UEBhMCQVUxEzARBgNVBAgM
+ClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEP
+MA0GA1UEAwwGdGVzdGNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8uJGLiTeC9u0
+74WxGP3Vw9zLmZu9aUEDo6hEtWoIXD0xUdOFg1iCFZs07lFI8+FwHKzn9QrE7k9T
+RF2Zx1//APfTmLMP55T0Yb4wIT2f5CuSh+zVivfje7Ln+0BT9DyVoz8wPTAMBgNV
+HRMEBTADAQH/MA4GA1UdDwEB/wQEAwICBDAdBgNVHQ4EFgQUb8tXaPFgds0JZZoJ
+YnC/wJlCbVQwCgYIKoZIzj0EAwIDaAAwZQIxAK8RnPWkSWG0cEf++GtjkHJ3y25Y
+KLkZ6uWM4nZIGzZPqEJbS5gIM6suXFjRtwRQqAIwEfAG1ncStBs3s3qx5XFcd/Uj
+7V61x1CjF+QVvMD0KW7xJB7Yl+EbY+2Y2xnG4PJL
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/ca_p521.key b/src/core/tsi/test_creds/ca_p521.key
new file mode 100644
index 0000000000..dee9ffb029
--- /dev/null
+++ b/src/core/tsi/test_creds/ca_p521.key
@@ -0,0 +1,8 @@
+-----BEGIN PRIVATE KEY-----
+MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBQ6PfMspzmbOlPa0e
+0UfWb7NGIIKvgCMmGVPSP7wR+jX//eJRO+YeLmcLq6zWOOs+5Z6oPKHR5Et5nht4
+FQR62gShgYkDgYYABAFRBRdfON+9qLmJlo0tHLIw9d4fIMYsM8hnbUPBAuIalAMo
+nDKdN8753qgnp74d9WQsYHtsw9dn6/0qwbh4qpYSrAE1nvVbh3zUkAqLQNkqV8cu
+fPCDLMvFDl3iy4hoOmK+fNYi+NS3gn6P1o6UIjN0xQEc7l/zUaw0D5VZqRoiniuR
+gA==
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/ca_p521.pem b/src/core/tsi/test_creds/ca_p521.pem
new file mode 100644
index 0000000000..2d617cd973
--- /dev/null
+++ b/src/core/tsi/test_creds/ca_p521.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICdDCCAdagAwIBAgIUKWOObDjdan+iuXsgkA6IDD68O2swCgYIKoZIzj0EAwIw
+VjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIzMTEw
+MzE2MzIzM1oXDTMzMTAzMTE2MzIzM1owVjELMAkGA1UEBhMCQVUxEzARBgNVBAgM
+ClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEP
+MA0GA1UEAwwGdGVzdGNhMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBUQUXXzjf
+vai5iZaNLRyyMPXeHyDGLDPIZ21DwQLiGpQDKJwynTfO+d6oJ6e+HfVkLGB7bMPX
+Z+v9KsG4eKqWEqwBNZ71W4d81JAKi0DZKlfHLnzwgyzLxQ5d4suIaDpivnzWIvjU
+t4J+j9aOlCIzdMUBHO5f81GsNA+VWakaIp4rkYCjPzA9MAwGA1UdEwQFMAMBAf8w
+DgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBTJAGZMKQJ9qfu5hutnaruWRZl2zjAK
+BggqhkjOPQQDAgOBiwAwgYcCQUUZ/IXyiGqtbxzdIHqv/1D+rp8aarvdaOTNB2JJ
+tB+1K70n+scJpIG8z7JE69HfX4wDk7abumj57IOxWu0y8kttAkIAlBTyuSm0qiH4
+Z6NzTDgSdw6Z6ufZQC+2HGRAOt/55XgmYURg+u9BNcYGUAHNpWjffgpe5ZMM3mwu
+IxgpucHjxPg=
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/client_p256.key b/src/core/tsi/test_creds/client_p256.key
new file mode 100644
index 0000000000..e0ac6e6806
--- /dev/null
+++ b/src/core/tsi/test_creds/client_p256.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgf/INCWORFRUTDFz8
+Cs/JBWd2bikxsZ3WQaiB+PhllGShRANCAATQBhts3haEdFCU9wRsuranYR2M/Hpu
+ot70CuQx3/8NHVoPDhBJmY8cT3Kl+cZbZZQVgI4K73654dCQX6iEKAr+
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/client_p256.pem b/src/core/tsi/test_creds/client_p256.pem
new file mode 100644
index 0000000000..29d7ace360
--- /dev/null
+++ b/src/core/tsi/test_creds/client_p256.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBqjCCAVECFHEbCKugIii9thZRk2zjetwgBvMMMAoGCCqGSM49BAMCMFYxCzAJ
+BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
+dCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMzExMDMxNjQ2
+MzlaFw0zMzEwMzExNjQ2MzlaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
+LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNV
+BAMMCnRlc3RjbGllbnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATQBhts3haE
+dFCU9wRsuranYR2M/Hpuot70CuQx3/8NHVoPDhBJmY8cT3Kl+cZbZZQVgI4K7365
+4dCQX6iEKAr+MAoGCCqGSM49BAMCA0cAMEQCIDH4032bdUo8bI7edpUZsY5P4uvc
+BPLhFiExTVcylcqgAiAkMLgS02akwRmLwlQeJYqVhl5bdN8IbpItL4NXlbkbZA==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/client_p384.key b/src/core/tsi/test_creds/client_p384.key
new file mode 100644
index 0000000000..88e4a08cab
--- /dev/null
+++ b/src/core/tsi/test_creds/client_p384.key
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCG55oUtgGStvL54n21
+gMY9Yt1Qs8SsJzZ8/51JmG1EIFWV0krJzJ/1z5I1wwLwRDqhZANiAAR3G/m1B73j
+aZ2BstNrjFKpdarWPTLLwuiozfzRYk/0NBPiVVByk6hYGqLsFS1+xuqLEdMviayK
+45LI41NfJ1RSoZ2/ozN/+oALK+L0mVkHKQwWDLidKFVETPL9eS3UX/U=
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/client_p384.pem b/src/core/tsi/test_creds/client_p384.pem
new file mode 100644
index 0000000000..698a34d786
--- /dev/null
+++ b/src/core/tsi/test_creds/client_p384.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB6TCCAW4CFBUrSSmZFLN1F4DSQ8GmD6ujE59NMAoGCCqGSM49BAMCMFYxCzAJ
+BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
+dCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMzExMDMxNjQ3
+MzNaFw0zMzEwMzExNjQ3MzNaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
+LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNV
+BAMMCnRlc3RjbGllbnQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR3G/m1B73jaZ2B
+stNrjFKpdarWPTLLwuiozfzRYk/0NBPiVVByk6hYGqLsFS1+xuqLEdMviayK45LI
+41NfJ1RSoZ2/ozN/+oALK+L0mVkHKQwWDLidKFVETPL9eS3UX/UwCgYIKoZIzj0E
+AwIDaQAwZgIxALyQfGdP8QNaNTG4thV6AMOMbeEZ7ic3ab3VUbrzGJL2Bm2QknAa
+aIKH7H/nfRo3zQIxAMuAfX6ua9m7O4juEsJUiWmCikU56OdCvJ7LdLz23Jr6BTFs
+lCwoCJMXp4SvFBjkXA==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/client_p521.key b/src/core/tsi/test_creds/client_p521.key
new file mode 100644
index 0000000000..d09991160e
--- /dev/null
+++ b/src/core/tsi/test_creds/client_p521.key
@@ -0,0 +1,8 @@
+-----BEGIN PRIVATE KEY-----
+MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBppzS8G/BisQYQ9ZS
+mUtjProQYh7ZbnXws+pAbSWuTBTDdy4M4DVabZT1Xz5F8vxHl19/6sPCSER2Q9ZO
+JcAENzihgYkDgYYABAF7CDUfwYbWRJA0pg6+6EF9a4fFu6KKbpaOZyLnf6M+A4cz
+MGZgld2gv7sKkbYqKLgWqubBl3xO29MNJtr44CpXeAA3fkUxGJH71nI7ciWWtD5j
+Y1uw9Jg4iECAHkUMkah0uMbS3Z3/MKZDnFcCn/lBViEKLyjqhGxGK3Imq14JREUE
+nA==
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/client_p521.pem b/src/core/tsi/test_creds/client_p521.pem
new file mode 100644
index 0000000000..dbbf988574
--- /dev/null
+++ b/src/core/tsi/test_creds/client_p521.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICMzCCAZQCFHpikmBZFARTiGZY/fLaXFwemK7JMAoGCCqGSM49BAMCMFYxCzAJ
+BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
+dCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMzExMDMxNjQ4
+MThaFw0zMzEwMzExNjQ4MThaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
+LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNV
+BAMMCnRlc3RjbGllbnQwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAF7CDUfwYbW
+RJA0pg6+6EF9a4fFu6KKbpaOZyLnf6M+A4czMGZgld2gv7sKkbYqKLgWqubBl3xO
+29MNJtr44CpXeAA3fkUxGJH71nI7ciWWtD5jY1uw9Jg4iECAHkUMkah0uMbS3Z3/
+MKZDnFcCn/lBViEKLyjqhGxGK3Imq14JREUEnDAKBggqhkjOPQQDAgOBjAAwgYgC
+QgHKR5TNOimX3u5CfyLmlLQfq2XV1p87T83VzcMZAZVLt0uY8HGVKgfz7lTZmeDU
+QLFdRfyL7xWU73E/IakzwxQ8XwJCAcMiStKsd/fEqakBOMaSrKf4HW0BKfBMknzX
+nB4jk/HrpAFH73U8RaEHkWNvZAZMRuuf42JEvD/WYo1NzkDKQCYv
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/server1_p256.key b/src/core/tsi/test_creds/server1_p256.key
new file mode 100644
index 0000000000..0afb640eec
--- /dev/null
+++ b/src/core/tsi/test_creds/server1_p256.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgX3lS1sVqqA4Y1okH
+gpPua6BQDQEx16BKNU7RJ2JnmHWhRANCAATSCk+bxOa91Fea4DIaxOk6Kr/BZ64I
+bdGfQhL5vpOr1lttUYY3Vrw0nRRpqwTfb/4ckWBCe0A2gJ3ZimcziDuW
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/server1_p256.pem b/src/core/tsi/test_creds/server1_p256.pem
new file mode 100644
index 0000000000..1204ae110b
--- /dev/null
+++ b/src/core/tsi/test_creds/server1_p256.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICajCCAhCgAwIBAgIUMzJGWNICD8UXAJZPxK6rLYLg+ywwCgYIKoZIzj0EAwIw
+VjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIzMTEw
+MzE3MDgzOVoXDTMzMTAzMTE3MDgzOVowZTELMAkGA1UEBhMCVVMxETAPBgNVBAgM
+CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxlLCBD
+by4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZI
+zj0DAQcDQgAE0gpPm8TmvdRXmuAyGsTpOiq/wWeuCG3Rn0IS+b6Tq9ZbbVGGN1a8
+NJ0UaasE32/+HJFgQntANoCd2YpnM4g7lqOBrDCBqTAJBgNVHRMEAjAAMAsGA1Ud
+DwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZyghh3YXRlcnpvb2ku
+dGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcEwKgBAzAdBgNVHQ4E
+FgQUvxQhs4Mo4oQb5yFMnRXgYLZCxA0wHwYDVR0jBBgwFoAUDBOWxCIXoDvRt03E
+CXhjXH7e5WUwCgYIKoZIzj0EAwIDSAAwRQIhAIXof8XuM6DC1zaTedKenL1kEGF1
+NK3LHr8ga0MqkfeIAiAqwDgN/+vL4M1MhBbHJjhJqwSsTu/xOCzEsz4rnPn3yA==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/server1_p384.key b/src/core/tsi/test_creds/server1_p384.key
new file mode 100644
index 0000000000..e6df544351
--- /dev/null
+++ b/src/core/tsi/test_creds/server1_p384.key
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBOMbTE7k26YMVxFgw7
+NEiptA2loi/OqNbhMtKZIWk3mQsANaSismkI+5XqvRFDOrihZANiAAQT/Fc/XtkC
+tQopM6yOWEbr5N+AQ3deMnhmJtJmqUjRaqJtFfC6DoPalKmSIJuiTt9kcTnX7GVu
+IP9PzNbcZhvBxaWvgd7Nqw82DMjXbhQZ0mYDxv4YE8baRubwi1kPzOw=
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/server1_p384.pem b/src/core/tsi/test_creds/server1_p384.pem
new file mode 100644
index 0000000000..16b5f8cdd3
--- /dev/null
+++ b/src/core/tsi/test_creds/server1_p384.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICpzCCAi2gAwIBAgIUKP1CPRwkJL8veW/rZ44TeLxhgf4wCgYIKoZIzj0EAwIw
+VjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIzMTEw
+MzE3MDU1OFoXDTMzMTAzMTE3MDU1OFowZTELMAkGA1UEBhMCVVMxETAPBgNVBAgM
+CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxlLCBD
+by4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMHYwEAYHKoZIzj0CAQYFK4EE
+ACIDYgAEE/xXP17ZArUKKTOsjlhG6+TfgEN3XjJ4ZibSZqlI0WqibRXwug6D2pSp
+kiCbok7fZHE51+xlbiD/T8zW3GYbwcWlr4HezasPNgzI124UGdJmA8b+GBPG2kbm
+8ItZD8zso4GsMIGpMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgME8GA1UdEQRIMEaC
+ECoudGVzdC5nb29nbGUuZnKCGHdhdGVyem9vaS50ZXN0Lmdvb2dsZS5iZYISKi50
+ZXN0LnlvdXR1YmUuY29thwTAqAEDMB0GA1UdDgQWBBQWdCAVIpUBjNOCSObz1XRq
+G24wbTAfBgNVHSMEGDAWgBRvy1do8WB2zQllmglicL/AmUJtVDAKBggqhkjOPQQD
+AgNoADBlAjEAigxqqVOPY/4yw9NJbLuy7rgCSIgmflU31Jv9pcShnB+lu09Ojntk
+lBVp6rvp3RK4AjBIYmXoXApZuhej7srweQ/GF332d4eQ/XdEvRRvueFJ+Z/5YRQK
+9QpyJqwWVXCmx8E=
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/server1_p521.key b/src/core/tsi/test_creds/server1_p521.key
new file mode 100644
index 0000000000..faa57fd900
--- /dev/null
+++ b/src/core/tsi/test_creds/server1_p521.key
@@ -0,0 +1,8 @@
+-----BEGIN PRIVATE KEY-----
+MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAopSSX3MXcdFj5ZMn
+6LAw90RqFabicgAumGtTdBpUg2Uh8WckBVaPZ2tCeByxBFzOdxbfRdoAh5HqDvYu
+gs//TqmhgYkDgYYABAHlLIip/GcdqheCKfcP+urfriemnLCtrwGHvmMCEwUmsi79
+/uw8KKC+53kkF/obVxWLW11zPTGvZTNB7o869vsNDwCUcivWDvIQTUcxLqfT+QLq
+3NK3AyKJsG2U8e5p3vziqwLQEHRkTukV/sZbd2l2PxC4LoRQnYpGJ1tAxqLvAfYF
+fw==
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/server1_p521.pem b/src/core/tsi/test_creds/server1_p521.pem
new file mode 100644
index 0000000000..7fc0a43432
--- /dev/null
+++ b/src/core/tsi/test_creds/server1_p521.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC8jCCAlOgAwIBAgIUG9PQMKWv/CO/fNFce9JE9YuIa74wCgYIKoZIzj0EAwIw
+VjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIzMTEw
+MzE3MDgwMloXDTMzMTAzMTE3MDgwMlowZTELMAkGA1UEBhMCVVMxETAPBgNVBAgM
+CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxlLCBD
+by4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIGbMBAGByqGSM49AgEGBSuB
+BAAjA4GGAAQB5SyIqfxnHaoXgin3D/rq364nppywra8Bh75jAhMFJrIu/f7sPCig
+vud5JBf6G1cVi1tdcz0xr2UzQe6POvb7DQ8AlHIr1g7yEE1HMS6n0/kC6tzStwMi
+ibBtlPHuad784qsC0BB0ZE7pFf7GW3dpdj8QuC6EUJ2KRidbQMai7wH2BX+jgaww
+gakwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdv
+b2dsZS5mcoIYd2F0ZXJ6b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHVi
+ZS5jb22HBMCoAQMwHQYDVR0OBBYEFPYv3eqdBfB9MAawZ6NwhJQEa2WRMB8GA1Ud
+IwQYMBaAFMkAZkwpAn2p+7mG62dqu5ZFmXbOMAoGCCqGSM49BAMCA4GMADCBiAJC
+AbAAt3BoGPWnHzlh8pEY8y5j23xaPtcvJRYhpWU+jklcoKqRfC0gwHystNfuSduT
+Oyc88KHtxL1jGJ/Iar7Bok7vAkIBPJ+Eo++AWSbthCfRfi3JKk3CVx5BgDfKiFBW
+31Dr6b9NgZik1NCrjWEiGCyRXQS9J582RT8s/Lbt8VlBPMwCzS0=
+-----END CERTIFICATE-----
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index 939db44b58..0e53196d72 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -656,6 +656,44 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "h2_ssl_certs_curves_test",
+ srcs = ["h2_ssl_certs_curves_test.cc"],
+ data = [
+ "//src/core/tsi/test_creds:ca_p256.pem",
+ "//src/core/tsi/test_creds:ca_p384.pem",
+ "//src/core/tsi/test_creds:ca_p521.pem",
+ "//src/core/tsi/test_creds:client_p256.key",
+ "//src/core/tsi/test_creds:client_p256.pem",
+ "//src/core/tsi/test_creds:client_p384.key",
+ "//src/core/tsi/test_creds:client_p384.pem",
+ "//src/core/tsi/test_creds:client_p521.key",
+ "//src/core/tsi/test_creds:client_p521.pem",
+ "//src/core/tsi/test_creds:server1_p256.key",
+ "//src/core/tsi/test_creds:server1_p256.pem",
+ "//src/core/tsi/test_creds:server1_p384.key",
+ "//src/core/tsi/test_creds:server1_p384.pem",
+ "//src/core/tsi/test_creds:server1_p521.key",
+ "//src/core/tsi/test_creds:server1_p521.pem",
+ ],
+ external_deps = ["gtest"],
+ language = "C++",
+ deps = [
+ "cq_verifier",
+ "//:channel_arg_names",
+ "//:config_vars",
+ "//:exec_ctx",
+ "//:gpr",
+ "//:grpc",
+ "//:grpc_public_hdrs",
+ "//src/core:channel_args",
+ "//src/core:error",
+ "//src/core:grpc_ssl_credentials",
+ "//src/core:useful",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "h2_tls_peer_property_external_verifier_test",
srcs = ["h2_tls_peer_property_external_verifier_test.cc"],
data = [
diff --git a/test/core/end2end/h2_ssl_certs_curves_test.cc b/test/core/end2end/h2_ssl_certs_curves_test.cc
new file mode 100644
index 0000000000..b1020c3218
--- /dev/null
+++ b/test/core/end2end/h2_ssl_certs_curves_test.cc
@@ -0,0 +1,378 @@
+//
+//
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+
+#include <string.h>
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/grpc_security_constants.h>
+#include <grpc/impl/channel_arg_names.h>
+#include <grpc/impl/propagation_bits.h>
+#include <grpc/slice.h>
+#include <grpc/status.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/config/config_vars.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/host_port.h"
+#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/load_file.h"
+#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+constexpr char kCaCertPath0[] = "src/core/tsi/test_creds/ca_p256.pem";
+constexpr char kCaCertPath1[] = "src/core/tsi/test_creds/ca_p384.pem";
+constexpr char kCaCertPath2[] = "src/core/tsi/test_creds/ca_p521.pem";
+constexpr char kClientCertPath0[] = "src/core/tsi/test_creds/client_p256.pem";
+constexpr char kClientKeyPath0[] = "src/core/tsi/test_creds/client_p256.key";
+constexpr char kClientCertPath1[] = "src/core/tsi/test_creds/client_p384.pem";
+constexpr char kClientKeyPath1[] = "src/core/tsi/test_creds/client_p384.key";
+constexpr char kClientCertPath2[] = "src/core/tsi/test_creds/client_p521.pem";
+constexpr char kClientKeyPath2[] = "src/core/tsi/test_creds/client_p521.key";
+constexpr char kServerCertPath0[] = "src/core/tsi/test_creds/server1_p256.pem";
+constexpr char kServerKeyPath0[] = "src/core/tsi/test_creds/server1_p256.key";
+constexpr char kServerCertPath1[] = "src/core/tsi/test_creds/server1_p384.pem";
+constexpr char kServerKeyPath1[] = "src/core/tsi/test_creds/server1_p384.key";
+constexpr char kServerCertPath2[] = "src/core/tsi/test_creds/server1_p521.pem";
+constexpr char kServerKeyPath2[] = "src/core/tsi/test_creds/server1_p521.key";
+
+namespace grpc {
+namespace testing {
+namespace {
+
+gpr_timespec five_seconds_time() { return grpc_timeout_seconds_to_deadline(5); }
+
+grpc_server* server_create(grpc_completion_queue* cq, const char* server_addr,
+ const char* ca_cert_path,
+ const char* server_cert_path,
+ const char* server_key_path) {
+ grpc_slice ca_slice, cert_slice, key_slice;
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+ grpc_load_file(ca_cert_path, 1, &ca_slice)));
+ GPR_ASSERT(GRPC_LOG_IF_ERROR(
+ "load_file", grpc_load_file(server_cert_path, 1, &cert_slice)));
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+ grpc_load_file(server_key_path, 1, &key_slice)));
+ const char* ca_cert =
+ reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
+ const char* server_cert =
+ reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
+ const char* server_key =
+ reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
+ grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {server_key, server_cert};
+ auto* cert_config =
+ grpc_ssl_server_certificate_config_create(ca_cert, &pem_cert_key_pair, 1);
+ auto* options = grpc_ssl_server_credentials_create_options_using_config(
+ GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, cert_config);
+ grpc_server_credentials* server_creds =
+ grpc_ssl_server_credentials_create_with_options(options);
+ // This is a hack but we don't have a public API to force TLS version yet.
+ //
+ // The tests in this file are only meaningful with TLSv1.2 only there is the
+ // public key from the certificate used for key exchange and the key type's
+ // compatibility will be checked:
+ // https://datatracker.ietf.org/doc/html/rfc8422#section-5.3.
+ // In TLSv1.3 key exchange negotiation follows a different flow
+ // (https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.7) and no longer
+ // involves the key in the certificate.
+ reinterpret_cast<grpc_ssl_server_credentials*>(server_creds)
+ ->set_max_tls_version(grpc_tls_version::TLS1_2);
+ grpc_server* server = grpc_server_create(nullptr, nullptr);
+ grpc_server_register_completion_queue(server, cq, nullptr);
+ GPR_ASSERT(grpc_server_add_http2_port(server, server_addr, server_creds));
+ grpc_server_credentials_release(server_creds);
+ grpc_server_start(server);
+
+ grpc_slice_unref(cert_slice);
+ grpc_slice_unref(key_slice);
+ grpc_slice_unref(ca_slice);
+ return server;
+}
+
+grpc_channel* client_create(const char* server_addr, const char* ca_cert_path,
+ const char* client_cert_path,
+ const char* client_key_path) {
+ grpc_slice ca_slice, cert_slice, key_slice;
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+ grpc_load_file(ca_cert_path, 1, &ca_slice)));
+ GPR_ASSERT(GRPC_LOG_IF_ERROR(
+ "load_file", grpc_load_file(client_cert_path, 1, &cert_slice)));
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
+ grpc_load_file(client_key_path, 1, &key_slice)));
+ const char* ca_cert =
+ reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
+ const char* client_cert =
+ reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
+ const char* client_key =
+ reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
+ grpc_ssl_pem_key_cert_pair signed_client_key_cert_pair = {client_key,
+ client_cert};
+ grpc_channel_credentials* client_creds = grpc_ssl_credentials_create(
+ ca_cert, &signed_client_key_cert_pair, nullptr, nullptr);
+
+ grpc_arg args[] = {
+ grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
+ const_cast<char*>("waterzooi.test.google.be")),
+ };
+
+ grpc_channel_args* client_args =
+ grpc_channel_args_copy_and_add(nullptr, args, GPR_ARRAY_SIZE(args));
+
+ grpc_channel* client =
+ grpc_channel_create(server_addr, client_creds, client_args);
+ GPR_ASSERT(client != nullptr);
+ grpc_channel_credentials_release(client_creds);
+
+ {
+ grpc_core::ExecCtx exec_ctx;
+ grpc_channel_args_destroy(client_args);
+ }
+
+ grpc_slice_unref(cert_slice);
+ grpc_slice_unref(key_slice);
+ grpc_slice_unref(ca_slice);
+ return client;
+}
+
+void do_round_trip(grpc_completion_queue* cq, grpc_server* server,
+ const char* server_addr, const char* ca_cert_path,
+ const char* client_cert_path, const char* client_key_path) {
+ grpc_channel* client = client_create(server_addr, ca_cert_path,
+ client_cert_path, client_key_path);
+
+ grpc_core::CqVerifier cqv(cq);
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+
+ gpr_timespec deadline = grpc_timeout_seconds_to_deadline(60);
+ grpc_call* c = grpc_channel_create_call(
+ client, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,
+ grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr);
+ GPR_ASSERT(c);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
+ grpc_core::CqVerifier::tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ grpc_call* s;
+ error = grpc_server_request_call(server, &s, &call_details,
+ &request_metadata_recv, cq, cq,
+ grpc_core::CqVerifier::tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ cqv.Expect(grpc_core::CqVerifier::tag(101), true);
+ cqv.Verify();
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_OK;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
+ grpc_core::CqVerifier::tag(103), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ cqv.Expect(grpc_core::CqVerifier::tag(103), true);
+ cqv.Expect(grpc_core::CqVerifier::tag(1), true);
+ cqv.Verify();
+
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ grpc_channel_destroy(client);
+}
+
+void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_time(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+TEST(H2SslCertsEllipicCurvesTest, RoundTripWithP256Curve) {
+ int port = grpc_pick_unused_port_or_die();
+
+ std::string server_addr = grpc_core::JoinHostPort("localhost", port);
+
+ grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
+
+ grpc_server* server = server_create(cq, server_addr.c_str(), kCaCertPath0,
+ kServerCertPath0, kServerKeyPath0);
+
+ do_round_trip(cq, server, server_addr.c_str(), kCaCertPath0, kClientCertPath0,
+ kClientKeyPath0);
+
+ GPR_ASSERT(grpc_completion_queue_next(
+ cq, grpc_timeout_milliseconds_to_deadline(100), nullptr)
+ .type == GRPC_QUEUE_TIMEOUT);
+
+ grpc_server_shutdown_and_notify(server, cq, grpc_core::CqVerifier::tag(1000));
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+ nullptr);
+ } while (ev.type != GRPC_OP_COMPLETE ||
+ ev.tag != grpc_core::CqVerifier::tag(1000));
+ grpc_server_destroy(server);
+
+ grpc_completion_queue_shutdown(cq);
+ drain_cq(cq);
+ grpc_completion_queue_destroy(cq);
+}
+
+TEST(H2SslCertsEllipicCurvesTest, RoundTripWithP384Curve) {
+ int port = grpc_pick_unused_port_or_die();
+
+ std::string server_addr = grpc_core::JoinHostPort("localhost", port);
+
+ grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
+
+ grpc_server* server = server_create(cq, server_addr.c_str(), kCaCertPath1,
+ kServerCertPath1, kServerKeyPath1);
+
+ do_round_trip(cq, server, server_addr.c_str(), kCaCertPath1, kClientCertPath1,
+ kClientKeyPath1);
+
+ GPR_ASSERT(grpc_completion_queue_next(
+ cq, grpc_timeout_milliseconds_to_deadline(100), nullptr)
+ .type == GRPC_QUEUE_TIMEOUT);
+
+ grpc_server_shutdown_and_notify(server, cq, grpc_core::CqVerifier::tag(1000));
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+ nullptr);
+ } while (ev.type != GRPC_OP_COMPLETE ||
+ ev.tag != grpc_core::CqVerifier::tag(1000));
+ grpc_server_destroy(server);
+
+ grpc_completion_queue_shutdown(cq);
+ drain_cq(cq);
+ grpc_completion_queue_destroy(cq);
+}
+
+TEST(H2SslCertsEllipicCurvesTest, RoundTripWithP521Curve) {
+ int port = grpc_pick_unused_port_or_die();
+
+ std::string server_addr = grpc_core::JoinHostPort("localhost", port);
+
+ grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
+
+ grpc_server* server = server_create(cq, server_addr.c_str(), kCaCertPath2,
+ kServerCertPath2, kServerKeyPath2);
+
+ do_round_trip(cq, server, server_addr.c_str(), kCaCertPath2, kClientCertPath2,
+ kClientKeyPath2);
+
+ GPR_ASSERT(grpc_completion_queue_next(
+ cq, grpc_timeout_milliseconds_to_deadline(100), nullptr)
+ .type == GRPC_QUEUE_TIMEOUT);
+
+ grpc_server_shutdown_and_notify(server, cq, grpc_core::CqVerifier::tag(1000));
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+ nullptr);
+ } while (ev.type != GRPC_OP_COMPLETE ||
+ ev.tag != grpc_core::CqVerifier::tag(1000));
+ grpc_server_destroy(server);
+
+ grpc_completion_queue_shutdown(cq);
+ drain_cq(cq);
+ grpc_completion_queue_destroy(cq);
+}
+
+} // namespace
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc::testing::TestEnvironment env(&argc, argv);
+ grpc_core::ConfigVars::Overrides overrides;
+ grpc_core::ConfigVars::SetOverrides(overrides);
+
+ grpc_init();
+ ::testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ grpc_shutdown();
+
+ return ret;
+}
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b24f41f5d1..3f3b6ad263 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -4362,6 +4362,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "h2_ssl_certs_curves_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "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_session_reuse_test",
"platforms": [
"linux",