|
@@ -20,7 +20,7 @@ use serde::{
|
|
|
ser::{Serializer, SerializeStruct},
|
|
|
};
|
|
|
use std::{
|
|
|
- str::FromStr, num::TryFromIntError,
|
|
|
+ str::FromStr, num::TryFromIntError, marker::PhantomData,
|
|
|
};
|
|
|
use strum_macros::{EnumString, EnumDiscriminants, Display};
|
|
|
|
|
@@ -35,7 +35,7 @@ pub(crate) enum Cryptotext<T: Serialize> {
|
|
|
|
|
|
/// Errors that can occur during cryptographic operations.
|
|
|
#[derive(Debug)]
|
|
|
-pub(crate) enum Error {
|
|
|
+pub enum Error {
|
|
|
NoReadCap,
|
|
|
NoKeyAvailable,
|
|
|
MissingPrivateKey,
|
|
@@ -108,7 +108,7 @@ impl<T, E: Into<Error>> ConvErr<T> for std::result::Result<T, E> {
|
|
|
|
|
|
/// A cryptographic hash.
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable, Clone, EnumDiscriminants)]
|
|
|
-#[strum_discriminants(derive(EnumString, Display))]
|
|
|
+#[strum_discriminants(derive(EnumString, Display, Serialize, Deserialize))]
|
|
|
#[strum_discriminants(name(HashKind))]
|
|
|
pub(crate) enum Hash {
|
|
|
Sha2_256([u8; 32]),
|
|
@@ -122,6 +122,15 @@ impl Default for HashKind {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl From<HashKind> for MessageDigest {
|
|
|
+ fn from(kind: HashKind) -> Self {
|
|
|
+ match kind {
|
|
|
+ HashKind::Sha2_256 => MessageDigest::sha256(),
|
|
|
+ HashKind::Sha2_512 => MessageDigest::sha512(),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Hash {
|
|
|
/// The character that's used to separate a hash type from its value in its string
|
|
|
/// representation.
|
|
@@ -283,59 +292,209 @@ impl SymKey {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
|
-pub(crate) enum AsymKeyKind {
|
|
|
- Rsa,
|
|
|
+pub trait Scheme: for<'de> Deserialize<'de> + Serialize + Copy + std::fmt::Debug + PartialEq {
|
|
|
+ type Kind;
|
|
|
+ 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>>;
|
|
|
}
|
|
|
|
|
|
-#[derive(Debug, Clone)]
|
|
|
-pub(crate) struct AsymKeyPub {
|
|
|
- kind: AsymKeyKind,
|
|
|
- pkey: PKey<Public>,
|
|
|
+pub enum SchemeKind {
|
|
|
+ Sign(Sign),
|
|
|
+ Encrypt(Encrypt),
|
|
|
}
|
|
|
|
|
|
-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).conv_err()?;
|
|
|
- PKey::from_rsa(rsa).conv_err()?
|
|
|
- }
|
|
|
- };
|
|
|
- Ok(AsymKeyPub { kind, pkey })
|
|
|
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Copy)]
|
|
|
+pub enum Encrypt {
|
|
|
+ RsaEsOaep(RsaEsOaep),
|
|
|
+}
|
|
|
+
|
|
|
+impl Scheme for Encrypt {
|
|
|
+ type Kind = Encrypt;
|
|
|
+
|
|
|
+ fn kind(self) -> Encrypt {
|
|
|
+ self
|
|
|
}
|
|
|
|
|
|
- fn digest(&self) -> MessageDigest {
|
|
|
- match self.kind {
|
|
|
- AsymKeyKind::Rsa => MessageDigest::sha256(),
|
|
|
+ fn as_enum(self) -> SchemeKind {
|
|
|
+ SchemeKind::Encrypt(self.kind())
|
|
|
+ }
|
|
|
+
|
|
|
+ fn message_digest(&self) -> MessageDigest {
|
|
|
+ match self {
|
|
|
+ Encrypt::RsaEsOaep(inner) => inner.message_digest(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn signature_buf(&self) -> Signature {
|
|
|
- match self.kind {
|
|
|
- AsymKeyKind::Rsa => Signature::new(SignatureKind::Rsa),
|
|
|
+ fn padding(&self) -> Option<OpensslPadding> {
|
|
|
+ match self {
|
|
|
+ Encrypt::RsaEsOaep(inner) => inner.padding(),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ match self {
|
|
|
+ Encrypt::RsaEsOaep(inner) => inner.public_from_der(der),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Encrypt {
|
|
|
+ pub const RSA_OAEP_3072_SHA_256: Encrypt = Encrypt::RsaEsOaep(RsaEsOaep {
|
|
|
+ key_bytes: 384,
|
|
|
+ hash_kind: HashKind::Sha2_256,
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Copy)]
|
|
|
+pub enum Sign {
|
|
|
+ RsaSsaPss(RsaSsaPss),
|
|
|
+}
|
|
|
+
|
|
|
+impl Scheme for Sign {
|
|
|
+ type Kind = Sign;
|
|
|
+
|
|
|
+ fn kind(self) -> Sign {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ fn as_enum(self) -> SchemeKind {
|
|
|
+ SchemeKind::Sign(self.kind())
|
|
|
+ }
|
|
|
+
|
|
|
+ fn message_digest(&self) -> MessageDigest {
|
|
|
+ match self {
|
|
|
+ Sign::RsaSsaPss(inner) => inner.message_digest(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
fn padding(&self) -> Option<OpensslPadding> {
|
|
|
- match self.kind {
|
|
|
- AsymKeyKind::Rsa => Some(OpensslPadding::PKCS1),
|
|
|
+ match self {
|
|
|
+ Sign::RsaSsaPss(inner) => inner.padding(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ match self {
|
|
|
+ Sign::RsaSsaPss(inner) => inner.public_from_der(der),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Sign {
|
|
|
+ pub const RSA_PSS_3072_SHA_256: Sign = Sign::RsaSsaPss(RsaSsaPss {
|
|
|
+ key_bytes: 384,
|
|
|
+ hash_kind: HashKind::Sha2_256,
|
|
|
+ });
|
|
|
+
|
|
|
+ fn sig_buf(&self) -> Signature {
|
|
|
+ match self {
|
|
|
+ Sign::RsaSsaPss(_) => Signature::Rsa([0u8; RSA_KEY_BYTES]),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Copy)]
|
|
|
+pub struct RsaEsOaep {
|
|
|
+ key_bytes: usize,
|
|
|
+ hash_kind: HashKind,
|
|
|
+}
|
|
|
+
|
|
|
+impl Scheme for RsaEsOaep {
|
|
|
+ type Kind = Encrypt;
|
|
|
+
|
|
|
+ fn kind(self) -> Encrypt {
|
|
|
+ Encrypt::RsaEsOaep(self)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn as_enum(self) -> SchemeKind {
|
|
|
+ SchemeKind::Encrypt(self.kind())
|
|
|
+ }
|
|
|
+
|
|
|
+ fn message_digest(&self) -> MessageDigest {
|
|
|
+ self.hash_kind.into()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn padding(&self) -> Option<OpensslPadding> {
|
|
|
+ Some(OpensslPadding::PKCS1_OAEP)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ PKey::public_key_from_der(der).conv_err()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Copy)]
|
|
|
+pub struct RsaSsaPss {
|
|
|
+ key_bytes: usize,
|
|
|
+ hash_kind: HashKind,
|
|
|
+}
|
|
|
+
|
|
|
+impl Scheme for RsaSsaPss {
|
|
|
+ type Kind = Sign;
|
|
|
+
|
|
|
+ fn kind(self) -> Sign {
|
|
|
+ Sign::RsaSsaPss(self)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn as_enum(self) -> SchemeKind {
|
|
|
+ SchemeKind::Sign(self.kind())
|
|
|
+ }
|
|
|
+
|
|
|
+ fn message_digest(&self) -> MessageDigest {
|
|
|
+ self.hash_kind.into()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn padding(&self) -> Option<OpensslPadding> {
|
|
|
+ Some(OpensslPadding::PKCS1_PSS)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn public_from_der(self, der: &[u8]) -> Result<PKey<Public>> {
|
|
|
+ PKey::public_key_from_der(der).conv_err()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Debug, Clone)]
|
|
|
+pub struct AsymKeyPub<S: Scheme> {
|
|
|
+ scheme: S,
|
|
|
+ pkey: PKey<Public>,
|
|
|
+}
|
|
|
+
|
|
|
+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 })
|
|
|
+ }
|
|
|
+
|
|
|
+ fn digest(&self) -> MessageDigest {
|
|
|
+ self.scheme.message_digest()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn padding(&self) -> Option<OpensslPadding> {
|
|
|
+ self.scheme.padding()
|
|
|
+ }
|
|
|
+
|
|
|
fn to_der(&self) -> Result<Vec<u8>> {
|
|
|
self.pkey.public_key_to_der().conv_err()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'de> Deserialize<'de> for AsymKeyPub {
|
|
|
+impl AsymKeyPub<Sign> {
|
|
|
+ fn signature_buf(&self) -> Signature {
|
|
|
+ self.scheme.sig_buf()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'de, S: Scheme> Deserialize<'de> for AsymKeyPub<S> {
|
|
|
fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
|
|
|
- const FIELDS: &[&str] = &["kind", "pkey"];
|
|
|
+ const FIELDS: &[&str] = &["scheme", "pkey"];
|
|
|
|
|
|
- struct StructVisitor;
|
|
|
+ struct StructVisitor<S: Scheme>(PhantomData<S>);
|
|
|
|
|
|
- impl<'de> Visitor<'de> for StructVisitor {
|
|
|
- type Value = AsymKeyPub;
|
|
|
+ impl<'de, S: Scheme> Visitor<'de> for StructVisitor<S> {
|
|
|
+ type Value = AsymKeyPub<S>;
|
|
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
formatter.write_fmt(format_args!("struct {}", stringify!(AsymKeyPub)))
|
|
@@ -343,37 +502,37 @@ impl<'de> Deserialize<'de> for AsymKeyPub {
|
|
|
|
|
|
fn visit_seq<V: SeqAccess<'de>>(
|
|
|
self, mut seq: V
|
|
|
- ) -> std::result::Result<AsymKeyPub, V::Error> {
|
|
|
- let kind: AsymKeyKind = seq.next_element()?
|
|
|
+ ) -> std::result::Result<Self::Value, V::Error> {
|
|
|
+ let scheme: S = 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())
|
|
|
+ AsymKeyPub::new(scheme, der.as_slice())
|
|
|
.map_err(de::Error::custom)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- d.deserialize_struct(stringify!(AsymKeyPub), FIELDS, StructVisitor)
|
|
|
+ d.deserialize_struct(stringify!(AsymKeyPub), FIELDS, StructVisitor(PhantomData))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Serialize for AsymKeyPub {
|
|
|
- fn serialize<S: Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
|
|
|
+impl<S: Scheme> Serialize for AsymKeyPub<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)?;
|
|
|
- struct_s.serialize_field("kind", &self.kind)?;
|
|
|
+ struct_s.serialize_field("scheme", &self.scheme)?;
|
|
|
let der = self.pkey.public_key_to_der().unwrap();
|
|
|
struct_s.serialize_field("pkey", der.as_slice())?;
|
|
|
struct_s.end()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl PartialEq for AsymKeyPub {
|
|
|
+impl<S: Scheme> PartialEq for AsymKeyPub<S> {
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
- self.kind == other.kind && self.pkey.public_eq(&other.pkey)
|
|
|
+ self.scheme == other.scheme && self.pkey.public_eq(&other.pkey)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Owned for AsymKeyPub {
|
|
|
+impl Owned for AsymKeyPub<Sign> {
|
|
|
fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
match kind {
|
|
|
HashKind::Sha2_256 => {
|
|
@@ -394,17 +553,15 @@ impl Owned for AsymKeyPub {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl CredsPub for AsymKeyPub {}
|
|
|
-
|
|
|
-pub(crate) struct RsaPriv {
|
|
|
+pub(crate) struct ConcreteCredsPriv {
|
|
|
pkey: PKey<Private>,
|
|
|
}
|
|
|
|
|
|
-impl RsaPriv {
|
|
|
- pub(crate) fn new(der: &[u8]) -> Result<RsaPriv> {
|
|
|
+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(RsaPriv { pkey })
|
|
|
+ Ok(ConcreteCredsPriv { pkey })
|
|
|
}
|
|
|
|
|
|
fn digest() -> MessageDigest {
|
|
@@ -416,7 +573,7 @@ impl RsaPriv {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Decrypter for RsaPriv {
|
|
|
+impl Decrypter for ConcreteCredsPriv {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
let decrypter = OsslDecrypter::new(&self.pkey).conv_err()?;
|
|
|
let buffer_len = decrypter.decrypt_len(slice).conv_err()?;
|
|
@@ -427,10 +584,10 @@ impl Decrypter for RsaPriv {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Signer for RsaPriv {
|
|
|
+impl Signer for ConcreteCredsPriv {
|
|
|
fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
- let digest = RsaPriv::digest();
|
|
|
- let mut signature = RsaPriv::signature_buf();
|
|
|
+ let digest = ConcreteCredsPriv::digest();
|
|
|
+ let mut signature = ConcreteCredsPriv::signature_buf();
|
|
|
|
|
|
let mut signer = OsslSigner::new(digest, &self.pkey).conv_err()?;
|
|
|
for part in parts {
|
|
@@ -442,30 +599,58 @@ impl Signer for RsaPriv {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl CredsPriv for RsaPriv {}
|
|
|
+impl CredsPriv for ConcreteCredsPriv {}
|
|
|
+
|
|
|
+pub struct ConcreteCredsPub {
|
|
|
+ pub encrypt: AsymKeyPub<Encrypt>,
|
|
|
+ pub sign: AsymKeyPub<Sign>,
|
|
|
+}
|
|
|
+
|
|
|
+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 Encrypter for ConcreteCredsPub {
|
|
|
+ fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ self.encrypt.encrypt(slice)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Owned for ConcreteCredsPub {
|
|
|
+ fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
|
+ self.sign.owner_of_kind(kind)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl CredsPub for ConcreteCredsPub {}
|
|
|
|
|
|
pub(crate) struct ConcreteCreds<T: CredsPriv> {
|
|
|
- public: AsymKeyPub,
|
|
|
+ public: ConcreteCredsPub,
|
|
|
private: T,
|
|
|
}
|
|
|
|
|
|
impl<T: CredsPriv> ConcreteCreds<T> {
|
|
|
- pub(crate) fn new(public: AsymKeyPub, private: T) -> ConcreteCreds<T> {
|
|
|
+ pub(crate) fn new(public: ConcreteCredsPub, private: T) -> ConcreteCreds<T> {
|
|
|
ConcreteCreds { public, private }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
-impl ConcreteCreds<RsaPriv> {
|
|
|
- pub(crate) fn generate() -> Result<ConcreteCreds<RsaPriv>> {
|
|
|
+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: AsymKeyPub::new(AsymKeyKind::Rsa, public_der.as_slice())?,
|
|
|
- private: RsaPriv::new(private_der.as_slice())?,
|
|
|
+ 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())?,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
@@ -505,8 +690,8 @@ impl<T: CredsPriv> Decrypter for ConcreteCreds<T> {
|
|
|
impl<T: CredsPriv> CredsPriv for ConcreteCreds<T> {}
|
|
|
|
|
|
impl<T: CredsPriv> Creds for ConcreteCreds<T> {
|
|
|
- fn public(&self) -> &AsymKeyPub {
|
|
|
- &self.public
|
|
|
+ fn public(&self) -> &AsymKeyPub<Sign> {
|
|
|
+ &self.public.sign
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -521,7 +706,7 @@ impl Encrypter for SymKey {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Encrypter for AsymKeyPub {
|
|
|
+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() {
|
|
@@ -555,7 +740,7 @@ pub(crate) trait Verifier {
|
|
|
fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool>;
|
|
|
}
|
|
|
|
|
|
-impl Verifier for AsymKeyPub {
|
|
|
+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 {
|
|
@@ -573,7 +758,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;
|
|
|
+ fn public(&self) -> &AsymKeyPub<Sign>;
|
|
|
}
|
|
|
|
|
|
/// A trait for types which store credentials.
|
|
@@ -692,7 +877,7 @@ struct WritecapSigInput<'a> {
|
|
|
issued_to: &'a Principal,
|
|
|
path: &'a Path,
|
|
|
expires: &'a Epoch,
|
|
|
- signing_key: &'a AsymKeyPub,
|
|
|
+ signing_key: &'a AsymKeyPub<Sign>,
|
|
|
}
|
|
|
|
|
|
impl<'a> From<&'a Writecap> for WritecapSigInput<'a> {
|
|
@@ -907,10 +1092,7 @@ mod tests {
|
|
|
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)?;
|
|
|
- let node_key = AsymKeyPub {
|
|
|
- kind: AsymKeyKind::Rsa,
|
|
|
- pkey: PKey::from_rsa(Rsa::public_key_from_der(NODE_PUBLIC_KEY.as_slice())?)?
|
|
|
- };
|
|
|
+ let node_key = AsymKeyPub::new(Sign::RSA_PSS_3072_SHA_256, NODE_PUBLIC_KEY.as_slice())?;
|
|
|
let node_principal = node_key.owner();
|
|
|
let writecap = make_writecap_trusted_by(
|
|
|
root_writecap, root_key, node_principal, vec!["apps", "contacts"])?;
|
|
@@ -925,10 +1107,7 @@ mod tests {
|
|
|
let owner = Principal(Hash::Sha2_256([0; 32]));
|
|
|
root_writecap.path = make_path_with_owner(owner, vec![]);
|
|
|
sign_writecap(&mut root_writecap, &root_key)?;
|
|
|
- let node_key = AsymKeyPub {
|
|
|
- kind: AsymKeyKind::Rsa,
|
|
|
- pkey: PKey::from_rsa(Rsa::public_key_from_der(NODE_PUBLIC_KEY.as_slice())?)?
|
|
|
- };
|
|
|
+ let node_key = AsymKeyPub::new(Sign::RSA_PSS_3072_SHA_256, NODE_PUBLIC_KEY.as_slice())?;
|
|
|
let node_owner = node_key.owner();
|
|
|
let writecap = make_writecap_trusted_by(
|
|
|
root_writecap, root_key, node_owner, vec!["apps", "contacts"])?;
|