use pgp::{
composed::SignedPublicKey,
crypto::ecc_curve::ECCCurve,
packet::{PublicKey, Signature},
types::{EcdsaPublicParams, EddsaLegacyPublicParams, PublicParams},
};
use crate::{
certificate::Certificate,
model::info::{print::print_cert_info, transform::cert_to_info},
signature::{merge_unhashed, signature_bytes_eq},
};
pub(crate) fn newer<'a>(a: &'a Signature, b: &'a Signature) -> &'a Signature {
if a.created() > b.created() { a } else { b }
}
pub(crate) fn algo_name(pp: &PublicParams) -> String {
match pp {
PublicParams::RSA(key) => {
use rsa::traits::PublicKeyParts;
format!("RSA({})", key.key.n().to_bytes_be().len() * 8)
}
PublicParams::DSA(key) => {
format!("DSA({})", key.key.y().to_bytes_be().len() * 8)
}
PublicParams::Elgamal(_) => "Elgamal".to_string(),
PublicParams::ECDH(params) => {
format!("ECDH/{}", params.curve().name())
}
PublicParams::ECDSA(params) => {
let curve = match params {
EcdsaPublicParams::P256 { .. } => ECCCurve::P256,
EcdsaPublicParams::P384 { .. } => ECCCurve::P384,
EcdsaPublicParams::P521 { .. } => ECCCurve::P521,
EcdsaPublicParams::Secp256k1 { .. } => ECCCurve::Secp256k1,
EcdsaPublicParams::Unsupported { curve, .. } => curve.clone(),
};
format!("ECDSA/{}", curve.name())
}
PublicParams::EdDSALegacy(EddsaLegacyPublicParams::Ed25519 { .. }) => {
"EdDSA/Curve25519".to_string()
}
PublicParams::Ed25519(_) => "Ed25519".to_string(),
PublicParams::X25519(_) => "X25519".to_string(),
PublicParams::Ed448(_) => "Ed448".to_string(),
PublicParams::X448(_) => "X448".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::MlKem768X25519(_) => "ML-KEM-768+X25519".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::MlKem1024X448(_) => "ML-KEM-1024+X448".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::MlDsa65Ed25519(_) => "ML-DSA-65+Ed25519".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::MlDsa87Ed448(_) => "ML-DSA-87+Ed448".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::SlhDsaShake128s(_) => "SLH-DSA-SHAKE-128s".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::SlhDsaShake128f(_) => "SLH-DSA-SHAKE-128f".to_string(),
#[cfg(feature = "draft-pqc")]
PublicParams::SlhDsaShake256s(_) => "SLH-DSA-SHAKE-256s".to_string(),
_ => format!("{pp:?}"),
}
}
pub fn print_cert(cert: &Certificate, verbose: bool, ordered: bool) {
let ci = cert_to_info(cert, ordered);
print_cert_info(&ci, verbose, ordered);
}
pub(crate) fn verify_signature(sig: &Signature, public: &PublicKey) -> bool {
sig.verify_key(public).is_ok()
}
fn dedup(sigs: &mut Vec<Signature>) {
fn dedup_inner(sigs: &mut [Signature]) -> Option<usize> {
for pos in 0..sigs.len() {
for check in pos + 1..sigs.len() {
if signature_bytes_eq(&sigs[pos], &sigs[check]) {
let chk = sigs[check].clone();
merge_unhashed(&mut sigs[pos], &chk);
return Some(check);
}
}
}
None
}
while let Some(pos) = dedup_inner(sigs) {
sigs.remove(pos);
}
}
pub fn canonicalize(spk: &mut SignedPublicKey) {
dedup(&mut spk.details.revocation_signatures);
dedup(&mut spk.details.direct_signatures);
for sk in &mut spk.public_subkeys {
dedup(&mut sk.signatures);
}
for user in &mut spk.details.users {
dedup(&mut user.signatures);
}
for ua in &mut spk.details.user_attributes {
dedup(&mut ua.signatures);
}
}