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