@openeudi/openid4vp 0.8.1 → 0.9.0

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.
package/dist/index.js CHANGED
@@ -126,10 +126,10 @@ var init_errors = __esm({
126
126
  code = "unsupported_jwe";
127
127
  alg;
128
128
  enc;
129
- constructor(alg, enc) {
130
- super(`Unsupported JWE algorithms: alg=${alg}, enc=${enc}`);
129
+ constructor(alg, enc3) {
130
+ super(`Unsupported JWE algorithms: alg=${alg}, enc=${enc3}`);
131
131
  this.alg = alg;
132
- this.enc = enc;
132
+ this.enc = enc3;
133
133
  }
134
134
  };
135
135
  DecryptionFailedError = class extends OpenID4VPError {
@@ -313,9 +313,9 @@ var init_index_es = __esm({
313
313
  static isBase64Url(data) {
314
314
  return typeof data === STRING_TYPE && BASE64URL_REGEX.test(data);
315
315
  }
316
- static ToString(buffer, enc = "utf8") {
316
+ static ToString(buffer, enc3 = "utf8") {
317
317
  const buf = BufferSourceConverter.toUint8Array(buffer);
318
- switch (enc.toLowerCase()) {
318
+ switch (enc3.toLowerCase()) {
319
319
  case "utf8":
320
320
  return this.ToUtf8String(buf);
321
321
  case "binary":
@@ -332,14 +332,14 @@ var init_index_es = __esm({
332
332
  case "utf16be":
333
333
  return Utf16Converter.toString(buf);
334
334
  default:
335
- throw new Error(`Unknown type of encoding '${enc}'`);
335
+ throw new Error(`Unknown type of encoding '${enc3}'`);
336
336
  }
337
337
  }
338
- static FromString(str, enc = "utf8") {
338
+ static FromString(str, enc3 = "utf8") {
339
339
  if (!str) {
340
340
  return new ArrayBuffer(0);
341
341
  }
342
- switch (enc.toLowerCase()) {
342
+ switch (enc3.toLowerCase()) {
343
343
  case "utf8":
344
344
  return this.FromUtf8String(str);
345
345
  case "binary":
@@ -356,7 +356,7 @@ var init_index_es = __esm({
356
356
  case "utf16be":
357
357
  return Utf16Converter.fromString(str);
358
358
  default:
359
- throw new Error(`Unknown type of encoding '${enc}'`);
359
+ throw new Error(`Unknown type of encoding '${enc3}'`);
360
360
  }
361
361
  }
362
362
  static ToBase64(buffer) {
@@ -8170,8 +8170,8 @@ async function createSignedAuthorizationRequest(input, query) {
8170
8170
  vp_formats_supported: input.vpFormatsSupported
8171
8171
  };
8172
8172
  if (responseMode === "direct_post.jwt" && input.encryptionKey) {
8173
- const enc = input.encryptionKey.supportedEncValues;
8174
- if (enc !== void 0 && enc.length === 0) {
8173
+ const enc3 = input.encryptionKey.supportedEncValues;
8174
+ if (enc3 !== void 0 && enc3.length === 0) {
8175
8175
  throw new SignedRequestBuildError(
8176
8176
  "empty_supported_enc_values",
8177
8177
  "encryptionKey.supportedEncValues must not be empty (omit to use defaults [A128GCM, A256GCM])"
@@ -8179,7 +8179,7 @@ async function createSignedAuthorizationRequest(input, query) {
8179
8179
  }
8180
8180
  const jwk = { ...input.encryptionKey.publicJwk, use: "enc" };
8181
8181
  clientMetadata.jwks = { keys: [jwk] };
8182
- const encValues = enc ?? [...DEFAULT_SUPPORTED_ENC_VALUES];
8182
+ const encValues = enc3 ?? [...DEFAULT_SUPPORTED_ENC_VALUES];
8183
8183
  clientMetadata.encrypted_response_enc_values_supported = encValues;
8184
8184
  clientMetadata.authorization_encrypted_response_alg = "ECDH-ES";
8185
8185
  clientMetadata.authorization_encrypted_response_enc = encValues[0];
@@ -8453,6 +8453,131 @@ async function verifyCoseSign1(coseSign1, publicKey, allowedAlgorithms) {
8453
8453
  }
8454
8454
  }
8455
8455
 
8456
+ // src/crypto/device-auth.ts
8457
+ init_errors();
8458
+ var enc = new Encoder({ mapsAsObjects: false, useRecords: false, tagUint8Array: false });
8459
+ var HEADER_ALG2 = 1;
8460
+ var COSE_ALG_TO_NAME2 = {
8461
+ [-7]: "ES256",
8462
+ [-35]: "ES384",
8463
+ [-36]: "ES512"
8464
+ };
8465
+ var ALG_TO_HASH2 = { ES256: "SHA-256", ES384: "SHA-384", ES512: "SHA-512" };
8466
+ var COSE_KEY_KTY = 1;
8467
+ var COSE_KEY_CRV = -1;
8468
+ var COSE_KEY_X = -2;
8469
+ var COSE_KEY_Y = -3;
8470
+ var COSE_KTY_EC2 = 2;
8471
+ var COSE_CRV_TO_JWK = { 1: "P-256", 2: "P-384", 3: "P-521" };
8472
+ function concatBytes(...chunks) {
8473
+ let len = 0;
8474
+ for (const c of chunks) len += c.length;
8475
+ const out = new Uint8Array(len);
8476
+ let off = 0;
8477
+ for (const c of chunks) {
8478
+ out.set(c, off);
8479
+ off += c.length;
8480
+ }
8481
+ return out;
8482
+ }
8483
+ function bytesToBase64Url(bytes) {
8484
+ let bin = "";
8485
+ for (const b of bytes) bin += String.fromCharCode(b);
8486
+ return globalThis.btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
8487
+ }
8488
+ function encodeTag24(inner) {
8489
+ return concatBytes(new Uint8Array([216, 24]), new Uint8Array(enc.encode(inner)));
8490
+ }
8491
+ function buildDeviceAuthenticationBytes(params) {
8492
+ const deviceAuthentication = concatBytes(
8493
+ new Uint8Array([132]),
8494
+ // array(4)
8495
+ new Uint8Array(enc.encode("DeviceAuthentication")),
8496
+ params.sessionTranscript,
8497
+ new Uint8Array(enc.encode(params.docType)),
8498
+ encodeTag24(params.deviceNameSpacesInner)
8499
+ );
8500
+ return encodeTag24(deviceAuthentication);
8501
+ }
8502
+ function encodeDeviceSigStructure(protectedBytes, deviceAuthBytes) {
8503
+ const sig = ["Signature1", protectedBytes, new Uint8Array(0), deviceAuthBytes];
8504
+ return new Uint8Array(enc.encode(sig));
8505
+ }
8506
+ async function importDeviceKeyFromCose(coseKey) {
8507
+ if (!(coseKey instanceof Map)) {
8508
+ throw new MalformedCredentialError("MSO deviceKeyInfo.deviceKey is not a COSE_Key map");
8509
+ }
8510
+ const kty = coseKey.get(COSE_KEY_KTY);
8511
+ if (kty !== COSE_KTY_EC2) {
8512
+ throw new MalformedCredentialError(`Unsupported COSE key type for device key: ${String(kty)}`);
8513
+ }
8514
+ const crv = coseKey.get(COSE_KEY_CRV);
8515
+ const crvName = typeof crv === "number" ? COSE_CRV_TO_JWK[crv] : void 0;
8516
+ const x = coseKey.get(COSE_KEY_X);
8517
+ const y = coseKey.get(COSE_KEY_Y);
8518
+ if (!crvName || !(x instanceof Uint8Array) || !(y instanceof Uint8Array)) {
8519
+ throw new MalformedCredentialError("Malformed EC2 COSE_Key in MSO deviceKeyInfo");
8520
+ }
8521
+ return crypto.subtle.importKey(
8522
+ "jwk",
8523
+ { kty: "EC", crv: crvName, x: bytesToBase64Url(x), y: bytesToBase64Url(y) },
8524
+ { name: "ECDSA", namedCurve: crvName },
8525
+ false,
8526
+ ["verify"]
8527
+ );
8528
+ }
8529
+ async function verifyDeviceAuth(params) {
8530
+ const { deviceSigned, deviceKeyCose, docType, sessionTranscript, allowedAlgorithms } = params;
8531
+ const deviceAuth = deviceSigned.get("deviceAuth");
8532
+ if (!(deviceAuth instanceof Map)) {
8533
+ throw new MalformedCredentialError("deviceSigned.deviceAuth is missing or malformed");
8534
+ }
8535
+ if (deviceAuth.has("deviceMac") && !deviceAuth.has("deviceSignature")) {
8536
+ throw new MalformedCredentialError("mDOC DeviceMac authentication is not supported");
8537
+ }
8538
+ const deviceSignature = deviceAuth.get("deviceSignature");
8539
+ if (!Array.isArray(deviceSignature) || deviceSignature.length !== 4) {
8540
+ throw new MalformedCredentialError("deviceAuth.deviceSignature must be a COSE_Sign1 array");
8541
+ }
8542
+ const protectedBytes = deviceSignature[0];
8543
+ const signature = deviceSignature[3];
8544
+ if (!(protectedBytes instanceof Uint8Array) || !(signature instanceof Uint8Array)) {
8545
+ throw new MalformedCredentialError("DeviceSignature protected header / signature must be byte strings");
8546
+ }
8547
+ let alg;
8548
+ try {
8549
+ const ph = enc.decode(protectedBytes);
8550
+ const label = ph instanceof Map ? ph.get(HEADER_ALG2) : void 0;
8551
+ alg = typeof label === "number" ? COSE_ALG_TO_NAME2[label] : void 0;
8552
+ } catch {
8553
+ throw new MalformedCredentialError("DeviceSignature protected header is not decodable CBOR");
8554
+ }
8555
+ if (!alg || !allowedAlgorithms.includes(alg)) {
8556
+ throw new MalformedCredentialError(`DeviceSignature uses a disallowed algorithm: ${String(alg)}`);
8557
+ }
8558
+ const deviceNameSpacesInner = extractTag24Inner(deviceSigned.get("nameSpaces"));
8559
+ const deviceAuthBytes = buildDeviceAuthenticationBytes({ sessionTranscript, docType, deviceNameSpacesInner });
8560
+ const sigInput = encodeDeviceSigStructure(protectedBytes, deviceAuthBytes);
8561
+ const deviceKey = await importDeviceKeyFromCose(deviceKeyCose);
8562
+ const ok = await crypto.subtle.verify(
8563
+ { name: "ECDSA", hash: ALG_TO_HASH2[alg] },
8564
+ deviceKey,
8565
+ new Uint8Array(signature),
8566
+ sigInput
8567
+ );
8568
+ if (!ok) {
8569
+ throw new MalformedCredentialError("mDOC device authentication (DeviceSignature) failed to verify");
8570
+ }
8571
+ }
8572
+ function extractTag24Inner(value) {
8573
+ if (value instanceof Uint8Array) return value;
8574
+ if (value !== null && typeof value === "object" && "value" in value && value.value instanceof Uint8Array && // Tag(24,bytes) and EmbeddedCbor both expose .value; both are fine here.
8575
+ ("tag" in value ? value.tag === 24 : true)) {
8576
+ return value.value;
8577
+ }
8578
+ throw new MalformedCredentialError("deviceSigned.nameSpaces must be tag-24 wrapped CBOR");
8579
+ }
8580
+
8456
8581
  // src/crypto/digest.ts
8457
8582
  init_errors();
8458
8583
  var decoder2 = new Encoder({ mapsAsObjects: false, useRecords: false });
@@ -8585,6 +8710,14 @@ function decodeMso(payload) {
8585
8710
  }
8586
8711
  valueDigests.set(ns, perNs);
8587
8712
  }
8713
+ let deviceKey;
8714
+ const dkiRaw = m.get("deviceKeyInfo");
8715
+ if (dkiRaw instanceof Map) {
8716
+ const dk = dkiRaw.get("deviceKey");
8717
+ if (dk instanceof Map) {
8718
+ deviceKey = dk;
8719
+ }
8720
+ }
8588
8721
  const viRaw = m.get("validityInfo");
8589
8722
  if (!(viRaw instanceof Map)) {
8590
8723
  throw new MalformedCredentialError("MSO.validityInfo must be a Map");
@@ -8598,7 +8731,7 @@ function decodeMso(payload) {
8598
8731
  if (vi.has("expectedUpdate")) {
8599
8732
  validityInfo.expectedUpdate = decodeDateLike(vi.get("expectedUpdate"));
8600
8733
  }
8601
- return { version, digestAlgorithm, valueDigests, docType, validityInfo };
8734
+ return { version, digestAlgorithm, valueDigests, docType, deviceKey, validityInfo };
8602
8735
  }
8603
8736
  function validateMsoValidity(mso, now) {
8604
8737
  const { signed, validFrom, validUntil } = mso.validityInfo;
@@ -8648,15 +8781,54 @@ ${lines.join("\n")}
8648
8781
  function extractCountryHintFromCert(_certDer) {
8649
8782
  return "";
8650
8783
  }
8784
+ function cborByteStringHeader(length) {
8785
+ if (length < 24) return Uint8Array.of(64 | length);
8786
+ if (length < 256) return Uint8Array.of(88, length);
8787
+ if (length < 65536) return Uint8Array.of(89, length >> 8 & 255, length & 255);
8788
+ if (length < 4294967296) {
8789
+ return Uint8Array.of(
8790
+ 90,
8791
+ length >>> 24 & 255,
8792
+ length >>> 16 & 255,
8793
+ length >>> 8 & 255,
8794
+ length & 255
8795
+ );
8796
+ }
8797
+ const hi = Math.floor(length / 4294967296);
8798
+ const lo = length >>> 0;
8799
+ return Uint8Array.of(
8800
+ 91,
8801
+ hi >>> 24 & 255,
8802
+ hi >>> 16 & 255,
8803
+ hi >>> 8 & 255,
8804
+ hi & 255,
8805
+ lo >>> 24 & 255,
8806
+ lo >>> 16 & 255,
8807
+ lo >>> 8 & 255,
8808
+ lo & 255
8809
+ );
8810
+ }
8811
+ function wrapIssuerSignedItemBytes(inner) {
8812
+ const header = cborByteStringHeader(inner.length);
8813
+ const out = new Uint8Array(2 + header.length + inner.length);
8814
+ out[0] = 216;
8815
+ out[1] = 24;
8816
+ out.set(header, 2);
8817
+ out.set(inner, 2 + header.length);
8818
+ return out;
8819
+ }
8651
8820
  function extractRawItemBytes(item) {
8652
8821
  if (item instanceof Tag && item.tag === 24 && item.value instanceof Uint8Array) {
8653
- return item.value;
8822
+ return wrapIssuerSignedItemBytes(item.value);
8654
8823
  }
8655
8824
  if (item instanceof Uint8Array) {
8656
- return item;
8825
+ if (item.length >= 2 && item[0] === 216 && item[1] === 24) {
8826
+ return item;
8827
+ }
8828
+ return wrapIssuerSignedItemBytes(item);
8657
8829
  }
8658
8830
  if (item !== null && typeof item === "object" && !(item instanceof Tag) && !(item instanceof Map) && "value" in item && item.value instanceof Uint8Array) {
8659
- return item.value;
8831
+ return wrapIssuerSignedItemBytes(item.value);
8660
8832
  }
8661
8833
  throw new MalformedCredentialError("IssuerSignedItem must be a tag-24 byte string");
8662
8834
  }
@@ -8846,6 +9018,54 @@ var MdocParser = class {
8846
9018
  nameSpaces.set(ns, items.map(extractRawItemBytes));
8847
9019
  }
8848
9020
  await verifyAllDigests(nameSpaces, mso);
9021
+ const deviceSigned = document.get("deviceSigned");
9022
+ if (!(deviceSigned instanceof Map)) {
9023
+ return {
9024
+ valid: false,
9025
+ format: this.format,
9026
+ claims: {},
9027
+ issuer: { certificate: issuerCertBytes, country: "" },
9028
+ error: "Missing deviceSigned \u2014 mDOC device authentication is required"
9029
+ };
9030
+ }
9031
+ if (!(options.mdocSessionTranscript instanceof Uint8Array) || options.mdocSessionTranscript.length === 0) {
9032
+ return {
9033
+ valid: false,
9034
+ format: this.format,
9035
+ claims: {},
9036
+ issuer: { certificate: issuerCertBytes, country: "" },
9037
+ error: "mdocSessionTranscript is required to verify mDOC device authentication"
9038
+ };
9039
+ }
9040
+ if (!mso.deviceKey) {
9041
+ return {
9042
+ valid: false,
9043
+ format: this.format,
9044
+ claims: {},
9045
+ issuer: { certificate: issuerCertBytes, country: "" },
9046
+ error: "MSO is missing deviceKeyInfo.deviceKey; cannot verify device authentication"
9047
+ };
9048
+ }
9049
+ try {
9050
+ await verifyDeviceAuth({
9051
+ deviceSigned,
9052
+ deviceKeyCose: mso.deviceKey,
9053
+ docType: mso.docType,
9054
+ sessionTranscript: options.mdocSessionTranscript,
9055
+ allowedAlgorithms
9056
+ });
9057
+ } catch (err) {
9058
+ if (err instanceof MalformedCredentialError) {
9059
+ return {
9060
+ valid: false,
9061
+ format: this.format,
9062
+ claims: {},
9063
+ issuer: { certificate: issuerCertBytes, country: "" },
9064
+ error: err.message
9065
+ };
9066
+ }
9067
+ throw err;
9068
+ }
8849
9069
  const { flat: claims, namespaced: namespacedClaims } = mapRawToClaims(nameSpaces);
8850
9070
  const issuer = {
8851
9071
  certificate: issuerCertBytes,
@@ -9118,11 +9338,21 @@ var SdJwtParser = class {
9118
9338
  return invalidResult("Disclosure hash mismatch");
9119
9339
  }
9120
9340
  }
9341
+ const cnf = payload["cnf"];
9342
+ const isHolderBound = !!cnf && typeof cnf === "object" && !!cnf["jwk"];
9343
+ const keyBindingRequired = isHolderBound || options.requireKeyBinding === true;
9344
+ if (keyBindingRequired && !parts.kbJwt) {
9345
+ return invalidResult(
9346
+ "Key binding JWT is required for holder-bound credentials but was not presented"
9347
+ );
9348
+ }
9121
9349
  if (parts.kbJwt) {
9122
- const cnf = payload["cnf"];
9123
- if (!cnf || typeof cnf !== "object" || !cnf["jwk"]) {
9350
+ if (!isHolderBound) {
9124
9351
  throw new MalformedCredentialError("Missing cnf.jwk in issuer JWT for key binding");
9125
9352
  }
9353
+ if (typeof options.nonce !== "string" || options.nonce.length === 0) {
9354
+ return invalidResult("A nonce is required to verify the key binding JWT");
9355
+ }
9126
9356
  let holderKey;
9127
9357
  try {
9128
9358
  const kbHeader = decodeProtectedHeader(parts.kbJwt);
@@ -9240,9 +9470,9 @@ async function decryptAuthorizationResponse(jwe, privateKey) {
9240
9470
  });
9241
9471
  }
9242
9472
  const alg = typeof header.alg === "string" ? header.alg : "";
9243
- const enc = typeof header.enc === "string" ? header.enc : "";
9244
- if (alg !== SUPPORTED_ALG || !SUPPORTED_ENC.has(enc)) {
9245
- throw new UnsupportedJweError(alg, enc);
9473
+ const enc3 = typeof header.enc === "string" ? header.enc : "";
9474
+ if (alg !== SUPPORTED_ALG || !SUPPORTED_ENC.has(enc3)) {
9475
+ throw new UnsupportedJweError(alg, enc3);
9246
9476
  }
9247
9477
  let plaintext;
9248
9478
  try {
@@ -9260,6 +9490,29 @@ async function decryptAuthorizationResponse(jwe, privateKey) {
9260
9490
  });
9261
9491
  }
9262
9492
  }
9493
+ var enc2 = new Encoder({ mapsAsObjects: false, useRecords: false, tagUint8Array: false });
9494
+ async function sha256(bytes) {
9495
+ return new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
9496
+ }
9497
+ async function buildOid4vpSessionTranscript(params) {
9498
+ const { clientId, responseUri, nonce, mdocGeneratedNonce } = params;
9499
+ const clientIdHash = await sha256(new Uint8Array(enc2.encode([clientId, mdocGeneratedNonce])));
9500
+ const responseUriHash = await sha256(new Uint8Array(enc2.encode([responseUri, mdocGeneratedNonce])));
9501
+ return new Uint8Array(enc2.encode([null, null, [clientIdHash, responseUriHash, nonce]]));
9502
+ }
9503
+ async function jwkSha256Thumbprint(jwk) {
9504
+ if (jwk.kty !== "EC") {
9505
+ throw new Error(`Unsupported JWK kty for thumbprint: ${jwk.kty}`);
9506
+ }
9507
+ const canonical = `{"crv":"${jwk.crv}","kty":"EC","x":"${jwk.x}","y":"${jwk.y}"}`;
9508
+ return sha256(new TextEncoder().encode(canonical));
9509
+ }
9510
+ async function buildOpenID4VPHandoverSessionTranscript(params) {
9511
+ const { clientId, nonce, responseUri, verifierEncryptionJwk } = params;
9512
+ const thumb = verifierEncryptionJwk ? await jwkSha256Thumbprint(verifierEncryptionJwk) : null;
9513
+ const infoHash = await sha256(new Uint8Array(enc2.encode([clientId, nonce, thumb, responseUri])));
9514
+ return new Uint8Array(enc2.encode([null, null, ["OpenID4VPHandover", infoHash]]));
9515
+ }
9263
9516
 
9264
9517
  // src/verify.ts
9265
9518
  init_errors();
@@ -9297,6 +9550,42 @@ async function verifyPresentation(vpToken, query, options) {
9297
9550
  function isEncryptedResponse(x) {
9298
9551
  return typeof x === "object" && x !== null && "response" in x && typeof x.response === "string" && Object.keys(x).length === 1;
9299
9552
  }
9553
+ var BASE64URL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
9554
+ function base64UrlToBytes(input) {
9555
+ const cleaned = input.replace(/=+$/, "");
9556
+ const byteLength = Math.floor(cleaned.length * 3 / 4);
9557
+ const bytes = new Uint8Array(byteLength);
9558
+ let byteIndex = 0;
9559
+ for (let i = 0; i < cleaned.length; i += 4) {
9560
+ const a = BASE64URL_CHARS.indexOf(cleaned[i]);
9561
+ const b = i + 1 < cleaned.length ? BASE64URL_CHARS.indexOf(cleaned[i + 1]) : 0;
9562
+ const c = i + 2 < cleaned.length ? BASE64URL_CHARS.indexOf(cleaned[i + 2]) : 0;
9563
+ const d = i + 3 < cleaned.length ? BASE64URL_CHARS.indexOf(cleaned[i + 3]) : 0;
9564
+ if (a === -1 || b === -1 || c === -1 || d === -1) {
9565
+ throw new TypeError("Invalid base64url character in vp_token/apu");
9566
+ }
9567
+ bytes[byteIndex++] = a << 2 | b >> 4;
9568
+ if (byteIndex < byteLength) bytes[byteIndex++] = (b & 15) << 4 | c >> 2;
9569
+ if (byteIndex < byteLength) bytes[byteIndex++] = (c & 3) << 6 | d;
9570
+ }
9571
+ return bytes;
9572
+ }
9573
+ function extractMdocGeneratedNonce(jwe) {
9574
+ let apu;
9575
+ try {
9576
+ apu = decodeProtectedHeader(jwe).apu;
9577
+ } catch {
9578
+ return void 0;
9579
+ }
9580
+ if (typeof apu !== "string" || apu.length === 0) {
9581
+ return void 0;
9582
+ }
9583
+ try {
9584
+ return new TextDecoder().decode(base64UrlToBytes(apu));
9585
+ } catch {
9586
+ return void 0;
9587
+ }
9588
+ }
9300
9589
  function isAuthorizationResponse(x) {
9301
9590
  return typeof x === "object" && x !== null && "vp_token" in x && typeof x.vp_token === "object" && x.vp_token !== null;
9302
9591
  }
@@ -9305,11 +9594,32 @@ async function verifyAuthorizationResponse(envelope, query, options) {
9305
9594
  if (!options.decryptionKey) {
9306
9595
  throw new MissingDecryptionKeyError();
9307
9596
  }
9597
+ const nextOptions = { ...options };
9598
+ if (options.mdocSessionTranscript === void 0 && options.clientId !== void 0 && options.responseUri !== void 0 && options.nonce !== void 0) {
9599
+ if (options.sessionTranscriptProfile === "openid4vp-1.0") {
9600
+ nextOptions.mdocSessionTranscript = await buildOpenID4VPHandoverSessionTranscript({
9601
+ clientId: options.clientId,
9602
+ nonce: options.nonce,
9603
+ responseUri: options.responseUri,
9604
+ verifierEncryptionJwk: options.verifierEncryptionJwk
9605
+ });
9606
+ } else {
9607
+ const mdocGeneratedNonce = extractMdocGeneratedNonce(envelope.response);
9608
+ if (mdocGeneratedNonce !== void 0) {
9609
+ nextOptions.mdocSessionTranscript = await buildOid4vpSessionTranscript({
9610
+ clientId: options.clientId,
9611
+ responseUri: options.responseUri,
9612
+ nonce: options.nonce,
9613
+ mdocGeneratedNonce
9614
+ });
9615
+ }
9616
+ }
9617
+ }
9308
9618
  const decrypted = await decryptAuthorizationResponse(
9309
9619
  envelope.response,
9310
9620
  options.decryptionKey
9311
9621
  );
9312
- return verifyAuthorizationResponse(decrypted, query, options);
9622
+ return verifyAuthorizationResponse(decrypted, query, nextOptions);
9313
9623
  }
9314
9624
  if (!isAuthorizationResponse(envelope)) {
9315
9625
  throw new TypeError("envelope must contain vp_token as a JSON object per OpenID4VP 1.0 \xA78.1");
@@ -9334,7 +9644,8 @@ async function verifyAuthorizationResponse(envelope, query, options) {
9334
9644
  throw new MultipleCredentialsNotSupportedError(queryIds.length, presentationCount);
9335
9645
  }
9336
9646
  const presentation = vpToken[queryIds[0]][0];
9337
- return verifyPresentation(presentation, query, options);
9647
+ const decodedPresentation = query.credentials[0]?.format === "mso_mdoc" && typeof presentation === "string" ? base64UrlToBytes(presentation) : presentation;
9648
+ return verifyPresentation(decodedPresentation, query, options);
9338
9649
  }
9339
9650
 
9340
9651
  // src/index.ts
@@ -10017,6 +10328,6 @@ asn1js/build/index.es.js:
10017
10328
  *)
10018
10329
  */
10019
10330
 
10020
- export { CertificateChainError, CompositeTrustStore, DecryptionFailedError, ExpiredCredentialError, HAIP_DOCTYPE_NAMESPACES, HaipValidationError, InMemoryCache, InvalidSignatureError, LotlFetchError, LotlSignatureError, LotlTrustStore, MalformedCredentialError, MdocParser, MissingDecryptionKeyError, MultipleCredentialsNotSupportedError, NonceValidationError, OpenID4VPError, RevocationCheckFailedError, RevokedCertificateError, SdJwtParser, SignedRequestBuildError, StaticTrustStore, TrustAnchorNotFoundError, UnsupportedFormatError, UnsupportedJweError, VERSION, buildHaipQuery, createAuthorizationRequest, createSignedAuthorizationRequest, decryptAuthorizationResponse, isHaipQuery, parsePresentation, validateHaipQuery, verifyAuthorizationResponse, verifyPresentation };
10331
+ export { CertificateChainError, CompositeTrustStore, DecryptionFailedError, ExpiredCredentialError, HAIP_DOCTYPE_NAMESPACES, HaipValidationError, InMemoryCache, InvalidSignatureError, LotlFetchError, LotlSignatureError, LotlTrustStore, MalformedCredentialError, MdocParser, MissingDecryptionKeyError, MultipleCredentialsNotSupportedError, NonceValidationError, OpenID4VPError, RevocationCheckFailedError, RevokedCertificateError, SdJwtParser, SignedRequestBuildError, StaticTrustStore, TrustAnchorNotFoundError, UnsupportedFormatError, UnsupportedJweError, VERSION, buildHaipQuery, buildOid4vpSessionTranscript, buildOpenID4VPHandoverSessionTranscript, createAuthorizationRequest, createSignedAuthorizationRequest, decryptAuthorizationResponse, isHaipQuery, parsePresentation, validateHaipQuery, verifyAuthorizationResponse, verifyPresentation };
10021
10332
  //# sourceMappingURL=index.js.map
10022
10333
  //# sourceMappingURL=index.js.map