Skip to main content

Pkcs11KeyStore

Struct Pkcs11KeyStore 

Source
pub struct Pkcs11KeyStore { /* private fields */ }
Available on crate feature pkcs11 only.
Expand description

A KeyStore over a token of a PKCS#11 module: an HSM, a smart card or a software token such as SoftHSM2.

The key id is the object label (CKA_LABEL): a key is the private key object and the public key object that share a label. Keys are referenced by label, so a label must name one key; the store refuses a label that names several.

Signing happens in the module. The store hashes in-process and signs the hash with CKM_ECDSA (ES256, ES256K), CKM_RSA_PKCS over a SHA-256 DigestInfo (RS256) or CKM_RSA_PKCS_PSS with SHA-256, MGF1-SHA-256 and a 32-byte salt (PS256); EdDSA signs the message itself with CKM_EDDSA. ECDSA signatures come back as raw r || s, the JWS form.

What the store signs with is read from the module’s mechanism list when it is opened: EdDSA when the module has CKM_EDDSA, ES256 and (feature secp256k1) ES256K when it has CKM_ECDSA, and rsa_algorithm when it has the matching RSA mechanism. Pkcs11KeyStoreOptions::algorithms narrows the list. The store generates and deletes keys unless the token is write-protected; a generated key is an Ed25519, P-256, secp256k1 or RSA (65537) key pair stored on the token, the private key sensitive and not extractable. The key id of a generated key is the spec’s label when set and the RFC 7638 thumbprint of the public key otherwise; such a key is generated under a label starting with STAGING_LABEL_PREFIX and relabelled once its thumbprint is known, so a generation interrupted in between leaves a key with that prefix on the token, to be removed with the module’s tools.

The module’s functions block, so every operation runs on tokio’s blocking thread pool; the store needs a tokio runtime. It keeps a pool of logged-in sessions (Pkcs11KeyStoreOptions::sessions) and an operation that finds all of them busy waits for one. A module is loaded and initialized when the first store on it is opened, shared by every later store on the same path, and never finalized or unloaded before the process ends. The PIN is kept in memory for logging in new sessions and zeroized when the store is dropped.

§Examples

use identity_kit::jose::{JwsAlgorithm, KeyType};
use identity_kit::keys::{KeySpec, KeyStore, Pkcs11KeyStore};

let store = Pkcs11KeyStore::open("/usr/lib/softhsm/libsofthsm2.so", "issuer", Some("1234"))?;
let key = store
    .generate(KeySpec::new(KeyType::P256, JwsAlgorithm::ES256).with_label("issuer-2026"))
    .await?;
let signature = store.sign(&key, JwsAlgorithm::ES256, b"payload").await?;
assert_eq!(signature.len(), 64);

Implementations§

Source§

impl Pkcs11KeyStore

Source

pub fn open( module: impl AsRef<Path>, token: impl Into<Pkcs11Token>, pin: Option<&str>, ) -> Result<Self, KeyStoreError>

Opens token of the PKCS#11 module at module with the default options.

Loads the module, initializes it if needed, finds the token, reads its mechanism list and opens one session, logging in as the user with pin when given. A token that needs no login, or one with a protected authentication path, is opened with None. This blocks while it talks to the module.

PKCS#11 logs the application in, not the session: when the process is logged in to the token already (through another store, say), the module reports that instead of checking pin, and a wrong PIN goes unnoticed until the process logs out.

§Errors

KeyStoreError::Backend carrying a Pkcs11Error: the module does not load, the token is not there, the PIN is wrong, or the options are not usable.

Source

pub fn open_with( module: impl AsRef<Path>, token: impl Into<Pkcs11Token>, pin: Option<&str>, options: Pkcs11KeyStoreOptions, ) -> Result<Self, KeyStoreError>

Opens token of the PKCS#11 module at module as options say.

§Errors

As Pkcs11KeyStore::open.

Source

pub fn module(&self) -> &Path

The module’s path.

Source

pub fn slot(&self) -> u64

The id of the slot the token is in.

Source

pub fn token_label(&self) -> &str

The token’s label.

Source

pub fn options(&self) -> &Pkcs11KeyStoreOptions

The options the store was opened with.

Trait Implementations§

Source§

impl Clone for Pkcs11KeyStore

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Pkcs11KeyStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl KeyStore for Pkcs11KeyStore

Source§

fn capabilities(&self) -> KeyStoreCapabilities

What this store can do.
Source§

fn public_jwk<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 KeyId, ) -> Pin<Box<dyn Future<Output = Result<Jwk, KeyStoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

The public key of key, without private parameters. Read more
Source§

fn sign<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 KeyId, alg: JwsAlgorithm, data: &'life2 [u8], ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyStoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Signs data with key under alg, returning the signature in its JWS form. Read more
Source§

fn exists<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 KeyId, ) -> Pin<Box<dyn Future<Output = Result<bool, KeyStoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Whether key exists. Read more
Source§

fn generate<'life0, 'async_trait>( &'life0 self, spec: KeySpec, ) -> Pin<Box<dyn Future<Output = Result<KeyId, KeyStoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Generates a key as spec describes and returns its id. Read more
Source§

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 KeyId, ) -> Pin<Box<dyn Future<Output = Result<(), KeyStoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Deletes key. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more