openwallet-foundation / credo-ts

Typescript framework for building decentralized identity and verifiable credential solutions
https://credo.js.org
Apache License 2.0
276 stars 202 forks source link

OID4VP: `submission` in `DifPexCredentialsForRequestRequirement` for `presentationDefinition`s with `pick` `submission_requirements` #1993

Closed DJHunn39 closed 3 months ago

DJHunn39 commented 3 months ago

Credo version: 0.5.9

tl;dr

Presentation definitions with pick requirements result in malformed presentationExchanges because of logic defined here, where getSubmissionRequirementRulePick assigns all satisfiedSubmissions to the submission property, instead of submissionEntry.

Description

I'm currently building an OID4VP presentation flow where the presentation definition has some submission_requirements. Here's what the presentation definition looks like:

{
    id: 'someId',
    purpose: 'Some purpose',
    submission_requirements: [
      {
        name: 'Some name',
        rule: 'pick',
        count: 1,
        from: 'someGroup'
      }
    ],
    input_descriptors: [
      {
        id: 'someInputDescriptorId',
        group: ['someGroup'],
        constraints: {
          limit_disclosure: 'required',
          fields: [
            {
              path: ['$.vct'],
              filter: {
                type: 'string',
                pattern: 'someType'
              }
            },
            {
              path: ['$.someDisclosedAttribute']
            }
          ]
        }
      },
      {
        id: 'someOtherInputDescriptorId',
        group: ['someGroup'],
        constraints: {
          limit_disclosure: 'required',
          fields: [
            {
              path: ['$.vct'],
              filter: {
                type: 'string',
                pattern: 'someOtherType'
              }
            },
            {
              path: ['$.someDisclosedAttribute']
            }
          ]
        }
      },
    ]
  }

The presentation request is built as expected, and can be resolved by a Holder agent, but the single requirement in resolvedPresentationRequest.presentationExchange.credentialsForRequest does not match the DifPexCredentialsForRequestRequirement type - what we would expect to be present under submissionEntry is actually found in the submission property, i.e:

{
    "requirements": [
        {
            "rule": "pick",
            "needsCount": 1,
            "name": "Some name",
            "submissionEntry": [], // This is empty
            "isRequirementSatisfied": true,
            "submission": [ // I'd expect this to be found under `submissionEntry`
                {
                    "inputDescriptorId": "SomeInputDescriptorId",
                    "verifiableCredentials": [
                        {
                            "type": "vc+sd-jwt",
                            "credentialRecord": {
                                "_tags": {
                                    "alg": "EdDSA",
                                    "sdAlg": "sha-256",
                                    "vct": "someType"
                                },
                                "metadata": {},
                                "id": "fcbcebd0-9577-4626-a2b3-730af7a89150",
                                "createdAt": "2024-08-05T15:08:59.583Z",
                                "compactSdJwtVc": "ey..........",
                                "updatedAt": "2024-08-05T15:08:59.583Z"
                            },
                            "disclosedPayload": {
                                "vct": "someType",
                                "exp": 1893456000000,
                                "validTo": 1893456000000,
                                "cnf": {
                                    "kid": "did:key:..."
                                },
                                "iss": "did:key:...",
                                "iat": 1722870539,
                                "someDisclosedAttribute": "someDisclosedValue",
                            }
                        },
                        {
                            "type": "vc+sd-jwt",
                            "credentialRecord": {
                                "_tags": {
                                    "alg": "EdDSA",
                                    "sdAlg": "sha-256",
                                    "vct": "someOtherType"
                                },
                                "metadata": {},
                                "id": "8aa3894c-c5e6-4344-896e-d872ff5dab17",
                                "createdAt": "2024-08-05T12:45:56.179Z",
                                "compactSdJwtVc": "ey........",
                                "updatedAt": "2024-08-05T12:45:56.179Z"
                            },
                            "disclosedPayload": {
                                "vct": "someOtherType",
                                "exp": 1754397955855,
                                "cnf": {
                                    "kid": "did:key:..."
                                },
                                "iss": "did:key:...",
                                "iat": 1722861955,
                                "someDisclosedAttribute":"someDisclosedValue"
                            }
                        }
                    ]
                }
            ]
        }
    ],
    "areRequirementsSatisfied": true,
    "purpose": "Some purpose"
}

This means that, for this type of presentationDefinition, presentationExchangeService.selectCredentialsForRequest cannot be used, as it leads to a No verifiable presentations created error, as selectCredentialsForRequest returns {}.

If I build my own selectCredentialsForRequest function, I need to adjust some types as Property 'submission' does not exist on type 'DifPexCredentialsForRequestRequirement'.

DJHunn39 commented 3 months ago

^ opened the above PR to cover the fix if it is as simple as changing that property from submission to submissionEntry