Add packet session key identifiers
This commit is contained in:
+24
-5
@@ -6,7 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const MAGIC: &[u8; 4] = b"DOSH";
|
||||
pub const VERSION: u8 = 1;
|
||||
pub const HEADER_LEN: usize = 42;
|
||||
pub const HEADER_LEN: usize = 58;
|
||||
const HEADER_AAD_LEN: usize = HEADER_LEN - 2;
|
||||
pub const CLIENT_TO_SERVER: u32 = 1;
|
||||
pub const SERVER_TO_CLIENT: u32 = 2;
|
||||
|
||||
@@ -80,6 +81,7 @@ pub struct Header {
|
||||
pub conn_id: [u8; 16],
|
||||
pub seq: u64,
|
||||
pub ack: u64,
|
||||
pub session_key_id: [u8; 16],
|
||||
pub body_len: u16,
|
||||
}
|
||||
|
||||
@@ -93,7 +95,8 @@ impl Header {
|
||||
out[8..24].copy_from_slice(&self.conn_id);
|
||||
out[24..32].copy_from_slice(&self.seq.to_be_bytes());
|
||||
out[32..40].copy_from_slice(&self.ack.to_be_bytes());
|
||||
out[40..42].copy_from_slice(&self.body_len.to_be_bytes());
|
||||
out[40..56].copy_from_slice(&self.session_key_id);
|
||||
out[56..58].copy_from_slice(&self.body_len.to_be_bytes());
|
||||
out
|
||||
}
|
||||
|
||||
@@ -113,13 +116,16 @@ impl Header {
|
||||
conn_id.copy_from_slice(&input[8..24]);
|
||||
let seq = u64::from_be_bytes(input[24..32].try_into().unwrap());
|
||||
let ack = u64::from_be_bytes(input[32..40].try_into().unwrap());
|
||||
let body_len = u16::from_be_bytes(input[40..42].try_into().unwrap());
|
||||
let mut session_key_id = [0u8; 16];
|
||||
session_key_id.copy_from_slice(&input[40..56]);
|
||||
let body_len = u16::from_be_bytes(input[56..58].try_into().unwrap());
|
||||
Ok(Self {
|
||||
kind,
|
||||
flags,
|
||||
conn_id,
|
||||
seq,
|
||||
ack,
|
||||
session_key_id,
|
||||
body_len,
|
||||
})
|
||||
}
|
||||
@@ -147,6 +153,7 @@ pub fn encode_plain(
|
||||
conn_id,
|
||||
seq,
|
||||
ack,
|
||||
session_key_id: [0u8; 16],
|
||||
body_len: body.len() as u16,
|
||||
};
|
||||
let mut out = Vec::with_capacity(HEADER_LEN + body.len());
|
||||
@@ -171,10 +178,11 @@ pub fn encode_encrypted(
|
||||
conn_id,
|
||||
seq,
|
||||
ack,
|
||||
session_key_id: session_key_id(key),
|
||||
body_len: 0,
|
||||
};
|
||||
let aad_without_len = header.aad();
|
||||
let ciphertext = crypto::seal(key, &nonce, &aad_without_len[..40], plaintext)?;
|
||||
let ciphertext = crypto::seal(key, &nonce, &aad_without_len[..HEADER_AAD_LEN], plaintext)?;
|
||||
if ciphertext.len() > u16::MAX as usize {
|
||||
bail!("packet body too large");
|
||||
}
|
||||
@@ -206,7 +214,18 @@ pub fn decrypt_body(packet: &Packet, key: &[u8; 32], direction: u32) -> Result<V
|
||||
}
|
||||
let nonce = crypto::nonce_from(direction, packet.header.seq);
|
||||
let aad = packet.header.aad();
|
||||
crypto::open(key, &nonce, &aad[..40], &packet.body)
|
||||
let expected_key_id = session_key_id(key);
|
||||
if packet.header.session_key_id != expected_key_id {
|
||||
bail!("stale or wrong session key id");
|
||||
}
|
||||
crypto::open(key, &nonce, &aad[..HEADER_AAD_LEN], &packet.body)
|
||||
}
|
||||
|
||||
pub fn session_key_id(key: &[u8; 32]) -> [u8; 16] {
|
||||
let digest = crypto::sha256(key);
|
||||
let mut out = [0u8; 16];
|
||||
out.copy_from_slice(&digest[..16]);
|
||||
out
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user