xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/h2_tls_peer_property_external_verifier_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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