Skip to content

Commit

Permalink
Implement FFDHE support in mbedcrypto-provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Arash Sahebolamri committed Dec 18, 2023
1 parent 08cae7a commit ad8dbf2
Show file tree
Hide file tree
Showing 14 changed files with 406 additions and 17 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ on:
paths-ignore:
- '*.md'
- 'LICENSE'
branches:
- master
merge_group:
schedule:
- cron: '30 13 * * *'
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ publish = false
rustls-mbedcrypto-provider = { path = "../rustls-mbedcrypto-provider", features = ["tls12"] }
rustls-mbedpki-provider = { path = "../rustls-mbedpki-provider" }
env_logger = "0.10"
rustls = { version = "0.22.1", default-features = false }
rustls = { git = "https://github.com/fortanix/rustls", branch = "ffdhe", default-features = false }
rustls-native-certs = "0.7.0"
rustls-pki-types = "1"
rustls-pemfile = "2"
64 changes: 64 additions & 0 deletions examples/src/bin/ffdhe-server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* Copyright (c) Fortanix, Inc.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

use std::io::Write;
use std::sync::Arc;

use rustls::crypto::CryptoProvider;
use rustls_mbedcrypto_provider::{kx_group, mbedtls_crypto_provider};
use rustls_pki_types::{CertificateDer, PrivateKeyDer};

/// Get a certificate chain from the contents of a pem file
fn get_chain(bytes: &[u8]) -> Vec<CertificateDer> {
rustls_pemfile::certs(&mut std::io::BufReader::new(bytes))
.map(Result::unwrap)
.map(CertificateDer::from)
.collect()
}

/// Get a private key from the contents of a pem file
fn get_key(bytes: &[u8]) -> PrivateKeyDer {
let value = rustls_pemfile::pkcs8_private_keys(&mut std::io::BufReader::new(bytes))
.next()
.unwrap()
.unwrap();
PrivateKeyDer::from(value)
}

fn main() {
env_logger::init();

let cert = get_chain(include_bytes!("../../../rustls-mbedpki-provider/test-data/rsa/end.fullchain").as_ref());
let key = get_key(include_bytes!("../../../rustls-mbedpki-provider/test-data/rsa/end.key").as_ref());
let config = rustls::ServerConfig::builder_with_provider(
CryptoProvider {
cipher_suites: vec![
rustls_mbedcrypto_provider::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256,
rustls_mbedcrypto_provider::cipher_suite::TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
],
kx_groups: vec![kx_group::FFDHE2048],
..mbedtls_crypto_provider()
}
.into(),
)
.with_safe_default_protocol_versions()
.unwrap()
.with_no_client_auth()
.with_single_cert(cert, key)
.unwrap();

let config = Arc::new(config);

let server = std::net::TcpListener::bind(("localhost", 8888)).unwrap();
loop {
let mut sock = server.accept().unwrap();
let mut conn = rustls::ServerConnection::new(config.clone()).unwrap();
let mut tls = rustls::Stream::new(&mut conn, &mut sock.0);
println!("write res: {:?}", tls.write_all(b"Hi there!"));
let _ = tls.flush();
}
}
123 changes: 123 additions & 0 deletions examples/src/bin/ffdhe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* Copyright (c) Fortanix, Inc.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

use std::io::{stdout, Read, Write};
use std::net::TcpStream;
use std::sync::Arc;

use rustls::client::danger::{ServerCertVerified, ServerCertVerifier};
use rustls::crypto::CryptoProvider;
use rustls_mbedcrypto_provider::kx_group;
use rustls_mbedcrypto_provider::mbedtls_crypto_provider;
use rustls_mbedpki_provider::MbedTlsServerCertVerifier;

