use msgs::enums::{HashAlgorithm, SignatureAlgorithm};
use untrusted;
use ring;
pub trait Signer {
fn sign(&self, hash_alg: &HashAlgorithm, message: &[u8]) -> Result<Vec<u8>, ()>;
fn algorithm(&self) -> SignatureAlgorithm;
}
pub struct RSASigner {
key: ring::signature::RSAKeyPair
}
impl RSASigner {
pub fn new(der: &[u8]) -> Result<RSASigner, ()> {
let key = ring::signature::RSAKeyPair::from_der(untrusted::Input::from(der));
key
.map(|k| RSASigner { key: k })
.map_err(|_| ())
}
}
impl Signer for RSASigner {
fn sign(&self, hash_alg: &HashAlgorithm, message: &[u8]) -> Result<Vec<u8>, ()> {
let mut sig = vec![0; self.key.public_modulus_len()];
let pad = match hash_alg {
&HashAlgorithm::SHA256 => &ring::signature::RSA_PKCS1_SHA256,
&HashAlgorithm::SHA384 => &ring::signature::RSA_PKCS1_SHA384,
&HashAlgorithm::SHA512 => &ring::signature::RSA_PKCS1_SHA512,
_ => unreachable!()
};
let rng = ring::rand::SystemRandom::new();
self.key.sign(pad, &rng, message, &mut sig)
.map(|_| sig)
.map_err(|_| ())
}
fn algorithm(&self) -> SignatureAlgorithm {
SignatureAlgorithm::RSA
}
}