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}