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

wip #4

Open
wants to merge 72 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
1545645
wip
jchartrand Jan 7, 2025
dfc8c27
add error handling
jchartrand Jan 7, 2025
584f9a9
update tests and readme
jchartrand Jan 8, 2025
c9b45b7
Update README.md
jchartrand Jan 8, 2025
9798dfb
wip: update readme and organize test fixtures
jchartrand Jan 8, 2025
e5bafe7
reorganize test fixtures
jchartrand Jan 9, 2025
1501002
add test vc combinations of revoked/expired
jchartrand Jan 9, 2025
a59c4fa
fix texts
jchartrand Jan 10, 2025
711d7b1
make knownRegistryList an argument of verifyCredential
jchartrand Jan 10, 2025
1f4c5f7
add credential to result
jchartrand Jan 10, 2025
0b47854
add deep equal test on positive result
jchartrand Jan 10, 2025
1ca9abf
add and reorganize tests
jchartrand Jan 10, 2025
9b3777e
switch testing to run after tsc compile
jchartrand Jan 12, 2025
9aff772
fix tests
jchartrand Jan 12, 2025
0bb989a
replace nullish coalescing with logical or for registry check
jchartrand Jan 13, 2025
d53e7f1
test for no proof
jchartrand Jan 13, 2025
f3135f9
fix invalid signature tests
jchartrand Jan 13, 2025
bf67187
add test for jsonld context
jchartrand Jan 13, 2025
588adbe
add test for missing vc context
jchartrand Jan 13, 2025
3ab3689
add bad id test
jchartrand Jan 13, 2025
a8d4866
add test for simultaneous expired and tampered
jchartrand Jan 14, 2025
46cc4b5
add tests for revoked with valid status
jchartrand Jan 14, 2025
664451b
fix linting
jchartrand Jan 14, 2025
de56d0b
remove types from .gitignore
jchartrand Jan 14, 2025
5272080
disable karma
jchartrand Jan 14, 2025
a0404fe
add eddsa verification
jchartrand Jan 15, 2025
02f7b59
fix lint errors
jchartrand Jan 15, 2025
de74064
update to beta vc package
jchartrand Jan 16, 2025
c6ea122
update result description and eddsa handling in README
jchartrand Jan 16, 2025
10aced7
add both signature suites to verify call
jchartrand Jan 17, 2025
ac99e17
add list of unloaded registries to result
jchartrand Jan 18, 2025
d9cceed
fix lint errors
jchartrand Jan 18, 2025
5a965b4
update registry client to new beta version
jchartrand Jan 18, 2025
dd9f0d5
add tests for bad registries and missing matches
jchartrand Jan 19, 2025
ee4f5ff
enable all tests
jchartrand Jan 19, 2025
8fde1f0
update tests
jchartrand Jan 19, 2025
37e4fbb
add handling for notFound status list
jchartrand Jan 19, 2025
39bfd3e
update unit tests
jchartrand Jan 19, 2025
763b342
add did:web fixture for testing
jchartrand Jan 20, 2025
2331e3a
add did:web tests
jchartrand Jan 21, 2025
243a8e7
add check for unresolved did:web
jchartrand Jan 21, 2025
1bbbd32
fix linting
jchartrand Jan 22, 2025
05def42
remove unnecessary did log entry; update README
jchartrand Jan 22, 2025
8a2de13
fix lint errors
jchartrand Jan 22, 2025
52a061b
update README
jchartrand Jan 22, 2025
f72814f
add presentation verification
jchartrand Jan 22, 2025
0ad410e
fix assertionMethod and challenge on verifyPresentation
jchartrand Jan 24, 2025
ff5d62c
extract verification result transformation
jchartrand Jan 24, 2025
a99fc09
transform vc verification responses in presentation
jchartrand Jan 27, 2025
69e30c5
reorganize tests
jchartrand Jan 27, 2025
05d5ac2
transform verification response
jchartrand Jan 28, 2025
dba2d31
fix lint errors
jchartrand Jan 28, 2025
ee809a8
add mixed VC presentation test
jchartrand Jan 28, 2025
8bce92c
add unsigned presentation tests
jchartrand Jan 28, 2025
dd1116c
remove isFatal flag from results
jchartrand Jan 28, 2025
d8435a1
update tests
jchartrand Jan 28, 2025
e70be8d
add test for bad challenge and presentation purpose
jchartrand Jan 28, 2025
10a625f
add coverage
jchartrand Jan 28, 2025
30e46b6
enable coverage badge
jchartrand Jan 28, 2025
6754a6d
fix test coverage
jchartrand Jan 28, 2025
4f0f983
update tests and README
jchartrand Jan 29, 2025
e455b38
update method signature in README
jchartrand Jan 29, 2025
c9122e2
update README examples and tests
jchartrand Jan 29, 2025
fa842ef
test for string valued issuer id
jchartrand Jan 29, 2025
1111a36
extract constants to files
jchartrand Jan 29, 2025
1e2360e
remove old status list check
jchartrand Jan 29, 2025
197845f
update error explanation in README
jchartrand Jan 29, 2025
e7ee7b7
add js extension to fix published package
jchartrand Feb 4, 2025
e8dba6e
update dependencies and version for publish
jchartrand Feb 6, 2025
a2116a7
add await to result transform call
jchartrand Feb 6, 2025
b875b05
update cryptosuite dependency and version for publish
jchartrand Feb 6, 2025
ea15abb
cleanup
jchartrand Feb 10, 2025
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
Prev Previous commit
Next Next commit
update README examples and tests
jchartrand committed Jan 29, 2025
commit c9122e210d7c4cc57fbdef416478e95db842848c
308 changes: 301 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ And verifies signatures from both [eddsa-rdfc-2022 Data Integrity Proof](https:/

The verification checks that the credential:

* has a valid signature, and so:
* has a valid signature, and so therefore:
* the credential hasn't been tampered with
* the signing key was retrieved from the did document
* hasn't expired
@@ -493,7 +493,7 @@ The proof property is missing, likely because the credential hasn't been signed:

<b>other problem</b>

Some other error might also prevent verification, and a stack trace might be returned:
Some other error might also prevent verification, and an error, possibly with a stack trace, might be returned:

```
{
@@ -512,11 +512,11 @@ Some other error might also prevent verification, and a stack trace might be ret

```verifyPresentation({presentation, reloadIssuerRegistry = true, unsignedPresentation = false})```

A Verifiable Presentation (VP) is a wrapper around zero or more Verifiable Credentials. A VP can also be cryptographically signed, like a VC, but whereas a VC is signed by the issuer of the credentials, the VP is signed by the holder of the credentials, typically to demonstrate 'control' of the contained credentials. The VP is signed with a DID that the holder owns, and often that DID is recorded inside the Verifiable Credentials as the 'owner' or 'holder' of the credential. So by signing the VP with the private key corresponding to that DID we can prove we 'own' the credentials.
A Verifiable Presentation (VP) is a wrapper around zero or more Verifiable Credentials. A VP can be cryptographically signed, like a VC, but whereas a VC is signed by the issuer of the credentials, the VP is signed by the holder of the credentials contained in the VP, typically to demonstrate 'control' of the contained credentials. The VP is signed with a DID that the holder owns, and usually that DID was recorded inside the Verifiable Credentials - at the time of issuance - as the 'owner' or 'holder' of the credential. So by signing the VP with the private key corresponding to that DID we can prove we 'own' the credentials, or in other words, that the credentials were issued to us (to our DID.)

A VP needn't be signed. It could simply be used as to 'package' together a set of VCs.

A VP is also sometimes used without any containted VC simply to prove that we control a given DID, say for authentication, or often for the case where when an issuer is issuing a credential to a DID, the issuer wants to know that the recipient in fact does control that DID. In these cases the VP is used as a `did-auth`. This verifier-core library does not, however, provide verification for `did-auth`, only to verify a presentation containing VCs.
A signed VP is also sometimes used for authentication, without any contained VC. Say for the case where when an issuer is issuing a credential to a DID, and the issuer wants to know that the recipient in fact does control that DID. In these cases the VP is typically the response to a request for [DIDAuthentication (DidAuth)](https://w3c-ccg.github.io/vp-request-spec/#did-authentication). This verifier-core library does not, however, provide verification for DidAuthentication, only to verify a presentation containing VCs.

Verifying a VP amounts to verifying the signature on the VP (if the signature exists) and also verifying all of the contained VCs, one by one.

@@ -530,13 +530,307 @@ Verifying a VP amounts to verifying the signature on the VP (if the signature ex

With a VP we have a result for the vp as well as for all the contained VCs. Each of the VC results follows exactly the format described above for the results of verifying an individual VCs. We may also have an error.

A successful VP result might look like so:
A successful signed VP result with two packaged VCs might look like so:

A VP that itself verfies (i.e, it's signature), but has one VC that doesn't might look like so:
```
{
"presentationResult": {
"signature": "valid"
},
"credentialResults": [
{
"log": [
{
"id": "valid_signature",
"valid": true
},
{
"id": "revocation_status",
"valid": true
},
{
"id": "expiration",
"valid": true
},
{
"id": "registered_issuer",
"valid": true,
"foundInRegistries": [
"DCC Sandbox Registry"
],
"registriesNotLoaded": []
}
],
"credential": {vc omitted for brevity/clarity}
},
{
"log": [
{
"id": "valid_signature",
"valid": true
},
{
"id": "revocation_status",
"valid": true
},
{
"id": "expiration",
"valid": true
},
{
"id": "registered_issuer",
"valid": true,
"foundInRegistries": [
"DCC Sandbox Registry"
],
"registriesNotLoaded": []
}
],
"credential": {vc omitted for brevity/clarity}
}
]
}
```

A VP that itself verfies (i.e, it's signature), but has one VC that doesn't, might look like so:

```
{
"presentationResult": {
"signature": "signed"
},
"credentialResults": [
{
"credential": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "0923lksjf",
"type": [
"VerifiableCredential",
"OpenBadgeCredential"
],
"issuer": {
"id": "did:key:z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q",
"type": [
"Profile"
],
"name": "Example Corp"
},
"validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": [
"AchievementSubject"
],
"achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": [
"Achievement"
],
"criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
},
"description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
"name": "Teamwork"
}
},
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-01-09T17:58:33Z",
"verificationMethod": "did:key:z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q#z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q",
"proofPurpose": "assertionMethod",
"proofValue": "z62t6TYCERpTKuWCRhHc2fV7JoMhiFuEcCXGkX9iit8atQPhviN5cZeZfXRnvJWa3Bm6DjagKyrauaSJfp9C9i7q3"
}
},
"errors": [
{
"name": "invalid_credential_id",
"message": "The credential's id uses an invalid format. It may have been issued as part of an early pilot. Please contact the issuer to get a replacement."
}
]
}
]
}
```

It is important to note in the above example that the validity of the signature of the presentation is different from the validity of each of the contained VCs. A valid presentation signature simply means that nothing in the VP was tampered with.

An unsigned VP containing a single verified credential:

```
{
"presentationResult": {
"signature": "unsigned"
},
"credentialResults": [
{
"log": [
{
"id": "valid_signature",
"valid": true
},
{
"id": "revocation_status",
"valid": true
},
{
"id": "expiration",
"valid": true
},
{
"id": "registered_issuer",
"valid": true,
"foundInRegistries": [
"DCC Sandbox Registry"
],
"registriesNotLoaded": []
}
],
"credential": {vc omitted for brevity/clarity}
}
]
}
```

A VP with a bad signature might look like so:
A VP where we've tampered with one of the packaged credentials (by changing the credential name). Note here that both the VP and the VC don't verify because changing the VC affected the VC signature bit also the VP signature which contains the VC.

```
{
"presentationResult": {
"signature": "invalid",
"errors": [
{
"message": {
"name": "VerificationError",
"errors": [
{
"name": "Error",
"message": "Invalid signature.",
"stack": "Error: Invalid signature.\n at Ed25519Signature2020.verifyProof (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/suites/LinkedDataSignature.js:189:15)\n at async /Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/ProofSet.js:273:53\n at async Promise.all (index 0)\n at async _verify (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/ProofSet.js:261:3)\n at async ProofSet.verify (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/ProofSet.js:195:23)\n at async Object.verify (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/jsonld-signatures.js:160:18)\n at async _verifyPresentation (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/vc/dist/index.js:578:30)\n at async verifyPresentation (file:///Users/jameschartrand/Documents/github/dcc/verifier-core/dist/src/Verify.js:24:24)\n at async Context.<anonymous> (file:///Users/jameschartrand/Documents/github/dcc/verifier-core/dist/test/Verify.presentation.spec.js:97:28)"
}
]
},
"name": "presentation_error"
}
]
},
"credentialResults": [
{
"credential": {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:2fe53dc9-b2ec-4939-9b2c-0d00f6663b6c",
"type": [
"VerifiableCredential",
"OpenBadgeCredential"
],
"name": "Tampered Name",
"issuer": {
"type": [
"Profile"
],
"id": "did:key:z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q",
"name": "Digital Credentials Consortium Test Issuer",
"url": "https://dcconsortium.org",
"image": "https://user-images.githubusercontent.com/752326/230469660-8f80d264-eccf-4edd-8e50-ea634d407778.png"
},
"issuanceDate": "2023-08-02T17:43:32.903Z",
"credentialSubject": {
"type": [
"AchievementSubject"
],
"achievement": {
"id": "urn:uuid:bd6d9316-f7ae-4073-a1e5-2f7f5bd22922",
"type": [
"Achievement"
],
"achievementType": "Diploma",
"name": "Badge",
"description": "This is a sample credential issued by the Digital Credentials Consortium to demonstrate the functionality of Verifiable Credentials for wallets and verifiers.",
"criteria": {
"type": "Criteria",
"narrative": "This credential was issued to a student that demonstrated proficiency in the Python programming language that occurred from **February 17, 2023** to **June 12, 2023**."
},
"image": {
"id": "https://user-images.githubusercontent.com/752326/214947713-15826a3a-b5ac-4fba-8d4a-884b60cb7157.png",
"type": "Image"
}
},
"name": "Jane Doe"
},
"proof": {
"type": "Ed25519Signature2020",
"created": "2023-10-05T11:17:41Z",
"verificationMethod": "did:key:z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q#z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q",
"proofPurpose": "assertionMethod",
"proofValue": "z5fk6gq9upyZvcFvJdRdeL5KmvHr69jxEkyDEd2HyQdyhk9VnDEonNSmrfLAcLEDT9j4gGdCG24WHhojVHPbRsNER"
}
},
"errors": [
{
"name": "invalid_signature",
"message": "The signature is not valid."
}
]
}
]
}
```

And here is a VP where just the VP has been tampered with, and not the embedded VC, and so the VC returns as valid, but not the presentation signature:

```
{
"presentationResult": {
"signature": "invalid",
"errors": [
{
"message": {
"name": "VerificationError",
"errors": [
{
"name": "Error",
"message": "Invalid signature.",
"stack": "Error: Invalid signature.\n at Ed25519Signature2020.verifyProof (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/suites/LinkedDataSignature.js:189:15)\n at async /Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/ProofSet.js:273:53\n at async Promise.all (index 0)\n at async _verify (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/ProofSet.js:261:3)\n at async ProofSet.verify (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/ProofSet.js:195:23)\n at async Object.verify (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/jsonld-signatures/lib/jsonld-signatures.js:160:18)\n at async _verifyPresentation (/Users/jameschartrand/Documents/github/dcc/verifier-core/node_modules/@digitalcredentials/vc/dist/index.js:578:30)\n at async verifyPresentation (file:///Users/jameschartrand/Documents/github/dcc/verifier-core/dist/src/Verify.js:24:24)\n at async Context.<anonymous> (file:///Users/jameschartrand/Documents/github/dcc/verifier-core/dist/test/Verify.presentation.spec.js:101:28)"
}
]
},
"name": "presentation_error"
}
]
},
"credentialResults": [
{
"log": [
{
"id": "valid_signature",
"valid": true
},
{
"id": "expiration",
"valid": true
},
{
"id": "registered_issuer",
"valid": true,
"foundInRegistries": [
"DCC Sandbox Registry"
],
"registriesNotLoaded": []
}
],
"credential": {vc ommitted for clarity/brevity}
}
]
}
```

## Install

12 changes: 0 additions & 12 deletions old.c8rc

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
"rebuild": "npm run clear && npm run build",
"test": "npm run lint && npm run test-node",
"test-karma": "karma start karma.conf.js",
"test-node-old": "cross-env NODE_ENV=test TS_NODE_PROJECT=tsconfig.spec.json TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register --project tsconfig.spec.json 'test/*.ts'",
"test-node-no-cov": "npm run build-test && mocha dist/test/*.spec.js && rm -rf dist/esm/test || true",
"test-node": "npm run build-test && npx c8 --exclude 'dist/test/**' mocha dist/test/*.spec.js && rm -rf dist/esm/test || true",
"coveralls": "npm run test; npx c8 --exclude 'dist/test/**' report --reporter=text-lcov > ./coverage/lcov.info"
},
Loading