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/tsi/ssl_transport_security.h"
22
23 #include <limits.h>
24 #include <string.h>
25
26 /* TODO(jboeuf): refactor inet_ntop into a portability header. */
27 /* Note: for whomever reads this and tries to refactor this, this
28 can't be in grpc, it has to be in gpr. */
29 #ifdef GPR_WINDOWS
30 #include <ws2tcpip.h>
31 #else
32 #include <arpa/inet.h>
33 #include <sys/socket.h>
34 #endif
35
36 #include <grpc/grpc_security.h>
37 #include <grpc/support/alloc.h>
38 #include <grpc/support/log.h>
39 #include <grpc/support/string_util.h>
40 #include <grpc/support/sync.h>
41 #include <grpc/support/thd_id.h>
42
43 #include "absl/strings/match.h"
44 #include "absl/strings/string_view.h"
45
46 extern "C" {
47 #include <openssl/bio.h>
48 #include <openssl/crypto.h> /* For OPENSSL_free */
49 #include <openssl/engine.h>
50 #include <openssl/err.h>
51 #include <openssl/ssl.h>
52 #include <openssl/x509.h>
53 #include <openssl/x509v3.h>
54 }
55
56 #include "src/core/lib/gpr/useful.h"
57 #include "src/core/tsi/ssl/session_cache/ssl_session_cache.h"
58 #include "src/core/tsi/ssl_types.h"
59 #include "src/core/tsi/transport_security.h"
60
61 /* --- Constants. ---*/
62
63 #define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND 16384
64 #define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024
65 #define TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE 1024
66
67 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
68 #define TSI_OPENSSL_ALPN_SUPPORT 1
69 #else
70 #define TSI_OPENSSL_ALPN_SUPPORT 0
71 #endif
72
73 /* TODO(jboeuf): I have not found a way to get this number dynamically from the
74 SSL structure. This is what we would ultimately want though... */
75 #define TSI_SSL_MAX_PROTECTION_OVERHEAD 100
76
77 /* --- Structure definitions. ---*/
78
79 struct tsi_ssl_root_certs_store {
80 X509_STORE* store;
81 };
82
83 struct tsi_ssl_handshaker_factory {
84 const tsi_ssl_handshaker_factory_vtable* vtable;
85 gpr_refcount refcount;
86 };
87
88 struct tsi_ssl_client_handshaker_factory {
89 tsi_ssl_handshaker_factory base;
90 SSL_CTX* ssl_context;
91 unsigned char* alpn_protocol_list;
92 size_t alpn_protocol_list_length;
93 grpc_core::RefCountedPtr<tsi::SslSessionLRUCache> session_cache;
94 };
95
96 struct tsi_ssl_server_handshaker_factory {
97 /* Several contexts to support SNI.
98 The tsi_peer array contains the subject names of the server certificates
99 associated with the contexts at the same index. */
100 tsi_ssl_handshaker_factory base;
101 SSL_CTX** ssl_contexts;
102 tsi_peer* ssl_context_x509_subject_names;
103 size_t ssl_context_count;
104 unsigned char* alpn_protocol_list;
105 size_t alpn_protocol_list_length;
106 };
107
108 struct tsi_ssl_handshaker {
109 tsi_handshaker base;
110 SSL* ssl;
111 BIO* network_io;
112 tsi_result result;
113 unsigned char* outgoing_bytes_buffer;
114 size_t outgoing_bytes_buffer_size;
115 tsi_ssl_handshaker_factory* factory_ref;
116 };
117 struct tsi_ssl_handshaker_result {
118 tsi_handshaker_result base;
119 SSL* ssl;
120 BIO* network_io;
121 unsigned char* unused_bytes;
122 size_t unused_bytes_size;
123 };
124 struct tsi_ssl_frame_protector {
125 tsi_frame_protector base;
126 SSL* ssl;
127 BIO* network_io;
128 unsigned char* buffer;
129 size_t buffer_size;
130 size_t buffer_offset;
131 };
132 /* --- Library Initialization. ---*/
133
134 static gpr_once g_init_openssl_once = GPR_ONCE_INIT;
135 static int g_ssl_ctx_ex_factory_index = -1;
136 static const unsigned char kSslSessionIdContext[] = {'g', 'r', 'p', 'c'};
137 #ifndef OPENSSL_IS_BORINGSSL
138 static const char kSslEnginePrefix[] = "engine:";
139 #endif
140
141 #if OPENSSL_VERSION_NUMBER < 0x10100000
142 static gpr_mu* g_openssl_mutexes = nullptr;
143 static void openssl_locking_cb(int mode, int type, const char* file,
144 int line) GRPC_UNUSED;
145 static unsigned long openssl_thread_id_cb(void) GRPC_UNUSED;
146
openssl_locking_cb(int mode,int type,const char * file,int line)147 static void openssl_locking_cb(int mode, int type, const char* file, int line) {
148 if (mode & CRYPTO_LOCK) {
149 gpr_mu_lock(&g_openssl_mutexes[type]);
150 } else {
151 gpr_mu_unlock(&g_openssl_mutexes[type]);
152 }
153 }
154
openssl_thread_id_cb(void)155 static unsigned long openssl_thread_id_cb(void) {
156 return static_cast<unsigned long>(gpr_thd_currentid());
157 }
158 #endif
159
init_openssl(void)160 static void init_openssl(void) {
161 #if OPENSSL_API_COMPAT >= 0x10100000L
162 OPENSSL_init_ssl(0, NULL);
163 #else
164 SSL_library_init();
165 SSL_load_error_strings();
166 OpenSSL_add_all_algorithms();
167 #endif
168 #if OPENSSL_VERSION_NUMBER < 0x10100000
169 if (!CRYPTO_get_locking_callback()) {
170 int num_locks = CRYPTO_num_locks();
171 GPR_ASSERT(num_locks > 0);
172 g_openssl_mutexes = static_cast<gpr_mu*>(
173 gpr_malloc(static_cast<size_t>(num_locks) * sizeof(gpr_mu)));
174 for (int i = 0; i < num_locks; i++) {
175 gpr_mu_init(&g_openssl_mutexes[i]);
176 }
177 CRYPTO_set_locking_callback(openssl_locking_cb);
178 CRYPTO_set_id_callback(openssl_thread_id_cb);
179 } else {
180 gpr_log(GPR_INFO, "OpenSSL callback has already been set.");
181 }
182 #endif
183 g_ssl_ctx_ex_factory_index =
184 SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
185 GPR_ASSERT(g_ssl_ctx_ex_factory_index != -1);
186 }
187
188 /* --- Ssl utils. ---*/
189
ssl_error_string(int error)190 static const char* ssl_error_string(int error) {
191 switch (error) {
192 case SSL_ERROR_NONE:
193 return "SSL_ERROR_NONE";
194 case SSL_ERROR_ZERO_RETURN:
195 return "SSL_ERROR_ZERO_RETURN";
196 case SSL_ERROR_WANT_READ:
197 return "SSL_ERROR_WANT_READ";
198 case SSL_ERROR_WANT_WRITE:
199 return "SSL_ERROR_WANT_WRITE";
200 case SSL_ERROR_WANT_CONNECT:
201 return "SSL_ERROR_WANT_CONNECT";
202 case SSL_ERROR_WANT_ACCEPT:
203 return "SSL_ERROR_WANT_ACCEPT";
204 case SSL_ERROR_WANT_X509_LOOKUP:
205 return "SSL_ERROR_WANT_X509_LOOKUP";
206 case SSL_ERROR_SYSCALL:
207 return "SSL_ERROR_SYSCALL";
208 case SSL_ERROR_SSL:
209 return "SSL_ERROR_SSL";
210 default:
211 return "Unknown error";
212 }
213 }
214
215 /* TODO(jboeuf): Remove when we are past the debugging phase with this code. */
ssl_log_where_info(const SSL * ssl,int where,int flag,const char * msg)216 static void ssl_log_where_info(const SSL* ssl, int where, int flag,
217 const char* msg) {
218 if ((where & flag) && GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) {
219 gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg,
220 SSL_state_string_long(ssl), SSL_state_string(ssl));
221 }
222 }
223
224 /* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */
ssl_info_callback(const SSL * ssl,int where,int ret)225 static void ssl_info_callback(const SSL* ssl, int where, int ret) {
226 if (ret == 0) {
227 gpr_log(GPR_ERROR, "ssl_info_callback: error occurred.\n");
228 return;
229 }
230
231 ssl_log_where_info(ssl, where, SSL_CB_LOOP, "LOOP");
232 ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START");
233 ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE");
234 }
235
236 /* Returns 1 if name looks like an IP address, 0 otherwise.
237 This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */
looks_like_ip_address(absl::string_view name)238 static int looks_like_ip_address(absl::string_view name) {
239 size_t dot_count = 0;
240 size_t num_size = 0;
241 for (size_t i = 0; i < name.size(); ++i) {
242 if (name[i] == ':') {
243 /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */
244 return 1;
245 }
246 if (name[i] >= '0' && name[i] <= '9') {
247 if (num_size > 3) return 0;
248 num_size++;
249 } else if (name[i] == '.') {
250 if (dot_count > 3 || num_size == 0) return 0;
251 dot_count++;
252 num_size = 0;
253 } else {
254 return 0;
255 }
256 }
257 if (dot_count < 3 || num_size == 0) return 0;
258 return 1;
259 }
260
261 /* Gets the subject CN from an X509 cert. */
ssl_get_x509_common_name(X509 * cert,unsigned char ** utf8,size_t * utf8_size)262 static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8,
263 size_t* utf8_size) {
264 int common_name_index = -1;
265 X509_NAME_ENTRY* common_name_entry = nullptr;
266 ASN1_STRING* common_name_asn1 = nullptr;
267 X509_NAME* subject_name = X509_get_subject_name(cert);
268 int utf8_returned_size = 0;
269 if (subject_name == nullptr) {
270 gpr_log(GPR_INFO, "Could not get subject name from certificate.");
271 return TSI_NOT_FOUND;
272 }
273 common_name_index =
274 X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1);
275 if (common_name_index == -1) {
276 gpr_log(GPR_INFO, "Could not get common name of subject from certificate.");
277 return TSI_NOT_FOUND;
278 }
279 common_name_entry = X509_NAME_get_entry(subject_name, common_name_index);
280 if (common_name_entry == nullptr) {
281 gpr_log(GPR_ERROR, "Could not get common name entry from certificate.");
282 return TSI_INTERNAL_ERROR;
283 }
284 common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
285 if (common_name_asn1 == nullptr) {
286 gpr_log(GPR_ERROR,
287 "Could not get common name entry asn1 from certificate.");
288 return TSI_INTERNAL_ERROR;
289 }
290 utf8_returned_size = ASN1_STRING_to_UTF8(utf8, common_name_asn1);
291 if (utf8_returned_size < 0) {
292 gpr_log(GPR_ERROR, "Could not extract utf8 from asn1 string.");
293 return TSI_OUT_OF_RESOURCES;
294 }
295 *utf8_size = static_cast<size_t>(utf8_returned_size);
296 return TSI_OK;
297 }
298
299 /* Gets the subject CN of an X509 cert as a tsi_peer_property. */
peer_property_from_x509_common_name(X509 * cert,tsi_peer_property * property)300 static tsi_result peer_property_from_x509_common_name(
301 X509* cert, tsi_peer_property* property) {
302 unsigned char* common_name;
303 size_t common_name_size;
304 tsi_result result =
305 ssl_get_x509_common_name(cert, &common_name, &common_name_size);
306 if (result != TSI_OK) {
307 if (result == TSI_NOT_FOUND) {
308 common_name = nullptr;
309 common_name_size = 0;
310 } else {
311 return result;
312 }
313 }
314 result = tsi_construct_string_peer_property(
315 TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY,
316 common_name == nullptr ? "" : reinterpret_cast<const char*>(common_name),
317 common_name_size, property);
318 OPENSSL_free(common_name);
319 return result;
320 }
321
322 /* Gets the X509 cert in PEM format as a tsi_peer_property. */
add_pem_certificate(X509 * cert,tsi_peer_property * property)323 static tsi_result add_pem_certificate(X509* cert, tsi_peer_property* property) {
324 BIO* bio = BIO_new(BIO_s_mem());
325 if (!PEM_write_bio_X509(bio, cert)) {
326 BIO_free(bio);
327 return TSI_INTERNAL_ERROR;
328 }
329 char* contents;
330 long len = BIO_get_mem_data(bio, &contents);
331 if (len <= 0) {
332 BIO_free(bio);
333 return TSI_INTERNAL_ERROR;
334 }
335 tsi_result result = tsi_construct_string_peer_property(
336 TSI_X509_PEM_CERT_PROPERTY, (const char*)contents,
337 static_cast<size_t>(len), property);
338 BIO_free(bio);
339 return result;
340 }
341
342 /* Gets the subject SANs from an X509 cert as a tsi_peer_property. */
add_subject_alt_names_properties_to_peer(tsi_peer * peer,GENERAL_NAMES * subject_alt_names,size_t subject_alt_name_count,int * current_insert_index)343 static tsi_result add_subject_alt_names_properties_to_peer(
344 tsi_peer* peer, GENERAL_NAMES* subject_alt_names,
345 size_t subject_alt_name_count, int* current_insert_index) {
346 size_t i;
347 tsi_result result = TSI_OK;
348
349 for (i = 0; i < subject_alt_name_count; i++) {
350 GENERAL_NAME* subject_alt_name =
351 sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i));
352 if (subject_alt_name->type == GEN_DNS ||
353 subject_alt_name->type == GEN_EMAIL ||
354 subject_alt_name->type == GEN_URI) {
355 unsigned char* name = nullptr;
356 int name_size;
357 if (subject_alt_name->type == GEN_DNS) {
358 name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName);
359 } else if (subject_alt_name->type == GEN_EMAIL) {
360 name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.rfc822Name);
361 } else {
362 name_size = ASN1_STRING_to_UTF8(
363 &name, subject_alt_name->d.uniformResourceIdentifier);
364 }
365 if (name_size < 0) {
366 gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string.");
367 result = TSI_INTERNAL_ERROR;
368 break;
369 }
370 result = tsi_construct_string_peer_property(
371 TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
372 reinterpret_cast<const char*>(name), static_cast<size_t>(name_size),
373 &peer->properties[(*current_insert_index)++]);
374 if (result != TSI_OK) {
375 OPENSSL_free(name);
376 break;
377 }
378 if (subject_alt_name->type == GEN_URI) {
379 result = tsi_construct_string_peer_property(
380 TSI_X509_URI_PEER_PROPERTY, reinterpret_cast<const char*>(name),
381 static_cast<size_t>(name_size),
382 &peer->properties[(*current_insert_index)++]);
383 }
384 OPENSSL_free(name);
385 } else if (subject_alt_name->type == GEN_IPADD) {
386 char ntop_buf[INET6_ADDRSTRLEN];
387 int af;
388
389 if (subject_alt_name->d.iPAddress->length == 4) {
390 af = AF_INET;
391 } else if (subject_alt_name->d.iPAddress->length == 16) {
392 af = AF_INET6;
393 } else {
394 gpr_log(GPR_ERROR, "SAN IP Address contained invalid IP");
395 result = TSI_INTERNAL_ERROR;
396 break;
397 }
398 const char* name = inet_ntop(af, subject_alt_name->d.iPAddress->data,
399 ntop_buf, INET6_ADDRSTRLEN);
400 if (name == nullptr) {
401 gpr_log(GPR_ERROR, "Could not get IP string from asn1 octet.");
402 result = TSI_INTERNAL_ERROR;
403 break;
404 }
405
406 result = tsi_construct_string_peer_property_from_cstring(
407 TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, name,
408 &peer->properties[(*current_insert_index)++]);
409 }
410 if (result != TSI_OK) break;
411 }
412 return result;
413 }
414
415 /* Gets information about the peer's X509 cert as a tsi_peer object. */
peer_from_x509(X509 * cert,int include_certificate_type,tsi_peer * peer)416 static tsi_result peer_from_x509(X509* cert, int include_certificate_type,
417 tsi_peer* peer) {
418 /* TODO(jboeuf): Maybe add more properties. */
419 GENERAL_NAMES* subject_alt_names = static_cast<GENERAL_NAMES*>(
420 X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr));
421 int subject_alt_name_count =
422 (subject_alt_names != nullptr)
423 ? static_cast<int>(sk_GENERAL_NAME_num(subject_alt_names))
424 : 0;
425 size_t property_count;
426 tsi_result result;
427 GPR_ASSERT(subject_alt_name_count >= 0);
428 property_count = (include_certificate_type ? static_cast<size_t>(1) : 0) +
429 2 /* common name, certificate */ +
430 static_cast<size_t>(subject_alt_name_count);
431 for (int i = 0; i < subject_alt_name_count; i++) {
432 GENERAL_NAME* subject_alt_name =
433 sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i));
434 if (subject_alt_name->type == GEN_URI) {
435 property_count += 1;
436 }
437 }
438 result = tsi_construct_peer(property_count, peer);
439 if (result != TSI_OK) return result;
440 int current_insert_index = 0;
441 do {
442 if (include_certificate_type) {
443 result = tsi_construct_string_peer_property_from_cstring(
444 TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
445 &peer->properties[current_insert_index++]);
446 if (result != TSI_OK) break;
447 }
448 result = peer_property_from_x509_common_name(
449 cert, &peer->properties[current_insert_index++]);
450 if (result != TSI_OK) break;
451
452 result =
453 add_pem_certificate(cert, &peer->properties[current_insert_index++]);
454 if (result != TSI_OK) break;
455
456 if (subject_alt_name_count != 0) {
457 result = add_subject_alt_names_properties_to_peer(
458 peer, subject_alt_names, static_cast<size_t>(subject_alt_name_count),
459 ¤t_insert_index);
460 if (result != TSI_OK) break;
461 }
462 } while (0);
463
464 if (subject_alt_names != nullptr) {
465 sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free);
466 }
467 if (result != TSI_OK) tsi_peer_destruct(peer);
468
469 GPR_ASSERT((int)peer->property_count == current_insert_index);
470 return result;
471 }
472
473 /* Logs the SSL error stack. */
log_ssl_error_stack(void)474 static void log_ssl_error_stack(void) {
475 unsigned long err;
476 while ((err = ERR_get_error()) != 0) {
477 char details[256];
478 ERR_error_string_n(static_cast<uint32_t>(err), details, sizeof(details));
479 gpr_log(GPR_ERROR, "%s", details);
480 }
481 }
482
483 /* Performs an SSL_read and handle errors. */
do_ssl_read(SSL * ssl,unsigned char * unprotected_bytes,size_t * unprotected_bytes_size)484 static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes,
485 size_t* unprotected_bytes_size) {
486 int read_from_ssl;
487 GPR_ASSERT(*unprotected_bytes_size <= INT_MAX);
488 read_from_ssl = SSL_read(ssl, unprotected_bytes,
489 static_cast<int>(*unprotected_bytes_size));
490 if (read_from_ssl <= 0) {
491 read_from_ssl = SSL_get_error(ssl, read_from_ssl);
492 switch (read_from_ssl) {
493 case SSL_ERROR_ZERO_RETURN: /* Received a close_notify alert. */
494 case SSL_ERROR_WANT_READ: /* We need more data to finish the frame. */
495 *unprotected_bytes_size = 0;
496 return TSI_OK;
497 case SSL_ERROR_WANT_WRITE:
498 gpr_log(
499 GPR_ERROR,
500 "Peer tried to renegotiate SSL connection. This is unsupported.");
501 return TSI_UNIMPLEMENTED;
502 case SSL_ERROR_SSL:
503 gpr_log(GPR_ERROR, "Corruption detected.");
504 log_ssl_error_stack();
505 return TSI_DATA_CORRUPTED;
506 default:
507 gpr_log(GPR_ERROR, "SSL_read failed with error %s.",
508 ssl_error_string(read_from_ssl));
509 return TSI_PROTOCOL_FAILURE;
510 }
511 }
512 *unprotected_bytes_size = static_cast<size_t>(read_from_ssl);
513 return TSI_OK;
514 }
515
516 /* Performs an SSL_write and handle errors. */
do_ssl_write(SSL * ssl,unsigned char * unprotected_bytes,size_t unprotected_bytes_size)517 static tsi_result do_ssl_write(SSL* ssl, unsigned char* unprotected_bytes,
518 size_t unprotected_bytes_size) {
519 int ssl_write_result;
520 GPR_ASSERT(unprotected_bytes_size <= INT_MAX);
521 ssl_write_result = SSL_write(ssl, unprotected_bytes,
522 static_cast<int>(unprotected_bytes_size));
523 if (ssl_write_result < 0) {
524 ssl_write_result = SSL_get_error(ssl, ssl_write_result);
525 if (ssl_write_result == SSL_ERROR_WANT_READ) {
526 gpr_log(GPR_ERROR,
527 "Peer tried to renegotiate SSL connection. This is unsupported.");
528 return TSI_UNIMPLEMENTED;
529 } else {
530 gpr_log(GPR_ERROR, "SSL_write failed with error %s.",
531 ssl_error_string(ssl_write_result));
532 return TSI_INTERNAL_ERROR;
533 }
534 }
535 return TSI_OK;
536 }
537
538 /* Loads an in-memory PEM certificate chain into the SSL context. */
ssl_ctx_use_certificate_chain(SSL_CTX * context,const char * pem_cert_chain,size_t pem_cert_chain_size)539 static tsi_result ssl_ctx_use_certificate_chain(SSL_CTX* context,
540 const char* pem_cert_chain,
541 size_t pem_cert_chain_size) {
542 tsi_result result = TSI_OK;
543 X509* certificate = nullptr;
544 BIO* pem;
545 GPR_ASSERT(pem_cert_chain_size <= INT_MAX);
546 pem = BIO_new_mem_buf((void*)pem_cert_chain,
547 static_cast<int>(pem_cert_chain_size));
548 if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
549
550 do {
551 certificate = PEM_read_bio_X509_AUX(pem, nullptr, nullptr, (void*)"");
552 if (certificate == nullptr) {
553 result = TSI_INVALID_ARGUMENT;
554 break;
555 }
556 if (!SSL_CTX_use_certificate(context, certificate)) {
557 result = TSI_INVALID_ARGUMENT;
558 break;
559 }
560 while (1) {
561 X509* certificate_authority =
562 PEM_read_bio_X509(pem, nullptr, nullptr, (void*)"");
563 if (certificate_authority == nullptr) {
564 ERR_clear_error();
565 break; /* Done reading. */
566 }
567 if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) {
568 X509_free(certificate_authority);
569 result = TSI_INVALID_ARGUMENT;
570 break;
571 }
572 /* We don't need to free certificate_authority as its ownership has been
573 transferred to the context. That is not the case for certificate
574 though.
575 */
576 }
577 } while (0);
578
579 if (certificate != nullptr) X509_free(certificate);
580 BIO_free(pem);
581 return result;
582 }
583
584 #ifndef OPENSSL_IS_BORINGSSL
ssl_ctx_use_engine_private_key(SSL_CTX * context,const char * pem_key,size_t pem_key_size)585 static tsi_result ssl_ctx_use_engine_private_key(SSL_CTX* context,
586 const char* pem_key,
587 size_t pem_key_size) {
588 tsi_result result = TSI_OK;
589 EVP_PKEY* private_key = nullptr;
590 ENGINE* engine = nullptr;
591 char* engine_name = nullptr;
592 // Parse key which is in following format engine:<engine_id>:<key_id>
593 do {
594 char* engine_start = (char*)pem_key + strlen(kSslEnginePrefix);
595 char* engine_end = (char*)strchr(engine_start, ':');
596 if (engine_end == nullptr) {
597 result = TSI_INVALID_ARGUMENT;
598 break;
599 }
600 char* key_id = engine_end + 1;
601 int engine_name_length = engine_end - engine_start;
602 if (engine_name_length == 0) {
603 result = TSI_INVALID_ARGUMENT;
604 break;
605 }
606 engine_name = static_cast<char*>(gpr_zalloc(engine_name_length + 1));
607 memcpy(engine_name, engine_start, engine_name_length);
608 gpr_log(GPR_DEBUG, "ENGINE key: %s", engine_name);
609 ENGINE_load_dynamic();
610 engine = ENGINE_by_id(engine_name);
611 if (engine == nullptr) {
612 // If not available at ENGINE_DIR, use dynamic to load from
613 // current working directory.
614 engine = ENGINE_by_id("dynamic");
615 if (engine == nullptr) {
616 gpr_log(GPR_ERROR, "Cannot load dynamic engine");
617 result = TSI_INVALID_ARGUMENT;
618 break;
619 }
620 if (!ENGINE_ctrl_cmd_string(engine, "ID", engine_name, 0) ||
621 !ENGINE_ctrl_cmd_string(engine, "DIR_LOAD", "2", 0) ||
622 !ENGINE_ctrl_cmd_string(engine, "DIR_ADD", ".", 0) ||
623 !ENGINE_ctrl_cmd_string(engine, "LIST_ADD", "1", 0) ||
624 !ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
625 gpr_log(GPR_ERROR, "Cannot find engine");
626 result = TSI_INVALID_ARGUMENT;
627 break;
628 }
629 }
630 if (!ENGINE_set_default(engine, ENGINE_METHOD_ALL)) {
631 gpr_log(GPR_ERROR, "ENGINE_set_default with ENGINE_METHOD_ALL failed");
632 result = TSI_INVALID_ARGUMENT;
633 break;
634 }
635 if (!ENGINE_init(engine)) {
636 gpr_log(GPR_ERROR, "ENGINE_init failed");
637 result = TSI_INVALID_ARGUMENT;
638 break;
639 }
640 private_key = ENGINE_load_private_key(engine, key_id, 0, 0);
641 if (private_key == nullptr) {
642 gpr_log(GPR_ERROR, "ENGINE_load_private_key failed");
643 result = TSI_INVALID_ARGUMENT;
644 break;
645 }
646 if (!SSL_CTX_use_PrivateKey(context, private_key)) {
647 gpr_log(GPR_ERROR, "SSL_CTX_use_PrivateKey failed");
648 result = TSI_INVALID_ARGUMENT;
649 break;
650 }
651 } while (0);
652 if (engine != nullptr) ENGINE_free(engine);
653 if (private_key != nullptr) EVP_PKEY_free(private_key);
654 if (engine_name != nullptr) gpr_free(engine_name);
655 return result;
656 }
657 #endif /* OPENSSL_IS_BORINGSSL */
658
ssl_ctx_use_pem_private_key(SSL_CTX * context,const char * pem_key,size_t pem_key_size)659 static tsi_result ssl_ctx_use_pem_private_key(SSL_CTX* context,
660 const char* pem_key,
661 size_t pem_key_size) {
662 tsi_result result = TSI_OK;
663 EVP_PKEY* private_key = nullptr;
664 BIO* pem;
665 GPR_ASSERT(pem_key_size <= INT_MAX);
666 pem = BIO_new_mem_buf((void*)pem_key, static_cast<int>(pem_key_size));
667 if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
668 do {
669 private_key = PEM_read_bio_PrivateKey(pem, nullptr, nullptr, (void*)"");
670 if (private_key == nullptr) {
671 result = TSI_INVALID_ARGUMENT;
672 break;
673 }
674 if (!SSL_CTX_use_PrivateKey(context, private_key)) {
675 result = TSI_INVALID_ARGUMENT;
676 break;
677 }
678 } while (0);
679 if (private_key != nullptr) EVP_PKEY_free(private_key);
680 BIO_free(pem);
681 return result;
682 }
683
684 /* Loads an in-memory PEM private key into the SSL context. */
ssl_ctx_use_private_key(SSL_CTX * context,const char * pem_key,size_t pem_key_size)685 static tsi_result ssl_ctx_use_private_key(SSL_CTX* context, const char* pem_key,
686 size_t pem_key_size) {
687 // BoringSSL does not have ENGINE support
688 #ifndef OPENSSL_IS_BORINGSSL
689 if (strncmp(pem_key, kSslEnginePrefix, strlen(kSslEnginePrefix)) == 0) {
690 return ssl_ctx_use_engine_private_key(context, pem_key, pem_key_size);
691 } else
692 #endif /* OPENSSL_IS_BORINGSSL */
693 {
694 return ssl_ctx_use_pem_private_key(context, pem_key, pem_key_size);
695 }
696 }
697
698 /* Loads in-memory PEM verification certs into the SSL context and optionally
699 returns the verification cert names (root_names can be NULL). */
x509_store_load_certs(X509_STORE * cert_store,const char * pem_roots,size_t pem_roots_size,STACK_OF (X509_NAME)** root_names)700 static tsi_result x509_store_load_certs(X509_STORE* cert_store,
701 const char* pem_roots,
702 size_t pem_roots_size,
703 STACK_OF(X509_NAME) * *root_names) {
704 tsi_result result = TSI_OK;
705 size_t num_roots = 0;
706 X509* root = nullptr;
707 X509_NAME* root_name = nullptr;
708 BIO* pem;
709 GPR_ASSERT(pem_roots_size <= INT_MAX);
710 pem = BIO_new_mem_buf((void*)pem_roots, static_cast<int>(pem_roots_size));
711 if (cert_store == nullptr) return TSI_INVALID_ARGUMENT;
712 if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
713 if (root_names != nullptr) {
714 *root_names = sk_X509_NAME_new_null();
715 if (*root_names == nullptr) return TSI_OUT_OF_RESOURCES;
716 }
717
718 while (1) {
719 root = PEM_read_bio_X509_AUX(pem, nullptr, nullptr, (void*)"");
720 if (root == nullptr) {
721 ERR_clear_error();
722 break; /* We're at the end of stream. */
723 }
724 if (root_names != nullptr) {
725 root_name = X509_get_subject_name(root);
726 if (root_name == nullptr) {
727 gpr_log(GPR_ERROR, "Could not get name from root certificate.");
728 result = TSI_INVALID_ARGUMENT;
729 break;
730 }
731 root_name = X509_NAME_dup(root_name);
732 if (root_name == nullptr) {
733 result = TSI_OUT_OF_RESOURCES;
734 break;
735 }
736 sk_X509_NAME_push(*root_names, root_name);
737 root_name = nullptr;
738 }
739 ERR_clear_error();
740 if (!X509_STORE_add_cert(cert_store, root)) {
741 unsigned long error = ERR_get_error();
742 if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
743 ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
744 gpr_log(GPR_ERROR, "Could not add root certificate to ssl context.");
745 result = TSI_INTERNAL_ERROR;
746 break;
747 }
748 }
749 X509_free(root);
750 num_roots++;
751 }
752 if (num_roots == 0) {
753 gpr_log(GPR_ERROR, "Could not load any root certificate.");
754 result = TSI_INVALID_ARGUMENT;
755 }
756
757 if (result != TSI_OK) {
758 if (root != nullptr) X509_free(root);
759 if (root_names != nullptr) {
760 sk_X509_NAME_pop_free(*root_names, X509_NAME_free);
761 *root_names = nullptr;
762 if (root_name != nullptr) X509_NAME_free(root_name);
763 }
764 }
765 BIO_free(pem);
766 return result;
767 }
768
ssl_ctx_load_verification_certs(SSL_CTX * context,const char * pem_roots,size_t pem_roots_size,STACK_OF (X509_NAME)** root_name)769 static tsi_result ssl_ctx_load_verification_certs(SSL_CTX* context,
770 const char* pem_roots,
771 size_t pem_roots_size,
772 STACK_OF(X509_NAME) *
773 *root_name) {
774 X509_STORE* cert_store = SSL_CTX_get_cert_store(context);
775 X509_STORE_set_flags(cert_store,
776 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_TRUSTED_FIRST);
777 return x509_store_load_certs(cert_store, pem_roots, pem_roots_size,
778 root_name);
779 }
780
781 /* Populates the SSL context with a private key and a cert chain, and sets the
782 cipher list and the ephemeral ECDH key. */
populate_ssl_context(SSL_CTX * context,const tsi_ssl_pem_key_cert_pair * key_cert_pair,const char * cipher_list)783 static tsi_result populate_ssl_context(
784 SSL_CTX* context, const tsi_ssl_pem_key_cert_pair* key_cert_pair,
785 const char* cipher_list) {
786 tsi_result result = TSI_OK;
787 if (key_cert_pair != nullptr) {
788 if (key_cert_pair->cert_chain != nullptr) {
789 result = ssl_ctx_use_certificate_chain(context, key_cert_pair->cert_chain,
790 strlen(key_cert_pair->cert_chain));
791 if (result != TSI_OK) {
792 gpr_log(GPR_ERROR, "Invalid cert chain file.");
793 return result;
794 }
795 }
796 if (key_cert_pair->private_key != nullptr) {
797 result = ssl_ctx_use_private_key(context, key_cert_pair->private_key,
798 strlen(key_cert_pair->private_key));
799 if (result != TSI_OK || !SSL_CTX_check_private_key(context)) {
800 gpr_log(GPR_ERROR, "Invalid private key.");
801 return result != TSI_OK ? result : TSI_INVALID_ARGUMENT;
802 }
803 }
804 }
805 if ((cipher_list != nullptr) &&
806 !SSL_CTX_set_cipher_list(context, cipher_list)) {
807 gpr_log(GPR_ERROR, "Invalid cipher list: %s.", cipher_list);
808 return TSI_INVALID_ARGUMENT;
809 }
810 {
811 EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
812 if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) {
813 gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key.");
814 EC_KEY_free(ecdh);
815 return TSI_INTERNAL_ERROR;
816 }
817 SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
818 EC_KEY_free(ecdh);
819 }
820 return TSI_OK;
821 }
822
823 /* Extracts the CN and the SANs from an X509 cert as a peer object. */
tsi_ssl_extract_x509_subject_names_from_pem_cert(const char * pem_cert,tsi_peer * peer)824 tsi_result tsi_ssl_extract_x509_subject_names_from_pem_cert(
825 const char* pem_cert, tsi_peer* peer) {
826 tsi_result result = TSI_OK;
827 X509* cert = nullptr;
828 BIO* pem;
829 pem = BIO_new_mem_buf((void*)pem_cert, static_cast<int>(strlen(pem_cert)));
830 if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
831
832 cert = PEM_read_bio_X509(pem, nullptr, nullptr, (void*)"");
833 if (cert == nullptr) {
834 gpr_log(GPR_ERROR, "Invalid certificate");
835 result = TSI_INVALID_ARGUMENT;
836 } else {
837 result = peer_from_x509(cert, 0, peer);
838 }
839 if (cert != nullptr) X509_free(cert);
840 BIO_free(pem);
841 return result;
842 }
843
844 /* Builds the alpn protocol name list according to rfc 7301. */
build_alpn_protocol_name_list(const char ** alpn_protocols,uint16_t num_alpn_protocols,unsigned char ** protocol_name_list,size_t * protocol_name_list_length)845 static tsi_result build_alpn_protocol_name_list(
846 const char** alpn_protocols, uint16_t num_alpn_protocols,
847 unsigned char** protocol_name_list, size_t* protocol_name_list_length) {
848 uint16_t i;
849 unsigned char* current;
850 *protocol_name_list = nullptr;
851 *protocol_name_list_length = 0;
852 if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT;
853 for (i = 0; i < num_alpn_protocols; i++) {
854 size_t length =
855 alpn_protocols[i] == nullptr ? 0 : strlen(alpn_protocols[i]);
856 if (length == 0 || length > 255) {
857 gpr_log(GPR_ERROR, "Invalid protocol name length: %d.",
858 static_cast<int>(length));
859 return TSI_INVALID_ARGUMENT;
860 }
861 *protocol_name_list_length += length + 1;
862 }
863 *protocol_name_list =
864 static_cast<unsigned char*>(gpr_malloc(*protocol_name_list_length));
865 if (*protocol_name_list == nullptr) return TSI_OUT_OF_RESOURCES;
866 current = *protocol_name_list;
867 for (i = 0; i < num_alpn_protocols; i++) {
868 size_t length = strlen(alpn_protocols[i]);
869 *(current++) = static_cast<uint8_t>(length); /* max checked above. */
870 memcpy(current, alpn_protocols[i], length);
871 current += length;
872 }
873 /* Safety check. */
874 if ((current < *protocol_name_list) ||
875 (static_cast<uintptr_t>(current - *protocol_name_list) !=
876 *protocol_name_list_length)) {
877 return TSI_INTERNAL_ERROR;
878 }
879 return TSI_OK;
880 }
881
882 // The verification callback is used for clients that don't really care about
883 // the server's certificate, but we need to pull it anyway, in case a higher
884 // layer wants to look at it. In this case the verification may fail, but
885 // we don't really care.
NullVerifyCallback(int,X509_STORE_CTX *)886 static int NullVerifyCallback(int /*preverify_ok*/, X509_STORE_CTX* /*ctx*/) {
887 return 1;
888 }
889
890 /* --- tsi_ssl_root_certs_store methods implementation. ---*/
891
tsi_ssl_root_certs_store_create(const char * pem_roots)892 tsi_ssl_root_certs_store* tsi_ssl_root_certs_store_create(
893 const char* pem_roots) {
894 if (pem_roots == nullptr) {
895 gpr_log(GPR_ERROR, "The root certificates are empty.");
896 return nullptr;
897 }
898 tsi_ssl_root_certs_store* root_store = static_cast<tsi_ssl_root_certs_store*>(
899 gpr_zalloc(sizeof(tsi_ssl_root_certs_store)));
900 if (root_store == nullptr) {
901 gpr_log(GPR_ERROR, "Could not allocate buffer for ssl_root_certs_store.");
902 return nullptr;
903 }
904 root_store->store = X509_STORE_new();
905 if (root_store->store == nullptr) {
906 gpr_log(GPR_ERROR, "Could not allocate buffer for X509_STORE.");
907 gpr_free(root_store);
908 return nullptr;
909 }
910 tsi_result result = x509_store_load_certs(root_store->store, pem_roots,
911 strlen(pem_roots), nullptr);
912 if (result != TSI_OK) {
913 gpr_log(GPR_ERROR, "Could not load root certificates.");
914 X509_STORE_free(root_store->store);
915 gpr_free(root_store);
916 return nullptr;
917 }
918 return root_store;
919 }
920
tsi_ssl_root_certs_store_destroy(tsi_ssl_root_certs_store * self)921 void tsi_ssl_root_certs_store_destroy(tsi_ssl_root_certs_store* self) {
922 if (self == nullptr) return;
923 X509_STORE_free(self->store);
924 gpr_free(self);
925 }
926
927 /* --- tsi_ssl_session_cache methods implementation. ---*/
928
tsi_ssl_session_cache_create_lru(size_t capacity)929 tsi_ssl_session_cache* tsi_ssl_session_cache_create_lru(size_t capacity) {
930 /* Pointer will be dereferenced by unref call. */
931 return reinterpret_cast<tsi_ssl_session_cache*>(
932 tsi::SslSessionLRUCache::Create(capacity).release());
933 }
934
tsi_ssl_session_cache_ref(tsi_ssl_session_cache * cache)935 void tsi_ssl_session_cache_ref(tsi_ssl_session_cache* cache) {
936 /* Pointer will be dereferenced by unref call. */
937 reinterpret_cast<tsi::SslSessionLRUCache*>(cache)->Ref().release();
938 }
939
tsi_ssl_session_cache_unref(tsi_ssl_session_cache * cache)940 void tsi_ssl_session_cache_unref(tsi_ssl_session_cache* cache) {
941 reinterpret_cast<tsi::SslSessionLRUCache*>(cache)->Unref();
942 }
943
944 /* --- tsi_frame_protector methods implementation. ---*/
945
ssl_protector_protect(tsi_frame_protector * self,const unsigned char * unprotected_bytes,size_t * unprotected_bytes_size,unsigned char * protected_output_frames,size_t * protected_output_frames_size)946 static tsi_result ssl_protector_protect(tsi_frame_protector* self,
947 const unsigned char* unprotected_bytes,
948 size_t* unprotected_bytes_size,
949 unsigned char* protected_output_frames,
950 size_t* protected_output_frames_size) {
951 tsi_ssl_frame_protector* impl =
952 reinterpret_cast<tsi_ssl_frame_protector*>(self);
953 int read_from_ssl;
954 size_t available;
955 tsi_result result = TSI_OK;
956
957 /* First see if we have some pending data in the SSL BIO. */
958 int pending_in_ssl = static_cast<int>(BIO_pending(impl->network_io));
959 if (pending_in_ssl > 0) {
960 *unprotected_bytes_size = 0;
961 GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
962 read_from_ssl = BIO_read(impl->network_io, protected_output_frames,
963 static_cast<int>(*protected_output_frames_size));
964 if (read_from_ssl < 0) {
965 gpr_log(GPR_ERROR,
966 "Could not read from BIO even though some data is pending");
967 return TSI_INTERNAL_ERROR;
968 }
969 *protected_output_frames_size = static_cast<size_t>(read_from_ssl);
970 return TSI_OK;
971 }
972
973 /* Now see if we can send a complete frame. */
974 available = impl->buffer_size - impl->buffer_offset;
975 if (available > *unprotected_bytes_size) {
976 /* If we cannot, just copy the data in our internal buffer. */
977 memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes,
978 *unprotected_bytes_size);
979 impl->buffer_offset += *unprotected_bytes_size;
980 *protected_output_frames_size = 0;
981 return TSI_OK;
982 }
983
984 /* If we can, prepare the buffer, send it to SSL_write and read. */
985 memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, available);
986 result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size);
987 if (result != TSI_OK) return result;
988
989 GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
990 read_from_ssl = BIO_read(impl->network_io, protected_output_frames,
991 static_cast<int>(*protected_output_frames_size));
992 if (read_from_ssl < 0) {
993 gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
994 return TSI_INTERNAL_ERROR;
995 }
996 *protected_output_frames_size = static_cast<size_t>(read_from_ssl);
997 *unprotected_bytes_size = available;
998 impl->buffer_offset = 0;
999 return TSI_OK;
1000 }
1001
ssl_protector_protect_flush(tsi_frame_protector * self,unsigned char * protected_output_frames,size_t * protected_output_frames_size,size_t * still_pending_size)1002 static tsi_result ssl_protector_protect_flush(
1003 tsi_frame_protector* self, unsigned char* protected_output_frames,
1004 size_t* protected_output_frames_size, size_t* still_pending_size) {
1005 tsi_result result = TSI_OK;
1006 tsi_ssl_frame_protector* impl =
1007 reinterpret_cast<tsi_ssl_frame_protector*>(self);
1008 int read_from_ssl = 0;
1009 int pending;
1010
1011 if (impl->buffer_offset != 0) {
1012 result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_offset);
1013 if (result != TSI_OK) return result;
1014 impl->buffer_offset = 0;
1015 }
1016
1017 pending = static_cast<int>(BIO_pending(impl->network_io));
1018 GPR_ASSERT(pending >= 0);
1019 *still_pending_size = static_cast<size_t>(pending);
1020 if (*still_pending_size == 0) return TSI_OK;
1021
1022 GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
1023 read_from_ssl = BIO_read(impl->network_io, protected_output_frames,
1024 static_cast<int>(*protected_output_frames_size));
1025 if (read_from_ssl <= 0) {
1026 gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
1027 return TSI_INTERNAL_ERROR;
1028 }
1029 *protected_output_frames_size = static_cast<size_t>(read_from_ssl);
1030 pending = static_cast<int>(BIO_pending(impl->network_io));
1031 GPR_ASSERT(pending >= 0);
1032 *still_pending_size = static_cast<size_t>(pending);
1033 return TSI_OK;
1034 }
1035
ssl_protector_unprotect(tsi_frame_protector * self,const unsigned char * protected_frames_bytes,size_t * protected_frames_bytes_size,unsigned char * unprotected_bytes,size_t * unprotected_bytes_size)1036 static tsi_result ssl_protector_unprotect(
1037 tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
1038 size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
1039 size_t* unprotected_bytes_size) {
1040 tsi_result result = TSI_OK;
1041 int written_into_ssl = 0;
1042 size_t output_bytes_size = *unprotected_bytes_size;
1043 size_t output_bytes_offset = 0;
1044 tsi_ssl_frame_protector* impl =
1045 reinterpret_cast<tsi_ssl_frame_protector*>(self);
1046
1047 /* First, try to read remaining data from ssl. */
1048 result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size);
1049 if (result != TSI_OK) return result;
1050 if (*unprotected_bytes_size == output_bytes_size) {
1051 /* We have read everything we could and cannot process any more input. */
1052 *protected_frames_bytes_size = 0;
1053 return TSI_OK;
1054 }
1055 output_bytes_offset = *unprotected_bytes_size;
1056 unprotected_bytes += output_bytes_offset;
1057 *unprotected_bytes_size = output_bytes_size - output_bytes_offset;
1058
1059 /* Then, try to write some data to ssl. */
1060 GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX);
1061 written_into_ssl = BIO_write(impl->network_io, protected_frames_bytes,
1062 static_cast<int>(*protected_frames_bytes_size));
1063 if (written_into_ssl < 0) {
1064 gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
1065 written_into_ssl);
1066 return TSI_INTERNAL_ERROR;
1067 }
1068 *protected_frames_bytes_size = static_cast<size_t>(written_into_ssl);
1069
1070 /* Now try to read some data again. */
1071 result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size);
1072 if (result == TSI_OK) {
1073 /* Don't forget to output the total number of bytes read. */
1074 *unprotected_bytes_size += output_bytes_offset;
1075 }
1076 return result;
1077 }
1078
ssl_protector_destroy(tsi_frame_protector * self)1079 static void ssl_protector_destroy(tsi_frame_protector* self) {
1080 tsi_ssl_frame_protector* impl =
1081 reinterpret_cast<tsi_ssl_frame_protector*>(self);
1082 if (impl->buffer != nullptr) gpr_free(impl->buffer);
1083 if (impl->ssl != nullptr) SSL_free(impl->ssl);
1084 if (impl->network_io != nullptr) BIO_free(impl->network_io);
1085 gpr_free(self);
1086 }
1087
1088 static const tsi_frame_protector_vtable frame_protector_vtable = {
1089 ssl_protector_protect,
1090 ssl_protector_protect_flush,
1091 ssl_protector_unprotect,
1092 ssl_protector_destroy,
1093 };
1094
1095 /* --- tsi_server_handshaker_factory methods implementation. --- */
1096
tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory * self)1097 static void tsi_ssl_handshaker_factory_destroy(
1098 tsi_ssl_handshaker_factory* self) {
1099 if (self == nullptr) return;
1100
1101 if (self->vtable != nullptr && self->vtable->destroy != nullptr) {
1102 self->vtable->destroy(self);
1103 }
1104 /* Note, we don't free(self) here because this object is always directly
1105 * embedded in another object. If tsi_ssl_handshaker_factory_init allocates
1106 * any memory, it should be free'd here. */
1107 }
1108
tsi_ssl_handshaker_factory_ref(tsi_ssl_handshaker_factory * self)1109 static tsi_ssl_handshaker_factory* tsi_ssl_handshaker_factory_ref(
1110 tsi_ssl_handshaker_factory* self) {
1111 if (self == nullptr) return nullptr;
1112 gpr_refn(&self->refcount, 1);
1113 return self;
1114 }
1115
tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory * self)1116 static void tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory* self) {
1117 if (self == nullptr) return;
1118
1119 if (gpr_unref(&self->refcount)) {
1120 tsi_ssl_handshaker_factory_destroy(self);
1121 }
1122 }
1123
1124 static tsi_ssl_handshaker_factory_vtable handshaker_factory_vtable = {nullptr};
1125
1126 /* Initializes a tsi_ssl_handshaker_factory object. Caller is responsible for
1127 * allocating memory for the factory. */
tsi_ssl_handshaker_factory_init(tsi_ssl_handshaker_factory * factory)1128 static void tsi_ssl_handshaker_factory_init(
1129 tsi_ssl_handshaker_factory* factory) {
1130 GPR_ASSERT(factory != nullptr);
1131
1132 factory->vtable = &handshaker_factory_vtable;
1133 gpr_ref_init(&factory->refcount, 1);
1134 }
1135
1136 /* Gets the X509 cert chain in PEM format as a tsi_peer_property. */
tsi_ssl_get_cert_chain_contents(STACK_OF (X509)* peer_chain,tsi_peer_property * property)1137 tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain,
1138 tsi_peer_property* property) {
1139 BIO* bio = BIO_new(BIO_s_mem());
1140 const auto peer_chain_len = sk_X509_num(peer_chain);
1141 for (auto i = decltype(peer_chain_len){0}; i < peer_chain_len; i++) {
1142 if (!PEM_write_bio_X509(bio, sk_X509_value(peer_chain, i))) {
1143 BIO_free(bio);
1144 return TSI_INTERNAL_ERROR;
1145 }
1146 }
1147 char* contents;
1148 long len = BIO_get_mem_data(bio, &contents);
1149 if (len <= 0) {
1150 BIO_free(bio);
1151 return TSI_INTERNAL_ERROR;
1152 }
1153 tsi_result result = tsi_construct_string_peer_property(
1154 TSI_X509_PEM_CERT_CHAIN_PROPERTY, (const char*)contents,
1155 static_cast<size_t>(len), property);
1156 BIO_free(bio);
1157 return result;
1158 }
1159
1160 /* --- tsi_handshaker_result methods implementation. ---*/
ssl_handshaker_result_extract_peer(const tsi_handshaker_result * self,tsi_peer * peer)1161 static tsi_result ssl_handshaker_result_extract_peer(
1162 const tsi_handshaker_result* self, tsi_peer* peer) {
1163 tsi_result result = TSI_OK;
1164 const unsigned char* alpn_selected = nullptr;
1165 unsigned int alpn_selected_len;
1166 const tsi_ssl_handshaker_result* impl =
1167 reinterpret_cast<const tsi_ssl_handshaker_result*>(self);
1168 X509* peer_cert = SSL_get_peer_certificate(impl->ssl);
1169 if (peer_cert != nullptr) {
1170 result = peer_from_x509(peer_cert, 1, peer);
1171 X509_free(peer_cert);
1172 if (result != TSI_OK) return result;
1173 }
1174 #if TSI_OPENSSL_ALPN_SUPPORT
1175 SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len);
1176 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
1177 if (alpn_selected == nullptr) {
1178 /* Try npn. */
1179 SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected,
1180 &alpn_selected_len);
1181 }
1182 // When called on the client side, the stack also contains the
1183 // peer's certificate; When called on the server side,
1184 // the peer's certificate is not present in the stack
1185 STACK_OF(X509)* peer_chain = SSL_get_peer_cert_chain(impl->ssl);
1186 // 1 is for session reused property.
1187 size_t new_property_count = peer->property_count + 3;
1188 if (alpn_selected != nullptr) new_property_count++;
1189 if (peer_chain != nullptr) new_property_count++;
1190 tsi_peer_property* new_properties = static_cast<tsi_peer_property*>(
1191 gpr_zalloc(sizeof(*new_properties) * new_property_count));
1192 for (size_t i = 0; i < peer->property_count; i++) {
1193 new_properties[i] = peer->properties[i];
1194 }
1195 if (peer->properties != nullptr) gpr_free(peer->properties);
1196 peer->properties = new_properties;
1197 // Add peer chain if available
1198 if (peer_chain != nullptr) {
1199 result = tsi_ssl_get_cert_chain_contents(
1200 peer_chain, &peer->properties[peer->property_count]);
1201 if (result == TSI_OK) peer->property_count++;
1202 }
1203 if (alpn_selected != nullptr) {
1204 result = tsi_construct_string_peer_property(
1205 TSI_SSL_ALPN_SELECTED_PROTOCOL,
1206 reinterpret_cast<const char*>(alpn_selected), alpn_selected_len,
1207 &peer->properties[peer->property_count]);
1208 if (result != TSI_OK) return result;
1209 peer->property_count++;
1210 }
1211 // Add security_level peer property.
1212 result = tsi_construct_string_peer_property_from_cstring(
1213 TSI_SECURITY_LEVEL_PEER_PROPERTY,
1214 tsi_security_level_to_string(TSI_PRIVACY_AND_INTEGRITY),
1215 &peer->properties[peer->property_count]);
1216 if (result != TSI_OK) return result;
1217 peer->property_count++;
1218
1219 const char* session_reused = SSL_session_reused(impl->ssl) ? "true" : "false";
1220 result = tsi_construct_string_peer_property_from_cstring(
1221 TSI_SSL_SESSION_REUSED_PEER_PROPERTY, session_reused,
1222 &peer->properties[peer->property_count]);
1223 if (result != TSI_OK) return result;
1224 peer->property_count++;
1225 return result;
1226 }
1227
ssl_handshaker_result_create_frame_protector(const tsi_handshaker_result * self,size_t * max_output_protected_frame_size,tsi_frame_protector ** protector)1228 static tsi_result ssl_handshaker_result_create_frame_protector(
1229 const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
1230 tsi_frame_protector** protector) {
1231 size_t actual_max_output_protected_frame_size =
1232 TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
1233 tsi_ssl_handshaker_result* impl =
1234 reinterpret_cast<tsi_ssl_handshaker_result*>(
1235 const_cast<tsi_handshaker_result*>(self));
1236 tsi_ssl_frame_protector* protector_impl =
1237 static_cast<tsi_ssl_frame_protector*>(
1238 gpr_zalloc(sizeof(*protector_impl)));
1239
1240 if (max_output_protected_frame_size != nullptr) {
1241 if (*max_output_protected_frame_size >
1242 TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) {
1243 *max_output_protected_frame_size =
1244 TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
1245 } else if (*max_output_protected_frame_size <
1246 TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) {
1247 *max_output_protected_frame_size =
1248 TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND;
1249 }
1250 actual_max_output_protected_frame_size = *max_output_protected_frame_size;
1251 }
1252 protector_impl->buffer_size =
1253 actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD;
1254 protector_impl->buffer =
1255 static_cast<unsigned char*>(gpr_malloc(protector_impl->buffer_size));
1256 if (protector_impl->buffer == nullptr) {
1257 gpr_log(GPR_ERROR,
1258 "Could not allocated buffer for tsi_ssl_frame_protector.");
1259 gpr_free(protector_impl);
1260 return TSI_INTERNAL_ERROR;
1261 }
1262
1263 /* Transfer ownership of ssl and network_io to the frame protector. */
1264 protector_impl->ssl = impl->ssl;
1265 impl->ssl = nullptr;
1266 protector_impl->network_io = impl->network_io;
1267 impl->network_io = nullptr;
1268 protector_impl->base.vtable = &frame_protector_vtable;
1269 *protector = &protector_impl->base;
1270 return TSI_OK;
1271 }
1272
ssl_handshaker_result_get_unused_bytes(const tsi_handshaker_result * self,const unsigned char ** bytes,size_t * bytes_size)1273 static tsi_result ssl_handshaker_result_get_unused_bytes(
1274 const tsi_handshaker_result* self, const unsigned char** bytes,
1275 size_t* bytes_size) {
1276 const tsi_ssl_handshaker_result* impl =
1277 reinterpret_cast<const tsi_ssl_handshaker_result*>(self);
1278 *bytes_size = impl->unused_bytes_size;
1279 *bytes = impl->unused_bytes;
1280 return TSI_OK;
1281 }
1282
ssl_handshaker_result_destroy(tsi_handshaker_result * self)1283 static void ssl_handshaker_result_destroy(tsi_handshaker_result* self) {
1284 tsi_ssl_handshaker_result* impl =
1285 reinterpret_cast<tsi_ssl_handshaker_result*>(self);
1286 SSL_free(impl->ssl);
1287 BIO_free(impl->network_io);
1288 gpr_free(impl->unused_bytes);
1289 gpr_free(impl);
1290 }
1291
1292 static const tsi_handshaker_result_vtable handshaker_result_vtable = {
1293 ssl_handshaker_result_extract_peer,
1294 nullptr, /* create_zero_copy_grpc_protector */
1295 ssl_handshaker_result_create_frame_protector,
1296 ssl_handshaker_result_get_unused_bytes,
1297 ssl_handshaker_result_destroy,
1298 };
1299
ssl_handshaker_result_create(tsi_ssl_handshaker * handshaker,const unsigned char * unused_bytes,size_t unused_bytes_size,tsi_handshaker_result ** handshaker_result)1300 static tsi_result ssl_handshaker_result_create(
1301 tsi_ssl_handshaker* handshaker, const unsigned char* unused_bytes,
1302 size_t unused_bytes_size, tsi_handshaker_result** handshaker_result) {
1303 if (handshaker == nullptr || handshaker_result == nullptr ||
1304 (unused_bytes_size > 0 && unused_bytes == nullptr)) {
1305 return TSI_INVALID_ARGUMENT;
1306 }
1307 tsi_ssl_handshaker_result* result =
1308 static_cast<tsi_ssl_handshaker_result*>(gpr_zalloc(sizeof(*result)));
1309 result->base.vtable = &handshaker_result_vtable;
1310 /* Transfer ownership of ssl and network_io to the handshaker result. */
1311 result->ssl = handshaker->ssl;
1312 handshaker->ssl = nullptr;
1313 result->network_io = handshaker->network_io;
1314 handshaker->network_io = nullptr;
1315 if (unused_bytes_size > 0) {
1316 result->unused_bytes =
1317 static_cast<unsigned char*>(gpr_malloc(unused_bytes_size));
1318 memcpy(result->unused_bytes, unused_bytes, unused_bytes_size);
1319 }
1320 result->unused_bytes_size = unused_bytes_size;
1321 *handshaker_result = &result->base;
1322 return TSI_OK;
1323 }
1324
1325 /* --- tsi_handshaker methods implementation. ---*/
1326
ssl_handshaker_get_bytes_to_send_to_peer(tsi_ssl_handshaker * impl,unsigned char * bytes,size_t * bytes_size)1327 static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(
1328 tsi_ssl_handshaker* impl, unsigned char* bytes, size_t* bytes_size) {
1329 int bytes_read_from_ssl = 0;
1330 if (bytes == nullptr || bytes_size == nullptr || *bytes_size == 0 ||
1331 *bytes_size > INT_MAX) {
1332 return TSI_INVALID_ARGUMENT;
1333 }
1334 GPR_ASSERT(*bytes_size <= INT_MAX);
1335 bytes_read_from_ssl =
1336 BIO_read(impl->network_io, bytes, static_cast<int>(*bytes_size));
1337 if (bytes_read_from_ssl < 0) {
1338 *bytes_size = 0;
1339 if (!BIO_should_retry(impl->network_io)) {
1340 impl->result = TSI_INTERNAL_ERROR;
1341 return impl->result;
1342 } else {
1343 return TSI_OK;
1344 }
1345 }
1346 *bytes_size = static_cast<size_t>(bytes_read_from_ssl);
1347 return BIO_pending(impl->network_io) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
1348 }
1349
ssl_handshaker_get_result(tsi_ssl_handshaker * impl)1350 static tsi_result ssl_handshaker_get_result(tsi_ssl_handshaker* impl) {
1351 if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) &&
1352 SSL_is_init_finished(impl->ssl)) {
1353 impl->result = TSI_OK;
1354 }
1355 return impl->result;
1356 }
1357
ssl_handshaker_process_bytes_from_peer(tsi_ssl_handshaker * impl,const unsigned char * bytes,size_t * bytes_size)1358 static tsi_result ssl_handshaker_process_bytes_from_peer(
1359 tsi_ssl_handshaker* impl, const unsigned char* bytes, size_t* bytes_size) {
1360 int bytes_written_into_ssl_size = 0;
1361 if (bytes == nullptr || bytes_size == nullptr || *bytes_size > INT_MAX) {
1362 return TSI_INVALID_ARGUMENT;
1363 }
1364 GPR_ASSERT(*bytes_size <= INT_MAX);
1365 bytes_written_into_ssl_size =
1366 BIO_write(impl->network_io, bytes, static_cast<int>(*bytes_size));
1367 if (bytes_written_into_ssl_size < 0) {
1368 gpr_log(GPR_ERROR, "Could not write to memory BIO.");
1369 impl->result = TSI_INTERNAL_ERROR;
1370 return impl->result;
1371 }
1372 *bytes_size = static_cast<size_t>(bytes_written_into_ssl_size);
1373
1374 if (ssl_handshaker_get_result(impl) != TSI_HANDSHAKE_IN_PROGRESS) {
1375 impl->result = TSI_OK;
1376 return impl->result;
1377 } else {
1378 /* Get ready to get some bytes from SSL. */
1379 int ssl_result = SSL_do_handshake(impl->ssl);
1380 ssl_result = SSL_get_error(impl->ssl, ssl_result);
1381 switch (ssl_result) {
1382 case SSL_ERROR_WANT_READ:
1383 if (BIO_pending(impl->network_io) == 0) {
1384 /* We need more data. */
1385 return TSI_INCOMPLETE_DATA;
1386 } else {
1387 return TSI_OK;
1388 }
1389 case SSL_ERROR_NONE:
1390 return TSI_OK;
1391 default: {
1392 char err_str[256];
1393 ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));
1394 gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.",
1395 ssl_error_string(ssl_result), err_str);
1396 impl->result = TSI_PROTOCOL_FAILURE;
1397 return impl->result;
1398 }
1399 }
1400 }
1401 }
1402
ssl_handshaker_destroy(tsi_handshaker * self)1403 static void ssl_handshaker_destroy(tsi_handshaker* self) {
1404 tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
1405 SSL_free(impl->ssl);
1406 BIO_free(impl->network_io);
1407 gpr_free(impl->outgoing_bytes_buffer);
1408 tsi_ssl_handshaker_factory_unref(impl->factory_ref);
1409 gpr_free(impl);
1410 }
1411
ssl_handshaker_next(tsi_handshaker * self,const unsigned char * received_bytes,size_t received_bytes_size,const unsigned char ** bytes_to_send,size_t * bytes_to_send_size,tsi_handshaker_result ** handshaker_result,tsi_handshaker_on_next_done_cb,void *)1412 static tsi_result ssl_handshaker_next(
1413 tsi_handshaker* self, const unsigned char* received_bytes,
1414 size_t received_bytes_size, const unsigned char** bytes_to_send,
1415 size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
1416 tsi_handshaker_on_next_done_cb /*cb*/, void* /*user_data*/) {
1417 /* Input sanity check. */
1418 if ((received_bytes_size > 0 && received_bytes == nullptr) ||
1419 bytes_to_send == nullptr || bytes_to_send_size == nullptr ||
1420 handshaker_result == nullptr) {
1421 return TSI_INVALID_ARGUMENT;
1422 }
1423 /* If there are received bytes, process them first. */
1424 tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
1425 tsi_result status = TSI_OK;
1426 size_t bytes_consumed = received_bytes_size;
1427 if (received_bytes_size > 0) {
1428 status = ssl_handshaker_process_bytes_from_peer(impl, received_bytes,
1429 &bytes_consumed);
1430 if (status != TSI_OK) return status;
1431 }
1432 /* Get bytes to send to the peer, if available. */
1433 size_t offset = 0;
1434 do {
1435 size_t to_send_size = impl->outgoing_bytes_buffer_size - offset;
1436 status = ssl_handshaker_get_bytes_to_send_to_peer(
1437 impl, impl->outgoing_bytes_buffer + offset, &to_send_size);
1438 offset += to_send_size;
1439 if (status == TSI_INCOMPLETE_DATA) {
1440 impl->outgoing_bytes_buffer_size *= 2;
1441 impl->outgoing_bytes_buffer = static_cast<unsigned char*>(gpr_realloc(
1442 impl->outgoing_bytes_buffer, impl->outgoing_bytes_buffer_size));
1443 }
1444 } while (status == TSI_INCOMPLETE_DATA);
1445 if (status != TSI_OK) return status;
1446 *bytes_to_send = impl->outgoing_bytes_buffer;
1447 *bytes_to_send_size = offset;
1448 /* If handshake completes, create tsi_handshaker_result. */
1449 if (ssl_handshaker_get_result(impl) == TSI_HANDSHAKE_IN_PROGRESS) {
1450 *handshaker_result = nullptr;
1451 } else {
1452 size_t unused_bytes_size = received_bytes_size - bytes_consumed;
1453 const unsigned char* unused_bytes =
1454 unused_bytes_size == 0 ? nullptr : received_bytes + bytes_consumed;
1455 status = ssl_handshaker_result_create(impl, unused_bytes, unused_bytes_size,
1456 handshaker_result);
1457 if (status == TSI_OK) {
1458 /* Indicates that the handshake has completed and that a handshaker_result
1459 * has been created. */
1460 self->handshaker_result_created = true;
1461 }
1462 }
1463 return status;
1464 }
1465
1466 static const tsi_handshaker_vtable handshaker_vtable = {
1467 nullptr, /* get_bytes_to_send_to_peer -- deprecated */
1468 nullptr, /* process_bytes_from_peer -- deprecated */
1469 nullptr, /* get_result -- deprecated */
1470 nullptr, /* extract_peer -- deprecated */
1471 nullptr, /* create_frame_protector -- deprecated */
1472 ssl_handshaker_destroy,
1473 ssl_handshaker_next,
1474 nullptr, /* shutdown */
1475 };
1476
1477 /* --- tsi_ssl_handshaker_factory common methods. --- */
1478
tsi_ssl_handshaker_resume_session(SSL * ssl,tsi::SslSessionLRUCache * session_cache)1479 static void tsi_ssl_handshaker_resume_session(
1480 SSL* ssl, tsi::SslSessionLRUCache* session_cache) {
1481 const char* server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1482 if (server_name == nullptr) {
1483 return;
1484 }
1485 tsi::SslSessionPtr session = session_cache->Get(server_name);
1486 if (session != nullptr) {
1487 // SSL_set_session internally increments reference counter.
1488 SSL_set_session(ssl, session.get());
1489 }
1490 }
1491
create_tsi_ssl_handshaker(SSL_CTX * ctx,int is_client,const char * server_name_indication,tsi_ssl_handshaker_factory * factory,tsi_handshaker ** handshaker)1492 static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
1493 const char* server_name_indication,
1494 tsi_ssl_handshaker_factory* factory,
1495 tsi_handshaker** handshaker) {
1496 SSL* ssl = SSL_new(ctx);
1497 BIO* network_io = nullptr;
1498 BIO* ssl_io = nullptr;
1499 tsi_ssl_handshaker* impl = nullptr;
1500 *handshaker = nullptr;
1501 if (ctx == nullptr) {
1502 gpr_log(GPR_ERROR, "SSL Context is null. Should never happen.");
1503 return TSI_INTERNAL_ERROR;
1504 }
1505 if (ssl == nullptr) {
1506 return TSI_OUT_OF_RESOURCES;
1507 }
1508 SSL_set_info_callback(ssl, ssl_info_callback);
1509
1510 if (!BIO_new_bio_pair(&network_io, 0, &ssl_io, 0)) {
1511 gpr_log(GPR_ERROR, "BIO_new_bio_pair failed.");
1512 SSL_free(ssl);
1513 return TSI_OUT_OF_RESOURCES;
1514 }
1515 SSL_set_bio(ssl, ssl_io, ssl_io);
1516 if (is_client) {
1517 int ssl_result;
1518 SSL_set_connect_state(ssl);
1519 if (server_name_indication != nullptr) {
1520 if (!SSL_set_tlsext_host_name(ssl, server_name_indication)) {
1521 gpr_log(GPR_ERROR, "Invalid server name indication %s.",
1522 server_name_indication);
1523 SSL_free(ssl);
1524 BIO_free(network_io);
1525 return TSI_INTERNAL_ERROR;
1526 }
1527 }
1528 tsi_ssl_client_handshaker_factory* client_factory =
1529 reinterpret_cast<tsi_ssl_client_handshaker_factory*>(factory);
1530 if (client_factory->session_cache != nullptr) {
1531 tsi_ssl_handshaker_resume_session(ssl,
1532 client_factory->session_cache.get());
1533 }
1534 ssl_result = SSL_do_handshake(ssl);
1535 ssl_result = SSL_get_error(ssl, ssl_result);
1536 if (ssl_result != SSL_ERROR_WANT_READ) {
1537 gpr_log(GPR_ERROR,
1538 "Unexpected error received from first SSL_do_handshake call: %s",
1539 ssl_error_string(ssl_result));
1540 SSL_free(ssl);
1541 BIO_free(network_io);
1542 return TSI_INTERNAL_ERROR;
1543 }
1544 } else {
1545 SSL_set_accept_state(ssl);
1546 }
1547
1548 impl = static_cast<tsi_ssl_handshaker*>(gpr_zalloc(sizeof(*impl)));
1549 impl->ssl = ssl;
1550 impl->network_io = network_io;
1551 impl->result = TSI_HANDSHAKE_IN_PROGRESS;
1552 impl->outgoing_bytes_buffer_size =
1553 TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE;
1554 impl->outgoing_bytes_buffer =
1555 static_cast<unsigned char*>(gpr_zalloc(impl->outgoing_bytes_buffer_size));
1556 impl->base.vtable = &handshaker_vtable;
1557 impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
1558 *handshaker = &impl->base;
1559 return TSI_OK;
1560 }
1561
select_protocol_list(const unsigned char ** out,unsigned char * outlen,const unsigned char * client_list,size_t client_list_len,const unsigned char * server_list,size_t server_list_len)1562 static int select_protocol_list(const unsigned char** out,
1563 unsigned char* outlen,
1564 const unsigned char* client_list,
1565 size_t client_list_len,
1566 const unsigned char* server_list,
1567 size_t server_list_len) {
1568 const unsigned char* client_current = client_list;
1569 while (static_cast<unsigned int>(client_current - client_list) <
1570 client_list_len) {
1571 unsigned char client_current_len = *(client_current++);
1572 const unsigned char* server_current = server_list;
1573 while ((server_current >= server_list) &&
1574 static_cast<uintptr_t>(server_current - server_list) <
1575 server_list_len) {
1576 unsigned char server_current_len = *(server_current++);
1577 if ((client_current_len == server_current_len) &&
1578 !memcmp(client_current, server_current, server_current_len)) {
1579 *out = server_current;
1580 *outlen = server_current_len;
1581 return SSL_TLSEXT_ERR_OK;
1582 }
1583 server_current += server_current_len;
1584 }
1585 client_current += client_current_len;
1586 }
1587 return SSL_TLSEXT_ERR_NOACK;
1588 }
1589
1590 /* --- tsi_ssl_client_handshaker_factory methods implementation. --- */
1591
tsi_ssl_client_handshaker_factory_create_handshaker(tsi_ssl_client_handshaker_factory * self,const char * server_name_indication,tsi_handshaker ** handshaker)1592 tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
1593 tsi_ssl_client_handshaker_factory* self, const char* server_name_indication,
1594 tsi_handshaker** handshaker) {
1595 return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
1596 &self->base, handshaker);
1597 }
1598
tsi_ssl_client_handshaker_factory_unref(tsi_ssl_client_handshaker_factory * self)1599 void tsi_ssl_client_handshaker_factory_unref(
1600 tsi_ssl_client_handshaker_factory* self) {
1601 if (self == nullptr) return;
1602 tsi_ssl_handshaker_factory_unref(&self->base);
1603 }
1604
tsi_ssl_client_handshaker_factory_destroy(tsi_ssl_handshaker_factory * factory)1605 static void tsi_ssl_client_handshaker_factory_destroy(
1606 tsi_ssl_handshaker_factory* factory) {
1607 if (factory == nullptr) return;
1608 tsi_ssl_client_handshaker_factory* self =
1609 reinterpret_cast<tsi_ssl_client_handshaker_factory*>(factory);
1610 if (self->ssl_context != nullptr) SSL_CTX_free(self->ssl_context);
1611 if (self->alpn_protocol_list != nullptr) gpr_free(self->alpn_protocol_list);
1612 self->session_cache.reset();
1613 gpr_free(self);
1614 }
1615
client_handshaker_factory_npn_callback(SSL *,unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)1616 static int client_handshaker_factory_npn_callback(
1617 SSL* /*ssl*/, unsigned char** out, unsigned char* outlen,
1618 const unsigned char* in, unsigned int inlen, void* arg) {
1619 tsi_ssl_client_handshaker_factory* factory =
1620 static_cast<tsi_ssl_client_handshaker_factory*>(arg);
1621 return select_protocol_list((const unsigned char**)out, outlen,
1622 factory->alpn_protocol_list,
1623 factory->alpn_protocol_list_length, in, inlen);
1624 }
1625
1626 /* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
1627
tsi_ssl_server_handshaker_factory_create_handshaker(tsi_ssl_server_handshaker_factory * self,tsi_handshaker ** handshaker)1628 tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
1629 tsi_ssl_server_handshaker_factory* self, tsi_handshaker** handshaker) {
1630 if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
1631 /* Create the handshaker with the first context. We will switch if needed
1632 because of SNI in ssl_server_handshaker_factory_servername_callback. */
1633 return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, nullptr,
1634 &self->base, handshaker);
1635 }
1636
tsi_ssl_server_handshaker_factory_unref(tsi_ssl_server_handshaker_factory * self)1637 void tsi_ssl_server_handshaker_factory_unref(
1638 tsi_ssl_server_handshaker_factory* self) {
1639 if (self == nullptr) return;
1640 tsi_ssl_handshaker_factory_unref(&self->base);
1641 }
1642
tsi_ssl_server_handshaker_factory_destroy(tsi_ssl_handshaker_factory * factory)1643 static void tsi_ssl_server_handshaker_factory_destroy(
1644 tsi_ssl_handshaker_factory* factory) {
1645 if (factory == nullptr) return;
1646 tsi_ssl_server_handshaker_factory* self =
1647 reinterpret_cast<tsi_ssl_server_handshaker_factory*>(factory);
1648 size_t i;
1649 for (i = 0; i < self->ssl_context_count; i++) {
1650 if (self->ssl_contexts[i] != nullptr) {
1651 SSL_CTX_free(self->ssl_contexts[i]);
1652 tsi_peer_destruct(&self->ssl_context_x509_subject_names[i]);
1653 }
1654 }
1655 if (self->ssl_contexts != nullptr) gpr_free(self->ssl_contexts);
1656 if (self->ssl_context_x509_subject_names != nullptr) {
1657 gpr_free(self->ssl_context_x509_subject_names);
1658 }
1659 if (self->alpn_protocol_list != nullptr) gpr_free(self->alpn_protocol_list);
1660 gpr_free(self);
1661 }
1662
does_entry_match_name(absl::string_view entry,absl::string_view name)1663 static int does_entry_match_name(absl::string_view entry,
1664 absl::string_view name) {
1665 if (entry.empty()) return 0;
1666
1667 /* Take care of '.' terminations. */
1668 if (name.back() == '.') {
1669 name.remove_suffix(1);
1670 }
1671 if (entry.back() == '.') {
1672 entry.remove_suffix(1);
1673 if (entry.empty()) return 0;
1674 }
1675
1676 if (absl::EqualsIgnoreCase(name, entry)) {
1677 return 1; /* Perfect match. */
1678 }
1679 if (entry.front() != '*') return 0;
1680
1681 /* Wildchar subdomain matching. */
1682 if (entry.size() < 3 || entry[1] != '.') { /* At least *.x */
1683 gpr_log(GPR_ERROR, "Invalid wildchar entry.");
1684 return 0;
1685 }
1686 size_t name_subdomain_pos = name.find('.');
1687 if (name_subdomain_pos == absl::string_view::npos) return 0;
1688 if (name_subdomain_pos >= name.size() - 2) return 0;
1689 absl::string_view name_subdomain =
1690 name.substr(name_subdomain_pos + 1); /* Starts after the dot. */
1691 entry.remove_prefix(2); /* Remove *. */
1692 size_t dot = name_subdomain.find('.');
1693 if (dot == absl::string_view::npos || dot == name_subdomain.size() - 1) {
1694 gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s",
1695 std::string(name_subdomain).c_str());
1696 return 0;
1697 }
1698 if (name_subdomain.back() == '.') {
1699 name_subdomain.remove_suffix(1);
1700 }
1701 return !entry.empty() && absl::EqualsIgnoreCase(name_subdomain, entry);
1702 }
1703
ssl_server_handshaker_factory_servername_callback(SSL * ssl,int *,void * arg)1704 static int ssl_server_handshaker_factory_servername_callback(SSL* ssl,
1705 int* /*ap*/,
1706 void* arg) {
1707 tsi_ssl_server_handshaker_factory* impl =
1708 static_cast<tsi_ssl_server_handshaker_factory*>(arg);
1709 size_t i = 0;
1710 const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1711 if (servername == nullptr || strlen(servername) == 0) {
1712 return SSL_TLSEXT_ERR_NOACK;
1713 }
1714
1715 for (i = 0; i < impl->ssl_context_count; i++) {
1716 if (tsi_ssl_peer_matches_name(&impl->ssl_context_x509_subject_names[i],
1717 servername)) {
1718 SSL_set_SSL_CTX(ssl, impl->ssl_contexts[i]);
1719 return SSL_TLSEXT_ERR_OK;
1720 }
1721 }
1722 gpr_log(GPR_ERROR, "No match found for server name: %s.", servername);
1723 return SSL_TLSEXT_ERR_NOACK;
1724 }
1725
1726 #if TSI_OPENSSL_ALPN_SUPPORT
server_handshaker_factory_alpn_callback(SSL *,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)1727 static int server_handshaker_factory_alpn_callback(
1728 SSL* /*ssl*/, const unsigned char** out, unsigned char* outlen,
1729 const unsigned char* in, unsigned int inlen, void* arg) {
1730 tsi_ssl_server_handshaker_factory* factory =
1731 static_cast<tsi_ssl_server_handshaker_factory*>(arg);
1732 return select_protocol_list(out, outlen, in, inlen,
1733 factory->alpn_protocol_list,
1734 factory->alpn_protocol_list_length);
1735 }
1736 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
1737
server_handshaker_factory_npn_advertised_callback(SSL *,const unsigned char ** out,unsigned int * outlen,void * arg)1738 static int server_handshaker_factory_npn_advertised_callback(
1739 SSL* /*ssl*/, const unsigned char** out, unsigned int* outlen, void* arg) {
1740 tsi_ssl_server_handshaker_factory* factory =
1741 static_cast<tsi_ssl_server_handshaker_factory*>(arg);
1742 *out = factory->alpn_protocol_list;
1743 GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX);
1744 *outlen = static_cast<unsigned int>(factory->alpn_protocol_list_length);
1745 return SSL_TLSEXT_ERR_OK;
1746 }
1747
1748 /// This callback is called when new \a session is established and ready to
1749 /// be cached. This session can be reused for new connections to similar
1750 /// servers at later point of time.
1751 /// It's intended to be used with SSL_CTX_sess_set_new_cb function.
1752 ///
1753 /// It returns 1 if callback takes ownership over \a session and 0 otherwise.
server_handshaker_factory_new_session_callback(SSL * ssl,SSL_SESSION * session)1754 static int server_handshaker_factory_new_session_callback(
1755 SSL* ssl, SSL_SESSION* session) {
1756 SSL_CTX* ssl_context = SSL_get_SSL_CTX(ssl);
1757 if (ssl_context == nullptr) {
1758 return 0;
1759 }
1760 void* arg = SSL_CTX_get_ex_data(ssl_context, g_ssl_ctx_ex_factory_index);
1761 tsi_ssl_client_handshaker_factory* factory =
1762 static_cast<tsi_ssl_client_handshaker_factory*>(arg);
1763 const char* server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1764 if (server_name == nullptr) {
1765 return 0;
1766 }
1767 factory->session_cache->Put(server_name, tsi::SslSessionPtr(session));
1768 // Return 1 to indicate transferred ownership over the given session.
1769 return 1;
1770 }
1771
1772 /* --- tsi_ssl_handshaker_factory constructors. --- */
1773
1774 static tsi_ssl_handshaker_factory_vtable client_handshaker_factory_vtable = {
1775 tsi_ssl_client_handshaker_factory_destroy};
1776
tsi_create_ssl_client_handshaker_factory(const tsi_ssl_pem_key_cert_pair * pem_key_cert_pair,const char * pem_root_certs,const char * cipher_suites,const char ** alpn_protocols,uint16_t num_alpn_protocols,tsi_ssl_client_handshaker_factory ** factory)1777 tsi_result tsi_create_ssl_client_handshaker_factory(
1778 const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair,
1779 const char* pem_root_certs, const char* cipher_suites,
1780 const char** alpn_protocols, uint16_t num_alpn_protocols,
1781 tsi_ssl_client_handshaker_factory** factory) {
1782 tsi_ssl_client_handshaker_options options;
1783 options.pem_key_cert_pair = pem_key_cert_pair;
1784 options.pem_root_certs = pem_root_certs;
1785 options.cipher_suites = cipher_suites;
1786 options.alpn_protocols = alpn_protocols;
1787 options.num_alpn_protocols = num_alpn_protocols;
1788 return tsi_create_ssl_client_handshaker_factory_with_options(&options,
1789 factory);
1790 }
1791
tsi_create_ssl_client_handshaker_factory_with_options(const tsi_ssl_client_handshaker_options * options,tsi_ssl_client_handshaker_factory ** factory)1792 tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
1793 const tsi_ssl_client_handshaker_options* options,
1794 tsi_ssl_client_handshaker_factory** factory) {
1795 SSL_CTX* ssl_context = nullptr;
1796 tsi_ssl_client_handshaker_factory* impl = nullptr;
1797 tsi_result result = TSI_OK;
1798
1799 gpr_once_init(&g_init_openssl_once, init_openssl);
1800
1801 if (factory == nullptr) return TSI_INVALID_ARGUMENT;
1802 *factory = nullptr;
1803 if (options->pem_root_certs == nullptr && options->root_store == nullptr) {
1804 return TSI_INVALID_ARGUMENT;
1805 }
1806
1807 #if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L
1808 ssl_context = SSL_CTX_new(TLS_method());
1809 #else
1810 ssl_context = SSL_CTX_new(TLSv1_2_method());
1811 #endif
1812 if (ssl_context == nullptr) {
1813 gpr_log(GPR_ERROR, "Could not create ssl context.");
1814 return TSI_INVALID_ARGUMENT;
1815 }
1816
1817 impl = static_cast<tsi_ssl_client_handshaker_factory*>(
1818 gpr_zalloc(sizeof(*impl)));
1819 tsi_ssl_handshaker_factory_init(&impl->base);
1820 impl->base.vtable = &client_handshaker_factory_vtable;
1821 impl->ssl_context = ssl_context;
1822 if (options->session_cache != nullptr) {
1823 // Unref is called manually on factory destruction.
1824 impl->session_cache =
1825 reinterpret_cast<tsi::SslSessionLRUCache*>(options->session_cache)
1826 ->Ref();
1827 SSL_CTX_set_ex_data(ssl_context, g_ssl_ctx_ex_factory_index, impl);
1828 SSL_CTX_sess_set_new_cb(ssl_context,
1829 server_handshaker_factory_new_session_callback);
1830 SSL_CTX_set_session_cache_mode(ssl_context, SSL_SESS_CACHE_CLIENT);
1831 }
1832
1833 do {
1834 result = populate_ssl_context(ssl_context, options->pem_key_cert_pair,
1835 options->cipher_suites);
1836 if (result != TSI_OK) break;
1837
1838 #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
1839 // X509_STORE_up_ref is only available since OpenSSL 1.1.
1840 if (options->root_store != nullptr) {
1841 X509_STORE_up_ref(options->root_store->store);
1842 SSL_CTX_set_cert_store(ssl_context, options->root_store->store);
1843 }
1844 #endif
1845 if (OPENSSL_VERSION_NUMBER < 0x10100000 || options->root_store == nullptr) {
1846 result = ssl_ctx_load_verification_certs(
1847 ssl_context, options->pem_root_certs, strlen(options->pem_root_certs),
1848 nullptr);
1849 if (result != TSI_OK) {
1850 gpr_log(GPR_ERROR, "Cannot load server root certificates.");
1851 break;
1852 }
1853 }
1854
1855 if (options->num_alpn_protocols != 0) {
1856 result = build_alpn_protocol_name_list(
1857 options->alpn_protocols, options->num_alpn_protocols,
1858 &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
1859 if (result != TSI_OK) {
1860 gpr_log(GPR_ERROR, "Building alpn list failed with error %s.",
1861 tsi_result_to_string(result));
1862 break;
1863 }
1864 #if TSI_OPENSSL_ALPN_SUPPORT
1865 GPR_ASSERT(impl->alpn_protocol_list_length < UINT_MAX);
1866 if (SSL_CTX_set_alpn_protos(
1867 ssl_context, impl->alpn_protocol_list,
1868 static_cast<unsigned int>(impl->alpn_protocol_list_length))) {
1869 gpr_log(GPR_ERROR, "Could not set alpn protocol list to context.");
1870 result = TSI_INVALID_ARGUMENT;
1871 break;
1872 }
1873 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
1874 SSL_CTX_set_next_proto_select_cb(
1875 ssl_context, client_handshaker_factory_npn_callback, impl);
1876 }
1877 } while (0);
1878 if (result != TSI_OK) {
1879 tsi_ssl_handshaker_factory_unref(&impl->base);
1880 return result;
1881 }
1882 if (options->skip_server_certificate_verification) {
1883 SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NullVerifyCallback);
1884 } else {
1885 SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, nullptr);
1886 }
1887 /* TODO(jboeuf): Add revocation verification. */
1888
1889 *factory = impl;
1890 return TSI_OK;
1891 }
1892
1893 static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
1894 tsi_ssl_server_handshaker_factory_destroy};
1895
tsi_create_ssl_server_handshaker_factory(const tsi_ssl_pem_key_cert_pair * pem_key_cert_pairs,size_t num_key_cert_pairs,const char * pem_client_root_certs,int force_client_auth,const char * cipher_suites,const char ** alpn_protocols,uint16_t num_alpn_protocols,tsi_ssl_server_handshaker_factory ** factory)1896 tsi_result tsi_create_ssl_server_handshaker_factory(
1897 const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
1898 size_t num_key_cert_pairs, const char* pem_client_root_certs,
1899 int force_client_auth, const char* cipher_suites,
1900 const char** alpn_protocols, uint16_t num_alpn_protocols,
1901 tsi_ssl_server_handshaker_factory** factory) {
1902 return tsi_create_ssl_server_handshaker_factory_ex(
1903 pem_key_cert_pairs, num_key_cert_pairs, pem_client_root_certs,
1904 force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
1905 : TSI_DONT_REQUEST_CLIENT_CERTIFICATE,
1906 cipher_suites, alpn_protocols, num_alpn_protocols, factory);
1907 }
1908
tsi_create_ssl_server_handshaker_factory_ex(const tsi_ssl_pem_key_cert_pair * pem_key_cert_pairs,size_t num_key_cert_pairs,const char * pem_client_root_certs,tsi_client_certificate_request_type client_certificate_request,const char * cipher_suites,const char ** alpn_protocols,uint16_t num_alpn_protocols,tsi_ssl_server_handshaker_factory ** factory)1909 tsi_result tsi_create_ssl_server_handshaker_factory_ex(
1910 const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
1911 size_t num_key_cert_pairs, const char* pem_client_root_certs,
1912 tsi_client_certificate_request_type client_certificate_request,
1913 const char* cipher_suites, const char** alpn_protocols,
1914 uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory) {
1915 tsi_ssl_server_handshaker_options options;
1916 options.pem_key_cert_pairs = pem_key_cert_pairs;
1917 options.num_key_cert_pairs = num_key_cert_pairs;
1918 options.pem_client_root_certs = pem_client_root_certs;
1919 options.client_certificate_request = client_certificate_request;
1920 options.cipher_suites = cipher_suites;
1921 options.alpn_protocols = alpn_protocols;
1922 options.num_alpn_protocols = num_alpn_protocols;
1923 return tsi_create_ssl_server_handshaker_factory_with_options(&options,
1924 factory);
1925 }
1926
tsi_create_ssl_server_handshaker_factory_with_options(const tsi_ssl_server_handshaker_options * options,tsi_ssl_server_handshaker_factory ** factory)1927 tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
1928 const tsi_ssl_server_handshaker_options* options,
1929 tsi_ssl_server_handshaker_factory** factory) {
1930 tsi_ssl_server_handshaker_factory* impl = nullptr;
1931 tsi_result result = TSI_OK;
1932 size_t i = 0;
1933
1934 gpr_once_init(&g_init_openssl_once, init_openssl);
1935
1936 if (factory == nullptr) return TSI_INVALID_ARGUMENT;
1937 *factory = nullptr;
1938 if (options->num_key_cert_pairs == 0 ||
1939 options->pem_key_cert_pairs == nullptr) {
1940 return TSI_INVALID_ARGUMENT;
1941 }
1942
1943 impl = static_cast<tsi_ssl_server_handshaker_factory*>(
1944 gpr_zalloc(sizeof(*impl)));
1945 tsi_ssl_handshaker_factory_init(&impl->base);
1946 impl->base.vtable = &server_handshaker_factory_vtable;
1947
1948 impl->ssl_contexts = static_cast<SSL_CTX**>(
1949 gpr_zalloc(options->num_key_cert_pairs * sizeof(SSL_CTX*)));
1950 impl->ssl_context_x509_subject_names = static_cast<tsi_peer*>(
1951 gpr_zalloc(options->num_key_cert_pairs * sizeof(tsi_peer)));
1952 if (impl->ssl_contexts == nullptr ||
1953 impl->ssl_context_x509_subject_names == nullptr) {
1954 tsi_ssl_handshaker_factory_unref(&impl->base);
1955 return TSI_OUT_OF_RESOURCES;
1956 }
1957 impl->ssl_context_count = options->num_key_cert_pairs;
1958
1959 if (options->num_alpn_protocols > 0) {
1960 result = build_alpn_protocol_name_list(
1961 options->alpn_protocols, options->num_alpn_protocols,
1962 &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
1963 if (result != TSI_OK) {
1964 tsi_ssl_handshaker_factory_unref(&impl->base);
1965 return result;
1966 }
1967 }
1968
1969 for (i = 0; i < options->num_key_cert_pairs; i++) {
1970 do {
1971 #if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L
1972 impl->ssl_contexts[i] = SSL_CTX_new(TLS_method());
1973 #else
1974 impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method());
1975 #endif
1976 if (impl->ssl_contexts[i] == nullptr) {
1977 gpr_log(GPR_ERROR, "Could not create ssl context.");
1978 result = TSI_OUT_OF_RESOURCES;
1979 break;
1980 }
1981 result = populate_ssl_context(impl->ssl_contexts[i],
1982 &options->pem_key_cert_pairs[i],
1983 options->cipher_suites);
1984 if (result != TSI_OK) break;
1985
1986 // TODO(elessar): Provide ability to disable session ticket keys.
1987
1988 // Allow client cache sessions (it's needed for OpenSSL only).
1989 int set_sid_ctx_result = SSL_CTX_set_session_id_context(
1990 impl->ssl_contexts[i], kSslSessionIdContext,
1991 GPR_ARRAY_SIZE(kSslSessionIdContext));
1992 if (set_sid_ctx_result == 0) {
1993 gpr_log(GPR_ERROR, "Failed to set session id context.");
1994 result = TSI_INTERNAL_ERROR;
1995 break;
1996 }
1997
1998 if (options->session_ticket_key != nullptr) {
1999 if (SSL_CTX_set_tlsext_ticket_keys(
2000 impl->ssl_contexts[i],
2001 const_cast<char*>(options->session_ticket_key),
2002 options->session_ticket_key_size) == 0) {
2003 gpr_log(GPR_ERROR, "Invalid STEK size.");
2004 result = TSI_INVALID_ARGUMENT;
2005 break;
2006 }
2007 }
2008
2009 if (options->pem_client_root_certs != nullptr) {
2010 STACK_OF(X509_NAME)* root_names = nullptr;
2011 result = ssl_ctx_load_verification_certs(
2012 impl->ssl_contexts[i], options->pem_client_root_certs,
2013 strlen(options->pem_client_root_certs), &root_names);
2014 if (result != TSI_OK) {
2015 gpr_log(GPR_ERROR, "Invalid verification certs.");
2016 break;
2017 }
2018 SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names);
2019 }
2020 switch (options->client_certificate_request) {
2021 case TSI_DONT_REQUEST_CLIENT_CERTIFICATE:
2022 SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr);
2023 break;
2024 case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
2025 SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER,
2026 NullVerifyCallback);
2027 break;
2028 case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
2029 SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr);
2030 break;
2031 case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
2032 SSL_CTX_set_verify(impl->ssl_contexts[i],
2033 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2034 NullVerifyCallback);
2035 break;
2036 case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
2037 SSL_CTX_set_verify(impl->ssl_contexts[i],
2038 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2039 nullptr);
2040 break;
2041 }
2042 /* TODO(jboeuf): Add revocation verification. */
2043
2044 result = tsi_ssl_extract_x509_subject_names_from_pem_cert(
2045 options->pem_key_cert_pairs[i].cert_chain,
2046 &impl->ssl_context_x509_subject_names[i]);
2047 if (result != TSI_OK) break;
2048
2049 SSL_CTX_set_tlsext_servername_callback(
2050 impl->ssl_contexts[i],
2051 ssl_server_handshaker_factory_servername_callback);
2052 SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl);
2053 #if TSI_OPENSSL_ALPN_SUPPORT
2054 SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i],
2055 server_handshaker_factory_alpn_callback, impl);
2056 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
2057 SSL_CTX_set_next_protos_advertised_cb(
2058 impl->ssl_contexts[i],
2059 server_handshaker_factory_npn_advertised_callback, impl);
2060 } while (0);
2061
2062 if (result != TSI_OK) {
2063 tsi_ssl_handshaker_factory_unref(&impl->base);
2064 return result;
2065 }
2066 }
2067
2068 *factory = impl;
2069 return TSI_OK;
2070 }
2071
2072 /* --- tsi_ssl utils. --- */
2073
tsi_ssl_peer_matches_name(const tsi_peer * peer,absl::string_view name)2074 int tsi_ssl_peer_matches_name(const tsi_peer* peer, absl::string_view name) {
2075 size_t i = 0;
2076 size_t san_count = 0;
2077 const tsi_peer_property* cn_property = nullptr;
2078 int like_ip = looks_like_ip_address(name);
2079
2080 /* Check the SAN first. */
2081 for (i = 0; i < peer->property_count; i++) {
2082 const tsi_peer_property* property = &peer->properties[i];
2083 if (property->name == nullptr) continue;
2084 if (strcmp(property->name,
2085 TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
2086 san_count++;
2087
2088 absl::string_view entry(property->value.data, property->value.length);
2089 if (!like_ip && does_entry_match_name(entry, name)) {
2090 return 1;
2091 } else if (like_ip && name == entry) {
2092 /* IP Addresses are exact matches only. */
2093 return 1;
2094 }
2095 } else if (strcmp(property->name,
2096 TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
2097 cn_property = property;
2098 }
2099 }
2100
2101 /* If there's no SAN, try the CN, but only if its not like an IP Address */
2102 if (san_count == 0 && cn_property != nullptr && !like_ip) {
2103 if (does_entry_match_name(absl::string_view(cn_property->value.data,
2104 cn_property->value.length),
2105 name)) {
2106 return 1;
2107 }
2108 }
2109
2110 return 0; /* Not found. */
2111 }
2112
2113 /* --- Testing support. --- */
tsi_ssl_handshaker_factory_swap_vtable(tsi_ssl_handshaker_factory * factory,tsi_ssl_handshaker_factory_vtable * new_vtable)2114 const tsi_ssl_handshaker_factory_vtable* tsi_ssl_handshaker_factory_swap_vtable(
2115 tsi_ssl_handshaker_factory* factory,
2116 tsi_ssl_handshaker_factory_vtable* new_vtable) {
2117 GPR_ASSERT(factory != nullptr);
2118 GPR_ASSERT(factory->vtable != nullptr);
2119
2120 const tsi_ssl_handshaker_factory_vtable* orig_vtable = factory->vtable;
2121 factory->vtable = new_vtable;
2122 return orig_vtable;
2123 }
2124