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