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

Implement import and export pub key #287

Merged
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
61 changes: 47 additions & 14 deletions src/providers/trusted_service/context/key_management.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
// Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use super::ts_protobuf::{
CloseKeyIn, DestroyKeyIn, DestroyKeyOut, GenerateKeyIn, GenerateKeyOut, KeyAttributes,
KeyLifetime, KeyPolicy, OpenKeyIn, OpenKeyOut,
CloseKeyIn, DestroyKeyIn, DestroyKeyOut, ExportPublicKeyIn, GenerateKeyIn, GenerateKeyOut,
ImportKeyIn, ImportKeyOut, KeyAttributes, KeyLifetime, KeyPolicy, OpenKeyIn, OpenKeyOut,
};
use super::Context;
use log::info;
use parsec_interface::operations::psa_key_attributes::Attributes;
use parsec_interface::requests::ResponseStatus;
use psa_crypto::types::status::Error;
use std::convert::{TryFrom, TryInto};
use zeroize::Zeroize;

impl Context {
pub fn generate_key(&self, key_attrs: Attributes, id: u32) -> Result<(), ResponseStatus> {
info!("Handling GenerateKey request");
let proto_req = GenerateKeyIn {
let generate_req = GenerateKeyIn {
attributes: Some(KeyAttributes {
r#type: u16::try_from(key_attrs.key_type)? as u32,
key_bits: key_attrs.bits.try_into()?,
Expand All @@ -26,34 +27,66 @@ impl Context {
}),
}),
};
let GenerateKeyOut { handle } = self.send_request(&proto_req)?;
let GenerateKeyOut { handle } = self.send_request(&generate_req)?;

let proto_req = CloseKeyIn { handle };
self.send_request(&proto_req)?;
let close_req = CloseKeyIn { handle };
self.send_request(&close_req)?;

Ok(())
}

pub fn import_key(
&self,
key_attrs: Attributes,
id: u32,
key_data: &[u8],
) -> Result<(), ResponseStatus> {
let mut import_req = ImportKeyIn {
attributes: Some(KeyAttributes {
r#type: u16::try_from(key_attrs.key_type)? as u32,
key_bits: key_attrs.bits.try_into()?,
lifetime: KeyLifetime::Persistent as u32,
id,
policy: Some(KeyPolicy {
usage: key_attrs.policy.usage_flags.try_into()?,
alg: key_attrs.policy.permitted_algorithms.try_into()?,
}),
}),
data: key_data.to_vec(),
};
let ImportKeyOut { handle } = self.send_request(&import_req)?;
import_req.data.zeroize();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯


let close_req = CloseKeyIn { handle };
self.send_request(&close_req)?;

Ok(())
}

pub fn export_public_key(&self, id: u32) -> Result<Vec<u8>, ResponseStatus> {
Ok(self.send_request_with_key(ExportPublicKeyIn::default(), id)?)
}

pub fn destroy_key(&self, key_id: u32) -> Result<(), ResponseStatus> {
info!("Handling DestroyKey request");
if !self.check_key_exists(key_id)? {
return Err(ResponseStatus::PsaErrorDoesNotExist);
}
let proto_req = OpenKeyIn { id: key_id };
let OpenKeyOut { handle } = self.send_request(&proto_req)?;
let open_req = OpenKeyIn { id: key_id };
let OpenKeyOut { handle } = self.send_request(&open_req)?;

let proto_req = DestroyKeyIn { handle };
let _proto_resp: DestroyKeyOut = self.send_request(&proto_req)?;
let destroy_req = DestroyKeyIn { handle };
let _proto_resp: DestroyKeyOut = self.send_request(&destroy_req)?;
Ok(())
}

pub fn check_key_exists(&self, key_id: u32) -> Result<bool, Error> {
info!("Handling CheckKey request");
let proto_req = OpenKeyIn { id: key_id };
match self.send_request(&proto_req) {
let open_req = OpenKeyIn { id: key_id };
match self.send_request(&open_req) {
Ok(OpenKeyOut { handle }) => {
let proto_req = CloseKeyIn { handle };
self.send_request(&proto_req)?;
let close_req = CloseKeyIn { handle };
self.send_request(&close_req)?;
Ok(true)
}
Err(e) => {
Expand Down
11 changes: 7 additions & 4 deletions src/providers/trusted_service/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ mod ts_protobuf {
opcode_impl!(DestroyKeyIn, DestroyKeyOut, DestroyKey);
opcode_impl!(SignHashIn, SignHashOut, SignHash);
opcode_impl!(VerifyHashIn, VerifyHashOut, VerifyHash);
opcode_impl!(ImportKeyIn, ImportKeyOut, ImportKey);
opcode_impl!(ExportPublicKeyIn, ExportPublicKeyOut, ExportPublicKey);

pub trait SetHandle {
fn set_handle(&mut self, handle: u32);
Expand All @@ -102,6 +104,7 @@ mod ts_protobuf {
set_handle_impl!(DestroyKeyIn);
set_handle_impl!(SignHashIn);
set_handle_impl!(VerifyHashIn);
set_handle_impl!(ExportPublicKeyIn);
}

// TODO:
Expand Down Expand Up @@ -231,12 +234,12 @@ impl Context {
mut req: impl Message + GetOpcode + SetHandle,
key_id: u32,
) -> Result<T, PsaError> {
let proto_req = OpenKeyIn { id: key_id };
let OpenKeyOut { handle } = self.send_request(&proto_req)?;
let open_req = OpenKeyIn { id: key_id };
let OpenKeyOut { handle } = self.send_request(&open_req)?;
req.set_handle(handle);
let res = self.send_request(&req);
let proto_req = CloseKeyIn { handle };
let res_close = self.send_request(&proto_req);
let close_req = CloseKeyIn { handle };
let res_close = self.send_request(&close_req);
let res = res?;
res_close?;
Ok(res)
Expand Down
64 changes: 63 additions & 1 deletion src/providers/trusted_service/key_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ use crate::key_info_managers::KeyTriple;
use crate::providers::mbed_crypto::key_management::{
create_key_id, get_key_id, key_info_exists, remove_key_id,
};
use parsec_interface::operations::{psa_destroy_key, psa_generate_key};
use parsec_interface::operations::{
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key,
};
use parsec_interface::requests::{ProviderID, ResponseStatus, Result};
use parsec_interface::secrecy::ExposeSecret;

impl Provider {
pub(super) fn psa_generate_key_internal(
Expand Down Expand Up @@ -43,6 +46,65 @@ impl Provider {
}
}

pub(super) fn psa_import_key_internal(
&self,
app_name: ApplicationName,
op: psa_import_key::Operation,
) -> Result<psa_import_key::Result> {
let key_name = op.key_name;
let key_attributes = op.attributes;
let key_data = op.data;
let key_triple = KeyTriple::new(app_name, ProviderID::TrustedService, key_name);
let mut store_handle = self
.key_info_store
.write()
.expect("Key store lock poisoned");
if key_info_exists(&key_triple, &*store_handle)? {
return Err(ResponseStatus::PsaErrorAlreadyExists);
}
let key_id = create_key_id(
key_triple.clone(),
key_attributes,
&mut *store_handle,
&self.id_counter,
)?;

match self
.context
.import_key(key_attributes, key_id, key_data.expose_secret())
{
Ok(_) => Ok(psa_import_key::Result {}),
Err(error) => {
remove_key_id(&key_triple, &mut *store_handle)?;
let error = ResponseStatus::from(error);
format_error!("Import key status: ", error);
Err(error)
}
}
}

pub(super) fn psa_export_public_key_internal(
&self,
app_name: ApplicationName,
op: psa_export_public_key::Operation,
) -> Result<psa_export_public_key::Result> {
let key_name = op.key_name;
let key_triple = KeyTriple::new(app_name, ProviderID::TrustedService, key_name);
let store_handle = self.key_info_store.read().expect("Key store lock poisoned");
let key_id = get_key_id(&key_triple, &*store_handle)?;

match self.context.export_public_key(key_id) {
Ok(pub_key) => Ok(psa_export_public_key::Result {
data: pub_key.into(),
}),
Err(error) => {
let error = ResponseStatus::from(error);
format_error!("Export key status: ", error);
Err(error)
}
}
}

pub(super) fn psa_destroy_key_internal(
&self,
app_name: ApplicationName,
Expand Down
21 changes: 20 additions & 1 deletion src/providers/trusted_service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use derivative::Derivative;
use log::{error, trace};
use parsec_interface::operations::list_providers::ProviderInfo;
use parsec_interface::operations::{
psa_destroy_key, psa_generate_key, psa_sign_hash, psa_verify_hash,
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, psa_sign_hash,
psa_verify_hash,
};
use parsec_interface::requests::{Opcode, ProviderID, Result};
use psa_crypto::types::key;
Expand Down Expand Up @@ -146,6 +147,24 @@ impl Provide for Provider {
self.psa_destroy_key_internal(app_name, op)
}

fn psa_import_key(
&self,
app_name: ApplicationName,
op: psa_import_key::Operation,
) -> Result<psa_import_key::Result> {
trace!("psa_import_key ingress");
self.psa_import_key_internal(app_name, op)
}

fn psa_export_public_key(
&self,
app_name: ApplicationName,
op: psa_export_public_key::Operation,
) -> Result<psa_export_public_key::Result> {
trace!("psa_export_public_key ingress");
self.psa_export_public_key_internal(app_name, op)
}

fn psa_sign_hash(
&self,
app_name: ApplicationName,
Expand Down