edockit 0.2.0 → 0.2.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.
- package/CHANGELOG.md +17 -0
- package/README.md +10 -2
- package/dist/core/revocation/crl.d.ts +1 -0
- package/dist/core/revocation/fetch.d.ts +12 -3
- package/dist/core/revocation/ocsp.d.ts +3 -1
- package/dist/core/revocation/types.d.ts +8 -1
- package/dist/core/timestamp/types.d.ts +3 -1
- package/dist/index.cjs.js +43 -17
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +43 -17
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +10 -10
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -107,9 +107,16 @@ function createXMLParser() {
|
|
|
107
107
|
function queryByXPath(parent, xpathExpression, namespaces = NAMESPACES) {
|
|
108
108
|
try {
|
|
109
109
|
// Browser environment with native XPath
|
|
110
|
-
if (typeof document !== "undefined" && document.evaluate) {
|
|
110
|
+
if (typeof document !== "undefined" && typeof document.evaluate === "function") {
|
|
111
|
+
// Use the document that owns the parent node, not the global document
|
|
112
|
+
const ownerDoc = "ownerDocument" in parent ? parent.ownerDocument : parent;
|
|
113
|
+
if (!ownerDoc || typeof ownerDoc.evaluate !== "function") {
|
|
114
|
+
// XMLDocuments from DOMParser don't have evaluate - silently return null
|
|
115
|
+
// (caller should use DOM traversal fallback)
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
111
118
|
const nsResolver = createNsResolverForBrowser(namespaces);
|
|
112
|
-
const result =
|
|
119
|
+
const result = ownerDoc.evaluate(xpathExpression, parent, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
113
120
|
return result.singleNodeValue;
|
|
114
121
|
}
|
|
115
122
|
// Node.js environment with xpath module
|
|
@@ -157,9 +164,16 @@ function queryByXPath(parent, xpathExpression, namespaces = NAMESPACES) {
|
|
|
157
164
|
function queryAllByXPath(parent, xpathExpression, namespaces = NAMESPACES) {
|
|
158
165
|
try {
|
|
159
166
|
// Browser environment with native XPath
|
|
160
|
-
if (typeof document !== "undefined" && document.evaluate) {
|
|
167
|
+
if (typeof document !== "undefined" && typeof document.evaluate === "function") {
|
|
168
|
+
// Use the document that owns the parent node, not the global document
|
|
169
|
+
const ownerDoc = "ownerDocument" in parent ? parent.ownerDocument : parent;
|
|
170
|
+
if (!ownerDoc || typeof ownerDoc.evaluate !== "function") {
|
|
171
|
+
// XMLDocuments from DOMParser don't have evaluate - silently return empty
|
|
172
|
+
// (caller should use DOM traversal fallback)
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
161
175
|
const nsResolver = createNsResolverForBrowser(namespaces);
|
|
162
|
-
const result =
|
|
176
|
+
const result = ownerDoc.evaluate(xpathExpression, parent, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
163
177
|
const elements = [];
|
|
164
178
|
for (let i = 0; i < result.snapshotLength; i++) {
|
|
165
179
|
elements.push(result.snapshotItem(i));
|
|
@@ -7922,7 +7936,9 @@ __decorate([
|
|
|
7922
7936
|
* @returns FetchResult with binary data or error
|
|
7923
7937
|
*/
|
|
7924
7938
|
async function fetchBinary(url, options = {}) {
|
|
7925
|
-
const { timeout = 10000, method = "GET", body, contentType, accept } = options;
|
|
7939
|
+
const { timeout = 10000, method = "GET", body, contentType, accept, proxyUrl } = options;
|
|
7940
|
+
// Apply proxy URL if provided
|
|
7941
|
+
const fetchUrl = proxyUrl ? `${proxyUrl}${encodeURIComponent(url)}` : url;
|
|
7926
7942
|
const controller = new AbortController();
|
|
7927
7943
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
7928
7944
|
try {
|
|
@@ -7933,7 +7949,7 @@ async function fetchBinary(url, options = {}) {
|
|
|
7933
7949
|
if (accept) {
|
|
7934
7950
|
headers["Accept"] = accept;
|
|
7935
7951
|
}
|
|
7936
|
-
const response = await fetch(
|
|
7952
|
+
const response = await fetch(fetchUrl, {
|
|
7937
7953
|
method,
|
|
7938
7954
|
headers,
|
|
7939
7955
|
body: body ? new Uint8Array(body) : undefined,
|
|
@@ -7982,41 +7998,47 @@ async function fetchBinary(url, options = {}) {
|
|
|
7982
7998
|
* @param url OCSP responder URL
|
|
7983
7999
|
* @param request DER-encoded OCSP request
|
|
7984
8000
|
* @param timeout Timeout in milliseconds
|
|
8001
|
+
* @param proxyUrl Optional CORS proxy URL
|
|
7985
8002
|
* @returns FetchResult with OCSP response data
|
|
7986
8003
|
*/
|
|
7987
|
-
async function fetchOCSP(url, request, timeout = 5000) {
|
|
8004
|
+
async function fetchOCSP(url, request, timeout = 5000, proxyUrl) {
|
|
7988
8005
|
return fetchBinary(url, {
|
|
7989
8006
|
method: "POST",
|
|
7990
8007
|
body: request,
|
|
7991
8008
|
contentType: "application/ocsp-request",
|
|
7992
8009
|
accept: "application/ocsp-response",
|
|
7993
8010
|
timeout,
|
|
8011
|
+
proxyUrl,
|
|
7994
8012
|
});
|
|
7995
8013
|
}
|
|
7996
8014
|
/**
|
|
7997
8015
|
* Fetch CRL from distribution point
|
|
7998
8016
|
* @param url CRL distribution point URL
|
|
7999
8017
|
* @param timeout Timeout in milliseconds
|
|
8018
|
+
* @param proxyUrl Optional CORS proxy URL
|
|
8000
8019
|
* @returns FetchResult with CRL data
|
|
8001
8020
|
*/
|
|
8002
|
-
async function fetchCRL(url, timeout = 10000) {
|
|
8021
|
+
async function fetchCRL(url, timeout = 10000, proxyUrl) {
|
|
8003
8022
|
return fetchBinary(url, {
|
|
8004
8023
|
method: "GET",
|
|
8005
8024
|
accept: "application/pkix-crl",
|
|
8006
8025
|
timeout,
|
|
8026
|
+
proxyUrl,
|
|
8007
8027
|
});
|
|
8008
8028
|
}
|
|
8009
8029
|
/**
|
|
8010
8030
|
* Fetch issuer certificate from AIA extension
|
|
8011
8031
|
* @param url CA Issuers URL
|
|
8012
8032
|
* @param timeout Timeout in milliseconds
|
|
8033
|
+
* @param proxyUrl Optional CORS proxy URL
|
|
8013
8034
|
* @returns FetchResult with certificate data
|
|
8014
8035
|
*/
|
|
8015
|
-
async function fetchIssuerCertificate(url, timeout = 5000) {
|
|
8036
|
+
async function fetchIssuerCertificate(url, timeout = 5000, proxyUrl) {
|
|
8016
8037
|
return fetchBinary(url, {
|
|
8017
8038
|
method: "GET",
|
|
8018
8039
|
accept: "application/pkix-cert",
|
|
8019
8040
|
timeout,
|
|
8041
|
+
proxyUrl,
|
|
8020
8042
|
});
|
|
8021
8043
|
}
|
|
8022
8044
|
|
|
@@ -8173,13 +8195,14 @@ function findIssuerInChain(cert, chain) {
|
|
|
8173
8195
|
* Fetch issuer certificate from AIA extension
|
|
8174
8196
|
* @param cert Certificate to fetch issuer for
|
|
8175
8197
|
* @param timeout Timeout in ms
|
|
8198
|
+
* @param proxyUrl Optional CORS proxy URL
|
|
8176
8199
|
* @returns Issuer certificate or null
|
|
8177
8200
|
*/
|
|
8178
|
-
async function fetchIssuerFromAIA(cert, timeout = 5000) {
|
|
8201
|
+
async function fetchIssuerFromAIA(cert, timeout = 5000, proxyUrl) {
|
|
8179
8202
|
const urls = extractCAIssuersUrls(cert);
|
|
8180
8203
|
for (const url of urls) {
|
|
8181
8204
|
try {
|
|
8182
|
-
const result = await fetchIssuerCertificate(url, timeout);
|
|
8205
|
+
const result = await fetchIssuerCertificate(url, timeout, proxyUrl);
|
|
8183
8206
|
if (result.ok && result.data) {
|
|
8184
8207
|
// Try to parse as DER first, then PEM
|
|
8185
8208
|
try {
|
|
@@ -8372,7 +8395,7 @@ function parseOCSPResponse(responseData) {
|
|
|
8372
8395
|
* @returns Revocation result
|
|
8373
8396
|
*/
|
|
8374
8397
|
async function checkOCSP(cert, issuerCert, options = {}) {
|
|
8375
|
-
const { timeout = 5000, certificateChain = [] } = options;
|
|
8398
|
+
const { timeout = 5000, certificateChain = [], proxyUrl } = options;
|
|
8376
8399
|
const now = new Date();
|
|
8377
8400
|
// Get OCSP URLs
|
|
8378
8401
|
const ocspUrls = extractOCSPUrls(cert);
|
|
@@ -8393,7 +8416,7 @@ async function checkOCSP(cert, issuerCert, options = {}) {
|
|
|
8393
8416
|
}
|
|
8394
8417
|
if (!issuer) {
|
|
8395
8418
|
// Try AIA extension
|
|
8396
|
-
issuer = await fetchIssuerFromAIA(cert, timeout);
|
|
8419
|
+
issuer = await fetchIssuerFromAIA(cert, timeout, proxyUrl);
|
|
8397
8420
|
}
|
|
8398
8421
|
if (!issuer) {
|
|
8399
8422
|
return {
|
|
@@ -8421,7 +8444,7 @@ async function checkOCSP(cert, issuerCert, options = {}) {
|
|
|
8421
8444
|
// Try each OCSP URL
|
|
8422
8445
|
for (const url of ocspUrls) {
|
|
8423
8446
|
try {
|
|
8424
|
-
const result = await fetchOCSP(url, request, timeout);
|
|
8447
|
+
const result = await fetchOCSP(url, request, timeout, proxyUrl);
|
|
8425
8448
|
if (result.ok && result.data) {
|
|
8426
8449
|
return parseOCSPResponse(result.data);
|
|
8427
8450
|
}
|
|
@@ -8528,7 +8551,7 @@ function parseCRL(data) {
|
|
|
8528
8551
|
* @returns Revocation result
|
|
8529
8552
|
*/
|
|
8530
8553
|
async function checkCRL(cert, options = {}) {
|
|
8531
|
-
const { timeout = 10000 } = options;
|
|
8554
|
+
const { timeout = 10000, proxyUrl } = options;
|
|
8532
8555
|
const now = new Date();
|
|
8533
8556
|
// Get CRL URLs
|
|
8534
8557
|
const crlUrls = extractCRLUrls(cert);
|
|
@@ -8545,7 +8568,7 @@ async function checkCRL(cert, options = {}) {
|
|
|
8545
8568
|
const errors = [];
|
|
8546
8569
|
for (const url of crlUrls) {
|
|
8547
8570
|
try {
|
|
8548
|
-
const result = await fetchCRL(url, timeout);
|
|
8571
|
+
const result = await fetchCRL(url, timeout, proxyUrl);
|
|
8549
8572
|
if (!result.ok || !result.data) {
|
|
8550
8573
|
errors.push(`${url}: ${result.error || "Failed to fetch"}`);
|
|
8551
8574
|
continue;
|
|
@@ -8634,6 +8657,7 @@ async function checkCertificateRevocation(cert, options = {}) {
|
|
|
8634
8657
|
ocspResult = await checkOCSP(x509Cert, null, {
|
|
8635
8658
|
timeout: opts.ocspTimeout,
|
|
8636
8659
|
certificateChain: opts.certificateChain,
|
|
8660
|
+
proxyUrl: options.proxyUrl,
|
|
8637
8661
|
});
|
|
8638
8662
|
// If OCSP gives a definitive answer (good or revoked), use it
|
|
8639
8663
|
if (ocspResult.status === "good" || ocspResult.status === "revoked") {
|
|
@@ -8645,6 +8669,7 @@ async function checkCertificateRevocation(cert, options = {}) {
|
|
|
8645
8669
|
if (opts.crlEnabled) {
|
|
8646
8670
|
crlResult = await checkCRL(x509Cert, {
|
|
8647
8671
|
timeout: opts.crlTimeout,
|
|
8672
|
+
proxyUrl: options.proxyUrl,
|
|
8648
8673
|
});
|
|
8649
8674
|
// If CRL gives a definitive answer, use it
|
|
8650
8675
|
if (crlResult.status === "good" || crlResult.status === "revoked") {
|
|
@@ -10107,7 +10132,7 @@ async function verifyTimestamp(timestampBase64, options = {}) {
|
|
|
10107
10132
|
// Check TSA certificate revocation if requested
|
|
10108
10133
|
if (options.checkTsaRevocation !== false) {
|
|
10109
10134
|
try {
|
|
10110
|
-
tsaRevocation = await checkCertificateRevocation(tsaCert);
|
|
10135
|
+
tsaRevocation = await checkCertificateRevocation(tsaCert, options.revocationOptions);
|
|
10111
10136
|
// If TSA certificate is revoked, the timestamp is invalid
|
|
10112
10137
|
if (tsaRevocation.status === "revoked") {
|
|
10113
10138
|
return {
|
|
@@ -10515,6 +10540,7 @@ async function verifySignature(signatureInfo, files, options = {}) {
|
|
|
10515
10540
|
timestampResult = await verifyTimestamp(signatureInfo.signatureTimestamp, {
|
|
10516
10541
|
signatureValue: signatureInfo.signatureValue,
|
|
10517
10542
|
verifyTsaCertificate: true,
|
|
10543
|
+
revocationOptions: options.revocationOptions,
|
|
10518
10544
|
});
|
|
10519
10545
|
if (timestampResult.isValid && timestampResult.info) {
|
|
10520
10546
|
// Use timestamp time as the trusted signing time
|