1
0
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:
Quentin Gliech
2023-12-05 16:45:40 +01:00
parent df3ca5ae66
commit a0f5f3c642
88 changed files with 567 additions and 236 deletions

View File

@@ -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)
}

View File

@@ -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.
///

View File

@@ -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,

View File

@@ -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))

View File

@@ -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

View File

@@ -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,

View File

@@ -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;