Skip to content

Commit f56682b

Browse files
committed
Implement import and export pub key
This commit implements import and export public key for the Trusted Service provider. Signed-off-by: Ionut Mihalcea <[email protected]>
1 parent c7120ca commit f56682b

File tree

4 files changed

+137
-20
lines changed

4 files changed

+137
-20
lines changed

src/providers/trusted_service/context/key_management.rs

+47-14
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
// Copyright 2020 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
33
use super::ts_protobuf::{
4-
CloseKeyIn, DestroyKeyIn, DestroyKeyOut, GenerateKeyIn, GenerateKeyOut, KeyAttributes,
5-
KeyLifetime, KeyPolicy, OpenKeyIn, OpenKeyOut,
4+
CloseKeyIn, DestroyKeyIn, DestroyKeyOut, ExportPublicKeyIn, GenerateKeyIn, GenerateKeyOut,
5+
ImportKeyIn, ImportKeyOut, KeyAttributes, KeyLifetime, KeyPolicy, OpenKeyIn, OpenKeyOut,
66
};
77
use super::Context;
88
use log::info;
99
use parsec_interface::operations::psa_key_attributes::Attributes;
1010
use parsec_interface::requests::ResponseStatus;
1111
use psa_crypto::types::status::Error;
1212
use std::convert::{TryFrom, TryInto};
13+
use zeroize::Zeroize;
1314

