Skip to content

Commit

Permalink
feat: add external suite provider
Browse files Browse the repository at this point in the history
To make signing mechanisms for JSON-LD pluggable.

Signed-off-by: Daniel Bluhm <[email protected]>
  • Loading branch information
dbluhm committed Mar 22, 2024
1 parent 6da07c6 commit 1022611
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
44 changes: 44 additions & 0 deletions aries_cloudagent/vc/vc_ld/external_suite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Plugin hook for providing an external signature suite implementation.
This enables greater control over where JSON-LD credentials are signed without
requiring knowledge of the complexities of the JSON-LD/VC-LDP subsystem.
"""

from abc import ABC, abstractmethod
from typing import Optional

from ...core.error import BaseError
from ...core.profile import Profile
from ...wallet.did_info import DIDInfo
from ..ld_proofs.suites.linked_data_proof import LinkedDataProof


class ExternalSuiteError(BaseError):
"""Raised when an error occurs in an external signature suite provider."""


class ExternalSuiteNotFoundError(ExternalSuiteError):
"""Raised when an external signature suite provider is not found.
This should be raised to prevent falling back to built in suites, if desired.
"""


class ExternalSuiteProvider(ABC):
"""Plugin hook for providing an external signature suite implementation."""

@abstractmethod
def get_suite(
self,
profile: Profile,
proof_type: str,
proof: dict,
verification_method: str,
did_info: DIDInfo,
) -> Optional[LinkedDataProof]:
"""Get a signature suite for the given proof type and verification method.
Implementing classes should raise ExternalSuiteNotFoundError if preventing
fallback to built-in suites is desired. Otherwise, return None to indicate
that the implementing class does not support the given proof type.
"""
22 changes: 19 additions & 3 deletions aries_cloudagent/vc/vc_ld/manager.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
"""Manager for performing Linked Data Proof signatures over JSON-LD formatted W3C VCs."""

from typing import Dict, List, Optional, Type, Union, cast

from pyld import jsonld
from pyld.jsonld import JsonLdProcessor

from ...core.profile import Profile
from ...storage.vc_holder.base import VCHolder
from ...storage.vc_holder.vc_record import VCRecord
from ...wallet.base import BaseWallet
from ...wallet.default_verification_key_strategy import BaseVerificationKeyStrategy
from ...wallet.did_info import DIDInfo
from ...wallet.error import WalletNotFoundError
from ...wallet.key_type import BLS12381G2, ED25519, KeyType
from ...storage.vc_holder.base import VCHolder
from ...storage.vc_holder.vc_record import VCRecord
from ..ld_proofs.constants import (
SECURITY_CONTEXT_BBS_URL,
SECURITY_CONTEXT_ED25519_2020_URL,
Expand All @@ -29,11 +30,12 @@
from ..ld_proofs.validation_result import DocumentVerificationResult
from ..vc_ld.models.presentation import VerifiablePresentation
from ..vc_ld.validation_result import PresentationVerificationResult
from .external_suite import ExternalSuiteNotFoundError, ExternalSuiteProvider
from .issue import issue as ldp_issue
from .prove import sign_presentation
from .models.credential import VerifiableCredential
from .models.linked_data_proof import LDProof
from .models.options import LDProofVCOptions
from .prove import sign_presentation
from .verify import verify_credential, verify_presentation

SignatureTypes = Union[
Expand Down Expand Up @@ -182,6 +184,20 @@ async def _get_suite(
did_info: Optional[DIDInfo] = None,
):
"""Get signature suite for issuance of verification."""
# Try to get suite from external provider first
try:
if (provider := self.profile.inject_or(ExternalSuiteProvider)) and (
suite := provider.get_suite(
self.profile, proof_type, proof, verification_method, did_info
)
):
return suite
except ExternalSuiteNotFoundError as error:
raise VcLdpManagerError(
f"Unable to get signature suite for proof type {proof_type} "
"using external provider."
) from error

# Get signature class based on proof type
SignatureClass = PROOF_TYPE_SIGNATURE_SUITE_MAPPING[proof_type]

Expand Down

0 comments on commit 1022611

Please sign in to comment.