cert: accept more sig_algs
This commit is contained in:
parent
7231438269
commit
d0488892fb
|
@ -5,6 +5,8 @@ use generic_array::GenericArray;
|
||||||
|
|
||||||
use crate::parse::parse_asn1_der_rsa_public_key;
|
use crate::parse::parse_asn1_der_rsa_public_key;
|
||||||
use crate::parse::parse_rsa_ssa_pss_parameters;
|
use crate::parse::parse_rsa_ssa_pss_parameters;
|
||||||
|
use crate::parse::parse_ecdsa_signature;
|
||||||
|
use crate::parse::parse_asn1_der_oid;
|
||||||
|
|
||||||
use crate::Error as TlsError;
|
use crate::Error as TlsError;
|
||||||
use crate::session::CertificatePublicKey;
|
use crate::session::CertificatePublicKey;
|
||||||
|
@ -15,9 +17,13 @@ use sha1::{Sha1, Digest};
|
||||||
use sha2::{Sha224, Sha256, Sha384, Sha512};
|
use sha2::{Sha224, Sha256, Sha384, Sha512};
|
||||||
use rsa::{PublicKey, RSAPublicKey, PaddingScheme, BigUint, Hash};
|
use rsa::{PublicKey, RSAPublicKey, PaddingScheme, BigUint, Hash};
|
||||||
|
|
||||||
|
use p256::ecdsa::signature::{Verifier, DigestVerifier};
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use heapless::{ Vec as HeaplessVec, consts::* };
|
use heapless::{ Vec as HeaplessVec, consts::* };
|
||||||
|
|
||||||
|
use core::convert::TryFrom;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Certificate<'a> {
|
pub struct Certificate<'a> {
|
||||||
pub tbs_certificate: TBSCertificate<'a>,
|
pub tbs_certificate: TBSCertificate<'a>,
|
||||||
|
@ -147,42 +153,6 @@ pub struct AlgorithmIdentifier<'a> {
|
||||||
pub parameters: &'a [u8],
|
pub parameters: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: MOve this to impl block of Certificate
|
|
||||||
// Verify self-signed root certificate parsed certificate
|
|
||||||
// TODO: Remove this method, it will be replaced
|
|
||||||
pub fn validate_root_certificate(cert: &Certificate) -> Result<bool, TlsError> {
|
|
||||||
// Verify Signature
|
|
||||||
match cert.signature_algorithm.algorithm {
|
|
||||||
SHA1_WITH_RSA_ENCRYPTION => {
|
|
||||||
let mut hasher = Sha1::new();
|
|
||||||
hasher.update(cert.tbs_certificate_encoded);
|
|
||||||
|
|
||||||
log::info!("Created hashed");
|
|
||||||
|
|
||||||
let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key(
|
|
||||||
cert.tbs_certificate.subject_public_key_info.subject_public_key
|
|
||||||
).map_err(|_| TlsError::ParsingError)?;
|
|
||||||
|
|
||||||
log::info!("Modulus: {:?}", modulus);
|
|
||||||
log::info!("Exponent: {:?}", exponent);
|
|
||||||
|
|
||||||
let rsa_public_key = RSAPublicKey::new(
|
|
||||||
BigUint::from_bytes_be(modulus),
|
|
||||||
BigUint::from_bytes_be(exponent)
|
|
||||||
).map_err(|_| TlsError::SignatureValidationError)?;
|
|
||||||
|
|
||||||
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1));
|
|
||||||
let verify_result = rsa_public_key.verify(
|
|
||||||
padding,
|
|
||||||
&hasher.finalize(),
|
|
||||||
cert.signature_value
|
|
||||||
).unwrap();
|
|
||||||
Ok(true)
|
|
||||||
},
|
|
||||||
_ => Err(TlsError::SignatureValidationError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Certificate<'a> {
|
impl<'a> Certificate<'a> {
|
||||||
// Return the public key, if used for RSA
|
// Return the public key, if used for RSA
|
||||||
pub fn return_rsa_public_key(&self) -> Result<RSAPublicKey, ()> {
|
pub fn return_rsa_public_key(&self) -> Result<RSAPublicKey, ()> {
|
||||||
|
@ -230,11 +200,16 @@ impl<'a> Certificate<'a> {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
ID_EC_PUBLIC_KEY => {
|
ID_EC_PUBLIC_KEY => {
|
||||||
// Check the type of EC, only support secp256r1
|
// Check the type of EC, only support secp256r1, parse as OID
|
||||||
|
// Other types of EC repreesntation (EC param) is not be supported
|
||||||
|
let (_, ec_oid) = parse_asn1_der_oid(algorithm_identifier.parameters)
|
||||||
|
.map_err(|_| ())?;
|
||||||
// Will definitely NOT support custom curve
|
// Will definitely NOT support custom curve
|
||||||
if algorithm_identifier.parameters != PRIME256V1 {
|
if ec_oid != PRIME256V1 {
|
||||||
return Err(());
|
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(
|
let p256_verify_key = p256::ecdsa::VerifyKey::from_encoded_point(
|
||||||
&p256::EncodedPoint::from_untagged_bytes(
|
&p256::EncodedPoint::from_untagged_bytes(
|
||||||
GenericArray::from_slice(
|
GenericArray::from_slice(
|
||||||
|
@ -242,6 +217,7 @@ impl<'a> Certificate<'a> {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).map_err(|_| ())?;
|
).map_err(|_| ())?;
|
||||||
|
log::info!("Have verify key");
|
||||||
Ok(
|
Ok(
|
||||||
CertificatePublicKey::ECDSA_SECP256R1_SHA256 {
|
CertificatePublicKey::ECDSA_SECP256R1_SHA256 {
|
||||||
cert_verify_key: p256_verify_key
|
cert_verify_key: p256_verify_key
|
||||||
|
@ -262,9 +238,9 @@ impl<'a> Certificate<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate certificate's signature
|
// Validate signature of self-signed certificate
|
||||||
// Do not be confused with TLS Certificate Verify
|
// Do not be confused with TLS Certificate Verify
|
||||||
pub fn validate_signature(&self) -> Result<(), TlsError> {
|
pub fn validate_self_signed_signature(&self) -> Result<(), TlsError> {
|
||||||
let sig_alg = self.signature_algorithm.algorithm;
|
let sig_alg = self.signature_algorithm.algorithm;
|
||||||
|
|
||||||
// Prepare hash value
|
// Prepare hash value
|
||||||
|
@ -328,8 +304,7 @@ impl<'a> Certificate<'a> {
|
||||||
.verify(padding, &hashed, sig)
|
.verify(padding, &hashed, sig)
|
||||||
.map_err(|_| TlsError::SignatureValidationError)
|
.map_err(|_| TlsError::SignatureValidationError)
|
||||||
},
|
},
|
||||||
// Further process the signature algorithm before creating digests
|
// Further process the signature algorithm of PSS before creating digests
|
||||||
// i.e. PSS, OAEP
|
|
||||||
ID_RSASSA_PSS => {
|
ID_RSASSA_PSS => {
|
||||||
let (_, (hash_alg, salt_len)) = parse_rsa_ssa_pss_parameters(
|
let (_, (hash_alg, salt_len)) = parse_rsa_ssa_pss_parameters(
|
||||||
self.signature_algorithm.parameters
|
self.signature_algorithm.parameters
|
||||||
|
@ -409,9 +384,40 @@ impl<'a> Certificate<'a> {
|
||||||
.verify(padding, &hashed, sig)
|
.verify(padding, &hashed, sig)
|
||||||
.map_err(|_| TlsError::SignatureValidationError)
|
.map_err(|_| TlsError::SignatureValidationError)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO: SHA3 is not on the table, implement better error rejection
|
||||||
_ => todo!()
|
_ => todo!()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 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 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()
|
||||||
|
.map_err(|_| TlsError::SignatureValidationError)?
|
||||||
|
.verify(self.tbs_certificate_encoded, &sig)
|
||||||
|
.map_err(|_| TlsError::SignatureValidationError)
|
||||||
|
},
|
||||||
|
|
||||||
|
// Ed25519 signature algorithm
|
||||||
|
ID_EDDSA_25519 => {
|
||||||
|
let sig = ed25519_dalek::Signature::try_from(
|
||||||
|
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()
|
||||||
|
.map_err(|_| TlsError::SignatureValidationError)?
|
||||||
|
.verify_strict(self.tbs_certificate_encoded, &sig)
|
||||||
|
.map_err(|_| TlsError::SignatureValidationError)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => todo!()
|
_ => todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -78,9 +78,9 @@ fn main() {
|
||||||
// tls_socket.tls_connect(&mut sockets).unwrap();
|
// tls_socket.tls_connect(&mut sockets).unwrap();
|
||||||
simple_logger::SimpleLogger::new().init().unwrap();
|
simple_logger::SimpleLogger::new().init().unwrap();
|
||||||
|
|
||||||
let (_, certificate) = parse_asn1_der_certificate(&RSA_PSS_CERT).unwrap();
|
let (_, certificate) = parse_asn1_der_certificate(&ED25519_CERT).unwrap();
|
||||||
|
|
||||||
certificate.validate_signature().unwrap();
|
certificate.validate_self_signed_signature().unwrap();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,4 +120,10 @@ const RSA_PSS_CERT: [u8; 0x3AB] =
|
||||||
hex_literal::hex!("308203a73082028fa00302010202146642be8f709457f9cd6eed72051c240a5565138c300d06092a864886f70d01010a30003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e6574301e170d3230313130343039313535325a170d3231313130343039313535325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e657430820122300d06092a864886f70d01010105000382010f003082010a0282010100b5a347b654ca0bad8d56990e70aa7411b78dedc9fd9a6760ee936ea01486238538dbc4d0bc95a1a5f060b6296ba67001f103cfd918ad1ec33a1a680d4e8283a24300391e9a53cd6641fc51f0a984c3cd16542b934a0ec8c3447782542628320d6c24988cf0b7b19bbaba91f1999968def724d8e65b624fbb9826208aece1ee90badda7c6b8a97fc4085299f9d32661a06bc67d2d662e0efcee1df5b6dc1d02e56929d8976441456d0fe50314c9861e9845f75f5dc2ca9828089b5d4bd109d1e8ada8986c5bd68ee004a7bfcb932768023e11fe8e299b25b8774ed8bdbb0f644ddaa83df1ff4e84bfc18d3b815decb5ca4f1db1125df98dba94e4ef5570ec5a510203010001a3533051301d0603551d0e04160414050928eff30f3094f01ddb09f1d7a9193addf854301f0603551d23041830168014050928eff30f3094f01ddb09f1d7a9193addf854300f0603551d130101ff040530030101ff300d06092a864886f70d01010a300003820101002d14281587dc33d4559e77852d17fade1a9f3f0e5af847bde80c921be360d6e3b598dfb50aad706de3832841798b66736b9296a83c06e0078dceabc39760a5bf5eb7a7287859b22e9beb7ebb928b99034d155fd12307ee541ea53979bb8afb62db233dfcf1e16afea5eac33817b8cbb13841cb89e9b65a5a4b08a6c6e3d1e0036bc9576b90cf62437e3ef985f02b88be4e6863068c9bc45dd473763f4cdcfc3bfb8a90d7b3225b67a3a39c6ac446de55596dc135221b4383773ddd9efdcca48f389af9c1c0547e0ada1c14153fc38e02c95e4c37da45af1e6d3b0a6cafb603d95a1c887384b476caf60783835a150ee7fd22b6838ce19adcb2e59572c6349703");
|
hex_literal::hex!("308203a73082028fa00302010202146642be8f709457f9cd6eed72051c240a5565138c300d06092a864886f70d01010a30003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e6574301e170d3230313130343039313535325a170d3231313130343039313535325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e657430820122300d06092a864886f70d01010105000382010f003082010a0282010100b5a347b654ca0bad8d56990e70aa7411b78dedc9fd9a6760ee936ea01486238538dbc4d0bc95a1a5f060b6296ba67001f103cfd918ad1ec33a1a680d4e8283a24300391e9a53cd6641fc51f0a984c3cd16542b934a0ec8c3447782542628320d6c24988cf0b7b19bbaba91f1999968def724d8e65b624fbb9826208aece1ee90badda7c6b8a97fc4085299f9d32661a06bc67d2d662e0efcee1df5b6dc1d02e56929d8976441456d0fe50314c9861e9845f75f5dc2ca9828089b5d4bd109d1e8ada8986c5bd68ee004a7bfcb932768023e11fe8e299b25b8774ed8bdbb0f644ddaa83df1ff4e84bfc18d3b815decb5ca4f1db1125df98dba94e4ef5570ec5a510203010001a3533051301d0603551d0e04160414050928eff30f3094f01ddb09f1d7a9193addf854301f0603551d23041830168014050928eff30f3094f01ddb09f1d7a9193addf854300f0603551d130101ff040530030101ff300d06092a864886f70d01010a300003820101002d14281587dc33d4559e77852d17fade1a9f3f0e5af847bde80c921be360d6e3b598dfb50aad706de3832841798b66736b9296a83c06e0078dceabc39760a5bf5eb7a7287859b22e9beb7ebb928b99034d155fd12307ee541ea53979bb8afb62db233dfcf1e16afea5eac33817b8cbb13841cb89e9b65a5a4b08a6c6e3d1e0036bc9576b90cf62437e3ef985f02b88be4e6863068c9bc45dd473763f4cdcfc3bfb8a90d7b3225b67a3a39c6ac446de55596dc135221b4383773ddd9efdcca48f389af9c1c0547e0ada1c14153fc38e02c95e4c37da45af1e6d3b0a6cafb603d95a1c887384b476caf60783835a150ee7fd22b6838ce19adcb2e59572c6349703");
|
||||||
|
|
||||||
const RSA_PKCS_CERT: [u8; 0x03AB] =
|
const RSA_PKCS_CERT: [u8; 0x03AB] =
|
||||||
hex_literal::hex!("308203a73082028fa00302010202144a5a52142c495ec189e661457ba0330809c9dede300d06092a864886f70d01010b05003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d301e170d3230313130343038353031325a170d3231313130343038353031325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100a665127e115e41937b51f87fa44d9894e52a45479a234110037f8c8ce2de6d263e12e3824d57a39d7386afe35cb926af1d6f593673eae31f1e27b8914895006fc7e5fdac11f369b73741a97663f2bb08edb7ab7c1ccc8be9259ce2c1b9d04ba066e05fd6a440ca99b148ddc95a23432228f5172b32939921f70f4f632691ee19a50d7deffb50cb9f018562c803065ca1f1817f1f93c25b3aa0ef91b2f91ef1c86fd346bc00ac165fbd5abf04d944a58e48fd24959133637a949cb85d498063aa4ed0927327591d125500430fa91782af806d46fe330251103c8139b3bf35034b009748324a0fffac2474eed6f04e8d90582dc6125cce0274305f28e82b5409170203010001a3533051301d0603551d0e04160414a36633b9660897096d8138d4f0281a3b76e6696c301f0603551d23041830168014a36633b9660897096d8138d4f0281a3b76e6696c300f0603551d130101ff040530030101ff300d06092a864886f70d01010b0500038201010090631de179bf4940e636e0e7142d9feb440d818c9ea095b6ae31a4ad9876fbd1c2b6808d2edc60e20b107daaf592d14bb9f1ca37c9d975b0c463478dbac8cb183b90bbaecdb1ad5541674f3ba957f2837e57480c445328f917c8a358fc5465c1f838108f60b59327cd1fba59e1635276372bdb17557b636b59be60b4c6b6cf3ecb9fd40b9469d7bfa4f2053be4c08e2e350453050a076d923923588c7f839c709d31c2296dfd837b850f0ba4b44a36c112b9a6ef7186b090162628367a95fa1673e4362d7a23aebd46a85c69eac76f7194d166c89ce6103c508eb970f35bf0b241cbbae5ddffc5ea6515e5f36a8645dc0c8a48798199f65f01b811bec2f287d5");
|
hex_literal::hex!("308203a73082028fa00302010202144a5a52142c495ec189e661457ba0330809c9dede300d06092a864886f70d01010b05003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d301e170d3230313130343038353031325a170d3231313130343038353031325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100a665127e115e41937b51f87fa44d9894e52a45479a234110037f8c8ce2de6d263e12e3824d57a39d7386afe35cb926af1d6f593673eae31f1e27b8914895006fc7e5fdac11f369b73741a97663f2bb08edb7ab7c1ccc8be9259ce2c1b9d04ba066e05fd6a440ca99b148ddc95a23432228f5172b32939921f70f4f632691ee19a50d7deffb50cb9f018562c803065ca1f1817f1f93c25b3aa0ef91b2f91ef1c86fd346bc00ac165fbd5abf04d944a58e48fd24959133637a949cb85d498063aa4ed0927327591d125500430fa91782af806d46fe330251103c8139b3bf35034b009748324a0fffac2474eed6f04e8d90582dc6125cce0274305f28e82b5409170203010001a3533051301d0603551d0e04160414a36633b9660897096d8138d4f0281a3b76e6696c301f0603551d23041830168014a36633b9660897096d8138d4f0281a3b76e6696c300f0603551d130101ff040530030101ff300d06092a864886f70d01010b0500038201010090631de179bf4940e636e0e7142d9feb440d818c9ea095b6ae31a4ad9876fbd1c2b6808d2edc60e20b107daaf592d14bb9f1ca37c9d975b0c463478dbac8cb183b90bbaecdb1ad5541674f3ba957f2837e57480c445328f917c8a358fc5465c1f838108f60b59327cd1fba59e1635276372bdb17557b636b59be60b4c6b6cf3ecb9fd40b9469d7bfa4f2053be4c08e2e350453050a076d923923588c7f839c709d31c2296dfd837b850f0ba4b44a36c112b9a6ef7186b090162628367a95fa1673e4362d7a23aebd46a85c69eac76f7194d166c89ce6103c508eb970f35bf0b241cbbae5ddffc5ea6515e5f36a8645dc0c8a48798199f65f01b811bec2f287d5");
|
||||||
|
|
||||||
|
const ECDSA_P256_CERT: [u8; 0x0219] =
|
||||||
|
hex_literal::hex!("30820215308201bba003020102021441d0428ae91b87ccb66e64cf3bdbd96ef0871630300a06082a8648ce3d0403023060310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643119301706092a864886f70d010901160a68656c6c6f776f726c64301e170d3230313130353033313932325a170d3330313130333033313932325a3060310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643119301706092a864886f70d010901160a68656c6c6f776f726c643059301306072a8648ce3d020106082a8648ce3d03010703420004d22bf2abba402fa10f6d97f941465d5966a965cc8f288bb7920e8c9e8c50607ef3a0a183916913ed9f4dfb42452fe972a2a5ac7a2f4443ef2a0012a481957d10a3533051301d0603551d0e041604147383be1d07af30366a8c3c377d048759f802e885301f0603551d230418301680147383be1d07af30366a8c3c377d048759f802e885300f0603551d130101ff040530030101ff300a06082a8648ce3d0403020348003045022100c048d13d28a811a67262d1593ea0f4af51812751632d391b7d85666fcd5e591702202b1a2db620b764ff61a7be0808069518c75d1bed60c1e9c98debfa98d7a23134");
|
||||||
|
|
||||||
|
const ED25519_CERT: [u8; 0x0187] =
|
||||||
|
hex_literal::hex!("30820183308201350214644c27b38f4bd515d9c06f72609ed50844499917300506032b65703064310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311d301b06035504030c146578616d706c65732e756c666865696d2e6e6574301e170d3230313130353035313435365a170d3232313030363035313435365a3064310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311d301b06035504030c146578616d706c65732e756c666865696d2e6e6574302a300506032b6570032100be9d2a3f45d7bd86a6fba8acf3dc58d1241e4272f100c81779bc43e96b779515300506032b6570034100b7017b76d0f9f6f58f7bb28de5459c127a3a539ed73997dcd42a0e0484d5768d42b5f5b0e275c99b856124b20983b2dca66dec380b15b5425f9ccf87a3dc5700");
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub const ID_RSASSA_PSS: &'static [u8] =
|
||||||
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A];
|
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A];
|
||||||
|
|
||||||
// RSAES_OAEP
|
// RSAES_OAEP
|
||||||
|
// This padding scheme is not supported by RSA for verification
|
||||||
pub const ID_RSAES_OAEP: &'static [u8] =
|
pub const ID_RSAES_OAEP: &'static [u8] =
|
||||||
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x07];
|
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x07];
|
||||||
|
|
||||||
|
|
70
src/parse.rs
70
src/parse.rs
|
@ -1146,7 +1146,7 @@ pub fn parse_asn1_der_rsa_public_key(bytes: &[u8]) -> IResult<&[u8], (&[u8], &[u
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prasers for PSS/OAEP signature algorithms parameters in certificate
|
* Prasers for PSS signature algorithms parameters in certificate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Take addition parameter of PSS algorithm idenfier
|
// Take addition parameter of PSS algorithm idenfier
|
||||||
|
@ -1180,61 +1180,6 @@ pub fn parse_rsa_ssa_pss_parameters(params: &[u8]) -> IResult<&[u8], (&[u8], usi
|
||||||
);
|
);
|
||||||
let salt_len = salt_len.unwrap_or(&[0x14]);
|
let salt_len = salt_len.unwrap_or(&[0x14]);
|
||||||
|
|
||||||
// // Parse HashAlgorithm [0]
|
|
||||||
// let (rest, (tag_val, _, hash_alg)) = parse_asn1_der_object(rsa_ssa_params)?;
|
|
||||||
// // Verify the tag is indeed 0xA0
|
|
||||||
// if tag_val != 0xA0 {
|
|
||||||
// return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
|
||||||
// }
|
|
||||||
// // Parse the encapsulated algorithm identifier, force completeness
|
|
||||||
// let (_, hash_alg) = complete(parse_asn1_der_algorithm_identifier)(hash_alg)?;
|
|
||||||
|
|
||||||
// // Parse MaskGenAlgorithm [1]
|
|
||||||
// let (rest, (tag_val, _, mask_gen_alg)) = parse_asn1_der_object(rest)?;
|
|
||||||
// // Verify the tag is indeed 0xA1
|
|
||||||
// if tag_val != 0xA1 {
|
|
||||||
// return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
|
||||||
// }
|
|
||||||
// // Parse the encapsulated algorithm identifier, force completeness
|
|
||||||
// let (_, mgf) = complete(parse_asn1_der_algorithm_identifier)(mask_gen_alg)?;
|
|
||||||
// // Algorithm field of mgf should always be mgf1
|
|
||||||
// if mgf.algorithm != ID_MGF1 {
|
|
||||||
// todo!()
|
|
||||||
// }
|
|
||||||
// // Parse the parameters of MGF Alg. Ident. to get hash algorithm under MGF
|
|
||||||
// let (_, mgf_hash_alg) = complete(parse_asn1_der_algorithm_identifier)(
|
|
||||||
// mgf.parameters
|
|
||||||
// )?;
|
|
||||||
|
|
||||||
// // Parse salt length [2]
|
|
||||||
// let (rest, (tag_val, _, salt_len)) = parse_asn1_der_object(rest)?;
|
|
||||||
// if tag_val != 0xA2 {
|
|
||||||
// return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
|
||||||
// }
|
|
||||||
// // Parse the encapsulated integer, force completeness
|
|
||||||
// let (_, salt_len) = complete(
|
|
||||||
// parse_asn1_der_integer
|
|
||||||
// )(salt_len)?;
|
|
||||||
|
|
||||||
// // If there are still unprocessed data left, parse for trailer field
|
|
||||||
// if rest.len() != 0 {
|
|
||||||
// // Parse trailer field [3]
|
|
||||||
// let (_, (tag_val, _, trailer_field)) = complete(
|
|
||||||
// parse_asn1_der_object
|
|
||||||
// )(rest)?;
|
|
||||||
// if tag_val != 0xA3 {
|
|
||||||
// return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
|
||||||
// }
|
|
||||||
// // Parse the encapsulated integer, force completeness
|
|
||||||
// let (_, trailer_field) = complete(
|
|
||||||
// parse_asn1_der_integer
|
|
||||||
// )(trailer_field)?;
|
|
||||||
// // The value must be 1 stated in RFC 4055
|
|
||||||
// if trailer_field.len() < 1 || trailer_field[trailer_field.len() - 1] != 1 {
|
|
||||||
// return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Verify that the hash functions listed in HashFunc and MGF are consistent
|
// Verify that the hash functions listed in HashFunc and MGF are consistent
|
||||||
if hash_alg.algorithm != mgf_hash_alg.algorithm {
|
if hash_alg.algorithm != mgf_hash_alg.algorithm {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -1330,3 +1275,16 @@ fn parse_trailer_field(bytes: &[u8]) -> IResult<&[u8], ()> {
|
||||||
&[], ()
|
&[], ()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parser for identifying `r` and `s` fields of ECDSA signatures
|
||||||
|
pub fn parse_ecdsa_signature(sig: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
|
||||||
|
let (_, sig_val) = complete(
|
||||||
|
parse_asn1_der_sequence
|
||||||
|
)(sig)?;
|
||||||
|
complete(
|
||||||
|
tuple((
|
||||||
|
parse_asn1_der_integer,
|
||||||
|
parse_asn1_der_integer
|
||||||
|
))
|
||||||
|
)(sig_val)
|
||||||
|
}
|
||||||
|
|
|
@ -62,7 +62,6 @@ pub(crate) struct Session {
|
||||||
server_sequence_number: u64,
|
server_sequence_number: u64,
|
||||||
// Certificate public key
|
// Certificate public key
|
||||||
// For Handling CertificateVerify
|
// For Handling CertificateVerify
|
||||||
cert_rsa_public_key: Option<RSAPublicKey>, // TODO: Replace and remove
|
|
||||||
cert_public_key: Option<CertificatePublicKey>,
|
cert_public_key: Option<CertificatePublicKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +93,6 @@ impl Session {
|
||||||
server_application_nonce: None,
|
server_application_nonce: None,
|
||||||
client_sequence_number: 0,
|
client_sequence_number: 0,
|
||||||
server_sequence_number: 0,
|
server_sequence_number: 0,
|
||||||
cert_rsa_public_key: None, // TODO: Remove over-specific public key
|
|
||||||
cert_public_key: None
|
cert_public_key: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,10 +475,10 @@ impl Session {
|
||||||
pub(crate) fn client_update_for_wait_cert_cr(
|
pub(crate) fn client_update_for_wait_cert_cr(
|
||||||
&mut self,
|
&mut self,
|
||||||
cert_slice: &[u8],
|
cert_slice: &[u8],
|
||||||
cert_rsa_public_key: RSAPublicKey
|
cert_public_key: CertificatePublicKey
|
||||||
) {
|
) {
|
||||||
self.hash.update(cert_slice);
|
self.hash.update(cert_slice);
|
||||||
self.cert_rsa_public_key.replace(cert_rsa_public_key);
|
self.cert_public_key.replace(cert_public_key);
|
||||||
self.state = TlsState::WAIT_CV;
|
self.state = TlsState::WAIT_CV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,9 +544,14 @@ impl Session {
|
||||||
.chain(&transcript_hash)
|
.chain(&transcript_hash)
|
||||||
.finalize();
|
.finalize();
|
||||||
let padding = get_rsa_padding_scheme(signature_algorithm);
|
let padding = get_rsa_padding_scheme(signature_algorithm);
|
||||||
let verify_result = self.cert_rsa_public_key.take().unwrap().verify(
|
let verify_result = self.cert_public_key
|
||||||
padding, &verify_hash, signature
|
.take()
|
||||||
);
|
.unwrap()
|
||||||
|
.get_rsa_public_key()
|
||||||
|
.unwrap()
|
||||||
|
.verify(
|
||||||
|
padding, &verify_hash, signature
|
||||||
|
);
|
||||||
if verify_result.is_err() {
|
if verify_result.is_err() {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -561,9 +564,14 @@ impl Session {
|
||||||
.chain(&transcript_hash)
|
.chain(&transcript_hash)
|
||||||
.finalize();
|
.finalize();
|
||||||
let padding = get_rsa_padding_scheme(signature_algorithm);
|
let padding = get_rsa_padding_scheme(signature_algorithm);
|
||||||
let verify_result = self.cert_rsa_public_key.take().unwrap().verify(
|
let verify_result = self.cert_public_key
|
||||||
padding, &verify_hash, signature
|
.take()
|
||||||
);
|
.unwrap()
|
||||||
|
.get_rsa_public_key()
|
||||||
|
.unwrap()
|
||||||
|
.verify(
|
||||||
|
padding, &verify_hash, signature
|
||||||
|
);
|
||||||
log::info!("Algorithm {:?} Certificate verify: {:?}", signature_algorithm, verify_result);
|
log::info!("Algorithm {:?} Certificate verify: {:?}", signature_algorithm, verify_result);
|
||||||
if verify_result.is_err() {
|
if verify_result.is_err() {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -577,9 +585,14 @@ impl Session {
|
||||||
.chain(&transcript_hash)
|
.chain(&transcript_hash)
|
||||||
.finalize();
|
.finalize();
|
||||||
let padding = get_rsa_padding_scheme(signature_algorithm);
|
let padding = get_rsa_padding_scheme(signature_algorithm);
|
||||||
let verify_result = self.cert_rsa_public_key.take().unwrap().verify(
|
let verify_result = self.cert_public_key
|
||||||
padding, &verify_hash, signature
|
.take()
|
||||||
);
|
.unwrap()
|
||||||
|
.get_rsa_public_key()
|
||||||
|
.unwrap()
|
||||||
|
.verify(
|
||||||
|
padding, &verify_hash, signature
|
||||||
|
);
|
||||||
if verify_result.is_err() {
|
if verify_result.is_err() {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
12
src/tls.rs
12
src/tls.rs
|
@ -36,7 +36,6 @@ use crate::parse::{
|
||||||
};
|
};
|
||||||
use crate::buffer::TlsBuffer;
|
use crate::buffer::TlsBuffer;
|
||||||
use crate::session::{Session, TlsRole};
|
use crate::session::{Session, TlsRole};
|
||||||
use crate::certificate::validate_root_certificate;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -468,10 +467,11 @@ impl<R: 'static + RngCore + CryptoRng> TlsSocket<R> {
|
||||||
|
|
||||||
// TODO: Replace this block after implementing a proper
|
// TODO: Replace this block after implementing a proper
|
||||||
// certificate verification procdeure
|
// certificate verification procdeure
|
||||||
match validate_root_certificate(cert) {
|
// match validate_root_certificate(cert) {
|
||||||
Ok(true) => {},
|
// Ok(true) => {},
|
||||||
_ => panic!("Certificate does not match")
|
// _ => panic!("Certificate does not match")
|
||||||
}
|
// }
|
||||||
|
cert.validate_self_signed_signature().expect("Signature mismatched");
|
||||||
|
|
||||||
// Update session TLS state to WAIT_CV
|
// Update session TLS state to WAIT_CV
|
||||||
// Length of handshake header is 4
|
// Length of handshake header is 4
|
||||||
|
@ -484,7 +484,7 @@ impl<R: 'static + RngCore + CryptoRng> TlsSocket<R> {
|
||||||
self.session.borrow_mut()
|
self.session.borrow_mut()
|
||||||
.client_update_for_wait_cert_cr(
|
.client_update_for_wait_cert_cr(
|
||||||
&cert_slice,
|
&cert_slice,
|
||||||
cert.return_rsa_public_key().unwrap()
|
cert.get_cert_public_key().unwrap()
|
||||||
);
|
);
|
||||||
log::info!("Received WAIT_CERT_CR");
|
log::info!("Received WAIT_CERT_CR");
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue