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