use msgs::enums::{SignatureAlgorithm, SignatureScheme};
use util;
use key;
use error::TLSError;
use untrusted;
use ring;
use ring::signature;
use ring::signature::RSAKeyPair;
use std::sync::Arc;
use std::mem;
pub trait SigningKey : Send + Sync {
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<Signer>>;
fn algorithm(&self) -> SignatureAlgorithm;
}
pub trait Signer : Send + Sync {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TLSError>;
fn get_scheme(&self) -> SignatureScheme;
}
#[derive(Clone)]
pub struct CertifiedKey {
pub cert: Vec<key::Certificate>,
pub key: Arc<Box<SigningKey>>,
pub ocsp: Option<Vec<u8>>,
pub sct_list: Option<Vec<u8>>,
}
impl CertifiedKey {
pub fn new(cert: Vec<key::Certificate>, key: Arc<Box<SigningKey>>) -> CertifiedKey {
CertifiedKey { cert: cert, key: key, ocsp: None, sct_list: None }
}
pub fn take_cert(&mut self) -> Vec<key::Certificate> {
mem::replace(&mut self.cert, Vec::new())
}
pub fn has_ocsp(&self) -> bool {
self.ocsp.is_some()
}
pub fn take_ocsp(&mut self) -> Option<Vec<u8>> {
mem::replace(&mut self.ocsp, None)
}
pub fn has_sct_list(&self) -> bool {
self.sct_list.is_some()
}
pub fn take_sct_list(&mut self) -> Option<Vec<u8>> {
mem::replace(&mut self.sct_list, None)
}
}
pub struct RSASigningKey {
key: Arc<RSAKeyPair>,
}
static ALL_RSA_SCHEMES: &'static [SignatureScheme] = &[
SignatureScheme::RSA_PSS_SHA512,
SignatureScheme::RSA_PSS_SHA384,
SignatureScheme::RSA_PSS_SHA256,
SignatureScheme::RSA_PKCS1_SHA512,
SignatureScheme::RSA_PKCS1_SHA384,
SignatureScheme::RSA_PKCS1_SHA256,
];
impl RSASigningKey {
pub fn new(der: &key::PrivateKey) -> Result<RSASigningKey, ()> {
RSAKeyPair::from_der(untrusted::Input::from(&der.0))
.or_else(|_| RSAKeyPair::from_pkcs8(untrusted::Input::from(&der.0)))
.map(|s| {
RSASigningKey {
key: Arc::new(s),
}
})
.map_err(|_| ())
}
}
impl SigningKey for RSASigningKey {
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<Signer>> {
util::first_in_both(ALL_RSA_SCHEMES, offered)
.map(|scheme| RSASigner::new(self.key.clone(), scheme))
}
fn algorithm(&self) -> SignatureAlgorithm {
SignatureAlgorithm::RSA
}
}
struct RSASigner {
key: Arc<RSAKeyPair>,
scheme: SignatureScheme,
encoding: &'static signature::RSAEncoding
}
impl RSASigner {
fn new(key: Arc<RSAKeyPair>, scheme: SignatureScheme) -> Box<Signer> {
let encoding: &signature::RSAEncoding = match scheme {
SignatureScheme::RSA_PKCS1_SHA256 => &signature::RSA_PKCS1_SHA256,
SignatureScheme::RSA_PKCS1_SHA384 => &signature::RSA_PKCS1_SHA384,
SignatureScheme::RSA_PKCS1_SHA512 => &signature::RSA_PKCS1_SHA512,
SignatureScheme::RSA_PSS_SHA256 => &signature::RSA_PSS_SHA256,
SignatureScheme::RSA_PSS_SHA384 => &signature::RSA_PSS_SHA384,
SignatureScheme::RSA_PSS_SHA512 => &signature::RSA_PSS_SHA512,
_ => unreachable!(),
};
Box::new(RSASigner { key, scheme, encoding })
}
}
impl Signer for RSASigner {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TLSError> {
let mut sig = vec![0; self.key.public_modulus_len()];
let rng = ring::rand::SystemRandom::new();
let mut signer = signature::RSASigningState::new(self.key.clone())
.map_err(|_| TLSError::General("signing state creation failed".to_string()))?;
signer.sign(self.encoding, &rng, message, &mut sig)
.map(|_| sig)
.map_err(|_| TLSError::General("signing failed".to_string()))
}
fn get_scheme(&self) -> SignatureScheme {
self.scheme
}
}