From 922c15f36cc75db5af33c46f9ea8934553fb808e Mon Sep 17 00:00:00 2001 From: Xiangfei Ding Date: Mon, 6 Jul 2026 14:53:45 +0000 Subject: [PATCH] rust: bssl-tls: Add cipher type Bug: 479599893 Signed-off-by: Xiangfei Ding Change-Id: I0805b41e484c585a6f917f39ed168f816a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/98793 Reviewed-by: Rudolf Polzer Reviewed-by: Adam Langley --- rust/bssl-tls/src/ciphers.rs | 129 +++++++++++++++++++++++++++++++++++ rust/bssl-tls/src/config.rs | 16 ----- rust/bssl-tls/src/lib.rs | 1 + 3 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 rust/bssl-tls/src/ciphers.rs diff --git a/rust/bssl-tls/src/ciphers.rs b/rust/bssl-tls/src/ciphers.rs new file mode 100644 index 0000000000..3f53759e84 --- /dev/null +++ b/rust/bssl-tls/src/ciphers.rs @@ -0,0 +1,129 @@ +// Copyright 2026 The BoringSSL Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! TLS Ciphers + +use core::{ + ffi::CStr, + ptr::NonNull, // +}; + +use crate::config::{ + CipherSuite, + ProtocolVersion, // +}; + +/// A TLS cipher suite. +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct CipherDescription(pub(crate) NonNull); + +// Safety: `SSL_CIPHER` is immutable and thread-safe. +unsafe impl Send for CipherDescription {} +unsafe impl Sync for CipherDescription {} + +impl CipherDescription { + /// Returns the cipher suite corresponding to the given RFC value. + pub fn from_value(value: CipherSuite) -> Option { + let ptr = unsafe { + // Safety: the cipher code is valid by construction. + bssl_sys::SSL_get_cipher_by_value(value.0) + }; + Self::from_ptr(ptr) + } + + pub(crate) fn from_ptr(ptr: *const bssl_sys::SSL_CIPHER) -> Option { + NonNull::new(ptr as *mut _).map(Self) + } + + pub(crate) fn ptr(self) -> *const bssl_sys::SSL_CIPHER { + self.0.as_ptr() + } + + /// Returns the two-byte protocol ID of the cipher suite per [IANA]. + /// + /// [IANA]: + pub fn id(&self) -> u16 { + unsafe { + // Safety: the cipher handle is valid. + bssl_sys::SSL_CIPHER_get_protocol_id(self.ptr()) + } + } + + /// Returns true if the cipher suite uses an AEAD cipher. + pub fn is_aead(&self) -> bool { + unsafe { + // Safety: the cipher handle is valid. + bssl_sys::SSL_CIPHER_is_aead(self.ptr()) != 0 + } + } + + /// Returns true if the cipher suite uses a block cipher. + pub fn is_block_cipher(&self) -> bool { + unsafe { + // Safety: the cipher handle is valid. + bssl_sys::SSL_CIPHER_is_block_cipher(self.ptr()) != 0 + } + } + + /// Returns the minimum protocol version required for the cipher suite. + pub fn min_version(&self) -> ProtocolVersion { + let version = unsafe { + // Safety: the cipher handle is valid. + bssl_sys::SSL_CIPHER_get_min_version(self.ptr()) + }; + let Ok(version) = ProtocolVersion::try_from(version) else { + unreachable!("BoringSSL invariant violated") + }; + version + } + + /// Returns the maximum protocol version that supports the cipher suite. + pub fn max_version(&self) -> ProtocolVersion { + let version = unsafe { + // Safety: the cipher handle is valid. + bssl_sys::SSL_CIPHER_get_max_version(self.ptr()) + }; + let Ok(version) = ProtocolVersion::try_from(version) else { + unreachable!("BoringSSL invariant violated") + }; + version + } + + /// Returns the standard IETF name for the cipher suite. + pub fn standard_name(&self) -> &'static str { + // Safety: the cipher handle is valid. + let ptr = unsafe { bssl_sys::SSL_CIPHER_standard_name(self.ptr()) }; + // Safety: BoringSSL returns cipher names as static strings which are valid UTF-8. + unsafe { CStr::from_ptr(ptr).to_str().unwrap() } + } + + /// Returns a string that describes the key-exchange method used by the cipher suite. + pub fn kx_name(&self) -> &'static str { + // Safety: the cipher handle is valid. + let ptr = unsafe { bssl_sys::SSL_CIPHER_get_kx_name(self.ptr()) }; + // Safety: BoringSSL returns key exchange group names as static strings + // which are valid UTF-8. + unsafe { CStr::from_ptr(ptr).to_str().unwrap() } + } +} + +impl core::fmt::Debug for CipherDescription { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Cipher") + .field("id", &self.id()) + .field("name", &self.standard_name()) + .finish() + } +} diff --git a/rust/bssl-tls/src/config.rs b/rust/bssl-tls/src/config.rs index 7e5c23f68d..eaebcf1267 100644 --- a/rust/bssl-tls/src/config.rs +++ b/rust/bssl-tls/src/config.rs @@ -131,22 +131,6 @@ impl core::fmt::Display for ConfigurationError { } } -/// Cipher information -#[derive(Clone)] -#[non_exhaustive] -pub struct CipherInfo { - /// Protocol ID as assigned by [IANA](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4) - pub id: u32, - /// IETF Name of the cipher - pub ietf_name: String, - /// Indicates whether this cipher is an AEAD cipher - pub is_aead: bool, - /// Indicates whether this cipher is a block cipher - pub is_block_cipher: bool, - /// Cipher strength in bits - pub strength: u16, -} - /// Supported cipher suites as registered with [IANA]. /// /// The following cipher suite values are assigned by IANA and correspond to diff --git a/rust/bssl-tls/src/lib.rs b/rust/bssl-tls/src/lib.rs index bf949c7132..8eb233b159 100644 --- a/rust/bssl-tls/src/lib.rs +++ b/rust/bssl-tls/src/lib.rs @@ -36,6 +36,7 @@ extern crate core; use core::panic::AssertUnwindSafe; pub mod alerts; +pub mod ciphers; pub mod config; pub mod connection; pub mod context;