Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ jobs:
- name: Cache build artifacts
uses: Swatinem/rust-cache@v2
- name: cargo test
run: cargo test --all-features
run: cargo test
# https://github.com/rust-lang/cargo/issues/6669
- name: cargo test --doc
run: cargo test --doc --all-features
run: cargo test --doc
lint:
name: Lint
runs-on: ubuntu-latest
Expand All @@ -44,4 +44,23 @@ jobs:
- name: cargo fmt (check)
run: cargo fmt -- --check -l
- name: cargo clippy (warnings)
run: cargo clippy --all-targets --all-features -- -D warnings
run: cargo clippy --all-targets -- -D warnings

test-fips:
name: Test using FIPS openssl
runs-on: ubuntu-latest
container:
image: registry.access.redhat.com/ubi8/ubi:latest
steps:
- name: Install dependencies
run: dnf install -y gcc openssl-devel openssl
- name: Check out repository
uses: actions/checkout@v4
- name: Install toolchain
uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
- name: Cache build artifacts
uses: Swatinem/rust-cache@v2
- name: Run cargo test --features fips
run: cargo test --features fips
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ rustls = { version = "0.23.0", default-features = false }
rustls-webpki = { version = "0.102.2", default-features = false }

[features]
default = ["tls12", "x25519"]
x25519 = []
default = ["tls12"]
fips = []
tls12 = ["rustls/tls12", "foreign-types-shared"]

[dev-dependencies]
Expand Down
45 changes: 3 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,7 @@
# rustls-openssl
A [rustls Crypto Provider](https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html) that uses OpenSSL for cryptographic operations.

## Status
**Early in development.**

## Usage
The main entry points are the `rustls_openssl::default_provider` and `rustls_openssl::custom_provider` functions.
See the [rustls documentation]((https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html)) for how to use them.

## Supported Ciphers

Supported cipher suites are listed below, in descending order of preference.
If OpenSSL is compiled with the `OPENSSL_NO_CHACHA` option, the ChaCha20-Poly1305 ciphers will not be available.

### TLS 1.3

The following cipher suites are supported for TLS 1.3. These support QUIC.

```
TLS13_AES_256_GCM_SHA384
TLS13_AES_128_GCM_SHA256
TLS13_CHACHA20_POLY1305_SHA256
```

### TLS 1.2
*Requires the `tls12` feature, which is a default feature.*

```
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
```
## Supported Key Exchanges

Key exchanges, in descending order ofpreference:

