#[non_exhaustive]pub enum KeyReference {
DidUrl(DidUrl),
Jwk(Box<Jwk>),
X509Chain(Vec<Vec<u8>>),
Jwks {
issuer: Url,
kid: String,
},
Jku {
url: Url,
kid: Option<String>,
},
}Expand description
Where a token says the key that signed it is (ADR 0006).
A JWT names its key in one of several ways: a DID URL in kid, a #fragment in kid
relative to a DID iss, a kid into the key set an HTTPS iss publishes, the key itself in
a jwk header, a certificate chain in x5c, or a key set URL in jku.
from_jws reads which from a JWS header; sd_jwt_vc builds one from a
cnf claim. A KeyResolver turns it into a key.
Resolving a reference says nothing about trust: a key by value resolves to itself whoever
made the token. Once the signature verifies, binds_to checks that the key
belongs to the party the token claims.
§Examples
use identity_kit::jose::{CompactJws, JwtClaims};
use identity_kit::resolver::{KeyReference, KeyReferenceError};
// {"alg":"EdDSA","kid":"#key-1"}.{"iss":"did:example:123"}
let jws = CompactJws::decode(
"eyJhbGciOiJFZERTQSIsImtpZCI6IiNrZXktMSJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMifQ.c2lnbmF0dXJl",
)?;
let claims: JwtClaims = jws.claims()?;
let reference = KeyReference::from_jws(&jws, claims.iss.as_deref())?;
assert_eq!(reference.to_string(), "did:example:123#key-1");
// A relative `kid` needs a DID to resolve against.
assert!(matches!(
KeyReference::from_jws(&jws, None),
Err(KeyReferenceError::RelativeKidWithoutIssuer(_))
));Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
DidUrl(DidUrl)
A verification method: a kid that is an absolute DID URL, or a #fragment joined with
a DID iss.
Jwk(Box<Jwk>)
The public key itself, from a jwk header or cnf.jwk.
X509Chain(Vec<Vec<u8>>)
An x5c certificate chain, DER, leaf first. No resolver in the crate handles it yet.
Jwks
The key kid names in the key set of the HTTPS issuer issuer (SD-JWT VC §3.5).
Fields
Jku
The key set at url, from jku, and the kid that selects a key in it. No resolver in
the crate handles it yet.
Implementations§
Source§impl KeyReference
impl KeyReference
Sourcepub fn from_jws(
jws: &CompactJws,
iss: Option<&str>,
) -> Result<Self, KeyReferenceError>
pub fn from_jws( jws: &CompactJws, iss: Option<&str>, ) -> Result<Self, KeyReferenceError>
Where the key of jws is, given the iss of its claims (when iss is a string).
The header parameters are tried in this order, and the first that applies decides:
- A
kidthat parses as a DID URL isDidUrl. A path or DID parameters such asversionIdare refused: they could select a document version that still lists a retired key (ADR 0004). - A
kidstarting with#is joined withissinto aDidUrlwhenissis a DID, and refused otherwise. - Another
kid, with anhttpsiss, isJwks. - A
jwkheader isJwk; a private key there is refused. - An
x5cheader isX509Chain, each certificate base64-decoded but not parsed. - A
jkuheader isJku, with thekidwhen there is one.
A kid that none of the first three cases takes is an error when no jwk, x5c or
jku follows.
§Errors
A KeyReferenceError: Missing when the header names no
key, otherwise the parameter that is wrong.
Sourcepub fn binds_to(&self, party: Option<&str>, key: &Jwk) -> bool
pub fn binds_to(&self, party: Option<&str>, key: &Jwk) -> bool
Whether key, which this reference resolved to and which verified the signature,
belongs to party, the issuer or holder the token claims:
| Reference | Binds when |
|---|---|
DidUrl | party is the DID of the URL |
Jwk | party is the did:jwk of key, or its RFC 7638 SHA-256 thumbprint, or absent (a SIOPv2 self-issued sub) |
Jwks | party is the issuer URL (compared as parsed URLs) |
X509Chain, Jku | never, until the crate resolves them |
Only a key by value can bind to no party; a validator that requires an issuer or holder passes it.
§Examples
use identity_kit::did::DidUrl;
use identity_kit::jose::Jwk;
use identity_kit::resolver::KeyReference;
// RFC 8037 Appendix A.2.
let key: Jwk = serde_json::from_str(
r#"{"kty":"OKP","crv":"Ed25519","x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"}"#,
)?;
let by_value = KeyReference::Jwk(Box::new(key.clone()));
// RFC 8037 Appendix A.3.
assert!(by_value.binds_to(Some("kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k"), &key));
assert!(by_value.binds_to(None, &key));
assert!(!by_value.binds_to(Some("did:example:123"), &key));
let by_url = KeyReference::DidUrl(DidUrl::parse("did:example:123#key-1")?);
assert!(by_url.binds_to(Some("did:example:123"), &key));
assert!(!by_url.binds_to(Some("did:example:456"), &key));
assert!(!by_url.binds_to(None, &key));Source§impl KeyReference
impl KeyReference
Sourcepub fn from_confirmation(cnf: &Confirmation) -> Result<Self, KeyReferenceError>
Available on crate feature sd-jwt only.
pub fn from_confirmation(cnf: &Confirmation) -> Result<Self, KeyReferenceError>
sd-jwt only.Where the holder’s key of a cnf claim (RFC 7800) is: jwk if present, else a kid
that is an absolute DID URL, else jku with the kid.
RFC 7800 §3.4 leaves the meaning of a key id to the application, and the confirmation
carries no DID or key set to resolve a #fragment or a bare id against (using sub
would conflate the subject with the holder), so a cnf.kid must be an absolute DID URL
without a path or DID parameters (ADR 0006).
§Examples
use identity_kit::resolver::{KeyReference, KeyReferenceError};
use identity_kit::sd_jwt_vc::Confirmation;
let cnf = Confirmation::kid("did:example:holder#key-1");
assert_eq!(KeyReference::from_confirmation(&cnf)?.to_string(), "did:example:holder#key-1");
let relative = Confirmation::kid("#key-1");
assert!(matches!(
KeyReference::from_confirmation(&relative),
Err(KeyReferenceError::InvalidKid { .. })
));§Errors
KeyReferenceError::Missing for an empty cnf,
KeyReferenceError::UnsupportedConfirmation for one that names its key only by another
method (x5t#S256, jwe), and otherwise the member that is wrong.
Trait Implementations§
Source§impl Clone for KeyReference
impl Clone for KeyReference
Source§impl Debug for KeyReference
impl Debug for KeyReference
Source§impl Display for KeyReference
impl Display for KeyReference
impl Eq for KeyReference
Source§impl PartialEq for KeyReference
impl PartialEq for KeyReference
impl StructuralPartialEq for KeyReference
Auto Trait Implementations§
impl Freeze for KeyReference
impl RefUnwindSafe for KeyReference
impl Send for KeyReference
impl Sync for KeyReference
impl Unpin for KeyReference
impl UnsafeUnpin for KeyReference
impl UnwindSafe for KeyReference
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.