diff --git a/bindings/wasm/Cargo.toml b/bindings/wasm/Cargo.toml index 1acaf0ce96..b3017d8dc8 100644 --- a/bindings/wasm/Cargo.toml +++ b/bindings/wasm/Cargo.toml @@ -20,6 +20,7 @@ async-trait = { version = "0.1", default-features = false } bls12_381_plus = "0.8.17" console_error_panic_hook = { version = "0.1" } futures = { version = "0.3" } +identity_ecdsa_verifier = { path = "../../identity_ecdsa_verifier", default-features = false, features = ["es256", "es256k"] } identity_eddsa_verifier = { path = "../../identity_eddsa_verifier", default-features = false, features = ["ed25519"] } js-sys = { version = "0.3.61" } json-proof-token = "0.3.4" diff --git a/bindings/wasm/docs/api-reference.md b/bindings/wasm/docs/api-reference.md index 6dd0837a69..25fdf6ba04 100644 --- a/bindings/wasm/docs/api-reference.md +++ b/bindings/wasm/docs/api-reference.md @@ -55,6 +55,10 @@ See: Duration

A span of time.

+
EcDSAJwsVerifier
+

An implementor of IJwsVerifier that can handle the +EcDSA algorithm.

+
EdDSAJwsVerifier

An implementor of IJwsVerifier that can handle the EdDSA algorithm.

@@ -255,8 +259,23 @@ working with storage backed DID documents.

## Members
-
PresentationProofAlgorithm
-
+
StatusCheck
+

Controls validation behaviour when checking whether or not a credential has been revoked by its +credentialStatus.

+
+
Strict
+

Validate the status if supported, reject any unsupported +credentialStatus types.

+

Only RevocationBitmap2022 is currently supported.

+

This is the default.

+
+
SkipUnsupported
+

Validate the status if supported, skip any unsupported +credentialStatus types.

+
+
SkipAll
+

Skip all status checks.

+
SubjectHolderRelationship

Declares how credential subjects must relate to the presentation holder.

See also the Subject-Holder Relationship section of the specification.

@@ -271,9 +290,14 @@ This variant is the default.

Any

The holder is not required to have any kind of relationship to any credential subject.

+
PresentationProofAlgorithm
+
+
StatusPurpose
+

Purpose of a StatusList2021.

+
ProofAlgorithm
-
StateMetadataEncoding
+
CredentialStatus
FailFast

Declares when validation should return if an error occurs.

@@ -284,34 +308,14 @@ This variant is the default.

FirstError

Return after the first error occurs.

-
StatusCheck
-

Controls validation behaviour when checking whether or not a credential has been revoked by its -credentialStatus.

-
-
Strict
-

Validate the status if supported, reject any unsupported -credentialStatus types.

-

Only RevocationBitmap2022 is currently supported.

-

This is the default.

-
-
SkipUnsupported
-

Validate the status if supported, skip any unsupported -credentialStatus types.

-
-
SkipAll
-

Skip all status checks.

-
+
StateMetadataEncoding
+
SerializationType
PayloadType
-
StatusPurpose
-

Purpose of a StatusList2021.

-
MethodRelationship
-
CredentialStatus
-
## Functions @@ -334,6 +338,12 @@ prior to calling the function.

start()

Initializes the console error panic hook for better error messages

+
encodeB64(data)string
+

Encode the given bytes in url-safe base64.

+
+
decodeB64(data)Uint8Array
+

Decode the given url-safe base64-encoded slice into its raw bytes.

