diff --git a/Cargo.lock b/Cargo.lock index 51cbd027..e1d1c322 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,7 +154,7 @@ dependencies = [ [[package]] name = "aries-askar" -version = "0.3.1" +version = "0.3.2" dependencies = [ "askar-crypto", "askar-storage", @@ -174,7 +174,7 @@ dependencies = [ [[package]] name = "askar-crypto" -version = "0.3.1" +version = "0.3.2" dependencies = [ "aead", "aes", diff --git a/askar-crypto/src/alg/any.rs b/askar-crypto/src/alg/any.rs index 06e80240..29b0b965 100644 --- a/askar-crypto/src/alg/any.rs +++ b/askar-crypto/src/alg/any.rs @@ -43,7 +43,7 @@ use super::p256_hardware::P256HardwareKeyPair; use super::{HasKeyAlg, HasKeyBackend, KeyAlg}; use crate::{ backend::KeyBackend, - buffer::{ResizeBuffer, WriteBuffer}, + buffer::{ResizeBuffer, SecretBytes, WriteBuffer}, encrypt::{KeyAeadInPlace, KeyAeadParams}, error::Error, jwk::{FromJwk, JwkEncoder, JwkParts, ToJwk}, @@ -92,6 +92,11 @@ impl AnyKey { pub fn key_type_id(&self) -> TypeId { self.0.as_any().type_id() } + + #[inline] + pub fn key_id(&self) -> Result { + get_key_id_any(self) + } } /// Create `AnyKey` instances from various sources @@ -570,6 +575,18 @@ fn convert_key_any(key: &AnyKey, alg: KeyAlg) -> Result { } } +#[inline] +fn get_key_id_any(key: &AnyKey) -> Result { + match key.algorithm() { + #[cfg(feature = "p256_hardware")] + KeyAlg::EcCurve(EcCurves::Secp256r1) => { + Ok(key.assume::().key_id.clone()) + } + #[allow(unreachable_patterns)] + _ => Err(err_msg!(Unsupported, "Unsupported get key id operation")), + } +} + impl FromJwk for Box { fn from_jwk_parts(jwk: JwkParts<'_>) -> Result { from_jwk_any(jwk) diff --git a/askar-crypto/src/alg/p256_hardware.rs b/askar-crypto/src/alg/p256_hardware.rs index 4f670ff0..f60668ed 100644 --- a/askar-crypto/src/alg/p256_hardware.rs +++ b/askar-crypto/src/alg/p256_hardware.rs @@ -8,7 +8,7 @@ use super::{ EcCurves, HasKeyAlg, HasKeyBackend, KeyAlg, KeyBackend, }; use crate::{ - buffer::WriteBuffer, + buffer::{SecretBytes, WriteBuffer}, error::{Error, ErrorKind}, generic_array::typenum::{U32, U33, U65}, jwk::ToJwk, @@ -50,17 +50,23 @@ impl From for Error { /// A P-256 (secp256r1) reference to a key pair stored in hardware #[derive(Debug)] -pub struct P256HardwareKeyPair(P256HardwareKeyReference); +pub struct P256HardwareKeyPair { + pub(crate) inner: P256HardwareKeyReference, + pub(crate) key_id: SecretBytes, +} impl P256HardwareKeyPair { pub(crate) fn get_p256_keypair(&self) -> Result { - let public_key = self.0.get_public_key()?; + let public_key = self.inner.get_public_key()?; P256KeyPair::from_public_bytes(&public_key) } /// Sign a message with the secret key pub fn sign(&self, message: &[u8]) -> Option<[u8; ES256_SIGNATURE_LENGTH]> { - self.0.sign(message).ok().and_then(|s| s.try_into().ok()) + self.inner + .sign(message) + .ok() + .and_then(|s| s.try_into().ok()) } /// Verify a signature with the public key @@ -75,12 +81,18 @@ impl P256HardwareKeyPair { /// For this method the `rng` source is disregarded and the Secure Elements source will be /// used. pub fn generate(id: &str) -> Result { - Ok(Self(SecureEnvironment::generate_keypair(id)?)) + Ok(Self { + inner: SecureEnvironment::generate_keypair(id)?, + key_id: SecretBytes::from_slice(id.as_bytes()), + }) } /// Fetch the keypair from the Secure Element via the id pub fn from_id(id: &str) -> Result { - Ok(Self(SecureEnvironment::get_keypair_by_id(id)?)) + Ok(Self { + inner: SecureEnvironment::get_keypair_by_id(id)?, + key_id: SecretBytes::from_slice(id.as_bytes()), + }) } } @@ -90,7 +102,7 @@ impl ToPublicBytes for P256HardwareKeyPair { } fn write_public_bytes(&self, out: &mut dyn WriteBuffer) -> Result<(), Error> { - let public_key = self.0.get_public_key()?; + let public_key = self.inner.get_public_key()?; out.buffer_write(&public_key) } } diff --git a/src/ffi/key.rs b/src/ffi/key.rs index 67526867..59228784 100644 --- a/src/ffi/key.rs +++ b/src/ffi/key.rs @@ -597,7 +597,6 @@ pub extern "C" fn askar_key_get_supported_backends(out: *mut StringListHandle) - let string_list = StringListHandle::create(FfiStringList::from(backends)); - unsafe { *out = string_list }; Ok(ErrorCode::Success) diff --git a/src/store.rs b/src/store.rs index f02319ac..59e024e4 100644 --- a/src/store.rs +++ b/src/store.rs @@ -345,7 +345,11 @@ impl Session { tags: Option<&[EntryTag]>, expiry_ms: Option, ) -> Result<(), Error> { - let data = key.encode()?; + let data = if key.is_hardware_backed() { + key.inner.key_id()? + } else { + key.encode()? + }; let params = KeyParams { metadata: metadata.map(str::to_string), reference,