• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <grpc/grpc.h>
18 #include <grpc/grpc_crl_provider.h>
19 #include <grpc/grpc_security.h>
20 #include <grpcpp/security/server_credentials.h>
21 #include <grpcpp/security/tls_credentials_options.h>
22 #include <grpcpp/security/tls_crl_provider.h>
23 #include <gtest/gtest.h>
24 
25 #include <memory>
26 
27 #include "absl/log/check.h"
28 #include "test/core/test_util/test_config.h"
29 #include "test/core/test_util/tls_utils.h"
30 #include "test/cpp/util/tls_test_utils.h"
31 
32 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
33 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
34 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
35 #define CRL_DIR_PATH "test/core/tsi/test_creds/crl_data/crls"
36 #define MALFORMED_CERT_PATH "src/core/tsi/test_creds/malformed-cert.pem"
37 
38 namespace {
39 
40 constexpr const char* kRootCertName = "root_cert_name";
41 constexpr const char* kRootCertContents = "root_cert_contents";
42 constexpr const char* kIdentityCertName = "identity_cert_name";
43 constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
44 constexpr const char* kIdentityCertContents = "identity_cert_contents";
45 
46 using ::grpc::experimental::CreateStaticCrlProvider;
47 using ::grpc::experimental::ExternalCertificateVerifier;
48 using ::grpc::experimental::FileWatcherCertificateProvider;
49 using ::grpc::experimental::NoOpCertificateVerifier;
50 using ::grpc::experimental::StaticDataCertificateProvider;
51 using ::grpc::experimental::TlsServerCredentials;
52 using ::grpc::experimental::TlsServerCredentialsOptions;
53 using ::grpc_core::testing::GetFileContents;
54 
55 }  // namespace
56 
57 namespace grpc {
58 namespace testing {
59 namespace {
60 
TEST(CredentialsTest,TlsServerCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity)61 TEST(
62     CredentialsTest,
63     TlsServerCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity) {
64   experimental::IdentityKeyCertPair key_cert_pair;
65   key_cert_pair.private_key = kIdentityCertPrivateKey;
66   key_cert_pair.certificate_chain = kIdentityCertContents;
67   std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
68   identity_key_cert_pairs.emplace_back(key_cert_pair);
69   auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
70       kRootCertContents, identity_key_cert_pairs);
71   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
72   options.watch_root_certs();
73   options.set_root_cert_name(kRootCertName);
74   options.watch_identity_key_cert_pairs();
75   options.set_identity_cert_name(kIdentityCertName);
76   options.set_cert_request_type(
77       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
78   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
79   CHECK_NE(server_credentials.get(), nullptr);
80 }
81 
82 // ServerCredentials should always have identity credential presented.
83 // Otherwise gRPC stack will fail.
TEST(CredentialsTest,TlsServerCredentialsWithStaticDataCertificateProviderLoadingIdentityOnly)84 TEST(CredentialsTest,
85      TlsServerCredentialsWithStaticDataCertificateProviderLoadingIdentityOnly) {
86   experimental::IdentityKeyCertPair key_cert_pair;
87   key_cert_pair.private_key = kIdentityCertPrivateKey;
88   key_cert_pair.certificate_chain = kIdentityCertContents;
89   std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
90   // Adding two key_cert_pair(s) should still work.
91   identity_key_cert_pairs.emplace_back(key_cert_pair);
92   identity_key_cert_pairs.emplace_back(key_cert_pair);
93   auto certificate_provider =
94       std::make_shared<StaticDataCertificateProvider>(identity_key_cert_pairs);
95   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
96   options.watch_identity_key_cert_pairs();
97   options.set_identity_cert_name(kIdentityCertName);
98   options.set_cert_request_type(
99       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
100   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
101   CHECK_NE(server_credentials.get(), nullptr);
102 }
103 
TEST(CredentialsTest,TlsServerCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity)104 TEST(
105     CredentialsTest,
106     TlsServerCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity) {
107   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
108       SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
109   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
110   options.watch_root_certs();
111   options.set_root_cert_name(kRootCertName);
112   options.watch_identity_key_cert_pairs();
113   options.set_identity_cert_name(kIdentityCertName);
114   options.set_cert_request_type(
115       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
116   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
117   CHECK_NE(server_credentials.get(), nullptr);
118 }
119 
TEST(CredentialsTest,StaticDataCertificateProviderValidationSuccessWithAllCredentials)120 TEST(CredentialsTest,
121      StaticDataCertificateProviderValidationSuccessWithAllCredentials) {
122   std::string root_certificates = GetFileContents(CA_CERT_PATH);
123   experimental::IdentityKeyCertPair key_cert_pair;
124   key_cert_pair.private_key = GetFileContents(SERVER_KEY_PATH);
125   key_cert_pair.certificate_chain = GetFileContents(SERVER_CERT_PATH);
126   StaticDataCertificateProvider provider(root_certificates, {key_cert_pair});
127   EXPECT_EQ(provider.ValidateCredentials(), absl::OkStatus());
128 }
129 
TEST(CredentialsTest,StaticDataCertificateProviderWithMalformedRoot)130 TEST(CredentialsTest, StaticDataCertificateProviderWithMalformedRoot) {
131   std::string root_certificates = GetFileContents(MALFORMED_CERT_PATH);
132   experimental::IdentityKeyCertPair key_cert_pair;
133   key_cert_pair.private_key = GetFileContents(SERVER_KEY_PATH);
134   key_cert_pair.certificate_chain = GetFileContents(SERVER_CERT_PATH);
135   StaticDataCertificateProvider provider(root_certificates, {key_cert_pair});
136   EXPECT_EQ(provider.ValidateCredentials(),
137             absl::FailedPreconditionError("Invalid PEM."));
138 }
139 
TEST(CredentialsTest,FileWatcherCertificateProviderValidationSuccessWithAllCredentials)140 TEST(CredentialsTest,
141      FileWatcherCertificateProviderValidationSuccessWithAllCredentials) {
142   FileWatcherCertificateProvider provider(SERVER_KEY_PATH, SERVER_CERT_PATH,
143                                           CA_CERT_PATH, 1);
144   EXPECT_EQ(provider.ValidateCredentials(), absl::OkStatus());
145 }
146 
TEST(CredentialsTest,FileWatcherCertificateProviderWithMalformedRoot)147 TEST(CredentialsTest, FileWatcherCertificateProviderWithMalformedRoot) {
148   FileWatcherCertificateProvider provider(SERVER_KEY_PATH, SERVER_CERT_PATH,
149                                           MALFORMED_CERT_PATH, 1);
150   EXPECT_EQ(provider.ValidateCredentials(),
151             absl::FailedPreconditionError("Invalid PEM."));
152 }
153 
TEST(CredentialsTest,TlsServerCredentialsWithCrlChecking)154 TEST(CredentialsTest, TlsServerCredentialsWithCrlChecking) {
155   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
156       SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
157   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
158   options.watch_root_certs();
159   options.set_root_cert_name(kRootCertName);
160   options.watch_identity_key_cert_pairs();
161   options.set_identity_cert_name(kIdentityCertName);
162   options.set_cert_request_type(
163       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
164   options.set_crl_directory(CRL_DIR_PATH);
165   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
166   CHECK_NE(server_credentials.get(), nullptr);
167 }
168 
169 // ServerCredentials should always have identity credential presented.
170 // Otherwise gRPC stack will fail.
TEST(CredentialsTest,TlsServerCredentialsWithFileWatcherCertificateProviderLoadingIdentityOnly)171 TEST(
172     CredentialsTest,
173     TlsServerCredentialsWithFileWatcherCertificateProviderLoadingIdentityOnly) {
174   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
175       SERVER_KEY_PATH, SERVER_CERT_PATH, 1);
176   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
177   options.watch_identity_key_cert_pairs();
178   options.set_identity_cert_name(kIdentityCertName);
179   options.set_cert_request_type(
180       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
181   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
182   CHECK_NE(server_credentials.get(), nullptr);
183 }
184 
TEST(CredentialsTest,TlsServerCredentialsWithSyncExternalVerifier)185 TEST(CredentialsTest, TlsServerCredentialsWithSyncExternalVerifier) {
186   auto verifier =
187       ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
188   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
189       SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
190   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
191   options.watch_root_certs();
192   options.set_root_cert_name(kRootCertName);
193   options.watch_identity_key_cert_pairs();
194   options.set_identity_cert_name(kIdentityCertName);
195   options.set_cert_request_type(
196       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
197   options.set_certificate_verifier(verifier);
198   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
199   CHECK_NE(server_credentials.get(), nullptr);
200 }
201 
TEST(CredentialsTest,TlsServerCredentialsWithAsyncExternalVerifier)202 TEST(CredentialsTest, TlsServerCredentialsWithAsyncExternalVerifier) {
203   auto verifier =
204       ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true);
205   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
206       SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
207   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
208   options.watch_root_certs();
209   options.set_root_cert_name(kRootCertName);
210   options.watch_identity_key_cert_pairs();
211   options.set_identity_cert_name(kIdentityCertName);
212   options.set_cert_request_type(
213       GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
214   options.set_certificate_verifier(verifier);
215   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
216   CHECK_NE(server_credentials.get(), nullptr);
217 }
218 
TEST(CredentialsTest,TlsServerCredentialsWithCrlProvider)219 TEST(CredentialsTest, TlsServerCredentialsWithCrlProvider) {
220   auto provider = experimental::CreateStaticCrlProvider({});
221   ASSERT_TRUE(provider.ok());
222   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
223       SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
224   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
225   options.set_crl_provider(*provider);
226   auto channel_credentials = grpc::experimental::TlsServerCredentials(options);
227   CHECK_NE(channel_credentials.get(), nullptr);
228 }
229 
TEST(CredentialsTest,TlsServerCredentialsWithCrlProviderAndDirectory)230 TEST(CredentialsTest, TlsServerCredentialsWithCrlProviderAndDirectory) {
231   auto provider = experimental::CreateStaticCrlProvider({});
232   ASSERT_TRUE(provider.ok());
233   auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
234       SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
235   grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
236   options.set_crl_directory(CRL_DIR_PATH);
237   options.set_crl_provider(*provider);
238   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
239   //   TODO(gtcooke94) - behavior might change to make this return nullptr in
240   //   the future
241   CHECK_NE(server_credentials, nullptr);
242 }
243 
TEST(CredentialsTest,TlsCredentialsOptionsDoesNotLeak)244 TEST(CredentialsTest, TlsCredentialsOptionsDoesNotLeak) {
245   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
246   TlsServerCredentialsOptions options(provider);
247   (void)options;
248 }
249 
TEST(CredentialsTest,MultipleOptionsOneCertificateProviderDoesNotLeak)250 TEST(CredentialsTest, MultipleOptionsOneCertificateProviderDoesNotLeak) {
251   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
252   TlsServerCredentialsOptions options_1(provider);
253   (void)options_1;
254   TlsServerCredentialsOptions options_2(provider);
255   (void)options_2;
256 }
257 
TEST(CredentialsTest,MultipleOptionsOneCertificateVerifierDoesNotLeak)258 TEST(CredentialsTest, MultipleOptionsOneCertificateVerifierDoesNotLeak) {
259   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
260   auto verifier = std::make_shared<NoOpCertificateVerifier>();
261   TlsServerCredentialsOptions options_1(provider);
262   options_1.set_certificate_verifier(verifier);
263   TlsServerCredentialsOptions options_2(provider);
264   options_2.set_certificate_verifier(verifier);
265 }
266 
TEST(CredentialsTest,MultipleOptionsOneCrlProviderDoesNotLeak)267 TEST(CredentialsTest, MultipleOptionsOneCrlProviderDoesNotLeak) {
268   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
269   auto crl_provider = CreateStaticCrlProvider(/*crls=*/{});
270   EXPECT_TRUE(crl_provider.ok());
271   TlsServerCredentialsOptions options_1(provider);
272   options_1.set_crl_provider(*crl_provider);
273   TlsServerCredentialsOptions options_2(provider);
274   options_2.set_crl_provider(*crl_provider);
275 }
276 
TEST(CredentialsTest,TlsServerCredentialsDoesNotLeak)277 TEST(CredentialsTest, TlsServerCredentialsDoesNotLeak) {
278   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
279   TlsServerCredentialsOptions options(provider);
280   auto server_creds = TlsServerCredentials(options);
281   EXPECT_NE(server_creds, nullptr);
282 }
283 
TEST(CredentialsTest,MultipleServerCredentialsOneOptionsDoesNotLeak)284 TEST(CredentialsTest, MultipleServerCredentialsOneOptionsDoesNotLeak) {
285   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
286   TlsServerCredentialsOptions options(provider);
287   auto server_creds_1 = TlsServerCredentials(options);
288   EXPECT_NE(server_creds_1, nullptr);
289   auto server_creds_2 = TlsServerCredentials(options);
290   EXPECT_NE(server_creds_2, nullptr);
291 }
292 
TEST(CredentialsTest,MultipleServerCredentialsOneCertificateVerifierDoesNotLeak)293 TEST(CredentialsTest,
294      MultipleServerCredentialsOneCertificateVerifierDoesNotLeak) {
295   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
296   TlsServerCredentialsOptions options(provider);
297   auto verifier = std::make_shared<NoOpCertificateVerifier>();
298   options.set_certificate_verifier(verifier);
299   auto server_creds_1 = TlsServerCredentials(options);
300   EXPECT_NE(server_creds_1, nullptr);
301   auto server_creds_2 = TlsServerCredentials(options);
302   EXPECT_NE(server_creds_2, nullptr);
303 }
304 
TEST(CredentialsTest,MultipleServerCredentialsOneCrlProviderDoesNotLeak)305 TEST(CredentialsTest, MultipleServerCredentialsOneCrlProviderDoesNotLeak) {
306   auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
307   TlsServerCredentialsOptions options(provider);
308   auto crl_provider = CreateStaticCrlProvider(/*crls=*/{});
309   EXPECT_TRUE(crl_provider.ok());
310   options.set_crl_provider(*crl_provider);
311   auto server_creds_1 = TlsServerCredentials(options);
312   EXPECT_NE(server_creds_1, nullptr);
313   auto server_creds_2 = TlsServerCredentials(options);
314   EXPECT_NE(server_creds_2, nullptr);
315 }
316 
TEST(CredentialsTest,TlsServerCredentialsWithGoodMinMaxTlsVersions)317 TEST(CredentialsTest, TlsServerCredentialsWithGoodMinMaxTlsVersions) {
318   grpc::experimental::TlsServerCredentialsOptions options(
319       /*certificate_provider=*/nullptr);
320   options.set_min_tls_version(grpc_tls_version::TLS1_2);
321   options.set_max_tls_version(grpc_tls_version::TLS1_3);
322   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
323   EXPECT_NE(server_credentials, nullptr);
324 }
325 
TEST(CredentialsTest,TlsServerCredentialsWithBadMinMaxTlsVersions)326 TEST(CredentialsTest, TlsServerCredentialsWithBadMinMaxTlsVersions) {
327   grpc::experimental::TlsServerCredentialsOptions options(
328       /*certificate_provider=*/nullptr);
329   options.set_min_tls_version(grpc_tls_version::TLS1_3);
330   options.set_max_tls_version(grpc_tls_version::TLS1_2);
331   auto server_credentials = grpc::experimental::TlsServerCredentials(options);
332   EXPECT_EQ(server_credentials, nullptr);
333 }
334 
335 }  // namespace
336 }  // namespace testing
337 }  // namespace grpc
338 
main(int argc,char ** argv)339 int main(int argc, char** argv) {
340   ::testing::InitGoogleTest(&argc, argv);
341   grpc::testing::TestEnvironment env(&argc, argv);
342   int ret = RUN_ALL_TESTS();
343   return ret;
344 }
345