+
@@ -557,7 +567,7 @@ if the object is being concurrently modified. * [.resolveMethod(query, [scope])](#CoreDocument+resolveMethod) ⇒ [VerificationMethod](#VerificationMethod) \| undefined * [.attachMethodRelationship(didUrl, relationship)](#CoreDocument+attachMethodRelationship) ⇒ boolean * [.detachMethodRelationship(didUrl, relationship)](#CoreDocument+detachMethodRelationship) ⇒ boolean - * [.verifyJws(jws, options, signatureVerifier, [detachedPayload])](#CoreDocument+verifyJws) ⇒ [DecodedJws](#DecodedJws) + * [.verifyJws(jws, options, [signatureVerifier], [detachedPayload])](#CoreDocument+verifyJws) ⇒ [DecodedJws](#DecodedJws) * [.revokeCredentials(serviceQuery, indices)](#CoreDocument+revokeCredentials) * [.unrevokeCredentials(serviceQuery, indices)](#CoreDocument+unrevokeCredentials) * [.clone()](#CoreDocument+clone) ⇒ [CoreDocument](#CoreDocument) @@ -832,7 +842,7 @@ Detaches the given relationship from the given method, if the method exists. -### coreDocument.verifyJws(jws, options, signatureVerifier, [detachedPayload]) ⇒ [DecodedJws](#DecodedJws) +### coreDocument.verifyJws(jws, options, [signatureVerifier], [detachedPayload]) ⇒ [DecodedJws](#DecodedJws) Decodes and verifies the provided JWS according to the passed `options` and `signatureVerifier`. If no `signatureVerifier` argument is provided a default verifier will be used that is (only) capable of verifying EdDSA signatures. @@ -849,7 +859,7 @@ or set explicitly in the `options`. | --- | --- | | jws | [Jws](#Jws) | | options | [JwsVerificationOptions](#JwsVerificationOptions) | -| signatureVerifier | IJwsVerifier | +| [signatureVerifier] | IJwsVerifier \| undefined | | [detachedPayload] | string \| undefined | @@ -2034,6 +2044,43 @@ Deserializes an instance from a JSON object. | --- | --- | | json | any | + + +## EcDSAJwsVerifier +An implementor of `IJwsVerifier` that can handle the +`EcDSA` algorithm. + +**Kind**: global class + +* [EcDSAJwsVerifier](#EcDSAJwsVerifier) + * [new EcDSAJwsVerifier()](#new_EcDSAJwsVerifier_new) + * [.verify(alg, signingInput, decodedSignature, publicKey)](#EcDSAJwsVerifier+verify) + + + +### new EcDSAJwsVerifier() +Constructs an EcDSAJwsVerifier. + + + +### ecDSAJwsVerifier.verify(alg, signingInput, decodedSignature, publicKey) +Verify a JWS signature secured with the `EcDSA` algorithm. +Only the `ES256` and `ES256K` curves are supported for now. + +# Warning + +This function does not check the `alg` property in the protected header. Callers are expected to assert this +prior to calling the function. + +**Kind**: instance method of [EcDSAJwsVerifier](#EcDSAJwsVerifier) + +| Param | Type | +| --- | --- | +| alg | JwsAlgorithm | +| signingInput | Uint8Array | +| decodedSignature | Uint8Array | +| publicKey | [Jwk](#Jwk) | + ## EdDSAJwsVerifier @@ -2315,7 +2362,7 @@ if the object is being concurrently modified. * [.resolveMethod(query, [scope])](#IotaDocument+resolveMethod) ⇒ [VerificationMethod](#VerificationMethod) \| undefined * [.attachMethodRelationship(didUrl, relationship)](#IotaDocument+attachMethodRelationship) ⇒ boolean * [.detachMethodRelationship(didUrl, relationship)](#IotaDocument+detachMethodRelationship) ⇒ boolean - * [.verifyJws(jws, options, signatureVerifier, [detachedPayload])](#IotaDocument+verifyJws) ⇒ [DecodedJws](#DecodedJws) + * [.verifyJws(jws, options, [signatureVerifier], [detachedPayload])](#IotaDocument+verifyJws) ⇒ [DecodedJws](#DecodedJws) * [.pack()](#IotaDocument+pack) ⇒ Uint8Array * [.packWithEncoding(encoding)](#IotaDocument+packWithEncoding) ⇒ Uint8Array * [.metadata()](#IotaDocument+metadata) ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) @@ -2556,7 +2603,7 @@ Detaches the given relationship from the given method, if the method exists. -### iotaDocument.verifyJws(jws, options, signatureVerifier, [detachedPayload]) ⇒ [DecodedJws](#DecodedJws) +### iotaDocument.verifyJws(jws, options, [signatureVerifier], [detachedPayload]) ⇒ [DecodedJws](#DecodedJws) Decodes and verifies the provided JWS according to the passed `options` and `signatureVerifier`. If no `signatureVerifier` argument is provided a default verifier will be used that is (only) capable of verifying EdDSA signatures. @@ -2572,7 +2619,7 @@ take place. | --- | --- | | jws | [Jws](#Jws) | | options | [JwsVerificationOptions](#JwsVerificationOptions) | -| signatureVerifier | IJwsVerifier | +| [signatureVerifier] | IJwsVerifier \| undefined | | [detachedPayload] | string \| undefined | @@ -4653,7 +4700,7 @@ A type for decoding and validating [Credential](#Credential). **Kind**: global class * [JwtCredentialValidator](#JwtCredentialValidator) - * [new JwtCredentialValidator(signatureVerifier)](#new_JwtCredentialValidator_new) + * [new JwtCredentialValidator([signatureVerifier])](#new_JwtCredentialValidator_new) * _instance_ * [.validate(credential_jwt, issuer, options, fail_fast)](#JwtCredentialValidator+validate) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) * [.verifySignature(credential, trustedIssuers, options)](#JwtCredentialValidator+verifySignature) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) @@ -4668,7 +4715,7 @@ A type for decoding and validating [Credential](#Credential). -### new JwtCredentialValidator(signatureVerifier) +### new JwtCredentialValidator([signatureVerifier]) Creates a new [JwtCredentialValidator](#JwtCredentialValidator). 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. @@ -4676,7 +4723,7 @@ algorithm will be used. | Param | Type | | --- | --- | -| signatureVerifier | IJwsVerifier | +| [signatureVerifier] | IJwsVerifier \| undefined | @@ -4847,21 +4894,21 @@ A validator for a Domain Linkage Configuration and Credentials. **Kind**: global class * [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) - * [new JwtDomainLinkageValidator(signatureVerifier)](#new_JwtDomainLinkageValidator_new) + * [new JwtDomainLinkageValidator([signatureVerifier])](#new_JwtDomainLinkageValidator_new) * [.validateLinkage(issuer, configuration, domain, options)](#JwtDomainLinkageValidator+validateLinkage) * [.validateCredential(issuer, credentialJwt, domain, options)](#JwtDomainLinkageValidator+validateCredential) -### new JwtDomainLinkageValidator(signatureVerifier) +### new JwtDomainLinkageValidator([signatureVerifier]) Creates a new [JwtDomainLinkageValidator](#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. +verifying decoded JWS signatures, otherwise the default which is capable of handling the `EdDSA`, `ES256`, `ES256K` +algorithms will be used. | Param | Type | | --- | --- | -| signatureVerifier | IJwsVerifier | +| [signatureVerifier] | IJwsVerifier \| undefined | @@ -5011,7 +5058,7 @@ Deserializes an instance from a JSON object. **Kind**: global class * [JwtPresentationValidator](#JwtPresentationValidator) - * [new JwtPresentationValidator(signatureVerifier)](#new_JwtPresentationValidator_new) + * [new JwtPresentationValidator([signatureVerifier])](#new_JwtPresentationValidator_new) * _instance_ * [.validate(presentationJwt, holder, validation_options)](#JwtPresentationValidator+validate) ⇒ [DecodedJwtPresentation](#DecodedJwtPresentation) * _static_ @@ -5020,7 +5067,7 @@ Deserializes an instance from a JSON object. -### new JwtPresentationValidator(signatureVerifier) +### new JwtPresentationValidator([signatureVerifier]) Creates a new [JwtPresentationValidator](#JwtPresentationValidator). 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. @@ -5028,7 +5075,7 @@ algorithm will be used. | Param | Type | | --- | --- | -| signatureVerifier | IJwsVerifier | +| [signatureVerifier] | IJwsVerifier \| undefined | @@ -6536,14 +6583,14 @@ A type for decoding and validating [Credential](#Credential). **Kind**: global class * [SdJwtCredentialValidator](#SdJwtCredentialValidator) - * [new SdJwtCredentialValidator(signatureVerifier)](#new_SdJwtCredentialValidator_new) + * [new SdJwtCredentialValidator([signatureVerifier])](#new_SdJwtCredentialValidator_new) * [.validateCredential(sd_jwt, issuer, options, fail_fast)](#SdJwtCredentialValidator+validateCredential) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) * [.verifySignature(credential, trustedIssuers, options)](#SdJwtCredentialValidator+verifySignature) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) * [.validateKeyBindingJwt(sdJwt, holder, options)](#SdJwtCredentialValidator+validateKeyBindingJwt) ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) -### new SdJwtCredentialValidator(signatureVerifier) +### new SdJwtCredentialValidator([signatureVerifier]) Creates a new `SdJwtCredentialValidator`. 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. @@ -6551,7 +6598,7 @@ algorithm will be used. | Param | Type | | --- | --- | -| signatureVerifier | IJwsVerifier | +| [signatureVerifier] | IJwsVerifier \| undefined | @@ -7657,9 +7704,36 @@ Deserializes an instance from a JSON object. | --- | --- | | json | any | - + + +## StatusCheck +Controls validation behaviour when checking whether or not a credential has been revoked by its +[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status). + +**Kind**: global variable + + +## Strict +Validate the status if supported, reject any unsupported +[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) types. + +Only `RevocationBitmap2022` is currently supported. + +This is the default. + +**Kind**: global variable + + +## SkipUnsupported +Validate the status if supported, skip any unsupported +[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) types. + +**Kind**: global variable + + +## SkipAll +Skip all status checks. -## PresentationProofAlgorithm **Kind**: global variable @@ -7668,33 +7742,42 @@ Declares how credential subjects must relate to the presentation holder. See also the [Subject-Holder Relationship](https://www.w3.org/TR/vc-data-model/#subject-holder-relationships) section of the specification. +## CredentialStatus **Kind**: global variable - + -## AlwaysSubject -The holder must always match the subject on all credentials, regardless of their [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property. -This variant is the default. +## encodeB64(data) ⇒ string +Encode the given bytes in url-safe base64. -**Kind**: global variable - +**Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +## decodeB64(data) ⇒ Uint8Array +Decode the given url-safe base64-encoded slice into its raw bytes. -## SubjectOnNonTransferable -The holder must match the subject only for credentials where the [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property is `true`. +**Kind**: global variable + +## PresentationProofAlgorithm **Kind**: global variable - + -## Any -The holder is not required to have any kind of relationship to any credential subject. +## StatusPurpose +Purpose of a [StatusList2021](#StatusList2021). **Kind**: global variable ## ProofAlgorithm **Kind**: global variable - + -## StateMetadataEncoding +## CredentialStatus **Kind**: global variable @@ -7714,36 +7797,9 @@ Return all errors that occur during validation. Return after the first error occurs. **Kind**: global variable - - -## StatusCheck -Controls validation behaviour when checking whether or not a credential has been revoked by its -[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status). - -**Kind**: global variable - - -## Strict -Validate the status if supported, reject any unsupported -[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) types. - -Only `RevocationBitmap2022` is currently supported. - -This is the default. - -**Kind**: global variable - - -## SkipUnsupported -Validate the status if supported, skip any unsupported -[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) types. - -**Kind**: global variable - - -## SkipAll -Skip all status checks. + +## StateMetadataEncoding **Kind**: global variable @@ -7752,43 +7808,11 @@ Skip all status checks. ## PayloadType -**Kind**: global variable - - -## StatusPurpose -Purpose of a [StatusList2021](#StatusList2021). - **Kind**: global variable ## MethodRelationship **Kind**: global variable - - -## CredentialStatus -**Kind**: global variable - - -## encodeB64(data) ⇒ string -Encode the given bytes in url-safe base64. - -**Kind**: global function - -| Param | Type | -| --- | --- | -| data | Uint8Array | - - - -## decodeB64(data) ⇒ Uint8Array -Decode the given url-safe base64-encoded slice into its raw bytes. - -**Kind**: global function - -| Param | Type | -| --- | --- | -| data | Uint8Array | - ## verifyEd25519(alg, signingInput, decodedSignature, publicKey) @@ -7817,3 +7841,25 @@ prior to calling the function. Initializes the console error panic hook for better error messages **Kind**: global function + + +## encodeB64(data) ⇒ string +Encode the given bytes in url-safe base64. + +**Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +## decodeB64(data) ⇒ Uint8Array +Decode the given url-safe base64-encoded slice into its raw bytes. + +**Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + diff --git a/bindings/wasm/src/credential/domain_linkage_validator.rs b/bindings/wasm/src/credential/domain_linkage_validator.rs index a38639d853..37674e21b7 100644 --- a/bindings/wasm/src/credential/domain_linkage_validator.rs +++ b/bindings/wasm/src/credential/domain_linkage_validator.rs @@ -24,11 +24,11 @@ pub struct WasmJwtDomainLinkageValidator { #[wasm_bindgen(js_class = JwtDomainLinkageValidator)] impl WasmJwtDomainLinkageValidator { /// Creates a new {@link 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. + /// verifying decoded JWS signatures, otherwise a default verifier capable of handling the `EdDSA`, `ES256`, `ES256K` + /// algorithms will be used. #[wasm_bindgen(constructor)] #[allow(non_snake_case)] - pub fn new(signatureVerifier: IJwsVerifier) -> WasmJwtDomainLinkageValidator { + pub fn new(signatureVerifier: Option) -> WasmJwtDomainLinkageValidator { let signature_verifier = WasmJwsVerifier::new(signatureVerifier); 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 9434a6d521..b6a26c35d5 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 @@ -37,11 +37,11 @@ pub struct WasmJwtCredentialValidator(JwtCredentialValidator); #[wasm_bindgen(js_class = JwtCredentialValidator)] impl WasmJwtCredentialValidator { /// Creates a new {@link JwtCredentialValidator}. 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. + /// verifying decoded JWS signatures, otherwise a default verifier capable of handling the `EdDSA`, `ES256`, `ES256K` + /// algorithms will be used. #[wasm_bindgen(constructor)] #[allow(non_snake_case)] - pub fn new(signatureVerifier: IJwsVerifier) -> WasmJwtCredentialValidator { + pub fn new(signatureVerifier: Option) -> WasmJwtCredentialValidator { let signature_verifier = WasmJwsVerifier::new(signatureVerifier); WasmJwtCredentialValidator(JwtCredentialValidator::with_signature_verifier(signature_verifier)) } diff --git a/bindings/wasm/src/credential/jwt_credential_validation/sd_jwt_validator.rs b/bindings/wasm/src/credential/jwt_credential_validation/sd_jwt_validator.rs index 812b25414b..a8342c9aec 100644 --- a/bindings/wasm/src/credential/jwt_credential_validation/sd_jwt_validator.rs +++ b/bindings/wasm/src/credential/jwt_credential_validation/sd_jwt_validator.rs @@ -29,11 +29,11 @@ pub struct WasmSdJwtCredentialValidator(SdJwtCredentialValidator WasmSdJwtCredentialValidator { + pub fn new(signatureVerifier: Option) -> WasmSdJwtCredentialValidator { let signature_verifier = WasmJwsVerifier::new(signatureVerifier); WasmSdJwtCredentialValidator(SdJwtCredentialValidator::with_signature_verifier( signature_verifier, diff --git a/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs b/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs index 40a44f916b..640f96c2ef 100644 --- a/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs +++ b/bindings/wasm/src/credential/jwt_presentation_validation/jwt_presentation_validator.rs @@ -23,11 +23,11 @@ pub struct WasmJwtPresentationValidator(JwtPresentationValidator WasmJwtPresentationValidator { + pub fn new(signatureVerifier: Option) -> WasmJwtPresentationValidator { let signature_verifier = WasmJwsVerifier::new(signatureVerifier); WasmJwtPresentationValidator(JwtPresentationValidator::with_signature_verifier(signature_verifier)) } diff --git a/bindings/wasm/src/did/wasm_core_document.rs b/bindings/wasm/src/did/wasm_core_document.rs index 2a7d896ac8..fd66c4e7ca 100644 --- a/bindings/wasm/src/did/wasm_core_document.rs +++ b/bindings/wasm/src/did/wasm_core_document.rs @@ -495,8 +495,9 @@ impl WasmCoreDocument { // =========================================================================== /// Decodes and verifies the provided JWS according to the passed `options` and `signatureVerifier`. - /// If no `signatureVerifier` argument is provided a default verifier will be used that is (only) capable of - /// verifying EdDSA signatures. + /// If a `signatureVerifier` is provided it will be used when + /// verifying decoded JWS signatures, otherwise a default verifier capable of handling the `EdDSA`, `ES256`, `ES256K` + /// algorithms will be used. /// /// Regardless of which options are passed the following conditions must be met in order for a verification attempt to /// take place. @@ -509,7 +510,7 @@ impl WasmCoreDocument { &self, jws: &WasmJws, options: &WasmJwsVerificationOptions, - signatureVerifier: IJwsVerifier, + signatureVerifier: Option, detachedPayload: Option, ) -> Result { let jws_verifier = WasmJwsVerifier::new(signatureVerifier); diff --git a/bindings/wasm/src/iota/iota_document.rs b/bindings/wasm/src/iota/iota_document.rs index 777a00e679..1747f82e6e 100644 --- a/bindings/wasm/src/iota/iota_document.rs +++ b/bindings/wasm/src/iota/iota_document.rs @@ -384,8 +384,9 @@ impl WasmIotaDocument { // =========================================================================== /// Decodes and verifies the provided JWS according to the passed `options` and `signatureVerifier`. - /// If no `signatureVerifier` argument is provided a default verifier will be used that is (only) capable of - /// verifying EdDSA signatures. + /// If a `signatureVerifier` is provided it will be used when + /// verifying decoded JWS signatures, otherwise a default verifier capable of handling the `EdDSA`, `ES256`, `ES256K` + /// algorithms will be used. /// /// Regardless of which options are passed the following conditions must be met in order for a verification attempt to /// take place. @@ -397,7 +398,7 @@ impl WasmIotaDocument { &self, jws: &WasmJws, options: &WasmJwsVerificationOptions, - signatureVerifier: IJwsVerifier, + signatureVerifier: Option, detachedPayload: Option, ) -> Result { let jws_verifier = WasmJwsVerifier::new(signatureVerifier); diff --git a/bindings/wasm/src/verification/custom_verification.rs b/bindings/wasm/src/verification/custom_verification.rs index 4c82d8dcfe..9fe2f9e8b7 100644 --- a/bindings/wasm/src/verification/custom_verification.rs +++ b/bindings/wasm/src/verification/custom_verification.rs @@ -1,6 +1,9 @@ // Copyright 2020-2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use identity_ecdsa_verifier::EcDSAJwsVerifier; +use identity_eddsa_verifier::EdDSAJwsVerifier; +use identity_iota::verification::jws::JwsAlgorithm; use identity_iota::verification::jws::JwsVerifier; use identity_iota::verification::jws::SignatureVerificationError; use identity_iota::verification::jws::SignatureVerificationErrorKind; @@ -10,12 +13,12 @@ use wasm_bindgen::prelude::*; use crate::jose::WasmJwk; /// Wrapper that enables custom TS JWS signature verification plugins to be used where the -/// JwsVerifier trait is required. Falls back to the default implementation if a custom -/// implementation was not passed. -pub(crate) struct WasmJwsVerifier(IJwsVerifier); +/// JwsVerifier trait is required. Falls back to the default implementation capable of handling +/// EdDSA (ED25519), ES256, ES256K if a custom implementation is not passed. +pub(crate) struct WasmJwsVerifier(Option); impl WasmJwsVerifier { - pub(crate) fn new(verifier: IJwsVerifier) -> Self { + pub(crate) fn new(verifier: Option) -> Self { Self(verifier) } } @@ -26,22 +29,30 @@ impl JwsVerifier for WasmJwsVerifier { input: identity_iota::verification::jws::VerificationInput, public_key: &identity_iota::verification::jwk::Jwk, ) -> Result<(), identity_iota::verification::jws::SignatureVerificationError> { - let VerificationInput { - alg, - signing_input, - decoded_signature, - } = input; - let verification_result = IJwsVerifier::verify( - &self.0, - alg.name().to_owned(), - signing_input.into(), - decoded_signature.into(), - WasmJwk(public_key.to_owned()), - ); - // Convert error - crate::error::stringify_js_error(verification_result).map_err(|error_string| { - SignatureVerificationError::new(SignatureVerificationErrorKind::Unspecified).with_custom_message(error_string) - }) + if let Some(verifier) = &self.0 { + let VerificationInput { + alg, + signing_input, + decoded_signature, + } = input; + let verification_result = IJwsVerifier::verify( + verifier, + alg.name().to_owned(), + signing_input.into(), + decoded_signature.into(), + WasmJwk(public_key.to_owned()), + ); + // Convert error + crate::error::stringify_js_error(verification_result).map_err(|error_string| { + SignatureVerificationError::new(SignatureVerificationErrorKind::Unspecified).with_custom_message(error_string) + }) + } else { + match input.alg { + JwsAlgorithm::EdDSA => EdDSAJwsVerifier::default().verify(input, public_key), + JwsAlgorithm::ES256 | JwsAlgorithm::ES256K => EcDSAJwsVerifier::default().verify(input, public_key), + _ => Err(identity_iota::verification::jws::SignatureVerificationErrorKind::UnsupportedAlg.into()), + } + } } } #[wasm_bindgen(typescript_custom_section)] diff --git a/bindings/wasm/src/verification/jws_verifier.rs b/bindings/wasm/src/verification/jws_verifier.rs index 6113674828..bd016910c8 100644 --- a/bindings/wasm/src/verification/jws_verifier.rs +++ b/bindings/wasm/src/verification/jws_verifier.rs @@ -1,6 +1,7 @@ // Copyright 2020-2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use identity_ecdsa_verifier::EcDSAJwsVerifier; use identity_eddsa_verifier::Ed25519Verifier; use identity_eddsa_verifier::EdDSAJwsVerifier; use identity_iota::verification::jws::JwsAlgorithm; @@ -80,3 +81,43 @@ impl WasmEdDSAJwsVerifier { EdDSAJwsVerifier::default().verify(input, &publicKey.0).wasm_result() } } + +/// An implementor of `IJwsVerifier` that can handle the +/// `EcDSA` algorithm. +#[wasm_bindgen(js_name = EcDSAJwsVerifier)] +pub struct WasmEcDSAJwsVerifier(); + +#[wasm_bindgen(js_class = EcDSAJwsVerifier)] +#[allow(clippy::new_without_default)] +impl WasmEcDSAJwsVerifier { + /// Constructs an EcDSAJwsVerifier. + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self() + } + + /// Verify a JWS signature secured with the `EcDSA` algorithm. + /// Only the `ES256` and `ES256K` curves are supported for now. + /// + /// # Warning + /// + /// This function does not check the `alg` property in the protected header. Callers are expected to assert this + /// prior to calling the function. + #[wasm_bindgen] + #[allow(non_snake_case)] + pub fn verify( + &self, + alg: WasmJwsAlgorithm, + signingInput: &[u8], + decodedSignature: &[u8], + publicKey: &WasmJwk, + ) -> Result<(), JsValue> { + let alg: JwsAlgorithm = JwsAlgorithm::try_from(alg)?; + let input: VerificationInput = VerificationInput { + alg, + signing_input: signingInput.into(), + decoded_signature: decodedSignature.into(), + }; + EcDSAJwsVerifier::default().verify(input, &publicKey.0).wasm_result() + } +}