diff --git a/packages/openid4vc/package.json b/packages/openid4vc/package.json index 4bba471c05..09d3213fa9 100644 --- a/packages/openid4vc/package.json +++ b/packages/openid4vc/package.json @@ -33,7 +33,7 @@ "@sphereon/oid4vci-common": "0.16.1-fix.173", "@sphereon/oid4vci-issuer": "0.16.1-fix.173", "@sphereon/ssi-types": "0.30.2-next.135", - "@openid-federation/core": "0.1.1-alpha.12", + "@openid-federation/core": "0.1.1-alpha.13", "class-transformer": "^0.5.1", "rxjs": "^7.8.0" }, diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts index 754f029238..4b4db015d2 100644 --- a/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts @@ -11,6 +11,7 @@ import type { import type { OpenId4VcSiopAcceptAuthorizationRequestOptions, OpenId4VcSiopResolveAuthorizationRequestOptions, + OpenId4VcSiopResolveTrustChainsOptions, } from './OpenId4vcSiopHolderServiceOptions' import { injectable, AgentContext } from '@credo-ts/core' @@ -187,4 +188,8 @@ export class OpenId4VcHolderApi { public async sendNotification(options: OpenId4VciSendNotificationOptions) { return this.openId4VciHolderService.sendNotification(options) } + + public async resolveOpenIdFederationChains(options: OpenId4VcSiopResolveTrustChainsOptions) { + return this.openId4VcSiopHolderService.resolveOpenIdFederationChains(this.agentContext, options) + } } diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts index c111f30492..e46bed9a18 100644 --- a/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts @@ -871,6 +871,4 @@ export class OpenId4VciHolderService { return jws } } - - // TODO: Add a function for resolving the entity statement. Which will be used in the holder to verify the entity statement and to show to the user } diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts index 49cf592f7c..413824a8a8 100644 --- a/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts @@ -3,6 +3,7 @@ import type { OpenId4VcSiopGetOpenIdProviderOptions, OpenId4VcSiopResolveAuthorizationRequestOptions, OpenId4VcSiopResolvedAuthorizationRequest, + OpenId4VcSiopResolveTrustChainsOptions, } from './OpenId4vcSiopHolderServiceOptions' import type { OpenId4VcJwtIssuer, OpenId4VcJwtIssuerFederation } from '../shared' import type { AgentContext, JwkJson, VerifiablePresentation } from '@credo-ts/core' @@ -30,7 +31,10 @@ import { MdocDeviceResponse, JwsService, } from '@credo-ts/core' -import { fetchEntityConfiguration } from '@openid-federation/core' +import { + resolveTrustChains as federationResolveTrustChains, + fetchEntityConfiguration as federationFetchEntityConfiguration, +} from '@openid-federation/core' import { OP, ResponseIss, ResponseMode, ResponseType, SupportedVersion, VPTokenLocation } from '@sphereon/did-auth-siop' import { getSphereonVerifiablePresentation } from '../shared/transform' @@ -74,7 +78,7 @@ export class OpenId4VcSiopHolderService { const jwsService = agentContext.dependencyManager.resolve(JwsService) - const entityConfiguration = await fetchEntityConfiguration({ + const entityConfiguration = await federationFetchEntityConfiguration({ entityId: clientId, verifyJwtCallback: async ({ jwt, jwk }) => { const res = await jwsService.verifyJws(agentContext, { @@ -434,4 +438,26 @@ export class OpenId4VcSiopHolderService { return jwe } + + public async resolveOpenIdFederationChains( + agentContext: AgentContext, + options: OpenId4VcSiopResolveTrustChainsOptions + ) { + const jwsService = agentContext.dependencyManager.resolve(JwsService) + + const { entityId, trustAnchorEntityIds } = options + + return federationResolveTrustChains({ + entityId, + trustAnchorEntityIds, + verifyJwtCallback: async ({ jwt, jwk }) => { + const res = await jwsService.verifyJws(agentContext, { + jws: jwt, + jwkResolver: () => getJwkFromJson(jwk), + }) + + return res.isValid + }, + }) + } } diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts index 04aa764610..559e690210 100644 --- a/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts @@ -77,3 +77,8 @@ export interface OpenId4VcSiopGetOpenIdProviderOptions { trustedEntityIds?: string[] } } + +export interface OpenId4VcSiopResolveTrustChainsOptions { + entityId: string + trustAnchorEntityIds: [string, ...string[]] +} diff --git a/packages/openid4vc/src/shared/utils.ts b/packages/openid4vc/src/shared/utils.ts index 5eea5dd8bc..5c868f6732 100644 --- a/packages/openid4vc/src/shared/utils.ts +++ b/packages/openid4vc/src/shared/utils.ts @@ -105,9 +105,9 @@ export function getVerifyJwtCallback( } // Pick the first valid trust chain for validation of the leaf entity jwks - const { entityConfiguration } = validTrustChains[0] + const { leafEntityConfiguration } = validTrustChains[0] // TODO: No support yet for signed jwks and external jwks - const rpSigningKeys = entityConfiguration?.metadata?.openid_relying_party?.jwks?.keys + const rpSigningKeys = leafEntityConfiguration?.metadata?.openid_relying_party?.jwks?.keys if (!rpSigningKeys || rpSigningKeys.length === 0) throw new CredoError('No rp signing keys found in the entity configuration.') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1b08f440b..04f91bfb38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -693,8 +693,8 @@ importers: specifier: workspace:* version: link:../core '@openid-federation/core': - specifier: 0.1.1-alpha.12 - version: 0.1.1-alpha.12 + specifier: 0.1.1-alpha.13 + version: 0.1.1-alpha.13 '@sphereon/did-auth-siop': specifier: 0.16.1-fix.173 version: 0.16.1-fix.173(ts-node@10.9.2(@swc/core@1.7.40)(@types/node@18.18.8)(typescript@5.5.4))(typescript@5.5.4) @@ -2227,8 +2227,8 @@ packages: resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - '@openid-federation/core@0.1.1-alpha.12': - resolution: {integrity: sha512-pGEt0Zz0Y+l0mlayeT5oeHILd0XKmzfpgVJcKM/DgBYaMTa8MdEdVZj6GLpBIqZWHzxoJXM+DB6OeNi9EemAlQ==} + '@openid-federation/core@0.1.1-alpha.13': + resolution: {integrity: sha512-QC4DSbiJ7eWstLs1O3XrX/yKFgaj+3ch8cA4N/02BywVNmkiYgW9qXhcvY50ULINuCeYdqIMIqCuHbaTa0A1hw==} '@peculiar/asn1-cms@2.3.13': resolution: {integrity: sha512-joqu8A7KR2G85oLPq+vB+NFr2ro7Ls4ol13Zcse/giPSzUNN0n2k3v8kMpf6QdGUhI13e5SzQYN8AKP8sJ8v4w==} @@ -9809,7 +9809,7 @@ snapshots: dependencies: semver: 7.6.3 - '@openid-federation/core@0.1.1-alpha.12': + '@openid-federation/core@0.1.1-alpha.13': dependencies: buffer: 6.0.3 zod: 3.23.8