You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Use new generated enums & query supported signing algs from the keystore
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -1571,6 +1571,7 @@ dependencies = [
|
|||||||
"indoc",
|
"indoc",
|
||||||
"mas-config",
|
"mas-config",
|
||||||
"mas-data-model",
|
"mas-data-model",
|
||||||
|
"mas-iana",
|
||||||
"mas-jose",
|
"mas-jose",
|
||||||
"mas-static-files",
|
"mas-static-files",
|
||||||
"mas-storage",
|
"mas-storage",
|
||||||
@ -1631,6 +1632,7 @@ dependencies = [
|
|||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
"hmac 0.12.0",
|
"hmac 0.12.0",
|
||||||
|
"mas-iana",
|
||||||
"p256",
|
"p256",
|
||||||
"pkcs1",
|
"pkcs1",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
@ -1954,6 +1956,7 @@ dependencies = [
|
|||||||
"indoc",
|
"indoc",
|
||||||
"itertools",
|
"itertools",
|
||||||
"language-tags",
|
"language-tags",
|
||||||
|
"mas-iana",
|
||||||
"parse-display",
|
"parse-display",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -59,6 +59,7 @@ mas-static-files = { path = "../static-files" }
|
|||||||
mas-storage = { path = "../storage" }
|
mas-storage = { path = "../storage" }
|
||||||
mas-warp-utils = { path = "../warp-utils" }
|
mas-warp-utils = { path = "../warp-utils" }
|
||||||
mas-jose = { path = "../jose" }
|
mas-jose = { path = "../jose" }
|
||||||
|
mas-iana = { path = "../iana" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
indoc = "1.0.3"
|
indoc = "1.0.3"
|
||||||
|
@ -15,15 +15,19 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use mas_config::OAuth2Config;
|
use mas_config::OAuth2Config;
|
||||||
|
use mas_jose::{JsonWebSignatureAlgorithm, SigningKeystore};
|
||||||
use oauth2_types::{
|
use oauth2_types::{
|
||||||
oidc::{ClaimType, Metadata, SigningAlgorithm, SubjectType},
|
oidc::{ClaimType, Metadata, SubjectType},
|
||||||
pkce::CodeChallengeMethod,
|
pkce::CodeChallengeMethod,
|
||||||
requests::{ClientAuthenticationMethod, Display, GrantType, ResponseMode},
|
requests::{ClientAuthenticationMethod, Display, GrantType, ResponseMode},
|
||||||
};
|
};
|
||||||
use warp::{filters::BoxedFilter, Filter, Reply};
|
use warp::{filters::BoxedFilter, Filter, Reply};
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
|
pub(super) fn filter(
|
||||||
|
key_store: impl SigningKeystore,
|
||||||
|
config: &OAuth2Config,
|
||||||
|
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||||
let base = config.issuer.clone();
|
let base = config.issuer.clone();
|
||||||
|
|
||||||
// This is how clients can authenticate
|
// This is how clients can authenticate
|
||||||
@ -39,25 +43,17 @@ pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(Box<dyn Reply>,)> {
|
|||||||
|
|
||||||
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(SigningAlgorithm::Hs256);
|
s.insert(JsonWebSignatureAlgorithm::Hs256);
|
||||||
s.insert(SigningAlgorithm::Hs384);
|
s.insert(JsonWebSignatureAlgorithm::Hs384);
|
||||||
s.insert(SigningAlgorithm::Hs512);
|
s.insert(JsonWebSignatureAlgorithm::Hs512);
|
||||||
s.insert(SigningAlgorithm::Rs256);
|
s.insert(JsonWebSignatureAlgorithm::Rs256);
|
||||||
s.insert(SigningAlgorithm::Rs384);
|
s.insert(JsonWebSignatureAlgorithm::Rs384);
|
||||||
s.insert(SigningAlgorithm::Rs512);
|
s.insert(JsonWebSignatureAlgorithm::Rs512);
|
||||||
s
|
s
|
||||||
});
|
});
|
||||||
|
|
||||||
// This is how we can sign stuff
|
// This is how we can sign stuff
|
||||||
// TODO: query the signing store
|
let jwt_signing_alg_values_supported = Some(key_store.supported_algorithms());
|
||||||
let jwt_signing_alg_values_supported = Some({
|
|
||||||
let mut s = HashSet::new();
|
|
||||||
s.insert(SigningAlgorithm::Rs256);
|
|
||||||
s.insert(SigningAlgorithm::Rs384);
|
|
||||||
s.insert(SigningAlgorithm::Rs512);
|
|
||||||
s.insert(SigningAlgorithm::Es256);
|
|
||||||
s
|
|
||||||
});
|
|
||||||
|
|
||||||
// Prepare all the endpoints
|
// Prepare all the endpoints
|
||||||
let issuer = Some(base.clone());
|
let issuer = Some(base.clone());
|
||||||
|
@ -43,7 +43,7 @@ pub fn filter(
|
|||||||
oauth2_config: &OAuth2Config,
|
oauth2_config: &OAuth2Config,
|
||||||
cookies_config: &CookiesConfig,
|
cookies_config: &CookiesConfig,
|
||||||
) -> BoxedFilter<(impl Reply,)> {
|
) -> BoxedFilter<(impl Reply,)> {
|
||||||
let discovery = discovery(oauth2_config);
|
let discovery = discovery(key_store.as_ref(), oauth2_config);
|
||||||
let keys = keys(key_store);
|
let keys = keys(key_store);
|
||||||
let authorization = authorization(pool, templates, oauth2_config, cookies_config);
|
let authorization = authorization(pool, templates, oauth2_config, cookies_config);
|
||||||
let userinfo = userinfo(pool, oauth2_config);
|
let userinfo = userinfo(pool, oauth2_config);
|
||||||
|
@ -31,3 +31,5 @@ thiserror = "1.0.30"
|
|||||||
tokio = { version = "1.15.0", features = ["macros", "rt", "sync"] }
|
tokio = { version = "1.15.0", features = ["macros", "rt", "sync"] }
|
||||||
url = { version = "2.2.2", features = ["serde"] }
|
url = { version = "2.2.2", features = ["serde"] }
|
||||||
zeroize = "1.4.3"
|
zeroize = "1.4.3"
|
||||||
|
|
||||||
|
mas-iana = { path = "../iana" }
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
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};
|
||||||
@ -34,6 +36,16 @@ 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> {
|
||||||
|
let mut algorithms = HashSet::with_capacity(3);
|
||||||
|
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Hs256);
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Hs384);
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Hs512);
|
||||||
|
|
||||||
|
algorithms
|
||||||
|
}
|
||||||
|
|
||||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader> {
|
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader> {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
alg,
|
alg,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@ -126,6 +126,26 @@ impl StaticKeystore {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SigningKeystore for &StaticKeystore {
|
impl SigningKeystore for &StaticKeystore {
|
||||||
|
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlgorithm> {
|
||||||
|
let has_rsa = !self.rsa_keys.is_empty();
|
||||||
|
let has_es256 = !self.es256_keys.is_empty();
|
||||||
|
|
||||||
|
let capacity = (if has_rsa { 3 } else { 0 }) + (if has_es256 { 1 } else { 0 });
|
||||||
|
let mut algorithms = HashSet::with_capacity(capacity);
|
||||||
|
|
||||||
|
if has_rsa {
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Rs256);
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Rs384);
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Rs512);
|
||||||
|
}
|
||||||
|
|
||||||
|
if has_es256 {
|
||||||
|
algorithms.insert(JsonWebSignatureAlgorithm::Es256);
|
||||||
|
}
|
||||||
|
|
||||||
|
algorithms
|
||||||
|
}
|
||||||
|
|
||||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader> {
|
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader> {
|
||||||
let header = JwtHeader::new(alg);
|
let header = JwtHeader::new(alg);
|
||||||
|
|
||||||
|
@ -12,12 +12,16 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::{iana::JsonWebSignatureAlgorithm, JsonWebKeySet, JwtHeader};
|
use crate::{iana::JsonWebSignatureAlgorithm, JsonWebKeySet, JwtHeader};
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait SigningKeystore {
|
pub trait SigningKeystore {
|
||||||
|
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlgorithm>;
|
||||||
|
|
||||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader>;
|
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> 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,8 +19,9 @@
|
|||||||
#![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 iana;
|
|
||||||
pub(crate) mod jwk;
|
pub(crate) mod jwk;
|
||||||
pub(crate) mod jwt;
|
pub(crate) mod jwt;
|
||||||
mod keystore;
|
mod keystore;
|
||||||
|
@ -19,3 +19,5 @@ sha2 = "0.10.0"
|
|||||||
data-encoding = "2.3.2"
|
data-encoding = "2.3.2"
|
||||||
thiserror = "1.0.30"
|
thiserror = "1.0.30"
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
|
|
||||||
|
mas-iana = { path = "../iana" }
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use mas_iana::jose::{JsonWebEncryptionAlgorithm, JsonWebSignatureAlgorithm};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@ -38,28 +39,6 @@ pub enum ClaimType {
|
|||||||
Distributed,
|
Distributed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
#[serde(rename_all = "UPPERCASE")]
|
|
||||||
pub enum SigningAlgorithm {
|
|
||||||
#[serde(rename = "none")]
|
|
||||||
None,
|
|
||||||
Hs256,
|
|
||||||
Hs384,
|
|
||||||
Hs512,
|
|
||||||
Ps256,
|
|
||||||
Ps384,
|
|
||||||
Ps512,
|
|
||||||
Rs256,
|
|
||||||
Rs384,
|
|
||||||
Rs512,
|
|
||||||
Es256,
|
|
||||||
Es256K,
|
|
||||||
Es384,
|
|
||||||
Es512,
|
|
||||||
#[serde(rename = "EcDSA")]
|
|
||||||
EcDsa,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Authorization server metadata, as described by the
|
/// Authorization server metadata, as described by the
|
||||||
/// [IANA registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata)
|
/// [IANA registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata)
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
@ -104,7 +83,8 @@ 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: Option<HashSet<SigningAlgorithm>>,
|
pub token_endpoint_auth_signing_alg_values_supported:
|
||||||
|
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.
|
||||||
@ -135,7 +115,8 @@ 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: Option<HashSet<SigningAlgorithm>>,
|
pub revocation_endpoint_auth_signing_alg_values_supported:
|
||||||
|
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>,
|
||||||
@ -147,7 +128,8 @@ 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 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: Option<HashSet<SigningAlgorithm>>,
|
pub introspection_endpoint_auth_signing_alg_values_supported:
|
||||||
|
Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
/// 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>>,
|
||||||
@ -165,45 +147,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<SigningAlgorithm>>,
|
pub id_token_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub id_token_encryption_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub id_token_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionAlgorithm>>,
|
||||||
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub userinfo_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub userinfo_encryption_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub userinfo_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionAlgorithm>>,
|
||||||
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub request_object_signing_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub request_object_encryption_alg_values_supported: Option<HashSet<JsonWebSignatureAlgorithm>>,
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
/// 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<SigningAlgorithm>>,
|
pub request_object_encryption_enc_values_supported: Option<HashSet<JsonWebEncryptionAlgorithm>>,
|
||||||
|
|
||||||
/// 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.
|
||||||
|
Reference in New Issue
Block a user