Bump boring to v5, align FIPS to SP 800-52r2, clean up features
- Bump boring/boring-sys from v4 to v5 (zero API breaks) - Merge fips/fips-only into a single fips feature that both enables FIPS-validated BoringSSL and restricts algorithms to SP 800-52r2 - Tighten FIPS KX groups to P-256 and P-384 only (aligned with boring's fips202205 compliance policy) - Remove ECDSA_P521_SHA512 from FIPS signature verification set - Simplify fips feature to forward boring/fips only (drop redundant boring-sys/fips) - Add fips-precompiled as deprecated alias matching boring's naming - Change default features to empty (TLS 1.2 now requires explicit tls12 feature opt-in) - Gate TLS 1.2 code paths properly so the crate compiles and passes tests with default (TLS 1.3 only) features - Update README to reflect current state: boring v5, feature docs, FIPS mode documentation, workspace structure
This commit is contained in:
parent
490340afa7
commit
271acbb315
11 changed files with 273 additions and 77 deletions
63
.github/workflows/ci.yml
vendored
63
.github/workflows/ci.yml
vendored
|
|
@ -9,10 +9,9 @@ on:
|
|||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUSTFLAGS: -Dwarnings
|
||||
FEATURES: "logging,tls12"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
|
@ -21,9 +20,57 @@ jobs:
|
|||
run: sudo apt-get install -y cmake clang
|
||||
- name: Check fmt
|
||||
run: make fmt
|
||||
- name: Lint
|
||||
run: make lint
|
||||
- name: Tests usual
|
||||
run: make test
|
||||
- name: Build usual
|
||||
run: make build
|
||||
|
||||
test-default:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -y cmake clang
|
||||
- name: Lint (default features)
|
||||
run: make lint FEATURES=""
|
||||
- name: Test (default features)
|
||||
run: make test FEATURES=""
|
||||
- name: Build (default features)
|
||||
run: make build FEATURES=""
|
||||
|
||||
test-tls12:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -y cmake clang
|
||||
- name: Lint (tls12)
|
||||
run: make lint FEATURES="tls12"
|
||||
- name: Test (tls12)
|
||||
run: make test FEATURES="tls12"
|
||||
- name: Build (tls12)
|
||||
run: make build FEATURES="tls12"
|
||||
|
||||
test-logging-tls12:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -y cmake clang
|
||||
- name: Lint (logging,tls12)
|
||||
run: make lint FEATURES="logging,tls12"
|
||||
- name: Test (logging,tls12)
|
||||
run: make test FEATURES="logging,tls12"
|
||||
- name: Build (logging,tls12)
|
||||
run: make build FEATURES="logging,tls12"
|
||||
|
||||
check-fips:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -y cmake clang
|
||||
- name: Check (fips)
|
||||
run: cargo check -p boring-rustls-provider --all-targets --features fips
|
||||
- name: Check (fips-precompiled)
|
||||
run: cargo check -p boring-rustls-provider --all-targets --features fips-precompiled
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ default-members = [
|
|||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
boring = { version = "4", default-features = false }
|
||||
boring-sys = { version = "4", default-features = false }
|
||||
boring = { version = "5", default-features = false }
|
||||
boring-sys = { version = "5", default-features = false }
|
||||
rustls = { version = "0.23", default-features = false }
|
||||
rustls-pemfile = { version = "2" }
|
||||
rustls-pki-types = { version = "1" }
|
||||
|
|
|
|||
11
Makefile
11
Makefile
|
|
@ -1,4 +1,5 @@
|
|||
FEATURES ?= logging,tls12
|
||||
CARGO_FEATURES := $(if $(strip $(FEATURES)),-F "$(FEATURES)",)
|
||||
|
||||
|
||||
.PHONY: fmt
|
||||
|
|
@ -7,12 +8,16 @@ fmt:
|
|||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
cargo clippy --workspace --all-targets -F "$(FEATURES)"
|
||||
cargo clippy --workspace --all-targets $(CARGO_FEATURES)
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
cargo check --workspace --all-targets $(CARGO_FEATURES)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
cargo test --all-targets -F "$(FEATURES)"
|
||||
cargo test --all-targets $(CARGO_FEATURES)
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
cargo build --all-targets -F "$(FEATURES)"
|
||||
cargo build --all-targets $(CARGO_FEATURES)
|
||||
|
|
|
|||
71
Readme.md
71
Readme.md
|
|
@ -2,55 +2,60 @@
|
|||
|
||||
[](https://github.com/janrueth/boring-rustls-provider/actions/workflows/ci.yml?query=branch%3Amain)
|
||||
|
||||
This is supposed to be the start to a [boringssl](https://github.com/cloudflare/boring)-based [rustls](https://github.com/rustls/rustls) crypto provider.
|
||||
A [BoringSSL](https://github.com/cloudflare/boring)-based [rustls](https://github.com/rustls/rustls) crypto provider.
|
||||
|
||||
## Status
|
||||
This is just a dump of me figuring out how to interface with boring and rustls.
|
||||
It works to establish a connection and exchange data but I haven't written real tests yet, nor did I cleanup the code or made the effort to make it look nice.
|
||||
There is probably some code in here that should rather live in the `boring` crate.
|
||||
Built on `boring` v5 and `rustls` 0.23.
|
||||
|
||||
Further, the rustls crypto provider API is still not stable it seems. This works currently with `rustls = 0.22.0-alpha.5`.
|
||||
## Features
|
||||
|
||||
### Supported ciphers
|
||||
Currently, supports only TLS 1.3:
|
||||
No features are enabled by default. The provider ships with TLS 1.3 support
|
||||
out of the box; additional capabilities are opt-in.
|
||||
|
||||
| Feature | Description |
|
||||
|---|---|
|
||||
| `fips` | Build against FIPS-validated BoringSSL and restrict the provider to FIPS-approved algorithms only (SP 800-52r2). See [FIPS mode](#fips-mode) below. |
|
||||
| `fips-precompiled` | Deprecated alias for `fips`. Matches the `boring` crate's feature name. |
|
||||
| `tls12` | Enable TLS 1.2 cipher suites (`ECDHE-ECDSA` and `ECDHE-RSA` with AES-GCM and ChaCha20-Poly1305). Without this only TLS 1.3 is available. |
|
||||
| `logging` | Enable debug logging of BoringSSL errors and provider internals via the `log` crate. |
|
||||
|
||||
## Supported Algorithms
|
||||
|
||||
### Cipher Suites
|
||||
|
||||
TLS 1.3 (always available):
|
||||
```
|
||||
AES_128_GCM_SHA256
|
||||
AES_256_GCM_SHA384
|
||||
CHACHA20_POLY1305_SHA256
|
||||
```
|
||||
|
||||
QUIC: not yet supported
|
||||
|
||||
TLS 1.2:
|
||||
TLS 1.2 (requires `tls12` feature):
|
||||
```
|
||||
ECDHE_ECDSA_AES128_GCM_SHA256
|
||||
ECDHE_RSA_AES128_GCM_SHA256
|
||||
|
||||
ECDHE_ECDSA_AES256_GCM_SHA384
|
||||
ECDHE_RSA_AES256_GCM_SHA384
|
||||
|
||||
ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
```
|
||||
|
||||
### Key Exchange Algorithms
|
||||
### Key Exchange Groups
|
||||
|
||||
`ECDHE` with curves:
|
||||
ECDHE:
|
||||
```
|
||||
X25519
|
||||
X448
|
||||
secp256r1
|
||||
secp384r1
|
||||
secp521r1
|
||||
secp256r1 (P-256)
|
||||
secp384r1 (P-384)
|
||||
secp521r1 (P-521)
|
||||
```
|
||||
|
||||
|
||||
`FFDHE` with:
|
||||
FFDHE:
|
||||
```
|
||||
ffdhe2048
|
||||
```
|
||||
|
||||
### Signature Generation / Verification
|
||||
### Signature Algorithms
|
||||
|
||||
```
|
||||
RSA_PKCS1_SHA256
|
||||
|
|
@ -66,6 +71,30 @@ ED25519
|
|||
ED448
|
||||
```
|
||||
|
||||
## FIPS Mode
|
||||
|
||||
When the `fips` feature is enabled the provider builds against a FIPS-validated
|
||||
version of BoringSSL and restricts all algorithm selections to those approved
|
||||
under [SP 800-52r2](https://doi.org/10.6028/NIST.SP.800-52r2), aligned with
|
||||
boring's `fips202205` compliance policy:
|
||||
|
||||
- **Cipher suites**: AES-GCM only (no ChaCha20-Poly1305).
|
||||
- **Key exchange groups**: P-256 and P-384 only (no X25519, X448, P-521, or FFDHE).
|
||||
- **Signature algorithms**: RSA PKCS#1 / PSS and ECDSA with P-256 or P-384 only
|
||||
(no P-521, Ed25519, or Ed448).
|
||||
|
||||
Post-quantum hybrid key exchange (`P256Kyber768Draft00`) is planned for the
|
||||
FIPS group set but not yet implemented.
|
||||
|
||||
## Workspace Structure
|
||||
|
||||
| Crate | Purpose |
|
||||
|---|---|
|
||||
| `boring-rustls-provider` | The main rustls crypto provider. |
|
||||
| `boring-additions` | Safe Rust wrappers for BoringSSL APIs not yet exposed by the `boring` crate (AEAD, EVP_PKEY_CTX, HMAC_CTX). Intended for upstreaming. |
|
||||
| `boring-sys-additions` | Raw FFI binding for `CRYPTO_tls1_prf` (internal BoringSSL symbol used for FIPS-compliant TLS 1.2 PRF). Intended for upstreaming. |
|
||||
| `examples` | Example client binary. |
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
|
|
|||
|
|
@ -8,13 +8,30 @@ description = "Boringssl rustls provider"
|
|||
publish = false
|
||||
|
||||
[features]
|
||||
default = ["tls12"]
|
||||
# Use a FIPS-validated version of boringssl.
|
||||
fips = ["boring/fips", "boring-sys/fips"]
|
||||
logging = ["log"]
|
||||
fips-only = ["boring/fips", "boring-sys/fips"]
|
||||
default = []
|
||||
|
||||
# Build against a FIPS-validated version of BoringSSL and restrict the
|
||||
# provider to FIPS-approved algorithms only. This affects:
|
||||
# - Cipher suites: AES-GCM only (no ChaCha20-Poly1305).
|
||||
# - Key exchange groups: P-256 and P-384 only (no X25519, X448, P-521,
|
||||
# or FFDHE). P256Kyber768Draft00 will be added once implemented.
|
||||
# - Signature algorithms: RSA PKCS#1 / PSS and ECDSA with P-256/P-384
|
||||
# only (no P-521, Ed25519, or Ed448).
|
||||
# Aligned with boring's `fips202205` compliance policy (SP 800-52r2).
|
||||
fips = ["boring/fips"]
|
||||
|
||||
# Deprecated alias for `fips`. Matches the boring crate's feature name
|
||||
# for backwards compatibility.
|
||||
fips-precompiled = ["fips"]
|
||||
|
||||
# Enable TLS 1.2 cipher suites (ECDHE-ECDSA and ECDHE-RSA with AES-GCM
|
||||
# and ChaCha20-Poly1305). Without this feature only TLS 1.3 is available.
|
||||
tls12 = ["rustls/tls12"]
|
||||
|
||||
# Enable debug logging of BoringSSL errors and provider internals via
|
||||
# the `log` crate. Useful for diagnosing handshake failures.
|
||||
logging = ["log"]
|
||||
|
||||
[dependencies]
|
||||
aead = {version = "0.5", default-features = false, features = ["alloc"] }
|
||||
boring = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ use std::marker::PhantomData;
|
|||
use aead::{AeadCore, AeadInPlace, Buffer, Nonce, Tag};
|
||||
use boring::error::ErrorStack;
|
||||
use boring_additions::aead::Algorithm;
|
||||
use rustls::crypto::cipher::{
|
||||
self, make_tls12_aad, make_tls13_aad, BorrowedPayload, Iv, PrefixedPayload,
|
||||
};
|
||||
#[cfg(feature = "tls12")]
|
||||
use rustls::crypto::cipher::make_tls12_aad;
|
||||
use rustls::crypto::cipher::{self, make_tls13_aad, BorrowedPayload, Iv, PrefixedPayload};
|
||||
use rustls::{ConnectionTrafficSecrets, ContentType, ProtocolVersion};
|
||||
|
||||
use crate::helper::log_and_map;
|
||||
|
|
@ -20,6 +20,8 @@ pub(crate) trait BoringCipher {
|
|||
/// The IV's fixed length (Not the full IV length, only the part that doesn't change).
|
||||
/// Together with [`BoringCipher::explicit_nonce_len`] it determines the total
|
||||
/// lengths of the used nonce.
|
||||
/// Used only by TLS 1.2 code paths.
|
||||
#[cfg(feature = "tls12")]
|
||||
const FIXED_IV_LEN: usize;
|
||||
/// The key size in bytes
|
||||
const KEY_SIZE: usize;
|
||||
|
|
@ -569,7 +571,8 @@ impl Buffer for EncryptBufferAdapter<'_> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hex_literal::hex;
|
||||
use rustls::crypto::cipher::{AeadKey, Iv};
|
||||
use rustls::crypto::cipher::AeadKey;
|
||||
use rustls::crypto::cipher::Iv;
|
||||
|
||||
use crate::aead::BoringAeadCrypter;
|
||||
use rustls::quic::PacketKey;
|
||||
|
|
@ -611,7 +614,7 @@ mod tests {
|
|||
let unprotected_header = hex!("4200bff4");
|
||||
|
||||
let protector = BoringAeadCrypter::<ChaCha20Poly1305>::new(
|
||||
Iv::new(iv),
|
||||
Iv::from(iv),
|
||||
&key,
|
||||
rustls::ProtocolVersion::TLSv1_3,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ impl BoringAead for Aes128 {}
|
|||
impl BoringCipher for Aes128 {
|
||||
const EXPLICIT_NONCE_LEN: usize = 8;
|
||||
|
||||
#[cfg(feature = "tls12")]
|
||||
const FIXED_IV_LEN: usize = 4;
|
||||
|
||||
const KEY_SIZE: usize = 16;
|
||||
|
|
@ -55,6 +56,7 @@ impl BoringAead for Aes256 {}
|
|||
impl BoringCipher for Aes256 {
|
||||
const EXPLICIT_NONCE_LEN: usize = 8;
|
||||
|
||||
#[cfg(feature = "tls12")]
|
||||
const FIXED_IV_LEN: usize = 4;
|
||||
|
||||
const KEY_SIZE: usize = 32;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ impl BoringAead for ChaCha20Poly1305 {}
|
|||
impl BoringCipher for ChaCha20Poly1305 {
|
||||
const EXPLICIT_NONCE_LEN: usize = 0;
|
||||
|
||||
#[cfg(feature = "tls12")]
|
||||
const FIXED_IV_LEN: usize = 12;
|
||||
|
||||
const KEY_SIZE: usize = 32;
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ pub mod tls13;
|
|||
pub mod verify;
|
||||
|
||||
pub fn provider() -> CryptoProvider {
|
||||
#[cfg(feature = "fips-only")]
|
||||
#[cfg(feature = "fips")]
|
||||
{
|
||||
provider_with_ciphers(ALL_FIPS_CIPHER_SUITES.to_vec())
|
||||
}
|
||||
#[cfg(not(feature = "fips-only"))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
{
|
||||
provider_with_ciphers(ALL_CIPHER_SUITES.to_vec())
|
||||
}
|
||||
|
|
@ -35,13 +35,13 @@ pub fn provider() -> CryptoProvider {
|
|||
pub fn provider_with_ciphers(ciphers: Vec<rustls::SupportedCipherSuite>) -> CryptoProvider {
|
||||
CryptoProvider {
|
||||
cipher_suites: ciphers,
|
||||
#[cfg(feature = "fips-only")]
|
||||
#[cfg(feature = "fips")]
|
||||
kx_groups: ALL_FIPS_KX_GROUPS.to_vec(),
|
||||
#[cfg(not(feature = "fips-only"))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
kx_groups: ALL_KX_GROUPS.to_vec(),
|
||||
#[cfg(feature = "fips-only")]
|
||||
#[cfg(feature = "fips")]
|
||||
signature_verification_algorithms: verify::ALL_FIPS_ALGORITHMS,
|
||||
#[cfg(not(feature = "fips-only"))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
signature_verification_algorithms: verify::ALL_ALGORITHMS,
|
||||
secure_random: &Provider,
|
||||
key_provider: &Provider,
|
||||
|
|
@ -99,18 +99,15 @@ static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
|
|||
SupportedCipherSuite::Tls12(&tls12::ECDHE_RSA_AES128_GCM_SHA256),
|
||||
];
|
||||
|
||||
/// Allowed KX curves for FIPS are recommended
|
||||
/// in [NIST SP 800-186](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186.pdf)
|
||||
/// Allowed KX groups for FIPS per [SP 800-52r2](https://doi.org/10.6028/NIST.SP.800-52r2),
|
||||
/// aligned with boring's `fips202205` compliance policy.
|
||||
///
|
||||
/// See Sec. 3.1.2 Table 2
|
||||
/// Ordered in decending order of security strength
|
||||
/// See Section 3.3.1 and 3.4.2.2.
|
||||
// TODO: Add P256Kyber768Draft00 once the PQ hybrid KEM is implemented (Step 3).
|
||||
#[allow(unused)]
|
||||
pub const ALL_FIPS_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
|
||||
&kx::Secp521r1 as _, // P-521 in FIPS lingo
|
||||
&kx::X448 as _, // Curve448 in FIPS lingo
|
||||
&kx::Secp384r1 as _, // P-384 in FIPS lingo
|
||||
&kx::X25519 as _, // Curve25519 in FIPS lingo
|
||||
&kx::Secp256r1 as _, // P-256 in FIPS lingo
|
||||
&kx::Secp256r1 as _, // P-256
|
||||
&kx::Secp384r1 as _, // P-384
|
||||
];
|
||||
|
||||
#[allow(unused)]
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ pub static ALL_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms
|
|||
],
|
||||
};
|
||||
|
||||
/// FIPS-approved signature verification algorithms per SP 800-52r2.
|
||||
///
|
||||
/// Aligned with boring's `fips202205` compliance policy:
|
||||
/// - RSA: PKCS#1 v1.5 and PSS with SHA-256/384/512
|
||||
/// - ECDSA: P-256 with SHA-256 and P-384 with SHA-384 only
|
||||
/// (SP 800-52r2 Table 4.1: "The curve should be P-256 or P-384")
|
||||
/// - No P-521, Ed25519, or Ed448
|
||||
#[allow(unused)]
|
||||
pub static ALL_FIPS_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
|
||||
all: &[
|
||||
|
|
@ -72,9 +79,6 @@ pub static ALL_FIPS_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgor
|
|||
&rsa::BoringRsaVerifier::RSA_PSS_SHA512,
|
||||
&ec::BoringEcVerifier::ECDSA_NISTP256_SHA256,
|
||||
&ec::BoringEcVerifier::ECDSA_NISTP384_SHA384,
|
||||
&ec::BoringEcVerifier::ECDSA_NISTP521_SHA512,
|
||||
//&ed::BoringEdVerifier::ED25519, // FIPS 186-5: requires SHA512 but boring doesn't want us to set a digest, correct?
|
||||
//&ed::BoringEdVerifier::ED448, // FIPS 186-5: requires SHAKE256 but boring doesn't want us to set a digest, correct?
|
||||
],
|
||||
mapping: &[
|
||||
(
|
||||
|
|
@ -109,11 +113,5 @@ pub static ALL_FIPS_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgor
|
|||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
&[&ec::BoringEcVerifier::ECDSA_NISTP384_SHA384],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP521_SHA512,
|
||||
&[&ec::BoringEcVerifier::ECDSA_NISTP521_SHA512],
|
||||
),
|
||||
// (SignatureScheme::ED25519, &[&ed::BoringEdVerifier::ED25519]),
|
||||
// (SignatureScheme::ED448, &[&ed::BoringEdVerifier::ED448]),
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ use tokio::{
|
|||
net::TcpStream,
|
||||
};
|
||||
|
||||
use boring_rustls_provider::{tls12, tls13};
|
||||
use rustls::{
|
||||
version::{TLS12, TLS13},
|
||||
ClientConfig, ServerConfig, SupportedCipherSuite,
|
||||
};
|
||||
#[cfg(feature = "tls12")]
|
||||
use boring_rustls_provider::tls12;
|
||||
use boring_rustls_provider::tls13;
|
||||
#[cfg(feature = "tls12")]
|
||||
use rustls::version::TLS12;
|
||||
use rustls::{version::TLS13, ClientConfig, ServerConfig, SupportedCipherSuite};
|
||||
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_rustls::{TlsAcceptor, TlsConnector};
|
||||
|
|
@ -41,17 +42,107 @@ async fn test_tls13_crypto() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "fips", feature = "fips-only"))]
|
||||
#[cfg(feature = "fips")]
|
||||
fn is_fips_enabled() {
|
||||
assert!(boring::fips::enabled());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-only")))]
|
||||
#[cfg(feature = "fips")]
|
||||
fn fips_provider_excludes_chacha20_cipher_suites() {
|
||||
use rustls::CipherSuite;
|
||||
|
||||
let provider = boring_rustls_provider::provider();
|
||||
let disallowed = [
|
||||
CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
];
|
||||
|
||||
for suite in provider.cipher_suites {
|
||||
let selected = suite.suite();
|
||||
assert!(
|
||||
!disallowed.contains(&selected),
|
||||
"FIPS provider exposed disallowed cipher suite: {selected:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "fips")]
|
||||
fn fips_provider_restricts_kx_groups() {
|
||||
use rustls::NamedGroup;
|
||||
|
||||
let provider = boring_rustls_provider::provider();
|
||||
let groups = provider
|
||||
.kx_groups
|
||||
.iter()
|
||||
.map(|group| group.name())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert!(groups.contains(&NamedGroup::secp256r1));
|
||||
assert!(groups.contains(&NamedGroup::secp384r1));
|
||||
for group in groups {
|
||||
assert!(
|
||||
matches!(group, NamedGroup::secp256r1 | NamedGroup::secp384r1),
|
||||
"FIPS provider exposed disallowed KX group: {group:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "fips")]
|
||||
fn fips_provider_excludes_disallowed_signature_schemes() {
|
||||
use rustls::SignatureScheme;
|
||||
|
||||
let provider = boring_rustls_provider::provider();
|
||||
let schemes = provider
|
||||
.signature_verification_algorithms
|
||||
.mapping
|
||||
.iter()
|
||||
.map(|(scheme, _)| *scheme)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert!(schemes.contains(&SignatureScheme::RSA_PSS_SHA256));
|
||||
assert!(schemes.contains(&SignatureScheme::ECDSA_NISTP256_SHA256));
|
||||
|
||||
for disallowed in [
|
||||
SignatureScheme::ECDSA_NISTP521_SHA512,
|
||||
SignatureScheme::ED25519,
|
||||
SignatureScheme::ED448,
|
||||
] {
|
||||
assert!(
|
||||
!schemes.contains(&disallowed),
|
||||
"FIPS provider exposed disallowed signature scheme: {disallowed:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
fn is_fips_disabled() {
|
||||
assert!(!boring::fips::enabled());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
fn non_fips_provider_keeps_non_fips_algorithms() {
|
||||
use rustls::{CipherSuite, NamedGroup};
|
||||
|
||||
let provider = boring_rustls_provider::provider();
|
||||
|
||||
assert!(provider
|
||||
.cipher_suites
|
||||
.iter()
|
||||
.any(|suite| { suite.suite() == CipherSuite::TLS13_CHACHA20_POLY1305_SHA256 }));
|
||||
|
||||
assert!(provider
|
||||
.kx_groups
|
||||
.iter()
|
||||
.any(|group| group.name() == NamedGroup::X25519));
|
||||
}
|
||||
|
||||
#[cfg(feature = "tls12")]
|
||||
#[tokio::test]
|
||||
async fn test_tls12_ec_crypto() {
|
||||
let pki = TestPki::new(&rcgen::PKCS_ECDSA_P256_SHA256);
|
||||
|
|
@ -78,6 +169,7 @@ async fn test_tls12_ec_crypto() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tls12")]
|
||||
#[tokio::test]
|
||||
async fn test_tls12_rsa_crypto() {
|
||||
let pki = TestPki::new(&rcgen::PKCS_RSA_SHA256);
|
||||
|
|
@ -188,9 +280,14 @@ impl TestPki {
|
|||
}
|
||||
|
||||
fn server_config(self) -> Arc<ServerConfig> {
|
||||
#[cfg(feature = "tls12")]
|
||||
let versions: &[&'static rustls::SupportedProtocolVersion] = &[&TLS12, &TLS13];
|
||||
#[cfg(not(feature = "tls12"))]
|
||||
let versions: &[&'static rustls::SupportedProtocolVersion] = &[&TLS13];
|
||||
|
||||
let mut server_config =
|
||||
ServerConfig::builder_with_provider(Arc::new(boring_rustls_provider::provider()))
|
||||
.with_protocol_versions(&[&TLS12, &TLS13])
|
||||
.with_protocol_versions(versions)
|
||||
.unwrap()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(vec![self.server_cert_der], self.server_key_der)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue