|
@@ -41,7 +41,7 @@ use std::{
|
|
|
fmt::Display,
|
|
|
io::{Read, Write},
|
|
|
marker::PhantomData,
|
|
|
- ops::Deref,
|
|
|
+ ops::{Deref, DerefMut},
|
|
|
sync::Arc,
|
|
|
};
|
|
|
use strum_macros::{Display, EnumDiscriminants, FromRepr};
|
|
@@ -113,6 +113,8 @@ pub enum Error {
|
|
|
SignatureMismatch(Box<SignatureMismatch>),
|
|
|
/// This variant is used to convey errors that originated in an underlying library.
|
|
|
Library(Box<dyn ::std::error::Error + Send + Sync + 'static>),
|
|
|
+ /// Occurs when an attempt is made to finish an [Op] that is already finished.
|
|
|
+ OpAlreadyFinished,
|
|
|
}
|
|
|
|
|
|
impl Error {
|
|
@@ -164,6 +166,7 @@ impl Display for Error {
|
|
|
)
|
|
|
}
|
|
|
Error::Library(err) => err.fmt(f),
|
|
|
+ Error::OpAlreadyFinished => write!(f, "operation is already finished"),
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -197,19 +200,23 @@ pub fn rand_vec(len: usize) -> Result<Vec<u8>> {
|
|
|
}
|
|
|
|
|
|
/// An ongoing Init-Update-Finish operation.
|
|
|
-pub trait Op: Sized {
|
|
|
- /// The type of the argument given to `init`.
|
|
|
- type Arg;
|
|
|
-
|
|
|
- /// Initialize a new operation.
|
|
|
- fn init(arg: Self::Arg) -> Result<Self>;
|
|
|
-
|
|
|
+pub trait Op {
|
|
|
/// Update this operation using the given data.
|
|
|
fn update(&mut self, data: &[u8]) -> Result<()>;
|
|
|
|
|
|
/// Finish this operation and write the result into the given buffer. If the given buffer is not
|
|
|
/// large enough the implementation must return Error::IncorrectSize.
|
|
|
- fn finish_into(self, buf: &mut [u8]) -> Result<usize>;
|
|
|
+ fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize>;
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: ?Sized + Op, P: DerefMut<Target = T>> Op for P {
|
|
|
+ fn update(&mut self, data: &[u8]) -> Result<()> {
|
|
|
+ self.deref_mut().update(data)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
+ self.deref_mut().finish_into(buf)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// An ongoing hash hash operation.
|
|
@@ -221,7 +228,7 @@ pub trait HashOp: Op {
|
|
|
fn kind(&self) -> HashKind;
|
|
|
|
|
|
/// Finish this operation and return a hash type containing the result.
|
|
|
- fn finish(self) -> Result<Self::Hash>;
|
|
|
+ fn finish(&mut self) -> Result<Self::Hash>;
|
|
|
}
|
|
|
|
|
|
// A hash operation which uses OpenSSL.
|
|
@@ -231,10 +238,8 @@ pub struct OsslHashOp<H> {
|
|
|
kind: HashKind,
|
|
|
}
|
|
|
|
|
|
-impl<H> Op for OsslHashOp<H> {
|
|
|
- type Arg = HashKind;
|
|
|
-
|
|
|
- fn init(arg: Self::Arg) -> Result<Self> {
|
|
|
+impl<H> OsslHashOp<H> {
|
|
|
+ fn new(arg: HashKind) -> Result<Self> {
|
|
|
let hasher = Hasher::new(arg.into())?;
|
|
|
let phantom = PhantomData;
|
|
|
Ok(OsslHashOp {
|
|
@@ -243,12 +248,14 @@ impl<H> Op for OsslHashOp<H> {
|
|
|
kind: arg,
|
|
|
})
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+impl<H> Op for OsslHashOp<H> {
|
|
|
fn update(&mut self, data: &[u8]) -> Result<()> {
|
|
|
Ok(self.hasher.update(data)?)
|
|
|
}
|
|
|
|
|
|
- fn finish_into(mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
+ fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
if buf.len() < self.kind.len() {
|
|
|
return Err(bterr!(Error::IncorrectSize {
|
|
|
expected: self.kind.len(),
|
|
@@ -269,7 +276,7 @@ impl<H: Hash + From<DigestBytes>> HashOp for OsslHashOp<H> {
|
|
|
self.kind
|
|
|
}
|
|
|
|
|
|
- fn finish(mut self) -> Result<Self::Hash> {
|
|
|
+ fn finish(&mut self) -> Result<Self::Hash> {
|
|
|
let digest = self.hasher.finish()?;
|
|
|
Ok(H::from(digest))
|
|
|
}
|
|
@@ -294,7 +301,7 @@ impl<T, Op: HashOp> HashStream<T, Op> {
|
|
|
|
|
|
/// Finish this hash operation and write the result into the given buffer. The number of bytes
|
|
|
/// written is returned.
|
|
|
- pub fn finish_into(self, buf: &mut [u8]) -> Result<usize> {
|
|
|
+ pub fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
if self.update_failed {
|
|
|
return Err(bterr!(
|
|
|
"HashStream::finish_into can't produce result due to HashOp update failure",
|
|
@@ -304,7 +311,7 @@ impl<T, Op: HashOp> HashStream<T, Op> {
|
|
|
}
|
|
|
|
|
|
/// Finish this hash operation and return the resulting hash.
|
|
|
- pub fn finish(self) -> Result<Op::Hash> {
|
|
|
+ pub fn finish(&mut self) -> Result<Op::Hash> {
|
|
|
if self.update_failed {
|
|
|
return Err(bterr!(
|
|
|
"HashStream::finish can't produce result due to HashOp update failure",
|
|
@@ -424,7 +431,7 @@ impl Hash for Sha2_256 {
|
|
|
}
|
|
|
|
|
|
fn start_op(&self) -> Result<Self::Op> {
|
|
|
- OsslHashOp::init(Self::KIND)
|
|
|
+ OsslHashOp::new(Self::KIND)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -481,7 +488,7 @@ impl Hash for Sha2_512 {
|
|
|
}
|
|
|
|
|
|
fn start_op(&self) -> Result<Self::Op> {
|
|
|
- OsslHashOp::init(Self::KIND)
|
|
|
+ OsslHashOp::new(Self::KIND)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -715,7 +722,7 @@ impl Hash for VarHash {
|
|
|
}
|
|
|
|
|
|
fn start_op(&self) -> Result<Self::Op> {
|
|
|
- VarHashOp::init(self.kind())
|
|
|
+ VarHashOp::new(self.kind())
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -752,19 +759,19 @@ pub struct VarHashOp {
|
|
|
hasher: Hasher,
|
|
|
}
|
|
|
|
|
|
-impl Op for VarHashOp {
|
|
|
- type Arg = HashKind;
|
|
|
-
|
|
|
- fn init(arg: Self::Arg) -> Result<Self> {
|
|
|
+impl VarHashOp {
|
|
|
+ pub fn new(arg: HashKind) -> Result<Self> {
|
|
|
let hasher = Hasher::new(arg.into())?;
|
|
|
Ok(VarHashOp { kind: arg, hasher })
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+impl Op for VarHashOp {
|
|
|
fn update(&mut self, data: &[u8]) -> Result<()> {
|
|
|
Ok(self.hasher.update(data)?)
|
|
|
}
|
|
|
|
|
|
- fn finish_into(mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
+ fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
btensure!(
|
|
|
buf.len() >= self.kind.len(),
|
|
|
bterr!(Error::IncorrectSize {
|
|
@@ -786,7 +793,7 @@ impl HashOp for VarHashOp {
|
|
|
self.kind
|
|
|
}
|
|
|
|
|
|
- fn finish(mut self) -> Result<Self::Hash> {
|
|
|
+ fn finish(&mut self) -> Result<Self::Hash> {
|
|
|
let digest = self.hasher.finish()?;
|
|
|
let mut hash: VarHash = self.kind.into();
|
|
|
hash.as_mut().copy_from_slice(digest.as_ref());
|
|
@@ -1586,13 +1593,12 @@ impl Decrypter for AsymKey<Private, Encrypt> {
|
|
|
}
|
|
|
|
|
|
impl Signer for AsymKey<Private, Sign> {
|
|
|
- type Op<'s> = OsslSignOp<'s>;
|
|
|
-
|
|
|
- fn init_sign(&self) -> Result<Self::Op<'_>> {
|
|
|
- OsslSignOp::init((self.scheme, self.pkey.as_ref()))
|
|
|
+ fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>> {
|
|
|
+ let op = OsslSignOp::new((self.scheme, self.pkey.as_ref()))?;
|
|
|
+ Ok(Box::new(op))
|
|
|
}
|
|
|
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature> {
|
|
|
let mut signer = OsslSigner::new(self.scheme.message_digest(), &self.pkey)?;
|
|
|
if let Some(padding) = self.scheme.padding() {
|
|
|
signer.set_rsa_padding(padding)?;
|
|
@@ -1611,13 +1617,12 @@ impl Signer for AsymKey<Private, Sign> {
|
|
|
}
|
|
|
|
|
|
impl Verifier for AsymKey<Public, Sign> {
|
|
|
- type Op<'v> = OsslVerifyOp<'v>;
|
|
|
-
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>> {
|
|
|
- OsslVerifyOp::init((self.scheme, self.pkey.as_ref()))
|
|
|
+ fn init_verify(&self) -> Result<Box<dyn '_ + VerifyOp>> {
|
|
|
+ let op = OsslVerifyOp::init(self.scheme, self.pkey.as_ref())?;
|
|
|
+ Ok(Box::new(op))
|
|
|
}
|
|
|
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()> {
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
|
|
|
let mut verifier = OsslVerifier::new(self.scheme.message_digest(), &self.pkey)?;
|
|
|
if let Some(padding) = self.scheme.padding() {
|
|
|
verifier.set_rsa_padding(padding)?;
|
|
@@ -1710,11 +1715,10 @@ impl Decrypter for AsymKeyPair<Encrypt> {
|
|
|
}
|
|
|
|
|
|
impl Signer for AsymKeyPair<Sign> {
|
|
|
- type Op<'s> = <AsymKey<Private, Sign> as Signer>::Op<'s>;
|
|
|
- fn init_sign(&self) -> Result<Self::Op<'_>> {
|
|
|
+ fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>> {
|
|
|
self.private.init_sign()
|
|
|
}
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature> {
|
|
|
self.private.sign(parts)
|
|
|
}
|
|
|
fn kind(&self) -> Sign {
|
|
@@ -1723,13 +1727,11 @@ impl Signer for AsymKeyPair<Sign> {
|
|
|
}
|
|
|
|
|
|
impl Verifier for AsymKeyPair<Sign> {
|
|
|
- type Op<'v> = OsslVerifyOp<'v>;
|
|
|
-
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>> {
|
|
|
+ fn init_verify(&self) -> Result<Box<dyn '_ + VerifyOp>> {
|
|
|
self.public.init_verify()
|
|
|
}
|
|
|
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()> {
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
|
|
|
self.public.verify(parts, signature)
|
|
|
}
|
|
|
|
|
@@ -1757,13 +1759,11 @@ impl Encrypter for ConcretePub {
|
|
|
}
|
|
|
|
|
|
impl Verifier for ConcretePub {
|
|
|
- type Op<'v> = OsslVerifyOp<'v>;
|
|
|
-
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>> {
|
|
|
+ fn init_verify(&self) -> Result<Box<dyn '_ + VerifyOp>> {
|
|
|
self.sign.init_verify()
|
|
|
}
|
|
|
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()> {
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
|
|
|
self.sign.verify(parts, signature)
|
|
|
}
|
|
|
|
|
@@ -1828,13 +1828,11 @@ impl ConcreteCreds {
|
|
|
}
|
|
|
|
|
|
impl Verifier for ConcreteCreds {
|
|
|
- type Op<'v> = OsslVerifyOp<'v>;
|
|
|
-
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>> {
|
|
|
+ fn init_verify(&self) -> Result<Box<dyn '_ + VerifyOp>> {
|
|
|
self.sign.init_verify()
|
|
|
}
|
|
|
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()> {
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
|
|
|
self.sign.verify(parts, signature)
|
|
|
}
|
|
|
|
|
@@ -1869,13 +1867,11 @@ impl CredsPub for ConcreteCreds {
|
|
|
}
|
|
|
|
|
|
impl Signer for ConcreteCreds {
|
|
|
- type Op<'s> = <AsymKeyPair<Sign> as Signer>::Op<'s>;
|
|
|
-
|
|
|
- fn init_sign(&self) -> Result<Self::Op<'_>> {
|
|
|
+ fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>> {
|
|
|
self.sign.init_sign()
|
|
|
}
|
|
|
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature> {
|
|
|
self.sign.sign(parts)
|
|
|
}
|
|
|
|
|
@@ -1900,7 +1896,7 @@ pub trait Encrypter {
|
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
|
-impl<T: Deref<Target = C>, C: Encrypter> Encrypter for T {
|
|
|
+impl<T: ?Sized + Encrypter, P: Deref<Target = T>> Encrypter for P {
|
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
self.deref().encrypt(slice)
|
|
|
}
|
|
@@ -1922,7 +1918,7 @@ pub trait Decrypter {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
|
-impl<T: Deref<Target = C>, C: Decrypter> Decrypter for T {
|
|
|
+impl<T: ?Sized + Decrypter, P: Deref<Target = T>> Decrypter for P {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
self.deref().decrypt(slice)
|
|
|
}
|
|
@@ -1943,7 +1939,7 @@ pub trait SignOp: Op {
|
|
|
fn scheme(&self) -> Sign;
|
|
|
|
|
|
/// Finishes this signature operation and returns a new signature containing the result.
|
|
|
- fn finish(self) -> Result<Signature> {
|
|
|
+ fn finish(&mut self) -> Result<Signature> {
|
|
|
let scheme = self.scheme();
|
|
|
let mut sig = Signature::empty(scheme);
|
|
|
self.finish_into(sig.as_mut())?;
|
|
@@ -1951,15 +1947,19 @@ pub trait SignOp: Op {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl<T: ?Sized + SignOp, P: DerefMut<Target = T>> SignOp for P {
|
|
|
+ fn scheme(&self) -> Sign {
|
|
|
+ self.deref().scheme()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub struct OsslSignOp<'a> {
|
|
|
signer: OsslSigner<'a>,
|
|
|
scheme: Sign,
|
|
|
}
|
|
|
|
|
|
-impl<'a> Op for OsslSignOp<'a> {
|
|
|
- type Arg = (Sign, &'a PKeyRef<Private>);
|
|
|
-
|
|
|
- fn init(arg: Self::Arg) -> Result<Self> {
|
|
|
+impl<'a> OsslSignOp<'a> {
|
|
|
+ pub fn new(arg: (Sign, &'a PKeyRef<Private>)) -> Result<Self> {
|
|
|
let scheme = arg.0;
|
|
|
let mut signer = OsslSigner::new(arg.0.message_digest(), arg.1)?;
|
|
|
if let Some(padding) = scheme.padding() {
|
|
@@ -1967,12 +1967,14 @@ impl<'a> Op for OsslSignOp<'a> {
|
|
|
}
|
|
|
Ok(OsslSignOp { signer, scheme })
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+impl<'a> Op for OsslSignOp<'a> {
|
|
|
fn update(&mut self, data: &[u8]) -> Result<()> {
|
|
|
Ok(self.signer.update(data)?)
|
|
|
}
|
|
|
|
|
|
- fn finish_into(self, buf: &mut [u8]) -> Result<usize> {
|
|
|
+ fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
Ok(self.signer.sign(buf)?)
|
|
|
}
|
|
|
}
|
|
@@ -1991,14 +1993,14 @@ pub struct SignWrite<T, Op> {
|
|
|
|
|
|
impl<T, Op: SignOp> SignWrite<T, Op> {
|
|
|
pub fn new(inner: T, op: Op) -> Self {
|
|
|
- SignWrite { inner, op }
|
|
|
+ SignWrite { inner, op, }
|
|
|
}
|
|
|
|
|
|
- pub fn finish_into(self, buf: &mut [u8]) -> Result<(usize, T)> {
|
|
|
+ pub fn finish_into(mut self, buf: &mut [u8]) -> Result<(usize, T)> {
|
|
|
Ok((self.op.finish_into(buf)?, self.inner))
|
|
|
}
|
|
|
|
|
|
- pub fn finish(self) -> Result<(Signature, T)> {
|
|
|
+ pub fn finish(mut self) -> Result<(Signature, T)> {
|
|
|
Ok((self.op.finish()?, self.inner))
|
|
|
}
|
|
|
}
|
|
@@ -2015,22 +2017,13 @@ impl<T: Write, Op: SignOp> Write for SignWrite<T, Op> {
|
|
|
}
|
|
|
|
|
|
pub trait Signer {
|
|
|
- type Op<'s>: SignOp
|
|
|
- where
|
|
|
- Self: 's;
|
|
|
-
|
|
|
/// Starts a new signing operation and returns the struct representing it.
|
|
|
- fn init_sign(&self) -> Result<Self::Op<'_>>;
|
|
|
+ fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>>;
|
|
|
+
|
|
|
/// Returns a signature over the given parts. It's critical that subsequent invocations
|
|
|
/// of this method on the same instance return a [Signature] with `data` fields of the same
|
|
|
/// length.
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature>;
|
|
|
-
|
|
|
- fn ser_sign<T: Serialize>(&self, value: &T) -> Result<Signed<T>> {
|
|
|
- let data = to_vec(value)?;
|
|
|
- let sig = self.sign(std::iter::once(data.as_slice()))?;
|
|
|
- Ok(Signed::new(data, sig))
|
|
|
- }
|
|
|
+ fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature>;
|
|
|
|
|
|
fn sign_writecap(&self, writecap: &mut Writecap) -> Result<()> {
|
|
|
let signed = self.ser_sign(&writecap.body)?;
|
|
@@ -2038,22 +2031,15 @@ pub trait Signer {
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
- fn ser_sign_into<T: Serialize>(&self, value: &T, buf: &mut Vec<u8>) -> Result<Signature> {
|
|
|
- write_to(value, &mut *buf)?;
|
|
|
- self.sign(std::iter::once(buf.as_slice()))
|
|
|
- }
|
|
|
-
|
|
|
fn kind(&self) -> Sign;
|
|
|
}
|
|
|
|
|
|
-impl<T: Signer> Signer for &T {
|
|
|
- type Op<'s> = T::Op<'s> where Self: 's;
|
|
|
-
|
|
|
- fn init_sign(&self) -> Result<Self::Op<'_>> {
|
|
|
+impl<T: ?Sized + Signer> Signer for &T {
|
|
|
+ fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>> {
|
|
|
(*self).init_sign()
|
|
|
}
|
|
|
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature> {
|
|
|
(*self).sign(parts)
|
|
|
}
|
|
|
|
|
@@ -2062,14 +2048,12 @@ impl<T: Signer> Signer for &T {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Signer> Signer for Arc<T> {
|
|
|
- type Op<'s> = T::Op<'s> where Self: 's;
|
|
|
-
|
|
|
- fn init_sign(&self) -> Result<Self::Op<'_>> {
|
|
|
+impl<T: ?Sized + Signer> Signer for Arc<T> {
|
|
|
+ fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>> {
|
|
|
self.deref().init_sign()
|
|
|
}
|
|
|
|
|
|
- fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
|
+ fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature> {
|
|
|
self.deref().sign(parts)
|
|
|
}
|
|
|
|
|
@@ -2078,40 +2062,64 @@ impl<T: Signer> Signer for Arc<T> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub trait VerifyOp: Sized {
|
|
|
- type Arg;
|
|
|
+pub trait SignerExt: Signer {
|
|
|
+ fn ser_sign<T: Serialize>(&self, value: &T) -> Result<Signed<T>> {
|
|
|
+ let data = to_vec(value)?;
|
|
|
+ let sig = self.sign(&mut std::iter::once(data.as_slice()))?;
|
|
|
+ Ok(Signed::new(data, sig))
|
|
|
+ }
|
|
|
+
|
|
|
+ fn ser_sign_into<T: Serialize>(&self, value: &T, buf: &mut Vec<u8>) -> Result<Signature> {
|
|
|
+ write_to(value, &mut *buf)?;
|
|
|
+ self.sign(&mut std::iter::once(buf.as_slice()))
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- fn init(arg: Self::Arg) -> Result<Self>;
|
|
|
+impl<T: ?Sized + Signer> SignerExt for T {}
|
|
|
|
|
|
+pub trait VerifyOp {
|
|
|
fn update(&mut self, data: &[u8]) -> Result<()>;
|
|
|
|
|
|
- fn finish(self, sig: &[u8]) -> Result<()>;
|
|
|
+ fn finish(&mut self, sig: &[u8]) -> Result<()>;
|
|
|
|
|
|
fn scheme(&self) -> Sign;
|
|
|
}
|
|
|
|
|
|
+impl<T: ?Sized + VerifyOp, P: DerefMut<Target = T>> VerifyOp for P {
|
|
|
+ fn update(&mut self, data: &[u8]) -> Result<()> {
|
|
|
+ self.deref_mut().update(data)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn finish(&mut self, sig: &[u8]) -> Result<()> {
|
|
|
+ self.deref_mut().finish(sig)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn scheme(&self) -> Sign {
|
|
|
+ self.deref().scheme()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub struct OsslVerifyOp<'a> {
|
|
|
verifier: OsslVerifier<'a>,
|
|
|
scheme: Sign,
|
|
|
}
|
|
|
|
|
|
-impl<'a> VerifyOp for OsslVerifyOp<'a> {
|
|
|
- type Arg = (Sign, &'a PKeyRef<Public>);
|
|
|
-
|
|
|
- fn init(arg: Self::Arg) -> Result<Self> {
|
|
|
- let scheme = arg.0;
|
|
|
- let mut verifier = OsslVerifier::new(scheme.message_digest(), arg.1)?;
|
|
|
+impl<'a> OsslVerifyOp<'a> {
|
|
|
+ pub fn init(scheme: Sign, pkey: &'a PKeyRef<Public>) -> Result<Self> {
|
|
|
+ let mut verifier = OsslVerifier::new(scheme.message_digest(), pkey)?;
|
|
|
if let Some(padding) = scheme.padding() {
|
|
|
verifier.set_rsa_padding(padding)?;
|
|
|
}
|
|
|
Ok(OsslVerifyOp { verifier, scheme })
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+impl<'a> VerifyOp for OsslVerifyOp<'a> {
|
|
|
fn update(&mut self, data: &[u8]) -> Result<()> {
|
|
|
Ok(self.verifier.update(data)?)
|
|
|
}
|
|
|
|
|
|
- fn finish(self, sig: &[u8]) -> Result<()> {
|
|
|
+ fn finish(&mut self, sig: &[u8]) -> Result<()> {
|
|
|
match self.verifier.verify(sig) {
|
|
|
Ok(true) => Ok(()),
|
|
|
Ok(false) => Err(bterr!(Error::InvalidSignature)),
|
|
@@ -2139,7 +2147,7 @@ impl<T: Read, Op: VerifyOp> VerifyRead<T, Op> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub fn finish(self, sig: &[u8]) -> std::result::Result<T, (T, crate::Error)> {
|
|
|
+ pub fn finish(mut self, sig: &[u8]) -> std::result::Result<T, (T, crate::Error)> {
|
|
|
if self.update_failed {
|
|
|
return Err((
|
|
|
self.inner,
|
|
@@ -2170,46 +2178,33 @@ impl<T: Read, Op: VerifyOp> Read for VerifyRead<T, Op> {
|
|
|
}
|
|
|
|
|
|
pub trait Verifier {
|
|
|
- type Op<'v>: VerifyOp
|
|
|
- where
|
|
|
- Self: 'v;
|
|
|
+ fn init_verify(&self) -> Result<Box<dyn '_ + VerifyOp>>;
|
|
|
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>>;
|
|
|
-
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()>;
|
|
|
-
|
|
|
- fn ser_verify<T: Serialize>(&self, value: &T, signature: &[u8]) -> Result<()> {
|
|
|
- let data = to_vec(value)?;
|
|
|
- self.verify(std::iter::once(data.as_slice()), signature)
|
|
|
- }
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()>;
|
|
|
|
|
|
fn kind(&self) -> Sign;
|
|
|
}
|
|
|
|
|
|
-impl<T: Verifier> Verifier for &T {
|
|
|
- type Op<'v> = T::Op<'v> where Self: 'v;
|
|
|
-
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>> {
|
|
|
- (*self).init_verify()
|
|
|
+impl<V: ?Sized + Verifier> Verifier for &V {
|
|
|
+ fn init_verify<'a>(&'a self) -> Result<Box<dyn 'a + VerifyOp>> {
|
|
|
+ self.deref().init_verify()
|
|
|
}
|
|
|
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()> {
|
|
|
- (*self).verify(parts, signature)
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
|
|
|
+ self.deref().verify(parts, signature)
|
|
|
}
|
|
|
|
|
|
fn kind(&self) -> Sign {
|
|
|
- (*self).kind()
|
|
|
+ self.deref().kind()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Verifier> Verifier for Arc<T> {
|
|
|
- type Op<'v> = T::Op<'v> where Self: 'v;
|
|
|
-
|
|
|
- fn init_verify(&self) -> Result<Self::Op<'_>> {
|
|
|
+impl<V: ?Sized + Verifier> Verifier for Arc<V> {
|
|
|
+ fn init_verify<'a>(&'a self) -> Result<Box<dyn 'a + VerifyOp>> {
|
|
|
self.deref().init_verify()
|
|
|
}
|
|
|
|
|
|
- fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()> {
|
|
|
+ fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
|
|
|
self.deref().verify(parts, signature)
|
|
|
}
|
|
|
|
|
@@ -2218,6 +2213,17 @@ impl<T: Verifier> Verifier for Arc<T> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+pub trait VerifierExt: Verifier {
|
|
|
+ fn ser_verify<T: Serialize>(&self, value: &T, signature: &[u8]) -> Result<()>;
|
|
|
+}
|
|
|
+
|
|
|
+impl<V: ?Sized + Verifier> VerifierExt for V {
|
|
|
+ fn ser_verify<T: Serialize>(&self, value: &T, signature: &[u8]) -> Result<()> {
|
|
|
+ let data = to_vec(value)?;
|
|
|
+ self.verify(&mut std::iter::once(data.as_slice()), signature)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/// Trait for types which can be used as public credentials.
|
|
|
pub trait CredsPub: Verifier + Encrypter + Principaled {
|
|
|
/// Returns a reference to the public signing key which can be used to verify signatures.
|
|
@@ -2230,7 +2236,7 @@ pub trait CredsPub: Verifier + Encrypter + Principaled {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPub> CredsPub for &T {
|
|
|
+impl<T: ?Sized + CredsPub> CredsPub for &T {
|
|
|
fn public_sign(&self) -> &AsymKey<Public, Sign> {
|
|
|
(*self).public_sign()
|
|
|
}
|
|
@@ -2240,7 +2246,7 @@ impl<T: CredsPub> CredsPub for &T {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPub> CredsPub for Arc<T> {
|
|
|
+impl<T: ?Sized + CredsPub> CredsPub for Arc<T> {
|
|
|
fn public_sign(&self) -> &AsymKey<Public, Sign> {
|
|
|
self.deref().public_sign()
|
|
|
}
|
|
@@ -2271,20 +2277,20 @@ pub trait CredsPriv: Decrypter + Signer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> CredsPriv for &T {
|
|
|
+impl<T: ?Sized + CredsPriv> CredsPriv for &T {
|
|
|
fn writecap(&self) -> Option<&Writecap> {
|
|
|
(*self).writecap()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: CredsPriv> CredsPriv for Arc<T> {
|
|
|
+impl<T: ?Sized + CredsPriv> CredsPriv for Arc<T> {
|
|
|
fn writecap(&self) -> Option<&Writecap> {
|
|
|
self.deref().writecap()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// Trait for types which contain both public and private credentials.
|
|
|
-pub trait Creds: CredsPriv + CredsPub + Clone {
|
|
|
+pub trait Creds: CredsPriv + CredsPub + Send + Sync {
|
|
|
fn issue_writecap(
|
|
|
&self,
|
|
|
issued_to: Principal,
|
|
@@ -2321,7 +2327,7 @@ pub trait Creds: CredsPriv + CredsPub + Clone {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<C: CredsPriv + CredsPub + Clone> Creds for C {}
|
|
|
+impl<C: CredsPriv + CredsPub + Clone + Send + Sync> Creds for C {}
|
|
|
|
|
|
/// A trait for types which store credentials.
|
|
|
pub trait CredStore {
|
|
@@ -2366,6 +2372,53 @@ pub trait CredStore {
|
|
|
-> Result<()>;
|
|
|
}
|
|
|
|
|
|
+impl<T: ?Sized + CredStore, P: Deref<Target = T>> CredStore for P {
|
|
|
+ type CredHandle = T::CredHandle;
|
|
|
+ type ExportedCreds = T::ExportedCreds;
|
|
|
+
|
|
|
+ fn node_creds(&self) -> Result<Self::CredHandle> {
|
|
|
+ self.deref().node_creds()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn root_creds(&self, password: &str) -> Result<Self::CredHandle> {
|
|
|
+ self.deref().root_creds(password)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn gen_root_creds(&self, password: &str) -> Result<Self::CredHandle> {
|
|
|
+ self.deref().gen_root_creds(password)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn storage_key(&self) -> Result<AsymKeyPub<Encrypt>> {
|
|
|
+ self.deref().storage_key()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn export_root_creds(
|
|
|
+ &self,
|
|
|
+ root_creds: &Self::CredHandle,
|
|
|
+ password: &str,
|
|
|
+ new_parent: &AsymKeyPub<Encrypt>,
|
|
|
+ ) -> Result<Self::ExportedCreds> {
|
|
|
+ self.deref()
|
|
|
+ .export_root_creds(root_creds, password, new_parent)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn import_root_creds(
|
|
|
+ &self,
|
|
|
+ password: &str,
|
|
|
+ exported: Self::ExportedCreds,
|
|
|
+ ) -> Result<Self::CredHandle> {
|
|
|
+ self.deref().import_root_creds(password, exported)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn assign_node_writecap(
|
|
|
+ &self,
|
|
|
+ handle: &mut Self::CredHandle,
|
|
|
+ writecap: Writecap,
|
|
|
+ ) -> Result<()> {
|
|
|
+ self.deref().assign_node_writecap(handle, writecap)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl BlockMeta {
|
|
|
/// Validates that this metadata struct contains a valid writecap, that this writecap is
|
|
|
/// permitted to write to the path of this block and that the signature in this metadata struct
|
|
@@ -2437,7 +2490,7 @@ impl Writecap {
|
|
|
write_to(&writecap.body, &mut sig_input_buf)
|
|
|
.map_err(|e| bterr!(WritecapAuthzErr::Serde(e.to_string())))?;
|
|
|
writecap.body.signing_key.verify(
|
|
|
- std::iter::once(sig_input_buf.as_slice()),
|
|
|
+ &mut std::iter::once(sig_input_buf.as_slice()),
|
|
|
writecap.signature.as_slice(),
|
|
|
)?;
|
|
|
match &writecap.next {
|
|
@@ -2494,8 +2547,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.sign([header, message].into_iter())?;
|
|
|
- key.verify([header, message].into_iter(), signature.as_slice())
|
|
|
+ let signature = key.sign(&mut [header, message].into_iter())?;
|
|
|
+ key.verify(&mut [header, message].into_iter(), signature.as_slice())
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
@@ -2659,7 +2712,7 @@ mod tests {
|
|
|
.unwrap();
|
|
|
expected
|
|
|
};
|
|
|
- let mut op = OsslHashOp::<H>::init(kind).unwrap();
|
|
|
+ let mut op = OsslHashOp::<H>::new(kind).unwrap();
|
|
|
|
|
|
for part in parts.iter() {
|
|
|
op.update(part.as_slice()).unwrap();
|
|
@@ -2689,7 +2742,7 @@ mod tests {
|
|
|
.unwrap();
|
|
|
expected
|
|
|
};
|
|
|
- let op = OsslHashOp::<Sha2_512>::init(Sha2_512::KIND).unwrap();
|
|
|
+ let op = OsslHashOp::<Sha2_512>::new(Sha2_512::KIND).unwrap();
|
|
|
let mut wrap = HashStream::new(cursor, op);
|
|
|
|
|
|
for part in parts.iter() {
|
|
@@ -2712,7 +2765,7 @@ mod tests {
|
|
|
.unwrap();
|
|
|
expected
|
|
|
};
|
|
|
- let mut op = VarHashOp::init(HashKind::Sha2_512).unwrap();
|
|
|
+ let mut op = VarHashOp::new(HashKind::Sha2_512).unwrap();
|
|
|
|
|
|
for part in parts.iter() {
|
|
|
op.update(part.as_slice()).unwrap();
|
|
@@ -2735,7 +2788,7 @@ mod tests {
|
|
|
}
|
|
|
let sig = sign_op.finish().expect("finish failed");
|
|
|
|
|
|
- keys.verify(get_parts(), sig.as_ref())
|
|
|
+ keys.verify(&mut get_parts(), sig.as_ref())
|
|
|
.expect("verify failed");
|
|
|
}
|
|
|
|
|
@@ -2756,7 +2809,7 @@ mod tests {
|
|
|
let (sig, cursor) = sign_write.finish().expect("finish failed");
|
|
|
let array = cursor.into_inner();
|
|
|
|
|
|
- keys.verify(std::iter::once(array.as_slice()), sig.as_ref())
|
|
|
+ keys.verify(&mut std::iter::once(array.as_slice()), sig.as_ref())
|
|
|
.expect("verify failed");
|
|
|
}
|
|
|
|
|
@@ -2834,4 +2887,58 @@ mod tests {
|
|
|
assert_eq!(48, private_len);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ mod obj_safety {
|
|
|
+ use super::*;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn op_obj_safe() {
|
|
|
+ assert_obj_safe!(Op);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn sign_op_obj_safe() {
|
|
|
+ assert_obj_safe!(SignOp);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn verify_op_obj_safe() {
|
|
|
+ assert_obj_safe!(VerifyOp);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn encrypter_obj_safe() {
|
|
|
+ assert_obj_safe!(Encrypter);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn decrypter_obj_safe() {
|
|
|
+ assert_obj_safe!(Decrypter);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn verifier_obj_safe() {
|
|
|
+ assert_obj_safe!(Verifier);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn signer_obj_safe() {
|
|
|
+ assert_obj_safe!(Signer);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn creds_pub_obj_safe() {
|
|
|
+ assert_obj_safe!(CredsPub);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn creds_priv_obj_safe() {
|
|
|
+ assert_obj_safe!(CredsPriv);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn creds_obj_safe() {
|
|
|
+ assert_obj_safe!(Creds);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|