You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-28 11:02:02 +03:00
Add variants for unknown values on mas-iana types
Remove the Copy derive and mark enums as non-exhaustive.
This commit is contained in:
committed by
Quentin Gliech
parent
9e3b3567b2
commit
80d317f23c
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2519,7 +2519,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"parse-display",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_with",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -92,7 +92,7 @@ impl Credentials {
|
||||
pub async fn verify<S: StorageBackend>(
|
||||
&self,
|
||||
encrypter: &Encrypter,
|
||||
method: OAuthClientAuthenticationMethod,
|
||||
method: &OAuthClientAuthenticationMethod,
|
||||
client: &Client<S>,
|
||||
) -> Result<(), CredentialsVerificationError> {
|
||||
match (self, method) {
|
||||
|
@ -162,7 +162,7 @@ pub(crate) async fn post(
|
||||
|
||||
let client = client_authorization.credentials.fetch(&mut conn).await?;
|
||||
|
||||
let method = match client.token_endpoint_auth_method {
|
||||
let method = match &client.token_endpoint_auth_method {
|
||||
None | Some(OAuthClientAuthenticationMethod::None) => {
|
||||
return Err(RouteError::NotAllowed);
|
||||
}
|
||||
|
@ -151,10 +151,10 @@ pub(crate) async fn post(
|
||||
metadata.tos_uri.as_ref().map(Localized::non_localized),
|
||||
metadata.jwks_uri.as_ref(),
|
||||
metadata.jwks.as_ref(),
|
||||
metadata.id_token_signed_response_alg,
|
||||
metadata.userinfo_signed_response_alg,
|
||||
metadata.token_endpoint_auth_method,
|
||||
metadata.token_endpoint_auth_signing_alg,
|
||||
metadata.id_token_signed_response_alg.as_ref(),
|
||||
metadata.userinfo_signed_response_alg.as_ref(),
|
||||
metadata.token_endpoint_auth_method.as_ref(),
|
||||
metadata.token_endpoint_auth_signing_alg.as_ref(),
|
||||
metadata.initiate_login_uri.as_ref(),
|
||||
)
|
||||
.await?;
|
||||
|
@ -198,6 +198,7 @@ pub(crate) async fn post(
|
||||
|
||||
let method = client
|
||||
.token_endpoint_auth_method
|
||||
.as_ref()
|
||||
.ok_or(RouteError::ClientNotAllowed)?;
|
||||
|
||||
client_authorization
|
||||
@ -333,17 +334,18 @@ async fn authorization_code_grant(
|
||||
|
||||
let alg = client
|
||||
.id_token_signed_response_alg
|
||||
.clone()
|
||||
.unwrap_or(JsonWebSignatureAlg::Rs256);
|
||||
let key = key_store
|
||||
.signing_key_for_algorithm(alg)
|
||||
.signing_key_for_algorithm(&alg)
|
||||
.context("no suitable key found")?;
|
||||
|
||||
claims::AT_HASH.insert(&mut claims, hash_token(alg, &access_token_str)?)?;
|
||||
claims::C_HASH.insert(&mut claims, hash_token(alg, &grant.code)?)?;
|
||||
claims::AT_HASH.insert(&mut claims, hash_token(&alg, &access_token_str)?)?;
|
||||
claims::C_HASH.insert(&mut claims, hash_token(&alg, &grant.code)?)?;
|
||||
|
||||
let signer = key.params().signing_key_for_alg(&alg)?;
|
||||
let header = JsonWebSignatureHeader::new(alg)
|
||||
.with_kid(key.kid().context("key has no `kid` for some reason")?);
|
||||
let signer = key.params().signing_key_for_alg(alg)?;
|
||||
let id_token = Jwt::sign(header, claims, &signer)?;
|
||||
|
||||
Some(id_token.as_str().to_owned())
|
||||
|
@ -75,12 +75,12 @@ pub async fn get(
|
||||
|
||||
if let Some(alg) = session.client.userinfo_signed_response_alg {
|
||||
let key = key_store
|
||||
.signing_key_for_algorithm(alg)
|
||||
.signing_key_for_algorithm(&alg)
|
||||
.context("no suitable key found")?;
|
||||
|
||||
let signer = key.params().signing_key_for_alg(&alg)?;
|
||||
let header = JsonWebSignatureHeader::new(alg)
|
||||
.with_kid(key.kid().context("key has no `kid` for some reason")?);
|
||||
let signer = key.params().signing_key_for_alg(alg)?;
|
||||
|
||||
let user_info = SignedUserInfo {
|
||||
iss: url_builder.oidc_issuer().to_string(),
|
||||
|
@ -105,7 +105,7 @@ impl Display for File {
|
||||
|
||||
use parse_display::{{Display, FromStr}};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{{Deserialize, Serialize}};"#,
|
||||
use serde_with::{{DeserializeFromStr, SerializeDisplay}};"#,
|
||||
self.registry_name, self.registry_url,
|
||||
)?;
|
||||
|
||||
@ -116,6 +116,14 @@ use serde::{{Deserialize, Serialize}};"#,
|
||||
continue;
|
||||
};
|
||||
|
||||
let is_exhaustive = section.key == "OAuthAuthorizationEndpointResponseType";
|
||||
|
||||
let non_exhaustive_attr = if is_exhaustive {
|
||||
""
|
||||
} else {
|
||||
"\n#[non_exhaustive]"
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
r#"
|
||||
@ -125,7 +133,6 @@ use serde::{{Deserialize, Serialize}};"#,
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -133,13 +140,14 @@ use serde::{{Deserialize, Serialize}};"#,
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
)]{}
|
||||
pub enum {} {{"#,
|
||||
section.doc,
|
||||
section.url.unwrap(),
|
||||
non_exhaustive_attr,
|
||||
section.key,
|
||||
)?;
|
||||
for member in list {
|
||||
@ -149,10 +157,20 @@ pub enum {} {{"#,
|
||||
} else {
|
||||
writeln!(f, " /// `{}`", member.value)?;
|
||||
}
|
||||
writeln!(f, " #[serde(rename = \"{}\")]", member.value)?;
|
||||
writeln!(f, " #[schemars(rename = \"{}\")]", member.value)?;
|
||||
writeln!(f, " #[display(\"{}\")]", member.value)?;
|
||||
writeln!(f, " {},", member.enum_name)?;
|
||||
}
|
||||
|
||||
if !is_exhaustive {
|
||||
// Add a variant for custom enums
|
||||
writeln!(f)?;
|
||||
writeln!(f, " /// An unknown value.")?;
|
||||
writeln!(f, " #[display(\"{{0}}\")]")?;
|
||||
writeln!(f, " #[schemars(skip)]")?;
|
||||
writeln!(f, " Unknown(String),")?;
|
||||
}
|
||||
|
||||
writeln!(f, "}}")?;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,6 @@ edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
serde = "1.0.145"
|
||||
serde_with = "2.0.0"
|
||||
schemars = "0.8.10"
|
||||
parse-display = "0.6.0"
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
use parse_display::{Display, FromStr};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
|
||||
/// JSON Web Signature "alg" parameter
|
||||
///
|
||||
@ -27,7 +27,6 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -35,85 +34,91 @@ use serde::{Deserialize, Serialize};
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebSignatureAlg {
|
||||
/// HMAC using SHA-256
|
||||
#[serde(rename = "HS256")]
|
||||
#[schemars(rename = "HS256")]
|
||||
#[display("HS256")]
|
||||
Hs256,
|
||||
|
||||
/// HMAC using SHA-384
|
||||
#[serde(rename = "HS384")]
|
||||
#[schemars(rename = "HS384")]
|
||||
#[display("HS384")]
|
||||
Hs384,
|
||||
|
||||
/// HMAC using SHA-512
|
||||
#[serde(rename = "HS512")]
|
||||
#[schemars(rename = "HS512")]
|
||||
#[display("HS512")]
|
||||
Hs512,
|
||||
|
||||
/// RSASSA-PKCS1-v1_5 using SHA-256
|
||||
#[serde(rename = "RS256")]
|
||||
#[schemars(rename = "RS256")]
|
||||
#[display("RS256")]
|
||||
Rs256,
|
||||
|
||||
/// RSASSA-PKCS1-v1_5 using SHA-384
|
||||
#[serde(rename = "RS384")]
|
||||
#[schemars(rename = "RS384")]
|
||||
#[display("RS384")]
|
||||
Rs384,
|
||||
|
||||
/// RSASSA-PKCS1-v1_5 using SHA-512
|
||||
#[serde(rename = "RS512")]
|
||||
#[schemars(rename = "RS512")]
|
||||
#[display("RS512")]
|
||||
Rs512,
|
||||
|
||||
/// ECDSA using P-256 and SHA-256
|
||||
#[serde(rename = "ES256")]
|
||||
#[schemars(rename = "ES256")]
|
||||
#[display("ES256")]
|
||||
Es256,
|
||||
|
||||
/// ECDSA using P-384 and SHA-384
|
||||
#[serde(rename = "ES384")]
|
||||
#[schemars(rename = "ES384")]
|
||||
#[display("ES384")]
|
||||
Es384,
|
||||
|
||||
/// ECDSA using P-521 and SHA-512
|
||||
#[serde(rename = "ES512")]
|
||||
#[schemars(rename = "ES512")]
|
||||
#[display("ES512")]
|
||||
Es512,
|
||||
|
||||
/// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
|
||||
#[serde(rename = "PS256")]
|
||||
#[schemars(rename = "PS256")]
|
||||
#[display("PS256")]
|
||||
Ps256,
|
||||
|
||||
/// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
|
||||
#[serde(rename = "PS384")]
|
||||
#[schemars(rename = "PS384")]
|
||||
#[display("PS384")]
|
||||
Ps384,
|
||||
|
||||
/// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
|
||||
#[serde(rename = "PS512")]
|
||||
#[schemars(rename = "PS512")]
|
||||
#[display("PS512")]
|
||||
Ps512,
|
||||
|
||||
/// No digital signature or MAC performed
|
||||
#[serde(rename = "none")]
|
||||
#[schemars(rename = "none")]
|
||||
#[display("none")]
|
||||
None,
|
||||
|
||||
/// EdDSA signature algorithms
|
||||
#[serde(rename = "EdDSA")]
|
||||
#[schemars(rename = "EdDSA")]
|
||||
#[display("EdDSA")]
|
||||
EdDsa,
|
||||
|
||||
/// ECDSA using secp256k1 curve and SHA-256
|
||||
#[serde(rename = "ES256K")]
|
||||
#[schemars(rename = "ES256K")]
|
||||
#[display("ES256K")]
|
||||
Es256K,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Encryption "alg" parameter
|
||||
@ -122,7 +127,6 @@ pub enum JsonWebSignatureAlg {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -130,105 +134,111 @@ pub enum JsonWebSignatureAlg {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebEncryptionAlg {
|
||||
/// RSAES-PKCS1-v1_5
|
||||
#[serde(rename = "RSA1_5")]
|
||||
#[schemars(rename = "RSA1_5")]
|
||||
#[display("RSA1_5")]
|
||||
Rsa15,
|
||||
|
||||
/// RSAES OAEP using default parameters
|
||||
#[serde(rename = "RSA-OAEP")]
|
||||
#[schemars(rename = "RSA-OAEP")]
|
||||
#[display("RSA-OAEP")]
|
||||
RsaOaep,
|
||||
|
||||
/// RSAES OAEP using SHA-256 and MGF1 with SHA-256
|
||||
#[serde(rename = "RSA-OAEP-256")]
|
||||
#[schemars(rename = "RSA-OAEP-256")]
|
||||
#[display("RSA-OAEP-256")]
|
||||
RsaOaep256,
|
||||
|
||||
/// AES Key Wrap using 128-bit key
|
||||
#[serde(rename = "A128KW")]
|
||||
#[schemars(rename = "A128KW")]
|
||||
#[display("A128KW")]
|
||||
A128Kw,
|
||||
|
||||
/// AES Key Wrap using 192-bit key
|
||||
#[serde(rename = "A192KW")]
|
||||
#[schemars(rename = "A192KW")]
|
||||
#[display("A192KW")]
|
||||
A192Kw,
|
||||
|
||||
/// AES Key Wrap using 256-bit key
|
||||
#[serde(rename = "A256KW")]
|
||||
#[schemars(rename = "A256KW")]
|
||||
#[display("A256KW")]
|
||||
A256Kw,
|
||||
|
||||
/// Direct use of a shared symmetric key
|
||||
#[serde(rename = "dir")]
|
||||
#[schemars(rename = "dir")]
|
||||
#[display("dir")]
|
||||
Dir,
|
||||
|
||||
/// ECDH-ES using Concat KDF
|
||||
#[serde(rename = "ECDH-ES")]
|
||||
#[schemars(rename = "ECDH-ES")]
|
||||
#[display("ECDH-ES")]
|
||||
EcdhEs,
|
||||
|
||||
/// ECDH-ES using Concat KDF and "A128KW" wrapping
|
||||
#[serde(rename = "ECDH-ES+A128KW")]
|
||||
#[schemars(rename = "ECDH-ES+A128KW")]
|
||||
#[display("ECDH-ES+A128KW")]
|
||||
EcdhEsA128Kw,
|
||||
|
||||
/// ECDH-ES using Concat KDF and "A192KW" wrapping
|
||||
#[serde(rename = "ECDH-ES+A192KW")]
|
||||
#[schemars(rename = "ECDH-ES+A192KW")]
|
||||
#[display("ECDH-ES+A192KW")]
|
||||
EcdhEsA192Kw,
|
||||
|
||||
/// ECDH-ES using Concat KDF and "A256KW" wrapping
|
||||
#[serde(rename = "ECDH-ES+A256KW")]
|
||||
#[schemars(rename = "ECDH-ES+A256KW")]
|
||||
#[display("ECDH-ES+A256KW")]
|
||||
EcdhEsA256Kw,
|
||||
|
||||
/// Key wrapping with AES GCM using 128-bit key
|
||||
#[serde(rename = "A128GCMKW")]
|
||||
#[schemars(rename = "A128GCMKW")]
|
||||
#[display("A128GCMKW")]
|
||||
A128Gcmkw,
|
||||
|
||||
/// Key wrapping with AES GCM using 192-bit key
|
||||
#[serde(rename = "A192GCMKW")]
|
||||
#[schemars(rename = "A192GCMKW")]
|
||||
#[display("A192GCMKW")]
|
||||
A192Gcmkw,
|
||||
|
||||
/// Key wrapping with AES GCM using 256-bit key
|
||||
#[serde(rename = "A256GCMKW")]
|
||||
#[schemars(rename = "A256GCMKW")]
|
||||
#[display("A256GCMKW")]
|
||||
A256Gcmkw,
|
||||
|
||||
/// PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
||||
#[serde(rename = "PBES2-HS256+A128KW")]
|
||||
#[schemars(rename = "PBES2-HS256+A128KW")]
|
||||
#[display("PBES2-HS256+A128KW")]
|
||||
Pbes2Hs256A128Kw,
|
||||
|
||||
/// PBES2 with HMAC SHA-384 and "A192KW" wrapping
|
||||
#[serde(rename = "PBES2-HS384+A192KW")]
|
||||
#[schemars(rename = "PBES2-HS384+A192KW")]
|
||||
#[display("PBES2-HS384+A192KW")]
|
||||
Pbes2Hs384A192Kw,
|
||||
|
||||
/// PBES2 with HMAC SHA-512 and "A256KW" wrapping
|
||||
#[serde(rename = "PBES2-HS512+A256KW")]
|
||||
#[schemars(rename = "PBES2-HS512+A256KW")]
|
||||
#[display("PBES2-HS512+A256KW")]
|
||||
Pbes2Hs512A256Kw,
|
||||
|
||||
/// RSA-OAEP using SHA-384 and MGF1 with SHA-384
|
||||
#[serde(rename = "RSA-OAEP-384")]
|
||||
#[schemars(rename = "RSA-OAEP-384")]
|
||||
#[display("RSA-OAEP-384")]
|
||||
RsaOaep384,
|
||||
|
||||
/// RSA-OAEP using SHA-512 and MGF1 with SHA-512
|
||||
#[serde(rename = "RSA-OAEP-512")]
|
||||
#[schemars(rename = "RSA-OAEP-512")]
|
||||
#[display("RSA-OAEP-512")]
|
||||
RsaOaep512,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Encryption "enc" parameter
|
||||
@ -237,7 +247,6 @@ pub enum JsonWebEncryptionAlg {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -245,40 +254,46 @@ pub enum JsonWebEncryptionAlg {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebEncryptionEnc {
|
||||
/// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm
|
||||
#[serde(rename = "A128CBC-HS256")]
|
||||
#[schemars(rename = "A128CBC-HS256")]
|
||||
#[display("A128CBC-HS256")]
|
||||
A128CbcHs256,
|
||||
|
||||
/// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm
|
||||
#[serde(rename = "A192CBC-HS384")]
|
||||
#[schemars(rename = "A192CBC-HS384")]
|
||||
#[display("A192CBC-HS384")]
|
||||
A192CbcHs384,
|
||||
|
||||
/// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm
|
||||
#[serde(rename = "A256CBC-HS512")]
|
||||
#[schemars(rename = "A256CBC-HS512")]
|
||||
#[display("A256CBC-HS512")]
|
||||
A256CbcHs512,
|
||||
|
||||
/// AES GCM using 128-bit key
|
||||
#[serde(rename = "A128GCM")]
|
||||
#[schemars(rename = "A128GCM")]
|
||||
#[display("A128GCM")]
|
||||
A128Gcm,
|
||||
|
||||
/// AES GCM using 192-bit key
|
||||
#[serde(rename = "A192GCM")]
|
||||
#[schemars(rename = "A192GCM")]
|
||||
#[display("A192GCM")]
|
||||
A192Gcm,
|
||||
|
||||
/// AES GCM using 256-bit key
|
||||
#[serde(rename = "A256GCM")]
|
||||
#[schemars(rename = "A256GCM")]
|
||||
#[display("A256GCM")]
|
||||
A256Gcm,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Encryption Compression Algorithm
|
||||
@ -287,7 +302,6 @@ pub enum JsonWebEncryptionEnc {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -295,15 +309,21 @@ pub enum JsonWebEncryptionEnc {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebEncryptionCompressionAlgorithm {
|
||||
/// DEFLATE
|
||||
#[serde(rename = "DEF")]
|
||||
#[schemars(rename = "DEF")]
|
||||
#[display("DEF")]
|
||||
Def,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Key Type
|
||||
@ -312,7 +332,6 @@ pub enum JsonWebEncryptionCompressionAlgorithm {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -320,30 +339,36 @@ pub enum JsonWebEncryptionCompressionAlgorithm {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebKeyType {
|
||||
/// Elliptic Curve
|
||||
#[serde(rename = "EC")]
|
||||
#[schemars(rename = "EC")]
|
||||
#[display("EC")]
|
||||
Ec,
|
||||
|
||||
/// RSA
|
||||
#[serde(rename = "RSA")]
|
||||
#[schemars(rename = "RSA")]
|
||||
#[display("RSA")]
|
||||
Rsa,
|
||||
|
||||
/// Octet sequence
|
||||
#[serde(rename = "oct")]
|
||||
#[schemars(rename = "oct")]
|
||||
#[display("oct")]
|
||||
Oct,
|
||||
|
||||
/// Octet string key pairs
|
||||
#[serde(rename = "OKP")]
|
||||
#[schemars(rename = "OKP")]
|
||||
#[display("OKP")]
|
||||
Okp,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Key EC Elliptic Curve
|
||||
@ -352,7 +377,6 @@ pub enum JsonWebKeyType {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -360,30 +384,36 @@ pub enum JsonWebKeyType {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebKeyEcEllipticCurve {
|
||||
/// P-256 Curve
|
||||
#[serde(rename = "P-256")]
|
||||
#[schemars(rename = "P-256")]
|
||||
#[display("P-256")]
|
||||
P256,
|
||||
|
||||
/// P-384 Curve
|
||||
#[serde(rename = "P-384")]
|
||||
#[schemars(rename = "P-384")]
|
||||
#[display("P-384")]
|
||||
P384,
|
||||
|
||||
/// P-521 Curve
|
||||
#[serde(rename = "P-521")]
|
||||
#[schemars(rename = "P-521")]
|
||||
#[display("P-521")]
|
||||
P521,
|
||||
|
||||
/// SECG secp256k1 curve
|
||||
#[serde(rename = "secp256k1")]
|
||||
#[schemars(rename = "secp256k1")]
|
||||
#[display("secp256k1")]
|
||||
Secp256K1,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Key OKP Elliptic Curve
|
||||
@ -392,7 +422,6 @@ pub enum JsonWebKeyEcEllipticCurve {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -400,30 +429,36 @@ pub enum JsonWebKeyEcEllipticCurve {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebKeyOkpEllipticCurve {
|
||||
/// Ed25519 signature algorithm key pairs
|
||||
#[serde(rename = "Ed25519")]
|
||||
#[schemars(rename = "Ed25519")]
|
||||
#[display("Ed25519")]
|
||||
Ed25519,
|
||||
|
||||
/// Ed448 signature algorithm key pairs
|
||||
#[serde(rename = "Ed448")]
|
||||
#[schemars(rename = "Ed448")]
|
||||
#[display("Ed448")]
|
||||
Ed448,
|
||||
|
||||
/// X25519 function key pairs
|
||||
#[serde(rename = "X25519")]
|
||||
#[schemars(rename = "X25519")]
|
||||
#[display("X25519")]
|
||||
X25519,
|
||||
|
||||
/// X448 function key pairs
|
||||
#[serde(rename = "X448")]
|
||||
#[schemars(rename = "X448")]
|
||||
#[display("X448")]
|
||||
X448,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Key Use
|
||||
@ -432,7 +467,6 @@ pub enum JsonWebKeyOkpEllipticCurve {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -440,20 +474,26 @@ pub enum JsonWebKeyOkpEllipticCurve {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebKeyUse {
|
||||
/// Digital Signature or MAC
|
||||
#[serde(rename = "sig")]
|
||||
#[schemars(rename = "sig")]
|
||||
#[display("sig")]
|
||||
Sig,
|
||||
|
||||
/// Encryption
|
||||
#[serde(rename = "enc")]
|
||||
#[schemars(rename = "enc")]
|
||||
#[display("enc")]
|
||||
Enc,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// JSON Web Key Operation
|
||||
@ -462,7 +502,6 @@ pub enum JsonWebKeyUse {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -470,48 +509,54 @@ pub enum JsonWebKeyUse {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonWebKeyOperation {
|
||||
/// Compute digital signature or MAC
|
||||
#[serde(rename = "sign")]
|
||||
#[schemars(rename = "sign")]
|
||||
#[display("sign")]
|
||||
Sign,
|
||||
|
||||
/// Verify digital signature or MAC
|
||||
#[serde(rename = "verify")]
|
||||
#[schemars(rename = "verify")]
|
||||
#[display("verify")]
|
||||
Verify,
|
||||
|
||||
/// Encrypt content
|
||||
#[serde(rename = "encrypt")]
|
||||
#[schemars(rename = "encrypt")]
|
||||
#[display("encrypt")]
|
||||
Encrypt,
|
||||
|
||||
/// Decrypt content and validate decryption, if applicable
|
||||
#[serde(rename = "decrypt")]
|
||||
#[schemars(rename = "decrypt")]
|
||||
#[display("decrypt")]
|
||||
Decrypt,
|
||||
|
||||
/// Encrypt key
|
||||
#[serde(rename = "wrapKey")]
|
||||
#[schemars(rename = "wrapKey")]
|
||||
#[display("wrapKey")]
|
||||
WrapKey,
|
||||
|
||||
/// Decrypt key and validate decryption, if applicable
|
||||
#[serde(rename = "unwrapKey")]
|
||||
#[schemars(rename = "unwrapKey")]
|
||||
#[display("unwrapKey")]
|
||||
UnwrapKey,
|
||||
|
||||
/// Derive key
|
||||
#[serde(rename = "deriveKey")]
|
||||
#[schemars(rename = "deriveKey")]
|
||||
#[display("deriveKey")]
|
||||
DeriveKey,
|
||||
|
||||
/// Derive bits not to be used as a key
|
||||
#[serde(rename = "deriveBits")]
|
||||
#[schemars(rename = "deriveBits")]
|
||||
#[display("deriveBits")]
|
||||
DeriveBits,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
use parse_display::{Display, FromStr};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
|
||||
/// OAuth Access Token Type
|
||||
///
|
||||
@ -27,7 +27,6 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -35,25 +34,31 @@ use serde::{Deserialize, Serialize};
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum OAuthAccessTokenType {
|
||||
/// `Bearer`
|
||||
#[serde(rename = "Bearer")]
|
||||
#[schemars(rename = "Bearer")]
|
||||
#[display("Bearer")]
|
||||
Bearer,
|
||||
|
||||
/// `N_A`
|
||||
#[serde(rename = "N_A")]
|
||||
#[schemars(rename = "N_A")]
|
||||
#[display("N_A")]
|
||||
Na,
|
||||
|
||||
/// `PoP`
|
||||
#[serde(rename = "PoP")]
|
||||
#[schemars(rename = "PoP")]
|
||||
#[display("PoP")]
|
||||
PoP,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// OAuth Authorization Endpoint Response Type
|
||||
@ -62,7 +67,6 @@ pub enum OAuthAccessTokenType {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -70,48 +74,48 @@ pub enum OAuthAccessTokenType {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
pub enum OAuthAuthorizationEndpointResponseType {
|
||||
/// `code`
|
||||
#[serde(rename = "code")]
|
||||
#[schemars(rename = "code")]
|
||||
#[display("code")]
|
||||
Code,
|
||||
|
||||
/// `code id_token`
|
||||
#[serde(rename = "code id_token")]
|
||||
#[schemars(rename = "code id_token")]
|
||||
#[display("code id_token")]
|
||||
CodeIdToken,
|
||||
|
||||
/// `code id_token token`
|
||||
#[serde(rename = "code id_token token")]
|
||||
#[schemars(rename = "code id_token token")]
|
||||
#[display("code id_token token")]
|
||||
CodeIdTokenToken,
|
||||
|
||||
/// `code token`
|
||||
#[serde(rename = "code token")]
|
||||
#[schemars(rename = "code token")]
|
||||
#[display("code token")]
|
||||
CodeToken,
|
||||
|
||||
/// `id_token`
|
||||
#[serde(rename = "id_token")]
|
||||
#[schemars(rename = "id_token")]
|
||||
#[display("id_token")]
|
||||
IdToken,
|
||||
|
||||
/// `id_token token`
|
||||
#[serde(rename = "id_token token")]
|
||||
#[schemars(rename = "id_token token")]
|
||||
#[display("id_token token")]
|
||||
IdTokenToken,
|
||||
|
||||
/// `none`
|
||||
#[serde(rename = "none")]
|
||||
#[schemars(rename = "none")]
|
||||
#[display("none")]
|
||||
None,
|
||||
|
||||
/// `token`
|
||||
#[serde(rename = "token")]
|
||||
#[schemars(rename = "token")]
|
||||
#[display("token")]
|
||||
Token,
|
||||
}
|
||||
@ -122,7 +126,6 @@ pub enum OAuthAuthorizationEndpointResponseType {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -130,25 +133,31 @@ pub enum OAuthAuthorizationEndpointResponseType {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum OAuthTokenTypeHint {
|
||||
/// `access_token`
|
||||
#[serde(rename = "access_token")]
|
||||
#[schemars(rename = "access_token")]
|
||||
#[display("access_token")]
|
||||
AccessToken,
|
||||
|
||||
/// `refresh_token`
|
||||
#[serde(rename = "refresh_token")]
|
||||
#[schemars(rename = "refresh_token")]
|
||||
#[display("refresh_token")]
|
||||
RefreshToken,
|
||||
|
||||
/// `pct`
|
||||
#[serde(rename = "pct")]
|
||||
#[schemars(rename = "pct")]
|
||||
#[display("pct")]
|
||||
Pct,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// OAuth Token Endpoint Authentication Method
|
||||
@ -157,7 +166,6 @@ pub enum OAuthTokenTypeHint {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -165,45 +173,51 @@ pub enum OAuthTokenTypeHint {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum OAuthClientAuthenticationMethod {
|
||||
/// `none`
|
||||
#[serde(rename = "none")]
|
||||
#[schemars(rename = "none")]
|
||||
#[display("none")]
|
||||
None,
|
||||
|
||||
/// `client_secret_post`
|
||||
#[serde(rename = "client_secret_post")]
|
||||
#[schemars(rename = "client_secret_post")]
|
||||
#[display("client_secret_post")]
|
||||
ClientSecretPost,
|
||||
|
||||
/// `client_secret_basic`
|
||||
#[serde(rename = "client_secret_basic")]
|
||||
#[schemars(rename = "client_secret_basic")]
|
||||
#[display("client_secret_basic")]
|
||||
ClientSecretBasic,
|
||||
|
||||
/// `client_secret_jwt`
|
||||
#[serde(rename = "client_secret_jwt")]
|
||||
#[schemars(rename = "client_secret_jwt")]
|
||||
#[display("client_secret_jwt")]
|
||||
ClientSecretJwt,
|
||||
|
||||
/// `private_key_jwt`
|
||||
#[serde(rename = "private_key_jwt")]
|
||||
#[schemars(rename = "private_key_jwt")]
|
||||
#[display("private_key_jwt")]
|
||||
PrivateKeyJwt,
|
||||
|
||||
/// `tls_client_auth`
|
||||
#[serde(rename = "tls_client_auth")]
|
||||
#[schemars(rename = "tls_client_auth")]
|
||||
#[display("tls_client_auth")]
|
||||
TlsClientAuth,
|
||||
|
||||
/// `self_signed_tls_client_auth`
|
||||
#[serde(rename = "self_signed_tls_client_auth")]
|
||||
#[schemars(rename = "self_signed_tls_client_auth")]
|
||||
#[display("self_signed_tls_client_auth")]
|
||||
SelfSignedTlsClientAuth,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
/// PKCE Code Challenge Method
|
||||
@ -212,7 +226,6 @@ pub enum OAuthClientAuthenticationMethod {
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
@ -220,18 +233,24 @@ pub enum OAuthClientAuthenticationMethod {
|
||||
Hash,
|
||||
Display,
|
||||
FromStr,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
SerializeDisplay,
|
||||
DeserializeFromStr,
|
||||
JsonSchema,
|
||||
)]
|
||||
#[non_exhaustive]
|
||||
pub enum PkceCodeChallengeMethod {
|
||||
/// `plain`
|
||||
#[serde(rename = "plain")]
|
||||
#[schemars(rename = "plain")]
|
||||
#[display("plain")]
|
||||
Plain,
|
||||
|
||||
/// `S256`
|
||||
#[serde(rename = "S256")]
|
||||
#[schemars(rename = "S256")]
|
||||
#[display("S256")]
|
||||
S256,
|
||||
|
||||
/// An unknown value.
|
||||
#[display("{0}")]
|
||||
#[schemars(skip)]
|
||||
Unknown(String),
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ impl From<&TimeOptions> for TimeNotBefore {
|
||||
/// Returns an error if the algorithm is not supported.
|
||||
///
|
||||
/// [OpenID Connect Core 1.0 specification]: https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken
|
||||
pub fn hash_token(alg: JsonWebSignatureAlg, token: &str) -> anyhow::Result<String> {
|
||||
pub fn hash_token(alg: &JsonWebSignatureAlg, token: &str) -> anyhow::Result<String> {
|
||||
let bits = match alg {
|
||||
JsonWebSignatureAlg::Hs256
|
||||
| JsonWebSignatureAlg::Rs256
|
||||
@ -281,9 +281,7 @@ pub fn hash_token(alg: JsonWebSignatureAlg, token: &str) -> anyhow::Result<Strin
|
||||
// Left-most half
|
||||
hash.get(..32).map(ToOwned::to_owned)
|
||||
}
|
||||
JsonWebSignatureAlg::EdDsa | JsonWebSignatureAlg::None => {
|
||||
return Err(anyhow::anyhow!("unsupported algorithm for hashing"))
|
||||
}
|
||||
_ => return Err(anyhow::anyhow!("unsupported algorithm for hashing")),
|
||||
}
|
||||
.context("failed to get first half of hash")?;
|
||||
|
||||
@ -292,14 +290,14 @@ pub fn hash_token(alg: JsonWebSignatureAlg, token: &str) -> anyhow::Result<Strin
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TokenHash<'a> {
|
||||
alg: JsonWebSignatureAlg,
|
||||
alg: &'a JsonWebSignatureAlg,
|
||||
token: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> TokenHash<'a> {
|
||||
/// Creates a new `TokenHash` validator for the given algorithm and token.
|
||||
#[must_use]
|
||||
pub fn new(alg: JsonWebSignatureAlg, token: &'a str) -> Self {
|
||||
pub fn new(alg: &'a JsonWebSignatureAlg, token: &'a str) -> Self {
|
||||
Self { alg, token }
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use crate::jwt::JsonWebSignatureHeader;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Constraint<'a> {
|
||||
Alg {
|
||||
constraint_alg: JsonWebSignatureAlg,
|
||||
constraint_alg: &'a JsonWebSignatureAlg,
|
||||
},
|
||||
|
||||
Algs {
|
||||
@ -33,17 +33,17 @@ pub enum Constraint<'a> {
|
||||
},
|
||||
|
||||
Use {
|
||||
constraint_use: JsonWebKeyUse,
|
||||
constraint_use: &'a JsonWebKeyUse,
|
||||
},
|
||||
|
||||
Kty {
|
||||
constraint_kty: JsonWebKeyType,
|
||||
constraint_kty: &'a JsonWebKeyType,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> Constraint<'a> {
|
||||
#[must_use]
|
||||
pub fn alg(constraint_alg: JsonWebSignatureAlg) -> Self {
|
||||
pub fn alg(constraint_alg: &'a JsonWebSignatureAlg) -> Self {
|
||||
Constraint::Alg { constraint_alg }
|
||||
}
|
||||
|
||||
@ -58,12 +58,12 @@ impl<'a> Constraint<'a> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn use_(constraint_use: JsonWebKeyUse) -> Self {
|
||||
pub fn use_(constraint_use: &'a JsonWebKeyUse) -> Self {
|
||||
Constraint::Use { constraint_use }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn kty(constraint_kty: JsonWebKeyType) -> Self {
|
||||
pub fn kty(constraint_kty: &'a JsonWebKeyType) -> Self {
|
||||
Constraint::Kty { constraint_kty }
|
||||
}
|
||||
}
|
||||
@ -76,7 +76,7 @@ pub enum ConstraintDecision {
|
||||
}
|
||||
|
||||
pub trait Constrainable {
|
||||
fn alg(&self) -> Option<JsonWebSignatureAlg> {
|
||||
fn alg(&self) -> Option<&JsonWebSignatureAlg> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ pub trait Constrainable {
|
||||
}
|
||||
|
||||
/// Usage specified for this key
|
||||
fn use_(&self) -> Option<JsonWebKeyUse> {
|
||||
fn use_(&self) -> Option<&JsonWebKeyUse> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ impl<'a> Constraint<'a> {
|
||||
}
|
||||
Constraint::Algs { constraint_algs } => {
|
||||
if let Some(alg) = constrainable.alg() {
|
||||
if constraint_algs.contains(&alg) {
|
||||
if constraint_algs.contains(alg) {
|
||||
ConstraintDecision::Positive
|
||||
} else {
|
||||
ConstraintDecision::Negative
|
||||
@ -158,7 +158,7 @@ impl<'a> Constraint<'a> {
|
||||
}
|
||||
}
|
||||
Constraint::Kty { constraint_kty } => {
|
||||
if *constraint_kty == constrainable.kty() {
|
||||
if **constraint_kty == constrainable.kty() {
|
||||
ConstraintDecision::Positive
|
||||
} else {
|
||||
ConstraintDecision::Negative
|
||||
@ -217,7 +217,7 @@ impl<'a> ConstraintSet<'a> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn alg(mut self, constraint_alg: JsonWebSignatureAlg) -> Self {
|
||||
pub fn alg(mut self, constraint_alg: &'a JsonWebSignatureAlg) -> Self {
|
||||
self.constraints.insert(Constraint::alg(constraint_alg));
|
||||
self
|
||||
}
|
||||
@ -235,13 +235,13 @@ impl<'a> ConstraintSet<'a> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn use_(mut self, constraint_use: JsonWebKeyUse) -> Self {
|
||||
pub fn use_(mut self, constraint_use: &'a JsonWebKeyUse) -> Self {
|
||||
self.constraints.insert(Constraint::use_(constraint_use));
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn kty(mut self, constraint_kty: JsonWebKeyType) -> Self {
|
||||
pub fn kty(mut self, constraint_kty: &'a JsonWebKeyType) -> Self {
|
||||
self.constraints.insert(Constraint::kty(constraint_kty));
|
||||
self
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl AsymmetricSigningKey {
|
||||
#[allow(dead_code)]
|
||||
pub fn from_jwk_and_alg(
|
||||
params: &JsonWebKeyPrivateParameters,
|
||||
alg: JsonWebSignatureAlg,
|
||||
alg: &JsonWebSignatureAlg,
|
||||
) -> Result<Self, AsymmetricKeyFromJwkError> {
|
||||
match (params, alg) {
|
||||
(JsonWebKeyPrivateParameters::Rsa(params), alg) => match alg {
|
||||
@ -69,7 +69,7 @@ impl AsymmetricSigningKey {
|
||||
JsonWebSignatureAlg::Ps256 => Ok(Self::Ps256(params.try_into()?)),
|
||||
JsonWebSignatureAlg::Ps384 => Ok(Self::Ps384(params.try_into()?)),
|
||||
JsonWebSignatureAlg::Ps512 => Ok(Self::Ps512(params.try_into()?)),
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
|
||||
},
|
||||
|
||||
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es256)
|
||||
@ -87,7 +87,7 @@ impl AsymmetricSigningKey {
|
||||
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es512)
|
||||
if params.crv == JsonWebKeyEcEllipticCurve::P521 =>
|
||||
{
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
|
||||
}
|
||||
|
||||
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es256K)
|
||||
@ -97,10 +97,10 @@ impl AsymmetricSigningKey {
|
||||
}
|
||||
|
||||
(JsonWebKeyPrivateParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
|
||||
}
|
||||
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,7 +219,7 @@ pub enum AsymmetricVerifyingKey {
|
||||
impl AsymmetricVerifyingKey {
|
||||
pub fn from_jwk_and_alg(
|
||||
params: &JsonWebKeyPublicParameters,
|
||||
alg: JsonWebSignatureAlg,
|
||||
alg: &JsonWebSignatureAlg,
|
||||
) -> Result<Self, AsymmetricKeyFromJwkError> {
|
||||
match (params, alg) {
|
||||
(JsonWebKeyPublicParameters::Rsa(params), alg) => match alg {
|
||||
@ -229,7 +229,7 @@ impl AsymmetricVerifyingKey {
|
||||
JsonWebSignatureAlg::Ps256 => Ok(Self::Ps256(params.try_into()?)),
|
||||
JsonWebSignatureAlg::Ps384 => Ok(Self::Ps384(params.try_into()?)),
|
||||
JsonWebSignatureAlg::Ps512 => Ok(Self::Ps512(params.try_into()?)),
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
|
||||
},
|
||||
|
||||
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es256)
|
||||
@ -247,7 +247,7 @@ impl AsymmetricVerifyingKey {
|
||||
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es512)
|
||||
if params.crv == JsonWebKeyEcEllipticCurve::P521 =>
|
||||
{
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
|
||||
}
|
||||
|
||||
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es256K)
|
||||
@ -257,10 +257,10 @@ impl AsymmetricVerifyingKey {
|
||||
}
|
||||
|
||||
(JsonWebKeyPublicParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
|
||||
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
|
||||
}
|
||||
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
|
||||
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,15 +33,15 @@ pub struct InvalidAlgorithm {
|
||||
}
|
||||
|
||||
impl SymmetricKey {
|
||||
pub const fn new_for_alg(
|
||||
key: Vec<u8>,
|
||||
alg: JsonWebSignatureAlg,
|
||||
) -> Result<Self, InvalidAlgorithm> {
|
||||
pub fn new_for_alg(key: Vec<u8>, alg: &JsonWebSignatureAlg) -> Result<Self, InvalidAlgorithm> {
|
||||
match alg {
|
||||
JsonWebSignatureAlg::Hs256 => Ok(Self::hs256(key)),
|
||||
JsonWebSignatureAlg::Hs384 => Ok(Self::hs384(key)),
|
||||
JsonWebSignatureAlg::Hs512 => Ok(Self::hs512(key)),
|
||||
_ => Err(InvalidAlgorithm { alg, key }),
|
||||
_ => Err(InvalidAlgorithm {
|
||||
alg: alg.clone(),
|
||||
key,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,9 +166,9 @@ impl<P> JsonWebKey<P> {
|
||||
{
|
||||
Ok(JsonWebKey {
|
||||
parameters: mapper(&self.parameters)?,
|
||||
r#use: self.r#use,
|
||||
r#use: self.r#use.clone(),
|
||||
key_ops: self.key_ops.clone(),
|
||||
alg: self.alg,
|
||||
alg: self.alg.clone(),
|
||||
kid: self.kid.clone(),
|
||||
x5u: self.x5u.clone(),
|
||||
x5c: self.x5c.clone(),
|
||||
@ -183,9 +183,9 @@ impl<P> JsonWebKey<P> {
|
||||
{
|
||||
JsonWebKey {
|
||||
parameters: mapper(&self.parameters),
|
||||
r#use: self.r#use,
|
||||
r#use: self.r#use.clone(),
|
||||
key_ops: self.key_ops.clone(),
|
||||
alg: self.alg,
|
||||
alg: self.alg.clone(),
|
||||
kid: self.kid.clone(),
|
||||
x5u: self.x5u.clone(),
|
||||
x5c: self.x5c.clone(),
|
||||
@ -195,7 +195,7 @@ impl<P> JsonWebKey<P> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_use(mut self, value: JsonWebKeyUse) -> Self {
|
||||
pub fn with_use(mut self, value: JsonWebKeyUse) -> Self {
|
||||
self.r#use = Some(value);
|
||||
self
|
||||
}
|
||||
@ -207,7 +207,7 @@ impl<P> JsonWebKey<P> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_alg(mut self, alg: JsonWebSignatureAlg) -> Self {
|
||||
pub fn with_alg(mut self, alg: JsonWebSignatureAlg) -> Self {
|
||||
self.alg = Some(alg);
|
||||
self
|
||||
}
|
||||
@ -219,8 +219,8 @@ impl<P> JsonWebKey<P> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn alg(&self) -> Option<JsonWebSignatureAlg> {
|
||||
self.alg
|
||||
pub const fn alg(&self) -> Option<&JsonWebSignatureAlg> {
|
||||
self.alg.as_ref()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@ -245,12 +245,12 @@ where
|
||||
self.parameters.possible_algs()
|
||||
}
|
||||
|
||||
fn alg(&self) -> Option<JsonWebSignatureAlg> {
|
||||
self.alg
|
||||
fn alg(&self) -> Option<&JsonWebSignatureAlg> {
|
||||
self.alg.as_ref()
|
||||
}
|
||||
|
||||
fn use_(&self) -> Option<JsonWebKeyUse> {
|
||||
self.r#use
|
||||
fn use_(&self) -> Option<&JsonWebKeyUse> {
|
||||
self.r#use.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,13 +317,13 @@ impl<P> JsonWebKeySet<P> {
|
||||
/// Find a key for the given algorithm. Returns `None` if no suitable key
|
||||
/// was found.
|
||||
#[must_use]
|
||||
pub fn signing_key_for_algorithm(&self, alg: JsonWebSignatureAlg) -> Option<&JsonWebKey<P>>
|
||||
pub fn signing_key_for_algorithm(&self, alg: &JsonWebSignatureAlg) -> Option<&JsonWebKey<P>>
|
||||
where
|
||||
P: ParametersInfo,
|
||||
{
|
||||
let constraints = ConstraintSet::new([
|
||||
Constraint::alg(alg),
|
||||
Constraint::use_(mas_iana::jose::JsonWebKeyUse::Sig),
|
||||
Constraint::use_(&mas_iana::jose::JsonWebKeyUse::Sig),
|
||||
]);
|
||||
self.find_key(&constraints)
|
||||
}
|
||||
@ -338,7 +338,7 @@ impl<P> JsonWebKeySet<P> {
|
||||
.keys
|
||||
.iter()
|
||||
.flat_map(|key| key.params().possible_algs())
|
||||
.copied()
|
||||
.cloned()
|
||||
.collect();
|
||||
algs.sort();
|
||||
algs.dedup();
|
||||
@ -389,15 +389,15 @@ mod tests {
|
||||
}
|
||||
|
||||
let constraints = ConstraintSet::default()
|
||||
.use_(JsonWebKeyUse::Sig)
|
||||
.kty(JsonWebKeyType::Rsa)
|
||||
.alg(JsonWebSignatureAlg::Rs256);
|
||||
.use_(&JsonWebKeyUse::Sig)
|
||||
.kty(&JsonWebKeyType::Rsa)
|
||||
.alg(&JsonWebSignatureAlg::Rs256);
|
||||
let candidates = constraints.filter(&jwks.keys);
|
||||
assert_eq!(candidates.len(), 2);
|
||||
|
||||
let constraints = ConstraintSet::default()
|
||||
.use_(JsonWebKeyUse::Sig)
|
||||
.kty(JsonWebKeyType::Rsa)
|
||||
.use_(&JsonWebKeyUse::Sig)
|
||||
.kty(&JsonWebKeyType::Rsa)
|
||||
.kid("03e84aed4ef4431014e8617567864c4efaaaede9");
|
||||
let candidates = constraints.filter(&jwks.keys);
|
||||
assert_eq!(candidates.len(), 1);
|
||||
|
@ -335,6 +335,7 @@ impl ParametersInfo for EcPrivateParameters {
|
||||
JsonWebKeyEcEllipticCurve::P384 => &[JsonWebSignatureAlg::Es384],
|
||||
JsonWebKeyEcEllipticCurve::P521 => &[JsonWebSignatureAlg::Es512],
|
||||
JsonWebKeyEcEllipticCurve::Secp256K1 => &[JsonWebSignatureAlg::Es256K],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,8 +137,8 @@ impl EcPublicParameters {
|
||||
Self { crv, x, y }
|
||||
}
|
||||
|
||||
pub const fn crv(&self) -> JsonWebKeyEcEllipticCurve {
|
||||
self.crv
|
||||
pub const fn crv(&self) -> &JsonWebKeyEcEllipticCurve {
|
||||
&self.crv
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,11 +148,12 @@ impl ParametersInfo for EcPublicParameters {
|
||||
}
|
||||
|
||||
fn possible_algs(&self) -> &[JsonWebSignatureAlg] {
|
||||
match self.crv {
|
||||
match &self.crv {
|
||||
JsonWebKeyEcEllipticCurve::P256 => &[JsonWebSignatureAlg::Es256],
|
||||
JsonWebKeyEcEllipticCurve::P384 => &[JsonWebSignatureAlg::Es384],
|
||||
JsonWebKeyEcEllipticCurve::P521 => &[JsonWebSignatureAlg::Es512],
|
||||
JsonWebKeyEcEllipticCurve::Secp256K1 => &[JsonWebSignatureAlg::Es256K],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,8 +183,8 @@ impl OkpPublicParameters {
|
||||
Self { crv, x }
|
||||
}
|
||||
|
||||
pub const fn crv(&self) -> JsonWebKeyOkpEllipticCurve {
|
||||
self.crv
|
||||
pub const fn crv(&self) -> &JsonWebKeyOkpEllipticCurve {
|
||||
&self.crv
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,7 +361,7 @@ mod ec_impls {
|
||||
type Error = ecdsa::Error;
|
||||
|
||||
fn try_from(value: &EcPublicParameters) -> Result<Self, Self::Error> {
|
||||
if value.crv() != C::CRV {
|
||||
if *value.crv() != C::CRV {
|
||||
return Err(Self::Error::default());
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,8 @@ impl JsonWebSignatureHeader {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn alg(&self) -> JsonWebSignatureAlg {
|
||||
self.alg
|
||||
pub const fn alg(&self) -> &JsonWebSignatureAlg {
|
||||
&self.alg
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -70,7 +70,7 @@ macro_rules! asymetric_jwt_test {
|
||||
fn validate_jwt() {
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
|
||||
assert_eq!(jwt.payload().hello, "world");
|
||||
assert_eq!(jwt.header().alg(), JsonWebSignatureAlg::$alg);
|
||||
assert_eq!(*jwt.header().alg(), JsonWebSignatureAlg::$alg);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -105,7 +105,7 @@ macro_rules! asymetric_jwt_test {
|
||||
|
||||
let key = mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(
|
||||
key.params(),
|
||||
JsonWebSignatureAlg::$alg,
|
||||
&JsonWebSignatureAlg::$alg,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -118,12 +118,12 @@ macro_rules! asymetric_jwt_test {
|
||||
let payload = Payload {
|
||||
hello: "world".to_string(),
|
||||
};
|
||||
let header = JsonWebSignatureHeader::new(alg);
|
||||
let header = JsonWebSignatureHeader::new(alg.clone());
|
||||
|
||||
let jwks = private_jwks();
|
||||
let key = jwks.signing_key_for_algorithm(alg).unwrap();
|
||||
let key = jwks.signing_key_for_algorithm(&alg).unwrap();
|
||||
|
||||
let key = mas_jose::jwa::AsymmetricSigningKey::from_jwk_and_alg(key.params(), alg)
|
||||
let key = mas_jose::jwa::AsymmetricSigningKey::from_jwk_and_alg(key.params(), &alg)
|
||||
.unwrap();
|
||||
|
||||
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap();
|
||||
@ -133,7 +133,7 @@ macro_rules! asymetric_jwt_test {
|
||||
let key = jwks.find_key(&jwt.header().into()).unwrap();
|
||||
|
||||
let key =
|
||||
mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(key.params(), alg)
|
||||
mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(key.params(), &alg)
|
||||
.unwrap();
|
||||
|
||||
jwt.verify(&key).unwrap();
|
||||
@ -155,14 +155,14 @@ macro_rules! symetric_jwt_test {
|
||||
fn validate_jwt() {
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
|
||||
assert_eq!(jwt.payload().hello, "world");
|
||||
assert_eq!(jwt.header().alg(), JsonWebSignatureAlg::$alg);
|
||||
assert_eq!(*jwt.header().alg(), JsonWebSignatureAlg::$alg);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_jwt() {
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
|
||||
let key =
|
||||
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
||||
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), &JsonWebSignatureAlg::$alg)
|
||||
.unwrap();
|
||||
jwt.verify(&key).unwrap();
|
||||
}
|
||||
@ -173,9 +173,9 @@ macro_rules! symetric_jwt_test {
|
||||
let payload = Payload {
|
||||
hello: "world".to_string(),
|
||||
};
|
||||
let header = JsonWebSignatureHeader::new(alg);
|
||||
let header = JsonWebSignatureHeader::new(alg.clone());
|
||||
|
||||
let key = mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), alg).unwrap();
|
||||
let key = mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), &alg).unwrap();
|
||||
|
||||
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap();
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();
|
||||
|
@ -415,7 +415,7 @@ impl PrivateKey {
|
||||
/// Returns an error if the key is not suited for the selected algorithm
|
||||
pub fn verifying_key_for_alg(
|
||||
&self,
|
||||
alg: JsonWebSignatureAlg,
|
||||
alg: &JsonWebSignatureAlg,
|
||||
) -> Result<AsymmetricVerifyingKey, WrongAlgorithmError> {
|
||||
let key = match (self, alg) {
|
||||
(Self::Rsa(key), _) => {
|
||||
@ -469,7 +469,7 @@ impl PrivateKey {
|
||||
/// Returns an error if the key is not suited for the selected algorithm
|
||||
pub fn signing_key_for_alg(
|
||||
&self,
|
||||
alg: JsonWebSignatureAlg,
|
||||
alg: &JsonWebSignatureAlg,
|
||||
) -> Result<AsymmetricSigningKey, WrongAlgorithmError> {
|
||||
let key = match (self, alg) {
|
||||
(Self::Rsa(key), _) => {
|
||||
|
@ -33,8 +33,8 @@ macro_rules! plain_test {
|
||||
let algs = key.possible_algs();
|
||||
assert_ne!(algs.len(), 0);
|
||||
|
||||
for &alg in algs {
|
||||
let header = JsonWebSignatureHeader::new(alg);
|
||||
for alg in algs {
|
||||
let header = JsonWebSignatureHeader::new(alg.clone());
|
||||
let payload = "hello";
|
||||
let signer = key.signing_key_for_alg(alg).unwrap();
|
||||
let jwt = Jwt::sign(header, payload, &signer).unwrap();
|
||||
@ -58,8 +58,8 @@ macro_rules! enc_test {
|
||||
let algs = key.possible_algs();
|
||||
assert_ne!(algs.len(), 0);
|
||||
|
||||
for &alg in algs {
|
||||
let header = JsonWebSignatureHeader::new(alg);
|
||||
for alg in algs {
|
||||
let header = JsonWebSignatureHeader::new(alg.clone());
|
||||
let payload = "hello";
|
||||
let signer = key.signing_key_for_alg(alg).unwrap();
|
||||
let jwt = Jwt::sign(header, payload, &signer).unwrap();
|
||||
|
@ -33,7 +33,7 @@ use crate::{
|
||||
/// An enum for types that accept either an [`OAuthClientAuthenticationMethod`]
|
||||
/// or an [`OAuthAccessTokenType`].
|
||||
#[derive(
|
||||
SerializeDisplay, DeserializeFromStr, Clone, Copy, PartialEq, Eq, Hash, Debug, Display, FromStr,
|
||||
SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, Debug, Display, FromStr,
|
||||
)]
|
||||
pub enum AuthenticationMethodOrAccessTokenType {
|
||||
/// An authentication method.
|
||||
@ -49,9 +49,9 @@ impl AuthenticationMethodOrAccessTokenType {
|
||||
/// Get the authentication method of this
|
||||
/// `AuthenticationMethodOrAccessTokenType`.
|
||||
#[must_use]
|
||||
pub fn authentication_method(&self) -> Option<OAuthClientAuthenticationMethod> {
|
||||
pub fn authentication_method(&self) -> Option<&OAuthClientAuthenticationMethod> {
|
||||
match self {
|
||||
Self::AuthenticationMethod(m) => Some(*m),
|
||||
Self::AuthenticationMethod(m) => Some(m),
|
||||
Self::AccessTokenType(_) => None,
|
||||
}
|
||||
}
|
||||
@ -59,10 +59,10 @@ impl AuthenticationMethodOrAccessTokenType {
|
||||
/// Get the access token type of this
|
||||
/// `AuthenticationMethodOrAccessTokenType`.
|
||||
#[must_use]
|
||||
pub fn access_token_type(&self) -> Option<OAuthAccessTokenType> {
|
||||
pub fn access_token_type(&self) -> Option<&OAuthAccessTokenType> {
|
||||
match self {
|
||||
Self::AuthenticationMethod(_) => None,
|
||||
Self::AccessTokenType(t) => Some(*t),
|
||||
Self::AccessTokenType(t) => Some(t),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,8 +470,14 @@ impl ProviderMetadata {
|
||||
|
||||
validate_signing_alg_values_supported(
|
||||
"token_endpoint",
|
||||
&metadata.token_endpoint_auth_signing_alg_values_supported,
|
||||
&metadata.token_endpoint_auth_methods_supported,
|
||||
metadata
|
||||
.token_endpoint_auth_signing_alg_values_supported
|
||||
.iter()
|
||||
.flatten(),
|
||||
metadata
|
||||
.token_endpoint_auth_methods_supported
|
||||
.iter()
|
||||
.flatten(),
|
||||
)?;
|
||||
|
||||
if let Some(url) = &metadata.revocation_endpoint {
|
||||
@ -480,8 +486,14 @@ impl ProviderMetadata {
|
||||
|
||||
validate_signing_alg_values_supported(
|
||||
"revocation_endpoint",
|
||||
&metadata.revocation_endpoint_auth_signing_alg_values_supported,
|
||||
&metadata.revocation_endpoint_auth_methods_supported,
|
||||
metadata
|
||||
.revocation_endpoint_auth_signing_alg_values_supported
|
||||
.iter()
|
||||
.flatten(),
|
||||
metadata
|
||||
.revocation_endpoint_auth_methods_supported
|
||||
.iter()
|
||||
.flatten(),
|
||||
)?;
|
||||
|
||||
if let Some(url) = &metadata.introspection_endpoint {
|
||||
@ -500,8 +512,11 @@ impl ProviderMetadata {
|
||||
});
|
||||
validate_signing_alg_values_supported(
|
||||
"introspection_endpoint",
|
||||
&metadata.introspection_endpoint_auth_signing_alg_values_supported,
|
||||
&introspection_methods,
|
||||
metadata
|
||||
.introspection_endpoint_auth_signing_alg_values_supported
|
||||
.iter()
|
||||
.flatten(),
|
||||
introspection_methods.into_iter().flatten(),
|
||||
)?;
|
||||
|
||||
if let Some(url) = &metadata.userinfo_endpoint {
|
||||
@ -957,24 +972,32 @@ fn validate_url(
|
||||
/// - The algorithm values must not contain `none`,
|
||||
/// - If the `client_secret_jwt` or `private_key_jwt` authentication methods are
|
||||
/// supported, the values must be present.
|
||||
fn validate_signing_alg_values_supported(
|
||||
fn validate_signing_alg_values_supported<'a>(
|
||||
endpoint: &'static str,
|
||||
values: &Option<Vec<JsonWebSignatureAlg>>,
|
||||
methods: &Option<Vec<OAuthClientAuthenticationMethod>>,
|
||||
values: impl Iterator<Item = &'a JsonWebSignatureAlg>,
|
||||
mut methods: impl Iterator<Item = &'a OAuthClientAuthenticationMethod>,
|
||||
) -> Result<(), ProviderMetadataVerificationError> {
|
||||
if let Some(values) = values {
|
||||
if values.contains(&JsonWebSignatureAlg::None) {
|
||||
let mut no_values = true;
|
||||
|
||||
for value in values {
|
||||
if *value == JsonWebSignatureAlg::None {
|
||||
return Err(ProviderMetadataVerificationError::SigningAlgValuesWithNone(
|
||||
endpoint,
|
||||
));
|
||||
}
|
||||
} else if methods.iter().flatten().any(|method| {
|
||||
|
||||
no_values = false;
|
||||
}
|
||||
|
||||
if no_values
|
||||
&& methods.any(|method| {
|
||||
matches!(
|
||||
method,
|
||||
OAuthClientAuthenticationMethod::ClientSecretJwt
|
||||
| OAuthClientAuthenticationMethod::PrivateKeyJwt
|
||||
)
|
||||
}) {
|
||||
})
|
||||
{
|
||||
return Err(ProviderMetadataVerificationError::MissingAuthSigningAlgValues(endpoint));
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,9 @@ pub enum CodeChallengeError {
|
||||
|
||||
#[error("challenge verification failed")]
|
||||
VerificationFailed,
|
||||
|
||||
#[error("unknown challenge method")]
|
||||
UnknownChallengeMethod,
|
||||
}
|
||||
|
||||
fn validate_verifier(verifier: &str) -> Result<(), CodeChallengeError> {
|
||||
@ -61,7 +64,7 @@ pub trait CodeChallengeMethodExt {
|
||||
///
|
||||
/// Returns an error if the verifier did not adhere to the rules defined by
|
||||
/// the RFC in terms of length and allowed characters
|
||||
fn compute_challenge(self, verifier: &str) -> Result<Cow<'_, str>, CodeChallengeError>;
|
||||
fn compute_challenge<'a>(&self, verifier: &'a str) -> Result<Cow<'a, str>, CodeChallengeError>;
|
||||
|
||||
/// Verify that a given verifier is valid for the given challenge
|
||||
///
|
||||
@ -70,7 +73,7 @@ pub trait CodeChallengeMethodExt {
|
||||
/// Returns an error if the verifier did not match the challenge, or if the
|
||||
/// verifier did not adhere to the rules defined by the RFC in terms of
|
||||
/// length and allowed characters
|
||||
fn verify(self, challenge: &str, verifier: &str) -> Result<(), CodeChallengeError>
|
||||
fn verify(&self, challenge: &str, verifier: &str) -> Result<(), CodeChallengeError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@ -83,7 +86,7 @@ pub trait CodeChallengeMethodExt {
|
||||
}
|
||||
|
||||
impl CodeChallengeMethodExt for PkceCodeChallengeMethod {
|
||||
fn compute_challenge(self, verifier: &str) -> Result<Cow<'_, str>, CodeChallengeError> {
|
||||
fn compute_challenge<'a>(&self, verifier: &'a str) -> Result<Cow<'a, str>, CodeChallengeError> {
|
||||
validate_verifier(verifier)?;
|
||||
|
||||
let challenge = match self {
|
||||
@ -95,6 +98,7 @@ impl CodeChallengeMethodExt for PkceCodeChallengeMethod {
|
||||
let verifier = BASE64URL_NOPAD.encode(&hash);
|
||||
verifier.into()
|
||||
}
|
||||
_ => return Err(CodeChallengeError::UnknownChallengeMethod),
|
||||
};
|
||||
|
||||
Ok(challenge)
|
||||
|
@ -42,13 +42,13 @@ pub const DEFAULT_GRANT_TYPES: &[GrantType] = &[GrantType::AuthorizationCode];
|
||||
|
||||
pub const DEFAULT_APPLICATION_TYPE: ApplicationType = ApplicationType::Web;
|
||||
|
||||
pub const DEFAULT_TOKEN_AUTH_METHOD: OAuthClientAuthenticationMethod =
|
||||
OAuthClientAuthenticationMethod::ClientSecretBasic;
|
||||
pub const DEFAULT_TOKEN_AUTH_METHOD: &OAuthClientAuthenticationMethod =
|
||||
&OAuthClientAuthenticationMethod::ClientSecretBasic;
|
||||
|
||||
pub const DEFAULT_SIGNING_ALGORITHM: JsonWebSignatureAlg = JsonWebSignatureAlg::Rs256;
|
||||
pub const DEFAULT_SIGNING_ALGORITHM: &JsonWebSignatureAlg = &JsonWebSignatureAlg::Rs256;
|
||||
|
||||
pub const DEFAULT_ENCRYPTION_ENC_ALGORITHM: JsonWebEncryptionEnc =
|
||||
JsonWebEncryptionEnc::A128CbcHs256;
|
||||
pub const DEFAULT_ENCRYPTION_ENC_ALGORITHM: &JsonWebEncryptionEnc =
|
||||
&JsonWebEncryptionEnc::A128CbcHs256;
|
||||
|
||||
/// A collection of localized variants.
|
||||
///
|
||||
@ -463,7 +463,7 @@ impl ClientMetadata {
|
||||
));
|
||||
}
|
||||
|
||||
if self.token_endpoint_auth_method() == OAuthClientAuthenticationMethod::PrivateKeyJwt
|
||||
if *self.token_endpoint_auth_method() == OAuthClientAuthenticationMethod::PrivateKeyJwt
|
||||
&& self.jwks_uri.is_none()
|
||||
&& self.jwks.is_none()
|
||||
{
|
||||
@ -486,26 +486,26 @@ impl ClientMetadata {
|
||||
));
|
||||
}
|
||||
|
||||
if self.id_token_signed_response_alg() == JsonWebSignatureAlg::None
|
||||
if *self.id_token_signed_response_alg() == JsonWebSignatureAlg::None
|
||||
&& response_types.iter().any(ResponseType::has_id_token)
|
||||
{
|
||||
return Err(ClientMetadataVerificationError::IdTokenSigningAlgNone);
|
||||
}
|
||||
|
||||
if self.id_token_encrypted_response_enc.is_some() {
|
||||
self.id_token_encrypted_response_alg.ok_or(
|
||||
self.id_token_encrypted_response_alg.as_ref().ok_or(
|
||||
ClientMetadataVerificationError::MissingEncryptionAlg("id_token"),
|
||||
)?;
|
||||
}
|
||||
|
||||
if self.userinfo_encrypted_response_enc.is_some() {
|
||||
self.userinfo_encrypted_response_alg.ok_or(
|
||||
self.userinfo_encrypted_response_alg.as_ref().ok_or(
|
||||
ClientMetadataVerificationError::MissingEncryptionAlg("userinfo"),
|
||||
)?;
|
||||
}
|
||||
|
||||
if self.request_object_encryption_enc.is_some() {
|
||||
self.request_object_encryption_alg.ok_or(
|
||||
self.request_object_encryption_alg.as_ref().ok_or(
|
||||
ClientMetadataVerificationError::MissingEncryptionAlg("request_object"),
|
||||
)?;
|
||||
}
|
||||
@ -522,7 +522,7 @@ impl ClientMetadata {
|
||||
}
|
||||
|
||||
if self.introspection_encrypted_response_enc.is_some() {
|
||||
self.introspection_encrypted_response_alg.ok_or(
|
||||
self.introspection_encrypted_response_alg.as_ref().ok_or(
|
||||
ClientMetadataVerificationError::MissingEncryptionAlg("introspection"),
|
||||
)?;
|
||||
}
|
||||
@ -542,9 +542,12 @@ impl ClientMetadata {
|
||||
/// [authorization endpoint]: https://www.rfc-editor.org/rfc/rfc6749.html#section-3.1
|
||||
#[must_use]
|
||||
pub fn response_types(&self) -> Vec<ResponseType> {
|
||||
self.response_types
|
||||
.clone()
|
||||
.unwrap_or_else(|| DEFAULT_RESPONSE_TYPES.map(ResponseType::from).into())
|
||||
self.response_types.clone().unwrap_or_else(|| {
|
||||
DEFAULT_RESPONSE_TYPES
|
||||
.into_iter()
|
||||
.filter_map(|t| ResponseType::try_from(t).ok())
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
/// Array of [OAuth 2.0 `grant_type` values] that the client can use at the
|
||||
@ -578,8 +581,9 @@ impl ClientMetadata {
|
||||
///
|
||||
/// [token endpoint]: https://www.rfc-editor.org/rfc/rfc6749.html#section-3.2
|
||||
#[must_use]
|
||||
pub fn token_endpoint_auth_method(&self) -> OAuthClientAuthenticationMethod {
|
||||
pub fn token_endpoint_auth_method(&self) -> &OAuthClientAuthenticationMethod {
|
||||
self.token_endpoint_auth_method
|
||||
.as_ref()
|
||||
.unwrap_or(DEFAULT_TOKEN_AUTH_METHOD)
|
||||
}
|
||||
|
||||
@ -594,8 +598,9 @@ impl ClientMetadata {
|
||||
///
|
||||
/// [JWS]: http://tools.ietf.org/html/draft-ietf-jose-json-web-signature
|
||||
#[must_use]
|
||||
pub fn id_token_signed_response_alg(&self) -> JsonWebSignatureAlg {
|
||||
pub fn id_token_signed_response_alg(&self) -> &JsonWebSignatureAlg {
|
||||
self.id_token_signed_response_alg
|
||||
.as_ref()
|
||||
.unwrap_or(DEFAULT_SIGNING_ALGORITHM)
|
||||
}
|
||||
|
||||
@ -610,11 +615,12 @@ impl ClientMetadata {
|
||||
#[must_use]
|
||||
pub fn id_token_encrypted_response(
|
||||
&self,
|
||||
) -> Option<(JsonWebEncryptionAlg, JsonWebEncryptionEnc)> {
|
||||
self.id_token_encrypted_response_alg.map(|alg| {
|
||||
) -> Option<(&JsonWebEncryptionAlg, &JsonWebEncryptionEnc)> {
|
||||
self.id_token_encrypted_response_alg.as_ref().map(|alg| {
|
||||
(
|
||||
alg,
|
||||
self.id_token_encrypted_response_enc
|
||||
.as_ref()
|
||||
.unwrap_or(DEFAULT_ENCRYPTION_ENC_ALGORITHM),
|
||||
)
|
||||
})
|
||||
@ -631,11 +637,12 @@ impl ClientMetadata {
|
||||
#[must_use]
|
||||
pub fn userinfo_encrypted_response(
|
||||
&self,
|
||||
) -> Option<(JsonWebEncryptionAlg, JsonWebEncryptionEnc)> {
|
||||
self.userinfo_encrypted_response_alg.map(|alg| {
|
||||
) -> Option<(&JsonWebEncryptionAlg, &JsonWebEncryptionEnc)> {
|
||||
self.userinfo_encrypted_response_alg.as_ref().map(|alg| {
|
||||
(
|
||||
alg,
|
||||
self.userinfo_encrypted_response_enc
|
||||
.as_ref()
|
||||
.unwrap_or(DEFAULT_ENCRYPTION_ENC_ALGORITHM),
|
||||
)
|
||||
})
|
||||
@ -652,11 +659,12 @@ impl ClientMetadata {
|
||||
#[must_use]
|
||||
pub fn request_object_encryption(
|
||||
&self,
|
||||
) -> Option<(JsonWebEncryptionAlg, JsonWebEncryptionEnc)> {
|
||||
self.request_object_encryption_alg.map(|alg| {
|
||||
) -> Option<(&JsonWebEncryptionAlg, &JsonWebEncryptionEnc)> {
|
||||
self.request_object_encryption_alg.as_ref().map(|alg| {
|
||||
(
|
||||
alg,
|
||||
self.request_object_encryption_enc
|
||||
.as_ref()
|
||||
.unwrap_or(DEFAULT_ENCRYPTION_ENC_ALGORITHM),
|
||||
)
|
||||
})
|
||||
@ -705,11 +713,14 @@ impl ClientMetadata {
|
||||
#[must_use]
|
||||
pub fn introspection_encrypted_response(
|
||||
&self,
|
||||
) -> Option<(JsonWebEncryptionAlg, JsonWebEncryptionEnc)> {
|
||||
self.introspection_encrypted_response_alg.map(|alg| {
|
||||
) -> Option<(&JsonWebEncryptionAlg, &JsonWebEncryptionEnc)> {
|
||||
self.introspection_encrypted_response_alg
|
||||
.as_ref()
|
||||
.map(|alg| {
|
||||
(
|
||||
alg,
|
||||
self.introspection_encrypted_response_enc
|
||||
.as_ref()
|
||||
.unwrap_or(DEFAULT_ENCRYPTION_ENC_ALGORITHM),
|
||||
)
|
||||
})
|
||||
|
@ -332,10 +332,10 @@ pub async fn insert_client(
|
||||
tos_uri: Option<&Url>,
|
||||
jwks_uri: Option<&Url>,
|
||||
jwks: Option<&PublicJsonWebKeySet>,
|
||||
id_token_signed_response_alg: Option<JsonWebSignatureAlg>,
|
||||
userinfo_signed_response_alg: Option<JsonWebSignatureAlg>,
|
||||
token_endpoint_auth_method: Option<OAuthClientAuthenticationMethod>,
|
||||
token_endpoint_auth_signing_alg: Option<JsonWebSignatureAlg>,
|
||||
id_token_signed_response_alg: Option<&JsonWebSignatureAlg>,
|
||||
userinfo_signed_response_alg: Option<&JsonWebSignatureAlg>,
|
||||
token_endpoint_auth_method: Option<&OAuthClientAuthenticationMethod>,
|
||||
token_endpoint_auth_signing_alg: Option<&JsonWebSignatureAlg>,
|
||||
initiate_login_uri: Option<&Url>,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
let response_types: Vec<String> = response_types.iter().map(ToString::to_string).collect();
|
||||
@ -347,10 +347,10 @@ pub async fn insert_client(
|
||||
let tos_uri = tos_uri.map(Url::as_str);
|
||||
let jwks = jwks.map(serde_json::to_value).transpose().unwrap(); // TODO
|
||||
let jwks_uri = jwks_uri.map(Url::as_str);
|
||||
let id_token_signed_response_alg = id_token_signed_response_alg.map(|v| v.to_string());
|
||||
let userinfo_signed_response_alg = userinfo_signed_response_alg.map(|v| v.to_string());
|
||||
let token_endpoint_auth_method = token_endpoint_auth_method.map(|v| v.to_string());
|
||||
let token_endpoint_auth_signing_alg = token_endpoint_auth_signing_alg.map(|v| v.to_string());
|
||||
let id_token_signed_response_alg = id_token_signed_response_alg.map(ToString::to_string);
|
||||
let userinfo_signed_response_alg = userinfo_signed_response_alg.map(ToString::to_string);
|
||||
let token_endpoint_auth_method = token_endpoint_auth_method.map(ToString::to_string);
|
||||
let token_endpoint_auth_signing_alg = token_endpoint_auth_signing_alg.map(ToString::to_string);
|
||||
let initiate_login_uri = initiate_login_uri.map(Url::as_str);
|
||||
|
||||
let id = sqlx::query_scalar!(
|
||||
|
Reference in New Issue
Block a user