tasign 0.2.0

TA ELF signing utilities with CMS/PKCS#7 support
//! SM2 byte-level primitives (used by `Pk` and `tasign::x509`).

extern crate alloc;

#[cfg(all(feature = "std", feature = "interop-bytes"))]
use alloc::vec::Vec;

use sm2::dsa::signature::hazmat::PrehashVerifier;
#[cfg(all(feature = "std", feature = "interop-bytes"))]
use sm2::dsa::signature::hazmat::RandomizedPrehashSigner;
#[cfg(all(feature = "std", feature = "interop-bytes"))]
use sm2::dsa::signature::RandomizedSigner;
use sm2::dsa::signature::Verifier;
use sm2::dsa::{Signature, VerifyingKey};
#[cfg(feature = "std")]
use sm2::dsa::SigningKey;

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

pub const DEFAULT_DISTINGUISHING_ID: &str = "1234567812345678";

#[cfg(feature = "std")]
fn signing_key_from_secret(secret_key: &[u8]) -> Result<SigningKey, CryptoError> {
    let sk = sm2::SecretKey::from_slice(secret_key).map_err(|_| CryptoError::InvalidKey)?;
    SigningKey::new(DEFAULT_DISTINGUISHING_ID, &sk).map_err(|_| CryptoError::InternalError)
}

fn verifying_key_from_sec1(public_key_sec1: &[u8]) -> Result<VerifyingKey, CryptoError> {
    VerifyingKey::from_sec1_bytes(DEFAULT_DISTINGUISHING_ID, public_key_sec1)
        .map_err(|_| CryptoError::InvalidKey)
}

fn parse_signature(signature: &[u8]) -> Result<Signature, CryptoError> {
    Signature::from_der(signature).map_err(|_| CryptoError::InvalidInput)
}

#[cfg(all(feature = "std", feature = "interop-bytes"))]
pub fn sm2_sign_message(
    secret_key: &[u8],
    msg: &[u8],
    rng: &mut dyn CryptoRng,
) -> Result<Vec<u8>, CryptoError> {
    let signing_key = signing_key_from_secret(secret_key)?;
    let mut drng = DynCryptoRng(rng);
    let sig = signing_key
        .try_sign_with_rng(&mut drng, msg)
        .map_err(|_| CryptoError::InternalError)?;
    Ok(sig.to_der().as_bytes().to_vec())
}

pub fn sm2_verify_message_sec1(
    public_key_sec1: &[u8],
    msg: &[u8],
    signature: &[u8],
) -> Result<(), CryptoError> {
    let verifying_key = verifying_key_from_sec1(public_key_sec1)?;
    let sig = parse_signature(signature)?;
    verifying_key
        .verify(msg, &sig)
        .map_err(|_| CryptoError::VerificationFailed)
}

#[cfg(all(feature = "std", feature = "interop-bytes"))]
pub fn sm2_sign_digest(
    secret_key: &[u8],
    digest: &[u8; 32],
    rng: &mut dyn CryptoRng,
) -> Result<Vec<u8>, CryptoError> {
    let signing_key = signing_key_from_secret(secret_key)?;
    let mut drng = DynCryptoRng(rng);
    let sig = signing_key
        .sign_prehash_with_rng(&mut drng, digest)
        .map_err(|_| CryptoError::InternalError)?;
    Ok(sig.to_der().as_bytes().to_vec())
}

#[cfg(feature = "interop-bytes")]
pub fn sm2_verify_digest_sec1(
    public_key_sec1: &[u8],
    digest: &[u8; 32],
    signature: &[u8],
) -> Result<(), CryptoError> {
    let verifying_key = verifying_key_from_sec1(public_key_sec1)?;
    let sig = parse_signature(signature)?;
    verifying_key
        .verify_prehash(digest, &sig)
        .map_err(|_| CryptoError::VerificationFailed)
}

pub(crate) fn verify_message_with_key(
    verifying_key: &VerifyingKey,
    msg: &[u8],
    signature: &[u8],
) -> Result<(), CryptoError> {
    let sig = parse_signature(signature)?;
    verifying_key
        .verify(msg, &sig)
        .map_err(|_| CryptoError::VerificationFailed)
}

pub(crate) fn verify_digest_with_key(
    verifying_key: &VerifyingKey,
    digest: &[u8; 32],
    signature: &[u8],
) -> Result<(), CryptoError> {
    let sig = parse_signature(signature)?;
    verifying_key
        .verify_prehash(digest, &sig)
        .map_err(|_| CryptoError::VerificationFailed)
}

#[cfg(feature = "std")]
pub(crate) fn signing_key_from_scalar(secret: &[u8; 32]) -> Result<SigningKey, CryptoError> {
    signing_key_from_secret(secret)
}

pub(crate) fn verifying_key_from_sec1_pub(sec1: &[u8]) -> Result<VerifyingKey, CryptoError> {
    verifying_key_from_sec1(sec1)
}