use crate::error::AlipayResult;
use md5::{Digest, Md5};
use openssl::{
nid::Nid,
x509::{X509NameEntries, X509},
};
use std::fs;
pub(crate) fn get_private_key_from_file(key_path: &str) -> AlipayResult<String> {
let private_key = fs::read_to_string(key_path)?;
Ok(private_key)
}
pub(crate) fn get_cert_sn(cert_path: &str) -> AlipayResult<String> {
let cert = fs::read_to_string(cert_path)?;
get_cert_sn_from_content(cert)
}
pub(crate) fn get_cert_sn_from_content(content: String) -> AlipayResult<String> {
let ssl = X509::from_pem(content.as_bytes())?;
let issuer = iter2string(ssl.issuer_name().entries())?;
let serial_number = ssl.serial_number().to_bn()?.to_dec_str()?;
let mut hasher = Md5::new();
hasher.update((issuer + &serial_number).as_bytes());
let res = hasher.finalize();
Ok(hex::encode(&res[..]))
}
pub(crate) fn get_root_cert_sn_from_content(cert_content: String) -> AlipayResult<String> {
let certificate_end = "-----END CERTIFICATE-----";
let mut array: Vec<&str> = cert_content.split(certificate_end).collect();
let mut i = 0;
while i < array.len() {
if array[i].is_empty() {
array.remove(i);
} else {
i += 1;
}
}
let mut sn: String = String::new();
for cert in array {
let c = cert.to_string() + certificate_end;
let ssl = X509::from_pem(c.as_bytes())?;
if ssl.signature_algorithm().object().nid() == Nid::SHA256WITHRSAENCRYPTION
|| ssl.signature_algorithm().object().nid() == Nid::SHA1WITHRSAENCRYPTION
{
let res = get_cert_sn_from_content(c)?;
if sn.is_empty() {
sn = res;
} else {
sn = sn + "_" + &res;
}
}
}
Ok(sn)
}
pub(crate) fn get_root_cert_sn(cert_path: &str) -> AlipayResult<String> {
let cert_content = fs::read_to_string(cert_path)?;
get_root_cert_sn_from_content(cert_content)
}
fn iter2string(iter: X509NameEntries) -> AlipayResult<String> {
let mut string: String = String::from("");
for value in iter {
let data = value.data().as_utf8()?.to_string();
let key = value.object().nid().short_name()?.to_owned();
string.insert_str(0, &(key + "=" + &data + ","));
}
string.pop();
Ok(string)
}