Closed HelgeKrueger closed 5 months ago
@HelgeKrueger Thank you so much for including your implementation. In addition to the comments above, I've also noticed that the verifiable credential issued by bovine has credentialSubject
that is a string. According to the specs https://www.w3.org/TR/vc-data-model/#credential-subject, it looks like the credential subject is expected to be an object or a set of objects. Not sure if that might cause validation issues during verification by other implementations.
@HelgeKrueger Thank you so much for including your implementation. In addition to the comments above, I've also noticed that the verifiable credential issued by bovine has
credentialSubject
that is a string. According to the specs https://www.w3.org/TR/vc-data-model/#credential-subject, it looks like the credential subject is expected to be an object or a set of objects. Not sure if that might cause validation issues during verification by other implementations.
I just looked at this and this seems to be caused by how I do "context injection". I do this by applying json-ld compaction of the old document against the old context + data integrity context. This compaction steps, compacts something of the form {"id": "some_id"}
down to just "some_id"
.
Not sure how to do context injection differently, without needing a highly custom json-ld processor.
The following illustrates the above with an example.
or compact
{
"@context": [
"https://www.w3.org/2018/credentials/v1"
],
"id": "urn:uuid:b4c30912-53bd-412f-8dac-5f13b554f615",
"type": [
"VerifiableCredential"
],
"issuer": "urn:uuid:my:implementation:issuer:id",
"issuanceDate": "2020-03-16T22:37:26.544Z",
"credentialSubject": {
"id": "did:key:z6MktKwz7Ge1Yxzr4JHavN33wiwa8y81QdcMRLXQsrH9T53b"
}
}
against
[
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/security/data-integrity/v2"
]
@HelgeKrueger @JSAssassin Hrm, having the credentialSubject
value be a string probably should be allowed. That said, it's a bit of a strange VC. This seems like it might just be a test suite issue? @HelgeKrueger can you add another property to your credentialSubject
besides id
, like name
? That would result in the compaction being a more acceptable value.
A regular JSON-LD processor should work for this concern... no specialized JSON-LD processor should be needed for VCs.
Is the test using a credentialSubject
with just an id
field? The way the VC spec is written, one MUST have at least one claim associated w/ the object associated w/ credentialSubject
. The example above doesn't have that.
@HelgeKrueger it's definitely the lack of claims in credentialSubject
that's causing the issue. We'll make sure to get a test added to make that clearer. Thanks!
@HelgeKrueger credentialSubject
string does get verified by DB. So I think no changes are required regarding that, sorry about the false alarm.
With the latest changes you've made, eddsa-rdfc-2022
tests (including the interoperability with DB) are passing for bovine. Thanks for the updates.
ecdsa-rdfc-2019
tests though are still having some interop verification issues. DB verifier is not able to verify VC issued by bovine and bovine is also unable to verify VC issued by DB.
I am seeing an invalid signature error.
The VC that is issued by bovine that fails verification by DB looks like this:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
{
"@protected": true,
"DriverLicense": {
"@context": {
"@protected": true,
"dateOfBirth": "urn:example:dateOfBirth",
"documentIdentifier": "urn:example:documentIdentifier",
"expirationDate": "urn:example:expiration",
"id": "@id",
"issuingAuthority": "urn:example:issuingAuthority",
"type": "@type"
},
"@id": "urn:example:DriverLicense"
},
"DriverLicenseCredential": "urn:example:DriverLicenseCredential",
"driverLicense": {
"@id": "urn:example:driverLicense",
"@type": "@id"
}
},
"https://w3id.org/security/data-integrity/v2"
],
"credentialSubject": {
"driverLicense": {
"dateOfBirth": "01-01-1990",
"documentIdentifier": "T21387yc328c7y32h23f23",
"expirationDate": "01-01-2030",
"issuingAuthority": "VA",
"type": "DriverLicense"
},
"id": "urn:uuid:1a0e4ef5-091f-4060-842e-18e519ab9440"
},
"id": "urn:uuid:19a7ccd2-fa67-4ee2-bab4-4f83d7b13561",
"issuanceDate": "2024-01-02T16:13:19Z",
"issuer": "did:key:zDnaeRpdr3KkQ1NtBhLAWFp76epvaU1spZzGH7AvKtY9KqjZr",
"proof": {
"created": "2024-01-02T16:13:20Z",
"cryptosuite": "ecdsa-rdfc-2019",
"proofPurpose": "assertionMethod",
"proofValue": "zAN1rKvtn4VewtoCHrxWr4RNYGjeinc5ttB7x7MeaXawtbtGVSvws5pNpw6WLa3bLPey46dHMAXHa3d3KYKBdjMs35GnujrWqk",
"type": "DataIntegrityProof",
"verificationMethod": "did:key:zDnaeRpdr3KkQ1NtBhLAWFp76epvaU1spZzGH7AvKtY9KqjZr#zDnaeRpdr3KkQ1NtBhLAWFp76epvaU1spZzGH7AvKtY9KqjZr"
},
"type": [
"VerifiableCredential",
"DriverLicenseCredential"
]
}
And the VC that is issued by DB that fails verification by bolive looks like:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
{
"@protected": true,
"DriverLicenseCredential": "urn:example:DriverLicenseCredential",
"DriverLicense": {
"@id": "urn:example:DriverLicense",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"documentIdentifier": "urn:example:documentIdentifier",
"dateOfBirth": "urn:example:dateOfBirth",
"expirationDate": "urn:example:expiration",
"issuingAuthority": "urn:example:issuingAuthority"
}
},
"driverLicense": {
"@id": "urn:example:driverLicense",
"@type": "@id"
}
},
"https://w3id.org/security/data-integrity/v2"
],
"id": "urn:uuid:6a6a9bb2-090a-4ffa-8462-4a614ae4c269",
"type": [
"VerifiableCredential",
"DriverLicenseCredential"
],
"credentialSubject": {
"id": "urn:uuid:1a0e4ef5-091f-4060-842e-18e519ab9440",
"driverLicense": {
"type": "DriverLicense",
"documentIdentifier": "T21387yc328c7y32h23f23",
"dateOfBirth": "01-01-1990",
"expirationDate": "01-01-2030",
"issuingAuthority": "VA"
}
},
"issuer": "did:key:zDnaeRZqxu4dSRPiLWwph8ghUy17tE9BWXTNqtpzTw2HjthdX",
"issuanceDate": "2024-01-02T16:13:22Z",
"proof": {
"type": "DataIntegrityProof",
"created": "2024-01-02T16:13:22Z",
"verificationMethod": "did:key:zDnaeRZqxu4dSRPiLWwph8ghUy17tE9BWXTNqtpzTw2HjthdX#zDnaeRZqxu4dSRPiLWwph8ghUy17tE9BWXTNqtpzTw2HjthdX",
"cryptosuite": "ecdsa-rdfc-2019",
"proofPurpose": "assertionMethod",
"proofValue": "z65xxPTTzV6w4Jtjiscbr5cX6QT5XJFZKC74hE6pzeboEGXknnVu8qT3JhBAJ12MdBWrVsEsuqWbh9Mb8StgF563N"
}
}
@HelgeKrueger can you add another property to your
credentialSubject
besidesid
, likename
?
The credential being used comes from https://github.com/w3c/vc-di-eddsa-test-suite/blob/main/tests/vc-generator/validVc.js If I modify it with
credentialSubject: {
id: "did:key:z6MktKwz7Ge1Yxzr4JHavN33wiwa8y81QdcMRLXQsrH9T53b",
"https://test.example/name": "testing",
},
my signed credential looks like
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/security/data-integrity/v2"
],
"id": "urn:uuid:444266b8-28ab-41bf-908a-ddbd27e3f60e",
"type": "VerifiableCredential",
"credentialSubject": {
"id": "did:key:z6MktKwz7Ge1Yxzr4JHavN33wiwa8y81QdcMRLXQsrH9T53b",
"https://test.example/name": "testing"
},
"issuanceDate": "2020-03-16T22:37:26.544Z",
"issuer": "urn:uuid:my:implementation:issuer:id",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"created": "2024-01-02T17:26:54Z",
"verificationMethod": "did:key:z6MkvQCqUiD64HouwuN2N6KDTocDjXQnLgfk7HcSbXtrwfW3#z6MkvQCqUiD64HouwuN2N6KDTocDjXQnLgfk7HcSbXtrwfW3",
"proofPurpose": "assertionMethod",
"proofValue": "zHpPNcfawRG27UKzstZS7cQvi63pH3LidusJH133TnvbSFEJMEtYvt9W9hydGKGxjAyKVe8CxnZpbNZkqXHzkdd7"
}
}
So the credential structure is respected.
@HelgeKrueger
credentialSubject
string does get verified by DB. So I think no changes are required regarding that, sorry ...ecdsa-rdfc-2019
tests though are still having some interop verification issues. DB verifier is not able to verify VC issued by bovine and bovine is also unable to verify VC issued by DB.
I've looked at it. The problem comes from the library, I use for ECDSA, returns a DER encoded signature.
This seems different from what is suggested at https://datatracker.ietf.org/doc/html/rfc7518#section-3.4
From a practical standpoint: My signatures are 72 bytes long instead of 64. I'll try to figure out how to translate between the two signature formats.
@HelgeKrueger you may want to look through the Hashing section in the VC Data Integrity ECDSA spec. That's likely got the steps described that are missing here.
@JSAssassin
ecdsa-rdfc-2019
tests though are still having some interop verification issues. DB verifier is not able to verify VC issued by bovine and bovine is also unable to verify VC issued by DB.
Can you recheck now? I updated the implementation, keys are the correct length now.
@HelgeKrueger Just checked, verifications are passing now for VCs using P-256
key types.
However, bovine verifier has P-384
specified as one of the supported key types but looks like it doesn't support verification of VCs using P-384
key types yet. Not sure if you intend to add support for it. If you don't, then P-384
can be removed from the list.
Verification is failing for the following VC:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
{
"@protected": true,
"DriverLicenseCredential": "urn:example:DriverLicenseCredential",
"DriverLicense": {
"@id": "urn:example:DriverLicense",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"documentIdentifier": "urn:example:documentIdentifier",
"dateOfBirth": "urn:example:dateOfBirth",
"expirationDate": "urn:example:expiration",
"issuingAuthority": "urn:example:issuingAuthority"
}
},
"driverLicense": {
"@id": "urn:example:driverLicense",
"@type": "@id"
}
},
"https://w3id.org/security/data-integrity/v2"
],
"id": "urn:uuid:1e30cef5-6a61-4703-809f-9b7df5bde1a3",
"type": [
"VerifiableCredential",
"DriverLicenseCredential"
],
"credentialSubject": {
"id": "urn:uuid:1a0e4ef5-091f-4060-842e-18e519ab9440",
"driverLicense": {
"type": "DriverLicense",
"documentIdentifier": "T21387yc328c7y32h23f23",
"dateOfBirth": "01-01-1990",
"expirationDate": "01-01-2030",
"issuingAuthority": "VA"
}
},
"issuer": "did:key:z82Lky21MA8mGLTpsgvGnikRjS12Ar8wik7L3BJi9xSvU89rZaKcNRrcddPHhNFTWdR84oB",
"issuanceDate": "2024-01-03T15:15:20Z",
"proof": {
"type": "DataIntegrityProof",
"created": "2024-01-03T15:15:20Z",
"verificationMethod": "did:key:z82Lky21MA8mGLTpsgvGnikRjS12Ar8wik7L3BJi9xSvU89rZaKcNRrcddPHhNFTWdR84oB#z82Lky21MA8mGLTpsgvGnikRjS12Ar8wik7L3BJi9xSvU89rZaKcNRrcddPHhNFTWdR84oB",
"cryptosuite": "ecdsa-rdfc-2019",
"proofPurpose": "assertionMethod",
"proofValue": "zrqP9MFHdZuRfF8jeFm57dQsqGpsv2JNHjCUy1Vrm7QJqwyesYkVv3ewn2SyH6MMgvVWzhNUziBUwZtwGW7CkA81GTMPYBb2ubKvMTXqhq2kwVwbC1oSEECevDHuhxdGqHaY"
}
}
As far as I can easily test myself, i.e. only rdfc tests and no interoperability with third party, everything should work.