Compare commits

...

3 Commits

Author SHA1 Message Date
occheung eadf776da3 fix tab/space 2020-10-21 18:18:54 +08:00
occheung 5986777770 parse: add ASN1 DER 2020-10-21 18:18:41 +08:00
occheung 2b107881d8 certificate: init 2020-10-21 18:17:55 +08:00
10 changed files with 1867 additions and 1686 deletions

View File

@ -12,6 +12,7 @@ num_enum = { version = "0.5.1", default-features = false }
log = "0.4.11" log = "0.4.11"
generic-array = "0.14.4" generic-array = "0.14.4"
heapless = "0.5.6" heapless = "0.5.6"
asn1_der = { version = "0.7.1", features = [ "native_types", "no_std" ] }
[dependencies.aes-gcm] [dependencies.aes-gcm]
version = "0.8.0" version = "0.8.0"

View File

@ -13,252 +13,252 @@ use crate::key::*;
// Only designed to support read or write the entire buffer // Only designed to support read or write the entire buffer
// TODO: Stricter visibility // TODO: Stricter visibility
pub struct TlsBuffer<'a> { pub struct TlsBuffer<'a> {
buffer: &'a mut [u8], buffer: &'a mut [u8],
index: RefCell<usize>, index: RefCell<usize>,
} }
impl<'a> Into<&'a [u8]> for TlsBuffer<'a> { impl<'a> Into<&'a [u8]> for TlsBuffer<'a> {
fn into(self) -> &'a [u8] { fn into(self) -> &'a [u8] {
&self.buffer[0..self.index.into_inner()] &self.buffer[0..self.index.into_inner()]
} }
} }
impl<'a> TlsBuffer<'a> { impl<'a> TlsBuffer<'a> {
pub fn new(buffer: &'a mut [u8]) -> Self { pub fn new(buffer: &'a mut [u8]) -> Self {
Self { Self {
buffer, buffer,
index: RefCell::new(0), index: RefCell::new(0),
} }
} }
pub(crate) fn get_size(&self) -> usize { pub(crate) fn get_size(&self) -> usize {
self.index.clone().into_inner() self.index.clone().into_inner()
} }
pub(crate) fn write(&mut self, data: &[u8]) -> Result<()> { pub(crate) fn write(&mut self, data: &[u8]) -> Result<()> {
let mut index = self.index.borrow_mut(); let mut index = self.index.borrow_mut();
if (self.buffer.len() - *index) < data.len() { if (self.buffer.len() - *index) < data.len() {
return Err(Error::Exhausted); return Err(Error::Exhausted);
} }
let next_index = *index + data.len(); let next_index = *index + data.len();
self.buffer[*index..next_index].copy_from_slice(data); self.buffer[*index..next_index].copy_from_slice(data);
*index = next_index; *index = next_index;
Ok(()) Ok(())
} }
pub(crate) fn write_u8(&mut self, data: u8) -> Result<()> { pub(crate) fn write_u8(&mut self, data: u8) -> Result<()> {
let mut index = self.index.borrow_mut(); let mut index = self.index.borrow_mut();
if (self.buffer.len() - *index) < 1 { if (self.buffer.len() - *index) < 1 {
return Err(Error::Exhausted); return Err(Error::Exhausted);
} }
self.buffer[*index] = data; self.buffer[*index] = data;
*index += 1; *index += 1;
Ok(()) Ok(())
} }
pub(crate) fn read_u8(&mut self) -> Result<u8> { pub(crate) fn read_u8(&mut self) -> Result<u8> {
let mut index = self.index.borrow_mut(); let mut index = self.index.borrow_mut();
if (self.buffer.len() - *index) < 1 { if (self.buffer.len() - *index) < 1 {
return Err(Error::Exhausted); return Err(Error::Exhausted);
} }
let data = self.buffer[*index]; let data = self.buffer[*index];
*index += 1; *index += 1;
Ok(data) Ok(data)
} }
pub(crate) fn read_all(self) -> &'a [u8] { pub(crate) fn read_all(self) -> &'a [u8] {
&self.buffer[self.index.into_inner()..] &self.buffer[self.index.into_inner()..]
} }
pub(crate) fn read_slice(&self, length: usize) -> Result<&[u8]> { pub(crate) fn read_slice(&self, length: usize) -> Result<&[u8]> {
let mut index = self.index.borrow_mut(); let mut index = self.index.borrow_mut();
if (self.buffer.len() - *index) < length { if (self.buffer.len() - *index) < length {
return Err(Error::Exhausted); return Err(Error::Exhausted);
} }
let next_index = *index + length; let next_index = *index + length;
let slice = &self.buffer[*index..next_index]; let slice = &self.buffer[*index..next_index];
*index = next_index; *index = next_index;
Ok(slice) Ok(slice)
} }
pub(crate) fn enqueue_tls_repr(&mut self, tls_repr: TlsRepr<'a>) -> Result<()> { pub(crate) fn enqueue_tls_repr(&mut self, tls_repr: TlsRepr<'a>) -> Result<()> {
self.write_u8(tls_repr.content_type.into())?; self.write_u8(tls_repr.content_type.into())?;
self.write_u16(tls_repr.version.into())?; self.write_u16(tls_repr.version.into())?;
self.write_u16(tls_repr.length)?; self.write_u16(tls_repr.length)?;
if let Some(app_data) = tls_repr.payload { if let Some(app_data) = tls_repr.payload {
self.write(app_data.as_slice())?; self.write(app_data.as_slice())?;
} else if let Some(handshake_repr) = tls_repr.handshake { } else if let Some(handshake_repr) = tls_repr.handshake {
// Queue handshake_repr into buffer // Queue handshake_repr into buffer
self.enqueue_handshake_repr(handshake_repr)?; self.enqueue_handshake_repr(handshake_repr)?;
} else { } else {
return Err(Error::Malformed); return Err(Error::Malformed);
} }
Ok(()) Ok(())
} }
fn enqueue_handshake_repr(&mut self, handshake_repr: HandshakeRepr<'a>) -> Result<()> { fn enqueue_handshake_repr(&mut self, handshake_repr: HandshakeRepr<'a>) -> Result<()> {
self.write_u8(handshake_repr.msg_type.into())?; self.write_u8(handshake_repr.msg_type.into())?;
self.write_u24(handshake_repr.length)?; self.write_u24(handshake_repr.length)?;
self.enqueue_handshake_data(handshake_repr.handshake_data) self.enqueue_handshake_data(handshake_repr.handshake_data)
} }
fn enqueue_handshake_data(&mut self, handshake_data: HandshakeData<'a>) -> Result<()> { fn enqueue_handshake_data(&mut self, handshake_data: HandshakeData<'a>) -> Result<()> {
match handshake_data { match handshake_data {
HandshakeData::ClientHello(client_hello) => { HandshakeData::ClientHello(client_hello) => {
self.enqueue_client_hello(client_hello) self.enqueue_client_hello(client_hello)
} }
HandshakeData::ServerHello(server_hello) => { HandshakeData::ServerHello(server_hello) => {
self.euqueue_server_hello(server_hello) self.euqueue_server_hello(server_hello)
} }
_ => { _ => {
Err(Error::Unrecognized) Err(Error::Unrecognized)
} }
} }
} }
fn enqueue_client_hello(&mut self, client_hello: ClientHello<'a>) -> Result<()> { fn enqueue_client_hello(&mut self, client_hello: ClientHello<'a>) -> Result<()> {
self.write_u16(client_hello.version.into())?; self.write_u16(client_hello.version.into())?;
self.write(&client_hello.random)?; self.write(&client_hello.random)?;
self.write_u8(client_hello.session_id_length)?; self.write_u8(client_hello.session_id_length)?;
self.write(&client_hello.session_id)?; self.write(&client_hello.session_id)?;
self.write_u16(client_hello.cipher_suites_length)?; self.write_u16(client_hello.cipher_suites_length)?;
for suite in client_hello.cipher_suites.iter() { for suite in client_hello.cipher_suites.iter() {
self.write_u16((*suite).into())?; self.write_u16((*suite).into())?;
} }
self.write_u8(client_hello.compression_method_length)?; self.write_u8(client_hello.compression_method_length)?;
self.write_u8(client_hello.compression_methods)?; self.write_u8(client_hello.compression_methods)?;
self.write_u16(client_hello.extension_length)?; self.write_u16(client_hello.extension_length)?;
self.enqueue_extensions(client_hello.extensions) self.enqueue_extensions(client_hello.extensions)
} }
fn euqueue_server_hello(&mut self, server_hello: ServerHello<'a>) -> Result<()> { fn euqueue_server_hello(&mut self, server_hello: ServerHello<'a>) -> Result<()> {
self.write_u16(server_hello.version.into())?; self.write_u16(server_hello.version.into())?;
self.write(&server_hello.random)?; self.write(&server_hello.random)?;
self.write_u8(server_hello.session_id_echo_length)?; self.write_u8(server_hello.session_id_echo_length)?;
self.write(&server_hello.session_id_echo)?; self.write(&server_hello.session_id_echo)?;
self.write_u16(server_hello.cipher_suite.into())?; self.write_u16(server_hello.cipher_suite.into())?;
self.write_u8(server_hello.compression_method)?; self.write_u8(server_hello.compression_method)?;
self.write_u16(server_hello.extension_length)?; self.write_u16(server_hello.extension_length)?;
self.enqueue_extensions(server_hello.extensions) self.enqueue_extensions(server_hello.extensions)
} }
fn enqueue_extensions(&mut self, extensions: Vec<Extension>) -> Result<()> { fn enqueue_extensions(&mut self, extensions: Vec<Extension>) -> Result<()> {
for extension in extensions { for extension in extensions {
self.write_u16(extension.extension_type.into())?; self.write_u16(extension.extension_type.into())?;
self.write_u16(extension.length)?; self.write_u16(extension.length)?;
self.enqueue_extension_data(extension.extension_data)?; self.enqueue_extension_data(extension.extension_data)?;
} }
Ok(()) Ok(())
} }
fn enqueue_extension_data(&mut self, extension_data: ExtensionData) -> Result<()> { fn enqueue_extension_data(&mut self, extension_data: ExtensionData) -> Result<()> {
use crate::tls_packet::ExtensionData::*; use crate::tls_packet::ExtensionData::*;
match extension_data { match extension_data {
SupportedVersions(s) => { SupportedVersions(s) => {
use crate::tls_packet::SupportedVersions::*; use crate::tls_packet::SupportedVersions::*;
match s { match s {
ClientHello { length, versions } => { ClientHello { length, versions } => {
self.write_u8(length)?; self.write_u8(length)?;
for version in versions.iter() { for version in versions.iter() {
self.write_u16((*version).into())?; self.write_u16((*version).into())?;
} }
}, },
ServerHello { selected_version } => { ServerHello { selected_version } => {
self.write_u16(selected_version.into())?; self.write_u16(selected_version.into())?;
} }
} }
}, },
SignatureAlgorithms(s) => { SignatureAlgorithms(s) => {
self.write_u16(s.length)?; self.write_u16(s.length)?;
for sig_alg in s.supported_signature_algorithms.iter() { for sig_alg in s.supported_signature_algorithms.iter() {
self.write_u16((*sig_alg).into())?; self.write_u16((*sig_alg).into())?;
} }
}, },
NegotiatedGroups(n) => { NegotiatedGroups(n) => {
self.write_u16(n.length)?; self.write_u16(n.length)?;
for group in n.named_group_list.iter() { for group in n.named_group_list.iter() {
self.write_u16((*group).into())?; self.write_u16((*group).into())?;
} }
}, },
KeyShareEntry(k) => { KeyShareEntry(k) => {
let mut key_share_entry_into = |buffer: &mut TlsBuffer, entry: crate::tls_packet::KeyShareEntry| { let mut key_share_entry_into = |buffer: &mut TlsBuffer, entry: crate::tls_packet::KeyShareEntry| {
buffer.write_u16(entry.group.into())?; buffer.write_u16(entry.group.into())?;
buffer.write_u16(entry.length)?; buffer.write_u16(entry.length)?;
buffer.write(entry.key_exchange.as_slice()) buffer.write(entry.key_exchange.as_slice())
}; };
use crate::tls_packet::KeyShareEntryContent::*; use crate::tls_packet::KeyShareEntryContent::*;
match k { match k {
KeyShareClientHello { length, client_shares } => { KeyShareClientHello { length, client_shares } => {
self.write_u16(length)?; self.write_u16(length)?;
for share in client_shares.iter() { for share in client_shares.iter() {
self.enqueue_key_share_entry(share)?; self.enqueue_key_share_entry(share)?;
} }
} }
KeyShareHelloRetryRequest { selected_group } => { KeyShareHelloRetryRequest { selected_group } => {
self.write_u16(selected_group.into())?; self.write_u16(selected_group.into())?;
} }
KeyShareServerHello { server_share } => { KeyShareServerHello { server_share } => {
self.enqueue_key_share_entry(&server_share)?; self.enqueue_key_share_entry(&server_share)?;
} }
} }
}, },
// TODO: Implement buffer formatting for other extensions // TODO: Implement buffer formatting for other extensions
_ => todo!() _ => todo!()
}; };
Ok(()) Ok(())
} }
fn enqueue_key_share_entry(&mut self, entry: &crate::tls_packet::KeyShareEntry) -> Result<()> { fn enqueue_key_share_entry(&mut self, entry: &crate::tls_packet::KeyShareEntry) -> Result<()> {
self.write_u16(entry.group.into())?; self.write_u16(entry.group.into())?;
self.write_u16(entry.length)?; self.write_u16(entry.length)?;
self.write(entry.key_exchange.as_slice()) self.write(entry.key_exchange.as_slice())
} }
pub fn enqueue_hkdf_label(&mut self, hkdf_label: HkdfLabel) -> Result<()> { pub fn enqueue_hkdf_label(&mut self, hkdf_label: HkdfLabel) -> Result<()> {
self.write_u16(hkdf_label.length)?; self.write_u16(hkdf_label.length)?;
self.write_u8(hkdf_label.label_length)?; self.write_u8(hkdf_label.label_length)?;
self.write(hkdf_label.label)?; self.write(hkdf_label.label)?;
self.write_u8(hkdf_label.context_length)?; self.write_u8(hkdf_label.context_length)?;
self.write(hkdf_label.context) self.write(hkdf_label.context)
} }
} }
macro_rules! export_byte_order_fn { macro_rules! export_byte_order_fn {
($($write_fn_name: ident, $read_fn_name: ident, $data_type: ty, $data_size: literal),+) => { ($($write_fn_name: ident, $read_fn_name: ident, $data_type: ty, $data_size: literal),+) => {
impl<'a> TlsBuffer<'a> { impl<'a> TlsBuffer<'a> {
$( $(
pub(crate) fn $write_fn_name(&mut self, data: $data_type) -> Result<()> { pub(crate) fn $write_fn_name(&mut self, data: $data_type) -> Result<()> {
let mut index = self.index.borrow_mut(); let mut index = self.index.borrow_mut();
if (self.buffer.len() - *index) < $data_size { if (self.buffer.len() - *index) < $data_size {
return Err(Error::Exhausted); return Err(Error::Exhausted);
} }
let next_index = *index + $data_size; let next_index = *index + $data_size;
NetworkEndian::$write_fn_name(&mut self.buffer[*index..next_index], data); NetworkEndian::$write_fn_name(&mut self.buffer[*index..next_index], data);
*index = next_index; *index = next_index;
Ok(()) Ok(())
} }
pub(crate) fn $read_fn_name(&self) -> Result<$data_type> { pub(crate) fn $read_fn_name(&self) -> Result<$data_type> {
let mut index = self.index.borrow_mut(); let mut index = self.index.borrow_mut();
if (self.buffer.len() - *index) < $data_size { if (self.buffer.len() - *index) < $data_size {
return Err(Error::Exhausted); return Err(Error::Exhausted);
} }
let next_index = *index + $data_size; let next_index = *index + $data_size;
let data = NetworkEndian::$read_fn_name(&self.buffer[*index..next_index]); let data = NetworkEndian::$read_fn_name(&self.buffer[*index..next_index]);
*index = next_index; *index = next_index;
Ok(data) Ok(data)
} }
)+ )+
} }
} }
} }
export_byte_order_fn!( export_byte_order_fn!(
write_u16, read_u16, u16, 2, write_u16, read_u16, u16, 2,
write_u24, read_u24, u32, 3, write_u24, read_u24, u32, 3,
write_u32, read_u32, u32, 4, write_u32, read_u32, u32, 4,
write_u48, read_u48, u64, 6, write_u48, read_u48, u64, 6,
write_u64, read_u64, u64, 8 write_u64, read_u64, u64, 8
); );

