diff --git a/Cargo.toml b/Cargo.toml index 6a69ddf..bad2186 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,11 @@ version = "0.5.0" default-features = false features = [ "ecdh", "ecdsa", "arithmetic" ] +[dependencies.ed25519-dalek] +version = "1.0.1" +default-features = false +features = [ "u64_backend" ] + # Fetch from master, for "no_std" + "alloc" combination [dependencies.rsa] git = "https://github.com/RustCrypto/RSA.git" @@ -56,6 +61,11 @@ version = "5.1.2" default-features = false features = [] +[dependencies.arraydeque] +version = "0.4.5" +default-features = false +features = [ "use_generic_array" ] + [dependencies.simple_logger] version = "1.11.0" optional = true diff --git a/src/buffer.rs b/src/buffer.rs index 5ee358a..87b4b7e 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,11 +1,10 @@ use core::cell::RefCell; -use core::convert::{ TryInto, TryFrom }; use smoltcp::{ Result, Error }; use alloc::vec::Vec; -use byteorder::{ByteOrder, NetworkEndian, BigEndian}; +use byteorder::{ByteOrder, NetworkEndian}; use crate::tls_packet::*; use crate::key::*; @@ -181,7 +180,7 @@ impl<'a> TlsBuffer<'a> { } }, KeyShareEntry(k) => { - let mut key_share_entry_into = |buffer: &mut TlsBuffer, entry: crate::tls_packet::KeyShareEntry| { + let key_share_entry_into = |buffer: &mut TlsBuffer, entry: crate::tls_packet::KeyShareEntry| { buffer.write_u16(entry.group.into())?; buffer.write_u16(entry.length)?; buffer.write(entry.key_exchange.as_slice()) diff --git a/src/certificate.rs b/src/certificate.rs index 6c8c1b6..b1f07b9 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -1,7 +1,6 @@ use num_enum::IntoPrimitive; use num_enum::TryFromPrimitive; -use crate::parse::parse_asn1_der_object; use crate::parse::parse_asn1_der_rsa_public_key; use crate::Error as TlsError; @@ -32,6 +31,7 @@ pub struct TBSCertificate<'a> { pub extensions: Extensions<'a>, } +#[allow(non_camel_case_types)] #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)] #[repr(u8)] pub enum Version { @@ -147,7 +147,6 @@ pub fn validate_root_certificate(cert: &Certificate) -> Result { let mut hasher = Sha1::new(); hasher.update(cert.tbs_certificate_encoded); - // TODO: invoke method to get public key let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key( cert.tbs_certificate.subject_public_key_info.subject_public_key ).map_err(|_| TlsError::ParsingError)?; @@ -165,9 +164,6 @@ pub fn validate_root_certificate(cert: &Certificate) -> Result { ); Ok(verify_result.is_ok()) } - _ => { - todo!() - } } } diff --git a/src/key.rs b/src/key.rs index f3fe58a..0d12afe 100644 --- a/src/key.rs +++ b/src/key.rs @@ -1,8 +1,8 @@ use hkdf::Hkdf; -use sha2::{ Digest, Sha256, Sha384, Sha512 }; +use sha2::Digest; use sha2::digest::{BlockInput, FixedOutput, Reset, Update}; use generic_array::{ GenericArray, ArrayLength }; -use heapless::{ String, Vec, consts::* }; +use heapless::{ String, consts::* }; use crate::buffer::TlsBuffer; diff --git a/src/lib.rs b/src/lib.rs index 6a5e2c3..4df4e5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,8 +11,6 @@ pub mod session; pub mod certificate; pub mod fake_rng; -use nom::error::ParseError; - // TODO: Implement errors // Details: Encapsulate smoltcp & nom errors #[derive(Debug, Clone)] diff --git a/src/parse.rs b/src/parse.rs index 3b8be87..41ae525 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -6,12 +6,9 @@ use nom::combinator::complete; use nom::combinator::opt; use nom::sequence::preceded; use nom::sequence::tuple; -use nom::error::make_error; use nom::error::ErrorKind; -use smoltcp::Error; -use smoltcp::Result; -use byteorder::{ByteOrder, NetworkEndian, BigEndian}; +use byteorder::{ByteOrder, NetworkEndian}; use crate::tls_packet::*; @@ -83,7 +80,7 @@ pub(crate) fn parse_inner_plaintext_for_handshake(bytes: &[u8]) -> IResult<&[u8] let mut remaining_bytes = bytes; let mut handshake_vec: Vec = Vec::new(); - while true { + loop { // Perform check on the number of remaining bytes // Case 1: At most 4 bytes left, then that must be the content type of the TLS record // Assert that it is indeed handshake (0x16) @@ -115,8 +112,6 @@ pub(crate) fn parse_inner_plaintext_for_handshake(bytes: &[u8]) -> IResult<&[u8] remaining_bytes = rem; handshake_vec.push(handshake_repr); } - - unreachable!() } // Input: The entire inner plaintext including TLS record @@ -281,7 +276,7 @@ fn parse_server_hello(bytes: &[u8]) -> IResult<&[u8], HandshakeData> { // } TLSInnerPlaintext; fn parse_encrypted_extensions(bytes: &[u8]) -> IResult<&[u8], EncryptedExtensions> { - let (mut rest, extension_length) = take(2_usize)(bytes)?; + let (rest, extension_length) = take(2_usize)(bytes)?; let extension_length: u16 = NetworkEndian::read_u16(extension_length); let mut extension_length_counter: i32 = extension_length.into(); let mut extension_vec: Vec = Vec::new(); diff --git a/src/session.rs b/src/session.rs index d749bf3..f6fb826 100644 --- a/src/session.rs +++ b/src/session.rs @@ -7,15 +7,10 @@ use chacha20poly1305::ChaCha20Poly1305; use ccm::Ccm; use hkdf::Hkdf; use generic_array::GenericArray; -use byteorder::{ByteOrder, NetworkEndian, BigEndian}; +use byteorder::{ByteOrder, NetworkEndian}; use rsa::{RSAPublicKey, PublicKey, PaddingScheme, Hash as RSAHash}; use hmac::{ Hmac, Mac, NewMac }; -use rand_core::RngCore; - -use core::convert::AsRef; -use core::cell::RefCell; - use crate::tls::TlsState; use crate::tls_packet::CipherSuite; use crate::key::*; @@ -505,12 +500,15 @@ impl Session { // Handle Ed25519 and p256 separately // These 2 algorithms have a mandated hash function - if signature_algorithm == SignatureScheme::ecdsa_secp256r1_sha256 || - signature_algorithm == SignatureScheme::ed25519 + if signature_algorithm == SignatureScheme::ecdsa_secp256r1_sha256 { todo!() } + if signature_algorithm == SignatureScheme::ed25519 { + todo!() + } + // Get verification hash, and verify the signature use crate::tls_packet::SignatureScheme::*; diff --git a/src/tls.rs b/src/tls.rs index 2867001..89f02e7 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -1,12 +1,8 @@ use smoltcp::socket::TcpSocket; use smoltcp::socket::TcpState; -use smoltcp::socket::Socket; -use smoltcp::socket::AnySocket; -use smoltcp::socket::SocketRef; use smoltcp::socket::SocketHandle; use smoltcp::socket::SocketSet; use smoltcp::socket::TcpSocketBuffer; -use smoltcp::wire::Ipv4Address; use smoltcp::wire::IpEndpoint; use smoltcp::Result; use smoltcp::Error; @@ -14,35 +10,26 @@ use smoltcp::iface::EthernetInterface; use smoltcp::time::Instant; use smoltcp::phy::Device; -use byteorder::{ByteOrder, NetworkEndian, BigEndian}; +use byteorder::{ByteOrder, NetworkEndian}; use generic_array::GenericArray; -use core::convert::TryInto; use core::convert::TryFrom; use core::cell::RefCell; use rand_core::{RngCore, CryptoRng}; -use p256::{EncodedPoint, AffinePoint, ecdh::EphemeralSecret, ecdh::SharedSecret}; -use aes_gcm::{Aes128Gcm, Aes256Gcm}; -use chacha20poly1305::{ChaCha20Poly1305, Key}; -use ccm::{Ccm, consts::*}; -use aes_gcm::aes::Aes128; -use aes_gcm::{AeadInPlace, NewAead}; -use sha2::{Sha256, Sha384, Sha512, Digest}; +use p256::{EncodedPoint, ecdh::EphemeralSecret}; +use ccm::consts::*; +use aes_gcm::AeadInPlace; use nom::bytes::complete::take; -use nom::IResult; -use nom::error::make_error; use nom::error::ErrorKind; -use alloc::vec::{ self, Vec }; +use alloc::vec::Vec; use heapless::Vec as HeaplessVec; -use crate::Error as TlsError; use crate::tls_packet::*; use crate::parse::{ parse_tls_repr, - parse_handshake, parse_inner_plaintext_for_handshake, get_content_type_inner_plaintext }; @@ -188,7 +175,7 @@ impl TlsSocket { // Send client Finished to end handshake TlsState::SERVER_CONNECTED => { - let mut inner_plaintext: HeaplessVec = { + let inner_plaintext: HeaplessVec = { let verify_data = self.session.borrow() .get_client_finished_verify_data(); let mut handshake_header: [u8; 4] = [20, 0, 0, 0]; @@ -214,13 +201,14 @@ impl TlsSocket { iface.poll(sockets, now); // Read for TLS packet + // Proposition: Decouple all data from TLS record layer before processing let mut array: [u8; 2048] = [0; 2048]; let mut tls_repr_vec = self.recv_tls_repr(sockets, &mut array)?; // Take the TLS representation out of the vector, // Process as a queue 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); self.process(repr)?; } @@ -398,7 +386,7 @@ impl TlsSocket { } let parse_result = parse_inner_plaintext_for_handshake(&payload); - let (_, (mut handshake_slice, mut handshake_vec)) = + let (_, (handshake_slice, mut handshake_vec)) = parse_result.map_err(|_| Error::Unrecognized)?; // Verify that it is indeed an EE @@ -414,7 +402,7 @@ impl TlsSocket { // Extension processing is therefore skipped // Update hash of the session, get EE by taking appropriate length of data // Length of handshake header is 4 - let (handshake_slice, ee_slice) = + let (_handshake_slice, ee_slice) = take::<_, _, (&[u8], ErrorKind)>( might_be_ee.length + 4 )(handshake_slice) @@ -483,7 +471,7 @@ impl TlsSocket { // Update session TLS state to WAIT_CV // Length of handshake header is 4 - let (handshake_slice, cert_slice) = + let (_handshake_slice, cert_slice) = take::<_, _, (&[u8], ErrorKind)>( might_be_cert.length + 4 )(handshake_slice) @@ -536,7 +524,7 @@ impl TlsSocket { // Take out the portion for CertificateVerify // Length of handshake header is 4 - let (handshake_slice, cert_verify_slice) = + let (_handshake_slice, cert_verify_slice) = take::<_, _, (&[u8], ErrorKind)>( might_be_cert_verify.length + 4 )(handshake_slice) @@ -714,7 +702,7 @@ impl TlsSocket { fn recv_tls_repr<'a>(&'a self, sockets: &mut SocketSet, byte_array: &'a mut [u8]) -> Result> { let mut tcp_socket = sockets.get::(self.tcp_handle); if !tcp_socket.can_recv() { - return Ok((Vec::new())); + return Ok(Vec::new()); } let array_size = tcp_socket.recv_slice(byte_array)?; let mut vec: Vec = Vec::new(); diff --git a/src/tls_packet.rs b/src/tls_packet.rs index 0b9d7c1..5ec2190 100644 --- a/src/tls_packet.rs +++ b/src/tls_packet.rs @@ -1,11 +1,7 @@ -use byteorder::{ByteOrder, NetworkEndian, BigEndian}; use num_enum::IntoPrimitive; use num_enum::TryFromPrimitive; -use rand_core::RngCore; -use rand_core::CryptoRng; - -use p256::{EncodedPoint, AffinePoint, ecdh::{EphemeralSecret, SharedSecret}}; +use p256::{EncodedPoint, ecdh::EphemeralSecret}; use core::convert::TryFrom; use core::convert::TryInto; @@ -242,7 +238,6 @@ pub(crate) enum HandshakeData<'a> { EncryptedExtensions(EncryptedExtensions), Certificate(Certificate<'a>), CertificateVerify(CertificateVerify<'a>), - FinishedNeedParse, Finished(Finished<'a>), } @@ -250,7 +245,7 @@ impl<'a> HandshakeData<'a> { pub(crate) fn get_length(&self) -> usize { match self { HandshakeData::ClientHello(data) => data.get_length(), - HandshakeData::ServerHello(data) => todo!(), + HandshakeData::ServerHello(_data) => todo!(), _ => 0, } } @@ -288,7 +283,7 @@ impl<'a> ClientHello<'a> { let mut versions = Vec::new(); versions.push(TlsVersion::Tls13); - let mut content = SupportedVersions::ClientHello { + let content = SupportedVersions::ClientHello { length, versions, }; @@ -308,7 +303,7 @@ impl<'a> ClientHello<'a> { pub(crate) fn add_sh_supported_versions(mut self) -> Self { let selected_version = TlsVersion::Tls13; - let mut content = SupportedVersions::ServerHello { + let content = SupportedVersions::ServerHello { selected_version }; @@ -570,6 +565,7 @@ pub(crate) struct Cookie { cookie: Vec, } +#[allow(non_camel_case_types)] #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)] #[repr(u16)] pub(crate) enum SignatureScheme { @@ -610,6 +606,7 @@ impl SignatureSchemeList { } } +#[allow(non_camel_case_types)] #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)] #[repr(u16)] pub(crate) enum NamedGroup { @@ -680,6 +677,7 @@ impl KeyShareEntryContent { } } +#[allow(non_camel_case_types)] #[derive(Debug, Clone)] #[repr(u16)] pub(crate) enum NameType {