Skip to content

Commit

Permalink
Update rustls to 0.22 and ring to 0.17
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Dec 6, 2023
1 parent b5d23a8 commit 74cdc00
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 53 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ debug = true

[profile.release]
debug = true

[patch."crates-io"]
rustls = { git = "https://github.com/rustls/rustls", branch = "quinn-support" }
12 changes: 7 additions & 5 deletions quinn-proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ all-features = true
maintenance = { status = "experimental" }

[features]
default = ["tls-rustls", "log"]
tls-rustls = ["rustls", "ring"]
default = ["tls-rustls", "rustls-ring", "log"]
tls-rustls = ["rustls-pki-types"]
rustls-ring = ["rustls/ring", "ring"] # Allow rustls to be used with other crypto providers
# Provides `ClientConfig::with_native_roots()` convenience method
native-certs = ["rustls-native-certs"]
# Write logs via the `log` crate when no `tracing` subscriber exists
Expand All @@ -29,9 +30,10 @@ arbitrary = { version = "1.0.1", features = ["derive"], optional = true }
bytes = "1"
rustc-hash = "1.1"
rand = "0.8"
ring = { version = "0.16.7", optional = true }
rustls = { version = "0.21.0", default-features = false, features = ["quic"], optional = true }
rustls-native-certs = { version = "0.6", optional = true }
ring = { version = "0.17", optional = true }
rustls-pki-types = { version = "1", optional = true }
rustls = { version = "0.22", default-features = false, optional = true }
rustls-native-certs = { version = "0.7", optional = true }
slab = "0.4"
thiserror = "1.0.21"
tinyvec = { version = "1.1", features = ["alloc"] }
Expand Down
9 changes: 5 additions & 4 deletions quinn-proto/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::{fmt, num::TryFromIntError, sync::Arc, time::Duration};

#[cfg(feature = "rustls")]
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
use thiserror::Error;

#[cfg(feature = "ring")]
use rand::RngCore;

