feat: x509
This commit is contained in:
14
src/sample_cert2.pem
Normal file
14
src/sample_cert2.pem
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICFDCCAXWgAwIBAgIUVHKGvbVXHNU88FnAjfsrXQdGDDMwCgYIKoZIzj0EAwIw
|
||||||
|
ITEfMB0GA1UEAwwWSGF0dGVyIFRlc3QgQ0EgRUMgUm9vdDAeFw0xOTA2MDcwMDAw
|
||||||
|
MDBaFw0zOTA2MDcwMDAwMDBaMCkxJzAlBgNVBAMMHkhhdHRlciBUZXN0IEludGVy
|
||||||
|
bWVkaWF0ZSBFQyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABPoKGtj8lGhDKb+l
|
||||||
|
p2LBIJ7C+UmxiLqg1F0n5w3041lLDq28688HLx6yzFuOnQo6UrbPvjvjifgqukq8
|
||||||
|
upIBlfe6MYh5s8HJytwcutaWFrNMXtW+1jTTno9y0LM8cTPA2KNmMGQwDgYDVR0P
|
||||||
|
AQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHMGwhbHXYJn
|
||||||
|
eh0XlzTk9zSv+jhVMB8GA1UdIwQYMBaAFLshgqxgJX87yP8C1wIFFoSMtQZuMAoG
|
||||||
|
CCqGSM49BAMCA4GMADCBiAJCAcHOv7ETFyrc7dyVBllqC/CPX1SggQ92Zwn8Mzya
|
||||||
|
EW1Y55uJaR/02Q2F+4h4dUtBSLjchyYhWuWC7QD79hFZD6v6AkIAhWZcyoN2n2dG
|
||||||
|
LPoQrggrN+nP/zhUIlqrkwQLni8Jj2FRc1bUnzP4s5t9W6la7q3c6f8Lj+c5lRvW
|
||||||
|
DH970YSv9fA=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
112
src/x509.rs
112
src/x509.rs
@@ -1,35 +1,107 @@
|
|||||||
use x509_parser::parse_x509_certificate;
|
use x509_parser::parse_x509_certificate;
|
||||||
use x509_parser::pem::parse_x509_pem;
|
use x509_parser::pem::parse_x509_pem;
|
||||||
use x509_parser::extensions::ParsedExtension;
|
use x509_parser::extensions::{ParsedExtension, GeneralName};
|
||||||
use x509_parser::der_parser::oid::Oid;
|
use x509_parser::der_parser::oid::Oid;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use rust_util::XResult;
|
||||||
|
use x509_parser::der_parser::der::parse_der_bitstring;
|
||||||
|
use x509_parser::der_parser::parse_der;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref OID_COMMON_NAME: Oid<'static> = Oid::from_str("2.5.4.3").unwrap();
|
static ref OID_COMMON_NAME: Oid<'static> = Oid::from_str("2.5.4.3").unwrap();
|
||||||
static ref OID_RSA_WITH_SHA256: Oid<'static> = Oid::from_str("1.2.840.113549.1.1.11").unwrap();
|
static ref OID_RSA_WITH_SHA256: Oid<'static> = Oid::from_str("1.2.840.113549.1.1.11").unwrap();
|
||||||
|
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_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();
|
||||||
|
static ref OID_SECP521R1: Oid<'static> = Oid::from_str("1.3.132.0.35").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum X509IssuerAlgo {
|
||||||
|
RsaWithSha256,
|
||||||
|
EcdsaWithSha256,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum X509EcPublicKeyAlgo {
|
||||||
|
Secp256r1,
|
||||||
|
Secp384r1,
|
||||||
|
Secp521r1,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum X509PublicKeyAlgo {
|
||||||
|
EcKey(X509EcPublicKeyAlgo)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct X509Certificate {
|
||||||
|
pub issuer_algo: X509IssuerAlgo,
|
||||||
|
pub common_name: String,
|
||||||
|
pub alt_names: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_x500(pem_id: &str, pem: &str) -> XResult<X509Certificate> {
|
||||||
|
let (_, der) = opt_result!(parse_x509_pem(pem.as_bytes()), "Parse pem: {} to der failed: {}", pem_id);
|
||||||
|
let (_, cert) = opt_result!(parse_x509_certificate(der.contents.as_slice()), "Parse cert: {} failed: {}", pem_id);
|
||||||
|
|
||||||
|
let mut common_name = None;
|
||||||
|
cert.subject().iter_common_name().for_each(|c| {
|
||||||
|
if c.attr_type == *OID_COMMON_NAME {
|
||||||
|
common_name = c.attr_value.content.as_str().ok();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let cert_algorithm_oid = &cert.signature_algorithm.algorithm;
|
||||||
|
let issuer_algo = if cert_algorithm_oid == &*OID_RSA_WITH_SHA256 {
|
||||||
|
X509IssuerAlgo::RsaWithSha256
|
||||||
|
} else if cert_algorithm_oid == &*OID_ECDSA_WITH_SHA256 {
|
||||||
|
X509IssuerAlgo::EcdsaWithSha256
|
||||||
|
} else {
|
||||||
|
return simple_error!("Unknown x509 algorithm oid: {:?}", cert_algorithm_oid);
|
||||||
|
};
|
||||||
|
let common_name = match common_name {
|
||||||
|
None => return simple_error!("Cannot find common name from: {}", pem_id),
|
||||||
|
Some(common_name) => common_name.to_string(),
|
||||||
|
};
|
||||||
|
let mut alt_names = vec![];
|
||||||
|
for (oid, ext) in cert.extensions().iter() {
|
||||||
|
if let ParsedExtension::SubjectAlternativeName(san) = ext.parsed_extension() {
|
||||||
|
for name in &san.general_names {
|
||||||
|
match name {
|
||||||
|
GeneralName::DNSName(dns_name) => alt_names.push(dns_name.to_string()),
|
||||||
|
n => warning!("Unknown general name from: {}, name: {:?}", pem_id, n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Ok(X509Certificate {
|
||||||
|
issuer_algo,
|
||||||
|
common_name,
|
||||||
|
alt_names,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_x509() {
|
fn test_x509() {
|
||||||
let pem = include_str!("sample_cert.pem");
|
let pem = include_str!("sample_cert2.pem");
|
||||||
let (_, parsed_pem) = parse_x509_pem(pem.as_bytes()).unwrap();
|
let (_, parsed_pem) = parse_x509_pem(pem.as_bytes()).unwrap();
|
||||||
let (_, cert) = parse_x509_certificate(parsed_pem.contents.as_slice()).unwrap();
|
let (_, cert) = parse_x509_certificate(parsed_pem.contents.as_slice()).unwrap();
|
||||||
// println!("{:?}", cert);
|
|
||||||
// println!("{:#?}", cert.subject().iter_common_name());
|
println!("{:#?}", parse_x500("id", pem));
|
||||||
cert.subject().iter_common_name().for_each(|c| {
|
|
||||||
if c.attr_type == *OID_COMMON_NAME {
|
println!("{:?}", cert.tbs_certificate.signature);
|
||||||
println!("{:?}", c.attr_value.content.as_str().unwrap());
|
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());
|
||||||
// println!("{:#?}", cert.extensions());
|
|
||||||
for (oid, ext) in cert.extensions().iter() {
|
let a = parse_der(cert.tbs_certificate.subject_pki.subject_public_key.data);
|
||||||
match ext.parsed_extension() {
|
println!("{:?}", a);
|
||||||
ParsedExtension::SubjectAlternativeName(san) => {
|
|
||||||
println!("{:?}", san);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("{:?}", cert.signature_algorithm.algorithm);
|
|
||||||
println!("{:?}", cert.signature_algorithm.algorithm.bytes());
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user