|
@@ -6,12 +6,12 @@ use super::*;
|
|
|
use openssl::{
|
|
|
error::ErrorStack,
|
|
|
encrypt::{Encrypter, Decrypter},
|
|
|
- pkey::{PKey, Public as OsslPublic, Private as OsslPrivate},
|
|
|
+ pkey::{PKey, Public as OsslPublic},
|
|
|
symm::{Cipher, encrypt as openssl_encrypt, decrypt as openssl_decrypt},
|
|
|
rand::rand_bytes,
|
|
|
rsa::{Rsa, Padding as OpensslPadding},
|
|
|
hash::{hash, MessageDigest},
|
|
|
- sign::{Signer, Verifier}
|
|
|
+ sign::{Signer as OsslSigner, Verifier as OsslVerifier}
|
|
|
};
|
|
|
use serde_block_tree::{self, to_vec, from_vec, write_to};
|
|
|
use serde::de::{DeserializeOwned};
|
|
@@ -295,6 +295,18 @@ impl<T> AsymKey<T> {
|
|
|
AsymKey::Rsa { der, .. } => der.as_slice()
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ fn digest(&self) -> MessageDigest {
|
|
|
+ match self {
|
|
|
+ AsymKey::Rsa { .. } => MessageDigest::sha256(),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn signature_buf(&self) -> Signature {
|
|
|
+ match self {
|
|
|
+ AsymKey::Rsa { .. } => Signature::new(SignatureKind::Rsa),
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl<T> Owned for AsymKey<T> {
|
|
@@ -407,37 +419,28 @@ impl Decryptor for AsymKey<Private> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-struct SignAlgo {
|
|
|
- key: PKey<OsslPrivate>,
|
|
|
- digest: MessageDigest,
|
|
|
- signature: Signature
|
|
|
+pub(crate) trait Signer {
|
|
|
+ fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature>;
|
|
|
}
|
|
|
|
|
|
-impl SignAlgo {
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&mut self, parts: I) -> Result<()> {
|
|
|
- let mut signer = Signer::new(self.digest, &self.key).map_err(Error::from)?;
|
|
|
+impl Signer for AsymKey<Private> {
|
|
|
+ fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ let pkey = match self {
|
|
|
+ AsymKey::Rsa { der, .. } => {
|
|
|
+ let rsa = Rsa::private_key_from_der(der.as_slice()).map_err(Error::from)?;
|
|
|
+ PKey::from_rsa(rsa).map_err(Error::from)?
|
|
|
+ }
|
|
|
+ };
|
|
|
+ let digest = self.digest();
|
|
|
+ let mut signature = self.signature_buf();
|
|
|
+
|
|
|
+ let mut signer = OsslSigner::new(digest, &pkey).map_err(Error::from)?;
|
|
|
for part in parts {
|
|
|
signer.update(part).map_err(Error::from)?;
|
|
|
}
|
|
|
- let buf = self.signature.as_mut_slice();
|
|
|
+ let buf = signature.as_mut_slice();
|
|
|
signer.sign(buf).map_err(Error::from)?;
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl TryFrom<&AsymKey<Private>> for SignAlgo {
|
|
|
- type Error = Error;
|
|
|
- fn try_from(key: &AsymKey<Private>) -> Result<SignAlgo> {
|
|
|
- match key {
|
|
|
- AsymKey::Rsa { der, .. } => {
|
|
|
- let rsa = Rsa::private_key_from_der(der.as_slice()).map_err(Error::from)?;
|
|
|
- Ok(SignAlgo {
|
|
|
- key: PKey::from_rsa(rsa).map_err(Error::from)?,
|
|
|
- digest: MessageDigest::sha256(),
|
|
|
- signature: Signature::new(SignatureKind::Rsa)
|
|
|
- })
|
|
|
- },
|
|
|
- }
|
|
|
+ Ok(signature)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -450,7 +453,7 @@ impl VerifyAlgo {
|
|
|
fn verify<'a, I: Iterator<Item = &'a [u8]>>(
|
|
|
&'a self, parts: I, signature: &[u8]
|
|
|
) -> Result<bool> {
|
|
|
- let mut verifier = Verifier::new(self.digest, &self.key).map_err(Error::from)?;
|
|
|
+ let mut verifier = OsslVerifier::new(self.digest, &self.key).map_err(Error::from)?;
|
|
|
for part in parts {
|
|
|
verifier.update(part).map_err(Error::from)?;
|
|
|
}
|
|
@@ -556,9 +559,7 @@ pub(crate) fn sign_block(
|
|
|
let body = get_body(block)?;
|
|
|
let sig_header = SigHeader::from(&*block);
|
|
|
let header = to_vec(&sig_header)?;
|
|
|
- let mut sign_algo = SignAlgo::try_from(&priv_key)?;
|
|
|
- sign_algo.sign([header.as_slice(), body].into_iter())?;
|
|
|
- block.signature = sign_algo.signature;
|
|
|
+ block.signature = priv_key.sign([header.as_slice(), body].into_iter())?;
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
@@ -590,11 +591,9 @@ impl<'a> From<&'a Writecap> for WritecapSig<'a> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub(crate) fn sign_writecap(writecap: &mut Writecap, priv_key: &AsymKey<Private>) -> Result<()> {
|
|
|
- let mut sign_algo = SignAlgo::try_from(priv_key)?;
|
|
|
+pub(crate) fn sign_writecap<S: Signer>(writecap: &mut Writecap, priv_key: &S) -> Result<()> {
|
|
|
let sig_input = to_vec(&WritecapSig::from(&*writecap))?;
|
|
|
- sign_algo.sign([sig_input.as_slice()].into_iter())?;
|
|
|
- writecap.signature = sign_algo.signature;
|
|
|
+ writecap.signature = priv_key.sign([sig_input.as_slice()].into_iter())?;
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
@@ -612,7 +611,7 @@ pub(crate) enum WritecapAuthzErr {
|
|
|
InvalidSignature,
|
|
|
/// The principal the root writecap was issued to does not own the given path.
|
|
|
RootDoesNotOwnPath,
|
|
|
- /// An error occured while serializing a writecap.
|
|
|
+ /// An error occurred while serializing a writecap.
|
|
|
Serde(String),
|
|
|
/// A cryptographic error occurred while attempting to verify a writecap.
|
|
|
Crypto(String),
|
|
@@ -710,10 +709,9 @@ mod tests {
|
|
|
let key = make_key_pair();
|
|
|
let header = b"About: lyrics".as_slice();
|
|
|
let message = b"Everything that feels so good is bad bad bad.".as_slice();
|
|
|
- let mut signer = SignAlgo::try_from(&key.private)?;
|
|
|
- signer.sign([header, message].into_iter())?;
|
|
|
+ let signature = key.private.sign([header, message].into_iter())?;
|
|
|
let verifier = VerifyAlgo::try_from(&key.public)?;
|
|
|
- let verified = verifier.verify([header, message].into_iter(), signer.signature.as_slice())?;
|
|
|
+ let verified = verifier.verify([header, message].into_iter(), signature.as_slice())?;
|
|
|
assert_eq!(true, verified);
|
|
|
Ok(())
|
|
|
}
|
|
@@ -878,13 +876,10 @@ mod tests {
|
|
|
fn rsa_signature_len() -> Result<()> {
|
|
|
use openssl::rsa::Rsa;
|
|
|
let key = make_key_pair();
|
|
|
- let sign_algo = SignAlgo::try_from(&key.private)?;
|
|
|
- let der = match &key.private {
|
|
|
- AsymKey::Rsa { der, .. } => der,
|
|
|
- };
|
|
|
+ let der = key.private.as_slice();
|
|
|
let rsa = Rsa::private_key_from_der(der)?;
|
|
|
let pkey = PKey::from_rsa(rsa)?;
|
|
|
- let signer = Signer::new(sign_algo.digest, &pkey)?;
|
|
|
+ let signer = OsslSigner::new(key.private.digest(), &pkey)?;
|
|
|
assert_eq!(RSA_SIG_LEN, signer.len()?);
|
|
|
Ok(())
|
|
|
}
|