openwallet-foundation / credo-ts

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

OID4VP ldp credential presentation failed #1895

Open Sshovon opened 2 months ago

Sshovon commented 2 months ago

I am trying to issue and verify a ldp credential using oid4vc module. The issuance part works and the holder is able to receive and store the credential. But during verification it fails to verify the presentation on the verifier end. Json-ld credential issuance and verification works perfectly which is quite similar format as ldp.
On the verifier end I get following error:

WARN: Error occurred during verification of presentation {
  "error": {
    "name": "CredoError",
    "message": "Presentation verification failed.",
    "stack": "CredoError: Presentation verification failed.\n    at /home/frcs/credo-playground/demo-openid/node_modules/@credo-ts/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierService.ts:529:17"
  }
}
WARN: [OID4VCI] Sending error response: {"error":"invalid_request","error_description":"The signature of the verifiable presentation is not valid"} {
  "error": {
    "name": "Error",
    "stack": "Error: The signature of the verifiable presentation is not valid\n    at /home/frcs/credo-playground/demo-openid/node_modules/@sphereon/did-auth-siop/src/authorization-response/PresentationExchange.ts:354:19\n    at Generator.throw (<anonymous>)\n    at rejected (/home/frcs/credo-playground/demo-openid/node_modules/@sphereon/did-auth-siop/dist/authorization-response/PresentationExchange.js:6:65)",
    "message": "The signature of the verifiable presentation is not valid"
  }
}

On the holder end I get following error:

/home/frcs/credo-playground/demo-openid/node_modules/@sphereon/did-auth-siop/dist/helpers/HttpUtils.js:5
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
                                                         ^
Error: {"error":"invalid_request","error_description":"The signature of the verifiable presentation is not valid"}
    at /home/frcs/credo-playground/demo-openid/node_modules/@sphereon/did-auth-siop/src/helpers/HttpUtils.ts:101:11
    at Generator.next (<anonymous>)
    at fulfilled (/home/frcs/credo-playground/demo-openid/node_modules/@sphereon/did-auth-siop/dist/helpers/HttpUtils.js:5:58)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
error Command failed with exit code 1.

When I accept the ldp credential offer on the holder end I get the following information from holder debugger which represents the credential I have received.

DEBUG: Full credential {
  "context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "https://openid4vc-issuer.com/credentials/UniversityDegreeCredentialLdp",
  "type": [
    "VerifiableCredential",
    "UniversityDegreeCredential"
  ],
  "issuer": {
    "id": "did:key:z6MktiQQEqm2yapXBDt1WEVB3dqgvyzi96FuFANYmrgTrKV9"
  },
  "issuanceDate": "2024-06-10T02:33:13Z",
  "expirationDate": "2025-06-10T02:33:13Z",
  "credentialSubject": {
    "id": "did:key:z6MkpGR4gs4Rc3Zph4vj8wRnjnAxgAPSxcR8MAVKutWspQzc",
    "claims": {
      "university": "innsbruck",
      "degree": "bachelor"
    }
  },
  "proof": {
    "verificationMethod": "did:key:z6MktiQQEqm2yapXBDt1WEVB3dqgvyzi96FuFANYmrgTrKV9#z6MktiQQEqm2yapXBDt1WEVB3dqgvyzi96FuFANYmrgTrKV9",
    "type": "Ed25519Signature2018",
    "created": "2024-06-10T02:33:13Z",
    "proofPurpose": "assertionMethod",
    "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..xwGijpsjJJc8WEKcynuvNeykpgQrUl969beHGqIpUL4q-PhcEQbaoJe4Z1b9p7opTiUtHRIaqJ8nbAUwDa4MDA"
  }
}
Received and stored the following credentials.
W3cCredentialRecord with claim format ldp_vc

And I am using the following presentation definition for creating the presentation requests

const universityDegreeCredentialLdp = {
  id: 'UniversityDegreeCredentialLdp',
  purpose: 'Present your UniversityDegreeCredential to verify your education level.',
  input_descriptors: [
    {
      id: 'UniversityDegreeCredentialDescriptor',
      format: { ldp_vc: { proof_type: ['Ed25519Signature2018'] } },
      constraints: {
        fields: [{ 
          path: ['$.type.*', '$.vc.type'],
          filter: { type: 'string', pattern: 'UniversityDegreeCredential' }
        }],
      },
    },
  ],
}

I have tried different approaches to make this work but couldn't be able to do so. Please let me know if I am making any mistakes during the whole process or any possible solution for this situation.

TimoGlastra commented 2 months ago

I have to look into it more, but I'm not 100% weeks already support Json-LD verification in OID4VP. If you verify the credential using the w3c module separately, does it verify correctly?

Sshovon commented 2 months ago

I haven't explicitly verified the presentation using the W3C module, but after accepting the presentation on the holder's end, it is sent to the W3C module on the verifier's end.

During the verification process in w3cCredentialService.verifyPresentation the condition typeof options.presentation === 'string' evaluates to true and Consequently, the presentation is passed to w3cJwtCredentialService.verifyPresentation where the W3cJwtVerifiablePresentation.fromSerializedJwt(options.presentation) throws the error during creating jwt instance.
In Jwt.fromSerializedJwt() the condition gets true !Jwt.format.test(serializedJwt which throws the error on the verifier end.

I guess I also need to find if the holder is somehow parsing wrong data when sending the presentation.