Skip to content

Commit

Permalink
Test against aws-lc-rs provider (#4)
Browse files Browse the repository at this point in the history
Add signing/verification of ECDSA/ED25119

Remove unwraps from key exchanges
  • Loading branch information
tofay authored Nov 8, 2024
1 parent ef1cf01 commit 140d73d
Show file tree
Hide file tree
Showing 10 changed files with 464 additions and 251 deletions.
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rustls-openssl"
authors = ["Tom Fay <[email protected]>"]
version = "0.1.0"
version = "0.0.1"
edition = "2021"
license = "MIT"
description = "Rustls crypto provider for OpenSSL"
Expand All @@ -15,7 +15,7 @@ rustls = { version = "0.23.0", features = [
"tls12",
"std",
], default-features = false }
rustls-webpki = "0.102.2"
rustls-webpki = { version = "0.102.2", default-features = false }

[features]
default = []
Expand All @@ -27,5 +27,7 @@ antidote = "1.0.0"
lazy_static = "1.4.0"
once_cell = "1.8.0"
rstest = "0.23.0"
# Use aws_lc_rs to test our provider
rustls = { version = "0.23.0", features = ["aws_lc_rs"] }
rustls-pemfile = "2"
webpki-roots = "0.26"
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# rustls-openssl
An experimental [rustls Crypto Provider](https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html) that uses OpenSSL for cryptographic operations.
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.
Expand All @@ -20,6 +23,9 @@ TLS13_CHACHA20_POLY1305_SHA256 // Requires the `chacha` feature
### TLS 1.2

```
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 // Requires the `chacha` feature
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 // Requires the `chacha` feature
Expand All @@ -36,4 +42,4 @@ X25519 // Requires the `x25519` feature

## Signature verification algorithms

ECDSA signature verification is done using the webpki ring implementation. ED25119 and RSA signature verification is done using openssl.
ECDSA signature verification is done using the webpki ring implementation. ED25519 and RSA signature verification is done using openssl.
98 changes: 49 additions & 49 deletions src/cipher_suites.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,20 @@ pub static TLS13_AES_128_GCM_SHA256: SupportedCipherSuite =

/// TLS 1.2
// /// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256.
// #[cfg(feature = "chacha")]
// pub static TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
// SupportedCipherSuite::Tls12(&Tls12CipherSuite {
// common: CipherSuiteCommon {
// suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
// hash_provider: &HashAlgorithm::SHA256,
// confidentiality_limit: u64::MAX,
// },
// kx: KeyExchangeAlgorithm::ECDHE,
// sign: TLS12_ECDSA_SCHEMES,
// aead_alg: &crate::tls12::Tls12ChaCha,
// prf_provider: &PrfUsingHmac(&HmacSha256),
// });
/// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256.
#[cfg(feature = "chacha")]
pub static TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
common: CipherSuiteCommon {
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: &HashAlgorithm::SHA256,
confidentiality_limit: u64::MAX,
},
kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES,
aead_alg: &crate::tls12::Tls12ChaCha,
prf_provider: &PrfUsingHmac(&HmacSha256),
});

/// The TLS1.2 ciphersuite TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
#[cfg(feature = "chacha")]
Expand Down Expand Up @@ -115,43 +115,43 @@ pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
prf_provider: &PrfUsingHmac(&HmacSha384),
});

// /// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
// pub static TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
// SupportedCipherSuite::Tls12(&Tls12CipherSuite {
// common: CipherSuiteCommon {
// suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
// hash_provider: &HashAlgorithm::SHA256,
// confidentiality_limit: 1 << 23,
// },
// kx: KeyExchangeAlgorithm::ECDHE,
// sign: TLS12_ECDSA_SCHEMES,
// aead_alg: &Tls12Gcm {
// algo_type: AesGcm::Aes128Gcm,
// },
// prf_provider: &PrfUsingHmac(&HmacSha256),
// });
/// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
pub static TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
common: CipherSuiteCommon {
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
hash_provider: &HashAlgorithm::SHA256,
confidentiality_limit: 1 << 23,
},
kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES,
aead_alg: &Tls12Gcm {
algo_type: AesGcm::Aes128Gcm,
},
prf_provider: &PrfUsingHmac(&HmacSha256),
});

// /// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
// pub static TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
// SupportedCipherSuite::Tls12(&Tls12CipherSuite {
// common: CipherSuiteCommon {
// suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// hash_provider: &HashAlgorithm::SHA384,
// confidentiality_limit: 1 << 23,
// },
// kx: KeyExchangeAlgorithm::ECDHE,
// sign: TLS12_ECDSA_SCHEMES,
// aead_alg: &Tls12Gcm {
// algo_type: AesGcm::Aes256Gcm,
// },
// prf_provider: &PrfUsingHmac(&HmacSha384),
// });
/// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
pub static TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
common: CipherSuiteCommon {
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
hash_provider: &HashAlgorithm::SHA384,
confidentiality_limit: 1 << 23,
},
kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES,
aead_alg: &Tls12Gcm {
algo_type: AesGcm::Aes256Gcm,
},
prf_provider: &PrfUsingHmac(&HmacSha384),
});

// static TLS12_ECDSA_SCHEMES: &[SignatureScheme] = &[
// SignatureScheme::ECDSA_NISTP521_SHA512,
// SignatureScheme::ECDSA_NISTP384_SHA384,
// SignatureScheme::ECDSA_NISTP256_SHA256,
// ];
static TLS12_ECDSA_SCHEMES: &[SignatureScheme] = &[
SignatureScheme::ECDSA_NISTP521_SHA512,
SignatureScheme::ECDSA_NISTP384_SHA384,
SignatureScheme::ECDSA_NISTP256_SHA256,
];

/// RSA schemes in descending order of preference
pub(crate) static TLS12_RSA_SCHEMES: &[SignatureScheme] = &[
Expand Down
87 changes: 50 additions & 37 deletions src/ecdh.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use openssl::bn::BigNumContext;
use openssl::derive::Deriver;
use openssl::ec::{EcGroup, EcKey, EcPoint, PointConversionForm};
use openssl::error::ErrorStack;
use openssl::nid::Nid;
#[cfg(feature = "x25519")]
use openssl::pkey::Id;
Expand Down Expand Up @@ -62,20 +63,23 @@ pub const SECP384R1: &dyn SupportedKxGroup = &EcKxGroup {

impl SupportedKxGroup for EcKxGroup {
fn start(&self) -> Result<Box<(dyn ActiveKeyExchange)>, Error> {
let group = EcGroup::from_curve_name(self.nid).unwrap();
let priv_key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let pub_key = priv_key
.public_key()
.to_bytes(&group, PointConversionForm::UNCOMPRESSED, &mut ctx)
.unwrap();

Ok(Box::new(EcKeyExchange {
priv_key,
name: self.name,
group,
pub_key,
}))
EcGroup::from_curve_name(self.nid)
.and_then(|group| {
let priv_key = EcKey::generate(&group)?;
let mut ctx = BigNumContext::new()?;
let pub_key = priv_key.public_key().to_bytes(
&group,
PointConversionForm::UNCOMPRESSED,
&mut ctx,
)?;
Ok(Box::new(EcKeyExchange {
priv_key,
name: self.name,
group,
pub_key,
}) as Box<dyn ActiveKeyExchange>)
})
.map_err(|e| Error::General(format!("OpenSSL error: {}", e)))
}

fn name(&self) -> NamedGroup {
Expand All @@ -84,24 +88,27 @@ impl SupportedKxGroup for EcKxGroup {
}

impl EcKeyExchange {
fn load_peer_key(&self, peer_pub_key: &[u8]) -> Result<PKey<Public>, Error> {
let mut ctx = BigNumContext::new().unwrap();
let point = EcPoint::from_bytes(&self.group, peer_pub_key, &mut ctx).unwrap();
let peer_key = EcKey::from_public_key(&self.group, &point).unwrap();
peer_key.check_key().unwrap();
let peer_key: PKey<_> = peer_key.try_into().unwrap();
fn load_peer_key(&self, peer_pub_key: &[u8]) -> Result<PKey<Public>, ErrorStack> {
let mut ctx = BigNumContext::new()?;
let point = EcPoint::from_bytes(&self.group, peer_pub_key, &mut ctx)?;
let peer_key = EcKey::from_public_key(&self.group, &point)?;
peer_key.check_key()?;
let peer_key: PKey<_> = peer_key.try_into()?;
Ok(peer_key)
}
}

impl ActiveKeyExchange for EcKeyExchange {
fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
let peer_key = self.load_peer_key(peer_pub_key).unwrap();
let key: PKey<_> = self.priv_key.try_into().unwrap();
let mut deriver = Deriver::new(&key).unwrap();
deriver.set_peer(&peer_key).unwrap();
let secret = deriver.derive_to_vec().unwrap();
Ok(SharedSecret::from(secret.as_slice()))
self.load_peer_key(peer_pub_key)
.and_then(|peer_key| {
let key: PKey<_> = self.priv_key.try_into()?;
let mut deriver = Deriver::new(&key)?;
deriver.set_peer(&peer_key)?;
let secret = deriver.derive_to_vec()?;
Ok(SharedSecret::from(secret.as_slice()))
})
.map_err(|e| Error::General(format!("OpenSSL error: {}", e)))
}

fn pub_key(&self) -> &[u8] {
Expand All @@ -116,12 +123,15 @@ impl ActiveKeyExchange for EcKeyExchange {
#[cfg(feature = "x25519")]
impl SupportedKxGroup for X25519KxGroup {
fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error> {
let private_key = PKey::generate_x25519().unwrap();
let public_key = private_key.raw_public_key().unwrap();
Ok(Box::new(X25519KeyExchange {
private_key,
public_key,
}))
PKey::generate_x25519()
.and_then(|private_key| {
let public_key = private_key.raw_public_key()?;
Ok(Box::new(X25519KeyExchange {
private_key,
public_key,
}) as Box<dyn ActiveKeyExchange>)
})
.map_err(|e| Error::General(format!("OpenSSL error: {}", e)))
}

fn name(&self) -> NamedGroup {
Expand All @@ -132,11 +142,14 @@ impl SupportedKxGroup for X25519KxGroup {
#[cfg(feature = "x25519")]
impl ActiveKeyExchange for X25519KeyExchange {
fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
let peer_public_key = PKey::public_key_from_raw_bytes(peer_pub_key, Id::X25519).unwrap();
let mut deriver = Deriver::new(&self.private_key).unwrap();
deriver.set_peer(&peer_public_key).unwrap();
let secret = deriver.derive_to_vec().unwrap();
Ok(SharedSecret::from(secret.as_slice()))
PKey::public_key_from_raw_bytes(peer_pub_key, Id::X25519)
.and_then(|peer_pub_key| {
let mut deriver = Deriver::new(&self.private_key)?;
deriver.set_peer(&peer_pub_key)?;
let secret = deriver.derive_to_vec()?;
Ok(SharedSecret::from(secret.as_slice()))
})
.map_err(|e| Error::General(format!("OpenSSL error: {}", e)))
}

fn pub_key(&self) -> &[u8] {
Expand Down
Loading

0 comments on commit 140d73d

Please sign in to comment.