• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 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_verifier.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/log.h"
28 #include "src/core/lib/security/security_connector/tls/tls_security_connector.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 namespace grpc_core {
36 
37 namespace testing {
38 
39 // Unit tests for grpc_tls_certificate_verifier and all its successors.
40 // In these tests, |request_| is not outliving the test itself, so it's fine to
41 // point fields in |request_| directly to the address of local variables. In
42 // actual implementation, these fields are dynamically allocated.
43 class GrpcTlsCertificateVerifierTest : public ::testing::Test {
44  protected:
SetUp()45   void SetUp() override { memset(&request_, 0, sizeof(request_)); }
46 
TearDown()47   void TearDown() override {}
48 
49   grpc_tls_custom_verification_check_request request_;
50   NoOpCertificateVerifier no_op_certificate_verifier_;
51   HostNameCertificateVerifier hostname_certificate_verifier_;
52 };
53 
TEST_F(GrpcTlsCertificateVerifierTest,SyncExternalVerifierSucceeds)54 TEST_F(GrpcTlsCertificateVerifierTest, SyncExternalVerifierSucceeds) {
55   auto* sync_verifier = new SyncExternalVerifier(true);
56   ExternalCertificateVerifier core_external_verifier(sync_verifier->base());
57   absl::Status sync_status;
58   EXPECT_TRUE(core_external_verifier.Verify(
59       &request_, [](absl::Status) {}, &sync_status));
60   EXPECT_TRUE(sync_status.ok())
61       << sync_status.code() << " " << sync_status.message();
62 }
63 
TEST_F(GrpcTlsCertificateVerifierTest,SyncExternalVerifierFails)64 TEST_F(GrpcTlsCertificateVerifierTest, SyncExternalVerifierFails) {
65   auto* sync_verifier = new SyncExternalVerifier(false);
66   ExternalCertificateVerifier core_external_verifier(sync_verifier->base());
67   absl::Status sync_status;
68   EXPECT_TRUE(core_external_verifier.Verify(
69       &request_, [](absl::Status) {}, &sync_status));
70   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
71   EXPECT_EQ(sync_status.ToString(),
72             "UNAUTHENTICATED: SyncExternalVerifier failed");
73 }
74 
TEST_F(GrpcTlsCertificateVerifierTest,AsyncExternalVerifierSucceeds)75 TEST_F(GrpcTlsCertificateVerifierTest, AsyncExternalVerifierSucceeds) {
76   absl::Status sync_status;
77   // This is to make sure the callback has already been completed before we
78   // destroy ExternalCertificateVerifier object.
79   gpr_event callback_completed_event;
80   gpr_event_init(&callback_completed_event);
81   auto* async_verifier = new AsyncExternalVerifier(true);
82   ExternalCertificateVerifier core_external_verifier(async_verifier->base());
83   EXPECT_FALSE(core_external_verifier.Verify(
84       &request_,
85       [&callback_completed_event](absl::Status async_status) {
86         EXPECT_TRUE(async_status.ok())
87             << async_status.code() << " " << async_status.message();
88         gpr_event_set(&callback_completed_event, reinterpret_cast<void*>(1));
89       },
90       &sync_status));
91   void* callback_completed =
92       gpr_event_wait(&callback_completed_event,
93                      gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
94                                   gpr_time_from_seconds(10, GPR_TIMESPAN)));
95   EXPECT_NE(callback_completed, nullptr);
96 }
97 
TEST_F(GrpcTlsCertificateVerifierTest,AsyncExternalVerifierFails)98 TEST_F(GrpcTlsCertificateVerifierTest, AsyncExternalVerifierFails) {
99   absl::Status sync_status;
100   // This is to make sure the callback has already been completed before we
101   // destroy ExternalCertificateVerifier object.
102   gpr_event callback_completed_event;
103   gpr_event_init(&callback_completed_event);
104   auto* async_verifier = new AsyncExternalVerifier(false);
105   ExternalCertificateVerifier core_external_verifier(async_verifier->base());
106   EXPECT_FALSE(core_external_verifier.Verify(
107       &request_,
108       [&callback_completed_event](absl::Status async_status) {
109         LOG(INFO) << "Callback is invoked.";
110         EXPECT_EQ(async_status.code(), absl::StatusCode::kUnauthenticated);
111         EXPECT_EQ(async_status.ToString(),
112                   "UNAUTHENTICATED: AsyncExternalVerifier failed");
113         gpr_event_set(&callback_completed_event, reinterpret_cast<void*>(1));
114       },
115       &sync_status));
116   void* callback_completed =
117       gpr_event_wait(&callback_completed_event,
118                      gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
119                                   gpr_time_from_seconds(10, GPR_TIMESPAN)));
120   EXPECT_NE(callback_completed, nullptr);
121 }
122 
TEST_F(GrpcTlsCertificateVerifierTest,NoOpCertificateVerifierSucceeds)123 TEST_F(GrpcTlsCertificateVerifierTest, NoOpCertificateVerifierSucceeds) {
124   absl::Status sync_status;
125   EXPECT_TRUE(no_op_certificate_verifier_.Verify(
126       &request_, [](absl::Status) {}, &sync_status));
127   EXPECT_TRUE(sync_status.ok())
128       << sync_status.code() << " " << sync_status.message();
129 }
130 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierNullTargetName)131 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierNullTargetName) {
132   absl::Status sync_status;
133   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
134       &request_, [](absl::Status) {}, &sync_status));
135   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
136   EXPECT_EQ(sync_status.ToString(),
137             "UNAUTHENTICATED: Target name is not specified.");
138 }
139 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierInvalidTargetName)140 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierInvalidTargetName) {
141   absl::Status sync_status;
142   request_.target_name = "[foo.com@443";
143   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
144       &request_, [](absl::Status) {}, &sync_status));
145   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
146   EXPECT_EQ(sync_status.ToString(),
147             "UNAUTHENTICATED: Failed to split hostname and port.");
148 }
149 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierDNSExactCheckSucceeds)150 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierDNSExactCheckSucceeds) {
151   absl::Status sync_status;
152   request_.target_name = "foo.com:443";
153   char* dns_names[] = {const_cast<char*>("foo.com")};
154   request_.peer_info.san_names.dns_names = dns_names;
155   request_.peer_info.san_names.dns_names_size = 1;
156   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
157       &request_, [](absl::Status) {}, &sync_status));
158   EXPECT_TRUE(sync_status.ok())
159       << sync_status.code() << " " << sync_status.message();
160 }
161 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierDNSWildcardCheckSucceeds)162 TEST_F(GrpcTlsCertificateVerifierTest,
163        HostnameVerifierDNSWildcardCheckSucceeds) {
164   absl::Status sync_status;
165   request_.target_name = "foo.bar.com:443";
166   char* dns_names[] = {const_cast<char*>("*.bar.com")};
167   request_.peer_info.san_names.dns_names = dns_names;
168   request_.peer_info.san_names.dns_names_size = 1;
169   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
170       &request_, [](absl::Status) {}, &sync_status));
171   EXPECT_TRUE(sync_status.ok())
172       << sync_status.code() << " " << sync_status.message();
173 }
174 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierDNSWildcardCaseInsensitiveCheckSucceeds)175 TEST_F(GrpcTlsCertificateVerifierTest,
176        HostnameVerifierDNSWildcardCaseInsensitiveCheckSucceeds) {
177   absl::Status sync_status;
178   request_.target_name = "fOo.bar.cOm:443";
179   char* dns_names[] = {const_cast<char*>("*.BaR.Com")};
180   request_.peer_info.san_names.dns_names = dns_names;
181   request_.peer_info.san_names.dns_names_size = 1;
182   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
183       &request_, [](absl::Status) {}, &sync_status));
184   EXPECT_TRUE(sync_status.ok())
185       << sync_status.code() << " " << sync_status.message();
186 }
187 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierDNSTopWildcardCheckFails)188 TEST_F(GrpcTlsCertificateVerifierTest,
189        HostnameVerifierDNSTopWildcardCheckFails) {
190   absl::Status sync_status;
191   request_.target_name = "foo.com:443";
192   char* dns_names[] = {const_cast<char*>("*.")};
193   request_.peer_info.san_names.dns_names = dns_names;
194   request_.peer_info.san_names.dns_names_size = 1;
195   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
196       &request_, [](absl::Status) {}, &sync_status));
197   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
198   EXPECT_EQ(sync_status.ToString(),
199             "UNAUTHENTICATED: Hostname Verification Check failed.");
200 }
201 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierDNSExactCheckFails)202 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierDNSExactCheckFails) {
203   absl::Status sync_status;
204   request_.target_name = "foo.com:443";
205   char* dns_names[] = {const_cast<char*>("bar.com")};
206   request_.peer_info.san_names.dns_names = dns_names;
207   request_.peer_info.san_names.dns_names_size = 1;
208   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
209       &request_, [](absl::Status) {}, &sync_status));
210   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
211   EXPECT_EQ(sync_status.ToString(),
212             "UNAUTHENTICATED: Hostname Verification Check failed.");
213 }
214 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierIpCheckSucceeds)215 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierIpCheckSucceeds) {
216   absl::Status sync_status;
217   request_.target_name = "192.168.0.1:443";
218   char* ip_names[] = {const_cast<char*>("192.168.0.1")};
219   request_.peer_info.san_names.ip_names = ip_names;
220   request_.peer_info.san_names.ip_names_size = 1;
221   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
222       &request_, [](absl::Status) {}, &sync_status));
223   EXPECT_TRUE(sync_status.ok())
224       << sync_status.code() << " " << sync_status.message();
225 }
226 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierIpCheckFails)227 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierIpCheckFails) {
228   absl::Status sync_status;
229   request_.target_name = "192.168.0.1:443";
230   char* ip_names[] = {const_cast<char*>("192.168.1.1")};
231   request_.peer_info.san_names.ip_names = ip_names;
232   request_.peer_info.san_names.ip_names_size = 1;
233   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
234       &request_, [](absl::Status) {}, &sync_status));
235   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
236   EXPECT_EQ(sync_status.ToString(),
237             "UNAUTHENTICATED: Hostname Verification Check failed.");
238 }
239 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierCommonNameCheckSucceeds)240 TEST_F(GrpcTlsCertificateVerifierTest,
241        HostnameVerifierCommonNameCheckSucceeds) {
242   absl::Status sync_status;
243   request_.target_name = "foo.com:443";
244   request_.peer_info.common_name = "foo.com";
245   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
246       &request_, [](absl::Status) {}, &sync_status));
247   EXPECT_TRUE(sync_status.ok())
248       << sync_status.code() << " " << sync_status.message();
249 }
250 
TEST_F(GrpcTlsCertificateVerifierTest,HostnameVerifierCommonNameCheckFails)251 TEST_F(GrpcTlsCertificateVerifierTest, HostnameVerifierCommonNameCheckFails) {
252   absl::Status sync_status;
253   request_.target_name = "foo.com:443";
254   request_.peer_info.common_name = "bar.com";
255   EXPECT_TRUE(hostname_certificate_verifier_.Verify(
256       &request_, [](absl::Status) {}, &sync_status));
257   EXPECT_EQ(sync_status.code(), absl::StatusCode::kUnauthenticated);
258   EXPECT_EQ(sync_status.ToString(),
259             "UNAUTHENTICATED: Hostname Verification Check failed.");
260 }
261 
TEST_F(GrpcTlsCertificateVerifierTest,ComparingDifferentObjectTypesFails)262 TEST_F(GrpcTlsCertificateVerifierTest, ComparingDifferentObjectTypesFails) {
263   grpc_tls_certificate_verifier_external verifier = {nullptr, nullptr, nullptr,
264                                                      nullptr};
265   ExternalCertificateVerifier external_verifier(&verifier);
266   HostNameCertificateVerifier hostname_certificate_verifier;
267   EXPECT_NE(external_verifier.Compare(&hostname_certificate_verifier), 0);
268   EXPECT_NE(hostname_certificate_verifier.Compare(&external_verifier), 0);
269 }
270 
TEST_F(GrpcTlsCertificateVerifierTest,HostNameCertificateVerifier)271 TEST_F(GrpcTlsCertificateVerifierTest, HostNameCertificateVerifier) {
272   HostNameCertificateVerifier hostname_certificate_verifier_1;
273   HostNameCertificateVerifier hostname_certificate_verifier_2;
274   EXPECT_EQ(
275       hostname_certificate_verifier_1.Compare(&hostname_certificate_verifier_2),
276       0);
277   EXPECT_EQ(
278       hostname_certificate_verifier_2.Compare(&hostname_certificate_verifier_1),
279       0);
280 }
281 
TEST_F(GrpcTlsCertificateVerifierTest,ExternalCertificateVerifierSuccess)282 TEST_F(GrpcTlsCertificateVerifierTest, ExternalCertificateVerifierSuccess) {
283   grpc_tls_certificate_verifier_external verifier = {nullptr, nullptr, nullptr,
284                                                      nullptr};
285   ExternalCertificateVerifier external_verifier_1(&verifier);
286   ExternalCertificateVerifier external_verifier_2(&verifier);
287   EXPECT_EQ(external_verifier_1.Compare(&external_verifier_2), 0);
288   EXPECT_EQ(external_verifier_2.Compare(&external_verifier_1), 0);
289 }
290 
TEST_F(GrpcTlsCertificateVerifierTest,ExternalCertificateVerifierFailure)291 TEST_F(GrpcTlsCertificateVerifierTest, ExternalCertificateVerifierFailure) {
292   grpc_tls_certificate_verifier_external verifier_1 = {nullptr, nullptr,
293                                                        nullptr, nullptr};
294   ExternalCertificateVerifier external_verifier_1(&verifier_1);
295   grpc_tls_certificate_verifier_external verifier_2 = {nullptr, nullptr,
296                                                        nullptr, nullptr};
297   ExternalCertificateVerifier external_verifier_2(&verifier_2);
298   EXPECT_NE(external_verifier_1.Compare(&external_verifier_2), 0);
299   EXPECT_NE(external_verifier_2.Compare(&external_verifier_1), 0);
300 }
301 
302 }  // namespace testing
303 
304 }  // namespace grpc_core
305 
main(int argc,char ** argv)306 int main(int argc, char** argv) {
307   grpc::testing::TestEnvironment env(&argc, argv);
308   ::testing::InitGoogleTest(&argc, argv);
309   grpc_init();
310   int ret = RUN_ALL_TESTS();
311   grpc_shutdown();
312   return ret;
313 }
314