You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Multiple IANA codegen enhancement
- JWS/JWE algorithms are properly splitted - Enums now have a proper description - They implement FromStr and Display - mas-jose does not reexport mas-iana anymore
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1599,6 +1599,7 @@ dependencies = [
|
|||||||
name = "mas-iana"
|
name = "mas-iana"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"parse-display",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use mas_config::OAuth2Config;
|
use mas_config::OAuth2Config;
|
||||||
use mas_jose::{JsonWebSignatureAlgorithm, SigningKeystore};
|
use mas_iana::jose::JsonWebSignatureAlg;
|
||||||
|
use mas_jose::SigningKeystore;
|
||||||
use oauth2_types::{
|
use oauth2_types::{
|
||||||
oidc::{ClaimType, Metadata, SubjectType},
|
oidc::{ClaimType, Metadata, SubjectType},
|
||||||
pkce::CodeChallengeMethod,
|
pkce::CodeChallengeMethod,
|
||||||
@ -43,12 +44,12 @@ pub(super) fn filter(
|
|||||||
|
|
||||||
let client_auth_signing_alg_values_supported = Some({
|
let client_auth_signing_alg_values_supported = Some({
|
||||||
let mut s = HashSet::new();
|
let mut s = HashSet::new();
|
||||||
s.insert(JsonWebSignatureAlgorithm::Hs256);
|
s.insert(JsonWebSignatureAlg::Hs256);
|
||||||
s.insert(JsonWebSignatureAlgorithm::Hs384);
|
s.insert(JsonWebSignatureAlg::Hs384);
|
||||||
s.insert(JsonWebSignatureAlgorithm::Hs512);
|
s.insert(JsonWebSignatureAlg::Hs512);
|
||||||
s.insert(JsonWebSignatureAlgorithm::Rs256);
|
s.insert(JsonWebSignatureAlg::Rs256);
|
||||||
s.insert(JsonWebSignatureAlgorithm::Rs384);
|
s.insert(JsonWebSignatureAlg::Rs384);
|
||||||
s.insert(JsonWebSignatureAlgorithm::Rs512);
|
s.insert(JsonWebSignatureAlg::Rs512);
|
||||||
s
|
s
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,9 +21,10 @@ use headers::{CacheControl, Pragma};
|
|||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
use mas_config::{OAuth2ClientConfig, OAuth2Config};
|
use mas_config::{OAuth2ClientConfig, OAuth2Config};
|
||||||
use mas_data_model::{AuthorizationGrantStage, TokenType};
|
use mas_data_model::{AuthorizationGrantStage, TokenType};
|
||||||
|
use mas_iana::jose::JsonWebSignatureAlg;
|
||||||
use mas_jose::{
|
use mas_jose::{
|
||||||
claims::{AT_HASH, AUD, AUTH_TIME, C_HASH, EXP, IAT, ISS, NONCE, SUB},
|
claims::{AT_HASH, AUD, AUTH_TIME, C_HASH, EXP, IAT, ISS, NONCE, SUB},
|
||||||
DecodedJsonWebToken, JsonWebSignatureAlgorithm, SigningKeystore, StaticKeystore,
|
DecodedJsonWebToken, SigningKeystore, StaticKeystore,
|
||||||
};
|
};
|
||||||
use mas_storage::{
|
use mas_storage::{
|
||||||
oauth2::{
|
oauth2::{
|
||||||
@ -288,7 +289,7 @@ async fn authorization_code_grant(
|
|||||||
.wrap_error()?;
|
.wrap_error()?;
|
||||||
|
|
||||||
let header = key_store
|
let header = key_store
|
||||||
.prepare_header(JsonWebSignatureAlgorithm::Rs256)
|
.prepare_header(JsonWebSignatureAlg::Rs256)
|
||||||
.await
|
.await
|
||||||
.wrap_error()?;
|
.wrap_error()?;
|
||||||
let id_token = DecodedJsonWebToken::new(header, claims);
|
let id_token = DecodedJsonWebToken::new(header, claims);
|
||||||
|
@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::EnumEntry;
|
use crate::{
|
||||||
|
traits::{s, Section},
|
||||||
|
EnumEntry,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||||
enum Usage {
|
enum Usage {
|
||||||
@ -60,13 +63,41 @@ pub struct WebEncryptionSignatureAlgorithm {
|
|||||||
impl EnumEntry for WebEncryptionSignatureAlgorithm {
|
impl EnumEntry for WebEncryptionSignatureAlgorithm {
|
||||||
const URL: &'static str =
|
const URL: &'static str =
|
||||||
"https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv";
|
"https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv";
|
||||||
const SECTIONS: &'static [&'static str] =
|
const SECTIONS: &'static [Section] = &[
|
||||||
&["JsonWebSignatureAlgorithm", "JsonWebEncryptionAlgorithm"];
|
s(
|
||||||
|
"JsonWebSignatureAlg",
|
||||||
|
r#"JSON Web Signature "alg" parameter"#,
|
||||||
|
),
|
||||||
|
s(
|
||||||
|
"JsonWebEncryptionAlg",
|
||||||
|
r#"JSON Web Encryption "alg" parameter"#,
|
||||||
|
),
|
||||||
|
s(
|
||||||
|
"JsonWebEncryptionEnc",
|
||||||
|
r#"JSON Web Encryption "enc" parameter"#,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
match self.usage {
|
match self.usage {
|
||||||
Usage::Alg => Some("JsonWebSignatureAlgorithm"),
|
Usage::Alg => {
|
||||||
Usage::Enc => Some("JsonWebEncryptionAlgorithm"),
|
// RFC7518 has one for signature algs and one for encryption algs. The other two
|
||||||
|
// RFCs are additional Elliptic curve signature algs
|
||||||
|
if self.reference.contains("RFC7518, Section 3")
|
||||||
|
|| self.reference.contains("RFC8037")
|
||||||
|
|| self.reference.contains("RFC8812")
|
||||||
|
{
|
||||||
|
Some("JsonWebSignatureAlg")
|
||||||
|
} else if self.reference.contains("RFC7518, Section 4")
|
||||||
|
|| self.reference.contains("WebCryptoAPI")
|
||||||
|
{
|
||||||
|
Some("JsonWebEncryptionAlg")
|
||||||
|
} else {
|
||||||
|
tracing::warn!("Unknown reference {} for JWA", self.reference);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Usage::Enc => Some("JsonWebEncryptionEnc"),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +127,10 @@ pub struct WebEncryptionCompressionAlgorithm {
|
|||||||
impl EnumEntry for WebEncryptionCompressionAlgorithm {
|
impl EnumEntry for WebEncryptionCompressionAlgorithm {
|
||||||
const URL: &'static str =
|
const URL: &'static str =
|
||||||
"https://www.iana.org/assignments/jose/web-encryption-compression-algorithms.csv";
|
"https://www.iana.org/assignments/jose/web-encryption-compression-algorithms.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["JsonWebEncryptionCompressionAlgorithm"];
|
const SECTIONS: &'static [Section] = &[s(
|
||||||
|
"JsonWebEncryptionCompressionAlgorithm",
|
||||||
|
"JSON Web Encryption Compression Algorithm",
|
||||||
|
)];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("JsonWebEncryptionCompressionAlgorithm")
|
Some("JsonWebEncryptionCompressionAlgorithm")
|
||||||
@ -128,7 +162,7 @@ pub struct WebKeyType {
|
|||||||
|
|
||||||
impl EnumEntry for WebKeyType {
|
impl EnumEntry for WebKeyType {
|
||||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-types.csv";
|
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-types.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["JsonWebKeyType"];
|
const SECTIONS: &'static [Section] = &[s("JsonWebKeyType", "JSON Web Key Type")];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("JsonWebKeyType")
|
Some("JsonWebKeyType")
|
||||||
@ -160,8 +194,16 @@ pub struct WebKeyEllipticCurve {
|
|||||||
|
|
||||||
impl EnumEntry for WebKeyEllipticCurve {
|
impl EnumEntry for WebKeyEllipticCurve {
|
||||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv";
|
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv";
|
||||||
const SECTIONS: &'static [&'static str] =
|
const SECTIONS: &'static [Section] = &[
|
||||||
&["JsonWebKeyEcEllipticCurve", "JsonWebKeyOkpEllipticCurve"];
|
s(
|
||||||
|
"JsonWebKeyEcEllipticCurve",
|
||||||
|
"JSON Web Key EC Elliptic Curve",
|
||||||
|
),
|
||||||
|
s(
|
||||||
|
"JsonWebKeyOkpEllipticCurve",
|
||||||
|
"JSON Web Key OKP Elliptic Curve",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
if self.name.starts_with("P-") || self.name == "secp256k1" {
|
if self.name.starts_with("P-") || self.name == "secp256k1" {
|
||||||
@ -195,7 +237,7 @@ pub struct WebKeyUse {
|
|||||||
|
|
||||||
impl EnumEntry for WebKeyUse {
|
impl EnumEntry for WebKeyUse {
|
||||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-use.csv";
|
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-use.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["JsonWebKeyUse"];
|
const SECTIONS: &'static [Section] = &[s("JsonWebKeyUse", "JSON Web Key Use")];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("JsonWebKeyUse")
|
Some("JsonWebKeyUse")
|
||||||
@ -225,7 +267,7 @@ pub struct WebKeyOperation {
|
|||||||
|
|
||||||
impl EnumEntry for WebKeyOperation {
|
impl EnumEntry for WebKeyOperation {
|
||||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-operations.csv";
|
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-operations.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["JsonWebKeyOperation"];
|
const SECTIONS: &'static [Section] = &[s("JsonWebKeyOperation", "JSON Web Key Operation")];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("JsonWebKeyOperation")
|
Some("JsonWebKeyOperation")
|
||||||
|
@ -27,8 +27,7 @@ struct File {
|
|||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
registry_name: &'static str,
|
registry_name: &'static str,
|
||||||
registry_url: &'static str,
|
registry_url: &'static str,
|
||||||
sections: Vec<&'static str>,
|
sections: Vec<Section>,
|
||||||
sources: Vec<&'static str>,
|
|
||||||
items: HashMap<&'static str, Vec<EnumMember>>,
|
items: HashMap<&'static str, Vec<EnumMember>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +45,6 @@ impl File {
|
|||||||
client,
|
client,
|
||||||
registry_name,
|
registry_name,
|
||||||
registry_url,
|
registry_url,
|
||||||
sources: Vec::new(),
|
|
||||||
sections: Vec::new(),
|
sections: Vec::new(),
|
||||||
items: HashMap::new(),
|
items: HashMap::new(),
|
||||||
}
|
}
|
||||||
@ -55,8 +53,7 @@ impl File {
|
|||||||
#[tracing::instrument(skip_all, fields(url))]
|
#[tracing::instrument(skip_all, fields(url))]
|
||||||
async fn load<T: EnumEntry>(mut self) -> anyhow::Result<Self> {
|
async fn load<T: EnumEntry>(mut self) -> anyhow::Result<Self> {
|
||||||
tracing::Span::current().record("url", &T::URL);
|
tracing::Span::current().record("url", &T::URL);
|
||||||
self.sections.extend_from_slice(T::SECTIONS);
|
self.sections.extend(T::sections());
|
||||||
self.sources.push(T::URL);
|
|
||||||
for (key, value) in T::fetch(&self.client).await? {
|
for (key, value) in T::fetch(&self.client).await? {
|
||||||
self.items.entry(key).or_default().push(value);
|
self.items.entry(key).or_default().push(value);
|
||||||
}
|
}
|
||||||
@ -99,43 +96,43 @@ impl Display for File {
|
|||||||
|
|
||||||
//! Enums from the {:?} IANA registry
|
//! Enums from the {:?} IANA registry
|
||||||
//! See <{}>
|
//! See <{}>
|
||||||
//!
|
|
||||||
//! Generated from:"#,
|
// Do not edit this file manually
|
||||||
|
|
||||||
|
use parse_display::{{Display, FromStr}};
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{{Deserialize, Serialize}};"#,
|
||||||
self.registry_name, self.registry_url,
|
self.registry_name, self.registry_url,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for source in &self.sources {
|
for section in &self.sections {
|
||||||
writeln!(f, "//! - <{}>", source)?;
|
let list = if let Some(list) = self.items.get(section.key) {
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(
|
|
||||||
f,
|
|
||||||
r#"
|
|
||||||
// Do not edit this file manually
|
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{{Deserialize, Serialize}};"#
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for key in &self.sections {
|
|
||||||
let list = if let Some(list) = self.items.get(key) {
|
|
||||||
list
|
list
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
writeln!(f)?;
|
write!(
|
||||||
writeln!(
|
|
||||||
f,
|
f,
|
||||||
"#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]"
|
r#"
|
||||||
|
/// {}
|
||||||
|
///
|
||||||
|
/// Source: <{}>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
|
pub enum {} {{"#,
|
||||||
|
section.doc,
|
||||||
|
section.url.unwrap(),
|
||||||
|
section.key,
|
||||||
)?;
|
)?;
|
||||||
write!(f, "pub enum {} {{", key)?;
|
|
||||||
for member in list {
|
for member in list {
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
if let Some(description) = &member.description {
|
if let Some(description) = &member.description {
|
||||||
writeln!(f, " /// {}", description)?;
|
writeln!(f, " /// {}", description)?;
|
||||||
}
|
}
|
||||||
writeln!(f, " #[serde(rename = \"{}\")]", member.value)?;
|
writeln!(f, " #[serde(rename = \"{}\")]", member.value)?;
|
||||||
|
writeln!(f, " #[display(\"{}\")]", member.value)?;
|
||||||
writeln!(f, " {},", member.enum_name)?;
|
writeln!(f, " {},", member.enum_name)?;
|
||||||
}
|
}
|
||||||
writeln!(f, "}}")?;
|
writeln!(f, "}}")?;
|
||||||
|
@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::EnumEntry;
|
use crate::{
|
||||||
|
traits::{s, Section},
|
||||||
|
EnumEntry,
|
||||||
|
};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@ -30,7 +33,7 @@ pub struct TokenTypeHint {
|
|||||||
impl EnumEntry for TokenTypeHint {
|
impl EnumEntry for TokenTypeHint {
|
||||||
const URL: &'static str =
|
const URL: &'static str =
|
||||||
"https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv";
|
"https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["OAuthTokenTypeHint"];
|
const SECTIONS: &'static [Section] = &[s("OAuthTokenTypeHint", "OAuth Token Type Hint")];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("OAuthTokenTypeHint")
|
Some("OAuthTokenTypeHint")
|
||||||
@ -54,7 +57,10 @@ pub struct AuthorizationEndpointResponseType {
|
|||||||
|
|
||||||
impl EnumEntry for AuthorizationEndpointResponseType {
|
impl EnumEntry for AuthorizationEndpointResponseType {
|
||||||
const URL: &'static str = "https://www.iana.org/assignments/oauth-parameters/endpoint.csv";
|
const URL: &'static str = "https://www.iana.org/assignments/oauth-parameters/endpoint.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["OAuthAuthorizationEndpointResponseType"];
|
const SECTIONS: &'static [Section] = &[s(
|
||||||
|
"OAuthAuthorizationEndpointResponseType",
|
||||||
|
"OAuth Authorization Endpoint Response Type",
|
||||||
|
)];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("OAuthAuthorizationEndpointResponseType")
|
Some("OAuthAuthorizationEndpointResponseType")
|
||||||
@ -79,7 +85,10 @@ pub struct TokenEndpointAuthenticationMethod {
|
|||||||
impl EnumEntry for TokenEndpointAuthenticationMethod {
|
impl EnumEntry for TokenEndpointAuthenticationMethod {
|
||||||
const URL: &'static str =
|
const URL: &'static str =
|
||||||
"https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv";
|
"https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["OAuthTokenEndpointAuthenticationMethod"];
|
const SECTIONS: &'static [Section] = &[s(
|
||||||
|
"OAuthTokenEndpointAuthenticationMethod",
|
||||||
|
"OAuth Token Endpoint Authentication Method",
|
||||||
|
)];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("OAuthTokenEndpointAuthenticationMethod")
|
Some("OAuthTokenEndpointAuthenticationMethod")
|
||||||
@ -104,7 +113,8 @@ pub struct PkceCodeChallengeMethod {
|
|||||||
impl EnumEntry for PkceCodeChallengeMethod {
|
impl EnumEntry for PkceCodeChallengeMethod {
|
||||||
const URL: &'static str =
|
const URL: &'static str =
|
||||||
"https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv";
|
"https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv";
|
||||||
const SECTIONS: &'static [&'static str] = &["PkceCodeChallengeMethod"];
|
const SECTIONS: &'static [Section] =
|
||||||
|
&[s("PkceCodeChallengeMethod", "PKCE Code Challenge Method")];
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str> {
|
fn key(&self) -> Option<&'static str> {
|
||||||
Some("PkceCodeChallengeMethod")
|
Some("PkceCodeChallengeMethod")
|
||||||
|
@ -18,6 +18,21 @@ use convert_case::{Case, Casing};
|
|||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Section {
|
||||||
|
pub key: &'static str,
|
||||||
|
pub doc: &'static str,
|
||||||
|
pub url: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn s(key: &'static str, doc: &'static str) -> Section {
|
||||||
|
Section {
|
||||||
|
key,
|
||||||
|
doc,
|
||||||
|
url: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EnumMember {
|
pub struct EnumMember {
|
||||||
pub value: String,
|
pub value: String,
|
||||||
@ -28,7 +43,17 @@ pub struct EnumMember {
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait EnumEntry: DeserializeOwned + Send + Sync {
|
pub trait EnumEntry: DeserializeOwned + Send + Sync {
|
||||||
const URL: &'static str;
|
const URL: &'static str;
|
||||||
const SECTIONS: &'static [&'static str];
|
const SECTIONS: &'static [Section];
|
||||||
|
|
||||||
|
fn sections() -> Vec<Section> {
|
||||||
|
Self::SECTIONS
|
||||||
|
.iter()
|
||||||
|
.map(|s| Section {
|
||||||
|
url: Some(Self::URL),
|
||||||
|
..*s
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn key(&self) -> Option<&'static str>;
|
fn key(&self) -> Option<&'static str>;
|
||||||
fn name(&self) -> &str;
|
fn name(&self) -> &str;
|
||||||
|
@ -8,3 +8,4 @@ license = "Apache-2.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "1.0.133"
|
serde = "1.0.133"
|
||||||
schemars = { version = "0.8.8" }
|
schemars = { version = "0.8.8" }
|
||||||
|
parse-display = "0.5.3"
|
||||||
|
@ -14,292 +14,396 @@
|
|||||||
|
|
||||||
//! Enums from the "JSON Object Signing and Encryption" IANA registry
|
//! Enums from the "JSON Object Signing and Encryption" IANA registry
|
||||||
//! See <https://www.iana.org/assignments/jose/jose.xhtml>
|
//! See <https://www.iana.org/assignments/jose/jose.xhtml>
|
||||||
//!
|
|
||||||
//! Generated from:
|
|
||||||
//! - <https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/jose/web-encryption-compression-algorithms.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/jose/web-key-types.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/jose/web-key-use.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/jose/web-key-operations.csv>
|
|
||||||
|
|
||||||
// Do not edit this file manually
|
// Do not edit this file manually
|
||||||
|
|
||||||
|
use parse_display::{Display, FromStr};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Signature "alg" parameter
|
||||||
pub enum JsonWebSignatureAlgorithm {
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
|
pub enum JsonWebSignatureAlg {
|
||||||
/// HMAC using SHA-256
|
/// HMAC using SHA-256
|
||||||
#[serde(rename = "HS256")]
|
#[serde(rename = "HS256")]
|
||||||
|
#[display("HS256")]
|
||||||
Hs256,
|
Hs256,
|
||||||
|
|
||||||
/// HMAC using SHA-384
|
/// HMAC using SHA-384
|
||||||
#[serde(rename = "HS384")]
|
#[serde(rename = "HS384")]
|
||||||
|
#[display("HS384")]
|
||||||
Hs384,
|
Hs384,
|
||||||
|
|
||||||
/// HMAC using SHA-512
|
/// HMAC using SHA-512
|
||||||
#[serde(rename = "HS512")]
|
#[serde(rename = "HS512")]
|
||||||
|
#[display("HS512")]
|
||||||
Hs512,
|
Hs512,
|
||||||
|
|
||||||
/// RSASSA-PKCS1-v1_5 using SHA-256
|
/// RSASSA-PKCS1-v1_5 using SHA-256
|
||||||
#[serde(rename = "RS256")]
|
#[serde(rename = "RS256")]
|
||||||
|
#[display("RS256")]
|
||||||
Rs256,
|
Rs256,
|
||||||
|
|
||||||
/// RSASSA-PKCS1-v1_5 using SHA-384
|
/// RSASSA-PKCS1-v1_5 using SHA-384
|
||||||
#[serde(rename = "RS384")]
|
#[serde(rename = "RS384")]
|
||||||
|
#[display("RS384")]
|
||||||
Rs384,
|
Rs384,
|
||||||
|
|
||||||
/// RSASSA-PKCS1-v1_5 using SHA-512
|
/// RSASSA-PKCS1-v1_5 using SHA-512
|
||||||
#[serde(rename = "RS512")]
|
#[serde(rename = "RS512")]
|
||||||
|
#[display("RS512")]
|
||||||
Rs512,
|
Rs512,
|
||||||
|
|
||||||
/// ECDSA using P-256 and SHA-256
|
/// ECDSA using P-256 and SHA-256
|
||||||
#[serde(rename = "ES256")]
|
#[serde(rename = "ES256")]
|
||||||
|
#[display("ES256")]
|
||||||
Es256,
|
Es256,
|
||||||
|
|
||||||
/// ECDSA using P-384 and SHA-384
|
/// ECDSA using P-384 and SHA-384
|
||||||
#[serde(rename = "ES384")]
|
#[serde(rename = "ES384")]
|
||||||
|
#[display("ES384")]
|
||||||
Es384,
|
Es384,
|
||||||
|
|
||||||
/// ECDSA using P-521 and SHA-512
|
/// ECDSA using P-521 and SHA-512
|
||||||
#[serde(rename = "ES512")]
|
#[serde(rename = "ES512")]
|
||||||
|
#[display("ES512")]
|
||||||
Es512,
|
Es512,
|
||||||
|
|
||||||
/// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
|
/// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
|
||||||
#[serde(rename = "PS256")]
|
#[serde(rename = "PS256")]
|
||||||
|
#[display("PS256")]
|
||||||
Ps256,
|
Ps256,
|
||||||
|
|
||||||
/// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
|
/// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
|
||||||
#[serde(rename = "PS384")]
|
#[serde(rename = "PS384")]
|
||||||
|
#[display("PS384")]
|
||||||
Ps384,
|
Ps384,
|
||||||
|
|
||||||
/// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
|
/// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
|
||||||
#[serde(rename = "PS512")]
|
#[serde(rename = "PS512")]
|
||||||
|
#[display("PS512")]
|
||||||
Ps512,
|
Ps512,
|
||||||
|
|
||||||
/// No digital signature or MAC performed
|
/// No digital signature or MAC performed
|
||||||
#[serde(rename = "none")]
|
#[serde(rename = "none")]
|
||||||
|
#[display("none")]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
|
/// EdDSA signature algorithms
|
||||||
|
#[serde(rename = "EdDSA")]
|
||||||
|
#[display("EdDSA")]
|
||||||
|
EdDsa,
|
||||||
|
|
||||||
|
/// ECDSA using secp256k1 curve and SHA-256
|
||||||
|
#[serde(rename = "ES256K")]
|
||||||
|
#[display("ES256K")]
|
||||||
|
Es256K,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// JSON Web Encryption "alg" parameter
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
|
pub enum JsonWebEncryptionAlg {
|
||||||
/// RSAES-PKCS1-v1_5
|
/// RSAES-PKCS1-v1_5
|
||||||
#[serde(rename = "RSA1_5")]
|
#[serde(rename = "RSA1_5")]
|
||||||
|
#[display("RSA1_5")]
|
||||||
Rsa15,
|
Rsa15,
|
||||||
|
|
||||||
/// RSAES OAEP using default parameters
|
/// RSAES OAEP using default parameters
|
||||||
#[serde(rename = "RSA-OAEP")]
|
#[serde(rename = "RSA-OAEP")]
|
||||||
|
#[display("RSA-OAEP")]
|
||||||
RsaOaep,
|
RsaOaep,
|
||||||
|
|
||||||
/// RSAES OAEP using SHA-256 and MGF1 with SHA-256
|
/// RSAES OAEP using SHA-256 and MGF1 with SHA-256
|
||||||
#[serde(rename = "RSA-OAEP-256")]
|
#[serde(rename = "RSA-OAEP-256")]
|
||||||
|
#[display("RSA-OAEP-256")]
|
||||||
RsaOaep256,
|
RsaOaep256,
|
||||||
|
|
||||||
/// AES Key Wrap using 128-bit key
|
/// AES Key Wrap using 128-bit key
|
||||||
#[serde(rename = "A128KW")]
|
#[serde(rename = "A128KW")]
|
||||||
|
#[display("A128KW")]
|
||||||
A128Kw,
|
A128Kw,
|
||||||
|
|
||||||
/// AES Key Wrap using 192-bit key
|
/// AES Key Wrap using 192-bit key
|
||||||
#[serde(rename = "A192KW")]
|
#[serde(rename = "A192KW")]
|
||||||
|
#[display("A192KW")]
|
||||||
A192Kw,
|
A192Kw,
|
||||||
|
|
||||||
/// AES Key Wrap using 256-bit key
|
/// AES Key Wrap using 256-bit key
|
||||||
#[serde(rename = "A256KW")]
|
#[serde(rename = "A256KW")]
|
||||||
|
#[display("A256KW")]
|
||||||
A256Kw,
|
A256Kw,
|
||||||
|
|
||||||
/// Direct use of a shared symmetric key
|
/// Direct use of a shared symmetric key
|
||||||
#[serde(rename = "dir")]
|
#[serde(rename = "dir")]
|
||||||
|
#[display("dir")]
|
||||||
Dir,
|
Dir,
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF
|
/// ECDH-ES using Concat KDF
|
||||||
#[serde(rename = "ECDH-ES")]
|
#[serde(rename = "ECDH-ES")]
|
||||||
|
#[display("ECDH-ES")]
|
||||||
EcdhEs,
|
EcdhEs,
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF and "A128KW" wrapping
|
/// ECDH-ES using Concat KDF and "A128KW" wrapping
|
||||||
#[serde(rename = "ECDH-ES+A128KW")]
|
#[serde(rename = "ECDH-ES+A128KW")]
|
||||||
|
#[display("ECDH-ES+A128KW")]
|
||||||
EcdhEsA128Kw,
|
EcdhEsA128Kw,
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF and "A192KW" wrapping
|
/// ECDH-ES using Concat KDF and "A192KW" wrapping
|
||||||
#[serde(rename = "ECDH-ES+A192KW")]
|
#[serde(rename = "ECDH-ES+A192KW")]
|
||||||
|
#[display("ECDH-ES+A192KW")]
|
||||||
EcdhEsA192Kw,
|
EcdhEsA192Kw,
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF and "A256KW" wrapping
|
/// ECDH-ES using Concat KDF and "A256KW" wrapping
|
||||||
#[serde(rename = "ECDH-ES+A256KW")]
|
#[serde(rename = "ECDH-ES+A256KW")]
|
||||||
|
#[display("ECDH-ES+A256KW")]
|
||||||
EcdhEsA256Kw,
|
EcdhEsA256Kw,
|
||||||
|
|
||||||
/// Key wrapping with AES GCM using 128-bit key
|
/// Key wrapping with AES GCM using 128-bit key
|
||||||
#[serde(rename = "A128GCMKW")]
|
#[serde(rename = "A128GCMKW")]
|
||||||
|
#[display("A128GCMKW")]
|
||||||
A128Gcmkw,
|
A128Gcmkw,
|
||||||
|
|
||||||
/// Key wrapping with AES GCM using 192-bit key
|
/// Key wrapping with AES GCM using 192-bit key
|
||||||
#[serde(rename = "A192GCMKW")]
|
#[serde(rename = "A192GCMKW")]
|
||||||
|
#[display("A192GCMKW")]
|
||||||
A192Gcmkw,
|
A192Gcmkw,
|
||||||
|
|
||||||
/// Key wrapping with AES GCM using 256-bit key
|
/// Key wrapping with AES GCM using 256-bit key
|
||||||
#[serde(rename = "A256GCMKW")]
|
#[serde(rename = "A256GCMKW")]
|
||||||
|
#[display("A256GCMKW")]
|
||||||
A256Gcmkw,
|
A256Gcmkw,
|
||||||
|
|
||||||
/// PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
/// PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
||||||
#[serde(rename = "PBES2-HS256+A128KW")]
|
#[serde(rename = "PBES2-HS256+A128KW")]
|
||||||
|
#[display("PBES2-HS256+A128KW")]
|
||||||
Pbes2Hs256A128Kw,
|
Pbes2Hs256A128Kw,
|
||||||
|
|
||||||
/// PBES2 with HMAC SHA-384 and "A192KW" wrapping
|
/// PBES2 with HMAC SHA-384 and "A192KW" wrapping
|
||||||
#[serde(rename = "PBES2-HS384+A192KW")]
|
#[serde(rename = "PBES2-HS384+A192KW")]
|
||||||
|
#[display("PBES2-HS384+A192KW")]
|
||||||
Pbes2Hs384A192Kw,
|
Pbes2Hs384A192Kw,
|
||||||
|
|
||||||
/// PBES2 with HMAC SHA-512 and "A256KW" wrapping
|
/// PBES2 with HMAC SHA-512 and "A256KW" wrapping
|
||||||
#[serde(rename = "PBES2-HS512+A256KW")]
|
#[serde(rename = "PBES2-HS512+A256KW")]
|
||||||
|
#[display("PBES2-HS512+A256KW")]
|
||||||
Pbes2Hs512A256Kw,
|
Pbes2Hs512A256Kw,
|
||||||
|
|
||||||
/// EdDSA signature algorithms
|
|
||||||
#[serde(rename = "EdDSA")]
|
|
||||||
EdDsa,
|
|
||||||
|
|
||||||
/// RSA-OAEP using SHA-384 and MGF1 with SHA-384
|
/// RSA-OAEP using SHA-384 and MGF1 with SHA-384
|
||||||
#[serde(rename = "RSA-OAEP-384")]
|
#[serde(rename = "RSA-OAEP-384")]
|
||||||
|
#[display("RSA-OAEP-384")]
|
||||||
RsaOaep384,
|
RsaOaep384,
|
||||||
|
|
||||||
/// RSA-OAEP using SHA-512 and MGF1 with SHA-512
|
/// RSA-OAEP using SHA-512 and MGF1 with SHA-512
|
||||||
#[serde(rename = "RSA-OAEP-512")]
|
#[serde(rename = "RSA-OAEP-512")]
|
||||||
|
#[display("RSA-OAEP-512")]
|
||||||
RsaOaep512,
|
RsaOaep512,
|
||||||
|
|
||||||
/// ECDSA using secp256k1 curve and SHA-256
|
|
||||||
#[serde(rename = "ES256K")]
|
|
||||||
Es256K,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Encryption "enc" parameter
|
||||||
pub enum JsonWebEncryptionAlgorithm {
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
|
pub enum JsonWebEncryptionEnc {
|
||||||
/// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm
|
/// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm
|
||||||
#[serde(rename = "A128CBC-HS256")]
|
#[serde(rename = "A128CBC-HS256")]
|
||||||
|
#[display("A128CBC-HS256")]
|
||||||
A128CbcHs256,
|
A128CbcHs256,
|
||||||
|
|
||||||
/// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm
|
/// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm
|
||||||
#[serde(rename = "A192CBC-HS384")]
|
#[serde(rename = "A192CBC-HS384")]
|
||||||
|
#[display("A192CBC-HS384")]
|
||||||
A192CbcHs384,
|
A192CbcHs384,
|
||||||
|
|
||||||
/// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm
|
/// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm
|
||||||
#[serde(rename = "A256CBC-HS512")]
|
#[serde(rename = "A256CBC-HS512")]
|
||||||
|
#[display("A256CBC-HS512")]
|
||||||
A256CbcHs512,
|
A256CbcHs512,
|
||||||
|
|
||||||
/// AES GCM using 128-bit key
|
/// AES GCM using 128-bit key
|
||||||
#[serde(rename = "A128GCM")]
|
#[serde(rename = "A128GCM")]
|
||||||
|
#[display("A128GCM")]
|
||||||
A128Gcm,
|
A128Gcm,
|
||||||
|
|
||||||
/// AES GCM using 192-bit key
|
/// AES GCM using 192-bit key
|
||||||
#[serde(rename = "A192GCM")]
|
#[serde(rename = "A192GCM")]
|
||||||
|
#[display("A192GCM")]
|
||||||
A192Gcm,
|
A192Gcm,
|
||||||
|
|
||||||
/// AES GCM using 256-bit key
|
/// AES GCM using 256-bit key
|
||||||
#[serde(rename = "A256GCM")]
|
#[serde(rename = "A256GCM")]
|
||||||
|
#[display("A256GCM")]
|
||||||
A256Gcm,
|
A256Gcm,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Encryption Compression Algorithm
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-encryption-compression-algorithms.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum JsonWebEncryptionCompressionAlgorithm {
|
pub enum JsonWebEncryptionCompressionAlgorithm {
|
||||||
/// DEFLATE
|
/// DEFLATE
|
||||||
#[serde(rename = "DEF")]
|
#[serde(rename = "DEF")]
|
||||||
|
#[display("DEF")]
|
||||||
Def,
|
Def,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Key Type
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-key-types.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum JsonWebKeyType {
|
pub enum JsonWebKeyType {
|
||||||
/// Elliptic Curve
|
/// Elliptic Curve
|
||||||
#[serde(rename = "EC")]
|
#[serde(rename = "EC")]
|
||||||
|
#[display("EC")]
|
||||||
Ec,
|
Ec,
|
||||||
|
|
||||||
/// RSA
|
/// RSA
|
||||||
#[serde(rename = "RSA")]
|
#[serde(rename = "RSA")]
|
||||||
|
#[display("RSA")]
|
||||||
Rsa,
|
Rsa,
|
||||||
|
|
||||||
/// Octet sequence
|
/// Octet sequence
|
||||||
#[serde(rename = "oct")]
|
#[serde(rename = "oct")]
|
||||||
|
#[display("oct")]
|
||||||
Oct,
|
Oct,
|
||||||
|
|
||||||
/// Octet string key pairs
|
/// Octet string key pairs
|
||||||
#[serde(rename = "OKP")]
|
#[serde(rename = "OKP")]
|
||||||
|
#[display("OKP")]
|
||||||
Okp,
|
Okp,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Key EC Elliptic Curve
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum JsonWebKeyEcEllipticCurve {
|
pub enum JsonWebKeyEcEllipticCurve {
|
||||||
/// P-256 Curve
|
/// P-256 Curve
|
||||||
#[serde(rename = "P-256")]
|
#[serde(rename = "P-256")]
|
||||||
|
#[display("P-256")]
|
||||||
P256,
|
P256,
|
||||||
|
|
||||||
/// P-384 Curve
|
/// P-384 Curve
|
||||||
#[serde(rename = "P-384")]
|
#[serde(rename = "P-384")]
|
||||||
|
#[display("P-384")]
|
||||||
P384,
|
P384,
|
||||||
|
|
||||||
/// P-521 Curve
|
/// P-521 Curve
|
||||||
#[serde(rename = "P-521")]
|
#[serde(rename = "P-521")]
|
||||||
|
#[display("P-521")]
|
||||||
P521,
|
P521,
|
||||||
|
|
||||||
/// SECG secp256k1 curve
|
/// SECG secp256k1 curve
|
||||||
#[serde(rename = "secp256k1")]
|
#[serde(rename = "secp256k1")]
|
||||||
|
#[display("secp256k1")]
|
||||||
Secp256K1,
|
Secp256K1,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Key OKP Elliptic Curve
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum JsonWebKeyOkpEllipticCurve {
|
pub enum JsonWebKeyOkpEllipticCurve {
|
||||||
/// Ed25519 signature algorithm key pairs
|
/// Ed25519 signature algorithm key pairs
|
||||||
#[serde(rename = "Ed25519")]
|
#[serde(rename = "Ed25519")]
|
||||||
|
#[display("Ed25519")]
|
||||||
Ed25519,
|
Ed25519,
|
||||||
|
|
||||||
/// Ed448 signature algorithm key pairs
|
/// Ed448 signature algorithm key pairs
|
||||||
#[serde(rename = "Ed448")]
|
#[serde(rename = "Ed448")]
|
||||||
|
#[display("Ed448")]
|
||||||
Ed448,
|
Ed448,
|
||||||
|
|
||||||
/// X25519 function key pairs
|
/// X25519 function key pairs
|
||||||
#[serde(rename = "X25519")]
|
#[serde(rename = "X25519")]
|
||||||
|
#[display("X25519")]
|
||||||
X25519,
|
X25519,
|
||||||
|
|
||||||
/// X448 function key pairs
|
/// X448 function key pairs
|
||||||
#[serde(rename = "X448")]
|
#[serde(rename = "X448")]
|
||||||
|
#[display("X448")]
|
||||||
X448,
|
X448,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Key Use
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-key-use.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum JsonWebKeyUse {
|
pub enum JsonWebKeyUse {
|
||||||
/// Digital Signature or MAC
|
/// Digital Signature or MAC
|
||||||
#[serde(rename = "sig")]
|
#[serde(rename = "sig")]
|
||||||
|
#[display("sig")]
|
||||||
Sig,
|
Sig,
|
||||||
|
|
||||||
/// Encryption
|
/// Encryption
|
||||||
#[serde(rename = "enc")]
|
#[serde(rename = "enc")]
|
||||||
|
#[display("enc")]
|
||||||
Enc,
|
Enc,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// JSON Web Key Operation
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/jose/web-key-operations.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum JsonWebKeyOperation {
|
pub enum JsonWebKeyOperation {
|
||||||
/// Compute digital signature or MAC
|
/// Compute digital signature or MAC
|
||||||
#[serde(rename = "sign")]
|
#[serde(rename = "sign")]
|
||||||
|
#[display("sign")]
|
||||||
Sign,
|
Sign,
|
||||||
|
|
||||||
/// Verify digital signature or MAC
|
/// Verify digital signature or MAC
|
||||||
#[serde(rename = "verify")]
|
#[serde(rename = "verify")]
|
||||||
|
#[display("verify")]
|
||||||
Verify,
|
Verify,
|
||||||
|
|
||||||
/// Encrypt content
|
/// Encrypt content
|
||||||
#[serde(rename = "encrypt")]
|
#[serde(rename = "encrypt")]
|
||||||
|
#[display("encrypt")]
|
||||||
Encrypt,
|
Encrypt,
|
||||||
|
|
||||||
/// Decrypt content and validate decryption, if applicable
|
/// Decrypt content and validate decryption, if applicable
|
||||||
#[serde(rename = "decrypt")]
|
#[serde(rename = "decrypt")]
|
||||||
|
#[display("decrypt")]
|
||||||
Decrypt,
|
Decrypt,
|
||||||
|
|
||||||
/// Encrypt key
|
/// Encrypt key
|
||||||
#[serde(rename = "wrapKey")]
|
#[serde(rename = "wrapKey")]
|
||||||
|
#[display("wrapKey")]
|
||||||
WrapKey,
|
WrapKey,
|
||||||
|
|
||||||
/// Decrypt key and validate decryption, if applicable
|
/// Decrypt key and validate decryption, if applicable
|
||||||
#[serde(rename = "unwrapKey")]
|
#[serde(rename = "unwrapKey")]
|
||||||
|
#[display("unwrapKey")]
|
||||||
UnwrapKey,
|
UnwrapKey,
|
||||||
|
|
||||||
/// Derive key
|
/// Derive key
|
||||||
#[serde(rename = "deriveKey")]
|
#[serde(rename = "deriveKey")]
|
||||||
|
#[display("deriveKey")]
|
||||||
DeriveKey,
|
DeriveKey,
|
||||||
|
|
||||||
/// Derive bits not to be used as a key
|
/// Derive bits not to be used as a key
|
||||||
#[serde(rename = "deriveBits")]
|
#[serde(rename = "deriveBits")]
|
||||||
|
#[display("deriveBits")]
|
||||||
DeriveBits,
|
DeriveBits,
|
||||||
}
|
}
|
||||||
|
@ -14,86 +14,121 @@
|
|||||||
|
|
||||||
//! Enums from the "OAuth Parameters" IANA registry
|
//! Enums from the "OAuth Parameters" IANA registry
|
||||||
//! See <https://www.iana.org/assignments/jose/jose.xhtml>
|
//! See <https://www.iana.org/assignments/jose/jose.xhtml>
|
||||||
//!
|
|
||||||
//! Generated from:
|
|
||||||
//! - <https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/oauth-parameters/endpoint.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv>
|
|
||||||
//! - <https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv>
|
|
||||||
|
|
||||||
// Do not edit this file manually
|
// Do not edit this file manually
|
||||||
|
|
||||||
|
use parse_display::{Display, FromStr};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// OAuth Token Type Hint
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum OAuthTokenTypeHint {
|
pub enum OAuthTokenTypeHint {
|
||||||
#[serde(rename = "access_token")]
|
#[serde(rename = "access_token")]
|
||||||
|
#[display("access_token")]
|
||||||
AccessToken,
|
AccessToken,
|
||||||
|
|
||||||
#[serde(rename = "refresh_token")]
|
#[serde(rename = "refresh_token")]
|
||||||
|
#[display("refresh_token")]
|
||||||
RefreshToken,
|
RefreshToken,
|
||||||
|
|
||||||
#[serde(rename = "pct")]
|
#[serde(rename = "pct")]
|
||||||
|
#[display("pct")]
|
||||||
Pct,
|
Pct,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// OAuth Authorization Endpoint Response Type
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/oauth-parameters/endpoint.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum OAuthAuthorizationEndpointResponseType {
|
pub enum OAuthAuthorizationEndpointResponseType {
|
||||||
#[serde(rename = "code")]
|
#[serde(rename = "code")]
|
||||||
|
#[display("code")]
|
||||||
Code,
|
Code,
|
||||||
|
|
||||||
#[serde(rename = "code id_token")]
|
#[serde(rename = "code id_token")]
|
||||||
|
#[display("code id_token")]
|
||||||
CodeIdToken,
|
CodeIdToken,
|
||||||
|
|
||||||
#[serde(rename = "code id_token token")]
|
#[serde(rename = "code id_token token")]
|
||||||
|
#[display("code id_token token")]
|
||||||
CodeIdTokenToken,
|
CodeIdTokenToken,
|
||||||
|
|
||||||
#[serde(rename = "code token")]
|
#[serde(rename = "code token")]
|
||||||
|
#[display("code token")]
|
||||||
CodeToken,
|
CodeToken,
|
||||||
|
|
||||||
#[serde(rename = "id_token")]
|
#[serde(rename = "id_token")]
|
||||||
|
#[display("id_token")]
|
||||||
IdToken,
|
IdToken,
|
||||||
|
|
||||||
#[serde(rename = "id_token token")]
|
#[serde(rename = "id_token token")]
|
||||||
|
#[display("id_token token")]
|
||||||
IdTokenToken,
|
IdTokenToken,
|
||||||
|
|
||||||
#[serde(rename = "none")]
|
#[serde(rename = "none")]
|
||||||
|
#[display("none")]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
#[serde(rename = "token")]
|
#[serde(rename = "token")]
|
||||||
|
#[display("token")]
|
||||||
Token,
|
Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// OAuth Token Endpoint Authentication Method
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum OAuthTokenEndpointAuthenticationMethod {
|
pub enum OAuthTokenEndpointAuthenticationMethod {
|
||||||
#[serde(rename = "none")]
|
#[serde(rename = "none")]
|
||||||
|
#[display("none")]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
#[serde(rename = "client_secret_post")]
|
#[serde(rename = "client_secret_post")]
|
||||||
|
#[display("client_secret_post")]
|
||||||
ClientSecretPost,
|
ClientSecretPost,
|
||||||
|
|
||||||
#[serde(rename = "client_secret_basic")]
|
#[serde(rename = "client_secret_basic")]
|
||||||
|
#[display("client_secret_basic")]
|
||||||
ClientSecretBasic,
|
ClientSecretBasic,
|
||||||
|
|
||||||
#[serde(rename = "client_secret_jwt")]
|
#[serde(rename = "client_secret_jwt")]
|
||||||
|
#[display("client_secret_jwt")]
|
||||||
ClientSecretJwt,
|
ClientSecretJwt,
|
||||||
|
|
||||||
#[serde(rename = "private_key_jwt")]
|
#[serde(rename = "private_key_jwt")]
|
||||||
|
#[display("private_key_jwt")]
|
||||||
PrivateKeyJwt,
|
PrivateKeyJwt,
|
||||||
|
|
||||||
#[serde(rename = "tls_client_auth")]
|
#[serde(rename = "tls_client_auth")]
|
||||||
|
#[display("tls_client_auth")]
|
||||||
TlsClientAuth,
|
TlsClientAuth,
|
||||||
|
|
||||||
#[serde(rename = "self_signed_tls_client_auth")]
|
#[serde(rename = "self_signed_tls_client_auth")]
|
||||||
|
#[display("self_signed_tls_client_auth")]
|
||||||
SelfSignedTlsClientAuth,
|
SelfSignedTlsClientAuth,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
/// PKCE Code Challenge Method
|
||||||
|
///
|
||||||
|
/// Source: <https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv>
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
pub enum PkceCodeChallengeMethod {
|
pub enum PkceCodeChallengeMethod {
|
||||||
#[serde(rename = "plain")]
|
#[serde(rename = "plain")]
|
||||||
|
#[display("plain")]
|
||||||
Plain,
|
Plain,
|
||||||
|
|
||||||
#[serde(rename = "S256")]
|
#[serde(rename = "S256")]
|
||||||
|
#[display("S256")]
|
||||||
S256,
|
S256,
|
||||||
}
|
}
|
||||||
|
@ -1,296 +0,0 @@
|
|||||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
//! Generated enums from the IANA JOSE registry
|
|
||||||
//!
|
|
||||||
//! <https://www.iana.org/assignments/jose/jose.xhtml>
|
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
|
||||||
pub enum JsonWebSignatureAlgorithm {
|
|
||||||
/// HMAC using SHA-256
|
|
||||||
#[serde(rename = "HS256")]
|
|
||||||
Hs256,
|
|
||||||
|
|
||||||
/// HMAC using SHA-384
|
|
||||||
#[serde(rename = "HS384")]
|
|
||||||
Hs384,
|
|
||||||
|
|
||||||
/// HMAC using SHA-512
|
|
||||||
#[serde(rename = "HS512")]
|
|
||||||
Hs512,
|
|
||||||
|
|
||||||
/// RSASSA-PKCS1-v1_5 using SHA-256
|
|
||||||
#[serde(rename = "RS256")]
|
|
||||||
Rs256,
|
|
||||||
|
|
||||||
/// RSASSA-PKCS1-v1_5 using SHA-384
|
|
||||||
#[serde(rename = "RS384")]
|
|
||||||
Rs384,
|
|
||||||
|
|
||||||
/// RSASSA-PKCS1-v1_5 using SHA-512
|
|
||||||
#[serde(rename = "RS512")]
|
|
||||||
Rs512,
|
|
||||||
|
|
||||||
/// ECDSA using P-256 and SHA-256
|
|
||||||
#[serde(rename = "ES256")]
|
|
||||||
Es256,
|
|
||||||
|
|
||||||
/// ECDSA using P-384 and SHA-384
|
|
||||||
#[serde(rename = "ES384")]
|
|
||||||
Es384,
|
|
||||||
|
|
||||||
/// ECDSA using P-521 and SHA-512
|
|
||||||
#[serde(rename = "ES512")]
|
|
||||||
Es512,
|
|
||||||
|
|
||||||
/// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
|
|
||||||
#[serde(rename = "PS256")]
|
|
||||||
Ps256,
|
|
||||||
|
|
||||||
/// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
|
|
||||||
#[serde(rename = "PS384")]
|
|
||||||
Ps384,
|
|
||||||
|
|
||||||
/// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
|
|
||||||
#[serde(rename = "PS512")]
|
|
||||||
Ps512,
|
|
||||||
|
|
||||||
/// No digital signature or MAC performed
|
|
||||||
#[serde(rename = "none")]
|
|
||||||
None,
|
|
||||||
|
|
||||||
/// RSAES-PKCS1-v1_5
|
|
||||||
#[serde(rename = "RSA1_5")]
|
|
||||||
Rsa15,
|
|
||||||
|
|
||||||
/// RSAES OAEP using default parameters
|
|
||||||
#[serde(rename = "RSA-OAEP")]
|
|
||||||
RsaOaep,
|
|
||||||
|
|
||||||
/// RSAES OAEP using SHA-256 and MGF1 with SHA-256
|
|
||||||
#[serde(rename = "RSA-OAEP-256")]
|
|
||||||
RsaOaep256,
|
|
||||||
|
|
||||||
/// AES Key Wrap using 128-bit key
|
|
||||||
#[serde(rename = "A128KW")]
|
|
||||||
A128Kw,
|
|
||||||
|
|
||||||
/// AES Key Wrap using 192-bit key
|
|
||||||
#[serde(rename = "A192KW")]
|
|
||||||
A192Kw,
|
|
||||||
|
|
||||||
/// AES Key Wrap using 256-bit key
|
|
||||||
#[serde(rename = "A256KW")]
|
|
||||||
A256Kw,
|
|
||||||
|
|
||||||
/// Direct use of a shared symmetric key
|
|
||||||
#[serde(rename = "dir")]
|
|
||||||
Dir,
|
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF
|
|
||||||
#[serde(rename = "ECDH-ES")]
|
|
||||||
EcdhEs,
|
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF and "A128KW" wrapping
|
|
||||||
#[serde(rename = "ECDH-ES+A128KW")]
|
|
||||||
EcdhEsA128Kw,
|
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF and "A192KW" wrapping
|
|
||||||
#[serde(rename = "ECDH-ES+A192KW")]
|
|
||||||
EcdhEsA192Kw,
|
|
||||||
|
|
||||||
/// ECDH-ES using Concat KDF and "A256KW" wrapping
|
|
||||||
#[serde(rename = "ECDH-ES+A256KW")]
|
|
||||||
EcdhEsA256Kw,
|
|
||||||
|
|
||||||
/// Key wrapping with AES GCM using 128-bit key
|
|
||||||
#[serde(rename = "A128GCMKW")]
|
|
||||||
A128Gcmkw,
|
|
||||||
|
|
||||||
/// Key wrapping with AES GCM using 192-bit key
|
|
||||||
#[serde(rename = "A192GCMKW")]
|
|
||||||
A192Gcmkw,
|
|
||||||
|
|
||||||
/// Key wrapping with AES GCM using 256-bit key
|
|
||||||
#[serde(rename = "A256GCMKW")]
|
|
||||||
A256Gcmkw,
|
|
||||||
|
|
||||||
/// PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
|
||||||
#[serde(rename = "PBES2-HS256+A128KW")]
|
|
||||||
Pbes2Hs256A128Kw,
|
|
||||||
|
|
||||||
/// PBES2 with HMAC SHA-384 and "A192KW" wrapping
|
|
||||||
#[serde(rename = "PBES2-HS384+A192KW")]
|
|
||||||
Pbes2Hs384A192Kw,
|
|
||||||
|
|
||||||
/// PBES2 with HMAC SHA-512 and "A256KW" wrapping
|
|
||||||
#[serde(rename = "PBES2-HS512+A256KW")]
|
|
||||||
Pbes2Hs512A256Kw,
|
|
||||||
|
|
||||||
/// EdDSA signature algorithms
|
|
||||||
#[serde(rename = "EdDSA")]
|
|
||||||
EdDsa,
|
|
||||||
|
|
||||||
/// RSA-OAEP using SHA-384 and MGF1 with SHA-384
|
|
||||||
#[serde(rename = "RSA-OAEP-384")]
|
|
||||||
RsaOaep384,
|
|
||||||
|
|
||||||
/// RSA-OAEP using SHA-512 and MGF1 with SHA-512
|
|
||||||
#[serde(rename = "RSA-OAEP-512")]
|
|
||||||
RsaOaep512,
|
|
||||||
|
|
||||||
/// ECDSA using secp256k1 curve and SHA-256
|
|
||||||
#[serde(rename = "ES256K")]
|
|
||||||
Es256K,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub enum JsonWebEncryptionAlgorithm {
|
|
||||||
/// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm
|
|
||||||
#[serde(rename = "A128CBC-HS256")]
|
|
||||||
A128CbcHs256,
|
|
||||||
|
|
||||||
/// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm
|
|
||||||
#[serde(rename = "A192CBC-HS384")]
|
|
||||||
A192CbcHs384,
|
|
||||||
|
|
||||||
/// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm
|
|
||||||
#[serde(rename = "A256CBC-HS512")]
|
|
||||||
A256CbcHs512,
|
|
||||||
|
|
||||||
/// AES GCM using 128-bit key
|
|
||||||
#[serde(rename = "A128GCM")]
|
|
||||||
A128Gcm,
|
|
||||||
|
|
||||||
/// AES GCM using 192-bit key
|
|
||||||
#[serde(rename = "A192GCM")]
|
|
||||||
A192Gcm,
|
|
||||||
|
|
||||||
/// AES GCM using 256-bit key
|
|
||||||
#[serde(rename = "A256GCM")]
|
|
||||||
A256Gcm,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub enum JsonWebEncryptionCompressionAlgorithm {
|
|
||||||
/// DEFLATE
|
|
||||||
#[serde(rename = "DEF")]
|
|
||||||
Def,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub enum JsonWebKeyType {
|
|
||||||
/// Elliptic Curve
|
|
||||||
#[serde(rename = "EC")]
|
|
||||||
Ec,
|
|
||||||
|
|
||||||
/// RSA
|
|
||||||
#[serde(rename = "RSA")]
|
|
||||||
Rsa,
|
|
||||||
|
|
||||||
/// Octet sequence
|
|
||||||
#[serde(rename = "oct")]
|
|
||||||
Oct,
|
|
||||||
|
|
||||||
/// Octet string key pairs
|
|
||||||
#[serde(rename = "OKP")]
|
|
||||||
Okp,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
|
||||||
pub enum JsonWebKeyEcEllipticCurve {
|
|
||||||
/// P-256 Curve
|
|
||||||
#[serde(rename = "P-256")]
|
|
||||||
P256,
|
|
||||||
|
|
||||||
/// P-384 Curve
|
|
||||||
#[serde(rename = "P-384")]
|
|
||||||
P384,
|
|
||||||
|
|
||||||
/// P-521 Curve
|
|
||||||
#[serde(rename = "P-521")]
|
|
||||||
P521,
|
|
||||||
|
|
||||||
/// SECG secp256k1 curve
|
|
||||||
#[serde(rename = "secp256k1")]
|
|
||||||
Secp256K1,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
|
||||||
pub enum JsonWebKeyOkpEllipticCurve {
|
|
||||||
/// Ed25519 signature algorithm key pairs
|
|
||||||
#[serde(rename = "Ed25519")]
|
|
||||||
Ed25519,
|
|
||||||
|
|
||||||
/// Ed448 signature algorithm key pairs
|
|
||||||
#[serde(rename = "Ed448")]
|
|
||||||
Ed448,
|
|
||||||
|
|
||||||
/// X25519 function key pairs
|
|
||||||
#[serde(rename = "X25519")]
|
|
||||||
X25519,
|
|
||||||
|
|
||||||
/// X448 function key pairs
|
|
||||||
#[serde(rename = "X448")]
|
|
||||||
X448,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
|
||||||
pub enum JsonWebKeyUse {
|
|
||||||
/// Digital Signature or MAC
|
|
||||||
#[serde(rename = "sig")]
|
|
||||||
Sig,
|
|
||||||
|
|
||||||
/// Encryption
|
|
||||||
#[serde(rename = "enc")]
|
|
||||||
Enc,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
|
||||||
pub enum JsonWebKeyOperation {
|
|
||||||
/// Compute digital signature or MAC
|
|
||||||
#[serde(rename = "sign")]
|
|
||||||
Sign,
|
|
||||||
|
|
||||||
/// Verify digital signature or MAC
|
|
||||||
#[serde(rename = "verify")]
|
|
||||||
Verify,
|
|
||||||
|
|
||||||
/// Encrypt content
|
|
||||||
#[serde(rename = "encrypt")]
|
|
||||||
Encrypt,
|
|
||||||
|
|
||||||
/// Decrypt content and validate decryption, if applicable
|
|
||||||
#[serde(rename = "decrypt")]
|
|
||||||
Decrypt,
|
|
||||||
|
|
||||||
/// Encrypt key
|
|
||||||
#[serde(rename = "wrapKey")]
|
|
||||||
WrapKey,
|
|
||||||
|
|
||||||
/// Decrypt key and validate decryption, if applicable
|
|
||||||
#[serde(rename = "unwrapKey")]
|
|
||||||
UnwrapKey,
|
|
||||||
|
|
||||||
/// Derive key
|
|
||||||
#[serde(rename = "deriveKey")]
|
|
||||||
DeriveKey,
|
|
||||||
|
|
||||||
/// Derive bits not to be used as a key
|
|
||||||
#[serde(rename = "deriveBits")]
|
|
||||||
DeriveBits,
|
|
||||||
}
|
|
@ -15,6 +15,10 @@
|
|||||||
//! Ref: <https://www.rfc-editor.org/rfc/rfc7517.html>
|
//! Ref: <https://www.rfc-editor.org/rfc/rfc7517.html>
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
|
use mas_iana::jose::{
|
||||||
|
JsonWebKeyEcEllipticCurve, JsonWebKeyOkpEllipticCurve, JsonWebKeyOperation, JsonWebKeyType,
|
||||||
|
JsonWebKeyUse, JsonWebSignatureAlg,
|
||||||
|
};
|
||||||
use p256::NistP256;
|
use p256::NistP256;
|
||||||
use rsa::{BigUint, PublicKeyParts};
|
use rsa::{BigUint, PublicKeyParts};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
@ -26,14 +30,6 @@ use serde_with::{
|
|||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
iana::{
|
|
||||||
JsonWebKeyEcEllipticCurve, JsonWebKeyOkpEllipticCurve, JsonWebKeyOperation, JsonWebKeyUse,
|
|
||||||
JsonWebSignatureAlgorithm,
|
|
||||||
},
|
|
||||||
JsonWebKeyType,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
@ -48,7 +44,7 @@ pub struct JsonWebKey {
|
|||||||
key_ops: Option<Vec<JsonWebKeyOperation>>,
|
key_ops: Option<Vec<JsonWebKeyOperation>>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
alg: Option<JsonWebSignatureAlgorithm>,
|
alg: Option<JsonWebSignatureAlg>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
kid: Option<String>,
|
kid: Option<String>,
|
||||||
@ -102,7 +98,7 @@ impl JsonWebKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_alg(mut self, alg: JsonWebSignatureAlgorithm) -> Self {
|
pub fn with_alg(mut self, alg: JsonWebSignatureAlg) -> Self {
|
||||||
self.alg = Some(alg);
|
self.alg = Some(alg);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use base64ct::{Base64UrlUnpadded, Encoding};
|
use base64ct::{Base64UrlUnpadded, Encoding};
|
||||||
|
use mas_iana::jose::{
|
||||||
|
JsonWebEncryptionCompressionAlgorithm, JsonWebEncryptionEnc, JsonWebSignatureAlg,
|
||||||
|
};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use serde_with::{
|
use serde_with::{
|
||||||
base64::{Base64, Standard, UrlSafe},
|
base64::{Base64, Standard, UrlSafe},
|
||||||
@ -23,23 +26,16 @@ use serde_with::{
|
|||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{jwk::JsonWebKey, SigningKeystore, VerifyingKeystore};
|
||||||
iana::{
|
|
||||||
JsonWebEncryptionAlgorithm, JsonWebEncryptionCompressionAlgorithm,
|
|
||||||
JsonWebSignatureAlgorithm,
|
|
||||||
},
|
|
||||||
jwk::JsonWebKey,
|
|
||||||
SigningKeystore, VerifyingKeystore,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct JwtHeader {
|
pub struct JwtHeader {
|
||||||
alg: JsonWebSignatureAlgorithm,
|
alg: JsonWebSignatureAlg,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
enc: Option<JsonWebEncryptionAlgorithm>,
|
enc: Option<JsonWebEncryptionEnc>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
jku: Option<Url>,
|
jku: Option<Url>,
|
||||||
@ -85,7 +81,7 @@ impl JwtHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(alg: JsonWebSignatureAlgorithm) -> Self {
|
pub fn new(alg: JsonWebSignatureAlg) -> Self {
|
||||||
Self {
|
Self {
|
||||||
alg,
|
alg,
|
||||||
enc: None,
|
enc: None,
|
||||||
@ -104,7 +100,7 @@ impl JwtHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn alg(&self) -> JsonWebSignatureAlgorithm {
|
pub fn alg(&self) -> JsonWebSignatureAlg {
|
||||||
self.alg
|
self.alg
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +250,7 @@ mod tests {
|
|||||||
jwt.decode_and_verify(&store).await.unwrap();
|
jwt.decode_and_verify(&store).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(jwt.header.typ, Some("JWT".to_string()));
|
assert_eq!(jwt.header.typ, Some("JWT".to_string()));
|
||||||
assert_eq!(jwt.header.alg, JsonWebSignatureAlgorithm::Hs256);
|
assert_eq!(jwt.header.alg, JsonWebSignatureAlg::Hs256);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
jwt.payload,
|
jwt.payload,
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
|
@ -18,15 +18,13 @@ use anyhow::bail;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use digest::Digest;
|
use digest::Digest;
|
||||||
|
use mas_iana::jose::{JsonWebKeyType, JsonWebSignatureAlg};
|
||||||
use rsa::{PublicKey, RsaPublicKey};
|
use rsa::{PublicKey, RsaPublicKey};
|
||||||
use sha2::{Sha256, Sha384, Sha512};
|
use sha2::{Sha256, Sha384, Sha512};
|
||||||
use signature::{Signature, Verifier};
|
use signature::{Signature, Verifier};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use crate::{
|
use crate::{ExportJwks, JsonWebKeySet, JwtHeader, VerifyingKeystore};
|
||||||
ExportJwks, JsonWebKeySet, JsonWebKeyType, JsonWebSignatureAlgorithm, JwtHeader,
|
|
||||||
VerifyingKeystore,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct StaticJwksStore {
|
pub struct StaticJwksStore {
|
||||||
key_set: JsonWebKeySet,
|
key_set: JsonWebKeySet,
|
||||||
@ -96,7 +94,7 @@ impl VerifyingKeystore for &StaticJwksStore {
|
|||||||
.ok_or_else(|| anyhow::anyhow!("missing kid"))?
|
.ok_or_else(|| anyhow::anyhow!("missing kid"))?
|
||||||
.to_string();
|
.to_string();
|
||||||
match header.alg() {
|
match header.alg() {
|
||||||
JsonWebSignatureAlgorithm::Rs256 => {
|
JsonWebSignatureAlg::Rs256 => {
|
||||||
let key = self.find_rsa_key(kid)?;
|
let key = self.find_rsa_key(kid)?;
|
||||||
|
|
||||||
let digest = {
|
let digest = {
|
||||||
@ -112,7 +110,7 @@ impl VerifyingKeystore for &StaticJwksStore {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Rs384 => {
|
JsonWebSignatureAlg::Rs384 => {
|
||||||
let key = self.find_rsa_key(kid)?;
|
let key = self.find_rsa_key(kid)?;
|
||||||
|
|
||||||
let digest = {
|
let digest = {
|
||||||
@ -128,7 +126,7 @@ impl VerifyingKeystore for &StaticJwksStore {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Rs512 => {
|
JsonWebSignatureAlg::Rs512 => {
|
||||||
let key = self.find_rsa_key(kid)?;
|
let key = self.find_rsa_key(kid)?;
|
||||||
|
|
||||||
let digest = {
|
let digest = {
|
||||||
@ -144,7 +142,7 @@ impl VerifyingKeystore for &StaticJwksStore {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Es256 => {
|
JsonWebSignatureAlg::Es256 => {
|
||||||
let key = self.find_ecdsa_key(kid)?;
|
let key = self.find_ecdsa_key(kid)?;
|
||||||
|
|
||||||
let signature = ecdsa::Signature::from_bytes(signature)?;
|
let signature = ecdsa::Signature::from_bytes(signature)?;
|
||||||
|
@ -17,10 +17,11 @@ use std::collections::HashSet;
|
|||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
|
use mas_iana::jose::JsonWebSignatureAlg;
|
||||||
use sha2::{Sha256, Sha384, Sha512};
|
use sha2::{Sha256, Sha384, Sha512};
|
||||||
|
|
||||||
use super::{SigningKeystore, VerifyingKeystore};
|
use super::{SigningKeystore, VerifyingKeystore};
|
||||||
use crate::{JsonWebSignatureAlgorithm, JwtHeader};
|
use crate::JwtHeader;
|
||||||
|
|
||||||
pub struct SharedSecret<'a> {
|
pub struct SharedSecret<'a> {
|
||||||
inner: &'a [u8],
|
inner: &'a [u8],
|
||||||
@ -36,22 +37,20 @@ impl<'a> SharedSecret<'a> {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<'a> SigningKeystore for &SharedSecret<'a> {
|
impl<'a> SigningKeystore for &SharedSecret<'a> {
|
||||||
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlgorithm> {
|
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlg> {
|
||||||
let mut algorithms = HashSet::with_capacity(3);
|
let mut algorithms = HashSet::with_capacity(3);
|
||||||
|
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Hs256);
|
algorithms.insert(JsonWebSignatureAlg::Hs256);
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Hs384);
|
algorithms.insert(JsonWebSignatureAlg::Hs384);
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Hs512);
|
algorithms.insert(JsonWebSignatureAlg::Hs512);
|
||||||
|
|
||||||
algorithms
|
algorithms
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader> {
|
async fn prepare_header(self, alg: JsonWebSignatureAlg) -> anyhow::Result<JwtHeader> {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
alg,
|
alg,
|
||||||
JsonWebSignatureAlgorithm::Hs256
|
JsonWebSignatureAlg::Hs256 | JsonWebSignatureAlg::Hs384 | JsonWebSignatureAlg::Hs512,
|
||||||
| JsonWebSignatureAlgorithm::Hs384
|
|
||||||
| JsonWebSignatureAlgorithm::Hs512,
|
|
||||||
) {
|
) {
|
||||||
bail!("unsupported algorithm")
|
bail!("unsupported algorithm")
|
||||||
}
|
}
|
||||||
@ -63,19 +62,19 @@ impl<'a> SigningKeystore for &SharedSecret<'a> {
|
|||||||
// TODO: do the signing in a blocking task
|
// TODO: do the signing in a blocking task
|
||||||
// TODO: should we bail out if the key is too small?
|
// TODO: should we bail out if the key is too small?
|
||||||
let signature = match header.alg() {
|
let signature = match header.alg() {
|
||||||
JsonWebSignatureAlgorithm::Hs256 => {
|
JsonWebSignatureAlg::Hs256 => {
|
||||||
let mut mac = Hmac::<Sha256>::new_from_slice(self.inner)?;
|
let mut mac = Hmac::<Sha256>::new_from_slice(self.inner)?;
|
||||||
mac.update(msg);
|
mac.update(msg);
|
||||||
mac.finalize().into_bytes().to_vec()
|
mac.finalize().into_bytes().to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Hs384 => {
|
JsonWebSignatureAlg::Hs384 => {
|
||||||
let mut mac = Hmac::<Sha384>::new_from_slice(self.inner)?;
|
let mut mac = Hmac::<Sha384>::new_from_slice(self.inner)?;
|
||||||
mac.update(msg);
|
mac.update(msg);
|
||||||
mac.finalize().into_bytes().to_vec()
|
mac.finalize().into_bytes().to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Hs512 => {
|
JsonWebSignatureAlg::Hs512 => {
|
||||||
let mut mac = Hmac::<Sha512>::new_from_slice(self.inner)?;
|
let mut mac = Hmac::<Sha512>::new_from_slice(self.inner)?;
|
||||||
mac.update(msg);
|
mac.update(msg);
|
||||||
mac.finalize().into_bytes().to_vec()
|
mac.finalize().into_bytes().to_vec()
|
||||||
@ -98,19 +97,19 @@ impl<'a> VerifyingKeystore for &SharedSecret<'a> {
|
|||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
// TODO: do the verification in a blocking task
|
// TODO: do the verification in a blocking task
|
||||||
match header.alg() {
|
match header.alg() {
|
||||||
JsonWebSignatureAlgorithm::Hs256 => {
|
JsonWebSignatureAlg::Hs256 => {
|
||||||
let mut mac = Hmac::<Sha256>::new_from_slice(self.inner)?;
|
let mut mac = Hmac::<Sha256>::new_from_slice(self.inner)?;
|
||||||
mac.update(payload);
|
mac.update(payload);
|
||||||
mac.verify(signature.try_into()?)?;
|
mac.verify(signature.try_into()?)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Hs384 => {
|
JsonWebSignatureAlg::Hs384 => {
|
||||||
let mut mac = Hmac::<Sha384>::new_from_slice(self.inner)?;
|
let mut mac = Hmac::<Sha384>::new_from_slice(self.inner)?;
|
||||||
mac.update(payload);
|
mac.update(payload);
|
||||||
mac.verify(signature.try_into()?)?;
|
mac.verify(signature.try_into()?)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Hs512 => {
|
JsonWebSignatureAlg::Hs512 => {
|
||||||
let mut mac = Hmac::<Sha512>::new_from_slice(self.inner)?;
|
let mut mac = Hmac::<Sha512>::new_from_slice(self.inner)?;
|
||||||
mac.update(payload);
|
mac.update(payload);
|
||||||
mac.verify(signature.try_into()?)?;
|
mac.verify(signature.try_into()?)?;
|
||||||
@ -133,9 +132,9 @@ mod tests {
|
|||||||
let message = "this is the message to sign".as_bytes();
|
let message = "this is the message to sign".as_bytes();
|
||||||
let store = SharedSecret::new(&secret);
|
let store = SharedSecret::new(&secret);
|
||||||
for alg in [
|
for alg in [
|
||||||
JsonWebSignatureAlgorithm::Hs256,
|
JsonWebSignatureAlg::Hs256,
|
||||||
JsonWebSignatureAlgorithm::Hs384,
|
JsonWebSignatureAlg::Hs384,
|
||||||
JsonWebSignatureAlgorithm::Hs512,
|
JsonWebSignatureAlg::Hs512,
|
||||||
] {
|
] {
|
||||||
let header = store.prepare_header(alg).await.unwrap();
|
let header = store.prepare_header(alg).await.unwrap();
|
||||||
assert_eq!(header.alg(), alg);
|
assert_eq!(header.alg(), alg);
|
||||||
|
@ -19,6 +19,7 @@ use async_trait::async_trait;
|
|||||||
use base64ct::{Base64UrlUnpadded, Encoding};
|
use base64ct::{Base64UrlUnpadded, Encoding};
|
||||||
use digest::Digest;
|
use digest::Digest;
|
||||||
use ecdsa::{SigningKey, VerifyingKey};
|
use ecdsa::{SigningKey, VerifyingKey};
|
||||||
|
use mas_iana::jose::{JsonWebKeyUse, JsonWebSignatureAlg};
|
||||||
use p256::{NistP256, PublicKey};
|
use p256::{NistP256, PublicKey};
|
||||||
use pkcs1::{DecodeRsaPrivateKey, EncodeRsaPublicKey};
|
use pkcs1::{DecodeRsaPrivateKey, EncodeRsaPublicKey};
|
||||||
use pkcs8::{DecodePrivateKey, EncodePublicKey};
|
use pkcs8::{DecodePrivateKey, EncodePublicKey};
|
||||||
@ -27,7 +28,7 @@ use sha2::{Sha256, Sha384, Sha512};
|
|||||||
use signature::{Signature, Signer, Verifier};
|
use signature::{Signature, Signer, Verifier};
|
||||||
|
|
||||||
use super::{ExportJwks, SigningKeystore, VerifyingKeystore};
|
use super::{ExportJwks, SigningKeystore, VerifyingKeystore};
|
||||||
use crate::{iana::JsonWebSignatureAlgorithm, JsonWebKey, JsonWebKeySet, JwtHeader};
|
use crate::{JsonWebKey, JsonWebKeySet, JwtHeader};
|
||||||
|
|
||||||
// Generate with
|
// Generate with
|
||||||
// openssl genrsa 2048
|
// openssl genrsa 2048
|
||||||
@ -126,7 +127,7 @@ impl StaticKeystore {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SigningKeystore for &StaticKeystore {
|
impl SigningKeystore for &StaticKeystore {
|
||||||
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlgorithm> {
|
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlg> {
|
||||||
let has_rsa = !self.rsa_keys.is_empty();
|
let has_rsa = !self.rsa_keys.is_empty();
|
||||||
let has_es256 = !self.es256_keys.is_empty();
|
let has_es256 = !self.es256_keys.is_empty();
|
||||||
|
|
||||||
@ -134,30 +135,30 @@ impl SigningKeystore for &StaticKeystore {
|
|||||||
let mut algorithms = HashSet::with_capacity(capacity);
|
let mut algorithms = HashSet::with_capacity(capacity);
|
||||||
|
|
||||||
if has_rsa {
|
if has_rsa {
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Rs256);
|
algorithms.insert(JsonWebSignatureAlg::Rs256);
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Rs384);
|
algorithms.insert(JsonWebSignatureAlg::Rs384);
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Rs512);
|
algorithms.insert(JsonWebSignatureAlg::Rs512);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_es256 {
|
if has_es256 {
|
||||||
algorithms.insert(JsonWebSignatureAlgorithm::Es256);
|
algorithms.insert(JsonWebSignatureAlg::Es256);
|
||||||
}
|
}
|
||||||
|
|
||||||
algorithms
|
algorithms
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader> {
|
async fn prepare_header(self, alg: JsonWebSignatureAlg) -> anyhow::Result<JwtHeader> {
|
||||||
let header = JwtHeader::new(alg);
|
let header = JwtHeader::new(alg);
|
||||||
|
|
||||||
let kid = match alg {
|
let kid = match alg {
|
||||||
JsonWebSignatureAlgorithm::Rs256
|
JsonWebSignatureAlg::Rs256
|
||||||
| JsonWebSignatureAlgorithm::Rs384
|
| JsonWebSignatureAlg::Rs384
|
||||||
| JsonWebSignatureAlgorithm::Rs512 => self
|
| JsonWebSignatureAlg::Rs512 => self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.keys()
|
.keys()
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| anyhow::anyhow!("no RSA keys in keystore"))?,
|
.ok_or_else(|| anyhow::anyhow!("no RSA keys in keystore"))?,
|
||||||
JsonWebSignatureAlgorithm::Es256 => self
|
JsonWebSignatureAlg::Es256 => self
|
||||||
.es256_keys
|
.es256_keys
|
||||||
.keys()
|
.keys()
|
||||||
.next()
|
.next()
|
||||||
@ -175,7 +176,7 @@ impl SigningKeystore for &StaticKeystore {
|
|||||||
|
|
||||||
// TODO: do the signing in a blocking task
|
// TODO: do the signing in a blocking task
|
||||||
let signature = match header.alg() {
|
let signature = match header.alg() {
|
||||||
JsonWebSignatureAlgorithm::Rs256 => {
|
JsonWebSignatureAlg::Rs256 => {
|
||||||
let key = self
|
let key = self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -193,7 +194,7 @@ impl SigningKeystore for &StaticKeystore {
|
|||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Rs384 => {
|
JsonWebSignatureAlg::Rs384 => {
|
||||||
let key = self
|
let key = self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -211,7 +212,7 @@ impl SigningKeystore for &StaticKeystore {
|
|||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Rs512 => {
|
JsonWebSignatureAlg::Rs512 => {
|
||||||
let key = self
|
let key = self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -229,7 +230,7 @@ impl SigningKeystore for &StaticKeystore {
|
|||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Es256 => {
|
JsonWebSignatureAlg::Es256 => {
|
||||||
let key = self
|
let key = self
|
||||||
.es256_keys
|
.es256_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -261,7 +262,7 @@ impl VerifyingKeystore for &StaticKeystore {
|
|||||||
|
|
||||||
// TODO: do the verification in a blocking task
|
// TODO: do the verification in a blocking task
|
||||||
match header.alg() {
|
match header.alg() {
|
||||||
JsonWebSignatureAlgorithm::Rs256 => {
|
JsonWebSignatureAlg::Rs256 => {
|
||||||
let key = self
|
let key = self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -282,7 +283,7 @@ impl VerifyingKeystore for &StaticKeystore {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Rs384 => {
|
JsonWebSignatureAlg::Rs384 => {
|
||||||
let key = self
|
let key = self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -303,7 +304,7 @@ impl VerifyingKeystore for &StaticKeystore {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Rs512 => {
|
JsonWebSignatureAlg::Rs512 => {
|
||||||
let key = self
|
let key = self
|
||||||
.rsa_keys
|
.rsa_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -324,7 +325,7 @@ impl VerifyingKeystore for &StaticKeystore {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWebSignatureAlgorithm::Es256 => {
|
JsonWebSignatureAlg::Es256 => {
|
||||||
let key = self
|
let key = self
|
||||||
.es256_keys
|
.es256_keys
|
||||||
.get(kid)
|
.get(kid)
|
||||||
@ -349,15 +350,15 @@ impl ExportJwks for StaticKeystore {
|
|||||||
let pubkey = RsaPublicKey::from(key);
|
let pubkey = RsaPublicKey::from(key);
|
||||||
JsonWebKey::new(pubkey.into())
|
JsonWebKey::new(pubkey.into())
|
||||||
.with_kid(kid)
|
.with_kid(kid)
|
||||||
.with_use(crate::JsonWebKeyUse::Sig)
|
.with_use(JsonWebKeyUse::Sig)
|
||||||
});
|
});
|
||||||
|
|
||||||
let es256 = self.es256_keys.iter().map(|(kid, key)| {
|
let es256 = self.es256_keys.iter().map(|(kid, key)| {
|
||||||
let pubkey = ecdsa::VerifyingKey::from(key);
|
let pubkey = ecdsa::VerifyingKey::from(key);
|
||||||
JsonWebKey::new(pubkey.into())
|
JsonWebKey::new(pubkey.into())
|
||||||
.with_kid(kid)
|
.with_kid(kid)
|
||||||
.with_use(crate::JsonWebKeyUse::Sig)
|
.with_use(JsonWebKeyUse::Sig)
|
||||||
.with_alg(JsonWebSignatureAlgorithm::Es256)
|
.with_alg(JsonWebSignatureAlg::Es256)
|
||||||
});
|
});
|
||||||
|
|
||||||
let keys = rsa.chain(es256).collect();
|
let keys = rsa.chain(es256).collect();
|
||||||
@ -380,10 +381,10 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for alg in [
|
for alg in [
|
||||||
JsonWebSignatureAlgorithm::Rs256,
|
JsonWebSignatureAlg::Rs256,
|
||||||
JsonWebSignatureAlgorithm::Rs384,
|
JsonWebSignatureAlg::Rs384,
|
||||||
JsonWebSignatureAlgorithm::Rs512,
|
JsonWebSignatureAlg::Rs512,
|
||||||
JsonWebSignatureAlgorithm::Es256,
|
JsonWebSignatureAlg::Es256,
|
||||||
] {
|
] {
|
||||||
let header = store.prepare_header(alg).await.unwrap();
|
let header = store.prepare_header(alg).await.unwrap();
|
||||||
assert_eq!(header.alg(), alg);
|
assert_eq!(header.alg(), alg);
|
||||||
|
@ -15,14 +15,15 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use mas_iana::jose::JsonWebSignatureAlg;
|
||||||
|
|
||||||
use crate::{iana::JsonWebSignatureAlgorithm, JsonWebKeySet, JwtHeader};
|
use crate::{JsonWebKeySet, JwtHeader};
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait SigningKeystore {
|
pub trait SigningKeystore {
|
||||||
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlgorithm>;
|
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlg>;
|
||||||
|
|
||||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader>;
|
async fn prepare_header(self, alg: JsonWebSignatureAlg) -> anyhow::Result<JwtHeader>;
|
||||||
|
|
||||||
async fn sign(self, header: &JwtHeader, msg: &[u8]) -> anyhow::Result<Vec<u8>>;
|
async fn sign(self, header: &JwtHeader, msg: &[u8]) -> anyhow::Result<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,12 @@
|
|||||||
#![allow(clippy::missing_errors_doc)]
|
#![allow(clippy::missing_errors_doc)]
|
||||||
#![allow(clippy::module_name_repetitions)]
|
#![allow(clippy::module_name_repetitions)]
|
||||||
|
|
||||||
pub(crate) use mas_iana::jose as iana;
|
|
||||||
|
|
||||||
pub mod claims;
|
pub mod claims;
|
||||||
pub(crate) mod jwk;
|
pub(crate) mod jwk;
|
||||||
pub(crate) mod jwt;
|
pub(crate) mod jwt;
|
||||||
mod keystore;
|
mod keystore;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
iana::{
|
|
||||||
JsonWebEncryptionAlgorithm, JsonWebEncryptionCompressionAlgorithm, JsonWebKeyOperation,
|
|
||||||
JsonWebKeyType, JsonWebKeyUse, JsonWebSignatureAlgorithm,
|
|
||||||
},
|
|
||||||
jwk::{JsonWebKey, JsonWebKeySet},
|
jwk::{JsonWebKey, JsonWebKeySet},
|
||||||
jwt::{DecodedJsonWebToken, JsonWebTokenParts, JwtHeader},
|
jwt::{DecodedJsonWebToken, JsonWebTokenParts, JwtHeader},
|
||||||
keystore::{
|
keystore::{
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use mas_iana::jose::{JsonWebEncryptionAlgorithm, JsonWebSignatureAlgorithm};
|
use mas_iana::jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@ -83,8 +83,7 @@ pub struct Metadata {
|
|||||||
/// JSON array containing a list of the JWS signing algorithms supported by
|
/// JSON array containing a list of the JWS signing algorithms supported by
|
||||||
/// the token endpoint for the signature on the JWT used to authenticate the
|
/// the token endpoint for the signature on the JWT used to authenticate the
|
||||||
/// client at the token endpoint.
|
/// client at the token endpoint.
|
||||||
pub token_endpoint_auth_signing_alg_values_supported:
|
pub token_endpoint_auth_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlg>>,
|
||||||
Option<HashSet<JsonWebSignatureAlgorithm>>,
|
|
||||||
|
|
||||||
/// URL of a page containing human-readable information that developers
|
/// URL of a page containing human-readable information that developers
|
||||||
/// might want or need to know when using the authorization server.
|
/// might want or need to know when using the authorization server.
|
||||||
@ -115,8 +114,7 @@ pub struct Metadata {
|
|||||||
/// JSON array containing a list of the JWS signing algorithms supported by
|
/// JSON array containing a list of the JWS signing algorithms supported by
|
||||||
/// the revocation endpoint for the signature on the JWT used to
|
/// the revocation endpoint for the signature on the JWT used to
|
||||||
/// authenticate the client at the revocation endpoint.
|
/// authenticate the client at the revocation endpoint.
|
||||||
pub revocation_endpoint_auth_signing_alg_values_supported:
|
pub revocation_endpoint_auth_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlg>>,
|
||||||
Option<HashSet<JsonWebSignatureAlgorithm>>,
|
|
||||||
|
|
||||||
/// URL of the authorization server's OAuth 2.0 introspection endpoint.
|
/// URL of the authorization server's OAuth 2.0 introspection endpoint.
|
||||||
pub introspection_endpoint: Option<Url>,
|
pub introspection_endpoint: Option<Url>,
|
||||||
@ -129,7 +127,7 @@ pub struct Metadata {
|
|||||||
/// the introspection endpoint for the signature on the JWT used to
|
/// the introspection endpoint for the signature on the JWT used to
|
||||||
/// authenticate the client at the introspection endpoint.
|
/// authenticate the client at the introspection endpoint.
|
||||||
pub introspection_endpoint_auth_signing_alg_values_supported:
|
pub introspection_endpoint_auth_signing_alg_values_supported:
|
||||||
Option<HashSet<JsonWebSignatureAlgorithm>>,
|
Option<HashSet<JsonWebSignatureAlg>>,
|
||||||
|
|
||||||
/// PKCE code challenge methods supported by this authorization server.
|
/// PKCE code challenge methods supported by this authorization server.
|
||||||
pub code_challenge_methods_supported: Option<HashSet<CodeChallengeMethod>>,
|
pub code_challenge_methods_supported: Option<HashSet<CodeChallengeMethod>>,
|
||||||
@ -147,39 +145,39 @@ pub struct Metadata {
|
|||||||
|
|
||||||
/// JSON array containing a list of the JWS "alg" values supported by the OP
|
/// JSON array containing a list of the JWS "alg" values supported by the OP
|
||||||
/// for the ID Token.
|
/// for the ID Token.
|
||||||
pub id_token_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
pub id_token_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlg>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWE "alg" values supported by the OP
|
/// JSON array containing a list of the JWE "alg" values supported by the OP
|
||||||
/// for the ID Token.
|
/// for the ID Token.
|
||||||
pub id_token_encryption_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
pub id_token_encryption_alg_values_supported: Option<HashSet<JsonWebEncryptionAlg>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWE "enc" values supported by the OP
|
/// JSON array containing a list of the JWE "enc" values supported by the OP
|
||||||
/// for the ID Token.
|
/// for the ID Token.
|
||||||
pub id_token_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionAlgorithm>>,
|
pub id_token_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionEnc>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWS "alg" values supported by the
|
/// JSON array containing a list of the JWS "alg" values supported by the
|
||||||
/// UserInfo Endpoint.
|
/// UserInfo Endpoint.
|
||||||
pub userinfo_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
pub userinfo_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlg>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWE "alg" values supported by the
|
/// JSON array containing a list of the JWE "alg" values supported by the
|
||||||
/// UserInfo Endpoint.
|
/// UserInfo Endpoint.
|
||||||
pub userinfo_encryption_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
pub userinfo_encryption_alg_values_supported: Option<HashSet<JsonWebEncryptionAlg>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWE "enc" values supported by the
|
/// JSON array containing a list of the JWE "enc" values supported by the
|
||||||
/// UserInfo Endpoint.
|
/// UserInfo Endpoint.
|
||||||
pub userinfo_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionAlgorithm>>,
|
pub userinfo_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionEnc>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWS "alg" values supported by the OP
|
/// JSON array containing a list of the JWS "alg" values supported by the OP
|
||||||
/// for Request Objects.
|
/// for Request Objects.
|
||||||
pub request_object_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
pub request_object_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlg>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWE "alg" values supported by the OP
|
/// JSON array containing a list of the JWE "alg" values supported by the OP
|
||||||
/// for Request Objects.
|
/// for Request Objects.
|
||||||
pub request_object_encryption_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
pub request_object_encryption_alg_values_supported: Option<HashSet<JsonWebEncryptionAlg>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the JWE "enc" values supported by the OP
|
/// JSON array containing a list of the JWE "enc" values supported by the OP
|
||||||
/// for Request Objects.
|
/// for Request Objects.
|
||||||
pub request_object_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionAlgorithm>>,
|
pub request_object_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionEnc>>,
|
||||||
|
|
||||||
/// JSON array containing a list of the "display" parameter values that the
|
/// JSON array containing a list of the "display" parameter values that the
|
||||||
/// OpenID Provider supports.
|
/// OpenID Provider supports.
|
||||||
|
@ -33,16 +33,14 @@ use sha2::{Digest, Sha256};
|
|||||||
Serialize,
|
Serialize,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "sqlx_type", derive(sqlx::Type))]
|
|
||||||
#[repr(i8)]
|
|
||||||
pub enum CodeChallengeMethod {
|
pub enum CodeChallengeMethod {
|
||||||
#[serde(rename = "plain")]
|
#[serde(rename = "plain")]
|
||||||
#[display("plain")]
|
#[display("plain")]
|
||||||
Plain = 0,
|
Plain,
|
||||||
|
|
||||||
#[serde(rename = "S256")]
|
#[serde(rename = "S256")]
|
||||||
#[display("S256")]
|
#[display("S256")]
|
||||||
S256 = 1,
|
S256,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeChallengeMethod {
|
impl CodeChallengeMethod {
|
||||||
|
@ -290,7 +290,7 @@ struct ClientAuthForm<T> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use headers::authorization::Credentials;
|
use headers::authorization::Credentials;
|
||||||
use mas_config::{ConfigurationSection, OAuth2ClientAuthMethodConfig};
|
use mas_config::{ConfigurationSection, OAuth2ClientAuthMethodConfig};
|
||||||
use mas_jose::{ExportJwks, JsonWebSignatureAlgorithm, SigningKeystore, StaticKeystore};
|
use mas_jose::{ExportJwks, SigningKeystore, StaticKeystore};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -364,17 +364,17 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_hs256() {
|
async fn client_secret_jwt_hs256() {
|
||||||
client_secret_jwt(JsonWebSignatureAlgorithm::Hs256).await;
|
client_secret_jwt("HS256").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_hs384() {
|
async fn client_secret_jwt_hs384() {
|
||||||
client_secret_jwt(JsonWebSignatureAlgorithm::Hs384).await;
|
client_secret_jwt("HS384").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_hs512() {
|
async fn client_secret_jwt_hs512() {
|
||||||
client_secret_jwt(JsonWebSignatureAlgorithm::Hs512).await;
|
client_secret_jwt("HS512").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_claims(
|
fn client_claims(
|
||||||
@ -395,7 +395,8 @@ mod tests {
|
|||||||
claims
|
claims
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn client_secret_jwt(alg: JsonWebSignatureAlgorithm) {
|
async fn client_secret_jwt(alg: &str) {
|
||||||
|
let alg = alg.parse().unwrap();
|
||||||
let audience = "https://example.com/token";
|
let audience = "https://example.com/token";
|
||||||
let filter = client_authentication::<Form>(&oauth2_config().await, audience.to_string());
|
let filter = client_authentication::<Form>(&oauth2_config().await, audience.to_string());
|
||||||
|
|
||||||
@ -463,25 +464,26 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_rs256() {
|
async fn client_secret_jwt_rs256() {
|
||||||
private_key_jwt(JsonWebSignatureAlgorithm::Rs256).await;
|
private_key_jwt("RS256").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_rs384() {
|
async fn client_secret_jwt_rs384() {
|
||||||
private_key_jwt(JsonWebSignatureAlgorithm::Rs384).await;
|
private_key_jwt("RS384").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_rs512() {
|
async fn client_secret_jwt_rs512() {
|
||||||
private_key_jwt(JsonWebSignatureAlgorithm::Rs512).await;
|
private_key_jwt("RS512").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn client_secret_jwt_es256() {
|
async fn client_secret_jwt_es256() {
|
||||||
private_key_jwt(JsonWebSignatureAlgorithm::Es256).await;
|
private_key_jwt("ES256").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn private_key_jwt(alg: JsonWebSignatureAlgorithm) {
|
async fn private_key_jwt(alg: &str) {
|
||||||
|
let alg = alg.parse().unwrap();
|
||||||
let audience = "https://example.com/token";
|
let audience = "https://example.com/token";
|
||||||
let filter = client_authentication::<Form>(&oauth2_config().await, audience.to_string());
|
let filter = client_authentication::<Form>(&oauth2_config().await, audience.to_string());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user