From 00b65cfc5b5cc4851edf0d1bea982358739f16dd Mon Sep 17 00:00:00 2001 From: Abdulrahim Al Methiab <31316147+abdulmth@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:12:22 +0200 Subject: [PATCH] Rename `CredentialValidator` to `JwtCredentialValidator` (#1207) --- bindings/wasm/docs/api-reference.md | 146 ++++++++-------- .../src/1_advanced/5_domain_linkage.ts | 6 +- .../credential/domain_linkage_validator.rs | 20 +-- .../jwt_credential_validator.rs | 2 +- .../jwt_credential_validation/options.rs | 2 +- bindings/wasm/src/error.rs | 2 +- examples/0_basic/5_create_vc.rs | 8 +- examples/0_basic/6_create_vp.rs | 14 +- examples/0_basic/7_revoke_vc.rs | 22 +-- examples/1_advanced/6_domain_linkage.rs | 12 +- identity_credential/README.md | 2 +- .../domain_linkage_configuration.rs | 8 +- .../domain_linkage_validator.rs | 86 +++++----- .../credential_jwt_validation_options.rs | 4 +- .../credential_jwt_validator.rs | 158 +++++++++--------- .../src/validator/vc_jwt_validation/error.rs | 4 +- .../src/validator/vp_jwt_validation/error.rs | 6 +- .../jwt_presentation_validator.rs | 34 ++-- identity_storage/src/storage/tests/api.rs | 6 +- .../src/storage/tests/credential_jws.rs | 14 +- .../storage/tests/credential_validation.rs | 58 +++---- .../storage/tests/presentation_validation.rs | 18 +- 22 files changed, 315 insertions(+), 317 deletions(-) diff --git a/bindings/wasm/docs/api-reference.md b/bindings/wasm/docs/api-reference.md index 40686ddf64..62e1610d1d 100644 --- a/bindings/wasm/docs/api-reference.md +++ b/bindings/wasm/docs/api-reference.md @@ -35,9 +35,6 @@ See: JSON Web Token Proof Format -
DomainLinkageValidator
-

A validator for a Domain Linkage Configuration and Credentials.

-
Duration

A span of time.

@@ -76,6 +73,9 @@ and resolution of DID documents in Alias Outputs.

JwtCredentialValidator

A type for decoding and validating Credentials.

+
JwtDomainLinkageValidator
+

A validator for a Domain Linkage Configuration and Credentials.

+
JwtPresentationOptions
JwtPresentationValidationOptions
@@ -822,7 +822,7 @@ See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1). ### coreDocument.createCredentialJwt(storage, fragment, credential, options) ⇒ [Promise.<Jwt>](#Jwt) Produces a JWT where the payload is produced from the given `credential` -in accordance with [VC-JWT version 1.1.](https://w3c.github.io/vc-jwt/#version-1.1). +in accordance with [VC-JWT version 1.1](https://w3c.github.io/vc-jwt/#version-1.1). The `kid` in the protected header is the `id` of the method identified by `fragment` and the JWS signature will be produced by the corresponding private key backed by the `storage` in accordance with the passed `options`. @@ -1398,71 +1398,6 @@ Deserializes an instance from a JSON object. | --- | --- | | json | any | - - -## DomainLinkageValidator -A validator for a Domain Linkage Configuration and Credentials. - -**Kind**: global class - -* [DomainLinkageValidator](#DomainLinkageValidator) - * [new DomainLinkageValidator(signatureVerifier)](#new_DomainLinkageValidator_new) - * [.validateLinkage(issuer, configuration, domain, options)](#DomainLinkageValidator+validateLinkage) - * [.validateCredential(issuer, credentialJwt, domain, options)](#DomainLinkageValidator+validateCredential) - - - -### new DomainLinkageValidator(signatureVerifier) -Creates a new `DomainLinkageValidator`. If a `signatureVerifier` is provided it will be used when -verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` -algorithm will be used. - - -| Param | Type | -| --- | --- | -| signatureVerifier | IJwsVerifier \| undefined | - - - -### domainLinkageValidator.validateLinkage(issuer, configuration, domain, options) -Validates the linkage between a domain and a DID. -[`DomainLinkageConfiguration`] is validated according to [DID Configuration Resource Verification](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource-verification). - -Linkage is valid if no error is thrown. - -# Note: -- Only the [JSON Web Token Proof Format](https://identity.foundation/.well-known/resources/did-configuration/#json-web-token-proof-format) -- Only the Credential issued by `issuer` is verified. - -# Errors - - Semantic structure of `configuration` is invalid. - - `configuration` includes multiple credentials issued by `issuer`. - - Validation of the matched Domain Linkage Credential fails. - -**Kind**: instance method of [DomainLinkageValidator](#DomainLinkageValidator) - -| Param | Type | -| --- | --- | -| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | -| configuration | [DomainLinkageConfiguration](#DomainLinkageConfiguration) | -| domain | string | -| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | - - - -### domainLinkageValidator.validateCredential(issuer, credentialJwt, domain, options) -Validates a [Domain Linkage Credential](https://identity.foundation/.well-known/resources/did-configuration/#domain-linkage-credential). -Error will be thrown in case the validation fails. - -**Kind**: instance method of [DomainLinkageValidator](#DomainLinkageValidator) - -| Param | Type | -| --- | --- | -| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | -| credentialJwt | [Jwt](#Jwt) | -| domain | string | -| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | - ## Duration @@ -1563,7 +1498,7 @@ A DID conforming to the IOTA DID method specification. * [IotaDID](#IotaDID) * [new IotaDID(bytes, network)](#new_IotaDID_new) * _instance_ - * [.networkStr()](#IotaDID+networkStr) ⇒ string + * [.network()](#IotaDID+network) ⇒ string * [.tag()](#IotaDID+tag) ⇒ string * [.toCoreDid()](#IotaDID+toCoreDid) ⇒ [CoreDID](#CoreDID) * [.scheme()](#IotaDID+scheme) ⇒ string @@ -1599,9 +1534,9 @@ See also [placeholder](#IotaDID.placeholder). | bytes | Uint8Array | | network | string | - + -### did.networkStr() ⇒ string +### did.network() ⇒ string Returns the Tangle network name of the `IotaDID`. **Kind**: instance method of [IotaDID](#IotaDID) @@ -2246,7 +2181,7 @@ See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1). ### iotaDocument.createCredentialJwt(storage, fragment, credential, options) ⇒ [Promise.<Jwt>](#Jwt) Produces a JWS where the payload is produced from the given `credential` -in accordance with [VC-JWT version 1.1.](https://w3c.github.io/vc-jwt/#version-1.1). +in accordance with [VC-JWT version 1.1](https://w3c.github.io/vc-jwt/#version-1.1). The `kid` in the protected header is the `id` of the method identified by `fragment` and the JWS signature will be produced by the corresponding private key backed by the `storage` in accordance with the passed `options`. @@ -3574,6 +3509,71 @@ If the JWT decoding fails or the issuer field is not a valid DID. | --- | --- | | credential | [Jwt](#Jwt) | + + +## JwtDomainLinkageValidator +A validator for a Domain Linkage Configuration and Credentials. + +**Kind**: global class + +* [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) + * [new JwtDomainLinkageValidator(signatureVerifier)](#new_JwtDomainLinkageValidator_new) + * [.validateLinkage(issuer, configuration, domain, options)](#JwtDomainLinkageValidator+validateLinkage) + * [.validateCredential(issuer, credentialJwt, domain, options)](#JwtDomainLinkageValidator+validateCredential) + + + +### new JwtDomainLinkageValidator(signatureVerifier) +Creates a new `JwtDomainLinkageValidator`. If a `signatureVerifier` is provided it will be used when +verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` +algorithm will be used. + + +| Param | Type | +| --- | --- | +| signatureVerifier | IJwsVerifier \| undefined | + + + +### jwtDomainLinkageValidator.validateLinkage(issuer, configuration, domain, options) +Validates the linkage between a domain and a DID. +[`DomainLinkageConfiguration`] is validated according to [DID Configuration Resource Verification](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource-verification). + +Linkage is valid if no error is thrown. + +# Note: +- Only the [JSON Web Token Proof Format](https://identity.foundation/.well-known/resources/did-configuration/#json-web-token-proof-format) +- Only the Credential issued by `issuer` is verified. + +# Errors + - Semantic structure of `configuration` is invalid. + - `configuration` includes multiple credentials issued by `issuer`. + - Validation of the matched Domain Linkage Credential fails. + +**Kind**: instance method of [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) + +| Param | Type | +| --- | --- | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| configuration | [DomainLinkageConfiguration](#DomainLinkageConfiguration) | +| domain | string | +| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | + + + +### jwtDomainLinkageValidator.validateCredential(issuer, credentialJwt, domain, options) +Validates a [Domain Linkage Credential](https://identity.foundation/.well-known/resources/did-configuration/#domain-linkage-credential). +Error will be thrown in case the validation fails. + +**Kind**: instance method of [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) + +| Param | Type | +| --- | --- | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| credentialJwt | [Jwt](#Jwt) | +| domain | string | +| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | + ## JwtPresentationOptions diff --git a/bindings/wasm/examples/src/1_advanced/5_domain_linkage.ts b/bindings/wasm/examples/src/1_advanced/5_domain_linkage.ts index 347caa3319..c5ee22c8b8 100644 --- a/bindings/wasm/examples/src/1_advanced/5_domain_linkage.ts +++ b/bindings/wasm/examples/src/1_advanced/5_domain_linkage.ts @@ -8,7 +8,6 @@ import { Credential, DIDUrl, DomainLinkageConfiguration, - DomainLinkageValidator, Duration, IotaDID, IotaDocument, @@ -16,6 +15,7 @@ import { JwkMemStore, JwsSignatureOptions, JwtCredentialValidationOptions, + JwtDomainLinkageValidator, KeyIdMemStore, LinkedDomainService, Storage, @@ -125,7 +125,7 @@ export async function domainLinkage() { // Validate the linkage between the Domain Linkage Credential in the configuration and the provided issuer DID. // Validation succeeds when no error is thrown. - new DomainLinkageValidator().validateLinkage( + new JwtDomainLinkageValidator().validateLinkage( issuerDocument, fetchedConfigurationResource, domainFoo, @@ -159,7 +159,7 @@ export async function domainLinkage() { // Validate the linkage between the Domain Linkage Credential in the configuration and the provided issuer DID. // Validation succeeds when no error is thrown. - new DomainLinkageValidator().validateLinkage( + new JwtDomainLinkageValidator().validateLinkage( didDocument, fetchedConfigurationResource, domains[0], diff --git a/bindings/wasm/src/credential/domain_linkage_validator.rs b/bindings/wasm/src/credential/domain_linkage_validator.rs index c553f830de..85b49d4dc7 100644 --- a/bindings/wasm/src/credential/domain_linkage_validator.rs +++ b/bindings/wasm/src/credential/domain_linkage_validator.rs @@ -10,28 +10,28 @@ use crate::error::WasmResult; use crate::verification::IJwsVerifier; use crate::verification::WasmJwsVerifier; use identity_iota::core::Url; -use identity_iota::credential::DomainLinkageValidator; +use identity_iota::credential::JwtDomainLinkageValidator; use wasm_bindgen::prelude::wasm_bindgen; use super::WasmJwt; /// A validator for a Domain Linkage Configuration and Credentials. -#[wasm_bindgen(js_name = DomainLinkageValidator)] -pub struct WasmDomainLinkageValidator { - validator: DomainLinkageValidator, +#[wasm_bindgen(js_name = JwtDomainLinkageValidator)] +pub struct WasmJwtDomainLinkageValidator { + validator: JwtDomainLinkageValidator, } -#[wasm_bindgen(js_class = DomainLinkageValidator)] -impl WasmDomainLinkageValidator { - /// Creates a new `DomainLinkageValidator`. If a `signatureVerifier` is provided it will be used when +#[wasm_bindgen(js_class = JwtDomainLinkageValidator)] +impl WasmJwtDomainLinkageValidator { + /// Creates a new `JwtDomainLinkageValidator`. If a `signatureVerifier` is provided it will be used when /// verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` /// algorithm will be used. #[wasm_bindgen(constructor)] #[allow(non_snake_case)] - pub fn new(signatureVerifier: Option) -> WasmDomainLinkageValidator { + pub fn new(signatureVerifier: Option) -> WasmJwtDomainLinkageValidator { let signature_verifier = WasmJwsVerifier::new(signatureVerifier); - WasmDomainLinkageValidator { - validator: DomainLinkageValidator::with_signature_verifier(signature_verifier), + WasmJwtDomainLinkageValidator { + validator: JwtDomainLinkageValidator::with_signature_verifier(signature_verifier), } } diff --git a/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs b/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs index af0e9d5d54..6a43540837 100644 --- a/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs +++ b/bindings/wasm/src/credential/jwt_credential_validation/jwt_credential_validator.rs @@ -3,7 +3,7 @@ use identity_iota::core::Object; use identity_iota::core::Url; -use identity_iota::credential::CredentialValidator as JwtCredentialValidator; +use identity_iota::credential::JwtCredentialValidator; use identity_iota::credential::StatusCheck; use identity_iota::did::CoreDID; diff --git a/bindings/wasm/src/credential/jwt_credential_validation/options.rs b/bindings/wasm/src/credential/jwt_credential_validation/options.rs index 1b12183279..f615f38b67 100644 --- a/bindings/wasm/src/credential/jwt_credential_validation/options.rs +++ b/bindings/wasm/src/credential/jwt_credential_validation/options.rs @@ -5,7 +5,7 @@ use crate::error::Result; use crate::error::WasmResult; use wasm_bindgen::prelude::*; -use identity_iota::credential::CredentialValidationOptions as JwtCredentialValidationOptions; +use identity_iota::credential::JwtCredentialValidationOptions; /// Options to declare validation criteria when validating credentials. #[wasm_bindgen(js_name = JwtCredentialValidationOptions)] diff --git a/bindings/wasm/src/error.rs b/bindings/wasm/src/error.rs index 3bf961895d..2ba31759c6 100644 --- a/bindings/wasm/src/error.rs +++ b/bindings/wasm/src/error.rs @@ -100,7 +100,7 @@ impl_wasm_error_from!( identity_iota::did::Error, identity_iota::document::Error, identity_iota::iota::Error, - identity_iota::credential::ValidationError, + identity_iota::credential::JwtValidationError, identity_iota::credential::RevocationError, identity_iota::verification::Error, identity_iota::credential::DomainLinkageValidationError diff --git a/examples/0_basic/5_create_vc.rs b/examples/0_basic/5_create_vc.rs index 26ffe0ddb3..f8f041a9d1 100644 --- a/examples/0_basic/5_create_vc.rs +++ b/examples/0_basic/5_create_vc.rs @@ -12,10 +12,10 @@ use examples::create_did; use examples::MemStorage; use identity_iota::core::Object; -use identity_iota::credential::CredentialValidationOptions; -use identity_iota::credential::CredentialValidator; use identity_iota::credential::DecodedJwtCredential; use identity_iota::credential::Jwt; +use identity_iota::credential::JwtCredentialValidationOptions; +use identity_iota::credential::JwtCredentialValidator; use identity_iota::storage::JwkDocumentExt; use identity_iota::storage::JwkMemStore; use identity_iota::storage::JwsSignatureOptions; @@ -93,11 +93,11 @@ async fn main() -> anyhow::Result<()> { // Validate the credential's signature using the issuer's DID Document, the credential's semantic structure, // that the issuance date is not in the future and that the expiration date is not in the past: - let decoded_credential: DecodedJwtCredential = CredentialValidator::new() + let decoded_credential: DecodedJwtCredential = JwtCredentialValidator::new() .validate::<_, Object>( &credential_jwt, &issuer_document, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), FailFast::FirstError, ) .unwrap(); diff --git a/examples/0_basic/6_create_vp.rs b/examples/0_basic/6_create_vp.rs index e934726220..5bb205c621 100644 --- a/examples/0_basic/6_create_vp.rs +++ b/examples/0_basic/6_create_vp.rs @@ -41,9 +41,9 @@ use identity_iota::core::Timestamp; use identity_iota::core::Url; use identity_iota::credential::Credential; use identity_iota::credential::CredentialBuilder; -use identity_iota::credential::CredentialValidationOptions; -use identity_iota::credential::CredentialValidator; use identity_iota::credential::FailFast; +use identity_iota::credential::JwtCredentialValidationOptions; +use identity_iota::credential::JwtCredentialValidator; use identity_iota::credential::Subject; use identity_iota::credential::SubjectHolderRelationship; use identity_iota::did::DID; @@ -119,11 +119,11 @@ async fn main() -> anyhow::Result<()> { // Validate the credential's signature using the issuer's DID Document, the credential's semantic structure, // that the issuance date is not in the future and that the expiration date is not in the past: - CredentialValidator::new() + JwtCredentialValidator::new() .validate::<_, Object>( &credential_jwt, &issuer_document, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), FailFast::FirstError, ) .unwrap(); @@ -203,13 +203,13 @@ async fn main() -> anyhow::Result<()> { let jwt_credentials: &OneOrMany = &presentation.presentation.verifiable_credential; let issuers: Vec = jwt_credentials .iter() - .map(CredentialValidator::extract_issuer_from_jwt) + .map(JwtCredentialValidator::extract_issuer_from_jwt) .collect::, _>>()?; let issuers_documents: HashMap = resolver.resolve_multiple(&issuers).await?; // Validate the credentials in the presentation. - let credential_validator: CredentialValidator = CredentialValidator::new(); - let validation_options: CredentialValidationOptions = CredentialValidationOptions::default() + let credential_validator: JwtCredentialValidator = JwtCredentialValidator::new(); + let validation_options: JwtCredentialValidationOptions = JwtCredentialValidationOptions::default() .subject_holder_relationship(holder_did.to_url().into(), SubjectHolderRelationship::AlwaysSubject); for (index, jwt_vc) in jwt_credentials.iter().enumerate() { diff --git a/examples/0_basic/7_revoke_vc.rs b/examples/0_basic/7_revoke_vc.rs index ab76fd8d6b..ea6ac6c43b 100644 --- a/examples/0_basic/7_revoke_vc.rs +++ b/examples/0_basic/7_revoke_vc.rs @@ -22,16 +22,16 @@ use identity_iota::core::Url; use identity_iota::credential::CompoundCredentialValidationError; use identity_iota::credential::Credential; use identity_iota::credential::CredentialBuilder; -use identity_iota::credential::CredentialValidationOptions; -use identity_iota::credential::CredentialValidator; use identity_iota::credential::DecodedJwtCredential; use identity_iota::credential::FailFast; use identity_iota::credential::Jwt; +use identity_iota::credential::JwtCredentialValidationOptions; +use identity_iota::credential::JwtCredentialValidator; +use identity_iota::credential::JwtValidationError; use identity_iota::credential::RevocationBitmap; use identity_iota::credential::RevocationBitmapStatus; use identity_iota::credential::Status; use identity_iota::credential::Subject; -use identity_iota::credential::ValidationError; use identity_iota::did::DIDUrl; use identity_iota::did::DID; use identity_iota::document::Service; @@ -145,10 +145,10 @@ async fn main() -> anyhow::Result<()> { .await?; // Validate the credential's signature using the issuer's DID Document. - CredentialValidator::new().validate::<_, Object>( + JwtCredentialValidator::new().validate::<_, Object>( &credential_jwt, &issuer_document, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), FailFast::FirstError, )?; @@ -169,17 +169,17 @@ async fn main() -> anyhow::Result<()> { issuer_document = client.publish_did_output(&secret_manager_issuer, alias_output).await?; let validation_result: std::result::Result = - CredentialValidator::new().validate( + JwtCredentialValidator::new().validate( &credential_jwt, &issuer_document, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), FailFast::FirstError, ); // We expect validation to no longer succeed because the credential was revoked. assert!(matches!( validation_result.unwrap_err().validation_errors[0], - ValidationError::Revoked + JwtValidationError::Revoked )); // =========================================================================== @@ -205,13 +205,13 @@ async fn main() -> anyhow::Result<()> { // We expect the verifiable credential to be revoked. let mut resolver: Resolver = Resolver::new(); resolver.attach_iota_handler(client); - let resolved_issuer_did: IotaDID = CredentialValidator::extract_issuer_from_jwt(&credential_jwt)?; + let resolved_issuer_did: IotaDID = JwtCredentialValidator::extract_issuer_from_jwt(&credential_jwt)?; let resolved_issuer_doc: IotaDocument = resolver.resolve(&resolved_issuer_did).await?; - let validation_result = CredentialValidator::new().validate::<_, Object>( + let validation_result = JwtCredentialValidator::new().validate::<_, Object>( &credential_jwt, &resolved_issuer_doc, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), FailFast::FirstError, ); diff --git a/examples/1_advanced/6_domain_linkage.rs b/examples/1_advanced/6_domain_linkage.rs index 0277248bd1..8bb072c5f1 100644 --- a/examples/1_advanced/6_domain_linkage.rs +++ b/examples/1_advanced/6_domain_linkage.rs @@ -13,12 +13,12 @@ use identity_iota::core::Timestamp; use identity_iota::core::ToJson; use identity_iota::core::Url; use identity_iota::credential::Credential; -use identity_iota::credential::CredentialValidationOptions; use identity_iota::credential::DomainLinkageConfiguration; use identity_iota::credential::DomainLinkageCredentialBuilder; use identity_iota::credential::DomainLinkageValidationError; -use identity_iota::credential::DomainLinkageValidator; use identity_iota::credential::Jwt; +use identity_iota::credential::JwtCredentialValidationOptions; +use identity_iota::credential::JwtDomainLinkageValidator; use identity_iota::credential::LinkedDomainService; use identity_iota::did::CoreDID; use identity_iota::did::DIDUrl; @@ -152,11 +152,11 @@ async fn main() -> anyhow::Result<()> { let issuer_did_document: IotaDocument = resolver.resolve(&did).await?; // Validate the linkage between the Domain Linkage Credential in the configuration and the provided issuer DID. - let validation_result: Result<(), DomainLinkageValidationError> = DomainLinkageValidator::new().validate_linkage( + let validation_result: Result<(), DomainLinkageValidationError> = JwtDomainLinkageValidator::new().validate_linkage( &issuer_did_document, &configuration_resource, &domain_foo, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(validation_result.is_ok()); @@ -196,11 +196,11 @@ async fn main() -> anyhow::Result<()> { DomainLinkageConfiguration::from_json(&configuration_resource_json)?; // Validate the linkage. - let validation_result: Result<(), DomainLinkageValidationError> = DomainLinkageValidator::new().validate_linkage( + let validation_result: Result<(), DomainLinkageValidationError> = JwtDomainLinkageValidator::new().validate_linkage( &did_document, &configuration_resource, &domain_foo, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(validation_result.is_ok()); Ok(()) diff --git a/identity_credential/README.md b/identity_credential/README.md index ff7ecebf6f..01b49a5beb 100644 --- a/identity_credential/README.md +++ b/identity_credential/README.md @@ -4,7 +4,7 @@ This crate contains types representing verifiable credentials and verifiable pre Convenience methods for validating [Verifiable Credentials](https://wiki.iota.org/identity.rs/concepts/verifiable_credentials/overview) and [Verifiable Presentations](https://wiki.iota.org/identity.rs/concepts/verifiable_credentials/verifiable_presentations) are also provided: -- [`CredentialValidator`](crate::validator::CredentialValidator) +- [`JwtCredentialValidator`](crate::validator::JwtCredentialValidator) - [`JwtPresentationValidator`](crate::validator::JwtPresentationValidator) The [IOTA Identity Framework Wiki](https://wiki.iota.org/identity.rs/concepts/verifiable_credentials/overview) offers a comprehensive overview of verifiable credentials and presentations along with practical demonstrations and examples showcasing the capabilities of this crate in creating and validating them. diff --git a/identity_credential/src/domain_linkage/domain_linkage_configuration.rs b/identity_credential/src/domain_linkage/domain_linkage_configuration.rs index 5f394649a2..efc7dd99a2 100644 --- a/identity_credential/src/domain_linkage/domain_linkage_configuration.rs +++ b/identity_credential/src/domain_linkage/domain_linkage_configuration.rs @@ -3,8 +3,8 @@ use crate::credential::Jwt; use crate::error::Result; -use crate::validator::CredentialValidator; -use crate::validator::ValidationError; +use crate::validator::JwtCredentialValidator; +use crate::validator::JwtValidationError; use identity_core::common::Context; use identity_core::common::Url; use identity_core::convert::FmtJson; @@ -93,12 +93,12 @@ impl DomainLinkageConfiguration { } /// List of the issuers of the Domain Linkage Credentials. - pub fn issuers(&self) -> std::result::Result, ValidationError> { + pub fn issuers(&self) -> std::result::Result, JwtValidationError> { self .0 .linked_dids .iter() - .map(CredentialValidator::extract_issuer_from_jwt::) + .map(JwtCredentialValidator::extract_issuer_from_jwt::) .collect() } diff --git a/identity_credential/src/domain_linkage/domain_linkage_validator.rs b/identity_credential/src/domain_linkage/domain_linkage_validator.rs index 227fbb7508..d3cfe40f8e 100644 --- a/identity_credential/src/domain_linkage/domain_linkage_validator.rs +++ b/identity_credential/src/domain_linkage/domain_linkage_validator.rs @@ -6,9 +6,9 @@ use crate::credential::Jwt; use crate::domain_linkage::DomainLinkageConfiguration; use crate::domain_linkage::DomainLinkageValidationError; use crate::domain_linkage::DomainLinkageValidationErrorCause; -use crate::validator::CredentialValidationOptions; -use crate::validator::CredentialValidator; use crate::validator::FailFast; +use crate::validator::JwtCredentialValidationOptions; +use crate::validator::JwtCredentialValidator; use identity_core::common::OneOrMany; use identity_core::common::Url; use identity_did::CoreDID; @@ -23,33 +23,33 @@ use super::DomainLinkageValidationResult; /// A validator for a Domain Linkage Configuration and Credentials. #[derive(Debug, Clone)] -pub struct DomainLinkageValidator { - validator: CredentialValidator, +pub struct JwtDomainLinkageValidator { + validator: JwtCredentialValidator, } -impl DomainLinkageValidator { - /// Creates a new [`DomainLinkageValidator`] capable of verifying a Domain Linkage Credential issued as a JWS +impl JwtDomainLinkageValidator { + /// Creates a new [`JwtDomainLinkageValidator`] capable of verifying a Domain Linkage Credential issued as a JWS /// using the [`EdDSA`](::identity_verification::jose::jws::JwsAlgorithm::EdDSA) algorithm. /// - /// See [`DomainLinkageValidator::with_signature_verifier`](DomainLinkageValidator::with_signature_verifier) + /// See [`JwtDomainLinkageValidator::with_signature_verifier`](JwtDomainLinkageValidator::with_signature_verifier) /// which enables you to supply a custom signature verifier if other JWS algorithms are of interest. pub fn new() -> Self { Self { - validator: CredentialValidator::new(), + validator: JwtCredentialValidator::new(), } } } -impl DomainLinkageValidator +impl JwtDomainLinkageValidator where V: JwsVerifier, { - /// Create a new [`DomainLinkageValidator`] that delegates cryptographic signature verification to the given + /// Create a new [`JwtDomainLinkageValidator`] that delegates cryptographic signature verification to the given /// `signature_verifier`. If you are only interested in `EdDSA` signatures (with `Ed25519`) then the default - /// constructor can be used. See [`DomainLinkageValidator::new`](DomainLinkageValidator::new). + /// constructor can be used. See [`JwtDomainLinkageValidator::new`](JwtDomainLinkageValidator::new). pub fn with_signature_verifier(signature_verifier: V) -> Self { Self { - validator: CredentialValidator::with_signature_verifier(signature_verifier), + validator: JwtCredentialValidator::with_signature_verifier(signature_verifier), } } @@ -76,7 +76,7 @@ where issuer: &DOC, configuration: &DomainLinkageConfiguration, domain: &Url, - validation_options: &CredentialValidationOptions, + validation_options: &JwtCredentialValidationOptions, ) -> DomainLinkageValidationResult { let issuers: Vec = configuration.issuers().map_err(|err| DomainLinkageValidationError { cause: DomainLinkageValidationErrorCause::InvalidJwt, @@ -123,7 +123,7 @@ where issuer: &DOC, credential: &Jwt, domain: &Url, - validation_options: &CredentialValidationOptions, + validation_options: &JwtCredentialValidationOptions, ) -> DomainLinkageValidationResult { let decoded_credential: DecodedJwtCredential = self .validator @@ -220,7 +220,7 @@ where } } -impl Default for DomainLinkageValidator { +impl Default for JwtDomainLinkageValidator { fn default() -> Self { Self::new() } @@ -235,9 +235,9 @@ mod tests { use crate::domain_linkage::DomainLinkageCredentialBuilder; use crate::domain_linkage::DomainLinkageValidationErrorCause; use crate::domain_linkage::DomainLinkageValidationResult; - use crate::domain_linkage::DomainLinkageValidator; + use crate::domain_linkage::JwtDomainLinkageValidator; use crate::validator::test_utils::generate_jwk_document_with_keys; - use crate::validator::CredentialValidationOptions; + use crate::validator::JwtCredentialValidationOptions; use crypto::signatures::ed25519::SecretKey; use identity_core::common::Duration; @@ -262,11 +262,11 @@ mod tests { let credential: Credential = create_domain_linkage_credential(document.id()); let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(validation_result.is_ok()); @@ -280,11 +280,11 @@ mod tests { // Sign with `other_secret_key` to produce an invalid signature. let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &other_secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( validation_result.unwrap_err().cause, @@ -299,11 +299,11 @@ mod tests { credential.id = Some(Url::parse("http://random.credential.id").unwrap()); let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -319,11 +319,11 @@ mod tests { credential.types = OneOrMany::One(Credential::::base_type().to_owned()); let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -343,11 +343,11 @@ mod tests { ]); let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(validation_result.is_ok()); @@ -365,11 +365,11 @@ mod tests { } let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -389,11 +389,11 @@ mod tests { } let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -414,11 +414,11 @@ mod tests { } let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(validation_result.is_ok()); @@ -434,11 +434,11 @@ mod tests { } let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -458,11 +458,11 @@ mod tests { let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -481,11 +481,11 @@ mod tests { } let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_credential( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_credential( &document, &jwt, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( @@ -502,11 +502,11 @@ mod tests { let configuration: DomainLinkageConfiguration = DomainLinkageConfiguration::new(vec![jwt.clone(), jwt]); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_linkage( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_linkage( &document, &configuration, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(matches!( validation_result.unwrap_err().cause, @@ -521,11 +521,11 @@ mod tests { let jwt: Jwt = sign_credential_jwt(&credential, &document, &fragment, &secret_key); let configuration: DomainLinkageConfiguration = DomainLinkageConfiguration::new(vec![jwt]); - let validation_result: DomainLinkageValidationResult = DomainLinkageValidator::new().validate_linkage( + let validation_result: DomainLinkageValidationResult = JwtDomainLinkageValidator::new().validate_linkage( &document, &configuration, &url_foo(), - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), ); assert!(validation_result.is_ok()); diff --git a/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validation_options.rs b/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validation_options.rs index 1b019bfdc1..eab4763b00 100644 --- a/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validation_options.rs +++ b/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validation_options.rs @@ -13,7 +13,7 @@ use crate::validator::SubjectHolderRelationship; #[non_exhaustive] #[derive(Debug, Default, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct CredentialValidationOptions { +pub struct JwtCredentialValidationOptions { /// Declares that the credential is **not** considered valid if it expires before this /// [`Timestamp`]. /// Uses the current datetime during validation if not set. @@ -42,7 +42,7 @@ pub struct CredentialValidationOptions { pub verification_options: JwsVerificationOptions, } -impl CredentialValidationOptions { +impl JwtCredentialValidationOptions { /// Constructor that sets all options to their defaults. pub fn new() -> Self { Self::default() diff --git a/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validator.rs b/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validator.rs index e124e9e948..bad3d8565f 100644 --- a/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validator.rs +++ b/identity_credential/src/validator/vc_jwt_validation/credential_jwt_validator.rs @@ -21,10 +21,10 @@ use identity_verification::jws::JwsValidationItem; use identity_verification::jws::JwsVerifier; use super::CompoundCredentialValidationError; -use super::CredentialValidationOptions; use super::DecodedJwtCredential; +use super::JwtCredentialValidationOptions; +use super::JwtValidationError; use super::SignerContext; -use super::ValidationError; use crate::credential::Credential; use crate::credential::CredentialJwtClaims; use crate::credential::Jwt; @@ -34,17 +34,17 @@ use crate::validator::SubjectHolderRelationship; /// A type for decoding and validating [`Credential`]s. #[derive(Debug, Clone)] #[non_exhaustive] -pub struct CredentialValidator(V); +pub struct JwtCredentialValidator(V); -type ValidationUnitResult = std::result::Result; +type ValidationUnitResult = std::result::Result; -impl CredentialValidator +impl JwtCredentialValidator where V: JwsVerifier, { - /// Create a new [`CredentialValidator`] that delegates cryptographic signature verification to the given + /// Create a new [`JwtCredentialValidator`] that delegates cryptographic signature verification to the given /// `signature_verifier`. If you are only interested in `EdDSA` signatures (with `Ed25519`) then the default - /// constructor can be used. See [`CredentialValidator::new`](CredentialValidator::new). + /// constructor can be used. See [`JwtCredentialValidator::new`](JwtCredentialValidator::new). pub fn with_signature_verifier(signature_verifier: V) -> Self { Self(signature_verifier) } @@ -76,7 +76,7 @@ where &self, credential_jwt: &Jwt, issuer: &DOC, - options: &CredentialValidationOptions, + options: &JwtCredentialValidationOptions, fail_fast: FailFast, ) -> Result, CompoundCredentialValidationError> where @@ -113,7 +113,7 @@ where credential: &Jwt, trusted_issuers: &[DOC], options: &JwsVerificationOptions, - ) -> Result, ValidationError> + ) -> Result, JwtValidationError> where T: ToOwned + serde::Serialize + serde::de::DeserializeOwned, DOC: AsRef, @@ -128,7 +128,7 @@ where signature_verifier: &S, credential: &Jwt, issuers: &[DOC], - options: &CredentialValidationOptions, + options: &JwtCredentialValidationOptions, fail_fast: FailFast, ) -> Result, CompoundCredentialValidationError> where @@ -149,24 +149,24 @@ where // Run all single concern Credential validations in turn and fail immediately if `fail_fast` is true. let expiry_date_validation = std::iter::once_with(|| { - CredentialValidator::check_expires_on_or_after( + JwtCredentialValidator::check_expires_on_or_after( &credential_token.credential, options.earliest_expiry_date.unwrap_or_default(), ) }); let issuance_date_validation = std::iter::once_with(|| { - CredentialValidator::check_issued_on_or_before(credential, options.latest_issuance_date.unwrap_or_default()) + JwtCredentialValidator::check_issued_on_or_before(credential, options.latest_issuance_date.unwrap_or_default()) }); - let structure_validation = std::iter::once_with(|| CredentialValidator::check_structure(credential)); + let structure_validation = std::iter::once_with(|| JwtCredentialValidator::check_structure(credential)); let subject_holder_validation = std::iter::once_with(|| { options .subject_holder_relationship .as_ref() .map(|(holder, relationship)| { - CredentialValidator::check_subject_holder_relationship(credential, holder, *relationship) + JwtCredentialValidator::check_subject_holder_relationship(credential, holder, *relationship) }) .unwrap_or(Ok(())) }); @@ -179,12 +179,12 @@ where #[cfg(feature = "revocation-bitmap")] let validation_units_iter = { let revocation_validation = - std::iter::once_with(|| CredentialValidator::check_status(credential, issuers, options.status)); + std::iter::once_with(|| JwtCredentialValidator::check_status(credential, issuers, options.status)); validation_units_iter.chain(revocation_validation) }; let validation_units_error_iter = validation_units_iter.filter_map(|result| result.err()); - let validation_errors: Vec = match fail_fast { + let validation_errors: Vec = match fail_fast { FailFast::FirstError => validation_units_error_iter.take(1).collect(), FailFast::AllErrors => validation_units_error_iter.collect(), }; @@ -202,7 +202,7 @@ where credential: &Jwt, trusted_issuers: &[DOC], options: &JwsVerificationOptions, - ) -> Result, ValidationError> + ) -> Result, JwtValidationError> where T: ToOwned + serde::Serialize + serde::de::DeserializeOwned, DOC: AsRef, @@ -218,7 +218,7 @@ where let nonce: Option<&str> = options.nonce.as_deref(); // Validate the nonce if decoded.nonce() != nonce { - return Err(ValidationError::JwsDecodingError( + return Err(JwtValidationError::JwsDecodingError( identity_verification::jose::error::Error::InvalidParam("invalid nonce value"), )); } @@ -226,18 +226,16 @@ where // Parse the `kid` to a DID Url which should be the identifier of a verification method in a trusted issuer's DID // document. let method_id: DIDUrl = { - let kid: &str = - decoded - .protected_header() - .and_then(|header| header.kid()) - .ok_or(ValidationError::MethodDataLookupError { - source: None, - message: "could not extract kid from protected header", - signer_ctx: SignerContext::Issuer, - })?; + let kid: &str = decoded.protected_header().and_then(|header| header.kid()).ok_or( + JwtValidationError::MethodDataLookupError { + source: None, + message: "could not extract kid from protected header", + signer_ctx: SignerContext::Issuer, + }, + )?; // Convert kid to DIDUrl - DIDUrl::parse(kid).map_err(|err| ValidationError::MethodDataLookupError { + DIDUrl::parse(kid).map_err(|err| JwtValidationError::MethodDataLookupError { source: Some(err.into()), message: "could not parse kid as a DID Url", signer_ctx: SignerContext::Issuer, @@ -249,13 +247,13 @@ where .iter() .map(AsRef::as_ref) .find(|issuer_doc| ::id(issuer_doc) == method_id.did()) - .ok_or(ValidationError::DocumentMismatch(SignerContext::Issuer))?; + .ok_or(JwtValidationError::DocumentMismatch(SignerContext::Issuer))?; // Obtain the public key from the issuer's DID document let public_key: &Jwk = issuer .resolve_method(&method_id, options.method_scope) .and_then(|method| method.data().public_key_jwk()) - .ok_or_else(|| ValidationError::MethodDataLookupError { + .ok_or_else(|| JwtValidationError::MethodDataLookupError { source: None, message: "could not extract JWK from a method identified by kid", signer_ctx: SignerContext::Issuer, @@ -265,9 +263,9 @@ where // Check that the DID component of the parsed `kid` does indeed correspond to the issuer in the credential before // returning. - let issuer_id: CoreDID = CredentialValidator::extract_issuer(&credential_token.credential)?; + let issuer_id: CoreDID = JwtCredentialValidator::extract_issuer(&credential_token.credential)?; if &issuer_id != method_id.did() { - return Err(ValidationError::IdentifierMismatch { + return Err(JwtValidationError::IdentifierMismatch { signer_ctx: SignerContext::Issuer, }); }; @@ -275,12 +273,12 @@ where } /// Decode the credential into a [`JwsValidationItem`]. - fn decode(credential_jws: &str) -> Result, ValidationError> { + fn decode(credential_jws: &str) -> Result, JwtValidationError> { let decoder: Decoder = Decoder::new(); decoder .decode_compact_serialization(credential_jws.as_bytes(), None) - .map_err(ValidationError::JwsDecodingError) + .map_err(JwtValidationError::JwsDecodingError) } /// Verify the signature using the given `public_key` and `signature_verifier`. @@ -288,7 +286,7 @@ where decoded: JwsValidationItem<'_>, public_key: &Jwk, signature_verifier: &S, - ) -> Result, ValidationError> + ) -> Result, JwtValidationError> where T: ToOwned + serde::Serialize + serde::de::DeserializeOwned, { @@ -296,7 +294,7 @@ where let DecodedJws { protected, claims, .. } = decoded .verify(signature_verifier, public_key) - .map_err(|err| ValidationError::Signature { + .map_err(|err| JwtValidationError::Signature { source: err, signer_ctx: SignerContext::Issuer, })?; @@ -304,13 +302,13 @@ where // Deserialize the raw claims let credential_claims: CredentialJwtClaims<'_, T> = CredentialJwtClaims::from_json_slice(&claims).map_err(|err| { - ValidationError::CredentialStructure(crate::Error::JwtClaimsSetDeserializationError(err.into())) + JwtValidationError::CredentialStructure(crate::Error::JwtClaimsSetDeserializationError(err.into())) })?; // Construct the credential token containing the credential and the protected header. let credential: Credential = credential_claims .try_into_credential() - .map_err(ValidationError::CredentialStructure)?; + .map_err(JwtValidationError::CredentialStructure)?; Ok(DecodedJwtCredential { credential, @@ -319,11 +317,11 @@ where } } -impl CredentialValidator { - /// Creates a new [`CredentialValidator`] capable of verifying a [`Credential`] issued as a JWS +impl JwtCredentialValidator { + /// Creates a new [`JwtCredentialValidator`] capable of verifying a [`Credential`] issued as a JWS /// using the [`EdDSA`](::identity_verification::jose::jws::JwsAlgorithm::EdDSA) algorithm. /// - /// See [`CredentialValidator::with_signature_verifier`](CredentialValidator::with_signature_verifier()) + /// See [`JwtCredentialValidator::with_signature_verifier`](JwtCredentialValidator::with_signature_verifier()) /// which enables you to supply a custom signature verifier if other JWS algorithms are of interest. pub fn new() -> Self { Self(EdDSAJwsVerifier::default()) @@ -336,7 +334,7 @@ impl CredentialValidator { pub fn check_structure(credential: &Credential) -> ValidationUnitResult { credential .check_structure() - .map_err(ValidationError::CredentialStructure) + .map_err(JwtValidationError::CredentialStructure) } /// Validate that the [`Credential`] expires on or after the specified [`Timestamp`]. @@ -344,14 +342,14 @@ impl CredentialValidator { let expiration_date: Option = credential.expiration_date; (expiration_date.is_none() || expiration_date >= Some(timestamp)) .then_some(()) - .ok_or(ValidationError::ExpirationDate) + .ok_or(JwtValidationError::ExpirationDate) } /// Validate that the [`Credential`] is issued on or before the specified [`Timestamp`]. pub fn check_issued_on_or_before(credential: &Credential, timestamp: Timestamp) -> ValidationUnitResult { (credential.issuance_date <= timestamp) .then_some(()) - .ok_or(ValidationError::IssuanceDate) + .ok_or(JwtValidationError::IssuanceDate) } /// Validate that the relationship between the `holder` and the credential subjects is in accordance with @@ -383,7 +381,7 @@ impl CredentialValidator { SubjectHolderRelationship::Any => true, }) .map(|_| ()) - .ok_or(ValidationError::SubjectHolderRelationship) + .ok_or(JwtValidationError::SubjectHolderRelationship) } /// Checks whether the credential status has been revoked. @@ -407,21 +405,21 @@ impl CredentialValidator { if status_check == crate::validator::StatusCheck::SkipUnsupported { return Ok(()); } - return Err(ValidationError::InvalidStatus(crate::Error::InvalidStatus(format!( + return Err(JwtValidationError::InvalidStatus(crate::Error::InvalidStatus(format!( "unsupported type '{}'", status.type_ )))); } let status: crate::credential::RevocationBitmapStatus = crate::credential::RevocationBitmapStatus::try_from(status.clone()) - .map_err(ValidationError::InvalidStatus)?; + .map_err(JwtValidationError::InvalidStatus)?; // Check the credential index against the issuer's DID Document. let issuer_did: CoreDID = Self::extract_issuer(credential)?; trusted_issuers .iter() .find(|issuer| ::id(issuer.as_ref()) == &issuer_did) - .ok_or(ValidationError::DocumentMismatch(SignerContext::Issuer)) + .ok_or(JwtValidationError::DocumentMismatch(SignerContext::Issuer)) .and_then(|issuer| Self::check_revocation_bitmap_status(issuer, status)) } } @@ -436,16 +434,16 @@ impl CredentialValidator { ) -> ValidationUnitResult { use crate::revocation::RevocationDocumentExt; - let issuer_service_url: identity_did::DIDUrl = status.id().map_err(ValidationError::InvalidStatus)?; + let issuer_service_url: identity_did::DIDUrl = status.id().map_err(JwtValidationError::InvalidStatus)?; // Check whether index is revoked. let revocation_bitmap: crate::revocation::RevocationBitmap = issuer .as_ref() .resolve_revocation_bitmap(issuer_service_url.into()) - .map_err(|_| ValidationError::ServiceLookupError)?; - let index: u32 = status.index().map_err(ValidationError::InvalidStatus)?; + .map_err(|_| JwtValidationError::ServiceLookupError)?; + let index: u32 = status.index().map_err(JwtValidationError::InvalidStatus)?; if revocation_bitmap.is_revoked(index) { - Err(ValidationError::Revoked) + Err(JwtValidationError::Revoked) } else { Ok(()) } @@ -456,12 +454,12 @@ impl CredentialValidator { /// # Errors /// /// Fails if the issuer field is not a valid DID. - pub fn extract_issuer(credential: &Credential) -> std::result::Result + pub fn extract_issuer(credential: &Credential) -> std::result::Result where D: DID, ::Err: std::error::Error + Send + Sync + 'static, { - D::from_str(credential.issuer.url().as_str()).map_err(|err| ValidationError::SignerUrl { + D::from_str(credential.issuer.url().as_str()).map_err(|err| JwtValidationError::SignerUrl { signer_ctx: SignerContext::Issuer, source: err.into(), }) @@ -472,28 +470,28 @@ impl CredentialValidator { /// # Errors /// /// If the JWT decoding fails or the issuer field is not a valid DID. - pub fn extract_issuer_from_jwt(credential: &Jwt) -> std::result::Result + pub fn extract_issuer_from_jwt(credential: &Jwt) -> std::result::Result where D: DID, ::Err: std::error::Error + Send + Sync + 'static, { let validation_item = Decoder::new() .decode_compact_serialization(credential.as_str().as_bytes(), None) - .map_err(ValidationError::JwsDecodingError)?; + .map_err(JwtValidationError::JwsDecodingError)?; let claims: CredentialJwtClaims<'_, Object> = CredentialJwtClaims::from_json_slice(&validation_item.claims()) .map_err(|err| { - ValidationError::CredentialStructure(crate::Error::JwtClaimsSetDeserializationError(err.into())) + JwtValidationError::CredentialStructure(crate::Error::JwtClaimsSetDeserializationError(err.into())) })?; - D::from_str(claims.iss.url().as_str()).map_err(|err| ValidationError::SignerUrl { + D::from_str(claims.iss.url().as_str()).map_err(|err| JwtValidationError::SignerUrl { signer_ctx: SignerContext::Issuer, source: err.into(), }) } } -impl Default for CredentialValidator { +impl Default for JwtCredentialValidator { fn default() -> Self { Self::new() } @@ -504,7 +502,7 @@ mod tests { use crate::credential::Subject; use identity_core::common::Duration; - // All tests here are essentially adaptations of the old CredentialValidator tests. + // All tests here are essentially adaptations of the old JwtCredentialValidator tests. use super::*; use identity_core::common::Object; use identity_core::common::Timestamp; @@ -538,7 +536,7 @@ mod tests { #[test] fn issued_on_or_before() { - assert!(CredentialValidator::check_issued_on_or_before( + assert!(JwtCredentialValidator::check_issued_on_or_before( &SIMPLE_CREDENTIAL, SIMPLE_CREDENTIAL .issuance_date @@ -548,7 +546,7 @@ mod tests { .is_err()); // and now with a later timestamp - assert!(CredentialValidator::check_issued_on_or_before( + assert!(JwtCredentialValidator::check_issued_on_or_before( &SIMPLE_CREDENTIAL, SIMPLE_CREDENTIAL .issuance_date @@ -568,21 +566,21 @@ mod tests { credential.non_transferable = Some(true); // checking with holder = subject passes for all defined subject holder relationships: - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential, &actual_holder_url, SubjectHolderRelationship::AlwaysSubject ) .is_ok()); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential, &actual_holder_url, SubjectHolderRelationship::SubjectOnNonTransferable ) .is_ok()); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential, &actual_holder_url, SubjectHolderRelationship::Any @@ -593,21 +591,21 @@ mod tests { let issuer_url = Url::parse("did:core:0x1234567890").unwrap(); assert!(actual_holder_url != issuer_url); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential, &issuer_url, SubjectHolderRelationship::AlwaysSubject ) .is_err()); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential, &issuer_url, SubjectHolderRelationship::SubjectOnNonTransferable ) .is_err()); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential, &issuer_url, SubjectHolderRelationship::Any @@ -618,7 +616,7 @@ mod tests { credential_transferable.non_transferable = Some(false); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential_transferable, &issuer_url, SubjectHolderRelationship::SubjectOnNonTransferable @@ -627,7 +625,7 @@ mod tests { credential_transferable.non_transferable = None; - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential_transferable, &issuer_url, SubjectHolderRelationship::SubjectOnNonTransferable @@ -640,21 +638,21 @@ mod tests { .credential_subject .push(Subject::with_id(actual_holder_url)); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential_duplicated_holder, &issuer_url, SubjectHolderRelationship::AlwaysSubject ) .is_err()); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential_duplicated_holder, &issuer_url, SubjectHolderRelationship::SubjectOnNonTransferable ) .is_err()); - assert!(CredentialValidator::check_subject_holder_relationship( + assert!(JwtCredentialValidator::check_subject_holder_relationship( &credential_duplicated_holder, &issuer_url, SubjectHolderRelationship::Any @@ -669,10 +667,10 @@ mod tests { .unwrap() .checked_add(Duration::minutes(1)) .unwrap(); - assert!(CredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, later_than_expiration_date).is_err()); + assert!(JwtCredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, later_than_expiration_date).is_err()); // and now with an earlier date let earlier_date = Timestamp::parse("2019-12-27T11:35:30Z").unwrap(); - assert!(CredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, earlier_date).is_ok()); + assert!(JwtCredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, earlier_date).is_ok()); } // test with a few timestamps that should be RFC3339 compatible @@ -681,8 +679,8 @@ mod tests { fn property_based_expires_after_with_expiration_date(seconds in 0..1_000_000_000_u32) { let after_expiration_date = SIMPLE_CREDENTIAL.expiration_date.unwrap().checked_add(Duration::seconds(seconds)).unwrap(); let before_expiration_date = SIMPLE_CREDENTIAL.expiration_date.unwrap().checked_sub(Duration::seconds(seconds)).unwrap(); - assert!(CredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, after_expiration_date).is_err()); - assert!(CredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, before_expiration_date).is_ok()); + assert!(JwtCredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, after_expiration_date).is_err()); + assert!(JwtCredentialValidator::check_expires_on_or_after(&SIMPLE_CREDENTIAL, before_expiration_date).is_ok()); } } @@ -692,7 +690,7 @@ mod tests { let mut credential = SIMPLE_CREDENTIAL.clone(); credential.expiration_date = None; // expires after whatever the timestamp may be because the expires_after field is None. - assert!(CredentialValidator::check_expires_on_or_after(&credential, Timestamp::from_unix(seconds).unwrap()).is_ok()); + assert!(JwtCredentialValidator::check_expires_on_or_after(&credential, Timestamp::from_unix(seconds).unwrap()).is_ok()); } } @@ -702,8 +700,8 @@ mod tests { let earlier_than_issuance_date = SIMPLE_CREDENTIAL.issuance_date.checked_sub(Duration::seconds(seconds)).unwrap(); let later_than_issuance_date = SIMPLE_CREDENTIAL.issuance_date.checked_add(Duration::seconds(seconds)).unwrap(); - assert!(CredentialValidator::check_issued_on_or_before(&SIMPLE_CREDENTIAL, earlier_than_issuance_date).is_err()); - assert!(CredentialValidator::check_issued_on_or_before(&SIMPLE_CREDENTIAL, later_than_issuance_date).is_ok()); + assert!(JwtCredentialValidator::check_issued_on_or_before(&SIMPLE_CREDENTIAL, earlier_than_issuance_date).is_err()); + assert!(JwtCredentialValidator::check_issued_on_or_before(&SIMPLE_CREDENTIAL, later_than_issuance_date).is_ok()); } } } diff --git a/identity_credential/src/validator/vc_jwt_validation/error.rs b/identity_credential/src/validator/vc_jwt_validation/error.rs index 153220e7b3..09dd086e8f 100644 --- a/identity_credential/src/validator/vc_jwt_validation/error.rs +++ b/identity_credential/src/validator/vc_jwt_validation/error.rs @@ -9,7 +9,7 @@ use itertools; #[derive(Debug, thiserror::Error, strum::IntoStaticStr)] #[non_exhaustive] /// An error associated with validating credentials and presentations. -pub enum ValidationError { +pub enum JwtValidationError { /// Indicates that the JWS representation of an issued credential or presentation could not be decoded. #[error("could not decode jws")] JwsDecodingError(#[source] identity_verification::jose::error::Error), @@ -127,7 +127,7 @@ impl Display for SignerContext { #[derive(Debug)] pub struct CompoundCredentialValidationError { /// List of credential validation errors. - pub validation_errors: Vec, + pub validation_errors: Vec, } impl Display for CompoundCredentialValidationError { diff --git a/identity_credential/src/validator/vp_jwt_validation/error.rs b/identity_credential/src/validator/vp_jwt_validation/error.rs index 37633356c8..4ab609fc9d 100644 --- a/identity_credential/src/validator/vp_jwt_validation/error.rs +++ b/identity_credential/src/validator/vp_jwt_validation/error.rs @@ -4,17 +4,17 @@ use std::error::Error; use std::fmt::Display; -use crate::validator::vc_jwt_validation::ValidationError; +use crate::validator::vc_jwt_validation::JwtValidationError; /// Errors caused by a failure to validate a [`Presentation`](crate::presentation::Presentation). #[derive(Debug)] pub struct CompoundJwtPresentationValidationError { /// Errors that occurred during validation of the presentation. - pub presentation_validation_errors: Vec, + pub presentation_validation_errors: Vec, } impl CompoundJwtPresentationValidationError { - pub(crate) fn one_presentation_error(error: ValidationError) -> Self { + pub(crate) fn one_presentation_error(error: JwtValidationError) -> Self { Self { presentation_validation_errors: vec![error], } diff --git a/identity_credential/src/validator/vp_jwt_validation/jwt_presentation_validator.rs b/identity_credential/src/validator/vp_jwt_validation/jwt_presentation_validator.rs index b710b50bcc..3fdd5629ac 100644 --- a/identity_credential/src/validator/vp_jwt_validation/jwt_presentation_validator.rs +++ b/identity_credential/src/validator/vp_jwt_validation/jwt_presentation_validator.rs @@ -17,8 +17,8 @@ use std::str::FromStr; use crate::credential::Jwt; use crate::presentation::Presentation; use crate::presentation::PresentationJwtClaims; +use crate::validator::vc_jwt_validation::JwtValidationError; use crate::validator::vc_jwt_validation::SignerContext; -use crate::validator::vc_jwt_validation::ValidationError; use super::CompoundJwtPresentationValidationError; use super::DecodedJwtPresentation; @@ -63,7 +63,7 @@ where /// /// * This method does NOT validate the constituent credentials and therefore also not the relationship between the /// credentials' subjects and the presentation holder. This can be done with - /// [`CredentialValidationOptions`](crate::validator::CredentialValidationOptions). + /// [`JwtCredentialValidationOptions`](crate::validator::JwtCredentialValidationOptions). /// * The lack of an error returned from this method is in of itself not enough to conclude that the presentation can /// be trusted. This section contains more information on additional checks that should be carried out before and /// after calling this method. @@ -96,19 +96,19 @@ where &options.presentation_verifier_options, ) .map_err(|err| { - CompoundJwtPresentationValidationError::one_presentation_error(ValidationError::PresentationJwsError(err)) + CompoundJwtPresentationValidationError::one_presentation_error(JwtValidationError::PresentationJwsError(err)) })?; let claims: PresentationJwtClaims<'_, CRED, T> = PresentationJwtClaims::from_json_slice(&decoded_jws.claims) .map_err(|err| { - CompoundJwtPresentationValidationError::one_presentation_error(ValidationError::PresentationStructure( + CompoundJwtPresentationValidationError::one_presentation_error(JwtValidationError::PresentationStructure( crate::Error::JwtClaimsSetDeserializationError(err.into()), )) })?; // Verify that holder document matches holder in presentation. let holder_did: CoreDID = CoreDID::from_str(claims.iss.as_str()).map_err(|err| { - CompoundJwtPresentationValidationError::one_presentation_error(ValidationError::SignerUrl { + CompoundJwtPresentationValidationError::one_presentation_error(JwtValidationError::SignerUrl { signer_ctx: SignerContext::Holder, source: err.into(), }) @@ -116,7 +116,7 @@ where if &holder_did != ::id(holder.as_ref()) { return Err(CompoundJwtPresentationValidationError::one_presentation_error( - ValidationError::DocumentMismatch(SignerContext::Holder), + JwtValidationError::DocumentMismatch(SignerContext::Holder), )); } @@ -125,7 +125,7 @@ where .exp .map(|exp| { Timestamp::from_unix(exp).map_err(|err| { - CompoundJwtPresentationValidationError::one_presentation_error(ValidationError::PresentationStructure( + CompoundJwtPresentationValidationError::one_presentation_error(JwtValidationError::PresentationStructure( crate::Error::JwtClaimsSetDeserializationError(err.into()), )) }) @@ -135,7 +135,7 @@ where (expiration_date.is_none() || expiration_date >= Some(options.earliest_expiry_date.unwrap_or_default())) .then_some(()) .ok_or(CompoundJwtPresentationValidationError::one_presentation_error( - ValidationError::ExpirationDate, + JwtValidationError::ExpirationDate, ))?; // Check issuance date. @@ -143,7 +143,7 @@ where Some(iss) => { if iss.iat.is_some() || iss.nbf.is_some() { Some(iss.to_issuance_date().map_err(|err| { - CompoundJwtPresentationValidationError::one_presentation_error(ValidationError::PresentationStructure( + CompoundJwtPresentationValidationError::one_presentation_error(JwtValidationError::PresentationStructure( crate::Error::JwtClaimsSetDeserializationError(err.into()), )) })?) @@ -157,13 +157,13 @@ where (issuance_date.is_none() || issuance_date <= Some(options.latest_issuance_date.unwrap_or_default())) .then_some(()) .ok_or(CompoundJwtPresentationValidationError::one_presentation_error( - ValidationError::IssuanceDate, + JwtValidationError::IssuanceDate, ))?; let aud: Option = claims.aud.clone(); let presentation: Presentation = claims.try_into_presentation().map_err(|err| { - CompoundJwtPresentationValidationError::one_presentation_error(ValidationError::PresentationStructure(err)) + CompoundJwtPresentationValidationError::one_presentation_error(JwtValidationError::PresentationStructure(err)) })?; let decoded_jwt_presentation: DecodedJwtPresentation = DecodedJwtPresentation { @@ -184,20 +184,20 @@ impl JwtPresentationValidator { /// # Errors: /// * If deserialization/decoding of the presentation fails. /// * If the holder can't be parsed as DIDs. - pub fn extract_holder(presentation: &Jwt) -> std::result::Result + pub fn extract_holder(presentation: &Jwt) -> std::result::Result where ::Err: std::error::Error + Send + Sync + 'static, { let validation_item = Decoder::new() .decode_compact_serialization(presentation.as_str().as_bytes(), None) - .map_err(ValidationError::JwsDecodingError)?; + .map_err(JwtValidationError::JwsDecodingError)?; let claims: PresentationJwtClaims<'_, identity_core::common::Value, Object> = PresentationJwtClaims::from_json_slice(&validation_item.claims()).map_err(|err| { - ValidationError::PresentationStructure(crate::Error::JwtClaimsSetDeserializationError(err.into())) + JwtValidationError::PresentationStructure(crate::Error::JwtClaimsSetDeserializationError(err.into())) })?; - let holder: H = H::from_str(claims.iss.as_str()).map_err(|err| ValidationError::SignerUrl { + let holder: H = H::from_str(claims.iss.as_str()).map_err(|err| JwtValidationError::SignerUrl { signer_ctx: SignerContext::Holder, source: err.into(), })?; @@ -205,9 +205,9 @@ impl JwtPresentationValidator { } /// Validates the semantic structure of the `Presentation`. - pub fn check_structure(presentation: &Presentation) -> Result<(), ValidationError> { + pub fn check_structure(presentation: &Presentation) -> Result<(), JwtValidationError> { presentation .check_structure() - .map_err(ValidationError::PresentationStructure) + .map_err(JwtValidationError::PresentationStructure) } } diff --git a/identity_storage/src/storage/tests/api.rs b/identity_storage/src/storage/tests/api.rs index 01e5eac3db..6215e51b46 100644 --- a/identity_storage/src/storage/tests/api.rs +++ b/identity_storage/src/storage/tests/api.rs @@ -7,7 +7,7 @@ use identity_core::convert::FromJson; use identity_credential::credential::Credential; use identity_credential::credential::Jws; -use identity_credential::validator::CredentialValidationOptions; +use identity_credential::validator::JwtCredentialValidationOptions; use identity_did::DIDUrl; use identity_document::document::CoreDocument; use identity_document::verifiable::JwsVerificationOptions; @@ -288,12 +288,12 @@ async fn signing_credential() { .await .unwrap(); // Verify the credential - let validator = identity_credential::validator::CredentialValidator::new(); + let validator = identity_credential::validator::JwtCredentialValidator::new(); assert!(validator .validate::<_, Object>( &jws, &document, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), identity_credential::validator::FailFast::FirstError ) .is_ok()); diff --git a/identity_storage/src/storage/tests/credential_jws.rs b/identity_storage/src/storage/tests/credential_jws.rs index 2555a2f53f..ea932d0152 100644 --- a/identity_storage/src/storage/tests/credential_jws.rs +++ b/identity_storage/src/storage/tests/credential_jws.rs @@ -5,7 +5,7 @@ use identity_core::common::Object; use identity_core::convert::FromJson; use identity_credential::credential::Credential; -use identity_credential::validator::CredentialValidationOptions; +use identity_credential::validator::JwtCredentialValidationOptions; use identity_document::document::CoreDocument; use identity_document::verifiable::JwsVerificationOptions; use identity_verification::jose::jws::JwsAlgorithm; @@ -103,12 +103,12 @@ async fn signing_credential_with_nonce_and_scope() { .await .unwrap(); - let validator = identity_credential::validator::CredentialValidator::new(); + let validator = identity_credential::validator::JwtCredentialValidator::new(); assert!(validator .validate::<_, Object>( &jws, &document, - &CredentialValidationOptions::default().verification_options( + &JwtCredentialValidationOptions::default().verification_options( JwsVerificationOptions::default() .nonce(nonce.to_owned()) .method_scope(MethodScope::assertion_method()) @@ -122,7 +122,7 @@ async fn signing_credential_with_nonce_and_scope() { .validate::<_, Object>( &jws, &document, - &CredentialValidationOptions::default().verification_options( + &JwtCredentialValidationOptions::default().verification_options( JwsVerificationOptions::default() .nonce("other-nonce".to_owned()) .method_scope(MethodScope::assertion_method()) @@ -136,7 +136,7 @@ async fn signing_credential_with_nonce_and_scope() { .validate::<_, Object>( &jws, &document, - &CredentialValidationOptions::default().verification_options( + &JwtCredentialValidationOptions::default().verification_options( JwsVerificationOptions::default() .nonce(nonce.to_owned()) .method_scope(MethodScope::key_agreement()) @@ -160,12 +160,12 @@ async fn signing_credential_with_b64() { .await .unwrap(); - let validator = identity_credential::validator::CredentialValidator::new(); + let validator = identity_credential::validator::JwtCredentialValidator::new(); let decoded = validator .validate::<_, Object>( &jws, &document, - &CredentialValidationOptions::default(), + &JwtCredentialValidationOptions::default(), identity_credential::validator::FailFast::FirstError, ) .unwrap(); diff --git a/identity_storage/src/storage/tests/credential_validation.rs b/identity_storage/src/storage/tests/credential_validation.rs index 042eb73e96..07127c2b23 100644 --- a/identity_storage/src/storage/tests/credential_validation.rs +++ b/identity_storage/src/storage/tests/credential_validation.rs @@ -10,11 +10,11 @@ use identity_credential::credential::RevocationBitmapStatus; use identity_credential::credential::Status; use identity_credential::revocation::RevocationBitmap; use identity_credential::revocation::RevocationDocumentExt; -use identity_credential::validator::CredentialValidationOptions; -use identity_credential::validator::CredentialValidator; use identity_credential::validator::FailFast; +use identity_credential::validator::JwtCredentialValidationOptions; +use identity_credential::validator::JwtCredentialValidator; +use identity_credential::validator::JwtValidationError; use identity_credential::validator::StatusCheck; -use identity_credential::validator::ValidationError; use identity_did::DID; use identity_document::document::CoreDocument; use identity_document::service::Service; @@ -60,12 +60,12 @@ where let issued_on_or_before = issuance_date; // expires_on_or_after > expiration_date let expires_on_or_after = expiration_date.checked_add(Duration::seconds(1)).unwrap(); - let options = CredentialValidationOptions::default() + let options = JwtCredentialValidationOptions::default() .latest_issuance_date(issued_on_or_before) .earliest_expiry_date(expires_on_or_after); // validate and extract the nested error according to our expectations - let validation_errors = CredentialValidator::new() + let validation_errors = JwtCredentialValidator::new() .validate::<_, Object>(&jws, &issuer_doc, &options, FailFast::FirstError) .unwrap_err() .validation_errors; @@ -75,7 +75,7 @@ where _ => unreachable!(), }; - assert!(matches!(error, &ValidationError::ExpirationDate)); + assert!(matches!(error, &JwtValidationError::ExpirationDate)); } // Test invalid issuance date. @@ -83,12 +83,12 @@ where // issued_on_or_before < issuance_date let issued_on_or_before = issuance_date.checked_sub(Duration::seconds(1)).unwrap(); let expires_on_or_after = expiration_date; - let options = CredentialValidationOptions::default() + let options = JwtCredentialValidationOptions::default() .latest_issuance_date(issued_on_or_before) .earliest_expiry_date(expires_on_or_after); // validate and extract the nested error according to our expectations - let validation_errors = CredentialValidator::new() + let validation_errors = JwtCredentialValidator::new() .validate::<_, Object>(&jws, &issuer_doc, &options, FailFast::FirstError) .unwrap_err() .validation_errors; @@ -98,7 +98,7 @@ where _ => unreachable!(), }; - assert!(matches!(error, &ValidationError::IssuanceDate)); + assert!(matches!(error, &JwtValidationError::IssuanceDate)); } } @@ -139,10 +139,10 @@ where let issued_on_or_before: Timestamp = issuance_date.checked_add(Duration::days(14)).unwrap(); let expires_on_or_after: Timestamp = expiration_date.checked_sub(Duration::hours(1)).unwrap(); - let options = CredentialValidationOptions::default() + let options = JwtCredentialValidationOptions::default() .latest_issuance_date(issued_on_or_before) .earliest_expiry_date(expires_on_or_after); - assert!(CredentialValidator::new() + assert!(JwtCredentialValidator::new() .validate::<_, Object>(&jwt, &issuer_doc, &options, FailFast::FirstError) .is_ok()); } @@ -180,17 +180,17 @@ where // the credential was not signed by this issuer // check that `verify_signature` returns the expected error - let error = CredentialValidator::new() + let error = JwtCredentialValidator::new() .verify_signature::<_, Object>(&jwt, &[&subject_doc], &JwsVerificationOptions::default()) .unwrap_err(); - assert!(matches!(error, ValidationError::DocumentMismatch { .. })); + assert!(matches!(error, JwtValidationError::DocumentMismatch { .. })); // also check that the full validation fails as expected - let options = CredentialValidationOptions::default(); + let options = JwtCredentialValidationOptions::default(); // validate and extract the nested error according to our expectations - let validation_errors = CredentialValidator::new() + let validation_errors = JwtCredentialValidator::new() .validate::<_, Object>(&jwt, &subject_doc, &options, FailFast::FirstError) .unwrap_err() .validation_errors; @@ -200,7 +200,7 @@ where _ => unreachable!(), }; - assert!(matches!(error, ValidationError::DocumentMismatch { .. })); + assert!(matches!(error, JwtValidationError::DocumentMismatch { .. })); } #[tokio::test] @@ -237,23 +237,23 @@ where .await .unwrap(); - let err = CredentialValidator::new() + let err = JwtCredentialValidator::new() .verify_signature::<_, Object>(&jwt, &[&issuer_doc], &JwsVerificationOptions::default()) .unwrap_err(); // run the validation unit // we expect that the kid won't resolve to a method on the issuer_doc's document. - assert!(matches!(err, ValidationError::Signature { .. })); + assert!(matches!(err, JwtValidationError::Signature { .. })); // check that full_validation also fails as expected let issued_on_or_before = issuance_date.checked_add(Duration::days(14)).unwrap(); let expires_on_or_after = expiration_date.checked_sub(Duration::hours(1)).unwrap(); - let options = CredentialValidationOptions::default() + let options = JwtCredentialValidationOptions::default() .latest_issuance_date(issued_on_or_before) .earliest_expiry_date(expires_on_or_after); // validate and extract the nested error according to our expectations - let validation_errors = CredentialValidator::new() + let validation_errors = JwtCredentialValidator::new() .validate::<_, Object>(&jwt, &issuer_doc, &options, FailFast::FirstError) .unwrap_err() .validation_errors; @@ -264,7 +264,7 @@ where }; // we expect that the kid won't resolve to a method on the issuer_doc's document. - assert!(matches!(error, &ValidationError::Signature { .. })); + assert!(matches!(error, &JwtValidationError::Signature { .. })); } #[tokio::test] @@ -300,7 +300,7 @@ where // 0: missing status always succeeds. for status_check in [StatusCheck::Strict, StatusCheck::SkipUnsupported, StatusCheck::SkipAll] { - assert!(CredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok()); + assert!(JwtCredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok()); } // 1: unsupported status type. @@ -314,7 +314,7 @@ where (StatusCheck::SkipAll, true), ] { assert_eq!( - CredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok(), + JwtCredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok(), expected ); } @@ -331,7 +331,7 @@ where (StatusCheck::SkipAll, true), ] { assert_eq!( - CredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok(), + JwtCredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok(), expected ); } @@ -343,7 +343,7 @@ where // 3: un-revoked index always succeeds. for status_check in [StatusCheck::Strict, StatusCheck::SkipUnsupported, StatusCheck::SkipAll] { - assert!(CredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok()); + assert!(JwtCredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok()); } // 4: revoked index. @@ -354,7 +354,7 @@ where (StatusCheck::SkipAll, true), ] { assert_eq!( - CredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok(), + JwtCredentialValidator::check_status(&credential, &[&issuer_doc], status_check).is_ok(), expected ); } @@ -405,18 +405,18 @@ where let issued_on_or_before = issuance_date.checked_sub(Duration::seconds(1)).unwrap(); // expires_on_or_after > expiration_date let expires_on_or_after = expiration_date.checked_add(Duration::seconds(1)).unwrap(); - let options = CredentialValidationOptions::default() + let options = JwtCredentialValidationOptions::default() .latest_issuance_date(issued_on_or_before) .earliest_expiry_date(expires_on_or_after); - let validation_errors = CredentialValidator::new() + let validation_errors = JwtCredentialValidator::new() .validate::<_, Object>(&jws, &issuer_doc, &options, FailFast::FirstError) .unwrap_err() .validation_errors; assert!(validation_errors.len() == 1); - let validation_errors = CredentialValidator::new() + let validation_errors = JwtCredentialValidator::new() .validate::<_, Object>(&jws, &issuer_doc, &options, FailFast::AllErrors) .unwrap_err() .validation_errors; diff --git a/identity_storage/src/storage/tests/presentation_validation.rs b/identity_storage/src/storage/tests/presentation_validation.rs index d0da672610..192c97b680 100644 --- a/identity_storage/src/storage/tests/presentation_validation.rs +++ b/identity_storage/src/storage/tests/presentation_validation.rs @@ -14,7 +14,7 @@ use identity_credential::presentation::PresentationBuilder; use identity_credential::validator::DecodedJwtPresentation; use identity_credential::validator::JwtPresentationValidationOptions; use identity_credential::validator::JwtPresentationValidator; -use identity_credential::validator::ValidationError; +use identity_credential::validator::JwtValidationError; use identity_did::CoreDID; use identity_did::DID; use identity_document::document::CoreDocument; @@ -210,7 +210,7 @@ where .await .unwrap(); let validator: JwtPresentationValidator = JwtPresentationValidator::new(); - let validation_error: ValidationError = validator + let validation_error: JwtValidationError = validator .validate::<_, Jwt, Object>( &presentation_jwt, &setup.subject_doc, @@ -225,7 +225,7 @@ where assert!(matches!( validation_error, - ValidationError::PresentationJwsError(identity_document::Error::JwsVerificationError(_)) + JwtValidationError::PresentationJwsError(identity_document::Error::JwsVerificationError(_)) )); } @@ -267,7 +267,7 @@ where .unwrap(); let validator: JwtPresentationValidator = JwtPresentationValidator::new(); - let validation_error: ValidationError = validator + let validation_error: JwtValidationError = validator .validate::<_, Jwt, Object>( &presentation_jwt, &setup.subject_doc, @@ -281,7 +281,7 @@ where .unwrap(); println!("{validation_error:?}"); - assert!(matches!(validation_error, ValidationError::ExpirationDate)); + assert!(matches!(validation_error, JwtValidationError::ExpirationDate)); // Set Validation options to allow expired presentation that were valid 2 hours back. let mut validation_options = JwtPresentationValidationOptions::default(); @@ -332,7 +332,7 @@ where .unwrap(); let validator: JwtPresentationValidator = JwtPresentationValidator::new(); - let validation_error: ValidationError = validator + let validation_error: JwtValidationError = validator .validate::<_, Jwt, Object>( &presentation_jwt, &setup.subject_doc, @@ -345,7 +345,7 @@ where .next() .unwrap(); - assert!(matches!(validation_error, ValidationError::IssuanceDate)); + assert!(matches!(validation_error, JwtValidationError::IssuanceDate)); // Set Validation options to allow presentation "issued" 2 hours in the future. let mut validation_options = JwtPresentationValidationOptions::default(); @@ -393,7 +393,7 @@ where .unwrap(); let validator: JwtPresentationValidator = JwtPresentationValidator::new(); - let validation_error: ValidationError = validator + let validation_error: JwtValidationError = validator .validate::<_, Jwt, Object>( &presentation_jwt, &setup.subject_doc, @@ -408,7 +408,7 @@ where assert!(matches!( validation_error, - ValidationError::PresentationJwsError(identity_document::Error::MethodNotFound) + JwtValidationError::PresentationJwsError(identity_document::Error::MethodNotFound) )); }