|
@@ -7,7 +7,7 @@ use super::*;
|
|
|
use openssl::{
|
|
|
error::ErrorStack,
|
|
|
encrypt::{Encrypter as OsslEncrypter, Decrypter as OsslDecrypter},
|
|
|
- pkey::{PKey, Public, Private},
|
|
|
+ pkey::{PKey, Public as OsslPublic, Private as OsslPrivate, HasPublic, HasPrivate},
|
|
|
symm::{Cipher, encrypt as openssl_encrypt, decrypt as openssl_decrypt},
|
|
|
rand::rand_bytes,
|
|
|
rsa::{Rsa, Padding as OpensslPadding},
|
|
@@ -23,6 +23,7 @@ use std::{
|
|
|
str::FromStr, num::TryFromIntError, marker::PhantomData,
|
|
|
};
|
|
|
use strum_macros::{EnumString, EnumDiscriminants, Display};
|
|
|
+use foreign_types::ForeignType;
|
|
|
|
|
|
/// Data that may or may not be encrypted.
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
@@ -292,13 +293,29 @@ impl SymKey {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl Encrypter for SymKey {
|
|
|
+ fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ let SymParams { cipher, key, iv } = self.params();
|
|
|
+ openssl_encrypt(cipher, key, iv, slice).conv_err()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Decrypter for SymKey {
|
|
|
+ fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ let SymParams { cipher, key, iv } = self.params();
|
|
|
+ openssl_decrypt(cipher, key, iv, slice).conv_err()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub trait Scheme: for<'de> Deserialize<'de> + Serialize + Copy + std::fmt::Debug + PartialEq {
|
|
|
- type Kind;
|
|
|
+ type Kind: Scheme;
|
|
|
fn kind(self) -> Self::Kind;
|
|
|
fn as_enum(self) -> SchemeKind;
|
|
|
fn message_digest(&self) -> MessageDigest;
|
|
|
fn padding(&self) -> Option<OpensslPadding>;
|
|
|
- fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>>;
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<OsslPublic>>;
|
|
|
+ fn private_from_der(self, der: &[u8]) -> Result<PKey<OsslPrivate>>;
|
|
|
+ fn generate(self) -> Result<AsymKeyPair<Self::Kind>>;
|
|
|
}
|
|
|
|
|
|
pub enum SchemeKind {
|
|
@@ -334,11 +351,23 @@ impl Scheme for Encrypt {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<OsslPublic>> {
|
|
|
match self {
|
|
|
Encrypt::RsaEsOaep(inner) => inner.public_from_der(der),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ fn private_from_der(self, der: &[u8]) -> Result<PKey<OsslPrivate>> {
|
|
|
+ match self {
|
|
|
+ Encrypt::RsaEsOaep(inner) => inner.private_from_der(der),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn generate(self) -> Result<AsymKeyPair<Self::Kind>> {
|
|
|
+ match self {
|
|
|
+ Encrypt::RsaEsOaep(inner) => inner.generate(),
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Encrypt {
|
|
@@ -376,11 +405,23 @@ impl Scheme for Sign {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<OsslPublic>> {
|
|
|
match self {
|
|
|
Sign::RsaSsaPss(inner) => inner.public_from_der(der),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ fn private_from_der(self, der: &[u8]) -> Result<PKey<OsslPrivate>> {
|
|
|
+ match self {
|
|
|
+ Sign::RsaSsaPss(inner) => inner.private_from_der(der),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn generate(self) -> Result<AsymKeyPair<Self::Kind>> {
|
|
|
+ match self {
|
|
|
+ Sign::RsaSsaPss(inner) => inner.generate(),
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Sign {
|
|
@@ -402,6 +443,17 @@ pub struct RsaEsOaep {
|
|
|
hash_kind: HashKind,
|
|
|
}
|
|
|
|
|
|
+fn generate_rsa<S: Scheme>(scheme: S) -> Result<AsymKeyPair<S>> {
|
|
|
+ let key_bits = 8 * u32::try_from(RSA_KEY_BYTES).conv_err()?;
|
|
|
+ let key = Rsa::generate(key_bits)?;
|
|
|
+ // TODO: Separating the keys this way seems inefficient. Investigate alternatives.
|
|
|
+ let public_der = key.public_key_to_der().conv_err()?;
|
|
|
+ let private_der = key.private_key_to_der().conv_err()?;
|
|
|
+ let public = AsymKey::<Public, S>::new(scheme, &public_der)?;
|
|
|
+ let private = AsymKey::<Private, S>::new(scheme, &private_der)?;
|
|
|
+ Ok(AsymKeyPair { public, private })
|
|
|
+}
|
|
|
+
|
|
|
impl Scheme for RsaEsOaep {
|
|
|
type Kind = Encrypt;
|
|
|
|
|
@@ -421,9 +473,23 @@ impl Scheme for RsaEsOaep {
|
|
|
Some(OpensslPadding::PKCS1_OAEP)
|
|
|
}
|
|
|
|
|
|
- fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<OsslPublic>> {
|
|
|
PKey::public_key_from_der(der).conv_err()
|
|
|
}
|
|
|
+
|
|
|
+ fn private_from_der(self, der: &[u8]) -> Result<PKey<OsslPrivate>> {
|
|
|
+ PKey::private_key_from_der(der).conv_err()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn generate(self) -> Result<AsymKeyPair<Self::Kind>> {
|
|
|
+ generate_rsa(self.kind())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<RsaEsOaep> for Encrypt {
|
|
|
+ fn from(scheme: RsaEsOaep) -> Self {
|
|
|
+ scheme.kind()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Copy)]
|
|
@@ -451,23 +517,64 @@ impl Scheme for RsaSsaPss {
|
|
|
Some(OpensslPadding::PKCS1_PSS)
|
|
|
}
|
|
|
|
|
|
- fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<OsslPublic>> {
|
|
|
PKey::public_key_from_der(der).conv_err()
|
|
|
}
|
|
|
+
|
|
|
+ fn private_from_der(self, der: &[u8]) -> Result<PKey<OsslPrivate>> {
|
|
|
+ PKey::private_key_from_der(der).conv_err()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn generate(self) -> Result<AsymKeyPair<Self::Kind>> {
|
|
|
+ generate_rsa(self.kind())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<RsaSsaPss> for Sign {
|
|
|
+ fn from(scheme: RsaSsaPss) -> Self {
|
|
|
+ scheme.kind()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+pub trait KeyPrivacy {}
|
|
|
+
|
|
|
+#[derive(Clone, Debug)]
|
|
|
+pub enum Public {}
|
|
|
+
|
|
|
+impl KeyPrivacy for Public {}
|
|
|
+
|
|
|
+unsafe impl HasPublic for Public {}
|
|
|
+
|
|
|
+pub enum Private {}
|
|
|
+
|
|
|
+impl KeyPrivacy for Private {}
|
|
|
+
|
|
|
+unsafe impl HasPrivate for Private {}
|
|
|
+
|
|
|
+fn conv_pkey<T, Q>(pkey: PKey<T>) -> PKey<Q> {
|
|
|
+ let ptr = pkey.as_ptr();
|
|
|
+ let new_pkey = unsafe { PKey::from_ptr(ptr) };
|
|
|
+ std::mem::forget(pkey);
|
|
|
+ new_pkey
|
|
|
+}
|
|
|
+
|
|
|
+fn conv_pkey_pub(pkey: PKey<OsslPublic>) -> PKey<Public> {
|
|
|
+ conv_pkey(pkey)
|
|
|
+}
|
|
|
+
|
|
|
+fn conv_pkey_priv(pkey: PKey<OsslPrivate>) -> PKey<Private> {
|
|
|
+ conv_pkey(pkey)
|
|
|
}
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
-pub struct AsymKeyPub<S: Scheme> {
|
|
|
+pub struct AsymKey<P: KeyPrivacy, S: Scheme> {
|
|
|
scheme: S,
|
|
|
- pkey: PKey<Public>,
|
|
|
+ pkey: PKey<P>,
|
|
|
}
|
|
|
|
|
|
-impl<S: Scheme> AsymKeyPub<S> {
|
|
|
- pub(crate) fn new(scheme: S, der: &[u8]) -> Result<AsymKeyPub<S>> {
|
|
|
- let pkey = scheme.public_from_der(der)?;
|
|
|
- Ok(AsymKeyPub { scheme, pkey })
|
|
|
- }
|
|
|
+pub type AsymKeyPub<S> = AsymKey<Public, S>;
|
|
|
|
|
|
+impl<P: KeyPrivacy, S: Scheme> AsymKey<P, S> {
|
|
|
fn digest(&self) -> MessageDigest {
|
|
|
self.scheme.message_digest()
|
|
|
}
|
|
@@ -475,29 +582,43 @@ impl<S: Scheme> AsymKeyPub<S> {
|
|
|
fn padding(&self) -> Option<OpensslPadding> {
|
|
|
self.scheme.padding()
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+impl<S: Scheme> AsymKey<Public, S> {
|
|
|
+ pub(crate) fn new(scheme: S, der: &[u8]) -> Result<AsymKey<Public, S>> {
|
|
|
+ let pkey = conv_pkey_pub(scheme.public_from_der(der)?);
|
|
|
+ Ok(AsymKey { scheme, pkey })
|
|
|
+ }
|
|
|
|
|
|
fn to_der(&self) -> Result<Vec<u8>> {
|
|
|
self.pkey.public_key_to_der().conv_err()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl AsymKeyPub<Sign> {
|
|
|
+impl<S: Scheme> AsymKey<Private, S> {
|
|
|
+ pub(crate) fn new(scheme: S, der: &[u8]) -> Result<AsymKey<Private, S>> {
|
|
|
+ let pkey = conv_pkey_priv(scheme.private_from_der(der)?);
|
|
|
+ Ok(AsymKey { scheme, pkey })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<P: KeyPrivacy> AsymKey<P, Sign> {
|
|
|
fn signature_buf(&self) -> Signature {
|
|
|
self.scheme.sig_buf()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'de, S: Scheme> Deserialize<'de> for AsymKeyPub<S> {
|
|
|
+impl<'de, S: Scheme> Deserialize<'de> for AsymKey<Public, S> {
|
|
|
fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
|
|
|
const FIELDS: &[&str] = &["scheme", "pkey"];
|
|
|
|
|
|
struct StructVisitor<S: Scheme>(PhantomData<S>);
|
|
|
|
|
|
impl<'de, S: Scheme> Visitor<'de> for StructVisitor<S> {
|
|
|
- type Value = AsymKeyPub<S>;
|
|
|
+ type Value = AsymKey<Public, S>;
|
|
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
- formatter.write_fmt(format_args!("struct {}", stringify!(AsymKeyPub)))
|
|
|
+ formatter.write_fmt(format_args!("struct {}", stringify!(AsymKey)))
|
|
|
}
|
|
|
|
|
|
fn visit_seq<V: SeqAccess<'de>>(
|
|
@@ -507,18 +628,20 @@ impl<'de, S: Scheme> Deserialize<'de> for AsymKeyPub<S> {
|
|
|
.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(scheme, der.as_slice())
|
|
|
+ AsymKey::<Public, _>::new(scheme, der.as_slice())
|
|
|
.map_err(de::Error::custom)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- d.deserialize_struct(stringify!(AsymKeyPub), FIELDS, StructVisitor(PhantomData))
|
|
|
+ d.deserialize_struct(
|
|
|
+ stringify!(AsymKey), FIELDS, StructVisitor(PhantomData)
|
|
|
+ )
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<S: Scheme> Serialize for AsymKeyPub<S> {
|
|
|
+impl<S: Scheme> Serialize for AsymKey<Public, S> {
|
|
|
fn serialize<T: Serializer>(&self, s: T) -> std::result::Result<T::Ok, T::Error> {
|
|
|
- let mut struct_s = s.serialize_struct(stringify!(AsymKeyPub), 2)?;
|
|
|
+ let mut struct_s = s.serialize_struct(stringify!(AsymKey), 2)?;
|
|
|
struct_s.serialize_field("scheme", &self.scheme)?;
|
|
|
let der = self.pkey.public_key_to_der().unwrap();
|
|
|
struct_s.serialize_field("pkey", der.as_slice())?;
|
|
@@ -526,13 +649,13 @@ impl<S: Scheme> Serialize for AsymKeyPub<S> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<S: Scheme> PartialEq for AsymKeyPub<S> {
|
|
|
+impl<S: Scheme> PartialEq for AsymKey<Public, S> {
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
self.scheme == other.scheme && self.pkey.public_eq(&other.pkey)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Owned for AsymKeyPub<Sign> {
|
|
|
+impl Owned for AsymKey<Public, Sign> {
|
|
|
fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
match kind {
|
|
|
HashKind::Sha2_256 => {
|
|
@@ -553,29 +676,34 @@ impl Owned for AsymKeyPub<Sign> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub(crate) struct ConcreteCredsPriv {
|
|
|
- pkey: PKey<Private>,
|
|
|
-}
|
|
|
-
|
|
|
-impl ConcreteCredsPriv {
|
|
|
- pub(crate) fn new(der: &[u8]) -> Result<ConcreteCredsPriv> {
|
|
|
- let rsa = Rsa::private_key_from_der(der).conv_err()?;
|
|
|
- let pkey = PKey::from_rsa(rsa).conv_err()?;
|
|
|
- Ok(ConcreteCredsPriv { pkey })
|
|
|
- }
|
|
|
-
|
|
|
- fn digest() -> MessageDigest {
|
|
|
- MessageDigest::sha256()
|
|
|
- }
|
|
|
-
|
|
|
- fn signature_buf() -> Signature {
|
|
|
- Signature::new(SignatureKind::Rsa)
|
|
|
+impl Encrypter for AsymKey<Public, Encrypt> {
|
|
|
+ fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ let mut encrypter = OsslEncrypter::new(&self.pkey)?;
|
|
|
+ if let Some(padding) = self.padding() {
|
|
|
+ encrypter.set_rsa_padding(padding)?;
|
|
|
+ }
|
|
|
+ {
|
|
|
+ let Encrypt::RsaEsOaep(inner) = self.scheme;
|
|
|
+ encrypter.set_rsa_oaep_md(inner.message_digest())?;
|
|
|
+ }
|
|
|
+ let buffer_len = encrypter.encrypt_len(slice)?;
|
|
|
+ let mut ciphertext = vec![0; buffer_len];
|
|
|
+ let ciphertext_len = encrypter.encrypt(slice, &mut ciphertext)?;
|
|
|
+ ciphertext.truncate(ciphertext_len);
|
|
|
+ Ok(ciphertext)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Decrypter for ConcreteCredsPriv {
|
|
|
+impl Decrypter for AsymKey<Private, Encrypt> {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- let decrypter = OsslDecrypter::new(&self.pkey).conv_err()?;
|
|
|
+ let mut decrypter = OsslDecrypter::new(&self.pkey).conv_err()?;
|
|
|
+ if let Some(padding) = self.padding() {
|
|
|
+ decrypter.set_rsa_padding(padding).conv_err()?;
|
|
|
+ }
|
|
|
+ {
|
|
|
+ let Encrypt::RsaEsOaep(inner) = self.scheme;
|
|
|
+ decrypter.set_rsa_oaep_md(inner.message_digest())?;
|
|
|
+ }
|
|
|
let buffer_len = decrypter.decrypt_len(slice).conv_err()?;
|
|
|
let mut plaintext = vec![0; buffer_len];
|
|
|
let plaintext_len = decrypter.decrypt(slice, &mut plaintext).conv_err()?;
|
|
@@ -584,114 +712,131 @@ impl Decrypter for ConcreteCredsPriv {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Signer for ConcreteCredsPriv {
|
|
|
+impl Signer for AsymKey<Private, Sign> {
|
|
|
fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
- let digest = ConcreteCredsPriv::digest();
|
|
|
- let mut signature = ConcreteCredsPriv::signature_buf();
|
|
|
-
|
|
|
- let mut signer = OsslSigner::new(digest, &self.pkey).conv_err()?;
|
|
|
+ let mut signer = OsslSigner::new(self.scheme.message_digest(), &self.pkey)?;
|
|
|
+ if let Some(padding) = self.scheme.padding() {
|
|
|
+ signer.set_rsa_padding(padding)?;
|
|
|
+ }
|
|
|
for part in parts {
|
|
|
- signer.update(part).conv_err()?;
|
|
|
+ signer.update(part)?;
|
|
|
}
|
|
|
- let buf = signature.as_mut_slice();
|
|
|
- signer.sign(buf).conv_err()?;
|
|
|
+ let mut signature = self.scheme.sig_buf();
|
|
|
+ signer.sign(signature.as_mut_slice())?;
|
|
|
Ok(signature)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl CredsPriv for ConcreteCredsPriv {}
|
|
|
+impl Verifier for AsymKey<Public, Sign> {
|
|
|
+ fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
|
+ let mut verifier = OsslVerifier::new(self.digest(), &self.pkey)?;
|
|
|
+ if let Some(padding) = self.scheme.padding() {
|
|
|
+ verifier.set_rsa_padding(padding)?;
|
|
|
+ }
|
|
|
+ for part in parts {
|
|
|
+ verifier.update(part)?;
|
|
|
+ }
|
|
|
+ Ok(verifier.verify(signature)?)
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-pub struct ConcreteCredsPub {
|
|
|
- pub encrypt: AsymKeyPub<Encrypt>,
|
|
|
- pub sign: AsymKeyPub<Sign>,
|
|
|
+pub struct AsymKeyPair<S: Scheme> {
|
|
|
+ public: AsymKey<Public, S>,
|
|
|
+ private: AsymKey<Private, S>,
|
|
|
}
|
|
|
|
|
|
-impl Verifier for ConcreteCredsPub {
|
|
|
- fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
|
- self.sign.verify(parts, signature)
|
|
|
+impl<S: Scheme> AsymKeyPair<S> {
|
|
|
+ pub fn new(scheme: S, public_der: &[u8], private_der: &[u8]) -> Result<AsymKeyPair<S>> {
|
|
|
+ let public = AsymKey::<Public, _>::new(scheme, public_der)?;
|
|
|
+ let private = AsymKey::<Private, _>::new(scheme, private_der)?;
|
|
|
+ Ok(AsymKeyPair { public, private })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Encrypter for ConcreteCredsPub {
|
|
|
- fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- self.encrypt.encrypt(slice)
|
|
|
+impl Owned for AsymKeyPair<Sign> {
|
|
|
+ fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
+ self.public.owner_of_kind(kind)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Owned for ConcreteCredsPub {
|
|
|
- fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
- self.sign.owner_of_kind(kind)
|
|
|
+impl Encrypter for AsymKeyPair<Encrypt> {
|
|
|
+ fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ self.public.encrypt(slice)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl CredsPub for ConcreteCredsPub {}
|
|
|
+impl Decrypter for AsymKeyPair<Encrypt> {
|
|
|
+ fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ self.private.decrypt(slice)
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-pub(crate) struct ConcreteCreds<T: CredsPriv> {
|
|
|
- public: ConcreteCredsPub,
|
|
|
- private: T,
|
|
|
+impl Signer for AsymKeyPair<Sign> {
|
|
|
+ fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ self.private.sign(parts)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> ConcreteCreds<T> {
|
|
|
- pub(crate) fn new(public: ConcreteCredsPub, private: T) -> ConcreteCreds<T> {
|
|
|
- ConcreteCreds { public, private }
|
|
|
+impl Verifier for AsymKeyPair<Sign> {
|
|
|
+ fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
|
+ self.public.verify(parts, signature)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+pub struct ConcreteCreds {
|
|
|
+ sign: AsymKeyPair<Sign>,
|
|
|
+ encrypt: AsymKeyPair<Encrypt>,
|
|
|
+}
|
|
|
|
|
|
-impl ConcreteCreds<ConcreteCredsPriv> {
|
|
|
- pub(crate) fn generate() -> Result<ConcreteCreds<ConcreteCredsPriv>> {
|
|
|
- let key_bits = 8 * u32::try_from(RSA_KEY_BYTES).conv_err()?;
|
|
|
- let key = Rsa::generate(key_bits)?;
|
|
|
- // TODO: Separating the keys this way seems inefficient. Investigate alternatives.
|
|
|
- let public_der = key.public_key_to_der().conv_err()?;
|
|
|
- let private_der = key.private_key_to_der().conv_err()?;
|
|
|
- Ok(ConcreteCreds {
|
|
|
- public: ConcreteCredsPub {
|
|
|
- encrypt: AsymKeyPub::new(Encrypt::RSA_OAEP_3072_SHA_256, public_der.as_slice())?,
|
|
|
- sign: AsymKeyPub::new(Sign::RSA_PSS_3072_SHA_256, public_der.as_slice())?,
|
|
|
- },
|
|
|
- private: ConcreteCredsPriv::new(private_der.as_slice())?,
|
|
|
- })
|
|
|
+impl ConcreteCreds {
|
|
|
+ pub(crate) fn new(sign: AsymKeyPair<Sign>, encrypt: AsymKeyPair<Encrypt>) -> ConcreteCreds {
|
|
|
+ ConcreteCreds { sign, encrypt }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub(crate) fn generate() -> Result<ConcreteCreds> {
|
|
|
+ let encrypt = Encrypt::RSA_OAEP_3072_SHA_256.generate()?;
|
|
|
+ let sign = Sign::RSA_PSS_3072_SHA_256.generate()?;
|
|
|
+ Ok(ConcreteCreds { sign, encrypt })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> Verifier for ConcreteCreds<T> {
|
|
|
+impl Verifier for ConcreteCreds {
|
|
|
fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
|
- self.public.verify(parts, signature)
|
|
|
+ self.sign.verify(parts, signature)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> Encrypter for ConcreteCreds<T> {
|
|
|
+impl Encrypter for ConcreteCreds {
|
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- self.public.encrypt(slice)
|
|
|
+ self.encrypt.encrypt(slice)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> Owned for ConcreteCreds<T> {
|
|
|
+impl Owned for ConcreteCreds {
|
|
|
fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
- self.public.owner_of_kind(kind)
|
|
|
+ self.sign.owner_of_kind(kind)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> CredsPub for ConcreteCreds<T> {}
|
|
|
+impl CredsPub for ConcreteCreds {}
|
|
|
|
|
|
-impl<T: CredsPriv> Signer for ConcreteCreds<T> {
|
|
|
+impl Signer for ConcreteCreds {
|
|
|
fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
- self.private.sign(parts)
|
|
|
+ self.sign.sign(parts)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> Decrypter for ConcreteCreds<T> {
|
|
|
+impl Decrypter for ConcreteCreds {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- self.private.decrypt(slice)
|
|
|
+ self.encrypt.decrypt(slice)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> CredsPriv for ConcreteCreds<T> {}
|
|
|
+impl CredsPriv for ConcreteCreds {}
|
|
|
|
|
|
-impl<T: CredsPriv> Creds for ConcreteCreds<T> {
|
|
|
- fn public(&self) -> &AsymKeyPub<Sign> {
|
|
|
- &self.public.sign
|
|
|
+impl Creds for ConcreteCreds {
|
|
|
+ fn public(&self) -> &AsymKey<Public, Sign> {
|
|
|
+ &self.sign.public
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -699,39 +844,10 @@ pub(crate) trait Encrypter {
|
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
|
-impl Encrypter for SymKey {
|
|
|
- fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- let SymParams { cipher, key, iv } = self.params();
|
|
|
- openssl_encrypt(cipher, key, iv, slice).conv_err()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl Encrypter for AsymKeyPub<Encrypt> {
|
|
|
- fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- let mut encrypter = OsslEncrypter::new(&self.pkey).conv_err()?;
|
|
|
- if let Some(padding) = self.padding() {
|
|
|
- encrypter.set_rsa_padding(padding).conv_err()?;
|
|
|
- }
|
|
|
- let buffer_len = encrypter.encrypt_len(slice).conv_err()?;
|
|
|
- let mut ciphertext = vec![0; buffer_len];
|
|
|
- let ciphertext_len = encrypter.encrypt(slice, &mut ciphertext)
|
|
|
- .conv_err()?;
|
|
|
- ciphertext.truncate(ciphertext_len);
|
|
|
- Ok(ciphertext)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
pub(crate) trait Decrypter {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
|
-impl Decrypter for SymKey {
|
|
|
- fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- let SymParams { cipher, key, iv } = self.params();
|
|
|
- openssl_decrypt(cipher, key, iv, slice).conv_err()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
pub(crate) trait Signer {
|
|
|
fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature>;
|
|
|
}
|
|
@@ -740,16 +856,6 @@ pub(crate) trait Verifier {
|
|
|
fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool>;
|
|
|
}
|
|
|
|
|
|
-impl Verifier for AsymKeyPub<Sign> {
|
|
|
- fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
|
- let mut verifier = OsslVerifier::new(self.digest(), &self.pkey).conv_err()?;
|
|
|
- for part in parts {
|
|
|
- verifier.update(part).conv_err()?;
|
|
|
- }
|
|
|
- verifier.verify(signature).conv_err()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/// Trait for types which can be used as public credentials.
|
|
|
pub(crate) trait CredsPub: Verifier + Encrypter + Owned {}
|
|
|
|
|
@@ -758,7 +864,7 @@ pub(crate) trait CredsPriv: Decrypter + Signer {}
|
|
|
|
|
|
/// Trait for types which contain both public and private credentials.
|
|
|
pub(crate) trait Creds: CredsPriv + CredsPub {
|
|
|
- fn public(&self) -> &AsymKeyPub<Sign>;
|
|
|
+ fn public(&self) -> &AsymKey<Public, Sign>;
|
|
|
}
|
|
|
|
|
|
/// A trait for types which store credentials.
|
|
@@ -776,7 +882,7 @@ pub(crate) trait CredStore {
|
|
|
fn gen_root_creds(&self, password: &str) -> Result<Self::CredHandle>;
|
|
|
}
|
|
|
|
|
|
-pub(crate) fn encrypt_block<C: Creds>(
|
|
|
+pub(crate) fn encrypt_block<C: Encrypter + Decrypter>(
|
|
|
mut block: Block, principal: &Principal, creds: &C
|
|
|
) -> Result<Block> {
|
|
|
let body = match block.body {
|
|
@@ -792,8 +898,8 @@ pub(crate) fn encrypt_block<C: Creds>(
|
|
|
Ok(block)
|
|
|
}
|
|
|
|
|
|
-pub(crate) fn decrypt_block<K: CredsPriv>(
|
|
|
- mut block: Block, principal: &Principal, key: &K
|
|
|
+pub(crate) fn decrypt_block<C: Decrypter>(
|
|
|
+ mut block: Block, principal: &Principal, creds: &C
|
|
|
) -> Result<Block> {
|
|
|
let body = match block.body {
|
|
|
Cryptotext::Plain(_) => return Ok(block),
|
|
@@ -801,7 +907,7 @@ pub(crate) fn decrypt_block<K: CredsPriv>(
|
|
|
};
|
|
|
let (principal_owned, read_cap) = block.readcaps.remove_entry(principal)
|
|
|
.ok_or(Error::NoReadCap)?;
|
|
|
- let block_key = decrypt(read_cap, key)?;
|
|
|
+ let block_key = decrypt(read_cap, creds)?;
|
|
|
let new_body = block_key.decrypt(&body)?;
|
|
|
block.body = Cryptotext::Plain(new_body);
|
|
|
block.readcaps.insert(principal_owned, Cryptotext::Plain(block_key));
|
|
@@ -814,7 +920,7 @@ fn encrypt<T: Serialize, K: Encrypter>(value: &T, key: &K) -> Result<Cryptotext<
|
|
|
Ok(Cryptotext::Cipher(vec?))
|
|
|
}
|
|
|
|
|
|
-fn decrypt<T: Serialize + DeserializeOwned, K: CredsPriv>(
|
|
|
+fn decrypt<T: Serialize + DeserializeOwned, K: Decrypter>(
|
|
|
cryptotext: Cryptotext<T>, key: &K
|
|
|
) -> Result<T> {
|
|
|
let data = match cryptotext {
|
|
@@ -877,7 +983,7 @@ struct WritecapSigInput<'a> {
|
|
|
issued_to: &'a Principal,
|
|
|
path: &'a Path,
|
|
|
expires: &'a Epoch,
|
|
|
- signing_key: &'a AsymKeyPub<Sign>,
|
|
|
+ signing_key: &'a AsymKey<Public, Sign>,
|
|
|
}
|
|
|
|
|
|
impl<'a> From<&'a Writecap> for WritecapSigInput<'a> {
|