Skip to content

Commit 17c5565

Browse files
committed
Added PsaExportKey
Signed-off-by: Samuel Bailey <samuel.bailey@arm.com>
1 parent 2b6e1d2 commit 17c5565

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ edition = "2018"
1313
documentation = "https://docs.rs/crate/parsec-client"
1414

1515
[dependencies]
16-
parsec-interface = "0.18.0"
16+
parsec-interface = { path = "../parsec-interface-rs" }
1717
num = "0.2.1"
1818
rand = "0.7.3"
1919
log = "0.4.8"

src/core/basic_client.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use parsec_interface::operations::psa_algorithm::{AsymmetricEncryption, Asymmetr
1111
use parsec_interface::operations::psa_asymmetric_decrypt::Operation as PsaAsymDecrypt;
1212
use parsec_interface::operations::psa_asymmetric_encrypt::Operation as PsaAsymEncrypt;
1313
use parsec_interface::operations::psa_destroy_key::Operation as PsaDestroyKey;
14+
use parsec_interface::operations::psa_export_key::Operation as PsaExportKey;
1415
use parsec_interface::operations::psa_export_public_key::Operation as PsaExportPublicKey;
1516
use parsec_interface::operations::psa_generate_key::Operation as PsaGenerateKey;
1617
use parsec_interface::operations::psa_import_key::Operation as PsaImportKey;
@@ -19,7 +20,7 @@ use parsec_interface::operations::psa_sign_hash::Operation as PsaSignHash;
1920
use parsec_interface::operations::psa_verify_hash::Operation as PsaVerifyHash;
2021
use parsec_interface::operations::{NativeOperation, NativeResult};
2122
use parsec_interface::requests::{Opcode, ProviderID};
22-
use parsec_interface::secrecy::Secret;
23+
use parsec_interface::secrecy::{ExposeSecret, Secret};
2324
use std::collections::HashSet;
2425
use zeroize::Zeroizing;
2526

@@ -422,6 +423,43 @@ impl BasicClient {
422423
}
423424
}
424425

426+
/// **[Cryptographic Operation]** Export a key.
427+
///
428+
/// The returned key material will follow the appropriate binary format expressed
429+
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_export_key.html).
430+
/// Several crates (e.g. [`picky-asn1`](https://crates.io/crates/picky-asn1))
431+
/// can greatly help in dealing with binary encodings.
432+
///
433+
/// # Errors
434+
///
435+
/// If the implicit client provider is `ProviderID::Core`, a client error
436+
/// of `InvalidProvider` type is returned.
437+
///
438+
/// If the implicit client provider has not been set, a client error of
439+
/// `NoProvider` type is returned.
440+
///
441+
/// See the operation-specific response codes returned by the service
442+
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_export_key.html#specific-response-status-codes).
443+
pub fn psa_export_key(&self, key_name: String) -> Result<Vec<u8>> {
444+
let crypto_provider = self.can_provide_crypto()?;
445+
446+
let op = PsaExportKey { key_name };
447+
448+
let res = self.op_client.process_operation(
449+
NativeOperation::PsaExportKey(op),
450+
crypto_provider,
451+
&self.auth_data,
452+
)?;
453+
454+
if let NativeResult::PsaExportKey(res) = res {
455+
Ok(res.data.expose_secret().to_vec())
456+
} else {
457+
// Should really not be reached given the checks we do, but it's not impossible if some
458+
// changes happen in the interface
459+
Err(Error::Client(ClientErrorKind::InvalidServiceResponseType))
460+
}
461+
}
462+
425463
/// **[Cryptographic Operation]** Create an asymmetric signature on a pre-computed message digest.
426464
///
427465
/// The key intended for signing **must** have its `sign_hash` flag set

src/core/testing/core_tests.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,34 @@ fn psa_export_public_key_test() {
286286
}
287287
}
288288

289+
#[test]
290+
fn psa_export_key_test() {
291+
let mut client: TestBasicClient = Default::default();
292+
let key_data = vec![0xa5; 128];
293+
client.set_mock_read(&get_response_bytes_from_result(NativeResult::PsaExportKey(
294+
operations::psa_export_key::Result {
295+
data: Secret::new(key_data.clone()),
296+
},
297+
)));
298+
299+
let key_name = String::from("key-name");
300+
// Check response:
301+
assert_eq!(
302+
client
303+
.psa_export_key(key_name.clone())
304+
.expect("Failed to export key"),
305+
key_data
306+
);
307+
308+
// Check request:
309+
let op = get_operation_from_req_bytes(client.get_mock_write());
310+
if let NativeOperation::PsaExportKey(op) = op {
311+
assert_eq!(op.key_name, key_name);
312+
} else {
313+
panic!("Got wrong operation type: {:?}", op);
314+
}
315+
}
316+
289317
#[test]
290318
fn psa_sign_hash_test() {
291319
let mut client: TestBasicClient = Default::default();

0 commit comments

Comments
 (0)