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 <memory>
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include <grpc/grpc.h>
23 #include <grpc/grpc_security.h>
24 #include <grpcpp/security/server_credentials.h>
25 #include <grpcpp/security/tls_credentials_options.h>
26
27 #include "src/cpp/client/secure_credentials.h"
28 #include "test/core/util/port.h"
29 #include "test/core/util/test_config.h"
30 #include "test/cpp/util/tls_test_utils.h"
31
32 namespace {
33
34 using ::grpc::experimental::ExternalCertificateVerifier;
35 using ::grpc::experimental::HostNameCertificateVerifier;
36 using ::grpc::experimental::NoOpCertificateVerifier;
37 using ::grpc::experimental::TlsCustomVerificationCheckRequest;
38
39 } // namespace
40
41 namespace grpc {
42 namespace testing {
43 namespace {
44
TEST(TlsCertificateVerifierTest,SyncCertificateVerifierSucceeds)45 TEST(TlsCertificateVerifierTest, SyncCertificateVerifierSucceeds) {
46 grpc_tls_custom_verification_check_request request;
47 auto verifier =
48 ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
49 TlsCustomVerificationCheckRequest cpp_request(&request);
50 grpc::Status sync_status;
51 verifier->Verify(&cpp_request, nullptr, &sync_status);
52 EXPECT_TRUE(sync_status.ok())
53 << sync_status.error_code() << " " << sync_status.error_message();
54 }
55
TEST(TlsCertificateVerifierTest,SyncCertificateVerifierFails)56 TEST(TlsCertificateVerifierTest, SyncCertificateVerifierFails) {
57 grpc_tls_custom_verification_check_request request;
58 auto verifier =
59 ExternalCertificateVerifier::Create<SyncCertificateVerifier>(false);
60 TlsCustomVerificationCheckRequest cpp_request(&request);
61 grpc::Status sync_status;
62 verifier->Verify(&cpp_request, nullptr, &sync_status);
63 EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
64 EXPECT_EQ(sync_status.error_message(), "SyncCertificateVerifier failed");
65 }
66
TEST(TlsCertificateVerifierTest,AsyncCertificateVerifierSucceeds)67 TEST(TlsCertificateVerifierTest, AsyncCertificateVerifierSucceeds) {
68 grpc_tls_custom_verification_check_request request;
69 auto verifier =
70 ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true);
71 TlsCustomVerificationCheckRequest cpp_request(&request);
72 std::function<void(grpc::Status)> callback = [](grpc::Status async_status) {
73 EXPECT_TRUE(async_status.ok())
74 << async_status.error_code() << " " << async_status.error_message();
75 };
76 grpc::Status sync_status;
77 EXPECT_FALSE(verifier->Verify(&cpp_request, callback, &sync_status));
78 }
79
TEST(TlsCertificateVerifierTest,AsyncCertificateVerifierFails)80 TEST(TlsCertificateVerifierTest, AsyncCertificateVerifierFails) {
81 grpc_tls_custom_verification_check_request request;
82 auto verifier =
83 ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(false);
84 TlsCustomVerificationCheckRequest cpp_request(&request);
85 std::function<void(grpc::Status)> callback = [](grpc::Status async_status) {
86 EXPECT_EQ(async_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
87 EXPECT_EQ(async_status.error_message(), "AsyncCertificateVerifier failed");
88 };
89 grpc::Status sync_status;
90 EXPECT_FALSE(verifier->Verify(&cpp_request, callback, &sync_status));
91 }
92
TEST(TlsCertificateVerifierTest,NoOpCertificateVerifierSucceeds)93 TEST(TlsCertificateVerifierTest, NoOpCertificateVerifierSucceeds) {
94 grpc_tls_custom_verification_check_request request;
95 memset(&request, 0, sizeof(request));
96 auto verifier = std::make_shared<NoOpCertificateVerifier>();
97 TlsCustomVerificationCheckRequest cpp_request(&request);
98 grpc::Status sync_status;
99 verifier->Verify(&cpp_request, nullptr, &sync_status);
100 EXPECT_TRUE(sync_status.ok())
101 << sync_status.error_code() << " " << sync_status.error_message();
102 }
103
TEST(TlsCertificateVerifierTest,HostNameCertificateVerifierSucceeds)104 TEST(TlsCertificateVerifierTest, HostNameCertificateVerifierSucceeds) {
105 grpc_tls_custom_verification_check_request request;
106 memset(&request, 0, sizeof(request));
107 request.target_name = "foo.bar.com";
108 request.peer_info.common_name = "foo.bar.com";
109 auto verifier = std::make_shared<HostNameCertificateVerifier>();
110 TlsCustomVerificationCheckRequest cpp_request(&request);
111 grpc::Status sync_status;
112 verifier->Verify(&cpp_request, nullptr, &sync_status);
113 EXPECT_TRUE(sync_status.ok())
114 << sync_status.error_code() << " " << sync_status.error_message();
115 }
116
TEST(TlsCertificateVerifierTest,HostNameCertificateVerifierFails)117 TEST(TlsCertificateVerifierTest, HostNameCertificateVerifierFails) {
118 grpc_tls_custom_verification_check_request request;
119 memset(&request, 0, sizeof(request));
120 request.target_name = "foo.bar.com";
121 request.peer_info.common_name = "foo.baz.com";
122 auto verifier = std::make_shared<HostNameCertificateVerifier>();
123 TlsCustomVerificationCheckRequest cpp_request(&request);
124 grpc::Status sync_status;
125 verifier->Verify(&cpp_request, nullptr, &sync_status);
126 EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
127 EXPECT_EQ(sync_status.error_message(), "Hostname Verification Check failed.");
128 }
129
TEST(TlsCertificateVerifierTest,HostNameCertificateVerifierSucceedsMultipleFields)130 TEST(TlsCertificateVerifierTest,
131 HostNameCertificateVerifierSucceedsMultipleFields) {
132 grpc_tls_custom_verification_check_request request;
133 memset(&request, 0, sizeof(request));
134 request.target_name = "foo.bar.com";
135 request.peer_info.common_name = "foo.baz.com";
136 char* dns_names[] = {const_cast<char*>("*.bar.com")};
137 request.peer_info.san_names.dns_names = dns_names;
138 request.peer_info.san_names.dns_names_size = 1;
139 auto verifier = std::make_shared<HostNameCertificateVerifier>();
140 TlsCustomVerificationCheckRequest cpp_request(&request);
141 grpc::Status sync_status;
142 verifier->Verify(&cpp_request, nullptr, &sync_status);
143 EXPECT_TRUE(sync_status.ok())
144 << sync_status.error_code() << " " << sync_status.error_message();
145 }
146
TEST(TlsCertificateVerifierTest,HostNameCertificateVerifierFailsMultipleFields)147 TEST(TlsCertificateVerifierTest,
148 HostNameCertificateVerifierFailsMultipleFields) {
149 grpc_tls_custom_verification_check_request request;
150 memset(&request, 0, sizeof(request));
151 request.target_name = "foo.bar.com";
152 request.peer_info.common_name = "foo.baz.com";
153 char* dns_names[] = {const_cast<char*>("*.")};
154 request.peer_info.san_names.dns_names = dns_names;
155 request.peer_info.san_names.dns_names_size = 1;
156 auto verifier = std::make_shared<HostNameCertificateVerifier>();
157 TlsCustomVerificationCheckRequest cpp_request(&request);
158 grpc::Status sync_status;
159 verifier->Verify(&cpp_request, nullptr, &sync_status);
160 EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
161 EXPECT_EQ(sync_status.error_message(), "Hostname Verification Check failed.");
162 }
163
TEST(TlsCertificateVerifierTest,VerifiedRootCertSubjectVerifierSucceeds)164 TEST(TlsCertificateVerifierTest, VerifiedRootCertSubjectVerifierSucceeds) {
165 grpc_tls_custom_verification_check_request request;
166 constexpr char kExpectedSubject[] =
167 "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU";
168 request.peer_info.verified_root_cert_subject = kExpectedSubject;
169 auto verifier =
170 ExternalCertificateVerifier::Create<VerifiedRootCertSubjectVerifier>(
171 kExpectedSubject);
172 TlsCustomVerificationCheckRequest cpp_request(&request);
173 grpc::Status sync_status;
174 bool is_sync = verifier->Verify(&cpp_request, nullptr, &sync_status);
175 EXPECT_TRUE(is_sync);
176 EXPECT_TRUE(sync_status.ok())
177 << sync_status.error_code() << " " << sync_status.error_message();
178 }
179
TEST(TlsCertificateVerifierTest,VerifiedRootCertSubjectVerifierFailsNull)180 TEST(TlsCertificateVerifierTest, VerifiedRootCertSubjectVerifierFailsNull) {
181 grpc_tls_custom_verification_check_request request;
182 constexpr char kExpectedSubject[] =
183 "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU";
184 request.peer_info.verified_root_cert_subject = nullptr;
185 auto verifier =
186 ExternalCertificateVerifier::Create<VerifiedRootCertSubjectVerifier>(
187 kExpectedSubject);
188 TlsCustomVerificationCheckRequest cpp_request(&request);
189 EXPECT_EQ(cpp_request.verified_root_cert_subject(), "");
190 grpc::Status sync_status;
191 verifier->Verify(&cpp_request, nullptr, &sync_status);
192 EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
193 EXPECT_EQ(sync_status.error_message(),
194 "VerifiedRootCertSubjectVerifier failed");
195 }
196
TEST(TlsCertificateVerifierTest,VerifiedRootCertSubjectVerifierFailsMismatch)197 TEST(TlsCertificateVerifierTest, VerifiedRootCertSubjectVerifierFailsMismatch) {
198 grpc_tls_custom_verification_check_request request;
199 constexpr char kExpectedSubject[] =
200 "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU";
201 request.peer_info.verified_root_cert_subject = "BAD_SUBJECT";
202 auto verifier =
203 ExternalCertificateVerifier::Create<VerifiedRootCertSubjectVerifier>(
204 kExpectedSubject);
205 TlsCustomVerificationCheckRequest cpp_request(&request);
206 grpc::Status sync_status;
207 verifier->Verify(&cpp_request, nullptr, &sync_status);
208 EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED);
209 EXPECT_EQ(sync_status.error_message(),
210 "VerifiedRootCertSubjectVerifier failed");
211 }
212
213 } // namespace
214 } // namespace testing
215 } // namespace grpc
216
main(int argc,char ** argv)217 int main(int argc, char** argv) {
218 ::testing::InitGoogleTest(&argc, argv);
219 grpc::testing::TestEnvironment env(&argc, argv);
220 int ret = RUN_ALL_TESTS();
221 return ret;
222 }
223