1 //
2 //
3 // Copyright 2018 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 #include <stdint.h>
19 #include <string.h>
20
21 #include <string>
22
23 #include <gtest/gtest.h>
24
25 #include "absl/types/optional.h"
26
27 #include <grpc/grpc.h>
28 #include <grpc/grpc_security.h>
29 #include <grpc/grpc_security_constants.h>
30 #include <grpc/impl/channel_arg_names.h>
31 #include <grpc/impl/propagation_bits.h>
32 #include <grpc/slice.h>
33 #include <grpc/status.h>
34 #include <grpc/support/log.h>
35 #include <grpc/support/time.h>
36
37 #include "src/core/lib/channel/channel_args.h"
38 #include "src/core/lib/config/config_vars.h"
39 #include "src/core/lib/gpr/useful.h"
40 #include "src/core/lib/gprpp/host_port.h"
41 #include "src/core/lib/iomgr/error.h"
42 #include "src/core/lib/iomgr/exec_ctx.h"
43 #include "test/core/end2end/cq_verifier.h"
44 #include "test/core/util/port.h"
45 #include "test/core/util/test_config.h"
46 #include "test/core/util/tls_utils.h"
47
48 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
49 #define CLIENT_CERT_PATH "src/core/tsi/test_creds/client.pem"
50 #define CLIENT_KEY_PATH "src/core/tsi/test_creds/client.key"
51 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
52 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
53
54 namespace grpc {
55 namespace testing {
56 namespace {
57
58 const std::string kCaCertSubject =
59 "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU";
60
tag(intptr_t t)61 void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
62
five_seconds_time()63 gpr_timespec five_seconds_time() { return grpc_timeout_seconds_to_deadline(5); }
64
server_create(grpc_completion_queue * cq,const char * server_addr,grpc_tls_certificate_provider ** server_provider,grpc_tls_certificate_verifier ** verifier)65 grpc_server* server_create(grpc_completion_queue* cq, const char* server_addr,
66 grpc_tls_certificate_provider** server_provider,
67 grpc_tls_certificate_verifier** verifier) {
68 std::string ca_cert = grpc_core::testing::GetFileContents(CA_CERT_PATH);
69 std::string server_cert =
70 grpc_core::testing::GetFileContents(SERVER_CERT_PATH);
71 std::string server_key = grpc_core::testing::GetFileContents(SERVER_KEY_PATH);
72
73 grpc_tls_credentials_options* options = grpc_tls_credentials_options_create();
74 // Set credential provider.
75 grpc_tls_identity_pairs* server_pairs = grpc_tls_identity_pairs_create();
76 grpc_tls_identity_pairs_add_pair(server_pairs, server_key.c_str(),
77 server_cert.c_str());
78 *server_provider = grpc_tls_certificate_provider_static_data_create(
79 ca_cert.c_str(), server_pairs);
80 grpc_tls_credentials_options_set_certificate_provider(options,
81 *server_provider);
82 grpc_tls_credentials_options_watch_root_certs(options);
83 grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
84 // Set client certificate request type.
85 grpc_tls_credentials_options_set_cert_request_type(
86 options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
87 // Set credential verifier.
88 auto* server_test_verifier =
89 new grpc_core::testing::PeerPropertyExternalVerifier(kCaCertSubject);
90 *verifier = grpc_tls_certificate_verifier_external_create(
91 server_test_verifier->base());
92 grpc_tls_credentials_options_set_certificate_verifier(options, *verifier);
93 grpc_server_credentials* creds = grpc_tls_server_credentials_create(options);
94
95 grpc_server* server = grpc_server_create(nullptr, nullptr);
96 grpc_server_register_completion_queue(server, cq, nullptr);
97 GPR_ASSERT(grpc_server_add_http2_port(server, server_addr, creds));
98 grpc_server_credentials_release(creds);
99
100 grpc_server_start(server);
101
102 return server;
103 }
104
client_create(const char * server_addr,grpc_tls_certificate_provider ** client_provider,grpc_tls_certificate_verifier ** verifier)105 grpc_channel* client_create(const char* server_addr,
106 grpc_tls_certificate_provider** client_provider,
107 grpc_tls_certificate_verifier** verifier) {
108 std::string ca_cert = grpc_core::testing::GetFileContents(CA_CERT_PATH);
109 std::string client_cert =
110 grpc_core::testing::GetFileContents(CLIENT_CERT_PATH);
111 std::string client_key = grpc_core::testing::GetFileContents(CLIENT_KEY_PATH);
112
113 grpc_tls_credentials_options* options = grpc_tls_credentials_options_create();
114 // Set credential provider.
115 grpc_tls_identity_pairs* client_pairs = grpc_tls_identity_pairs_create();
116 grpc_tls_identity_pairs_add_pair(client_pairs, client_key.c_str(),
117 client_cert.c_str());
118 *client_provider = grpc_tls_certificate_provider_static_data_create(
119 ca_cert.c_str(), client_pairs);
120
121 grpc_tls_credentials_options_set_certificate_provider(options,
122 *client_provider);
123 grpc_tls_credentials_options_watch_root_certs(options);
124 grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
125 // Set client certificate request type.
126 grpc_tls_credentials_options_set_cert_request_type(
127 options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
128 // Set credential verifier.
129 auto* client_test_verifier =
130 new grpc_core::testing::PeerPropertyExternalVerifier(kCaCertSubject);
131 *verifier = grpc_tls_certificate_verifier_external_create(
132 client_test_verifier->base());
133 grpc_tls_credentials_options_set_certificate_verifier(options, *verifier);
134 grpc_channel_credentials* creds = grpc_tls_credentials_create(options);
135
136 grpc_arg args[] = {
137 grpc_channel_arg_string_create(
138 const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
139 const_cast<char*>("waterzooi.test.google.be")),
140 };
141
142 grpc_channel_args* client_args =
143 grpc_channel_args_copy_and_add(nullptr, args, GPR_ARRAY_SIZE(args));
144
145 grpc_channel* client = grpc_channel_create(server_addr, creds, client_args);
146 GPR_ASSERT(client != nullptr);
147 grpc_channel_credentials_release(creds);
148
149 {
150 grpc_core::ExecCtx exec_ctx;
151 grpc_channel_args_destroy(client_args);
152 }
153
154 return client;
155 }
156
do_round_trip(grpc_completion_queue * cq,grpc_server * server,const char * server_addr)157 void do_round_trip(grpc_completion_queue* cq, grpc_server* server,
158 const char* server_addr) {
159 grpc_tls_certificate_provider* provider = nullptr;
160 grpc_tls_certificate_verifier* verifier = nullptr;
161 grpc_channel* client = client_create(server_addr, &provider, &verifier);
162
163 grpc_core::CqVerifier cqv(cq);
164 grpc_op ops[6];
165 grpc_op* op;
166 grpc_metadata_array initial_metadata_recv;
167 grpc_metadata_array trailing_metadata_recv;
168 grpc_metadata_array request_metadata_recv;
169 grpc_call_details call_details;
170 grpc_status_code status;
171 grpc_call_error error;
172 grpc_slice details;
173 int was_cancelled = 2;
174
175 gpr_timespec deadline = grpc_timeout_seconds_to_deadline(60);
176 grpc_call* c = grpc_channel_create_call(
177 client, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,
178 grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr);
179 GPR_ASSERT(c);
180
181 grpc_metadata_array_init(&initial_metadata_recv);
182 grpc_metadata_array_init(&trailing_metadata_recv);
183 grpc_metadata_array_init(&request_metadata_recv);
184 grpc_call_details_init(&call_details);
185
186 memset(ops, 0, sizeof(ops));
187 op = ops;
188 op->op = GRPC_OP_SEND_INITIAL_METADATA;
189 op->data.send_initial_metadata.count = 0;
190 op->flags = 0;
191 op->reserved = nullptr;
192 op++;
193 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
194 op->flags = 0;
195 op->reserved = nullptr;
196 op++;
197 op->op = GRPC_OP_RECV_INITIAL_METADATA;
198 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
199 op->flags = 0;
200 op->reserved = nullptr;
201 op++;
202 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
203 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
204 op->data.recv_status_on_client.status = &status;
205 op->data.recv_status_on_client.status_details = &details;
206 op->flags = 0;
207 op->reserved = nullptr;
208 op++;
209 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
210 nullptr);
211 GPR_ASSERT(GRPC_CALL_OK == error);
212
213 grpc_call* s;
214 error = grpc_server_request_call(server, &s, &call_details,
215 &request_metadata_recv, cq, cq, tag(101));
216 GPR_ASSERT(GRPC_CALL_OK == error);
217 cqv.Expect(tag(101), true);
218 cqv.Verify();
219
220 memset(ops, 0, sizeof(ops));
221 op = ops;
222 op->op = GRPC_OP_SEND_INITIAL_METADATA;
223 op->data.send_initial_metadata.count = 0;
224 op->flags = 0;
225 op->reserved = nullptr;
226 op++;
227 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
228 op->data.recv_close_on_server.cancelled = &was_cancelled;
229 op->flags = 0;
230 op->reserved = nullptr;
231 op++;
232 op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
233 op->data.send_status_from_server.trailing_metadata_count = 0;
234 op->data.send_status_from_server.status = GRPC_STATUS_OK;
235 op->flags = 0;
236 op->reserved = nullptr;
237 op++;
238 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
239 nullptr);
240 GPR_ASSERT(GRPC_CALL_OK == error);
241
242 cqv.Expect(tag(103), true);
243 cqv.Expect(tag(1), true);
244 cqv.Verify();
245
246 grpc_metadata_array_destroy(&initial_metadata_recv);
247 grpc_metadata_array_destroy(&trailing_metadata_recv);
248 grpc_metadata_array_destroy(&request_metadata_recv);
249 grpc_call_details_destroy(&call_details);
250
251 grpc_call_unref(c);
252 grpc_call_unref(s);
253
254 grpc_channel_destroy(client);
255 grpc_tls_certificate_provider_release(provider);
256 grpc_tls_certificate_verifier_release(verifier);
257 }
258
drain_cq(grpc_completion_queue * cq)259 void drain_cq(grpc_completion_queue* cq) {
260 grpc_event ev;
261 do {
262 ev = grpc_completion_queue_next(cq, five_seconds_time(), nullptr);
263 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
264 }
265
TEST(H2TlsPeerPropertyExternalVerifier,PeerPropertyExternalVerifierTest)266 TEST(H2TlsPeerPropertyExternalVerifier, PeerPropertyExternalVerifierTest) {
267 int port = grpc_pick_unused_port_or_die();
268
269 std::string server_addr = grpc_core::JoinHostPort("localhost", port);
270
271 grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
272
273 grpc_tls_certificate_provider* provider = nullptr;
274 grpc_tls_certificate_verifier* verifier = nullptr;
275 grpc_server* server =
276 server_create(cq, server_addr.c_str(), &provider, &verifier);
277
278 do_round_trip(cq, server, server_addr.c_str());
279
280 GPR_ASSERT(grpc_completion_queue_next(
281 cq, grpc_timeout_milliseconds_to_deadline(100), nullptr)
282 .type == GRPC_QUEUE_TIMEOUT);
283
284 grpc_server_shutdown_and_notify(server, cq, tag(1000));
285 grpc_event ev;
286 do {
287 ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
288 nullptr);
289 } while (ev.type != GRPC_OP_COMPLETE || ev.tag != tag(1000));
290 grpc_server_destroy(server);
291 grpc_tls_certificate_provider_release(provider);
292 grpc_tls_certificate_verifier_release(verifier);
293
294 grpc_completion_queue_shutdown(cq);
295 drain_cq(cq);
296 grpc_completion_queue_destroy(cq);
297 }
298
299 } // namespace
300 } // namespace testing
301 } // namespace grpc
302
main(int argc,char ** argv)303 int main(int argc, char** argv) {
304 grpc::testing::TestEnvironment env(&argc, argv);
305 grpc_core::ConfigVars::Overrides overrides;
306 overrides.default_ssl_roots_file_path = CA_CERT_PATH;
307 grpc_core::ConfigVars::SetOverrides(overrides);
308 grpc_init();
309 ::testing::InitGoogleTest(&argc, argv);
310 int ret = RUN_ALL_TESTS();
311 grpc_shutdown();
312
313 return ret;
314 }
315