attempt to decrypt

This commit is contained in:
nora 2024-07-20 14:48:40 +02:00
parent b930bc0c5d
commit 0f93d225e7
7 changed files with 174 additions and 252 deletions

228
Cargo.lock generated
View file

@ -2,6 +2,41 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aead"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"generic-array",
]
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aes-gcm"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
"aead",
"aes",
"cipher",
"ctr",
"ghash",
"subtle",
]
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.4" version = "0.10.4"
@ -11,30 +46,28 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.5.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.12" version = "0.2.12"
@ -51,9 +84,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [ dependencies = [
"generic-array", "generic-array",
"rand_core",
"typenum", "typenum",
] ]
[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
"cipher",
]
[[package]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "4.1.2" version = "4.1.2"
@ -119,6 +162,16 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "ghash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
dependencies = [
"opaque-debug",
"polyval",
]
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.12.4" version = "0.12.4"
@ -138,12 +191,12 @@ dependencies = [
] ]
[[package]] [[package]]
name = "js-sys" name = "inout"
version = "0.3.69" version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [ dependencies = [
"wasm-bindgen", "generic-array",
] ]
[[package]] [[package]]
@ -153,16 +206,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]] [[package]]
name = "log" name = "opaque-debug"
version = "0.4.21" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "platforms" name = "platforms"
@ -170,6 +217,18 @@ version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7"
[[package]]
name = "polyval"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [
"cfg-if",
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.17"
@ -224,21 +283,6 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"web-sys",
"winapi",
]
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.0" version = "0.4.0"
@ -285,12 +329,6 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.5.0" version = "2.5.0"
@ -312,10 +350,10 @@ dependencies = [
name = "tls" name = "tls"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aes-gcm",
"byteorder", "byteorder",
"hkdf", "hkdf",
"rand", "rand",
"ring",
"sha2", "sha2",
"x25519-dalek", "x25519-dalek",
] ]
@ -333,10 +371,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "untrusted" name = "universal-hash"
version = "0.7.1" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
"crypto-common",
"subtle",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
@ -350,92 +392,6 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "web-sys"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "x25519-dalek" name = "x25519-dalek"
version = "2.0.1" version = "2.0.1"

View file

@ -6,9 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
aes-gcm = "0.10.3"
byteorder = "1.4.3" byteorder = "1.4.3"
hkdf = "0.12.3" hkdf = "0.12.3"
rand = "0.8.5" rand = "0.8.5"
ring = "0.16.20"
sha2 = "0.10.8" sha2 = "0.10.8"
x25519-dalek = "2.0.0" x25519-dalek = "2.0.0"

View file

