Skip to content

Commit

Permalink
client: add ciphersuite and version arrays (#242)
Browse files Browse the repository at this point in the history
This adds arrays of ciphersuites and versions as suggested in #165 and #203.
  • Loading branch information
divergentdave authored Nov 19, 2021
1 parent d7a8692 commit b30b051
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
88 changes: 88 additions & 0 deletions src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 5 additions & 3 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
47 changes: 47 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
22 changes: 19 additions & 3 deletions src/rustls.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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`.
Expand Down

0 comments on commit b30b051

Please sign in to comment.