Skip to content

Commit

Permalink
Update to rustls = 0.22.0-alpha.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Rüth committed Nov 26, 2023
1 parent 71a9f7c commit c368aa2
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ resolver = "2"
[workspace.dependencies]
boring = { version = "4.0", default-features = false }
boring-sys = { version = "4.0", default-features = false }
rustls = { version = "=0.22.0-alpha.4", default-features = false }
rustls = { version = "=0.22.0-alpha.5", default-features = false }
4 changes: 3 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ 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.

Further, the rustls crypto provider API is still not stable it seems. This works currently with `rustls = 0.22.0-alpha.4`.
Further, the rustls crypto provider API is still not stable it seems. This works currently with `rustls = 0.22.0-alpha.5`.

### Supported ciphers
Currently, supports only TLS 1.3:
Expand All @@ -17,6 +17,8 @@ AES_256_GCM_SHA384
CHACHA20_POLY1305_SHA256
```

QUIC: not yet supported

TLS 1.2:
```
ECDHE_ECDSA_AES128_GCM_SHA256
Expand Down
22 changes: 13 additions & 9 deletions boring-rustls-provider/src/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ where
T: BoringAead,
{
fn encrypt(
&self,
&mut self,
msg: cipher::BorrowedPlainMessage,
seq: u64,
) -> Result<cipher::OpaqueMessage, rustls::Error> {
Expand All @@ -121,8 +121,7 @@ where
let fixed_iv_len = <T as BoringCipher>::FIXED_IV_LEN;
let explicit_nonce_len = <T as BoringCipher>::EXPLICIT_NONCE_LEN;

let total_len =
msg.payload.len() + self.crypter.max_overhead() + explicit_nonce_len;
let total_len = self.encrypted_payload_len(msg.payload.len());

let mut full_payload = Vec::with_capacity(total_len);
full_payload.extend_from_slice(&nonce.0.as_ref()[fixed_iv_len..]);
Expand All @@ -139,7 +138,7 @@ where
}

ProtocolVersion::TLSv1_3 => {
let total_len = msg.payload.len() + 1 + self.crypter.max_overhead();
let total_len = self.encrypted_payload_len(msg.payload.len());

let mut payload = Vec::with_capacity(total_len);
payload.extend_from_slice(msg.payload);
Expand All @@ -160,18 +159,23 @@ where
}
}

// Next version seems to add this
// fn encrypted_payload_len(&self, payload_len: usize) -> usize {
// payload_len + 1 + self.crypter.max_overhead()
// }
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
match self.tls_version {
ProtocolVersion::TLSv1_2 => {
payload_len + self.crypter.max_overhead() + <T as BoringCipher>::EXPLICIT_NONCE_LEN
}
ProtocolVersion::TLSv1_3 => payload_len + 1 + self.crypter.max_overhead(),
_ => unimplemented!(),
}
}
}

