tasign 0.2.0

TA ELF signing utilities with CMS/PKCS#7 support
//! RSA PKCS#1 v1.5 + ECDSA P-256 (SHA-256) helpers for CMS detached signing.

extern crate alloc;

use p256::ecdsa::signature::hazmat::PrehashVerifier;
use p256::ecdsa::{Signature as EcdsaSignature, VerifyingKey as P256VerifyingKey};
#[cfg(feature = "std")]
use p256::ecdsa::signature::hazmat::RandomizedPrehashSigner;
#[cfg(feature = "std")]
use p256::ecdsa::SigningKey as P256SigningKey;
use rsa::pkcs1v15::{Signature as RsaSignature, VerifyingKey as RsaVerifyingKey};
#[cfg(feature = "std")]
use rsa::pkcs1v15::SigningKey as RsaSigningKey;
#[cfg(feature = "std")]
use rsa::signature::hazmat::PrehashSigner;
#[cfg(feature = "std")]
use rsa::signature::SignatureEncoding;
use rsa::traits::PublicKeyParts;
use rsa::RsaPublicKey;
#[cfg(feature = "std")]
use rsa::RsaPrivateKey;
use sha2::Sha256;

#[cfg(feature = "std")]
use super::rng::{CryptoRng, DynCryptoRng};
use crate::crypto::CryptoError;

/// PKCS#1 v1.5 prehash signing is deterministic; `rng` is accepted for API parity with
/// [`super::pk::Pk::sign`] and ECDSA paths only.
#[cfg(feature = "std")]
pub fn rsa_sign_digest(
    key: &RsaPrivateKey,
    digest: &[u8; 32],
    _rng: &mut dyn CryptoRng,
) -> Result<alloc::vec::Vec<u8>, CryptoError> {
    let signing_key = RsaSigningKey::<Sha256>::new(key.clone());
    let sig = signing_key
        .sign_prehash(digest)
        .map_err(|_| CryptoError::InternalError)?;
    Ok(sig.to_vec())
}

pub fn rsa_verify_digest(key: &RsaPublicKey, digest: &[u8; 32], sig: &[u8]) -> Result<(), CryptoError> {
    let verifying_key = RsaVerifyingKey::<Sha256>::new(key.clone());
    let sig = RsaSignature::try_from(sig).map_err(|_| CryptoError::InvalidInput)?;
    verifying_key
        .verify_prehash(digest, &sig)
        .map_err(|_| CryptoError::VerificationFailed)
}

#[cfg(feature = "std")]
pub fn ecdsa_sign_digest(
    key: &P256SigningKey,
    digest: &[u8; 32],
    rng: &mut dyn CryptoRng,
) -> Result<alloc::vec::Vec<u8>, CryptoError> {
    let mut drng = DynCryptoRng(rng);
    let sig: EcdsaSignature = key
        .sign_prehash_with_rng(&mut drng, digest)
        .map_err(|_| CryptoError::InternalError)?;
    Ok(sig.to_der().as_bytes().to_vec())
}

pub fn ecdsa_verify_digest(
    key: &P256VerifyingKey,
    digest: &[u8; 32],
    sig: &[u8],
) -> Result<(), CryptoError> {
    let sig = EcdsaSignature::from_der(sig).map_err(|_| CryptoError::InvalidInput)?;
    let sig = sig.normalize_s();
    key.verify_prehash(digest, &sig)
        .map_err(|_| CryptoError::VerificationFailed)
}

pub fn rsa_pub_key_bits(key: &RsaPublicKey) -> usize {
    key.n().bits() as usize
}

#[cfg(feature = "std")]
pub fn rsa_key_bits(key: &RsaPrivateKey) -> usize {
    key.n().bits() as usize
}