54
src/certificate.rs Normal file
View File

@ -0,0 +1,54 @@
use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive;
pub struct Certificate<'a> {
tbs_certificate: TBSCertificate<'a>,
signature_algorithm: AlgorithmIdentifier<'a>,
signature_value: &'a [u8]
}
pub struct TBSCertificate<'a> {
version: Version,
serial_number: &'a [u8],
signature: AlgorithmIdentifier<'a>,
issuer: &'a [u8],
validity: Validity<'a>,
subject: &'a [u8],
subject_public_key_info: SubjectPublicKeyInfo<'a>,
issuer_unique_id: Option<&'a [u8]>,
subject_unique_id: Option<&'a [u8]>,
extensions: Extensions,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum Version {
#[num_enum(default)]
v1 = 0,
v2 = 1,
v3 = 2,
}
pub struct Validity<'a> {
not_before: Time<'a>,
not_after: Time<'a>,
}
pub enum Time<'a> {
UTCTime(&'a [u8]),
GeneralizedTime(&'a [u8]),
}
pub struct SubjectPublicKeyInfo<'a> {
algorithm: AlgorithmIdentifier<'a>,
subject_public_key: &'a [u8],
}
pub struct Extensions {
}
pub struct AlgorithmIdentifier<'a> {
pub algorithm: &'a [u8],
pub parameters: &'a [u8],
}

