digitalbazaar / jsonld.js

A JSON-LD Processor and API implementation in JavaScript
https://json-ld.org/
Other
1.65k stars 195 forks source link

Fix for issue with frame validation when type is `@json` #506

Closed pasquale95 closed 1 year ago

pasquale95 commented 1 year ago

Problem

The problem arises when we try to generate a derivedProof from a JSON-LD Credential by using a frameDocument (also called revealDocument) which wants to disclose a field whose type is defined as @json inside the credential context.

Use-case scenario

To explain better the issue let me draft a real use-case scenario where the problem arises. I own a VDL Credential which looks like the following:

{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/vdl/v1",
    "https://w3id.org/security/bbs/v1"
  ],
  "type": [
    "VerifiableCredential",
    "Iso18013DriversLicenseCredential"
  ],
  "credentialSubject": {
    "id": "did:key:z6MkiiViqftXJKZNnWwpS7aKM7jiJBbGiFEZzPSKYB8p8oyy",
    "license": {
      "type": "Iso18013DriversLicense",
      "document_number": "542426814",
      "family_name": "TURNER",
      "given_name": "SUSAN",
      "portrait": "/9j/4AAQSkZJRgABAQEAkACQA...gcdgck5HtRRSClooooP/2Q==",
      "birth_date": "1998-08-28",
      "issue_date": "2018-01-15T10:00:00Z",
      "expiry_date": "2022-08-27T12:00:00Z",
      "issuing_country": "US",
      "issuing_authority": "AL",
      "driving_privileges": [
        {
          "codes": [
            {
              "code": "D"
            }
          ],
          "vehicle_category_code": "D",
          "issue_date": "2019-01-01",
          "expiry_date": "2027-01-01"
        },
        {
          "codes": [
            {
              "code": "C"
            }
          ],
          "vehicle_category_code": "C",
          "issue_date": "2019-01-01",
          "expiry_date": "2017-01-01"
        }
      ],
      "un_distinguishing_sign": "USA"
    }
  },
  "proof": {
    "type": "BbsBlsSignature2020",
    "created": "2022-12-01T12:37:18Z",
    "proofPurpose": "assertionMethod",
    "proofValue": "qYbNq0bTdOa+XeHJ8+vQsdFFUOxF2crZMqJsMWvLyy+wLRMm5sNelzoqgJDrFMnfXjZlTy4XBKlOh0rdQtxKRE9VHeH50eYYrXIrcrbsOhYNEyp45kkFpaFgLT5diA71qYzVYhVrzt86NCr5oWHvkg==",
    "verificationMethod": "did:example:489398593#test"
  }
}

The verifier provides me the following frameDocument to disclose only some fields of the VDL Credential:

{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/vdl/v1",
    "https://w3id.org/security/bbs/v1"
  ],
  "type": ["VerifiableCredential", "Iso18013DriversLicenseCredential"],
  "credentialSubject": {
    "@explicit": true,
    "license": {
      "type": "Iso18013DriversLicense",
      "@explicit": true,
      "birth_date": {},
      "document_number": {},
      "expiry_date": {},
      "issuing_authority": {},
      "driving_privileges": {}
    }
  }
}

Among the requested fields there is the driving_privileges one which is defined as "@type": "@json" inside the VLD context (available here).

The goal is to produce a derivedProof containing the requested fields which performs correctly when verified.

Expected behaviour

The frame gets validated and used to produce a derivedProof as the following one:

{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/vdl/v1",
    "https://w3id.org/security/bbs/v1"
  ],
  "id": "urn:bnid:_:c14n0",
  "type": [
    "Iso18013DriversLicenseCredential",
    "VerifiableCredential"
  ],
  "credentialSubject": {
    "id": "did:key:z6MkiiViqftXJKZNnWwpS7aKM7jiJBbGiFEZzPSKYB8p8oyy",
    "license": {
      "id": "urn:bnid:_:c14n1",
      "type": "Iso18013DriversLicense",
      "birth_date": "1998-08-28",
      "document_number": "542426814",
      "driving_privileges": [
        {
          "codes": [
            {
              "code": "D"
            }
          ],
          "expiry_date": "2027-01-01",
          "issue_date": "2019-01-01",
          "vehicle_category_code": "D"
        },
        {
          "codes": [
            {
              "code": "C"
            }
          ],
          "expiry_date": "2017-01-01",
          "issue_date": "2019-01-01",
          "vehicle_category_code": "C"
        }
      ],
      "expiry_date": "2022-08-27T12:00:00Z",
      "issuing_authority": "AL"
    }
  },
  "proof": {
    "type": "BbsBlsSignatureProof2020",
    "created": "2022-12-01T12:43:45Z",
    "nonce": "hRg1hNhdBbsbQxTwK0ELyJh3kNtbMkTx42mLBi/An7IWZyDisVVy0b/u92dXqwCba7k=",
    "proofPurpose": "assertionMethod",
    "proofValue": "ABQBH/+3WRxSu8ebwOuHBjNFggw/oDwAfIlQqCBBa5mbjkVc6p+TvTLh+bv1HJ8eijLnNtSg+pgh2XEaxvdiKvkdVafJgYiWkLyIfdOsiBPPWiRTbXhjLE9klYQKWH8ZthU5Ub2JDLER/4A+oJ4CGP7jj0I+CPXt8SosYR+dUMMzd0rmFyyyDAMhZWh88TH3HUCY6bsAAAB0iw98nUtHdc5/cCIPrd9Dx3v+cj8vvJwHCbn9lYMx+p6TnIsF/6DbLErSpsqkO3NyAAAAAhKYEHO8iSQhQwCqaZECE3Y7YOPNZCGT7UfOIHwVCdwmDXaDb9CrtEp2sBRL3v5Ra9mskfkiN4KMh5vvj7XIAGm2Q2B3NmnNAlOYH5V0AoXVZzlFhNkGWsWsGHPD7dLplx8FYL8HO4VSp7SVf33///QAAAAIC17FayyxWRzFbxWQDf5AYtC0mOejFu1UdqdsxOKF19olrrRD17/a/HUQUNTTT0AlGGOLUSOLEvSFmk34l8wuoScNQkQulD81AiIy54c/lwfzLZ36h7VdnJUZeEGYpwVkcrPL/hebOpVjQoa+kLno0rMeAGywbBRPSPrM8eaHXhYy2t0FwXD89sqyYDQumxnomRHt5ZnG6bTwX7BNsm/KRkjkAfrAbYsaCqqK64lZRV8XL+2QQCPpxzZVWLaarh3aCAjWRr06CovvJzqtBTHz1eOWt+H7ld8RdBds3CWfG5RneUgOcfgyanGjjHoYRoyBdr1fWTA0NACrru+2TGQanQ==",
    "verificationMethod": "did:example:489398593#test"
  }
}

