Browse Source

Converted SignAlgo and VerifyAlgo to the Signer and Verifier traits.

Matthew Carr 2 years ago
parent
commit
e38ca3620a
2 changed files with 45 additions and 44 deletions
  1. 6 0
      crates/.vscode/settings.json
  2. 39 44
      crates/btnode/src/crypto/mod.rs

+ 6 - 0
crates/.vscode/settings.json

@@ -5,11 +5,17 @@
         "bodhi",
         "Crypter",
         "Cryptotext",
+        "Decryptor",
+        "Encryptor",
         "decrypter",
         "encrypter",
         "Hashable",
         "newtype",
+        "PKCS",
+        "readcap",
+        "readcaps",
         "writecap",
+        "writecaps",
         "Xsalsa"
     ]
 }

+ 39 - 44
crates/btnode/src/crypto/mod.rs

@@ -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(())
         }