ssi_vc/v2/data_model/
credential.rs

1use iref::Uri;
2use ssi_claims_core::{ClaimsValidity, DateTimeProvider, InvalidClaims};
3use xsd_types::DateTimeStamp;
4
5use super::{AnyInternationalString, RelatedResource};
6
7pub use crate::v1::CredentialTypes;
8use crate::{Identified, MaybeIdentified, Typed};
9
10/// Verifiable Credential.
11pub trait Credential: MaybeIdentified {
12    /// Credential subject type.
13    type Subject;
14
15    /// Return type of the [`issuer`](Credential::issuer) method.
16    ///
17    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#issuer>
18    type Issuer: Identified;
19
20    type Status: MaybeIdentified + Typed;
21
22    type Schema: Identified + Typed;
23
24    type RelatedResource: RelatedResource;
25
26    /// Refresh service.
27    ///
28    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#refreshing>
29    type RefreshService: Typed;
30
31    /// Terms of Use type.
32    ///
33    /// Terms of use can be utilized by an issuer or a holder to communicate the
34    /// terms under which a verifiable credential or verifiable presentation was
35    /// issued.
36    ///
37    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#terms-of-use>
38    type TermsOfUse: MaybeIdentified + Typed;
39
40    /// Evidence type.
41    ///
42    /// Can be included by an issuer to provide the verifier with additional
43    /// supporting information in a verifiable credential.
44    type Evidence: MaybeIdentified + Typed;
45
46    /// Identifier.
47    fn id(&self) -> Option<&Uri> {
48        MaybeIdentified::id(self)
49    }
50
51    /// Types that are **not** `VerifiableCredential`.
52    ///
53    /// Since the `VerifiableCredential` type is *required*, it is omitted from
54    /// the value returned by this function. If you need to iterate over
55    /// all the credential types, including `VerifiableCredential`, use the
56    /// [`Self::types`] method.
57    fn additional_types(&self) -> &[String] {
58        &[]
59    }
60
61    fn types(&self) -> CredentialTypes {
62        CredentialTypes::from_additional_types(self.additional_types())
63    }
64
65    /// Name of the credential.
66    ///
67    /// Ideally, the name of a credential is concise, human-readable, and could
68    /// enable an individual to quickly differentiate one credential from any
69    /// other credentials that they might hold.
70    ///
71    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#names-and-descriptions>
72    fn name(&self) -> Option<impl AnyInternationalString> {
73        Option::<String>::None
74    }
75
76    /// Details about the credential.
77    ///
78    /// Ideally, the description of a credential is no more than a few sentences
79    /// in length and conveys enough information about the credential to remind
80    /// an individual of its contents without their having to look through the
81    /// entirety of the claims.
82    ///
83    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#names-and-descriptions>
84    fn description(&self) -> Option<impl AnyInternationalString> {
85        Option::<String>::None
86    }
87
88    /// Credential subject.
89    ///
90    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#credential-subject>
91    fn credential_subjects(&self) -> &[Self::Subject] {
92        &[]
93    }
94
95    /// Issuer.
96    ///
97    /// It is *recommended* that the URL be one which, if dereferenced, results
98    /// in a controller document, as defined in [VC-DATA-INTEGRITY] or
99    /// [VC-JOSE-COSE], about the issuer that can be used to verify the
100    /// information expressed in the credential.
101    ///
102    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#issuer>
103    ///
104    /// [VC-DATA-INTEGRITY]: <https://www.w3.org/TR/vc-data-integrity/>
105    /// [VC-JOSE-COSE]: <https://www.w3.org/TR/vc-jose-cose/>
106    fn issuer(&self) -> &Self::Issuer;
107
108    /// Date and time the credential becomes valid.
109    ///
110    /// Could be a date and time in the future or in the past.
111    /// Note that this value represents the earliest point in time at which the
112    /// information associated with the
113    /// [`credential_subject`](Credential::credential_subjects) property becomes
114    /// valid.
115    ///
116    /// If a [`valid_until`](Credential::valid_until) value also exists, the
117    /// [`valid_from`](Credential::valid_from) value *must* express a datetime
118    /// that is temporally the same or earlier than the datetime expressed by
119    /// the `valid_until` value.
120    ///
121    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#validity-period>
122    fn valid_from(&self) -> Option<DateTimeStamp> {
123        None
124    }
125
126    /// Date and time the credential ceases to be valid.
127    ///
128    /// Could be a date and time in the past or in the future.
129    /// Note that this value represents the latest point in time at which the
130    /// information associated with the
131    /// [`credential_subject`](Credential::credential_subjects) property is
132    /// valid.
133    ///
134    /// If a [`valid_from`](Credential::valid_from) value also exists, the
135    /// [`valid_until`](Credential::valid_until) value *must* express a datetime
136    /// that is temporally the same or later than the datetime expressed by the
137    /// `valid_from` value.
138    ///
139    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#validity-period>
140    fn valid_until(&self) -> Option<DateTimeStamp> {
141        None
142    }
143
144    /// Credential status.
145    ///
146    /// Helps discover information related to the status of the verifiable
147    /// credential, such as whether it is suspended or revoked.
148    ///
149    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#status>
150    fn credential_status(&self) -> &[Self::Status] {
151        &[]
152    }
153
154    /// Data schemas.
155    ///
156    /// Data schemas are useful when enforcing a specific structure on a given
157    /// collection of data.
158    ///
159    /// See: <https://www.w3.org/TR/vc-data-model-2.0/#data-schemas>
160    fn credential_schemas(&self) -> &[Self::Schema] {
161        &[]
162    }
163
164    /// Integrity metadata about each resource referenced by the verifiable
165    /// credential.
166    fn related_resources(&self) -> &[Self::RelatedResource] {
167        &[]
168    }
169
170    fn refresh_services(&self) -> &[Self::RefreshService] {
171        &[]
172    }
173
174    fn terms_of_use(&self) -> &[Self::TermsOfUse] {
175        &[]
176    }
177
178    fn evidence(&self) -> &[Self::Evidence] {
179        &[]
180    }
181
182    /// Validates the credential.
183    ///
184    /// Validation consists in verifying that the claims themselves are
185    /// consistent and valid with regard to the verification environment.
186    /// For instance, checking that a credential's expiration date is not in the
187    /// past, or the issue date not in the future.
188    ///
189    /// Validation may fail even if the credential proof is successfully
190    /// verified.
191    fn validate_credential<E>(&self, env: &E) -> ClaimsValidity
192    where
193        E: DateTimeProvider,
194    {
195        let now = env.date_time();
196
197        if let Some(valid_from) = self.valid_from().map(Into::into) {
198            if valid_from > now {
199                // Credential is issued in the future!
200                return Err(InvalidClaims::Premature { now, valid_from });
201            }
202        }
203
204        if let Some(valid_until) = self.valid_until().map(Into::into) {
205            if now >= valid_until {
206                // Credential has expired.
207                return Err(InvalidClaims::Expired { now, valid_until });
208            }
209        }
210
211        Ok(())
212    }
213}