|
@@ -6,7 +6,7 @@ use super::*;
|
|
|
use openssl::{
|
|
|
error::ErrorStack,
|
|
|
encrypt::{Encrypter, Decrypter},
|
|
|
- pkey::{PKey, Public as OsslPublic},
|
|
|
+ pkey::{PKey, Public, Private},
|
|
|
symm::{Cipher, encrypt as openssl_encrypt, decrypt as openssl_decrypt},
|
|
|
rand::rand_bytes,
|
|
|
rsa::{Rsa, Padding as OpensslPadding},
|
|
@@ -14,8 +14,14 @@ use openssl::{
|
|
|
sign::{Signer as OsslSigner, Verifier as OsslVerifier}
|
|
|
};
|
|
|
use serde_block_tree::{self, to_vec, from_vec, write_to};
|
|
|
-use serde::de::{DeserializeOwned};
|
|
|
-use std::str::FromStr;
|
|
|
+use serde::{
|
|
|
+ de::{self, DeserializeOwned, Deserializer, SeqAccess, Visitor},
|
|
|
+ ser::{Serializer, SerializeStruct},
|
|
|
+};
|
|
|
+use std::{
|
|
|
+ str::FromStr,
|
|
|
+ sync::Arc,
|
|
|
+};
|
|
|
use strum_macros::{EnumString, EnumDiscriminants, Display};
|
|
|
|
|
|
/// Data that may or may not be encrypted.
|
|
@@ -195,33 +201,6 @@ impl Default for Signature {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
|
-pub(crate) enum RsaPadding {
|
|
|
- None,
|
|
|
- Pkcs1,
|
|
|
- Pkcs1Oaep,
|
|
|
- Pkcs1Pss,
|
|
|
-}
|
|
|
-
|
|
|
-impl Default for RsaPadding {
|
|
|
- fn default() -> Self {
|
|
|
- RsaPadding::Pkcs1
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl Copy for RsaPadding {}
|
|
|
-
|
|
|
-impl From<RsaPadding> for OpensslPadding {
|
|
|
- fn from(padding: RsaPadding) -> OpensslPadding {
|
|
|
- match padding {
|
|
|
- RsaPadding::None => OpensslPadding::NONE,
|
|
|
- RsaPadding::Pkcs1 => OpensslPadding::PKCS1,
|
|
|
- RsaPadding::Pkcs1Oaep => OpensslPadding::PKCS1_OAEP,
|
|
|
- RsaPadding::Pkcs1Pss => OpensslPadding::PKCS1_PSS,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, EnumDiscriminants)]
|
|
|
#[strum_discriminants(name(SymKeyKind))]
|
|
|
pub(crate) enum SymKey {
|
|
@@ -264,7 +243,7 @@ impl SymKey {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn params<'a>(&'a self) -> SymParams<'a> {
|
|
|
+ fn params(&self) -> SymParams {
|
|
|
let (cipher, key, iv) = match self {
|
|
|
SymKey::Aes256Cbc { key, iv } => (Cipher::aes_256_cbc(), key, Some(iv.as_slice())),
|
|
|
SymKey::Aes256Ctr { key, iv } => (Cipher::aes_256_ctr(), key, Some(iv.as_slice())),
|
|
@@ -274,53 +253,109 @@ impl SymKey {
|
|
|
}
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
|
-pub(crate) struct Public;
|
|
|
-
|
|
|
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
|
-pub(crate) struct Private;
|
|
|
+pub(crate) enum AsymKeyKind {
|
|
|
+ Rsa,
|
|
|
+}
|
|
|
|
|
|
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, EnumDiscriminants)]
|
|
|
-#[strum_discriminants(name(AsymKeyKind))]
|
|
|
-pub(crate) enum AsymKey<T> {
|
|
|
- Rsa {
|
|
|
- der: Vec<u8>,
|
|
|
- padding: RsaPadding,
|
|
|
- kind: T,
|
|
|
- }
|
|
|
+#[derive(Debug, Clone)]
|
|
|
+pub(crate) struct AsymKeyPub {
|
|
|
+ kind: AsymKeyKind,
|
|
|
+ pkey: PKey<Public>,
|
|
|
}
|
|
|
|
|
|
-impl<T> AsymKey<T> {
|
|
|
- pub(crate) fn as_slice(&self) -> &[u8] {
|
|
|
- match self {
|
|
|
- AsymKey::Rsa { der, .. } => der.as_slice()
|
|
|
- }
|
|
|
+impl AsymKeyPub {
|
|
|
+ pub(crate) fn new(kind: AsymKeyKind, der: &[u8]) -> Result<AsymKeyPub> {
|
|
|
+ let pkey = match kind {
|
|
|
+ AsymKeyKind::Rsa => {
|
|
|
+ let rsa = Rsa::public_key_from_der(der).map_err(Error::from)?;
|
|
|
+ PKey::from_rsa(rsa).map_err(Error::from)?
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Ok(AsymKeyPub { kind, pkey })
|
|
|
}
|
|
|
|
|
|
fn digest(&self) -> MessageDigest {
|
|
|
- match self {
|
|
|
- AsymKey::Rsa { .. } => MessageDigest::sha256(),
|
|
|
+ match self.kind {
|
|
|
+ AsymKeyKind::Rsa => MessageDigest::sha256(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
fn signature_buf(&self) -> Signature {
|
|
|
- match self {
|
|
|
- AsymKey::Rsa { .. } => Signature::new(SignatureKind::Rsa),
|
|
|
+ match self.kind {
|
|
|
+ AsymKeyKind::Rsa => Signature::new(SignatureKind::Rsa),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn padding(&self) -> Option<OpensslPadding> {
|
|
|
+ match self.kind {
|
|
|
+ AsymKeyKind::Rsa => Some(OpensslPadding::PKCS1),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn to_der(&self) -> Result<Vec<u8>> {
|
|
|
+ self.pkey.public_key_to_der().map_err(Error::from)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'de> Deserialize<'de> for AsymKeyPub {
|
|
|
+ fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
|
|
|
+ const FIELDS: &[&str] = &["kind", "pkey"];
|
|
|
+
|
|
|
+ struct StructVisitor;
|
|
|
+
|
|
|
+ impl<'de> Visitor<'de> for StructVisitor {
|
|
|
+ type Value = AsymKeyPub;
|
|
|
+
|
|
|
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
+ formatter.write_fmt(format_args!("struct {}", stringify!(AsymKeyPub)))
|
|
|
+ }
|
|
|
+
|
|
|
+ fn visit_seq<V: SeqAccess<'de>>(
|
|
|
+ self, mut seq: V
|
|
|
+ ) -> std::result::Result<AsymKeyPub, V::Error> {
|
|
|
+ let kind: AsymKeyKind = seq.next_element()?
|
|
|
+ .ok_or_else(|| de::Error::missing_field(FIELDS[0]))?;
|
|
|
+ let der: Vec<u8> = seq.next_element()?
|
|
|
+ .ok_or_else(|| de::Error::missing_field(FIELDS[1]))?;
|
|
|
+ AsymKeyPub::new(kind, der.as_slice())
|
|
|
+ .map_err(|e| de::Error::custom(e.to_string()))
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ d.deserialize_struct(stringify!(AsymKeyPub), FIELDS, StructVisitor)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Serialize for AsymKeyPub {
|
|
|
+ fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
|
|
|
+ let mut struct_s = s.serialize_struct(stringify!(AsymKeyPub), 2)?;
|
|
|
+ struct_s.serialize_field("kind", &self.kind)?;
|
|
|
+ let der = self.pkey.public_key_to_der().unwrap();
|
|
|
+ struct_s.serialize_field("pkey", der.as_slice())?;
|
|
|
+ struct_s.end()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl PartialEq for AsymKeyPub {
|
|
|
+ fn eq(&self, other: &Self) -> bool {
|
|
|
+ self.kind == other.kind && self.pkey.public_eq(&other.pkey)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T> Owned for AsymKey<T> {
|
|
|
+impl Owned for AsymKeyPub {
|
|
|
fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
match kind {
|
|
|
HashKind::Sha2_256 => {
|
|
|
let mut buf = [0; 32];
|
|
|
- let bytes = hash(MessageDigest::sha256(), self.as_slice()).unwrap();
|
|
|
+ let der = self.to_der().unwrap();
|
|
|
+ let bytes = hash(MessageDigest::sha256(), der.as_slice()).unwrap();
|
|
|
buf.copy_from_slice(&*bytes);
|
|
|
Principal(Hash::Sha2_256(buf))
|
|
|
},
|
|
|
HashKind::Sha2_512 => {
|
|
|
let mut buf = [0; 64];
|
|
|
- let bytes = hash(MessageDigest::sha512(), self.as_slice()).unwrap();
|
|
|
+ let der = self.to_der().unwrap();
|
|
|
+ let bytes = hash(MessageDigest::sha512(), der.as_slice()).unwrap();
|
|
|
buf.copy_from_slice(&*bytes);
|
|
|
Principal(Hash::Sha2_512(buf))
|
|
|
}
|
|
@@ -328,29 +363,74 @@ impl<T> Owned for AsymKey<T> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+pub(crate) trait AsymKeyPriv: Decryptor + Signer {}
|
|
|
+
|
|
|
+pub(crate) struct RsaPriv {
|
|
|
+ pkey: PKey<Private>,
|
|
|
+}
|
|
|
+
|
|
|
+impl RsaPriv {
|
|
|
+ fn digest() -> MessageDigest {
|
|
|
+ MessageDigest::sha256()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn signature_buf() -> Signature {
|
|
|
+ Signature::new(SignatureKind::Rsa)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Decryptor for RsaPriv {
|
|
|
+ fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ let decrypter = Decrypter::new(&self.pkey).map_err(Error::from)?;
|
|
|
+ let buffer_len = decrypter.decrypt_len(slice).map_err(Error::from)?;
|
|
|
+ let mut plaintext = vec![0; buffer_len];
|
|
|
+ let plaintext_len = decrypter.decrypt(slice, &mut plaintext).map_err(Error::from)?;
|
|
|
+ plaintext.truncate(plaintext_len);
|
|
|
+ Ok(plaintext)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Signer for RsaPriv {
|
|
|
+ fn sign<'a>(&self, parts: &mut dyn Iterator<Item=&'a [u8]>) -> Result<Signature> {
|
|
|
+ let digest = RsaPriv::digest();
|
|
|
+ let mut signature = RsaPriv::signature_buf();
|
|
|
+
|
|
|
+ let mut signer = OsslSigner::new(digest, &self.pkey).map_err(Error::from)?;
|
|
|
+ for part in parts {
|
|
|
+ signer.update(part).map_err(Error::from)?;
|
|
|
+ }
|
|
|
+ let buf = signature.as_mut_slice();
|
|
|
+ signer.sign(buf).map_err(Error::from)?;
|
|
|
+ Ok(signature)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl AsymKeyPriv for RsaPriv {}
|
|
|
+
|
|
|
+impl RsaPriv {
|
|
|
+ pub(crate) fn new(der: &[u8]) -> Result<RsaPriv> {
|
|
|
+ let rsa = Rsa::private_key_from_der(der).map_err(Error::from)?;
|
|
|
+ let pkey = PKey::from_rsa(rsa).map_err(Error::from)?;
|
|
|
+ Ok(RsaPriv { pkey })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub(crate) struct KeyPair {
|
|
|
- pub(crate) public: AsymKey<Public>,
|
|
|
- pub(crate) private: AsymKey<Private>,
|
|
|
+ pub(crate) public: AsymKeyPub,
|
|
|
+ pub(crate) private: Arc<dyn AsymKeyPriv>,
|
|
|
}
|
|
|
|
|
|
impl KeyPair {
|
|
|
pub(crate) fn generate(kind: AsymKeyKind) -> Result<KeyPair> {
|
|
|
match kind {
|
|
|
AsymKeyKind::Rsa => {
|
|
|
- let key = PKey::from_rsa(Rsa::generate(4096)?)?;
|
|
|
- let public = key.public_key_to_der().map_err(Error::from)?;
|
|
|
- let private = key.private_key_to_der().map_err(Error::from)?;
|
|
|
+ let key = Rsa::generate(4096)?;
|
|
|
+ // TODO: Separating the keys this way seems inefficient. Investigate alternatives.
|
|
|
+ let public_der = key.public_key_to_der().map_err(Error::from)?;
|
|
|
+ let private_der = key.private_key_to_der().map_err(Error::from)?;
|
|
|
Ok(KeyPair {
|
|
|
- public: AsymKey::Rsa {
|
|
|
- der: public,
|
|
|
- padding: RsaPadding::default(),
|
|
|
- kind: Public,
|
|
|
- },
|
|
|
- private: AsymKey::Rsa {
|
|
|
- der: private,
|
|
|
- padding: RsaPadding::default(),
|
|
|
- kind: Private,
|
|
|
- },
|
|
|
+ public: AsymKeyPub::new(AsymKeyKind::Rsa, public_der.as_slice())?,
|
|
|
+ private: Arc::new(RsaPriv::new(private_der.as_slice())?),
|
|
|
})
|
|
|
},
|
|
|
}
|
|
@@ -374,15 +454,11 @@ impl Encryptor for SymKey {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Encryptor for AsymKey<Public> {
|
|
|
+impl Encryptor for AsymKeyPub {
|
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- let (pkey, rsa_padding) = match self {
|
|
|
- AsymKey::Rsa { der, padding, .. }
|
|
|
- => (PKey::public_key_from_der(der.as_slice()).map_err(Error::from)?, Some(padding)),
|
|
|
- };
|
|
|
- let mut encrypter = Encrypter::new(&pkey).map_err(Error::from)?;
|
|
|
- if let Some(padding) = rsa_padding {
|
|
|
- encrypter.set_rsa_padding((*padding).into()).map_err(Error::from)?;
|
|
|
+ let mut encrypter = Encrypter::new(&self.pkey).map_err(Error::from)?;
|
|
|
+ if let Some(padding) = self.padding() {
|
|
|
+ encrypter.set_rsa_padding(padding).map_err(Error::from)?;
|
|
|
}
|
|
|
let buffer_len = encrypter.encrypt_len(slice).map_err(Error::from)?;
|
|
|
let mut ciphertext = vec![0; buffer_len];
|
|
@@ -393,7 +469,7 @@ impl Encryptor for AsymKey<Public> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-trait Decryptor {
|
|
|
+pub(crate) trait Decryptor {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
@@ -404,56 +480,17 @@ impl Decryptor for SymKey {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Decryptor for AsymKey<Private> {
|
|
|
- fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- let pkey = match self {
|
|
|
- AsymKey::Rsa { der, .. }
|
|
|
- => PKey::private_key_from_der(der.as_slice()).map_err(Error::from)?
|
|
|
- };
|
|
|
- let decrypter = Decrypter::new(&pkey).map_err(Error::from)?;
|
|
|
- let buffer_len = decrypter.decrypt_len(slice).map_err(Error::from)?;
|
|
|
- let mut plaintext = vec![0; buffer_len];
|
|
|
- let plaintext_len = decrypter.decrypt(slice, &mut plaintext).map_err(Error::from)?;
|
|
|
- plaintext.truncate(plaintext_len);
|
|
|
- Ok(plaintext)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
pub(crate) trait Signer {
|
|
|
- fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature>;
|
|
|
-}
|
|
|
-
|
|
|
-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 = signature.as_mut_slice();
|
|
|
- signer.sign(buf).map_err(Error::from)?;
|
|
|
- Ok(signature)
|
|
|
- }
|
|
|
+ fn sign<'a>(&self, parts: &mut dyn Iterator<Item=&'a [u8]>) -> Result<Signature>;
|
|
|
}
|
|
|
|
|
|
-struct VerifyAlgo {
|
|
|
- key: PKey<OsslPublic>,
|
|
|
- digest: MessageDigest,
|
|
|
+trait Verifier {
|
|
|
+ fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool>;
|
|
|
}
|
|
|
|
|
|
-impl VerifyAlgo {
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(
|
|
|
- &'a self, parts: I, signature: &[u8]
|
|
|
- ) -> Result<bool> {
|
|
|
- let mut verifier = OsslVerifier::new(self.digest, &self.key).map_err(Error::from)?;
|
|
|
+impl Verifier for AsymKeyPub {
|
|
|
+ fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
|
+ let mut verifier = OsslVerifier::new(self.digest(), &self.pkey).map_err(Error::from)?;
|
|
|
for part in parts {
|
|
|
verifier.update(part).map_err(Error::from)?;
|
|
|
}
|
|
@@ -461,21 +498,6 @@ impl VerifyAlgo {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl TryFrom<&AsymKey<Public>> for VerifyAlgo {
|
|
|
- type Error = Error;
|
|
|
- fn try_from(key: &AsymKey<Public>) -> Result<VerifyAlgo> {
|
|
|
- match key {
|
|
|
- AsymKey::Rsa { der, .. } => {
|
|
|
- let rsa = Rsa::public_key_from_der(der.as_slice()).map_err(Error::from)?;
|
|
|
- Ok(VerifyAlgo {
|
|
|
- key: PKey::from_rsa(rsa).map_err(Error::from)?,
|
|
|
- digest: MessageDigest::sha256()
|
|
|
- })
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
pub(crate) fn encrypt_block(
|
|
|
mut block: Block, principal: &Principal, key: &KeyPair
|
|
|
) -> Result<Block> {
|
|
@@ -485,7 +507,7 @@ pub(crate) fn encrypt_block(
|
|
|
};
|
|
|
let (principal_owned, read_cap) = block.readcaps.remove_entry(principal)
|
|
|
.ok_or(Error::NoReadCap)?;
|
|
|
- let block_key = decrypt(read_cap, &key.private)?;
|
|
|
+ let block_key = decrypt(read_cap, key.private.as_ref())?;
|
|
|
let new_body = block_key.encrypt(&body)?;
|
|
|
block.body = Cryptotext::Cipher(new_body);
|
|
|
block.readcaps.insert(principal_owned, encrypt(&block_key, &key.public)?);
|
|
@@ -493,7 +515,7 @@ pub(crate) fn encrypt_block(
|
|
|
}
|
|
|
|
|
|
pub(crate) fn decrypt_block(
|
|
|
- mut block: Block, principal: &Principal, key: &AsymKey<Private>
|
|
|
+ mut block: Block, principal: &Principal, key: &dyn AsymKeyPriv
|
|
|
) -> Result<Block> {
|
|
|
let body = match block.body {
|
|
|
Cryptotext::Plain(_) => return Ok(block),
|
|
@@ -508,14 +530,16 @@ pub(crate) fn decrypt_block(
|
|
|
Ok(block)
|
|
|
}
|
|
|
|
|
|
-fn encrypt<'a, T: Serialize, K: Encryptor>(value: &T, key: &K) -> Result<Cryptotext<T>> {
|
|
|
+fn encrypt<T: Serialize, K: Encryptor>(value: &T, key: &K) -> Result<Cryptotext<T>> {
|
|
|
let data = to_vec(value).map_err(Error::from)?;
|
|
|
let vec = key.encrypt(&data);
|
|
|
Ok(Cryptotext::Cipher(vec?))
|
|
|
}
|
|
|
|
|
|
-fn decrypt<'a, T: Serialize + DeserializeOwned, K: Decryptor>(
|
|
|
- cryptotext: Cryptotext<T>, key: &K
|
|
|
+/// TODO: When the trait upcasting feature lands in the stable channel change the type of `key`
|
|
|
+/// to `dyn Decryptor`. Tracking issue: https://github.com/rust-lang/rust/issues/65991
|
|
|
+fn decrypt<T: Serialize + DeserializeOwned>(
|
|
|
+ cryptotext: Cryptotext<T>, key: &dyn AsymKeyPriv
|
|
|
) -> Result<T> {
|
|
|
let data = match cryptotext {
|
|
|
Cryptotext::Plain(value) => return Ok(value),
|
|
@@ -553,13 +577,14 @@ fn get_body(block: &Block) -> Result<&[u8]> {
|
|
|
}
|
|
|
|
|
|
pub(crate) fn sign_block(
|
|
|
- block: &mut Block, writecap: Writecap, priv_key: AsymKey<Private>
|
|
|
+ block: &mut Block, writecap: Writecap, priv_key: &dyn AsymKeyPriv
|
|
|
) -> Result<()> {
|
|
|
block.writecap = writecap;
|
|
|
let body = get_body(block)?;
|
|
|
let sig_header = SigHeader::from(&*block);
|
|
|
let header = to_vec(&sig_header)?;
|
|
|
- block.signature = priv_key.sign([header.as_slice(), body].into_iter())?;
|
|
|
+ let signature = priv_key.sign(&mut [header.as_slice(), body].into_iter())?;
|
|
|
+ block.signature = signature;
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
@@ -567,9 +592,8 @@ pub(crate) fn verify_block(block: &Block) -> Result<bool> {
|
|
|
let body = get_body(block)?;
|
|
|
let sig_header = SigHeader::from(&*block);
|
|
|
let header = to_vec(&sig_header)?;
|
|
|
- let verify_algo = VerifyAlgo::try_from(&block.writecap.signing_key)?;
|
|
|
let parts = [header.as_slice(), body].into_iter();
|
|
|
- verify_algo.verify(parts, block.signature.as_slice())
|
|
|
+ block.writecap.signing_key.verify(parts, block.signature.as_slice())
|
|
|
}
|
|
|
|
|
|
#[derive(Serialize)]
|
|
@@ -577,7 +601,7 @@ struct WritecapSig<'a> {
|
|
|
issued_to: &'a Principal,
|
|
|
path: &'a Path,
|
|
|
expires: &'a Epoch,
|
|
|
- signing_key: &'a AsymKey<Public>,
|
|
|
+ signing_key: &'a AsymKeyPub,
|
|
|
}
|
|
|
|
|
|
impl<'a> From<&'a Writecap> for WritecapSig<'a> {
|
|
@@ -591,9 +615,11 @@ impl<'a> From<&'a Writecap> for WritecapSig<'a> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub(crate) fn sign_writecap<S: Signer>(writecap: &mut Writecap, priv_key: &S) -> Result<()> {
|
|
|
+/// TODO: When the trait upcasting feature lands in the stable channel change the type of `priv_key`
|
|
|
+/// to `dyn Decryptor`. Tracking issue: https://github.com/rust-lang/rust/issues/65991
|
|
|
+pub(crate) fn sign_writecap(writecap: &mut Writecap, priv_key: &dyn AsymKeyPriv) -> Result<()> {
|
|
|
let sig_input = to_vec(&WritecapSig::from(&*writecap))?;
|
|
|
- writecap.signature = priv_key.sign([sig_input.as_slice()].into_iter())?;
|
|
|
+ writecap.signature = priv_key.sign(&mut [sig_input.as_slice()].into_iter())?;
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
@@ -639,9 +665,7 @@ pub(crate) fn verify_writecap(
|
|
|
let sig = WritecapSig::from(writecap);
|
|
|
sig_input.clear();
|
|
|
write_to(&sig, &mut sig_input).map_err(|e| WritecapAuthzErr::Serde(e.to_string()))?;
|
|
|
- let verify_algo = VerifyAlgo::try_from(&writecap.signing_key)
|
|
|
- .map_err(|e| WritecapAuthzErr::Crypto(e.to_string()))?;
|
|
|
- let valid = verify_algo
|
|
|
+ let valid = writecap.signing_key
|
|
|
.verify([sig_input.as_slice()].into_iter(), writecap.signature.as_slice())
|
|
|
.map_err(|e| WritecapAuthzErr::Crypto(e.to_string()))?;
|
|
|
if !valid {
|
|
@@ -681,7 +705,7 @@ mod tests {
|
|
|
Cryptotext::Plain(_) => false
|
|
|
};
|
|
|
assert!(encrypted);
|
|
|
- actual = decrypt_block(actual, principal, &key.private)?;
|
|
|
+ actual = decrypt_block(actual, principal, key.private.as_ref())?;
|
|
|
assert_eq!(expected, actual);
|
|
|
Ok(())
|
|
|
}
|
|
@@ -709,9 +733,8 @@ 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 signature = key.private.sign([header, message].into_iter())?;
|
|
|
- let verifier = VerifyAlgo::try_from(&key.public)?;
|
|
|
- let verified = verifier.verify([header, message].into_iter(), signature.as_slice())?;
|
|
|
+ let signature = key.private.sign(&mut [header, message].into_iter())?;
|
|
|
+ let verified = key.public.verify([header, message].into_iter(), signature.as_slice())?;
|
|
|
assert_eq!(true, verified);
|
|
|
Ok(())
|
|
|
}
|
|
@@ -731,7 +754,7 @@ mod tests {
|
|
|
next: None,
|
|
|
};
|
|
|
block = encrypt_block(block, &principal, &key)?;
|
|
|
- sign_block(&mut block, writecap, key.private)?;
|
|
|
+ sign_block(&mut block, writecap, key.private.as_ref())?;
|
|
|
assert_eq!(true, verify_block(&block)?);
|
|
|
Ok(())
|
|
|
}
|
|
@@ -794,11 +817,10 @@ mod tests {
|
|
|
fn verify_writecap_invalid_not_chained() -> Result<()> {
|
|
|
let (mut root_writecap, root_key) = make_self_signed_writecap()?;
|
|
|
root_writecap.issued_to = Principal(Hash::Sha2_256([0; 32]));
|
|
|
- sign_writecap(&mut root_writecap, &root_key.private)?;
|
|
|
- let node_key = AsymKey::Rsa {
|
|
|
- der: Vec::from(NODE_PUBLIC_KEY),
|
|
|
- padding: RsaPadding::Pkcs1,
|
|
|
- kind: Public {},
|
|
|
+ sign_writecap(&mut root_writecap, root_key.private.as_ref())?;
|
|
|
+ let node_key = AsymKeyPub {
|
|
|
+ kind: AsymKeyKind::Rsa,
|
|
|
+ pkey: PKey::from_rsa(Rsa::public_key_from_der(NODE_PUBLIC_KEY.as_slice())?)?
|
|
|
};
|
|
|
let node_principal = node_key.owner();
|
|
|
let writecap = make_writecap_trusted_by(
|
|
@@ -813,11 +835,10 @@ mod tests {
|
|
|
let (mut root_writecap, root_key) = make_self_signed_writecap()?;
|
|
|
let owner = Principal(Hash::Sha2_256([0; 32]));
|
|
|
root_writecap.path = make_path_with_owner(owner, vec![]);
|
|
|
- sign_writecap(&mut root_writecap, &root_key.private)?;
|
|
|
- let node_key = AsymKey::Rsa {
|
|
|
- der: Vec::from(NODE_PUBLIC_KEY),
|
|
|
- padding: RsaPadding::Pkcs1,
|
|
|
- kind: Public {}
|
|
|
+ sign_writecap(&mut root_writecap, root_key.private.as_ref())?;
|
|
|
+ let node_key = AsymKeyPub {
|
|
|
+ kind: AsymKeyKind::Rsa,
|
|
|
+ pkey: PKey::from_rsa(Rsa::public_key_from_der(NODE_PUBLIC_KEY.as_slice())?)?
|
|
|
};
|
|
|
let node_owner = node_key.owner();
|
|
|
let writecap = make_writecap_trusted_by(
|
|
@@ -874,13 +895,12 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn rsa_signature_len() -> Result<()> {
|
|
|
- use openssl::rsa::Rsa;
|
|
|
let key = make_key_pair();
|
|
|
- let der = key.private.as_slice();
|
|
|
- let rsa = Rsa::private_key_from_der(der)?;
|
|
|
- let pkey = PKey::from_rsa(rsa)?;
|
|
|
- let signer = OsslSigner::new(key.private.digest(), &pkey)?;
|
|
|
- assert_eq!(RSA_SIG_LEN, signer.len()?);
|
|
|
+ let signature = key.private.sign(&mut [NODE_PUBLIC_KEY.as_slice()].into_iter())?;
|
|
|
+ let length = match signature {
|
|
|
+ Signature::Rsa(data) => data.len(),
|
|
|
+ };
|
|
|
+ assert_eq!(RSA_SIG_LEN, length);
|
|
|
Ok(())
|
|
|
}
|
|
|
}
|