Expand Down Expand Up @@ -829,8 +830,8 @@ impl ServerConfig {
///
/// Uses a randomized handshake token key.
pub fn with_single_cert(
cert_chain: Vec<rustls::Certificate>,
key: rustls::PrivateKey,
cert_chain: Vec<CertificateDer<'static>>,
key: PrivateKeyDer<'static>,
) -> Result<Self, rustls::Error> {
let crypto = crypto::rustls::server_config(cert_chain, key)?;
Ok(Self::with_crypto(Arc::new(crypto)))
Expand Down Expand Up @@ -914,7 +915,7 @@ impl ClientConfig {
match rustls_native_certs::load_native_certs() {
Ok(certs) => {
for cert in certs {
if let Err(e) = roots.add(&rustls::Certificate(cert.0)) {
if let Err(e) = roots.add(cert) {
tracing::warn!("failed to parse trust anchor: {}", e);
}
}
Expand Down
46 changes: 26 additions & 20 deletions quinn-proto/src/crypto/rustls.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::{any::Any, convert::TryInto, io, str, sync::Arc};
use std::{any::Any, io, str, sync::Arc};

use bytes::BytesMut;
use ring::aead;
pub use rustls::Error;
use rustls::{
self,
quic::{Connection, HeaderProtectionKey, KeyChange, PacketKey, Secrets, Version},
Tls13CipherSuite,
};
use rustls_pki_types::{CertificateDer, PrivateKeyDer, ServerName};

use crate::{
crypto::{
Expand Down Expand Up @@ -61,9 +63,9 @@ impl crypto::Session for TlsSession {
}

fn peer_identity(&self) -> Option<Box<dyn Any>> {
self.inner
.peer_certificates()
.map(|v| -> Box<dyn Any> { Box::new(v.to_vec()) })
self.inner.peer_certificates().map(|v| -> Box<dyn Any> {
Box::new(v.iter().map(|v| v.clone().into_owned()).collect::<Vec<_>>())
})
}

fn early_crypto(&self) -> Option<(Box<dyn HeaderKey>, Box<dyn crypto::PacketKey>)> {
Expand Down Expand Up @@ -204,7 +206,7 @@ const RETRY_INTEGRITY_NONCE_V1: [u8; 12] = [
0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb,
];

impl crypto::HeaderKey for HeaderProtectionKey {
impl crypto::HeaderKey for Box<dyn HeaderProtectionKey> {
fn decrypt(&self, pn_offset: usize, packet: &mut [u8]) {
let (header, sample) = packet.split_at_mut(pn_offset + 4);
let (first, rest) = header.split_at_mut(1);
Expand Down Expand Up @@ -262,9 +264,9 @@ impl crypto::ClientConfig for rustls::ClientConfig {
rustls::quic::ClientConnection::new(
self,
version,
server_name
.try_into()
.map_err(|_| ConnectError::InvalidDnsName(server_name.into()))?,
ServerName::try_from(server_name)
.map_err(|_| ConnectError::InvalidDnsName(server_name.into()))?
.to_owned(),
to_vec(params),
)
.unwrap(),
Expand Down Expand Up @@ -332,7 +334,14 @@ fn to_vec(params: &TransportParameters) -> Vec<u8> {
}

pub(crate) fn initial_keys(version: Version, dst_cid: &ConnectionId, side: Side) -> Keys {
let keys = rustls::quic::Keys::initial(version, dst_cid, side.into());
let keys = rustls::quic::Keys::initial(
version,
INITIAL,
INITIAL.quic.unwrap(),
dst_cid,
side.into(),
);

Keys {
header: KeyPair {
local: Box::new(keys.local.header),
Expand All @@ -345,7 +354,12 @@ pub(crate) fn initial_keys(version: Version, dst_cid: &ConnectionId, side: Side)
}
}

impl crypto::PacketKey for PacketKey {
static INITIAL: &'static Tls13CipherSuite =
rustls::crypto::ring::cipher_suite::TLS13_AES_128_GCM_SHA256
.tls13()
.unwrap();

impl crypto::PacketKey for Box<dyn PacketKey> {
fn encrypt(&self, packet: u64, buf: &mut [u8], header_len: usize) {
let (header, payload_tag) = buf.split_at_mut(header_len);
let (payload, tag_storage) = payload_tag.split_at_mut(payload_tag.len() - self.tag_len());
Expand Down Expand Up @@ -386,10 +400,6 @@ impl crypto::PacketKey for PacketKey {
/// satisfies this requirement.
pub(crate) fn client_config(roots: rustls::RootCertStore) -> rustls::ClientConfig {
let mut cfg = rustls::ClientConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_root_certificates(roots)
.with_no_client_auth();
cfg.enable_early_data = true;
Expand All @@ -402,14 +412,10 @@ pub(crate) fn client_config(roots: rustls::RootCertStore) -> rustls::ClientConfi
/// `u32::MAX`. Advanced users can use any [`rustls::ServerConfig`] that satisfies these
/// requirements.
pub(crate) fn server_config(
cert_chain: Vec<rustls::Certificate>,
key: rustls::PrivateKey,
cert_chain: Vec<CertificateDer<'static>>,
key: PrivateKeyDer<'static>,
) -> Result<rustls::ServerConfig, Error> {
let mut cfg = rustls::ServerConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_no_client_auth()
.with_single_cert(cert_chain, key)?;
cfg.max_early_data_size = u32::MAX;
Expand Down
31 changes: 16 additions & 15 deletions quinn-proto/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use bytes::{Bytes, BytesMut};
use hex_literal::hex;
use rand::RngCore;
use ring::hmac;
use rustls::AlertDescription;
use rustls::{server::WebPkiClientVerifier, AlertDescription, RootCertStore};
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use tracing::info;

use super::*;
Expand Down Expand Up @@ -375,18 +376,16 @@ fn reject_self_signed_server_cert() {
fn reject_missing_client_cert() {
let _guard = subscribe();

let key = rustls::PrivateKey(CERTIFICATE.serialize_private_key_der());
let cert = util::CERTIFICATE.serialize_der().unwrap();
let key = PrivatePkcs8KeyDer::from(CERTIFICATE.serialize_private_key_der());
let cert = CertificateDer::from(util::CERTIFICATE.serialize_der().unwrap());

let config = rustls::ServerConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_client_cert_verifier(Arc::new(rustls::server::AllowAnyAuthenticatedClient::new(
rustls::RootCertStore::empty(),
)))
.with_single_cert(vec![rustls::Certificate(cert)], key)
.with_client_cert_verifier(
WebPkiClientVerifier::builder(Arc::new(RootCertStore::empty()))
.build()
.unwrap(),
)
.with_single_cert(vec![cert], PrivateKeyDer::from(key))
.unwrap();

let mut pair = Pair::new(
Expand Down Expand Up @@ -1918,17 +1917,19 @@ fn server_can_send_3_inital_packets() {
}

/// Generate a big fat certificate that can't fit inside the initial anti-amplification limit
fn big_cert_and_key() -> (rustls::Certificate, rustls::PrivateKey) {
fn big_cert_and_key() -> (CertificateDer<'static>, PrivateKeyDer<'static>) {
let cert = rcgen::generate_simple_self_signed(
Some("localhost".into())
.into_iter()
.chain((0..1000).map(|x| format!("foo_{x}")))
.collect::<Vec<_>>(),
)
.unwrap();
let key = rustls::PrivateKey(cert.serialize_private_key_der());
let cert = rustls::Certificate(cert.serialize_der().unwrap());
(cert, key)

(
CertificateDer::from(cert.serialize_der().unwrap()),
PrivateKeyDer::Pkcs8(cert.serialize_private_key_der().into()),
)
}

#[test]
Expand Down
19 changes: 10 additions & 9 deletions quinn-proto/src/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use std::{
use assert_matches::assert_matches;
use bytes::BytesMut;
use lazy_static::lazy_static;
use rustls::{Certificate, KeyLogFile, PrivateKey};
use rustls::KeyLogFile;
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
use tracing::{info_span, trace};

use super::*;
Expand Down Expand Up @@ -467,17 +468,17 @@ pub(super) fn server_config() -> ServerConfig {
ServerConfig::with_crypto(Arc::new(server_crypto()))
}

pub(super) fn server_config_with_cert(cert: Certificate, key: PrivateKey) -> ServerConfig {
pub(super) fn server_config_with_cert(cert: CertificateDer<'static>, key: PrivateKeyDer<'static>) -> ServerConfig {
ServerConfig::with_crypto(Arc::new(server_crypto_with_cert(cert, key)))
}

pub(super) fn server_crypto() -> rustls::ServerConfig {
let cert = Certificate(CERTIFICATE.serialize_der().unwrap());
let key = PrivateKey(CERTIFICATE.serialize_private_key_der());
let cert = CertificateDer::from(CERTIFICATE.serialize_der().unwrap());
let key = PrivateKeyDer::Pkcs8(CERTIFICATE.serialize_private_key_der().into());
server_crypto_with_cert(cert, key)
}

pub(super) fn server_crypto_with_cert(cert: Certificate, key: PrivateKey) -> rustls::ServerConfig {
pub(super) fn server_crypto_with_cert(cert: CertificateDer<'static>, key: PrivateKeyDer<'static>) -> rustls::ServerConfig {
crate::crypto::rustls::server_config(vec![cert], key).unwrap()
}

Expand All @@ -493,19 +494,19 @@ pub(super) fn client_config_with_deterministic_pns() -> ClientConfig {
cfg
}

pub(super) fn client_config_with_certs(certs: Vec<rustls::Certificate>) -> ClientConfig {
pub(super) fn client_config_with_certs(certs: Vec<CertificateDer<'static>>) -> ClientConfig {
ClientConfig::new(Arc::new(client_crypto_with_certs(certs)))
}

pub(super) fn client_crypto() -> rustls::ClientConfig {
let cert = rustls::Certificate(CERTIFICATE.serialize_der().unwrap());
let cert = CertificateDer::from(CERTIFICATE.serialize_der().unwrap());
client_crypto_with_certs(vec![cert])
}

pub(super) fn client_crypto_with_certs(certs: Vec<rustls::Certificate>) -> rustls::ClientConfig {
pub(super) fn client_crypto_with_certs(certs: Vec<CertificateDer<'static>>) -> rustls::ClientConfig {
let mut roots = rustls::RootCertStore::empty();
for cert in certs {
roots.add(&cert).unwrap();
roots.add(cert).unwrap();
}
let mut config = crate::crypto::rustls::client_config(roots);
config.key_log = Arc::new(KeyLogFile::new());
Expand Down

0 comments on commit 74cdc00

Please sign in to comment.