diff --git a/CHANGELOG.md b/CHANGELOG.md index 6435efd4..9a21b56b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ rustls_result (#227). - rustls_session_store_get_callback and rustls_session_store_put_callback now return uint32_t (#227). + - Added arrays ALL_CIPHER_SUITES, DEFAULT_CIPHER_SUITES, ALL_VERSIONS, and + DEFAULT_VERSIONS as more convenient alternatives to + rustls_default_ciphersuites_get_entry(), etc. ## 0.8.2 (2021-11-13) diff --git a/src/cipher.rs b/src/cipher.rs index 7ad431ef..f827037d 100644 --- a/src/cipher.rs +++ b/src/cipher.rs @@ -123,6 +123,94 @@ pub extern "C" fn rustls_default_ciphersuites_get_entry( } } +/// Rustls' list of supported cipher suites. This is an array of pointers, and +/// its length is given by `RUSTLS_ALL_CIPHER_SUITES_LEN`. The pointers will +/// always be valid. The contents and order of this array may change between +/// releases. +#[no_mangle] +static mut RUSTLS_ALL_CIPHER_SUITES: [*const rustls_supported_ciphersuite; 9] = [ + &rustls::cipher_suite::TLS13_AES_256_GCM_SHA384 as *const SupportedCipherSuite as *const _, + &rustls::cipher_suite::TLS13_AES_128_GCM_SHA256 as *const SupportedCipherSuite as *const _, + &rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + as *const SupportedCipherSuite as *const _, + &rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + as *const SupportedCipherSuite as *const _, +]; + +/// The length of the array `RUSTLS_ALL_CIPHER_SUITES`. +#[no_mangle] +pub static RUSTLS_ALL_CIPHER_SUITES_LEN: usize = unsafe { RUSTLS_ALL_CIPHER_SUITES.len() }; + +/// Rustls' list of default cipher suites. This is an array of pointers, and +/// its length is given by `RUSTLS_DEFAULT_CIPHER_SUITES_LEN`. The pointers +/// will always be valid. The contents and order of this array may change +/// between releases. +#[no_mangle] +pub static mut RUSTLS_DEFAULT_CIPHER_SUITES: [*const rustls_supported_ciphersuite; 9] = [ + &rustls::cipher_suite::TLS13_AES_256_GCM_SHA384 as *const SupportedCipherSuite as *const _, + &rustls::cipher_suite::TLS13_AES_128_GCM_SHA256 as *const SupportedCipherSuite as *const _, + &rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + as *const SupportedCipherSuite as *const _, + &rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 as *const SupportedCipherSuite + as *const _, + &rustls::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + as *const SupportedCipherSuite as *const _, +]; + +/// The length of the array `RUSTLS_DEFAULT_CIPHER_SUITES`. +#[no_mangle] +pub static RUSTLS_DEFAULT_CIPHER_SUITES_LEN: usize = unsafe { RUSTLS_DEFAULT_CIPHER_SUITES.len() }; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn all_cipher_suites_arrays() { + assert_eq!(RUSTLS_ALL_CIPHER_SUITES_LEN, ALL_CIPHER_SUITES.len()); + for (original, ffi) in ALL_CIPHER_SUITES + .iter() + .zip(unsafe { RUSTLS_ALL_CIPHER_SUITES }.iter().copied()) + { + let ffi_cipher_suite = try_ref_from_ptr!(ffi); + assert_eq!(original, ffi_cipher_suite); + } + } + + #[test] + fn default_cipher_suites_arrays() { + assert_eq!( + RUSTLS_DEFAULT_CIPHER_SUITES_LEN, + DEFAULT_CIPHER_SUITES.len() + ); + for (original, ffi) in DEFAULT_CIPHER_SUITES + .iter() + .zip(unsafe { RUSTLS_DEFAULT_CIPHER_SUITES }.iter().copied()) + { + let ffi_cipher_suite = try_ref_from_ptr!(ffi); + assert_eq!(original, ffi_cipher_suite); + } + } +} + /// The complete chain of certificates to send during a TLS handshake, /// plus a private key that matches the end-entity (leaf) certificate. /// Corresponds to `CertifiedKey` in the Rust API. diff --git a/src/client.rs b/src/client.rs index cbaf0da6..fee8c32a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -112,12 +112,14 @@ impl rustls_client_config_builder { /// resulting rustls_client_config. Specify cipher suites in preference /// order; the `cipher_suites` parameter must point to an array containing /// `len` pointers to `rustls_supported_ciphersuite` previously obtained - /// from `rustls_all_ciphersuites_get_entry()`. Set the TLS protocol - /// versions to use when negotiating a TLS session. + /// from `rustls_all_ciphersuites_get_entry()`, or to a provided array, + /// RUSTLS_DEFAULT_CIPHER_SUITES or RUSTLS_ALL_CIPHER_SUITES. Set the TLS + /// protocol versions to use when negotiating a TLS session. /// /// `tls_version` is the version of the protocol, as defined in rfc8446, /// ch. 4.2.1 and end of ch. 5.1. Some values are defined in - /// `rustls_tls_version` for convenience. + /// `rustls_tls_version` for convenience, and the arrays + /// RUSTLS_DEFAULT_VERSIONS or RUSTLS_ALL_VERSIONS can be used directly. /// /// `versions` will only be used during the call and the application retains /// ownership. `len` is the number of consecutive `uint16_t` pointed to by `versions`. diff --git a/src/enums.rs b/src/enums.rs index f83214a7..f65d00d8 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -9,3 +9,50 @@ pub enum rustls_tls_version { Tlsv1_2 = 0x0303, Tlsv1_3 = 0x0304, } + +/// Rustls' list of supported protocol versions. The length of the array is +/// given by `RUSTLS_ALL_VERSIONS_LEN`. +#[no_mangle] +pub static RUSTLS_ALL_VERSIONS: [u16; 2] = [ + rustls_tls_version::Tlsv1_3 as u16, + rustls_tls_version::Tlsv1_2 as u16, +]; + +/// The length of the array `RUSTLS_ALL_VERSIONS`. +#[no_mangle] +pub static RUSTLS_ALL_VERSIONS_LEN: usize = RUSTLS_ALL_VERSIONS.len(); + +/// Rustls' default list of protocol versions. The length of the array is +/// given by `RUSTLS_DEFAULT_VERSIONS_LEN`. +#[no_mangle] +pub static RUSTLS_DEFAULT_VERSIONS: [u16; 2] = [ + rustls_tls_version::Tlsv1_3 as u16, + rustls_tls_version::Tlsv1_2 as u16, +]; + +/// The length of the array `RUSTLS_DEFAULT_VERSIONS`. +#[no_mangle] +pub static RUSTLS_DEFAULT_VERSIONS_LEN: usize = RUSTLS_DEFAULT_VERSIONS.len(); + +#[cfg(test)] +mod tests { + use super::*; + + use rustls::{ALL_VERSIONS, DEFAULT_VERSIONS}; + + #[test] + fn all_versions_arrays() { + assert_eq!(RUSTLS_ALL_VERSIONS_LEN, ALL_VERSIONS.len()); + for (original, ffi) in ALL_VERSIONS.iter().zip(RUSTLS_ALL_VERSIONS.iter()) { + assert_eq!(original.version.get_u16(), *ffi); + } + } + + #[test] + fn default_versions_arrays() { + assert_eq!(RUSTLS_DEFAULT_VERSIONS_LEN, DEFAULT_VERSIONS.len()); + for (original, ffi) in DEFAULT_VERSIONS.iter().zip(RUSTLS_DEFAULT_VERSIONS.iter()) { + assert_eq!(original.version.get_u16(), *ffi); + } + } +} diff --git a/src/rustls.h b/src/rustls.h index e99ade53..1d19d35a 100644 --- a/src/rustls.h +++ b/src/rustls.h @@ -460,6 +460,20 @@ typedef uint32_t (*rustls_session_store_get_callback)(rustls_session_store_userd */ typedef uint32_t (*rustls_session_store_put_callback)(rustls_session_store_userdata userdata, const struct rustls_slice_bytes *key, const struct rustls_slice_bytes *val); +extern const size_t RUSTLS_ALL_CIPHER_SUITES_LEN; + +extern const struct rustls_supported_ciphersuite *RUSTLS_DEFAULT_CIPHER_SUITES[9]; + +extern const size_t RUSTLS_DEFAULT_CIPHER_SUITES_LEN; + +extern const uint16_t RUSTLS_ALL_VERSIONS[2]; + +extern const size_t RUSTLS_ALL_VERSIONS_LEN; + +extern const uint16_t RUSTLS_DEFAULT_VERSIONS[2]; + +extern const size_t RUSTLS_DEFAULT_VERSIONS_LEN; + /** * Returns a static string containing the rustls-ffi version as well as the * rustls version. The string is alive for the lifetime of the program and does @@ -648,12 +662,14 @@ struct rustls_client_config_builder *rustls_client_config_builder_new(void); * resulting rustls_client_config. Specify cipher suites in preference * order; the `cipher_suites` parameter must point to an array containing * `len` pointers to `rustls_supported_ciphersuite` previously obtained - * from `rustls_all_ciphersuites_get_entry()`. Set the TLS protocol - * versions to use when negotiating a TLS session. + * from `rustls_all_ciphersuites_get_entry()`, or to a provided array, + * RUSTLS_DEFAULT_CIPHER_SUITES or RUSTLS_ALL_CIPHER_SUITES. Set the TLS + * protocol versions to use when negotiating a TLS session. * * `tls_version` is the version of the protocol, as defined in rfc8446, * ch. 4.2.1 and end of ch. 5.1. Some values are defined in - * `rustls_tls_version` for convenience. + * `rustls_tls_version` for convenience, and the arrays + * RUSTLS_DEFAULT_VERSIONS or RUSTLS_ALL_VERSIONS can be used directly. * * `versions` will only be used during the call and the application retains * ownership. `len` is the number of consecutive `uint16_t` pointed to by `versions`.