From 507f574eeccb63f3ec123c747f4e9ff21b69983c Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Sun, 9 Jul 2023 00:57:17 +0200 Subject: [PATCH] feat(session): support Signer trait through a Session `signature` is a widely used "standard" trait offering high level APIs to manipulate signers and verifiers. This implements a `Signer` trait on a returned `SignatureRequest` through `Session` which is a prepared "signature request" with filled mechanism and key. This makes it possible to wire cryptoki further with other APIs of the Rust ecosystem. --- cryptoki/Cargo.toml | 3 +++ cryptoki/src/session/signing_macing.rs | 36 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) 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) + } +}