Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vcdm 2.0 issuance/verification #3056

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions aries_cloudagent/messaging/valid.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,28 @@ def __call__(self, value):
return value


class CredentialV2Context(Validator):
"""Credential V2 Context."""

FIRST_CONTEXT = "https://www.w3.org/ns/credentials/v2"
EXAMPLE = [FIRST_CONTEXT, "https://www.w3.org/ns/credentials/examples/v2"]

def __init__(self) -> None:
"""Initialize the instance."""
super().__init__()

def __call__(self, value):
"""Validate input value."""
length = len(value)

if length < 1 or value[0] != CredentialV2Context.FIRST_CONTEXT:
raise ValidationError(
f"First context must be {CredentialV2Context.FIRST_CONTEXT}"
)

return value


class CredentialSubject(Validator):
"""Credential subject."""

Expand Down Expand Up @@ -1007,6 +1029,9 @@ def __init__(
CREDENTIAL_CONTEXT_VALIDATE = CredentialContext()
CREDENTIAL_CONTEXT_EXAMPLE = CredentialContext.EXAMPLE

CREDENTIAL_V2_CONTEXT_VALIDATE = CredentialV2Context()
CREDENTIAL_V2_CONTEXT_EXAMPLE = CredentialV2Context.EXAMPLE

URI_VALIDATE = Uri()
URI_EXAMPLE = Uri.EXAMPLE

Expand Down
1 change: 1 addition & 0 deletions aries_cloudagent/vc/ld_proofs/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
SECURITY_CONTEXT_URL = SECURITY_CONTEXT_V2_URL
DID_V1_CONTEXT_URL = "https://www.w3.org/ns/did/v1"
CREDENTIALS_CONTEXT_V1_URL = "https://www.w3.org/2018/credentials/v1"
CREDENTIALS_CONTEXT_V2_URL = "https://www.w3.org/ns/credentials/v2"
SECURITY_CONTEXT_BBS_URL = "https://w3id.org/security/bbs/v1"
SECURITY_CONTEXT_ED25519_2020_URL = "https://w3id.org/security/suites/ed25519-2020/v1"

Expand Down
18 changes: 16 additions & 2 deletions aries_cloudagent/vc/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@
from .vc_ld.manager import VcLdpManager, VcLdpManagerError
from .vc_ld.models import web_schemas
from .vc_ld.models.credential import VerifiableCredential
from .vc_ld.models.credentialv2 import VerifiableCredentialV2
from .vc_ld.models.options import LDProofVCOptions
from .vc_ld.models.presentation import VerifiablePresentation
from .ld_proofs.constants import (
CREDENTIALS_CONTEXT_V1_URL,
CREDENTIALS_CONTEXT_V2_URL,
)


@docs(tags=["vc-api"], summary="List credentials")
Expand Down Expand Up @@ -92,7 +97,11 @@ async def issue_credential_route(request: web.BaseRequest):
elif key_type == "bls12381g2":
options["proofType"] = "BbsBlsSignature2020"

credential = VerifiableCredential.deserialize(credential)
if credential["@context"][0] == CREDENTIALS_CONTEXT_V1_URL:
credential = VerifiableCredential.deserialize(credential)

elif credential["@context"][0] == CREDENTIALS_CONTEXT_V2_URL:
credential = VerifiableCredentialV2.deserialize(credential)
options = LDProofVCOptions.deserialize(options)

vc = await manager.issue(credential, options)
Expand All @@ -117,7 +126,12 @@ async def verify_credential_route(request: web.BaseRequest):
context: AdminRequestContext = request["context"]
manager = VcLdpManager(context.profile)
try:
vc = VerifiableCredential.deserialize(body["verifiableCredential"])
vc = body["verifiableCredential"]
if vc["@context"][0] == CREDENTIALS_CONTEXT_V1_URL:
vc = VerifiableCredential.deserialize(vc)
elif vc["@context"][0] == CREDENTIALS_CONTEXT_V2_URL:
vc = VerifiableCredentialV2.deserialize(vc)

result = await manager.verify_credential(vc)
result = result.serialize()
return web.json_response(result)
Expand Down
10 changes: 9 additions & 1 deletion aries_cloudagent/vc/vc_ld/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
DocumentLoaderMethod,
LinkedDataProofException,
)
from ..ld_proofs.constants import (
CREDENTIALS_CONTEXT_V1_URL,
CREDENTIALS_CONTEXT_V2_URL,
)
from .models.credential import CredentialSchema
from .models.credentialv2 import CredentialV2Schema


