Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include "src/core/security/security_connector.h"
35 :
36 : #include <string.h>
37 :
38 : #include "src/core/security/credentials.h"
39 : #include "src/core/security/handshake.h"
40 : #include "src/core/security/secure_endpoint.h"
41 : #include "src/core/security/security_context.h"
42 : #include "src/core/support/env.h"
43 : #include "src/core/support/file.h"
44 : #include "src/core/support/string.h"
45 : #include "src/core/transport/chttp2/alpn.h"
46 :
47 : #include <grpc/support/alloc.h>
48 : #include <grpc/support/host_port.h>
49 : #include <grpc/support/log.h>
50 : #include <grpc/support/slice_buffer.h>
51 : #include <grpc/support/string_util.h>
52 : #include "src/core/tsi/fake_transport_security.h"
53 : #include "src/core/tsi/ssl_transport_security.h"
54 :
55 : /* -- Constants. -- */
56 :
57 : #ifndef INSTALL_PREFIX
58 : static const char *installed_roots_path = "/usr/share/grpc/roots.pem";
59 : #else
60 : static const char *installed_roots_path =
61 : INSTALL_PREFIX "/share/grpc/roots.pem";
62 : #endif
63 :
64 : /* -- Cipher suites. -- */
65 :
66 : /* Defines the cipher suites that we accept by default. All these cipher suites
67 : are compliant with HTTP2. */
68 : #define GRPC_SSL_CIPHER_SUITES \
69 : "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \
70 : "SHA384:ECDHE-RSA-AES256-GCM-SHA384"
71 :
72 : static gpr_once cipher_suites_once = GPR_ONCE_INIT;
73 : static const char *cipher_suites = NULL;
74 :
75 133 : static void init_cipher_suites(void) {
76 133 : char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES");
77 133 : cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES;
78 133 : }
79 :
80 1144 : static const char *ssl_cipher_suites(void) {
81 1165 : gpr_once_init(&cipher_suites_once, init_cipher_suites);
82 1165 : return cipher_suites;
83 : }
84 :
85 : /* -- Common methods. -- */
86 :
87 : /* Returns the first property with that name. */
88 961 : const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
89 : const char *name) {
90 : size_t i;
91 961 : if (peer == NULL) return NULL;
92 3322 : for (i = 0; i < peer->property_count; i++) {
93 3356 : const tsi_peer_property *property = &peer->properties[i];
94 3356 : if (name == NULL && property->name == NULL) {
95 0 : return property;
96 : }
97 6712 : if (name != NULL && property->name != NULL &&
98 3356 : strcmp(property->name, name) == 0) {
99 961 : return property;
100 : }
101 : }
102 0 : return NULL;
103 : }
104 :
105 704 : void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
106 : grpc_security_connector *connector) {
107 : grpc_security_connector_handshake_list *tmp;
108 704 : if (!connector->is_client_side) {
109 704 : gpr_mu_lock(&connector->mu);
110 1413 : while (connector->handshaking_handshakes) {
111 5 : tmp = connector->handshaking_handshakes;
112 5 : grpc_security_handshake_shutdown(
113 5 : exec_ctx, connector->handshaking_handshakes->handshake);
114 5 : connector->handshaking_handshakes = tmp->next;
115 5 : gpr_free(tmp);
116 : }
117 704 : gpr_mu_unlock(&connector->mu);
118 : }
119 704 : }
120 :
121 1190 : void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
122 : grpc_security_connector *sc,
123 : grpc_endpoint *nonsecure_endpoint,
124 : grpc_security_handshake_done_cb cb,
125 : void *user_data) {
126 1190 : if (sc == NULL || nonsecure_endpoint == NULL) {
127 0 : cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL);
128 : } else {
129 1190 : sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
130 : }
131 1190 : }
132 :
133 1177 : grpc_security_status grpc_security_connector_check_peer(
134 : grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
135 : void *user_data) {
136 1177 : if (sc == NULL) {
137 0 : tsi_peer_destruct(&peer);
138 0 : return GRPC_SECURITY_ERROR;
139 : }
140 1177 : return sc->vtable->check_peer(sc, peer, cb, user_data);
141 : }
142 :
143 152302 : grpc_security_status grpc_channel_security_connector_check_call_host(
144 : grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
145 : const char *host, grpc_security_check_cb cb, void *user_data) {
146 152302 : if (sc == NULL || sc->check_call_host == NULL) return GRPC_SECURITY_ERROR;
147 152302 : return sc->check_call_host(exec_ctx, sc, host, cb, user_data);
148 : }
149 :
150 : #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
151 : grpc_security_connector *grpc_security_connector_ref(
152 : grpc_security_connector *sc, const char *file, int line,
153 : const char *reason) {
154 : if (sc == NULL) return NULL;
155 : gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
156 : "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc,
157 : (int)sc->refcount.count, (int)sc->refcount.count + 1, reason);
158 : #else
159 6220 : grpc_security_connector *grpc_security_connector_ref(
160 : grpc_security_connector *sc) {
161 6220 : if (sc == NULL) return NULL;
162 : #endif
163 6220 : gpr_ref(&sc->refcount);
164 6220 : return sc;
165 : }
166 :
167 : #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
168 : void grpc_security_connector_unref(grpc_security_connector *sc,
169 : const char *file, int line,
170 : const char *reason) {
171 : if (sc == NULL) return;
172 : gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
173 : "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
174 : (int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
175 : #else
176 7569 : void grpc_security_connector_unref(grpc_security_connector *sc) {
177 15138 : if (sc == NULL) return;
178 : #endif
179 7569 : if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
180 : }
181 :
182 3689 : static void connector_pointer_arg_destroy(void *p) {
183 3689 : GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg");
184 3689 : }
185 :
186 3728 : static void *connector_pointer_arg_copy(void *p) {
187 3728 : return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg");
188 : }
189 :
190 717 : grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
191 : grpc_arg result;
192 699 : result.type = GRPC_ARG_POINTER;
193 699 : result.key = GRPC_SECURITY_CONNECTOR_ARG;
194 699 : result.value.pointer.destroy = connector_pointer_arg_destroy;
195 699 : result.value.pointer.copy = connector_pointer_arg_copy;
196 699 : result.value.pointer.p = sc;
197 717 : return result;
198 : }
199 :
200 2737 : grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
201 2737 : if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL;
202 585 : if (arg->type != GRPC_ARG_POINTER) {
203 0 : gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
204 : GRPC_SECURITY_CONNECTOR_ARG);
205 0 : return NULL;
206 : }
207 585 : return arg->value.pointer.p;
208 : }
209 :
210 1302 : grpc_security_connector *grpc_find_security_connector_in_args(
211 : const grpc_channel_args *args) {
212 : size_t i;
213 1302 : if (args == NULL) return NULL;
214 3329 : for (i = 0; i < args->num_args; i++) {
215 2737 : grpc_security_connector *sc =
216 2737 : grpc_security_connector_from_arg(&args->args[i]);
217 2737 : if (sc != NULL) return sc;
218 : }
219 609 : return NULL;
220 : }
221 :
222 : /* -- Fake implementation. -- */
223 :
224 : typedef struct {
225 : grpc_channel_security_connector base;
226 : int call_host_check_is_async;
227 : } grpc_fake_channel_security_connector;
228 :
229 129 : static void fake_channel_destroy(grpc_security_connector *sc) {
230 129 : grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
231 129 : grpc_call_credentials_unref(c->request_metadata_creds);
232 129 : GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
233 129 : gpr_free(sc);
234 129 : }
235 :
236 128 : static void fake_server_destroy(grpc_security_connector *sc) {
237 128 : GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
238 128 : gpr_mu_destroy(&sc->mu);
239 128 : gpr_free(sc);
240 128 : }
241 :
242 214 : static grpc_security_status fake_check_peer(grpc_security_connector *sc,
243 : tsi_peer peer,
244 : grpc_security_check_cb cb,
245 : void *user_data) {
246 : const char *prop_name;
247 214 : grpc_security_status status = GRPC_SECURITY_OK;
248 214 : if (peer.property_count != 1) {
249 0 : gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
250 0 : status = GRPC_SECURITY_ERROR;
251 0 : goto end;
252 : }
253 214 : prop_name = peer.properties[0].name;
254 428 : if (prop_name == NULL ||
255 214 : strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
256 0 : gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
257 : prop_name == NULL ? "<EMPTY>" : prop_name);
258 0 : status = GRPC_SECURITY_ERROR;
259 0 : goto end;
260 : }
261 214 : if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
262 214 : peer.properties[0].value.length)) {
263 0 : gpr_log(GPR_ERROR, "Invalid value for cert type property.");
264 0 : status = GRPC_SECURITY_ERROR;
265 0 : goto end;
266 : }
267 214 : GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
268 214 : sc->auth_context = grpc_auth_context_create(NULL);
269 214 : grpc_auth_context_add_cstring_property(
270 : sc->auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
271 : GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
272 :
273 : end:
274 214 : tsi_peer_destruct(&peer);
275 214 : return status;
276 : }
277 :
278 26173 : static grpc_security_status fake_channel_check_call_host(
279 : grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
280 : const char *host, grpc_security_check_cb cb, void *user_data) {
281 26173 : grpc_fake_channel_security_connector *c =
282 : (grpc_fake_channel_security_connector *)sc;
283 26173 : if (c->call_host_check_is_async) {
284 26173 : cb(exec_ctx, user_data, GRPC_SECURITY_OK);
285 26173 : return GRPC_SECURITY_PENDING;
286 : } else {
287 0 : return GRPC_SECURITY_OK;
288 : }
289 : }
290 :
291 109 : static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
292 : grpc_security_connector *sc,
293 : grpc_endpoint *nonsecure_endpoint,
294 : grpc_security_handshake_done_cb cb,
295 : void *user_data) {
296 109 : grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), sc,
297 : nonsecure_endpoint, cb, user_data);
298 109 : }
299 :
300 107 : static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx,
301 : grpc_security_connector *sc,
302 : grpc_endpoint *nonsecure_endpoint,
303 : grpc_security_handshake_done_cb cb,
304 : void *user_data) {
305 107 : grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), sc,
306 : nonsecure_endpoint, cb, user_data);
307 107 : }
308 :
309 : static grpc_security_connector_vtable fake_channel_vtable = {
310 : fake_channel_destroy, fake_channel_do_handshake, fake_check_peer};
311 :
312 : static grpc_security_connector_vtable fake_server_vtable = {
313 : fake_server_destroy, fake_server_do_handshake, fake_check_peer};
314 :
315 129 : grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
316 : grpc_call_credentials *request_metadata_creds,
317 : int call_host_check_is_async) {
318 129 : grpc_fake_channel_security_connector *c =
319 : gpr_malloc(sizeof(grpc_fake_channel_security_connector));
320 129 : memset(c, 0, sizeof(grpc_fake_channel_security_connector));
321 129 : gpr_ref_init(&c->base.base.refcount, 1);
322 129 : c->base.base.is_client_side = 1;
323 129 : c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
324 129 : c->base.base.vtable = &fake_channel_vtable;
325 129 : c->base.request_metadata_creds =
326 129 : grpc_call_credentials_ref(request_metadata_creds);
327 129 : c->base.check_call_host = fake_channel_check_call_host;
328 129 : c->call_host_check_is_async = call_host_check_is_async;
329 129 : return &c->base;
330 : }
331 :
332 128 : grpc_security_connector *grpc_fake_server_security_connector_create(void) {
333 128 : grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector));
334 128 : memset(c, 0, sizeof(grpc_security_connector));
335 128 : gpr_ref_init(&c->refcount, 1);
336 128 : c->is_client_side = 0;
337 128 : c->vtable = &fake_server_vtable;
338 128 : c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
339 128 : gpr_mu_init(&c->mu);
340 128 : return c;
341 : }
342 :
343 : /* --- Ssl implementation. --- */
344 :
345 : typedef struct {
346 : grpc_channel_security_connector base;
347 : tsi_ssl_handshaker_factory *handshaker_factory;
348 : char *target_name;
349 : char *overridden_target_name;
350 : tsi_peer peer;
351 : } grpc_ssl_channel_security_connector;
352 :
353 : typedef struct {
354 : grpc_security_connector base;
355 : tsi_ssl_handshaker_factory *handshaker_factory;
356 : } grpc_ssl_server_security_connector;
357 :
358 567 : static void ssl_channel_destroy(grpc_security_connector *sc) {
359 567 : grpc_ssl_channel_security_connector *c =
360 : (grpc_ssl_channel_security_connector *)sc;
361 567 : grpc_call_credentials_unref(c->base.request_metadata_creds);
362 567 : if (c->handshaker_factory != NULL) {
363 567 : tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
364 : }
365 567 : if (c->target_name != NULL) gpr_free(c->target_name);
366 567 : if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
367 567 : tsi_peer_destruct(&c->peer);
368 567 : GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
369 567 : gpr_free(sc);
370 567 : }
371 :
372 576 : static void ssl_server_destroy(grpc_security_connector *sc) {
373 574 : grpc_ssl_server_security_connector *c =
374 : (grpc_ssl_server_security_connector *)sc;
375 :
376 576 : if (c->handshaker_factory != NULL) {
377 576 : tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
378 : }
379 576 : GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
380 576 : gpr_mu_destroy(&sc->mu);
381 576 : gpr_free(sc);
382 576 : }
383 :
384 972 : static grpc_security_status ssl_create_handshaker(
385 : tsi_ssl_handshaker_factory *handshaker_factory, int is_client,
386 : const char *peer_name, tsi_handshaker **handshaker) {
387 938 : tsi_result result = TSI_OK;
388 972 : if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
389 972 : result = tsi_ssl_handshaker_factory_create_handshaker(
390 : handshaker_factory, is_client ? peer_name : NULL, handshaker);
391 972 : if (result != TSI_OK) {
392 0 : gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
393 : tsi_result_to_string(result));
394 0 : return GRPC_SECURITY_ERROR;
395 : }
396 938 : return GRPC_SECURITY_OK;
397 : }
398 :
399 484 : static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
400 : grpc_security_connector *sc,
401 : grpc_endpoint *nonsecure_endpoint,
402 : grpc_security_handshake_done_cb cb,
403 : void *user_data) {
404 467 : grpc_ssl_channel_security_connector *c =
405 : (grpc_ssl_channel_security_connector *)sc;
406 : tsi_handshaker *handshaker;
407 484 : grpc_security_status status = ssl_create_handshaker(
408 : c->handshaker_factory, 1,
409 484 : c->overridden_target_name != NULL ? c->overridden_target_name
410 : : c->target_name,
411 : &handshaker);
412 484 : if (status != GRPC_SECURITY_OK) {
413 0 : cb(exec_ctx, user_data, status, NULL);
414 : } else {
415 484 : grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
416 : user_data);
417 : }
418 484 : }
419 :
420 488 : static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
421 : grpc_security_connector *sc,
422 : grpc_endpoint *nonsecure_endpoint,
423 : grpc_security_handshake_done_cb cb,
424 : void *user_data) {
425 471 : grpc_ssl_server_security_connector *c =
426 : (grpc_ssl_server_security_connector *)sc;
427 : tsi_handshaker *handshaker;
428 488 : grpc_security_status status =
429 488 : ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker);
430 488 : if (status != GRPC_SECURITY_OK) {
431 0 : cb(exec_ctx, user_data, status, NULL);
432 : } else {
433 488 : grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
434 : user_data);
435 : }
436 488 : }
437 :
438 126607 : static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
439 126607 : char *allocated_name = NULL;
440 : int r;
441 :
442 126607 : if (strchr(peer_name, ':') != NULL) {
443 : char *ignored_port;
444 78509 : gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
445 78509 : gpr_free(ignored_port);
446 78509 : peer_name = allocated_name;
447 78509 : if (!peer_name) return 0;
448 : }
449 126607 : r = tsi_ssl_peer_matches_name(peer, peer_name);
450 126607 : gpr_free(allocated_name);
451 126607 : return r;
452 : }
453 :
454 966 : grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) {
455 : size_t i;
456 932 : grpc_auth_context *ctx = NULL;
457 932 : const char *peer_identity_property_name = NULL;
458 :
459 : /* The caller has checked the certificate type property. */
460 966 : GPR_ASSERT(peer->property_count >= 1);
461 966 : ctx = grpc_auth_context_create(NULL);
462 966 : grpc_auth_context_add_cstring_property(
463 : ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
464 : GRPC_SSL_TRANSPORT_SECURITY_TYPE);
465 4340 : for (i = 0; i < peer->property_count; i++) {
466 3374 : const tsi_peer_property *prop = &peer->properties[i];
467 3374 : if (prop->name == NULL) continue;
468 3374 : if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
469 : /* If there is no subject alt name, have the CN as the identity. */
470 483 : if (peer_identity_property_name == NULL) {
471 466 : peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
472 : }
473 966 : grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME,
474 483 : prop->value.data, prop->value.length);
475 2891 : } else if (strcmp(prop->name,
476 : TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
477 1393 : peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
478 2888 : grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME,
479 1444 : prop->value.data, prop->value.length);
480 : }
481 : }
482 966 : if (peer_identity_property_name != NULL) {
483 483 : GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
484 : ctx, peer_identity_property_name) == 1);
485 : }
486 966 : return ctx;
487 : }
488 :
489 961 : static grpc_security_status ssl_check_peer(grpc_security_connector *sc,
490 : const char *peer_name,
491 : const tsi_peer *peer) {
492 : /* Check the ALPN. */
493 961 : const tsi_peer_property *p =
494 : tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
495 961 : if (p == NULL) {
496 0 : gpr_log(GPR_ERROR, "Missing selected ALPN property.");
497 0 : return GRPC_SECURITY_ERROR;
498 : }
499 961 : if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
500 0 : gpr_log(GPR_ERROR, "Invalid ALPN value.");
501 0 : return GRPC_SECURITY_ERROR;
502 : }
503 :
504 : /* Check the peer name if specified. */
505 961 : if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
506 0 : gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
507 0 : return GRPC_SECURITY_ERROR;
508 : }
509 961 : if (sc->auth_context != NULL) {
510 79 : GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
511 : }
512 961 : sc->auth_context = tsi_ssl_peer_to_auth_context(peer);
513 927 : return GRPC_SECURITY_OK;
514 : }
515 :
516 478 : static grpc_security_status ssl_channel_check_peer(grpc_security_connector *sc,
517 : tsi_peer peer,
518 : grpc_security_check_cb cb,
519 : void *user_data) {
520 461 : grpc_ssl_channel_security_connector *c =
521 : (grpc_ssl_channel_security_connector *)sc;
522 : grpc_security_status status;
523 478 : tsi_peer_destruct(&c->peer);
524 478 : c->peer = peer;
525 478 : status = ssl_check_peer(sc, c->overridden_target_name != NULL
526 : ? c->overridden_target_name
527 : : c->target_name,
528 : &peer);
529 478 : return status;
530 : }
531 :
532 483 : static grpc_security_status ssl_server_check_peer(grpc_security_connector *sc,
533 : tsi_peer peer,
534 : grpc_security_check_cb cb,
535 : void *user_data) {
536 483 : grpc_security_status status = ssl_check_peer(sc, NULL, &peer);
537 483 : tsi_peer_destruct(&peer);
538 483 : return status;
539 : }
540 :
541 126129 : static grpc_security_status ssl_channel_check_call_host(
542 : grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
543 : const char *host, grpc_security_check_cb cb, void *user_data) {
544 126106 : grpc_ssl_channel_security_connector *c =
545 : (grpc_ssl_channel_security_connector *)sc;
546 :
547 126129 : if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
548 :
549 : /* If the target name was overridden, then the original target_name was
550 : 'checked' transitively during the previous peer check at the end of the
551 : handshake. */
552 0 : if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) {
553 0 : return GRPC_SECURITY_OK;
554 : } else {
555 0 : return GRPC_SECURITY_ERROR;
556 : }
557 : }
558 :
559 : static grpc_security_connector_vtable ssl_channel_vtable = {
560 : ssl_channel_destroy, ssl_channel_do_handshake, ssl_channel_check_peer};
561 :
562 : static grpc_security_connector_vtable ssl_server_vtable = {
563 : ssl_server_destroy, ssl_server_do_handshake, ssl_server_check_peer};
564 :
565 : static gpr_slice default_pem_root_certs;
566 :
567 97 : static void init_default_pem_root_certs(void) {
568 : /* First try to load the roots from the environment. */
569 97 : char *default_root_certs_path =
570 : gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
571 97 : if (default_root_certs_path == NULL) {
572 0 : default_pem_root_certs = gpr_empty_slice();
573 : } else {
574 97 : default_pem_root_certs = gpr_load_file(default_root_certs_path, 0, NULL);
575 97 : gpr_free(default_root_certs_path);
576 : }
577 :
578 : /* Fall back to installed certs if needed. */
579 97 : if (GPR_SLICE_IS_EMPTY(default_pem_root_certs)) {
580 0 : default_pem_root_certs = gpr_load_file(installed_roots_path, 0, NULL);
581 : }
582 97 : }
583 :
584 398 : size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
585 : /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
586 : loading all the roots once for the lifetime of the process. */
587 : static gpr_once once = GPR_ONCE_INIT;
588 398 : gpr_once_init(&once, init_default_pem_root_certs);
589 398 : *pem_root_certs = GPR_SLICE_START_PTR(default_pem_root_certs);
590 398 : return GPR_SLICE_LENGTH(default_pem_root_certs);
591 : }
592 :
593 588 : grpc_security_status grpc_ssl_channel_security_connector_create(
594 : grpc_call_credentials *request_metadata_creds,
595 : const grpc_ssl_config *config, const char *target_name,
596 : const char *overridden_target_name, grpc_channel_security_connector **sc) {
597 588 : size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
598 588 : const unsigned char **alpn_protocol_strings =
599 588 : gpr_malloc(sizeof(const char *) * num_alpn_protocols);
600 588 : unsigned char *alpn_protocol_string_lengths =
601 : gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
602 570 : tsi_result result = TSI_OK;
603 : grpc_ssl_channel_security_connector *c;
604 : size_t i;
605 : const unsigned char *pem_root_certs;
606 : size_t pem_root_certs_size;
607 : char *port;
608 :
609 1176 : for (i = 0; i < num_alpn_protocols; i++) {
610 1176 : alpn_protocol_strings[i] =
611 588 : (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
612 1176 : alpn_protocol_string_lengths[i] =
613 588 : (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
614 : }
615 :
616 588 : if (config == NULL || target_name == NULL) {
617 0 : gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
618 0 : goto error;
619 : }
620 588 : if (config->pem_root_certs == NULL) {
621 396 : pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
622 396 : if (pem_root_certs == NULL || pem_root_certs_size == 0) {
623 0 : gpr_log(GPR_ERROR, "Could not get default pem root certs.");
624 0 : goto error;
625 : }
626 : } else {
627 192 : pem_root_certs = config->pem_root_certs;
628 192 : pem_root_certs_size = config->pem_root_certs_size;
629 : }
630 :
631 588 : c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector));
632 588 : memset(c, 0, sizeof(grpc_ssl_channel_security_connector));
633 :
634 588 : gpr_ref_init(&c->base.base.refcount, 1);
635 588 : c->base.base.vtable = &ssl_channel_vtable;
636 588 : c->base.base.is_client_side = 1;
637 588 : c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
638 588 : c->base.request_metadata_creds =
639 588 : grpc_call_credentials_ref(request_metadata_creds);
640 588 : c->base.check_call_host = ssl_channel_check_call_host;
641 588 : gpr_split_host_port(target_name, &c->target_name, &port);
642 588 : gpr_free(port);
643 588 : if (overridden_target_name != NULL) {
644 588 : c->overridden_target_name = gpr_strdup(overridden_target_name);
645 : }
646 2370 : result = tsi_create_ssl_client_handshaker_factory(
647 588 : config->pem_private_key, config->pem_private_key_size,
648 588 : config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs,
649 : pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings,
650 588 : alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
651 : &c->handshaker_factory);
652 588 : if (result != TSI_OK) {
653 0 : gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
654 : tsi_result_to_string(result));
655 0 : ssl_channel_destroy(&c->base.base);
656 0 : *sc = NULL;
657 0 : goto error;
658 : }
659 588 : *sc = &c->base;
660 588 : gpr_free((void *)alpn_protocol_strings);
661 588 : gpr_free(alpn_protocol_string_lengths);
662 588 : return GRPC_SECURITY_OK;
663 :
664 : error:
665 0 : gpr_free((void *)alpn_protocol_strings);
666 0 : gpr_free(alpn_protocol_string_lengths);
667 0 : return GRPC_SECURITY_ERROR;
668 : }
669 :
670 577 : grpc_security_status grpc_ssl_server_security_connector_create(
671 : const grpc_ssl_server_config *config, grpc_security_connector **sc) {
672 577 : size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
673 577 : const unsigned char **alpn_protocol_strings =
674 577 : gpr_malloc(sizeof(const char *) * num_alpn_protocols);
675 577 : unsigned char *alpn_protocol_string_lengths =
676 : gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
677 574 : tsi_result result = TSI_OK;
678 : grpc_ssl_server_security_connector *c;
679 : size_t i;
680 :
681 1154 : for (i = 0; i < num_alpn_protocols; i++) {
682 1154 : alpn_protocol_strings[i] =
683 577 : (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
684 1154 : alpn_protocol_string_lengths[i] =
685 577 : (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
686 : }
687 :
688 577 : if (config == NULL || config->num_key_cert_pairs == 0) {
689 0 : gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
690 0 : goto error;
691 : }
692 577 : c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
693 577 : memset(c, 0, sizeof(grpc_ssl_server_security_connector));
694 :
695 577 : gpr_ref_init(&c->base.refcount, 1);
696 577 : c->base.url_scheme = GRPC_SSL_URL_SCHEME;
697 577 : c->base.vtable = &ssl_server_vtable;
698 2311 : result = tsi_create_ssl_server_handshaker_factory(
699 577 : (const unsigned char **)config->pem_private_keys,
700 577 : config->pem_private_keys_sizes,
701 577 : (const unsigned char **)config->pem_cert_chains,
702 577 : config->pem_cert_chains_sizes, config->num_key_cert_pairs,
703 577 : config->pem_root_certs, config->pem_root_certs_size,
704 : config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings,
705 577 : alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
706 : &c->handshaker_factory);
707 577 : if (result != TSI_OK) {
708 0 : gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
709 : tsi_result_to_string(result));
710 0 : ssl_server_destroy(&c->base);
711 0 : *sc = NULL;
712 0 : goto error;
713 : }
714 577 : gpr_mu_init(&c->base.mu);
715 577 : *sc = &c->base;
716 577 : gpr_free((void *)alpn_protocol_strings);
717 577 : gpr_free(alpn_protocol_string_lengths);
718 577 : return GRPC_SECURITY_OK;
719 :
720 : error:
721 0 : gpr_free((void *)alpn_protocol_strings);
722 0 : gpr_free(alpn_protocol_string_lengths);
723 0 : return GRPC_SECURITY_ERROR;
724 : }
|