Skip to content

Commit

Permalink
feat: Add JARM response support
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Oct 3, 2024
1 parent 078276d commit 8e9cb20
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 136 deletions.
8 changes: 4 additions & 4 deletions packages/ebsi-support/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
},
"dependencies": {
"@ethersproject/random": "^5.7.0",
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop-adapter": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/did-auth-siop-adapter": "0.16.1-unstable.122",
"@sphereon/pex": "5.0.0-unstable.10",
"@sphereon/pex-models": "^2.3.1",
"@sphereon/ssi-sdk-ext.did-resolver-ebsi": "0.24.1-unstable.134",
Expand Down Expand Up @@ -44,8 +44,8 @@
"xstate": "^4.38.3"
},
"devDependencies": {
"@sphereon/oid4vci-client": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-client": "0.16.1-unstable.122",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.kms-local": "0.24.1-unstable.134",
Expand Down
6 changes: 3 additions & 3 deletions packages/mdl-mdoc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/kmp-mdl-mdoc": "0.2.0-SNAPSHOT.22",
"@sphereon/pex": "5.0.0-unstable.10",
"@sphereon/pex-models": "^2.3.1",
Expand All @@ -35,8 +35,8 @@
"uuid": "^9.0.1"
},
"devDependencies": {
"@sphereon/oid4vci-client": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-client": "0.16.1-unstable.122",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.kms-local": "0.24.1-unstable.134",
Expand Down
4 changes: 2 additions & 2 deletions packages/oid4vci-holder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
},
"dependencies": {
"@sphereon/kmp-mdl-mdoc": "0.2.0-SNAPSHOT.22",
"@sphereon/oid4vci-client": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-client": "0.16.1-unstable.122",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.jwt-service": "0.24.1-unstable.134",
Expand Down
6 changes: 3 additions & 3 deletions packages/oid4vci-issuer-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"start:dev": "ts-node __tests__/RestAPI.ts"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-issuer": "0.16.1-unstable.105",
"@sphereon/oid4vci-issuer-server": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/oid4vci-issuer": "0.16.1-unstable.122",
"@sphereon/oid4vci-issuer-server": "0.16.1-unstable.122",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-unstable.134",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-rest-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"generate-plugin-schema": "ts-node ../../packages/dev/bin/sphereon.js dev generate-plugin-schema"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/ssi-types": "workspace:*",
"@veramo/core": "4.2.0",
"cross-fetch": "^3.1.8"
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-unstable.134",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions packages/oid4vci-issuer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-unstable.105",
"@sphereon/oid4vci-issuer": "0.16.1-unstable.105",
"@sphereon/oid4vci-common": "0.16.1-unstable.122",
"@sphereon/oid4vci-issuer": "0.16.1-unstable.122",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-unstable.134",
"@sphereon/ssi-sdk.agent-config": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/siopv2-oid4vp-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"access": "public"
},
"dependencies": {
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-types": "workspace:*",
"uint8arrays": "3.1.1"
Expand Down
6 changes: 3 additions & 3 deletions packages/siopv2-oid4vp-op-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop-adapter": "0.16.1-unstable.105",
"@sphereon/oid4vc-common": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/did-auth-siop-adapter": "0.16.1-unstable.122",
"@sphereon/oid4vc-common": "0.16.1-unstable.122",
"@sphereon/pex": "5.0.0-unstable.10",
"@sphereon/pex-models": "^2.3.1",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-unstable.134",
Expand Down
106 changes: 84 additions & 22 deletions packages/siopv2-oid4vp-op-auth/src/session/OpSession.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
import {
AuthorizationResponsePayload,
JwksMetadataParams,
OP,
PresentationDefinitionWithLocation,
PresentationExchangeResponseOpts,
PresentationVerificationResult,
RequestObjectPayload,
ResponseIss,
SupportedVersion,
URI,
Verification,
VerifiedAuthorizationRequest,
VerifiedAuthorizationRequest
} from '@sphereon/did-auth-siop'
import { PresentationVerificationResult } from '@sphereon/did-auth-siop'
import { ResolveOpts } from '@sphereon/did-auth-siop-adapter'
import { JwtIssuer } from '@sphereon/oid4vc-common'
import { getAgentDIDMethods, getAgentResolver } from '@sphereon/ssi-sdk-ext.did-utils'
import { CompactSdJwtVc, W3CVerifiablePresentation, CredentialMapper, PresentationSubmission, parseDid } from '@sphereon/ssi-types'
import { encodeBase64url } from '@sphereon/ssi-sdk.core'
import {
CompactSdJwtVc,
CredentialMapper,
parseDid,
PresentationSubmission,
W3CVerifiablePresentation
} from '@sphereon/ssi-types'
import { IIdentifier, IVerifyResult, TKeyType } from '@veramo/core'
import Debug from 'debug'
import { IOPOptions, IOpSessionArgs, IOpSessionGetOID4VPArgs, IOpsSendSiopAuthorizationResponseArgs, IRequiredContext } from '../types'
import { v4 } from 'uuid'
import {
IOPOptions,
IOpSessionArgs,
IOpSessionGetOID4VPArgs,
IOpsSendSiopAuthorizationResponseArgs,
IRequiredContext
} from '../types'
import { createOP } from './functions'
import { OID4VP } from './OID4VP'
import { ResolveOpts } from '@sphereon/did-auth-siop-adapter'

const debug = Debug(`sphereon:sdk:siop:op-session`)

Expand Down Expand Up @@ -112,7 +133,7 @@ export class OpSession {
debug(`agent methods supported: ${JSON.stringify(agentMethods)}`)
const authReq = await this.getAuthorizationRequest()
const subjectSyntaxTypesSupported = authReq.registrationMetadataPayload?.subject_syntax_types_supported?.map((method) =>
convertDidMethod(method, opts.didPrefix),
convertDidMethod(method, opts.didPrefix)
)
debug(`subject syntax types supported in rp method supported: ${JSON.stringify(subjectSyntaxTypesSupported)}`)
const aud = await authReq.authorizationRequest.getMergedProperty<string>('aud')
Expand All @@ -134,7 +155,7 @@ export class OpSession {
rpMethods = [didMethod]
} else if (subjectSyntaxTypesSupported) {
rpMethods = (Array.isArray(subjectSyntaxTypesSupported) ? subjectSyntaxTypesSupported : [subjectSyntaxTypesSupported]).map((method) =>
convertDidMethod(method, opts.didPrefix),
convertDidMethod(method, opts.didPrefix)
)
}
const isEBSI =
Expand Down Expand Up @@ -169,11 +190,11 @@ export class OpSession {
if (opts?.createInCaseNoDIDFound !== false) {
const { codecName, keyType } = await this.getRPDIDMethodsSupported({
didPrefix: true,
agentMethods: methods,
agentMethods: methods
})
const identifier = await this.context.agent.didManagerCreate({
provider: methods[0],
options: { codecName, keyType, type: keyType }, // both keyType and type, because not every did provider has the same param
options: { codecName, keyType, type: keyType } // both keyType and type, because not every did provider has the same param
})
debug(`Created a new identifier for the SIOP interaction: ${identifier.did}`)
identifiers.push(identifier)
Expand Down Expand Up @@ -210,20 +231,20 @@ export class OpSession {
private createPresentationVerificationCallback(context: IRequiredContext) {
async function presentationVerificationCallback(
args: W3CVerifiablePresentation | CompactSdJwtVc,
presentationSubmission: PresentationSubmission,
presentationSubmission: PresentationSubmission
): Promise<PresentationVerificationResult> {
let result: IVerifyResult
if (CredentialMapper.isSdJwtEncoded(args)) {
try {
const sdJwtResult = await context.agent.verifySdJwtPresentation({ presentation: args })
result = {
verified: 'header' in sdJwtResult,
error: 'header' in sdJwtResult ? undefined : { message: 'could not verify SD JWT presentation' },
error: 'header' in sdJwtResult ? undefined : { message: 'could not verify SD JWT presentation' }
}
} catch (error: any) {
result = {
verified: false,
error: { message: error.message },
error: { message: error.message }
}
}
} else {
Expand All @@ -236,20 +257,60 @@ export class OpSession {
return presentationVerificationCallback
}

private async createJarmResponseCallback({ responseOpts }: {
responseOpts: {
jwtIssuer?: JwtIssuer
version?: SupportedVersion
correlationId?: string
audience?: string
issuer?: ResponseIss | string
verification?: Verification
}
}) {
const agent = this.context.agent
return async function jarmResponse(opts: {
authorizationResponsePayload: AuthorizationResponsePayload
requestObjectPayload: RequestObjectPayload
clientMetadata: JwksMetadataParams
}): Promise<{ response: string }> {
const { clientMetadata, authorizationResponsePayload: authResponse } = opts
const jwk = await OP.extractEncJwksFromClientMetadata(clientMetadata)
// @ts-ignore // FIXME: Fix jwk inference
const recipientKey = await agent.identifierExternalResolveByJwk({ identifier: jwk })

return await agent.jwtEncryptJweCompactJwt({
recipientKey,
protectedHeader: {},
//FIXME. Get from metadata
alg: 'ECDH-ES',
enc: 'A256GCM',
apv: encodeBase64url(opts.requestObjectPayload.nonce),
apu: encodeBase64url(v4()),
payload: authResponse,
issuer: responseOpts.issuer,
audience: responseOpts.audience
}).then(result => {
return { response: result.jwt }
})

}
}


public async sendAuthorizationResponse(args: IOpsSendSiopAuthorizationResponseArgs): Promise<Response> {
const resolveOpts: ResolveOpts = this.options.resolveOpts ?? {
resolver: getAgentResolver(this.context, {
uniresolverResolution: true,
localResolution: true,
resolverResolution: true,
}),
resolverResolution: true
})
}
if (!resolveOpts.subjectSyntaxTypesSupported || resolveOpts.subjectSyntaxTypesSupported.length === 0) {
resolveOpts.subjectSyntaxTypesSupported = await this.getSupportedDIDMethods(true)
}
//todo: populate with the right verification params. In did-auth-siop we don't have any test that actually passes this parameter
const verification: Verification = {
presentationVerificationCallback: this.createPresentationVerificationCallback(this.context),
presentationVerificationCallback: this.createPresentationVerificationCallback(this.context)
}

const request = await this.getAuthorizationRequest()
Expand All @@ -261,7 +322,7 @@ export class OpSession {
args.verifiablePresentations.length !== request.presentationDefinitions.length
) {
throw Error(
`Amount of presentations ${args.verifiablePresentations?.length}, doesn't match expected ${request.presentationDefinitions?.length}`,
`Amount of presentations ${args.verifiablePresentations?.length}, doesn't match expected ${request.presentationDefinitions?.length}`
)
} else if (!args.presentationSubmission) {
throw Error(`Presentation submission is required when verifiable presentations are required`)
Expand All @@ -278,10 +339,10 @@ export class OpSession {
eventEmitter: this.options.eventEmitter,
presentationSignCallback: this.options.presentationSignCallback,
wellknownDIDVerifyCallback: this.options.wellknownDIDVerifyCallback,
supportedVersions: request.versions,
supportedVersions: request.versions
},
idOpts: args.responseSignerOpts,
context: this.context,
context: this.context
})

//TODO change this to use the new functionalities by identifier-resolver and get the jwkIssuer for the responseOpts
Expand All @@ -292,13 +353,14 @@ export class OpSession {
...(args.verifiablePresentations && {
presentationExchange: {
verifiablePresentations,
presentationSubmission: args.presentationSubmission,
} as PresentationExchangeResponseOpts,
}),
presentationSubmission: args.presentationSubmission
} as PresentationExchangeResponseOpts
})
}

const authResponse = await op.createAuthorizationResponse(request, responseOpts)
const response = await op.submitAuthorizationResponse(authResponse)
const response = await op.submitAuthorizationResponse(authResponse, await this.createJarmResponseCallback({ responseOpts })
)

if (response.status >= 400) {
throw Error(`Error ${response.status}: ${response.statusText || (await response.text())}`)
Expand Down
6 changes: 3 additions & 3 deletions packages/siopv2-oid4vp-rp-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop-adapter": "0.16.1-unstable.105",
"@sphereon/oid4vc-common": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/did-auth-siop-adapter": "0.16.1-unstable.122",
"@sphereon/oid4vc-common": "0.16.1-unstable.122",
"@sphereon/pex": "5.0.0-unstable.10",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-unstable.134",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-unstable.134",
Expand Down
2 changes: 1 addition & 1 deletion packages/siopv2-oid4vp-rp-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"start:dev": "ts-node __tests__/RestAPI.ts"
},
"dependencies": {
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/w3c-vc-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"start:dev": "ts-node __tests__/agent.ts"
},
"dependencies": {
"@sphereon/did-auth-siop": "0.16.1-unstable.105",
"@sphereon/did-auth-siop": "0.16.1-unstable.122",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk.agent-config": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
Expand Down
Loading

0 comments on commit 8e9cb20

Please sign in to comment.