Skip to content

Commit

Permalink
Upgrade to rustls 0.20
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Jun 28, 2021
1 parent 3403a2d commit e535472
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 255 deletions.
9 changes: 5 additions & 4 deletions quinn-proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@ maintenance = { status = "experimental" }
default = ["tls-rustls"]
# Use Google's list of CT logs to enable certificate transparency checks
certificate-transparency = ["ct-logs"]
tls-rustls = ["rustls", "webpki", "ring"]
tls-rustls = ["rustls", "webpki", "ring", "rustls-pemfile"]
# Trust the contents of the OS certificate store by default
native-certs = ["rustls-native-certs"]

[dependencies]
arbitrary = { version = "0.4.5", features = ["derive"], optional = true }
bytes = "1"
fxhash = "0.2.1"
ct-logs = { version = "0.8", optional = true }
ct-logs = { version = "0.9", optional = true }
rand = "0.8"
ring = { version = "0.16.7", optional = true }
# If rustls gets updated to a new version which contains
# https://github.com/ctz/rustls/commit/7117a805e0104705da50259357d8effa7d599e37
# the custom cipher list in `quinn-proto/src/crypto/rustls.rs` can be removed.
rustls = { version = "0.19", features = ["quic"], optional = true }
rustls = { version = "0.20.0-beta1", git = "https://github.com/djc/rustls", rev = "8f77bf5c878a2264b50756400982fbc141eb9940", features = ["quic"], optional = true }
rustls-native-certs = { git = "https://github.com/djc/rustls-native-certs", rev = "c862ff371d8766deab109990f3e7b2e89d9af168", optional = true }
rustls-pemfile = { version = "0.2.1", optional = true }
slab = "0.4"
thiserror = "1.0.21"
tinyvec = { version = "1.1", features = ["alloc"] }
tracing = "0.1.10"
webpki = { version = "0.21", optional = true }
webpki = { version = "0.22", optional = true }

[dev-dependencies]
assert_matches = "1.1"
Expand Down
50 changes: 3 additions & 47 deletions quinn-proto/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ use std::{convert::TryInto, fmt, num::TryFromIntError, sync::Arc, time::Duration
use rand::RngCore;
use thiserror::Error;

#[cfg(feature = "rustls")]
use crate::crypto::types::{Certificate, CertificateChain, PrivateKey};
use crate::{
cid_generator::{ConnectionIdGenerator, RandomConnectionIdGenerator},
congestion,
crypto::{self, ClientConfig as _, HandshakeTokenKey as _, HmacKey as _, ServerConfig as _},
crypto::{self, ClientConfig as _, HandshakeTokenKey as _, HmacKey as _},
VarInt, VarIntBoundsExceeded, DEFAULT_SUPPORTED_VERSIONS,
};

Expand Down Expand Up @@ -457,10 +455,10 @@ where
S: crypto::Session,
{
/// Create a default config with a particular `master_key`
pub fn new(prk: S::HandshakeTokenKey) -> Self {
pub fn new(prk: S::HandshakeTokenKey, crypto: S::ServerConfig) -> Self {
Self {
transport: Arc::new(TransportConfig::default()),
crypto: S::ServerConfig::new(),
crypto,

token_key: Arc::new(prk),
use_stateless_retry: false,
Expand Down Expand Up @@ -511,19 +509,6 @@ where
}
}

#[cfg(feature = "rustls")]
impl ServerConfig<crypto::rustls::TlsSession> {
/// Set the certificate chain that will be presented to clients
pub fn certificate(
&mut self,
cert_chain: CertificateChain,
key: PrivateKey,
) -> Result<&mut Self, rustls::TLSError> {
Arc::make_mut(&mut self.crypto).set_single_cert(cert_chain.certs, key.inner)?;
Ok(self)
}
}

impl<S> fmt::Debug for ServerConfig<S>
where
S: crypto::Session,
Expand All @@ -541,20 +526,6 @@ where
}
}

impl<S> Default for ServerConfig<S>
where
S: crypto::Session,
{
fn default() -> Self {
let rng = &mut rand::thread_rng();

let mut master_key = [0u8; 64];
rng.fill_bytes(&mut master_key);

Self::new(S::HandshakeTokenKey::from_secret(&master_key))
}
}

impl<S> Clone for ServerConfig<S>
where
S: crypto::Session,
Expand Down Expand Up @@ -587,21 +558,6 @@ where
pub crypto: S::ClientConfig,
}

