Struct parsec_client::core::basic_client::BasicClient [−][src]
pub struct BasicClient { /* fields omitted */ }
Expand description
Core client for the Parsec service
The client exposes low-level functionality for using the Parsec service. Below you can see code examples for a few of the operations supported.
Providers are abstracted representations of the secure elements that Parsec offers abstraction over. Providers are the ones to execute the cryptographic operations requested by the user.
For all cryptographic operations an implicit provider is used which can be changed between operations. The client starts with the default provider, the first one returned by the ListProviders operation.
For crypto operations, if the implicit client provider is ProviderId::Core
, a client error
of InvalidProvider
type is returned.
See the operation-specific response codes returned by the service in the operation’s page
here.
Implementations
Main client functionality.
Create a new Parsec client.
The client will be initialised with default values obtained from the service for the implicit provider and for application identity.
app_name
is the application name to be used if direct authentication is the default authentication choice
This client will use the default configuration. That includes using a Protobuf converter for message bodies and a Unix Domain Socket IPC handler. The default timeout length is 60 seconds.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?;
Create a client that can initially only be used with Core operations not necessitating authentication (eg ping).
Setting an authentication method and an implicit provider is needed before calling crypto operations.
Example
use parsec_client::BasicClient; let client = BasicClient::new_naked(); let (major, minor) = client.ping()?;
Query the service for the list of authenticators provided and use the first one as default
app_name
is to be used if direct authentication is the default choice
Errors
If no authenticator is reported by the service, a NoAuthenticator
error kind is returned.
If the default authenticator is DirectAuthenticator
and app_name
was set to None
,
an error of type MissingParam
is returned.
If none of the authenticators returned by the service is supported, NoAuthenticator
is
returned.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::requests::ProviderId; let mut client = BasicClient::new_naked(); client.set_implicit_provider(ProviderId::Pkcs11); client.set_default_auth(Some("main_client".to_string()))?;
Update the authentication data of the client.
This is useful if you want to use a different authentication method than the default one.
Example
See [set_default_provider
].
Retrieve authentication data of the client.
Example
use parsec_client::BasicClient; use parsec_client::auth::Authentication; let mut client = BasicClient::new_naked(); client.set_auth_data(Authentication::UnixPeerCredentials); assert_eq!(Authentication::UnixPeerCredentials, client.auth_data());
Query for the service provider list and set the default one as implicit
Errors
If no provider is returned by the service, an client error of NoProvider
type is returned.
Example
use parsec_client::BasicClient; use parsec_client::auth::Authentication; let mut client = BasicClient::new_naked(); client.set_default_provider()?; client.set_auth_data(Authentication::UnixPeerCredentials);
Retrieve client’s implicit provider.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::requests::ProviderId; let mut client = BasicClient::new_naked(); client.set_implicit_provider(ProviderId::Pkcs11); assert_eq!(ProviderId::Pkcs11, client.implicit_provider());
[Core Operation] List the opcodes supported by the specified provider.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::requests::{Opcode, ProviderId}; let client: BasicClient = BasicClient::new(None)?; let opcodes = client.list_opcodes(ProviderId::Pkcs11)?; if opcodes.contains(&Opcode::PsaGenerateRandom) { let random_bytes = client.psa_generate_random(10)?; }
[Core Operation] List the providers that are supported by the service.
Example
use parsec_client::BasicClient; let mut client: BasicClient = BasicClient::new_naked(); let providers = client.list_providers()?; client.set_implicit_provider(providers[1].id);
[Core Operation] List the authenticators that are supported by the service.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; let opcodes = client.list_authenticators()?;
[Core Operation] List all keys belonging to the application.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; let keys = client.list_keys()?;
[Core Operation, Admin Operation] Lists all clients currently having data in the service.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; let clients = client.list_clients()?;
[Core Operation, Admin Operation] Delete all data a client has in the service.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; client.delete_client("main_client")?;
[Core Operation] Send a ping request to the service.
This operation is intended for testing connectivity to the service and for retrieving the maximum wire protocol version it supports.
Example
See [new_naked
].
[Cryptographic Operation] Generate a key.
Creates a new key with the given name within the namespace of the implicit client provider. Any UTF-8 string is considered a valid key name, however names must be unique per provider.
Persistence of keys is implemented at provider level, and currently all providers persist all the keys users create.
If this method returns an error, no key will have been generated and the name used will still be available for another key.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, Lifetime, Policy, Type, UsageFlags}; use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; let client: BasicClient = BasicClient::new(None)?; let key_attrs = Attributes { lifetime: Lifetime::Persistent, key_type: Type::RsaKeyPair, bits: 2048, policy: Policy { usage_flags: UsageFlags::default(), permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), }.into(), }, }; client.psa_generate_key("my_key", key_attrs)?;
[Cryptographic Operation] Destroy a key.
Given that keys are namespaced at a provider level, it is
important to call psa_destroy_key
on the correct combination of
implicit client provider and key_name
.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; client.psa_destroy_key("my_key")?;
[Cryptographic Operation] Import a key.
Creates a new key with the given name within the namespace of the implicit client provider using the user-provided data. Any UTF-8 string is considered a valid key name, however names must be unique per provider.
The key material should follow the appropriate binary format expressed
here.
Several crates (e.g. picky-asn1
)
can greatly help in dealing with binary encodings.
If this method returns an error, no key will have been imported and the name used will still be available for another key.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, Lifetime, Policy, Type, UsageFlags, EccFamily}; use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; let client: BasicClient = BasicClient::new(None)?; let ecc_private_key = vec![ 0x26, 0xc8, 0x82, 0x9e, 0x22, 0xe3, 0x0c, 0xa6, 0x3d, 0x29, 0xf5, 0xf7, 0x27, 0x39, 0x58, 0x47, 0x41, 0x81, 0xf6, 0x57, 0x4f, 0xdb, 0xcb, 0x4d, 0xbb, 0xdd, 0x52, 0xff, 0x3a, 0xc0, 0xf6, 0x0d, ]; let key_attrs = Attributes { lifetime: Lifetime::Persistent, key_type: Type::EccKeyPair { curve_family: EccFamily::SecpR1, }, bits: 256, policy: Policy { usage_flags: UsageFlags::default(), permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), }.into(), }, }; client.psa_import_key("my_key", &ecc_private_key, key_attrs)?;
[Cryptographic Operation] Export a public key or the public part of a key pair.
The returned key material will follow the appropriate binary format expressed
here.
Several crates (e.g. picky-asn1
)
can greatly help in dealing with binary encodings.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; let public_key_data = client.psa_export_public_key("my_key");
[Cryptographic Operation] Export a key.
The returned key material will follow the appropriate binary format expressed
here.
Several crates (e.g. picky-asn1
)
can greatly help in dealing with binary encodings.
Example
use parsec_client::BasicClient; let client: BasicClient = BasicClient::new(None)?; let key_data = client.psa_export_key("my_key");
[Cryptographic Operation] Create an asymmetric signature on a pre-computed message digest.
The key intended for signing must have its sign_hash
flag set
to true
in its key policy.
The signature will be created with the algorithm defined in
sign_algorithm
, but only after checking that the key policy
and type conform with it.
hash
must be a hash pre-computed over the message of interest
with the algorithm specified within sign_algorithm
.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, Lifetime, Policy, Type, UsageFlags}; use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; let client: BasicClient = BasicClient::new(None)?; let hash = vec![ 0x69, 0x3E, 0xDB, 0x1B, 0x22, 0x79, 0x03, 0xF4, 0xC0, 0xBF, 0xD6, 0x91, 0x76, 0x37, 0x84, 0xA2, 0x94, 0x8E, 0x92, 0x50, 0x35, 0xC2, 0x8C, 0x5C, 0x3C, 0xCA, 0xFE, 0x18, 0xE8, 0x81, 0x37, 0x78, ]; let signature = client.psa_sign_hash("my_key", &hash, AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), })?;
[Cryptographic Operation] Verify an existing asymmetric signature over a pre-computed message digest.
The key intended for signing must have its verify_hash
flag set
to true
in its key policy.
The signature will be verifyied with the algorithm defined in
sign_algorithm
, but only after checking that the key policy
and type conform with it.
hash
must be a hash pre-computed over the message of interest
with the algorithm specified within sign_algorithm
.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, Lifetime, Policy, Type, UsageFlags}; use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; let client: BasicClient = BasicClient::new(None)?; let hash = vec![ 0x69, 0x3E, 0xDB, 0x1B, 0x22, 0x79, 0x03, 0xF4, 0xC0, 0xBF, 0xD6, 0x91, 0x76, 0x37, 0x84, 0xA2, 0x94, 0x8E, 0x92, 0x50, 0x35, 0xC2, 0x8C, 0x5C, 0x3C, 0xCA, 0xFE, 0x18, 0xE8, 0x81, 0x37, 0x78, ]; let alg = AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), }; let signature = client.psa_sign_hash("my_key", &hash, alg)?; client.psa_verify_hash("my_key", &hash, alg, &signature)?;
[Cryptographic Operation] Create an asymmetric signature on a message.
The key intended for signing must have its sign_message
flag set
to true
in its key policy.
The signature will be created with the algorithm defined in
sign_algorithm
, but only after checking that the key policy
and type conform with it.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, Lifetime, Policy, Type, UsageFlags}; use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; let client: BasicClient = BasicClient::new(None)?; let message = "This is the message to sign which can be of any size!".as_bytes(); let signature = client.psa_sign_message( "my_key", message, AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), } )?;
[Cryptographic Operation] Verify an existing asymmetric signature over a message.
The key intended for signing must have its verify_message
flag set
to true
in its key policy.
The signature will be verifyied with the algorithm defined in
sign_algorithm
, but only after checking that the key policy
and type conform with it.
Example
use parsec_client::BasicClient; use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, Lifetime, Policy, Type, UsageFlags}; use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; let client: BasicClient = BasicClient::new(None)?; let message = "This is the message to sign which can be of any size!".as_bytes(); let alg = AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), }; let signature = client.psa_sign_message("my_key", message, alg)?; client.psa_verify_message("my_key", message, alg, &signature)?;
[Cryptographic Operation] Encrypt a short message.
The key intended for encrypting must have its encrypt
flag set
to true
in its key policy.
The encryption will be performed with the algorithm defined in alg
,
but only after checking that the key policy and type conform with it.
salt
can be provided if supported by the algorithm. If the algorithm does not support salt, pass
an empty vector. If the algorithm supports optional salt, pass an empty vector to indicate no
salt. For RSA PKCS#1 v1.5 encryption, no salt is supported.
[Cryptographic Operation] Decrypt a short message.
The key intended for decrypting must have its decrypt
flag set
to true
in its key policy.
salt
can be provided if supported by the algorithm. If the algorithm does not support salt, pass
an empty vector. If the algorithm supports optional salt, pass an empty vector to indicate no
salt. For RSA PKCS#1 v1.5 encryption, no salt is supported.
The decryption will be performed with the algorithm defined in alg
,
but only after checking that the key policy and type conform with it.
[Cryptographic Operation] Compute hash of a message.
The hash computation will be performed with the algorithm defined in alg
.
[Cryptographic Operation] Compute hash of a message and compare it with a reference value.
The hash computation will be performed with the algorithm defined in alg
.
If this operation returns no error, the hash was computed successfully and it matches the reference value.
[Cryptographic Operation] Authenticate and encrypt a short message.
The key intended for decrypting must have its encrypt
flag set
to true
in its key policy.
The encryption will be performed with the algorithm defined in alg
,
but only after checking that the key policy and type conform with it.
nonce
must be appropriate for the selected alg
.
For algorithms where the encrypted data and the authentication tag are defined as separate outputs, the returned buffer will contain the encrypted data followed by the authentication data.
[Cryptographic Operation] Decrypt and authenticate a short message.
The key intended for decrypting must have its decrypt
flag set
to true
in its key policy.
The decryption will be performed with the algorithm defined in alg
,
but only after checking that the key policy and type conform with it.
nonce
must be appropriate for the selected alg
.
For algorithms where the encrypted data and the authentication tag are defined as separate inputs,
ciphertext
must contain the encrypted data followed by the authentication data.
[Cryptographic Operation] Perform a raw key agreement.
The provided private key must have its derive
flag set
to true
in its key policy.
The raw_key_agreement will be performed with the algorithm defined in alg
,
but only after checking that the key policy and type conform with it.
peer_key
must be the peer public key to use in the raw key derivation. It must
be in a format supported by PsaImportKey
.
Configuration methods for controlling communication with the service.
Set the converter used for request bodies handled by this client.
By default Protobuf will be used for this.
Configuration methods for controlling IPC-level options.
Set the maximum body size allowed for requests.
Defaults to the maximum value of usize
.
Set the IPC handler used for communication with the service.
By default the Unix domain socket client is used.
Set the timeout for operations on the IPC stream.
The value defaults to 1 second.