Skip to content

Commit

Permalink
chore: Resolve the OID Federation metadata oid4vp
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoe Maas committed Nov 25, 2024
1 parent 60f5f3c commit 2f91ee2
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 11 deletions.
34 changes: 27 additions & 7 deletions packages/siop-oid4vp/lib/authorization-request/URI.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { parseJWT } from '@sphereon/oid4vc-common'
import { FederationClient, TrustChainResolveResponse } from '@sphereon/openid-federation-client'

import { PresentationExchange } from '../authorization-response/PresentationExchange'
import { decodeUriAsJson, encodeJsonAsURI, fetchByReferenceOrUseByValue } from '../helpers'
Expand Down Expand Up @@ -126,7 +127,6 @@ export class URI implements AuthorizationRequestURI {
...authorizationRequest.options.requestObject,
version: authorizationRequest.options.version,
uriScheme: authorizationRequest.options.uriScheme,

},
authorizationRequest.payload,
authorizationRequest.requestObject,
Expand Down Expand Up @@ -194,7 +194,8 @@ export class URI implements AuthorizationRequestURI {
}
} else {
try {
scheme = (await authorizationRequest.getSupportedVersion()) === SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1 ? 'openid-vc://' : 'openid4vp://'
scheme =
(await authorizationRequest.getSupportedVersion()) === SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1 ? 'openid-vc://' : 'openid4vp://'
} catch (error: unknown) {
scheme = 'openid4vp://'
}
Expand Down Expand Up @@ -235,16 +236,35 @@ export class URI implements AuthorizationRequestURI {
return { scheme, authorizationRequestPayload }
}

public static async parseAndResolve(uri: string) {
public static async parseAndResolve(uri: string, trustChain?: Array<string>) {
if (!uri) {
throw Error(SIOPErrors.BAD_PARAMS)
}
const { authorizationRequestPayload, scheme } = this.parse(uri)

const requestObjectJwt = await fetchByReferenceOrUseByValue(authorizationRequestPayload.request_uri, authorizationRequestPayload.request, true)
const registrationMetadata: RPRegistrationMetadataPayload = await fetchByReferenceOrUseByValue(
authorizationRequestPayload['client_metadata_uri'] ?? authorizationRequestPayload['registration_uri'],
authorizationRequestPayload['client_metadata'] ?? authorizationRequestPayload['registration'],
)
let registrationMetadata: RPRegistrationMetadataPayload
if (trustChain !== undefined && trustChain !== null) {
const fedClient = new FederationClient(null, null)
const resolvedTrustChain: TrustChainResolveResponse = await fedClient.resolveTrustChain(
authorizationRequestPayload['client_metadata_uri'],
trustChain,
)
if (resolvedTrustChain !== null && resolvedTrustChain !== undefined) {
const clientMetadata = resolvedTrustChain.trustChain.asJsReadonlyArrayView()[1]
const subordinateStatement = JSON.parse(Buffer.from(clientMetadata.split('.')[1]).toString('base64url'))
registrationMetadata = {}
registrationMetadata.federation_entity = subordinateStatement.federationEntity
registrationMetadata.openid_credential_verifier = subordinateStatement.openIdRelyingParty
} else {
throw new Error('Cannot resolve OID Federation metadata')
}
} else {
registrationMetadata = await fetchByReferenceOrUseByValue(
authorizationRequestPayload['client_metadata_uri'] ?? authorizationRequestPayload['registration_uri'],
authorizationRequestPayload['client_metadata'] ?? authorizationRequestPayload['registration'],
)
}
assertValidRPRegistrationMedataPayload(registrationMetadata)
return { scheme, authorizationRequestPayload, requestObjectJwt, registrationMetadata }
}
Expand Down
4 changes: 3 additions & 1 deletion packages/siop-oid4vp/lib/op/OP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ import { createResponseOptsFromBuilderOrExistingOpts, createVerifyRequestOptsFro
export class OP {
private readonly _createResponseOptions: AuthorizationResponseOpts
private readonly _verifyRequestOptions: Partial<VerifyAuthorizationRequestOpts>
private readonly _trustChain: Array<string>
private readonly _eventEmitter?: EventEmitter

private constructor(opts: { builder?: OPBuilder; responseOpts?: AuthorizationResponseOpts; verifyOpts?: VerifyAuthorizationRequestOpts }) {
this._trustChain = opts.builder?.trustChain
this._createResponseOptions = { ...createResponseOptsFromBuilderOrExistingOpts(opts) }
this._verifyRequestOptions = { ...createVerifyRequestOptsFromBuilderOrExistingOpts(opts) }
this._eventEmitter = opts.builder?.eventEmitter
Expand Down Expand Up @@ -276,7 +278,7 @@ export class OP {
* @param encodedUri
*/
public async parseAuthorizationRequestURI(encodedUri: string): Promise<ParsedAuthorizationRequestURI> {
const { scheme, requestObjectJwt, authorizationRequestPayload, registrationMetadata } = await URI.parseAndResolve(encodedUri)
const { scheme, requestObjectJwt, authorizationRequestPayload, registrationMetadata } = await URI.parseAndResolve(encodedUri, this._trustChain)

return {
encodedUri,
Expand Down
6 changes: 6 additions & 0 deletions packages/siop-oid4vp/lib/op/OPBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class OPBuilder {
createJwtCallback?: CreateJwtCallback
verifyJwtCallback?: VerifyJwtCallback
presentationSignCallback?: PresentationSignCallback
trustChain?: Array<string>
supportedVersions?: SupportedVersion[]
eventEmitter?: EventEmitter

Expand Down Expand Up @@ -94,6 +95,11 @@ export class OPBuilder {
return this
}

withTrustChain(trustChain: Array<string>): OPBuilder {
this.trustChain = trustChain
return this
}

withEventEmitter(eventEmitter?: EventEmitter): OPBuilder {
this.eventEmitter = eventEmitter ?? new EventEmitter()
return this
Expand Down
5 changes: 5 additions & 0 deletions packages/siop-oid4vp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@
"tsimp": "^2.0.11",
"typescript": "5.4.5"
},
"peerDependencies": {
"@sphereon/openid-federation-client": "^0.1.1-unstable.21e8440",
"@sphereon/openid-federation-common": "^0.1.1-unstable.21e8440",
"@sphereon/openid-federation-open-api": "^0.1.1-unstable.21e8440"
},
"resolutions": {
"isomorphic-webcrypto": "npm:@sphereon/isomorphic-webcrypto@^2.4.1-unstable.0",
"esline/**/strip-ansi": "6.0.1"
Expand Down
85 changes: 82 additions & 3 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 2f91ee2

Please sign in to comment.