You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-07 17:03:01 +03:00
Enable clippy lints on a workspace level
This enables a lot more lints than before in some crates, so this fixed a lot of warnings as well.
This commit is contained in:
@@ -56,6 +56,10 @@ impl<C: Encoding> Base64<C> {
|
||||
}
|
||||
|
||||
/// Parse some base64-encoded data to create a `Base64` instance.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the input is not valid base64.
|
||||
pub fn parse(encoded: &str) -> Result<Self, base64ct::Error> {
|
||||
C::decode_vec(encoded).map(Self::new)
|
||||
}
|
||||
|
@@ -37,7 +37,14 @@ pub enum ClaimError {
|
||||
}
|
||||
|
||||
pub trait Validator<T> {
|
||||
/// The associated error type returned by this validator.
|
||||
type Error;
|
||||
|
||||
/// Validate a claim value
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value is invalid.
|
||||
fn validate(&self, value: &T) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
@@ -68,6 +75,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a claim into the given claims map.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value failed to serialize.
|
||||
pub fn insert<I>(
|
||||
&self,
|
||||
claims: &mut HashMap<String, serde_json::Value>,
|
||||
@@ -85,6 +97,12 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Extract a claim from the given claims map.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value failed to deserialize, if its value is
|
||||
/// invalid or if the claim is missing.
|
||||
pub fn extract_required(
|
||||
&self,
|
||||
claims: &mut HashMap<String, serde_json::Value>,
|
||||
@@ -98,6 +116,12 @@ where
|
||||
self.extract_required_with_options(claims, validator)
|
||||
}
|
||||
|
||||
/// Extract a claim from the given claims map, with the given options.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value failed to deserialize, if its value is
|
||||
/// invalid or if the claim is missing.
|
||||
pub fn extract_required_with_options<I>(
|
||||
&self,
|
||||
claims: &mut HashMap<String, serde_json::Value>,
|
||||
@@ -124,6 +148,12 @@ where
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Extract a claim from the given claims map, if it exists.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value failed to deserialize or if its value is
|
||||
/// invalid.
|
||||
pub fn extract_optional(
|
||||
&self,
|
||||
claims: &mut HashMap<String, serde_json::Value>,
|
||||
@@ -137,6 +167,13 @@ where
|
||||
self.extract_optional_with_options(claims, validator)
|
||||
}
|
||||
|
||||
/// Extract a claim from the given claims map, if it exists, with the given
|
||||
/// options.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value failed to deserialize or if its value is
|
||||
/// invalid.
|
||||
pub fn extract_optional_with_options<I>(
|
||||
&self,
|
||||
claims: &mut HashMap<String, serde_json::Value>,
|
||||
@@ -238,7 +275,7 @@ impl From<&TimeOptions> for TimeNotBefore {
|
||||
///
|
||||
/// According to the [OpenID Connect Core 1.0 specification].
|
||||
///
|
||||
/// # Errors
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the algorithm is not supported.
|
||||
///
|
||||
|
@@ -57,21 +57,29 @@ pub enum AsymmetricSigningKey {
|
||||
}
|
||||
|
||||
impl AsymmetricSigningKey {
|
||||
/// Create a new signing key with the RS256 algorithm from the given RSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn rs256(key: rsa::RsaPrivateKey) -> Self {
|
||||
Self::Rs256(rsa::pkcs1v15::SigningKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the RS384 algorithm from the given RSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn rs384(key: rsa::RsaPrivateKey) -> Self {
|
||||
Self::Rs384(rsa::pkcs1v15::SigningKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the RS512 algorithm from the given RSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn rs512(key: rsa::RsaPrivateKey) -> Self {
|
||||
Self::Rs512(rsa::pkcs1v15::SigningKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the PS256 algorithm from the given RSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn ps256(key: rsa::RsaPrivateKey) -> Self {
|
||||
Self::Ps256(rsa::pss::SigningKey::new_with_salt_len(
|
||||
@@ -80,6 +88,8 @@ impl AsymmetricSigningKey {
|
||||
))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the PS384 algorithm from the given RSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn ps384(key: rsa::RsaPrivateKey) -> Self {
|
||||
Self::Ps384(rsa::pss::SigningKey::new_with_salt_len(
|
||||
@@ -88,6 +98,8 @@ impl AsymmetricSigningKey {
|
||||
))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the PS512 algorithm from the given RSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn ps512(key: rsa::RsaPrivateKey) -> Self {
|
||||
Self::Ps512(rsa::pss::SigningKey::new_with_salt_len(
|
||||
@@ -96,21 +108,34 @@ impl AsymmetricSigningKey {
|
||||
))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the ES256 algorithm from the given ECDSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn es256(key: elliptic_curve::SecretKey<p256::NistP256>) -> Self {
|
||||
Self::Es256(ecdsa::SigningKey::from(key))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the ES384 algorithm from the given ECDSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn es384(key: elliptic_curve::SecretKey<p384::NistP384>) -> Self {
|
||||
Self::Es384(ecdsa::SigningKey::from(key))
|
||||
}
|
||||
|
||||
/// Create a new signing key with the ES256K algorithm from the given ECDSA
|
||||
/// private key.
|
||||
#[must_use]
|
||||
pub fn es256k(key: elliptic_curve::SecretKey<k256::Secp256k1>) -> Self {
|
||||
Self::Es256K(ecdsa::SigningKey::from(key))
|
||||
}
|
||||
|
||||
/// Create a new signing key for the given algorithm from the given private
|
||||
/// JWK parameters.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the key parameters are not suitable for the given
|
||||
/// algorithm.
|
||||
pub fn from_jwk_and_alg(
|
||||
params: &JsonWebKeyPrivateParameters,
|
||||
alg: &JsonWebSignatureAlg,
|
||||
@@ -275,51 +300,76 @@ pub enum AsymmetricVerifyingKey {
|
||||
}
|
||||
|
||||
impl AsymmetricVerifyingKey {
|
||||
/// Create a new verifying key with the RS256 algorithm from the given RSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn rs256(key: rsa::RsaPublicKey) -> Self {
|
||||
Self::Rs256(rsa::pkcs1v15::VerifyingKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the RS384 algorithm from the given RSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn rs384(key: rsa::RsaPublicKey) -> Self {
|
||||
Self::Rs384(rsa::pkcs1v15::VerifyingKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the RS512 algorithm from the given RSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn rs512(key: rsa::RsaPublicKey) -> Self {
|
||||
Self::Rs512(rsa::pkcs1v15::VerifyingKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the PS256 algorithm from the given RSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn ps256(key: rsa::RsaPublicKey) -> Self {
|
||||
Self::Ps256(rsa::pss::VerifyingKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the PS384 algorithm from the given RSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn ps384(key: rsa::RsaPublicKey) -> Self {
|
||||
Self::Ps384(rsa::pss::VerifyingKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the PS512 algorithm from the given RSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn ps512(key: rsa::RsaPublicKey) -> Self {
|
||||
Self::Ps512(rsa::pss::VerifyingKey::new(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the ES256 algorithm from the given ECDSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn es256(key: elliptic_curve::PublicKey<p256::NistP256>) -> Self {
|
||||
Self::Es256(ecdsa::VerifyingKey::from(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the ES384 algorithm from the given ECDSA
|
||||
/// public key.
|
||||
#[must_use]
|
||||
pub fn es384(key: elliptic_curve::PublicKey<p384::NistP384>) -> Self {
|
||||
Self::Es384(ecdsa::VerifyingKey::from(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key with the ES256K algorithm from the given
|
||||
/// ECDSA public key.
|
||||
#[must_use]
|
||||
pub fn es256k(key: elliptic_curve::PublicKey<k256::Secp256k1>) -> Self {
|
||||
Self::Es256K(ecdsa::VerifyingKey::from(key))
|
||||
}
|
||||
|
||||
/// Create a new verifying key for the given algorithm from the given public
|
||||
/// JWK parameters.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the key parameters are not suitable for the given
|
||||
/// algorithm.
|
||||
pub fn from_jwk_and_alg(
|
||||
params: &JsonWebKeyPublicParameters,
|
||||
alg: &JsonWebSignatureAlg,
|
||||
|
@@ -33,6 +33,11 @@ pub struct InvalidAlgorithm {
|
||||
}
|
||||
|
||||
impl SymmetricKey {
|
||||
/// Create a new symmetric key for the given algorithm with the given key.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the algorithm is not supported.
|
||||
pub fn new_for_alg(key: Vec<u8>, alg: &JsonWebSignatureAlg) -> Result<Self, InvalidAlgorithm> {
|
||||
match alg {
|
||||
JsonWebSignatureAlg::Hs256 => Ok(Self::hs256(key)),
|
||||
@@ -45,16 +50,19 @@ impl SymmetricKey {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new symmetric key using the HS256 algorithm with the given key.
|
||||
#[must_use]
|
||||
pub const fn hs256(key: Vec<u8>) -> Self {
|
||||
Self::Hs256(super::Hs256Key::new(key))
|
||||
}
|
||||
|
||||
/// Create a new symmetric key using the HS384 algorithm with the given key.
|
||||
#[must_use]
|
||||
pub const fn hs384(key: Vec<u8>) -> Self {
|
||||
Self::Hs384(super::Hs384Key::new(key))
|
||||
}
|
||||
|
||||
/// Create a new symmetric key using the HS512 algorithm with the given key.
|
||||
#[must_use]
|
||||
pub const fn hs512(key: Vec<u8>) -> Self {
|
||||
Self::Hs512(super::Hs512Key::new(key))
|
||||
|
@@ -106,6 +106,7 @@ impl TryFrom<PrivateJsonWebKey> for PublicJsonWebKey {
|
||||
}
|
||||
|
||||
impl<P> JsonWebKey<P> {
|
||||
/// Create a new [`JsonWebKey`] with the given parameters.
|
||||
#[must_use]
|
||||
pub const fn new(parameters: P) -> Self {
|
||||
Self {
|
||||
@@ -121,6 +122,12 @@ impl<P> JsonWebKey<P> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Map the parameters of this [`JsonWebKey`] to a new type, with a fallible
|
||||
/// mapper, consuming the original key.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the mapper returns an error.
|
||||
pub fn try_map<M, O, E>(self, mapper: M) -> Result<JsonWebKey<O>, E>
|
||||
where
|
||||
M: FnOnce(P) -> Result<O, E>,
|
||||
@@ -138,6 +145,8 @@ impl<P> JsonWebKey<P> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Map the parameters of this [`JsonWebKey`] to a new type, consuming the
|
||||
/// original key.
|
||||
pub fn map<M, O>(self, mapper: M) -> JsonWebKey<O>
|
||||
where
|
||||
M: FnOnce(P) -> O,
|
||||
@@ -155,6 +164,12 @@ impl<P> JsonWebKey<P> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Map the parameters of this [`JsonWebKey`] to a new type, with a fallible
|
||||
/// mapper, cloning the other fields.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the mapper returns an error.
|
||||
pub fn try_cloned_map<M, O, E>(&self, mapper: M) -> Result<JsonWebKey<O>, E>
|
||||
where
|
||||
M: FnOnce(&P) -> Result<O, E>,
|
||||
@@ -172,6 +187,8 @@ impl<P> JsonWebKey<P> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Map the parameters of this [`JsonWebKey`] to a new type, cloning the
|
||||
/// other fields.
|
||||
pub fn cloned_map<M, O>(&self, mapper: M) -> JsonWebKey<O>
|
||||
where
|
||||
M: FnOnce(&P) -> O,
|
||||
@@ -189,35 +206,41 @@ impl<P> JsonWebKey<P> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the `use` field of this [`JsonWebKey`].
|
||||
#[must_use]
|
||||
pub fn with_use(mut self, value: JsonWebKeyUse) -> Self {
|
||||
self.r#use = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the `key_ops` field of this [`JsonWebKey`].
|
||||
#[must_use]
|
||||
pub fn with_key_ops(mut self, key_ops: Vec<JsonWebKeyOperation>) -> Self {
|
||||
self.key_ops = Some(key_ops);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the `alg` field of this [`JsonWebKey`].
|
||||
#[must_use]
|
||||
pub fn with_alg(mut self, alg: JsonWebSignatureAlg) -> Self {
|
||||
self.alg = Some(alg);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the `kid` field of this [`JsonWebKey`].
|
||||
#[must_use]
|
||||
pub fn with_kid(mut self, kid: impl Into<String>) -> Self {
|
||||
self.kid = Some(kid.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the `kid` field of this [`JsonWebKey`], if set.
|
||||
#[must_use]
|
||||
pub const fn alg(&self) -> Option<&JsonWebSignatureAlg> {
|
||||
self.alg.as_ref()
|
||||
}
|
||||
|
||||
/// Get the inner parameters of this [`JsonWebKey`].
|
||||
#[must_use]
|
||||
pub const fn params(&self) -> &P {
|
||||
&self.parameters
|
||||
|
@@ -192,10 +192,12 @@ pub struct NoKeyWorked {
|
||||
}
|
||||
|
||||
impl<'a, T> Jwt<'a, T> {
|
||||
/// Get the JWT header
|
||||
pub fn header(&self) -> &JsonWebSignatureHeader {
|
||||
&self.header
|
||||
}
|
||||
|
||||
/// Get the JWT payload
|
||||
pub fn payload(&self) -> &T {
|
||||
&self.payload
|
||||
}
|
||||
@@ -209,6 +211,11 @@ impl<'a, T> Jwt<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify the signature of this JWT using the given key.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the signature is invalid.
|
||||
pub fn verify<K, S>(&self, key: &K) -> Result<(), JwtVerificationError>
|
||||
where
|
||||
K: Verifier<S>,
|
||||
@@ -221,6 +228,12 @@ impl<'a, T> Jwt<'a, T> {
|
||||
.map_err(JwtVerificationError::verify)
|
||||
}
|
||||
|
||||
/// Verify the signature of this JWT using the given symmetric key.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the signature is invalid or if the algorithm is not
|
||||
/// supported.
|
||||
pub fn verify_with_shared_secret(&self, secret: Vec<u8>) -> Result<(), NoKeyWorked> {
|
||||
let verifier = crate::jwa::SymmetricKey::new_for_alg(secret, self.header().alg())
|
||||
.map_err(|_| NoKeyWorked::default())?;
|
||||
@@ -230,6 +243,12 @@ impl<'a, T> Jwt<'a, T> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Verify the signature of this JWT using the given JWKS.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the signature is invalid, if no key matches the
|
||||
/// constraints, or if the algorithm is not supported.
|
||||
pub fn verify_with_jwks(&self, jwks: &PublicJsonWebKeySet) -> Result<(), NoKeyWorked> {
|
||||
let constraints = ConstraintSet::from(self.header());
|
||||
let candidates = constraints.filter(&**jwks);
|
||||
@@ -250,14 +269,17 @@ impl<'a, T> Jwt<'a, T> {
|
||||
Err(NoKeyWorked::default())
|
||||
}
|
||||
|
||||
/// Get the raw JWT string as a borrowed [`str`]
|
||||
pub fn as_str(&'a self) -> &'a str {
|
||||
&self.raw
|
||||
}
|
||||
|
||||
/// Get the raw JWT string as an owned [`String`]
|
||||
pub fn into_string(self) -> String {
|
||||
self.raw.into()
|
||||
}
|
||||
|
||||
/// Split the JWT into its parts (header and payload).
|
||||
pub fn into_parts(self) -> (JsonWebSignatureHeader, T) {
|
||||
(self.header, self.payload)
|
||||
}
|
||||
@@ -295,6 +317,12 @@ impl JwtSignatureError {
|
||||
}
|
||||
|
||||
impl<T> Jwt<'static, T> {
|
||||
/// Sign the given payload with the given key.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the payload could not be serialized or if the key
|
||||
/// could not sign the payload.
|
||||
pub fn sign<K, S>(
|
||||
header: JsonWebSignatureHeader,
|
||||
payload: T,
|
||||
@@ -309,6 +337,12 @@ impl<T> Jwt<'static, T> {
|
||||
Self::sign_with_rng(&mut thread_rng(), header, payload, key)
|
||||
}
|
||||
|
||||
/// Sign the given payload with the given key using the given RNG.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the payload could not be serialized or if the key
|
||||
/// could not sign the payload.
|
||||
pub fn sign_with_rng<R, K, S>(
|
||||
rng: &mut R,
|
||||
header: JsonWebSignatureHeader,
|
||||
|
@@ -12,10 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(clippy::all, clippy::str_to_string, rustdoc::broken_intra_doc_links)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(clippy::missing_errors_doc, clippy::module_name_repetitions)]
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
|
||||
mod base64;
|
||||
pub mod claims;
|
||||
|
Reference in New Issue
Block a user