From 57ff74c183f428cbae4080cb5ea5599517435402 Mon Sep 17 00:00:00 2001 From: occheung Date: Fri, 6 Nov 2020 13:14:40 +0800 Subject: [PATCH] cert: verify using ca key --- src/certificate.rs | 63 ++++++++++++++++++---------------------------- src/main.rs | 26 +++++++++++++++++-- src/session.rs | 2 +- src/tls.rs | 4 --- src/tls_packet.rs | 21 ++++++++++++++++ 5 files changed, 71 insertions(+), 45 deletions(-) diff --git a/src/certificate.rs b/src/certificate.rs index fbe5f06..fcb57d5 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -224,6 +224,18 @@ impl<'a> Certificate<'a> { // Validate signature of self-signed certificate // Do not be confused with TLS Certificate Verify pub fn validate_self_signed_signature(&self) -> Result<(), TlsError> { + let cert_public_key = self.get_cert_public_key() + .map_err(|_| TlsError::SignatureValidationError)?; + self.validate_signature_with_trusted(&cert_public_key) + } + + // Validate signature of certificate signed by some CA's public key + // Do not be confused with TLS Certificate Verify + pub fn validate_signature_with_trusted( + &self, + trusted_public_key: &CertificatePublicKey + ) -> Result<(), TlsError> + { let sig_alg = self.signature_algorithm.algorithm; // Prepare hash value @@ -232,9 +244,7 @@ impl<'a> Certificate<'a> { let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1)); let hashed = Sha1::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -244,9 +254,7 @@ impl<'a> Certificate<'a> { let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_224)); let hashed = Sha224::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -256,9 +264,7 @@ impl<'a> Certificate<'a> { let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256)); let hashed = Sha256::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -268,9 +274,7 @@ impl<'a> Certificate<'a> { let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_384)); let hashed = Sha384::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -280,9 +284,7 @@ impl<'a> Certificate<'a> { let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_512)); let hashed = Sha512::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -300,9 +302,7 @@ impl<'a> Certificate<'a> { ); let hashed = Sha1::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -315,9 +315,7 @@ impl<'a> Certificate<'a> { ); let hashed = Sha224::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -330,9 +328,7 @@ impl<'a> Certificate<'a> { ); let hashed = Sha256::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -345,9 +341,7 @@ impl<'a> Certificate<'a> { ); let hashed = Sha384::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -360,9 +354,7 @@ impl<'a> Certificate<'a> { ); let hashed = Sha512::digest(self.tbs_certificate_encoded); let sig = self.signature_value; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_rsa_public_key() + trusted_public_key.get_rsa_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(padding, &hashed, sig) .map_err(|_| TlsError::SignatureValidationError) @@ -379,9 +371,7 @@ impl<'a> Certificate<'a> { .map_err(|_| TlsError::SignatureValidationError)?; let sig = p256::ecdsa::Signature::from_asn1(self.signature_value) .map_err(|_| TlsError::SignatureValidationError)?; - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_ecdsa_secp256r1_sha256_verify_key() + trusted_public_key.get_ecdsa_secp256r1_sha256_verify_key() .map_err(|_| TlsError::SignatureValidationError)? .verify(self.tbs_certificate_encoded, &sig) .map_err(|_| TlsError::SignatureValidationError) @@ -393,16 +383,13 @@ impl<'a> Certificate<'a> { self.signature_value ).map_err(|_| TlsError::SignatureValidationError)?; log::info!("Ed25519 signature: {:?}", sig); - self.get_cert_public_key() - .map_err(|_| TlsError::SignatureValidationError)? - .get_ed25519_public_key() + trusted_public_key.get_ed25519_public_key() .map_err(|_| TlsError::SignatureValidationError)? .verify_strict(self.tbs_certificate_encoded, &sig) .map_err(|_| TlsError::SignatureValidationError) - } + }, _ => todo!() } - } } diff --git a/src/main.rs b/src/main.rs index 89b6e41..0cd652a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,9 +78,26 @@ fn main() { // tls_socket.tls_connect(&mut sockets).unwrap(); simple_logger::SimpleLogger::new().init().unwrap(); - let (_, certificate) = parse_asn1_der_certificate(&ED25519_CERT).unwrap(); + let (_, certificate) = parse_asn1_der_certificate(&CA_SIGNED_CERT).unwrap(); + println!("Certificate print: {:?}", certificate); - certificate.validate_self_signed_signature().unwrap(); + 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 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"); } @@ -127,3 +144,8 @@ const ECDSA_P256_CERT: [u8; 0x0219] = const ED25519_CERT: [u8; 0x0187] = hex_literal::hex!("30820183308201350214644c27b38f4bd515d9c06f72609ed50844499917300506032b65703064310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311d301b06035504030c146578616d706c65732e756c666865696d2e6e6574301e170d3230313130353035313435365a170d3232313030363035313435365a3064310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311d301b06035504030c146578616d706c65732e756c666865696d2e6e6574302a300506032b6570032100be9d2a3f45d7bd86a6fba8acf3dc58d1241e4272f100c81779bc43e96b779515300506032b6570034100b7017b76d0f9f6f58f7bb28de5459c127a3a539ed73997dcd42a0e0484d5768d42b5f5b0e275c99b856124b20983b2dca66dec380b15b5425f9ccf87a3dc5700"); + +const CA_SIGNED_CERT: [u8; 0x0356] = + hex_literal::hex!( + "308203523082023a02146048517ee55aabd1e8f2bd7db1d91e679708e644300d06092a864886f70d01010b05003067310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643120301e06035504030c176578616d706c65732e63612e756c666865696d2e6e6574301e170d3230313130363034323035305a170d3230313230363034323035305a3064310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311d301b06035504030c146578616d706c65732e756c666865696d2e6e657430820122300d06092a864886f70d01010105000382010f003082010a0282010100b2940671bfe7ace7416ba9d34018c229588e9d4eed8bd6623e44ab1239e8f1f0de9050b2f485a98e63f5b483330fb0b5abaeb33d11889033b0b684bf34696d28206bb361782c4b106a8d47874cbbdf971b5ab887bca508bccf250a1a811cee078464638e441941347d4c8885ac9b59d9fc9636276912b04d9e3ab29bd8ad319572ae54f0b6145c4d675a78607dcc4793a4d432f1c2a41ea29dd4f7262b6fe472dfaea51aca992b4624e73fa9901fa364fc5b721052ef3187e659d58d2706770d365380a7ebab6caac5b23271c01531fdf95368ee48af5383035f249be7c18f50ce9e52877558efe4b2e29f61328396e2a3b5e71309ad13d93d6ba3d5c3eb2b650203010001300d06092a864886f70d01010b0500038201010063c9ab0f5d2e164513e8e74b656ae4f48dd004c3ead9f1026b7741cbf02bb0efcf19e0fbf8a788dae059a2393167f016bafc0e3efd5c5b4c43079b6506eb67f17f44f9591503c7d1fdb77bf631894817393ea82610ad5106d23ec6bf1a6d96d749f05c0136cd71256617a51fe862529aee4a37d5f456dc7da8b220ff10ede4e87bc63e4589b3f81133a7f82ab900419e8a2d802d59e99cfbbd268702efd17616168b45b5211da0e644c29dcb92dbbf32b43586bbab05deb0261771605c52836363bd28ff9853d44436349f5ba11f2640bc9c42688e0d5eb6cac9f3f5e5f98652fa4f4ba52604371ec45f09d678e31d463285a4b3734f587f35a339920544f476" + ); diff --git a/src/session.rs b/src/session.rs index c7c3ded..004c22f 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1481,7 +1481,7 @@ impl Cipher { } } -pub(crate) enum CertificatePublicKey { +pub enum CertificatePublicKey { RSA { cert_rsa_public_key: RSAPublicKey }, diff --git a/src/tls.rs b/src/tls.rs index 8faeee3..c51f0f0 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -472,10 +472,6 @@ impl TlsSocket { // TODO: Replace this block after implementing a proper // certificate verification procdeure - // match validate_root_certificate(cert) { - // Ok(true) => {}, - // _ => panic!("Certificate does not match") - // } cert.validate_self_signed_signature().expect("Signature mismatched"); // Update session TLS state to WAIT_CV diff --git a/src/tls_packet.rs b/src/tls_packet.rs index 66c6d92..09f619c 100644 --- a/src/tls_packet.rs +++ b/src/tls_packet.rs @@ -178,6 +178,19 @@ impl<'a, 'b> HandshakeRepr<'a> { } } + pub(crate) fn get_all_asn1_der_certificates(&self) -> Result, ()> { + if self.msg_type != HandshakeType::Certificate { + return Err(()) + }; + if let HandshakeData::Certificate( + cert + ) = &self.handshake_data { + Ok(cert.get_all_certificates()) + } else { + Err(()) + } + } + pub(crate) fn get_signature(&self) -> Result<(SignatureScheme, &[u8]), ()> { if self.msg_type != HandshakeType::CertificateVerify { return Err(()) @@ -767,6 +780,14 @@ impl<'a> Certificate<'a> { pub(crate) fn get_certificate(&self, index: usize) -> &Asn1DerCertificate { self.certificate_list[index].get_certificate() } + + pub(crate) fn get_all_certificates(&self) -> Vec<&Asn1DerCertificate> { + let mut certificate_vec = Vec::new(); + for cert_entry in self.certificate_list.iter() { + certificate_vec.push(cert_entry.get_certificate()) + } + certificate_vec + } } #[derive(Debug, Clone)]