Expose `set_compliance_policy` and `get_ciphers`
This commit is contained in:
parent
0f5731b1d8
commit
e370083af5
|
|
@ -89,7 +89,7 @@ use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
|
|||
use crate::ssl::bio::BioMethod;
|
||||
use crate::ssl::callbacks::*;
|
||||
use crate::ssl::error::InnerError;
|
||||
use crate::stack::{Stack, StackRef};
|
||||
use crate::stack::{Stack, StackRef, Stackable};
|
||||
use crate::x509::store::{X509Store, X509StoreBuilderRef, X509StoreRef};
|
||||
use crate::x509::verify::X509VerifyParamRef;
|
||||
use crate::x509::{
|
||||
|
|
@ -701,6 +701,27 @@ impl SslCurve {
|
|||
pub const P256_KYBER768_DRAFT00: SslCurve = SslCurve(ffi::NID_P256Kyber768Draft00);
|
||||
}
|
||||
|
||||
/// A compliance policy.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
pub struct CompliancePolicy(ffi::ssl_compliance_policy_t);
|
||||
|
||||
#[cfg(not(feature = "fips"))]
|
||||
impl CompliancePolicy {
|
||||
/// Does nothing, however setting this does not undo other policies, so trying to set this is an error.
|
||||
pub const NONE: Self = Self(ffi::ssl_compliance_policy_t::ssl_compliance_policy_none);
|
||||
|
||||
/// Configures a TLS connection to try and be compliant with NIST requirements, but does not guarantee success.
|
||||
/// This policy can be called even if Boring is not built with FIPS.
|
||||
pub const FIPS_202205: Self =
|
||||
Self(ffi::ssl_compliance_policy_t::ssl_compliance_policy_fips_202205);
|
||||
|
||||
/// Partially configures a TLS connection to be compliant with WPA3. Callers must enforce certificate chain requirements themselves.
|
||||
/// Use of this policy is less secure than the default and not recommended.
|
||||
pub const WPA3_192_202304: Self =
|
||||
Self(ffi::ssl_compliance_policy_t::ssl_compliance_policy_wpa3_192_202304);
|
||||
}
|
||||
|
||||
/// A standard implementation of protocol selection for Application Layer Protocol Negotiation
|
||||
/// (ALPN).
|
||||
///
|
||||
|
|
@ -1262,7 +1283,9 @@ impl SslContextBuilder {
|
|||
|
||||
/// Sets the list of supported ciphers for protocols before TLSv1.3.
|
||||
///
|
||||
/// The `set_ciphersuites` method controls the cipher suites for TLSv1.3.
|
||||
/// The `set_ciphersuites` method controls the cipher suites for TLSv1.3 in OpenSSL.
|
||||
/// BoringSSL doesn't implement `set_ciphersuites`.
|
||||
/// See https://github.com/google/boringssl/blob/master/include/openssl/ssl.h#L1542-L1544
|
||||
///
|
||||
/// See [`ciphers`] for details on the format.
|
||||
///
|
||||
|
|
@ -1281,6 +1304,18 @@ impl SslContextBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the list of supported ciphers for protocols before TLSv1.3.
|
||||
///
|
||||
/// See [`ciphers`] for details on the format
|
||||
///
|
||||
/// This corresponds to [`SSL_CTX_get_ciphers`].
|
||||
///
|
||||
/// [`ciphers`]: https://www.openssl.org/docs/manmaster/man1/ciphers.html
|
||||
/// [`SSL_CTX_set_cipher_list`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_ciphers.html
|
||||
pub fn ciphers(&self) -> Option<&StackRef<SslCipher>> {
|
||||
self.ctx.ciphers()
|
||||
}
|
||||
|
||||
/// Sets the options used by the context, returning the old set.
|
||||
///
|
||||
/// This corresponds to [`SSL_CTX_set_options`].
|
||||
|
|
@ -1856,6 +1891,17 @@ impl SslContextBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the context's compliance policy.
|
||||
///
|
||||
/// This corresponds to [`SSL_CTX_set_compliance_policy`]
|
||||
///
|
||||
/// [`SSL_CTX_set_compliance_policy`] https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_compliance_policy
|
||||
/// This feature isn't available in the certified version of BoringSSL.
|
||||
#[cfg(not(feature = "fips"))]
|
||||
pub fn set_compliance_policy(&mut self, policy: CompliancePolicy) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt_0i(ffi::SSL_CTX_set_compliance_policy(self.as_ptr(), policy.0)).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Consumes the builder, returning a new `SslContext`.
|
||||
pub fn build(self) -> SslContext {
|
||||
self.ctx
|
||||
|
|
@ -1936,6 +1982,25 @@ impl SslContext {
|
|||
Index::from_raw(idx)
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the list of supported ciphers for protocols before TLSv1.3.
|
||||
///
|
||||
/// See [`ciphers`] for details on the format
|
||||
///
|
||||
/// This corresponds to [`SSL_CTX_get_ciphers`].
|
||||
///
|
||||
/// [`ciphers`]: https://www.openssl.org/docs/manmaster/man1/ciphers.html
|
||||
/// [`SSL_CTX_set_cipher_list`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_ciphers.html
|
||||
pub fn ciphers(&self) -> Option<&StackRef<SslCipher>> {
|
||||
unsafe {
|
||||
let ciphers = ffi::SSL_CTX_get_ciphers(self.as_ptr());
|
||||
if ciphers.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(StackRef::from_ptr(ciphers))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SslContextRef {
|
||||
|
|
@ -2181,6 +2246,10 @@ impl ClientHello<'_> {
|
|||
/// Information about a cipher.
|
||||
pub struct SslCipher(*mut ffi::SSL_CIPHER);
|
||||
|
||||
impl Stackable for SslCipher {
|
||||
type StackType = ffi::stack_st_SSL_CIPHER;
|
||||
}
|
||||
|
||||
unsafe impl ForeignType for SslCipher {
|
||||
type CType = ffi::SSL_CIPHER;
|
||||
type Ref = SslCipherRef;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ use crate::ssl::{
|
|||
use crate::x509::verify::X509CheckFlags;
|
||||
use crate::x509::{X509Name, X509};
|
||||
|
||||
#[cfg(not(feature = "fips"))]
|
||||
use super::CompliancePolicy;
|
||||
|
||||
mod custom_verify;
|
||||
mod private_key_method;
|
||||
mod server;
|
||||
|
|
@ -917,6 +920,80 @@ fn server_set_default_curves_list() {
|
|||
ssl.server_set_default_curves_list();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_ciphers() {
|
||||
let ctx_builder = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
let ctx_builder_ciphers: Vec<&str> = ctx_builder
|
||||
.ciphers()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|v| v.name())
|
||||
.collect();
|
||||
assert!(!(ctx_builder_ciphers.is_empty()));
|
||||
|
||||
let ctx = ctx_builder.build();
|
||||
let ctx_ciphers: Vec<&str> = ctx
|
||||
.ciphers()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|v| v.name())
|
||||
.collect();
|
||||
assert!(!(ctx_ciphers.is_empty()));
|
||||
|
||||
assert_eq!(ctx_builder_ciphers.len(), ctx_ciphers.len());
|
||||
|
||||
for (ctx_builder_cipher, ctx_cipher) in ctx_builder_ciphers.into_iter().zip(ctx_ciphers) {
|
||||
assert_eq!(ctx_builder_cipher, ctx_cipher);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
fn test_set_compliance() {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
ctx.set_compliance_policy(CompliancePolicy::FIPS_202205)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(ctx.max_proto_version().unwrap(), SslVersion::TLS1_3);
|
||||
assert_eq!(ctx.min_proto_version().unwrap(), SslVersion::TLS1_2);
|
||||
|
||||
const FIPS_CIPHERS: [&str; 4] = [
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
"ECDHE-RSA-AES128-GCM-SHA256",
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
"ECDHE-RSA-AES256-GCM-SHA384",
|
||||
];
|
||||
|
||||
let ciphers = ctx.ciphers().unwrap();
|
||||
assert_eq!(ciphers.len(), FIPS_CIPHERS.len());
|
||||
|
||||
for cipher in ciphers.into_iter().zip(FIPS_CIPHERS) {
|
||||
assert_eq!(cipher.0.name(), cipher.1)
|
||||
}
|
||||
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
ctx.set_compliance_policy(CompliancePolicy::WPA3_192_202304)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(ctx.max_proto_version().unwrap(), SslVersion::TLS1_3);
|
||||
assert_eq!(ctx.min_proto_version().unwrap(), SslVersion::TLS1_2);
|
||||
|
||||
const WPA3_192_CIPHERS: [&str; 2] = [
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
"ECDHE-RSA-AES256-GCM-SHA384",
|
||||
];
|
||||
|
||||
let ciphers = ctx.ciphers().unwrap();
|
||||
assert_eq!(ciphers.len(), WPA3_192_CIPHERS.len());
|
||||
|
||||
for cipher in ciphers.into_iter().zip(WPA3_192_CIPHERS) {
|
||||
assert_eq!(cipher.0.name(), cipher.1)
|
||||
}
|
||||
|
||||
ctx.set_compliance_policy(CompliancePolicy::NONE)
|
||||
.expect_err("Testing expect err if set compliance policy to NONE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drop_ex_data_in_context() {
|
||||
let index = SslContext::new_ex_index::<&'static str>().unwrap();
|
||||
|
|
|
|||
Loading…
Reference in New Issue