View File

@ -10,12 +10,12 @@ use core::convert::TryFrom;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct HkdfLabel<'a> { pub struct HkdfLabel<'a> {
// Length of hash function // Length of hash function
pub length: u16, pub length: u16,
// Label vector: "tls13 " + label // Label vector: "tls13 " + label
pub label_length: u8, pub label_length: u8,
pub label: &'a [u8], pub label: &'a [u8],
// Context vector: Hashed message // Context vector: Hashed message
pub context_length: u8, pub context_length: u8,
pub context: &'a [u8], pub context: &'a [u8],
} }

View File

@ -9,13 +9,16 @@ pub mod parse;
pub mod buffer; pub mod buffer;
pub mod key; pub mod key;
pub mod session; pub mod session;
pub mod certificate;
use nom::error::ParseError;
// TODO: Implement errors // TODO: Implement errors
// Details: Encapsulate smoltcp & nom errors // Details: Encapsulate smoltcp & nom errors
pub enum Error { pub enum Error {
PropagatedError(smoltcp::Error), PropagatedError(smoltcp::Error),
ParsingError, ParsingError(nom::error::ErrorKind),
EncryptionError, EncryptionError,
DecryptionError, DecryptionError,
CapacityError, CapacityError,
} }

View File

@ -22,31 +22,30 @@ use hkdf::Hkdf;
use smoltcp_tls::key::*; use smoltcp_tls::key::*;
use smoltcp_tls::buffer::TlsBuffer; use smoltcp_tls::buffer::TlsBuffer;
use asn1_der::{ use smoltcp_tls::certificate::*;
DerObject,
typed::{ DerEncodable, DerDecodable }
};
use asn1_der::DerObject;
use smoltcp_tls::parse::*;
struct CountingRng(u64); struct CountingRng(u64);
impl RngCore for CountingRng { impl RngCore for CountingRng {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
self.next_u64() as u32 self.next_u64() as u32
} }
fn next_u64(&mut self) -> u64 { fn next_u64(&mut self) -> u64 {
self.0 += 1; self.0 += 1;
self.0 self.0
} }
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
impls::fill_bytes_via_next(self, dest) impls::fill_bytes_via_next(self, dest)
} }
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest)) Ok(self.fill_bytes(dest))
} }
} }
impl CryptoRng for CountingRng {} impl CryptoRng for CountingRng {}
@ -54,40 +53,40 @@ impl CryptoRng for CountingRng {}
static mut RNG: CountingRng = CountingRng(0); static mut RNG: CountingRng = CountingRng(0);
fn main() { fn main() {
let mut socket_set_entries: [_; 8] = Default::default(); let mut socket_set_entries: [_; 8] = Default::default();
let mut sockets = SocketSet::new(&mut socket_set_entries[..]); let mut sockets = SocketSet::new(&mut socket_set_entries[..]);
let mut tx_storage = [0; 4096]; let mut tx_storage = [0; 4096];
let mut rx_storage = [0; 4096]; let mut rx_storage = [0; 4096];
let mut tls_socket = unsafe { let mut tls_socket = unsafe {
let tx_buffer = TcpSocketBuffer::new(&mut tx_storage[..]); let tx_buffer = TcpSocketBuffer::new(&mut tx_storage[..]);
let rx_buffer = TcpSocketBuffer::new(&mut rx_storage[..]); let rx_buffer = TcpSocketBuffer::new(&mut rx_storage[..]);
TlsSocket::new( TlsSocket::new(
&mut sockets, &mut sockets,
rx_buffer, rx_buffer,
tx_buffer, tx_buffer,
&mut RNG, &mut RNG,
) )
}; };
tls_socket.tcp_connect( tls_socket.tcp_connect(
&mut sockets, &mut sockets,
(Ipv4Address::new(192, 168, 1, 125), 1883), (Ipv4Address::new(192, 168, 1, 125), 1883),
49600 49600
).unwrap(); ).unwrap();
// tls_socket.tls_connect(&mut sockets).unwrap();
let object = DerObject::decode(&CERT).expect("Failed to decode object");
println!("raw: {:2X?},\nheader: {:2X?},\ntag: {:2X?},\nvalue: {:2X?}\n",
object.raw(),
object.header(),
object.tag(),
object.value()
);
// tls_socket.tls_connect(&mut sockets).unwrap();
let (rest, result) = parse_asn1_der_certificate(&CERT).unwrap();
println!(
"{:X?}\n{:X?}\n{:X?}\n{:X?}",
rest,
result.0,
result.1,
result.2
);
} }
const CERT: [u8; 805] = [ const CERT: [u8; 805] = [
0x30, 0x82, 0x03, 0x21, 0x30, 0x82, 0x02, 0x09, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x15, 0x5a, 0x92, 0xad, 0xc2, 0x04, 0x8f, 0x90, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x30, 0x2b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x75, 0x6c, 0x66, 0x68, 0x65, 0x69, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0x80, 0x36, 0x06, 0xba, 0xe7, 0x47, 0x6b, 0x08, 0x94, 0x04, 0xec, 0xa7, 0xb6, 0x91, 0x04, 0x3f, 0xf7, 0x92, 0xbc, 0x19, 0xee, 0xfb, 0x7d, 0x74, 0xd7, 0xa8, 0x0d, 0x00, 0x1e, 0x7b, 0x4b, 0x3a, 0x4a, 0xe6, 0x0f, 0xe8, 0xc0, 0x71, 0xfc, 0x73, 0xe7, 0x02, 0x4c, 0x0d, 0xbc, 0xf4, 0xbd, 0xd1, 0x1d, 0x39, 0x6b, 0xba, 0x70, 0x46, 0x4a, 0x13, 0xe9, 0x4a, 0xf8, 0x3d, 0xf3, 0xe1, 0x09, 0x59, 0x54, 0x7b, 0xc9, 0x55, 0xfb, 0x41, 0x2d, 0xa3, 0x76, 0x52, 0x11, 0xe1, 0xf3, 0xdc, 0x77, 0x6c, 0xaa, 0x53, 0x37, 0x6e, 0xca, 0x3a, 0xec, 0xbe, 0xc3, 0xaa, 0xb7, 0x3b, 0x31, 0xd5, 0x6c, 0xb6, 0x52, 0x9c, 0x80, 0x98, 0xbc, 0xc9, 0xe0, 0x28, 0x18, 0xe2, 0x0b, 0xf7, 0xf8, 0xa0, 0x3a, 0xfd, 0x17, 0x04, 0x50, 0x9e, 0xce, 0x79, 0xbd, 0x9f, 0x39, 0xf1, 0xea, 0x69, 0xec, 0x47, 0x97, 0x2e, 0x83, 0x0f, 0xb5, 0xca, 0x95, 0xde, 0x95, 0xa1, 0xe6, 0x04, 0x22, 0xd5, 0xee, 0xbe, 0x52, 0x79, 0x54, 0xa1, 0xe7, 0xbf, 0x8a, 0x86, 0xf6, 0x46, 0x6d, 0x0d, 0x9f, 0x16, 0x95, 0x1a, 0x4c, 0xf7, 0xa0, 0x46, 0x92, 0x59, 0x5c, 0x13, 0x52, 0xf2, 0x54, 0x9e, 0x5a, 0xfb, 0x4e, 0xbf, 0xd7, 0x7a, 0x37, 0x95, 0x01, 0x44, 0xe4, 0xc0, 0x26, 0x87, 0x4c, 0x65, 0x3e, 0x40, 0x7d, 0x7d, 0x23, 0x07, 0x44, 0x01, 0xf4, 0x84, 0xff, 0xd0, 0x8f, 0x7a, 0x1f, 0xa0, 0x52, 0x10, 0xd1, 0xf4, 0xf0, 0xd5, 0xce, 0x79, 0x70, 0x29, 0x32, 0xe2, 0xca, 0xbe, 0x70, 0x1f, 0xdf, 0xad, 0x6b, 0x4b, 0xb7, 0x11, 0x01, 0xf4, 0x4b, 0xad, 0x66, 0x6a, 0x11, 0x13, 0x0f, 0xe2, 0xee, 0x82, 0x9e, 0x4d, 0x02, 0x9d, 0xc9, 0x1c, 0xdd, 0x67, 0x16, 0xdb, 0xb9, 0x06, 0x18, 0x86, 0xed, 0xc1, 0xba, 0x94, 0x21, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x52, 0x30, 0x50, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x89, 0x4f, 0xde, 0x5b, 0xcc, 0x69, 0xe2, 0x52, 0xcf, 0x3e, 0xa3, 0x00, 0xdf, 0xb1, 0x97, 0xb8, 0x1d, 0xe1, 0xc1, 0x46, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x16, 0x45, 0xa6, 0x9a, 0x2e, 0x37, 0x79, 0xe4, 0xf6, 0xdd, 0x27, 0x1a, 0xba, 0x1c, 0x0b, 0xfd, 0x6c, 0xd7, 0x55, 0x99, 0xb5, 0xe7, 0xc3, 0x6e, 0x53, 0x3e, 0xff, 0x36, 0x59, 0x08, 0x43, 0x24, 0xc9, 0xe7, 0xa5, 0x04, 0x07, 0x9d, 0x39, 0xe0, 0xd4, 0x29, 0x87, 0xff, 0xe3, 0xeb, 0xdd, 0x09, 0xc1, 0xcf, 0x1d, 0x91, 0x44, 0x55, 0x87, 0x0b, 0x57, 0x1d, 0xd1, 0x9b, 0xdf, 0x1d, 0x24, 0xf8, 0xbb, 0x9a, 0x11, 0xfe, 0x80, 0xfd, 0x59, 0x2b, 0xa0, 0x39, 0x8c, 0xde, 0x11, 0xe2, 0x65, 0x1e, 0x61, 0x8c, 0xe5, 0x98, 0xfa, 0x96, 0xe5, 0x37, 0x2e, 0xef, 0x3d, 0x24, 0x8a, 0xfd, 0xe1, 0x74, 0x63, 0xeb, 0xbf, 0xab, 0xb8, 0xe4, 0xd1, 0xab, 0x50, 0x2a, 0x54, 0xec, 0x00, 0x64, 0xe9, 0x2f, 0x78, 0x19, 0x66, 0x0d, 0x3f, 0x27, 0xcf, 0x20, 0x9e, 0x66, 0x7f, 0xce, 0x5a, 0xe2, 0xe4, 0xac, 0x99, 0xc7, 0xc9, 0x38, 0x18, 0xf8, 0xb2, 0x51, 0x07, 0x22, 0xdf, 0xed, 0x97, 0xf3, 0x2e, 0x3e, 0x93, 0x49, 0xd4, 0xc6, 0x6c, 0x9e, 0xa6, 0x39, 0x6d, 0x74, 0x44, 0x62, 0xa0, 0x6b, 0x42, 0xc6, 0xd5, 0xba, 0x68, 0x8e, 0xac, 0x3a, 0x01, 0x7b, 0xdd, 0xfc, 0x8e, 0x2c, 0xfc, 0xad, 0x27, 0xcb, 0x69, 0xd3, 0xcc, 0xdc, 0xa2, 0x80, 0x41, 0x44, 0x65, 0xd3, 0xae, 0x34, 0x8c, 0xe0, 0xf3, 0x4a, 0xb2, 0xfb, 0x9c, 0x61, 0x83, 0x71, 0x31, 0x2b, 0x19, 0x10, 0x41, 0x64, 0x1c, 0x23, 0x7f, 0x11, 0xa5, 0xd6, 0x5c, 0x84, 0x4f, 0x04, 0x04, 0x84, 0x99, 0x38, 0x71, 0x2b, 0x95, 0x9e, 0xd6, 0x85, 0xbc, 0x5c, 0x5d, 0xd6, 0x45, 0xed, 0x19, 0x90, 0x94, 0x73, 0x40, 0x29, 0x26, 0xdc, 0xb4, 0x0e, 0x34, 0x69, 0xa1, 0x59, 0x41, 0xe8, 0xe2, 0xcc, 0xa8, 0x4b, 0xb6, 0x08, 0x46, 0x36, 0xa0 0x30, 0x82, 0x03, 0x21, 0x30, 0x82, 0x02, 0x09, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x15, 0x5a, 0x92, 0xad, 0xc2, 0x04, 0x8f, 0x90, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x33, 0x38, 0x31, 0x37, 0x5a, 0x30, 0x2b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x75, 0x6c, 0x66, 0x68, 0x65, 0x69, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0x80, 0x36, 0x06, 0xba, 0xe7, 0x47, 0x6b, 0x08, 0x94, 0x04, 0xec, 0xa7, 0xb6, 0x91, 0x04, 0x3f, 0xf7, 0x92, 0xbc, 0x19, 0xee, 0xfb, 0x7d, 0x74, 0xd7, 0xa8, 0x0d, 0x00, 0x1e, 0x7b, 0x4b, 0x3a, 0x4a, 0xe6, 0x0f, 0xe8, 0xc0, 0x71, 0xfc, 0x73, 0xe7, 0x02, 0x4c, 0x0d, 0xbc, 0xf4, 0xbd, 0xd1, 0x1d, 0x39, 0x6b, 0xba, 0x70, 0x46, 0x4a, 0x13, 0xe9, 0x4a, 0xf8, 0x3d, 0xf3, 0xe1, 0x09, 0x59, 0x54, 0x7b, 0xc9, 0x55, 0xfb, 0x41, 0x2d, 0xa3, 0x76, 0x52, 0x11, 0xe1, 0xf3, 0xdc, 0x77, 0x6c, 0xaa, 0x53, 0x37, 0x6e, 0xca, 0x3a, 0xec, 0xbe, 0xc3, 0xaa, 0xb7, 0x3b, 0x31, 0xd5, 0x6c, 0xb6, 0x52, 0x9c, 0x80, 0x98, 0xbc, 0xc9, 0xe0, 0x28, 0x18, 0xe2, 0x0b, 0xf7, 0xf8, 0xa0, 0x3a, 0xfd, 0x17, 0x04, 0x50, 0x9e, 0xce, 0x79, 0xbd, 0x9f, 0x39, 0xf1, 0xea, 0x69, 0xec, 0x47, 0x97, 0x2e, 0x83, 0x0f, 0xb5, 0xca, 0x95, 0xde, 0x95, 0xa1, 0xe6, 0x04, 0x22, 0xd5, 0xee, 0xbe, 0x52, 0x79, 0x54, 0xa1, 0xe7, 0xbf, 0x8a, 0x86, 0xf6, 0x46, 0x6d, 0x0d, 0x9f, 0x16, 0x95, 0x1a, 0x4c, 0xf7, 0xa0, 0x46, 0x92, 0x59, 0x5c, 0x13, 0x52, 0xf2, 0x54, 0x9e, 0x5a, 0xfb, 0x4e, 0xbf, 0xd7, 0x7a, 0x37, 0x95, 0x01, 0x44, 0xe4, 0xc0, 0x26, 0x87, 0x4c, 0x65, 0x3e, 0x40, 0x7d, 0x7d, 0x23, 0x07, 0x44, 0x01, 0xf4, 0x84, 0xff, 0xd0, 0x8f, 0x7a, 0x1f, 0xa0, 0x52, 0x10, 0xd1, 0xf4, 0xf0, 0xd5, 0xce, 0x79, 0x70, 0x29, 0x32, 0xe2, 0xca, 0xbe, 0x70, 0x1f, 0xdf, 0xad, 0x6b, 0x4b, 0xb7, 0x11, 0x01, 0xf4, 0x4b, 0xad, 0x66, 0x6a, 0x11, 0x13, 0x0f, 0xe2, 0xee, 0x82, 0x9e, 0x4d, 0x02, 0x9d, 0xc9, 0x1c, 0xdd, 0x67, 0x16, 0xdb, 0xb9, 0x06, 0x18, 0x86, 0xed, 0xc1, 0xba, 0x94, 0x21, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x52, 0x30, 0x50, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x89, 0x4f, 0xde, 0x5b, 0xcc, 0x69, 0xe2, 0x52, 0xcf, 0x3e, 0xa3, 0x00, 0xdf, 0xb1, 0x97, 0xb8, 0x1d, 0xe1, 0xc1, 0x46, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x16, 0x45, 0xa6, 0x9a, 0x2e, 0x37, 0x79, 0xe4, 0xf6, 0xdd, 0x27, 0x1a, 0xba, 0x1c, 0x0b, 0xfd, 0x6c, 0xd7, 0x55, 0x99, 0xb5, 0xe7, 0xc3, 0x6e, 0x53, 0x3e, 0xff, 0x36, 0x59, 0x08, 0x43, 0x24, 0xc9, 0xe7, 0xa5, 0x04, 0x07, 0x9d, 0x39, 0xe0, 0xd4, 0x29, 0x87, 0xff, 0xe3, 0xeb, 0xdd, 0x09, 0xc1, 0xcf, 0x1d, 0x91, 0x44, 0x55, 0x87, 0x0b, 0x57, 0x1d, 0xd1, 0x9b, 0xdf, 0x1d, 0x24, 0xf8, 0xbb, 0x9a, 0x11, 0xfe, 0x80, 0xfd, 0x59, 0x2b, 0xa0, 0x39, 0x8c, 0xde, 0x11, 0xe2, 0x65, 0x1e, 0x61, 0x8c, 0xe5, 0x98, 0xfa, 0x96, 0xe5, 0x37, 0x2e, 0xef, 0x3d, 0x24, 0x8a, 0xfd, 0xe1, 0x74, 0x63, 0xeb, 0xbf, 0xab, 0xb8, 0xe4, 0xd1, 0xab, 0x50, 0x2a, 0x54, 0xec, 0x00, 0x64, 0xe9, 0x2f, 0x78, 0x19, 0x66, 0x0d, 0x3f, 0x27, 0xcf, 0x20, 0x9e, 0x66, 0x7f, 0xce, 0x5a, 0xe2, 0xe4, 0xac, 0x99, 0xc7, 0xc9, 0x38, 0x18, 0xf8, 0xb2, 0x51, 0x07, 0x22, 0xdf, 0xed, 0x97, 0xf3, 0x2e, 0x3e, 0x93, 0x49, 0xd4, 0xc6, 0x6c, 0x9e, 0xa6, 0x39, 0x6d, 0x74, 0x44, 0x62, 0xa0, 0x6b, 0x42, 0xc6, 0xd5, 0xba, 0x68, 0x8e, 0xac, 0x3a, 0x01, 0x7b, 0xdd, 0xfc, 0x8e, 0x2c, 0xfc, 0xad, 0x27, 0xcb, 0x69, 0xd3, 0xcc, 0xdc, 0xa2, 0x80, 0x41, 0x44, 0x65, 0xd3, 0xae, 0x34, 0x8c, 0xe0, 0xf3, 0x4a, 0xb2, 0xfb, 0x9c, 0x61, 0x83, 0x71, 0x31, 0x2b, 0x19, 0x10, 0x41, 0x64, 0x1c, 0x23, 0x7f, 0x11, 0xa5, 0xd6, 0x5c, 0x84, 0x4f, 0x04, 0x04, 0x84, 0x99, 0x38, 0x71, 0x2b, 0x95, 0x9e, 0xd6, 0x85, 0xbc, 0x5c, 0x5d, 0xd6, 0x45, 0xed, 0x19, 0x90, 0x94, 0x73, 0x40, 0x29, 0x26, 0xdc, 0xb4, 0x0e, 0x34, 0x69, 0xa1, 0x59, 0x41, 0xe8, 0xe2, 0xcc, 0xa8, 0x4b, 0xb6, 0x08, 0x46, 0x36, 0xa0
]; ];

