pub struct JsonWebKey<A = ()> { /* private fields */ }
Expand description
A JsonWebKey
is a JSON Object representing
the components of a cryptographic keys that can be used for
JWE and
JWS.
The format of Json Web Keys is defined in RFC 7517 with key specific
parameters defined in section 6 of RFC 7518. The JsonWebKey
struct is
an abstract representation of all possible key types. The JsonWebKeyType
enum is used to specialize on concrete key type.
§Comparison and equality
It is not defined how to determine if a JsonWebKey
is equal
to another. Therefore, JsonWebKey
does not implement PartialEq
.
If you want to compare a JsonWebKey
, you should either use something
like the kid
parameter or a Thumbprint
of
the key (or ideally, a Thumbprint
as kid
).
You should avoid comparing the serialized form of a JsonWebKey
as it
may contain optional parameters, which may not always be present and would
lead to unexpected results.
§Examples
Parse a JsonWebKey from its json representation:
use jose::{jwk::KeyUsage, JsonWebKey};
// The following json object represents a RSA key used for signing
let json = r#"
{
"kty": "RSA",
"kid": "bilbo.baggins@hobbiton.example",
"use": "sig",
"n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw",
"e": "AQAB"
}"#;
// deserialize the key from it's json representation using serde_json
let jwk: JsonWebKey = serde_json::from_str(json)?;
// You can use the JsonWebKey to access parameters defined by the spec.
// For example, we might want to ensure that this key is for signing by
// checking the `use` parameter
assert_eq!(jwk.key_usage(), Some(&KeyUsage::Signing));
§Additional parameters
The spec allows custom/additional parameters that are not registered in the
IANA JSON Web Key Parameters
registry. The A
generic parameter of
JsonWebKey<A>
allows you to bring your own type to do just that.
To do so, create a container type that holds all your parameters (and maybe
even another container).
Imagine we have a custom parameter intended_party
which holds a String
identifying the application which should use the JsonWebKey
:
use jose::JsonWebKey;
use serde::{Deserialize, Serialize};
// don't forget to derive or implement the serde traits since they are used for (de)serialization
#[derive(Deserialize, Serialize)]
struct MyCustomParameters {
intended_party: String,
}
/// A type alias so we dont have to type so much
type MyJsonWebKey = JsonWebKey<MyCustomParameters>;
// consider the same key as before but this time it needs our custom parameter `intended_party`
let json = r#"
{
"intended_party": "my_application",
"kty": "RSA",
"kid": "bilbo.baggins@hobbiton.example",
"use": "sig",
"n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw",
"e": "AQAB"
}"#;
let jwk: MyJsonWebKey = serde_json::from_str(json)?;
// access the custom parameter
assert_eq!("my_application", jwk.additional().intended_party.as_str());
§Implementing Checkable
for your additional type
The Checkable
trait should be implemented by types that can utilize some
(potentially expensive) checks to ensure their validity optionally using a
Policy
. For example, JsonWebKey
implements the Checkable
trait
to validate some parameters which can’t be validated during deserialization.
For JsonWebKey
to implement Checkable
, your additional type also
needs to implement Checkable
. If we recall the example from before, we
might want to ensure that our intended_party
parameter containts only
ascii characters. An implementation for that purpose might look like this:
use jose::policy::{Checkable, Checked, Policy, PolicyError};
use serde::{Deserialize, Serialize};
// our type from before
#[derive(Deserialize, Serialize)]
struct MyCustomParameters {
intended_party: String,
}
impl Checkable for MyCustomParameters {
fn check<P: Policy>(self, policy: P) -> Result<Checked<Self, P>, (Self, P::Error)> {
if self.intended_party.is_ascii() {
Ok(Checked::new(self, policy))
} else {
Err((
self,
<P::Error as PolicyError>::custom(
"`intended_party` parameter must contain ascii characters only",
),
))
}
}
}
Implementations§
Source§impl JsonWebKey<()>
impl JsonWebKey<()>
Sourcepub fn builder(key_type: impl Into<JsonWebKeyType>) -> JsonWebKeyBuilder<()>
pub fn builder(key_type: impl Into<JsonWebKeyType>) -> JsonWebKeyBuilder<()>
Create a JsonWebKeyBuilder
to construct a new JWK.
Source§impl<T> JsonWebKey<T>
impl<T> JsonWebKey<T>
Sourcepub fn into_builder(self) -> JsonWebKeyBuilder<T>
pub fn into_builder(self) -> JsonWebKeyBuilder<T>
Turn this Json Web Key into a builder to modify it’s contents.
Sourcepub fn key_type(&self) -> &JsonWebKeyType
pub fn key_type(&self) -> &JsonWebKeyType
Section 4.1 of RFC 7517 defines the kty
(Key Type) Parameter.
Since the kty
parameter is used to distinguish different key types, we
use the JsonWebKeyType
to also store key specific data. You can
match the JsonWebKeyType
to determine the exact key type used.
Sourcepub fn key_usage(&self) -> Option<&KeyUsage>
pub fn key_usage(&self) -> Option<&KeyUsage>
Section 4.2 of RFC 7517 defines the use
(Public Key Use) Parameter.
See the documentation of KeyUsage
for details.
Sourcepub fn key_operations(&self) -> Option<&HashSet<KeyOperation>>
pub fn key_operations(&self) -> Option<&HashSet<KeyOperation>>
Section 4.3 of RFC 7517 defines the key_ops
(Key Operations)
Parameter.
It is a set of different operations a key may perform.
See the documentation of KeyOperation
for details.
Sourcepub fn algorithm(&self) -> Option<&JsonWebAlgorithm>
pub fn algorithm(&self) -> Option<&JsonWebAlgorithm>
Section 4.4 of RFC 7517 defines the alg
(Algorithm) Parameter.
See the documentation of JsonWebAlgorithm
for details.
Sourcepub fn key_id(&self) -> Option<&str>
pub fn key_id(&self) -> Option<&str>
Section 4.5 of RFC 7517 defines the kid
(Key ID) Parameter.
Sourcepub fn x509_url(&self) -> Option<BorrowedUri<'_>>
pub fn x509_url(&self) -> Option<BorrowedUri<'_>>
Section 4.6 of RFC 7517 defines the x5u
(X.509 URL) Parameter.
Sourcepub fn x509_certificate_chain(&self) -> impl ExactSizeIterator<Item = &[u8]>
pub fn x509_certificate_chain(&self) -> impl ExactSizeIterator<Item = &[u8]>
Section 4.7 of RFC 7517 defines the x5c
(X.509 Certificate Chain)
Parameter.
This parameter is a list of X.509 certificates. The first certificate in
the ExactSizeIterator
returned by this method is the PKIX
certificate containing the key value as required by the RFC. Note
that this parameter is OPTIONAL and if not present, this
ExactSizeIterator
will be empty (next
will be
None
and len
will be 0
).
Each Item
will be the byte representation of a
DER-encoded X.509 certificate.
Sourcepub fn x509_certificate_sha1_thumbprint(&self) -> Option<&[u8; 20]>
pub fn x509_certificate_sha1_thumbprint(&self) -> Option<&[u8; 20]>
Section 4.8 of RFC 7517 defines the x5t
(X.509 Certificate SHA-1
Thumbprint) Parameter.
It is the SHA-1 hash of the DER-encoded X.509 certificate.
§Warning: Cryptographically broken!
TL;DR: check if you can use the SHA-256 thumbprint instead.
The following text is taken from the sha1
crate:
The SHA-1 hash function should be considered cryptographically broken
and unsuitable for further use in any security critical capacity, as it
is practically vulnerable to chosen-prefix collisions.
Sourcepub fn x509_certificate_sha256_thumbprint(&self) -> Option<&[u8; 32]>
pub fn x509_certificate_sha256_thumbprint(&self) -> Option<&[u8; 32]>
Section 4.9 of RFC 7517 defines the x5t#S256
(X.509 Certificate
SHA-256 Thumbprint) Parameter.
It is the SHA-256 hash of the DER-encoded X.509 certificate.
Sourcepub fn additional(&self) -> &T
pub fn additional(&self) -> &T
Additional members in the JsonWebKey
as permitted by the fourth
paragraph of section 4 in RFC 7517
Sourcepub fn is_symmetric(&self) -> bool
pub fn is_symmetric(&self) -> bool
Checks if this JsonWebKey
is a symmetric key.
Sourcepub fn is_asymmetric(&self) -> bool
pub fn is_asymmetric(&self) -> bool
Checks if this JsonWebKey
is an asymmetric key.
Sourcepub fn is_signing_key(&self) -> bool
pub fn is_signing_key(&self) -> bool
Checks if this JsonWebKey
can be used for signing.
For asymmetric keys, this method is equivalent to checking
if this key is a private key.
For symmetric keys, this always returns true
.
Sourcepub fn strip_secret_material(self) -> Option<Self>
pub fn strip_secret_material(self) -> Option<Self>
Strips the secret material from this JsonWebKey
.
After calling this method, the key can safely be shared as it only contains the public parts.
For symmetric keys, this method returns None
, as symmetric
keys will always hold the secret material.
Sourcepub fn into_verifying_key(self) -> Self
pub fn into_verifying_key(self) -> Self
Converts this JsonWebKey
into a JsonWebKey
that is only meant to
be uesd for verifying signatures.
For asymmetric keys, this operation is equivalent to converting a private key into it’s public key.
For symmetric keys, this operation is a no-op, as the secret material can not be removed from the key.
Source§impl<T: Serialize> JsonWebKey<T>
impl<T: Serialize> JsonWebKey<T>
Sourcepub fn into_untyped_additional(
self,
) -> Result<JsonWebKey<UntypedAdditionalProperties>, Error>
pub fn into_untyped_additional( self, ) -> Result<JsonWebKey<UntypedAdditionalProperties>, Error>
Converts this JsonWebKey
with custom additional parameters,
into a JsonWebKey
with untyped additional parameters.
§Errors
This function fails if the serialization of the additional parameters failed, or the serialization does not result in a JSON object.
Source§impl JsonWebKey<UntypedAdditionalProperties>
impl JsonWebKey<UntypedAdditionalProperties>
Sourcepub fn deserialize_additional<T: DeserializeOwned>(
self,
) -> Result<JsonWebKey<T>, Error>
pub fn deserialize_additional<T: DeserializeOwned>( self, ) -> Result<JsonWebKey<T>, Error>
Deserializes the additional members of this JsonWebKey
to the given type.
§Errors
The given type failed to be deserialized from the additional members.
Trait Implementations§
Source§impl<T> Checkable for JsonWebKey<T>where
T: Checkable,
impl<T> Checkable for JsonWebKey<T>where
T: Checkable,
Source§impl<A: Clone> Clone for JsonWebKey<A>
impl<A: Clone> Clone for JsonWebKey<A>
Source§fn clone(&self) -> JsonWebKey<A>
fn clone(&self) -> JsonWebKey<A>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<A: Debug> Debug for JsonWebKey<A>
impl<A: Debug> Debug for JsonWebKey<A>
Source§impl<'de, A> Deserialize<'de> for JsonWebKey<A>where
A: Deserialize<'de>,
impl<'de, A> Deserialize<'de> for JsonWebKey<A>where
A: Deserialize<'de>,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Hash for JsonWebKey
The Hash
implementation of JsonWebKey
uses the Hash
implementation of the underlying
JsonWebKeyType
.
impl Hash for JsonWebKey
The Hash
implementation of JsonWebKey
uses the Hash
implementation of the underlying
JsonWebKeyType
.
Note: Hash
and Thumbprint
are used
differently. A Thumbprint
does does distinguish
between a private and a public key. But the Hash
implementation of
all JsonWebKey
s does, because otherwise two different versions of
JsonWebKey
with different capabilities would have the same hash.