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