1 #ifndef AWS_IO_TLS_CHANNEL_HANDLER_H 2 #define AWS_IO_TLS_CHANNEL_HANDLER_H 3 /** 4 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 * SPDX-License-Identifier: Apache-2.0. 6 */ 7 #include <aws/common/byte_buf.h> 8 #include <aws/common/ref_count.h> 9 #include <aws/io/io.h> 10 11 struct aws_channel_slot; 12 struct aws_channel_handler; 13 struct aws_string; 14 15 enum aws_tls_versions { 16 AWS_IO_SSLv3, 17 AWS_IO_TLSv1, 18 AWS_IO_TLSv1_1, 19 AWS_IO_TLSv1_2, 20 AWS_IO_TLSv1_3, 21 AWS_IO_TLS_VER_SYS_DEFAULTS = 128, 22 }; 23 24 enum aws_tls_cipher_pref { 25 AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT = 0, 26 AWS_IO_TLS_CIPHER_PREF_KMS_PQ_TLSv1_0_2019_06 = 1, 27 AWS_IO_TLS_CIPHER_PREF_KMS_PQ_SIKE_TLSv1_0_2019_11 = 2, 28 AWS_IO_TLS_CIPHER_PREF_KMS_PQ_TLSv1_0_2020_02 = 3, 29 AWS_IO_TLS_CIPHER_PREF_KMS_PQ_SIKE_TLSv1_0_2020_02 = 4, 30 AWS_IO_TLS_CIPHER_PREF_KMS_PQ_TLSv1_0_2020_07 = 5, 31 AWS_IO_TLS_CIPHER_PREF_PQ_TLSv1_0_2021_05 = 6, 32 33 AWS_IO_TLS_CIPHER_PREF_END_RANGE = 0xFFFF 34 }; 35 36 struct aws_tls_ctx { 37 struct aws_allocator *alloc; 38 void *impl; 39 struct aws_ref_count ref_count; 40 }; 41 42 /** 43 * Invoked upon completion of the TLS handshake. If successful error_code will be AWS_OP_SUCCESS, otherwise 44 * the negotiation failed and immediately after this function is invoked, the channel will be shutting down. 45 */ 46 typedef void(aws_tls_on_negotiation_result_fn)( 47 struct aws_channel_handler *handler, 48 struct aws_channel_slot *slot, 49 int error_code, 50 void *user_data); 51 52 /** 53 * Only used if the TLS handler is the last handler in the channel. This allows you to read any data that 54 * was read and decrypted by the handler. If you have application protocol channel handlers, this function 55 * is not necessary and certainly not recommended. 56 */ 57 typedef void(aws_tls_on_data_read_fn)( 58 struct aws_channel_handler *handler, 59 struct aws_channel_slot *slot, 60 struct aws_byte_buf *buffer, 61 void *user_data); 62 63 /** 64 * Invoked when an error occurs in the TLS state machine AFTER the handshake has completed. This function should only 65 * be used in conjunction with the rules of aws_tls_on_data_read_fn. 66 */ 67 typedef void(aws_tls_on_error_fn)( 68 struct aws_channel_handler *handler, 69 struct aws_channel_slot *slot, 70 int err, 71 const char *message, 72 void *user_data); 73 74 struct aws_tls_connection_options { 75 /** semi-colon delimited list of protocols. Example: 76 * h2;http/1.1 77 */ 78 struct aws_string *alpn_list; 79 /** 80 * Serves two purposes. If SNI is supported (hint... it is), 81 * this sets the SNI extension. 82 * 83 * For X.509 validation this also sets the name that will be used 84 * for verifying the subj alt name and common name of the peer's certificate. 85 */ 86 struct aws_string *server_name; 87 aws_tls_on_negotiation_result_fn *on_negotiation_result; 88 aws_tls_on_data_read_fn *on_data_read; 89 aws_tls_on_error_fn *on_error; 90 void *user_data; 91 struct aws_tls_ctx *ctx; 92 bool advertise_alpn_message; 93 uint32_t timeout_ms; 94 }; 95 96 struct aws_tls_ctx_options { 97 struct aws_allocator *allocator; 98 99 /** 100 * minimum tls version to use. If you just want us to use the 101 * system defaults, you can set: AWS_IO_TLS_VER_SYS_DEFAULTS. This 102 * has the added benefit of automatically picking up new TLS versions 103 * as your OS or distribution adds support. 104 */ 105 enum aws_tls_versions minimum_tls_version; 106 107 /** 108 * The Cipher Preference List to use 109 */ 110 enum aws_tls_cipher_pref cipher_pref; 111 112 /** 113 * A PEM armored PKCS#7 collection of CAs you want to trust as a string. 114 * Only use this if it's a CA not currently installed on your system. 115 */ 116 struct aws_byte_buf ca_file; 117 /** 118 * Only used on Unix systems using an openssl style trust API. 119 * this is typically something like /etc/pki/tls/certs/" 120 */ 121 struct aws_string *ca_path; 122 /** 123 * Sets ctx wide alpn string. This is most useful for servers. 124 * This is a semi-colon delimited list. example: 125 * h2;http/1.1 126 */ 127 struct aws_string *alpn_list; 128 /** 129 * A PEM armored PKCS#7 certificate as a string. 130 * It is supported on every operating system. 131 */ 132 struct aws_byte_buf certificate; 133 134 #ifdef _WIN32 135 /** The path to a system 136 * installed certficate/private key pair. Example: 137 * CurrentUser\\MY\\<thumprint> 138 */ 139 const char *system_certificate_path; 140 #endif 141 142 /** 143 * A PEM armored PKCS#7 private key as a string. 144 * 145 * On windows, this field should be NULL only if you are 146 * using a system installed certficate. 147 */ 148 struct aws_byte_buf private_key; 149 150 #ifdef __APPLE__ 151 /** 152 * Apple Only! 153 * 154 * On Apple OS you can also use a pkcs#12 for your certificate 155 * and private key. This is the contents the certificate. 156 */ 157 struct aws_byte_buf pkcs12; 158 159 /** 160 * Password for the pkcs12 data in pkcs12. 161 */ 162 struct aws_byte_buf pkcs12_password; 163 164 # if !defined(AWS_OS_IOS) 165 /** 166 * On Apple OS you can also use a custom keychain instead of 167 * the default keychain of the account. 168 */ 169 struct aws_string *keychain_path; 170 # endif 171 172 #endif 173 174 /** max tls fragment size. Default is the value of g_aws_channel_max_fragment_size. */ 175 size_t max_fragment_size; 176 177 /** 178 * default is true for clients and false for servers. 179 * You should not change this default for clients unless 180 * you're testing and don't want to fool around with CA trust stores. 181 * Before you release to production, you'll want to turn this back on 182 * and add your custom CA to the aws_tls_ctx_options. 183 * 184 * If you set this in server mode, it enforces client authentication. 185 */ 186 bool verify_peer; 187 188 /** 189 * For use when adding BYO_CRYPTO implementations. You can set extra data in here for use with your TLS 190 * implementation. 191 */ 192 void *ctx_options_extension; 193 }; 194 195 struct aws_tls_negotiated_protocol_message { 196 struct aws_byte_buf protocol; 197 }; 198 199 static const int AWS_TLS_NEGOTIATED_PROTOCOL_MESSAGE = 0x01; 200 201 typedef struct aws_channel_handler *( 202 *aws_tls_on_protocol_negotiated)(struct aws_channel_slot *new_slot, struct aws_byte_buf *protocol, void *user_data); 203 204 /** 205 * An enum for the current state of tls negotiation within a tls channel handler 206 */ 207 enum aws_tls_negotiation_status { 208 AWS_TLS_NEGOTIATION_STATUS_NONE, 209 AWS_TLS_NEGOTIATION_STATUS_ONGOING, 210 AWS_TLS_NEGOTIATION_STATUS_SUCCESS, 211 AWS_TLS_NEGOTIATION_STATUS_FAILURE 212 }; 213 214 #ifdef BYO_CRYPTO 215 /** 216 * Callback for creating a TLS handler. If you're using this you're using BYO_CRYPTO. This function should return 217 * a fully implemented aws_channel_handler instance for TLS. Note: the aws_tls_options passed to your 218 * aws_tls_handler_new_fn contains multiple callbacks. Namely: aws_tls_on_negotiation_result_fn. You are responsible for 219 * invoking this function when TLs session negotiation has completed. 220 */ 221 typedef struct aws_channel_handler *(aws_tls_handler_new_fn)( 222 struct aws_allocator *allocator, 223 struct aws_tls_connection_options *options, 224 struct aws_channel_slot *slot, 225 void *user_data); 226 227 /** 228 * Invoked when it's time to start TLS negotiation. Note: the aws_tls_options passed to your aws_tls_handler_new_fn 229 * contains multiple callbacks. Namely: aws_tls_on_negotiation_result_fn. You are responsible for invoking this function 230 * when TLS session negotiation has completed. 231 */ 232 typedef int(aws_tls_client_handler_start_negotiation_fn)(struct aws_channel_handler *handler, void *user_data); 233 234 struct aws_tls_byo_crypto_setup_options { 235 aws_tls_handler_new_fn *new_handler_fn; 236 /* ignored for server implementations, required for clients. */ 237 aws_tls_client_handler_start_negotiation_fn *start_negotiation_fn; 238 void *user_data; 239 }; 240 241 #endif /* BYO_CRYPTO */ 242 243 AWS_EXTERN_C_BEGIN 244 245 /******************************** tls options init stuff ***********************/ 246 /** 247 * Initializes options with default client options 248 */ 249 AWS_IO_API void aws_tls_ctx_options_init_default_client( 250 struct aws_tls_ctx_options *options, 251 struct aws_allocator *allocator); 252 /** 253 * Cleans up resources allocated by init_* functions 254 */ 255 AWS_IO_API void aws_tls_ctx_options_clean_up(struct aws_tls_ctx_options *options); 256 257 #if !defined(AWS_OS_IOS) 258 259 /** 260 * Initializes options for use with mutual tls in client mode. 261 * cert_path and pkey_path are paths to files on disk. cert_path 262 * and pkey_path are treated as PKCS#7 PEM armored. They are loaded 263 * from disk and stored in buffers internally. 264 */ 265 AWS_IO_API int aws_tls_ctx_options_init_client_mtls_from_path( 266 struct aws_tls_ctx_options *options, 267 struct aws_allocator *allocator, 268 const char *cert_path, 269 const char *pkey_path); 270 271 /** 272 * Initializes options for use with mutual tls in client mode. 273 * cert and pkey are copied. cert and pkey are treated as PKCS#7 PEM 274 * armored. 275 */ 276 AWS_IO_API int aws_tls_ctx_options_init_client_mtls( 277 struct aws_tls_ctx_options *options, 278 struct aws_allocator *allocator, 279 const struct aws_byte_cursor *cert, 280 const struct aws_byte_cursor *pkey); 281 282 # ifdef __APPLE__ 283 /** 284 * Sets a custom keychain path for storing the cert and pkey with mutual tls in client mode. 285 */ 286 AWS_IO_API int aws_tls_ctx_options_set_keychain_path( 287 struct aws_tls_ctx_options *options, 288 struct aws_byte_cursor *keychain_path_cursor); 289 # endif 290 291 /** 292 * Initializes options for use with in server mode. 293 * cert_path and pkey_path are paths to files on disk. cert_path 294 * and pkey_path are treated as PKCS#7 PEM armored. They are loaded 295 * from disk and stored in buffers internally. 296 */ 297 AWS_IO_API int aws_tls_ctx_options_init_default_server_from_path( 298 struct aws_tls_ctx_options *options, 299 struct aws_allocator *allocator, 300 const char *cert_path, 301 const char *pkey_path); 302 303 /** 304 * Initializes options for use with in server mode. 305 * cert and pkey are copied. cert and pkey are treated as PKCS#7 PEM 306 * armored. 307 */ 308 AWS_IO_API int aws_tls_ctx_options_init_default_server( 309 struct aws_tls_ctx_options *options, 310 struct aws_allocator *allocator, 311 struct aws_byte_cursor *cert, 312 struct aws_byte_cursor *pkey); 313 314 #endif /* AWS_OS_IOS */ 315 316 #ifdef _WIN32 317 /** 318 * Initializes options for use with mutual tls in client mode. This function is only available on 319 * windows. cert_reg_path is the path to a system 320 * installed certficate/private key pair. Example: 321 * CurrentUser\\MY\\<thumprint> 322 */ 323 AWS_IO_API void aws_tls_ctx_options_init_client_mtls_from_system_path( 324 struct aws_tls_ctx_options *options, 325 struct aws_allocator *allocator, 326 const char *cert_reg_path); 327 328 /** 329 * Initializes options for use with server mode. This function is only available on 330 * windows. cert_reg_path is the path to a system 331 * installed certficate/private key pair. Example: 332 * CurrentUser\\MY\\<thumprint> 333 */ 334 AWS_IO_API void aws_tls_ctx_options_init_default_server_from_system_path( 335 struct aws_tls_ctx_options *options, 336 struct aws_allocator *allocator, 337 const char *cert_reg_path); 338 #endif /* _WIN32 */ 339 340 #ifdef __APPLE__ 341 /** 342 * Initializes options for use with mutual tls in client mode. This function is only available on 343 * apple machines. pkcs12_path is a path to a file on disk containing a pkcs#12 file. The file is loaded 344 * into an internal buffer. pkcs_pwd is the corresponding password for the pkcs#12 file; it is copied. 345 */ 346 AWS_IO_API int aws_tls_ctx_options_init_client_mtls_pkcs12_from_path( 347 struct aws_tls_ctx_options *options, 348 struct aws_allocator *allocator, 349 const char *pkcs12_path, 350 struct aws_byte_cursor *pkcs_pwd); 351 352 /** 353 * Initializes options for use with mutual tls in client mode. This function is only available on 354 * apple machines. pkcs12 is a buffer containing a pkcs#12 certificate and private key; it is copied. 355 * pkcs_pwd is the corresponding password for the pkcs#12 buffer; it is copied. 356 */ 357 AWS_IO_API int aws_tls_ctx_options_init_client_mtls_pkcs12( 358 struct aws_tls_ctx_options *options, 359 struct aws_allocator *allocator, 360 struct aws_byte_cursor *pkcs12, 361 struct aws_byte_cursor *pkcs_pwd); 362 363 /** 364 * Initializes options for use in server mode. This function is only available on 365 * apple machines. pkcs12_path is a path to a file on disk containing a pkcs#12 file. The file is loaded 366 * into an internal buffer. pkcs_pwd is the corresponding password for the pkcs#12 file; it is copied. 367 */ 368 AWS_IO_API int aws_tls_ctx_options_init_server_pkcs12_from_path( 369 struct aws_tls_ctx_options *options, 370 struct aws_allocator *allocator, 371 const char *pkcs12_path, 372 struct aws_byte_cursor *pkcs_password); 373 374 /** 375 * Initializes options for use in server mode. This function is only available on 376 * apple machines. pkcs12 is a buffer containing a pkcs#12 certificate and private key; it is copied. 377 * pkcs_pwd is the corresponding password for the pkcs#12 buffer; it is copied. 378 */ 379 AWS_IO_API int aws_tls_ctx_options_init_server_pkcs12( 380 struct aws_tls_ctx_options *options, 381 struct aws_allocator *allocator, 382 struct aws_byte_cursor *pkcs12, 383 struct aws_byte_cursor *pkcs_password); 384 #endif /* __APPLE__ */ 385 386 /** 387 * Sets alpn list in the form <protocol1;protocol2;...>. A maximum of 4 protocols are supported. 388 * alpn_list is copied. 389 */ 390 AWS_IO_API int aws_tls_ctx_options_set_alpn_list(struct aws_tls_ctx_options *options, const char *alpn_list); 391 392 /** 393 * Enables or disables x.509 validation. Disable this only for testing. To enable mutual TLS in server mode, 394 * set verify_peer to true. 395 */ 396 AWS_IO_API void aws_tls_ctx_options_set_verify_peer(struct aws_tls_ctx_options *options, bool verify_peer); 397 398 /** 399 * Sets the minimum TLS version to allow. 400 */ 401 AWS_IO_API void aws_tls_ctx_options_set_minimum_tls_version( 402 struct aws_tls_ctx_options *options, 403 enum aws_tls_versions minimum_tls_version); 404 405 /** 406 * Override the default trust store. ca_file is a buffer containing a PEM armored chain of trusted CA certificates. 407 * ca_file is copied. 408 */ 409 AWS_IO_API int aws_tls_ctx_options_override_default_trust_store( 410 struct aws_tls_ctx_options *options, 411 const struct aws_byte_cursor *ca_file); 412 413 /** 414 * Override the default trust store. ca_path is a path to a directory on disk containing trusted certificates. This is 415 * only supported on Unix systems (otherwise this parameter is ignored). ca_file is a path to a file on disk containing 416 * trusted certificates. ca_file is loaded from disk and stored in an internal buffer. 417 */ 418 AWS_IO_API int aws_tls_ctx_options_override_default_trust_store_from_path( 419 struct aws_tls_ctx_options *options, 420 const char *ca_path, 421 const char *ca_file); 422 423 /** 424 * When implementing BYO_CRYPTO, if you need extra data to pass to your tls implementation, set it here. The lifetime of 425 * extension_data must outlive the options object and be cleaned up after options is cleaned up. 426 */ 427 AWS_IO_API void aws_tls_ctx_options_set_extension_data(struct aws_tls_ctx_options *options, void *extension_data); 428 429 /** 430 * Initializes default connection options from an instance ot aws_tls_ctx. 431 */ 432 AWS_IO_API void aws_tls_connection_options_init_from_ctx( 433 struct aws_tls_connection_options *conn_options, 434 struct aws_tls_ctx *ctx); 435 436 /** 437 * Cleans up resources in aws_tls_connection_options. This can be called immediately after initializing 438 * a tls handler, or if using the bootstrap api, immediately after asking for a channel. 439 */ 440 AWS_IO_API void aws_tls_connection_options_clean_up(struct aws_tls_connection_options *connection_options); 441 442 /** 443 * Copies 'from' to 'to' 444 */ 445 AWS_IO_API int aws_tls_connection_options_copy( 446 struct aws_tls_connection_options *to, 447 const struct aws_tls_connection_options *from); 448 449 /** 450 * Sets callbacks for use with a tls connection. 451 */ 452 AWS_IO_API void aws_tls_connection_options_set_callbacks( 453 struct aws_tls_connection_options *conn_options, 454 aws_tls_on_negotiation_result_fn *on_negotiation_result, 455 aws_tls_on_data_read_fn *on_data_read, 456 aws_tls_on_error_fn *on_error, 457 void *user_data); 458 459 /** 460 * Sets server name to use for the SNI extension (supported everywhere), as well as x.509 validation. If you don't 461 * set this, your x.509 validation will likely fail. 462 */ 463 AWS_IO_API int aws_tls_connection_options_set_server_name( 464 struct aws_tls_connection_options *conn_options, 465 struct aws_allocator *allocator, 466 struct aws_byte_cursor *server_name); 467 468 /** 469 * Sets alpn list in the form <protocol1;protocol2;...>. A maximum of 4 protocols are supported. 470 * alpn_list is copied. This value is already inherited from aws_tls_ctx, but the aws_tls_ctx is expensive, 471 * and should be used across as many connections as possible. If you want to set this per connection, set it here. 472 */ 473 AWS_IO_API int aws_tls_connection_options_set_alpn_list( 474 struct aws_tls_connection_options *conn_options, 475 struct aws_allocator *allocator, 476 const char *alpn_list); 477 478 /********************************* TLS context and state management *********************************/ 479 480 /** 481 * Returns true if alpn is available in the underlying tls implementation. 482 * This function should always be called before setting an alpn list. 483 */ 484 AWS_IO_API bool aws_tls_is_alpn_available(void); 485 486 /** 487 * Returns true if this Cipher Preference is available in the underlying TLS implementation. 488 * This function should always be called before setting a Cipher Preference 489 */ 490 AWS_IO_API bool aws_tls_is_cipher_pref_supported(enum aws_tls_cipher_pref cipher_pref); 491 492 /** 493 * Creates a new tls channel handler in client mode. Options will be copied. 494 * You must call aws_tls_client_handler_start_negotiation and wait on the 495 * aws_tls_on_negotiation_result_fn callback before the handler can begin processing 496 * application data. 497 */ 498 AWS_IO_API struct aws_channel_handler *aws_tls_client_handler_new( 499 struct aws_allocator *allocator, 500 struct aws_tls_connection_options *options, 501 struct aws_channel_slot *slot); 502 503 /** 504 * Creates a new tls channel handler in server mode. Options will be copied. 505 * You must wait on the aws_tls_on_negotiation_result_fn callback before the handler can begin processing 506 * application data. 507 */ 508 AWS_IO_API struct aws_channel_handler *aws_tls_server_handler_new( 509 struct aws_allocator *allocator, 510 struct aws_tls_connection_options *options, 511 struct aws_channel_slot *slot); 512 513 #ifdef BYO_CRYPTO 514 /** 515 * If using BYO_CRYPTO, you need to call this function prior to creating any client channels in the application. 516 */ 517 AWS_IO_API void aws_tls_byo_crypto_set_client_setup_options(const struct aws_tls_byo_crypto_setup_options *options); 518 /** 519 * If using BYO_CRYPTO, you need to call this function prior to creating any server channels in the application. 520 */ 521 AWS_IO_API void aws_tls_byo_crypto_set_server_setup_options(const struct aws_tls_byo_crypto_setup_options *options); 522 523 #endif /* BYO_CRYPTO */ 524 525 /** 526 * Creates a channel handler, for client or server mode, that handles alpn. This isn't necessarily required 527 * since you can always call aws_tls_handler_protocol in the aws_tls_on_negotiation_result_fn callback, but 528 * this makes channel bootstrap easier to handle. 529 */ 530 AWS_IO_API struct aws_channel_handler *aws_tls_alpn_handler_new( 531 struct aws_allocator *allocator, 532 aws_tls_on_protocol_negotiated on_protocol_negotiated, 533 void *user_data); 534 535 /** 536 * Kicks off the negotiation process. This function must be called when in client mode to initiate the 537 * TLS handshake. Once the handshake has completed the aws_tls_on_negotiation_result_fn will be invoked. 538 */ 539 AWS_IO_API int aws_tls_client_handler_start_negotiation(struct aws_channel_handler *handler); 540 541 #ifndef BYO_CRYPTO 542 /** 543 * Creates a new server ctx. This ctx can be used for the lifetime of the application assuming you want the same 544 * options for every incoming connection. Options will be copied. 545 */ 546 AWS_IO_API struct aws_tls_ctx *aws_tls_server_ctx_new( 547 struct aws_allocator *alloc, 548 const struct aws_tls_ctx_options *options); 549 550 /** 551 * Creates a new client ctx. This ctx can be used for the lifetime of the application assuming you want the same 552 * options for every outgoing connection. Options will be copied. 553 */ 554 AWS_IO_API struct aws_tls_ctx *aws_tls_client_ctx_new( 555 struct aws_allocator *alloc, 556 const struct aws_tls_ctx_options *options); 557 #endif /* BYO_CRYPTO */ 558 559 /** 560 * Increments the reference count on the tls context, allowing the caller to take a reference to it. 561 * 562 * Returns the same tls context passed in. 563 */ 564 AWS_IO_API struct aws_tls_ctx *aws_tls_ctx_acquire(struct aws_tls_ctx *ctx); 565 566 /** 567 * Decrements a tls context's ref count. When the ref count drops to zero, the object will be destroyed. 568 */ 569 AWS_IO_API void aws_tls_ctx_release(struct aws_tls_ctx *ctx); 570 571 /** 572 * Not necessary if you are installing more handlers into the channel, but if you just want to have TLS for arbitrary 573 * data and use the channel handler directly, this function allows you to write data to the channel and have it 574 * encrypted. 575 */ 576 AWS_IO_API int aws_tls_handler_write( 577 struct aws_channel_handler *handler, 578 struct aws_channel_slot *slot, 579 struct aws_byte_buf *buf, 580 aws_channel_on_message_write_completed_fn *on_write_completed, 581 void *completion_user_data); 582 583 /** 584 * Returns a byte buffer by copy of the negotiated protocols. If there is no agreed upon protocol, len will be 0 and 585 * buffer will be NULL. 586 */ 587 AWS_IO_API struct aws_byte_buf aws_tls_handler_protocol(struct aws_channel_handler *handler); 588 589 /** 590 * Client mode only. This is the server name that was used for SNI and host name validation. 591 */ 592 AWS_IO_API struct aws_byte_buf aws_tls_handler_server_name(struct aws_channel_handler *handler); 593 594 /********************************* Misc TLS related *********************************/ 595 596 /* 597 * Injects a tls handler/slot into a channel and begins tls negotiation. 598 * If desired, ALPN must be handled separately 599 * 600 * right_of_slot must be an existing slot in a channel 601 */ 602 AWS_IO_API int aws_channel_setup_client_tls( 603 struct aws_channel_slot *right_of_slot, 604 struct aws_tls_connection_options *tls_options); 605 606 AWS_EXTERN_C_END 607 608 #endif /* AWS_IO_TLS_CHANNEL_HANDLER_H */ 609