mirror of https://github.com/ctz/rustls
make Decrypt trait use Borrowed{Opaque,Plain}Message
This commit is contained in:
parent
1b551e712e
commit
dc4cf38c03
|
@ -1,8 +1,11 @@
|
|||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use chacha20poly1305::aead::Buffer;
|
||||
use chacha20poly1305::{AeadInPlace, KeyInit, KeySizeUser};
|
||||
use rustls::crypto::cipher::{self, AeadKey, Iv, UnsupportedOperationError, NONCE_LEN};
|
||||
use rustls::crypto::cipher::{
|
||||
self, AeadKey, BorrowedPayload, Iv, UnsupportedOperationError, NONCE_LEN,
|
||||
};
|
||||
use rustls::{ConnectionTrafficSecrets, ContentType, ProtocolVersion};
|
||||
|
||||
pub struct Chacha20Poly1305;
|
||||
|
@ -114,17 +117,17 @@ impl cipher::MessageEncrypter for Tls13Cipher {
|
|||
}
|
||||
|
||||
impl cipher::MessageDecrypter for Tls13Cipher {
|
||||
fn decrypt(
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut m: cipher::OpaqueMessage,
|
||||
mut m: cipher::BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<cipher::PlainMessage, rustls::Error> {
|
||||
let payload = m.payload_mut();
|
||||
) -> Result<cipher::BorrowedPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &mut m.payload;
|
||||
let nonce = chacha20poly1305::Nonce::from(cipher::Nonce::new(&self.1, seq).0);
|
||||
let aad = cipher::make_tls13_aad(payload.len());
|
||||
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, payload)
|
||||
.decrypt_in_place(&nonce, &aad, &mut BufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
m.into_tls13_unpadded_message()
|
||||
|
@ -159,12 +162,12 @@ impl cipher::MessageEncrypter for Tls12Cipher {
|
|||
}
|
||||
|
||||
impl cipher::MessageDecrypter for Tls12Cipher {
|
||||
fn decrypt(
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut m: cipher::OpaqueMessage,
|
||||
mut m: cipher::BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<cipher::PlainMessage, rustls::Error> {
|
||||
let payload = m.payload();
|
||||
) -> Result<cipher::BorrowedPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &m.payload;
|
||||
let nonce = chacha20poly1305::Nonce::from(cipher::Nonce::new(&self.1, seq).0);
|
||||
let aad = cipher::make_tls12_aad(
|
||||
seq,
|
||||
|
@ -173,9 +176,9 @@ impl cipher::MessageDecrypter for Tls12Cipher {
|
|||
payload.len() - CHACHAPOLY1305_OVERHEAD,
|
||||
);
|
||||
|
||||
let payload = m.payload_mut();
|
||||
let payload = &mut m.payload;
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, payload)
|
||||
.decrypt_in_place(&nonce, &aad, &mut BufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
Ok(m.into_plain_message())
|
||||
|
@ -183,3 +186,27 @@ impl cipher::MessageDecrypter for Tls12Cipher {
|
|||
}
|
||||
|
||||
const CHACHAPOLY1305_OVERHEAD: usize = 16;
|
||||
|
||||
struct BufferAdapter<'a, 'p>(&'a mut BorrowedPayload<'p>);
|
||||
|
||||
impl AsRef<[u8]> for BufferAdapter<'_, '_> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for BufferAdapter<'_, '_> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer for BufferAdapter<'_, '_> {
|
||||
fn extend_from_slice(&mut self, _: &[u8]) -> chacha20poly1305::aead::Result<()> {
|
||||
unreachable!("not used by `AeadInPlace::decrypt_in_place`")
|
||||
}
|
||||
|
||||
fn truncate(&mut self, len: usize) {
|
||||
self.0.truncate(len)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::crypto::cipher::{
|
||||
make_tls12_aad, AeadKey, Iv, KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce,
|
||||
Tls12AeadAlgorithm, UnsupportedOperationError, NONCE_LEN,
|
||||
make_tls12_aad, AeadKey, BorrowedOpaqueMessage, Iv, KeyBlockShape, MessageDecrypter,
|
||||
MessageEncrypter, Nonce, Tls12AeadAlgorithm, UnsupportedOperationError, NONCE_LEN,
|
||||
};
|
||||
use crate::crypto::tls12::Prf;
|
||||
use crate::crypto::{ActiveKeyExchange, KeyExchangeAlgorithm};
|
||||
use crate::enums::{CipherSuite, SignatureScheme};
|
||||
use crate::error::Error;
|
||||
use crate::msgs::fragmenter::MAX_FRAGMENT_LEN;
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage, PlainMessage};
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage};
|
||||
use crate::suites::{CipherSuiteCommon, ConnectionTrafficSecrets, SupportedCipherSuite};
|
||||
use crate::tls12::Tls12CipherSuite;
|
||||
|
||||
|
@ -252,8 +252,12 @@ const GCM_EXPLICIT_NONCE_LEN: usize = 8;
|
|||
const GCM_OVERHEAD: usize = GCM_EXPLICIT_NONCE_LEN + 16;
|
||||
|
||||
impl MessageDecrypter for GcmMessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &msg.payload;
|
||||
if payload.len() < GCM_OVERHEAD {
|
||||
return Err(Error::DecryptError);
|
||||
}
|
||||
|
@ -272,7 +276,7 @@ impl MessageDecrypter for GcmMessageDecrypter {
|
|||
payload.len() - GCM_OVERHEAD,
|
||||
));
|
||||
|
||||
let payload = msg.payload_mut();
|
||||
let payload = &mut msg.payload;
|
||||
let plain_len = self
|
||||
.dec_key
|
||||
.open_within(nonce, aad, payload, GCM_EXPLICIT_NONCE_LEN..)
|
||||
|
@ -330,8 +334,12 @@ struct ChaCha20Poly1305MessageDecrypter {
|
|||
const CHACHAPOLY1305_OVERHEAD: usize = 16;
|
||||
|
||||
impl MessageDecrypter for ChaCha20Poly1305MessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &msg.payload;
|
||||
|
||||
if payload.len() < CHACHAPOLY1305_OVERHEAD {
|
||||
return Err(Error::DecryptError);
|
||||
|
@ -345,7 +353,7 @@ impl MessageDecrypter for ChaCha20Poly1305MessageDecrypter {
|
|||
payload.len() - CHACHAPOLY1305_OVERHEAD,
|
||||
));
|
||||
|
||||
let payload = msg.payload_mut();
|
||||
let payload = &mut msg.payload;
|
||||
let plain_len = self
|
||||
.dec_key
|
||||
.open_in_place(nonce, aad, payload)
|
||||
|
|
|
@ -3,14 +3,14 @@ use alloc::vec::Vec;
|
|||
|
||||
use crate::crypto;
|
||||
use crate::crypto::cipher::{
|
||||
make_tls13_aad, AeadKey, Iv, MessageDecrypter, MessageEncrypter, Nonce, Tls13AeadAlgorithm,
|
||||
UnsupportedOperationError,
|
||||
make_tls13_aad, AeadKey, BorrowedOpaqueMessage, Iv, MessageDecrypter, MessageEncrypter, Nonce,
|
||||
Tls13AeadAlgorithm, UnsupportedOperationError,
|
||||
};
|
||||
use crate::crypto::tls13::{Hkdf, HkdfExpander, OkmBlock, OutputLengthError};
|
||||
use crate::enums::{CipherSuite, ContentType, ProtocolVersion};
|
||||
use crate::error::Error;
|
||||
use crate::msgs::codec::Codec;
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage, PlainMessage};
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage};
|
||||
use crate::suites::{CipherSuiteCommon, ConnectionTrafficSecrets, SupportedCipherSuite};
|
||||
use crate::tls13::Tls13CipherSuite;
|
||||
|
||||
|
@ -235,8 +235,12 @@ impl MessageEncrypter for AeadMessageEncrypter {
|
|||
}
|
||||
|
||||
impl MessageDecrypter for AeadMessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload_mut();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &mut msg.payload;
|
||||
if payload.len() < self.dec_key.algorithm().tag_len() {
|
||||
return Err(Error::DecryptError);
|
||||
}
|
||||
|
@ -290,8 +294,12 @@ struct GcmMessageDecrypter {
|
|||
}
|
||||
|
||||
impl MessageDecrypter for GcmMessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload_mut();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &mut msg.payload;
|
||||
if payload.len() < self.dec_key.algorithm().tag_len() {
|
||||
return Err(Error::DecryptError);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,11 @@ pub struct KeyBlockShape {
|
|||
pub trait MessageDecrypter: Send + Sync {
|
||||
/// Decrypt the given TLS message `msg`, using the sequence number
|
||||
/// `seq` which can be used to derive a unique [`Nonce`].
|
||||
fn decrypt(&mut self, msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error>;
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error>;
|
||||
}
|
||||
|
||||
/// Objects with this trait can encrypt TLS messages.
|
||||
|
@ -317,7 +321,11 @@ impl MessageEncrypter for InvalidMessageEncrypter {
|
|||
struct InvalidMessageDecrypter {}
|
||||
|
||||
impl MessageDecrypter for InvalidMessageDecrypter {
|
||||
fn decrypt(&mut self, _m: OpaqueMessage, _seq: u64) -> Result<PlainMessage, Error> {
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
_m: BorrowedOpaqueMessage<'a>,
|
||||
_seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
Err(Error::DecryptError)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::crypto::cipher::{
|
||||
make_tls12_aad, AeadKey, Iv, KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce,
|
||||
Tls12AeadAlgorithm, UnsupportedOperationError, NONCE_LEN,
|
||||
make_tls12_aad, AeadKey, BorrowedOpaqueMessage, Iv, KeyBlockShape, MessageDecrypter,
|
||||
MessageEncrypter, Nonce, Tls12AeadAlgorithm, UnsupportedOperationError, NONCE_LEN,
|
||||
};
|
||||
use crate::crypto::tls12::PrfUsingHmac;
|
||||
use crate::crypto::KeyExchangeAlgorithm;
|
||||
use crate::enums::{CipherSuite, SignatureScheme};
|
||||
use crate::error::Error;
|
||||
use crate::msgs::fragmenter::MAX_FRAGMENT_LEN;
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage, PlainMessage};
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage};
|
||||
use crate::suites::{CipherSuiteCommon, ConnectionTrafficSecrets, SupportedCipherSuite};
|
||||
use crate::tls12::Tls12CipherSuite;
|
||||
|
||||
|
@ -237,8 +237,12 @@ const GCM_EXPLICIT_NONCE_LEN: usize = 8;
|
|||
const GCM_OVERHEAD: usize = GCM_EXPLICIT_NONCE_LEN + 16;
|
||||
|
||||
impl MessageDecrypter for GcmMessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &msg.payload;
|
||||
if payload.len() < GCM_OVERHEAD {
|
||||
return Err(Error::DecryptError);
|
||||
}
|
||||
|
@ -257,7 +261,7 @@ impl MessageDecrypter for GcmMessageDecrypter {
|
|||
payload.len() - GCM_OVERHEAD,
|
||||
));
|
||||
|
||||
let payload = msg.payload_mut();
|
||||
let payload = &mut msg.payload;
|
||||
let plain_len = self
|
||||
.dec_key
|
||||
.open_within(nonce, aad, payload, GCM_EXPLICIT_NONCE_LEN..)
|
||||
|
@ -315,8 +319,12 @@ struct ChaCha20Poly1305MessageDecrypter {
|
|||
const CHACHAPOLY1305_OVERHEAD: usize = 16;
|
||||
|
||||
impl MessageDecrypter for ChaCha20Poly1305MessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &msg.payload;
|
||||
|
||||
if payload.len() < CHACHAPOLY1305_OVERHEAD {
|
||||
return Err(Error::DecryptError);
|
||||
|
@ -330,7 +338,7 @@ impl MessageDecrypter for ChaCha20Poly1305MessageDecrypter {
|
|||
payload.len() - CHACHAPOLY1305_OVERHEAD,
|
||||
));
|
||||
|
||||
let payload = msg.payload_mut();
|
||||
let payload = &mut msg.payload;
|
||||
let plain_len = self
|
||||
.dec_key
|
||||
.open_in_place(nonce, aad, payload)
|
||||
|
|
|
@ -3,14 +3,14 @@ use alloc::vec::Vec;
|
|||
|
||||
use crate::crypto;
|
||||
use crate::crypto::cipher::{
|
||||
make_tls13_aad, AeadKey, Iv, MessageDecrypter, MessageEncrypter, Nonce, Tls13AeadAlgorithm,
|
||||
UnsupportedOperationError,
|
||||
make_tls13_aad, AeadKey, BorrowedOpaqueMessage, Iv, MessageDecrypter, MessageEncrypter, Nonce,
|
||||
Tls13AeadAlgorithm, UnsupportedOperationError,
|
||||
};
|
||||
use crate::crypto::tls13::{Hkdf, HkdfExpander, OkmBlock, OutputLengthError};
|
||||
use crate::enums::{CipherSuite, ContentType, ProtocolVersion};
|
||||
use crate::error::Error;
|
||||
use crate::msgs::codec::Codec;
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage, PlainMessage};
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage};
|
||||
use crate::suites::{CipherSuiteCommon, ConnectionTrafficSecrets, SupportedCipherSuite};
|
||||
use crate::tls13::Tls13CipherSuite;
|
||||
|
||||
|
@ -207,8 +207,12 @@ impl MessageEncrypter for Tls13MessageEncrypter {
|
|||
}
|
||||
|
||||
impl MessageDecrypter for Tls13MessageDecrypter {
|
||||
fn decrypt(&mut self, mut msg: OpaqueMessage, seq: u64) -> Result<PlainMessage, Error> {
|
||||
let payload = msg.payload_mut();
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: BorrowedOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &mut msg.payload;
|
||||
if payload.len() < self.dec_key.algorithm().tag_len() {
|
||||
return Err(Error::DecryptError);
|
||||
}
|
||||
|
|
|
@ -57,9 +57,39 @@ impl<'a> DerefMut for BorrowedPayload<'a> {
|
|||
}
|
||||
|
||||
impl<'a> BorrowedPayload<'a> {
|
||||
#[cfg(test)]
|
||||
pub(crate) fn new(bytes: &'a mut [u8]) -> Self {
|
||||
Self(bytes)
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, len: usize) {
|
||||
if len >= self.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.0 = core::mem::take(&mut self.0)
|
||||
.split_at_mut(len)
|
||||
.0;
|
||||
}
|
||||
|
||||
pub(crate) fn read(r: &mut ReaderMut<'a>) -> Self {
|
||||
Self(r.rest())
|
||||
}
|
||||
|
||||
pub(crate) fn into_inner(self) -> &'a mut [u8] {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub(crate) fn pop(&mut self) -> Option<u8> {
|
||||
if self.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let len = self.len();
|
||||
let last = self[len - 1];
|
||||
self.truncate(len - 1);
|
||||
Some(last)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Codec for CertificateDer<'a> {
|
||||
|
|
|
@ -68,7 +68,7 @@ impl MessageDeframer {
|
|||
// If so, deframe it and place the message onto the frames output queue.
|
||||
let mut rd = codec::ReaderMut::init(buffer.filled_get_mut(start..));
|
||||
let m = match BorrowedOpaqueMessage::read(&mut rd) {
|
||||
Ok(m) => m.into_owned(),
|
||||
Ok(m) => m,
|
||||
Err(msg_err) => {
|
||||
let err_kind = match msg_err {
|
||||
MessageError::TooShortForHeader | MessageError::TooShortForLength => {
|
||||
|
@ -101,7 +101,7 @@ impl MessageDeframer {
|
|||
ContentType::Alert
|
||||
if version_is_tls13
|
||||
&& !record_layer.has_decrypted()
|
||||
&& m.payload().len() <= 2 =>
|
||||
&& m.payload.len() <= 2 =>
|
||||
{
|
||||
true
|
||||
}
|
||||
|
@ -109,13 +109,14 @@ impl MessageDeframer {
|
|||
_ => false,
|
||||
};
|
||||
if self.joining_hs.is_none() && allowed_plaintext {
|
||||
let message = m.into_plain_message().into_owned();
|
||||
// This is unencrypted. We check the contents later.
|
||||
buffer.queue_discard(end);
|
||||
return Ok(Some(Deframed {
|
||||
want_close_before_decrypt: false,
|
||||
aligned: true,
|
||||
trial_decryption_finished: false,
|
||||
message: m.into_plain_message(),
|
||||
message,
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -84,9 +84,8 @@ impl MessagePayload {
|
|||
/// # Decryption
|
||||
/// Internally the message payload is stored as a `Vec<u8>`; this can by mutably borrowed with
|
||||
/// [`OpaqueMessage::payload_mut()`]. This is useful for decrypting a message in-place.
|
||||
/// After the message is decrypted, call [`OpaqueMessage::into_plain_message()`] or
|
||||
/// [`OpaqueMessage::into_tls13_unpadded_message()`] (depending on the
|
||||
/// protocol version).
|
||||
/// After the message is decrypted, call [`OpaqueMessage::into_plain_message()`] or borrow this
|
||||
/// message and call [`BorrowedOpaqueMessage::into_tls13_unpadded_message`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OpaqueMessage {
|
||||
pub typ: ContentType,
|
||||
|
@ -154,28 +153,13 @@ impl OpaqueMessage {
|
|||
}
|
||||
}
|
||||
|
||||
/// For TLS1.3 (only), checks the length msg.payload is valid and removes the padding.
|
||||
///
|
||||
/// Returns an error if the message (pre-unpadding) is too long, or the padding is invalid,
|
||||
/// or the message (post-unpadding) is too long.
|
||||
pub fn into_tls13_unpadded_message(mut self) -> Result<PlainMessage, Error> {
|
||||
let payload = &mut self.payload.0;
|
||||
|
||||
if payload.len() > MAX_FRAGMENT_LEN + 1 {
|
||||
return Err(Error::PeerSentOversizedRecord);
|
||||
#[cfg(test)]
|
||||
pub(crate) fn borrow(&mut self) -> BorrowedOpaqueMessage {
|
||||
BorrowedOpaqueMessage {
|
||||
typ: self.typ,
|
||||
version: self.version,
|
||||
payload: BorrowedPayload::new(self.payload_mut()),
|
||||
}
|
||||
|
||||
self.typ = unpad_tls13(payload);
|
||||
if self.typ == ContentType::Unknown(0) {
|
||||
return Err(PeerMisbehaved::IllegalTlsInnerPlaintext.into());
|
||||
}
|
||||
|
||||
if payload.len() > MAX_FRAGMENT_LEN {
|
||||
return Err(Error::PeerSentOversizedRecord);
|
||||
}
|
||||
|
||||
self.version = ProtocolVersion::TLSv1_3;
|
||||
Ok(self.into_plain_message())
|
||||
}
|
||||
|
||||
/// This is the maximum on-the-wire size of a TLSCiphertext.
|
||||
|
@ -197,8 +181,42 @@ pub struct BorrowedOpaqueMessage<'a> {
|
|||
pub payload: BorrowedPayload<'a>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<'a> BorrowedOpaqueMessage<'a> {
|
||||
/// Force conversion into a plaintext message.
|
||||
///
|
||||
/// See [`OpaqueMessage::into_plain_message`] for more information
|
||||
pub fn into_plain_message(self) -> BorrowedPlainMessage<'a> {
|
||||
BorrowedPlainMessage {
|
||||
typ: self.typ,
|
||||
version: self.version,
|
||||
payload: self.payload.into_inner(),
|
||||
}
|
||||
}
|
||||
|
||||
/// For TLS1.3 (only), checks the length msg.payload is valid and removes the padding.
|
||||
///
|
||||
/// Returns an error if the message (pre-unpadding) is too long, or the padding is invalid,
|
||||
/// or the message (post-unpadding) is too long.
|
||||
pub fn into_tls13_unpadded_message(mut self) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
let payload = &mut self.payload;
|
||||
|
||||
if payload.len() > MAX_FRAGMENT_LEN + 1 {
|
||||
return Err(Error::PeerSentOversizedRecord);
|
||||
}
|
||||
|
||||
self.typ = unpad_tls13_payload(payload);
|
||||
if self.typ == ContentType::Unknown(0) {
|
||||
return Err(PeerMisbehaved::IllegalTlsInnerPlaintext.into());
|
||||
}
|
||||
|
||||
if payload.len() > MAX_FRAGMENT_LEN {
|
||||
return Err(Error::PeerSentOversizedRecord);
|
||||
}
|
||||
|
||||
self.version = ProtocolVersion::TLSv1_3;
|
||||
Ok(self.into_plain_message())
|
||||
}
|
||||
|
||||
pub(crate) fn read(r: &mut ReaderMut<'a>) -> Result<Self, MessageError> {
|
||||
let (typ, version, len) = r.as_reader(read_opaque_message_header)?;
|
||||
|
||||
|
@ -213,19 +231,6 @@ impl<'a> BorrowedOpaqueMessage<'a> {
|
|||
payload,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn into_owned(self) -> OpaqueMessage {
|
||||
let Self {
|
||||
typ,
|
||||
version,
|
||||
payload,
|
||||
} = self;
|
||||
OpaqueMessage {
|
||||
typ,
|
||||
version,
|
||||
payload: Payload::new(&*payload),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_opaque_message_header(
|
||||
|
@ -268,9 +273,9 @@ fn read_opaque_message_header(
|
|||
/// the content type, which is returned. See RFC8446 s5.2.
|
||||
///
|
||||
/// ContentType(0) is returned if the message payload is empty or all zeroes.
|
||||
fn unpad_tls13(v: &mut Vec<u8>) -> ContentType {
|
||||
fn unpad_tls13_payload(p: &mut BorrowedPayload) -> ContentType {
|
||||
loop {
|
||||
match v.pop() {
|
||||
match p.pop() {
|
||||
Some(0) => {}
|
||||
Some(content_type) => return ContentType::from(content_type),
|
||||
None => return ContentType::Unknown(0),
|
||||
|
@ -385,6 +390,7 @@ impl TryFrom<PlainMessage> for Message {
|
|||
///
|
||||
/// This type also cannot decode its internals and
|
||||
/// cannot be read/encoded; only `OpaqueMessage` can do that.
|
||||
#[derive(Debug)]
|
||||
pub struct BorrowedPlainMessage<'a> {
|
||||
pub typ: ContentType,
|
||||
pub version: ProtocolVersion,
|
||||
|
@ -403,6 +409,19 @@ impl<'a> BorrowedPlainMessage<'a> {
|
|||
pub fn encoded_len(&self, record_layer: &RecordLayer) -> usize {
|
||||
OpaqueMessage::HEADER_SIZE as usize + record_layer.encrypted_len(self.payload.len())
|
||||
}
|
||||
|
||||
pub(crate) fn into_owned(self) -> PlainMessage {
|
||||
let Self {
|
||||
typ,
|
||||
version,
|
||||
payload,
|
||||
} = self;
|
||||
PlainMessage {
|
||||
typ,
|
||||
version,
|
||||
payload: Payload::new(payload),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use core::num::NonZeroU64;
|
||||
|
||||
use crate::crypto::cipher::{MessageDecrypter, MessageEncrypter};
|
||||
use crate::crypto::cipher::{BorrowedOpaqueMessage, MessageDecrypter, MessageEncrypter};
|
||||
use crate::error::Error;
|
||||
use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage, PlainMessage};
|
||||
|
||||
|
@ -62,12 +62,12 @@ impl RecordLayer {
|
|||
/// an error is returned.
|
||||
pub(crate) fn decrypt_incoming(
|
||||
&mut self,
|
||||
encr: OpaqueMessage,
|
||||
encr: BorrowedOpaqueMessage<'_>,
|
||||
) -> Result<Option<Decrypted>, Error> {
|
||||
if self.decrypt_state != DirectionState::Active {
|
||||
return Ok(Some(Decrypted {
|
||||
want_close_before_decrypt: false,
|
||||
plaintext: encr.into_plain_message(),
|
||||
plaintext: encr.into_plain_message().into_owned(),
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ impl RecordLayer {
|
|||
// failure has already happened.
|
||||
let want_close_before_decrypt = self.read_seq == SEQ_SOFT_LIMIT;
|
||||
|
||||
let encrypted_len = encr.payload().len();
|
||||
let encrypted_len = encr.payload.len();
|
||||
match self
|
||||
.message_decrypter
|
||||
.decrypt(encr, self.read_seq)
|
||||
|
@ -93,7 +93,7 @@ impl RecordLayer {
|
|||
}
|
||||
Ok(Some(Decrypted {
|
||||
want_close_before_decrypt,
|
||||
plaintext,
|
||||
plaintext: plaintext.into_owned(),
|
||||
}))
|
||||
}
|
||||
Err(Error::DecryptError) if self.doing_trial_decryption(encrypted_len) => {
|
||||
|
@ -255,7 +255,11 @@ mod tests {
|
|||
|
||||
struct PassThroughDecrypter;
|
||||
impl MessageDecrypter for PassThroughDecrypter {
|
||||
fn decrypt(&mut self, m: OpaqueMessage, _: u64) -> Result<PlainMessage, Error> {
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
m: BorrowedOpaqueMessage<'a>,
|
||||
_: u64,
|
||||
) -> Result<BorrowedPlainMessage<'a>, Error> {
|
||||
Ok(m.into_plain_message())
|
||||
}
|
||||
}
|
||||
|
@ -287,13 +291,13 @@ mod tests {
|
|||
|
||||
// Decrypting a message should update the read_seq and track that we have now performed
|
||||
// a decryption.
|
||||
let msg = OpaqueMessage::new(
|
||||
let mut msg = OpaqueMessage::new(
|
||||
ContentType::Handshake,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
vec![0xC0, 0xFF, 0xEE],
|
||||
);
|
||||
record_layer
|
||||
.decrypt_incoming(msg)
|
||||
.decrypt_incoming(msg.borrow())
|
||||
.unwrap();
|
||||
assert!(matches!(record_layer.decrypt_state, DirectionState::Active));
|
||||
assert_eq!(record_layer.read_seq, 1);
|
||||
|
|
Loading…
Reference in New Issue