View File

@ -5,6 +5,7 @@ use nom::bytes::complete::take_till;
use nom::combinator::complete; use nom::combinator::complete;
use nom::sequence::preceded; use nom::sequence::preceded;
use nom::sequence::tuple; use nom::sequence::tuple;
use nom::error::make_error;
use nom::error::ErrorKind; use nom::error::ErrorKind;
use smoltcp::Error; use smoltcp::Error;
use smoltcp::Result; use smoltcp::Result;
@ -12,7 +13,18 @@ use smoltcp::Result;
use byteorder::{ByteOrder, NetworkEndian, BigEndian}; use byteorder::{ByteOrder, NetworkEndian, BigEndian};
use crate::tls_packet::*; use crate::tls_packet::*;
use crate::certificate::Certificate as Asn1DerCertificate;
use crate::certificate::Version as Asn1DerVersion;
use crate::certificate::AlgorithmIdentifier as Asn1DerAlgId;
use core::convert::TryFrom; use core::convert::TryFrom;
use core::convert::TryInto;
use asn1_der::{
DerObject,
typed::{ DerEncodable, DerDecodable },
Asn1DerError,
};
use alloc::vec::Vec; use alloc::vec::Vec;
@ -327,3 +339,115 @@ fn parse_extension(bytes: &[u8], handshake_type: HandshakeType) -> IResult<&[u8]
} }
)) ))
} }
pub fn parse_asn1_der_header(bytes: &[u8]) -> IResult<&[u8], (u8, usize)> {
// Parse tag
let (rest, tag) = take(1_usize)(bytes)?;
// Parse length
let (rest, length_byte) = take(1_usize)(rest)?;
if length_byte[0] <= 0x7F {
Ok((rest, (tag[0], length_byte[0].into())))
} else {
if length_byte[0] & 0x7F > core::mem::size_of::<usize>().try_into().unwrap() {
return Err(nom::Err::Failure((length_byte, ErrorKind::TooLarge)));
}
let length_size = length_byte[0] & 0x7F;
let (rem, length_slice) = take(length_size)(rest)?;
let mut length_array: [u8; 8] = [0; 8];
for array_index in 0..length_slice.len() {
length_array[array_index + 8 - length_slice.len()] = length_slice[array_index];
}
Ok((rem, (tag[0], usize::from_be_bytes(length_array))))
}
}
pub fn parse_asn1_der_object(bytes: &[u8]) -> IResult<&[u8], (u8, usize, &[u8])> {
let (rest, (tag, length)) = parse_asn1_der_header(bytes)?;
let (rest, value) = take(length)(rest)?;
Ok((rest, (tag, length, value)))
}
pub fn parse_asn1_der_certificate(bytes: &[u8]) -> IResult<&[u8], (&[u8], &[u8], &[u8])> {
let (_, (_, _, rest)) = parse_asn1_der_object(bytes)?;
let (rest, (_, _, tbscertificate_slice)) = parse_asn1_der_object(rest)?;
let (rest, (_, _, signature_alg)) = parse_asn1_der_object(rest)?;
let (rest, (_, _, sig_val)) = parse_asn1_der_object(rest)?;
Ok((rest, (tbscertificate_slice, signature_alg, sig_val)))
}
pub fn parse_asn1_der_tbs_certificate(bytes: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
todo!()
}
// version: [0] EXPLICIT Version DEFAULT V1
// Version encapsulates an Integer
// i.e. context-specific, constructed, type [0] -> tag: A0
pub fn parse_asn1_der_version(bytes: &[u8]) -> IResult<&[u8], Asn1DerVersion> {
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
// Verify the tag is indeed 0xA0
if tag_val != 0xA0 {
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
}
// Parse the encapsulated INTEGER, force completeness
let (_, integer) = complete(parse_asn1_der_integer)(value)?;
// Either 0, 1, or 2, take the last byte and assert all former bytes to be 0
let (zeroes, version_byte) = take(integer.len()-1)(integer)?;
complete(take_till(|byte| byte != 0))(zeroes)?;
Ok((rest, Asn1DerVersion::try_from(version_byte[0]).unwrap()))
}
// INTEGER: tag: 0x02
pub fn parse_asn1_der_integer(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
// Verify the tag is indeed 0x02
if tag_val != 0x02 {
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
}
Ok((rest, value))
}
// CertificateSerialNumber: alias of INTEGER
pub fn parse_asn1_der_serial_number(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
parse_asn1_der_integer(bytes)
}
// Algorithm Identifier: Sequence -> universal, constructed, 0 (0x30)
// Encapsulates OID (alg) and optional params (params)
pub fn parse_asn1_der_algorithm_identifier(bytes: &[u8]) -> IResult<&[u8], Asn1DerAlgId> {
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
// Verify the tag_val is indeed 0x30
if tag_val != 0x30 {
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
}
// Parse OID and then optionl parameters
let (_, (oid, (_, _, optional_param))) = complete(
tuple((
parse_asn1_der_oid,
parse_asn1_der_object
))
)(value)?;
Ok((
rest,
Asn1DerAlgId {
algorithm: oid,
parameters: optional_param,
}
))
}
// Parser for Universal OID type (0x06)
pub fn parse_asn1_der_oid(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
// Verify the tag_val is indeed 0x06
if tag_val != 0x06 {
return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
}
Ok((rest, value))
}
// Parser for Time Validity Structure
pub fn parse_asn1_der_validity(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
let (rest, (tag_val, length, value)) = parse_asn1_der_object(bytes)?;
}

