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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! Claims verification traits.
//!
//! This modules defines all the trait taking part in the verification pipeline.
//!
//! # Verification pipeline
//!
//! The "verification pipeline" is the sequence of steps executed by this
//! library to go from a set of verifiable claims ([`VerifiableClaims`]) to a
//! [`ProofValidity`] result.
//! It is defined as follows:
//!   - Proof extraction: the claims are separated from the proof using the
//!     [`ExtractProof`] trait.
//!   - Proof preparation: the proof is *prepared* to verify the input claims
//!     using the [`PrepareWith`] trait. This steps computes any information
//!     derived from the claims and/or proof required for the verification.
//!     At this point, the claims and prepared proof are stored together in a
//!     [`Verifiable`](crate::Verifiable) instance, ready for verification.
//!   - Claims validation: the claims are validated using the [`Validate`]
//!     trait.
//!   - Proof validation: the claims verified against the proof using the
//!     [`ValidateProof`] trait.
mod claims;

use chrono::{DateTime, Utc};
pub use claims::*;
mod proof;
pub use proof::*;
mod parameters;
pub use parameters::*;

/// Verifiable Claims.
///
/// Set of claims bundled with a proof.
pub trait VerifiableClaims {
    /// Claims type.
    type Claims;

    /// Proof type.
    type Proof;

    /// The claims.
    fn claims(&self) -> &Self::Claims;

    /// The proof.
    fn proof(&self) -> &Self::Proof;

    /// Validates the claims and proof.
    ///
    /// The `params` argument provides all the verification parameters required
    /// to validate the claims and proof.
    ///
    /// # What verification parameters should I use?
    ///
    /// It really depends on the claims type `Self::Claims` and proof type
    /// `Self::Proof`, but the [`VerificationParameters`] type is a good
    /// starting point that should work most of the time.
    ///
    /// # Passing the parameters by reference
    ///
    /// If the validation traits are implemented for `P`, they will be
    /// implemented for `&P` as well. This means the parameters can be passed
    /// by move *or* by reference.
    #[allow(async_fn_in_trait)]
    async fn verify<P>(&self, params: P) -> Result<Verification, ProofValidationError>
    where
        Self::Claims: ValidateClaims<P, Self::Proof>,
        Self::Proof: ValidateProof<P, Self::Claims>,
    {
        match self.claims().validate_claims(&params, self.proof()) {
            Ok(_) => self
                .proof()
                .validate_proof(&params, self.claims())
                .await
                .map(|r| r.map_err(Invalid::Proof)),
            Err(e) => {
                // Claims are not valid on their own.
                Ok(Err(Invalid::Claims(e)))
            }
        }
    }
}

/// Proof bundling trait.
///
/// Provides a method to bundle the set of claims with a proof.
pub trait AttachProof<T> {
    /// Set of claims with a proof.
    type Attached;

    /// Bundles the given claims with this proof.
    fn attach_to(self, claims: T) -> Self::Attached;
}

/// Verification outcome.
pub type Verification = Result<(), Invalid>;

/// Invalid verifiable claims.
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum Invalid {
    #[error("invalid claims: {0}")]
    Claims(#[from] InvalidClaims),

    #[error("invalid proof: {0}")]
    Proof(#[from] InvalidProof),
}

/// Arbitrary resource provider.
pub trait ResourceProvider<T> {
    /// Returns a reference to the resource of type `T`.
    fn get_resource(&self) -> &T;
}

/// Anything can return the unit resource.
impl<T> ResourceProvider<()> for T {
    fn get_resource(&self) -> &() {
        &()
    }
}

/// Type that provides a public key resolver.
pub trait ResolverProvider {
    /// Public key resolver.
    type Resolver;

    /// Returns a reference to the environment's public key resolver.
    fn resolver(&self) -> &Self::Resolver;
}

impl<'a, E: ResolverProvider> ResolverProvider for &'a E {
    type Resolver = E::Resolver;

    fn resolver(&self) -> &Self::Resolver {
        E::resolver(*self)
    }
}

/// Type that provides date and time.
///
/// Used to check the validity period of given claims.
pub trait DateTimeProvider {
    /// Returns the current date and time.
    fn date_time(&self) -> DateTime<Utc>;
}

impl<'a, E: DateTimeProvider> DateTimeProvider for &'a E {
    fn date_time(&self) -> DateTime<Utc> {
        E::date_time(*self)
    }
}