@@ -24,16 +24,23 @@ use std::collections::HashSet;
24
24
/// The client exposes low-level functionality for using the Parsec service.
25
25
/// Below you can see code examples for a few of the operations supported.
26
26
///
27
+ /// For all cryptographic operations an implicit provider is used which can be
28
+ /// changed between operations. The client starts with no such defined provider
29
+ /// and it is the responsibility of the user to identify and set an appropriate
30
+ /// one. As such, it is critical that before attempting to use cryptographic
31
+ /// operations users call [`list_providers`](#method.list_providers)
32
+ /// and [`list_opcodes`](#method.list_opcodes)
33
+ /// in order to figure out if their desired use case and provider are
34
+ /// available.
35
+ ///
27
36
/// Creating a `BasicClient` instance:
28
37
///```no_run
29
38
///use parsec_client::auth::AuthenticationData;
30
39
///use parsec_client::BasicClient;
31
- ///use parsec_client::core::ProviderID;
32
40
///
33
41
///let app_name = String::from("app-name");
34
42
///let app_auth_data = AuthenticationData::AppIdentity(app_name);
35
- ///let desired_provider = ProviderID::Pkcs11;
36
- ///let client: BasicClient = BasicClient::new(app_auth_data, desired_provider);
43
+ ///let client: BasicClient = BasicClient::new(app_auth_data);
37
44
///```
38
45
///
39
46
/// Performing a Ping operation helps to determine if the service is available
@@ -43,7 +50,7 @@ use std::collections::HashSet;
43
50
///# use parsec_client::auth::AuthenticationData;
44
51
///# use parsec_client::BasicClient;
45
52
///# use parsec_client::core::ProviderID;
46
- ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")), ProviderID::Pkcs11 );
53
+ ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")));
47
54
///let res = client.ping();
48
55
///
49
56
///if let Ok((wire_prot_v_maj, wire_prot_v_min)) = res {
@@ -65,7 +72,7 @@ use std::collections::HashSet;
65
72
///# use parsec_client::auth::AuthenticationData;
66
73
///# use parsec_client::BasicClient;
67
74
///# use parsec_client::core::ProviderID;
68
- ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")), ProviderID::Pkcs11 );
75
+ ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")));
69
76
///use uuid::Uuid;
70
77
///
71
78
///// Identify provider by its UUID (in this case, the PKCS11 provider)
@@ -82,30 +89,33 @@ use std::collections::HashSet;
82
89
///```
83
90
///
84
91
/// Checking operations supported by the provider we're interested in is done
85
- /// through the `list_provider_operations ` method:
92
+ /// through the `list_opcodes ` method:
86
93
///```no_run
87
94
///# use parsec_client::auth::AuthenticationData;
88
95
///# use parsec_client::BasicClient;
89
96
///# use parsec_client::core::ProviderID;
90
- ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")), ProviderID::Pkcs11 );
97
+ ///# let mut client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")));
91
98
///use parsec_client::core::Opcode;
92
99
///
93
100
///let desired_provider = ProviderID::Pkcs11;
94
101
///let provider_opcodes = client
95
- /// .list_provider_operations (desired_provider)
102
+ /// .list_opcodes (desired_provider)
96
103
/// .expect("Failed to list opcodes");
97
104
///// Each operation is identified by a specific `Opcode`
98
105
///assert!(provider_opcodes.contains(&Opcode::PsaGenerateKey));
99
106
///assert!(provider_opcodes.contains(&Opcode::PsaSignHash));
100
107
///assert!(provider_opcodes.contains(&Opcode::PsaDestroyKey));
108
+ ///
109
+ ///// Now that we're certain our desired provider offers all the functionality we need...
110
+ ///client.set_implicit_provider(desired_provider);
101
111
///```
102
112
///
103
113
/// Creating a key-pair for signing SHA256 digests with RSA PKCS#1 v1.5:
104
114
///```no_run
105
115
///# use parsec_client::auth::AuthenticationData;
106
116
///# use parsec_client::BasicClient;
107
117
///# use parsec_client::core::ProviderID;
108
- ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")), ProviderID::Pkcs11 );
118
+ ///# let client: BasicClient = BasicClient::new(AuthenticationData::AppIdentity(String::from("app-name")));
109
119
///use parsec_client::core::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
110
120
///use parsec_client::core::psa_key_attributes::{KeyAttributes, KeyPolicy, KeyType, UsageFlags};
111
121
///
@@ -143,35 +153,25 @@ use std::collections::HashSet;
143
153
/// .psa_generate_key(key_name, key_attrs)
144
154
/// .expect("Failed to create key!");
145
155
///```
146
- ///
147
- /// It is recommended that before attempting to use cryptographic
148
- /// operations users call [`list_providers`](#method.list_providers)
149
- /// and [`list_provider_operations`](#method.list_provider_operations)
150
- /// in order to figure out if their desired use case and provider are
151
- /// available.
152
156
#[ derive( Debug ) ]
153
157
pub struct BasicClient {
154
158
pub ( crate ) op_client : OperationClient ,
155
159
pub ( crate ) auth_data : AuthenticationData ,
156
- pub ( crate ) implicit_provider : ProviderID ,
160
+ pub ( crate ) implicit_provider : Option < ProviderID > ,
157
161
}
158
162
159
163
/// Main client functionality.
160
164
impl BasicClient {
161
- /// Create a new Parsec client given the authentication data of the app and a provider ID.
162
- ///
163
- /// The `implicit_provider` will be used for all non-core operations. Thus, until a
164
- /// different provider ID is set using [`set_implicit_provider`](#method.set_implicit_provider),
165
- /// all cryptographic operations will be executed in the context of this provider (if it is
166
- /// available within the service).
165
+ /// Create a new Parsec client given the authentication data of the app.
167
166
///
168
- /// In order to get a list of supported providers, call the [`list_providers`](#method.list_providers)
169
- /// method.
170
- pub fn new ( auth_data : AuthenticationData , implicit_provider : ProviderID ) -> Self {
167
+ /// Before you can use this client for cryptographic operations, you first need to call
168
+ /// [`set_implicit_provider`](#method.set_implicit_provider). In order to get a list of
169
+ /// supported providers, call the [`list_providers`](#method.list_providers) method.
170
+ pub fn new ( auth_data : AuthenticationData ) -> Self {
171
171
BasicClient {
172
172
op_client : Default :: default ( ) ,
173
173
auth_data,
174
- implicit_provider,
174
+ implicit_provider : None ,
175
175
}
176
176
}
177
177
@@ -187,16 +187,16 @@ impl BasicClient {
187
187
188
188
/// Set the provider that the client will be implicitly working with.
189
189
pub fn set_implicit_provider ( & mut self , provider : ProviderID ) {
190
- self . implicit_provider = provider;
190
+ self . implicit_provider = Some ( provider) ;
191
191
}
192
192
193
193
/// Retrieve client's implicit provider.
194
- pub fn implicit_provider ( & self ) -> ProviderID {
194
+ pub fn implicit_provider ( & self ) -> Option < ProviderID > {
195
195
self . implicit_provider
196
196
}
197
197
198
198
/// **[Core Operation]** List the opcodes supported by the specified provider.
199
- pub fn list_provider_operations ( & self , provider : ProviderID ) -> Result < HashSet < Opcode > > {
199
+ pub fn list_opcodes ( & self , provider : ProviderID ) -> Result < HashSet < Opcode > > {
200
200
let res = self . op_client . process_operation (
201
201
NativeOperation :: ListOpcodes ( ListOpcodes {
202
202
provider_id : provider,
@@ -271,10 +271,13 @@ impl BasicClient {
271
271
/// If the implicit client provider is `ProviderID::Core`, a client error
272
272
/// of `InvalidProvider` type is returned.
273
273
///
274
+ /// If the implicit client provider has not been set, a client error of
275
+ /// `NoProvider` type is returned.
276
+ ///
274
277
/// See the operation-specific response codes returned by the service
275
278
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_generate_key.html#specific-response-status-codes).
276
279
pub fn psa_generate_key ( & self , key_name : String , key_attributes : KeyAttributes ) -> Result < ( ) > {
277
- self . can_provide_crypto ( ) ?;
280
+ let crypto_provider = self . can_provide_crypto ( ) ?;
278
281
279
282
let op = PsaGenerateKey {
280
283
key_name,
@@ -283,7 +286,7 @@ impl BasicClient {
283
286
284
287
let _ = self . op_client . process_operation (
285
288
NativeOperation :: PsaGenerateKey ( op) ,
286
- self . implicit_provider ,
289
+ crypto_provider ,
287
290
& self . auth_data ,
288
291
) ?;
289
292
@@ -301,16 +304,19 @@ impl BasicClient {
301
304
/// If the implicit client provider is `ProviderID::Core`, a client error
302
305
/// of `InvalidProvider` type is returned.
303
306
///
307
+ /// If the implicit client provider has not been set, a client error of
308
+ /// `NoProvider` type is returned.
309
+ ///
304
310
/// See the operation-specific response codes returned by the service
305
311
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_destroy_key.html#specific-response-status-codes).
306
312
pub fn psa_destroy_key ( & self , key_name : String ) -> Result < ( ) > {
307
- self . can_provide_crypto ( ) ?;
313
+ let crypto_provider = self . can_provide_crypto ( ) ?;
308
314
309
315
let op = PsaDestroyKey { key_name } ;
310
316
311
317
let _ = self . op_client . process_operation (
312
318
NativeOperation :: PsaDestroyKey ( op) ,
313
- self . implicit_provider ,
319
+ crypto_provider ,
314
320
& self . auth_data ,
315
321
) ?;
316
322
@@ -341,6 +347,9 @@ impl BasicClient {
341
347
/// If the implicit client provider is `ProviderID::Core`, a client error
342
348
/// of `InvalidProvider` type is returned.
343
349
///
350
+ /// If the implicit client provider has not been set, a client error of
351
+ /// `NoProvider` type is returned.
352
+ ///
344
353
/// See the operation-specific response codes returned by the service
345
354
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_import_key.html#specific-response-status-codes).
346
355
pub fn psa_import_key (
@@ -349,7 +358,7 @@ impl BasicClient {
349
358
key_material : Vec < u8 > ,
350
359
key_attributes : KeyAttributes ,
351
360
) -> Result < ( ) > {
352
- self . can_provide_crypto ( ) ?;
361
+ let crypto_provider = self . can_provide_crypto ( ) ?;
353
362
354
363
let op = PsaImportKey {
355
364
key_name,
@@ -359,7 +368,7 @@ impl BasicClient {
359
368
360
369
let _ = self . op_client . process_operation (
361
370
NativeOperation :: PsaImportKey ( op) ,
362
- self . implicit_provider ,
371
+ crypto_provider ,
363
372
& self . auth_data ,
364
373
) ?;
365
374
@@ -382,16 +391,19 @@ impl BasicClient {
382
391
/// If the implicit client provider is `ProviderID::Core`, a client error
383
392
/// of `InvalidProvider` type is returned.
384
393
///
394
+ /// If the implicit client provider has not been set, a client error of
395
+ /// `NoProvider` type is returned.
396
+ ///
385
397
/// See the operation-specific response codes returned by the service
386
398
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_export_public_key.html#specific-response-status-codes).
387
399
pub fn psa_export_public_key ( & self , key_name : String ) -> Result < Vec < u8 > > {
388
- self . can_provide_crypto ( ) ?;
400
+ let crypto_provider = self . can_provide_crypto ( ) ?;
389
401
390
402
let op = PsaExportPublicKey { key_name } ;
391
403
392
404
let res = self . op_client . process_operation (
393
405
NativeOperation :: PsaExportPublicKey ( op) ,
394
- self . implicit_provider ,
406
+ crypto_provider ,
395
407
& self . auth_data ,
396
408
) ?;
397
409
@@ -421,6 +433,9 @@ impl BasicClient {
421
433
/// If the implicit client provider is `ProviderID::Core`, a client error
422
434
/// of `InvalidProvider` type is returned.
423
435
///
436
+ /// If the implicit client provider has not been set, a client error of
437
+ /// `NoProvider` type is returned.
438
+ ///
424
439
/// See the operation-specific response codes returned by the service
425
440
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_sign_hash.html#specific-response-status-codes).
426
441
pub fn psa_sign_hash (
@@ -429,7 +444,7 @@ impl BasicClient {
429
444
hash : Vec < u8 > ,
430
445
sign_algorithm : AsymmetricSignature ,
431
446
) -> Result < Vec < u8 > > {
432
- self . can_provide_crypto ( ) ?;
447
+ let crypto_provider = self . can_provide_crypto ( ) ?;
433
448
434
449
let op = PsaSignHash {
435
450
key_name,
@@ -439,7 +454,7 @@ impl BasicClient {
439
454
440
455
let res = self . op_client . process_operation (
441
456
NativeOperation :: PsaSignHash ( op) ,
442
- self . implicit_provider ,
457
+ crypto_provider ,
443
458
& self . auth_data ,
444
459
) ?;
445
460
@@ -469,6 +484,9 @@ impl BasicClient {
469
484
/// If the implicit client provider is `ProviderID::Core`, a client error
470
485
/// of `InvalidProvider` type is returned.
471
486
///
487
+ /// If the implicit client provider has not been set, a client error of
488
+ /// `NoProvider` type is returned.
489
+ ///
472
490
/// See the operation-specific response codes returned by the service
473
491
/// [here](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_verify_hash.html#specific-response-status-codes).
474
492
pub fn psa_verify_hash (
@@ -478,7 +496,7 @@ impl BasicClient {
478
496
sign_algorithm : AsymmetricSignature ,
479
497
signature : Vec < u8 > ,
480
498
) -> Result < ( ) > {
481
- self . can_provide_crypto ( ) ?;
499
+ let crypto_provider = self . can_provide_crypto ( ) ?;
482
500
483
501
let op = PsaVerifyHash {
484
502
key_name,
@@ -489,17 +507,18 @@ impl BasicClient {
489
507
490
508
let _ = self . op_client . process_operation (
491
509
NativeOperation :: PsaVerifyHash ( op) ,
492
- self . implicit_provider ,
510
+ crypto_provider ,
493
511
& self . auth_data ,
494
512
) ?;
495
513
496
514
Ok ( ( ) )
497
515
}
498
516
499
- fn can_provide_crypto ( & self ) -> Result < ( ) > {
517
+ fn can_provide_crypto ( & self ) -> Result < ProviderID > {
500
518
match self . implicit_provider {
501
- ProviderID :: Core => Err ( Error :: Client ( ClientErrorKind :: InvalidProvider ) ) ,
502
- _ => Ok ( ( ) ) ,
519
+ None => Err ( Error :: Client ( ClientErrorKind :: NoProvider ) ) ,
520
+ Some ( ProviderID :: Core ) => Err ( Error :: Client ( ClientErrorKind :: InvalidProvider ) ) ,
521
+ Some ( crypto_provider) => Ok ( crypto_provider) ,
503
522
}
504
523
}
505
524
}
0 commit comments