Fix signer and add e2e tls13 test
This commit is contained in:
parent
31ed3963a6
commit
b597423237
4 changed files with 151 additions and 15 deletions
|
|
@ -33,6 +33,9 @@ webpki = { package = "rustls-webpki", version = "0.102.0-alpha.1", default-featu
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex-literal = "0.4"
|
hex-literal = "0.4"
|
||||||
|
rcgen = "0.11.3"
|
||||||
|
tokio = { version = "1.34", features = ["macros", "rt", "net", "io-util", "io-std"] }
|
||||||
|
tokio-rustls = "0.25.0-alpha.2"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ mod hmac;
|
||||||
mod kx;
|
mod kx;
|
||||||
#[cfg(feature = "tls12")]
|
#[cfg(feature = "tls12")]
|
||||||
mod prf;
|
mod prf;
|
||||||
mod sign;
|
pub mod sign;
|
||||||
#[cfg(feature = "tls12")]
|
#[cfg(feature = "tls12")]
|
||||||
mod tls12;
|
pub mod tls12;
|
||||||
mod tls13;
|
pub mod tls13;
|
||||||
mod verify;
|
pub mod verify;
|
||||||
|
|
||||||
/// The boringssl-based Rustls Crypto provider
|
/// The boringssl-based Rustls Crypto provider
|
||||||
pub static PROVIDER: &'static dyn CryptoProvider = &Provider;
|
pub static PROVIDER: &'static dyn CryptoProvider = &Provider;
|
||||||
|
|
|
||||||
|
|
@ -174,17 +174,21 @@ impl BoringSigner {
|
||||||
|
|
||||||
impl rustls::sign::Signer for BoringSigner {
|
impl rustls::sign::Signer for BoringSigner {
|
||||||
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, rustls::Error> {
|
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, rustls::Error> {
|
||||||
let signer = self.get_signer();
|
let mut signer = self.get_signer();
|
||||||
let mut msg_with_sig =
|
let max_sig_len = signer
|
||||||
Vec::<u8>::with_capacity(message.len() + boring_sys::EVP_MAX_MD_SIZE as usize);
|
.len()
|
||||||
msg_with_sig.extend_from_slice(message);
|
.map_err(|e| log_and_map("len", e, rustls::Error::General("failed signing".into())))?;
|
||||||
msg_with_sig.extend_from_slice(&[0u8; boring_sys::EVP_MAX_MD_SIZE as usize]);
|
let mut sig = vec![0u8; max_sig_len];
|
||||||
|
|
||||||
let toatl_len = signer
|
let sig_len = signer.sign_oneshot(&mut sig[..], message).map_err(|e| {
|
||||||
.sign(&mut msg_with_sig[..])
|
log_and_map(
|
||||||
.map_err(|e| log_and_map("sign", e, rustls::Error::General("failed signing".into())))?;
|
"sign_oneshot",
|
||||||
msg_with_sig.truncate(toatl_len);
|
e,
|
||||||
Ok(msg_with_sig)
|
rustls::Error::General("failed signing".into()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
sig.truncate(sig_len);
|
||||||
|
Ok(sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scheme(&self) -> rustls::SignatureScheme {
|
fn scheme(&self) -> rustls::SignatureScheme {
|
||||||
|
|
|
||||||
129
boring-rustls-provider/tests/e2e.rs
Normal file
129
boring-rustls-provider/tests/e2e.rs
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::{
|
||||||
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
|
net::TcpStream,
|
||||||
|
};
|
||||||
|
|
||||||
|
use boring_rustls_provider::{tls13, PROVIDER};
|
||||||
|
use rustls::{version::TLS13, ServerConfig, SupportedCipherSuite};
|
||||||
|
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
use tokio_rustls::{TlsAcceptor, TlsConnector};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_tls13_crypto() {
|
||||||
|
let pki = TestPki::new(&rcgen::PKCS_ECDSA_P256_SHA256);
|
||||||
|
|
||||||
|
let root_store = pki.client_root_store();
|
||||||
|
let server_config = pki.server_config();
|
||||||
|
|
||||||
|
let ciphers = [
|
||||||
|
SupportedCipherSuite::Tls13(&tls13::AES_128_GCM_SHA256),
|
||||||
|
SupportedCipherSuite::Tls13(&tls13::AES_256_GCM_SHA384),
|
||||||
|
];
|
||||||
|
|
||||||
|
for cipher in ciphers {
|
||||||
|
let config = rustls::ClientConfig::builder_with_provider(PROVIDER)
|
||||||
|
.with_cipher_suites(&[cipher])
|
||||||
|
.with_safe_default_kx_groups()
|
||||||
|
.with_protocol_versions(&[&TLS13])
|
||||||
|
.unwrap()
|
||||||
|
.with_root_certificates(root_store.clone())
|
||||||
|
.with_no_client_auth();
|
||||||
|
|
||||||
|
let listener = new_listener().await;
|
||||||
|
let addr = listener.local_addr().unwrap();
|
||||||
|
tokio::spawn(spawn_echo_server(listener, server_config.clone()));
|
||||||
|
|
||||||
|
let connector = TlsConnector::from(Arc::new(config));
|
||||||
|
let stream = TcpStream::connect(&addr).await.unwrap();
|
||||||
|
|
||||||
|
let mut stream = connector
|
||||||
|
.connect(rustls::ServerName::try_from("localhost").unwrap(), stream)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
stream.write_all(b"HELLO").await.unwrap();
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let bytes = stream.read_to_end(&mut buf).await.unwrap();
|
||||||
|
assert_eq!(&buf[..bytes], b"HELLO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn new_listener() -> TcpListener {
|
||||||
|
TcpListener::bind("localhost:0").await.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn spawn_echo_server(listener: TcpListener, config: Arc<ServerConfig>) {
|
||||||
|
let acceptor = TlsAcceptor::from(config);
|
||||||
|
|
||||||
|
let (stream, _) = listener.accept().await.unwrap();
|
||||||
|
let acceptor = acceptor.clone();
|
||||||
|
let mut stream = acceptor.accept(stream).await.unwrap();
|
||||||
|
|
||||||
|
let mut buf = vec![0u8; 5];
|
||||||
|
let bytes = stream.read_exact(buf.as_mut_slice()).await.unwrap();
|
||||||
|
stream.write_all(&buf[..bytes]).await.unwrap();
|
||||||
|
stream.flush().await.unwrap();
|
||||||
|
stream.shutdown().await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TestPki {
|
||||||
|
ca_cert_der: CertificateDer<'static>,
|
||||||
|
server_cert_der: CertificateDer<'static>,
|
||||||
|
server_key_der: PrivateKeyDer<'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestPki {
|
||||||
|
fn new(alg: &'static rcgen::SignatureAlgorithm) -> Self {
|
||||||
|
let mut ca_params = rcgen::CertificateParams::new(Vec::new());
|
||||||
|
ca_params
|
||||||
|
.distinguished_name
|
||||||
|
.push(rcgen::DnType::OrganizationName, "Provider Server Example");
|
||||||
|
ca_params
|
||||||
|
.distinguished_name
|
||||||
|
.push(rcgen::DnType::CommonName, "Example CA");
|
||||||
|
ca_params.is_ca = rcgen::IsCa::Ca(rcgen::BasicConstraints::Unconstrained);
|
||||||
|
ca_params.key_usages = vec![
|
||||||
|
rcgen::KeyUsagePurpose::KeyCertSign,
|
||||||
|
rcgen::KeyUsagePurpose::DigitalSignature,
|
||||||
|
];
|
||||||
|
ca_params.alg = alg;
|
||||||
|
let ca_cert = rcgen::Certificate::from_params(ca_params).unwrap();
|
||||||
|
|
||||||
|
let ca_cert_der = CertificateDer::from(ca_cert.serialize_der().unwrap());
|
||||||
|
// Create a server end entity cert issued by the CA.
|
||||||
|
let mut server_ee_params = rcgen::CertificateParams::new(vec!["localhost".to_string()]);
|
||||||
|
server_ee_params.is_ca = rcgen::IsCa::NoCa;
|
||||||
|
server_ee_params.extended_key_usages = vec![rcgen::ExtendedKeyUsagePurpose::ServerAuth];
|
||||||
|
server_ee_params.alg = alg;
|
||||||
|
let server_cert = rcgen::Certificate::from_params(server_ee_params).unwrap();
|
||||||
|
let server_cert_der =
|
||||||
|
CertificateDer::from(server_cert.serialize_der_with_signer(&ca_cert).unwrap());
|
||||||
|
let server_key_der =
|
||||||
|
PrivatePkcs8KeyDer::from(server_cert.serialize_private_key_der()).into();
|
||||||
|
Self {
|
||||||
|
ca_cert_der,
|
||||||
|
server_cert_der,
|
||||||
|
server_key_der,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn server_config(self) -> Arc<ServerConfig> {
|
||||||
|
let mut server_config = ServerConfig::builder_with_provider(PROVIDER)
|
||||||
|
.with_safe_defaults()
|
||||||
|
.with_no_client_auth()
|
||||||
|
.with_single_cert(vec![self.server_cert_der], self.server_key_der)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
server_config.key_log = Arc::new(rustls::KeyLogFile::new());
|
||||||
|
|
||||||
|
Arc::new(server_config)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn client_root_store(&self) -> rustls::RootCertStore {
|
||||||
|
let mut root_store = rustls::RootCertStore::empty();
|
||||||
|
root_store.add(self.ca_cert_der.clone()).unwrap();
|
||||||
|
root_store
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue