Skip to content

Commit

Permalink
cipher: allow getting the proto of a ciphersuite
Browse files Browse the repository at this point in the history
This commit adds a `rustls_supported_ciphersuite_protocol_version()` fn
for getting the `rustls_tls_version` IANA registered protocol version
identifier supported by a given `rustls_supported_ciphersuite`. This
avoids downstream users having to use
`rustls_supported_ciphersuite_get_name()` and then matching on the
protocol version prefix in that identifier.
  • Loading branch information
cpu committed Sep 10, 2024
1 parent 99f40a2 commit 8c0e3bc
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ requirements.
a `rustls_client_config_builder` with
`rustls_client_config_builder_set_server_verifier()`.

* A new `rustls_supported_ciphersuite_protocol_version()` function was added for
getting the `rustls_tls_version` IANA registered protocol version identifier
supported by a given `rustls_supported_ciphersuite`.

* When using `aws-lc-rs` as the crypto provider, NIST P-521 signatures are now
supported.

Expand Down
16 changes: 15 additions & 1 deletion src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustls_pemfile::{certs, crls};
use webpki::{RevocationCheckDepth, UnknownStatusPolicy};

use crate::crypto_provider::{rustls_crypto_provider, rustls_signing_key};
use crate::enums::rustls_tls_version;
use crate::error::{self, map_error, rustls_result};
use crate::rslice::{rustls_slice_bytes, rustls_str};
use crate::{
Expand Down Expand Up @@ -100,6 +101,18 @@ pub extern "C" fn rustls_supported_ciphersuite_get_name(
}
}

/// Returns the `rustls_tls_version` of the ciphersuite.
///
/// See also `RUSTLS_ALL_VERSIONS`.
#[no_mangle]
pub extern "C" fn rustls_supported_ciphersuite_protocol_version(
supported_ciphersuite: *const rustls_supported_ciphersuite,
) -> rustls_tls_version {
ffi_panic_boundary! {
rustls_tls_version::from(try_ref_from_ptr!(supported_ciphersuite).version())
}
}

arc_castable! {
/// The complete chain of certificates to send during a TLS handshake,
/// plus a private key that matches the end-entity (leaf) certificate.
Expand Down Expand Up @@ -1162,7 +1175,8 @@ mod tests {
let suite = rustls_default_crypto_provider_ciphersuites_get(i);
let name = rustls_supported_ciphersuite_get_name(suite);
let name = unsafe { name.to_str() };
println!("{}: {}", i, name);
let proto = rustls_supported_ciphersuite_protocol_version(suite);
println!("{}: {} {:?}", i, name, proto);
}
}
}
20 changes: 19 additions & 1 deletion src/enums.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use rustls::{ProtocolVersion, SupportedProtocolVersion};

#[derive(Debug, Default)]
#[repr(C)]
#[allow(dead_code)]
/// Definitions of known TLS protocol versions.
pub enum rustls_tls_version {
#[default]
Unknown = 0x0000,
Sslv2 = 0x0200,
Sslv3 = 0x0300,
Tlsv1_0 = 0x0301,
Expand All @@ -10,6 +14,20 @@ pub enum rustls_tls_version {
Tlsv1_3 = 0x0304,
}

impl From<&SupportedProtocolVersion> for rustls_tls_version {
fn from(version: &SupportedProtocolVersion) -> Self {
match version.version {
ProtocolVersion::SSLv2 => rustls_tls_version::Sslv2,
ProtocolVersion::SSLv3 => rustls_tls_version::Sslv3,
ProtocolVersion::TLSv1_0 => rustls_tls_version::Tlsv1_0,
ProtocolVersion::TLSv1_1 => rustls_tls_version::Tlsv1_1,
ProtocolVersion::TLSv1_2 => rustls_tls_version::Tlsv1_2,
ProtocolVersion::TLSv1_3 => rustls_tls_version::Tlsv1_3,
_ => rustls_tls_version::Unknown,
}
}
}

/// Rustls' list of supported protocol versions. The length of the array is
/// given by `RUSTLS_ALL_VERSIONS_LEN`.
#[no_mangle]
Expand Down
7 changes: 7 additions & 0 deletions src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use libc::EINVAL;
use crate::error::{rustls_io_result, rustls_result};
use crate::rslice::{rustls_slice_bytes, rustls_str};

use crate::enums::rustls_tls_version;
use std::ptr::{null, null_mut};

// We wrap all function calls in an ffi_panic_boundary! macro, which catches
Expand All @@ -28,9 +29,15 @@ pub(crate) trait NullParameterOrDefault {
pub(crate) trait Defaultable: Default {}

impl Defaultable for u16 {}

impl Defaultable for usize {}

impl Defaultable for bool {}

impl Defaultable for () {}

impl Defaultable for rustls_tls_version {}

impl<T> Defaultable for Option<T> {}

impl<'a> Defaultable for rustls_slice_bytes<'a> {}
Expand Down
8 changes: 8 additions & 0 deletions src/rustls.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ typedef uint32_t rustls_result;
* Definitions of known TLS protocol versions.
*/
typedef enum rustls_tls_version {
RUSTLS_TLS_VERSION_UNKNOWN = 0,
RUSTLS_TLS_VERSION_SSLV2 = 512,
RUSTLS_TLS_VERSION_SSLV3 = 768,
RUSTLS_TLS_VERSION_TLSV1_0 = 769,
Expand Down Expand Up @@ -1018,6 +1019,13 @@ uint16_t rustls_supported_ciphersuite_get_suite(const struct rustls_supported_ci
*/
struct rustls_str rustls_supported_ciphersuite_get_name(const struct rustls_supported_ciphersuite *supported_ciphersuite);

/**
* Returns the `rustls_tls_version` of the ciphersuite.
*
* See also `RUSTLS_ALL_VERSIONS`.
*/
enum rustls_tls_version rustls_supported_ciphersuite_protocol_version(const struct rustls_supported_ciphersuite *supported_ciphersuite);

/**
* Build a `rustls_certified_key` from a certificate chain and a private key
* and the default process-wide crypto provider.
Expand Down

0 comments on commit 8c0e3bc

Please sign in to comment.