1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
|
#ifndef AWS_IO_TLS_CHANNEL_HANDLER_H
#define AWS_IO_TLS_CHANNEL_HANDLER_H
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/byte_buf.h>
#include <aws/common/ref_count.h>
#include <aws/io/io.h>
AWS_PUSH_SANE_WARNING_LEVEL
#define AWS_TLS_NEGOTIATED_PROTOCOL_MESSAGE 0x01
struct aws_channel_slot;
struct aws_channel_handler;
struct aws_pkcs11_session;
struct aws_string;
enum aws_tls_versions {
AWS_IO_SSLv3,
AWS_IO_TLSv1,
AWS_IO_TLSv1_1,
AWS_IO_TLSv1_2,
AWS_IO_TLSv1_3,
AWS_IO_TLS_VER_SYS_DEFAULTS = 128,
};
enum aws_tls_cipher_pref {
AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT = 0,
/* Deprecated */ AWS_IO_TLS_CIPHER_PREF_KMS_PQ_TLSv1_0_2019_06 = 1,
/* Deprecated */ AWS_IO_TLS_CIPHER_PREF_KMS_PQ_SIKE_TLSv1_0_2019_11 = 2,
/* Deprecated */ AWS_IO_TLS_CIPHER_PREF_KMS_PQ_TLSv1_0_2020_02 = 3,
/* Deprecated */ AWS_IO_TLS_CIPHER_PREF_KMS_PQ_SIKE_TLSv1_0_2020_02 = 4,
/* Deprecated */ AWS_IO_TLS_CIPHER_PREF_KMS_PQ_TLSv1_0_2020_07 = 5,
/*
* This TLS cipher preference list contains post-quantum key exchange algorithms that have been submitted to NIST
* for potential future standardization. Support for this preference list, or PQ algorithms present in it, may be
* removed at any time in the future. PQ algorithms in this preference list will be used in hybrid mode, and always
* combined with a classical ECDHE key exchange.
*/
AWS_IO_TLS_CIPHER_PREF_PQ_TLSv1_0_2021_05 = 6,
AWS_IO_TLS_CIPHER_PREF_END_RANGE = 0xFFFF
};
/**
* The hash algorithm of a TLS private key operation. Any custom private key operation handlers are expected to perform
* operations on the input TLS data using the correct hash algorithm or fail the operation.
*/
enum aws_tls_hash_algorithm {
AWS_TLS_HASH_UNKNOWN,
AWS_TLS_HASH_SHA1,
AWS_TLS_HASH_SHA224,
AWS_TLS_HASH_SHA256,
AWS_TLS_HASH_SHA384,
AWS_TLS_HASH_SHA512,
};
/**
* The signature of a TLS private key operation. Any custom private key operation handlers are expected to perform
* operations on the input TLS data using the correct signature algorithm or fail the operation.
*/
enum aws_tls_signature_algorithm {
AWS_TLS_SIGNATURE_UNKNOWN,
AWS_TLS_SIGNATURE_RSA,
AWS_TLS_SIGNATURE_ECDSA,
};
/**
* The TLS private key operation that needs to be performed by a custom private key operation handler when making
* a connection using mutual TLS.
*/
enum aws_tls_key_operation_type {
AWS_TLS_KEY_OPERATION_UNKNOWN,
AWS_TLS_KEY_OPERATION_SIGN,
AWS_TLS_KEY_OPERATION_DECRYPT,
};
struct aws_tls_ctx {
struct aws_allocator *alloc;
void *impl;
struct aws_ref_count ref_count;
};
/**
* Invoked upon completion of the TLS handshake. If successful error_code will be AWS_OP_SUCCESS, otherwise
* the negotiation failed and immediately after this function is invoked, the channel will be shutting down.
*/
typedef void(aws_tls_on_negotiation_result_fn)(
struct aws_channel_handler *handler,
struct aws_channel_slot *slot,
int error_code,
void *user_data);
/**
* Only used if the TLS handler is the last handler in the channel. This allows you to read any data that
* was read and decrypted by the handler. If you have application protocol channel handlers, this function
* is not necessary and certainly not recommended.
*/
typedef void(aws_tls_on_data_read_fn)(
struct aws_channel_handler *handler,
struct aws_channel_slot *slot,
struct aws_byte_buf *buffer,
void *user_data);
/**
* Invoked when an error occurs in the TLS state machine AFTER the handshake has completed. This function should only
* be used in conjunction with the rules of aws_tls_on_data_read_fn.
*/
typedef void(aws_tls_on_error_fn)(
struct aws_channel_handler *handler,
struct aws_channel_slot *slot,
int err,
const char *message,
void *user_data);
struct aws_tls_connection_options {
/** semi-colon delimited list of protocols. Example:
* h2;http/1.1
*/
struct aws_string *alpn_list;
/**
* Serves two purposes. If SNI is supported (hint... it is),
* this sets the SNI extension.
*
* For X.509 validation this also sets the name that will be used
* for verifying the subj alt name and common name of the peer's certificate.
*/
struct aws_string *server_name;
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;
struct aws_tls_ctx *ctx;
bool advertise_alpn_message;
uint32_t timeout_ms;
};
/**
* A struct containing all of the data needed for a private key operation when
* making a mutual TLS connection. This struct contains the data that needs
* to be operated on, like performing a sign operation or a decrypt operation.
*/
struct aws_tls_key_operation;
struct aws_tls_ctx_options {
struct aws_allocator *allocator;
/**
* minimum tls version to use. If you just want us to use the
* system defaults, you can set: AWS_IO_TLS_VER_SYS_DEFAULTS. This
* has the added benefit of automatically picking up new TLS versions
* as your OS or distribution adds support.
*/
enum aws_tls_versions minimum_tls_version;
/**
* The Cipher Preference List to use
*/
enum aws_tls_cipher_pref cipher_pref;
/**
* A PEM armored PKCS#7 collection of CAs you want to trust as a string.
* Only use this if it's a CA not currently installed on your system.
*/
struct aws_byte_buf ca_file;
/**
* Only used on Unix systems using an openssl style trust API.
* this is typically something like /etc/pki/tls/certs/"
*/
struct aws_string *ca_path;
/**
* Sets ctx wide alpn string. This is most useful for servers.
* This is a semi-colon delimited list. example:
* h2;http/1.1
*/
struct aws_string *alpn_list;
/**
* A PEM armored PKCS#7 certificate as a string.
* It is supported on every operating system.
*/
struct aws_byte_buf certificate;
#ifdef _WIN32
/** The path to a system
* installed certficate/private key pair. Example:
* CurrentUser\\MY\\<thumprint>
*/
const char *system_certificate_path;
#endif
/**
* A PEM armored PKCS#7 private key as a string.
*
* On windows, this field should be NULL only if you are
* using a system installed certficate.
*/
struct aws_byte_buf private_key;
#ifdef __APPLE__
/**
* Apple Only!
*
* On Apple OS you can also use a pkcs#12 for your certificate
* and private key. This is the contents the certificate.
*/
struct aws_byte_buf pkcs12;
/**
* Password for the pkcs12 data in pkcs12.
*/
struct aws_byte_buf pkcs12_password;
# if !defined(AWS_OS_IOS)
/**
* On Apple OS you can also use a custom keychain instead of
* the default keychain of the account.
*/
struct aws_string *keychain_path;
# endif
#endif
/** max tls fragment size. Default is the value of g_aws_channel_max_fragment_size. */
size_t max_fragment_size;
/**
* default is true for clients and false for servers.
* You should not change this default for clients unless
* you're testing and don't want to fool around with CA trust stores.
* Before you release to production, you'll want to turn this back on
* and add your custom CA to the aws_tls_ctx_options.
*
* If you set this in server mode, it enforces client authentication.
*/
bool verify_peer;
/**
* For use when adding BYO_CRYPTO implementations. You can set extra data in here for use with your TLS
* implementation.
*/
void *ctx_options_extension;
/**
* Set if using custom private key operations.
* See aws_custom_key_op_handler for more details
*
* Note: Custom key operations (and PKCS#11 integration) hasn't been tested with TLS 1.3, so don't use
* cipher preferences that allow TLS 1.3. If this is set, we will always use non TLS 1.3 preferences.
*/
struct aws_custom_key_op_handler *custom_key_op_handler;
};
struct aws_tls_negotiated_protocol_message {
struct aws_byte_buf protocol;
};
typedef struct aws_channel_handler *(
*aws_tls_on_protocol_negotiated)(struct aws_channel_slot *new_slot, struct aws_byte_buf *protocol, void *user_data);
/**
* An enum for the current state of tls negotiation within a tls channel handler
*/
enum aws_tls_negotiation_status {
AWS_TLS_NEGOTIATION_STATUS_NONE,
AWS_TLS_NEGOTIATION_STATUS_ONGOING,
AWS_TLS_NEGOTIATION_STATUS_SUCCESS,
AWS_TLS_NEGOTIATION_STATUS_FAILURE
};
#ifdef BYO_CRYPTO
/**
* Callback for creating a TLS handler. If you're using this you're using BYO_CRYPTO. This function should return
* a fully implemented aws_channel_handler instance for TLS. Note: the aws_tls_options passed to your
* aws_tls_handler_new_fn contains multiple callbacks. Namely: aws_tls_on_negotiation_result_fn. You are responsible for
* invoking this function when TLs session negotiation has completed.
*/
typedef struct aws_channel_handler *(aws_tls_handler_new_fn)(
struct aws_allocator *allocator,
struct aws_tls_connection_options *options,
struct aws_channel_slot *slot,
void *user_data);
/**
* Invoked when it's time to start TLS negotiation. Note: the aws_tls_options passed to your aws_tls_handler_new_fn
* contains multiple callbacks. Namely: aws_tls_on_negotiation_result_fn. You are responsible for invoking this function
* when TLS session negotiation has completed.
*/
typedef int(aws_tls_client_handler_start_negotiation_fn)(struct aws_channel_handler *handler, void *user_data);
struct aws_tls_byo_crypto_setup_options {
aws_tls_handler_new_fn *new_handler_fn;
/* ignored for server implementations, required for clients. */
aws_tls_client_handler_start_negotiation_fn *start_negotiation_fn;
void *user_data;
};
#endif /* BYO_CRYPTO */
AWS_EXTERN_C_BEGIN
/******************************** tls options init stuff ***********************/
/**
* Initializes options with default client options
*/
AWS_IO_API void aws_tls_ctx_options_init_default_client(
struct aws_tls_ctx_options *options,
struct aws_allocator *allocator);
/**
* Cleans up resources allocated by init_* functions
*/
AWS_IO_API void aws_tls_ctx_options_clean_up(struct aws_tls_ctx_options *options);
/**
* Initializes options for use with mutual tls in client mode.
* cert_path and pkey_path are paths to files on disk. cert_path
* and pkey_path are treated as PKCS#7 PEM armored. They are loaded
* from disk and stored in buffers internally.
*
* NOTE: This is unsupported on iOS.
*/
AWS_IO_API int 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);
/**
* Initializes options for use with mutual tls in client mode.
* cert and pkey are copied. cert and pkey are treated as PKCS#7 PEM
* armored.
*
* NOTE: This is unsupported on iOS.
*/
AWS_IO_API int 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);
/**
* vtable for aws_custom_key_op_handler.
*/
struct aws_custom_key_op_handler_vtable {
/**
* Called when the a TLS handshake has an operation it needs the custom key operation handler to perform.
* NOTE: You must call aws_tls_key_operation_complete() or aws_tls_key_operation_complete_with_error()
* otherwise the TLS handshake will stall the TLS connection indefinitely and leak memory.
*/
void (*on_key_operation)(struct aws_custom_key_op_handler *key_op_handler, struct aws_tls_key_operation *operation);
};
/**
* The custom key operation that is used when performing a mutual TLS handshake. This can
* be extended to provide custom private key operations, like PKCS11 or similar.
*/
struct aws_custom_key_op_handler {
/**
* A void* intended to be populated with a reference to whatever class is extending this class. For example,
* if you have extended aws_custom_key_op_handler with a custom struct, you would put a pointer to this struct
* to *impl so you can retrieve it back in the vtable functions.
*/
void *impl;
/**
* A vtable containing all of the functions the aws_custom_key_op_handler implements. Is intended to be extended.
* NOTE: Use "aws_custom_key_op_handler_<func>" to access vtable functions.
*/
const struct aws_custom_key_op_handler_vtable *vtable;
/**
* A reference count for handling memory usage.
* Use aws_custom_key_op_handler_acquire and aws_custom_key_op_handler_release to increase/decrease count.
*/
struct aws_ref_count ref_count;
};
/**
* Increases the reference count for the passed-in aws_custom_key_op_handler and returns it.
*/
AWS_IO_API struct aws_custom_key_op_handler *aws_custom_key_op_handler_acquire(
struct aws_custom_key_op_handler *key_op_handler);
/**
* Decreases the reference count for the passed-in aws_custom_key_op_handler and returns NULL.
*/
AWS_IO_API struct aws_custom_key_op_handler *aws_custom_key_op_handler_release(
struct aws_custom_key_op_handler *key_op_handler);
/**
* Calls the on_key_operation vtable function. See aws_custom_key_op_handler_vtable for function details.
*/
AWS_IO_API void aws_custom_key_op_handler_perform_operation(
struct aws_custom_key_op_handler *key_op_handler,
struct aws_tls_key_operation *operation);
/**
* Initializes options for use with mutual TLS in client mode,
* where private key operations are handled by custom code.
*
* Note: cert_file_contents will be copied into a new buffer after this
* function is called, so you do not need to keep that data alive
* after calling this function.
*
* @param options aws_tls_ctx_options to be initialized.
* @param allocator Allocator to use.
* @param custom Options for custom key operations.
* @param cert_file_contents The contents of a certificate file.
*/
AWS_IO_API int aws_tls_ctx_options_init_client_mtls_with_custom_key_operations(
struct aws_tls_ctx_options *options,
struct aws_allocator *allocator,
struct aws_custom_key_op_handler *custom,
const struct aws_byte_cursor *cert_file_contents);
/**
* This struct exists as a graceful way to pass many arguments when
* calling init-with-pkcs11 functions on aws_tls_ctx_options (this also makes
* it easy to introduce optional arguments in the future).
* Instances of this struct should only exist briefly on the stack.
*
* Instructions for binding this to high-level languages:
* - Python: The members of this struct should be the keyword args to the init-with-pkcs11 functions.
* - JavaScript: This should be an options map passed to init-with-pkcs11 functions.
* - Java: This should be an options class passed to init-with-pkcs11 functions.
* - C++: Same as Java
*
* Notes on integer types:
* PKCS#11 uses `unsigned long` for IDs, handles, etc but we expose them as `uint64_t` in public APIs.
* We do this because sizeof(long) is inconsistent across platform/arch/language
* (ex: always 64bit in Java, always 32bit in C on Windows, matches CPU in C on Linux and Apple).
* By using uint64_t in our public API, we can keep the careful bounds-checking all in one
* place, instead of expecting each high-level language binding to get it just right.
*/
struct aws_tls_ctx_pkcs11_options {
/**
* The PKCS#11 library to use.
* This field is required.
*/
struct aws_pkcs11_lib *pkcs11_lib;
/**
* User PIN, for logging into the PKCS#11 token (UTF-8).
* Zero out to log into a token with a "protected authentication path".
*/
struct aws_byte_cursor user_pin;
/**
* ID of slot containing PKCS#11 token.
* If set to NULL, the token will be chosen based on other criteria
* (such as token label).
*/
const uint64_t *slot_id;
/**
* Label of PKCS#11 token to use.
* If zeroed out, the token will be chosen based on other criteria
* (such as slot ID).
*/
struct aws_byte_cursor token_label;
/**
* Label of private key object on PKCS#11 token (UTF-8).
* If zeroed out, the private key will be chosen based on other criteria
* (such as being the only available private key on the token).
*/
struct aws_byte_cursor private_key_object_label;
/**
* Certificate's file path on disk (UTF-8).
* The certificate must be PEM formatted and UTF-8 encoded.
* Zero out if passing in certificate by some other means (such as file contents).
*/
struct aws_byte_cursor cert_file_path;
/**
* Certificate's file contents (UTF-8).
* The certificate must be PEM formatted and UTF-8 encoded.
* Zero out if passing in certificate by some other means (such as file path).
*/
struct aws_byte_cursor cert_file_contents;
};
/**
* Initializes options for use with mutual TLS in client mode,
* where a PKCS#11 library provides access to the private key.
*
* NOTE: This only works on Unix devices.
*
* @param options aws_tls_ctx_options to be initialized.
* @param allocator Allocator to use.
* @param pkcs11_options Options for using PKCS#11 (contents are copied)
*/
AWS_IO_API int aws_tls_ctx_options_init_client_mtls_with_pkcs11(
struct aws_tls_ctx_options *options,
struct aws_allocator *allocator,
const struct aws_tls_ctx_pkcs11_options *pkcs11_options);
/**
* @Deprecated
*
* Sets a custom keychain path for storing the cert and pkey with mutual tls in client mode.
*
* NOTE: This only works on MacOS.
*/
AWS_IO_API int aws_tls_ctx_options_set_keychain_path(
struct aws_tls_ctx_options *options,
struct aws_byte_cursor *keychain_path_cursor);
/**
* Initializes options for use with in server mode.
* cert_path and pkey_path are paths to files on disk. cert_path
* and pkey_path are treated as PKCS#7 PEM armored. They are loaded
* from disk and stored in buffers internally.
*/
AWS_IO_API int 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);
/**
* Initializes options for use with in server mode.
* cert and pkey are copied. cert and pkey are treated as PKCS#7 PEM
* armored.
*/
AWS_IO_API int 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);
/**
* Initializes options for use with mutual tls in client mode.
* cert_reg_path is the path to a system
* installed certficate/private key pair. Example:
* CurrentUser\\MY\\<thumprint>
*
* NOTE: This only works on Windows.
*/
AWS_IO_API int 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);
/**
* Initializes options for use with server mode.
* cert_reg_path is the path to a system
* installed certficate/private key pair. Example:
* CurrentUser\\MY\\<thumprint>
*
* NOTE: This only works on Windows.
*/
AWS_IO_API int 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);
/**
* Initializes options for use with mutual tls in client mode.
* pkcs12_path is a path to a file on disk containing a pkcs#12 file. The file is loaded
* into an internal buffer. pkcs_pwd is the corresponding password for the pkcs#12 file; it is copied.
*
* NOTE: This only works on Apple devices.
*/
AWS_IO_API int aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(
struct aws_tls_ctx_options *options,
struct aws_allocator *allocator,
const char *pkcs12_path,
const struct aws_byte_cursor *pkcs_pwd);
/**
* Initializes options for use with mutual tls in client mode.
* pkcs12 is a buffer containing a pkcs#12 certificate and private key; it is copied.
* pkcs_pwd is the corresponding password for the pkcs#12 buffer; it is copied.
*
* NOTE: This only works on Apple devices.
*/
AWS_IO_API int 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);
/**
* Initializes options for use in server mode.
* pkcs12_path is a path to a file on disk containing a pkcs#12 file. The file is loaded
* into an internal buffer. pkcs_pwd is the corresponding password for the pkcs#12 file; it is copied.
*
* NOTE: This only works on Apple devices.
*/
AWS_IO_API int 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);
/**
* Initializes options for use in server mode.
* pkcs12 is a buffer containing a pkcs#12 certificate and private key; it is copied.
* pkcs_pwd is the corresponding password for the pkcs#12 buffer; it is copied.
*
* NOTE: This only works on Apple devices.
*/
AWS_IO_API int 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);
/**
* Sets alpn list in the form <protocol1;protocol2;...>. A maximum of 4 protocols are supported.
* alpn_list is copied.
*/
AWS_IO_API int aws_tls_ctx_options_set_alpn_list(struct aws_tls_ctx_options *options, const char *alpn_list);
/**
* Enables or disables x.509 validation. Disable this only for testing. To enable mutual TLS in server mode,
* set verify_peer to true.
*/
AWS_IO_API void aws_tls_ctx_options_set_verify_peer(struct aws_tls_ctx_options *options, bool verify_peer);
/**
* Sets preferred TLS Cipher List
*/
AWS_IO_API void aws_tls_ctx_options_set_tls_cipher_preference(
struct aws_tls_ctx_options *options,
enum aws_tls_cipher_pref cipher_pref);
/**
* Sets the minimum TLS version to allow.
*/
AWS_IO_API void aws_tls_ctx_options_set_minimum_tls_version(
struct aws_tls_ctx_options *options,
enum aws_tls_versions minimum_tls_version);
/**
* Override the default trust store. ca_file is a buffer containing a PEM armored chain of trusted CA certificates.
* ca_file is copied.
*/
AWS_IO_API int aws_tls_ctx_options_override_default_trust_store(
struct aws_tls_ctx_options *options,
const struct aws_byte_cursor *ca_file);
/**
* Override the default trust store. ca_path is a path to a directory on disk containing trusted certificates. This is
* only supported on Unix systems (otherwise this parameter is ignored). ca_file is a path to a file on disk containing
* trusted certificates. ca_file is loaded from disk and stored in an internal buffer.
*/
AWS_IO_API int aws_tls_ctx_options_override_default_trust_store_from_path(
struct aws_tls_ctx_options *options,
const char *ca_path,
const char *ca_file);
/**
* When implementing BYO_CRYPTO, if you need extra data to pass to your tls implementation, set it here. The lifetime of
* extension_data must outlive the options object and be cleaned up after options is cleaned up.
*/
AWS_IO_API void aws_tls_ctx_options_set_extension_data(struct aws_tls_ctx_options *options, void *extension_data);
/**
* Initializes default connection options from an instance ot aws_tls_ctx.
*/
AWS_IO_API void aws_tls_connection_options_init_from_ctx(
struct aws_tls_connection_options *conn_options,
struct aws_tls_ctx *ctx);
/**
* Cleans up resources in aws_tls_connection_options. This can be called immediately after initializing
* a tls handler, or if using the bootstrap api, immediately after asking for a channel.
*/
AWS_IO_API void aws_tls_connection_options_clean_up(struct aws_tls_connection_options *connection_options);
/**
* Copies 'from' to 'to'
*/
AWS_IO_API int aws_tls_connection_options_copy(
struct aws_tls_connection_options *to,
const struct aws_tls_connection_options *from);
/**
* Sets callbacks for use with a tls connection.
*/
AWS_IO_API void 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);
/**
* Sets server name to use for the SNI extension (supported everywhere), as well as x.509 validation. If you don't
* set this, your x.509 validation will likely fail.
*/
AWS_IO_API int aws_tls_connection_options_set_server_name(
struct aws_tls_connection_options *conn_options,
struct aws_allocator *allocator,
const struct aws_byte_cursor *server_name);
/**
* Sets alpn list in the form <protocol1;protocol2;...>. A maximum of 4 protocols are supported.
* alpn_list is copied. This value is already inherited from aws_tls_ctx, but the aws_tls_ctx is expensive,
* and should be used across as many connections as possible. If you want to set this per connection, set it here.
*/
AWS_IO_API int aws_tls_connection_options_set_alpn_list(
struct aws_tls_connection_options *conn_options,
struct aws_allocator *allocator,
const char *alpn_list);
/********************************* TLS context and state management *********************************/
/**
* Returns true if alpn is available in the underlying tls implementation.
* This function should always be called before setting an alpn list.
*/
AWS_IO_API bool aws_tls_is_alpn_available(void);
/**
* Returns true if this Cipher Preference is available in the underlying TLS implementation.
* This function should always be called before setting a Cipher Preference
*/
AWS_IO_API bool aws_tls_is_cipher_pref_supported(enum aws_tls_cipher_pref cipher_pref);
/**
* Creates a new tls channel handler in client mode. Options will be copied.
* You must call aws_tls_client_handler_start_negotiation and wait on the
* aws_tls_on_negotiation_result_fn callback before the handler can begin processing
* application data.
*/
AWS_IO_API struct aws_channel_handler *aws_tls_client_handler_new(
struct aws_allocator *allocator,
struct aws_tls_connection_options *options,
struct aws_channel_slot *slot);
/**
* Creates a new tls channel handler in server mode. Options will be copied.
* You must wait on the aws_tls_on_negotiation_result_fn callback before the handler can begin processing
* application data.
*/
AWS_IO_API struct aws_channel_handler *aws_tls_server_handler_new(
struct aws_allocator *allocator,
struct aws_tls_connection_options *options,
struct aws_channel_slot *slot);
#ifdef BYO_CRYPTO
/**
* If using BYO_CRYPTO, you need to call this function prior to creating any client channels in the application.
*/
AWS_IO_API void aws_tls_byo_crypto_set_client_setup_options(const struct aws_tls_byo_crypto_setup_options *options);
/**
* If using BYO_CRYPTO, you need to call this function prior to creating any server channels in the application.
*/
AWS_IO_API void aws_tls_byo_crypto_set_server_setup_options(const struct aws_tls_byo_crypto_setup_options *options);
#endif /* BYO_CRYPTO */
/**
* Creates a channel handler, for client or server mode, that handles alpn. This isn't necessarily required
* since you can always call aws_tls_handler_protocol in the aws_tls_on_negotiation_result_fn callback, but
* this makes channel bootstrap easier to handle.
*/
AWS_IO_API struct aws_channel_handler *aws_tls_alpn_handler_new(
struct aws_allocator *allocator,
aws_tls_on_protocol_negotiated on_protocol_negotiated,
void *user_data);
/**
* Kicks off the negotiation process. This function must be called when in client mode to initiate the
* TLS handshake. Once the handshake has completed the aws_tls_on_negotiation_result_fn will be invoked.
*/
AWS_IO_API int aws_tls_client_handler_start_negotiation(struct aws_channel_handler *handler);
#ifndef BYO_CRYPTO
/**
* Creates a new server ctx. This ctx can be used for the lifetime of the application assuming you want the same
* options for every incoming connection. Options will be copied.
*/
AWS_IO_API struct aws_tls_ctx *aws_tls_server_ctx_new(
struct aws_allocator *alloc,
const struct aws_tls_ctx_options *options);
/**
* Creates a new client ctx. This ctx can be used for the lifetime of the application assuming you want the same
* options for every outgoing connection. Options will be copied.
*/
AWS_IO_API struct aws_tls_ctx *aws_tls_client_ctx_new(
struct aws_allocator *alloc,
const struct aws_tls_ctx_options *options);
#endif /* BYO_CRYPTO */
/**
* Increments the reference count on the tls context, allowing the caller to take a reference to it.
*
* Returns the same tls context passed in.
*/
AWS_IO_API struct aws_tls_ctx *aws_tls_ctx_acquire(struct aws_tls_ctx *ctx);
/**
* Decrements a tls context's ref count. When the ref count drops to zero, the object will be destroyed.
*/
AWS_IO_API void aws_tls_ctx_release(struct aws_tls_ctx *ctx);
/**
* Not necessary if you are installing more handlers into the channel, but if you just want to have TLS for arbitrary
* data and use the channel handler directly, this function allows you to write data to the channel and have it
* encrypted.
*/
AWS_IO_API int aws_tls_handler_write(
struct aws_channel_handler *handler,
struct aws_channel_slot *slot,
struct aws_byte_buf *buf,
aws_channel_on_message_write_completed_fn *on_write_completed,
void *completion_user_data);
/**
* Returns a byte buffer by copy of the negotiated protocols. If there is no agreed upon protocol, len will be 0 and
* buffer will be NULL.
*/
AWS_IO_API struct aws_byte_buf aws_tls_handler_protocol(struct aws_channel_handler *handler);
/**
* Client mode only. This is the server name that was used for SNI and host name validation.
*/
AWS_IO_API struct aws_byte_buf aws_tls_handler_server_name(struct aws_channel_handler *handler);
/**************************** TLS KEY OPERATION *******************************/
/* Note: Currently this assumes the user knows what key is being used for key/cert pairs
but s2n supports multiple cert/key pairs. This functionality is not used in the
CRT currently, but in the future, we may need to implement this */
/**
* Complete a successful TLS private key operation by providing its output.
* The output is copied into the TLS connection.
* The operation is freed by this call.
*
* You MUST call this or aws_tls_key_operation_complete_with_error().
* Failure to do so will stall the TLS connection indefinitely and leak memory.
*/
AWS_IO_API
void aws_tls_key_operation_complete(struct aws_tls_key_operation *operation, struct aws_byte_cursor output);
/**
* Complete an failed TLS private key operation.
* The TLS connection will fail.
* The operation is freed by this call.
*
* You MUST call this or aws_tls_key_operation_complete().
* Failure to do so will stall the TLS connection indefinitely and leak memory.
*/
AWS_IO_API
void aws_tls_key_operation_complete_with_error(struct aws_tls_key_operation *operation, int error_code);
/**
* Returns the input data that needs to be operated on by the custom key operation.
*/
AWS_IO_API
struct aws_byte_cursor aws_tls_key_operation_get_input(const struct aws_tls_key_operation *operation);
/**
* Returns the type of operation that needs to be performed by the custom key operation.
* If the implementation cannot perform the operation,
* use aws_tls_key_operation_complete_with_error() to preventing stalling the TLS connection.
*/
AWS_IO_API
enum aws_tls_key_operation_type aws_tls_key_operation_get_type(const struct aws_tls_key_operation *operation);
/**
* Returns the algorithm the operation is expected to be operated with.
* If the implementation does not support the signature algorithm,
* use aws_tls_key_operation_complete_with_error() to preventing stalling the TLS connection.
*/
AWS_IO_API
enum aws_tls_signature_algorithm aws_tls_key_operation_get_signature_algorithm(
const struct aws_tls_key_operation *operation);
/**
* Returns the algorithm the operation digest is signed with.
* If the implementation does not support the digest algorithm,
* use aws_tls_key_operation_complete_with_error() to preventing stalling the TLS connection.
*/
AWS_IO_API
enum aws_tls_hash_algorithm aws_tls_key_operation_get_digest_algorithm(const struct aws_tls_key_operation *operation);
/********************************* Misc TLS related *********************************/
/*
* Injects a tls handler/slot into a channel and begins tls negotiation.
* If desired, ALPN must be handled separately
*
* right_of_slot must be an existing slot in a channel
*/
AWS_IO_API int aws_channel_setup_client_tls(
struct aws_channel_slot *right_of_slot,
struct aws_tls_connection_options *tls_options);
/**
* Given enum, return string like: AWS_TLS_HASH_SHA256 -> "SHA256"
*/
AWS_IO_API
const char *aws_tls_hash_algorithm_str(enum aws_tls_hash_algorithm hash);
/**
* Given enum, return string like: AWS_TLS_SIGNATURE_RSA -> "RSA"
*/
AWS_IO_API
const char *aws_tls_signature_algorithm_str(enum aws_tls_signature_algorithm signature);
/**
* Given enum, return string like: AWS_TLS_SIGNATURE_RSA -> "RSA"
*/
AWS_IO_API
const char *aws_tls_key_operation_type_str(enum aws_tls_key_operation_type operation_type);
AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_IO_TLS_CHANNEL_HANDLER_H */
|