Skip to content

Commit

Permalink
Fix: Fixed the SD-JWT sign callback and added extra DCQL test
Browse files Browse the repository at this point in the history
  • Loading branch information
zoemaas committed Jan 3, 2025
1 parent e5a1854 commit 1c2838f
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 13 deletions.
71 changes: 69 additions & 2 deletions packages/siop-oid4vp/lib/__tests__/SdJwt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,11 +437,78 @@ describe('RP and OP interaction should', () => {
const verifiedAuthReqWithJWT = await op.verifyAuthorizationRequest(parsedAuthReqURI.requestObjectJwt)
expect(verifiedAuthReqWithJWT.issuer).toMatch(rpMockEntity.did)

// FIXME kb-sd-jwts are not working with pex, so the presentation was not added to getVCs(...)
const dcqlCredentials: DcqlCredentialRepresentation[] = [KB_SD_JWT_PRESENTATION].map(vc => ({ claims: decodeSdJwtVc(vc as string, defaultHasher).decodedPayload as { [x: string]: Json } }))
// The KB property is added to the JWT when the presentation is signed. Passing a VC will make the test fail
const dcqlCredentials: DcqlCredentialRepresentation[] = [KB_SD_JWT_PRESENTATION].map(vc => ({ claims: decodeSdJwtVc(vc as string, defaultHasher).decodedPayload as { [x: string]: Json }, vct: decodeSdJwtVc(vc as string, defaultHasher).decodedPayload.vct } ))

const queryResult = DcqlQuery.query(sdJwtVcQuery, dcqlCredentials)

expect(queryResult).toEqual({
"canBeSatisfied": true,
"credential_matches": {
"my_credential": {
"all": [
[
{
"credential_index": 0,
"output": {
"claims": {
"license": {
"number": 10
},
"user": {
"name": "John"
}
},
"vct": "https://high-assurance.com/StateBusinessLicense"
},
"success": true,
"typed": true
}
]
],
"credential_index": 0,
"output": {
"claims": {
"license": {
"number": 10
},
"user": {
"name": "John"
}
},
"vct": "https://high-assurance.com/StateBusinessLicense"
},
"success": true,
"typed": true
}
},
"credentials": [
{
"claims": [
{
"path": [
"license",
"number"
]
},
{
"path": [
"user",
"name"
]
}
],
"format": "vc+sd-jwt",
"id": "my_credential",
"meta": {
"vct_values": [
"https://high-assurance.com/StateBusinessLicense"
]
}
}
]
})

const encodedPresentationRecord: { [x: string]: string | { [x: string]: Json } } = {}

for (const [key, _] of Object.entries(queryResult.credential_matches)) {
Expand Down
61 changes: 50 additions & 11 deletions packages/siop-oid4vp/lib/__tests__/TestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// @ts-ignore
import crypto, { createHash } from 'crypto'

import { digest, ES256, generateSalt } from '@sd-jwt/crypto-nodejs'
import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc'
import { JwtPayload, parseJWT, SigningAlgo, uuidv4 } from '@sphereon/oid4vc-common'
import { PartialSdJwtDecodedVerifiableCredential } from '@sphereon/pex/dist/main/lib'
import { IProofType } from '@sphereon/ssi-types'
import { IProofType, SdJwtVcKbJwtPayload } from '@sphereon/ssi-types'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import base58 from 'bs58'
Expand All @@ -26,7 +28,7 @@ import {
RPRegistrationMetadataPayload,
Scope,
SubjectSyntaxTypesSupportedValues,
SubjectType,
SubjectType
} from '../'
import SIOPErrors from '../types/Errors'

Expand All @@ -38,9 +40,10 @@ import {
VERIFIER_NAME_FOR_CLIENT,
VERIFIER_NAME_FOR_CLIENT_NL,
VERIFIERZ_PURPOSE_TO_VERIFY,
VERIFIERZ_PURPOSE_TO_VERIFY_NL,
VERIFIERZ_PURPOSE_TO_VERIFY_NL
} from './data/mockedData'


export interface TESTKEY {
key: JWK
did: string
Expand Down Expand Up @@ -303,15 +306,51 @@ export const sdJwtVcPresentationSignCallback: PresentationSignCallback = async (
},
})

const header = {
...presentation.kbJwt.header,
alg: 'ES256K',
const createSignerVerifier = async () => {
const { privateKey, publicKey } = await ES256.generateKeyPair();
return {
signer: await ES256.getSigner(privateKey),
verifier: await ES256.getVerifier(publicKey)
}
}
const payload = {
...presentation.kbJwt.payload,
aud: '123',

const { signer, verifier } = await createSignerVerifier();

const sdjwt = new SDJwtVcInstance({
signer,
signAlg: ES256.alg,
verifier,
hasher: digest,
saltGenerator: generateSalt,
kbSigner: signer,
kbSignAlg: ES256.alg,
kbVerifier: verifier
})

const claims = {
license: {
number: 10
},
user: {
name: 'John',
date_of_birth: '01/01/1970'
}
}

const kbJwtCompact = `${Buffer.from(JSON.stringify(header)).toString('base64url')}.${Buffer.from(JSON.stringify(payload)).toString('base64url')}.signature`
return presentation.compactSdJwtVc + kbJwtCompact
const kbPayload: Omit<SdJwtVcKbJwtPayload, 'sd_hash'> = presentation.kbJwt.payload

presentation.compactSdJwtVc = await sdjwt.present<typeof claims>(
presentation.compactSdJwtVc,
{
user: { name: true },
license: { number: true }
},
{
kb: {
payload: kbPayload,
},
},
);

return presentation.compactSdJwtVc
}
3 changes: 3 additions & 0 deletions packages/siop-oid4vp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
"@digitalcredentials/ed25519-signature-2020": "^3.0.2",
"@digitalcredentials/jsonld-signatures": "^9.3.2",
"@digitalcredentials/vc": "^6.0.0",
"@sd-jwt/crypto-nodejs": "0.7.2",
"@sd-jwt/sd-jwt-vc": "0.7.2",
"@sd-jwt/types": "0.7.2",
"@sphereon/wellknown-dids-client": "^0.1.3",
"@sphereon/did-uni-client": "^0.6.2",
"@transmute/did-key-ed25519": "^0.3.0-unstable.10",
Expand Down
46 changes: 46 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1c2838f

Please sign in to comment.