1 /*
2 *
3 * Copyright 2015 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
19 #include <grpc/support/port_platform.h>
20
21 #include "src/core/lib/security/security_connector/security_connector.h"
22
23 #include <stdbool.h>
24
25 #include <grpc/slice_buffer.h>
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/log.h>
28 #include <grpc/support/string_util.h>
29
30 #include "src/core/ext/transport/chttp2/alpn/alpn.h"
31 #include "src/core/lib/channel/channel_args.h"
32 #include "src/core/lib/channel/handshaker.h"
33 #include "src/core/lib/gpr/env.h"
34 #include "src/core/lib/gpr/host_port.h"
35 #include "src/core/lib/gpr/string.h"
36 #include "src/core/lib/iomgr/load_file.h"
37 #include "src/core/lib/security/context/security_context.h"
38 #include "src/core/lib/security/credentials/credentials.h"
39 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
40 #include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
41 #include "src/core/lib/security/security_connector/load_system_roots.h"
42 #include "src/core/lib/security/transport/secure_endpoint.h"
43 #include "src/core/lib/security/transport/security_handshaker.h"
44 #include "src/core/lib/security/transport/target_authority_table.h"
45 #include "src/core/tsi/fake_transport_security.h"
46 #include "src/core/tsi/ssl_transport_security.h"
47
48 grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount(
49 false, "security_connector_refcount");
50
51 /* -- Constants. -- */
52
53 #ifndef INSTALL_PREFIX
54 static const char* installed_roots_path = "/usr/share/grpc/roots.pem";
55 #else
56 static const char* installed_roots_path =
57 INSTALL_PREFIX "/share/grpc/roots.pem";
58 #endif
59
60 /** Environment variable used as a flag to enable/disable loading system root
61 certificates from the OS trust store. */
62 #ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR
63 #define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS"
64 #endif
65
66 #ifndef TSI_OPENSSL_ALPN_SUPPORT
67 #define TSI_OPENSSL_ALPN_SUPPORT 1
68 #endif
69
70 /* -- Overridden default roots. -- */
71
72 static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr;
73
grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb)74 void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
75 ssl_roots_override_cb = cb;
76 }
77
78 /* -- Cipher suites. -- */
79
80 /* Defines the cipher suites that we accept by default. All these cipher suites
81 are compliant with HTTP2. */
82 #define GRPC_SSL_CIPHER_SUITES \
83 "ECDHE-ECDSA-AES128-GCM-SHA256:" \
84 "ECDHE-ECDSA-AES256-GCM-SHA384:" \
85 "ECDHE-RSA-AES128-GCM-SHA256:" \
86 "ECDHE-RSA-AES256-GCM-SHA384"
87
88 static gpr_once cipher_suites_once = GPR_ONCE_INIT;
89 static const char* cipher_suites = nullptr;
90
init_cipher_suites(void)91 static void init_cipher_suites(void) {
92 char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES");
93 cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES;
94 }
95
ssl_cipher_suites(void)96 static const char* ssl_cipher_suites(void) {
97 gpr_once_init(&cipher_suites_once, init_cipher_suites);
98 return cipher_suites;
99 }
100
101 /* -- Common methods. -- */
102
103 /* Returns the first property with that name. */
tsi_peer_get_property_by_name(const tsi_peer * peer,const char * name)104 const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer,
105 const char* name) {
106 size_t i;
107 if (peer == nullptr) return nullptr;
108 for (i = 0; i < peer->property_count; i++) {
109 const tsi_peer_property* property = &peer->properties[i];
110 if (name == nullptr && property->name == nullptr) {
111 return property;
112 }
113 if (name != nullptr && property->name != nullptr &&
114 strcmp(property->name, name) == 0) {
115 return property;
116 }
117 }
118 return nullptr;
119 }
120
grpc_channel_security_connector_add_handshakers(grpc_channel_security_connector * connector,grpc_handshake_manager * handshake_mgr)121 void grpc_channel_security_connector_add_handshakers(
122 grpc_channel_security_connector* connector,
123 grpc_handshake_manager* handshake_mgr) {
124 if (connector != nullptr) {
125 connector->add_handshakers(connector, handshake_mgr);
126 }
127 }
128
grpc_server_security_connector_add_handshakers(grpc_server_security_connector * connector,grpc_handshake_manager * handshake_mgr)129 void grpc_server_security_connector_add_handshakers(
130 grpc_server_security_connector* connector,
131 grpc_handshake_manager* handshake_mgr) {
132 if (connector != nullptr) {
133 connector->add_handshakers(connector, handshake_mgr);
134 }
135 }
136
grpc_security_connector_check_peer(grpc_security_connector * sc,tsi_peer peer,grpc_auth_context ** auth_context,grpc_closure * on_peer_checked)137 void grpc_security_connector_check_peer(grpc_security_connector* sc,
138 tsi_peer peer,
139 grpc_auth_context** auth_context,
140 grpc_closure* on_peer_checked) {
141 if (sc == nullptr) {
142 GRPC_CLOSURE_SCHED(on_peer_checked,
143 GRPC_ERROR_CREATE_FROM_STATIC_STRING(
144 "cannot check peer -- no security connector"));
145 tsi_peer_destruct(&peer);
146 } else {
147 sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked);
148 }
149 }
150
grpc_security_connector_cmp(grpc_security_connector * sc,grpc_security_connector * other)151 int grpc_security_connector_cmp(grpc_security_connector* sc,
152 grpc_security_connector* other) {
153 if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other);
154 int c = GPR_ICMP(sc->vtable, other->vtable);
155 if (c != 0) return c;
156 return sc->vtable->cmp(sc, other);
157 }
158
grpc_channel_security_connector_cmp(grpc_channel_security_connector * sc1,grpc_channel_security_connector * sc2)159 int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1,
160 grpc_channel_security_connector* sc2) {
161 GPR_ASSERT(sc1->channel_creds != nullptr);
162 GPR_ASSERT(sc2->channel_creds != nullptr);
163 int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds);
164 if (c != 0) return c;
165 c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds);
166 if (c != 0) return c;
167 c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host);
168 if (c != 0) return c;
169 c = GPR_ICMP((void*)sc1->cancel_check_call_host,
170 (void*)sc2->cancel_check_call_host);
171 if (c != 0) return c;
172 return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
173 }
174
grpc_server_security_connector_cmp(grpc_server_security_connector * sc1,grpc_server_security_connector * sc2)175 int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
176 grpc_server_security_connector* sc2) {
177 GPR_ASSERT(sc1->server_creds != nullptr);
178 GPR_ASSERT(sc2->server_creds != nullptr);
179 int c = GPR_ICMP(sc1->server_creds, sc2->server_creds);
180 if (c != 0) return c;
181 return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
182 }
183
grpc_channel_security_connector_check_call_host(grpc_channel_security_connector * sc,const char * host,grpc_auth_context * auth_context,grpc_closure * on_call_host_checked,grpc_error ** error)184 bool grpc_channel_security_connector_check_call_host(
185 grpc_channel_security_connector* sc, const char* host,
186 grpc_auth_context* auth_context, grpc_closure* on_call_host_checked,
187 grpc_error** error) {
188 if (sc == nullptr || sc->check_call_host == nullptr) {
189 *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
190 "cannot check call host -- no security connector");
191 return true;
192 }
193 return sc->check_call_host(sc, host, auth_context, on_call_host_checked,
194 error);
195 }
196
grpc_channel_security_connector_cancel_check_call_host(grpc_channel_security_connector * sc,grpc_closure * on_call_host_checked,grpc_error * error)197 void grpc_channel_security_connector_cancel_check_call_host(
198 grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
199 grpc_error* error) {
200 if (sc == nullptr || sc->cancel_check_call_host == nullptr) {
201 GRPC_ERROR_UNREF(error);
202 return;
203 }
204 sc->cancel_check_call_host(sc, on_call_host_checked, error);
205 }
206
207 #ifndef NDEBUG
grpc_security_connector_ref(grpc_security_connector * sc,const char * file,int line,const char * reason)208 grpc_security_connector* grpc_security_connector_ref(
209 grpc_security_connector* sc, const char* file, int line,
210 const char* reason) {
211 if (sc == nullptr) return nullptr;
212 if (grpc_trace_security_connector_refcount.enabled()) {
213 gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
214 gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
215 "SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
216 val, val + 1, reason);
217 }
218 #else
219 grpc_security_connector* grpc_security_connector_ref(
220 grpc_security_connector* sc) {
221 if (sc == nullptr) return nullptr;
222 #endif
223 gpr_ref(&sc->refcount);
224 return sc;
225 }
226
227 #ifndef NDEBUG
228 void grpc_security_connector_unref(grpc_security_connector* sc,
229 const char* file, int line,
230 const char* reason) {
231 if (sc == nullptr) return;
232 if (grpc_trace_security_connector_refcount.enabled()) {
233 gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
234 gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
235 "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
236 val, val - 1, reason);
237 }
238 #else
239 void grpc_security_connector_unref(grpc_security_connector* sc) {
240 if (sc == nullptr) return;
241 #endif
242 if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
243 }
244
245 static void connector_arg_destroy(void* p) {
246 GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p,
247 "connector_arg_destroy");
248 }
249
250 static void* connector_arg_copy(void* p) {
251 return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p,
252 "connector_arg_copy");
253 }
254
255 static int connector_cmp(void* a, void* b) {
256 return grpc_security_connector_cmp(static_cast<grpc_security_connector*>(a),
257 static_cast<grpc_security_connector*>(b));
258 }
259
260 static const grpc_arg_pointer_vtable connector_arg_vtable = {
261 connector_arg_copy, connector_arg_destroy, connector_cmp};
262
263 grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc) {
264 return grpc_channel_arg_pointer_create((char*)GRPC_ARG_SECURITY_CONNECTOR, sc,
265 &connector_arg_vtable);
266 }
267
268 grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg) {
269 if (strcmp(arg->key, GRPC_ARG_SECURITY_CONNECTOR)) return nullptr;
270 if (arg->type != GRPC_ARG_POINTER) {
271 gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
272 GRPC_ARG_SECURITY_CONNECTOR);
273 return nullptr;
274 }
275 return static_cast<grpc_security_connector*>(arg->value.pointer.p);
276 }
277
278 grpc_security_connector* grpc_security_connector_find_in_args(
279 const grpc_channel_args* args) {
280 size_t i;
281 if (args == nullptr) return nullptr;
282 for (i = 0; i < args->num_args; i++) {
283 grpc_security_connector* sc =
284 grpc_security_connector_from_arg(&args->args[i]);
285 if (sc != nullptr) return sc;
286 }
287 return nullptr;
288 }
289
290 static tsi_client_certificate_request_type
291 get_tsi_client_certificate_request_type(
292 grpc_ssl_client_certificate_request_type grpc_request_type) {
293 switch (grpc_request_type) {
294 case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
295 return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
296
297 case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
298 return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
299
300 case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
301 return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
302
303 case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
304 return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
305
306 case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
307 return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
308
309 default:
310 return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
311 }
312 }
313
314 /* -- Fake implementation. -- */
315
316 typedef struct {
317 grpc_channel_security_connector base;
318 char* target;
319 char* expected_targets;
320 bool is_lb_channel;
321 char* target_name_override;
322 } grpc_fake_channel_security_connector;
323
324 static void fake_channel_destroy(grpc_security_connector* sc) {
325 grpc_fake_channel_security_connector* c =
326 reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
327 grpc_call_credentials_unref(c->base.request_metadata_creds);
328 gpr_free(c->target);
329 gpr_free(c->expected_targets);
330 gpr_free(c->target_name_override);
331 gpr_free(c);
332 }
333
334 static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); }
335
336 static bool fake_check_target(const char* target_type, const char* target,
337 const char* set_str) {
338 GPR_ASSERT(target_type != nullptr);
339 GPR_ASSERT(target != nullptr);
340 char** set = nullptr;
341 size_t set_size = 0;
342 gpr_string_split(set_str, ",", &set, &set_size);
343 bool found = false;
344 for (size_t i = 0; i < set_size; ++i) {
345 if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true;
346 }
347 for (size_t i = 0; i < set_size; ++i) {
348 gpr_free(set[i]);
349 }
350 gpr_free(set);
351 return found;
352 }
353
354 static void fake_secure_name_check(const char* target,
355 const char* expected_targets,
356 bool is_lb_channel) {
357 if (expected_targets == nullptr) return;
358 char** lbs_and_backends = nullptr;
359 size_t lbs_and_backends_size = 0;
360 bool success = false;
361 gpr_string_split(expected_targets, ";", &lbs_and_backends,
362 &lbs_and_backends_size);
363 if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) {
364 gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'",
365 expected_targets);
366 goto done;
367 }
368 if (is_lb_channel) {
369 if (lbs_and_backends_size != 2) {
370 gpr_log(GPR_ERROR,
371 "Invalid expected targets arg value: '%s'. Expectations for LB "
372 "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...",
373 expected_targets);
374 goto done;
375 }
376 if (!fake_check_target("LB", target, lbs_and_backends[1])) {
377 gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'",
378 target, lbs_and_backends[1]);
379 goto done;
380 }
381 success = true;
382 } else {
383 if (!fake_check_target("Backend", target, lbs_and_backends[0])) {
384 gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'",
385 target, lbs_and_backends[0]);
386 goto done;
387 }
388 success = true;
389 }
390 done:
391 for (size_t i = 0; i < lbs_and_backends_size; ++i) {
392 gpr_free(lbs_and_backends[i]);
393 }
394 gpr_free(lbs_and_backends);
395 if (!success) abort();
396 }
397
398 static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer,
399 grpc_auth_context** auth_context,
400 grpc_closure* on_peer_checked) {
401 const char* prop_name;
402 grpc_error* error = GRPC_ERROR_NONE;
403 *auth_context = nullptr;
404 if (peer.property_count != 1) {
405 error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
406 "Fake peers should only have 1 property.");
407 goto end;
408 }
409 prop_name = peer.properties[0].name;
410 if (prop_name == nullptr ||
411 strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
412 char* msg;
413 gpr_asprintf(&msg, "Unexpected property in fake peer: %s.",
414 prop_name == nullptr ? "<EMPTY>" : prop_name);
415 error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
416 gpr_free(msg);
417 goto end;
418 }
419 if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
420 peer.properties[0].value.length)) {
421 error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
422 "Invalid value for cert type property.");
423 goto end;
424 }
425 *auth_context = grpc_auth_context_create(nullptr);
426 grpc_auth_context_add_cstring_property(
427 *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
428 GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
429 end:
430 GRPC_CLOSURE_SCHED(on_peer_checked, error);
431 tsi_peer_destruct(&peer);
432 }
433
434 static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer,
435 grpc_auth_context** auth_context,
436 grpc_closure* on_peer_checked) {
437 fake_check_peer(sc, peer, auth_context, on_peer_checked);
438 grpc_fake_channel_security_connector* c =
439 reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
440 fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel);
441 }
442
443 static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer,
444 grpc_auth_context** auth_context,
445 grpc_closure* on_peer_checked) {
446 fake_check_peer(sc, peer, auth_context, on_peer_checked);
447 }
448
449 static int fake_channel_cmp(grpc_security_connector* sc1,
450 grpc_security_connector* sc2) {
451 grpc_fake_channel_security_connector* c1 =
452 reinterpret_cast<grpc_fake_channel_security_connector*>(sc1);
453 grpc_fake_channel_security_connector* c2 =
454 reinterpret_cast<grpc_fake_channel_security_connector*>(sc2);
455 int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
456 if (c != 0) return c;
457 c = strcmp(c1->target, c2->target);
458 if (c != 0) return c;
459 if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) {
460 c = GPR_ICMP(c1->expected_targets, c2->expected_targets);
461 } else {
462 c = strcmp(c1->expected_targets, c2->expected_targets);
463 }
464 if (c != 0) return c;
465 return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel);
466 }
467
468 static int fake_server_cmp(grpc_security_connector* sc1,
469 grpc_security_connector* sc2) {
470 return grpc_server_security_connector_cmp(
471 reinterpret_cast<grpc_server_security_connector*>(sc1),
472 reinterpret_cast<grpc_server_security_connector*>(sc2));
473 }
474
475 static bool fake_channel_check_call_host(grpc_channel_security_connector* sc,
476 const char* host,
477 grpc_auth_context* auth_context,
478 grpc_closure* on_call_host_checked,
479 grpc_error** error) {
480 grpc_fake_channel_security_connector* c =
481 reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
482 char* authority_hostname = nullptr;
483 char* authority_ignored_port = nullptr;
484 char* target_hostname = nullptr;
485 char* target_ignored_port = nullptr;
486 gpr_split_host_port(host, &authority_hostname, &authority_ignored_port);
487 gpr_split_host_port(c->target, &target_hostname, &target_ignored_port);
488 if (c->target_name_override != nullptr) {
489 char* fake_security_target_name_override_hostname = nullptr;
490 char* fake_security_target_name_override_ignored_port = nullptr;
491 gpr_split_host_port(c->target_name_override,
492 &fake_security_target_name_override_hostname,
493 &fake_security_target_name_override_ignored_port);
494 if (strcmp(authority_hostname,
495 fake_security_target_name_override_hostname) != 0) {
496 gpr_log(GPR_ERROR,
497 "Authority (host) '%s' != Fake Security Target override '%s'",
498 host, fake_security_target_name_override_hostname);
499 abort();
500 }
501 gpr_free(fake_security_target_name_override_hostname);
502 gpr_free(fake_security_target_name_override_ignored_port);
503 } else if (strcmp(authority_hostname, target_hostname) != 0) {
504 gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'",
505 authority_hostname, target_hostname);
506 abort();
507 }
508 gpr_free(authority_hostname);
509 gpr_free(authority_ignored_port);
510 gpr_free(target_hostname);
511 gpr_free(target_ignored_port);
512 return true;
513 }
514
515 static void fake_channel_cancel_check_call_host(
516 grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
517 grpc_error* error) {
518 GRPC_ERROR_UNREF(error);
519 }
520
521 static void fake_channel_add_handshakers(
522 grpc_channel_security_connector* sc,
523 grpc_handshake_manager* handshake_mgr) {
524 grpc_handshake_manager_add(
525 handshake_mgr,
526 grpc_security_handshaker_create(
527 tsi_create_fake_handshaker(true /* is_client */), &sc->base));
528 }
529
530 static void fake_server_add_handshakers(grpc_server_security_connector* sc,
531 grpc_handshake_manager* handshake_mgr) {
532 grpc_handshake_manager_add(
533 handshake_mgr,
534 grpc_security_handshaker_create(
535 tsi_create_fake_handshaker(false /* is_client */), &sc->base));
536 }
537
538 static grpc_security_connector_vtable fake_channel_vtable = {
539 fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp};
540
541 static grpc_security_connector_vtable fake_server_vtable = {
542 fake_server_destroy, fake_server_check_peer, fake_server_cmp};
543
544 grpc_channel_security_connector* grpc_fake_channel_security_connector_create(
545 grpc_channel_credentials* channel_creds,
546 grpc_call_credentials* request_metadata_creds, const char* target,
547 const grpc_channel_args* args) {
548 grpc_fake_channel_security_connector* c =
549 static_cast<grpc_fake_channel_security_connector*>(
550 gpr_zalloc(sizeof(*c)));
551 gpr_ref_init(&c->base.base.refcount, 1);
552 c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
553 c->base.base.vtable = &fake_channel_vtable;
554 c->base.channel_creds = channel_creds;
555 c->base.request_metadata_creds =
556 grpc_call_credentials_ref(request_metadata_creds);
557 c->base.check_call_host = fake_channel_check_call_host;
558 c->base.cancel_check_call_host = fake_channel_cancel_check_call_host;
559 c->base.add_handshakers = fake_channel_add_handshakers;
560 c->target = gpr_strdup(target);
561 const char* expected_targets = grpc_fake_transport_get_expected_targets(args);
562 c->expected_targets = gpr_strdup(expected_targets);
563 c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
564 const grpc_arg* target_name_override_arg =
565 grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
566 if (target_name_override_arg != nullptr) {
567 c->target_name_override =
568 gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg));
569 }
570 return &c->base;
571 }
572
573 grpc_server_security_connector* grpc_fake_server_security_connector_create(
574 grpc_server_credentials* server_creds) {
575 grpc_server_security_connector* c =
576 static_cast<grpc_server_security_connector*>(
577 gpr_zalloc(sizeof(grpc_server_security_connector)));
578 gpr_ref_init(&c->base.refcount, 1);
579 c->base.vtable = &fake_server_vtable;
580 c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
581 c->server_creds = server_creds;
582 c->add_handshakers = fake_server_add_handshakers;
583 return c;
584 }
585
586 /* --- Ssl implementation. --- */
587
588 grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) {
589 tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity);
590 return reinterpret_cast<grpc_ssl_session_cache*>(cache);
591 }
592
593 void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) {
594 tsi_ssl_session_cache* tsi_cache =
595 reinterpret_cast<tsi_ssl_session_cache*>(cache);
596 tsi_ssl_session_cache_unref(tsi_cache);
597 }
598
599 static void* grpc_ssl_session_cache_arg_copy(void* p) {
600 tsi_ssl_session_cache* tsi_cache =
601 reinterpret_cast<tsi_ssl_session_cache*>(p);
602 // destroy call below will unref the pointer.
603 tsi_ssl_session_cache_ref(tsi_cache);
604 return p;
605 }
606
607 static void grpc_ssl_session_cache_arg_destroy(void* p) {
608 tsi_ssl_session_cache* tsi_cache =
609 reinterpret_cast<tsi_ssl_session_cache*>(p);
610 tsi_ssl_session_cache_unref(tsi_cache);
611 }
612
613 static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) {
614 return GPR_ICMP(p, q);
615 }
616
617 grpc_arg grpc_ssl_session_cache_create_channel_arg(
618 grpc_ssl_session_cache* cache) {
619 static const grpc_arg_pointer_vtable vtable = {
620 grpc_ssl_session_cache_arg_copy,
621 grpc_ssl_session_cache_arg_destroy,
622 grpc_ssl_session_cache_arg_cmp,
623 };
624 return grpc_channel_arg_pointer_create(
625 const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable);
626 }
627
628 typedef struct {
629 grpc_channel_security_connector base;
630 tsi_ssl_client_handshaker_factory* client_handshaker_factory;
631 char* target_name;
632 char* overridden_target_name;
633 const verify_peer_options* verify_options;
634 } grpc_ssl_channel_security_connector;
635
636 typedef struct {
637 grpc_server_security_connector base;
638 tsi_ssl_server_handshaker_factory* server_handshaker_factory;
639 } grpc_ssl_server_security_connector;
640
641 static bool server_connector_has_cert_config_fetcher(
642 grpc_ssl_server_security_connector* c) {
643 GPR_ASSERT(c != nullptr);
644 grpc_ssl_server_credentials* server_creds =
645 reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds);
646 GPR_ASSERT(server_creds != nullptr);
647 return server_creds->certificate_config_fetcher.cb != nullptr;
648 }
649
650 static void ssl_channel_destroy(grpc_security_connector* sc) {
651 grpc_ssl_channel_security_connector* c =
652 reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
653 grpc_channel_credentials_unref(c->base.channel_creds);
654 grpc_call_credentials_unref(c->base.request_metadata_creds);
655 tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory);
656 c->client_handshaker_factory = nullptr;
657 if (c->target_name != nullptr) gpr_free(c->target_name);
658 if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name);
659 gpr_free(sc);
660 }
661
662 static void ssl_server_destroy(grpc_security_connector* sc) {
663 grpc_ssl_server_security_connector* c =
664 reinterpret_cast<grpc_ssl_server_security_connector*>(sc);
665 grpc_server_credentials_unref(c->base.server_creds);
666 tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory);
667 c->server_handshaker_factory = nullptr;
668 gpr_free(sc);
669 }
670
671 static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc,
672 grpc_handshake_manager* handshake_mgr) {
673 grpc_ssl_channel_security_connector* c =
674 reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
675 // Instantiate TSI handshaker.
676 tsi_handshaker* tsi_hs = nullptr;
677 tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
678 c->client_handshaker_factory,
679 c->overridden_target_name != nullptr ? c->overridden_target_name
680 : c->target_name,
681 &tsi_hs);
682 if (result != TSI_OK) {
683 gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
684 tsi_result_to_string(result));
685 return;
686 }
687 // Create handshakers.
688 grpc_handshake_manager_add(
689 handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
690 }
691
692 static const char** fill_alpn_protocol_strings(size_t* num_alpn_protocols) {
693 GPR_ASSERT(num_alpn_protocols != nullptr);
694 *num_alpn_protocols = grpc_chttp2_num_alpn_versions();
695 const char** alpn_protocol_strings = static_cast<const char**>(
696 gpr_malloc(sizeof(const char*) * (*num_alpn_protocols)));
697 for (size_t i = 0; i < *num_alpn_protocols; i++) {
698 alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
699 }
700 return alpn_protocol_strings;
701 }
702
703 /* Attempts to replace the server_handshaker_factory with a new factory using
704 * the provided grpc_ssl_server_certificate_config. Should new factory creation
705 * fail, the existing factory will not be replaced. Returns true on success (new
706 * factory created). */
707 static bool try_replace_server_handshaker_factory(
708 grpc_ssl_server_security_connector* sc,
709 const grpc_ssl_server_certificate_config* config) {
710 if (config == nullptr) {
711 gpr_log(GPR_ERROR,
712 "Server certificate config callback returned invalid (NULL) "
713 "config.");
714 return false;
715 }
716 gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
717
718 size_t num_alpn_protocols = 0;
719 const char** alpn_protocol_strings =
720 fill_alpn_protocol_strings(&num_alpn_protocols);
721 tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
722 config->pem_key_cert_pairs, config->num_key_cert_pairs);
723 tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr;
724 grpc_ssl_server_credentials* server_creds =
725 reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds);
726 tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
727 cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
728 get_tsi_client_certificate_request_type(
729 server_creds->config.client_certificate_request),
730 ssl_cipher_suites(), alpn_protocol_strings,
731 static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory);
732 gpr_free(cert_pairs);
733 gpr_free((void*)alpn_protocol_strings);
734
735 if (result != TSI_OK) {
736 gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
737 tsi_result_to_string(result));
738 return false;
739 }
740 tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory);
741 sc->server_handshaker_factory = new_handshaker_factory;
742 return true;
743 }
744
745 /* Attempts to fetch the server certificate config if a callback is available.
746 * Current certificate config will continue to be used if the callback returns
747 * an error. Returns true if new credentials were sucessfully loaded. */
748 static bool try_fetch_ssl_server_credentials(
749 grpc_ssl_server_security_connector* sc) {
750 grpc_ssl_server_certificate_config* certificate_config = nullptr;
751 bool status;
752
753 GPR_ASSERT(sc != nullptr);
754 if (!server_connector_has_cert_config_fetcher(sc)) return false;
755
756 grpc_ssl_server_credentials* server_creds =
757 reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds);
758 grpc_ssl_certificate_config_reload_status cb_result =
759 server_creds->certificate_config_fetcher.cb(
760 server_creds->certificate_config_fetcher.user_data,
761 &certificate_config);
762 if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
763 gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
764 status = false;
765 } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
766 status = try_replace_server_handshaker_factory(sc, certificate_config);
767 } else {
768 // Log error, continue using previously-loaded credentials.
769 gpr_log(GPR_ERROR,
770 "Failed fetching new server credentials, continuing to "
771 "use previously-loaded credentials.");
772 status = false;
773 }
774
775 if (certificate_config != nullptr) {
776 grpc_ssl_server_certificate_config_destroy(certificate_config);
777 }
778 return status;
779 }
780
781 static void ssl_server_add_handshakers(grpc_server_security_connector* sc,
782 grpc_handshake_manager* handshake_mgr) {
783 grpc_ssl_server_security_connector* c =
784 reinterpret_cast<grpc_ssl_server_security_connector*>(sc);
785 // Instantiate TSI handshaker.
786 try_fetch_ssl_server_credentials(c);
787 tsi_handshaker* tsi_hs = nullptr;
788 tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
789 c->server_handshaker_factory, &tsi_hs);
790 if (result != TSI_OK) {
791 gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
792 tsi_result_to_string(result));
793 return;
794 }
795 // Create handshakers.
796 grpc_handshake_manager_add(
797 handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
798 }
799
800 int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
801 char* allocated_name = nullptr;
802 int r;
803
804 char* ignored_port;
805 gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
806 gpr_free(ignored_port);
807 peer_name = allocated_name;
808 if (!peer_name) return 0;
809
810 // IPv6 zone-id should not be included in comparisons.
811 char* const zone_id = strchr(allocated_name, '%');
812 if (zone_id != nullptr) *zone_id = '\0';
813
814 r = tsi_ssl_peer_matches_name(peer, peer_name);
815 gpr_free(allocated_name);
816 return r;
817 }
818
819 grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) {
820 size_t i;
821 grpc_auth_context* ctx = nullptr;
822 const char* peer_identity_property_name = nullptr;
823
824 /* The caller has checked the certificate type property. */
825 GPR_ASSERT(peer->property_count >= 1);
826 ctx = grpc_auth_context_create(nullptr);
827 grpc_auth_context_add_cstring_property(
828 ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
829 GRPC_SSL_TRANSPORT_SECURITY_TYPE);
830 for (i = 0; i < peer->property_count; i++) {
831 const tsi_peer_property* prop = &peer->properties[i];
832 if (prop->name == nullptr) continue;
833 if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
834 /* If there is no subject alt name, have the CN as the identity. */
835 if (peer_identity_property_name == nullptr) {
836 peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
837 }
838 grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME,
839 prop->value.data, prop->value.length);
840 } else if (strcmp(prop->name,
841 TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
842 peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
843 grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME,
844 prop->value.data, prop->value.length);
845 } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) {
846 grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME,
847 prop->value.data, prop->value.length);
848 } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) {
849 grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY,
850 prop->value.data, prop->value.length);
851 }
852 }
853 if (peer_identity_property_name != nullptr) {
854 GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
855 ctx, peer_identity_property_name) == 1);
856 }
857 return ctx;
858 }
859
860 static grpc_error* ssl_check_peer(grpc_security_connector* sc,
861 const char* peer_name, const tsi_peer* peer,
862 grpc_auth_context** auth_context) {
863 #if TSI_OPENSSL_ALPN_SUPPORT
864 /* Check the ALPN if ALPN is supported. */
865 const tsi_peer_property* p =
866 tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
867 if (p == nullptr) {
868 return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
869 "Cannot check peer: missing selected ALPN property.");
870 }
871 if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
872 return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
873 "Cannot check peer: invalid ALPN value.");
874 }
875 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
876 /* Check the peer name if specified. */
877 if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
878 char* msg;
879 gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
880 grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
881 gpr_free(msg);
882 return error;
883 }
884 *auth_context = grpc_ssl_peer_to_auth_context(peer);
885 return GRPC_ERROR_NONE;
886 }
887
888 static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer,
889 grpc_auth_context** auth_context,
890 grpc_closure* on_peer_checked) {
891 grpc_ssl_channel_security_connector* c =
892 reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
893 const char* target_name = c->overridden_target_name != nullptr
894 ? c->overridden_target_name
895 : c->target_name;
896 grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context);
897 if (error == GRPC_ERROR_NONE &&
898 c->verify_options->verify_peer_callback != nullptr) {
899 const tsi_peer_property* p =
900 tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
901 if (p == nullptr) {
902 error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
903 "Cannot check peer: missing pem cert property.");
904 } else {
905 char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
906 memcpy(peer_pem, p->value.data, p->value.length);
907 peer_pem[p->value.length] = '\0';
908 int callback_status = c->verify_options->verify_peer_callback(
909 target_name, peer_pem,
910 c->verify_options->verify_peer_callback_userdata);
911 gpr_free(peer_pem);
912 if (callback_status) {
913 char* msg;
914 gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)",
915 callback_status);
916 error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
917 gpr_free(msg);
918 }
919 }
920 }
921 GRPC_CLOSURE_SCHED(on_peer_checked, error);
922 tsi_peer_destruct(&peer);
923 }
924
925 static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer,
926 grpc_auth_context** auth_context,
927 grpc_closure* on_peer_checked) {
928 grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context);
929 tsi_peer_destruct(&peer);
930 GRPC_CLOSURE_SCHED(on_peer_checked, error);
931 }
932
933 static int ssl_channel_cmp(grpc_security_connector* sc1,
934 grpc_security_connector* sc2) {
935 grpc_ssl_channel_security_connector* c1 =
936 reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1);
937 grpc_ssl_channel_security_connector* c2 =
938 reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2);
939 int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
940 if (c != 0) return c;
941 c = strcmp(c1->target_name, c2->target_name);
942 if (c != 0) return c;
943 return (c1->overridden_target_name == nullptr ||
944 c2->overridden_target_name == nullptr)
945 ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name)
946 : strcmp(c1->overridden_target_name, c2->overridden_target_name);
947 }
948
949 static int ssl_server_cmp(grpc_security_connector* sc1,
950 grpc_security_connector* sc2) {
951 return grpc_server_security_connector_cmp(
952 reinterpret_cast<grpc_server_security_connector*>(sc1),
953 reinterpret_cast<grpc_server_security_connector*>(sc2));
954 }
955
956 static void add_shallow_auth_property_to_peer(tsi_peer* peer,
957 const grpc_auth_property* prop,
958 const char* tsi_prop_name) {
959 tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++];
960 tsi_prop->name = const_cast<char*>(tsi_prop_name);
961 tsi_prop->value.data = prop->value;
962 tsi_prop->value.length = prop->value_length;
963 }
964
965 tsi_peer grpc_shallow_peer_from_ssl_auth_context(
966 const grpc_auth_context* auth_context) {
967 size_t max_num_props = 0;
968 grpc_auth_property_iterator it;
969 const grpc_auth_property* prop;
970 tsi_peer peer;
971 memset(&peer, 0, sizeof(peer));
972
973 it = grpc_auth_context_property_iterator(auth_context);
974 while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++;
975
976 if (max_num_props > 0) {
977 peer.properties = static_cast<tsi_peer_property*>(
978 gpr_malloc(max_num_props * sizeof(tsi_peer_property)));
979 it = grpc_auth_context_property_iterator(auth_context);
980 while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) {
981 if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) {
982 add_shallow_auth_property_to_peer(
983 &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY);
984 } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) {
985 add_shallow_auth_property_to_peer(
986 &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
987 } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) {
988 add_shallow_auth_property_to_peer(&peer, prop,
989 TSI_X509_PEM_CERT_PROPERTY);
990 }
991 }
992 }
993 return peer;
994 }
995
996 void grpc_shallow_peer_destruct(tsi_peer* peer) {
997 if (peer->properties != nullptr) gpr_free(peer->properties);
998 }
999
1000 static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc,
1001 const char* host,
1002 grpc_auth_context* auth_context,
1003 grpc_closure* on_call_host_checked,
1004 grpc_error** error) {
1005 grpc_ssl_channel_security_connector* c =
1006 reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
1007 grpc_security_status status = GRPC_SECURITY_ERROR;
1008 tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
1009 if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
1010 /* If the target name was overridden, then the original target_name was
1011 'checked' transitively during the previous peer check at the end of the
1012 handshake. */
1013 if (c->overridden_target_name != nullptr &&
1014 strcmp(host, c->target_name) == 0) {
1015 status = GRPC_SECURITY_OK;
1016 }
1017 if (status != GRPC_SECURITY_OK) {
1018 *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
1019 "call host does not match SSL server name");
1020 }
1021 grpc_shallow_peer_destruct(&peer);
1022 return true;
1023 }
1024
1025 static void ssl_channel_cancel_check_call_host(
1026 grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
1027 grpc_error* error) {
1028 GRPC_ERROR_UNREF(error);
1029 }
1030
1031 static grpc_security_connector_vtable ssl_channel_vtable = {
1032 ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp};
1033
1034 static grpc_security_connector_vtable ssl_server_vtable = {
1035 ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp};
1036
1037 grpc_security_status grpc_ssl_channel_security_connector_create(
1038 grpc_channel_credentials* channel_creds,
1039 grpc_call_credentials* request_metadata_creds,
1040 const grpc_ssl_config* config, const char* target_name,
1041 const char* overridden_target_name,
1042 tsi_ssl_session_cache* ssl_session_cache,
1043 grpc_channel_security_connector** sc) {
1044 tsi_result result = TSI_OK;
1045 grpc_ssl_channel_security_connector* c;
1046 char* port;
1047 bool has_key_cert_pair;
1048 tsi_ssl_client_handshaker_options options;
1049 memset(&options, 0, sizeof(options));
1050 options.alpn_protocols =
1051 fill_alpn_protocol_strings(&options.num_alpn_protocols);
1052
1053 if (config == nullptr || target_name == nullptr) {
1054 gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
1055 goto error;
1056 }
1057 if (config->pem_root_certs == nullptr) {
1058 // Use default root certificates.
1059 options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts();
1060 options.root_store = grpc_core::DefaultSslRootStore::GetRootStore();
1061 if (options.pem_root_certs == nullptr) {
1062 gpr_log(GPR_ERROR, "Could not get default pem root certs.");
1063 goto error;
1064 }
1065 } else {
1066 options.pem_root_certs = config->pem_root_certs;
1067 }
1068 c = static_cast<grpc_ssl_channel_security_connector*>(
1069 gpr_zalloc(sizeof(grpc_ssl_channel_security_connector)));
1070
1071 gpr_ref_init(&c->base.base.refcount, 1);
1072 c->base.base.vtable = &ssl_channel_vtable;
1073 c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
1074 c->base.channel_creds = grpc_channel_credentials_ref(channel_creds);
1075 c->base.request_metadata_creds =
1076 grpc_call_credentials_ref(request_metadata_creds);
1077 c->base.check_call_host = ssl_channel_check_call_host;
1078 c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host;
1079 c->base.add_handshakers = ssl_channel_add_handshakers;
1080 gpr_split_host_port(target_name, &c->target_name, &port);
1081 gpr_free(port);
1082 if (overridden_target_name != nullptr) {
1083 c->overridden_target_name = gpr_strdup(overridden_target_name);
1084 }
1085 c->verify_options = &config->verify_options;
1086
1087 has_key_cert_pair = config->pem_key_cert_pair != nullptr &&
1088 config->pem_key_cert_pair->private_key != nullptr &&
1089 config->pem_key_cert_pair->cert_chain != nullptr;
1090 if (has_key_cert_pair) {
1091 options.pem_key_cert_pair = config->pem_key_cert_pair;
1092 }
1093 options.cipher_suites = ssl_cipher_suites();
1094 options.session_cache = ssl_session_cache;
1095 result = tsi_create_ssl_client_handshaker_factory_with_options(
1096 &options, &c->client_handshaker_factory);
1097 if (result != TSI_OK) {
1098 gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
1099 tsi_result_to_string(result));
1100 ssl_channel_destroy(&c->base.base);
1101 *sc = nullptr;
1102 goto error;
1103 }
1104 *sc = &c->base;
1105 gpr_free((void*)options.alpn_protocols);
1106 return GRPC_SECURITY_OK;
1107
1108 error:
1109 gpr_free((void*)options.alpn_protocols);
1110 return GRPC_SECURITY_ERROR;
1111 }
1112
1113 static grpc_ssl_server_security_connector*
1114 grpc_ssl_server_security_connector_initialize(
1115 grpc_server_credentials* server_creds) {
1116 grpc_ssl_server_security_connector* c =
1117 static_cast<grpc_ssl_server_security_connector*>(
1118 gpr_zalloc(sizeof(grpc_ssl_server_security_connector)));
1119 gpr_ref_init(&c->base.base.refcount, 1);
1120 c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
1121 c->base.base.vtable = &ssl_server_vtable;
1122 c->base.add_handshakers = ssl_server_add_handshakers;
1123 c->base.server_creds = grpc_server_credentials_ref(server_creds);
1124 return c;
1125 }
1126
1127 grpc_security_status grpc_ssl_server_security_connector_create(
1128 grpc_server_credentials* gsc, grpc_server_security_connector** sc) {
1129 tsi_result result = TSI_OK;
1130 grpc_ssl_server_credentials* server_credentials =
1131 reinterpret_cast<grpc_ssl_server_credentials*>(gsc);
1132 grpc_security_status retval = GRPC_SECURITY_OK;
1133
1134 GPR_ASSERT(server_credentials != nullptr);
1135 GPR_ASSERT(sc != nullptr);
1136
1137 grpc_ssl_server_security_connector* c =
1138 grpc_ssl_server_security_connector_initialize(gsc);
1139 if (server_connector_has_cert_config_fetcher(c)) {
1140 // Load initial credentials from certificate_config_fetcher:
1141 if (!try_fetch_ssl_server_credentials(c)) {
1142 gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher.");
1143 retval = GRPC_SECURITY_ERROR;
1144 }
1145 } else {
1146 size_t num_alpn_protocols = 0;
1147 const char** alpn_protocol_strings =
1148 fill_alpn_protocol_strings(&num_alpn_protocols);
1149 result = tsi_create_ssl_server_handshaker_factory_ex(
1150 server_credentials->config.pem_key_cert_pairs,
1151 server_credentials->config.num_key_cert_pairs,
1152 server_credentials->config.pem_root_certs,
1153 get_tsi_client_certificate_request_type(
1154 server_credentials->config.client_certificate_request),
1155 ssl_cipher_suites(), alpn_protocol_strings,
1156 static_cast<uint16_t>(num_alpn_protocols),
1157 &c->server_handshaker_factory);
1158 gpr_free((void*)alpn_protocol_strings);
1159 if (result != TSI_OK) {
1160 gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
1161 tsi_result_to_string(result));
1162 retval = GRPC_SECURITY_ERROR;
1163 }
1164 }
1165
1166 if (retval == GRPC_SECURITY_OK) {
1167 *sc = &c->base;
1168 } else {
1169 if (c != nullptr) ssl_server_destroy(&c->base.base);
1170 if (sc != nullptr) *sc = nullptr;
1171 }
1172 return retval;
1173 }
1174
1175 namespace grpc_core {
1176
1177 tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_;
1178 grpc_slice DefaultSslRootStore::default_pem_root_certs_;
1179
1180 const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() {
1181 InitRootStore();
1182 return default_root_store_;
1183 }
1184
1185 const char* DefaultSslRootStore::GetPemRootCerts() {
1186 InitRootStore();
1187 return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)
1188 ? nullptr
1189 : reinterpret_cast<const char*>
1190 GRPC_SLICE_START_PTR(default_pem_root_certs_);
1191 }
1192
1193 grpc_slice DefaultSslRootStore::ComputePemRootCerts() {
1194 grpc_slice result = grpc_empty_slice();
1195 char* not_use_system_roots_env_value =
1196 gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR);
1197 const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value);
1198 gpr_free(not_use_system_roots_env_value);
1199 // First try to load the roots from the environment.
1200 char* default_root_certs_path =
1201 gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
1202 if (default_root_certs_path != nullptr) {
1203 GRPC_LOG_IF_ERROR("load_file",
1204 grpc_load_file(default_root_certs_path, 1, &result));
1205 gpr_free(default_root_certs_path);
1206 }
1207 // Try overridden roots if needed.
1208 grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL;
1209 if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) {
1210 char* pem_root_certs = nullptr;
1211 ovrd_res = ssl_roots_override_cb(&pem_root_certs);
1212 if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
1213 GPR_ASSERT(pem_root_certs != nullptr);
1214 result = grpc_slice_from_copied_buffer(
1215 pem_root_certs,
1216 strlen(pem_root_certs) + 1); // nullptr terminator.
1217 }
1218 gpr_free(pem_root_certs);
1219 }
1220 // Try loading roots from OS trust store if flag is enabled.
1221 if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) {
1222 result = LoadSystemRootCerts();
1223 }
1224 // Fallback to roots manually shipped with gRPC.
1225 if (GRPC_SLICE_IS_EMPTY(result) &&
1226 ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
1227 GRPC_LOG_IF_ERROR("load_file",
1228 grpc_load_file(installed_roots_path, 1, &result));
1229 }
1230 return result;
1231 }
1232
1233 void DefaultSslRootStore::InitRootStore() {
1234 static gpr_once once = GPR_ONCE_INIT;
1235 gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce);
1236 }
1237
1238 void DefaultSslRootStore::InitRootStoreOnce() {
1239 default_pem_root_certs_ = ComputePemRootCerts();
1240 if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) {
1241 default_root_store_ =
1242 tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>(
1243 GRPC_SLICE_START_PTR(default_pem_root_certs_)));
1244 }
1245 }
1246
1247 } // namespace grpc_core
1248