pub struct KeySigner<S> { /* private fields */ }Expand description
A Signer over one key of a KeyStore.
S is the handle the signer holds the store by: a reference (&InMemoryKeyStore,
&dyn KeyStore) for a signer that lives next to the store, or an Arc<dyn KeyStore> for one
that outlives the scope it was made in, moved into a spawned task or kept in shared
application state. Every such handle implements KeyStore itself.
The signer looks the key up once, when it is created, and keeps the public Jwk so that a
caller building a DID document or a JWS header never round-trips to the store for it
(KeySigner::public_jwk). A caller that already has the public key, for instance stored
next to the DID document it published, skips that lookup with KeySigner::from_public_jwk.
Signing goes to the store on every call.
Signer::kid is the key id, unless KeySigner::with_kid set another value, such as the
DID URL of the verification method the key backs.
§Examples
use identity_kit::jose::{CompactJws, DefaultVerifier, JwsAlgorithm, JwsHeader, KeyType, encode_compact};
use identity_kit::keys::{InMemoryKeyStore, KeySigner, KeySpec, KeyStore};
let store = InMemoryKeyStore::new();
let key = store.generate(KeySpec::new(KeyType::Ed25519, JwsAlgorithm::EdDSA)).await?;
let signer = KeySigner::new(&store, key, JwsAlgorithm::EdDSA).await?;
let header = JwsHeader::new(JwsAlgorithm::EdDSA).with_kid(signer.key_id().as_str());
let token = encode_compact(&header, b"{}", &signer).await?;
let jws = CompactJws::decode(&token)?;
jws.verify(&DefaultVerifier, signer.public_jwk())?;A signer over an Arc<dyn KeyStore> is 'static and moves into a spawned task:
use std::sync::Arc;
use identity_kit::jose::{JwsAlgorithm, JwsHeader, KeyType, encode_compact};
use identity_kit::keys::{InMemoryKeyStore, KeySigner, KeySpec, KeyStore};
let store: Arc<dyn KeyStore> = Arc::new(InMemoryKeyStore::new());
let key = store.generate(KeySpec::new(KeyType::P256, JwsAlgorithm::ES256)).await?;
let signer = KeySigner::new(Arc::clone(&store), key, JwsAlgorithm::ES256).await?;
let token = tokio::spawn(async move {
encode_compact(&JwsHeader::new(JwsAlgorithm::ES256), b"{}", &signer).await
})
.await??;
assert_eq!(token.split('.').count(), 3);Implementations§
Source§impl<S: KeyStore> KeySigner<S>
impl<S: KeyStore> KeySigner<S>
Sourcepub async fn new(
store: S,
key: KeyId,
alg: JwsAlgorithm,
) -> Result<Self, KeyStoreError>
pub async fn new( store: S, key: KeyId, alg: JwsAlgorithm, ) -> Result<Self, KeyStoreError>
A signer over key of store, signing with alg.
§Errors
KeyStoreError::UnsupportedAlgorithm when the store does not advertise alg,
KeyStoreError::NotFound when the key does not exist,
KeyStoreError::AlgorithmMismatch when the key’s public JWK names another algorithm,
and whatever else the store reports.
Sourcepub fn from_public_jwk(
store: S,
key: KeyId,
alg: JwsAlgorithm,
public: Jwk,
) -> Result<Self, KeyStoreError>
pub fn from_public_jwk( store: S, key: KeyId, alg: JwsAlgorithm, public: Jwk, ) -> Result<Self, KeyStoreError>
A signer over key of store, signing with alg, whose public key the caller already
has. The store is not asked for anything until the first signature.
The caller vouches that public is the public key of key: the signer cannot tell, and
with a wrong one it makes signatures that verify against no key the caller publishes.
§Errors
KeyStoreError::UnsupportedAlgorithm when the store does not advertise alg,
KeyStoreError::AlgorithmMismatch when public names another algorithm, and
KeyStoreError::InvalidKey when public carries private parameters or is not a key
for alg (its kty and crv).
§Examples
use identity_kit::jose::{JwsAlgorithm, KeyType};
use identity_kit::keys::{InMemoryKeyStore, KeySigner, KeySpec, KeyStore};
let store = InMemoryKeyStore::new();
let key = store.generate(KeySpec::new(KeyType::Ed25519, JwsAlgorithm::EdDSA)).await?;
// Fetched once and kept, for instance next to the DID document.
let public = store.public_jwk(&key).await?;
let signer = KeySigner::from_public_jwk(&store, key, JwsAlgorithm::EdDSA, public)?;Sourcepub fn with_kid(self, kid: impl Into<String>) -> Self
pub fn with_kid(self, kid: impl Into<String>) -> Self
This signer with Signer::kid set to kid instead of the key id.
Sourcepub fn public_jwk(&self) -> &Jwk
pub fn public_jwk(&self) -> &Jwk
The public key, as the store reported it when the signer was created, or as given to
KeySigner::from_public_jwk.