Skip to content

Commit 4299533

Browse files
Johan SellströmJohan Sellström
authored andcommitted
Use x509 wallet verifier client ID scheme
1 parent 6ffd86c commit 4299533

4 files changed

Lines changed: 22 additions & 14 deletions

File tree

STATUS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
- [x] Add the missing `client_id_scheme=pre-registered` fields to the wallet verifier flow
44
- [x] Verify the wallet verifier request shape locally with tests
55
- [x] Redeploy the public verifier and confirm the live wallet request JWT includes the preregistered client ID scheme
6+
- [x] Switch the public wallet verifier flow to the x509 SAN DNS client ID scheme for wallet compatibility
7+
- [x] Verify the x509 wallet verifier request shape locally with tests
8+
- [x] Redeploy the public verifier and confirm the live wallet request JWT uses x509 SAN DNS with the existing x5c certificate
69

710
- [x] Add a local demo-conductor package for the Village speed-build presentation
811
- [x] Verify the demo-conductor build and unit tests locally

verifier/src/wallet-rp.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ const SESSION_TTL_MS = 15 * 60_000
55
const QR_SIZE = 280
66
const EUDI_PID_VCTS = ['urn:eudi:pid:1']
77
const LAB_AGE_VCTS = ['https://example.org/vct/age-credential']
8-
const PREREGISTERED_CLIENT_ID_SCHEME = 'pre-registered'
8+
const X509_SAN_DNS_CLIENT_ID_SCHEME = 'x509_san_dns'
99

1010
export type WalletVerifierProfile = {
1111
baseUrl: string
1212
clientId: string
13+
requestClientId: string
1314
legalName: string
1415
}
1516

@@ -36,6 +37,7 @@ export type WalletRpSession = {
3637
state: string
3738
nonce: string
3839
clientId: string
40+
requestClientId: string
3941
legalName: string
4042
verifierApi: string
4143
requestUri: string
@@ -56,7 +58,7 @@ export type WalletDirectPostBody = {
5658

5759
export type WalletRequestObject = {
5860
client_id: string
59-
client_id_scheme: 'pre-registered'
61+
client_id_scheme: 'x509_san_dns'
6062
response_uri: string
6163
response_type: 'vp_token'
6264
response_mode: 'direct_post'
@@ -89,6 +91,7 @@ export function deriveWalletVerifierProfile(baseUrl: string): WalletVerifierProf
8991
return {
9092
baseUrl: url.origin,
9193
clientId: url.host,
94+
requestClientId: `${X509_SAN_DNS_CLIENT_ID_SCHEME}:${url.host}`,
9295
legalName: 'iProov Verifier'
9396
}
9497
}
@@ -108,24 +111,25 @@ export function createWalletSession(baseUrl: string, now = Date.now()): WalletRp
108111
state,
109112
nonce,
110113
clientId: profile.clientId,
114+
requestClientId: profile.requestClientId,
111115
legalName: profile.legalName,
112116
verifierApi: profile.baseUrl,
113117
requestUri,
114118
responseUri,
115119
resultUri,
116-
deepLink: buildWalletDeepLink(profile.clientId, requestUri),
120+
deepLink: buildWalletDeepLink(profile.clientId, profile.requestClientId, requestUri),
117121
outcome: { status: 'pending' }
118122
}
119123
}
120124