fn main() {
env_logger::init();

let check_server_cert = true;
let server = "browserleaks.com";
let path = "/";
let port = 443;

let server_cert_verifier: Arc<dyn ServerCertVerifier> = if check_server_cert {
let root_certs: Vec<_> = rustls_native_certs::load_native_certs()
.expect("could not load platform certs")
.into_iter()
.map(|cert| cert.into())
.collect();
Arc::new(MbedTlsServerCertVerifier::new(&root_certs).unwrap())
} else {
Arc::new(NoopServerCertVerifier)
};

let config = rustls::ClientConfig::builder_with_provider(
CryptoProvider {
cipher_suites: vec![
rustls_mbedcrypto_provider::cipher_suite::TLS13_AES_256_GCM_SHA384,
rustls_mbedcrypto_provider::cipher_suite::TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
rustls_mbedcrypto_provider::cipher_suite::TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
rustls_mbedcrypto_provider::cipher_suite::TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
],
kx_groups: vec![kx_group::FFDHE2048, kx_group::FFDHE3072, kx_group::FFDHE4096],
..mbedtls_crypto_provider()
}
.into(),
)
.with_safe_default_protocol_versions()
.unwrap()
.dangerous()
.with_custom_certificate_verifier(server_cert_verifier)
.with_no_client_auth();

let server_name = server.try_into().unwrap();
let mut conn = rustls::ClientConnection::new(Arc::new(config), server_name).unwrap();
let mut sock = TcpStream::connect((server, port)).unwrap();
conn.complete_io(&mut sock).unwrap();
println!("tls connection established");
let mut tls = rustls::Stream::new(&mut conn, &mut sock);
tls.write_all(
format!(
"HEAD {path} HTTP/1.1\r\n \
Host: {server}\r\n \
Connection: close\r\n \
Accept-Encoding: identity\r\n \
\r\n"
)
.as_bytes(),
)
.unwrap();
tls.flush().unwrap();

let ciphersuite = tls
.conn
.negotiated_cipher_suite()
.unwrap();
println!("Current ciphersuite: {:?}", ciphersuite.suite());

let mut plaintext = Vec::new();
tls.read_to_end(&mut plaintext).unwrap();
println!("Response:");
stdout().write_all(&plaintext).unwrap();
}

#[derive(Debug)]
#[allow(dead_code)]
struct NoopServerCertVerifier;
impl ServerCertVerifier for NoopServerCertVerifier {
fn verify_server_cert(
&self,
_end_entity: &rustls_pki_types::CertificateDer<'_>,
_intermediates: &[rustls_pki_types::CertificateDer<'_>],
_server_name: &rustls_pki_types::ServerName<'_>,
_ocsp_response: &[u8],
_now: rustls_pki_types::UnixTime,
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(ServerCertVerified::assertion())
}

fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &rustls_pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}

fn verify_tls13_signature(
&self,
_message: &[u8],
_cert: &rustls_pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}

fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
rustls_mbedpki_provider::SUPPORTED_SIGNATURE_SCHEMA.to_vec()
}
}
6 changes: 4 additions & 2 deletions rustls-mbedcrypto-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ categories = ["network-programming", "cryptography"]
resolver = "2"

[dependencies]
rustls = { version = "0.22.1", default-features = false }
rustls = { git = "https://github.com/fortanix/rustls", branch = "ffdhe", default-features = false }
mbedtls = { version = "0.12.1", default-features = false, features = ["std"] }
log = { version = "0.4.4", optional = true }
webpki = { package = "rustls-webpki", version = "0.102.0", features = [
Expand All @@ -25,7 +25,9 @@ bit-vec = "0.6.3"


[dev-dependencies]
rustls = { version = "0.22.1", default-features = false, features = ["ring"] }
rustls = { git = "https://github.com/fortanix/rustls", branch = "ffdhe", default-features = false, features = [
"ring",
] }
webpki-roots = "0.26.0"
rustls-pemfile = "2"
env_logger = "0.10"
Expand Down
Loading

0 comments on commit ad8dbf2

Please sign in to comment.