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
Make the JWK generic over the parameters
This commit is contained in:
@ -31,8 +31,8 @@ use mas_data_model::{Client, JwksOrJwksUri, StorageBackend};
|
|||||||
use mas_http::HttpServiceExt;
|
use mas_http::HttpServiceExt;
|
||||||
use mas_iana::oauth::OAuthClientAuthenticationMethod;
|
use mas_iana::oauth::OAuthClientAuthenticationMethod;
|
||||||
use mas_jose::{
|
use mas_jose::{
|
||||||
DecodedJsonWebToken, DynamicJwksStore, Either, JsonWebKeySet, JsonWebSignatureHeader,
|
jwk::PublicJsonWebKeySet, DecodedJsonWebToken, DynamicJwksStore, Either,
|
||||||
JsonWebTokenParts, SharedSecret, StaticJwksStore, VerifyingKeystore,
|
JsonWebSignatureHeader, JsonWebTokenParts, SharedSecret, StaticJwksStore, VerifyingKeystore,
|
||||||
};
|
};
|
||||||
use mas_storage::{
|
use mas_storage::{
|
||||||
oauth2::client::{lookup_client_by_client_id, ClientFetchError},
|
oauth2::client::{lookup_client_by_client_id, ClientFetchError},
|
||||||
@ -185,7 +185,7 @@ fn jwks_key_store(jwks: &JwksOrJwksUri) -> Either<StaticJwksStore, DynamicJwksSt
|
|||||||
// TODO: get the client from somewhere else?
|
// TODO: get the client from somewhere else?
|
||||||
let exporter = mas_http::client("fetch-jwks")
|
let exporter = mas_http::client("fetch-jwks")
|
||||||
.response_body_to_bytes()
|
.response_body_to_bytes()
|
||||||
.json_response::<JsonWebKeySet>()
|
.json_response::<PublicJsonWebKeySet>()
|
||||||
.map_request(move |_: ()| {
|
.map_request(move |_: ()| {
|
||||||
http::Request::builder()
|
http::Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
|
@ -16,7 +16,7 @@ use std::ops::{Deref, DerefMut};
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use mas_iana::oauth::OAuthClientAuthenticationMethod;
|
use mas_iana::oauth::OAuthClientAuthenticationMethod;
|
||||||
use mas_jose::JsonWebKeySet;
|
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
@ -28,12 +28,12 @@ use super::ConfigurationSection;
|
|||||||
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum JwksOrJwksUri {
|
pub enum JwksOrJwksUri {
|
||||||
Jwks(JsonWebKeySet),
|
Jwks(PublicJsonWebKeySet),
|
||||||
JwksUri(Url),
|
JwksUri(Url),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<JsonWebKeySet> for JwksOrJwksUri {
|
impl From<PublicJsonWebKeySet> for JwksOrJwksUri {
|
||||||
fn from(jwks: JsonWebKeySet) -> Self {
|
fn from(jwks: PublicJsonWebKeySet) -> Self {
|
||||||
Self::Jwks(jwks)
|
Self::Jwks(jwks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ impl ClientConfig {
|
|||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn jwks(&self) -> Option<&JsonWebKeySet> {
|
pub fn jwks(&self) -> Option<&PublicJsonWebKeySet> {
|
||||||
match &self.client_auth_method {
|
match &self.client_auth_method {
|
||||||
ClientAuthMethodConfig::PrivateKeyJwt(JwksOrJwksUri::Jwks(jwks)) => Some(jwks),
|
ClientAuthMethodConfig::PrivateKeyJwt(JwksOrJwksUri::Jwks(jwks)) => Some(jwks),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -16,7 +16,7 @@ use mas_iana::{
|
|||||||
jose::JsonWebSignatureAlg,
|
jose::JsonWebSignatureAlg,
|
||||||
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
||||||
};
|
};
|
||||||
use mas_jose::JsonWebKeySet;
|
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||||
use oauth2_types::requests::GrantType;
|
use oauth2_types::requests::GrantType;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -28,7 +28,7 @@ use crate::traits::{StorageBackend, StorageBackendMarker};
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum JwksOrJwksUri {
|
pub enum JwksOrJwksUri {
|
||||||
/// Client's JSON Web Key Set document, passed by value.
|
/// Client's JSON Web Key Set document, passed by value.
|
||||||
Jwks(JsonWebKeySet),
|
Jwks(PublicJsonWebKeySet),
|
||||||
|
|
||||||
/// URL for the Client's JSON Web Key Set document.
|
/// URL for the Client's JSON Web Key Set document.
|
||||||
JwksUri(Url),
|
JwksUri(Url),
|
||||||
|
@ -34,6 +34,10 @@ pub(crate) mod public_parameters;
|
|||||||
|
|
||||||
pub use self::public_parameters::JsonWebKeyPublicParameters as JsonWebKeyParameters;
|
pub use self::public_parameters::JsonWebKeyPublicParameters as JsonWebKeyParameters;
|
||||||
|
|
||||||
|
pub trait JwkKty {
|
||||||
|
fn kty(&self) -> JsonWebKeyType;
|
||||||
|
}
|
||||||
|
|
||||||
trait JwkEcCurve {
|
trait JwkEcCurve {
|
||||||
const CRV: JsonWebKeyEcEllipticCurve;
|
const CRV: JsonWebKeyEcEllipticCurve;
|
||||||
}
|
}
|
||||||
@ -53,9 +57,9 @@ impl JwkEcCurve for k256::Secp256k1 {
|
|||||||
#[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)]
|
||||||
pub struct JsonWebKey {
|
pub struct JsonWebKey<P> {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
parameters: JsonWebKeyParameters,
|
parameters: P,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
r#use: Option<JsonWebKeyUse>,
|
r#use: Option<JsonWebKeyUse>,
|
||||||
@ -89,9 +93,12 @@ pub struct JsonWebKey {
|
|||||||
x5t_s256: Option<Vec<u8>>,
|
x5t_s256: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonWebKey {
|
pub type PublicJsonWebKey = JsonWebKey<self::public_parameters::JsonWebKeyPublicParameters>;
|
||||||
|
pub type PrivateJsonWebKey = JsonWebKey<self::private_parameters::JsonWebKeyPrivateParameters>;
|
||||||
|
|
||||||
|
impl<P> JsonWebKey<P> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn new(parameters: JsonWebKeyParameters) -> Self {
|
pub const fn new(parameters: P) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parameters,
|
parameters,
|
||||||
r#use: None,
|
r#use: None,
|
||||||
@ -135,30 +142,29 @@ impl JsonWebKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn params(&self) -> &JsonWebKeyParameters {
|
pub const fn params(&self) -> &P {
|
||||||
&self.parameters
|
&self.parameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Constrainable for JsonWebKey {
|
impl<P> Constrainable for JsonWebKey<P>
|
||||||
|
where
|
||||||
|
P: JwkKty,
|
||||||
|
{
|
||||||
fn kid(&self) -> Option<&str> {
|
fn kid(&self) -> Option<&str> {
|
||||||
self.kid.as_deref()
|
self.kid.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kty(&self) -> JsonWebKeyType {
|
fn kty(&self) -> JsonWebKeyType {
|
||||||
match self.parameters {
|
self.parameters.kty()
|
||||||
JsonWebKeyParameters::Ec { .. } => JsonWebKeyType::Ec,
|
|
||||||
JsonWebKeyParameters::Rsa { .. } => JsonWebKeyType::Rsa,
|
|
||||||
JsonWebKeyParameters::Okp { .. } => JsonWebKeyType::Okp,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn algs(&self) -> Option<Vec<JsonWebSignatureAlg>> {
|
fn algs(&self) -> Option<Vec<JsonWebSignatureAlg>> {
|
||||||
if let Some(alg) = self.alg {
|
if let Some(alg) = self.alg {
|
||||||
Some(vec![alg])
|
Some(vec![alg])
|
||||||
} else {
|
} else {
|
||||||
match &self.parameters {
|
match self.parameters.kty() {
|
||||||
JsonWebKeyParameters::Rsa { .. } => Some(vec![
|
JsonWebKeyType::Rsa => Some(vec![
|
||||||
JsonWebSignatureAlg::Rs256,
|
JsonWebSignatureAlg::Rs256,
|
||||||
JsonWebSignatureAlg::Rs384,
|
JsonWebSignatureAlg::Rs384,
|
||||||
JsonWebSignatureAlg::Rs512,
|
JsonWebSignatureAlg::Rs512,
|
||||||
@ -166,13 +172,22 @@ impl Constrainable for JsonWebKey {
|
|||||||
JsonWebSignatureAlg::Ps384,
|
JsonWebSignatureAlg::Ps384,
|
||||||
JsonWebSignatureAlg::Ps512,
|
JsonWebSignatureAlg::Ps512,
|
||||||
]),
|
]),
|
||||||
JsonWebKeyParameters::Ec(params) => match params.crv() {
|
JsonWebKeyType::Ec => {
|
||||||
|
todo!()
|
||||||
|
/*
|
||||||
|
match params.crv() {
|
||||||
JsonWebKeyEcEllipticCurve::P256 => Some(vec![JsonWebSignatureAlg::Es256]),
|
JsonWebKeyEcEllipticCurve::P256 => Some(vec![JsonWebSignatureAlg::Es256]),
|
||||||
JsonWebKeyEcEllipticCurve::P384 => Some(vec![JsonWebSignatureAlg::Es384]),
|
JsonWebKeyEcEllipticCurve::P384 => Some(vec![JsonWebSignatureAlg::Es384]),
|
||||||
JsonWebKeyEcEllipticCurve::P521 => Some(vec![JsonWebSignatureAlg::Es512]),
|
JsonWebKeyEcEllipticCurve::P521 => Some(vec![JsonWebSignatureAlg::Es512]),
|
||||||
JsonWebKeyEcEllipticCurve::Secp256K1 => Some(vec![JsonWebSignatureAlg::Es256K]),
|
JsonWebKeyEcEllipticCurve::Secp256K1 => Some(vec![JsonWebSignatureAlg::Es256K]),
|
||||||
},
|
}, */
|
||||||
JsonWebKeyParameters::Okp { .. } => Some(vec![JsonWebSignatureAlg::EdDsa]),
|
}
|
||||||
|
JsonWebKeyType::Okp => Some(vec![JsonWebSignatureAlg::EdDsa]),
|
||||||
|
JsonWebKeyType::Oct => Some(vec![
|
||||||
|
JsonWebSignatureAlg::Hs256,
|
||||||
|
JsonWebSignatureAlg::Hs384,
|
||||||
|
JsonWebSignatureAlg::Hs512,
|
||||||
|
]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,21 +198,25 @@ impl Constrainable for JsonWebKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct JsonWebKeySet {
|
pub struct JsonWebKeySet<P> {
|
||||||
keys: Vec<JsonWebKey>,
|
keys: Vec<JsonWebKey<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for JsonWebKeySet {
|
pub type PublicJsonWebKeySet = JsonWebKeySet<self::public_parameters::JsonWebKeyPublicParameters>;
|
||||||
type Target = Vec<JsonWebKey>;
|
pub type PrivateJsonWebKeySet =
|
||||||
|
JsonWebKeySet<self::private_parameters::JsonWebKeyPrivateParameters>;
|
||||||
|
|
||||||
|
impl<P> std::ops::Deref for JsonWebKeySet<P> {
|
||||||
|
type Target = Vec<JsonWebKey<P>>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.keys
|
&self.keys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonWebKeySet {
|
impl<P> JsonWebKeySet<P> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(keys: Vec<JsonWebKey>) -> Self {
|
pub fn new(keys: Vec<JsonWebKey<P>>) -> Self {
|
||||||
Self { keys }
|
Self { keys }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebKeyOkpEllipticCurve};
|
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebKeyOkpEllipticCurve, JsonWebKeyType};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::{
|
use serde_with::{
|
||||||
@ -21,6 +21,8 @@ use serde_with::{
|
|||||||
serde_as,
|
serde_as,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::JwkKty;
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(tag = "kty")]
|
#[serde(tag = "kty")]
|
||||||
@ -38,6 +40,17 @@ pub enum JsonWebKeyPrivateParameters {
|
|||||||
Okp(OkpPrivateParameters),
|
Okp(OkpPrivateParameters),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl JwkKty for JsonWebKeyPrivateParameters {
|
||||||
|
fn kty(&self) -> JsonWebKeyType {
|
||||||
|
match self {
|
||||||
|
Self::Oct(_) => JsonWebKeyType::Oct,
|
||||||
|
Self::Rsa(_) => JsonWebKeyType::Rsa,
|
||||||
|
Self::Ec(_) => JsonWebKeyType::Ec,
|
||||||
|
Self::Okp(_) => JsonWebKeyType::Okp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct OctPrivateParameters {
|
pub struct OctPrivateParameters {
|
||||||
|
@ -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 mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebKeyOkpEllipticCurve};
|
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebKeyOkpEllipticCurve, JsonWebKeyType};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::{
|
use serde_with::{
|
||||||
@ -21,6 +21,8 @@ use serde_with::{
|
|||||||
serde_as,
|
serde_as,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::JwkKty;
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(tag = "kty")]
|
#[serde(tag = "kty")]
|
||||||
@ -35,6 +37,16 @@ pub enum JsonWebKeyPublicParameters {
|
|||||||
Okp(OkpPublicParameters),
|
Okp(OkpPublicParameters),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl JwkKty for JsonWebKeyPublicParameters {
|
||||||
|
fn kty(&self) -> JsonWebKeyType {
|
||||||
|
match self {
|
||||||
|
Self::Rsa(_) => JsonWebKeyType::Rsa,
|
||||||
|
Self::Ec(_) => JsonWebKeyType::Ec,
|
||||||
|
Self::Okp(_) => JsonWebKeyType::Okp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct RsaPublicParameters {
|
pub struct RsaPublicParameters {
|
||||||
|
@ -21,7 +21,7 @@ use serde_with::{
|
|||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::jwk::JsonWebKey;
|
use crate::jwk::PublicJsonWebKey;
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
@ -33,7 +33,7 @@ pub struct JsonWebSignatureHeader {
|
|||||||
jku: Option<Url>,
|
jku: Option<Url>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
jwk: Option<JsonWebKey>,
|
jwk: Option<PublicJsonWebKey>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
kid: Option<String>,
|
kid: Option<String>,
|
||||||
@ -98,12 +98,12 @@ impl JsonWebSignatureHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn jwk(&self) -> Option<&JsonWebKey> {
|
pub const fn jwk(&self) -> Option<&PublicJsonWebKey> {
|
||||||
self.jwk.as_ref()
|
self.jwk.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_jwk(mut self, jwk: JsonWebKey) -> Self {
|
pub fn with_jwk(mut self, jwk: PublicJsonWebKey) -> Self {
|
||||||
self.jwk = Some(jwk);
|
self.jwk = Some(jwk);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ use tower::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::StaticJwksStore;
|
use super::StaticJwksStore;
|
||||||
use crate::{JsonWebKeySet, JsonWebSignatureHeader, VerifyingKeystore};
|
use crate::{jwk::PublicJsonWebKeySet, JsonWebSignatureHeader, VerifyingKeystore};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -60,7 +60,7 @@ impl<E> Default for State<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<E> State<E> {
|
impl<E> State<E> {
|
||||||
fn fullfill(&mut self, key_set: JsonWebKeySet) {
|
fn fullfill(&mut self, key_set: PublicJsonWebKeySet) {
|
||||||
*self = Self::Fulfilled {
|
*self = Self::Fulfilled {
|
||||||
at: Utc::now(),
|
at: Utc::now(),
|
||||||
store: StaticJwksStore::new(key_set),
|
store: StaticJwksStore::new(key_set),
|
||||||
@ -100,14 +100,14 @@ impl<E> State<E> {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DynamicJwksStore {
|
pub struct DynamicJwksStore {
|
||||||
exporter: BoxCloneService<(), JsonWebKeySet, BoxError>,
|
exporter: BoxCloneService<(), PublicJsonWebKeySet, BoxError>,
|
||||||
cache: Arc<RwLock<State<Arc<BoxError>>>>,
|
cache: Arc<RwLock<State<Arc<BoxError>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DynamicJwksStore {
|
impl DynamicJwksStore {
|
||||||
pub fn new<T>(exporter: T) -> Self
|
pub fn new<T>(exporter: T) -> Self
|
||||||
where
|
where
|
||||||
T: Service<(), Response = JsonWebKeySet, Error = BoxError> + Send + Clone + 'static,
|
T: Service<(), Response = PublicJsonWebKeySet, Error = BoxError> + Send + Clone + 'static,
|
||||||
T::Future: Send,
|
T::Future: Send,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
|
@ -22,8 +22,9 @@ use signature::{Signature, Verifier};
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constraints::Constrainable, JsonWebKey, JsonWebKeySet, JsonWebSignatureHeader,
|
constraints::Constrainable,
|
||||||
VerifyingKeystore,
|
jwk::{PublicJsonWebKey, PublicJsonWebKeySet},
|
||||||
|
JsonWebSignatureHeader, VerifyingKeystore,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
@ -60,7 +61,7 @@ struct KeyConstraint<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> KeyConstraint<'a> {
|
impl<'a> KeyConstraint<'a> {
|
||||||
fn matches(&self, key: &'a JsonWebKey) -> bool {
|
fn matches(&self, key: &'a PublicJsonWebKey) -> bool {
|
||||||
// If a specific KID was asked, match the key only if it has a matching kid
|
// If a specific KID was asked, match the key only if it has a matching kid
|
||||||
// field
|
// field
|
||||||
if let Some(kid) = self.kid {
|
if let Some(kid) = self.kid {
|
||||||
@ -84,22 +85,25 @@ impl<'a> KeyConstraint<'a> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_keys(&self, key_set: &'a JsonWebKeySet) -> Vec<&'a JsonWebKey> {
|
fn find_keys(&self, key_set: &'a PublicJsonWebKeySet) -> Vec<&'a PublicJsonWebKey> {
|
||||||
key_set.iter().filter(|k| self.matches(k)).collect()
|
key_set.iter().filter(|k| self.matches(k)).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StaticJwksStore {
|
pub struct StaticJwksStore {
|
||||||
key_set: JsonWebKeySet,
|
key_set: PublicJsonWebKeySet,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StaticJwksStore {
|
impl StaticJwksStore {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(key_set: JsonWebKeySet) -> Self {
|
pub fn new(key_set: PublicJsonWebKeySet) -> Self {
|
||||||
Self { key_set }
|
Self { key_set }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_key<'a>(&'a self, constraint: &KeyConstraint<'a>) -> Result<&'a JsonWebKey, Error> {
|
fn find_key<'a>(
|
||||||
|
&'a self,
|
||||||
|
constraint: &KeyConstraint<'a>,
|
||||||
|
) -> Result<&'a PublicJsonWebKey, Error> {
|
||||||
let keys = constraint.find_keys(&self.key_set);
|
let keys = constraint.find_keys(&self.key_set);
|
||||||
|
|
||||||
match &keys[..] {
|
match &keys[..] {
|
||||||
|
@ -34,7 +34,7 @@ use signature::{Signature, Signer, Verifier};
|
|||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
use super::{SigningKeystore, VerifyingKeystore};
|
use super::{SigningKeystore, VerifyingKeystore};
|
||||||
use crate::{JsonWebKey, JsonWebKeySet, JsonWebSignatureHeader};
|
use crate::{jwk::PublicJsonWebKeySet, JsonWebKey, JsonWebKeySet, JsonWebSignatureHeader};
|
||||||
|
|
||||||
// Generate with
|
// Generate with
|
||||||
// openssl genrsa 2048
|
// openssl genrsa 2048
|
||||||
@ -365,7 +365,7 @@ impl VerifyingKeystore for StaticKeystore {
|
|||||||
|
|
||||||
impl Service<()> for &StaticKeystore {
|
impl Service<()> for &StaticKeystore {
|
||||||
type Future = Ready<Result<Self::Response, Self::Error>>;
|
type Future = Ready<Result<Self::Response, Self::Error>>;
|
||||||
type Response = JsonWebKeySet;
|
type Response = PublicJsonWebKeySet;
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
pub mod claims;
|
pub mod claims;
|
||||||
pub mod constraints;
|
pub mod constraints;
|
||||||
pub mod hmac;
|
pub mod hmac;
|
||||||
pub(crate) mod jwk;
|
pub mod jwk;
|
||||||
pub(crate) mod jwt;
|
pub(crate) mod jwt;
|
||||||
mod keystore;
|
mod keystore;
|
||||||
pub(crate) mod rsa;
|
pub(crate) mod rsa;
|
||||||
|
@ -20,7 +20,7 @@ use mas_iana::{
|
|||||||
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
||||||
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
||||||
};
|
};
|
||||||
use mas_jose::JsonWebKeySet;
|
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{DeserializeOwned, Error},
|
de::{DeserializeOwned, Error},
|
||||||
ser::SerializeMap,
|
ser::SerializeMap,
|
||||||
@ -99,7 +99,7 @@ pub struct ClientMetadataSerdeHelper {
|
|||||||
application_type: Option<ApplicationType>,
|
application_type: Option<ApplicationType>,
|
||||||
contacts: Option<Vec<String>>,
|
contacts: Option<Vec<String>>,
|
||||||
jwks_uri: Option<Url>,
|
jwks_uri: Option<Url>,
|
||||||
jwks: Option<JsonWebKeySet>,
|
jwks: Option<PublicJsonWebKeySet>,
|
||||||
sector_identifier_uri: Option<Url>,
|
sector_identifier_uri: Option<Url>,
|
||||||
subject_type: Option<SubjectType>,
|
subject_type: Option<SubjectType>,
|
||||||
token_endpoint_auth_method: Option<OAuthClientAuthenticationMethod>,
|
token_endpoint_auth_method: Option<OAuthClientAuthenticationMethod>,
|
||||||
|
@ -20,7 +20,7 @@ use mas_iana::{
|
|||||||
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
||||||
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
||||||
};
|
};
|
||||||
use mas_jose::JsonWebKeySet;
|
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::{serde_as, skip_serializing_none, TimestampSeconds};
|
use serde_with::{serde_as, skip_serializing_none, TimestampSeconds};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -197,7 +197,7 @@ pub struct ClientMetadata {
|
|||||||
/// This field is mutually exclusive with `jwks_uri`.
|
/// This field is mutually exclusive with `jwks_uri`.
|
||||||
///
|
///
|
||||||
/// [JWK]: https://www.rfc-editor.org/rfc/rfc7517.html
|
/// [JWK]: https://www.rfc-editor.org/rfc/rfc7517.html
|
||||||
pub jwks: Option<JsonWebKeySet>,
|
pub jwks: Option<PublicJsonWebKeySet>,
|
||||||
|
|
||||||
/// URL to be used in calculating pseudonymous identifiers by the OpenID
|
/// URL to be used in calculating pseudonymous identifiers by the OpenID
|
||||||
/// Connect provider when [pairwise subject identifiers] are used.
|
/// Connect provider when [pairwise subject identifiers] are used.
|
||||||
@ -861,7 +861,7 @@ mod tests {
|
|||||||
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
jose::{JsonWebEncryptionAlg, JsonWebEncryptionEnc, JsonWebSignatureAlg},
|
||||||
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
||||||
};
|
};
|
||||||
use mas_jose::JsonWebKeySet;
|
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use super::{ClientMetadata, ClientMetadataVerificationError};
|
use super::{ClientMetadata, ClientMetadataVerificationError};
|
||||||
@ -874,7 +874,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jwks() -> JsonWebKeySet {
|
fn jwks() -> PublicJsonWebKeySet {
|
||||||
serde_json::from_value(serde_json::json!({
|
serde_json::from_value(serde_json::json!({
|
||||||
"keys": [
|
"keys": [
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ use mas_iana::{
|
|||||||
jose::JsonWebSignatureAlg,
|
jose::JsonWebSignatureAlg,
|
||||||
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
||||||
};
|
};
|
||||||
use mas_jose::JsonWebKeySet;
|
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||||
use oauth2_types::requests::GrantType;
|
use oauth2_types::requests::GrantType;
|
||||||
use sqlx::{PgConnection, PgExecutor};
|
use sqlx::{PgConnection, PgExecutor};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -331,7 +331,7 @@ pub async fn insert_client(
|
|||||||
policy_uri: Option<&Url>,
|
policy_uri: Option<&Url>,
|
||||||
tos_uri: Option<&Url>,
|
tos_uri: Option<&Url>,
|
||||||
jwks_uri: Option<&Url>,
|
jwks_uri: Option<&Url>,
|
||||||
jwks: Option<&JsonWebKeySet>,
|
jwks: Option<&PublicJsonWebKeySet>,
|
||||||
id_token_signed_response_alg: Option<JsonWebSignatureAlg>,
|
id_token_signed_response_alg: Option<JsonWebSignatureAlg>,
|
||||||
userinfo_signed_response_alg: Option<JsonWebSignatureAlg>,
|
userinfo_signed_response_alg: Option<JsonWebSignatureAlg>,
|
||||||
token_endpoint_auth_method: Option<OAuthClientAuthenticationMethod>,
|
token_endpoint_auth_method: Option<OAuthClientAuthenticationMethod>,
|
||||||
@ -421,7 +421,7 @@ pub async fn insert_client_from_config(
|
|||||||
client_id: &str,
|
client_id: &str,
|
||||||
client_auth_method: OAuthClientAuthenticationMethod,
|
client_auth_method: OAuthClientAuthenticationMethod,
|
||||||
encrypted_client_secret: Option<&str>,
|
encrypted_client_secret: Option<&str>,
|
||||||
jwks: Option<&JsonWebKeySet>,
|
jwks: Option<&PublicJsonWebKeySet>,
|
||||||
jwks_uri: Option<&Url>,
|
jwks_uri: Option<&Url>,
|
||||||
redirect_uris: &[Url],
|
redirect_uris: &[Url],
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
Reference in New Issue
Block a user