diff --git a/cryptoki/Cargo.toml b/cryptoki/Cargo.toml index aeb03458..d1eaf309 100644 --- a/cryptoki/Cargo.toml +++ b/cryptoki/Cargo.toml @@ -19,6 +19,7 @@ psa-crypto = { version = "0.9.0", default-features = false, optional = true } cryptoki-sys = { path = "../cryptoki-sys", version = "0.1.4" } paste = "1.0.6" secrecy = "0.8.0" +signature = { version = "2.1.0", optional = true, features = [ "std" ] } [dev-dependencies] num-traits = "0.2.14" @@ -27,6 +28,8 @@ serial_test = "0.5.1" testresult = "0.2.0" [features] +default = [ "signature-traits" ] psa-crypto-conversions = ["psa-crypto"] +signature-traits = ["signature"] generate-bindings = ["cryptoki-sys/generate-bindings"] serde = ["secrecy/serde"] diff --git a/cryptoki/src/session/signing_macing.rs b/cryptoki/src/session/signing_macing.rs index d100c72b..a012a1c0 100644 --- a/cryptoki/src/session/signing_macing.rs +++ b/cryptoki/src/session/signing_macing.rs @@ -9,7 +9,16 @@ use crate::session::Session; use cryptoki_sys::*; use std::convert::TryInto; +#[cfg(feature = "signature-traits")] +use signature::Signer; + impl Session { + #[cfg(feature = "signature-traits")] + /// Prepare a signature request which implements the signature::Signer trait. + pub fn prepare_signature<'a>(&'a self, mechanism: &'a Mechanism<'a>, key: ObjectHandle) -> SignatureRequest { + SignatureRequest::new(mechanism, key, self) + } + /// Sign data in single-part pub fn sign(&self, mechanism: &Mechanism, key: ObjectHandle, data: &[u8]) -> Result> { let mut mechanism: CK_MECHANISM = mechanism.into(); @@ -86,3 +95,30 @@ impl Session { } } } + +#[cfg(feature = "signature-traits")] +#[derive(Debug)] +pub struct SignatureRequest<'sess: 'a, 'a, 'b> { + mechanism: &'a Mechanism<'b>, + key: ObjectHandle, + session: &'sess Session +} + +#[cfg(feature = "signature-traits")] +impl<'sess, 'a, 'b> SignatureRequest<'sess, 'a, 'b> { + pub fn new(mechanism: &'a Mechanism<'b>, key: ObjectHandle, session: &'sess Session) -> Self { + SignatureRequest { + mechanism, + key, + session + } + } +} + + +#[cfg(feature = "signature-traits")] +impl<'sess, 'a, 'b> Signer> for SignatureRequest<'sess, 'a, 'b> { + fn try_sign(&self, msg: &[u8]) -> core::result::Result, signature::Error> { + self.session.sign(self.mechanism, self.key, msg).map_err(signature::Error::from_source) + } +}