Skip to main content

rustls_ffi/
cipher.rs

1use rustls::SupportedCipherSuite;
2
3use crate::enums::rustls_tls_version;
4use crate::ffi::{Castable, OwnershipRef, try_ref_from_ptr};
5use crate::panic::ffi_panic_boundary;
6use crate::rslice::rustls_str;
7
8/// A cipher suite supported by rustls.
9pub struct rustls_supported_ciphersuite {
10    _private: [u8; 0],
11}
12
13impl Castable for rustls_supported_ciphersuite {
14    type Ownership = OwnershipRef;
15    type RustType = SupportedCipherSuite;
16}
17
18impl rustls_supported_ciphersuite {
19    /// Return a 16-bit unsigned integer corresponding to this cipher suite's assignment from
20    /// <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4>.
21    ///
22    /// The bytes from the assignment are interpreted in network order.
23    #[no_mangle]
24    pub extern "C" fn rustls_supported_ciphersuite_get_suite(
25        supported_ciphersuite: *const rustls_supported_ciphersuite,
26    ) -> u16 {
27        let supported_ciphersuite = try_ref_from_ptr!(supported_ciphersuite);
28        u16::from(
29            match supported_ciphersuite {
30                SupportedCipherSuite::Tls12(sc) => &sc.common,
31                SupportedCipherSuite::Tls13(sc) => &sc.common,
32            }
33            .suite,
34        )
35    }
36}
37
38/// Returns the name of the ciphersuite as a `rustls_str`.
39///
40/// If the provided ciphersuite is invalid, the `rustls_str` will contain the
41/// empty string. The lifetime of the `rustls_str` is the lifetime of the program,
42/// it does not need to be freed.
43#[no_mangle]
44pub extern "C" fn rustls_supported_ciphersuite_get_name(
45    supported_ciphersuite: *const rustls_supported_ciphersuite,
46) -> rustls_str<'static> {
47    let supported_ciphersuite = try_ref_from_ptr!(supported_ciphersuite);
48    let s = supported_ciphersuite.suite().as_str().unwrap_or("");
49    match rustls_str::try_from(s) {
50        Ok(s) => s,
51        Err(_) => rustls_str::from_str_unchecked(""),
52    }
53}
54
55/// Returns the `rustls_tls_version` of the ciphersuite.
56///
57/// See also `RUSTLS_ALL_VERSIONS`.
58#[no_mangle]
59pub extern "C" fn rustls_supported_ciphersuite_protocol_version(
60    supported_ciphersuite: *const rustls_supported_ciphersuite,
61) -> rustls_tls_version {
62    ffi_panic_boundary! {
63        rustls_tls_version::from(try_ref_from_ptr!(supported_ciphersuite).version())
64    }
65}
66
67#[cfg(all(test, any(feature = "ring", feature = "aws-lc-rs")))]
68mod tests {
69    use crate::crypto_provider::{
70        rustls_default_crypto_provider_ciphersuites_get,
71        rustls_default_crypto_provider_ciphersuites_len,
72    };
73
74    use super::*;
75
76    #[test]
77    fn default_cipher_suites() {
78        let num_suites = rustls_default_crypto_provider_ciphersuites_len();
79        assert!(num_suites > 2);
80        for i in 0..num_suites {
81            let suite = rustls_default_crypto_provider_ciphersuites_get(i);
82            let name = rustls_supported_ciphersuite_get_name(suite);
83            let name = unsafe { name.to_str() };
84            let proto = rustls_supported_ciphersuite_protocol_version(suite);
85            println!("{i}: {name} {proto:?}");
86        }
87    }
88}