121-
export function buildWalletDeepLink(clientId: string, requestUri: string) {
122-
return `eudi-openid4vp://${clientId}?client_id=${encodeURIComponent(clientId)}&client_id_scheme=${encodeURIComponent(PREREGISTERED_CLIENT_ID_SCHEME)}&request_uri=${encodeURIComponent(requestUri)}`
125+
export function buildWalletDeepLink(clientId: string, requestClientId: string, requestUri: string) {
126+
return `eudi-openid4vp://${clientId}?client_id=${encodeURIComponent(requestClientId)}&client_id_scheme=${encodeURIComponent(X509_SAN_DNS_CLIENT_ID_SCHEME)}&request_uri=${encodeURIComponent(requestUri)}`
123127
}
124128

125129
export function buildWalletRequestObject(session: WalletRpSession, walletNonce?: string): WalletRequestObject & { wallet_nonce?: string } {
126130
return {
127-
client_id: session.clientId,
128-
client_id_scheme: PREREGISTERED_CLIENT_ID_SCHEME,
131+
client_id: session.requestClientId,
132+
client_id_scheme: X509_SAN_DNS_CLIENT_ID_SCHEME,
129133
response_uri: session.responseUri,
130134
response_type: 'vp_token',
131135
response_mode: 'direct_post',

verifier/test/wallet-request-signing.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ test('wallet request signer embeds an x5c certificate for verifier.ipid.me', asy
2323
assert.match(certificate.subject, /CN=verifier\.ipid\.me/)
2424

2525
const verified = await jwtVerify(jwt, await importX509(pem, 'ES256'), {
26-
issuer: 'verifier.ipid.me',
26+
issuer: 'x509_san_dns:verifier.ipid.me',
2727
audience: WALLET_REQUEST_AUDIENCE
2828
})
2929

30-
assert.equal(verified.payload.client_id, 'verifier.ipid.me')
31-
assert.equal(verified.payload.client_id_scheme, 'pre-registered')
30+
assert.equal(verified.payload.client_id, 'x509_san_dns:verifier.ipid.me')
31+
assert.equal(verified.payload.client_id_scheme, 'x509_san_dns')
3232
assert.equal(verified.payload.response_mode, 'direct_post')
3333
})
3434

verifier/test/wallet-rp.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,27 @@ import {
77
normalizeWalletDirectPostBody
88
} from '../src/wallet-rp.ts'
99

10-
test('createWalletSession builds a preregistered deep link for the public verifier', () => {
10+
test('createWalletSession builds an x509 SAN DNS deep link for the public verifier', () => {
1111
const session = createWalletSession('https://verifier.ipid.me', Date.UTC(2026, 2, 23, 12, 0, 0))
1212

1313
assert.equal(session.clientId, 'verifier.ipid.me')
14+
assert.equal(session.requestClientId, 'x509_san_dns:verifier.ipid.me')
1415
assert.equal(session.legalName, 'iProov Verifier')
1516
assert.match(session.requestUri, /^https:\/\/verifier\.ipid\.me\/wallet\/request\.jwt\//)
1617
assert.match(session.responseUri, /^https:\/\/verifier\.ipid\.me\/wallet\/direct_post\//)
1718
assert.match(session.resultUri, /^https:\/\/verifier\.ipid\.me\/wallet\/session\//)
1819
assert.match(
1920
session.deepLink,
20-
/^eudi-openid4vp:\/\/verifier\.ipid\.me\?client_id=verifier\.ipid\.me&client_id_scheme=pre-registered&request_uri=https%3A%2F%2Fverifier\.ipid\.me%2Fwallet%2Frequest\.jwt%2F/
21+
/^eudi-openid4vp:\/\/verifier\.ipid\.me\?client_id=x509_san_dns%3Averifier\.ipid\.me&client_id_scheme=x509_san_dns&request_uri=https%3A%2F%2Fverifier\.ipid\.me%2Fwallet%2Frequest\.jwt%2F/
2122
)
2223
})
2324

2425
test('buildWalletRequestObject asks for over-21 plus nationality with a fallback credential', () => {
2526
const session = createWalletSession('https://verifier.ipid.me')
2627
const request = buildWalletRequestObject(session)
2728

28-
assert.equal(request.client_id, 'verifier.ipid.me')
29-
assert.equal(request.client_id_scheme, 'pre-registered')
29+
assert.equal(request.client_id, 'x509_san_dns:verifier.ipid.me')
30+
assert.equal(request.client_id_scheme, 'x509_san_dns')
3031
assert.equal(request.response_uri, session.responseUri)
3132
assert.equal(request.response_type, 'vp_token')
3233
assert.equal(request.response_mode, 'direct_post')

0 commit comments

Comments
 (0)