#[cfg(feature = "rustls")]
impl ClientConfig<crypto::rustls::TlsSession> {
/// Add a trusted certificate authority
pub fn add_certificate_authority(
&mut self,
cert: Certificate,
) -> Result<&mut Self, webpki::Error> {
let anchor = webpki::trust_anchor_util::cert_der_as_trust_anchor(&cert.inner.0)?;
Arc::make_mut(&mut self.crypto)
.root_store
.add_server_trust_anchors(&webpki::TLSServerTrustAnchors(&[anchor]));
Ok(self)
}
}

impl<S> Default for ClientConfig<S>
where
S: crypto::Session,
Expand Down
5 changes: 3 additions & 2 deletions quinn-proto/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
config::ConfigError, shared::ConnectionId, transport_parameters::TransportParameters,
ConnectError, Side, TransportError,
};
use crate::{Certificate, PrivateKey};

/// Cryptography interface based on *ring*
#[cfg(feature = "ring")]
Expand Down Expand Up @@ -158,8 +159,8 @@ pub trait ServerConfig<S>: Clone + Send + Sync
where
S: Session,
{
/// Construct the default configuration
fn new() -> Self
/// Construct a default configuration with a single server certificate
fn with_single_cert(cert_chain: Vec<Certificate>, key_der: PrivateKey) -> Self
where
Self: Sized;

Expand Down
45 changes: 0 additions & 45 deletions quinn-proto/src/crypto/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,8 @@ use ring::{aead, hkdf, hmac};
use crate::{
config::ConfigError,
crypto::{self, CryptoError},
packet::{PacketNumber, LONG_HEADER_FORM},
};

impl crypto::HeaderKey for aead::quic::HeaderProtectionKey {
fn decrypt(&self, pn_offset: usize, packet: &mut [u8]) {
let (header, sample) = packet.split_at_mut(pn_offset + 4);
let mask = self.new_mask(&sample[0..self.sample_size()]).unwrap();
if header[0] & LONG_HEADER_FORM == LONG_HEADER_FORM {
// Long header: 4 bits masked
header[0] ^= mask[0] & 0x0f;
} else {
// Short header: 5 bits masked
header[0] ^= mask[0] & 0x1f;
}
let pn_length = PacketNumber::decode_len(header[0]);
for (out, inp) in header[pn_offset..pn_offset + pn_length]
.iter_mut()
.zip(&mask[1..])
{
*out ^= inp;
}
}

fn encrypt(&self, pn_offset: usize, packet: &mut [u8]) {
let (header, sample) = packet.split_at_mut(pn_offset + 4);
let mask = self.new_mask(&sample[0..self.sample_size()]).unwrap();
let pn_length = PacketNumber::decode_len(header[0]);
if header[0] & LONG_HEADER_FORM == LONG_HEADER_FORM {
// Long header: 4 bits masked
header[0] ^= mask[0] & 0x0f;
} else {
// Short header: 5 bits masked
header[0] ^= mask[0] & 0x1f;
}
for (out, inp) in header[pn_offset..pn_offset + pn_length]
.iter_mut()
.zip(&mask[1..])
{
*out ^= inp;
}
}

fn sample_size(&self) -> usize {
self.algorithm().sample_len()
}
}

impl crypto::HmacKey for hmac::Key {
const KEY_LEN: usize = 64;
type Signature = hmac::Tag;
Expand Down
Loading

0 comments on commit e535472

Please sign in to comment.