xref: /aosp_15_r20/external/grpc-grpc/test/core/security/grpc_tls_certificate_provider_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
18 
19 #include <deque>
20 #include <list>
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/string_util.h>
28 
29 #include "src/core/lib/gpr/tmpfile.h"
30 #include "src/core/lib/gprpp/crash.h"
31 #include "src/core/lib/slice/slice_internal.h"
32 #include "test/core/util/test_config.h"
33 #include "test/core/util/tls_utils.h"
34 
35 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
36 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
37 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
38 #define CA_CERT_PATH_2 "src/core/tsi/test_creds/multi-domain.pem"
39 #define SERVER_CERT_PATH_2 "src/core/tsi/test_creds/server0.pem"
40 #define SERVER_KEY_PATH_2 "src/core/tsi/test_creds/server0.key"
41 #define INVALID_PATH "invalid/path"
42 
43 namespace grpc_core {
44 
45 namespace testing {
46 
47 constexpr const char* kCertName = "cert_name";
48 constexpr const char* kRootError = "Unable to get latest root certificates.";
49 constexpr const char* kIdentityError =
50     "Unable to get latest identity certificates.";
51 
52 class GrpcTlsCertificateProviderTest : public ::testing::Test {
53  protected:
54   // Forward declaration.
55   class TlsCertificatesTestWatcher;
56 
57   // CredentialInfo contains the parameters when calling OnCertificatesChanged
58   // of a watcher. When OnCertificatesChanged is invoked, we will push a
59   // CredentialInfo to the cert_update_queue of state_, and check in each test
60   // if the status updates are correct.
61   struct CredentialInfo {
62     std::string root_certs;
63     PemKeyCertPairList key_cert_pairs;
CredentialInfogrpc_core::testing::GrpcTlsCertificateProviderTest::CredentialInfo64     CredentialInfo(std::string root, PemKeyCertPairList key_cert)
65         : root_certs(std::move(root)), key_cert_pairs(std::move(key_cert)) {}
operator ==grpc_core::testing::GrpcTlsCertificateProviderTest::CredentialInfo66     bool operator==(const CredentialInfo& other) const {
67       return root_certs == other.root_certs &&
68              key_cert_pairs == other.key_cert_pairs;
69     }
70   };
71 
72   // ErrorInfo contains the parameters when calling OnError of a watcher. When
73   // OnError is invoked, we will push a ErrorInfo to the error_queue of state_,
74   // and check in each test if the status updates are correct.
75   struct ErrorInfo {
76     std::string root_cert_str;
77     std::string identity_cert_str;
ErrorInfogrpc_core::testing::GrpcTlsCertificateProviderTest::ErrorInfo78     ErrorInfo(std::string root, std::string identity)
79         : root_cert_str(std::move(root)),
80           identity_cert_str(std::move(identity)) {}
operator ==grpc_core::testing::GrpcTlsCertificateProviderTest::ErrorInfo81     bool operator==(const ErrorInfo& other) const {
82       return root_cert_str == other.root_cert_str &&
83              identity_cert_str == other.identity_cert_str;
84     }
85   };
86 
87   struct WatcherState {
88     TlsCertificatesTestWatcher* watcher = nullptr;
89     std::deque<CredentialInfo> cert_update_queue;
90     std::deque<ErrorInfo> error_queue;
91     Mutex mu;
92 
GetCredentialQueuegrpc_core::testing::GrpcTlsCertificateProviderTest::WatcherState93     std::deque<CredentialInfo> GetCredentialQueue() {
94       // We move the data member value so the data member will be re-initiated
95       // with size 0, and ready for the next check.
96       MutexLock lock(&mu);
97       return std::move(cert_update_queue);
98     }
GetErrorQueuegrpc_core::testing::GrpcTlsCertificateProviderTest::WatcherState99     std::deque<ErrorInfo> GetErrorQueue() {
100       // We move the data member value so the data member will be re-initiated
101       // with size 0, and ready for the next check.
102       MutexLock lock(&mu);
103       return std::move(error_queue);
104     }
105   };
106 
107   class TlsCertificatesTestWatcher : public grpc_tls_certificate_distributor::
108                                          TlsCertificatesWatcherInterface {
109    public:
110     // ctor sets state->watcher to this.
TlsCertificatesTestWatcher(WatcherState * state)111     explicit TlsCertificatesTestWatcher(WatcherState* state) : state_(state) {
112       state_->watcher = this;
113     }
114 
115     // dtor sets state->watcher to nullptr.
~TlsCertificatesTestWatcher()116     ~TlsCertificatesTestWatcher() override { state_->watcher = nullptr; }
117 
OnCertificatesChanged(absl::optional<absl::string_view> root_certs,absl::optional<PemKeyCertPairList> key_cert_pairs)118     void OnCertificatesChanged(
119         absl::optional<absl::string_view> root_certs,
120         absl::optional<PemKeyCertPairList> key_cert_pairs) override {
121       MutexLock lock(&state_->mu);
122       std::string updated_root;
123       if (root_certs.has_value()) {
124         updated_root = std::string(*root_certs);
125       }
126       PemKeyCertPairList updated_identity;
127       if (key_cert_pairs.has_value()) {
128         updated_identity = std::move(*key_cert_pairs);
129       }
130       state_->cert_update_queue.emplace_back(std::move(updated_root),
131                                              std::move(updated_identity));
132     }
133 
OnError(grpc_error_handle root_cert_error,grpc_error_handle identity_cert_error)134     void OnError(grpc_error_handle root_cert_error,
135                  grpc_error_handle identity_cert_error) override {
136       MutexLock lock(&state_->mu);
137       GPR_ASSERT(!root_cert_error.ok() || !identity_cert_error.ok());
138       std::string root_error_str;
139       std::string identity_error_str;
140       if (!root_cert_error.ok()) {
141         GPR_ASSERT(grpc_error_get_str(
142             root_cert_error, StatusStrProperty::kDescription, &root_error_str));
143       }
144       if (!identity_cert_error.ok()) {
145         GPR_ASSERT(grpc_error_get_str(identity_cert_error,
146                                       StatusStrProperty::kDescription,
147                                       &identity_error_str));
148       }
149       state_->error_queue.emplace_back(std::move(root_error_str),
150                                        std::move(identity_error_str));
151     }
152 
153    private:
154     WatcherState* state_;
155   };
156 
SetUp()157   void SetUp() override {
158     root_cert_ = GetFileContents(CA_CERT_PATH);
159     cert_chain_ = GetFileContents(SERVER_CERT_PATH);
160     private_key_ = GetFileContents(SERVER_KEY_PATH);
161     root_cert_2_ = GetFileContents(CA_CERT_PATH_2);
162     cert_chain_2_ = GetFileContents(SERVER_CERT_PATH_2);
163     private_key_2_ = GetFileContents(SERVER_KEY_PATH_2);
164   }
165 
MakeWatcher(RefCountedPtr<grpc_tls_certificate_distributor> distributor,absl::optional<std::string> root_cert_name,absl::optional<std::string> identity_cert_name)166   WatcherState* MakeWatcher(
167       RefCountedPtr<grpc_tls_certificate_distributor> distributor,
168       absl::optional<std::string> root_cert_name,
169       absl::optional<std::string> identity_cert_name) {
170     MutexLock lock(&mu_);
171     distributor_ = distributor;
172     watchers_.emplace_back();
173     // TlsCertificatesTestWatcher ctor takes a pointer to the WatcherState.
174     // It sets WatcherState::watcher to point to itself.
175     // The TlsCertificatesTestWatcher dtor will set WatcherState::watcher back
176     // to nullptr to indicate that it's been destroyed.
177     auto watcher =
178         std::make_unique<TlsCertificatesTestWatcher>(&watchers_.back());
179     distributor_->WatchTlsCertificates(std::move(watcher),
180                                        std::move(root_cert_name),
181                                        std::move(identity_cert_name));
182     return &watchers_.back();
183   }
184 
CancelWatch(WatcherState * state)185   void CancelWatch(WatcherState* state) {
186     MutexLock lock(&mu_);
187     distributor_->CancelTlsCertificatesWatch(state->watcher);
188     EXPECT_EQ(state->watcher, nullptr);
189   }
190 
191   std::string root_cert_;
192   std::string private_key_;
193   std::string cert_chain_;
194   std::string root_cert_2_;
195   std::string private_key_2_;
196   std::string cert_chain_2_;
197   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
198   // Use a std::list<> here to avoid the address invalidation caused by internal
199   // reallocation of std::vector<>.
200   std::list<WatcherState> watchers_;
201   // This is to make watchers_ thread-safe.
202   Mutex mu_;
203 };
204 
TEST_F(GrpcTlsCertificateProviderTest,StaticDataCertificateProviderCreation)205 TEST_F(GrpcTlsCertificateProviderTest, StaticDataCertificateProviderCreation) {
206   StaticDataCertificateProvider provider(
207       root_cert_, MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
208   // Watcher watching both root and identity certs.
209   WatcherState* watcher_state_1 =
210       MakeWatcher(provider.distributor(), kCertName, kCertName);
211   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
212               ::testing::ElementsAre(CredentialInfo(
213                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
214                                                cert_chain_.c_str()))));
215   CancelWatch(watcher_state_1);
216   // Watcher watching only root certs.
217   WatcherState* watcher_state_2 =
218       MakeWatcher(provider.distributor(), kCertName, absl::nullopt);
219   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
220               ::testing::ElementsAre(CredentialInfo(root_cert_, {})));
221   CancelWatch(watcher_state_2);
222   // Watcher watching only identity certs.
223   WatcherState* watcher_state_3 =
224       MakeWatcher(provider.distributor(), absl::nullopt, kCertName);
225   EXPECT_THAT(
226       watcher_state_3->GetCredentialQueue(),
227       ::testing::ElementsAre(CredentialInfo(
228           "", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()))));
229   CancelWatch(watcher_state_3);
230 }
231 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderWithGoodPaths)232 TEST_F(GrpcTlsCertificateProviderTest,
233        FileWatcherCertificateProviderWithGoodPaths) {
234   FileWatcherCertificateProvider provider(SERVER_KEY_PATH, SERVER_CERT_PATH,
235                                           CA_CERT_PATH, 1);
236   // Watcher watching both root and identity certs.
237   WatcherState* watcher_state_1 =
238       MakeWatcher(provider.distributor(), kCertName, kCertName);
239   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
240               ::testing::ElementsAre(CredentialInfo(
241                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
242                                                cert_chain_.c_str()))));
243   CancelWatch(watcher_state_1);
244   // Watcher watching only root certs.
245   WatcherState* watcher_state_2 =
246       MakeWatcher(provider.distributor(), kCertName, absl::nullopt);
247   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
248               ::testing::ElementsAre(CredentialInfo(root_cert_, {})));
249   CancelWatch(watcher_state_2);
250   // Watcher watching only identity certs.
251   WatcherState* watcher_state_3 =
252       MakeWatcher(provider.distributor(), absl::nullopt, kCertName);
253   EXPECT_THAT(
254       watcher_state_3->GetCredentialQueue(),
255       ::testing::ElementsAre(CredentialInfo(
256           "", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()))));
257   CancelWatch(watcher_state_3);
258 }
259 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderWithBadPaths)260 TEST_F(GrpcTlsCertificateProviderTest,
261        FileWatcherCertificateProviderWithBadPaths) {
262   FileWatcherCertificateProvider provider(INVALID_PATH, INVALID_PATH,
263                                           INVALID_PATH, 1);
264   // Watcher watching both root and identity certs.
265   WatcherState* watcher_state_1 =
266       MakeWatcher(provider.distributor(), kCertName, kCertName);
267   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
268               ::testing::ElementsAre(ErrorInfo(kRootError, kIdentityError)));
269   EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
270   CancelWatch(watcher_state_1);
271   // Watcher watching only root certs.
272   WatcherState* watcher_state_2 =
273       MakeWatcher(provider.distributor(), kCertName, absl::nullopt);
274   EXPECT_THAT(watcher_state_2->GetErrorQueue(),
275               ::testing::ElementsAre(ErrorInfo(kRootError, "")));
276   EXPECT_THAT(watcher_state_2->GetCredentialQueue(), ::testing::ElementsAre());
277   CancelWatch(watcher_state_2);
278   // Watcher watching only identity certs.
279   WatcherState* watcher_state_3 =
280       MakeWatcher(provider.distributor(), absl::nullopt, kCertName);
281   EXPECT_THAT(watcher_state_3->GetErrorQueue(),
282               ::testing::ElementsAre(ErrorInfo("", kIdentityError)));
283   EXPECT_THAT(watcher_state_3->GetCredentialQueue(), ::testing::ElementsAre());
284   CancelWatch(watcher_state_3);
285 }
286 
287 // The following tests write credential data to temporary files to test the
288 // transition behavior of the provider.
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderOnBothCertsRefreshed)289 TEST_F(GrpcTlsCertificateProviderTest,
290        FileWatcherCertificateProviderOnBothCertsRefreshed) {
291   // Create temporary files and copy cert data into them.
292   TmpFile tmp_root_cert(root_cert_);
293   TmpFile tmp_identity_key(private_key_);
294   TmpFile tmp_identity_cert(cert_chain_);
295   // Create FileWatcherCertificateProvider.
296   FileWatcherCertificateProvider provider(tmp_identity_key.name(),
297                                           tmp_identity_cert.name(),
298                                           tmp_root_cert.name(), 1);
299   WatcherState* watcher_state_1 =
300       MakeWatcher(provider.distributor(), kCertName, kCertName);
301   // Expect to see the credential data.
302   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
303               ::testing::ElementsAre(CredentialInfo(
304                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
305                                                cert_chain_.c_str()))));
306   // Copy new data to files.
307   // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
308   // update when the directory renaming is added in gpr.
309   tmp_root_cert.RewriteFile(root_cert_2_);
310   tmp_identity_key.RewriteFile(private_key_2_);
311   tmp_identity_cert.RewriteFile(cert_chain_2_);
312   // Wait 2 seconds for the provider's refresh thread to read the updated files.
313   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
314                                gpr_time_from_seconds(2, GPR_TIMESPAN)));
315   // Expect to see the new credential data.
316   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
317               ::testing::ElementsAre(CredentialInfo(
318                   root_cert_2_, MakeCertKeyPairs(private_key_2_.c_str(),
319                                                  cert_chain_2_.c_str()))));
320   // Clean up.
321   CancelWatch(watcher_state_1);
322 }
323 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderOnRootCertsRefreshed)324 TEST_F(GrpcTlsCertificateProviderTest,
325        FileWatcherCertificateProviderOnRootCertsRefreshed) {
326   // Create temporary files and copy cert data into them.
327   TmpFile tmp_root_cert(root_cert_);
328   TmpFile tmp_identity_key(private_key_);
329   TmpFile tmp_identity_cert(cert_chain_);
330   // Create FileWatcherCertificateProvider.
331   FileWatcherCertificateProvider provider(tmp_identity_key.name(),
332                                           tmp_identity_cert.name(),
333                                           tmp_root_cert.name(), 1);
334   WatcherState* watcher_state_1 =
335       MakeWatcher(provider.distributor(), kCertName, kCertName);
336   // Expect to see the credential data.
337   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
338               ::testing::ElementsAre(CredentialInfo(
339                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
340                                                cert_chain_.c_str()))));
341   // Copy new data to files.
342   // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
343   // update when the directory renaming is added in gpr.
344   tmp_root_cert.RewriteFile(root_cert_2_);
345   // Wait 2 seconds for the provider's refresh thread to read the updated files.
346   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
347                                gpr_time_from_seconds(2, GPR_TIMESPAN)));
348   // Expect to see the new credential data.
349   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
350               ::testing::ElementsAre(CredentialInfo(
351                   root_cert_2_, MakeCertKeyPairs(private_key_.c_str(),
352                                                  cert_chain_.c_str()))));
353   // Clean up.
354   CancelWatch(watcher_state_1);
355 }
356 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderOnIdentityCertsRefreshed)357 TEST_F(GrpcTlsCertificateProviderTest,
358        FileWatcherCertificateProviderOnIdentityCertsRefreshed) {
359   // Create temporary files and copy cert data into them.
360   TmpFile tmp_root_cert(root_cert_);
361   TmpFile tmp_identity_key(private_key_);
362   TmpFile tmp_identity_cert(cert_chain_);
363   // Create FileWatcherCertificateProvider.
364   FileWatcherCertificateProvider provider(tmp_identity_key.name(),
365                                           tmp_identity_cert.name(),
366                                           tmp_root_cert.name(), 1);
367   WatcherState* watcher_state_1 =
368       MakeWatcher(provider.distributor(), kCertName, kCertName);
369   // Expect to see the credential data.
370   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
371               ::testing::ElementsAre(CredentialInfo(
372                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
373                                                cert_chain_.c_str()))));
374   // Copy new data to files.
375   // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
376   // update when the directory renaming is added in gpr.
377   tmp_identity_key.RewriteFile(private_key_2_);
378   tmp_identity_cert.RewriteFile(cert_chain_2_);
379   // Wait 2 seconds for the provider's refresh thread to read the updated files.
380   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
381                                gpr_time_from_seconds(2, GPR_TIMESPAN)));
382   // Expect to see the new credential data.
383   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
384               ::testing::ElementsAre(CredentialInfo(
385                   root_cert_, MakeCertKeyPairs(private_key_2_.c_str(),
386                                                cert_chain_2_.c_str()))));
387   // Clean up.
388   CancelWatch(watcher_state_1);
389 }
390 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderWithGoodAtFirstThenDeletedBothCerts)391 TEST_F(GrpcTlsCertificateProviderTest,
392        FileWatcherCertificateProviderWithGoodAtFirstThenDeletedBothCerts) {
393   // Create temporary files and copy cert data into it.
394   auto tmp_root_cert = std::make_unique<TmpFile>(root_cert_);
395   auto tmp_identity_key = std::make_unique<TmpFile>(private_key_);
396   auto tmp_identity_cert = std::make_unique<TmpFile>(cert_chain_);
397   // Create FileWatcherCertificateProvider.
398   FileWatcherCertificateProvider provider(tmp_identity_key->name(),
399                                           tmp_identity_cert->name(),
400                                           tmp_root_cert->name(), 1);
401   WatcherState* watcher_state_1 =
402       MakeWatcher(provider.distributor(), kCertName, kCertName);
403   // The initial data is all good, so we expect to have successful credential
404   // updates.
405   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
406               ::testing::ElementsAre(CredentialInfo(
407                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
408                                                cert_chain_.c_str()))));
409   // Delete TmpFile objects, which will remove the corresponding files.
410   tmp_root_cert.reset();
411   tmp_identity_key.reset();
412   tmp_identity_cert.reset();
413   // Wait 2 seconds for the provider's refresh thread to read the deleted files.
414   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
415                                gpr_time_from_seconds(2, GPR_TIMESPAN)));
416   // Expect to see errors sent to watchers, and no credential updates.
417   // We have no ideas on how many errors we will receive, so we only check once.
418   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
419               ::testing::Contains(ErrorInfo(kRootError, kIdentityError)));
420   EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
421   // Clean up.
422   CancelWatch(watcher_state_1);
423 }
424 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderWithGoodAtFirstThenDeletedRootCerts)425 TEST_F(GrpcTlsCertificateProviderTest,
426        FileWatcherCertificateProviderWithGoodAtFirstThenDeletedRootCerts) {
427   // Create temporary files and copy cert data into it.
428   auto tmp_root_cert = std::make_unique<TmpFile>(root_cert_);
429   TmpFile tmp_identity_key(private_key_);
430   TmpFile tmp_identity_cert(cert_chain_);
431   // Create FileWatcherCertificateProvider.
432   FileWatcherCertificateProvider provider(tmp_identity_key.name(),
433                                           tmp_identity_cert.name(),
434                                           tmp_root_cert->name(), 1);
435   WatcherState* watcher_state_1 =
436       MakeWatcher(provider.distributor(), kCertName, kCertName);
437   // The initial data is all good, so we expect to have successful credential
438   // updates.
439   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
440               ::testing::ElementsAre(CredentialInfo(
441                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
442                                                cert_chain_.c_str()))));
443   // Delete root TmpFile object, which will remove the corresponding file.
444   tmp_root_cert.reset();
445   // Wait 2 seconds for the provider's refresh thread to read the deleted files.
446   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
447                                gpr_time_from_seconds(2, GPR_TIMESPAN)));
448   // Expect to see errors sent to watchers, and no credential updates.
449   // We have no ideas on how many errors we will receive, so we only check once.
450   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
451               ::testing::Contains(ErrorInfo(kRootError, "")));
452   EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
453   // Clean up.
454   CancelWatch(watcher_state_1);
455 }
456 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderWithGoodAtFirstThenDeletedIdentityCerts)457 TEST_F(GrpcTlsCertificateProviderTest,
458        FileWatcherCertificateProviderWithGoodAtFirstThenDeletedIdentityCerts) {
459   // Create temporary files and copy cert data into it.
460   TmpFile tmp_root_cert(root_cert_);
461   auto tmp_identity_key = std::make_unique<TmpFile>(private_key_);
462   auto tmp_identity_cert = std::make_unique<TmpFile>(cert_chain_);
463   // Create FileWatcherCertificateProvider.
464   FileWatcherCertificateProvider provider(tmp_identity_key->name(),
465                                           tmp_identity_cert->name(),
466                                           tmp_root_cert.name(), 1);
467   WatcherState* watcher_state_1 =
468       MakeWatcher(provider.distributor(), kCertName, kCertName);
469   // The initial data is all good, so we expect to have successful credential
470   // updates.
471   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
472               ::testing::ElementsAre(CredentialInfo(
473                   root_cert_, MakeCertKeyPairs(private_key_.c_str(),
474                                                cert_chain_.c_str()))));
475   // Delete identity TmpFile objects, which will remove the corresponding files.
476   tmp_identity_key.reset();
477   tmp_identity_cert.reset();
478   // Wait 2 seconds for the provider's refresh thread to read the deleted files.
479   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
480                                gpr_time_from_seconds(2, GPR_TIMESPAN)));
481   // Expect to see errors sent to watchers, and no credential updates.
482   // We have no ideas on how many errors we will receive, so we only check once.
483   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
484               ::testing::Contains(ErrorInfo("", kIdentityError)));
485   EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
486   // Clean up.
487   CancelWatch(watcher_state_1);
488 }
489 
TEST_F(GrpcTlsCertificateProviderTest,FileWatcherCertificateProviderTooShortRefreshIntervalIsOverwritten)490 TEST_F(GrpcTlsCertificateProviderTest,
491        FileWatcherCertificateProviderTooShortRefreshIntervalIsOverwritten) {
492   FileWatcherCertificateProvider provider(SERVER_KEY_PATH, SERVER_CERT_PATH,
493                                           CA_CERT_PATH, 0);
494   ASSERT_THAT(provider.TestOnlyGetRefreshIntervalSecond(), 1);
495 }
496 
TEST_F(GrpcTlsCertificateProviderTest,FailedKeyCertMatchOnEmptyPrivateKey)497 TEST_F(GrpcTlsCertificateProviderTest, FailedKeyCertMatchOnEmptyPrivateKey) {
498   absl::StatusOr<bool> status =
499       PrivateKeyAndCertificateMatch(/*private_key=*/"", cert_chain_);
500   EXPECT_FALSE(status.ok());
501   EXPECT_EQ(status.status().code(), absl::StatusCode::kInvalidArgument);
502   EXPECT_EQ(status.status().message(), "Private key string is empty.");
503 }
504 
TEST_F(GrpcTlsCertificateProviderTest,FailedKeyCertMatchOnEmptyCertificate)505 TEST_F(GrpcTlsCertificateProviderTest, FailedKeyCertMatchOnEmptyCertificate) {
506   absl::StatusOr<bool> status =
507       PrivateKeyAndCertificateMatch(private_key_2_, /*cert_chain=*/"");
508   EXPECT_FALSE(status.ok());
509   EXPECT_EQ(status.status().code(), absl::StatusCode::kInvalidArgument);
510   EXPECT_EQ(status.status().message(), "Certificate string is empty.");
511 }
512 
TEST_F(GrpcTlsCertificateProviderTest,FailedKeyCertMatchOnInvalidCertFormat)513 TEST_F(GrpcTlsCertificateProviderTest, FailedKeyCertMatchOnInvalidCertFormat) {
514   absl::StatusOr<bool> status =
515       PrivateKeyAndCertificateMatch(private_key_2_, "invalid_certificate");
516   EXPECT_FALSE(status.ok());
517   EXPECT_EQ(status.status().code(), absl::StatusCode::kInvalidArgument);
518   EXPECT_EQ(status.status().message(),
519             "Conversion from PEM string to X509 failed.");
520 }
521 
TEST_F(GrpcTlsCertificateProviderTest,FailedKeyCertMatchOnInvalidPrivateKeyFormat)522 TEST_F(GrpcTlsCertificateProviderTest,
523        FailedKeyCertMatchOnInvalidPrivateKeyFormat) {
524   absl::StatusOr<bool> status =
525       PrivateKeyAndCertificateMatch("invalid_private_key", cert_chain_2_);
526   EXPECT_EQ(status.status().code(), absl::StatusCode::kInvalidArgument);
527   EXPECT_EQ(status.status().message(),
528             "Conversion from PEM string to EVP_PKEY failed.");
529 }
530 
TEST_F(GrpcTlsCertificateProviderTest,SuccessfulKeyCertMatch)531 TEST_F(GrpcTlsCertificateProviderTest, SuccessfulKeyCertMatch) {
532   absl::StatusOr<bool> status =
533       PrivateKeyAndCertificateMatch(private_key_2_, cert_chain_2_);
534   EXPECT_TRUE(status.ok());
535   EXPECT_TRUE(*status);
536 }
537 
TEST_F(GrpcTlsCertificateProviderTest,FailedKeyCertMatchOnInvalidPair)538 TEST_F(GrpcTlsCertificateProviderTest, FailedKeyCertMatchOnInvalidPair) {
539   absl::StatusOr<bool> status =
540       PrivateKeyAndCertificateMatch(private_key_2_, cert_chain_);
541   EXPECT_TRUE(status.ok());
542   EXPECT_FALSE(*status);
543 }
544 
545 }  // namespace testing
546 }  // namespace grpc_core
547 
main(int argc,char ** argv)548 int main(int argc, char** argv) {
549   grpc::testing::TestEnvironment env(&argc, argv);
550   ::testing::InitGoogleTest(&argc, argv);
551   grpc_init();
552   int ret = RUN_ALL_TESTS();
553   grpc_shutdown();
554   return ret;
555 }
556