// // Copyright 2020 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 #include #include #include #include #include #include #include #include "test/core/util/test_config.h" #include "test/cpp/util/tls_test_utils.h" #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem" #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem" #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key" #define CRL_DIR_PATH "test/core/tsi/test_creds/crl_data/crls" namespace { constexpr const char* kRootCertName = "root_cert_name"; constexpr const char* kRootCertContents = "root_cert_contents"; constexpr const char* kIdentityCertName = "identity_cert_name"; constexpr const char* kIdentityCertPrivateKey = "identity_private_key"; constexpr const char* kIdentityCertContents = "identity_cert_contents"; using ::grpc::experimental::CreateStaticCrlProvider; using ::grpc::experimental::ExternalCertificateVerifier; using ::grpc::experimental::FileWatcherCertificateProvider; using ::grpc::experimental::NoOpCertificateVerifier; using ::grpc::experimental::StaticDataCertificateProvider; using ::grpc::experimental::TlsServerCredentials; using ::grpc::experimental::TlsServerCredentialsOptions; } // namespace namespace grpc { namespace testing { namespace { TEST( CredentialsTest, TlsServerCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity) { experimental::IdentityKeyCertPair key_cert_pair; key_cert_pair.private_key = kIdentityCertPrivateKey; key_cert_pair.certificate_chain = kIdentityCertContents; std::vector identity_key_cert_pairs; identity_key_cert_pairs.emplace_back(key_cert_pair); auto certificate_provider = std::make_shared( kRootCertContents, identity_key_cert_pairs); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_root_certs(); options.set_root_cert_name(kRootCertName); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } // ServerCredentials should always have identity credential presented. // Otherwise gRPC stack will fail. TEST(CredentialsTest, TlsServerCredentialsWithStaticDataCertificateProviderLoadingIdentityOnly) { experimental::IdentityKeyCertPair key_cert_pair; key_cert_pair.private_key = kIdentityCertPrivateKey; key_cert_pair.certificate_chain = kIdentityCertContents; std::vector identity_key_cert_pairs; // Adding two key_cert_pair(s) should still work. identity_key_cert_pairs.emplace_back(key_cert_pair); identity_key_cert_pairs.emplace_back(key_cert_pair); auto certificate_provider = std::make_shared(identity_key_cert_pairs); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } TEST( CredentialsTest, TlsServerCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity) { auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_root_certs(); options.set_root_cert_name(kRootCertName); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithCrlChecking) { auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_root_certs(); options.set_root_cert_name(kRootCertName); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); options.set_crl_directory(CRL_DIR_PATH); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } // ServerCredentials should always have identity credential presented. // Otherwise gRPC stack will fail. TEST( CredentialsTest, TlsServerCredentialsWithFileWatcherCertificateProviderLoadingIdentityOnly) { auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithSyncExternalVerifier) { auto verifier = ExternalCertificateVerifier::Create(true); auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_root_certs(); options.set_root_cert_name(kRootCertName); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); options.set_certificate_verifier(verifier); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithAsyncExternalVerifier) { auto verifier = ExternalCertificateVerifier::Create(true); auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.watch_root_certs(); options.set_root_cert_name(kRootCertName); options.watch_identity_key_cert_pairs(); options.set_identity_cert_name(kIdentityCertName); options.set_cert_request_type( GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); options.set_certificate_verifier(verifier); auto server_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(server_credentials.get() != nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithCrlProvider) { auto provider = experimental::CreateStaticCrlProvider({}); ASSERT_TRUE(provider.ok()); auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.set_crl_provider(*provider); auto channel_credentials = grpc::experimental::TlsServerCredentials(options); GPR_ASSERT(channel_credentials.get() != nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithCrlProviderAndDirectory) { auto provider = experimental::CreateStaticCrlProvider({}); ASSERT_TRUE(provider.ok()); auto certificate_provider = std::make_shared( SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1); grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); options.set_crl_directory(CRL_DIR_PATH); options.set_crl_provider(*provider); auto server_credentials = grpc::experimental::TlsServerCredentials(options); // TODO(gtcooke94) - behavior might change to make this return nullptr in // the future GPR_ASSERT(server_credentials != nullptr); } TEST(CredentialsTest, TlsCredentialsOptionsDoesNotLeak) { auto provider = std::make_shared("root-pem"); TlsServerCredentialsOptions options(provider); (void)options; } TEST(CredentialsTest, MultipleOptionsOneCertificateProviderDoesNotLeak) { auto provider = std::make_shared("root-pem"); TlsServerCredentialsOptions options_1(provider); (void)options_1; TlsServerCredentialsOptions options_2(provider); (void)options_2; } TEST(CredentialsTest, MultipleOptionsOneCertificateVerifierDoesNotLeak) { auto provider = std::make_shared("root-pem"); auto verifier = std::make_shared(); TlsServerCredentialsOptions options_1(provider); options_1.set_certificate_verifier(verifier); TlsServerCredentialsOptions options_2(provider); options_2.set_certificate_verifier(verifier); } TEST(CredentialsTest, MultipleOptionsOneCrlProviderDoesNotLeak) { auto provider = std::make_shared("root-pem"); auto crl_provider = CreateStaticCrlProvider(/*crls=*/{}); EXPECT_TRUE(crl_provider.ok()); TlsServerCredentialsOptions options_1(provider); options_1.set_crl_provider(*crl_provider); TlsServerCredentialsOptions options_2(provider); options_2.set_crl_provider(*crl_provider); } TEST(CredentialsTest, TlsServerCredentialsDoesNotLeak) { auto provider = std::make_shared("root-pem"); TlsServerCredentialsOptions options(provider); auto server_creds = TlsServerCredentials(options); EXPECT_NE(server_creds, nullptr); } TEST(CredentialsTest, MultipleServerCredentialsOneOptionsDoesNotLeak) { auto provider = std::make_shared("root-pem"); TlsServerCredentialsOptions options(provider); auto server_creds_1 = TlsServerCredentials(options); EXPECT_NE(server_creds_1, nullptr); auto server_creds_2 = TlsServerCredentials(options); EXPECT_NE(server_creds_2, nullptr); } TEST(CredentialsTest, MultipleServerCredentialsOneCertificateVerifierDoesNotLeak) { auto provider = std::make_shared("root-pem"); TlsServerCredentialsOptions options(provider); auto verifier = std::make_shared(); options.set_certificate_verifier(verifier); auto server_creds_1 = TlsServerCredentials(options); EXPECT_NE(server_creds_1, nullptr); auto server_creds_2 = TlsServerCredentials(options); EXPECT_NE(server_creds_2, nullptr); } TEST(CredentialsTest, MultipleServerCredentialsOneCrlProviderDoesNotLeak) { auto provider = std::make_shared("root-pem"); TlsServerCredentialsOptions options(provider); auto crl_provider = CreateStaticCrlProvider(/*crls=*/{}); EXPECT_TRUE(crl_provider.ok()); options.set_crl_provider(*crl_provider); auto server_creds_1 = TlsServerCredentials(options); EXPECT_NE(server_creds_1, nullptr); auto server_creds_2 = TlsServerCredentials(options); EXPECT_NE(server_creds_2, nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithGoodMinMaxTlsVersions) { grpc::experimental::TlsServerCredentialsOptions options( /*certificate_provider=*/nullptr); options.set_min_tls_version(grpc_tls_version::TLS1_2); options.set_max_tls_version(grpc_tls_version::TLS1_3); auto server_credentials = grpc::experimental::TlsServerCredentials(options); EXPECT_NE(server_credentials, nullptr); } TEST(CredentialsTest, TlsServerCredentialsWithBadMinMaxTlsVersions) { grpc::experimental::TlsServerCredentialsOptions options( /*certificate_provider=*/nullptr); options.set_min_tls_version(grpc_tls_version::TLS1_3); options.set_max_tls_version(grpc_tls_version::TLS1_2); auto server_credentials = grpc::experimental::TlsServerCredentials(options); EXPECT_EQ(server_credentials, nullptr); } } // namespace } // namespace testing } // namespace grpc int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; }