use alloc::vec::Vec;
use super::{AnyPublicKey, Error, algorithm_identifier, oid};
use crate::ec::{BoxedEcdsaPrivateKey, CurveId, Ed448PrivateKey, Ed25519PrivateKey};
use crate::hash::{Sha256, Sha384, Sha512};
#[cfg(feature = "mldsa")]
use crate::mldsa::{MlDsa44PrivateKey, MlDsa65PrivateKey, MlDsa87PrivateKey};
#[cfg(any(feature = "mldsa", feature = "slhdsa"))]
use crate::rng::RngCore;
use crate::rsa::BoxedRsaPrivateKey;
#[cfg(feature = "slhdsa")]
use crate::slhdsa;
#[non_exhaustive]
pub enum CertSigner<'a> {
Rsa(&'a BoxedRsaPrivateKey),
Ecdsa(&'a BoxedEcdsaPrivateKey),
Ed25519(&'a Ed25519PrivateKey),
Ed448(&'a Ed448PrivateKey),
#[cfg(feature = "mldsa")]
MlDsa44(&'a MlDsa44PrivateKey),
#[cfg(feature = "mldsa")]
MlDsa65(&'a MlDsa65PrivateKey),
#[cfg(feature = "mldsa")]
MlDsa87(&'a MlDsa87PrivateKey),
#[cfg(feature = "slhdsa")]
SlhDsa(&'a slhdsa::PrivateKey),
}
impl CertSigner<'_> {
pub(crate) fn sig_alg_oid(&self) -> &'static [u64] {
match self {
CertSigner::Rsa(_) => oid::SHA256_WITH_RSA,
CertSigner::Ecdsa(k) => match k.curve() {
CurveId::P256 | CurveId::Secp256k1 | CurveId::Sm2p256v1 => oid::ECDSA_WITH_SHA256,
CurveId::P384 => oid::ECDSA_WITH_SHA384,
CurveId::P521 => oid::ECDSA_WITH_SHA512,
},
CertSigner::Ed25519(_) => oid::ID_ED25519,
CertSigner::Ed448(_) => oid::ID_ED448,
#[cfg(feature = "mldsa")]
CertSigner::MlDsa44(_) => oid::ID_ML_DSA_44,
#[cfg(feature = "mldsa")]
CertSigner::MlDsa65(_) => oid::ID_ML_DSA_65,
#[cfg(feature = "mldsa")]
CertSigner::MlDsa87(_) => oid::ID_ML_DSA_87,
#[cfg(feature = "slhdsa")]
CertSigner::SlhDsa(k) => k.parameter_set().oid(),
}
}
pub(crate) fn algorithm_identifier(&self) -> Vec<u8> {
algorithm_identifier(self.sig_alg_oid(), matches!(self, CertSigner::Rsa(_)))
}
pub(crate) fn sign(&self, tbs: &[u8]) -> Result<Vec<u8>, Error> {
match self {
CertSigner::Rsa(k) => Ok(k.sign_pkcs1v15::<Sha256>(tbs)?),
CertSigner::Ecdsa(k) => {
let curve = k.curve();
let sig = match curve {
CurveId::P256 | CurveId::Secp256k1 | CurveId::Sm2p256v1 => {
k.sign::<Sha256>(tbs)
}
CurveId::P384 => k.sign::<Sha384>(tbs),
CurveId::P521 => k.sign::<Sha512>(tbs),
}
.map_err(|_| Error::Verification)?;
Ok(sig.to_der(curve))
}
CertSigner::Ed25519(k) => Ok(k.sign(tbs).to_bytes().to_vec()),
CertSigner::Ed448(k) => Ok(k.sign(tbs).to_bytes().to_vec()),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa44(k) => k
.sign_deterministic(tbs, b"")
.map_err(|_| Error::Verification),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa65(k) => k
.sign_deterministic(tbs, b"")
.map_err(|_| Error::Verification),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa87(k) => k
.sign_deterministic(tbs, b"")
.map_err(|_| Error::Verification),
#[cfg(feature = "slhdsa")]
CertSigner::SlhDsa(k) => k
.sign_deterministic(tbs, b"")
.map_err(|_| Error::Verification),
}
}
#[cfg(any(feature = "mldsa", feature = "slhdsa"))]
#[allow(dead_code)]
pub(crate) fn sign_with_rng<R: RngCore>(
&self,
tbs: &[u8],
rng: &mut R,
) -> Result<Vec<u8>, Error> {
match self {
#[cfg(feature = "mldsa")]
CertSigner::MlDsa44(k) => k.sign(rng, tbs, b"").map_err(|_| Error::Verification),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa65(k) => k.sign(rng, tbs, b"").map_err(|_| Error::Verification),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa87(k) => k.sign(rng, tbs, b"").map_err(|_| Error::Verification),
#[cfg(feature = "slhdsa")]
CertSigner::SlhDsa(k) => k.sign(rng, tbs, b"").map_err(|_| Error::Verification),
other => other.sign(tbs),
}
}
pub fn public_key(&self) -> AnyPublicKey {
match self {
CertSigner::Rsa(k) => AnyPublicKey::Rsa(k.public_key()),
CertSigner::Ecdsa(k) => AnyPublicKey::Ecdsa(k.public_key()),
CertSigner::Ed25519(k) => AnyPublicKey::Ed25519(k.public_key()),
CertSigner::Ed448(k) => AnyPublicKey::Ed448(k.public_key()),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa44(k) => AnyPublicKey::MlDsa44(k.public_key()),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa65(k) => AnyPublicKey::MlDsa65(k.public_key()),
#[cfg(feature = "mldsa")]
CertSigner::MlDsa87(k) => AnyPublicKey::MlDsa87(k.public_key()),
#[cfg(feature = "slhdsa")]
CertSigner::SlhDsa(k) => AnyPublicKey::SlhDsa(k.public_key()),
}
}
}