impl<T> cipher::MessageDecrypter for BoringAeadCrypter<T>
where
T: BoringAead,
{
fn decrypt(
&self,
&mut self,
mut m: cipher::OpaqueMessage,
seq: u64,
) -> Result<cipher::PlainMessage, rustls::Error> {
Expand Down
12 changes: 12 additions & 0 deletions boring-rustls-provider/src/tls12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub static ECDHE_ECDSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
hash_provider: hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
aead_alg: &aead::Aead::<aead::aes::Aes128>::DEFAULT,
prf_provider: &PRF_SHA256,
Expand All @@ -37,6 +39,8 @@ pub static ECDHE_RSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
hash_provider: hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
aead_alg: &aead::Aead::<aead::aes::Aes128>::DEFAULT,
prf_provider: &PRF_SHA256,
Expand All @@ -48,6 +52,8 @@ pub static ECDHE_ECDSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
hash_provider: hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
aead_alg: &aead::Aead::<aead::aes::Aes256>::DEFAULT,
prf_provider: &PRF_SHA384,
Expand All @@ -59,6 +65,8 @@ pub static ECDHE_RSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
hash_provider: hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
aead_alg: &aead::Aead::<aead::aes::Aes256>::DEFAULT,
prf_provider: &PRF_SHA384,
Expand All @@ -70,6 +78,8 @@ pub static ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12Ci
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
aead_alg: &aead::Aead::<aead::chacha20::ChaCha20Poly1305>::DEFAULT,
prf_provider: &PRF_SHA256,
Expand All @@ -81,6 +91,8 @@ pub static ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12Ciph
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
aead_alg: &aead::Aead::<aead::chacha20::ChaCha20Poly1305>::DEFAULT,
prf_provider: &PRF_SHA256,
Expand Down
9 changes: 9 additions & 0 deletions boring-rustls-provider/src/tls13.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,35 @@ pub static AES_128_GCM_SHA256: Tls13CipherSuite = Tls13CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS13_AES_128_GCM_SHA256,
hash_provider: hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
hkdf_provider: &hkdf::Hkdf::<hkdf::Sha256>::DEFAULT,
aead_alg: &aead::Aead::<aead::aes::Aes128>::DEFAULT,
quic: None,
};

pub static AES_256_GCM_SHA384: Tls13CipherSuite = Tls13CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS13_AES_256_GCM_SHA384,
hash_provider: hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
hkdf_provider: &hkdf::Hkdf::<hkdf::Sha384>::DEFAULT,
aead_alg: &aead::Aead::<aead::aes::Aes256>::DEFAULT,
quic: None,
};

pub static CHACHA20_POLY1305_SHA256: Tls13CipherSuite = Tls13CipherSuite {
common: rustls::CipherSuiteCommon {
suite: rustls::CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
hash_provider: hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},

hkdf_provider: &hkdf::Hkdf::<hkdf::Sha256>::DEFAULT,
aead_alg: &aead::Aead::<aead::chacha20::ChaCha20Poly1305>::DEFAULT,
quic: None,
};
81 changes: 29 additions & 52 deletions boring-rustls-provider/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use tokio::{
use boring_rustls_provider::{tls12, tls13, PROVIDER};
use rustls::{
version::{TLS12, TLS13},
ServerConfig, SupportedCipherSuite,
ClientConfig, ServerConfig, SupportedCipherSuite,
};
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use tokio::net::TcpListener;
Expand All @@ -28,30 +28,15 @@ async fn test_tls13_crypto() {
];

for cipher in ciphers {
let config = rustls::ClientConfig::builder_with_provider(PROVIDER)
let config = 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");
do_exchange(config, server_config.clone()).await;
}
}

Expand All @@ -69,30 +54,15 @@ async fn test_tls12_ec_crypto() {
];

for cipher in ciphers {
let config = rustls::ClientConfig::builder_with_provider(PROVIDER)
let config = ClientConfig::builder_with_provider(PROVIDER)
.with_cipher_suites(&[cipher])
.with_safe_default_kx_groups()
.with_protocol_versions(&[&TLS12])
.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");
do_exchange(config, server_config.clone()).await;
}
}

Expand All @@ -110,37 +80,44 @@ async fn test_tls12_rsa_crypto() {
];

for cipher in ciphers {
let config = rustls::ClientConfig::builder_with_provider(PROVIDER)
let config = ClientConfig::builder_with_provider(PROVIDER)
.with_cipher_suites(&[cipher])
.with_safe_default_kx_groups()
.with_protocol_versions(&[&TLS12])
.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");
do_exchange(config, server_config.clone()).await;
}
}

async fn new_listener() -> TcpListener {
TcpListener::bind("localhost:0").await.unwrap()
}

async fn do_exchange(config: ClientConfig, server_config: Arc<ServerConfig>) {
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_pki_types::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 spawn_echo_server(listener: TcpListener, config: Arc<ServerConfig>) {
let acceptor = TlsAcceptor::from(config);

Expand Down

0 comments on commit c368aa2

Please sign in to comment.