@openeudi/openid4vp 0.5.0 → 0.7.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/README.md +93 -1
- package/dist/index.cjs +371 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -2
- package/dist/index.d.ts +103 -2
- package/dist/index.js +369 -90
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var x509 = require('@peculiar/x509');
|
|
4
4
|
var uuid = require('uuid');
|
|
5
|
-
var cborX = require('cbor-x');
|
|
6
5
|
var jose = require('jose');
|
|
6
|
+
var cborX = require('cbor-x');
|
|
7
7
|
var decode = require('@sd-jwt/decode');
|
|
8
8
|
var dcql = require('@openeudi/dcql');
|
|
9
9
|
var xmldom = require('@xmldom/xmldom');
|
|
@@ -40,7 +40,7 @@ var __export = (target, all) => {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
// src/errors.ts
|
|
43
|
-
exports.InvalidSignatureError = void 0; exports.ExpiredCredentialError = void 0; exports.UnsupportedFormatError = void 0; exports.MalformedCredentialError = void 0; exports.NonceValidationError = void 0; exports.HaipValidationError = void 0; exports.OpenID4VPError = void 0; exports.TrustAnchorNotFoundError = void 0; exports.CertificateChainError = void 0; exports.RevokedCertificateError = void 0; exports.RevocationCheckFailedError = void 0; exports.LotlFetchError = void 0; exports.LotlSignatureError = void 0;
|
|
43
|
+
exports.InvalidSignatureError = void 0; exports.ExpiredCredentialError = void 0; exports.UnsupportedFormatError = void 0; exports.MalformedCredentialError = void 0; exports.NonceValidationError = void 0; exports.HaipValidationError = void 0; exports.OpenID4VPError = void 0; exports.TrustAnchorNotFoundError = void 0; exports.CertificateChainError = void 0; exports.RevokedCertificateError = void 0; exports.RevocationCheckFailedError = void 0; exports.LotlFetchError = void 0; exports.LotlSignatureError = void 0; exports.SignedRequestBuildError = void 0; exports.UnsupportedJweError = void 0; exports.DecryptionFailedError = void 0; exports.MissingDecryptionKeyError = void 0; exports.MultipleCredentialsNotSupportedError = void 0;
|
|
44
44
|
var init_errors = __esm({
|
|
45
45
|
"src/errors.ts"() {
|
|
46
46
|
exports.InvalidSignatureError = class extends Error {
|
|
@@ -136,6 +136,47 @@ var init_errors = __esm({
|
|
|
136
136
|
exports.LotlSignatureError = class extends exports.OpenID4VPError {
|
|
137
137
|
code = "lotl_signature_invalid";
|
|
138
138
|
};
|
|
139
|
+
exports.SignedRequestBuildError = class extends exports.OpenID4VPError {
|
|
140
|
+
code;
|
|
141
|
+
constructor(code, message) {
|
|
142
|
+
super(message);
|
|
143
|
+
this.code = code;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
exports.UnsupportedJweError = class extends exports.OpenID4VPError {
|
|
147
|
+
code = "unsupported_jwe";
|
|
148
|
+
alg;
|
|
149
|
+
enc;
|
|
150
|
+
constructor(alg, enc) {
|
|
151
|
+
super(`Unsupported JWE algorithms: alg=${alg}, enc=${enc}`);
|
|
152
|
+
this.alg = alg;
|
|
153
|
+
this.enc = enc;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
exports.DecryptionFailedError = class extends exports.OpenID4VPError {
|
|
157
|
+
code = "decryption_failed";
|
|
158
|
+
constructor(message = "Failed to decrypt authorization response", options) {
|
|
159
|
+
super(message, options);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
exports.MissingDecryptionKeyError = class extends exports.OpenID4VPError {
|
|
163
|
+
code = "missing_decryption_key";
|
|
164
|
+
constructor(message = "decryptionKey is required to verify a direct_post.jwt response") {
|
|
165
|
+
super(message);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
exports.MultipleCredentialsNotSupportedError = class extends exports.OpenID4VPError {
|
|
169
|
+
code = "multi_credential_unsupported";
|
|
170
|
+
entryCount;
|
|
171
|
+
presentationCount;
|
|
172
|
+
constructor(entryCount, presentationCount) {
|
|
173
|
+
super(
|
|
174
|
+
`Multi-credential presentations are not yet supported: ${entryCount} queryId entries, ${presentationCount} presentations`
|
|
175
|
+
);
|
|
176
|
+
this.entryCount = entryCount;
|
|
177
|
+
this.presentationCount = presentationCount;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
139
180
|
}
|
|
140
181
|
});
|
|
141
182
|
|
|
@@ -631,6 +672,9 @@ __export(index_es_exports, {
|
|
|
631
672
|
Choice: () => Choice,
|
|
632
673
|
Constructed: () => Constructed,
|
|
633
674
|
DATE: () => DATE,
|
|
675
|
+
DEFAULT_MAX_CONTENT_LENGTH: () => DEFAULT_MAX_CONTENT_LENGTH,
|
|
676
|
+
DEFAULT_MAX_DEPTH: () => DEFAULT_MAX_DEPTH,
|
|
677
|
+
DEFAULT_MAX_NODES: () => DEFAULT_MAX_NODES,
|
|
634
678
|
DateTime: () => DateTime,
|
|
635
679
|
Duration: () => Duration,
|
|
636
680
|
EndOfContent: () => EndOfContent,
|
|
@@ -725,7 +769,7 @@ function HexBlock(BaseClass) {
|
|
|
725
769
|
this.isHexOnly = (_b = params.isHexOnly) !== null && _b !== void 0 ? _b : false;
|
|
726
770
|
this.valueHexView = params.valueHex ? BufferSourceConverter.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
|
727
771
|
}
|
|
728
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
772
|
+
fromBER(inputBuffer, inputOffset, inputLength, _context) {
|
|
729
773
|
const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer;
|
|
730
774
|
if (!checkBufferParams(this, view, inputOffset, inputLength)) {
|
|
731
775
|
return -1;
|
|
@@ -769,6 +813,49 @@ function prepareIndefiniteForm(baseBlock) {
|
|
|
769
813
|
}
|
|
770
814
|
return !!((_a2 = baseBlock.lenBlock) === null || _a2 === void 0 ? void 0 : _a2.isIndefiniteForm);
|
|
771
815
|
}
|
|
816
|
+
function createFromBerContext(options = {}) {
|
|
817
|
+
var _a2, _b, _c;
|
|
818
|
+
return {
|
|
819
|
+
depth: 0,
|
|
820
|
+
maxDepth: (_a2 = options.maxDepth) !== null && _a2 !== void 0 ? _a2 : DEFAULT_MAX_DEPTH,
|
|
821
|
+
nodesCount: 0,
|
|
822
|
+
maxNodes: (_b = options.maxNodes) !== null && _b !== void 0 ? _b : DEFAULT_MAX_NODES,
|
|
823
|
+
maxContentLength: (_c = options.maxContentLength) !== null && _c !== void 0 ? _c : DEFAULT_MAX_CONTENT_LENGTH
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
function createErrorResult(error) {
|
|
827
|
+
const result = new BaseBlock({}, ValueBlock);
|
|
828
|
+
result.error = error;
|
|
829
|
+
return {
|
|
830
|
+
offset: -1,
|
|
831
|
+
result
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function checkNodesLimit(context) {
|
|
835
|
+
context.nodesCount += 1;
|
|
836
|
+
if (context.nodesCount > context.maxNodes) {
|
|
837
|
+
return MAX_NODES_EXCEEDED_ERROR;
|
|
838
|
+
}
|
|
839
|
+
return void 0;
|
|
840
|
+
}
|
|
841
|
+
function checkContentLengthLimit(inputLength, context) {
|
|
842
|
+
if (inputLength > context.maxContentLength) {
|
|
843
|
+
return MAX_CONTENT_LENGTH_EXCEEDED_ERROR;
|
|
844
|
+
}
|
|
845
|
+
return void 0;
|
|
846
|
+
}
|
|
847
|
+
function localFromBERWithChildContext(inputBuffer, inputOffset, inputLength, context) {
|
|
848
|
+
const childDepth = context.depth + 1;
|
|
849
|
+
if (childDepth > context.maxDepth) {
|
|
850
|
+
return createErrorResult(MAX_DEPTH_EXCEEDED_ERROR);
|
|
851
|
+
}
|
|
852
|
+
context.depth = childDepth;
|
|
853
|
+
try {
|
|
854
|
+
return localFromBER(inputBuffer, inputOffset, inputLength, context);
|
|
855
|
+
} finally {
|
|
856
|
+
context.depth -= 1;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
772
859
|
function localChangeType(inputObject, newType) {
|
|
773
860
|
if (inputObject instanceof newType) {
|
|
774
861
|
return inputObject;
|
|
@@ -780,7 +867,7 @@ function localChangeType(inputObject, newType) {
|
|
|
780
867
|
newObject.valueBeforeDecodeView = inputObject.valueBeforeDecodeView;
|
|
781
868
|
return newObject;
|
|
782
869
|
}
|
|
783
|
-
function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length) {
|
|
870
|
+
function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length, context = createFromBerContext()) {
|
|
784
871
|
const incomingOffset = inputOffset;
|
|
785
872
|
let returnObject = new BaseBlock({}, ValueBlock);
|
|
786
873
|
const baseBlock = new LocalBaseBlock();
|
|
@@ -799,6 +886,14 @@ function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.le
|
|
|
799
886
|
result: returnObject
|
|
800
887
|
};
|
|
801
888
|
}
|
|
889
|
+
const nodesLimitError = checkNodesLimit(context);
|
|
890
|
+
if (nodesLimitError) {
|
|
891
|
+
returnObject.error = nodesLimitError;
|
|
892
|
+
return {
|
|
893
|
+
offset: -1,
|
|
894
|
+
result: returnObject
|
|
895
|
+
};
|
|
896
|
+
}
|
|
802
897
|
let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength);
|
|
803
898
|
if (returnObject.idBlock.warnings.length) {
|
|
804
899
|
returnObject.warnings.concat(returnObject.idBlock.warnings);
|
|
@@ -825,6 +920,15 @@ function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.le
|
|
|
825
920
|
}
|
|
826
921
|
inputOffset = resultOffset;
|
|
827
922
|
inputLength -= returnObject.lenBlock.blockLength;
|
|
923
|
+
const valueLength = returnObject.lenBlock.isIndefiniteForm ? inputLength : returnObject.lenBlock.length;
|
|
924
|
+
const contentLengthError = checkContentLengthLimit(valueLength, context);
|
|
925
|
+
if (contentLengthError) {
|
|
926
|
+
returnObject.error = contentLengthError;
|
|
927
|
+
return {
|
|
928
|
+
offset: -1,
|
|
929
|
+
result: returnObject
|
|
930
|
+
};
|
|
931
|
+
}
|
|
828
932
|
if (!returnObject.idBlock.isConstructed && returnObject.lenBlock.isIndefiniteForm) {
|
|
829
933
|
returnObject.error = "Indefinite length form used for primitive encoding form";
|
|
830
934
|
return {
|
|
@@ -963,14 +1067,14 @@ function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.le
|
|
|
963
1067
|
}
|
|
964
1068
|
}
|
|
965
1069
|
returnObject = localChangeType(returnObject, newASN1Type);
|
|
966
|
-
resultOffset = returnObject.fromBER(inputBuffer, inputOffset,
|
|
1070
|
+
resultOffset = returnObject.fromBER(inputBuffer, inputOffset, valueLength, context);
|
|
967
1071
|
returnObject.valueBeforeDecodeView = inputBuffer.subarray(incomingOffset, incomingOffset + returnObject.blockLength);
|
|
968
1072
|
return {
|
|
969
1073
|
offset: resultOffset,
|
|
970
1074
|
result: returnObject
|
|
971
1075
|
};
|
|
972
1076
|
}
|
|
973
|
-
function fromBER(inputBuffer) {
|
|
1077
|
+
function fromBER(inputBuffer, options = {}) {
|
|
974
1078
|
if (!inputBuffer.byteLength) {
|
|
975
1079
|
const result = new BaseBlock({}, ValueBlock);
|
|
976
1080
|
result.error = "Input buffer has zero length";
|
|
@@ -979,7 +1083,7 @@ function fromBER(inputBuffer) {
|
|
|
979
1083
|
result
|
|
980
1084
|
};
|
|
981
1085
|
}
|
|
982
|
-
return localFromBER(BufferSourceConverter.toUint8Array(inputBuffer).slice(), 0, inputBuffer.byteLength);
|
|
1086
|
+
return localFromBER(BufferSourceConverter.toUint8Array(inputBuffer).slice(), 0, inputBuffer.byteLength, createFromBerContext(options));
|
|
983
1087
|
}
|
|
984
1088
|
function checkLen(indefiniteLength, length) {
|
|
985
1089
|
if (indefiniteLength) {
|
|
@@ -1385,7 +1489,7 @@ function verifySchema(inputBuffer, inputSchema) {
|
|
|
1385
1489
|
}
|
|
1386
1490
|
return compareSchema(asn1.result, asn1.result, inputSchema);
|
|
1387
1491
|
}
|
|
1388
|
-
var ViewWriter, powers2, digitsString, NAME, VALUE_HEX_VIEW, IS_HEX_ONLY, ID_BLOCK, TAG_CLASS, TAG_NUMBER, IS_CONSTRUCTED, FROM_BER, TO_BER, LOCAL, EMPTY_STRING, EMPTY_BUFFER, EMPTY_VIEW, END_OF_CONTENT_NAME, OCTET_STRING_NAME, BIT_STRING_NAME, LocalBaseBlock, ValueBlock, LocalIdentificationBlock, LocalLengthBlock, typeStore, BaseBlock, BaseStringBlock, LocalPrimitiveValueBlock, _a$w, Primitive, LocalConstructedValueBlock, _a$v, Constructed, LocalEndOfContentValueBlock, _a$u, EndOfContent, _a$t, Null, LocalBooleanValueBlock, _a$s, Boolean2, LocalOctetStringValueBlock, _a$r, OctetString, LocalBitStringValueBlock, _a$q, BitString, _a$p, LocalIntegerValueBlock, _a$o, Integer, _a$n, Enumerated, LocalSidValueBlock, LocalObjectIdentifierValueBlock, _a$m, ObjectIdentifier, LocalRelativeSidValueBlock, LocalRelativeObjectIdentifierValueBlock, _a$l, RelativeObjectIdentifier, _a$k, Sequence, _a$j, Set2, LocalStringValueBlock, LocalSimpleStringValueBlock, LocalSimpleStringBlock, LocalUtf8StringValueBlock, _a$i, Utf8String, LocalBmpStringValueBlock, _a$h, BmpString, LocalUniversalStringValueBlock, _a$g, UniversalString, _a$f, NumericString, _a$e, PrintableString, _a$d, TeletexString, _a$c, VideotexString, _a$b, IA5String, _a$a, GraphicString, _a$9, VisibleString, _a$8, GeneralString, _a$7, CharacterString, _a$6, UTCTime, _a$5, GeneralizedTime, _a$4, DATE, _a$3, TimeOfDay, _a$2, DateTime, _a$1, Duration, _a, TIME, Any, Choice, Repeated, RawData;
|
|
1492
|
+
var ViewWriter, powers2, digitsString, NAME, VALUE_HEX_VIEW, IS_HEX_ONLY, ID_BLOCK, TAG_CLASS, TAG_NUMBER, IS_CONSTRUCTED, FROM_BER, TO_BER, LOCAL, EMPTY_STRING, EMPTY_BUFFER, EMPTY_VIEW, END_OF_CONTENT_NAME, OCTET_STRING_NAME, BIT_STRING_NAME, LocalBaseBlock, ValueBlock, LocalIdentificationBlock, LocalLengthBlock, typeStore, BaseBlock, BaseStringBlock, LocalPrimitiveValueBlock, _a$w, Primitive, DEFAULT_MAX_DEPTH, DEFAULT_MAX_NODES, DEFAULT_MAX_CONTENT_LENGTH, MAX_DEPTH_EXCEEDED_ERROR, MAX_NODES_EXCEEDED_ERROR, MAX_CONTENT_LENGTH_EXCEEDED_ERROR, LocalConstructedValueBlock, _a$v, Constructed, LocalEndOfContentValueBlock, _a$u, EndOfContent, _a$t, Null, LocalBooleanValueBlock, _a$s, Boolean2, LocalOctetStringValueBlock, _a$r, OctetString, LocalBitStringValueBlock, _a$q, BitString, _a$p, LocalIntegerValueBlock, _a$o, Integer, _a$n, Enumerated, LocalSidValueBlock, LocalObjectIdentifierValueBlock, _a$m, ObjectIdentifier, LocalRelativeSidValueBlock, LocalRelativeObjectIdentifierValueBlock, _a$l, RelativeObjectIdentifier, _a$k, Sequence, _a$j, Set2, LocalStringValueBlock, LocalSimpleStringValueBlock, LocalSimpleStringBlock, LocalUtf8StringValueBlock, _a$i, Utf8String, LocalBmpStringValueBlock, _a$h, BmpString, LocalUniversalStringValueBlock, _a$g, UniversalString, _a$f, NumericString, _a$e, PrintableString, _a$d, TeletexString, _a$c, VideotexString, _a$b, IA5String, _a$a, GraphicString, _a$9, VisibleString, _a$8, GeneralString, _a$7, CharacterString, _a$6, UTCTime, _a$5, GeneralizedTime, _a$4, DATE, _a$3, TimeOfDay, _a$2, DateTime, _a$1, Duration, _a, TIME, Any, Choice, Repeated, RawData;
|
|
1389
1493
|
var init_index_es2 = __esm({
|
|
1390
1494
|
"node_modules/asn1js/build/index.es.js"() {
|
|
1391
1495
|
init_index_es();
|
|
@@ -1447,7 +1551,7 @@ var init_index_es2 = __esm({
|
|
|
1447
1551
|
};
|
|
1448
1552
|
LocalBaseBlock.NAME = "baseBlock";
|
|
1449
1553
|
ValueBlock = class extends LocalBaseBlock {
|
|
1450
|
-
fromBER(_inputBuffer, _inputOffset, _inputLength) {
|
|
1554
|
+
fromBER(_inputBuffer, _inputOffset, _inputLength, _context) {
|
|
1451
1555
|
throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'");
|
|
1452
1556
|
}
|
|
1453
1557
|
toBER(_sizeOnly, _writer) {
|
|
@@ -1560,31 +1664,21 @@ var init_index_es2 = __esm({
|
|
|
1560
1664
|
this.tagNumber = tagNumberMask;
|
|
1561
1665
|
this.blockLength = 1;
|
|
1562
1666
|
} else {
|
|
1563
|
-
let count =
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
intTagNumberBuffer[count - 1] = intBuffer[count] & 127;
|
|
1568
|
-
count++;
|
|
1569
|
-
if (count >= intBuffer.length) {
|
|
1667
|
+
let count = 0;
|
|
1668
|
+
while (true) {
|
|
1669
|
+
const tagByteIndex = count + 1;
|
|
1670
|
+
if (tagByteIndex >= intBuffer.length) {
|
|
1570
1671
|
this.error = "End of input reached before message was fully decoded";
|
|
1571
1672
|
return -1;
|
|
1572
1673
|
}
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
for (let i = 0; i < intTagNumberBuffer.length; i++)
|
|
1577
|
-
tempBufferView2[i] = intTagNumberBuffer[i];
|
|
1578
|
-
intTagNumberBuffer = this.valueHexView = new Uint8Array(tagNumberBufferMaxLength);
|
|
1579
|
-
}
|
|
1674
|
+
count++;
|
|
1675
|
+
if ((intBuffer[tagByteIndex] & 128) === 0)
|
|
1676
|
+
break;
|
|
1580
1677
|
}
|
|
1581
1678
|
this.blockLength = count + 1;
|
|
1582
|
-
intTagNumberBuffer
|
|
1583
|
-
const tempBufferView = new Uint8Array(count);
|
|
1679
|
+
const intTagNumberBuffer = this.valueHexView = new Uint8Array(count);
|
|
1584
1680
|
for (let i = 0; i < count; i++)
|
|
1585
|
-
|
|
1586
|
-
intTagNumberBuffer = this.valueHexView = new Uint8Array(count);
|
|
1587
|
-
intTagNumberBuffer.set(tempBufferView);
|
|
1681
|
+
intTagNumberBuffer[i] = intBuffer[i + 1] & 127;
|
|
1588
1682
|
if (this.blockLength <= 9)
|
|
1589
1683
|
this.tagNumber = utilFromBase(intTagNumberBuffer, 7);
|
|
1590
1684
|
else {
|
|
@@ -1734,8 +1828,8 @@ var init_index_es2 = __esm({
|
|
|
1734
1828
|
this.lenBlock = new LocalLengthBlock(parameters);
|
|
1735
1829
|
this.valueBlock = valueBlockType ? new valueBlockType(parameters) : new ValueBlock(parameters);
|
|
1736
1830
|
}
|
|
1737
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
1738
|
-
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length);
|
|
1831
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
1832
|
+
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length, context);
|
|
1739
1833
|
if (resultOffset === -1) {
|
|
1740
1834
|
this.error = this.valueBlock.error;
|
|
1741
1835
|
return resultOffset;
|
|
@@ -1859,14 +1953,21 @@ var init_index_es2 = __esm({
|
|
|
1859
1953
|
typeStore.Primitive = _a$w;
|
|
1860
1954
|
})();
|
|
1861
1955
|
Primitive.NAME = "PRIMITIVE";
|
|
1956
|
+
DEFAULT_MAX_DEPTH = 100;
|
|
1957
|
+
DEFAULT_MAX_NODES = 1e4;
|
|
1958
|
+
DEFAULT_MAX_CONTENT_LENGTH = 16 * 1024 * 1024;
|
|
1959
|
+
MAX_DEPTH_EXCEEDED_ERROR = "Maximum ASN.1 nesting depth exceeded";
|
|
1960
|
+
MAX_NODES_EXCEEDED_ERROR = "Maximum ASN.1 node count exceeded";
|
|
1961
|
+
MAX_CONTENT_LENGTH_EXCEEDED_ERROR = "Maximum ASN.1 content length exceeded";
|
|
1862
1962
|
LocalConstructedValueBlock = class extends ValueBlock {
|
|
1863
1963
|
constructor({ value = [], isIndefiniteForm = false, ...parameters } = {}) {
|
|
1864
1964
|
super(parameters);
|
|
1865
1965
|
this.value = value;
|
|
1866
1966
|
this.isIndefiniteForm = isIndefiniteForm;
|
|
1867
1967
|
}
|
|
1868
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
1968
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
1869
1969
|
const view = BufferSourceConverter.toUint8Array(inputBuffer);
|
|
1970
|
+
const parseContext = context !== null && context !== void 0 ? context : createFromBerContext();
|
|
1870
1971
|
if (!checkBufferParams(this, view, inputOffset, inputLength)) {
|
|
1871
1972
|
return -1;
|
|
1872
1973
|
}
|
|
@@ -1877,7 +1978,7 @@ var init_index_es2 = __esm({
|
|
|
1877
1978
|
}
|
|
1878
1979
|
let currentOffset = inputOffset;
|
|
1879
1980
|
while (checkLen(this.isIndefiniteForm, inputLength) > 0) {
|
|
1880
|
-
const returnObject =
|
|
1981
|
+
const returnObject = localFromBERWithChildContext(view, currentOffset, inputLength, parseContext);
|
|
1881
1982
|
if (returnObject.offset === -1) {
|
|
1882
1983
|
this.error = returnObject.result.error;
|
|
1883
1984
|
this.warnings.concat(returnObject.result.warnings);
|
|
@@ -1928,9 +2029,9 @@ var init_index_es2 = __esm({
|
|
|
1928
2029
|
super(parameters, LocalConstructedValueBlock);
|
|
1929
2030
|
this.idBlock.isConstructed = true;
|
|
1930
2031
|
}
|
|
1931
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
2032
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
1932
2033
|
this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
|
|
1933
|
-
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length);
|
|
2034
|
+
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length, context);
|
|
1934
2035
|
if (resultOffset === -1) {
|
|
1935
2036
|
this.error = this.valueBlock.error;
|
|
1936
2037
|
return resultOffset;
|
|
@@ -2093,11 +2194,11 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2093
2194
|
super(parameters);
|
|
2094
2195
|
this.isConstructed = isConstructed;
|
|
2095
2196
|
}
|
|
2096
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
2197
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
2097
2198
|
let resultOffset = 0;
|
|
2098
2199
|
if (this.isConstructed) {
|
|
2099
2200
|
this.isHexOnly = false;
|
|
2100
|
-
resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength);
|
|
2201
|
+
resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength, context);
|
|
2101
2202
|
if (resultOffset === -1)
|
|
2102
2203
|
return resultOffset;
|
|
2103
2204
|
for (let i = 0; i < this.value.length; i++) {
|
|
@@ -2153,7 +2254,7 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2153
2254
|
this.idBlock.tagClass = 1;
|
|
2154
2255
|
this.idBlock.tagNumber = 4;
|
|
2155
2256
|
}
|
|
2156
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
2257
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
2157
2258
|
this.valueBlock.isConstructed = this.idBlock.isConstructed;
|
|
2158
2259
|
this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
|
|
2159
2260
|
if (inputLength === 0) {
|
|
@@ -2168,7 +2269,8 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2168
2269
|
const buf = view.subarray(inputOffset, inputOffset + inputLength);
|
|
2169
2270
|
try {
|
|
2170
2271
|
if (buf.byteLength) {
|
|
2171
|
-
const
|
|
2272
|
+
const parseContext = context !== null && context !== void 0 ? context : createFromBerContext();
|
|
2273
|
+
const asn = localFromBERWithChildContext(buf, 0, buf.byteLength, parseContext);
|
|
2172
2274
|
if (asn.offset !== -1 && asn.offset === inputLength) {
|
|
2173
2275
|
this.valueBlock.value = [asn.result];
|
|
2174
2276
|
}
|
|
@@ -2176,7 +2278,7 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2176
2278
|
} catch {
|
|
2177
2279
|
}
|
|
2178
2280
|
}
|
|
2179
|
-
return super.fromBER(inputBuffer, inputOffset, inputLength);
|
|
2281
|
+
return super.fromBER(inputBuffer, inputOffset, inputLength, context);
|
|
2180
2282
|
}
|
|
2181
2283
|
onAsciiEncoding() {
|
|
2182
2284
|
if (this.valueBlock.isConstructed || this.valueBlock.value && this.valueBlock.value.length) {
|
|
@@ -2211,13 +2313,13 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2211
2313
|
this.isConstructed = isConstructed;
|
|
2212
2314
|
this.blockLength = this.valueHexView.byteLength;
|
|
2213
2315
|
}
|
|
2214
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
2316
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
2215
2317
|
if (!inputLength) {
|
|
2216
2318
|
return inputOffset;
|
|
2217
2319
|
}
|
|
2218
2320
|
let resultOffset = -1;
|
|
2219
2321
|
if (this.isConstructed) {
|
|
2220
|
-
resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength);
|
|
2322
|
+
resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength, context);
|
|
2221
2323
|
if (resultOffset === -1)
|
|
2222
2324
|
return resultOffset;
|
|
2223
2325
|
for (const value of this.value) {
|
|
@@ -2257,7 +2359,8 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2257
2359
|
const buf = intBuffer.subarray(1);
|
|
2258
2360
|
try {
|
|
2259
2361
|
if (buf.byteLength) {
|
|
2260
|
-
const
|
|
2362
|
+
const parseContext = context !== null && context !== void 0 ? context : createFromBerContext();
|
|
2363
|
+
const asn = localFromBERWithChildContext(buf, 0, buf.byteLength, parseContext);
|
|
2261
2364
|
if (asn.offset !== -1 && asn.offset === inputLength - 1) {
|
|
2262
2365
|
this.value = [asn.result];
|
|
2263
2366
|
}
|
|
@@ -2313,10 +2416,10 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
2313
2416
|
this.idBlock.tagClass = 1;
|
|
2314
2417
|
this.idBlock.tagNumber = 3;
|
|
2315
2418
|
}
|
|
2316
|
-
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
2419
|
+
fromBER(inputBuffer, inputOffset, inputLength, context) {
|
|
2317
2420
|
this.valueBlock.isConstructed = this.idBlock.isConstructed;
|
|
2318
2421
|
this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
|
|
2319
|
-
return super.fromBER(inputBuffer, inputOffset, inputLength);
|
|
2422
|
+
return super.fromBER(inputBuffer, inputOffset, inputLength, context);
|
|
2320
2423
|
}
|
|
2321
2424
|
onAsciiEncoding() {
|
|
2322
2425
|
if (this.valueBlock.isConstructed || this.valueBlock.value && this.valueBlock.value.length) {
|
|
@@ -7983,6 +8086,135 @@ function createAuthorizationRequest(input, query) {
|
|
|
7983
8086
|
};
|
|
7984
8087
|
}
|
|
7985
8088
|
|
|
8089
|
+
// src/signed-authorization.ts
|
|
8090
|
+
init_errors();
|
|
8091
|
+
var DEFAULT_SUPPORTED_ENC_VALUES = ["A128GCM", "A256GCM"];
|
|
8092
|
+
var SUPPORTED_SIGNING_ALGS = /* @__PURE__ */ new Set(["ES256", "ES384", "RS256"]);
|
|
8093
|
+
async function createSignedAuthorizationRequest(input, query) {
|
|
8094
|
+
if (input.certificateChain.length === 0) {
|
|
8095
|
+
throw new exports.SignedRequestBuildError(
|
|
8096
|
+
"empty_cert_chain",
|
|
8097
|
+
"certificateChain must contain at least the leaf certificate"
|
|
8098
|
+
);
|
|
8099
|
+
}
|
|
8100
|
+
const signingAlg = input.signingAlgorithm ?? "ES256";
|
|
8101
|
+
if (!SUPPORTED_SIGNING_ALGS.has(signingAlg)) {
|
|
8102
|
+
throw new exports.SignedRequestBuildError(
|
|
8103
|
+
"unsupported_signing_alg",
|
|
8104
|
+
`signingAlgorithm ${signingAlg} is not supported (expected ES256/ES384/RS256)`
|
|
8105
|
+
);
|
|
8106
|
+
}
|
|
8107
|
+
if (!input.vpFormatsSupported || Object.keys(input.vpFormatsSupported).length === 0) {
|
|
8108
|
+
throw new exports.SignedRequestBuildError(
|
|
8109
|
+
"missing_vp_formats",
|
|
8110
|
+
"vpFormatsSupported is required and must be non-empty"
|
|
8111
|
+
);
|
|
8112
|
+
}
|
|
8113
|
+
const leafCert = new x509.X509Certificate(toArrayBuffer(input.certificateChain[0]));
|
|
8114
|
+
const sanDnsNames = extractDnsNames(leafCert);
|
|
8115
|
+
if (!sanDnsNames.includes(input.hostname)) {
|
|
8116
|
+
throw new exports.SignedRequestBuildError(
|
|
8117
|
+
"hostname_cert_mismatch",
|
|
8118
|
+
`leaf cert SAN DNSName values [${sanDnsNames.join(", ")}] do not include hostname "${input.hostname}"`
|
|
8119
|
+
);
|
|
8120
|
+
}
|
|
8121
|
+
const signerPublicSpki = new Uint8Array(
|
|
8122
|
+
await crypto.subtle.exportKey("spki", input.signer.publicKey)
|
|
8123
|
+
);
|
|
8124
|
+
const leafSpki = new Uint8Array(leafCert.publicKey.rawData);
|
|
8125
|
+
if (!bytesEqual(signerPublicSpki, leafSpki)) {
|
|
8126
|
+
throw new exports.SignedRequestBuildError(
|
|
8127
|
+
"signing_key_cert_mismatch",
|
|
8128
|
+
"signer.publicKey SPKI does not match leaf certificate SPKI"
|
|
8129
|
+
);
|
|
8130
|
+
}
|
|
8131
|
+
const responseMode = input.responseMode ?? "direct_post.jwt";
|
|
8132
|
+
if (responseMode === "direct_post.jwt") {
|
|
8133
|
+
if (!input.encryptionKey?.publicJwk) {
|
|
8134
|
+
throw new exports.SignedRequestBuildError(
|
|
8135
|
+
"missing_encryption_jwk",
|
|
8136
|
+
"direct_post.jwt response mode requires encryptionKey.publicJwk"
|
|
8137
|
+
);
|
|
8138
|
+
}
|
|
8139
|
+
if (!input.encryptionKey.publicJwk.alg) {
|
|
8140
|
+
throw new exports.SignedRequestBuildError(
|
|
8141
|
+
"missing_encryption_alg",
|
|
8142
|
+
"encryptionKey.publicJwk must carry alg (OpenID4VP 1.0 \xA78.3)"
|
|
8143
|
+
);
|
|
8144
|
+
}
|
|
8145
|
+
}
|
|
8146
|
+
const state = input.state ?? uuid.v4();
|
|
8147
|
+
const clientId = `x509_san_dns:${input.hostname}`;
|
|
8148
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
8149
|
+
const clientMetadata = {
|
|
8150
|
+
vp_formats_supported: input.vpFormatsSupported
|
|
8151
|
+
};
|
|
8152
|
+
if (responseMode === "direct_post.jwt" && input.encryptionKey) {
|
|
8153
|
+
const enc = input.encryptionKey.supportedEncValues;
|
|
8154
|
+
if (enc !== void 0 && enc.length === 0) {
|
|
8155
|
+
throw new exports.SignedRequestBuildError(
|
|
8156
|
+
"empty_supported_enc_values",
|
|
8157
|
+
"encryptionKey.supportedEncValues must not be empty (omit to use defaults [A128GCM, A256GCM])"
|
|
8158
|
+
);
|
|
8159
|
+
}
|
|
8160
|
+
const jwk = { ...input.encryptionKey.publicJwk, use: "enc" };
|
|
8161
|
+
clientMetadata.jwks = { keys: [jwk] };
|
|
8162
|
+
clientMetadata.encrypted_response_enc_values_supported = enc ?? [...DEFAULT_SUPPORTED_ENC_VALUES];
|
|
8163
|
+
}
|
|
8164
|
+
const payload = {
|
|
8165
|
+
iss: clientId,
|
|
8166
|
+
aud: "https://self-issued.me/v2",
|
|
8167
|
+
response_type: "vp_token",
|
|
8168
|
+
response_mode: responseMode,
|
|
8169
|
+
client_id: clientId,
|
|
8170
|
+
response_uri: input.responseUri,
|
|
8171
|
+
nonce: input.nonce,
|
|
8172
|
+
state,
|
|
8173
|
+
dcql_query: query,
|
|
8174
|
+
client_metadata: clientMetadata,
|
|
8175
|
+
iat: now,
|
|
8176
|
+
exp: now + 120
|
|
8177
|
+
};
|
|
8178
|
+
const x5c = input.certificateChain.map((der) => bytesToBase64(der));
|
|
8179
|
+
const jws = await new jose.SignJWT(payload).setProtectedHeader({ typ: "oauth-authz-req+jwt", alg: signingAlg, x5c }).sign(input.signer.privateKey);
|
|
8180
|
+
const uriParams = new URLSearchParams({
|
|
8181
|
+
client_id: clientId,
|
|
8182
|
+
request_uri: input.requestUri
|
|
8183
|
+
});
|
|
8184
|
+
return {
|
|
8185
|
+
uri: `openid4vp://authorize?${uriParams.toString()}`,
|
|
8186
|
+
requestObject: jws,
|
|
8187
|
+
dcqlQuery: query,
|
|
8188
|
+
nonce: input.nonce,
|
|
8189
|
+
state
|
|
8190
|
+
};
|
|
8191
|
+
}
|
|
8192
|
+
function extractDnsNames(cert) {
|
|
8193
|
+
const SAN_OID = "2.5.29.17";
|
|
8194
|
+
const ext = cert.extensions.find((e) => e.type === SAN_OID);
|
|
8195
|
+
if (!ext) return [];
|
|
8196
|
+
const names = ext.names;
|
|
8197
|
+
const items = names?.items ?? [];
|
|
8198
|
+
return items.filter((e) => e.type === "dns").map((e) => e.value);
|
|
8199
|
+
}
|
|
8200
|
+
function bytesEqual(a, b) {
|
|
8201
|
+
if (a.length !== b.length) return false;
|
|
8202
|
+
for (let i = 0; i < a.length; i++) {
|
|
8203
|
+
if (a[i] !== b[i]) return false;
|
|
8204
|
+
}
|
|
8205
|
+
return true;
|
|
8206
|
+
}
|
|
8207
|
+
function bytesToBase64(bytes) {
|
|
8208
|
+
let s = "";
|
|
8209
|
+
for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
|
|
8210
|
+
return btoa(s);
|
|
8211
|
+
}
|
|
8212
|
+
function toArrayBuffer(bytes) {
|
|
8213
|
+
const out = new ArrayBuffer(bytes.byteLength);
|
|
8214
|
+
new Uint8Array(out).set(bytes);
|
|
8215
|
+
return out;
|
|
8216
|
+
}
|
|
8217
|
+
|
|
7986
8218
|
// src/haip.ts
|
|
7987
8219
|
init_errors();
|
|
7988
8220
|
var HAIP_DOCTYPE_NAMESPACES = {
|
|
@@ -8209,7 +8441,7 @@ async function computeItemDigest(itemBytes, digestAlgorithm) {
|
|
|
8209
8441
|
const buf = await crypto.subtle.digest(digestAlgorithm, new Uint8Array(itemBytes));
|
|
8210
8442
|
return new Uint8Array(buf);
|
|
8211
8443
|
}
|
|
8212
|
-
function
|
|
8444
|
+
function bytesEqual2(a, b) {
|
|
8213
8445
|
if (a.length !== b.length) return false;
|
|
8214
8446
|
for (let i = 0; i < a.length; i++) {
|
|
8215
8447
|
if (a[i] !== b[i]) return false;
|
|
@@ -8255,7 +8487,7 @@ async function verifyAllDigests(nameSpaces, mso) {
|
|
|
8255
8487
|
if (!expectedDigest) {
|
|
8256
8488
|
throw new exports.MalformedCredentialError(`digestID ${digestID} missing from MSO valueDigests[${ns}]`);
|
|
8257
8489
|
}
|
|
8258
|
-
if (!
|
|
8490
|
+
if (!bytesEqual2(hash, expectedDigest)) {
|
|
8259
8491
|
throw new exports.MalformedCredentialError(`digest mismatch for ns=${ns} digestID=${digestID}`);
|
|
8260
8492
|
}
|
|
8261
8493
|
}
|
|
@@ -8374,7 +8606,7 @@ init_errors();
|
|
|
8374
8606
|
var decoder4 = new cborX.Encoder({ mapsAsObjects: false, useRecords: false });
|
|
8375
8607
|
var encoder = new cborX.Encoder({ mapsAsObjects: false, useRecords: false });
|
|
8376
8608
|
var DEFAULT_ALLOWED_ALGORITHMS = ["ES256", "ES384", "ES512"];
|
|
8377
|
-
function
|
|
8609
|
+
function bytesEqual3(a, b) {
|
|
8378
8610
|
if (a.length !== b.length) return false;
|
|
8379
8611
|
for (let i = 0; i < a.length; i++) {
|
|
8380
8612
|
if (a[i] !== b[i]) return false;
|
|
@@ -8510,8 +8742,8 @@ var MdocParser = class {
|
|
|
8510
8742
|
cache: options.cache,
|
|
8511
8743
|
clockSkewTolerance: options.clockSkewTolerance
|
|
8512
8744
|
});
|
|
8513
|
-
const { X509Certificate:
|
|
8514
|
-
const leaf = new
|
|
8745
|
+
const { X509Certificate: X509Certificate9 } = await import('@peculiar/x509');
|
|
8746
|
+
const leaf = new X509Certificate9(issuerCertBytes);
|
|
8515
8747
|
trustResult = await evaluator.evaluate(leaf);
|
|
8516
8748
|
} else {
|
|
8517
8749
|
if (options.trustedCertificates.length === 0) {
|
|
@@ -8521,7 +8753,7 @@ var MdocParser = class {
|
|
|
8521
8753
|
);
|
|
8522
8754
|
}
|
|
8523
8755
|
} else {
|
|
8524
|
-
const trusted = options.trustedCertificates.some((t) =>
|
|
8756
|
+
const trusted = options.trustedCertificates.some((t) => bytesEqual3(t, issuerCertBytes));
|
|
8525
8757
|
if (!trusted) {
|
|
8526
8758
|
return {
|
|
8527
8759
|
valid: false,
|
|
@@ -8636,7 +8868,7 @@ function base64ToBytes(base64) {
|
|
|
8636
8868
|
}
|
|
8637
8869
|
return bytes;
|
|
8638
8870
|
}
|
|
8639
|
-
function
|
|
8871
|
+
function bytesEqual4(a, b) {
|
|
8640
8872
|
if (a.length !== b.length) return false;
|
|
8641
8873
|
for (let i = 0; i < a.length; i++) {
|
|
8642
8874
|
if (a[i] !== b[i]) return false;
|
|
@@ -8759,8 +8991,8 @@ var SdJwtParser = class {
|
|
|
8759
8991
|
cache: options.cache,
|
|
8760
8992
|
clockSkewTolerance: options.clockSkewTolerance
|
|
8761
8993
|
});
|
|
8762
|
-
const { X509Certificate:
|
|
8763
|
-
const leaf = new
|
|
8994
|
+
const { X509Certificate: X509Certificate9 } = await import('@peculiar/x509');
|
|
8995
|
+
const leaf = new X509Certificate9(issuerCertBytes);
|
|
8764
8996
|
trustResult = await evaluator.evaluate(leaf);
|
|
8765
8997
|
} else {
|
|
8766
8998
|
if (options.trustedCertificates.length === 0) {
|
|
@@ -8770,7 +9002,7 @@ var SdJwtParser = class {
|
|
|
8770
9002
|
);
|
|
8771
9003
|
}
|
|
8772
9004
|
} else {
|
|
8773
|
-
const isTrusted = options.trustedCertificates.some((trusted) =>
|
|
9005
|
+
const isTrusted = options.trustedCertificates.some((trusted) => bytesEqual4(trusted, issuerCertBytes));
|
|
8774
9006
|
if (!isTrusted) {
|
|
8775
9007
|
return invalidResult("Issuer certificate is not trusted");
|
|
8776
9008
|
}
|
|
@@ -8867,42 +9099,48 @@ async function parsePresentation(vpToken, options) {
|
|
|
8867
9099
|
error: "Unsupported credential format"
|
|
8868
9100
|
};
|
|
8869
9101
|
}
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
9102
|
+
|
|
9103
|
+
// src/decrypt-response.ts
|
|
9104
|
+
init_errors();
|
|
9105
|
+
var SUPPORTED_ALG = "ECDH-ES";
|
|
9106
|
+
var SUPPORTED_ENC = /* @__PURE__ */ new Set(["A128GCM", "A256GCM"]);
|
|
9107
|
+
async function decryptAuthorizationResponse(jwe, privateKey) {
|
|
9108
|
+
let header;
|
|
9109
|
+
try {
|
|
9110
|
+
header = jose.decodeProtectedHeader(jwe);
|
|
9111
|
+
} catch (err) {
|
|
9112
|
+
throw new exports.DecryptionFailedError("Malformed JWE header", {
|
|
9113
|
+
cause: err
|
|
9114
|
+
});
|
|
8881
9115
|
}
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
9116
|
+
const alg = typeof header.alg === "string" ? header.alg : "";
|
|
9117
|
+
const enc = typeof header.enc === "string" ? header.enc : "";
|
|
9118
|
+
if (alg !== SUPPORTED_ALG || !SUPPORTED_ENC.has(enc)) {
|
|
9119
|
+
throw new exports.UnsupportedJweError(alg, enc);
|
|
8885
9120
|
}
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
const
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
9121
|
+
let plaintext;
|
|
9122
|
+
try {
|
|
9123
|
+
const result = await jose.compactDecrypt(jwe, privateKey);
|
|
9124
|
+
plaintext = result.plaintext;
|
|
9125
|
+
} catch (err) {
|
|
9126
|
+
throw new exports.DecryptionFailedError(void 0, { cause: err });
|
|
9127
|
+
}
|
|
9128
|
+
try {
|
|
9129
|
+
const text = new TextDecoder().decode(plaintext);
|
|
9130
|
+
return JSON.parse(text);
|
|
9131
|
+
} catch (err) {
|
|
9132
|
+
throw new exports.DecryptionFailedError("Decrypted plaintext is not valid JSON", {
|
|
9133
|
+
cause: err
|
|
9134
|
+
});
|
|
8892
9135
|
}
|
|
8893
|
-
if (hasDetail) return "missing_claims";
|
|
8894
|
-
return "no_credential_found";
|
|
8895
|
-
}
|
|
8896
|
-
function refineUnmatched(query, decoded, match) {
|
|
8897
|
-
if (match.unmatched.length === 0) return match;
|
|
8898
|
-
const refined = match.unmatched.map((entry) => {
|
|
8899
|
-
const credentialQuery = query.credentials.find((c) => c.id === entry.queryId);
|
|
8900
|
-
if (!credentialQuery) return entry;
|
|
8901
|
-
const specific = classifyMismatch(credentialQuery, decoded, entry.detail !== void 0);
|
|
8902
|
-
return { ...entry, reason: specific };
|
|
8903
|
-
});
|
|
8904
|
-
return { ...match, unmatched: refined };
|
|
8905
9136
|
}
|
|
9137
|
+
|
|
9138
|
+
// src/verify.ts
|
|
9139
|
+
init_errors();
|
|
9140
|
+
var INTERNAL_TO_DCQL_FORMAT = {
|
|
9141
|
+
"sd-jwt-vc": "dc+sd-jwt",
|
|
9142
|
+
mdoc: "mso_mdoc"
|
|
9143
|
+
};
|
|
8906
9144
|
async function verifyPresentation(vpToken, query, options) {
|
|
8907
9145
|
const parsed = await parsePresentation(vpToken, options);
|
|
8908
9146
|
const dcqlFormat = INTERNAL_TO_DCQL_FORMAT[parsed.format] ?? parsed.format;
|
|
@@ -8921,8 +9159,7 @@ async function verifyPresentation(vpToken, query, options) {
|
|
|
8921
9159
|
if (parsed.trust?.trustedAuthorityIds && parsed.trust.trustedAuthorityIds.length > 0) {
|
|
8922
9160
|
decoded.trusted_authority_ids = [...parsed.trust.trustedAuthorityIds];
|
|
8923
9161
|
}
|
|
8924
|
-
const
|
|
8925
|
-
const match = refineUnmatched(query, decoded, rawMatch);
|
|
9162
|
+
const match = dcql.matchQuery(query, [decoded]);
|
|
8926
9163
|
const submission = match.satisfied ? dcql.buildSubmission(query, match) : null;
|
|
8927
9164
|
return {
|
|
8928
9165
|
parsed,
|
|
@@ -8931,6 +9168,48 @@ async function verifyPresentation(vpToken, query, options) {
|
|
|
8931
9168
|
valid: parsed.valid && match.satisfied
|
|
8932
9169
|
};
|
|
8933
9170
|
}
|
|
9171
|
+
function isEncryptedResponse(x) {
|
|
9172
|
+
return typeof x === "object" && x !== null && "response" in x && typeof x.response === "string" && Object.keys(x).length === 1;
|
|
9173
|
+
}
|
|
9174
|
+
function isAuthorizationResponse(x) {
|
|
9175
|
+
return typeof x === "object" && x !== null && "vp_token" in x && typeof x.vp_token === "object" && x.vp_token !== null;
|
|
9176
|
+
}
|
|
9177
|
+
async function verifyAuthorizationResponse(envelope, query, options) {
|
|
9178
|
+
if (isEncryptedResponse(envelope)) {
|
|
9179
|
+
if (!options.decryptionKey) {
|
|
9180
|
+
throw new exports.MissingDecryptionKeyError();
|
|
9181
|
+
}
|
|
9182
|
+
const decrypted = await decryptAuthorizationResponse(
|
|
9183
|
+
envelope.response,
|
|
9184
|
+
options.decryptionKey
|
|
9185
|
+
);
|
|
9186
|
+
return verifyAuthorizationResponse(decrypted, query, options);
|
|
9187
|
+
}
|
|
9188
|
+
if (!isAuthorizationResponse(envelope)) {
|
|
9189
|
+
throw new TypeError("envelope must contain vp_token as a JSON object per OpenID4VP 1.0 \xA78.1");
|
|
9190
|
+
}
|
|
9191
|
+
const vpToken = envelope.vp_token;
|
|
9192
|
+
const queryIds = Object.keys(vpToken);
|
|
9193
|
+
if (queryIds.length === 0) {
|
|
9194
|
+
throw new TypeError("vp_token cannot be empty per OpenID4VP 1.0 \xA78.1");
|
|
9195
|
+
}
|
|
9196
|
+
for (const id of queryIds) {
|
|
9197
|
+
if (!Array.isArray(vpToken[id])) {
|
|
9198
|
+
throw new TypeError(
|
|
9199
|
+
`vp_token entry "${id}" must be an array of presentations per OpenID4VP 1.0 \xA78.1`
|
|
9200
|
+
);
|
|
9201
|
+
}
|
|
9202
|
+
}
|
|
9203
|
+
const presentationCount = queryIds.reduce(
|
|
9204
|
+
(sum, id) => sum + vpToken[id].length,
|
|
9205
|
+
0
|
|
9206
|
+
);
|
|
9207
|
+
if (queryIds.length > 1 || presentationCount > 1) {
|
|
9208
|
+
throw new exports.MultipleCredentialsNotSupportedError(queryIds.length, presentationCount);
|
|
9209
|
+
}
|
|
9210
|
+
const presentation = vpToken[queryIds[0]][0];
|
|
9211
|
+
return verifyPresentation(presentation, query, options);
|
|
9212
|
+
}
|
|
8934
9213
|
|
|
8935
9214
|
// src/index.ts
|
|
8936
9215
|
init_errors();
|
|
@@ -9542,7 +9821,7 @@ function equalBytes(a, b) {
|
|
|
9542
9821
|
|
|
9543
9822
|
// src/index.ts
|
|
9544
9823
|
init_errors();
|
|
9545
|
-
var VERSION = "0.
|
|
9824
|
+
var VERSION = "0.7.0";
|
|
9546
9825
|
/*! Bundled license information:
|
|
9547
9826
|
|
|
9548
9827
|
pvtsutils/build/index.es.js:
|
|
@@ -9630,9 +9909,12 @@ exports.StaticTrustStore = StaticTrustStore;
|
|
|
9630
9909
|
exports.VERSION = VERSION;
|
|
9631
9910
|
exports.buildHaipQuery = buildHaipQuery;
|
|
9632
9911
|
exports.createAuthorizationRequest = createAuthorizationRequest;
|
|
9912
|
+
exports.createSignedAuthorizationRequest = createSignedAuthorizationRequest;
|
|
9913
|
+
exports.decryptAuthorizationResponse = decryptAuthorizationResponse;
|
|
9633
9914
|
exports.isHaipQuery = isHaipQuery;
|
|
9634
9915
|
exports.parsePresentation = parsePresentation;
|
|
9635
9916
|
exports.validateHaipQuery = validateHaipQuery;
|
|
9917
|
+
exports.verifyAuthorizationResponse = verifyAuthorizationResponse;
|
|
9636
9918
|
exports.verifyPresentation = verifyPresentation;
|
|
9637
9919
|
//# sourceMappingURL=index.cjs.map
|
|
9638
9920
|
//# sourceMappingURL=index.cjs.map
|