cert: add more sig alg

This commit is contained in:
occheung 2020-11-04 17:45:23 +08:00
parent bfc13dcebc
commit 7231438269
7 changed files with 507 additions and 121 deletions

View File

@ -69,6 +69,10 @@ optional = true
version = "0.7.3" version = "0.7.3"
optional = true optional = true
[dependencies.hex-literal]
version = "0.3.1"
optional = true
[features] [features]
default = [] default = []
std = [ "simple_logger", "rand" ] std = [ "simple_logger", "rand", "hex-literal" ]

View File

@ -4,13 +4,19 @@ use num_enum::TryFromPrimitive;
use generic_array::GenericArray; 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::Error as TlsError; use crate::Error as TlsError;
use crate::session::CertificatePublicKey; use crate::session::CertificatePublicKey;
use crate::oid::*;
use crate::fake_rng::FakeRandom;
use sha1::{Sha1, Digest}; use sha1::{Sha1, Digest};
use sha2::{Sha224, Sha256, Sha384, Sha512};
use rsa::{PublicKey, RSAPublicKey, PaddingScheme, BigUint, Hash}; use rsa::{PublicKey, RSAPublicKey, PaddingScheme, BigUint, Hash};
use alloc::vec::Vec; use alloc::vec::Vec;
use heapless::{ Vec as HeaplessVec, consts::* };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Certificate<'a> { pub struct Certificate<'a> {
@ -143,6 +149,7 @@ pub struct AlgorithmIdentifier<'a> {
// TODO: MOve this to impl block of Certificate // TODO: MOve this to impl block of Certificate
// Verify self-signed root certificate parsed 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> { pub fn validate_root_certificate(cert: &Certificate) -> Result<bool, TlsError> {
// Verify Signature // Verify Signature
match cert.signature_algorithm.algorithm { match cert.signature_algorithm.algorithm {
@ -150,10 +157,15 @@ pub fn validate_root_certificate(cert: &Certificate) -> Result<bool, TlsError> {
let mut hasher = Sha1::new(); let mut hasher = Sha1::new();
hasher.update(cert.tbs_certificate_encoded); hasher.update(cert.tbs_certificate_encoded);
log::info!("Created hashed");
let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key( let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key(
cert.tbs_certificate.subject_public_key_info.subject_public_key cert.tbs_certificate.subject_public_key_info.subject_public_key
).map_err(|_| TlsError::ParsingError)?; ).map_err(|_| TlsError::ParsingError)?;
log::info!("Modulus: {:?}", modulus);
log::info!("Exponent: {:?}", exponent);
let rsa_public_key = RSAPublicKey::new( let rsa_public_key = RSAPublicKey::new(
BigUint::from_bytes_be(modulus), BigUint::from_bytes_be(modulus),
BigUint::from_bytes_be(exponent) BigUint::from_bytes_be(exponent)
@ -164,16 +176,17 @@ pub fn validate_root_certificate(cert: &Certificate) -> Result<bool, TlsError> {
padding, padding,
&hasher.finalize(), &hasher.finalize(),
cert.signature_value cert.signature_value
); ).unwrap();
Ok(verify_result.is_ok()) 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, ()> {
if self.signature_algorithm.algorithm != oid::SHA1_WITH_RSA_ENCRYPTION { if self.signature_algorithm.algorithm != SHA1_WITH_RSA_ENCRYPTION {
return Err(()); return Err(());
} }
let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key( let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key(
@ -195,25 +208,31 @@ impl<'a> Certificate<'a> {
// 3 possibilities: RSA_ENCRYPTION, ID_EC_PUBLIC_KEY, and EdDSA25519 // 3 possibilities: RSA_ENCRYPTION, ID_EC_PUBLIC_KEY, and EdDSA25519
match algorithm_identifier.algorithm { match algorithm_identifier.algorithm {
oid::RSA_ENCRYPTION => { RSA_ENCRYPTION => {
log::info!("Chose rsa encryption");
log::info!("Entire key: {:X?}", self.tbs_certificate.subject_public_key_info.subject_public_key);
let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key( let (_, (modulus, exponent)) = parse_asn1_der_rsa_public_key(
self.tbs_certificate.subject_public_key_info.subject_public_key self.tbs_certificate.subject_public_key_info.subject_public_key
).map_err(|_| ())?; ).map_err(|_| ())?;
log::info!("Modulus: {:X?}\n, Exponent: {:X?}", modulus, exponent);
log::info!("Big int modulus: {:?}", BigUint::from_bytes_be(modulus));
let public_key = RSAPublicKey::new( let public_key = RSAPublicKey::new(
BigUint::from_bytes_be(modulus), BigUint::from_bytes_be(modulus),
BigUint::from_bytes_be(exponent) BigUint::from_bytes_be(exponent)
).map_err(|_| ())?; ).map_err(|_| ())?;
log::info!("Got rsa key parts");
Ok( Ok(
CertificatePublicKey::RSA { CertificatePublicKey::RSA {
cert_rsa_public_key: public_key cert_rsa_public_key: public_key
} }
) )
}, },
oid::ID_EC_PUBLIC_KEY => { ID_EC_PUBLIC_KEY => {
// Check the type of EC, only support secp256r1 // Check the type of EC, only support secp256r1
// Will definitely NOT support custom curve // Will definitely NOT support custom curve
if algorithm_identifier.parameters != oid::PRIME256V1 { if algorithm_identifier.parameters != PRIME256V1 {
return Err(()); return Err(());
} }
let p256_verify_key = p256::ecdsa::VerifyKey::from_encoded_point( let p256_verify_key = p256::ecdsa::VerifyKey::from_encoded_point(
@ -229,7 +248,7 @@ impl<'a> Certificate<'a> {
} }
) )
}, },
oid::ID_EDDSA_25519 => { ID_EDDSA_25519 => {
let ed25519_public_key = ed25519_dalek::PublicKey::from_bytes( let ed25519_public_key = ed25519_dalek::PublicKey::from_bytes(
public_key_info.subject_public_key public_key_info.subject_public_key
).map_err(|_| ())?; ).map_err(|_| ())?;
@ -242,55 +261,159 @@ impl<'a> Certificate<'a> {
_ => Err(()) _ => Err(())
} }
} }
// Validate certificate's signature
// Do not be confused with TLS Certificate Verify
pub fn validate_signature(&self) -> Result<(), TlsError> {
let sig_alg = self.signature_algorithm.algorithm;
// Prepare hash value
match sig_alg {
SHA1_WITH_RSA_ENCRYPTION => {
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
SHA224_WITH_RSA_ENCRYPTION => {
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
SHA256_WITH_RSA_ENCRYPTION => {
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
SHA384_WITH_RSA_ENCRYPTION => {
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
SHA512_WITH_RSA_ENCRYPTION => {
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
// Further process the signature algorithm before creating digests
// i.e. PSS, OAEP
ID_RSASSA_PSS => {
let (_, (hash_alg, salt_len)) = parse_rsa_ssa_pss_parameters(
self.signature_algorithm.parameters
).unwrap();
match hash_alg {
ID_SHA1 => {
let padding = PaddingScheme::new_pss_with_salt::<Sha1, FakeRandom>(
FakeRandom {},
salt_len
);
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
ID_SHA224 => {
let padding = PaddingScheme::new_pss_with_salt::<Sha224, FakeRandom>(
FakeRandom {},
salt_len
);
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
ID_SHA256 => {
let padding = PaddingScheme::new_pss_with_salt::<Sha256, FakeRandom>(
FakeRandom {},
salt_len
);
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
ID_SHA384 => {
let padding = PaddingScheme::new_pss_with_salt::<Sha384, FakeRandom>(
FakeRandom {},
salt_len
);
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
ID_SHA512 => {
let padding = PaddingScheme::new_pss_with_salt::<Sha512, FakeRandom>(
FakeRandom {},
salt_len
);
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()
.map_err(|_| TlsError::SignatureValidationError)?
.verify(padding, &hashed, sig)
.map_err(|_| TlsError::SignatureValidationError)
},
_ => todo!()
}
}
_ => todo!()
}
}
} }
// TODO: Centralize OID, another OID module can be found in `parse.rs`
mod oid {
// RSA public key
pub const RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01];
// EC public key for secp256r1
pub const ID_EC_PUBLIC_KEY: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01];
pub const PRIME256V1: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07];
// EDDSA25519 public key, signature algorithm
pub const ID_EDDSA_25519: &'static [u8] =
&[0x2B, 0x65, 0x70];
// Supported Signature Algorithm (RFC 4055, RFC 3279)
// PKCS #1 v1.5
pub const SHA1_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05];
pub const SHA224_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E];
pub const SHA256_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B];
pub const SHA384_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C];
pub const SHA512_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D];
// RSASSA_PSS
pub const ID_RSASSA_PSS: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A];
// RSAES_OAEP
pub const ID_RSAES_OAEP: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x07];
// ECDSA signature algorithms, from OID repo
pub const ECDSA_WITH_SHA1: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01];
pub const ECDSA_WITH_SHA224: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01];
pub const ECDSA_WITH_SHA256: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02];
pub const ECDSA_WITH_SHA384: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03];
pub const ECDSA_WITH_SHA512: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04];
}

View File

@ -10,6 +10,7 @@ pub mod key;
pub mod session; pub mod session;
pub mod certificate; pub mod certificate;
pub mod fake_rng; pub mod fake_rng;
pub mod oid;
// TODO: Implement errors // TODO: Implement errors
// Details: Encapsulate smoltcp & nom errors // Details: Encapsulate smoltcp & nom errors

View File

@ -78,44 +78,10 @@ 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 (rest, result) = parse_asn1_der_certificate(&CERTIFICATE).unwrap(); let (_, certificate) = parse_asn1_der_certificate(&RSA_PSS_CERT).unwrap();
// println!(
// "{:X?}\n{:X?}",
// rest,
// result
// );
use rsa::RSAPublicKey;
use rsa::BigUint;
use rsa::PaddingScheme;
use rsa::Hash;
use rsa::PublicKey;
let mut rng = OsRng; certificate.validate_signature().unwrap();
let public_key = RSAPublicKey::new(
BigUint::from_bytes_be(&PUBLIC_KEY),
BigUint::from_bytes_be(&[01, 00 ,01])
).unwrap();
println!("{:X?}", public_key);
let transcript_hash = sha2::Sha256::new()
.chain(&CLIENT_HELLO)
.chain(&SERVER_HELLO)
.chain(&ENCRYPTED_EXTENSION)
.chain(&CERTIFICATE)
.finalize();
println!("Transcript: {:X?}", transcript_hash);
let hash = sha2::Sha256::new()
.chain(&MANY20)
.chain(&CONTEXT_STRING)
.chain(&SINGLE_ZERO_BYTE)
.chain(&transcript_hash)
.finalize();
println!("Hash: {:X?}", hash);
let padding = PaddingScheme::new_pss::<sha2::Sha256, OsRng>(rng);
println!("Sig Verify: {:?}", public_key.verify(padding, &hash, &VERIFY_SIGNATURE));
} }
const CLIENT_HELLO: [u8; 0xCA] = [ const CLIENT_HELLO: [u8; 0xCA] = [
@ -149,3 +115,9 @@ const SIGNATURE: [u8; 256] = [
const VERIFY_SIGNATURE: [u8; 256] = [ const VERIFY_SIGNATURE: [u8; 256] = [
0x17, 0xfe, 0xb5, 0x33, 0xca, 0x6d, 0x00, 0x7d, 0x00, 0x58, 0x25, 0x79, 0x68, 0x42, 0x4b, 0xbc, 0x3a, 0xa6, 0x90, 0x9e, 0x9d, 0x49, 0x55, 0x75, 0x76, 0xa5, 0x20, 0xe0, 0x4a, 0x5e, 0xf0, 0x5f, 0x0e, 0x86, 0xd2, 0x4f, 0xf4, 0x3f, 0x8e, 0xb8, 0x61, 0xee, 0xf5, 0x95, 0x22, 0x8d, 0x70, 0x32, 0xaa, 0x36, 0x0f, 0x71, 0x4e, 0x66, 0x74, 0x13, 0x92, 0x6e, 0xf4, 0xf8, 0xb5, 0x80, 0x3b, 0x69, 0xe3, 0x55, 0x19, 0xe3, 0xb2, 0x3f, 0x43, 0x73, 0xdf, 0xac, 0x67, 0x87, 0x06, 0x6d, 0xcb, 0x47, 0x56, 0xb5, 0x45, 0x60, 0xe0, 0x88, 0x6e, 0x9b, 0x96, 0x2c, 0x4a, 0xd2, 0x8d, 0xab, 0x26, 0xba, 0xd1, 0xab, 0xc2, 0x59, 0x16, 0xb0, 0x9a, 0xf2, 0x86, 0x53, 0x7f, 0x68, 0x4f, 0x80, 0x8a, 0xef, 0xee, 0x73, 0x04, 0x6c, 0xb7, 0xdf, 0x0a, 0x84, 0xfb, 0xb5, 0x96, 0x7a, 0xca, 0x13, 0x1f, 0x4b, 0x1c, 0xf3, 0x89, 0x79, 0x94, 0x03, 0xa3, 0x0c, 0x02, 0xd2, 0x9c, 0xbd, 0xad, 0xb7, 0x25, 0x12, 0xdb, 0x9c, 0xec, 0x2e, 0x5e, 0x1d, 0x00, 0xe5, 0x0c, 0xaf, 0xcf, 0x6f, 0x21, 0x09, 0x1e, 0xbc, 0x4f, 0x25, 0x3c, 0x5e, 0xab, 0x01, 0xa6, 0x79, 0xba, 0xea, 0xbe, 0xed, 0xb9, 0xc9, 0x61, 0x8f, 0x66, 0x00, 0x6b, 0x82, 0x44, 0xd6, 0x62, 0x2a, 0xaa, 0x56, 0x88, 0x7c, 0xcf, 0xc6, 0x6a, 0x0f, 0x38, 0x51, 0xdf, 0xa1, 0x3a, 0x78, 0xcf, 0xf7, 0x99, 0x1e, 0x03, 0xcb, 0x2c, 0x3a, 0x0e, 0xd8, 0x7d, 0x73, 0x67, 0x36, 0x2e, 0xb7, 0x80, 0x5b, 0x00, 0xb2, 0x52, 0x4f, 0xf2, 0x98, 0xa4, 0xda, 0x48, 0x7c, 0xac, 0xde, 0xaf, 0x8a, 0x23, 0x36, 0xc5, 0x63, 0x1b, 0x3e, 0xfa, 0x93, 0x5b, 0xb4, 0x11, 0xe7, 0x53, 0xca, 0x13, 0xb0, 0x15, 0xfe, 0xc7, 0xe4, 0xa7, 0x30, 0xf1, 0x36, 0x9f, 0x9e 0x17, 0xfe, 0xb5, 0x33, 0xca, 0x6d, 0x00, 0x7d, 0x00, 0x58, 0x25, 0x79, 0x68, 0x42, 0x4b, 0xbc, 0x3a, 0xa6, 0x90, 0x9e, 0x9d, 0x49, 0x55, 0x75, 0x76, 0xa5, 0x20, 0xe0, 0x4a, 0x5e, 0xf0, 0x5f, 0x0e, 0x86, 0xd2, 0x4f, 0xf4, 0x3f, 0x8e, 0xb8, 0x61, 0xee, 0xf5, 0x95, 0x22, 0x8d, 0x70, 0x32, 0xaa, 0x36, 0x0f, 0x71, 0x4e, 0x66, 0x74, 0x13, 0x92, 0x6e, 0xf4, 0xf8, 0xb5, 0x80, 0x3b, 0x69, 0xe3, 0x55, 0x19, 0xe3, 0xb2, 0x3f, 0x43, 0x73, 0xdf, 0xac, 0x67, 0x87, 0x06, 0x6d, 0xcb, 0x47, 0x56, 0xb5, 0x45, 0x60, 0xe0, 0x88, 0x6e, 0x9b, 0x96, 0x2c, 0x4a, 0xd2, 0x8d, 0xab, 0x26, 0xba, 0xd1, 0xab, 0xc2, 0x59, 0x16, 0xb0, 0x9a, 0xf2, 0x86, 0x53, 0x7f, 0x68, 0x4f, 0x80, 0x8a, 0xef, 0xee, 0x73, 0x04, 0x6c, 0xb7, 0xdf, 0x0a, 0x84, 0xfb, 0xb5, 0x96, 0x7a, 0xca, 0x13, 0x1f, 0x4b, 0x1c, 0xf3, 0x89, 0x79, 0x94, 0x03, 0xa3, 0x0c, 0x02, 0xd2, 0x9c, 0xbd, 0xad, 0xb7, 0x25, 0x12, 0xdb, 0x9c, 0xec, 0x2e, 0x5e, 0x1d, 0x00, 0xe5, 0x0c, 0xaf, 0xcf, 0x6f, 0x21, 0x09, 0x1e, 0xbc, 0x4f, 0x25, 0x3c, 0x5e, 0xab, 0x01, 0xa6, 0x79, 0xba, 0xea, 0xbe, 0xed, 0xb9, 0xc9, 0x61, 0x8f, 0x66, 0x00, 0x6b, 0x82, 0x44, 0xd6, 0x62, 0x2a, 0xaa, 0x56, 0x88, 0x7c, 0xcf, 0xc6, 0x6a, 0x0f, 0x38, 0x51, 0xdf, 0xa1, 0x3a, 0x78, 0xcf, 0xf7, 0x99, 0x1e, 0x03, 0xcb, 0x2c, 0x3a, 0x0e, 0xd8, 0x7d, 0x73, 0x67, 0x36, 0x2e, 0xb7, 0x80, 0x5b, 0x00, 0xb2, 0x52, 0x4f, 0xf2, 0x98, 0xa4, 0xda, 0x48, 0x7c, 0xac, 0xde, 0xaf, 0x8a, 0x23, 0x36, 0xc5, 0x63, 0x1b, 0x3e, 0xfa, 0x93, 0x5b, 0xb4, 0x11, 0xe7, 0x53, 0xca, 0x13, 0xb0, 0x15, 0xfe, 0xc7, 0xe4, 0xa7, 0x30, 0xf1, 0x36, 0x9f, 0x9e
]; ];
const RSA_PSS_CERT: [u8; 0x3AB] =
hex_literal::hex!("308203a73082028fa00302010202146642be8f709457f9cd6eed72051c240a5565138c300d06092a864886f70d01010a30003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e6574301e170d3230313130343039313535325a170d3231313130343039313535325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c136578616d706c652e756c666865696d2e6e657430820122300d06092a864886f70d01010105000382010f003082010a0282010100b5a347b654ca0bad8d56990e70aa7411b78dedc9fd9a6760ee936ea01486238538dbc4d0bc95a1a5f060b6296ba67001f103cfd918ad1ec33a1a680d4e8283a24300391e9a53cd6641fc51f0a984c3cd16542b934a0ec8c3447782542628320d6c24988cf0b7b19bbaba91f1999968def724d8e65b624fbb9826208aece1ee90badda7c6b8a97fc4085299f9d32661a06bc67d2d662e0efcee1df5b6dc1d02e56929d8976441456d0fe50314c9861e9845f75f5dc2ca9828089b5d4bd109d1e8ada8986c5bd68ee004a7bfcb932768023e11fe8e299b25b8774ed8bdbb0f644ddaa83df1ff4e84bfc18d3b815decb5ca4f1db1125df98dba94e4ef5570ec5a510203010001a3533051301d0603551d0e04160414050928eff30f3094f01ddb09f1d7a9193addf854301f0603551d23041830168014050928eff30f3094f01ddb09f1d7a9193addf854300f0603551d130101ff040530030101ff300d06092a864886f70d01010a300003820101002d14281587dc33d4559e77852d17fade1a9f3f0e5af847bde80c921be360d6e3b598dfb50aad706de3832841798b66736b9296a83c06e0078dceabc39760a5bf5eb7a7287859b22e9beb7ebb928b99034d155fd12307ee541ea53979bb8afb62db233dfcf1e16afea5eac33817b8cbb13841cb89e9b65a5a4b08a6c6e3d1e0036bc9576b90cf62437e3ef985f02b88be4e6863068c9bc45dd473763f4cdcfc3bfb8a90d7b3225b67a3a39c6ac446de55596dc135221b4383773ddd9efdcca48f389af9c1c0547e0ada1c14153fc38e02c95e4c37da45af1e6d3b0a6cafb603d95a1c887384b476caf60783835a150ee7fd22b6838ce19adcb2e59572c6349703");
const RSA_PKCS_CERT: [u8; 0x03AB] =
hex_literal::hex!("308203a73082028fa00302010202144a5a52142c495ec189e661457ba0330809c9dede300d06092a864886f70d01010b05003063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d301e170d3230313130343038353031325a170d3231313130343038353031325a3063310b30090603550406130255533113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464311c301a06035504030c13746573742e68656c6c6f776f726c642e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100a665127e115e41937b51f87fa44d9894e52a45479a234110037f8c8ce2de6d263e12e3824d57a39d7386afe35cb926af1d6f593673eae31f1e27b8914895006fc7e5fdac11f369b73741a97663f2bb08edb7ab7c1ccc8be9259ce2c1b9d04ba066e05fd6a440ca99b148ddc95a23432228f5172b32939921f70f4f632691ee19a50d7deffb50cb9f018562c803065ca1f1817f1f93c25b3aa0ef91b2f91ef1c86fd346bc00ac165fbd5abf04d944a58e48fd24959133637a949cb85d498063aa4ed0927327591d125500430fa91782af806d46fe330251103c8139b3bf35034b009748324a0fffac2474eed6f04e8d90582dc6125cce0274305f28e82b5409170203010001a3533051301d0603551d0e04160414a36633b9660897096d8138d4f0281a3b76e6696c301f0603551d23041830168014a36633b9660897096d8138d4f0281a3b76e6696c300f0603551d130101ff040530030101ff300d06092a864886f70d01010b0500038201010090631de179bf4940e636e0e7142d9feb440d818c9ea095b6ae31a4ad9876fbd1c2b6808d2edc60e20b107daaf592d14bb9f1ca37c9d975b0c463478dbac8cb183b90bbaecdb1ad5541674f3ba957f2837e57480c445328f917c8a358fc5465c1f838108f60b59327cd1fba59e1635276372bdb17557b636b59be60b4c6b6cf3ecb9fd40b9469d7bfa4f2053be4c08e2e350453050a076d923923588c7f839c709d31c2296dfd837b850f0ba4b44a36c112b9a6ef7186b090162628367a95fa1673e4362d7a23aebd46a85c69eac76f7194d166c89ce6103c508eb970f35bf0b241cbbae5ddffc5ea6515e5f36a8645dc0c8a48798199f65f01b811bec2f287d5");

81
src/oid.rs Normal file
View File

@ -0,0 +1,81 @@
// RSA public key
pub const RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01];
// EC public key for secp256r1
pub const ID_EC_PUBLIC_KEY: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01];
pub const PRIME256V1: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07];
// EDDSA25519 public key, signature algorithm
pub const ID_EDDSA_25519: &'static [u8] =
&[0x2B, 0x65, 0x70];
// Supported Signature Algorithm (RFC 4055, RFC 3279)
// PKCS #1 v1.5
pub const SHA1_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05];
pub const SHA224_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E];
pub const SHA256_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B];
pub const SHA384_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C];
pub const SHA512_WITH_RSA_ENCRYPTION: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D];
// RSASSA_PSS
pub const ID_RSASSA_PSS: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A];
// RSAES_OAEP
pub const ID_RSAES_OAEP: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x07];
// ECDSA signature algorithms, from OID repo
pub const ECDSA_WITH_SHA1: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01];
pub const ECDSA_WITH_SHA224: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01];
pub const ECDSA_WITH_SHA256: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02];
pub const ECDSA_WITH_SHA384: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03];
pub const ECDSA_WITH_SHA512: &'static [u8] =
&[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04];
// Hash OIDs
pub const ID_SHA1: &'static [u8] =
&[0x2B, 0x0E, 0x03, 0x02, 0x1A];
pub const ID_SHA224: &'static [u8] =
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04];
pub const ID_SHA256: &'static [u8] =
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01];
pub const ID_SHA384: &'static [u8] =
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02];
pub const ID_SHA512: &'static [u8] =
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03];
// Mask Generation Function (mgf1)
pub const ID_MGF1: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x08];
// Algorithm Identifier with specific parameters
pub const ID_P_SPECIFIED: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x09];
// Extensions
pub const CERT_KEY_USAGE: &'static [u8] = &[85, 29, 15]; // 2.5.29.15
pub const CERT_POLICIES: &'static [u8] = &[85, 29, 32]; // 2.5.29.32
pub const CERT_BASIC_CONSTRAINTS: &'static [u8] = &[85, 29, 19]; // 2.5.29.19
pub const CERT_EXT_KEY_USAGE: &'static [u8] = &[85, 29, 37]; // 2.5.29.37
pub const CERT_INHIBIT_ANY_POLICY: &'static [u8] = &[85, 29, 54]; // 2.5.29.54
// Extended Key Extensions
pub const ANY_EXTENDED_KEY_USAGE: &'static [u8] = &[85, 29, 37, 0]; // 2.5.29.37.0
pub const ID_KP_SERVER_AUTH: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 1]; // 1.3.6.1.5.5.7.3.1
pub const ID_KP_CLIENT_AUTH: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 2]; // 1.3.6.1.5.5.7.3.2
pub const ID_KP_CODE_SIGNING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 3]; // 1.3.6.1.5.5.7.3.3
pub const ID_KP_EMAIL_PROTECTION: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 4]; // 1.3.6.1.5.5.7.3.4
pub const ID_KP_TIME_STAMPING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 8]; // 1.3.6.1.5.5.7.3.8
pub const ID_KP_OCSP_SIGNING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 9];

