blob: c4c838a1145e221645cdb0dfc1dc8980c804a38d [file] [log] [blame]
// 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 Configurations
use alloc::string::String;
use core::ffi::c_int;
use bssl_macros::bssl_enum;
bssl_enum! {
/// Protocol version for TLS or DTLS
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum ProtocolVersion: u16 {
/// TLS version 1.2
Tls12 = bssl_sys::TLS1_2_VERSION as u16,
/// TLS version 1.3
Tls13 = bssl_sys::TLS1_3_VERSION as u16,
/// DTLS version 1.2
Dtls12 = bssl_sys::DTLS1_2_VERSION as u16,
/// DTLS version 1.3
Dtls13 = bssl_sys::DTLS1_3_VERSION as u16,
}
}
impl TryFrom<c_int> for ProtocolVersion {
type Error = c_int;
fn try_from(version: c_int) -> Result<Self, Self::Error> {
let Ok(val) = u16::try_from(version) else {
return Err(version);
};
if let Ok(version) = ProtocolVersion::try_from(val) {
Ok(version)
} else {
Err(version)
}
}
}
bssl_enum! {
/// Key exchange groups for TLS or DTLS
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum KeyExchangeGroups: u16 {
/// Key exchange using `ECDH-P256`
Secp256r1 = bssl_sys::SSL_GROUP_SECP256R1 as u16,
/// Key exchange using `ECDH-P384`
Secp384r1 = bssl_sys::SSL_GROUP_SECP384R1 as u16,
/// Key exchange using `ECDH-P521`
Secp521r1 = bssl_sys::SSL_GROUP_SECP521R1 as u16,
/// Key exchange using `X25519`
X25519 = bssl_sys::SSL_GROUP_X25519 as u16,
/// Key exchange using post-quantum hybrid scheme `X25519MLKEM768`
X25519Mlkem768 = bssl_sys::SSL_GROUP_X25519_MLKEM768 as u16,
/// Key exchange using `MLKEM-1024`
Mlkem1024 = bssl_sys::SSL_GROUP_MLKEM1024 as u16,
}
}
bitflags::bitflags! {
/// Flags to control how key exchange group could be chosen
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct KeyExchangeGroupFlag: u32 {
/// `EQUAL_PREFERENCE_WITH_NEXT` indicates that the corresponding group has equal preference
/// with the next member of the list of groups being configured.
const EQUAL_PREFERENCE_WITH_NEXT = 0x01;
}
}
/// Configuration errors
#[derive(Debug)]
pub enum ConfigurationError {
/// Some key exchange group is specified twice.
DuplicatedKeyExchangeGroup,
/// Some string is not acceptable.
InvalidString,
/// Session ID context data is too large.
SessionIdContextTooLarge,
/// Preshared Key is too long.
PskTooLong,
/// Value is out of range.
ValueOutOfRange,
/// IP address is invalid.
/// It should either be 4 bytes for IPv4 addresses or 16 bytes for IPv6 addresses.
InvalidIp,
/// Invalid parameters.
InvalidParameters,
}
impl core::fmt::Display for ConfigurationError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
ConfigurationError::DuplicatedKeyExchangeGroup => {
f.write_str("duplicated key exchange group")
}
ConfigurationError::InvalidString => f.write_str("invalid string"),
ConfigurationError::SessionIdContextTooLarge => {
f.write_str("session ID context data is too large")
}
ConfigurationError::PskTooLong => f.write_str("preshared key is too long"),
ConfigurationError::ValueOutOfRange => f.write_str("value is out of range"),
ConfigurationError::InvalidIp => f.write_str("invalid IP address"),
ConfigurationError::InvalidParameters => f.write_str("invalid parameters"),
}
}
}
/// 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,
}
bssl_enum! {
/// Compliance Policy.
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum CompliancePolicy: u8 {
/// FIPS 202205
///
/// This policy configures a TLS connection to use:
/// - TLS 1.2 or 1.3;
/// - For TLS 1.2, only `ECDHE_[RSA|ECDSA]_WITH_AES_*_GCM_SHA*`;
/// - For TLS 1.3, only `AES-GCM`;
/// - P-256 or P-384 for key agreement;
/// - For server signatures, only PKCS#1/PSS with SHA256/384/512,
/// or ECDSA with P-256 or P-384 and SHA256/SHA384.
Fips202205 = bssl_sys::ssl_compliance_policy_t_ssl_compliance_policy_fips_202205 as u8,
/// WPA3-192 202304
///
/// This policy configures a TLS connection to use:
/// - TLS 1.2 or 1.3.
/// - For TLS 1.2, only `TLS_ECDHE_[ECDSA|RSA]_WITH_AES_256_GCM_SHA384`.
/// - For TLS 1.3, only `AES-256-GCM`.
/// - P-384 for key agreement.
/// - For handshake signatures, only ECDSA with P-384 and SHA-384, or RSA
/// with SHA-384 or SHA-512.
///
/// No limitations on the certificate chain nor leaf public key are imposed,
/// other than by the supported signature algorithms.
/// But WPA3's "192-bit" mode requires at least P-384 or 3072-bit RSA along the chain.
/// The caller must enforce this themselves on the verified chain using functions such as
/// [`crate::credentials::TlsCredentialBuilder::with_certificate_chain`].
///
/// Note that this setting is less secure than the default.
/// The implementation risks of using a more obscure primitive like P-384 dominate other
/// considerations.
Wpa3_192_202304 = bssl_sys::ssl_compliance_policy_t_ssl_compliance_policy_wpa3_192_202304 as u8,
/// CNSA 202407
///
/// This policy configures a TLS connection to use:
/// - For TLS 1.3, AES-256-GCM over AES-128-GCM over ChaCha20-Poly1305.
///
/// I.e. it ensures that AES-GCM will be used whenever the client supports it.
/// The cipher suite configuration mini-language can be used to similarly
/// configure prior TLS versions if they are enabled.
Cnsa202407 = bssl_sys::ssl_compliance_policy_t_ssl_compliance_policy_cnsa_202407 as u8,
}
}