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
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",
|
||||
"mas-config",
|
||||
"mas-data-model",
|
||||
"mas-iana",
|
||||
"mas-jose",
|
||||
"mas-static-files",
|
||||
"mas-storage",
|
||||
@ -1631,6 +1632,7 @@ dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"hmac 0.12.0",
|
||||
"mas-iana",
|
||||
"p256",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
@ -1954,6 +1956,7 @@ dependencies = [
|
||||
"indoc",
|
||||
"itertools",
|
||||
"language-tags",
|
||||
"mas-iana",
|
||||
"parse-display",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -59,6 +59,7 @@ mas-static-files = { path = "../static-files" }
|
||||
mas-storage = { path = "../storage" }
|
||||
mas-warp-utils = { path = "../warp-utils" }
|
||||
mas-jose = { path = "../jose" }
|
||||
mas-iana = { path = "../iana" }
|
||||
|
||||
[dev-dependencies]
|
||||
indoc = "1.0.3"
|
||||
|
@ -15,15 +15,19 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use mas_config::OAuth2Config;
|
||||
use mas_jose::{JsonWebSignatureAlgorithm, SigningKeystore};
|
||||
use oauth2_types::{
|
||||
oidc::{ClaimType, Metadata, SigningAlgorithm, SubjectType},
|
||||
oidc::{ClaimType, Metadata, SubjectType},
|
||||
pkce::CodeChallengeMethod,
|
||||
requests::{ClientAuthenticationMethod, Display, GrantType, ResponseMode},
|
||||
};
|
||||
use warp::{filters::BoxedFilter, Filter, Reply};
|
||||
|
||||
#[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();
|
||||
|
||||
// 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 mut s = HashSet::new();
|
||||
s.insert(SigningAlgorithm::Hs256);
|
||||
s.insert(SigningAlgorithm::Hs384);
|
||||
s.insert(SigningAlgorithm::Hs512);
|
||||
s.insert(SigningAlgorithm::Rs256);
|
||||
s.insert(SigningAlgorithm::Rs384);
|
||||
s.insert(SigningAlgorithm::Rs512);
|
||||
s.insert(JsonWebSignatureAlgorithm::Hs256);
|
||||
s.insert(JsonWebSignatureAlgorithm::Hs384);
|
||||
s.insert(JsonWebSignatureAlgorithm::Hs512);
|
||||
s.insert(JsonWebSignatureAlgorithm::Rs256);
|
||||
s.insert(JsonWebSignatureAlgorithm::Rs384);
|
||||
s.insert(JsonWebSignatureAlgorithm::Rs512);
|
||||
s
|
||||
});
|
||||
|
||||
// This is how we can sign stuff
|
||||
// TODO: query the signing store
|
||||
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
|
||||
});
|
||||
let jwt_signing_alg_values_supported = Some(key_store.supported_algorithms());
|
||||
|
||||
// Prepare all the endpoints
|
||||
let issuer = Some(base.clone());
|
||||
|
@ -43,7 +43,7 @@ pub fn filter(
|
||||
oauth2_config: &OAuth2Config,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
let discovery = discovery(oauth2_config);
|
||||
let discovery = discovery(key_store.as_ref(), oauth2_config);
|
||||
let keys = keys(key_store);
|
||||
let authorization = authorization(pool, templates, oauth2_config, cookies_config);
|
||||
let userinfo = userinfo(pool, oauth2_config);
|
||||
|
@ -31,3 +31,5 @@ thiserror = "1.0.30"
|
||||
tokio = { version = "1.15.0", features = ["macros", "rt", "sync"] }
|
||||
url = { version = "2.2.2", features = ["serde"] }
|
||||
zeroize = "1.4.3"
|
||||
|
||||
mas-iana = { path = "../iana" }
|
||||
|
@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use anyhow::bail;
|
||||
use async_trait::async_trait;
|
||||
use hmac::{Hmac, Mac};
|
||||
@ -34,6 +36,16 @@ impl<'a> SharedSecret<'a> {
|
||||
|
||||
#[async_trait]
|
||||
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> {
|
||||
if !matches!(
|
||||
alg,
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use anyhow::bail;
|
||||
use async_trait::async_trait;
|
||||
@ -126,6 +126,26 @@ impl StaticKeystore {
|
||||
|
||||
#[async_trait]
|
||||
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> {
|
||||
let header = JwtHeader::new(alg);
|
||||
|
||||
|
@ -12,12 +12,16 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::{iana::JsonWebSignatureAlgorithm, JsonWebKeySet, JwtHeader};
|
||||
|
||||
#[async_trait]
|
||||
pub trait SigningKeystore {
|
||||
fn supported_algorithms(self) -> HashSet<JsonWebSignatureAlgorithm>;
|
||||
|
||||
async fn prepare_header(self, alg: JsonWebSignatureAlgorithm) -> anyhow::Result<JwtHeader>;
|
||||
|
||||
async fn sign(self, header: &JwtHeader, msg: &[u8]) -> anyhow::Result<Vec<u8>>;
|
||||
|
@ -19,8 +19,9 @@
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
|
||||
pub(crate) use mas_iana::jose as iana;
|
||||
|
||||
pub mod claims;
|
||||
pub(crate) mod iana;
|
||||
pub(crate) mod jwk;
|
||||
pub(crate) mod jwt;
|
||||
mod keystore;
|
||||
|
@ -19,3 +19,5 @@ sha2 = "0.10.0"
|
||||
data-encoding = "2.3.2"
|
||||
thiserror = "1.0.30"
|
||||
itertools = "0.10.3"
|
||||
|
||||
mas-iana = { path = "../iana" }
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use mas_iana::jose::{JsonWebEncryptionAlgorithm, JsonWebSignatureAlgorithm};
|
||||
use serde::Serialize;
|
||||
use serde_with::skip_serializing_none;
|
||||
use url::Url;
|
||||
@ -38,28 +39,6 @@ pub enum ClaimType {
|
||||
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
|
||||
/// [IANA registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata)
|
||||
#[skip_serializing_none]
|
||||
@ -104,7 +83,8 @@ pub struct Metadata {
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// the revocation endpoint for the signature on the JWT used to
|
||||
/// 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.
|
||||
pub introspection_endpoint: Option<Url>,
|
||||
@ -147,7 +128,8 @@ pub struct Metadata {
|
||||
/// JSON array containing a list of the JWS signing algorithms supported by
|
||||
/// the introspection endpoint for the signature on the JWT used to
|
||||
/// 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.
|
||||
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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// OpenID Provider supports.
|
||||
|
Reference in New Issue
Block a user