View File

@ -26,6 +26,9 @@ use crate::certificate::{
TBSCertificate as Asn1DerTBSCertificate, TBSCertificate as Asn1DerTBSCertificate,
}; };
use crate::oid;
use crate::oid::*;
use core::convert::TryFrom; use core::convert::TryFrom;
use core::convert::TryInto; use core::convert::TryInto;
@ -650,7 +653,7 @@ pub fn parse_asn1_der_tbs_certificate(bytes: &[u8]) -> IResult<&[u8], Asn1DerTBS
subject_public_key_info, issuer_unique_id, subject_unique_id, extensions subject_public_key_info, issuer_unique_id, subject_unique_id, extensions
)) = complete( )) = complete(
tuple(( tuple((
parse_asn1_der_version, opt(parse_asn1_der_version),
parse_asn1_der_serial_number, parse_asn1_der_serial_number,
parse_asn1_der_algorithm_identifier, parse_asn1_der_algorithm_identifier,
parse_asn1_der_sequence, parse_asn1_der_sequence,
@ -659,10 +662,16 @@ pub fn parse_asn1_der_tbs_certificate(bytes: &[u8]) -> IResult<&[u8], Asn1DerTBS
parse_asn1_der_subject_key_public_info, parse_asn1_der_subject_key_public_info,
opt(parse_asn1_der_bit_string), opt(parse_asn1_der_bit_string),
opt(parse_asn1_der_bit_string), opt(parse_asn1_der_bit_string),
parse_asn1_der_extensions opt(parse_asn1_der_extensions)
)) ))
)(value)?; )(value)?;
log::info!("Parsed tbscert");
let version = version.unwrap_or(Asn1DerVersion::v1);
let extensions = extensions.unwrap_or(
Asn1DerExtensions { extensions: Vec::new() }
);
Ok(( Ok((
rest, rest,
Asn1DerTBSCertificate { Asn1DerTBSCertificate {
@ -687,7 +696,7 @@ pub fn parse_asn1_der_version(bytes: &[u8]) -> IResult<&[u8], Asn1DerVersion> {
let (rest, (tag_val, _, value)) = parse_asn1_der_object(bytes)?; let (rest, (tag_val, _, value)) = parse_asn1_der_object(bytes)?;
// Verify the tag is indeed 0xA0 // Verify the tag is indeed 0xA0
if tag_val != 0xA0 { if tag_val != 0xA0 {
return Err(nom::Err::Failure((&[], ErrorKind::Verify))); return Err(nom::Err::Error((bytes, ErrorKind::Verify)));
} }
// Parse the encapsulated INTEGER, force completeness // Parse the encapsulated INTEGER, force completeness
let (_, integer) = complete(parse_asn1_der_integer)(value)?; let (_, integer) = complete(parse_asn1_der_integer)(value)?;
@ -759,13 +768,11 @@ pub fn parse_asn1_der_algorithm_identifier(bytes: &[u8]) -> IResult<&[u8], Asn1D
if tag_val != 0x30 { if tag_val != 0x30 {
return Err(nom::Err::Failure((&[], ErrorKind::Verify))); return Err(nom::Err::Failure((&[], ErrorKind::Verify)));
} }
// Parse OID and then optionl parameters // Parse OID, leave the rest as optionl parameters
let (_, (oid, (_, _, optional_param))) = complete( let (optional_param, oid) = parse_asn1_der_oid(value)?;
tuple(( log::info!("OID: {:X?}", oid);
parse_asn1_der_oid, log::info!("Optional parameter: {:X?}", optional_param);
parse_asn1_der_object
))
)(value)?;
Ok(( Ok((
rest, rest,
Asn1DerAlgId { Asn1DerAlgId {
@ -841,6 +848,8 @@ pub fn parse_asn1_der_subject_key_public_info(bytes: &[u8]) -> IResult<&[u8], As
parse_asn1_der_bit_string, parse_asn1_der_bit_string,
)) ))
)(value)?; )(value)?;
log::info!("Parsed subject key alg ident: {:?}", algorithm);
log::info!("Parsed key: {:X?}", subject_public_key);
Ok(( Ok((
rest, rest,
Asn1DerSubjectPublicKeyInfo { Asn1DerSubjectPublicKeyInfo {
@ -852,6 +861,7 @@ 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) // Parser for extensions (Context-specific Sequence: 0xA3, then universal Sequence: 0x30)
pub fn parse_asn1_der_extensions(bytes: &[u8]) -> IResult<&[u8], Asn1DerExtensions> { 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)?; let (rest, (tag_val, _, value)) = parse_asn1_der_object(bytes)?;
// Verify the tag_val is indeed 0xA3 // Verify the tag_val is indeed 0xA3
if tag_val != 0xA3 { if tag_val != 0xA3 {
@ -1135,19 +1145,188 @@ pub fn parse_asn1_der_rsa_public_key(bytes: &[u8]) -> IResult<&[u8], (&[u8], &[u
)) ))
} }
mod oid { /*
// Extensions * Prasers for PSS/OAEP signature algorithms parameters in certificate
pub const CERT_KEY_USAGE: &'static [u8] = &[85, 29, 15]; // 2.5.29.15 */
pub const CERT_POLICIES: &'static [u8] = &[85, 29, 32]; // 2.5.29.32
pub const CERT_BASIC_CONSTRAINTS: &'static [u8] = &[85, 29, 19]; // 2.5.29.19 // Take addition parameter of PSS algorithm idenfier
pub const CERT_EXT_KEY_USAGE: &'static [u8] = &[85, 29, 37]; // 2.5.29.37 // Return hash function OID
pub const CERT_INHIBIT_ANY_POLICY: &'static [u8] = &[85, 29, 54]; // 2.5.29.54 pub fn parse_rsa_ssa_pss_parameters(params: &[u8]) -> IResult<&[u8], (&[u8], usize)> {
// Extended Key Extensions // Handle the case where there is literally no optional parameter
pub const ANY_EXTENDED_KEY_USAGE: &'static [u8] = &[85, 29, 37, 0]; // 2.5.29.37.0 // Return default SHA1 OID and 20 salt length
pub const ID_KP_SERVER_AUTH: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 1]; // 1.3.6.1.5.5.7.3.1 if params.len() == 0 {
pub const ID_KP_CLIENT_AUTH: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 2]; // 1.3.6.1.5.5.7.3.2 return Ok((&[], (ID_SHA1, 20)))
pub const ID_KP_CODE_SIGNING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 3]; // 1.3.6.1.5.5.7.3.3 }
pub const ID_KP_EMAIL_PROTECTION: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 4]; // 1.3.6.1.5.5.7.3.4
pub const ID_KP_TIME_STAMPING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 8]; // 1.3.6.1.5.5.7.3.8 // Parse as RSASSA-PSS-params (Sequence: 0x30)
pub const ID_KP_OCSP_SIGNING: &'static [u8] = &[43, 6, 1, 5, 5, 7, 3, 9]; // 1.3.6.1.5.5.7.3.9 let (_, rsa_ssa_params) = complete(
parse_asn1_der_sequence
)(params)?;
let (_, (hash_alg, mgf_hash_alg, salt_len, _)) = complete(
tuple((
opt(parse_hash_algorithm),
opt(parse_mask_gen_algorithm),
opt(parse_salt_length),
opt(parse_trailer_field)
))
)(params)?;
let hash_alg = hash_alg.unwrap_or(
Asn1DerAlgId { algorithm: ID_SHA1, parameters: &[] }
);
let mgf_hash_alg = mgf_hash_alg.unwrap_or(
Asn1DerAlgId { algorithm: ID_SHA1, parameters: &[] }
);
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
if hash_alg.algorithm != mgf_hash_alg.algorithm {
todo!()
}
// Parse encoded salt length integer into usize
if salt_len.len() > core::mem::size_of::<usize>() {
todo!()
}
let mut array_buffer: [u8; core::mem::size_of::<usize>()] = [0; core::mem::size_of::<usize>()];
array_buffer[(8-salt_len.len())..].clone_from_slice(salt_len);
let salt_len = usize::from_be_bytes(array_buffer);
Ok((
&[],
(
hash_alg.algorithm,
salt_len
)
))
}
fn parse_hash_algorithm(bytes: &[u8]) -> IResult<&[u8], Asn1DerAlgId> {
// Parse HashAlgorithm [0]
let (rest, (tag_val, _, hash_alg)) = parse_asn1_der_object(bytes)?;
// Verify the tag is indeed 0xA0
if tag_val != 0xA0 {
return Err(nom::Err::Error((bytes, ErrorKind::Verify)));
}
// Parse the encapsulated algorithm identifier, force completeness
let (_, hash_alg) = complete(parse_asn1_der_algorithm_identifier)(hash_alg)?;
Ok((
rest, hash_alg
))
}
fn parse_mask_gen_algorithm(bytes: &[u8]) -> IResult<&[u8], Asn1DerAlgId> {
// Parse MaskGenAlgorithm [1]
let (rest, (tag_val, _, mask_gen_alg)) = parse_asn1_der_object(bytes)?;
// Verify the tag is indeed 0xA1
if tag_val != 0xA1 {
return Err(nom::Err::Error((bytes, 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
)?;
Ok((
rest, mgf_hash_alg
))
}
fn parse_salt_length(bytes: &[u8]) -> IResult<&[u8], &[u8]> {
// Parse salt length [2]
let (rest, (tag_val, _, salt_len)) = parse_asn1_der_object(bytes)?;
if tag_val != 0xA2 {
return Err(nom::Err::Error((bytes, ErrorKind::Verify)));
}
// Parse the encapsulated integer, force completeness
let (_, salt_len) = complete(
parse_asn1_der_integer
)(salt_len)?;
Ok((
rest, salt_len
))
}
fn parse_trailer_field(bytes: &[u8]) -> IResult<&[u8], ()> {
// Parse trailer field [3]
let (_, (tag_val, _, trailer_field)) = complete(
parse_asn1_der_object
)(bytes)?;
if tag_val != 0xA3 {
return Err(nom::Err::Error((bytes, 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)));
}
Ok((
&[], ()
))
} }

View File

@ -1455,3 +1455,29 @@ pub(crate) enum CertificatePublicKey {
cert_eddsa_key: ed25519_dalek::PublicKey cert_eddsa_key: ed25519_dalek::PublicKey
} }
} }
impl CertificatePublicKey {
pub(crate) fn get_rsa_public_key(&self) -> Result<&RSAPublicKey, ()> {
if let CertificatePublicKey::RSA { cert_rsa_public_key } = self {
Ok(&cert_rsa_public_key)
} else {
Err(())
}
}
pub(crate) fn get_ecdsa_secp256r1_sha256_verify_key(&self) -> Result<&p256::ecdsa::VerifyKey, ()> {
if let CertificatePublicKey::ECDSA_SECP256R1_SHA256 {
cert_verify_key
} = self {
Ok(&cert_verify_key)
} else {
Err(())
}
}
pub(crate) fn get_ed25519_public_key(&self) -> Result<&ed25519_dalek::PublicKey, ()> {
if let CertificatePublicKey::ED25519 { cert_eddsa_key } = self {
Ok(&cert_eddsa_key)
} else {
Err(())
}
}
}