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