@ -1,70 +1,51 @@
use ring::aead::Nonce; //! Symmetric AEAD-based record encryption.
//! <https://datatracker.ietf.org/doc/html/rfc8446#section-5.2>
use aes_gcm::{
aead::{Aead, Payload},
Aes128Gcm, KeyInit,
};
use crate::proto; use crate::proto;
use super::{keys, TlsCiphertext, TlsInnerPlaintext}; use super::{keys, TlsInnerPlaintext};
pub type AeadKey = aes_gcm::Key<Aes128Gcm>;
pub type Nonce = aes_gcm::Nonce<<Aes128Gcm as aes_gcm::AeadCore>::NonceSize>;
fn decrypt(key: &AeadKey, ciphertext: &[u8], nonce: &Nonce, additional_data: &[u8]) -> Vec<u8> {
pub struct AeadKey { let cipher = Aes128Gcm::new(key);
key: ring::aead::LessSafeKey, cipher
.decrypt(
nonce,
Payload {
msg: ciphertext,
aad: additional_data,
},
)
.unwrap()
} }
impl AeadKey { pub fn decrypt_ciphertext(
fn new(algorithm: proto::CipherSuite, key_bytes: &[u8]) -> Self { encrypted_record: &[u8],
Self { secret: &[u8],
key: ring::aead::LessSafeKey::new( nonce: Nonce,
ring::aead::UnboundKey::new(proto_algo_to_ring(algorithm), key_bytes) ) -> TlsInnerPlaintext {
.expect("invalid key"), // <https://datatracker.ietf.org/doc/html/rfc8446#section-7.3>
), let key = keys::hkdf_expand_label::<sha2::Sha256>(secret, b"key", &[], 128/8);
}
} let key = aes_gcm::Key::<Aes128Gcm>::from_slice(&key[0..(128 / 8)]);
}
// TLS v1.2 0x03, 0x03
let mut additional_data = [proto::TLSPlaintext::APPLICATION_DATA, 0x03, 0x03, 0, 0];
fn proto_algo_to_ring(algo: proto::CipherSuite) -> &'static ring::aead::Algorithm { let ciphertext_len = encrypted_record.as_ref().len() as u16;
match algo { additional_data[3..].copy_from_slice(&ciphertext_len.to_be_bytes());
proto::CipherSuite::TLS_AES_128_GCM_SHA256 => &ring::aead::AES_128_GCM,
proto::CipherSuite::TLS_AES_256_GCM_SHA384 => &ring::aead::AES_256_GCM, let result = decrypt(key, encrypted_record, &nonce, &additional_data);
proto::CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => &ring::aead::CHACHA20_POLY1305,
proto::CipherSuite::TLS_AES_128_CCM_SHA256 => todo!("TLS_AES_128_CCM_SHA256"), TlsInnerPlaintext {
proto::CipherSuite::TLS_AES_128_CCM_8_SHA256 => todo!("TLS_AES_128_CCM_8_SHA256"), content: result,
} content_type: 0,
} padding_len: 0,
fn encrypt(key: AeadKey, message: &[u8], seq: u8, nonce: Nonce) -> Vec<u8> {
let total_len = message.len() + key.key.algorithm().tag_len();
let mut ciphertext_payload = Vec::with_capacity(total_len);
ciphertext_payload.extend_from_slice(message);
// FIXME: fill out the AAD properly
let aad = ring::aead::Aad::from([0; 5]);
key.key
.seal_in_place_append_tag(nonce, aad, &mut ciphertext_payload)
.unwrap();
ciphertext_payload
}
fn decrypt(key: AeadKey, msg: &mut [u8], nonce: ring::aead::Nonce) {
// FIXME: fill out the AAD properly
let aad = ring::aead::Aad::from([0; 5]);
key.key.open_in_place(nonce, aad, msg);
}
impl TlsCiphertext {
pub fn decrypt(mut self, secret: &[u8], nonce: Nonce) -> TlsInnerPlaintext {
let key = keys::hkdf_expand_label::<sha2::Sha256>(secret, b"key", &[]);
let iv = keys::hkdf_expand_label::<sha2::Sha256>(secret, b"iv", &[]);
let key = AeadKey::new(proto::CipherSuite::TLS_AES_128_GCM_SHA256, secret);
decrypt(key, &mut self.encrypted_record, nonce);
TlsInnerPlaintext {
content: self.encrypted_record,
content_type: 0,
padding_len: 0,
}
} }
} }

View file

