1 /**
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0.
4 */
5
6 #include <aws/io/channel.h>
7 #include <aws/io/file_utils.h>
8 #include <aws/io/logging.h>
9 #include <aws/io/private/pem_utils.h>
10 #include <aws/io/private/tls_channel_handler_shared.h>
11 #include <aws/io/tls_channel_handler.h>
12
13 #define AWS_DEFAULT_TLS_TIMEOUT_MS 10000
14
15 #include <aws/common/string.h>
16
aws_tls_ctx_options_init_default_client(struct aws_tls_ctx_options * options,struct aws_allocator * allocator)17 void aws_tls_ctx_options_init_default_client(struct aws_tls_ctx_options *options, struct aws_allocator *allocator) {
18 AWS_ZERO_STRUCT(*options);
19 options->allocator = allocator;
20 options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
21 options->cipher_pref = AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT;
22 options->verify_peer = true;
23 options->max_fragment_size = g_aws_channel_max_fragment_size;
24 }
25
aws_tls_ctx_options_clean_up(struct aws_tls_ctx_options * options)26 void aws_tls_ctx_options_clean_up(struct aws_tls_ctx_options *options) {
27 aws_byte_buf_clean_up(&options->ca_file);
28 aws_string_destroy(options->ca_path);
29 aws_byte_buf_clean_up(&options->certificate);
30 aws_byte_buf_clean_up_secure(&options->private_key);
31
32 #ifdef __APPLE__
33 aws_byte_buf_clean_up_secure(&options->pkcs12);
34 aws_byte_buf_clean_up_secure(&options->pkcs12_password);
35
36 # if !defined(AWS_OS_IOS)
37 aws_string_destroy(options->keychain_path);
38 # endif
39 #endif
40
41 aws_string_destroy(options->alpn_list);
42
43 AWS_ZERO_STRUCT(*options);
44 }
45
46 #if !defined(AWS_OS_IOS)
47
aws_tls_ctx_options_init_client_mtls(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const struct aws_byte_cursor * cert,const struct aws_byte_cursor * pkey)48 int aws_tls_ctx_options_init_client_mtls(
49 struct aws_tls_ctx_options *options,
50 struct aws_allocator *allocator,
51 const struct aws_byte_cursor *cert,
52 const struct aws_byte_cursor *pkey) {
53
54 AWS_ZERO_STRUCT(*options);
55 options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
56 options->cipher_pref = AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT;
57 options->verify_peer = true;
58 options->allocator = allocator;
59 options->max_fragment_size = g_aws_channel_max_fragment_size;
60
61 if (aws_byte_buf_init_copy_from_cursor(&options->certificate, allocator, *cert)) {
62 goto error;
63 }
64
65 if (aws_sanitize_pem(&options->certificate, allocator)) {
66 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid certificate. File must contain PEM encoded data");
67 goto error;
68 }
69
70 if (aws_byte_buf_init_copy_from_cursor(&options->private_key, allocator, *pkey)) {
71 goto error;
72 }
73
74 if (aws_sanitize_pem(&options->private_key, allocator)) {
75 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid private key. File must contain PEM encoded data");
76 goto error;
77 }
78
79 return AWS_OP_SUCCESS;
80 error:
81 aws_tls_ctx_options_clean_up(options);
82 return AWS_OP_ERR;
83 }
84
aws_tls_ctx_options_init_client_mtls_from_path(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const char * cert_path,const char * pkey_path)85 int aws_tls_ctx_options_init_client_mtls_from_path(
86 struct aws_tls_ctx_options *options,
87 struct aws_allocator *allocator,
88 const char *cert_path,
89 const char *pkey_path) {
90
91 AWS_ZERO_STRUCT(*options);
92 options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
93 options->cipher_pref = AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT;
94 options->verify_peer = true;
95 options->allocator = allocator;
96 options->max_fragment_size = g_aws_channel_max_fragment_size;
97
98 if (aws_byte_buf_init_from_file(&options->certificate, allocator, cert_path)) {
99 goto error;
100 }
101
102 if (aws_sanitize_pem(&options->certificate, allocator)) {
103 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid certificate. File must contain PEM encoded data");
104 goto error;
105 }
106
107 if (aws_byte_buf_init_from_file(&options->private_key, allocator, pkey_path)) {
108 goto error;
109 }
110
111 if (aws_sanitize_pem(&options->private_key, allocator)) {
112 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid private key. File must contain PEM encoded data");
113 goto error;
114 }
115
116 return AWS_OP_SUCCESS;
117 error:
118 aws_tls_ctx_options_clean_up(options);
119 return AWS_OP_ERR;
120 }
121
122 # if defined(__APPLE__)
aws_tls_ctx_options_set_keychain_path(struct aws_tls_ctx_options * options,struct aws_byte_cursor * keychain_path_cursor)123 int aws_tls_ctx_options_set_keychain_path(
124 struct aws_tls_ctx_options *options,
125 struct aws_byte_cursor *keychain_path_cursor) {
126 options->keychain_path = aws_string_new_from_cursor(options->allocator, keychain_path_cursor);
127 if (!options->keychain_path) {
128 return AWS_OP_ERR;
129 }
130
131 return AWS_OP_SUCCESS;
132 }
133 # endif /* __APPLE__ */
134
135 #endif /* !AWS_OS_IOS */
136
137 #ifdef _WIN32
aws_tls_ctx_options_init_client_mtls_from_system_path(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const char * cert_reg_path)138 void aws_tls_ctx_options_init_client_mtls_from_system_path(
139 struct aws_tls_ctx_options *options,
140 struct aws_allocator *allocator,
141 const char *cert_reg_path) {
142 AWS_ZERO_STRUCT(*options);
143 options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
144 options->verify_peer = true;
145 options->allocator = allocator;
146 options->max_fragment_size = g_aws_channel_max_fragment_size;
147 options->system_certificate_path = cert_reg_path;
148 }
149
aws_tls_ctx_options_init_default_server_from_system_path(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const char * cert_reg_path)150 void aws_tls_ctx_options_init_default_server_from_system_path(
151 struct aws_tls_ctx_options *options,
152 struct aws_allocator *allocator,
153 const char *cert_reg_path) {
154 aws_tls_ctx_options_init_client_mtls_from_system_path(options, allocator, cert_reg_path);
155 options->verify_peer = false;
156 }
157 #endif /* _WIN32 */
158
159 #ifdef __APPLE__
aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const char * pkcs12_path,struct aws_byte_cursor * pkcs_pwd)160 int aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(
161 struct aws_tls_ctx_options *options,
162 struct aws_allocator *allocator,
163 const char *pkcs12_path,
164 struct aws_byte_cursor *pkcs_pwd) {
165 AWS_ZERO_STRUCT(*options);
166 options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
167 options->verify_peer = true;
168 options->allocator = allocator;
169 options->max_fragment_size = g_aws_channel_max_fragment_size;
170
171 if (aws_byte_buf_init_from_file(&options->pkcs12, allocator, pkcs12_path)) {
172 return AWS_OP_ERR;
173 }
174
175 if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12_password, allocator, *pkcs_pwd)) {
176 aws_byte_buf_clean_up_secure(&options->pkcs12);
177 return AWS_OP_ERR;
178 }
179
180 return AWS_OP_SUCCESS;
181 }
182
aws_tls_ctx_options_init_client_mtls_pkcs12(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,struct aws_byte_cursor * pkcs12,struct aws_byte_cursor * pkcs_pwd)183 int aws_tls_ctx_options_init_client_mtls_pkcs12(
184 struct aws_tls_ctx_options *options,
185 struct aws_allocator *allocator,
186 struct aws_byte_cursor *pkcs12,
187 struct aws_byte_cursor *pkcs_pwd) {
188 AWS_ZERO_STRUCT(*options);
189 options->minimum_tls_version = AWS_IO_TLS_VER_SYS_DEFAULTS;
190 options->verify_peer = true;
191 options->allocator = allocator;
192 options->max_fragment_size = g_aws_channel_max_fragment_size;
193
194 if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12, allocator, *pkcs12)) {
195 return AWS_OP_ERR;
196 }
197
198 if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12_password, allocator, *pkcs_pwd)) {
199 aws_byte_buf_clean_up_secure(&options->pkcs12);
200 return AWS_OP_ERR;
201 }
202
203 return AWS_OP_SUCCESS;
204 }
205
aws_tls_ctx_options_init_server_pkcs12_from_path(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const char * pkcs12_path,struct aws_byte_cursor * pkcs_password)206 int aws_tls_ctx_options_init_server_pkcs12_from_path(
207 struct aws_tls_ctx_options *options,
208 struct aws_allocator *allocator,
209 const char *pkcs12_path,
210 struct aws_byte_cursor *pkcs_password) {
211 if (aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(options, allocator, pkcs12_path, pkcs_password)) {
212 return AWS_OP_ERR;
213 }
214
215 options->verify_peer = false;
216 return AWS_OP_SUCCESS;
217 }
218
aws_tls_ctx_options_init_server_pkcs12(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,struct aws_byte_cursor * pkcs12,struct aws_byte_cursor * pkcs_password)219 int aws_tls_ctx_options_init_server_pkcs12(
220 struct aws_tls_ctx_options *options,
221 struct aws_allocator *allocator,
222 struct aws_byte_cursor *pkcs12,
223 struct aws_byte_cursor *pkcs_password) {
224 if (aws_tls_ctx_options_init_client_mtls_pkcs12(options, allocator, pkcs12, pkcs_password)) {
225 return AWS_OP_ERR;
226 }
227
228 options->verify_peer = false;
229 return AWS_OP_SUCCESS;
230 }
231
232 #endif /* __APPLE__ */
233
234 #if !defined(AWS_OS_IOS)
235
aws_tls_ctx_options_init_default_server_from_path(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,const char * cert_path,const char * pkey_path)236 int aws_tls_ctx_options_init_default_server_from_path(
237 struct aws_tls_ctx_options *options,
238 struct aws_allocator *allocator,
239 const char *cert_path,
240 const char *pkey_path) {
241 if (aws_tls_ctx_options_init_client_mtls_from_path(options, allocator, cert_path, pkey_path)) {
242 return AWS_OP_ERR;
243 }
244
245 options->verify_peer = false;
246 return AWS_OP_SUCCESS;
247 }
248
aws_tls_ctx_options_init_default_server(struct aws_tls_ctx_options * options,struct aws_allocator * allocator,struct aws_byte_cursor * cert,struct aws_byte_cursor * pkey)249 int aws_tls_ctx_options_init_default_server(
250 struct aws_tls_ctx_options *options,
251 struct aws_allocator *allocator,
252 struct aws_byte_cursor *cert,
253 struct aws_byte_cursor *pkey) {
254 if (aws_tls_ctx_options_init_client_mtls(options, allocator, cert, pkey)) {
255 return AWS_OP_ERR;
256 }
257
258 options->verify_peer = false;
259 return AWS_OP_SUCCESS;
260 }
261
262 #endif /* AWS_OS_IOS */
263
aws_tls_ctx_options_set_alpn_list(struct aws_tls_ctx_options * options,const char * alpn_list)264 int aws_tls_ctx_options_set_alpn_list(struct aws_tls_ctx_options *options, const char *alpn_list) {
265 options->alpn_list = aws_string_new_from_c_str(options->allocator, alpn_list);
266 if (!options->alpn_list) {
267 return AWS_OP_ERR;
268 }
269
270 return AWS_OP_SUCCESS;
271 }
272
aws_tls_ctx_options_set_verify_peer(struct aws_tls_ctx_options * options,bool verify_peer)273 void aws_tls_ctx_options_set_verify_peer(struct aws_tls_ctx_options *options, bool verify_peer) {
274 options->verify_peer = verify_peer;
275 }
276
aws_tls_ctx_options_set_minimum_tls_version(struct aws_tls_ctx_options * options,enum aws_tls_versions minimum_tls_version)277 void aws_tls_ctx_options_set_minimum_tls_version(
278 struct aws_tls_ctx_options *options,
279 enum aws_tls_versions minimum_tls_version) {
280 options->minimum_tls_version = minimum_tls_version;
281 }
282
aws_tls_ctx_options_override_default_trust_store_from_path(struct aws_tls_ctx_options * options,const char * ca_path,const char * ca_file)283 int aws_tls_ctx_options_override_default_trust_store_from_path(
284 struct aws_tls_ctx_options *options,
285 const char *ca_path,
286 const char *ca_file) {
287
288 /* Note: on success these are not cleaned up, their data is "moved" into the options struct */
289 struct aws_string *ca_path_tmp = NULL;
290 struct aws_byte_buf ca_file_tmp;
291 AWS_ZERO_STRUCT(ca_file_tmp);
292
293 if (ca_path) {
294 if (options->ca_path) {
295 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: cannot override trust store multiple times");
296 aws_raise_error(AWS_ERROR_INVALID_STATE);
297 goto error;
298 }
299
300 ca_path_tmp = aws_string_new_from_c_str(options->allocator, ca_path);
301 if (!ca_path_tmp) {
302 goto error;
303 }
304 }
305
306 if (ca_file) {
307 if (aws_tls_options_buf_is_set(&options->ca_file)) {
308 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: cannot override trust store multiple times");
309 aws_raise_error(AWS_ERROR_INVALID_STATE);
310 goto error;
311 }
312
313 if (aws_byte_buf_init_from_file(&ca_file_tmp, options->allocator, ca_file)) {
314 goto error;
315 }
316
317 if (aws_sanitize_pem(&ca_file_tmp, options->allocator)) {
318 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid CA file. File must contain PEM encoded data");
319 goto error;
320 }
321 }
322
323 /* Success, set new values. (no need to clean up old values, we checked earlier that they were unallocated) */
324 if (ca_path) {
325 options->ca_path = ca_path_tmp;
326 }
327 if (ca_file) {
328 options->ca_file = ca_file_tmp;
329 }
330 return AWS_OP_SUCCESS;
331
332 error:
333 aws_string_destroy_secure(ca_path_tmp);
334 aws_byte_buf_clean_up_secure(&ca_file_tmp);
335 return AWS_OP_ERR;
336 }
337
aws_tls_ctx_options_set_extension_data(struct aws_tls_ctx_options * options,void * extension_data)338 void aws_tls_ctx_options_set_extension_data(struct aws_tls_ctx_options *options, void *extension_data) {
339 options->ctx_options_extension = extension_data;
340 }
341
aws_tls_ctx_options_override_default_trust_store(struct aws_tls_ctx_options * options,const struct aws_byte_cursor * ca_file)342 int aws_tls_ctx_options_override_default_trust_store(
343 struct aws_tls_ctx_options *options,
344 const struct aws_byte_cursor *ca_file) {
345
346 if (aws_tls_options_buf_is_set(&options->ca_file)) {
347 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: cannot override trust store multiple times");
348 return aws_raise_error(AWS_ERROR_INVALID_STATE);
349 }
350
351 if (aws_byte_buf_init_copy_from_cursor(&options->ca_file, options->allocator, *ca_file)) {
352 goto error;
353 }
354
355 if (aws_sanitize_pem(&options->ca_file, options->allocator)) {
356 AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: Invalid CA file. File must contain PEM encoded data");
357 goto error;
358 }
359
360 return AWS_OP_SUCCESS;
361
362 error:
363 aws_byte_buf_clean_up_secure(&options->ca_file);
364 return AWS_OP_ERR;
365 }
366
aws_tls_connection_options_init_from_ctx(struct aws_tls_connection_options * conn_options,struct aws_tls_ctx * ctx)367 void aws_tls_connection_options_init_from_ctx(
368 struct aws_tls_connection_options *conn_options,
369 struct aws_tls_ctx *ctx) {
370 AWS_ZERO_STRUCT(*conn_options);
371 /* the assumption here, is that if it was set in the context, we WANT it to be NULL here unless it's different.
372 * so only set verify peer at this point. */
373 conn_options->ctx = aws_tls_ctx_acquire(ctx);
374
375 conn_options->timeout_ms = AWS_DEFAULT_TLS_TIMEOUT_MS;
376 }
377
aws_tls_connection_options_copy(struct aws_tls_connection_options * to,const struct aws_tls_connection_options * from)378 int aws_tls_connection_options_copy(
379 struct aws_tls_connection_options *to,
380 const struct aws_tls_connection_options *from) {
381 /* copy everything copyable over, then override the rest with deep copies. */
382 *to = *from;
383
384 to->ctx = aws_tls_ctx_acquire(from->ctx);
385
386 if (from->alpn_list) {
387 to->alpn_list = aws_string_new_from_string(from->alpn_list->allocator, from->alpn_list);
388
389 if (!to->alpn_list) {
390 return AWS_OP_ERR;
391 }
392 }
393
394 if (from->server_name) {
395 to->server_name = aws_string_new_from_string(from->server_name->allocator, from->server_name);
396
397 if (!to->server_name) {
398 aws_string_destroy(to->server_name);
399 return AWS_OP_ERR;
400 }
401 }
402
403 return AWS_OP_SUCCESS;
404 }
405
aws_tls_connection_options_clean_up(struct aws_tls_connection_options * connection_options)406 void aws_tls_connection_options_clean_up(struct aws_tls_connection_options *connection_options) {
407 aws_tls_ctx_release(connection_options->ctx);
408
409 if (connection_options->alpn_list) {
410 aws_string_destroy(connection_options->alpn_list);
411 }
412
413 if (connection_options->server_name) {
414 aws_string_destroy(connection_options->server_name);
415 }
416
417 AWS_ZERO_STRUCT(*connection_options);
418 }
419
aws_tls_connection_options_set_callbacks(struct aws_tls_connection_options * conn_options,aws_tls_on_negotiation_result_fn * on_negotiation_result,aws_tls_on_data_read_fn * on_data_read,aws_tls_on_error_fn * on_error,void * user_data)420 void aws_tls_connection_options_set_callbacks(
421 struct aws_tls_connection_options *conn_options,
422 aws_tls_on_negotiation_result_fn *on_negotiation_result,
423 aws_tls_on_data_read_fn *on_data_read,
424 aws_tls_on_error_fn *on_error,
425 void *user_data) {
426 conn_options->on_negotiation_result = on_negotiation_result;
427 conn_options->on_data_read = on_data_read;
428 conn_options->on_error = on_error;
429 conn_options->user_data = user_data;
430 }
431
aws_tls_connection_options_set_server_name(struct aws_tls_connection_options * conn_options,struct aws_allocator * allocator,struct aws_byte_cursor * server_name)432 int aws_tls_connection_options_set_server_name(
433 struct aws_tls_connection_options *conn_options,
434 struct aws_allocator *allocator,
435 struct aws_byte_cursor *server_name) {
436
437 if (conn_options->server_name != NULL) {
438 aws_string_destroy(conn_options->server_name);
439 conn_options->server_name = NULL;
440 }
441
442 conn_options->server_name = aws_string_new_from_cursor(allocator, server_name);
443 if (!conn_options->server_name) {
444 return AWS_OP_ERR;
445 }
446
447 return AWS_OP_SUCCESS;
448 }
449
aws_tls_connection_options_set_alpn_list(struct aws_tls_connection_options * conn_options,struct aws_allocator * allocator,const char * alpn_list)450 int aws_tls_connection_options_set_alpn_list(
451 struct aws_tls_connection_options *conn_options,
452 struct aws_allocator *allocator,
453 const char *alpn_list) {
454
455 if (conn_options->alpn_list != NULL) {
456 aws_string_destroy(conn_options->alpn_list);
457 conn_options->alpn_list = NULL;
458 }
459
460 conn_options->alpn_list = aws_string_new_from_c_str(allocator, alpn_list);
461 if (!conn_options->alpn_list) {
462 return AWS_OP_ERR;
463 }
464
465 return AWS_OP_SUCCESS;
466 }
467
468 #ifdef BYO_CRYPTO
469
aws_tls_server_ctx_new(struct aws_allocator * alloc,const struct aws_tls_ctx_options * options)470 struct aws_tls_ctx *aws_tls_server_ctx_new(struct aws_allocator *alloc, const struct aws_tls_ctx_options *options) {
471 (void)alloc;
472 (void)options;
473 AWS_FATAL_ASSERT(
474 false &&
475 "When using BYO_CRYPTO, user is responsible for creating aws_tls_ctx manually. You cannot call this function.");
476 }
477
aws_tls_client_ctx_new(struct aws_allocator * alloc,const struct aws_tls_ctx_options * options)478 struct aws_tls_ctx *aws_tls_client_ctx_new(struct aws_allocator *alloc, const struct aws_tls_ctx_options *options) {
479 (void)alloc;
480 (void)options;
481 AWS_FATAL_ASSERT(
482 false &&
483 "When using BYO_CRYPTO, user is responsible for creating aws_tls_ctx manually. You cannot call this function.");
484 }
485
486 static aws_tls_handler_new_fn *s_client_handler_new = NULL;
487 static aws_tls_client_handler_start_negotiation_fn *s_start_negotiation_fn = NULL;
488 static void *s_client_user_data = NULL;
489
490 static aws_tls_handler_new_fn *s_server_handler_new = NULL;
491 static void *s_server_user_data = NULL;
492
aws_tls_client_handler_new(struct aws_allocator * allocator,struct aws_tls_connection_options * options,struct aws_channel_slot * slot)493 struct aws_channel_handler *aws_tls_client_handler_new(
494 struct aws_allocator *allocator,
495 struct aws_tls_connection_options *options,
496 struct aws_channel_slot *slot) {
497 AWS_FATAL_ASSERT(
498 s_client_handler_new &&
499 "For BYO_CRYPTO, you must call aws_tls_client_handler_new_set_callback() with a non-null value.");
500 return s_client_handler_new(allocator, options, slot, s_client_user_data);
501 }
502
aws_tls_server_handler_new(struct aws_allocator * allocator,struct aws_tls_connection_options * options,struct aws_channel_slot * slot)503 struct aws_channel_handler *aws_tls_server_handler_new(
504 struct aws_allocator *allocator,
505 struct aws_tls_connection_options *options,
506 struct aws_channel_slot *slot) {
507 AWS_FATAL_ASSERT(
508 s_client_handler_new &&
509 "For BYO_CRYPTO, you must call aws_tls_server_handler_new_set_callback() with a non-null value.")
510 return s_server_handler_new(allocator, options, slot, s_server_user_data);
511 }
512
aws_tls_byo_crypto_set_client_setup_options(const struct aws_tls_byo_crypto_setup_options * options)513 void aws_tls_byo_crypto_set_client_setup_options(const struct aws_tls_byo_crypto_setup_options *options) {
514 AWS_FATAL_ASSERT(options);
515 AWS_FATAL_ASSERT(options->new_handler_fn);
516 AWS_FATAL_ASSERT(options->start_negotiation_fn);
517
518 s_client_handler_new = options->new_handler_fn;
519 s_start_negotiation_fn = options->start_negotiation_fn;
520 s_client_user_data = options->user_data;
521 }
522
aws_tls_byo_crypto_set_server_setup_options(const struct aws_tls_byo_crypto_setup_options * options)523 void aws_tls_byo_crypto_set_server_setup_options(const struct aws_tls_byo_crypto_setup_options *options) {
524 AWS_FATAL_ASSERT(options);
525 AWS_FATAL_ASSERT(options->new_handler_fn);
526
527 s_server_handler_new = options->new_handler_fn;
528 s_server_user_data = options->user_data;
529 }
530
aws_tls_client_handler_start_negotiation(struct aws_channel_handler * handler)531 int aws_tls_client_handler_start_negotiation(struct aws_channel_handler *handler) {
532 AWS_FATAL_ASSERT(
533 s_start_negotiation_fn &&
534 "For BYO_CRYPTO, you must call aws_tls_client_handler_set_start_negotiation_callback() with a non-null value.")
535 return s_start_negotiation_fn(handler, s_client_user_data);
536 }
537
aws_tls_init_static_state(struct aws_allocator * alloc)538 void aws_tls_init_static_state(struct aws_allocator *alloc) {
539 (void)alloc;
540 }
541
aws_tls_clean_up_static_state(void)542 void aws_tls_clean_up_static_state(void) {}
543
544 #endif /* BYO_CRYPTO */
545
aws_channel_setup_client_tls(struct aws_channel_slot * right_of_slot,struct aws_tls_connection_options * tls_options)546 int aws_channel_setup_client_tls(
547 struct aws_channel_slot *right_of_slot,
548 struct aws_tls_connection_options *tls_options) {
549
550 AWS_FATAL_ASSERT(right_of_slot != NULL);
551 struct aws_channel *channel = right_of_slot->channel;
552 struct aws_allocator *allocator = right_of_slot->alloc;
553
554 struct aws_channel_slot *tls_slot = aws_channel_slot_new(channel);
555
556 /* as far as cleanup goes, since this stuff is being added to a channel, the caller will free this memory
557 when they clean up the channel. */
558 if (!tls_slot) {
559 return AWS_OP_ERR;
560 }
561
562 struct aws_channel_handler *tls_handler = aws_tls_client_handler_new(allocator, tls_options, tls_slot);
563 if (!tls_handler) {
564 aws_mem_release(allocator, tls_slot);
565 return AWS_OP_ERR;
566 }
567
568 /*
569 * From here on out, channel shutdown will handle slot/handler cleanup
570 */
571 aws_channel_slot_insert_right(right_of_slot, tls_slot);
572 AWS_LOGF_TRACE(
573 AWS_LS_IO_CHANNEL,
574 "id=%p: Setting up client TLS with handler %p on slot %p",
575 (void *)channel,
576 (void *)tls_handler,
577 (void *)tls_slot);
578
579 if (aws_channel_slot_set_handler(tls_slot, tls_handler) != AWS_OP_SUCCESS) {
580 return AWS_OP_ERR;
581 }
582
583 if (aws_tls_client_handler_start_negotiation(tls_handler) != AWS_OP_SUCCESS) {
584 return AWS_OP_ERR;
585 }
586
587 return AWS_OP_SUCCESS;
588 }
589
aws_tls_ctx_acquire(struct aws_tls_ctx * ctx)590 struct aws_tls_ctx *aws_tls_ctx_acquire(struct aws_tls_ctx *ctx) {
591 if (ctx != NULL) {
592 aws_ref_count_acquire(&ctx->ref_count);
593 }
594
595 return ctx;
596 }
597
aws_tls_ctx_release(struct aws_tls_ctx * ctx)598 void aws_tls_ctx_release(struct aws_tls_ctx *ctx) {
599 if (ctx != NULL) {
600 aws_ref_count_release(&ctx->ref_count);
601 }
602 }
603