1415
impl Context {
1516
pub fn generate_key(&self, key_attrs: Attributes, id: u32) -> Result<(), ResponseStatus> {
1617
info!("Handling GenerateKey request");
17-
let proto_req = GenerateKeyIn {
18+
let generate_req = GenerateKeyIn {
1819
attributes: Some(KeyAttributes {
1920
r#type: u16::try_from(key_attrs.key_type)? as u32,
2021
key_bits: key_attrs.bits.try_into()?,
@@ -26,34 +27,66 @@ impl Context {
2627
}),
2728
}),
2829
};
29-
let GenerateKeyOut { handle } = self.send_request(&proto_req)?;
30+
let GenerateKeyOut { handle } = self.send_request(&generate_req)?;
3031

31-
let proto_req = CloseKeyIn { handle };
32-
self.send_request(&proto_req)?;
32+
let close_req = CloseKeyIn { handle };
33+
self.send_request(&close_req)?;
3334

3435
Ok(())
3536
}
3637

38+
pub fn import_key(
39+
&self,
40+
key_attrs: Attributes,
41+
id: u32,
42+
key_data: &[u8],
43+
) -> Result<(), ResponseStatus> {
44+
let mut import_req = ImportKeyIn {
45+
attributes: Some(KeyAttributes {
46+
r#type: u16::try_from(key_attrs.key_type)? as u32,
47+
key_bits: key_attrs.bits.try_into()?,
48+
lifetime: KeyLifetime::Persistent as u32,
49+
id,
50+
policy: Some(KeyPolicy {
51+
usage: key_attrs.policy.usage_flags.try_into()?,
52+
alg: key_attrs.policy.permitted_algorithms.try_into()?,
53+
}),
54+
}),
55+
data: key_data.to_vec(),
56+
};
57+
let ImportKeyOut { handle } = self.send_request(&import_req)?;
58+
import_req.data.zeroize();
59+
60+
let close_req = CloseKeyIn { handle };
61+
self.send_request(&close_req)?;
62+
63+
Ok(())
64+
}
65+
66+
pub fn export_public_key(&self, id: u32) -> Result<Vec<u8>, ResponseStatus> {
67+
Ok(self.send_request_with_key(ExportPublicKeyIn::default(), id)?)
68+
}
69+
3770
pub fn destroy_key(&self, key_id: u32) -> Result<(), ResponseStatus> {
3871
info!("Handling DestroyKey request");
3972
if !self.check_key_exists(key_id)? {
4073
return Err(ResponseStatus::PsaErrorDoesNotExist);
4174
}
42-
let proto_req = OpenKeyIn { id: key_id };
43-
let OpenKeyOut { handle } = self.send_request(&proto_req)?;
75+
let open_req = OpenKeyIn { id: key_id };
76+
let OpenKeyOut { handle } = self.send_request(&open_req)?;
4477

45-
let proto_req = DestroyKeyIn { handle };
46-
let _proto_resp: DestroyKeyOut = self.send_request(&proto_req)?;
78+
let destroy_req = DestroyKeyIn { handle };
79+
let _proto_resp: DestroyKeyOut = self.send_request(&destroy_req)?;
4780
Ok(())
4881
}
4982

5083
pub fn check_key_exists(&self, key_id: u32) -> Result<bool, Error> {
5184
info!("Handling CheckKey request");
52-
let proto_req = OpenKeyIn { id: key_id };
53-
match self.send_request(&proto_req) {
85+
let open_req = OpenKeyIn { id: key_id };
86+
match self.send_request(&open_req) {
5487
Ok(OpenKeyOut { handle }) => {
55-
let proto_req = CloseKeyIn { handle };
56-
self.send_request(&proto_req)?;
88+
let close_req = CloseKeyIn { handle };
89+
self.send_request(&close_req)?;
5790
Ok(true)
5891
}
5992
Err(e) => {

src/providers/trusted_service/context/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ mod ts_protobuf {
8484
opcode_impl!(DestroyKeyIn, DestroyKeyOut, DestroyKey);
8585
opcode_impl!(SignHashIn, SignHashOut, SignHash);
8686
opcode_impl!(VerifyHashIn, VerifyHashOut, VerifyHash);
87+
opcode_impl!(ImportKeyIn, ImportKeyOut, ImportKey);
88+
opcode_impl!(ExportPublicKeyIn, ExportPublicKeyOut, ExportPublicKey);
8789

8890
pub trait SetHandle {
8991
fn set_handle(&mut self, handle: u32);
@@ -102,6 +104,7 @@ mod ts_protobuf {
102104
set_handle_impl!(DestroyKeyIn);
103105
set_handle_impl!(SignHashIn);
104106
set_handle_impl!(VerifyHashIn);
107+
set_handle_impl!(ExportPublicKeyIn);
105108
}
106109

107110
// TODO:
@@ -231,12 +234,12 @@ impl Context {
231234
mut req: impl Message + GetOpcode + SetHandle,
232235
key_id: u32,
233236
) -> Result<T, PsaError> {
234-
let proto_req = OpenKeyIn { id: key_id };
235-
let OpenKeyOut { handle } = self.send_request(&proto_req)?;
237+
let open_req = OpenKeyIn { id: key_id };
238+
let OpenKeyOut { handle } = self.send_request(&open_req)?;
236239
req.set_handle(handle);
237240
let res = self.send_request(&req);
238-
let proto_req = CloseKeyIn { handle };
239-
let res_close = self.send_request(&proto_req);
241+
let close_req = CloseKeyIn { handle };
242+
let res_close = self.send_request(&close_req);
240243
let res = res?;
241244
res_close?;
242245
Ok(res)

src/providers/trusted_service/key_management.rs

+63-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ use crate::key_info_managers::KeyTriple;
66
use crate::providers::mbed_crypto::key_management::{
77
create_key_id, get_key_id, insert_key_id, key_info_exists, remove_key_id,
88
};
9-
use parsec_interface::operations::{psa_destroy_key, psa_generate_key};
9+
use parsec_interface::operations::{
10+
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key,
11+
};
1012
use parsec_interface::requests::{ProviderID, ResponseStatus, Result};
13+
use parsec_interface::secrecy::ExposeSecret;
1114

1215
impl Provider {
1316
pub(super) fn psa_generate_key_internal(
@@ -48,6 +51,65 @@ impl Provider {
4851
}
4952
}
5053

54+
pub(super) fn psa_import_key_internal(
55+
&self,
56+
app_name: ApplicationName,
57+
op: psa_import_key::Operation,
58+
) -> Result<psa_import_key::Result> {
59+
let key_name = op.key_name;
60+
let key_attributes = op.attributes;
61+
let key_data = op.data;
62+
let key_triple = KeyTriple::new(app_name, ProviderID::TrustedService, key_name);
63+
let mut store_handle = self
64+
.key_info_store
65+
.write()
66+
.expect("Key store lock poisoned");
67+
if key_info_exists(&key_triple, &*store_handle)? {
68+
return Err(ResponseStatus::PsaErrorAlreadyExists);
69+
}
70+
let key_id = create_key_id(
71+
key_triple.clone(),
72+
key_attributes,
73+
&mut *store_handle,
74+
&self.id_counter,
75+
)?;
76+
77+
match self
78+
.context
79+
.import_key(key_attributes, key_id, key_data.expose_secret())
80+
{
81+
Ok(_) => Ok(psa_import_key::Result {}),
82+
Err(error) => {
83+
remove_key_id(&key_triple, &mut *store_handle)?;
84+
let error = ResponseStatus::from(error);
85+
format_error!("Import key status: ", error);
86+
Err(error)
87+
}
88+
}
89+
}
90+
91+
pub(super) fn psa_export_public_key_internal(
92+
&self,
93+
app_name: ApplicationName,
94+
op: psa_export_public_key::Operation,
95+
) -> Result<psa_export_public_key::Result> {
96+
let key_name = op.key_name;
97+
let key_triple = KeyTriple::new(app_name, ProviderID::TrustedService, key_name);
98+
let store_handle = self.key_info_store.read().expect("Key store lock poisoned");
99+
let key_id = get_key_id(&key_triple, &*store_handle)?;
100+
101+
match self.context.export_public_key(key_id) {
102+
Ok(pub_key) => Ok(psa_export_public_key::Result {
103+
data: pub_key.into(),
104+
}),
105+
Err(error) => {
106+
let error = ResponseStatus::from(error);
107+
format_error!("Export key status: ", error);
108+
Err(error)
109+
}
110+
}
111+
}
112+
51113
pub(super) fn psa_destroy_key_internal(
52114
&self,
53115
app_name: ApplicationName,

src/providers/trusted_service/mod.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use derivative::Derivative;
1313
use log::{error, trace};
1414
use parsec_interface::operations::list_providers::ProviderInfo;
1515
use parsec_interface::operations::{
16-
psa_destroy_key, psa_generate_key, psa_sign_hash, psa_verify_hash,
16+
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, psa_sign_hash,
17+
psa_verify_hash,
1718
};
1819
use parsec_interface::requests::{Opcode, ProviderID, Result};
1920
use psa_crypto::types::key;
@@ -146,6 +147,24 @@ impl Provide for Provider {
146147
self.psa_destroy_key_internal(app_name, op)
147148
}
148149

150+
fn psa_import_key(
151+
&self,
152+
app_name: ApplicationName,
153+
op: psa_import_key::Operation,
154+
) -> Result<psa_import_key::Result> {
155+
trace!("psa_import_key ingress");
156+
self.psa_import_key_internal(app_name, op)
157+
}
158+
159+
fn psa_export_public_key(
160+
&self,
161+
app_name: ApplicationName,
162+
op: psa_export_public_key::Operation,
163+
) -> Result<psa_export_public_key::Result> {
164+
trace!("psa_export_public_key ingress");
165+
self.psa_export_public_key_internal(app_name, op)
166+
}
167+
149168
fn psa_sign_hash(
150169
&self,
151170
app_name: ApplicationName,

0 commit comments

Comments
 (0)