identity_jose/jws/custom_verification/jws_verifier.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
// Copyright 2020-2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
use super::SignatureVerificationError;
use crate::jwk::Jwk;
use crate::jws::JwsAlgorithm;
/// Input a [`JwsVerifier`] verifies.
pub struct VerificationInput {
/// The `alg` parsed from the protected header.
pub alg: JwsAlgorithm,
/// The signing input.
///
/// See [RFC 7515: section 5.2 part 8.](https://www.rfc-editor.org/rfc/rfc7515#section-5.2) and
/// [RFC 7797 section 3](https://www.rfc-editor.org/rfc/rfc7797#section-3).
pub signing_input: Box<[u8]>,
/// The decoded signature to validate the `signing_input` against in the manner defined by the `alg` field.
pub decoded_signature: Box<[u8]>,
}
/// Trait for cryptographically verifying a JWS signature.
///
/// Any type implementing this trait can be passed to
/// [`JwsValidationItem::verify`](`crate::jws::JwsValidationItem::verify`) which is intended
/// as the most convenient way to verify a decoded JWS.
///
/// [`JwsValidationItem::verify`](crate::jws::JwsValidationItem::verify)
///
/// ## Implementation
///
/// Implementers are expected to provide a procedure for step 8 of
/// [RFC 7515 section 5.2](https://www.rfc-editor.org/rfc/rfc7515#section-5.2) for
/// the JWS signature algorithms they want to support.
///
/// Custom implementations can be constructed inline by converting a suitable closure into a [`JwsVerifierFn`]
/// using the [`From`] trait.
///
/// ## Default implementation
///
/// When the `eddsa` feature is enabled one can construct an implementor
/// provided by the IOTA Identity library. See
/// [`EdDSAJwsVerifier::verify`](EdDSAJwsVerifier::verify).
pub trait JwsVerifier {
/// Validate the `decoded_signature` against the `signing_input` in the manner defined by `alg` using the
/// `public_key`.
///
/// Implementors may decide to error with
/// [`SignatureVerificationErrorKind::UnsupportedAlg`](crate::jws::SignatureVerificationErrorKind::UnsupportedAlg) if
/// they are not interested in supporting a given algorithm.
fn verify(&self, input: VerificationInput, public_key: &Jwk) -> Result<(), SignatureVerificationError>;
}
impl JwsVerifier for Box<dyn JwsVerifier> {
fn verify(&self, input: VerificationInput, public_key: &Jwk) -> Result<(), SignatureVerificationError> {
<dyn JwsVerifier>::verify(self, input, public_key)
}
}
// =================================================================================================================
// Implementation
// ================================================================================================================
/// Simple wrapper around a closure capable of verifying a JWS signature. This wrapper implements
/// [`JwsVerifier`].
///
/// Note: One can convert a closure to this wrapper using the [`From`] trait.
pub struct JwsVerifierFn<F>(F);
impl<F> From<F> for JwsVerifierFn<F>
where
F: Fn(VerificationInput, &Jwk) -> Result<(), SignatureVerificationError>,
{
fn from(value: F) -> Self {
Self(value)
}
}
impl<F> JwsVerifier for JwsVerifierFn<F>
where
F: Fn(VerificationInput, &Jwk) -> Result<(), SignatureVerificationError>,
{
fn verify(&self, input: VerificationInput, public_key: &Jwk) -> Result<(), SignatureVerificationError> {
self.0(input, public_key)
}
}