diff --git a/src/buffer.rs b/src/buffer.rs index 87b4b7e..e168f8c 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -180,12 +180,6 @@ impl<'a> TlsBuffer<'a> { } }, KeyShareEntry(k) => { - 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()) - }; - use crate::tls_packet::KeyShareEntryContent::*; match k { KeyShareClientHello { length, client_shares } => { @@ -256,8 +250,8 @@ macro_rules! export_byte_order_fn { export_byte_order_fn!( write_u16, read_u16, u16, 2, - write_u24, read_u24, u32, 3, - write_u32, read_u32, u32, 4, - write_u48, read_u48, u64, 6, - write_u64, read_u64, u64, 8 + write_u24, read_u24, u32, 3 + // write_u32, read_u32, u32, 4, + // write_u48, read_u48, u64, 6, + // write_u64, read_u64, u64, 8 ); diff --git a/src/certificate.rs b/src/certificate.rs index 3d20e75..f2141b3 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -29,7 +29,7 @@ use byteorder::{ByteOrder, NetworkEndian}; use core::convert::TryFrom; use core::convert::TryInto; -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct Certificate<'a> { pub tbs_certificate: TBSCertificate<'a>, pub signature_algorithm: AlgorithmIdentifier<'a>, @@ -37,6 +37,16 @@ pub struct Certificate<'a> { pub tbs_certificate_encoded: &'a [u8], } +impl<'a> core::fmt::Debug for Certificate<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Certificate") + .field("tbs_certificate", &self.tbs_certificate) + .field("signature_algorithm", &self.signature_algorithm) + .field("signature_value", &self.signature_value) + .finish() + } +} + #[derive(Debug, Clone)] pub struct TBSCertificate<'a> { pub version: Version, @@ -540,27 +550,25 @@ pub struct AttributeTypeAndValue<'a> { impl<'a> Certificate<'a> { // General return public key method - pub(crate) fn get_cert_public_key(&self) -> Result { + pub fn get_cert_public_key(&self) -> Result { let public_key_info = &self.tbs_certificate.subject_public_key_info; let algorithm_identifier = &public_key_info.algorithm; + log::info!("sig alg ident: {:?}", algorithm_identifier); // 3 possibilities: RSA_ENCRYPTION, ID_EC_PUBLIC_KEY, and EdDSA25519 match algorithm_identifier.algorithm { - RSA_ENCRYPTION => { - log::info!("Chose rsa encryption"); - log::info!("Entire key: {:X?}", self.tbs_certificate.subject_public_key_info.subject_public_key); + RSA_ENCRYPTION | ID_RSASSA_PSS => { let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key( self.tbs_certificate.subject_public_key_info.subject_public_key ).map_err(|_| ())?; - log::info!("Modulus: {:X?}\n, Exponent: {:X?}", modulus, exponent); - log::info!("Big int modulus: {:?}", BigUint::from_bytes_be(modulus)); + log::info!("Mod: {:?}, exp: {:?}", modulus, exponent); let public_key = RSAPublicKey::new( BigUint::from_bytes_be(modulus), BigUint::from_bytes_be(exponent) ).map_err(|_| ())?; - log::info!("Got rsa key parts"); + Ok( CertificatePublicKey::RSA { cert_rsa_public_key: public_key @@ -576,8 +584,6 @@ impl<'a> Certificate<'a> { if ec_oid != PRIME256V1 { return Err(()); } - log::info!("Acceptable OID"); - log::info!("Public key into slice: {:X?}", &public_key_info.subject_public_key[1..]); let p256_verify_key = p256::ecdsa::VerifyKey::from_encoded_point( &p256::EncodedPoint::from_untagged_bytes( GenericArray::from_slice( @@ -585,7 +591,6 @@ impl<'a> Certificate<'a> { ) ) ).map_err(|_| ())?; - log::info!("Have verify key"); Ok( CertificatePublicKey::ECDSA_SECP256R1_SHA256 { cert_verify_key: p256_verify_key @@ -611,6 +616,7 @@ impl<'a> Certificate<'a> { pub fn validate_self_signed_signature(&self) -> Result<(), TlsError> { let cert_public_key = self.get_cert_public_key() .map_err(|_| TlsError::SignatureValidationError)?; + log::info!("Own public key: {:?}", cert_public_key); self.validate_signature_with_trusted(&cert_public_key) } @@ -624,6 +630,7 @@ impl<'a> Certificate<'a> { let sig_alg = self.signature_algorithm.algorithm; // Prepare hash value + log::info!("sig alg: {:?}", sig_alg); match sig_alg { SHA1_WITH_RSA_ENCRYPTION => { let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1)); @@ -679,6 +686,7 @@ impl<'a> Certificate<'a> { let (_, (hash_alg, salt_len)) = parse_rsa_ssa_pss_parameters( self.signature_algorithm.parameters ).unwrap(); + log::info!("Hash alg, salt_len: {:X?}, {:X?}", hash_alg, salt_len); match hash_alg { ID_SHA1 => { let padding = PaddingScheme::new_pss_with_salt::( @@ -707,12 +715,15 @@ impl<'a> Certificate<'a> { }, ID_SHA256 => { + log::info!("Selected SHA256 with salt length: {:?}", salt_len); let padding = PaddingScheme::new_pss_with_salt::( FakeRandom {}, salt_len ); let hashed = Sha256::digest(self.tbs_certificate_encoded); let sig = self.signature_value; + log::info!("signature: {:X?}", sig); + log::info!("Trusted key: {:?}", trusted_public_key); trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) @@ -752,8 +763,8 @@ impl<'a> Certificate<'a> { // ECDSA signature algorithm (support only `edcsa_secp256r1_sha256`) ECDSA_WITH_SHA256 => { - let (_, (r, s)) = parse_ecdsa_signature(self.signature_value) - .map_err(|_| TlsError::SignatureValidationError)?; + // let (_, (r, s)) = parse_ecdsa_signature(self.signature_value) + // .map_err(|_| TlsError::SignatureValidationError)?; let sig = p256::ecdsa::Signature::from_asn1(self.signature_value) .map_err(|_| TlsError::SignatureValidationError)?; trusted_public_key.get_ecdsa_secp256r1_sha256_verify_key() @@ -779,6 +790,7 @@ impl<'a> Certificate<'a> { } } +#[derive(Debug, Clone)] pub struct ValidPolicyNode<'a> { valid_policy: &'a [u8], qualifier_set: &'a [u8], @@ -838,17 +850,21 @@ pub fn verify_certificate_chain( let mut max_path_length = certificates.len(); for cert_index in 0..certificates.len() { + log::trace!("Processing certificate {:?}", cert_index); let current_certificate = &certificates[cert_index]; current_certificate .validate_signature_with_trusted(&working_public_key) .map_err(|_| TlsError::SignatureValidationError)?; + log::trace!("Certificate signature verified"); current_certificate.tbs_certificate.validity .is_valid(¤t_time)?; + log::trace!("Certificate time is within limit"); // Certificate Revocation List is not implemented // This is a certificate-in-certificate scenario if current_certificate.tbs_certificate.issuer != working_issuer_name { return Err(TlsError::CertificateIssuerMismatch); } + log::trace!("Certificate name is verified"); // (b, c) If certificate is self-issued and not the end-entity certificate, // verify that subject name is @@ -859,7 +875,7 @@ pub fn verify_certificate_chain( // - within one of the permitted_subtrees for that type // - not within any of the excluded_subtrees for that name type if current_certificate.tbs_certificate.issuer != current_certificate.tbs_certificate.subject - && (cert_index + 1) != certificates.len() { + || (cert_index + 1) == certificates.len() { /* * Permitted subtreee block @@ -945,6 +961,8 @@ pub fn verify_certificate_chain( } } + log::trace!("Subject name and SAN prmitted"); + /* * Excluded subtrees block */ @@ -986,6 +1004,8 @@ pub fn verify_certificate_chain( } } } + + log::trace!("Subject name and SAN not excluded"); } // Certificate policy, find a new set of leaves if exist @@ -1027,7 +1047,7 @@ pub fn verify_certificate_chain( policy_not_matched = false; } - if policy_parent.valid_policy == crate::oid::ANY_POLICY { + if policy_parent.valid_policy == ANY_POLICY { any_policy_found = true; } } @@ -1038,7 +1058,7 @@ pub fn verify_certificate_chain( // There is no need to add more than once // Only `horizontal` leaf search will be performed, // will only duplicate branch - if !policy_not_matched && any_policy_found { + if policy_not_matched && any_policy_found { let mut new_node = ValidPolicyNode { valid_policy: policy.id, qualifier_set: policy.qualifier, @@ -1056,6 +1076,7 @@ pub fn verify_certificate_chain( && inhibit_any_policy > 0 && cert_index + 1 < certificates.len() { + log::trace!("Can add any policy to policy tree"); for policy_parent in valid_policy_tree.iter() { for expected_policy in policy_parent.expected_policy_set.iter() { // If any expected policy cannot be found among the new leaves @@ -1083,6 +1104,7 @@ pub fn verify_certificate_chain( // (d) prune childless branches, and // (e) set the entire tree to NULL, if there are no cert policies. valid_policy_tree = new_valid_policy_leaves; + log::trace!("Policy tree: {:?}", valid_policy_tree); // (f) Verify that either: // -`explicit_policy` is greater than 0, OR @@ -1435,22 +1457,22 @@ fn get_subtree_intersection<'a>( // Should both names be homogeneous, it should imply an all-blocking name else { match (self_name, other_name) { - (GeneralName::URI(self_uri), GeneralName::URI(other_uri)) => { + (GeneralName::URI(..), GeneralName::URI(..)) => { preserved_subtrees.push( GeneralName::URI(&[]) ) }, - (GeneralName::RFC822Name(self_mail), GeneralName::RFC822Name(other_mail)) => { + (GeneralName::RFC822Name(..), GeneralName::RFC822Name(..)) => { preserved_subtrees.push( GeneralName::RFC822Name(&[]) ) }, - (GeneralName::DNSName(self_dns), GeneralName::DNSName(other_dns)) => { + (GeneralName::DNSName(..), GeneralName::DNSName(..)) => { preserved_subtrees.push( GeneralName::DNSName(&[]) ) }, - (GeneralName::IPAddress(self_ip), GeneralName::IPAddress(other_ip)) => { + (GeneralName::IPAddress(..), GeneralName::IPAddress(..)) => { preserved_subtrees.push( GeneralName::IPAddress(&[]) ) diff --git a/src/fake_rng.rs b/src/fake_rng.rs index e28af21..c658d44 100644 --- a/src/fake_rng.rs +++ b/src/fake_rng.rs @@ -17,9 +17,9 @@ impl RngCore for FakeRandom { 0 } - fn fill_bytes(&mut self, dest: &mut [u8]) {} + fn fill_bytes(&mut self, _dest: &mut [u8]) {} - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), Error> { Ok(()) } } diff --git a/src/key.rs b/src/key.rs index 0d12afe..3cc10ce 100644 --- a/src/key.rs +++ b/src/key.rs @@ -36,7 +36,7 @@ where // suffix: at most 12 chars as per RFC8446, section 7.1 let mut label_string: String = String::new(); label_string.push_str("tls13 ").unwrap(); - label_string.push_str(label); + label_string.push_str(label).unwrap(); let length = u16::try_from(Hash::output_size()).unwrap(); let label_length = u8::try_from(label_string.len()).unwrap(); @@ -55,7 +55,7 @@ where // context_vec: 48 bytes for SHA384 + 1 byte (len) let mut array = [0; 100]; let mut buffer = TlsBuffer::new(&mut array); - buffer.enqueue_hkdf_label(hkdf_label); + buffer.enqueue_hkdf_label(hkdf_label).unwrap(); let info: &[u8] = buffer.into(); // Define output key material (OKM), dynamically sized by hash @@ -81,7 +81,7 @@ where // suffix: at most 12 chars as per RFC8446, section 7.1 let mut label_string: String = String::new(); label_string.push_str("tls13 ").unwrap(); - label_string.push_str(label); + label_string.push_str(label).unwrap(); let label_length = u8::try_from(label_string.len()).unwrap(); let context_slice = context.as_bytes(); diff --git a/src/main.rs b/src/main.rs index f79cd2d..4de9aa9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,11 +16,13 @@ use aes_gcm::aes::Aes128; use aes_gcm::{AeadInPlace, NewAead}; use generic_array::GenericArray; use sha2::{ Digest, Sha256, Sha384, Sha512 }; -use heapless::Vec; +use std::vec::Vec; use hkdf::Hkdf; use rand::rngs::OsRng; +use chrono::prelude::*; + use smoltcp_tls::key::*; use smoltcp_tls::buffer::TlsBuffer; use smoltcp_tls::certificate::*; @@ -78,34 +80,126 @@ fn main() { // tls_socket.tls_connect(&mut sockets).unwrap(); simple_logger::SimpleLogger::new().init().unwrap(); - let (_, certificate) = parse_asn1_der_certificate(&SELF_SIGNED_WITH_SAN).unwrap(); + let (_, certificate) = parse_asn1_der_certificate(&RSA_PSS_SELF_CERT).unwrap(); println!("Certificate print: {:?}", certificate); - let modulus = [ - 0x00, 0xe1, 0x64, 0x42, 0x1f, 0x32, 0x2c, 0xa2, 0x81, 0x3a, 0x6f, 0x9d, 0x4e, 0x6d, 0xa7, 0xc9, 0xed, 0xb9, 0x47, 0x3e, 0xd8, 0x98, 0xe6, 0xba, 0xab, 0x07, 0x93, 0xb3, 0xc5, 0x80, 0x62, 0x7e, 0xb7, 0xe3, 0x9a, 0xfb, 0x9c, 0xf4, 0x0c, 0xc7, 0x49, 0x08, 0x73, 0x45, 0xe8, 0x94, 0xff, 0xb1, 0xe7, 0x52, 0xb6, 0x77, 0xa7, 0x53, 0x49, 0x0b, 0xf3, 0xe6, 0x13, 0x4a, 0x79, 0xd7, 0xef, 0x53, 0x7c, 0x8d, 0x84, 0x5b, 0xf3, 0x30, 0x6d, 0x4d, 0x43, 0x14, 0xa0, 0xc9, 0x8b, 0x86, 0x17, 0x16, 0x8a, 0x09, 0x60, 0xa9, 0xdb, 0x76, 0x8f, 0x5c, 0x58, 0x92, 0xf3, 0x63, 0xdb, 0x39, 0x82, 0xa7, 0x4a, 0x79, 0x08, 0x29, 0x1d, 0x94, 0x3c, 0xec, 0x11, 0x46, 0x70, 0xf8, 0xd1, 0xe4, 0xc2, 0x6f, 0x9d, 0x40, 0x8d, 0x8a, 0x29, 0x2e, 0x2b, 0x82, 0xd6, 0x1b, 0x0f, 0xbd, 0x49, 0xe4, 0xc9, 0xfb, 0xc3, 0x81, 0x29, 0x7f, 0x99, 0x07, 0x99, 0x5a, 0x28, 0x46, 0xf7, 0xdd, 0xca, 0xb2, 0x4c, 0xce, 0x21, 0x01, 0x24, 0xfc, 0xfe, 0x8f, 0xea, 0x73, 0x36, 0x39, 0xdf, 0xa0, 0x6c, 0x43, 0xf5, 0x3c, 0x74, 0xb3, 0x17, 0x00, 0xfd, 0xb4, 0xa2, 0x82, 0x1e, 0xed, 0xdf, 0x22, 0x2a, 0x35, 0x6d, 0xf7, 0x8a, 0x4d, 0xc8, 0x19, 0xb9, 0xd3, 0x88, 0x29, 0x10, 0x8e, 0xae, 0x30, 0xf2, 0x23, 0xce, 0x3b, 0xce, 0xe0, 0x7c, 0x5e, 0x52, 0xa1, 0x1f, 0xc1, 0x59, 0xcc, 0x14, 0xf6, 0x6f, 0xf1, 0xa6, 0xbb, 0xfd, 0x9b, 0x66, 0x96, 0x89, 0xbb, 0xd4, 0x0b, 0x9e, 0x5f, 0xac, 0xf0, 0x1d, 0x88, 0xa6, 0x27, 0x53, 0x48, 0xf2, 0x12, 0x54, 0x43, 0xf8, 0x92, 0x42, 0xcd, 0x6e, 0x00, 0x54, 0x67, 0x55, 0x6f, 0xfa, 0x38, 0x30, 0x7b, 0xea, 0xaa, 0x85, 0x9b, 0x31, 0xbf, 0x78, 0xb8, 0x2a, 0x97, 0x77, 0xd0, 0x23 - ]; + // let modulus = [ + // 0x00, 0xe1, 0x64, 0x42, 0x1f, 0x32, 0x2c, 0xa2, 0x81, 0x3a, 0x6f, 0x9d, 0x4e, 0x6d, 0xa7, 0xc9, 0xed, 0xb9, 0x47, 0x3e, 0xd8, 0x98, 0xe6, 0xba, 0xab, 0x07, 0x93, 0xb3, 0xc5, 0x80, 0x62, 0x7e, 0xb7, 0xe3, 0x9a, 0xfb, 0x9c, 0xf4, 0x0c, 0xc7, 0x49, 0x08, 0x73, 0x45, 0xe8, 0x94, 0xff, 0xb1, 0xe7, 0x52, 0xb6, 0x77, 0xa7, 0x53, 0x49, 0x0b, 0xf3, 0xe6, 0x13, 0x4a, 0x79, 0xd7, 0xef, 0x53, 0x7c, 0x8d, 0x84, 0x5b, 0xf3, 0x30, 0x6d, 0x4d, 0x43, 0x14, 0xa0, 0xc9, 0x8b, 0x86, 0x17, 0x16, 0x8a, 0x09, 0x60, 0xa9, 0xdb, 0x76, 0x8f, 0x5c, 0x58, 0x92, 0xf3, 0x63, 0xdb, 0x39, 0x82, 0xa7, 0x4a, 0x79, 0x08, 0x29, 0x1d, 0x94, 0x3c, 0xec, 0x11, 0x46, 0x70, 0xf8, 0xd1, 0xe4, 0xc2, 0x6f, 0x9d, 0x40, 0x8d, 0x8a, 0x29, 0x2e, 0x2b, 0x82, 0xd6, 0x1b, 0x0f, 0xbd, 0x49, 0xe4, 0xc9, 0xfb, 0xc3, 0x81, 0x29, 0x7f, 0x99, 0x07, 0x99, 0x5a, 0x28, 0x46, 0xf7, 0xdd, 0xca, 0xb2, 0x4c, 0xce, 0x21, 0x01, 0x24, 0xfc, 0xfe, 0x8f, 0xea, 0x73, 0x36, 0x39, 0xdf, 0xa0, 0x6c, 0x43, 0xf5, 0x3c, 0x74, 0xb3, 0x17, 0x00, 0xfd, 0xb4, 0xa2, 0x82, 0x1e, 0xed, 0xdf, 0x22, 0x2a, 0x35, 0x6d, 0xf7, 0x8a, 0x4d, 0xc8, 0x19, 0xb9, 0xd3, 0x88, 0x29, 0x10, 0x8e, 0xae, 0x30, 0xf2, 0x23, 0xce, 0x3b, 0xce, 0xe0, 0x7c, 0x5e, 0x52, 0xa1, 0x1f, 0xc1, 0x59, 0xcc, 0x14, 0xf6, 0x6f, 0xf1, 0xa6, 0xbb, 0xfd, 0x9b, 0x66, 0x96, 0x89, 0xbb, 0xd4, 0x0b, 0x9e, 0x5f, 0xac, 0xf0, 0x1d, 0x88, 0xa6, 0x27, 0x53, 0x48, 0xf2, 0x12, 0x54, 0x43, 0xf8, 0x92, 0x42, 0xcd, 0x6e, 0x00, 0x54, 0x67, 0x55, 0x6f, 0xfa, 0x38, 0x30, 0x7b, 0xea, 0xaa, 0x85, 0x9b, 0x31, 0xbf, 0x78, 0xb8, 0x2a, 0x97, 0x77, 0xd0, 0x23 + // ]; - let exponent = [1, 0, 1]; + // let exponent = [1, 0, 1]; - let rsa_public_key = rsa::RSAPublicKey::new( - rsa::BigUint::from_bytes_be(&modulus), - rsa::BigUint::from_bytes_be(&exponent) - ).unwrap(); - - let ca_public_key = smoltcp_tls::session::CertificatePublicKey::RSA { - cert_rsa_public_key: rsa_public_key - }; + // let rsa_public_key = rsa::RSAPublicKey::new( + // rsa::BigUint::from_bytes_be(&modulus), + // rsa::BigUint::from_bytes_be(&exponent) + // ).unwrap(); + // let ca_public_key = smoltcp_tls::session::CertificatePublicKey::RSA { + // cert_rsa_public_key: rsa_public_key + // }; // certificate.validate_signature_with_trusted(&ca_public_key).unwrap(); // println!("Certificate should be trusted"); certificate.validate_self_signed_signature().unwrap(); + println!("Certificate should be trusted"); +/* + + + let mut certificate_vec = Vec::new(); + let name = parse_asn1_der_name(&SELF_SIGNED_WITH_SAN_ISSUER).unwrap().1; + let public_key = certificate.get_cert_public_key().unwrap(); + let mut permitted_name: Vec = Vec::new(); + let mut excluded_name: Vec = Vec::new(); + + // let mut stricter_name = name.clone(); + // let att = AttributeTypeAndValue { + // attribute_type: &[1, 2, 3, 4, 5], + // attribute_value: "additional value" + // }; + // let mut rdn = RelativeDistinguishedName { + // type_and_attributes: Vec::new() + // }; + // rdn.type_and_attributes.push(att); + // stricter_name.relative_distinguished_name.push(rdn); + // log::info!("Stricter name: {:?}", stricter_name); + // let directory_general_name = GeneralName::DirectoryName(stricter_name.clone()); + + // let mut broader_name = name.clone(); + // broader_name.relative_distinguished_name.remove(0); + // log::info!("Broader name: {:?}", broader_name); + // let directory_general_name = GeneralName::DirectoryName(broader_name.clone()); + + let mut empty_name = Name { + relative_distinguished_name: Vec::new() + }; + log::info!("Empty name: {:?}", empty_name); + let directory_general_name = GeneralName::DirectoryName(empty_name.clone()); + + permitted_name.push(directory_general_name.clone()); + // excluded_name.push(directory_general_name); + + certificate_vec.push(certificate); + + verify_certificate_chain( + certificate_vec, + DateTime::::from(Utc::now()), + name, + public_key, + false, + false, + false, + permitted_name, + excluded_name + ).unwrap(); +*/ + let google_end_entity_certificate = parse_asn1_der_certificate( + &GOOGLE_END_ENTITY_CERT + ).unwrap().1; + + let google_root_ca_certificate = parse_asn1_der_certificate( + &GOOGLE_ROOT_CERT + ).unwrap().1; + + google_end_entity_certificate.validate_signature_with_trusted( + &google_root_ca_certificate.get_cert_public_key().unwrap() + ).unwrap(); + log::info!("End entity certificate verified"); + + // google_root_ca_certificate.validate_self_signed_signature().unwrap(); + // log::info!("root certificate verified"); + +// let mut certificate_vec: Vec = Vec::new(); +// certificate_vec.push(google_root_ca_certificate); +// certificate_vec.push(google_end_entity_certificate); + +// let mut certificate_vec = Vec::new(); +// let name = google_root_ca_certificate.tbs_certificate.issuer; +// let public_key = google_root_ca_certificate.get_cert_public_key().unwrap(); +// let mut permitted_name: Vec = Vec::new(); +// let mut excluded_name: Vec = Vec::new(); + +// verify_certificate_chain( +// certificate_vec, +// DateTime::::from(Utc::now()), +// name, +// public_key, +// false, +// false, +// false, +// permitted_name, +// excluded_name +// ).unwrap(); } const RSA_PSS_CERT: [u8; 0x3AB] = hex_literal::hex!("308203a73082028fa00302010202146642be8f709457f9cd6eed72051c240a5565138c300d06092a864886f70d01010a30003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e6574301e170d3230313130343039313535325a170d3231313130343039313535325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e657430820122300d06092a864886f70d01010105000382010f003082010a0282010100b5a347b654ca0bad8d56990e70aa7411b78dedc9fd9a6760ee936ea01486238538dbc4d0bc95a1a5f060b6296ba67001f103cfd918ad1ec33a1a680d4e8283a24300391e9a53cd6641fc51f0a984c3cd16542b934a0ec8c3447782542628320d6c24988cf0b7b19bbaba91f1999968def724d8e65b624fbb9826208aece1ee90badda7c6b8a97fc4085299f9d32661a06bc67d2d662e0efcee1df5b6dc1d02e56929d8976441456d0fe50314c9861e9845f75f5dc2ca9828089b5d4bd109d1e8ada8986c5bd68ee004a7bfcb932768023e11fe8e299b25b8774ed8bdbb0f644ddaa83df1ff4e84bfc18d3b815decb5ca4f1db1125df98dba94e4ef5570ec5a510203010001a3533051301d0603551d0e04160414050928eff30f3094f01ddb09f1d7a9193addf854301f0603551d23041830168014050928eff30f3094f01ddb09f1d7a9193addf854300f0603551d130101ff040530030101ff300d06092a864886f70d01010a300003820101002d14281587dc33d4559e77852d17fade1a9f3f0e5af847bde80c921be360d6e3b598dfb50aad706de3832841798b66736b9296a83c06e0078dceabc39760a5bf5eb7a7287859b22e9beb7ebb928b99034d155fd12307ee541ea53979bb8afb62db233dfcf1e16afea5eac33817b8cbb13841cb89e9b65a5a4b08a6c6e3d1e0036bc9576b90cf62437e3ef985f02b88be4e6863068c9bc45dd473763f4cdcfc3bfb8a90d7b3225b67a3a39c6ac446de55596dc135221b4383773ddd9efdcca48f389af9c1c0547e0ada1c14153fc38e02c95e4c37da45af1e6d3b0a6cafb603d95a1c887384b476caf60783835a150ee7fd22b6838ce19adcb2e59572c6349703"); +const RSA_PSS_SELF_CERT: [u8; 0x405] = + hex_literal::hex!( + "30820401308202b8a0030201020214298b26a4c6033fbde6cae4add099ebad73837d57303e06092a864886f70d01010a3031a00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a204020200de3060310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643119301706035504030c106e6f775f776974685f7368615f323536301e170d3230313131363039343634395a170d3230313231363039343634395a3060310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643119301706035504030c106e6f775f776974685f7368615f32353630820120300b06092a864886f70d01010a0382010f003082010a0282010100c9f77901168ee11c6f3a62143a7d6c693012e34e76910c64292ea38049e5f60b7aa9aa3d17cf28d91e2449864a42b45db2283412d714ecb50200723dda269fac3a36841f2627cf4c808676c87dd116a361bbdfcacaa6bd74f27a67e2f8d1532646ecec9ddb5a0a3fb490cf440c1f9381cb764d1fdfe9d7ce1aab606e1f30267771e21af1d6b9c11c39e21c9628789d1812d6d776abe80dcc4f11ce51facafd8dbde0d8beccf10ce1309f160ec49f1e42a2b1c26e8567a8db62af1d267ec84341c0851b121ec158f0ba383b46128b23d4397c5393a3032c50036197da8b7673e38a755ce41744322b0bffb228fe3084f0fa6177741d59613dfad61c8f419f32cb0203010001a3533051301d0603551d0e04160414ee19f554ae1d1cb9d5a316a997412168a23f1408301f0603551d23041830168014ee19f554ae1d1cb9d5a316a997412168a23f1408300f0603551d130101ff040530030101ff303e06092a864886f70d01010a3031a00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a204020200de0382010100bebe84986a245ed68b35acb1b9683bea68d43481f02e2eabe5c2a5091ee16896dbc8a0d3c27602e1136ec81ba3be5fcd2d565001085c399ae166c74fc798ae61201df4a6e5a308b8b0ab4ac3dce5e6668a10843a477ec5c6555cca2dd0520b0151cf942cc3293c31e0242bf6d3a19c33df9a29fab1a151542949e126243f468cb4268200fd61a9b5f0be128adf8616ca284180cbc8c4db09607fd03e1dc687ce2dd843b63cb02133f3c22c1f4c0024ff89352611dda6efba9c7b5ad4fefcb76a3aea75c922f3a1bcc669656b920878339827bbf09bca982f878fe4a72a63316b8fedd8a5654e5f1d876cc6083d64d8ea1c12e182ee200f9766734f212e460d56" + ); + const RSA_PKCS_CERT: [u8; 0x03AB] = hex_literal::hex!("308203a73082028fa00302010202144a5a52142c495ec189e661457ba0330809c9dede300d06092a864886f70d01010b05003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d301e170d3230313130343038353031325a170d3231313130343038353031325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100a665127e115e41937b51f87fa44d9894e52a45479a234110037f8c8ce2de6d263e12e3824d57a39d7386afe35cb926af1d6f593673eae31f1e27b8914895006fc7e5fdac11f369b73741a97663f2bb08edb7ab7c1ccc8be9259ce2c1b9d04ba066e05fd6a440ca99b148ddc95a23432228f5172b32939921f70f4f632691ee19a50d7deffb50cb9f018562c803065ca1f1817f1f93c25b3aa0ef91b2f91ef1c86fd346bc00ac165fbd5abf04d944a58e48fd24959133637a949cb85d498063aa4ed0927327591d125500430fa91782af806d46fe330251103c8139b3bf35034b009748324a0fffac2474eed6f04e8d90582dc6125cce0274305f28e82b5409170203010001a3533051301d0603551d0e04160414a36633b9660897096d8138d4f0281a3b76e6696c301f0603551d23041830168014a36633b9660897096d8138d4f0281a3b76e6696c300f0603551d130101ff040530030101ff300d06092a864886f70d01010b0500038201010090631de179bf4940e636e0e7142d9feb440d818c9ea095b6ae31a4ad9876fbd1c2b6808d2edc60e20b107daaf592d14bb9f1ca37c9d975b0c463478dbac8cb183b90bbaecdb1ad5541674f3ba957f2837e57480c445328f917c8a358fc5465c1f838108f60b59327cd1fba59e1635276372bdb17557b636b59be60b4c6b6cf3ecb9fd40b9469d7bfa4f2053be4c08e2e350453050a076d923923588c7f839c709d31c2296dfd837b850f0ba4b44a36c112b9a6ef7186b090162628367a95fa1673e4362d7a23aebd46a85c69eac76f7194d166c89ce6103c508eb970f35bf0b241cbbae5ddffc5ea6515e5f36a8645dc0c8a48798199f65f01b811bec2f287d5"); @@ -124,3 +218,18 @@ const SELF_SIGNED_WITH_SAN: [u8; 0x048A] = hex_literal::hex!( "308204863082036ea003020102021447e58ecab88d894c58ec746381e6d039c04e3a93300d06092a864886f70d01010b05003073310b3009060355040613025553310b300906035504080c0256413114301206035504070c0b416e6f746865724369747931123010060355040a0c094d79436f6d70616e7931133011060355040b0c0a4d794469766973696f6e3118301606035504030c0f7777772e636f6d70616e792e636f6d301e170d3230313131303032313132385a170d3231313131303032313132385a3073310b3009060355040613025553310b300906035504080c0256413114301206035504070c0b416e6f746865724369747931123010060355040a0c094d79436f6d70616e7931133011060355040b0c0a4d794469766973696f6e3118301606035504030c0f7777772e636f6d70616e792e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100bacdd00cf364e116a6b7cd23df3ccc31f6d6d2e6e82da833d50f7bd850b1e482acd1e9ecc9e0ea2c36925576fff44bdefbbb73f38c8d7db67ac7210801e5580329504ebc6982e5c95a758a36a1d0ff891478ab2f7392c1c6b4657d08645ff97ef23b0870de511d3532599eb250eac82bae22d6de23f2a5a48733d3a045fe0c5f942b5f79dbb08117bf1a814f00489e4118f30f8e37e66c61c5c4398cdc9f77ec39de78bf0b4c677cb9e485b868ce03c32c41f78849b82949df8231290172618234de85ec02990206fec3ed74b6b18e9d0acd6b4bed1c4f52749574f7cd9b8ad0db14be78a99eb8a894adecdbd0922ab953e3e447346022a4485ffd121efdfe1d0203010001a38201103082010c300b0603551d0f04040302043030130603551d25040c300a06082b0601050507030130760603551d11046f306d820f7777772e636f6d70616e792e6e6574820b636f6d70616e792e636f6d820b636f6d70616e792e6e6574810b626f6240636f6d70616e79810d616c69636540636f6d70616e79a01e06032a0304a0170c15736f6d65206f74686572206964656e7469666965728704c0a801c830430603551d1e043c303aa01c300e820c2e6578616d706c652e636f6d300a8708c0a80001ffffff00a11a300a8708c0aa0001ffffff00300c820a2e6c6f63616c686f7374300f0603551d2404083006800103810105301a0603551d200413301130060604551d2000300706052b05071314300d06092a864886f70d01010b050003820101008e6891f7bf506cb9bbc2d8f679d2d510b0b3121ee4662cbe90ddd1b1fa4f8a5b9cca49877fc64b9c08a2dbbb4563e3e92be62ce79088b2a1b382724f1b479efaba1749696461893335f56e9ad7b89359997af85a20425250be0559b2daf1179b61b65284f39da4386377a035038af179b93508925c227d4f205538c1dedfc768a98cd243196a9476ac79bb91c16e827ff84376520e89b09a236037be4f21b0262b151d156638ccfafac7cf383c5f20213cdd29d0f95329a4a2783328986fa2e70b501289c263e0bdc42cb439412b8be2601b6f1fe8c3e15f11230760d36ff008ccb42d8b10c5c92db35ae2a6a8dfcf461233cefbc30fc2d709608452744f1ce7" ); + +const SELF_SIGNED_WITH_SAN_ISSUER: [u8; 0x75] = + hex_literal::hex!( + "3073310b3009060355040613025553310b300906035504080c0256413114301206035504070c0b416e6f746865724369747931123010060355040a0c094d79436f6d70616e7931133011060355040b0c0a4d794469766973696f6e3118301606035504030c0f7777772e636f6d70616e792e636f6d" + ); + +const GOOGLE_ROOT_CERT: [u8; 0x044e] = + hex_literal::hex!( + "3082044a30820332a003020102020d01e3b49aa18d8aa981256950b8300d06092a864886f70d01010b0500304c3120301e060355040b1317476c6f62616c5369676e20526f6f74204341202d20523231133011060355040a130a476c6f62616c5369676e311330110603550403130a476c6f62616c5369676e301e170d3137303631353030303034325a170d3231313231353030303034325a3042310b3009060355040613025553311e301c060355040a1315476f6f676c65205472757374205365727669636573311330110603550403130a47545320434120314f3130820122300d06092a864886f70d01010105000382010f003082010a0282010100d018cf45d48bcdd39ce440ef7eb4dd69211bc9cf3c8e4c75b90f3119843d9e3c29ef500d10936f0580809f2aa0bd124b02e13d9f581624fe309f0b747755931d4bf74de1928210f651ac0cc3b222940f346b981049e70b9d8339dd20c61c2defd1186165e7238320a82312ffd2247fd42fe7446a5b4dd75066b0af9e426305fbe01cc46361af9f6a33ff6297bd48d9d37c1467dc75dc2e69e8f86d7869d0b71005b8f131c23b24fd1a3374f823e0ec6b198a16c6e3cda4cd0bdbb3a4596038883bad1db9c68ca7531bfcbcd9a4abbcdd3c61d7931598ee81bd8fe264472040064ed7ac97e8b9c05912a1492523e4ed70342ca5b4637cf9a33d83d1cd6d24ac070203010001a38201333082012f300e0603551d0f0101ff040403020186301d0603551d250416301406082b0601050507030106082b0601050507030230120603551d130101ff040830060101ff020100301d0603551d0e0416041498d1f86e10ebcf9bec609f18901ba0eb7d09fd2b301f0603551d230418301680149be20757671c1ec06a06de59b49a2ddfdc19862e303506082b0601050507010104293027302506082b060105050730018619687474703a2f2f6f6373702e706b692e676f6f672f6773723230320603551d1f042b30293027a025a0238621687474703a2f2f63726c2e706b692e676f6f672f677372322f677372322e63726c303f0603551d20043830363034060667810c010202302a302806082b06010505070201161c68747470733a2f2f706b692e676f6f672f7265706f7369746f72792f300d06092a864886f70d01010b050003820101001a803e3679fbf32ea946377d5e541635aec74e0899febdd13469265266073d0aba49cb62f4f11a8efc114f68964c742bd367deb2a3aa058d844d4c20650fa596da0d16f86c3bdb6f0423886b3a6cc160bd689f718eee2d583407f0d554e98659fd7b5e0d2194f58cc9a8f8d8f2adcc0f1af39aa7a90427f9a3c9b0ff02786b61bac7352be856fa4fc31c0cedb63cb44beaedcce13cecdc0d8cd63e9bca42588bcc16211740bca2d666efdac4155bcd89aa9b0926e732d20d6e6720025b10b090099c0c1f9eadd83beaa1fc6ce8105c085219512a71bbac7ab5dd15ed2bc9082a2c8ab4a621ab63ffd7524950d089b7adf2affb50ae2fe1950df346ad9d9cf5ca" + ); + +const GOOGLE_END_ENTITY_CERT: [u8; 0x0974] = + hex_literal::hex!( + "3082097030820858a00302010202103c8415c8e1e38e7702000000007fd492300d06092a864886f70d01010b05003042310b3009060355040613025553311e301c060355040a1315476f6f676c65205472757374205365727669636573311330110603550403130a47545320434120314f31301e170d3230313032383136313833365a170d3231303132303136313833365a3066310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c65204c4c433115301306035504030c0c2a2e676f6f676c652e636f6d3059301306072a8648ce3d020106082a8648ce3d03010703420004928f17ebaacb747f1c091d80bab6397cefca2ceed75053a05a196074295add702ed9298d45937515d53026c4ae3bdede339607b42b7525ad2713f1eb455208a6a382070730820703300e0603551d0f0101ff04040302078030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000301d0603551d0e04160414c2f35a502b0f66ccd7cf4ce9f687b6203f0d3b7c301f0603551d2304183016801498d1f86e10ebcf9bec609f18901ba0eb7d09fd2b306806082b06010505070101045c305a302b06082b06010505073001861f687474703a2f2f6f6373702e706b692e676f6f672f677473316f31636f7265302b06082b06010505073002861f687474703a2f2f706b692e676f6f672f677372322f475453314f312e637274308204c20603551d11048204b9308204b5820c2a2e676f6f676c652e636f6d820d2a2e616e64726f69642e636f6d82162a2e617070656e67696e652e676f6f676c652e636f6d82092a2e62646e2e64657682122a2e636c6f75642e676f6f676c652e636f6d82182a2e63726f7764736f757263652e676f6f676c652e636f6d82182a2e64617461636f6d707574652e676f6f676c652e636f6d82062a2e672e636f820e2a2e6763702e677674322e636f6d82112a2e67637063646e2e677674312e636f6d820a2a2e67677068742e636e820e2a2e676b65636e617070732e636e82162a2e676f6f676c652d616e616c79746963732e636f6d820b2a2e676f6f676c652e6361820b2a2e676f6f676c652e636c820e2a2e676f6f676c652e636f2e696e820e2a2e676f6f676c652e636f2e6a70820e2a2e676f6f676c652e636f2e756b820f2a2e676f6f676c652e636f6d2e6172820f2a2e676f6f676c652e636f6d2e6175820f2a2e676f6f676c652e636f6d2e6272820f2a2e676f6f676c652e636f6d2e636f820f2a2e676f6f676c652e636f6d2e6d78820f2a2e676f6f676c652e636f6d2e7472820f2a2e676f6f676c652e636f6d2e766e820b2a2e676f6f676c652e6465820b2a2e676f6f676c652e6573820b2a2e676f6f676c652e6672820b2a2e676f6f676c652e6875820b2a2e676f6f676c652e6974820b2a2e676f6f676c652e6e6c820b2a2e676f6f676c652e706c820b2a2e676f6f676c652e707482122a2e676f6f676c656164617069732e636f6d820f2a2e676f6f676c65617069732e636e82112a2e676f6f676c65636e617070732e636e82142a2e676f6f676c65636f6d6d657263652e636f6d82112a2e676f6f676c65766964656f2e636f6d820c2a2e677374617469632e636e820d2a2e677374617469632e636f6d82122a2e67737461746963636e617070732e636e820a2a2e677674312e636f6d820a2a2e677674322e636f6d82142a2e6d65747269632e677374617469632e636f6d820c2a2e75726368696e2e636f6d82102a2e75726c2e676f6f676c652e636f6d82132a2e776561722e676b65636e617070732e636e82162a2e796f75747562652d6e6f636f6f6b69652e636f6d820d2a2e796f75747562652e636f6d82162a2e796f7574756265656475636174696f6e2e636f6d82112a2e796f75747562656b6964732e636f6d82072a2e79742e6265820b2a2e7974696d672e636f6d821a616e64726f69642e636c69656e74732e676f6f676c652e636f6d820b616e64726f69642e636f6d821b646576656c6f7065722e616e64726f69642e676f6f676c652e636e821c646576656c6f706572732e616e64726f69642e676f6f676c652e636e8204672e636f820867677068742e636e820c676b65636e617070732e636e8206676f6f2e676c8214676f6f676c652d616e616c79746963732e636f6d820a676f6f676c652e636f6d820f676f6f676c65636e617070732e636e8212676f6f676c65636f6d6d657263652e636f6d8218736f757263652e616e64726f69642e676f6f676c652e636e820a75726368696e2e636f6d820a7777772e676f6f2e676c8208796f7574752e6265820b796f75747562652e636f6d8214796f7574756265656475636174696f6e2e636f6d820f796f75747562656b6964732e636f6d820579742e626530210603551d20041a30183008060667810c010202300c060a2b06010401d67902050330330603551d1f042c302a3028a026a0248622687474703a2f2f63726c2e706b692e676f6f672f475453314f31636f72652e63726c30820104060a2b06010401d6790204020481f50481f200f0007700f65c942fd1773022145418083094568ee34d131933bfdf0c2f200bcc4ef164e3000001757037f6230000040300483046022100aac1f73dd8213ad0f7cacfb97830908dd1bf945331fde26b369992cd52731ef1022100bcaa58c50418f910ac3aab1b9f4963c86a8abe79a4ce751ad9489008ae8db433007500eec095ee8d72640f92e3c3b91bc712a3696a097b4b6a1a1438e647b2cbedc5f9000001757037f675000004030046304402203534f394062ad3c22a3ee6b4fc4515824331e758179dbc003d1b30714858e7a802206b2f82038e90b0b1497a50adfa02edabc14c72a68f29ef8beebcdeb3aa79c5f9300d06092a864886f70d01010b05000382010100483bacd4bcba6181eaae86db235942cf84c89dd91ec973525eb46a0582b6fad7ef02124c94521e5d92272a4f87f82a23804adacc08f9da02f7f9b4a25f7d3c819a215b9b8f9308b943b0cd6c9121ecb6f9bd6491c20ec8c149fd171a5c13d17cf6bf1b7cfb2031016637d0daa2ce2f419d498abfdde0eb200c0586068789cbbaea3dd6b9e9e6ba124c6c4e9bf00c5bc79df57f91b849a6a8340883b5d2e1a3b00f86b7c56b34ef740a80ebce142c4973241934a5f257b406e4d2159ae0c27a70a88e8e3036b40611234fa7ece6dff1a5ed0dbc118a361879f0f26b6497cc17b36e2750c92ac0e64db12e5a2ac4142a5ca135ef6ea90f82c20a0eb4b4ed1a31d1" + ); diff --git a/src/parse.rs b/src/parse.rs index 0f686b8..caaa5af 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -113,11 +113,6 @@ pub(crate) fn parse_inner_plaintext_for_handshake(bytes: &[u8]) -> IResult<&[u8] )(remaining_bytes)?; return Ok(( &[], - // // A concatenation of all handshakes received - // // The remaining content_type byte and zero paddings are stripped - // &bytes[ - // ..(bytes.len()-remaining_bytes.len()) - // ], handshake_vec )); } @@ -155,11 +150,8 @@ pub(crate) fn get_content_type_inner_plaintext(inner_plaintext: &[u8]) -> (TlsCo ) } -// TODO: Redo EE -// Not very appropriate to classify EE as proper handshake -// It may include multiple handshakes -// Solution 1: Parse handshake again -> Recursion & return type -// Solution 2: Force caller to parse in a loop -> Extra parser to handle EE +// Turn bytes into a handshake struct +// Will return trailing bytes, if too much bytes were supplied pub(crate) fn parse_handshake(bytes: &[u8]) -> IResult<&[u8], HandshakeRepr> { let handshake_type = take(1_usize); let length = take(3_usize); @@ -191,6 +183,17 @@ pub(crate) fn parse_handshake(bytes: &[u8]) -> IResult<&[u8], HandshakeRepr> { Ok((rest, repr)) }, + CertificateRequest => { + // Process certificate request + let (rest, handshake_data) = parse_certificate_request( + rest + )?; + repr.handshake_data = HandshakeData::CertificateRequest( + handshake_data + ); + + Ok((rest, repr)) + }, Certificate => { // Process Certificate let (rest, handshake_data) = parse_handshake_certificate( @@ -329,6 +332,42 @@ fn parse_encrypted_extensions(bytes: &[u8]) -> IResult<&[u8], EncryptedExtension Ok((rest, encrypted_extensions)) } +fn parse_certificate_request(bytes: &[u8]) -> IResult<&[u8], CertificateRequest> { + let (rest, certificate_request_context_length) = take(1_usize)(bytes)?; + let certificate_request_context_length = certificate_request_context_length[0]; + + let (rest, certificate_request_context) = take( + certificate_request_context_length + )(rest)?; + + let (rest, extensions_length) = take(2_usize)(rest)?; + let extensions_length = NetworkEndian::read_u16(extensions_length); + let (rest, mut extensions_data) = take(extensions_length)(rest)?; + + let mut extensions: Vec = Vec::new(); + + while extensions_data.len() != 0 { + let (rem, extension) = parse_extension( + extensions_data, + HandshakeType::CertificateRequest + )?; + extensions_data = rem; + extensions.push(extension); + } + + let certificate_request = CertificateRequest { + certificate_request_context_length, + certificate_request_context, + extensions_length, + extensions + }; + + Ok(( + rest, + certificate_request + )) +} + fn parse_handshake_certificate(bytes: &[u8]) -> IResult<&[u8], Certificate> { let (rest, certificate_request_context_length) = take(1_usize)(bytes)?; let certificate_request_context_length = certificate_request_context_length[0]; @@ -675,7 +714,6 @@ pub fn parse_asn1_der_tbs_certificate(bytes: &[u8]) -> IResult<&[u8], Asn1DerTBS )) )(value)?; - log::info!("Parsed tbscert"); let version = version.unwrap_or(Asn1DerVersion::v1); let extensions = extensions.unwrap_or( Asn1DerExtensions { extensions: Vec::new() } @@ -931,14 +969,16 @@ pub fn parse_ans1_der_time(bytes: &[u8]) -> IResult<&[u8], DateTime pub fn parse_asn1_der_utc_time(bytes: &[u8]) -> IResult<&[u8], DateTime> { // Buffer for building string + // Need 19 characters to store the whole UTC time, + // and parsible by `chrono` parser let mut string: String = String::new(); // Decide the appropriate century (1950 to 2049) let year_tag: u8 = core::str::from_utf8(&bytes[..2]).unwrap().parse().unwrap(); if year_tag < 50 { - string.push_str("20"); + string.push_str("20").unwrap(); } else { - string.push_str("19"); + string.push_str("19").unwrap(); } // Take out YYMMDDhhmm first @@ -950,7 +990,8 @@ pub fn parse_asn1_der_utc_time(bytes: &[u8]) -> IResult<&[u8], DateTime IResult<&[u8], DateTime { string.push_str(core::str::from_utf8(rest).unwrap()) } - }; + }.unwrap(); Ok(( &[], @@ -1028,8 +1069,6 @@ pub fn parse_asn1_der_subject_key_public_info(bytes: &[u8]) -> IResult<&[u8], As parse_asn1_der_bit_string, )) )(value)?; - log::info!("Parsed subject key alg ident: {:?}", algorithm); - log::info!("Parsed key: {:X?}", subject_public_key); Ok(( rest, Asn1DerSubjectPublicKeyInfo { @@ -1041,7 +1080,6 @@ pub fn parse_asn1_der_subject_key_public_info(bytes: &[u8]) -> IResult<&[u8], As // Parser for extensions (Context-specific Sequence: 0xA3, then universal Sequence: 0x30) pub fn parse_asn1_der_extensions(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensions> { - log::info!("Invoked extension parsing"); let (rest, (tag_val, _, value)) = parse_asn1_der_object(bytes)?; // Verify the tag_val is indeed 0xA3 if tag_val != 0xA3 { @@ -1071,7 +1109,6 @@ pub fn parse_asn1_der_extensions(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensio // Parser for an extension (Sequence: 0x30) pub fn parse_asn1_der_extension(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtension> { - log::info!("Extension: {:X?}\n", bytes); let (rest, (tag_val, _, value)) = parse_asn1_der_object(bytes)?; // Verify the tag_val is indeed 0x30 if tag_val != 0x30 { @@ -1183,7 +1220,6 @@ pub fn parse_asn1_der_subject_alternative_name(bytes: &[u8]) -> IResult<&[u8], A let mut general_names: Vec = Vec::new(); while names.len() != 0 { - log::info!("Name bytes: {:X?}\nLength: {:?}\n", names, names.len()); let (rest, general_name) = parse_asn1_der_general_name(names)?; general_names.push(general_name); @@ -1210,7 +1246,6 @@ pub fn parse_asn1_der_general_name(bytes: &[u8]) -> IResult<&[u8], Asn1DerGenera if inner_tag_val != 0xA0 { return Err(nom::Err::Error((bytes, ErrorKind::Verify))); } - log::info!("Parsed inner tag"); // Further parse the value into an ASN.1 DER object let (_, (_, _, name_value)) = complete( parse_asn1_der_object @@ -1588,6 +1623,7 @@ pub fn parse_rsa_ssa_pss_parameters(params: &[u8]) -> IResult<&[u8], (&[u8], usi } // Parse as RSASSA-PSS-params (Sequence: 0x30) + log::info!("sig_alg sequence: {:X?}", params); let (_, rsa_ssa_params) = complete( parse_asn1_der_sequence )(params)?; @@ -1599,7 +1635,9 @@ pub fn parse_rsa_ssa_pss_parameters(params: &[u8]) -> IResult<&[u8], (&[u8], usi opt(parse_salt_length), opt(parse_trailer_field) )) - )(params)?; + )(rsa_ssa_params)?; + + log::info!("Parser hash algorithm: {:?}", hash_alg); let hash_alg = hash_alg.unwrap_or( Asn1DerAlgId { algorithm: ID_SHA1, parameters: &[] } @@ -1633,6 +1671,7 @@ pub fn parse_rsa_ssa_pss_parameters(params: &[u8]) -> IResult<&[u8], (&[u8], usi fn parse_hash_algorithm(bytes: &[u8]) -> IResult<&[u8], Asn1DerAlgId> { // Parse HashAlgorithm [0] + log::info!("Hash algorithm: {:X?}", bytes); let (rest, (tag_val, _, hash_alg)) = parse_asn1_der_object(bytes)?; // Verify the tag is indeed 0xA0 if tag_val != 0xA0 { @@ -1640,6 +1679,7 @@ fn parse_hash_algorithm(bytes: &[u8]) -> IResult<&[u8], Asn1DerAlgId> { } // Parse the encapsulated algorithm identifier, force completeness let (_, hash_alg) = complete(parse_asn1_der_algorithm_identifier)(hash_alg)?; + log::info!("Parsed hash algorithm {:?}", hash_alg); Ok(( rest, hash_alg )) diff --git a/src/session.rs b/src/session.rs index 004c22f..d042568 100644 --- a/src/session.rs +++ b/src/session.rs @@ -536,7 +536,7 @@ impl Session { use crate::tls_packet::SignatureScheme::*; let get_rsa_padding_scheme = |sig_alg: SignatureScheme| -> PaddingScheme { - match signature_algorithm { + match sig_alg { rsa_pkcs1_sha256 => { PaddingScheme::new_pkcs1v15_sign(Some(RSAHash::SHA2_256)) }, @@ -1313,7 +1313,7 @@ impl Hash { pub(crate) fn select_sha256(self) -> Self { match self { - Self::Undetermined { sha256, sha384 } => { + Self::Undetermined { sha256, .. } => { Self::Sha256 { sha256 } @@ -1324,7 +1324,7 @@ impl Hash { pub(crate) fn select_sha384(self) -> Self { match self { - Self::Undetermined { sha256, sha384 } => { + Self::Undetermined { sha384, .. } => { Self::Sha384 { sha384 } @@ -1465,22 +1465,23 @@ impl Cipher { pub(crate) fn get_cipher_suite_type(&self) -> CipherSuite { match self { - Cipher::Aes128Gcm { aes128gcm } => { + Cipher::Aes128Gcm { .. } => { CipherSuite::TLS_AES_128_GCM_SHA256 }, - Cipher::Aes256Gcm { aes256gcm } => { + Cipher::Aes256Gcm { .. } => { CipherSuite::TLS_AES_256_GCM_SHA384 }, - Cipher::Chacha20poly1305 { chacha20poly1305 } => { + Cipher::Chacha20poly1305 { .. } => { CipherSuite::TLS_CHACHA20_POLY1305_SHA256 }, - Cipher::Ccm { ccm } => { + Cipher::Ccm { .. } => { CipherSuite::TLS_AES_128_CCM_SHA256 } } } } +#[derive(Debug, Clone)] pub enum CertificatePublicKey { RSA { cert_rsa_public_key: RSAPublicKey diff --git a/src/tls.rs b/src/tls.rs index c51f0f0..2cc4eb0 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -213,13 +213,8 @@ impl TlsSocket { let tls_repr_vec_size = tls_repr_vec.len(); for _index in 0..tls_repr_vec_size { let (repr_slice, mut repr) = tls_repr_vec.remove(0); - // TODO: - // Check TLS content type - // If application data, decrypt before process. - // If there are multiple handshakes within a record, - // give each of them a unique TLS record wrapper and process - // If a pure application data is found, sliently ignore - // Otherwise process directly + + // Process record base on content type log::info!("Record type: {:?}", repr.content_type); if repr.content_type == TlsContentType::ApplicationData { log::info!("Found application data"); @@ -241,7 +236,6 @@ impl TlsSocket { &associated_data, &mut app_data ).unwrap(); - // log::info!("Decypted data: {:?}", app_data); session.increment_server_sequence_number(); } @@ -298,10 +292,8 @@ impl TlsSocket { // Drop the message and update `received_change_cipher_spec` // Note: CSS doesn't count as a proper record, no need to increment sequence number if repr.is_change_cipher_spec() { - log::info!("Change Cipher Spec"); let mut session = self.session.try_borrow_mut().expect("Cannot borrow mut"); session.receive_change_cipher_spec(); - log::info!("Changed Cipher Spec"); return Ok(()) } @@ -311,7 +303,6 @@ impl TlsSocket { match tls_state { // During WAIT_SH for a TLS client, client should wait for ServerHello TlsState::WAIT_SH => { - // TODO: Validate SH if repr.is_server_hello() { // Check SH content: // random: Cannot represent HelloRequestRetry @@ -429,7 +420,6 @@ impl TlsSocket { // Expect encrypted extensions after receiving SH TlsState::WAIT_EE => { // Verify that it is indeed an EE - // let might_be_ee = handshake_vec.remove(0); let might_be_ee = repr.handshake.take().unwrap(); if might_be_ee.get_msg_type() != HandshakeType::EncryptedExtensions { // Process the other handshakes in "handshake_vec" @@ -460,14 +450,17 @@ impl TlsSocket { // Parse the certificate and check its content TlsState::WAIT_CERT_CR => { // Verify that it is indeed an Certificate - // let might_be_cert = handshake_vec.remove(0); let might_be_cert = repr.handshake.take().unwrap(); if might_be_cert.get_msg_type() != HandshakeType::Certificate { // Process the other handshakes in "handshake_vec" todo!() } - // TODO: Process Certificate + // let all_certificates = might_be_cert.get_all_asn1_der_certificates().unwrap(); + // log::info!("Number of certificates: {:?}", all_certificates.len()); + // log::info!("All certificates: {:?}", all_certificates); + + // TODO: Process all certificates let cert = might_be_cert.get_asn1_der_certificate().unwrap(); // TODO: Replace this block after implementing a proper @@ -523,7 +516,6 @@ impl TlsSocket { // Client will receive a Finished handshake from server TlsState::WAIT_FINISHED => { // Ensure that it is Finished - // let might_be_server_finished = handshake_vec.remove(0); let might_be_server_finished = repr.handshake.take().unwrap(); if might_be_server_finished.get_msg_type() != HandshakeType::Finished { // Process the other handshakes in "handshake_vec" @@ -748,10 +740,8 @@ impl TlsSocket { + 16 // Auth tag length ); - // TODO: Dynamically size typed Heapless Vec on socket instantiation, - // just like MiniMQ let mut vec: HeaplessVec = HeaplessVec::from_slice(data).unwrap(); - vec.push(0x17); // Content type + vec.push(0x17).unwrap(); // Content type let mut session = self.session.borrow_mut(); let tag = session.encrypt_application_data_in_place_detached( diff --git a/src/tls_packet.rs b/src/tls_packet.rs index 62d3780..9a37455 100644 --- a/src/tls_packet.rs +++ b/src/tls_packet.rs @@ -251,6 +251,7 @@ pub(crate) enum HandshakeData<'a> { EncryptedExtensions(EncryptedExtensions), Certificate(Certificate<'a>), CertificateVerify(CertificateVerify<'a>), + CertificateRequest(CertificateRequest<'a>), Finished(Finished<'a>), } @@ -801,3 +802,11 @@ pub(crate) struct CertificateVerify<'a> { pub(crate) struct Finished<'a> { pub(crate) verify_data: &'a [u8] } + +#[derive(Debug, Clone)] +pub(crate) struct CertificateRequest<'a> { + pub(crate) certificate_request_context_length: u8, + pub(crate) certificate_request_context: &'a [u8], + pub(crate) extensions_length: u16, + pub(crate) extensions: Vec, +}