use crate::{certificate::Certificate, digest::DigestAlgorithm, error::AdesError};
pub trait Signer {
type Error: std::error::Error + Send + Sync + 'static;
fn sign_digest(&self, digest: &[u8]) -> Result<Vec<u8>, Self::Error>;
fn certificate(&self) -> &Certificate;
fn digest_algorithm(&self) -> DigestAlgorithm;
}
#[cfg(feature = "soft")]
pub struct SoftSigner {
private_key: rsa::RsaPrivateKey,
certificate: Certificate,
digest: DigestAlgorithm,
}
#[cfg(feature = "soft")]
impl SoftSigner {
pub fn generate(bits: usize) -> Result<Self, AdesError> {
use der::{Decode, Encode};
use rand_core::OsRng;
use rsa::pkcs1v15::SigningKey;
use sha2::Sha256;
use signature::Keypair;
use spki::{EncodePublicKey, SubjectPublicKeyInfoOwned};
use x509_cert::{
builder::{Builder, CertificateBuilder, Profile},
name::RdnSequence,
serial_number::SerialNumber,
time::Validity,
};
let private_key = rsa::RsaPrivateKey::new(&mut OsRng, bits).map_err(AdesError::Rsa)?;
let signing_key = SigningKey::<Sha256>::new(private_key.clone());
let verifying_key = signing_key.verifying_key();
let pub_key_doc = verifying_key
.to_public_key_der()
.map_err(|e| AdesError::Signer(Box::new(e)))?;
let spki = SubjectPublicKeyInfoOwned::from_der(pub_key_doc.as_bytes())?;
let validity = Validity::from_now(std::time::Duration::from_secs(60 * 60 * 24 * 365 * 10))?;
let subject = RdnSequence::default();
let serial = SerialNumber::from(1u32);
let builder =
CertificateBuilder::new(Profile::Root, serial, validity, subject, spki, &signing_key)?;
let cert = builder.build::<rsa::pkcs1v15::Signature>()?;
let cert_der = cert.to_der()?;
let certificate = Certificate::from_der(&cert_der)?;
Ok(Self {
private_key,
certificate,
digest: DigestAlgorithm::Sha256,
})
}
pub fn from_parts(
private_key: rsa::RsaPrivateKey,
cert_der: &[u8],
digest: DigestAlgorithm,
) -> Result<Self, AdesError> {
let certificate = Certificate::from_der(cert_der)?;
Ok(Self {
private_key,
certificate,
digest,
})
}
}
#[cfg(feature = "soft")]
impl Signer for SoftSigner {
type Error = AdesError;
fn sign_digest(&self, digest: &[u8]) -> Result<Vec<u8>, Self::Error> {
use rsa::pkcs1v15::SigningKey;
use rsa::signature::hazmat::PrehashSigner;
use rsa::signature::SignatureEncoding;
use sha2::Sha256;
let signing_key = SigningKey::<Sha256>::new(self.private_key.clone());
let signature: rsa::pkcs1v15::Signature = signing_key.sign_prehash(digest)?;
Ok(signature.to_vec())
}
fn certificate(&self) -> &Certificate {
&self.certificate
}
fn digest_algorithm(&self) -> DigestAlgorithm {
self.digest
}
}