File diff suppressed because it is too large Load Diff

View File

@ -41,443 +41,443 @@ use crate::session::{Session, TlsRole};
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub(crate) enum TlsState { pub(crate) enum TlsState {
START, START,
WAIT_SH, WAIT_SH,
WAIT_EE, WAIT_EE,
WAIT_CERT_CR, WAIT_CERT_CR,
WAIT_CERT, WAIT_CERT,
WAIT_CV, WAIT_CV,
WAIT_FINISHED, WAIT_FINISHED,
CONNECTED, CONNECTED,
} }
// TODO: Group up all session_specific parameters into a separate structure // TODO: Group up all session_specific parameters into a separate structure
pub struct TlsSocket<R: 'static + RngCore + CryptoRng> pub struct TlsSocket<R: 'static + RngCore + CryptoRng>
{ {
tcp_handle: SocketHandle, tcp_handle: SocketHandle,
rng: R, rng: R,
session: RefCell<Session>, session: RefCell<Session>,
} }
impl<R: RngCore + CryptoRng> TlsSocket<R> { impl<R: RngCore + CryptoRng> TlsSocket<R> {
pub fn new<'a, 'b, 'c>( pub fn new<'a, 'b, 'c>(
sockets: &mut SocketSet<'a, 'b, 'c>, sockets: &mut SocketSet<'a, 'b, 'c>,
rx_buffer: TcpSocketBuffer<'b>, rx_buffer: TcpSocketBuffer<'b>,
tx_buffer: TcpSocketBuffer<'b>, tx_buffer: TcpSocketBuffer<'b>,
rng: R, rng: R,
) -> Self ) -> Self
where where
'b: 'c, 'b: 'c,
{ {
let tcp_socket = TcpSocket::new(rx_buffer, tx_buffer); let tcp_socket = TcpSocket::new(rx_buffer, tx_buffer);
let tcp_handle = sockets.add(tcp_socket); let tcp_handle = sockets.add(tcp_socket);
TlsSocket { TlsSocket {
tcp_handle, tcp_handle,
rng, rng,
session: RefCell::new( session: RefCell::new(
Session::new(TlsRole::Client) Session::new(TlsRole::Client)
), ),
} }
} }
pub fn tcp_connect<T, U>( pub fn tcp_connect<T, U>(
&mut self, &mut self,
sockets: &mut SocketSet, sockets: &mut SocketSet,
remote_endpoint: T, remote_endpoint: T,
local_endpoint: U, local_endpoint: U,
) -> Result<()> ) -> Result<()>
where where
T: Into<IpEndpoint>, T: Into<IpEndpoint>,
U: Into<IpEndpoint>, U: Into<IpEndpoint>,
{ {
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle); let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
if tcp_socket.state() == TcpState::Established { if tcp_socket.state() == TcpState::Established {
Ok(()) Ok(())
} else { } else {
tcp_socket.connect(remote_endpoint, local_endpoint) tcp_socket.connect(remote_endpoint, local_endpoint)
} }
} }
pub fn tls_connect<DeviceT>( pub fn tls_connect<DeviceT>(
&mut self, &mut self,
iface: &mut EthernetInterface<DeviceT>, iface: &mut EthernetInterface<DeviceT>,
sockets: &mut SocketSet, sockets: &mut SocketSet,
now: Instant now: Instant
) -> Result<bool> ) -> Result<bool>
where where
DeviceT: for<'d> Device<'d> DeviceT: for<'d> Device<'d>
{ {
// Check tcp_socket connectivity // Check tcp_socket connectivity
{ {
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle); let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
tcp_socket.set_keep_alive(Some(smoltcp::time::Duration::from_millis(1000))); tcp_socket.set_keep_alive(Some(smoltcp::time::Duration::from_millis(1000)));
if tcp_socket.state() != TcpState::Established { if tcp_socket.state() != TcpState::Established {
return Ok(false); return Ok(false);
} }
} }
// Handle TLS handshake through TLS states // Handle TLS handshake through TLS states
let tls_state = { let tls_state = {
self.session.borrow().get_tls_state() self.session.borrow().get_tls_state()
}; };
match tls_state { match tls_state {
// Initiate TLS handshake // Initiate TLS handshake
TlsState::START => { TlsState::START => {
// Prepare field that is randomised, // Prepare field that is randomised,
// Supply it to the TLS repr builder. // Supply it to the TLS repr builder.
let ecdh_secret = EphemeralSecret::random(&mut self.rng); let ecdh_secret = EphemeralSecret::random(&mut self.rng);
let mut random: [u8; 32] = [0; 32]; let mut random: [u8; 32] = [0; 32];
let mut session_id: [u8; 32] = [0; 32]; let mut session_id: [u8; 32] = [0; 32];
self.rng.fill_bytes(&mut random); self.rng.fill_bytes(&mut random);
self.rng.fill_bytes(&mut session_id); self.rng.fill_bytes(&mut session_id);
let repr = TlsRepr::new() let repr = TlsRepr::new()
.client_hello(&ecdh_secret, random, session_id.clone()); .client_hello(&ecdh_secret, random, session_id.clone());
// Update hash function with client hello handshake // Update hash function with client hello handshake
let mut array = [0; 512]; let mut array = [0; 512];
let mut buffer = TlsBuffer::new(&mut array); let mut buffer = TlsBuffer::new(&mut array);
buffer.enqueue_tls_repr(repr)?; buffer.enqueue_tls_repr(repr)?;
let slice: &[u8] = buffer.into(); let slice: &[u8] = buffer.into();
// Send the packet // Send the packet
self.send_tls_slice(sockets, slice)?; self.send_tls_slice(sockets, slice)?;
// Update TLS session // Update TLS session
self.session.borrow_mut().client_update_for_ch( self.session.borrow_mut().client_update_for_ch(
ecdh_secret, ecdh_secret,
session_id, session_id,
&slice[5..] &slice[5..]
); );
}, },
// TLS Client wait for Server Hello // TLS Client wait for Server Hello
// No need to send anything // No need to send anything
TlsState::WAIT_SH => {}, TlsState::WAIT_SH => {},
// TLS Client wait for certificate from TLS server // TLS Client wait for certificate from TLS server
// No need to send anything // No need to send anything
// Note: TLS server should normally send SH alongside EE // Note: TLS server should normally send SH alongside EE
// TLS client should jump from WAIT_SH directly to WAIT_CERT_CR directly. // TLS client should jump from WAIT_SH directly to WAIT_CERT_CR directly.
TlsState::WAIT_EE => {}, TlsState::WAIT_EE => {},
// TLS Client wait for server's certificate // TLS Client wait for server's certificate
// No need to send anything // No need to send anything
TlsState::WAIT_CERT_CR => {}, TlsState::WAIT_CERT_CR => {},
_ => todo!() _ => todo!()
} }
// Poll the network interface // Poll the network interface
iface.poll(sockets, now); iface.poll(sockets, now);
// Read for TLS packet // Read for TLS packet
let mut array: [u8; 2048] = [0; 2048]; let mut array: [u8; 2048] = [0; 2048];
let mut tls_repr_vec = self.recv_tls_repr(sockets, &mut array)?; let mut tls_repr_vec = self.recv_tls_repr(sockets, &mut array)?;
// Take the TLS representation out of the vector, // Take the TLS representation out of the vector,
// Process as a queue // Process as a queue
let tls_repr_vec_size = tls_repr_vec.len(); let tls_repr_vec_size = tls_repr_vec.len();
for index in 0..tls_repr_vec_size { for index in 0..tls_repr_vec_size {
let repr = tls_repr_vec.remove(0); let repr = tls_repr_vec.remove(0);
self.process(repr)?; self.process(repr)?;
} }
Ok(self.session.borrow().has_completed_handshake()) Ok(self.session.borrow().has_completed_handshake())
} }
// Process TLS ingress during handshake // Process TLS ingress during handshake
fn process(&self, mut repr: TlsRepr) -> Result<()> { fn process(&self, mut repr: TlsRepr) -> Result<()> {
// Change_cipher_spec check: // Change_cipher_spec check:
// Must receive CCS before recv peer's FINISH message // Must receive CCS before recv peer's FINISH message
// i.e. Must happen after START and before CONNECTED // i.e. Must happen after START and before CONNECTED
// //
// CCS message only exist for compatibility reason, // CCS message only exist for compatibility reason,
// Drop the message and update `received_change_cipher_spec` // Drop the message and update `received_change_cipher_spec`
// Note: CSS doesn't count as a proper record, no need to increment sequence number // Note: CSS doesn't count as a proper record, no need to increment sequence number
if repr.is_change_cipher_spec() { if repr.is_change_cipher_spec() {
let mut session = self.session.borrow_mut(); let mut session = self.session.borrow_mut();
session.receive_change_cipher_spec(); session.receive_change_cipher_spec();
return Ok(()) return Ok(())
} }
let tls_state = { let tls_state = {
self.session.borrow().get_tls_state() self.session.borrow().get_tls_state()
}; };
match tls_state { match tls_state {
// During WAIT_SH for a TLS client, client should wait for ServerHello // During WAIT_SH for a TLS client, client should wait for ServerHello
TlsState::WAIT_SH => { TlsState::WAIT_SH => {
// Legacy_protocol must be TLS 1.2 // Legacy_protocol must be TLS 1.2
if repr.version != TlsVersion::Tls12 { if repr.version != TlsVersion::Tls12 {
// Abort communication // Abort communication
todo!() todo!()
} }
// TODO: Validate SH // TODO: Validate SH
if repr.is_server_hello() { if repr.is_server_hello() {
// Check SH content: // Check SH content:
// random: Cannot represent HelloRequestRetry // random: Cannot represent HelloRequestRetry
// (TODO: Support other key shares, e.g. X25519) // (TODO: Support other key shares, e.g. X25519)
// session_id_echo: should be same as the one sent by client // session_id_echo: should be same as the one sent by client
// cipher_suite: Store // cipher_suite: Store
// (TODO: Check if such suite was offered) // (TODO: Check if such suite was offered)
// compression_method: Must be null, not supported in TLS 1.3 // compression_method: Must be null, not supported in TLS 1.3
// //
// Check extensions: // Check extensions:
// supported_version: Must be TLS 1.3 // supported_version: Must be TLS 1.3
// key_share: Store key, must be in secp256r1 // key_share: Store key, must be in secp256r1
// (TODO: Support other key shares ^) // (TODO: Support other key shares ^)
// "Cache" for ECDHE server public info // "Cache" for ECDHE server public info
let mut server_public: Option<EncodedPoint> = None; let mut server_public: Option<EncodedPoint> = None;
let mut selected_cipher: Option<CipherSuite> = None; let mut selected_cipher: Option<CipherSuite> = None;
// Process the handshake data within ServerHello // Process the handshake data within ServerHello
let handshake_data = &repr.handshake.as_ref().unwrap().handshake_data; let handshake_data = &repr.handshake.as_ref().unwrap().handshake_data;
if let HandshakeData::ServerHello(server_hello) = handshake_data { if let HandshakeData::ServerHello(server_hello) = handshake_data {
// Check random: Cannot be SHA-256 of "HelloRetryRequest" // Check random: Cannot be SHA-256 of "HelloRetryRequest"
if server_hello.random == HRR_RANDOM { if server_hello.random == HRR_RANDOM {
// Abort communication // Abort communication
todo!() todo!()
} }
// Check session_id_echo // Check session_id_echo
// The socket should have a session_id after moving from START state // The socket should have a session_id after moving from START state
if !self.session.borrow().verify_session_id_echo(server_hello.session_id_echo) { if !self.session.borrow().verify_session_id_echo(server_hello.session_id_echo) {
// Abort communication // Abort communication
todo!() todo!()
} }
// Note the selected cipher suite // Note the selected cipher suite
selected_cipher.replace(server_hello.cipher_suite); selected_cipher.replace(server_hello.cipher_suite);
// TLSv13 forbidden key compression // TLSv13 forbidden key compression
if server_hello.compression_method != 0 { if server_hello.compression_method != 0 {
// Abort communciation // Abort communciation
todo!() todo!()
} }
for extension in server_hello.extensions.iter() { for extension in server_hello.extensions.iter() {
if extension.extension_type == ExtensionType::SupportedVersions { if extension.extension_type == ExtensionType::SupportedVersions {
if let ExtensionData::SupportedVersions( if let ExtensionData::SupportedVersions(
SupportedVersions::ServerHello { SupportedVersions::ServerHello {
selected_version selected_version
} }
) = extension.extension_data { ) = extension.extension_data {
if selected_version != TlsVersion::Tls13 { if selected_version != TlsVersion::Tls13 {
// Abort for choosing not offered TLS version // Abort for choosing not offered TLS version
todo!() todo!()
} }
} else { } else {
// Abort for illegal extension // Abort for illegal extension
todo!() todo!()
} }
} }
if extension.extension_type == ExtensionType::KeyShare { if extension.extension_type == ExtensionType::KeyShare {
if let ExtensionData::KeyShareEntry( if let ExtensionData::KeyShareEntry(
KeyShareEntryContent::KeyShareServerHello { KeyShareEntryContent::KeyShareServerHello {
server_share server_share
} }
) = &extension.extension_data { ) = &extension.extension_data {
// TODO: Use legitimate checking to ensure the chosen // TODO: Use legitimate checking to ensure the chosen
// group is indeed acceptable, when allowing more (EC)DHE // group is indeed acceptable, when allowing more (EC)DHE
// key sharing // key sharing
if server_share.group != NamedGroup::secp256r1 { if server_share.group != NamedGroup::secp256r1 {
// Abort for wrong key sharing // Abort for wrong key sharing
todo!() todo!()
} }
// Store key // Store key
// It is surely from secp256r1, no other groups are permitted // It is surely from secp256r1, no other groups are permitted
// Convert untagged bytes into encoded point on p256 eliptic curve // Convert untagged bytes into encoded point on p256 eliptic curve
// Slice the first byte out of the bytes // Slice the first byte out of the bytes
server_public.replace( server_public.replace(
EncodedPoint::from_untagged_bytes( EncodedPoint::from_untagged_bytes(
GenericArray::from_slice(&server_share.key_exchange[1..]) GenericArray::from_slice(&server_share.key_exchange[1..])
) )
); );
} }
} }
} }
} else { } else {
// Handle invalid TLS packet // Handle invalid TLS packet
todo!() todo!()
} }
// Check that both selected_cipher and server_public were received // Check that both selected_cipher and server_public were received
if selected_cipher.is_none() || server_public.is_none() { if selected_cipher.is_none() || server_public.is_none() {
// Abort communication // Abort communication
todo!() todo!()
} }
// This is indeed a desirable ServerHello TLS repr // This is indeed a desirable ServerHello TLS repr
// Reprocess ServerHello into a slice // Reprocess ServerHello into a slice
// Update session with required parameter // Update session with required parameter
let mut array = [0; 512]; let mut array = [0; 512];
let mut buffer = TlsBuffer::new(&mut array); let mut buffer = TlsBuffer::new(&mut array);
buffer.enqueue_tls_repr(repr)?; buffer.enqueue_tls_repr(repr)?;
let slice: &[u8] = buffer.into(); let slice: &[u8] = buffer.into();
let mut session = self.session.borrow_mut(); let mut session = self.session.borrow_mut();
session.client_update_for_sh( session.client_update_for_sh(
selected_cipher.unwrap(), selected_cipher.unwrap(),
server_public.unwrap(), server_public.unwrap(),
&slice[5..] &slice[5..]
); );
// Key exchange occurred, seq_num is set to 0 // Key exchange occurred, seq_num is set to 0
// Do NOT update seq_num again. Early return. // Do NOT update seq_num again. Early return.
return Ok(()); return Ok(());
} }
}, },
// Expect encrypted extensions after receiving SH // Expect encrypted extensions after receiving SH
TlsState::WAIT_EE => { TlsState::WAIT_EE => {
// Check that the packet is classified as application data // Check that the packet is classified as application data
if !repr.is_application_data() { if !repr.is_application_data() {
// Abort communication, this affect IV calculation // Abort communication, this affect IV calculation
todo!() todo!()
} }
// ExcepytedExtensions are disguised as ApplicationData // ExcepytedExtensions are disguised as ApplicationData
// Pull out the `payload` from TlsRepr, decrypt as EE // Pull out the `payload` from TlsRepr, decrypt as EE
let mut payload = repr.payload.take().unwrap(); let mut payload = repr.payload.take().unwrap();
log::info!("Encrypted payload: {:?}", payload); log::info!("Encrypted payload: {:?}", payload);
let mut array: [u8; 5] = [0; 5]; let mut array: [u8; 5] = [0; 5];
let mut buffer = TlsBuffer::new(&mut array); let mut buffer = TlsBuffer::new(&mut array);
buffer.write_u8(repr.content_type.into())?; buffer.write_u8(repr.content_type.into())?;
buffer.write_u16(repr.version.into())?; buffer.write_u16(repr.version.into())?;
buffer.write_u16(repr.length)?; buffer.write_u16(repr.length)?;
let associated_data: &[u8] = buffer.into(); let associated_data: &[u8] = buffer.into();
log::info!("Associated Data: {:?}", associated_data); log::info!("Associated Data: {:?}", associated_data);
{ {
self.session.borrow_mut().decrypt_in_place( self.session.borrow_mut().decrypt_in_place(
associated_data, associated_data,
&mut payload &mut payload
); );
} }
log::info!("decrypted EE"); log::info!("decrypted EE");
log::info!("{:?}", payload); log::info!("{:?}", payload);
// TODO: Parse payload of EE // TODO: Parse payload of EE
let parse_result = parse_handshake(&payload); let parse_result = parse_handshake(&payload);
let (_, encrypted_extensions_handshake) = parse_result let (_, encrypted_extensions_handshake) = parse_result
.map_err(|_| Error::Unrecognized)?; .map_err(|_| Error::Unrecognized)?;
// TODO: Process payload // TODO: Process payload
// Practically, nothing will be done about cookies/server name // Practically, nothing will be done about cookies/server name
// Extension processing is therefore skipped // Extension processing is therefore skipped
log::info!("Parsed EE"); log::info!("Parsed EE");
self.session.borrow_mut().client_update_for_ee(); self.session.borrow_mut().client_update_for_ee();
}, },
// In this stage, wait for a certificate from server // In this stage, wait for a certificate from server
// Parse the certificate and check its content // Parse the certificate and check its content
TlsState::WAIT_CERT_CR => { TlsState::WAIT_CERT_CR => {
// Check that the packet is classified as application data // Check that the packet is classified as application data
// Certificates transfer is disguised as application data // Certificates transfer is disguised as application data
if !repr.is_application_data() { if !repr.is_application_data() {
// Abort communication, this affect IV calculation // Abort communication, this affect IV calculation
todo!() todo!()
} }
// Pull out the `payload` from TlsRepr, decrypt as EE // Pull out the `payload` from TlsRepr, decrypt as EE
let mut payload = repr.payload.take().unwrap(); let mut payload = repr.payload.take().unwrap();
// Instantiate associated data and decrypt // Instantiate associated data and decrypt
let mut array: [u8; 5] = [0; 5]; let mut array: [u8; 5] = [0; 5];
let mut buffer = TlsBuffer::new(&mut array); let mut buffer = TlsBuffer::new(&mut array);
buffer.write_u8(repr.content_type.into())?; buffer.write_u8(repr.content_type.into())?;
buffer.write_u16(repr.version.into())?; buffer.write_u16(repr.version.into())?;
buffer.write_u16(repr.length)?; buffer.write_u16(repr.length)?;
let associated_data: &[u8] = buffer.into(); let associated_data: &[u8] = buffer.into();
{ {
self.session.borrow_mut().decrypt_in_place( self.session.borrow_mut().decrypt_in_place(
associated_data, associated_data,
&mut payload &mut payload
); );
} }
log::info!("Decrypted payload {:?}", payload); log::info!("Decrypted payload {:?}", payload);
}, },
_ => {}, _ => {},
} }
// A TLS Record was received and processed and verified // A TLS Record was received and processed and verified
// Increment sequence number // Increment sequence number
self.session.borrow_mut().increment_sequence_number(); self.session.borrow_mut().increment_sequence_number();
Ok(()) Ok(())
} }
// Generic inner send method, through TCP socket // Generic inner send method, through TCP socket
fn send_tls_repr(&self, sockets: &mut SocketSet, tls_repr: TlsRepr) -> Result<()> { fn send_tls_repr(&self, sockets: &mut SocketSet, tls_repr: TlsRepr) -> Result<()> {
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle); let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
if !tcp_socket.can_send() { if !tcp_socket.can_send() {
return Err(Error::Illegal); return Err(Error::Illegal);
} }
let mut array = [0; 2048]; let mut array = [0; 2048];
let mut buffer = TlsBuffer::new(&mut array); let mut buffer = TlsBuffer::new(&mut array);
buffer.enqueue_tls_repr(tls_repr)?; buffer.enqueue_tls_repr(tls_repr)?;
let buffer_size = buffer.get_size(); let buffer_size = buffer.get_size();
// Force send to return if send is unsuccessful // Force send to return if send is unsuccessful
// Only update sequence number if the send is successful // Only update sequence number if the send is successful
tcp_socket.send_slice(buffer.into()) tcp_socket.send_slice(buffer.into())
.and_then( .and_then(
|size| if size == buffer_size { |size| if size == buffer_size {
Ok(()) Ok(())
} else { } else {
Err(Error::Truncated) Err(Error::Truncated)
} }
)?; )?;
self.session.borrow_mut().increment_sequence_number(); self.session.borrow_mut().increment_sequence_number();
Ok(()) Ok(())
} }
// Generic inner send method for buffer IO, through TCP socket // Generic inner send method for buffer IO, through TCP socket
// Usage: Push a slice representation of ONE TLS packet // Usage: Push a slice representation of ONE TLS packet
// This function will only increment sequence number by 1 // This function will only increment sequence number by 1
// Repeatedly call this function if sending multiple TLS packets is needed // Repeatedly call this function if sending multiple TLS packets is needed
fn send_tls_slice(&self, sockets: &mut SocketSet, slice: &[u8]) -> Result<()> { fn send_tls_slice(&self, sockets: &mut SocketSet, slice: &[u8]) -> Result<()> {
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle); let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
if !tcp_socket.can_send() { if !tcp_socket.can_send() {
return Err(Error::Illegal); return Err(Error::Illegal);
} }
let buffer_size = slice.len(); let buffer_size = slice.len();
tcp_socket.send_slice(slice) tcp_socket.send_slice(slice)
.and_then( .and_then(
|size| if size == buffer_size { |size| if size == buffer_size {
Ok(()) Ok(())
} else { } else {
Err(Error::Truncated) Err(Error::Truncated)
} }
)?; )?;
self.session.borrow_mut().increment_sequence_number(); self.session.borrow_mut().increment_sequence_number();
Ok(()) Ok(())
} }
// Generic inner recv method, through TCP socket // Generic inner recv method, through TCP socket
// A TCP packet can contain multiple TLS records (including 0) // A TCP packet can contain multiple TLS records (including 0)
// Therefore, sequence nubmer incrementation is not completed here // Therefore, sequence nubmer incrementation is not completed here
fn recv_tls_repr<'a>(&'a self, sockets: &mut SocketSet, byte_array: &'a mut [u8]) -> Result<Vec::<TlsRepr>> { fn recv_tls_repr<'a>(&'a self, sockets: &mut SocketSet, byte_array: &'a mut [u8]) -> Result<Vec::<TlsRepr>> {
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle); let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
if !tcp_socket.can_recv() { if !tcp_socket.can_recv() {
return Ok((Vec::new())); return Ok((Vec::new()));
} }
let array_size = tcp_socket.recv_slice(byte_array)?; let array_size = tcp_socket.recv_slice(byte_array)?;
let mut vec: Vec<TlsRepr> = Vec::new(); let mut vec: Vec<TlsRepr> = Vec::new();
let mut bytes: &[u8] = &byte_array[..array_size]; let mut bytes: &[u8] = &byte_array[..array_size];
loop { loop {
match parse_tls_repr(bytes) { match parse_tls_repr(bytes) {
Ok((rest, repr)) => { Ok((rest, repr)) => {
vec.push(repr); vec.push(repr);
if rest.len() == 0 { if rest.len() == 0 {
return Ok(vec); return Ok(vec);
} else { } else {
bytes = rest; bytes = rest;
} }
}, },
_ => return Err(Error::Unrecognized), _ => return Err(Error::Unrecognized),
}; };
} }
} }
} }

File diff suppressed because it is too large Load Diff