```
SECP384R1
SECP256R1
X25519 // Requires the `x25519` feature
```
[Documentation](https://docs.rs/rustls-openssl)

## Status
**In development.**
5 changes: 5 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const OPENSSL_NO_CHACHA: &str = "OPENSSL_NO_CHACHA";

fn main() {
println!("cargo:rustc-check-cfg=cfg(chacha)");
println!("cargo:rustc-check-cfg=cfg(fips_module)");
// Determine whether to work around https://github.com/openssl/openssl/issues/23448
// according to the OpenSSL version
println!("cargo:rustc-check-cfg=cfg(bugged_add_hkdf_info)");
Expand All @@ -15,6 +16,10 @@ fn main() {
if (0x3_00_00_00_0..0x3_04_00_00_0).contains(&version) {
println!("cargo:rustc-cfg=bugged_add_hkdf_info");
}

if version < 0x3_00_00_00_0 {
println!("cargo:rustc-cfg=fips_module");
}
}

// Enable the `chacha` cfg if the `OPENSSL_NO_CHACHA` OpenSSL config is not set.
Expand Down
4 changes: 2 additions & 2 deletions src/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustls::Error;
pub(crate) enum Algorithm {
Aes128Gcm,
Aes256Gcm,
#[cfg(chacha)]
#[cfg(all(chacha, not(feature = "fips")))]
ChaCha20Poly1305,
}

Expand All @@ -19,7 +19,7 @@ impl Algorithm {
match self {
Self::Aes128Gcm => Cipher::aes_128_gcm(),
Self::Aes256Gcm => Cipher::aes_256_gcm(),
#[cfg(chacha)]
#[cfg(all(chacha, not(feature = "fips")))]
Self::ChaCha20Poly1305 => Cipher::chacha20_poly1305(),
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ impl rustls::crypto::hash::Hash for Algorithm {
Algorithm::SHA384 => rustls::crypto::hash::HashAlgorithm::SHA384,
}
}

fn fips(&self) -> bool {
crate::fips()
}
}

impl Context {
Expand Down
4 changes: 4 additions & 0 deletions src/hkdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ impl RustlsHkdf for Hkdf {
fn hmac_sign(&self, key: &OkmBlock, message: &[u8]) -> Tag {
Hmac(self.0).with_key(key.as_ref()).sign(&[message])
}

fn fips(&self) -> bool {
crate::fips()
}
}

impl RustlsHkdfExpander for HkdfExpander {
Expand Down
4 changes: 4 additions & 0 deletions src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ impl rustls::crypto::hmac::Hmac for Hmac {
fn hash_output_len(&self) -> usize {
self.0.output_len()
}

fn fips(&self) -> bool {
crate::fips()
}
}

impl Key for HmacKey {
Expand Down
35 changes: 20 additions & 15 deletions src/kx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ use openssl::derive::Deriver;
use openssl::ec::{EcGroup, EcKey, EcPoint, PointConversionForm};
use openssl::error::ErrorStack;
use openssl::nid::Nid;
#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
use openssl::pkey::Id;
use openssl::pkey::{PKey, Private, Public};
use rustls::crypto::{ActiveKeyExchange, SharedSecret, SupportedKxGroup};
use rustls::{Error, NamedGroup};

/// Supported `KeyExchange` groups.
/// ```ignore
/// SECP384R1
/// SECP256R1
/// X25519 // Enabled with the `x25519` feature
/// ```
/// [Supported KeyExchange groups](SupportedKxGroup).
/// * [SECP384R1]
/// * [SECP256R1]
/// * [X25519]
///
/// If the `fips` feature is enabled, only [SECP384R1] and [SECP256R1] are available.
pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
SECP256R1,
SECP384R1,
#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
X25519,
];

Expand All @@ -36,26 +36,27 @@ struct EcKeyExchange {
pub_key: Vec<u8>,
}

#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
/// KXGroup for X25519
#[derive(Debug)]
struct X25519KxGroup {}

#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
#[derive(Debug)]
struct X25519KeyExchange {
private_key: PKey<Private>,
public_key: Vec<u8>,
}

#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
/// X25519 key exchange group as registered with [IANA](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8).
pub const X25519: &dyn SupportedKxGroup = &X25519KxGroup {};

/// secp256r1 key exchange group as registered with [IANA](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8)
pub const SECP256R1: &dyn SupportedKxGroup = &EcKxGroup {
name: NamedGroup::secp256r1,
nid: Nid::X9_62_PRIME256V1,
};

/// secp384r1 key exchange group as registered with [IANA](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8)
pub const SECP384R1: &dyn SupportedKxGroup = &EcKxGroup {
name: NamedGroup::secp384r1,
nid: Nid::SECP384R1,
Expand Down Expand Up @@ -85,6 +86,10 @@ impl SupportedKxGroup for EcKxGroup {
fn name(&self) -> NamedGroup {
self.name
}

fn fips(&self) -> bool {
crate::fips()
}
}

impl EcKeyExchange {
Expand Down Expand Up @@ -120,7 +125,7 @@ impl ActiveKeyExchange for EcKeyExchange {
}
}

#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
impl SupportedKxGroup for X25519KxGroup {
fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error> {
PKey::generate_x25519()
Expand All @@ -139,7 +144,7 @@ impl SupportedKxGroup for X25519KxGroup {
}
}

#[cfg(feature = "x25519")]
#[cfg(not(feature = "fips"))]
impl ActiveKeyExchange for X25519KeyExchange {
fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
PKey::public_key_from_raw_bytes(peer_pub_key, Id::X25519)
Expand Down
Loading