@ -1,4 +1,4 @@
use sha2::{digest::OutputSizeUser, Digest}; use sha2::Digest;
use x25519_dalek::SharedSecret; use x25519_dalek::SharedSecret;
use crate::proto::{self, ser_de::Value}; use crate::proto::{self, ser_de::Value};
@ -9,7 +9,12 @@ use super::{CryptoProvider, TlsHasher};
// https://datatracker.ietf.org/doc/html/rfc8446#section-7.1 // https://datatracker.ietf.org/doc/html/rfc8446#section-7.1
// The Hash function used by Transcript-Hash and HKDF is the cipher suite hash algorithm // The Hash function used by Transcript-Hash and HKDF is the cipher suite hash algorithm
pub(super) fn hkdf_expand_label<H: TlsHasher>(secret: &[u8], label: &[u8], context: &[u8]) -> Vec<u8> { pub(super) fn hkdf_expand_label<H: TlsHasher>(
secret: &[u8],
label: &[u8],
context: &[u8],
length: usize,
) -> Vec<u8> {
proto::ser_de::proto_struct! { proto::ser_de::proto_struct! {
#[derive(Debug)] #[derive(Debug)]
pub struct HkdfLabel { pub struct HkdfLabel {
@ -21,7 +26,7 @@ pub(super) fn hkdf_expand_label<H: TlsHasher>(secret: &[u8], label: &[u8], conte
let mut hkdf_label = Vec::new(); let mut hkdf_label = Vec::new();
HkdfLabel { HkdfLabel {
// Hash.length is its output length in bytes // Hash.length is its output length in bytes
length: <H as OutputSizeUser>::output_size().try_into().unwrap(), length: length.try_into().unwrap(),
label: { label: {
let mut v = b"tls13 ".to_vec(); let mut v = b"tls13 ".to_vec();
v.extend_from_slice(label); v.extend_from_slice(label);
@ -34,14 +39,18 @@ pub(super) fn hkdf_expand_label<H: TlsHasher>(secret: &[u8], label: &[u8], conte
let mut okm = [0u8; 128]; let mut okm = [0u8; 128];
H::expand(secret, &hkdf_label, &mut okm).unwrap(); H::expand(secret, &hkdf_label, &mut okm).unwrap();
okm[..<H as OutputSizeUser>::output_size()].to_vec() okm[..length].to_vec()
} }
/// Messages is the concatenation of the indicated handshake messages, /// Messages is the concatenation of the indicated handshake messages,
/// including the handshake message type and length fields, but not /// including the handshake message type and length fields, but not
/// including record layer headers. /// including record layer headers.
pub(super) fn derive_secret<H: TlsHasher>(secret: &[u8], label: &[u8], messages_hash: &[u8]) -> Vec<u8> { pub(super) fn derive_secret<H: TlsHasher>(
hkdf_expand_label::<H>(secret, label, messages_hash) secret: &[u8],
label: &[u8],
messages_hash: &[u8],
) -> Vec<u8> {
hkdf_expand_label::<H>(secret, label, messages_hash, H::output_size())
} }
pub struct TranscriptHash { pub struct TranscriptHash {
@ -117,7 +126,6 @@ impl TranscriptHash {
pub struct KeysAfterServerHello { pub struct KeysAfterServerHello {
provider: CryptoProvider, provider: CryptoProvider,
handhske_secret: Vec<u8>,
pub client_handshake_traffic_secret: Vec<u8>, pub client_handshake_traffic_secret: Vec<u8>,
pub server_handshake_traffic_secret: Vec<u8>, pub server_handshake_traffic_secret: Vec<u8>,
master_secret: Vec<u8>, master_secret: Vec<u8>,
@ -167,20 +175,20 @@ impl KeysAfterServerHello {
Self { Self {
provider, provider,
handhske_secret,
client_handshake_traffic_secret, client_handshake_traffic_secret,
server_handshake_traffic_secret, server_handshake_traffic_secret,
master_secret, master_secret,
} }
} }
#[allow(dead_code)]
fn after_handshake(self, transcript: &TranscriptHash) { fn after_handshake(self, transcript: &TranscriptHash) {
let client_application_traffic_secret_0 = (self.provider.derive_secret)( let _client_application_traffic_secret_0 = (self.provider.derive_secret)(
&self.master_secret, &self.master_secret,
b"c ap traffic", b"c ap traffic",
&transcript.get_current(), &transcript.get_current(),
); );
let server_application_traffic_secret_0 = (self.provider.derive_secret)( let _server_application_traffic_secret_0 = (self.provider.derive_secret)(
&self.master_secret, &self.master_secret,
b"s ap traffic", b"s ap traffic",
&transcript.get_current(), &transcript.get_current(),

View file

@ -3,36 +3,8 @@
pub mod aead; pub mod aead;
pub mod keys; pub mod keys;
use crate::proto::{
self,
ser_de::{proto_enum, proto_struct, Value},
Handshake,
};
use hkdf::{hmac::Hmac, HmacImpl};
use ring::aead::Nonce;
pub use seq::{SeqId, SeqIdGen}; pub use seq::{SeqId, SeqIdGen};
use sha2::{ use sha2::digest::{typenum::Unsigned, OutputSizeUser};
digest::{
core_api::{self, CoreProxy},
generic_array::ArrayLength,
typenum::Unsigned,
OutputSizeUser,
},
Digest,
};
use x25519_dalek::SharedSecret;
pub struct TlsCiphertext {
/// The encrypted [`TlsInnerPlaintext`] record.
pub encrypted_record: Vec<u8>,
}
impl From<Vec<u8>> for TlsCiphertext {
fn from(value: Vec<u8>) -> Self {
TlsCiphertext {
encrypted_record: value,
}
}
}
trait TlsHasher: OutputSizeUser { trait TlsHasher: OutputSizeUser {
const ZEROED: &'static [u8]; const ZEROED: &'static [u8];
@ -47,7 +19,7 @@ macro_rules! impl_hkdf_hasher {
hkdf::Hkdf::<Self>::new(None, ikm).expand(&label, okm) hkdf::Hkdf::<Self>::new(None, ikm).expand(&label, okm)
} }
fn extract(salt: &[u8], ikm: &[u8]) -> Vec<u8> { fn extract(salt: &[u8], ikm: &[u8]) -> Vec<u8> {
hkdf::Hkdf::<Self>::extract(Some(&[]), &[]) hkdf::Hkdf::<Self>::extract(Some(salt), ikm)
.0 .0
.as_slice() .as_slice()
.to_vec() .to_vec()
@ -79,7 +51,7 @@ impl CryptoProvider {
mod seq { mod seq {
use std::cell::Cell; use std::cell::Cell;
use ring::aead::{self, Nonce}; use super::aead::Nonce;
/// The sequence ID generator. /// The sequence ID generator.
/// There is a separate one maintained for reading and writing. /// There is a separate one maintained for reading and writing.
@ -100,13 +72,14 @@ mod seq {
pub struct SeqId(u64); pub struct SeqId(u64);
impl SeqId { impl SeqId {
pub fn to_nonce(self) -> Nonce { pub fn to_nonce(self) -> Nonce {
let mut nonce = [0; aead::NONCE_LEN]; let mut nonce = [0; 12];
nonce[4..].copy_from_slice(&self.0.to_be_bytes()); nonce[4..].copy_from_slice(&self.0.to_be_bytes());
Nonce::assume_unique_for_key(nonce) Nonce::from(nonce)
} }
} }
} }
#[allow(dead_code)]
pub struct TlsInnerPlaintext { pub struct TlsInnerPlaintext {
/// The `TLSPlaintext.fragment`` value /// The `TLSPlaintext.fragment`` value
pub content: Vec<u8>, pub content: Vec<u8>,

View file

@ -1,5 +1,3 @@
#![allow(unused)]
mod crypto; mod crypto;
pub mod proto; pub mod proto;
@ -10,7 +8,10 @@ use std::{
}; };
use crypto::keys::{KeysAfterServerHello, TranscriptHash}; use crypto::keys::{KeysAfterServerHello, TranscriptHash};
use proto::{ser_de::Value, CipherSuite}; use proto::{
ser_de::{FrameReader, Value},
CipherSuite, TlsCiphertext,
};
use crate::proto::TLSPlaintext; use crate::proto::TLSPlaintext;
@ -117,6 +118,7 @@ https://datatracker.ietf.org/doc/html/rfc8446#appendix-A.1
CONNECTED CONNECTED
``` ```
*/ */
#[allow(dead_code)]
enum ConnectState { enum ConnectState {
Start, Start,
WaitServerHello { WaitServerHello {
@ -216,7 +218,7 @@ impl<W: Read + Write> ClientSetupConnection<W> {
cipher_suites, cipher_suites,
transcript, transcript,
} => { } => {
let (frame, seq_id) = self.stream.read_record()?; let (frame, _seq_id) = self.stream.read_record()?;
if frame.should_drop() { if frame.should_drop() {
continue; continue;
} }
@ -332,11 +334,13 @@ impl<W: Read + Write> ClientSetupConnection<W> {
if frame.should_drop() { if frame.should_drop() {
continue; continue;
} }
let proto::TLSPlaintext::ApplicationData { data } = frame else { // Frame is a TLSCiphertext.
let proto::TLSPlaintext::ApplicationData { data: encrypted_record } = frame else {
return unexpected_message!("expected ApplicationData, got {frame:?}"); return unexpected_message!("expected ApplicationData, got {frame:?}");
}; };
// Encrypted with server_handshake_traffic_secret // Encrypted with server_handshake_traffic_secret
crypto::TlsCiphertext::from(data).decrypt( crypto::aead::decrypt_ciphertext(
&encrypted_record,
&keys &keys
.borrow() .borrow()
.as_ref() .as_ref()

View file

@ -38,11 +38,11 @@ pub enum TLSPlaintext {
} }
impl TLSPlaintext { impl TLSPlaintext {
const INVALID: u8 = 0; pub const INVALID: u8 = 0;
const CHANGE_CIPHER_SPEC: u8 = 20; pub const CHANGE_CIPHER_SPEC: u8 = 20;
const ALERT: u8 = 21; pub const ALERT: u8 = 21;
const HANDSHAKE: u8 = 22; pub const HANDSHAKE: u8 = 22;
const APPLICATION_DATA: u8 = 23; pub const APPLICATION_DATA: u8 = 23;
pub fn write(&self, w: &mut impl Write) -> io::Result<()> { pub fn write(&self, w: &mut impl Write) -> io::Result<()> {
match self { match self {