async def issue(
Expand Down Expand Up @@ -40,7 +45,10 @@ async def issue(

"""
# Validate credential
errors = CredentialSchema().validate(credential)
if credential["@context"][0] == CREDENTIALS_CONTEXT_V1_URL:
errors = CredentialSchema().validate(credential)
elif credential["@context"][0] == CREDENTIALS_CONTEXT_V2_URL:
errors = CredentialV2Schema().validate(credential)
if len(errors) > 0:
raise LinkedDataProofException(
f"Credential contains invalid structure: {errors}"
Expand Down
31 changes: 23 additions & 8 deletions aries_cloudagent/vc/vc_ld/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from ...wallet.error import WalletNotFoundError
from ...wallet.key_type import BLS12381G2, ED25519, KeyType
from ..ld_proofs.constants import (
CREDENTIALS_CONTEXT_V1_URL,
CREDENTIALS_CONTEXT_V2_URL,
SECURITY_CONTEXT_BBS_URL,
SECURITY_CONTEXT_ED25519_2020_URL,
)
Expand All @@ -33,6 +35,7 @@
from .external_suite import ExternalSuiteNotFoundError, ExternalSuiteProvider
from .issue import issue as ldp_issue
from .models.credential import VerifiableCredential
from .models.credentialv2 import VerifiableCredentialV2
from .models.linked_data_proof import LDProof
from .models.options import LDProofVCOptions
from .prove import sign_presentation
Expand Down Expand Up @@ -315,10 +318,14 @@ async def prepare_presentation(

async def _get_suite_for_document(
self,
document: Union[VerifiableCredential, VerifiablePresentation],
document: Union[
VerifiableCredential, VerifiableCredentialV2, VerifiablePresentation
],
options: LDProofVCOptions,
) -> LinkedDataProof:
if isinstance(document, VerifiableCredential):
if isinstance(document, VerifiableCredential) or isinstance(
document, VerifiableCredentialV2
):
issuer_id = document.issuer_id
elif isinstance(document, VerifiablePresentation):
issuer_id = document.holder_id
Expand Down Expand Up @@ -384,8 +391,10 @@ async def _get_all_proof_suites(self) -> List[LinkedDataProof]:
]

async def issue(
self, credential: VerifiableCredential, options: LDProofVCOptions
) -> VerifiableCredential:
self,
credential: Union[VerifiableCredential, VerifiableCredentialV2],
options: LDProofVCOptions,
) -> Union[VerifiableCredential, VerifiableCredentialV2]:
"""Sign a VC with a Linked Data Proof."""
credential = await self.prepare_credential(credential, options)

Expand All @@ -404,11 +413,17 @@ async def issue(
document_loader=document_loader,
purpose=proof_purpose,
)
return VerifiableCredential.deserialize(vc)
if vc["@context"][0] == CREDENTIALS_CONTEXT_V1_URL:
return VerifiableCredential.deserialize(vc)
elif vc["@context"][0] == CREDENTIALS_CONTEXT_V2_URL:
return VerifiableCredentialV2.deserialize(vc)

async def store_credential(
self, vc: VerifiableCredential, options: LDProofVCOptions, cred_id: str = None
) -> VerifiableCredential:
self,
vc: Union[VerifiableCredential, VerifiableCredentialV2],
options: LDProofVCOptions,
cred_id: str = None,
) -> Union[VerifiableCredential, VerifiableCredentialV2]:
"""Store a verifiable credential."""

# Saving expanded type as a cred_tag
Expand Down Expand Up @@ -439,7 +454,7 @@ async def store_credential(
await vc_holder.store_credential(vc_record)

async def verify_credential(
self, vc: VerifiableCredential
self, vc: Union[VerifiableCredential, VerifiableCredentialV2]
) -> DocumentVerificationResult:
"""Verify a VC with a Linked Data Proof."""
return await verify_credential(
Expand Down
8 changes: 8 additions & 0 deletions aries_cloudagent/vc/vc_ld/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
VerifiableCredentialSchema as _VerifiableCredentialSchema,
CredentialSchema as _CredentialSchema,
)
from .credentialv2 import (
VerifiableCredentialV2 as _VerifiableCredentialV2,
VerifiableCredentialV2Schema as _VerifiableCredentialV2Schema,
CredentialV2Schema as _CredentialV2Schema,
)
from .linked_data_proof import (
LDProof as _LDProof,
LinkedDataProofSchema as _LinkedDataProofSchema,
Expand All @@ -12,6 +17,9 @@
"_VerifiableCredential",
"_CredentialSchema",
"_VerifiableCredentialSchema",
"_VerifiableCredentialV2",
"_CredentialV2Schema",
"_VerifiableCredentialV2Schema",
"_LDProof",
"_LinkedDataProofSchema",
]
Loading
Loading