@ -24,6 +24,7 @@
# include <gtest/gtest.h>
# include <openssl/bio.h>
# include <openssl/crypto.h>
# include <openssl/evp.h>
# include <openssl/ssl.h>
# include <openssl/x509.h>
@ -43,6 +44,11 @@
namespace grpc_core {
namespace testing {
using : : testing : : ContainerEq ;
using : : testing : : NotNull ;
using : : testing : : TestWithParam ;
using : : testing : : ValuesIn ;
const char * kValidCrl = " test/core/tsi/test_creds/crl_data/crls/current.crl " ;
const char * kCrlIssuer = " test/core/tsi/test_creds/crl_data/ca.pem " ;
const char * kModifiedSignature =
@ -60,10 +66,73 @@ const char* kCaWithAkid = "test/core/tsi/test_creds/crl_data/ca_with_akid.pem";
const char * kCrlWithAkid =
" test/core/tsi/test_creds/crl_data/crl_with_akid.crl " ;
using : : testing : : ContainerEq ;
using : : testing : : NotNull ;
using : : testing : : TestWithParam ;
using : : testing : : ValuesIn ;
constexpr absl : : string_view kLeafCertPem =
" -----BEGIN CERTIFICATE----- \n "
" MIICZzCCAdCgAwIBAgIIN18/ctj3wpAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE \n "
" ChMOR29vZ2xlIFRFU1RJTkcxDzANBgNVBAMTBnRlc3RDQTAeFw0xNTAxMDEwMDAw \n "
" MDBaFw0yNTAxMDEwMDAwMDBaMC8xFzAVBgNVBAoTDkdvb2dsZSBURVNUSU5HMRQw \n "
" EgYDVQQDDAt0ZXN0X2NlcnRfMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA \n "
" 20oOyI+fNCCeHJ3DNjGooPPP43Q6emhVvuWD8ppta582Rgxq/4j1bl9cPHdoCdyy \n "
" HsWFVUZzscj2qhClmlBAMEA595OU2NX2d81nSih5dwZWLMRQkEIzyxUR7Vee3eyo \n "
" nQD4HSamaevMSv79WTUBCozEGITqWnjYA152KUbA/IsCAwEAAaOBkDCBjTAOBgNV \n "
" HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1Ud \n "
" EwEB/wQCMAAwGQYDVR0OBBIEECnFWP/UkDrV+SoXra58k64wGwYDVR0jBBQwEoAQ \n "
" p7JSbajiTZaIRUDSV1C81jAWBgNVHREEDzANggt0ZXN0X2NlcnRfMTANBgkqhkiG \n "
" 9w0BAQsFAAOBgQCpJJssfN62T3G5z+5SBB+9KCzXnGxcTHtaTJkb04KLe+19EwhV \n "
" yRY4lZadKHjcNS6GCBogd069wNFUVYOU9VI7uUiEPdcTO+VRV5MYW0wjSi1zlkBZ \n "
" e8OAfYVeGUMfvThFpJ41f8vZ6GHgg95Lwv+Zh89SL8g1J3RWll9YVG8HWw== \n "
" -----END CERTIFICATE----- " ;
constexpr absl : : string_view kPrivateKeyPem =
" -----BEGIN RSA PRIVATE KEY----- \n "
" MIICXQIBAAKBgQDbSg7Ij580IJ4cncM2Maig88/jdDp6aFW+5YPymm1rnzZGDGr/ \n "
" iPVuX1w8d2gJ3LIexYVVRnOxyPaqEKWaUEAwQDn3k5TY1fZ3zWdKKHl3BlYsxFCQ \n "
" QjPLFRHtV57d7KidAPgdJqZp68xK/v1ZNQEKjMQYhOpaeNgDXnYpRsD8iwIDAQAB \n "
" AoGAbq4kZApJeo/z/dGK0/GggQxOIylo0puSm7VQMcTL8YP8asKdxrgj2D99WG+U \n "
" LVYc+PcM4wuaHWOnTBL24roaitCNhrpIsJfWDkexzHXMj622SYlUcCuwsfjYOEyw \n "
" ntoNAnh0o4S+beYAfzT5VHCh4is9G9u+mwKYiGpJXROrYUECQQD4eq4nuGq3mfYJ \n "
" B0+md30paDVVCyBsuZTAtnu3MbRjMXy5LLE+vhno5nocvVSTOv3QC7Wk6yAa8/bG \n "
" iPT/MWixAkEA4e0zqPGo8tSimVv/1ei8Chyb+YqdSx+Oj5eZpa6X/KB/C1uS1tm6 \n "
" DTgHW2GUhV4ypqdGH+t8quprJUtFuzqH+wJBAMRiicSg789eouMt4RjrdYPFdela \n "
" Gu1zm4rYb10xrqV7Vl0wYoH5U5cMmdSfGvomdLX6mzzWDJDg4ti1JBWRonECQQCD \n "
" Umtq0j1QGQUCe5Vz8zoJ7qNDI61WU1t8X7Rxt9CkiW4PXgU2WYxpzp2IImpAM4bh \n "
" k+2Q9EKc3nG1VdGMiPMtAkARkQF+pL8SBrUoh8G8glCam0brh3tW/cdW8L4UGTNF \n "
" 2ZKC/LFH6DQBjYs3UXjvMGJxz4k9LysyY6o2Nf1JG6/L \n "
" -----END RSA PRIVATE KEY----- " ;
constexpr absl : : string_view kEcPrivateKeyPem =
" -----BEGIN PRIVATE KEY----- \n "
" MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgOM7iHjJw/N6n8HtM \n "
" bVVVRhEYXoHFF+MSaTYQxOWM1p+hRANCAASMeWC+pIJAm/1fn0Wz3yyWGQzVPm9v \n "
" LCQo5JvK0a2t+Aa6d3AtLRwo6vh1VbJ8zFZxxIwyJNis3n1jRMWal7Vo \n "
" -----END PRIVATE KEY----- " ;
constexpr absl : : string_view kRsaPrivateKeyPem =
" -----BEGIN PRIVATE KEY----- \n "
" MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqyrzsrS8mWQwz \n "
" VFudLgte2kJX/pZ3KqJQBtMrkLxpgyJJU8mVBB+quDwnfH6PnQk+sF9omTlGAAxR \n "
" JzSEe8BS1Wnxld6rr6o/381VVW/2b+2kSifCtx/gVwCQQLnf4dbjfGW7ZClu1URG \n "
" ks2lK9T9BIh9SMSnYLEKEC8sWW1LibzJxHapFjIP88GrqgpPNGdEK7ABMsqHASuU \n "
" MvQ+0w7sdX2Pdu+Gm8ChxawvLiQVSh9ehtJiPl/jWbcZ6K3caTUxMf9tn8ky0DMK \n "
" xmHHmmxu19ehegzi7KSzjHmJ4QAtrtDaB/+ud0ZJ5l+pwfk7DL1TRjFYOyPVpExb \n "
" nLcQQxzfAgMBAAECggEATc+kFygnzQ7Q0iniu0+Y+pPxmelxX8VawZ76YmTEkkWe \n "
" P04fDvcb/kmFjm/XsVJYPelY7mywfUXUVrzH3nwK+TIl3FztX8beh89M203bfqkr \n "
" 2ae3Sazopuq8ZPw4MtnPb0DjkGZnwgkD3CtR6ah4lvWTwZB/l8ojnnQVKd1sP/c4 \n "
" LQSlVm2aiD6+D/NxbyJ4AOMWgUFrWBKqnV30mTZ5Lwv8fjznopgWMfsUl+Nx/HzV \n "
" J1ZRtLE+Z9euFJOUeMSEG1+YFxXAA3XuRdY/4PpzvK8Rlxb2rtJvt+dHojQCz66U \n "
" 6PcspPt6MOcUFnpamJ513oKDwmdR8puRg7/bk2VKYQKBgQDVHz/NQaS8czTCkx8p \n "
" jXmZcGv1DH+T3SWeNI871BXQbSSKuqrOXDfzfrIFK7uXAWtIAOKLVaZOcSEDk+Rj \n "
" kbifkqRZuMy+iLdBLj/Gw3xVfkOb3m4g7OqWc7RBlfTCTCCUTVPiQkKZLGJ/eIJx \n "
" sGvdyJP6f12MODqUobgQC2UniQKBgQDNJ0vDHdqRQYI4zz1gAYDaCruRjtwWvRSL \n "
" tcBFlcVnMXjfZpxOKnGU1xEO4wDhEXra9yLwi/6IwGFtk0Zi2C9rYptniiURReuX \n "
" TkNNf1JmyZhYuSXD9Pg1Ssa/t3ZtauFzK1rHL1R1UB/pnD8xxuB4aAl+kZKi1Ie+ \n "
" E6IXHuyfJwKBgQDOac+viq503tfww/Fgm2d0lw/YbNx7Z6rxiVJYzda64ZqMyrJ3 \n "
" 35VJPiJJI8wyOuue90xzSuch/ivNfUWssgwwcSTAyV10BJIIjTSz283mN75fjpT3 \n "
" Sr8CLNoe05AVRwoe2K4v66D5HaXgc+VTG129lnDMIuOF1UfXgLH2yDKWkQKBgQC4 \n "
" ajqQiqWPLXQB3UkupCtP1ZYGooT1a8KsVBUieB+bQ72EFJktKrovMaUD3MtNhokJ \n "
" jF68HRwRkd4CwgDjmbIGtf08ddIcVN4ShSe64lkQTOfF2ak5HVyBi1ZdwG2Urh87 \n "
" iB1yL/mb+wq01N95v2zIz7y5KeLGvIXJN5zda88IwQKBgFLk68ZMEDMVCLpdvywb \n "
" bRC3rOl2CTHfXFD6RY0SIv4De+w7iQkYOn+4NIyG+hMfGfj5ooOO5gbsDyGagZqV \n "
" OLc6cW5HnwN+PERByn+hSoyGq8IOk8Vn5DeV7PoqIlbbdfUmTUx69EtzvViZoa+O \n "
" O2XDljPcjgc+pobqzebPIR6R \n "
" -----END PRIVATE KEY----- " ;
constexpr std : : size_t kMaxPlaintextBytesPerTlsRecord = 16384 ;
constexpr std : : size_t kTlsRecordOverhead = 100 ;
@ -117,38 +186,6 @@ class FlowTest : public TestWithParam<FrameProtectorUtilTestData> {
return absl : : InvalidArgumentError (
" Client and server SSL object must not be null. " ) ;
}
std : : string cert_pem =
" -----BEGIN CERTIFICATE----- \n "
" MIICZzCCAdCgAwIBAgIIN18/ctj3wpAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE \n "
" ChMOR29vZ2xlIFRFU1RJTkcxDzANBgNVBAMTBnRlc3RDQTAeFw0xNTAxMDEwMDAw \n "
" MDBaFw0yNTAxMDEwMDAwMDBaMC8xFzAVBgNVBAoTDkdvb2dsZSBURVNUSU5HMRQw \n "
" EgYDVQQDDAt0ZXN0X2NlcnRfMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA \n "
" 20oOyI+fNCCeHJ3DNjGooPPP43Q6emhVvuWD8ppta582Rgxq/4j1bl9cPHdoCdyy \n "
" HsWFVUZzscj2qhClmlBAMEA595OU2NX2d81nSih5dwZWLMRQkEIzyxUR7Vee3eyo \n "
" nQD4HSamaevMSv79WTUBCozEGITqWnjYA152KUbA/IsCAwEAAaOBkDCBjTAOBgNV \n "
" HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1Ud \n "
" EwEB/wQCMAAwGQYDVR0OBBIEECnFWP/UkDrV+SoXra58k64wGwYDVR0jBBQwEoAQ \n "
" p7JSbajiTZaIRUDSV1C81jAWBgNVHREEDzANggt0ZXN0X2NlcnRfMTANBgkqhkiG \n "
" 9w0BAQsFAAOBgQCpJJssfN62T3G5z+5SBB+9KCzXnGxcTHtaTJkb04KLe+19EwhV \n "
" yRY4lZadKHjcNS6GCBogd069wNFUVYOU9VI7uUiEPdcTO+VRV5MYW0wjSi1zlkBZ \n "
" e8OAfYVeGUMfvThFpJ41f8vZ6GHgg95Lwv+Zh89SL8g1J3RWll9YVG8HWw== \n "
" -----END CERTIFICATE----- \n " ;
std : : string key_pem =
" -----BEGIN RSA PRIVATE KEY----- \n "
" MIICXQIBAAKBgQDbSg7Ij580IJ4cncM2Maig88/jdDp6aFW+5YPymm1rnzZGDGr/ \n "
" iPVuX1w8d2gJ3LIexYVVRnOxyPaqEKWaUEAwQDn3k5TY1fZ3zWdKKHl3BlYsxFCQ \n "
" QjPLFRHtV57d7KidAPgdJqZp68xK/v1ZNQEKjMQYhOpaeNgDXnYpRsD8iwIDAQAB \n "
" AoGAbq4kZApJeo/z/dGK0/GggQxOIylo0puSm7VQMcTL8YP8asKdxrgj2D99WG+U \n "
" LVYc+PcM4wuaHWOnTBL24roaitCNhrpIsJfWDkexzHXMj622SYlUcCuwsfjYOEyw \n "
" ntoNAnh0o4S+beYAfzT5VHCh4is9G9u+mwKYiGpJXROrYUECQQD4eq4nuGq3mfYJ \n "
" B0+md30paDVVCyBsuZTAtnu3MbRjMXy5LLE+vhno5nocvVSTOv3QC7Wk6yAa8/bG \n "
" iPT/MWixAkEA4e0zqPGo8tSimVv/1ei8Chyb+YqdSx+Oj5eZpa6X/KB/C1uS1tm6 \n "
" DTgHW2GUhV4ypqdGH+t8quprJUtFuzqH+wJBAMRiicSg789eouMt4RjrdYPFdela \n "
" Gu1zm4rYb10xrqV7Vl0wYoH5U5cMmdSfGvomdLX6mzzWDJDg4ti1JBWRonECQQCD \n "
" Umtq0j1QGQUCe5Vz8zoJ7qNDI61WU1t8X7Rxt9CkiW4PXgU2WYxpzp2IImpAM4bh \n "
" k+2Q9EKc3nG1VdGMiPMtAkARkQF+pL8SBrUoh8G8glCam0brh3tW/cdW8L4UGTNF \n "
" 2ZKC/LFH6DQBjYs3UXjvMGJxz4k9LysyY6o2Nf1JG6/L \n "
" -----END RSA PRIVATE KEY----- \n " ;
// Create the context objects.
SSL_CTX * client_ctx = nullptr ;
@ -161,18 +198,22 @@ class FlowTest : public TestWithParam<FrameProtectorUtilTestData> {
server_ctx = SSL_CTX_new ( TLSv1_2_method ( ) ) ;
# endif
BIO * client_cert_bio ( BIO_new_mem_buf ( cert_pem . c_str ( ) , cert_pem . size ( ) ) ) ;
BIO * client_cert_bio (
BIO_new_mem_buf ( kLeafCertPem . data ( ) , kLeafCertPem . size ( ) ) ) ;
X509 * client_cert = PEM_read_bio_X509 ( client_cert_bio , /*x=*/ nullptr ,
/*cb=*/ nullptr , /*u=*/ nullptr ) ;
BIO * client_key_bio ( BIO_new_mem_buf ( key_pem . c_str ( ) , key_pem . size ( ) ) ) ;
BIO * client_key_bio (
BIO_new_mem_buf ( kPrivateKeyPem . data ( ) , kPrivateKeyPem . size ( ) ) ) ;
EVP_PKEY * client_key =
PEM_read_bio_PrivateKey ( client_key_bio , /*x=*/ nullptr ,
/*cb=*/ nullptr , /*u=*/ nullptr ) ;
BIO * server_cert_bio ( BIO_new_mem_buf ( cert_pem . c_str ( ) , cert_pem . size ( ) ) ) ;
BIO * server_cert_bio (
BIO_new_mem_buf ( kLeafCertPem . data ( ) , kLeafCertPem . size ( ) ) ) ;
X509 * server_cert = PEM_read_bio_X509 ( server_cert_bio , /*x=*/ nullptr ,
/*cb=*/ nullptr , /*u=*/ nullptr ) ;
BIO * server_key_bio ( BIO_new_mem_buf ( key_pem . c_str ( ) , key_pem . size ( ) ) ) ;
BIO * server_key_bio (
BIO_new_mem_buf ( kPrivateKeyPem . data ( ) , kPrivateKeyPem . size ( ) ) ) ;
EVP_PKEY * server_key =
PEM_read_bio_PrivateKey ( server_key_bio , /*x=*/ nullptr ,
/*cb=*/ nullptr , /*u=*/ nullptr ) ;
@ -673,6 +714,128 @@ TEST_F(CrlUtils, CrlAkidNullptr) {
auto akid = AkidFromCrl ( nullptr ) ;
EXPECT_EQ ( akid . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
}
TEST ( ParsePemCertificateChainTest , EmptyPem ) {
EXPECT_EQ ( ParsePemCertificateChain ( /*cert_chain_pem=*/ " " ) . status ( ) ,
absl : : InvalidArgumentError ( " Cert chain PEM is empty. " ) ) ;
}
TEST ( ParsePemCertificateChainTest , InvalidPem ) {
EXPECT_EQ ( ParsePemCertificateChain ( " invalid-pem " ) . status ( ) ,
absl : : NotFoundError ( " No certificates found. " ) ) ;
}
TEST ( ParsePemCertificateChainTest , PartialPem ) {
std : : string pem ( kLeafCertPem ) ;
EXPECT_EQ ( ParsePemCertificateChain ( pem . substr ( 0 , pem . length ( ) / 2 ) ) . status ( ) ,
absl : : FailedPreconditionError ( " Invalid PEM. " ) ) ;
}
TEST ( ParsePemCertificateChainTest , SingleCertSuccess ) {
absl : : StatusOr < std : : vector < X509 * > > certs =
ParsePemCertificateChain ( kLeafCertPem ) ;
EXPECT_EQ ( certs . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_EQ ( certs - > size ( ) , 1 ) ;
EXPECT_NE ( certs - > at ( 0 ) , nullptr ) ;
X509_free ( certs - > at ( 0 ) ) ;
}
TEST ( ParsePemCertificateChainTest , MultipleCertFailure ) {
EXPECT_EQ ( ParsePemCertificateChain ( absl : : StrCat ( kLeafCertPem , kLeafCertPem ) )
. status ( ) ,
absl : : FailedPreconditionError ( " Invalid PEM. " ) ) ;
}
TEST ( ParsePemCertificateChainTest , MultipleCertSuccess ) {
absl : : StatusOr < std : : vector < X509 * > > certs =
ParsePemCertificateChain ( absl : : StrCat ( kLeafCertPem , " \n " , kLeafCertPem ) ) ;
EXPECT_EQ ( certs . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_EQ ( certs - > size ( ) , 2 ) ;
EXPECT_NE ( certs - > at ( 0 ) , nullptr ) ;
EXPECT_NE ( certs - > at ( 1 ) , nullptr ) ;
X509_free ( certs - > at ( 0 ) ) ;
X509_free ( certs - > at ( 1 ) ) ;
}
TEST ( ParsePemCertificateChainTest , MultipleCertWithExtraMiddleLinesSuccess ) {
absl : : StatusOr < std : : vector < X509 * > > certs = ParsePemCertificateChain (
absl : : StrCat ( kLeafCertPem , " \n Garbage \n " , kLeafCertPem ) ) ;
EXPECT_EQ ( certs . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_EQ ( certs - > size ( ) , 2 ) ;
EXPECT_NE ( certs - > at ( 0 ) , nullptr ) ;
EXPECT_NE ( certs - > at ( 1 ) , nullptr ) ;
X509_free ( certs - > at ( 0 ) ) ;
X509_free ( certs - > at ( 1 ) ) ;
}
TEST ( ParsePemCertificateChainTest , MultipleCertWitManyMiddleLinesSuccess ) {
absl : : StatusOr < std : : vector < X509 * > > certs = ParsePemCertificateChain (
absl : : StrCat ( kLeafCertPem , " \n \n \n \n \n \n \n " , kLeafCertPem ) ) ;
EXPECT_EQ ( certs . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_EQ ( certs - > size ( ) , 2 ) ;
EXPECT_NE ( certs - > at ( 0 ) , nullptr ) ;
EXPECT_NE ( certs - > at ( 1 ) , nullptr ) ;
X509_free ( certs - > at ( 0 ) ) ;
X509_free ( certs - > at ( 1 ) ) ;
}
TEST ( ParsePemCertificateChainTest , ValidCertWithInvalidSuffix ) {
EXPECT_EQ ( ParsePemCertificateChain ( absl : : StrCat ( kLeafCertPem , " invalid-pem " ) )
. status ( ) ,
absl : : FailedPreconditionError ( " Invalid PEM. " ) ) ;
}
TEST ( ParsePemCertificateChainTest , ValidCertWithInvalidPrefix ) {
EXPECT_EQ ( ParsePemCertificateChain ( absl : : StrCat ( " invalid-pem " , kLeafCertPem ) )
. status ( ) ,
absl : : NotFoundError ( " No certificates found. " ) ) ;
}
TEST ( ParsePemCertificateChainTest , ValidCertWithInvalidLeadingLine ) {
absl : : StatusOr < std : : vector < X509 * > > certs =
ParsePemCertificateChain ( absl : : StrCat ( " invalid-pem \n " , kLeafCertPem ) ) ;
EXPECT_EQ ( certs . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_EQ ( certs - > size ( ) , 1 ) ;
EXPECT_NE ( certs - > at ( 0 ) , nullptr ) ;
X509_free ( certs - > at ( 0 ) ) ;
}
TEST ( ParsePemPrivateKeyTest , EmptyPem ) {
EXPECT_EQ ( ParsePemPrivateKey ( /*private_key_pem=*/ " " ) . status ( ) ,
absl : : NotFoundError ( " No private key found. " ) ) ;
}
TEST ( ParsePemPrivateKeyTest , InvalidPem ) {
EXPECT_EQ ( ParsePemPrivateKey ( " invalid-pem " ) . status ( ) ,
absl : : NotFoundError ( " No private key found. " ) ) ;
}
TEST ( ParsePemPrivateKeyTest , PartialPem ) {
std : : string pem ( kPrivateKeyPem ) ;
EXPECT_EQ ( ParsePemPrivateKey ( pem . substr ( 0 , pem . length ( ) / 2 ) ) . status ( ) ,
absl : : NotFoundError ( " No private key found. " ) ) ;
}
TEST ( ParsePemPrivateKeyTest , RsaSuccess1 ) {
absl : : StatusOr < EVP_PKEY * > pkey = ParsePemPrivateKey ( kPrivateKeyPem ) ;
EXPECT_EQ ( pkey . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_NE ( * pkey , nullptr ) ;
EVP_PKEY_free ( * pkey ) ;
}
TEST ( ParsePemPrivateKeyTest , RsaSuccess2 ) {
absl : : StatusOr < EVP_PKEY * > pkey = ParsePemPrivateKey ( kRsaPrivateKeyPem ) ;
EXPECT_EQ ( pkey . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_NE ( * pkey , nullptr ) ;
EVP_PKEY_free ( * pkey ) ;
}
TEST ( ParsePemPrivateKeyTest , EcSuccess ) {
absl : : StatusOr < EVP_PKEY * > pkey = ParsePemPrivateKey ( kEcPrivateKeyPem ) ;
EXPECT_EQ ( pkey . status ( ) , absl : : OkStatus ( ) ) ;
EXPECT_NE ( * pkey , nullptr ) ;
EVP_PKEY_free ( * pkey ) ;
}
} // namespace testing
} // namespace grpc_core