extern crate byteorder;
extern crate hex;
use std::fmt;
use handshake_packet::byteorder::ByteOrder;
use keys::crypto_box::PublicKey;
use keys::ToBase32;
#[derive(Eq, PartialEq, Debug, Clone)]
pub enum HandshakePacketType {
Hello, RepeatHello, Key, RepeatKey, }
pub(crate) fn peek_perm_pub_key(packet: &[u8]) -> Result<[u8; 32], bool> {
if packet.len() < 120 {
Err(false)
} else {
let packet_type = byteorder::BigEndian::read_u32(&packet[0..4]);
match packet_type {
0u32 | 1u32 | 2u32 | 3u32 => {
let mut sender_perm_pub_key = [0u8; 32];
sender_perm_pub_key.copy_from_slice(&packet[40..72]);
Ok(sender_perm_pub_key)
}
_ => Err(true),
}
}
}
pub struct HandshakePacket {
pub raw: Vec<u8>,
}
impl fmt::Debug for HandshakePacket {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"HandshakePacket {{
raw: 0x{},
packet_type: {:?},
auth_challenge: 0x{} ({:?}),
nonce: 0x{},
sender_perm_pub_key: 0x{} ({}),
msg_auth_code: 0x{},
sender_enc_temp_pub_key: 0x{},
encrypted_data: 0x{}
}}",
hex::encode(self.raw.to_vec()),
self.packet_type(),
hex::encode(self.auth_challenge().to_vec()),
self.auth_challenge(),
hex::encode(self.random_nonce().to_vec()),
hex::encode(self.sender_perm_pub_key().to_vec()),
PublicKey(self.sender_perm_pub_key()).to_base32(),
hex::encode(self.msg_auth_code().to_vec()),
hex::encode(self.sender_encrypted_temp_pub_key().to_vec()),
hex::encode(self.encrypted_data().to_vec())
)
}
}
impl HandshakePacket {
pub fn new_from_raw(raw: Vec<u8>) -> Result<HandshakePacket, Vec<u8>> {
if raw.len() < 120 {
Err(raw)
} else {
Ok(HandshakePacket { raw })
}
}
pub fn packet_type(&self) -> Result<HandshakePacketType, u32> {
match byteorder::BigEndian::read_u32(&self.raw[0..4]) {
0u32 => Ok(HandshakePacketType::Hello),
1u32 => Ok(HandshakePacketType::RepeatHello),
2u32 => Ok(HandshakePacketType::Key),
3u32 => Ok(HandshakePacketType::RepeatKey),
n => Err(n),
}
}
pub fn auth_challenge(&self) -> [u8; 12] {
let mut auth_challenge = [0u8; 12];
auth_challenge.copy_from_slice(&self.raw[4..16]);
auth_challenge
}
pub fn random_nonce(&self) -> [u8; 24] {
let mut random_nonce = [0u8; 24];
random_nonce.copy_from_slice(&self.raw[16..40]);
random_nonce
}
pub fn sender_perm_pub_key(&self) -> [u8; 32] {
let mut sender_perm_pub_key = [0u8; 32];
sender_perm_pub_key.copy_from_slice(&self.raw[40..72]);
sender_perm_pub_key
}
pub fn msg_auth_code(&self) -> [u8; 16] {
let mut msg_auth_code = [0u8; 16];
msg_auth_code.copy_from_slice(&self.raw[72..88]);
msg_auth_code
}
pub fn sender_encrypted_temp_pub_key(&self) -> [u8; 32] {
let mut sender_encrypted_temp_pub_key = [0u8; 32];
sender_encrypted_temp_pub_key.copy_from_slice(&self.raw[88..120]);
sender_encrypted_temp_pub_key
}
pub fn encrypted_data(&self) -> &[u8] {
&self.raw[120..]
}
pub fn sealed_data(&self) -> &[u8] {
&self.raw[72..]
}
}
#[derive(Debug)]
pub struct HandshakePacketBuilder {
pub raw: Vec<u8>,
packet_type: bool,
auth_challenge: bool,
random_nonce: bool,
sender_perm_pub_key: bool,
msg_auth_code: bool,
sender_encrypted_temp_pub_key: bool,
}
impl HandshakePacketBuilder {
pub fn new() -> HandshakePacketBuilder {
HandshakePacketBuilder {
raw: vec![0; 120],
packet_type: false,
auth_challenge: false,
random_nonce: false,
sender_perm_pub_key: false,
msg_auth_code: false,
sender_encrypted_temp_pub_key: false,
}
}
pub fn packet_type(mut self, packet_type: &HandshakePacketType) -> HandshakePacketBuilder {
self.packet_type = true;
let value = match *packet_type {
HandshakePacketType::Hello => 0u32,
HandshakePacketType::RepeatHello => 1u32,
HandshakePacketType::Key => 2u32,
HandshakePacketType::RepeatKey => 3u32,
};
byteorder::BigEndian::write_u32(&mut self.raw[0..4], value);
self
}
pub fn auth_challenge(mut self, auth_challenge: &[u8; 12]) -> HandshakePacketBuilder {
self.auth_challenge = true;
self.raw[4..16].clone_from_slice(auth_challenge);
self
}
pub fn random_nonce(mut self, random_nonce: &[u8; 24]) -> HandshakePacketBuilder {
self.random_nonce = true;
self.raw[16..40].clone_from_slice(random_nonce);
self
}
pub fn sender_perm_pub_key(mut self, sender_perm_pub_key: &[u8; 32]) -> HandshakePacketBuilder {
self.sender_perm_pub_key = true;
self.raw[40..72].clone_from_slice(sender_perm_pub_key);
self
}
pub fn msg_auth_code(mut self, msg_auth_code: &[u8; 16]) -> HandshakePacketBuilder {
self.msg_auth_code = true;
self.raw[72..88].clone_from_slice(msg_auth_code);
self
}
pub fn sender_encrypted_temp_pub_key(
mut self,
sender_encrypted_temp_pub_key: &[u8; 32],
) -> HandshakePacketBuilder {
self.sender_encrypted_temp_pub_key = true;
self.raw[88..120].clone_from_slice(sender_encrypted_temp_pub_key);
self
}
pub fn encrypted_data(mut self, encrypted_data: &[u8]) -> HandshakePacketBuilder {
self.raw.truncate(120);
self.raw.extend_from_slice(encrypted_data);
self
}
pub fn sealed_data(mut self, sealed_data: &[u8]) -> HandshakePacketBuilder {
self.raw.truncate(72);
self.raw.extend_from_slice(sealed_data);
self
}
pub fn finalize(self) -> Result<HandshakePacket, [bool; 6]> {
let booleans = [
self.packet_type,
self.auth_challenge,
self.random_nonce,
self.sender_perm_pub_key,
self.msg_auth_code,
self.sender_encrypted_temp_pub_key,
];
if booleans.contains(&false) {
Err(booleans)
} else {
Ok(HandshakePacket { raw: self.raw })
}
}
}