Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

store key id for hardware keys #284

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion askar-crypto/src/alg/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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<SecretBytes, Error> {
get_key_id_any(self)
}
}

/// Create `AnyKey` instances from various sources
Expand Down Expand Up @@ -570,6 +575,18 @@ fn convert_key_any<R: AllocKey>(key: &AnyKey, alg: KeyAlg) -> Result<R, Error> {
}
}

#[inline]
fn get_key_id_any(key: &AnyKey) -> Result<SecretBytes, Error> {
match key.algorithm() {
#[cfg(feature = "p256_hardware")]
KeyAlg::EcCurve(EcCurves::Secp256r1) => {
Ok(key.assume::<P256HardwareKeyPair>().key_id.clone())
}
#[allow(unreachable_patterns)]
_ => Err(err_msg!(Unsupported, "Unsupported get key id operation")),
}
}

impl FromJwk for Box<AnyKey> {
fn from_jwk_parts(jwk: JwkParts<'_>) -> Result<Self, Error> {
from_jwk_any(jwk)
Expand Down
26 changes: 19 additions & 7 deletions askar-crypto/src/alg/p256_hardware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -50,17 +50,23 @@ impl From<SecureEnvError> 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<P256KeyPair, Error> {
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
Expand All @@ -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<Self, Error> {
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<Self, Error> {
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()),
})
}
}

Expand All @@ -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)
}
}
Expand Down
1 change: 0 additions & 1 deletion src/ffi/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,11 @@ impl Session {
tags: Option<&[EntryTag]>,
expiry_ms: Option<i64>,
) -> 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,
Expand Down
Loading