diff --git a/src/x509.rs b/src/x509.rs index 2ea9f54..dee722a 100644 --- a/src/x509.rs +++ b/src/x509.rs @@ -6,6 +6,7 @@ use std::str::FromStr; use rust_util::XResult; use x509_parser::der_parser::der::parse_der_bitstring; use x509_parser::der_parser::parse_der; +use x509_parser::x509::AlgorithmIdentifier; lazy_static! { static ref OID_COMMON_NAME: Oid<'static> = Oid::from_str("2.5.4.3").unwrap(); @@ -13,6 +14,7 @@ lazy_static! { static ref OID_ECDSA_WITH_SHA256: Oid<'static> = Oid::from_str("1.2.840.10045.4.3.2").unwrap(); static ref OID_EC_PUBLIC_KEY: Oid<'static> = Oid::from_str("1.2.840.10045.2.1").unwrap(); + static ref OID_RSA_PUBLIC_KEY: Oid<'static> = Oid::from_str("1.2.840.113549.1.1.11").unwrap(); static ref OID_SECP256R1: Oid<'static> = Oid::from_str("1.2.840.10045.3.1.7").unwrap(); static ref OID_SECP384R1: Oid<'static> = Oid::from_str("1.3.132.0.34").unwrap(); @@ -25,14 +27,44 @@ pub enum X509IssuerAlgo { EcdsaWithSha256, } +#[derive(Debug, Clone)] pub enum X509EcPublicKeyAlgo { Secp256r1, Secp384r1, Secp521r1, } +#[derive(Debug, Clone)] pub enum X509PublicKeyAlgo { - EcKey(X509EcPublicKeyAlgo) + EcKey(X509EcPublicKeyAlgo), + Rsa, +} + +impl X509PublicKeyAlgo { + pub fn parse<'a>(pem_id: &str, algorithm: &AlgorithmIdentifier<'a>) -> XResult { + let public_key_algo_oid = &algorithm.algorithm; + if public_key_algo_oid == &*OID_EC_PUBLIC_KEY { + let parameters = match &algorithm.parameters { + None => return simple_error!("Cannot find ec public key parameters: {}", pem_id), + Some(parameters) => parameters, + }; + let ec_public_key_algo_oid = opt_result!(parameters.content.as_oid(), "Parse public algo: {}, failed: {}", pem_id); + let ec_public_key_algo = if ec_public_key_algo_oid == &*OID_SECP256R1 { + X509EcPublicKeyAlgo::Secp256r1 + } else if ec_public_key_algo_oid == &*OID_SECP384R1 { + X509EcPublicKeyAlgo::Secp384r1 + } else if ec_public_key_algo_oid == &*OID_SECP521R1 { + X509EcPublicKeyAlgo::Secp521r1 + } else { + return simple_error!("Parse : {}, unknown ec public key algo: {:?}", pem_id, ec_public_key_algo_oid); + }; + Ok(Self::EcKey(ec_public_key_algo)) + } else if public_key_algo_oid == &*OID_RSA_PUBLIC_KEY { + Ok(Self::Rsa) + } else { + simple_error!("Parse cert: {}, unknown public key algo oid: {}", pem_id, public_key_algo_oid) + } + } } #[derive(Debug, Clone)] @@ -40,6 +72,7 @@ pub struct X509Certificate { pub issuer_algo: X509IssuerAlgo, pub common_name: String, pub alt_names: Vec, + pub public_key_algo: X509PublicKeyAlgo, } pub fn parse_x500(pem_id: &str, pem: &str) -> XResult { @@ -75,33 +108,12 @@ pub fn parse_x500(pem_id: &str, pem: &str) -> XResult { } } } - let public_key_algo_oid = &cert.tbs_certificate.subject_pki.algorithm.algorithm; - let public_key_algo = if public_key_algo_oid == &*OID_EC_PUBLIC_KEY { - // TODO ... - let ec_public_key_algo_oid = cert.tbs_certificate.subject_pki.algorithm.parameters.unwrap().content.as_oid().unwrap(); - }; - + let public_key_algo = X509PublicKeyAlgo::parse(pem_id, &cert.tbs_certificate.subject_pki.algorithm)?; Ok(X509Certificate { issuer_algo, common_name, alt_names, + public_key_algo, }) } - -#[test] -fn test_x509() { - let pem = include_str!("sample_cert2.pem"); - let (_, parsed_pem) = parse_x509_pem(pem.as_bytes()).unwrap(); - let (_, cert) = parse_x509_certificate(parsed_pem.contents.as_slice()).unwrap(); - - println!("{:#?}", parse_x500("id", pem)); - - println!("{:?}", cert.tbs_certificate.signature); - println!("{:?}", cert.tbs_certificate.subject_pki); - println!("{:?}", cert.tbs_certificate.subject_pki.algorithm.algorithm); - println!("{:?}", cert.tbs_certificate.subject_pki.algorithm.parameters.unwrap().content.as_oid().unwrap()); - - let a = parse_der(cert.tbs_certificate.subject_pki.subject_public_key.data); - println!("{:?}", a); -} \ No newline at end of file