Update to rustls 0.23
This commit is contained in:
parent
03b48134ca
commit
aa6e1c36f8
7 changed files with 116 additions and 44 deletions
|
|
@ -19,9 +19,9 @@ resolver = "2"
|
|||
[workspace.dependencies]
|
||||
boring = { version = "4", default-features = false }
|
||||
boring-sys = { version = "4", default-features = false }
|
||||
rustls = { version = "0.22", default-features = false }
|
||||
rustls = { version = "0.23", default-features = false }
|
||||
rustls-pemfile = { version = "2" }
|
||||
rustls-pki-types = { version = "1" }
|
||||
tokio-rustls = { version = "0.25" }
|
||||
tokio-rustls = { version = "0.26", default-features = false }
|
||||
webpki = { package = "rustls-webpki", version = "0.102", default-features = false }
|
||||
webpki-roots = { version = "0.26" }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use aead::{AeadCore, AeadInPlace, Nonce, Tag};
|
||||
use aead::{AeadCore, AeadInPlace, Buffer, Nonce, Tag};
|
||||
use boring::error::ErrorStack;
|
||||
use boring_additions::aead::Algorithm;
|
||||
use rustls::crypto::cipher::{self, make_tls12_aad, make_tls13_aad, Iv};
|
||||
use rustls::crypto::cipher::{
|
||||
self, make_tls12_aad, make_tls13_aad, BorrowedPayload, Iv, PrefixedPayload,
|
||||
};
|
||||
use rustls::{ConnectionTrafficSecrets, ContentType, ProtocolVersion};
|
||||
|
||||
use crate::helper::log_and_map;
|
||||
|
|
@ -25,6 +27,12 @@ pub(crate) trait BoringCipher {
|
|||
/// The length of the authentication tag
|
||||
const TAG_LEN: usize;
|
||||
|
||||
/// integrity limit
|
||||
const INTEGRITY_LIMIT: u64;
|
||||
|
||||
/// confidentiality limit
|
||||
const CONFIDENTIALITY_LIMIT: u64;
|
||||
|
||||
/// Constructs a new instance of this cipher as an AEAD algorithm
|
||||
fn new_cipher() -> Algorithm;
|
||||
|
||||
|
|
@ -123,11 +131,10 @@ where
|
|||
{
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: cipher::BorrowedPlainMessage,
|
||||
msg: cipher::OutboundPlainMessage,
|
||||
seq: u64,
|
||||
) -> Result<cipher::OpaqueMessage, rustls::Error> {
|
||||
) -> Result<cipher::OutboundOpaqueMessage, rustls::Error> {
|
||||
let nonce = cipher::Nonce::new(&self.iv, seq);
|
||||
|
||||
match self.tls_version {
|
||||
#[cfg(feature = "tls12")]
|
||||
ProtocolVersion::TLSv1_2 => {
|
||||
|
|
@ -136,37 +143,41 @@ where
|
|||
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
|
||||
let mut full_payload = Vec::with_capacity(total_len);
|
||||
let mut full_payload = PrefixedPayload::with_capacity(total_len);
|
||||
full_payload.extend_from_slice(&nonce.0.as_ref()[fixed_iv_len..]);
|
||||
full_payload.extend_from_slice(msg.payload);
|
||||
full_payload.extend_from_chunks(&msg.payload);
|
||||
full_payload.extend_from_slice(&vec![0u8; self.crypter.max_overhead()]);
|
||||
|
||||
let (_, payload) = full_payload.split_at_mut(explicit_nonce_len);
|
||||
let (_, payload) = full_payload.as_mut().split_at_mut(explicit_nonce_len);
|
||||
let (payload, tag) = payload.split_at_mut(msg.payload.len());
|
||||
let aad = cipher::make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len());
|
||||
self.crypter
|
||||
.seal_in_place(&nonce.0, &aad, payload, tag)
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| cipher::OpaqueMessage::new(msg.typ, msg.version, full_payload))
|
||||
.map(|_| cipher::OutboundOpaqueMessage::new(msg.typ, msg.version, full_payload))
|
||||
}
|
||||
|
||||
ProtocolVersion::TLSv1_3 => {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
|
||||
let mut payload = Vec::with_capacity(total_len);
|
||||
payload.extend_from_slice(msg.payload);
|
||||
payload.push(msg.typ.get_u8());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
payload.extend_from_slice(&msg.typ.to_array());
|
||||
|
||||
let aad = cipher::make_tls13_aad(total_len);
|
||||
self.encrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, &mut payload)
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
cipher::OpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
self.encrypt_in_place(
|
||||
Nonce::<T>::from_slice(&nonce.0),
|
||||
&aad,
|
||||
&mut EncryptBufferAdapter(&mut payload),
|
||||
)
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
cipher::OutboundOpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
|
@ -187,11 +198,11 @@ impl<T> cipher::MessageDecrypter for BoringAeadCrypter<T>
|
|||
where
|
||||
T: BoringAead,
|
||||
{
|
||||
fn decrypt(
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut m: cipher::OpaqueMessage,
|
||||
mut m: cipher::InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<cipher::PlainMessage, rustls::Error> {
|
||||
) -> Result<cipher::InboundPlainMessage<'a>, rustls::Error> {
|
||||
match self.tls_version {
|
||||
#[cfg(feature = "tls12")]
|
||||
ProtocolVersion::TLSv1_2 => {
|
||||
|
|
@ -199,11 +210,11 @@ where
|
|||
|
||||
// payload is: [nonce] | [ciphertext] | [auth tag]
|
||||
let actual_payload_length =
|
||||
m.payload().len() - self.crypter.max_overhead() - explicit_nonce_len;
|
||||
m.payload.len() - self.crypter.max_overhead() - explicit_nonce_len;
|
||||
|
||||
let aad = make_tls12_aad(seq, m.typ, m.version, actual_payload_length);
|
||||
|
||||
let payload = m.payload_mut();
|
||||
let payload = &mut m.payload;
|
||||
|
||||
// get the nonce
|
||||
let (explicit_nonce, payload) = payload.split_at_mut(explicit_nonce_len);
|
||||
|
|
@ -230,20 +241,24 @@ where
|
|||
.map_err(|e| log_and_map("open_in_place", e, rustls::Error::DecryptError))
|
||||
.map(|_| {
|
||||
// rotate the nonce to the end
|
||||
m.payload_mut().rotate_left(explicit_nonce_len);
|
||||
m.payload.rotate_left(explicit_nonce_len);
|
||||
|
||||
// truncate buffer to the actual payload
|
||||
m.payload_mut().truncate(actual_payload_length);
|
||||
m.payload.truncate(actual_payload_length);
|
||||
|
||||
m.into_plain_message()
|
||||
})
|
||||
}
|
||||
ProtocolVersion::TLSv1_3 => {
|
||||
let nonce = cipher::Nonce::new(&self.iv, seq);
|
||||
let aad = make_tls13_aad(m.payload().len());
|
||||
self.decrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, m.payload_mut())
|
||||
.map_err(|_| rustls::Error::DecryptError)
|
||||
.and_then(|_| m.into_tls13_unpadded_message())
|
||||
let aad = make_tls13_aad(m.payload.len());
|
||||
self.decrypt_in_place(
|
||||
Nonce::<T>::from_slice(&nonce.0),
|
||||
&aad,
|
||||
&mut DecryptBufferAdapter(&mut m.payload),
|
||||
)
|
||||
.map_err(|_| rustls::Error::DecryptError)
|
||||
.and_then(|_| m.into_tls13_unpadded_message())
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
|
@ -290,6 +305,14 @@ where
|
|||
fn tag_len(&self) -> usize {
|
||||
<T as BoringCipher>::TAG_LEN
|
||||
}
|
||||
|
||||
fn confidentiality_limit(&self) -> u64 {
|
||||
<T as BoringCipher>::CONFIDENTIALITY_LIMIT
|
||||
}
|
||||
|
||||
fn integrity_limit(&self) -> u64 {
|
||||
<T as BoringCipher>::INTEGRITY_LIMIT
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Aead<T>(PhantomData<T>);
|
||||
|
|
@ -494,6 +517,55 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
struct DecryptBufferAdapter<'a, 'p>(&'a mut BorrowedPayload<'p>);
|
||||
|
||||
impl AsRef<[u8]> for DecryptBufferAdapter<'_, '_> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for DecryptBufferAdapter<'_, '_> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer for DecryptBufferAdapter<'_, '_> {
|
||||
fn extend_from_slice(&mut self, _: &[u8]) -> aead::Result<()> {
|
||||
unreachable!("not used by `AeadInPlace::decrypt_in_place`")
|
||||
}
|
||||
|
||||
fn truncate(&mut self, len: usize) {
|
||||
self.0.truncate(len)
|
||||
}
|
||||
}
|
||||
|
||||
struct EncryptBufferAdapter<'a>(&'a mut PrefixedPayload);
|
||||
|
||||
impl AsRef<[u8]> for EncryptBufferAdapter<'_> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for EncryptBufferAdapter<'_> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
self.0.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer for EncryptBufferAdapter<'_> {
|
||||
fn extend_from_slice(&mut self, other: &[u8]) -> aead::Result<()> {
|
||||
self.0.extend_from_slice(other);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn truncate(&mut self, len: usize) {
|
||||
self.0.truncate(len)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hex_literal::hex;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ impl BoringCipher for Aes128 {
|
|||
|
||||
const TAG_LEN: usize = 16;
|
||||
|
||||
const INTEGRITY_LIMIT: u64 = 1 << 52;
|
||||
const CONFIDENTIALITY_LIMIT: u64 = 1 << 23;
|
||||
|
||||
fn new_cipher() -> Algorithm {
|
||||
Algorithm::aes_128_gcm()
|
||||
}
|
||||
|
|
@ -58,6 +61,9 @@ impl BoringCipher for Aes256 {
|
|||
|
||||
const TAG_LEN: usize = 16;
|
||||
|
||||
const INTEGRITY_LIMIT: u64 = 1 << 52;
|
||||
const CONFIDENTIALITY_LIMIT: u64 = 1 << 23;
|
||||
|
||||
fn new_cipher() -> Algorithm {
|
||||
Algorithm::aes_256_gcm()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ impl BoringCipher for ChaCha20Poly1305 {
|
|||
|
||||
const TAG_LEN: usize = 16;
|
||||
|
||||
const INTEGRITY_LIMIT: u64 = 1 << 36;
|
||||
const CONFIDENTIALITY_LIMIT: u64 = u64::MAX;
|
||||
|
||||
fn new_cipher() -> Algorithm {
|
||||
Algorithm::chacha20_poly1305()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ pub static ECDHE_ECDSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite {
|
|||
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,
|
||||
|
|
@ -40,7 +39,6 @@ pub static ECDHE_RSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite {
|
|||
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,
|
||||
|
|
@ -53,7 +51,6 @@ pub static ECDHE_ECDSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite {
|
|||
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,
|
||||
|
|
@ -66,7 +63,6 @@ pub static ECDHE_RSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite {
|
|||
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,
|
||||
|
|
@ -79,7 +75,6 @@ pub static ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12Ci
|
|||
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,
|
||||
|
|
@ -92,7 +87,6 @@ pub static ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12Ciph
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ pub static AES_128_GCM_SHA256: Tls13CipherSuite = Tls13CipherSuite {
|
|||
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,
|
||||
|
|
@ -19,7 +18,6 @@ pub static AES_256_GCM_SHA384: Tls13CipherSuite = Tls13CipherSuite {
|
|||
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,
|
||||
|
|
@ -31,7 +29,6 @@ pub static CHACHA20_POLY1305_SHA256: Tls13CipherSuite = Tls13CipherSuite {
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ log = { version = "0.4.4" }
|
|||
mio = { version = "0.8", features = ["net", "os-poll"] }
|
||||
pki-types = { package = "rustls-pki-types", version = "0.2" }
|
||||
rcgen = { version = "0.11.3", features = ["pem"], default-features = false }
|
||||
rustls = { workspace = true, features = [ "logging" ]}
|
||||
rustls = { workspace = true, features = [ "logging", "std" ]}
|
||||
boring-rustls-provider = { path = "../boring-rustls-provider", features = ["logging"] }
|
||||
rustls-pemfile = { workspace = true }
|
||||
serde = "1.0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue