#[cfg(any(feature = "openssl", feature = "nss"))]
use synta::ObjectIdentifier;
#[cfg(any(feature = "openssl", feature = "nss"))]
pub(crate) fn pkcs8_key_oid(pkcs8_der: &[u8]) -> Option<ObjectIdentifier> {
crate::pkcs8_types::PrivateKeyInfo::from_der(pkcs8_der)
.ok()
.map(|pki| pki.private_key_algorithm.algorithm)
}
#[cfg(any(feature = "openssl", feature = "nss"))]
pub(crate) fn key_type_from_oid(oid: &ObjectIdentifier) -> &'static str {
use crate::names;
let comps = oid.components();
if comps.len() == 9 && comps.starts_with(crate::oids::COMPOSITE_MLDSA_ARC) {
return "composite-mldsa";
}
match crate::identify_public_key_algorithm(oid) {
Some(names::RSA) => "rsa",
Some(names::ECDSA) => "ec",
Some(names::ED25519) => "ed25519",
Some(names::ED448) => "ed448",
Some(names::DSA) => "dsa",
Some(names::ML_DSA_44) => "ml-dsa-44",
Some(names::ML_DSA_65) => "ml-dsa-65",
Some(names::ML_DSA_87) => "ml-dsa-87",
Some(names::ML_KEM_512) => "ml-kem-512",
Some(names::ML_KEM_768) => "ml-kem-768",
Some(names::ML_KEM_1024) => "ml-kem-1024",
None | Some(_) => "unknown",
}
}
#[cfg(any(feature = "openssl", feature = "nss"))]
pub(crate) fn key_type_from_pkcs8(pkcs8_der: &[u8]) -> &'static str {
pkcs8_key_oid(pkcs8_der)
.as_ref()
.map(key_type_from_oid)
.unwrap_or("unknown")
}
#[cfg(any(feature = "openssl", feature = "nss"))]
use synta::{Decoder, Encoding};
#[cfg(all(feature = "nss", not(feature = "openssl")))]
pub(crate) fn sig_alg_der_from_pkcs8(pkcs8_der: &[u8], hash_algo: &str) -> Option<Vec<u8>> {
use synta::{Encoding, Integer};
let mut dec = synta::Decoder::new(pkcs8_der, Encoding::Der);
dec.read_tag().ok()?;
dec.read_length().ok()?.definite().ok()?;
let _: Integer = dec.decode().ok()?;
let alg_start = dec.position();
dec.read_tag().ok()?;
let alg_content_len = dec.read_length().ok()?.definite().ok()?;
let alg_end = dec.position() + alg_content_len;
let mut alg_dec = synta::Decoder::new(&pkcs8_der[alg_start..alg_end], Encoding::Der);
alg_dec.read_tag().ok()?; alg_dec.read_length().ok()?.definite().ok()?; let key_oid: synta::ObjectIdentifier = alg_dec.decode().ok()?;
crate::signing_algorithm_der(&key_oid, hash_algo)
}
#[cfg(any(feature = "openssl", feature = "nss"))]
pub(crate) fn split_alg_id<E>(
der: &[u8],
to_err: impl Fn(synta::Error) -> E,
) -> Result<(ObjectIdentifier, &[u8], &[u8]), E> {
let mut outer = Decoder::new(der, Encoding::Der);
outer.read_tag().map_err(&to_err)?;
let seq_len = outer
.read_length()
.and_then(|l| l.definite())
.map_err(&to_err)?;
let seq_start = outer.position();
let seq_body = &der[seq_start..seq_start + seq_len];
let mut inner = Decoder::new(seq_body, Encoding::Der);
inner.read_tag().map_err(&to_err)?;
let oid_len = inner
.read_length()
.and_then(|l| l.definite())
.map_err(&to_err)?;
let oid_value_start = inner.position();
let oid_value = &seq_body[oid_value_start..oid_value_start + oid_len];
let mut inner2 = Decoder::new(seq_body, Encoding::Der);
let oid: ObjectIdentifier = inner2.decode().map_err(&to_err)?;
let params_start = inner2.position();
Ok((oid, oid_value, &seq_body[params_start..]))
}