Actual behaviour

The process stops when validating the frame (i.e. before generating the derivedProof) complaining that the attribute driving_privileges has an invalid type @json:

JsonLdError [jsonld.SyntaxError]: Invalid JSON-LD syntax; invalid @type in frame.
    at _validateFrame (bbs/node_modules/jsonld/lib/frame.js:470:15)
    at _filterSubject (bbs/node_modules/jsonld/lib/frame.js:573:9)
    at _filterSubjects (bbs/node_modules/jsonld/lib/frame.js:493:8)
    at Object.api.frame (bbs/node_modules/jsonld/lib/frame.js:96:19)
    at Object.api.frame (bbs/node_modules/jsonld/lib/frame.js:258:15)
    at Object.api.frame (bbs/node_modules/jsonld/lib/frame.js:258:15)
    at api.frameMergedOrDefault (bbs/node_modules/jsonld/lib/frame.js:53:7)
    at Function.jsonld.frame (bbs/node_modules/jsonld/lib/jsonld.js:490:18)
    at async BbsBlsSignatureProof2020.deriveProof (bbs/node_modules/@mattrglobal/jsonld-signatures-bbs/lib/BbsBlsSignatureProof2020.js:106:38)
    at async exports.deriveProof (bbs/node_modules/@mattrglobal/jsonld-signatures-bbs/lib/deriveProof.js:48:20)

As the stack trace shows, the error is located inside this library, therefore our PR to try to solve this issue.

Our Solution

We added the type @json among the ones which can be considered valid in the frame validation. By doing this the process runs fine and the derivedProof is generated correctly (the one I've put inside the Expected Behaviour section has been generated once we applied the fix defined inside this PR.

I remind that the type @json is an official type as indicated in the JSON-LD specs.

pasquale95 commented 1 year ago

Hi, did somebody have a quick look to this PR? I didn't get any news and it's been 3 months. A comment would be appreciated.

davidlehn commented 1 year ago

I'm not clear on what the state of this issue is given the discussion in the spec repos, and there's an open issue on the single related test case. I haven't wrapped my head around the core issue enough to understand if the change here will have any side effects. I'm guessing it's probably ok though?

It would be good to have more test cases on tricky things like this. Simplify (greatly) the example here and in the ones in the spec repo discussions to test cases to ensure implementations are doing the right thing.

@gkellogg Is this change safe to merge in order to be a bit more correct?

pasquale95 commented 1 year ago

You can find the simplified examples inside the spec repo as 0069*.jsonld test files. Here the associated PR.

pasquale95 commented 1 year ago

@davidlehn, @gkellogg any update on this PR?

gkellogg commented 1 year ago

Sorry, been away. Does the suggested change in https://github.com/w3c/json-ld-framing/pull/146 work if you exclude "@type": "@json" from matching? Given the inherent issues with matching. If we decide to do this, it's appropriate to make a change here, but would be a substantive erratum against Framing, which can't really be merged until the WG process allows for this; if https://github.com/w3c/json-ld-framing/pull/146 depends on the change to the algorithm, it would also have to wait.

pasquale95 commented 1 year ago

Hi all, I've seen some commits in master from @davidlehn regarding the @json type. Do you support now framing over such type in JSON-LD?

davidlehn commented 1 year ago

@pasquale95 I did add a change (https://github.com/digitalbazaar/jsonld.js/commit/ffb62fcc3aed1d3949f96918ed32b05a85a48a9d) to ignore the related failing frame test 0069. That was just to keep the build systems working until this issue is resolved.

My comments above still stand. I'm unclear on what to do here. At a minimum, I suspect more test cases are needed to ensure a feature like this is properly working.

@gkellogg Should this be merged? It does fix the single test that's now in the test suite. But it seems from the above links that more work is needed for the feature?

davidlehn commented 1 year ago

I did a minor rework of the patch and applied it here: https://github.com/digitalbazaar/jsonld.js/pull/521.

I'm not quite sure if this is fully addressed. I still think more test cases are needed at least. But we'll release it and see if there are new issues. If the CG/WG works on this we'll adapt.

Thanks.