@bedrock/vc-delivery 7.18.1 → 7.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-2026 Digital Bazaar, Inc.
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc.
|
|
3
3
|
*/
|
|
4
4
|
import * as bedrock from '@bedrock/core';
|
|
5
5
|
import {
|
|
@@ -16,8 +16,6 @@ const VALIDATORS = {
|
|
|
16
16
|
presentationSubmission: null
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const VC_CONTEXT_2 = 'https://www.w3.org/ns/credentials/v2';
|
|
20
|
-
|
|
21
19
|
bedrock.events.on('bedrock.init', () => {
|
|
22
20
|
VALIDATORS.presentation = compile({schema: verifiablePresentationSchema()});
|
|
23
21
|
VALIDATORS.presentationSubmission = compile({
|
|
@@ -33,11 +31,14 @@ export async function parse({
|
|
|
33
31
|
const {
|
|
34
32
|
responseMode, parsed, protectedHeader,
|
|
35
33
|
recipientPublicJwk, recipientPublicJwkThumbprint,
|
|
36
|
-
vpTokenMediaType
|
|
34
|
+
vpTokenMediaType,
|
|
35
|
+
envelope, presentation, mdocOptions
|
|
37
36
|
} = await oid4vp.verifier.parseAuthorizationResponse({
|
|
38
37
|
body,
|
|
39
|
-
getDecryptParameters() {
|
|
40
|
-
return _getDecryptParameters({
|
|
38
|
+
getDecryptParameters({mdocOptions} = {}) {
|
|
39
|
+
return _getDecryptParameters({
|
|
40
|
+
exchange, clientProfileId, authorizationRequest, mdocOptions
|
|
41
|
+
});
|
|
41
42
|
},
|
|
42
43
|
authorizationRequest
|
|
43
44
|
});
|
|
@@ -48,22 +49,8 @@ export async function parse({
|
|
|
48
49
|
_validate(VALIDATORS.presentationSubmission, presentationSubmission);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
let presentation;
|
|
54
|
-
let envelope;
|
|
55
|
-
|
|
56
|
-
if(vpTokenMediaType !== 'application/vp') {
|
|
57
|
-
// `vp_token` contains some enveloped format
|
|
58
|
-
presentation = {
|
|
59
|
-
'@context': VC_CONTEXT_2,
|
|
60
|
-
id: `data:${vpTokenMediaType},${vpToken}`,
|
|
61
|
-
type: 'EnvelopedVerifiablePresentation'
|
|
62
|
-
};
|
|
63
|
-
envelope = {mediaType: vpTokenMediaType};
|
|
64
|
-
} else {
|
|
65
|
-
// simplest case: `vpToken` is a VP; validate it against basic schema
|
|
66
|
-
presentation = vpToken;
|
|
52
|
+
// validate `presentation` against basic schema
|
|
53
|
+
if(vpTokenMediaType === 'application/vp') {
|
|
67
54
|
_validate(VALIDATORS.presentation, presentation);
|
|
68
55
|
}
|
|
69
56
|
|
|
@@ -74,7 +61,8 @@ export async function parse({
|
|
|
74
61
|
envelope,
|
|
75
62
|
protectedHeader,
|
|
76
63
|
recipientPublicJwk,
|
|
77
|
-
recipientPublicJwkThumbprint
|
|
64
|
+
recipientPublicJwkThumbprint,
|
|
65
|
+
mdocOptions
|
|
78
66
|
};
|
|
79
67
|
} catch(cause) {
|
|
80
68
|
throw new BedrockError(
|
|
@@ -89,12 +77,28 @@ export async function parse({
|
|
|
89
77
|
}
|
|
90
78
|
}
|
|
91
79
|
|
|
92
|
-
function _getDecryptParameters({
|
|
80
|
+
function _getDecryptParameters({
|
|
81
|
+
exchange, clientProfileId, authorizationRequest, mdocOptions
|
|
82
|
+
}) {
|
|
93
83
|
// get private key agreement keys in JWT format
|
|
94
84
|
const {keyAgreementKeyPairs} = exchange.secrets?.oid4vp?.clientProfiles
|
|
95
85
|
?.[clientProfileId ?? 'default'] ?? {};
|
|
96
86
|
const keys = keyAgreementKeyPairs.map(({privateKeyJwk}) => privateKeyJwk);
|
|
97
|
-
|
|
87
|
+
|
|
88
|
+
// include decryption AAD info if `response_mode` calls for it
|
|
89
|
+
let getInfo;
|
|
90
|
+
if(authorizationRequest.response_mode === 'dc_api') {
|
|
91
|
+
// include `recipientPublicJwk` in expected mdoc handover
|
|
92
|
+
getInfo = ({recipientPublicJwk}) => {
|
|
93
|
+
const handover = {
|
|
94
|
+
...mdocOptions?.expectedHandover,
|
|
95
|
+
recipientPublicJwk
|
|
96
|
+
};
|
|
97
|
+
return oid4vp.mdl.encodeSessionTranscript({handover});
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {keys, getInfo};
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
function _validate(validator, data) {
|
package/lib/oid4/oid4vp.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-2026 Digital Bazaar, Inc.
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc.
|
|
3
3
|
*/
|
|
4
4
|
import * as bedrock from '@bedrock/core';
|
|
5
5
|
import {
|
|
@@ -199,52 +199,9 @@ export async function processAuthorizationResponse({req, clientProfileId}) {
|
|
|
199
199
|
expectedDomain = verifyPresentationOptions.domain;
|
|
200
200
|
|
|
201
201
|
const {envelope} = parseResponseResult;
|
|
202
|
-
if(
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
// generate `handover` for mdoc verification
|
|
206
|
-
let handover;
|
|
207
|
-
|
|
208
|
-
// common `handover` parameters:
|
|
209
|
-
const origin = authorizationRequest?.expected_origins?.[0] ??
|
|
210
|
-
new URL(authorizationRequest.response_uri).origin;
|
|
211
|
-
const nonce = authorizationRequest.nonce;
|
|
212
|
-
|
|
213
|
-
// `direct_post.jwt` => ISO18013-7 Annex B
|
|
214
|
-
// FIXME: same response mode is also used for OID4VP 1.0 with
|
|
215
|
-
// `OpenID4VPHandover` for non-Annex-B; this is not yet supported
|
|
216
|
-
// https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-invocation-via-redirects
|
|
217
|
-
const {responseMode} = parseResponseResult;
|
|
218
|
-
if(responseMode === 'direct_post.jwt') {
|
|
219
|
-
handover = {
|
|
220
|
-
type: 'AnnexBHandover',
|
|
221
|
-
// per ISO 18013-7 B the `mdocGeneratedNonce` is base64url-encoded
|
|
222
|
-
// and put into the `apu` protected header parameter, so parse that
|
|
223
|
-
// here and convert it to a UTF-8 string instead
|
|
224
|
-
mdocGeneratedNonce: Buffer
|
|
225
|
-
.from(parseResponseResult.protectedHeader?.apu ?? '', 'base64url')
|
|
226
|
-
.toString('utf8'),
|
|
227
|
-
clientId: authorizationRequest.client_id,
|
|
228
|
-
responseUri: authorizationRequest.response_uri,
|
|
229
|
-
verifierGeneratedNonce: nonce
|
|
230
|
-
};
|
|
231
|
-
} else if(responseMode === 'dc_api') {
|
|
232
|
-
// `dc_api` => ISO18013-7 Annex C
|
|
233
|
-
handover = {
|
|
234
|
-
type: 'dcapi',
|
|
235
|
-
origin,
|
|
236
|
-
nonce,
|
|
237
|
-
recipientPublicJwk: parseResponseResult.recipientPublicJwk
|
|
238
|
-
};
|
|
239
|
-
} else if(responseMode === 'dc_api.jwt') {
|
|
240
|
-
// `dc_api.jwt` => ISO18013-7 Annex D
|
|
241
|
-
handover = {
|
|
242
|
-
type: 'OpenID4VPDCAPIHandover',
|
|
243
|
-
origin,
|
|
244
|
-
nonce,
|
|
245
|
-
jwkThumbprint: parseResponseResult.recipientPublicJwkThumbprint
|
|
246
|
-
};
|
|
247
|
-
}
|
|
202
|
+
if(parseResponseResult?.mdocOptions) {
|
|
203
|
+
// get expected `handover` for mdoc verification
|
|
204
|
+
const {expectedHandover: handover} = parseResponseResult.mdocOptions;
|
|
248
205
|
|
|
249
206
|
// handle deprecated `mdl` option; `mdoc` is preferred
|
|
250
207
|
const mdocKey = envelope.mediaType === 'application/mdoc-vp-token' ?
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bedrock/vc-delivery",
|
|
3
|
-
"version": "7.18.
|
|
3
|
+
"version": "7.18.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bedrock Verifiable Credential Delivery",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@digitalbazaar/ed25519-signature-2020": "^5.4.0",
|
|
41
41
|
"@digitalbazaar/ezcap": "^4.1.0",
|
|
42
42
|
"@digitalbazaar/http-client": "^4.4.0",
|
|
43
|
-
"@digitalbazaar/oid4-client": "^5.
|
|
43
|
+
"@digitalbazaar/oid4-client": "^5.15.0",
|
|
44
44
|
"@digitalbazaar/vc": "^7.2.0",
|
|
45
45
|
"@digitalbazaar/webkms-client": "^14.2.0",
|
|
46
46
|
"assert-plus": "^1.0.0",
|
|
@@ -547,6 +547,8 @@ const oid4vpClientProfile = {
|
|
|
547
547
|
required: ['x5c'],
|
|
548
548
|
additionalProperties: false,
|
|
549
549
|
properties: {
|
|
550
|
+
// FIXME: consider adding `privateKeyJwk` as an alternative to using
|
|
551
|
+
// a zcap for a WebKMS key
|
|
550
552
|
x5c: {
|
|
551
553
|
type: 'array',
|
|
552
554
|
minItems: 1,
|
|
@@ -999,6 +1001,13 @@ export function openIdAuthorizationResponseBody() {
|
|
|
999
1001
|
not: {
|
|
1000
1002
|
required: ['presentation_submission', 'vp_token', 'state']
|
|
1001
1003
|
}
|
|
1004
|
+
}, {
|
|
1005
|
+
// for response_mode == 'dc_api'
|
|
1006
|
+
required: ['Response'],
|
|
1007
|
+
// cannot also use any other params
|
|
1008
|
+
not: {
|
|
1009
|
+
required: ['presentation_submission', 'vp_token', 'state']
|
|
1010
|
+
}
|
|
1002
1011
|
}],
|
|
1003
1012
|
properties: {
|
|
1004
1013
|
// is a JSON string in the x-www-form-urlencoded body
|
|
@@ -1027,6 +1036,10 @@ export function openIdAuthorizationResponseBody() {
|
|
|
1027
1036
|
// must be an encrypted JWT
|
|
1028
1037
|
type: 'string'
|
|
1029
1038
|
},
|
|
1039
|
+
Response: {
|
|
1040
|
+
// must be an HPKE encrypted mdoc device response (ISO 18013-7 Annex C)
|
|
1041
|
+
type: 'string'
|
|
1042
|
+
},
|
|
1030
1043
|
state: {
|
|
1031
1044
|
type: 'string'
|
|
1032
1045
|
}
|