Skip to content

Commit 4239ba3

Browse files
authored
Merge pull request #173 from ionut-arm/list-opcodes
Improve handling of list_opcodes
2 parents f1eb4b8 + 6a737e5 commit 4239ba3

File tree

10 files changed

+111
-120
lines changed

10 files changed

+111
-120
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ name = "parsec"
1818
path = "src/bin/main.rs"
1919

2020
[dependencies]
21-
parsec-interface = "0.14.1"
21+
parsec-interface = "0.14.2"
2222
rand = "0.7.2"
2323
base64 = "0.10.1"
2424
uuid = "0.7.4"

e2e_tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ picky-asn1-der = "0.2.2"
1818
picky-asn1 = "0.2.1"
1919
serde = { version = "1.0", features = ["derive"] }
2020
sha2 = "0.8.1"
21-
parsec-client = { version = "0.2.0", features = ["testing"] }
21+
parsec-client = { version = "0.3.0", features = ["testing"] }
2222
log = "0.4.8"
2323
rand = "0.7.3"
2424

e2e_tests/tests/all_providers/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ fn list_providers() {
2222
}
2323

2424
#[test]
25-
// ListOpcodes is not currently supported only by the Core Provider, see
26-
// parallaxsecond/parsec-operations#9
27-
#[ignore]
2825
fn list_opcodes() {
2926
let mut client = TestClient::new();
3027
let mut crypto_providers_opcodes = HashSet::new();

src/providers/core_provider/mod.rs

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use log::error;
1010
use parsec_interface::operations::list_providers::ProviderInfo;
1111
use parsec_interface::operations::{list_opcodes, list_providers, ping};
1212
use parsec_interface::requests::{Opcode, ProviderID, ResponseStatus, Result};
13+
use std::collections::{HashMap, HashSet};
1314
use std::io::{Error, ErrorKind};
1415
use std::str::FromStr;
1516
use uuid::Uuid;
@@ -26,37 +27,24 @@ const SUPPORTED_OPCODES: [Opcode; 3] = [Opcode::ListProviders, Opcode::ListOpcod
2627
pub struct CoreProvider {
2728
wire_protocol_version_min: u8,
2829
wire_protocol_version_maj: u8,
29-
providers: Vec<ProviderInfo>,
30+
provider_info: Vec<ProviderInfo>,
31+
provider_opcodes: HashMap<ProviderID, HashSet<Opcode>>,
3032
}
3133

3234
impl Provide for CoreProvider {
33-
fn list_opcodes(&self, _op: list_opcodes::Operation) -> Result<list_opcodes::Result> {
35+
fn list_opcodes(&self, op: list_opcodes::Operation) -> Result<list_opcodes::Result> {
3436
Ok(list_opcodes::Result {
35-
opcodes: SUPPORTED_OPCODES.iter().copied().collect(),
37+
opcodes: self
38+
.provider_opcodes
39+
.get(&op.provider_id)
40+
.ok_or(ResponseStatus::ProviderNotRegistered)?
41+
.clone(),
3642
})
3743
}
3844

3945
fn list_providers(&self, _op: list_providers::Operation) -> Result<list_providers::Result> {
4046
Ok(list_providers::Result {
41-
providers: self.providers.clone(),
42-
})
43-
}
44-
45-
fn describe(&self) -> Result<ProviderInfo> {
46-
let crate_version: Version = Version::from_str(version!()).or_else(|e| {
47-
error!("Error parsing the crate version: {}.", e);
48-
Err(ResponseStatus::InvalidEncoding)
49-
})?;
50-
51-
Ok(ProviderInfo {
52-
// Assigned UUID for this provider: 47049873-2a43-4845-9d72-831eab668784
53-
uuid: Uuid::parse_str("47049873-2a43-4845-9d72-831eab668784").or(Err(ResponseStatus::InvalidEncoding))?,
54-
description: String::from("Software provider that implements only administrative (i.e. no cryptographic) operations"),
55-
vendor: String::new(),
56-
version_maj: crate_version.major,
57-
version_min: crate_version.minor,
58-
version_rev: crate_version.patch,
59-
id: ProviderID::Core,
47+
providers: self.provider_info.clone(),
6048
})
6149
}
6250

@@ -75,16 +63,46 @@ impl Provide for CoreProvider {
7563
pub struct CoreProviderBuilder {
7664
version_maj: Option<u8>,
7765
version_min: Option<u8>,
78-
providers: Option<Vec<ProviderInfo>>,
66+
provider_info: Vec<ProviderInfo>,
67+
provider_opcodes: HashMap<ProviderID, HashSet<Opcode>>,
7968
}
8069

8170
impl CoreProviderBuilder {
82-
pub fn new() -> Self {
83-
CoreProviderBuilder {
71+
pub fn new() -> std::io::Result<Self> {
72+
let crate_version: Version = Version::from_str(version!()).or_else(|e| {
73+
error!("Error parsing the crate version: {}.", e);
74+
Err(Error::new(
75+
ErrorKind::InvalidData,
76+
"crate version number has invalid format",
77+
))
78+
})?;
79+
80+
let provider_info = vec![ProviderInfo {
81+
// Assigned UUID for this provider: 47049873-2a43-4845-9d72-831eab668784
82+
uuid: Uuid::parse_str("47049873-2a43-4845-9d72-831eab668784").or_else(|_| Err(Error::new(
83+
ErrorKind::InvalidData,
84+
"provider UUID is invalid",
85+
)))?,
86+
description: String::from("Software provider that implements only administrative (i.e. no cryptographic) operations"),
87+
vendor: String::new(),
88+
version_maj: crate_version.major,
89+
version_min: crate_version.minor,
90+
version_rev: crate_version.patch,
91+
id: ProviderID::Core,
92+
}];
93+
94+
let mut provider_opcodes = HashMap::new();
95+
let _ = provider_opcodes.insert(
96+
ProviderID::Core,
97+
SUPPORTED_OPCODES.iter().copied().collect(),
98+
);
99+
100+
Ok(CoreProviderBuilder {
84101
version_maj: None,
85102
version_min: None,
86-
providers: None,
87-
}
103+
provider_info,
104+
provider_opcodes,
105+
})
88106
}
89107

90108
pub fn with_wire_protocol_version(mut self, version_min: u8, version_maj: u8) -> Self {
@@ -94,44 +112,29 @@ impl CoreProviderBuilder {
94112
self
95113
}
96114

97-
pub fn with_provider_info(mut self, provider_info: ProviderInfo) -> Self {
98-
match self.providers {
99-
Some(mut providers) => {
100-
providers.push(provider_info);
101-
self.providers = Some(providers);
102-
}
103-
None => {
104-
let mut providers = Vec::new();
105-
providers.push(provider_info);
106-
self.providers = Some(providers);
107-
}
108-
}
115+
pub fn with_provider_details(
116+
mut self,
117+
provider_info: ProviderInfo,
118+
opcodes: HashSet<Opcode>,
119+
) -> Self {
120+
let _ = self.provider_opcodes.insert(provider_info.id, opcodes);
121+
self.provider_info.push(provider_info);
109122

110123
self
111124
}
112125

113126
pub fn build(self) -> std::io::Result<CoreProvider> {
114-
let mut core_provider = CoreProvider {
127+
let core_provider = CoreProvider {
115128
wire_protocol_version_maj: self
116129
.version_maj
117130
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "version maj is missing"))?,
118131
wire_protocol_version_min: self
119132
.version_min
120133
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "version min is missing"))?,
121-
providers: self
122-
.providers
123-
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "provider info is missing"))?,
134+
provider_opcodes: self.provider_opcodes,
135+
provider_info: self.provider_info,
124136
};
125137

126-
core_provider
127-
.providers
128-
.push(core_provider.describe().or_else(|_| {
129-
Err(Error::new(
130-
ErrorKind::InvalidData,
131-
"error describing Core provider",
132-
))
133-
})?);
134-
135138
Ok(core_provider)
136139
}
137140
}
@@ -145,7 +148,8 @@ mod tests {
145148
let provider = CoreProvider {
146149
wire_protocol_version_min: 8,
147150
wire_protocol_version_maj: 10,
148-
providers: Vec::new(),
151+
provider_info: Vec::new(),
152+
provider_opcodes: HashMap::new(),
149153
};
150154
let op = ping::Operation {};
151155
let result = provider.ping(op).unwrap();

src/providers/mbed_provider/mod.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use derivative::Derivative;
88
use log::error;
99
use parsec_interface::operations::list_providers::ProviderInfo;
1010
use parsec_interface::operations::{
11-
list_opcodes, psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key,
12-
psa_sign_hash, psa_verify_hash,
11+
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, psa_sign_hash,
12+
psa_verify_hash,
1313
};
1414
use parsec_interface::requests::{Opcode, ProviderID, ResponseStatus, Result};
1515
use psa_crypto_binding::psa_key_id_t;
@@ -40,14 +40,13 @@ mod utils;
4040

4141
type LocalIdStore = HashSet<psa_key_id_t>;
4242

43-
const SUPPORTED_OPCODES: [Opcode; 7] = [
43+
const SUPPORTED_OPCODES: [Opcode; 6] = [
4444
Opcode::PsaGenerateKey,
4545
Opcode::PsaDestroyKey,
4646
Opcode::PsaSignHash,
4747
Opcode::PsaVerifyHash,
4848
Opcode::PsaImportKey,
4949
Opcode::PsaExportPublicKey,
50-
Opcode::ListOpcodes,
5150
];
5251

5352
#[derive(Derivative)]
@@ -153,14 +152,8 @@ impl MbedProvider {
153152
}
154153

155154
impl Provide for MbedProvider {
156-
fn list_opcodes(&self, _op: list_opcodes::Operation) -> Result<list_opcodes::Result> {
157-
Ok(list_opcodes::Result {
158-
opcodes: SUPPORTED_OPCODES.iter().copied().collect(),
159-
})
160-
}
161-
162-
fn describe(&self) -> Result<ProviderInfo> {
163-
Ok(ProviderInfo {
155+
fn describe(&self) -> Result<(ProviderInfo, HashSet<Opcode>)> {
156+
Ok((ProviderInfo {
164157
// Assigned UUID for this provider: 1c1139dc-ad7c-47dc-ad6b-db6fdb466552
165158
uuid: Uuid::parse_str("1c1139dc-ad7c-47dc-ad6b-db6fdb466552").or(Err(ResponseStatus::InvalidEncoding))?,
166159
description: String::from("User space software provider, based on Mbed Crypto - the reference implementation of the PSA crypto API"),
@@ -169,7 +162,7 @@ impl Provide for MbedProvider {
169162
version_min: 1,
170163
version_rev: 0,
171164
id: ProviderID::MbedCrypto,
172-
})
165+
}, SUPPORTED_OPCODES.iter().copied().collect()))
173166
}
174167

175168
fn psa_generate_key(

src/providers/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
//! are the real implementors of the operations that Parsec claims to support. They map to
77
//! functionality in the underlying hardware which allows the PSA Crypto operations to be
88
//! backed by a hardware root of trust.
9-
use parsec_interface::requests::ProviderID;
9+
use parsec_interface::requests::{Opcode, ProviderID};
1010
use serde::Deserialize;
11+
use std::collections::HashSet;
1112

1213
pub mod core_provider;
1314

@@ -86,15 +87,19 @@ pub trait Provide {
8687
/// Return a description of the current provider.
8788
///
8889
/// The descriptions are gathered in the Core Provider and returned for a ListProviders operation.
89-
fn describe(&self) -> Result<list_providers::ProviderInfo>;
90+
fn describe(&self) -> Result<(list_providers::ProviderInfo, HashSet<Opcode>)> {
91+
Err(ResponseStatus::PsaErrorNotSupported)
92+
}
9093

9194
/// List the providers running in the service.
9295
fn list_providers(&self, _op: list_providers::Operation) -> Result<list_providers::Result> {
9396
Err(ResponseStatus::PsaErrorNotSupported)
9497
}
9598

96-
/// List the opcodes supported by the current provider.
97-
fn list_opcodes(&self, _op: list_opcodes::Operation) -> Result<list_opcodes::Result>;
99+
/// List the opcodes supported by the given provider.
100+
fn list_opcodes(&self, _op: list_opcodes::Operation) -> Result<list_opcodes::Result> {
101+
Err(ResponseStatus::PsaErrorNotSupported)
102+
}
98103

99104
/// Execute a Ping operation to get the wire protocol version major and minor information.
100105
///

src/providers/pkcs11_provider/mod.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use derivative::Derivative;
1111
use log::{error, info, warn};
1212
use parsec_interface::operations::list_providers::ProviderInfo;
1313
use parsec_interface::operations::{
14-
list_opcodes, psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key,
15-
psa_sign_hash, psa_verify_hash,
14+
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, psa_sign_hash,
15+
psa_verify_hash,
1616
};
1717
use parsec_interface::requests::{Opcode, ProviderID, ResponseStatus, Result};
1818
use pkcs11::types::{CKF_OS_LOCKING_OK, CK_C_INITIALIZE_ARGS, CK_SLOT_ID};
@@ -29,14 +29,13 @@ mod asym_sign;
2929
mod key_management;
3030
mod utils;
3131

32-
const SUPPORTED_OPCODES: [Opcode; 7] = [
32+
const SUPPORTED_OPCODES: [Opcode; 6] = [
3333
Opcode::PsaGenerateKey,
3434
Opcode::PsaDestroyKey,
3535
Opcode::PsaSignHash,
3636
Opcode::PsaVerifyHash,
3737
Opcode::PsaImportKey,
3838
Opcode::PsaExportPublicKey,
39-
Opcode::ListOpcodes,
4039
];
4140

4241
/// Provider for Public Key Cryptography Standard #11
@@ -162,24 +161,23 @@ impl Pkcs11Provider {
162161
}
163162

164163
impl Provide for Pkcs11Provider {
165-
fn list_opcodes(&self, _op: list_opcodes::Operation) -> Result<list_opcodes::Result> {
166-
Ok(list_opcodes::Result {
167-
opcodes: SUPPORTED_OPCODES.iter().copied().collect(),
168-
})
169-
}
170-
171-
fn describe(&self) -> Result<ProviderInfo> {
172-
Ok(ProviderInfo {
173-
// Assigned UUID for this provider: 30e39502-eba6-4d60-a4af-c518b7f5e38f
174-
uuid: Uuid::parse_str("30e39502-eba6-4d60-a4af-c518b7f5e38f")
175-
.or(Err(ResponseStatus::InvalidEncoding))?,
176-
description: String::from("PKCS #11 provider, interfacing with a PKCS #11 library."),
177-
vendor: String::from("OASIS Standard."),
178-
version_maj: 0,
179-
version_min: 1,
180-
version_rev: 0,
181-
id: ProviderID::Pkcs11,
182-
})
164+
fn describe(&self) -> Result<(ProviderInfo, HashSet<Opcode>)> {
165+
Ok((
166+
ProviderInfo {
167+
// Assigned UUID for this provider: 30e39502-eba6-4d60-a4af-c518b7f5e38f
168+
uuid: Uuid::parse_str("30e39502-eba6-4d60-a4af-c518b7f5e38f")
169+
.or(Err(ResponseStatus::InvalidEncoding))?,
170+
description: String::from(
171+
"PKCS #11 provider, interfacing with a PKCS #11 library.",
172+
),
173+
vendor: String::from("OASIS Standard."),
174+
version_maj: 0,
175+
version_min: 1,
176+
version_rev: 0,
177+
id: ProviderID::Pkcs11,
178+
},
179+
SUPPORTED_OPCODES.iter().copied().collect(),
180+
))
183181
}
184182

185183
fn psa_generate_key(

0 commit comments

Comments
 (0)