@gerege-systems/eid-mongolia-sdk 0.15.0 → 0.15.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.
@@ -0,0 +1,1043 @@
1
+ // src/pades/bytes.ts
2
+ var enc = new TextEncoder();
3
+ function latin1(s) {
4
+ const out = new Uint8Array(s.length);
5
+ for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 255;
6
+ return out;
7
+ }
8
+ function fromLatin1(b, start = 0, end = b.length) {
9
+ let s = "";
10
+ for (let i = start; i < end; i += 32768) s += String.fromCharCode(...b.subarray(i, Math.min(end, i + 32768)));
11
+ return s;
12
+ }
13
+ function concat(parts) {
14
+ let n = 0;
15
+ for (const p of parts) n += p.length;
16
+ const out = new Uint8Array(n);
17
+ let o = 0;
18
+ for (const p of parts) {
19
+ out.set(p, o);
20
+ o += p.length;
21
+ }
22
+ return out;
23
+ }
24
+ function equal(a, b) {
25
+ if (a.length !== b.length) return false;
26
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
27
+ return true;
28
+ }
29
+ function compare(a, b) {
30
+ const n = Math.min(a.length, b.length);
31
+ for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
32
+ return a.length - b.length;
33
+ }
34
+ var HEX = "0123456789abcdef";
35
+ function toHex(b) {
36
+ let s = "";
37
+ for (const x of b) s += HEX[x >> 4] + HEX[x & 15];
38
+ return s;
39
+ }
40
+ function fromHex(s) {
41
+ if (s.length % 2 !== 0 || /[^0-9a-fA-F]/.test(s)) throw new Error("hex \u0431\u0443\u0440\u0443\u0443");
42
+ const out = new Uint8Array(s.length / 2);
43
+ for (let i = 0; i < out.length; i++) out[i] = parseInt(s.substr(i * 2, 2), 16);
44
+ return out;
45
+ }
46
+ function toB64(b) {
47
+ return btoa(fromLatin1(b));
48
+ }
49
+ function fromB64(s) {
50
+ return latin1(atob(s));
51
+ }
52
+ var ByteWriter = class {
53
+ buf = new Uint8Array(1 << 16);
54
+ len = 0;
55
+ grow(n) {
56
+ if (this.len + n <= this.buf.length) return;
57
+ let cap = this.buf.length * 2;
58
+ while (cap < this.len + n) cap *= 2;
59
+ const nb = new Uint8Array(cap);
60
+ nb.set(this.buf.subarray(0, this.len));
61
+ this.buf = nb;
62
+ }
63
+ bytes(b) {
64
+ this.grow(b.length);
65
+ this.buf.set(b, this.len);
66
+ this.len += b.length;
67
+ return this;
68
+ }
69
+ /** ASCII/latin1 мөр. */
70
+ str(s) {
71
+ this.grow(s.length);
72
+ for (let i = 0; i < s.length; i++) this.buf[this.len + i] = s.charCodeAt(i) & 255;
73
+ this.len += s.length;
74
+ return this;
75
+ }
76
+ byte(x) {
77
+ this.grow(1);
78
+ this.buf[this.len++] = x & 255;
79
+ return this;
80
+ }
81
+ /** Хуулбар. */
82
+ result() {
83
+ return this.buf.slice(0, this.len);
84
+ }
85
+ };
86
+
87
+ // src/pades/crypto.ts
88
+ var subtlePromise;
89
+ var nodeImport = (m) => import(
90
+ /* @vite-ignore */
91
+ /* webpackIgnore: true */
92
+ m
93
+ );
94
+ async function webcrypto() {
95
+ const g = globalThis.crypto;
96
+ if (g?.subtle) return g;
97
+ const m = await nodeImport("node:crypto");
98
+ if (!m.webcrypto) throw new Error("Web Crypto \u0430\u043B\u0433\u0430");
99
+ return m.webcrypto;
100
+ }
101
+ function subtle() {
102
+ subtlePromise ??= webcrypto().then((c) => c.subtle);
103
+ return subtlePromise;
104
+ }
105
+ async function randomBytes(n) {
106
+ return (await webcrypto()).getRandomValues(new Uint8Array(n));
107
+ }
108
+ async function sha256(b) {
109
+ return new Uint8Array(await (await subtle()).digest("SHA-256", b));
110
+ }
111
+ async function sha1(b) {
112
+ return new Uint8Array(await (await subtle()).digest("SHA-1", b));
113
+ }
114
+ async function digest(alg, b) {
115
+ return new Uint8Array(await (await subtle()).digest(alg, b));
116
+ }
117
+
118
+ // src/pades/asn1.ts
119
+ var Asn1Error = class extends Error {
120
+ };
121
+ var TAG = {
122
+ BOOLEAN: 1,
123
+ INTEGER: 2,
124
+ BIT_STRING: 3,
125
+ OCTET_STRING: 4,
126
+ NULL: 5,
127
+ OID: 6,
128
+ ENUMERATED: 10,
129
+ UTF8String: 12,
130
+ SEQUENCE: 48,
131
+ SET: 49,
132
+ PrintableString: 19,
133
+ IA5String: 22,
134
+ UTCTime: 23,
135
+ GeneralizedTime: 24
136
+ };
137
+ function readNode(b, off = 0) {
138
+ if (off + 2 > b.length) throw new Asn1Error("asn1: \u0434\u0443\u0442\u0443\u0443");
139
+ const tag = b[off];
140
+ if ((tag & 31) === 31) throw new Asn1Error("asn1: \u043E\u043B\u043E\u043D \u0431\u0430\u0439\u0442 tag \u0434\u044D\u043C\u0436\u0438\u0433\u0434\u044D\u0445\u0433\u04AF\u0439");
141
+ let len = b[off + 1];
142
+ let p = off + 2;
143
+ if (len & 128) {
144
+ const n = len & 127;
145
+ if (n === 0 || n > 4) throw new Asn1Error("asn1: \u0443\u0440\u0442 \u0431\u0443\u0440\u0443\u0443");
146
+ if (p + n > b.length) throw new Asn1Error("asn1: \u0434\u0443\u0442\u0443\u0443");
147
+ if (b[p] === 0) throw new Asn1Error("asn1: \u0443\u0440\u0442 minimal \u0431\u0438\u0448");
148
+ len = 0;
149
+ for (let i = 0; i < n; i++) len = len * 256 + b[p + i];
150
+ if (len < 128) throw new Asn1Error("asn1: \u0443\u0440\u0442 minimal \u0431\u0438\u0448");
151
+ p += n;
152
+ }
153
+ if (p + len > b.length) throw new Asn1Error("asn1: \u0434\u0443\u0442\u0443\u0443");
154
+ return { tag, raw: b.subarray(off, p + len), value: b.subarray(p, p + len) };
155
+ }
156
+ function parseOne(b) {
157
+ const n = readNode(b, 0);
158
+ if (n.raw.length !== b.length) throw new Asn1Error("asn1: \u0438\u043B\u04AF\u04AF \u04E9\u0433\u04E9\u0433\u0434\u04E9\u043B");
159
+ return n;
160
+ }
161
+ function children(n) {
162
+ const v = n instanceof Uint8Array ? n : n.value;
163
+ const out = [];
164
+ for (let p = 0; p < v.length; ) {
165
+ const c = readNode(v, p);
166
+ out.push(c);
167
+ p += c.raw.length;
168
+ }
169
+ return out;
170
+ }
171
+ function expect(n, tag, what) {
172
+ if (!n || n.tag !== tag) throw new Asn1Error(`asn1: ${what} \u0445\u04AF\u043B\u044D\u044D\u0441\u044D\u043D`);
173
+ return n;
174
+ }
175
+ function lenBytes(n) {
176
+ if (n < 128) return Uint8Array.of(n);
177
+ const out = [];
178
+ for (let x = n; x > 0; x = Math.floor(x / 256)) out.unshift(x & 255);
179
+ return Uint8Array.from([128 | out.length, ...out]);
180
+ }
181
+ function tlv(tag, ...content) {
182
+ const v = concat(content);
183
+ return concat([Uint8Array.of(tag), lenBytes(v.length), v]);
184
+ }
185
+ var seq = (...c) => tlv(TAG.SEQUENCE, ...c);
186
+ var set = (...c) => tlv(TAG.SET, ...c);
187
+ var octet = (b) => tlv(TAG.OCTET_STRING, b);
188
+ var nullDer = () => Uint8Array.of(5, 0);
189
+ var ctx = (n, constructed, ...c) => tlv(128 | (constructed ? 32 : 0) | n, ...c);
190
+ function oid(s) {
191
+ const parts = s.split(".").map((x) => BigInt(x));
192
+ const body = [];
193
+ const enc2 = (v) => {
194
+ const tmp = [Number(v & 0x7fn)];
195
+ for (v >>= 7n; v > 0n; v >>= 7n) tmp.unshift(Number(v & 0x7fn) | 128);
196
+ body.push(...tmp);
197
+ };
198
+ enc2(parts[0] * 40n + parts[1]);
199
+ for (const p of parts.slice(2)) enc2(p);
200
+ return tlv(TAG.OID, Uint8Array.from(body));
201
+ }
202
+ function oidString(v) {
203
+ const out = [];
204
+ let cur = 0n;
205
+ for (const b of v) {
206
+ cur = cur << 7n | BigInt(b & 127);
207
+ if (!(b & 128)) {
208
+ out.push(cur);
209
+ cur = 0n;
210
+ }
211
+ }
212
+ if (out.length === 0) return "";
213
+ const first = out[0];
214
+ const a = first < 40n ? 0n : first < 80n ? 1n : 2n;
215
+ return [a, first - a * 40n, ...out.slice(1)].join(".");
216
+ }
217
+ function intFromBig(v) {
218
+ if (v === 0n) return tlv(TAG.INTEGER, Uint8Array.of(0));
219
+ const bytes = [];
220
+ if (v > 0n) {
221
+ for (let x = v; x > 0n; x >>= 8n) bytes.unshift(Number(x & 0xffn));
222
+ if (bytes[0] & 128) bytes.unshift(0);
223
+ } else {
224
+ let x = v;
225
+ for (; ; ) {
226
+ bytes.unshift(Number(x & 0xffn));
227
+ x >>= 8n;
228
+ if (x === -1n && bytes[0] & 128) break;
229
+ }
230
+ }
231
+ return tlv(TAG.INTEGER, Uint8Array.from(bytes));
232
+ }
233
+ function bigFromBytes(b) {
234
+ let v = 0n;
235
+ for (const x of b) v = v << 8n | BigInt(x);
236
+ return v;
237
+ }
238
+ function intValue(v) {
239
+ if (v.length === 0) throw new Asn1Error("asn1: \u0445\u043E\u043E\u0441\u043E\u043D INTEGER");
240
+ let x = bigFromBytes(v);
241
+ if (v[0] & 128) x -= 1n << BigInt(v.length * 8);
242
+ return x;
243
+ }
244
+ function parseTime(n) {
245
+ const s = String.fromCharCode(...n.value);
246
+ let m;
247
+ if (n.tag === TAG.UTCTime) {
248
+ m = /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})?(Z|[+-]\d{4})$/.exec(s);
249
+ if (!m) throw new Asn1Error("asn1: UTCTime \u0431\u0443\u0440\u0443\u0443");
250
+ let y = Number(m[1]);
251
+ y += y < 50 ? 2e3 : 1900;
252
+ return mkDate(y, m[2], m[3], m[4], m[5], m[6] ?? "00", "", m[7]);
253
+ }
254
+ if (n.tag === TAG.GeneralizedTime) {
255
+ m = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d+)?(Z|[+-]\d{4})$/.exec(s);
256
+ if (!m) throw new Asn1Error("asn1: GeneralizedTime \u0431\u0443\u0440\u0443\u0443");
257
+ return mkDate(Number(m[1]), m[2], m[3], m[4], m[5], m[6], m[7] ?? "", m[8]);
258
+ }
259
+ throw new Asn1Error("asn1: \u0446\u0430\u0433 \u0445\u04AF\u043B\u044D\u044D\u0441\u044D\u043D");
260
+ }
261
+ function parsePreciseTime(n) {
262
+ const date = parseTime(n);
263
+ const m = /\.(\d+)/.exec(String.fromCharCode(...n.value));
264
+ const nanos = m ? Number((m[1] + "000000000").slice(0, 9)) : 0;
265
+ return { date, nanos };
266
+ }
267
+ function mkDate(y, mo, d, h, mi, s, frac, z) {
268
+ let t = Date.UTC(y, Number(mo) - 1, Number(d), Number(h), Number(mi), Number(s));
269
+ if (frac) t += Math.floor(Number("0" + frac) * 1e3);
270
+ if (z !== "Z") {
271
+ const off = (Number(z.slice(1, 3)) * 60 + Number(z.slice(3, 5))) * 6e4;
272
+ t += z[0] === "+" ? -off : off;
273
+ }
274
+ return new Date(t);
275
+ }
276
+
277
+ // src/pades/x509.ts
278
+ var OID = {
279
+ rsaEncryption: "1.2.840.113549.1.1.1",
280
+ rsaPSS: "1.2.840.113549.1.1.10",
281
+ sha256WithRSA: "1.2.840.113549.1.1.11",
282
+ sha384WithRSA: "1.2.840.113549.1.1.12",
283
+ sha512WithRSA: "1.2.840.113549.1.1.13",
284
+ ecPublicKey: "1.2.840.10045.2.1",
285
+ ecdsaSHA256: "1.2.840.10045.4.3.2",
286
+ ecdsaSHA384: "1.2.840.10045.4.3.3",
287
+ ecdsaSHA512: "1.2.840.10045.4.3.4",
288
+ p256: "1.2.840.10045.3.1.7",
289
+ p384: "1.3.132.0.34",
290
+ p521: "1.3.132.0.35",
291
+ sha1: "1.3.14.3.2.26",
292
+ sha256: "2.16.840.1.101.3.4.2.1",
293
+ sha384: "2.16.840.1.101.3.4.2.2",
294
+ sha512: "2.16.840.1.101.3.4.2.3",
295
+ commonName: "2.5.4.3",
296
+ surname: "2.5.4.4",
297
+ givenName: "2.5.4.42",
298
+ extKeyUsage: "2.5.29.37",
299
+ keyUsage: "2.5.29.15",
300
+ basicConstraints: "2.5.29.19",
301
+ crlDP: "2.5.29.31",
302
+ aia: "1.3.6.1.5.5.7.1.1",
303
+ ocspMethod: "1.3.6.1.5.5.7.48.1",
304
+ kpTimeStamping: "1.3.6.1.5.5.7.3.8",
305
+ kpOCSPSigning: "1.3.6.1.5.5.7.3.9",
306
+ kpAny: "2.5.29.37.0"
307
+ };
308
+ var CertError = class extends Error {
309
+ };
310
+ function bitString(n) {
311
+ expect(n, TAG.BIT_STRING, "BIT STRING");
312
+ if (n.value.length === 0) throw new Asn1Error("BIT STRING \u0445\u043E\u043E\u0441\u043E\u043D");
313
+ return n.value.subarray(1);
314
+ }
315
+ function decodeDirString(n) {
316
+ if (n.tag === 30) {
317
+ let s = "";
318
+ for (let i = 0; i + 1 < n.value.length; i += 2) s += String.fromCharCode(n.value[i] << 8 | n.value[i + 1]);
319
+ return s;
320
+ }
321
+ if (n.tag === TAG.UTF8String) return new TextDecoder().decode(n.value);
322
+ return String.fromCharCode(...n.value);
323
+ }
324
+ function nameAttrs(name) {
325
+ const out = [];
326
+ for (const rdn of children(name)) {
327
+ for (const atv of children(rdn)) {
328
+ const [t, v] = children(atv);
329
+ if (!t || !v) continue;
330
+ out.push([oidString(t.value), decodeDirString(v)]);
331
+ }
332
+ }
333
+ return out;
334
+ }
335
+ function parseCertificate(der) {
336
+ try {
337
+ const top = parseOne(der);
338
+ expect(top, TAG.SEQUENCE, "Certificate");
339
+ const [tbsN, sigAlg, sigN] = children(top);
340
+ const tbs = expect(tbsN, TAG.SEQUENCE, "TBSCertificate");
341
+ const f = children(tbs);
342
+ let i = 0;
343
+ let version = 1;
344
+ if (f[0]?.tag === 160) {
345
+ const v = expect(children(f[0])[0], TAG.INTEGER, "version");
346
+ version = v.value[0] + 1;
347
+ i++;
348
+ }
349
+ const serial = expect(f[i++], TAG.INTEGER, "serial").value;
350
+ i++;
351
+ const issuer = expect(f[i++], TAG.SEQUENCE, "issuer");
352
+ const validity = children(expect(f[i++], TAG.SEQUENCE, "validity"));
353
+ const subject = expect(f[i++], TAG.SEQUENCE, "subject");
354
+ const spki = expect(f[i++], TAG.SEQUENCE, "SPKI");
355
+ const [algN, pkN] = children(spki);
356
+ const algParts = children(expect(algN, TAG.SEQUENCE, "AlgorithmIdentifier"));
357
+ const keyAlg = oidString(expect(algParts[0], TAG.OID, "alg").value);
358
+ const curve = keyAlg === OID.ecPublicKey && algParts[1]?.tag === TAG.OID ? oidString(algParts[1].value) : void 0;
359
+ const extensions = [];
360
+ for (; i < f.length; i++) {
361
+ if (f[i].tag !== 163) continue;
362
+ for (const e of children(expect(children(f[i])[0], TAG.SEQUENCE, "extensions"))) {
363
+ const p = children(e);
364
+ const o = oidString(expect(p[0], TAG.OID, "ext oid").value);
365
+ let critical = false;
366
+ let val = p[1];
367
+ if (val?.tag === TAG.BOOLEAN) {
368
+ critical = val.value[0] !== 0;
369
+ val = p[2];
370
+ }
371
+ extensions.push({ oid: o, critical, value: expect(val, TAG.OCTET_STRING, "ext value").value });
372
+ }
373
+ }
374
+ const subj = nameAttrs(subject);
375
+ const iss = nameAttrs(issuer);
376
+ const last = (a, o) => a.filter(([k]) => k === o).map(([, v]) => v).pop() ?? "";
377
+ const cert = {
378
+ raw: top.raw,
379
+ tbs: tbs.raw,
380
+ version,
381
+ serial,
382
+ sigAlg: expect(sigAlg, TAG.SEQUENCE, "sigAlg"),
383
+ signature: bitString(sigN),
384
+ rawIssuer: issuer.raw,
385
+ rawSubject: subject.raw,
386
+ spki: spki.raw,
387
+ keyAlg,
388
+ curve,
389
+ publicKey: bitString(pkN),
390
+ notBefore: parseTime(validity[0]),
391
+ notAfter: parseTime(validity[1]),
392
+ extensions,
393
+ subjectCN: last(subj, OID.commonName),
394
+ issuerCN: last(iss, OID.commonName),
395
+ // Go SignerDisplayName: Subject.Names-ийн давталтын сүүлийн утга.
396
+ givenName: last(subj, OID.givenName),
397
+ surname: last(subj, OID.surname),
398
+ ocspServers: [],
399
+ crlDPs: [],
400
+ isCA: false,
401
+ basicConstraintsValid: false,
402
+ keyUsage: 0,
403
+ extKeyUsage: []
404
+ };
405
+ for (const e of extensions) parseExtension(cert, e);
406
+ return cert;
407
+ } catch (e) {
408
+ throw new CertError(`\u0433\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D \u0437\u0430\u0434\u0430\u0440\u0441\u0430\u043D\u0433\u04AF\u0439: ${e instanceof Error ? e.message : String(e)}`);
409
+ }
410
+ }
411
+ function parseExtension(c, e) {
412
+ const n = parseOne(e.value);
413
+ switch (e.oid) {
414
+ case OID.basicConstraints: {
415
+ c.basicConstraintsValid = true;
416
+ const p = children(n);
417
+ c.isCA = p[0]?.tag === TAG.BOOLEAN && p[0].value[0] !== 0;
418
+ break;
419
+ }
420
+ case OID.keyUsage: {
421
+ const bs = n.value;
422
+ let ku = 0;
423
+ for (let i = 1; i < bs.length; i++) {
424
+ for (let b = 0; b < 8; b++) if (bs[i] & 128 >> b) ku |= 1 << (i - 1) * 8 + b;
425
+ }
426
+ c.keyUsage = ku;
427
+ break;
428
+ }
429
+ case OID.extKeyUsage:
430
+ c.extKeyUsage = children(n).map((x) => oidString(x.value));
431
+ break;
432
+ case OID.aia:
433
+ for (const ad of children(n)) {
434
+ const [m, loc] = children(ad);
435
+ if (m && loc && oidString(m.value) === OID.ocspMethod && loc.tag === 134) c.ocspServers.push(String.fromCharCode(...loc.value));
436
+ }
437
+ break;
438
+ case OID.crlDP:
439
+ for (const dp of children(n)) {
440
+ for (const f of children(dp)) {
441
+ if (f.tag !== 160) continue;
442
+ for (const fn of children(f)) {
443
+ if (fn.tag !== 160) continue;
444
+ for (const gn of children(fn)) if (gn.tag === 134) c.crlDPs.push(String.fromCharCode(...gn.value));
445
+ }
446
+ }
447
+ }
448
+ break;
449
+ }
450
+ }
451
+ function isTSASigningCert(c) {
452
+ const ekus = c.extensions.filter((e2) => e2.oid === OID.extKeyUsage);
453
+ if (ekus.length !== 1) return false;
454
+ const e = ekus[0];
455
+ try {
456
+ const oids = children(parseOne(e.value));
457
+ return e.critical && oids.length === 1 && oids[0].tag === TAG.OID && oidString(oids[0].value) === OID.kpTimeStamping;
458
+ } catch {
459
+ return false;
460
+ }
461
+ }
462
+ var HASH_BY_OID = {
463
+ [OID.sha1]: "SHA-1",
464
+ [OID.sha256]: "SHA-256",
465
+ [OID.sha384]: "SHA-384",
466
+ [OID.sha512]: "SHA-512"
467
+ };
468
+ function schemeFor(alg) {
469
+ const p = children(alg);
470
+ const o = oidString(expect(p[0], TAG.OID, "sigAlg").value);
471
+ switch (o) {
472
+ case "1.2.840.113549.1.1.5":
473
+ return { kind: "rsa", hash: "SHA-1" };
474
+ case OID.sha256WithRSA:
475
+ return { kind: "rsa", hash: "SHA-256" };
476
+ case OID.sha384WithRSA:
477
+ return { kind: "rsa", hash: "SHA-384" };
478
+ case OID.sha512WithRSA:
479
+ return { kind: "rsa", hash: "SHA-512" };
480
+ case OID.ecdsaSHA256:
481
+ return { kind: "ecdsa", hash: "SHA-256" };
482
+ case OID.ecdsaSHA384:
483
+ return { kind: "ecdsa", hash: "SHA-384" };
484
+ case OID.ecdsaSHA512:
485
+ return { kind: "ecdsa", hash: "SHA-512" };
486
+ case OID.rsaPSS: {
487
+ let hash = "SHA-1";
488
+ let salt = 20;
489
+ for (const f of p[1] ? children(p[1]) : []) {
490
+ if (f.tag === 160) hash = HASH_BY_OID[oidString(children(children(f)[0])[0].value)] ?? hash;
491
+ if (f.tag === 162) salt = Number(children(f)[0].value[0]);
492
+ }
493
+ return { kind: "pss", hash, saltLength: salt };
494
+ }
495
+ }
496
+ throw new CertError(`\u0433\u0430\u0440\u044B\u043D \u04AF\u0441\u0433\u0438\u0439\u043D \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C \u0434\u044D\u043C\u0436\u0438\u0433\u0434\u044D\u0445\u0433\u04AF\u0439: ${o}`);
497
+ }
498
+ var CURVES = {
499
+ [OID.p256]: { name: "P-256", size: 32 },
500
+ [OID.p384]: { name: "P-384", size: 48 },
501
+ [OID.p521]: { name: "P-521", size: 66 }
502
+ };
503
+ function ecdsaDerToRaw(der, size) {
504
+ const [r, s] = children(parseOne(der));
505
+ const out = new Uint8Array(2 * size);
506
+ const put = (v, at) => {
507
+ let x = v;
508
+ while (x.length > 0 && x[0] === 0) x = x.subarray(1);
509
+ if (x.length > size) throw new CertError("ECDSA \u0443\u0442\u0433\u0430 \u0445\u044D\u0442 \u0443\u0440\u0442");
510
+ out.set(x, at + size - x.length);
511
+ };
512
+ put(expect(r, TAG.INTEGER, "r").value, 0);
513
+ put(expect(s, TAG.INTEGER, "s").value, size);
514
+ return out;
515
+ }
516
+ async function verifySignature(pub, alg, data, sig) {
517
+ const sch = schemeFor(alg);
518
+ return verifyWith(pub, sch, data, sig);
519
+ }
520
+ async function verifyWith(pub, sch, data, sig) {
521
+ const s = await subtle();
522
+ try {
523
+ if (sch.kind === "ecdsa") {
524
+ if (pub.keyAlg !== OID.ecPublicKey) return false;
525
+ const c = CURVES[pub.curve ?? ""];
526
+ if (!c) return false;
527
+ const key2 = await s.importKey("spki", pub.spki, { name: "ECDSA", namedCurve: c.name }, false, ["verify"]);
528
+ return await s.verify({ name: "ECDSA", hash: sch.hash }, key2, ecdsaDerToRaw(sig, c.size), data);
529
+ }
530
+ if (pub.keyAlg !== OID.rsaEncryption) return false;
531
+ if (sch.kind === "pss") {
532
+ const key2 = await s.importKey("spki", pub.spki, { name: "RSA-PSS", hash: sch.hash }, false, ["verify"]);
533
+ return await s.verify({ name: "RSA-PSS", saltLength: sch.saltLength ?? 32 }, key2, sig, data);
534
+ }
535
+ const key = await s.importKey("spki", pub.spki, { name: "RSASSA-PKCS1-v1_5", hash: sch.hash }, false, ["verify"]);
536
+ return await s.verify({ name: "RSASSA-PKCS1-v1_5" }, key, sig, data);
537
+ } catch {
538
+ return false;
539
+ }
540
+ }
541
+ async function verifyCitizen(cert, signedAttrs, sig) {
542
+ if (cert.keyAlg === OID.rsaEncryption) {
543
+ return await verifyWith(cert, { kind: "rsa", hash: "SHA-256" }, signedAttrs, sig) ? sig : void 0;
544
+ }
545
+ if (cert.keyAlg === OID.ecPublicKey) {
546
+ const c = CURVES[cert.curve ?? ""];
547
+ if (!c) return void 0;
548
+ if (sig.length === 2 * c.size) {
549
+ const der = rawToEcdsaDer(sig, c.size);
550
+ if (await verifyWith(cert, { kind: "ecdsa", hash: "SHA-256" }, signedAttrs, der)) return der;
551
+ }
552
+ try {
553
+ return await verifyWith(cert, { kind: "ecdsa", hash: "SHA-256" }, signedAttrs, sig) ? sig : void 0;
554
+ } catch {
555
+ return void 0;
556
+ }
557
+ }
558
+ return void 0;
559
+ }
560
+ function rawToEcdsaDer(raw, size) {
561
+ const int = (v) => {
562
+ let x = Array.from(v);
563
+ while (x.length > 1 && x[0] === 0) x = x.slice(1);
564
+ if (x.length === 1 && x[0] === 0) return [2, 1, 0];
565
+ if (x[0] & 128) x = [0, ...x];
566
+ return [2, x.length, ...x];
567
+ };
568
+ const body = [...int(raw.subarray(0, size)), ...int(raw.subarray(size))];
569
+ return Uint8Array.from(body.length < 128 ? [48, body.length, ...body] : [48, 129, body.length, ...body]);
570
+ }
571
+ function checkSignature(parent, alg, signed, sig) {
572
+ return verifySignature(parent, alg, signed, sig);
573
+ }
574
+ async function checkSignatureFrom(c, parent) {
575
+ if (parent.version === 3 && !parent.basicConstraintsValid || parent.basicConstraintsValid && !parent.isCA) return false;
576
+ if (parent.keyUsage !== 0 && !(parent.keyUsage & 1 << 5)) return false;
577
+ return verifySignature(parent, c.sigAlg, c.tbs, c.signature);
578
+ }
579
+ async function verifyChain(leaf, pool, roots, at, eku) {
580
+ const valid = (c) => c.notBefore.getTime() <= at.getTime() && at.getTime() <= c.notAfter.getTime();
581
+ if (!valid(leaf)) return false;
582
+ if (leaf.extKeyUsage.length > 0 && !leaf.extKeyUsage.includes(eku) && !leaf.extKeyUsage.includes(OID.kpAny)) return false;
583
+ if (hasUnhandledCritical(leaf)) return false;
584
+ const walk = async (cur, depth) => {
585
+ if (depth > 8) return false;
586
+ for (const r of roots) {
587
+ if (equal(r.rawSubject, cur.rawIssuer) && await checkSignatureFrom(cur, r)) return true;
588
+ }
589
+ for (const p of pool) {
590
+ if (equal(p.raw, cur.raw) || !equal(p.rawSubject, cur.rawIssuer) || !valid(p) || hasUnhandledCritical(p)) continue;
591
+ if (p.extKeyUsage.length > 0 && !p.extKeyUsage.includes(eku) && !p.extKeyUsage.includes(OID.kpAny)) continue;
592
+ if (await checkSignatureFrom(cur, p) && await walk(p, depth + 1)) return true;
593
+ }
594
+ return false;
595
+ };
596
+ return walk(leaf, 0);
597
+ }
598
+ var HANDLED = /* @__PURE__ */ new Set([
599
+ OID.keyUsage,
600
+ OID.extKeyUsage,
601
+ OID.basicConstraints,
602
+ "2.5.29.17",
603
+ // SAN
604
+ "2.5.29.30",
605
+ // name constraints
606
+ "2.5.29.32",
607
+ // policies
608
+ OID.crlDP,
609
+ OID.aia,
610
+ "2.5.29.14",
611
+ "2.5.29.35"
612
+ ]);
613
+ function hasUnhandledCritical(c) {
614
+ return c.extensions.some((e) => e.critical && !HANDLED.has(e.oid));
615
+ }
616
+
617
+ // src/pades/cms.ts
618
+ var O = {
619
+ data: "1.2.840.113549.1.7.1",
620
+ signedData: "1.2.840.113549.1.7.2",
621
+ contentType: "1.2.840.113549.1.9.3",
622
+ messageDigest: "1.2.840.113549.1.9.4",
623
+ signingTime: "1.2.840.113549.1.9.5",
624
+ signingCertV2: "1.2.840.113549.1.9.16.2.47",
625
+ timeStampToken: "1.2.840.113549.1.9.16.2.14",
626
+ signerAttrV2: "0.4.0.19122.1.1",
627
+ role: "2.5.4.72"
628
+ };
629
+ var CLAIMED_ROLE_MAX_RUNES = 900;
630
+ async function signedAttributes(messageDigest, signer, claimedRole) {
631
+ if (messageDigest.length !== 32) throw new Error("pades: messageDigest SHA-256 \u0431\u0438\u0448");
632
+ if (claimedRole !== "" && ([...claimedRole].length > CLAIMED_ROLE_MAX_RUNES || /[\ud800-\udfff]/.test(claimedRole.replace(/[\ud800-\udbff][\udc00-\udfff]/g, "")))) {
633
+ throw new Error("pades: claimed role \u0431\u0443\u0440\u0443\u0443 \u044D\u0441\u0432\u044D\u043B \u0445\u044D\u0442 \u0443\u0440\u0442");
634
+ }
635
+ const certHash = await sha256(signer.raw);
636
+ const attr = (o, ...vals) => seq(oid(o), set(...vals));
637
+ const attrs = [
638
+ attr(O.contentType, oid(O.data)),
639
+ attr(O.messageDigest, octet(messageDigest)),
640
+ attr(
641
+ O.signingCertV2,
642
+ seq(seq(seq(octet(certHash), seq(seq(ctx(4, true, signer.rawIssuer)), tlv(TAG.INTEGER, signer.serial)))))
643
+ )
644
+ ];
645
+ if (claimedRole !== "") {
646
+ attrs.push(attr(O.signerAttrV2, seq(ctx(0, true, seq(seq(oid(O.role), set(tlv(TAG.UTF8String, enc.encode(claimedRole)))))))));
647
+ }
648
+ attrs.sort(compare);
649
+ return set(...attrs);
650
+ }
651
+ function assembleCMS(signedAttrs, signer, chain, signature, tst) {
652
+ if (signedAttrs.length < 2 || signedAttrs[0] !== 49) throw new Error("pades: signedAttrs \u043D\u044C DER SET \u0431\u0438\u0448");
653
+ let sigAlg;
654
+ if (signer.keyAlg === OID.rsaEncryption) sigAlg = seq(oid(OID.sha256WithRSA), nullDer());
655
+ else if (signer.keyAlg === OID.ecPublicKey) sigAlg = seq(oid(OID.ecdsaSHA256));
656
+ else throw new Error("pades: \u0433\u0430\u0440\u044B\u043D \u04AF\u0441\u0433\u0438\u0439\u043D \u0442\u04AF\u043B\u0445\u04AF\u04AF\u0440\u0438\u0439\u043D \u0442\u04E9\u0440\u04E9\u043B \u0434\u044D\u043C\u0436\u0438\u0433\u0434\u044D\u0445\u0433\u04AF\u0439");
657
+ const implicitAttrs = signedAttrs.slice();
658
+ implicitAttrs[0] = 160;
659
+ const certs = [signer.raw];
660
+ for (const c of chain) if (!equal(c.raw, signer.raw)) certs.push(c.raw);
661
+ certs.sort(compare);
662
+ const sha256Alg = seq(oid(OID.sha256));
663
+ const unsigned = tst.length > 0 ? [ctx(1, true, seq(oid(O.timeStampToken), set(tst)))] : [];
664
+ const signerInfo = seq(
665
+ intFromBig(1n),
666
+ seq(signer.rawIssuer, tlv(TAG.INTEGER, signer.serial)),
667
+ sha256Alg,
668
+ implicitAttrs,
669
+ sigAlg,
670
+ octet(signature),
671
+ ...unsigned
672
+ );
673
+ const sd = seq(intFromBig(1n), set(sha256Alg), seq(oid(O.data)), ctx(0, true, ...certs), set(signerInfo));
674
+ return seq(oid(O.signedData), ctx(0, true, sd));
675
+ }
676
+ function parseSignedData(contentInfo) {
677
+ const ci = children(expect(parseOne(contentInfo), TAG.SEQUENCE, "ContentInfo"));
678
+ if (oidString(expect(ci[0], TAG.OID, "contentType").value) !== O.signedData) throw new Error("pkcs7: SignedData \u0431\u0438\u0448");
679
+ const sd = children(expect(children(expect(ci[1], 160, "[0]"))[0], TAG.SEQUENCE, "SignedData"));
680
+ let i = 1;
681
+ const digestAlgs = children(expect(sd[i++], TAG.SET, "digestAlgorithms"));
682
+ const eci = children(expect(sd[i++], TAG.SEQUENCE, "EncapsulatedContentInfo"));
683
+ let content = new Uint8Array();
684
+ if (eci[1]) {
685
+ const inner = children(expect(eci[1], 160, "eContent"))[0];
686
+ if (inner?.tag === TAG.OCTET_STRING) content = inner.value;
687
+ else if (inner?.tag === 36) content = concat(children(inner).map((x) => x.value));
688
+ }
689
+ const certificates = [];
690
+ if (sd[i]?.tag === 160) {
691
+ for (const c of children(sd[i])) if (c.tag === TAG.SEQUENCE) certificates.push(parseCertificate(c.raw));
692
+ i++;
693
+ }
694
+ if (sd[i]?.tag === 161) i++;
695
+ const signerInfos = children(expect(sd[i], TAG.SET, "signerInfos"));
696
+ return { content, certificates, signerInfos, digestAlgs };
697
+ }
698
+ var HASHES = {
699
+ [OID.sha1]: "SHA-1",
700
+ [OID.sha256]: "SHA-256",
701
+ [OID.sha384]: "SHA-384",
702
+ [OID.sha512]: "SHA-512"
703
+ };
704
+ function signerCert(sd, si) {
705
+ const f = children(si);
706
+ const sid = f[1];
707
+ if (sid.tag === TAG.SEQUENCE) {
708
+ const [iss, ser] = children(sid);
709
+ return sd.certificates.find((c) => equal(c.rawIssuer, iss.raw) && equal(c.serial, ser.value));
710
+ }
711
+ return void 0;
712
+ }
713
+ async function verifySignedData(sd) {
714
+ if (sd.signerInfos.length === 0) return false;
715
+ for (const si of sd.signerInfos) {
716
+ const cert = signerCert(sd, si);
717
+ if (!cert) return false;
718
+ const f = children(si);
719
+ let i = 2;
720
+ const digAlg = oidString(children(f[i++])[0].value);
721
+ const hash = HASHES[digAlg];
722
+ if (!hash) return false;
723
+ let attrs;
724
+ if (f[i]?.tag === 160) attrs = f[i++];
725
+ const sigAlg = f[i++];
726
+ const sig = expect(f[i++], TAG.OCTET_STRING, "signature").value;
727
+ let signed = sd.content;
728
+ if (attrs) {
729
+ let md;
730
+ let signingTime;
731
+ for (const a of children(attrs)) {
732
+ const [t, v] = children(a);
733
+ if (!t || !v) continue;
734
+ const o = oidString(t.value);
735
+ if (o === O.messageDigest) md = children(v)[0]?.value;
736
+ if (o === O.signingTime) {
737
+ const n = children(v)[0];
738
+ if (n) signingTime = parseTime(n);
739
+ }
740
+ }
741
+ if (!md || !equal(md, await digest(hash, sd.content))) return false;
742
+ if (signingTime && (signingTime > cert.notAfter || signingTime < cert.notBefore)) return false;
743
+ signed = concat([Uint8Array.of(49), attrs.raw.subarray(1)]);
744
+ }
745
+ let alg = sigAlg;
746
+ const so = oidString(children(sigAlg)[0].value);
747
+ if (so === OID.rsaEncryption) {
748
+ const m = { "SHA-1": "1.2.840.113549.1.1.5", "SHA-256": OID.sha256WithRSA, "SHA-384": OID.sha384WithRSA, "SHA-512": OID.sha512WithRSA };
749
+ alg = parseOne(seq(oid(m[hash]), nullDer()));
750
+ } else if (so === OID.ecPublicKey) {
751
+ const m = { "SHA-256": OID.ecdsaSHA256, "SHA-384": OID.ecdsaSHA384, "SHA-512": OID.ecdsaSHA512 };
752
+ if (!m[hash]) return false;
753
+ alg = parseOne(seq(oid(m[hash])));
754
+ }
755
+ if (!await verifySignature(cert, alg, signed, sig)) return false;
756
+ }
757
+ return true;
758
+ }
759
+
760
+ // src/pades/ltv.ts
761
+ var MAX_TSA_SKEW_MS = 10 * 6e4;
762
+ var tsMs = (t) => t.date.getTime();
763
+ function after(a, b) {
764
+ const am = Math.floor(a.date.getTime() / 1e3);
765
+ const bm = Math.floor(b.date.getTime() / 1e3);
766
+ if (am !== bm) return am > bm;
767
+ return a.nanos > b.nanos;
768
+ }
769
+ function tsaRequest(hash, nonce) {
770
+ return seq(intFromBig(1n), seq(seq(oid(OID.sha256), nullDer()), octet(hash)), intFromBig(bigFromBytes(nonce)), Uint8Array.of(1, 1, 255));
771
+ }
772
+ async function timestampToken(f, tsaURL, signature, roots, inter, now, nonce) {
773
+ const sum = await sha256(signature);
774
+ const body = await f.do("POST", tsaURL, "application/timestamp-query", tsaRequest(sum, nonce));
775
+ const top = children(expect(parseOne(body), TAG.SEQUENCE, "TimeStampResp"));
776
+ const status = intValue(expect(children(expect(top[0], TAG.SEQUENCE, "PKIStatusInfo"))[0], TAG.INTEGER, "status").value);
777
+ if (status > 0n) throw new Error(`TSA status ${status}`);
778
+ const tok = top[1];
779
+ if (!tok || tok.value.length === 0) throw new Error("no pkcs7 data in Time-Stamp response");
780
+ const rawToken = tok.raw;
781
+ const sd = parseSignedData(rawToken);
782
+ if (sd.certificates.length > 0 && !await verifySignedData(sd)) throw new Error("TSA token-\u0438\u0439\u043D \u0433\u0430\u0440\u044B\u043D \u04AF\u0441\u044D\u0433 \u0431\u0443\u0440\u0443\u0443");
783
+ const info = children(expect(parseOne(sd.content), TAG.SEQUENCE, "TSTInfo"));
784
+ const mi = children(expect(info[2], TAG.SEQUENCE, "messageImprint"));
785
+ const hashAlg = oidString(children(mi[0])[0].value);
786
+ const hashed = expect(mi[1], TAG.OCTET_STRING, "hashedMessage").value;
787
+ if (hashed.length === 0) throw new Error("Time-Stamp response contains no hashed message");
788
+ const genTime = parsePreciseTime(expect(info[4], TAG.GeneralizedTime, "genTime"));
789
+ let tsNonce;
790
+ for (const n of info.slice(5)) if (n.tag === TAG.INTEGER) tsNonce = n.value;
791
+ if (!tsNonce || intValue(tsNonce) !== bigFromBytes(nonce)) throw new Error("nonce \u0442\u0430\u0430\u0440\u0430\u0445\u0433\u04AF\u0439");
792
+ if (!equal(hashed, sum) || hashAlg !== OID.sha256) throw new Error("timestamp hash does not match");
793
+ if (sd.signerInfos.length !== 1) throw new Error("TSA signer \u0433\u0430\u043D\u0446 \u0431\u0438\u0448");
794
+ const sid = children(sd.signerInfos[0])[1];
795
+ const [iss, ser] = children(sid);
796
+ const signer = sd.certificates.find((c) => equal(c.rawIssuer, iss.raw) && equal(c.serial, ser.value));
797
+ if (!signer) throw new Error("signer cert \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
798
+ if (!isTSASigningCert(signer)) throw new Error("signer cert-\u0438\u0439\u043D EKU \u043D\u044C critical {timeStamping} \u0431\u0438\u0448 (RFC 3161 \xA72.3)");
799
+ const pool = [...sd.certificates, ...inter].filter((c) => !equal(c.raw, signer.raw));
800
+ if (!await verifyChain(signer, pool, roots, genTime.date, OID.kpTimeStamping)) throw new Error("TSA cert \u0433\u0438\u043D\u0436");
801
+ const d = now.getTime() - tsMs(genTime);
802
+ if (d > MAX_TSA_SKEW_MS || d < -MAX_TSA_SKEW_MS) throw new Error("TSA genTime \u043B\u043E\u043A\u0430\u043B \u0446\u0430\u0433\u0430\u0430\u0441 10 \u043C\u0438\u043D\u0443\u0442\u0430\u0430\u0441 \u0438\u0445 \u0437\u04E9\u0440\u04E9\u0432");
803
+ if (sd.certificates.length === 0) throw new Error("TSA token-\u0434 \u0433\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D \u0430\u043B\u0433\u0430");
804
+ return { rawToken, time: genTime, certificates: sd.certificates };
805
+ }
806
+ async function ocspRequest(c, issuer) {
807
+ const keyHash = await sha1(issuer.publicKey);
808
+ const nameHash = await sha1(issuer.rawSubject);
809
+ const certID = seq(seq(oid(OID.sha1), nullDer()), octet(nameHash), octet(keyHash), Uint8Array.of(TAG.INTEGER, ...lenOf(c.serial.length), ...c.serial));
810
+ return seq(seq(seq(seq(certID))));
811
+ }
812
+ function lenOf(n) {
813
+ if (n < 128) return [n];
814
+ const out = [];
815
+ for (let x = n; x > 0; x = Math.floor(x / 256)) out.unshift(x & 255);
816
+ return [128 | out.length, ...out];
817
+ }
818
+ var OID_OCSP_BASIC = "1.3.6.1.5.5.7.48.1.1";
819
+ async function parseOCSPForCert(der, c, issuer) {
820
+ const top = children(expect(parseOne(der), TAG.SEQUENCE, "OCSPResponse"));
821
+ if (expect(top[0], TAG.ENUMERATED, "status").value[0] !== 0) throw new Error("OCSP response status");
822
+ const rb = children(expect(children(expect(top[1], 160, "responseBytes"))[0], TAG.SEQUENCE, "ResponseBytes"));
823
+ if (oidString(expect(rb[0], TAG.OID, "responseType").value) !== OID_OCSP_BASIC) throw new Error("bad OCSP response type");
824
+ const basic = children(expect(parseOne(expect(rb[1], TAG.OCTET_STRING, "response").value), TAG.SEQUENCE, "BasicOCSPResponse"));
825
+ const tbs = expect(basic[0], TAG.SEQUENCE, "tbsResponseData");
826
+ const sigAlg = expect(basic[1], TAG.SEQUENCE, "sigAlg");
827
+ const sigBits = expect(basic[2], TAG.BIT_STRING, "signature").value.subarray(1);
828
+ const tf = children(tbs);
829
+ let i = 0;
830
+ if (tf[0]?.tag === 160) i++;
831
+ const rid = tf[i++];
832
+ if (rid.tag !== 161 && rid.tag !== 162) throw new Error("invalid responder id tag");
833
+ i++;
834
+ const responses = children(expect(tf[i], TAG.SEQUENCE, "responses"));
835
+ if (responses.length === 0) throw new Error("OCSP response contains bad number of responses");
836
+ const serial = intValue(c.serial);
837
+ let single;
838
+ for (const r of responses) {
839
+ const f = children(r);
840
+ const cid2 = children(f[0]);
841
+ if (intValue(expect(cid2[3], TAG.INTEGER, "serial").value) === serial) {
842
+ single = f;
843
+ break;
844
+ }
845
+ }
846
+ if (!single) throw new Error("no response matching the supplied certificate");
847
+ let certificate;
848
+ if (basic[3]?.tag === 160) {
849
+ const certs = children(expect(children(basic[3])[0], TAG.SEQUENCE, "certs"));
850
+ if (certs[0]) certificate = parseCertificate(certs[0].raw);
851
+ }
852
+ if (certificate) {
853
+ if (!await verifySignature(certificate, sigAlg, tbs.raw, sigBits)) throw new Error("bad signature on embedded certificate");
854
+ if (!await checkSignature(issuer, certificate.sigAlg, certificate.tbs, certificate.signature)) throw new Error("bad OCSP signature");
855
+ } else if (!await verifySignature(issuer, sigAlg, tbs.raw, sigBits)) {
856
+ throw new Error("bad OCSP signature");
857
+ }
858
+ const cid = children(single[0]);
859
+ const hashAlg = oidString(children(cid[0])[0].value);
860
+ if (![OID.sha1, OID.sha256, OID.sha384, OID.sha512].includes(hashAlg)) throw new Error("unsupported issuer hash algorithm");
861
+ const st = single[1];
862
+ const status = st.tag === 128 ? "good" : st.tag === 161 ? "revoked" : st.tag === 130 ? "unknown" : void 0;
863
+ if (!status) throw new Error("OCSP certStatus");
864
+ const thisUpdate = parsePreciseTime(expect(single[2], TAG.GeneralizedTime, "thisUpdate"));
865
+ let nextUpdate;
866
+ for (const x of single.slice(3)) {
867
+ if (x.tag === 160) nextUpdate = parsePreciseTime(children(x)[0]).date;
868
+ if (x.tag === 161) {
869
+ for (const ext of children(children(x)[0])) {
870
+ const e = children(ext);
871
+ if (e[1]?.tag === TAG.BOOLEAN && e[1].value[0] !== 0) throw new Error("unsupported critical extension");
872
+ }
873
+ }
874
+ }
875
+ return { status, thisUpdate, nextUpdate, certificate };
876
+ }
877
+ function responderOK(resp, issuer) {
878
+ if (!resp.certificate || equal(resp.certificate.raw, issuer.raw)) return true;
879
+ return resp.certificate.extKeyUsage.includes(OID.kpOCSPSigning);
880
+ }
881
+ var NotFresh = class extends Error {
882
+ };
883
+ async function fetchOCSP(f, url, c, issuer, now, fresh) {
884
+ const der = await f.do("POST", url, "application/ocsp-request", await ocspRequest(c, issuer));
885
+ const resp = await parseOCSPForCert(der, c, issuer);
886
+ if (!responderOK(resp, issuer)) throw new Error("OCSP responder-\u0438\u0439\u043D EKU OCSPSigning \u0431\u0438\u0448");
887
+ if (resp.status !== "good" || resp.nextUpdate && resp.nextUpdate.getTime() < now.getTime()) throw new Error(`OCSP ${c.subjectCN}: ${resp.status}`);
888
+ if (fresh && !after(resp.thisUpdate, fresh)) throw new NotFresh("OCSP thisUpdate \u043D\u044C timestamp-\u0430\u0430\u0441 \u0445\u043E\u0436\u0443\u0443 \u0431\u0438\u0448");
889
+ return [der, resp];
890
+ }
891
+ async function crlCovers(der, c, issuer, now) {
892
+ try {
893
+ const top = children(expect(parseOne(der), TAG.SEQUENCE, "CertificateList"));
894
+ const tbs = expect(top[0], TAG.SEQUENCE, "TBSCertList");
895
+ const sigAlg = expect(top[1], TAG.SEQUENCE, "sigAlg");
896
+ const sig = expect(top[2], TAG.BIT_STRING, "sig").value.subarray(1);
897
+ const f = children(tbs);
898
+ let i = 0;
899
+ if (f[0]?.tag === TAG.INTEGER) i++;
900
+ i++;
901
+ const iss = expect(f[i++], TAG.SEQUENCE, "issuer");
902
+ if (!equal(iss.raw, c.rawIssuer)) return false;
903
+ if (issuer.version === 3 && !issuer.basicConstraintsValid) return false;
904
+ if (issuer.keyUsage !== 0 && !(issuer.keyUsage & 1 << 6)) return false;
905
+ if (!await verifySignature(issuer, sigAlg, tbs.raw, sig)) return false;
906
+ i++;
907
+ const nu = f[i];
908
+ if (!nu || nu.tag !== TAG.UTCTime && nu.tag !== TAG.GeneralizedTime) return false;
909
+ if (parsePreciseTime(nu).date.getTime() < now.getTime()) return false;
910
+ i++;
911
+ const serial = intValue(c.serial);
912
+ const revoked = f[i];
913
+ if (revoked?.tag === TAG.SEQUENCE) {
914
+ for (const e of children(revoked)) {
915
+ if (intValue(expect(children(e)[0], TAG.INTEGER, "serial").value) === serial) return false;
916
+ }
917
+ }
918
+ return true;
919
+ } catch {
920
+ return false;
921
+ }
922
+ }
923
+ async function collectLTV(f, now, fresh, roots, chains) {
924
+ const d = { certs: [], ocsps: [], crls: [] };
925
+ const addTo = (list, der) => {
926
+ if (!list.some((b) => equal(b, der))) list.push(der);
927
+ };
928
+ const pool = chains.flat();
929
+ const issuerOf = async (c) => {
930
+ for (const cand of [...pool, ...roots]) if (equal(cand.rawSubject, c.rawIssuer) && await checkSignatureFrom(c, cand)) return cand;
931
+ return void 0;
932
+ };
933
+ const isRoot = (c) => roots.some((r) => equal(r.raw, c.raw));
934
+ const seen = /* @__PURE__ */ new Set();
935
+ for (const ch of chains) {
936
+ for (let i = 0; i < ch.length; i++) {
937
+ const c = ch[i];
938
+ const k = toHex(c.raw);
939
+ if (seen.has(k) || isRoot(c)) continue;
940
+ seen.add(k);
941
+ addTo(d.certs, c.raw);
942
+ const issuer = await issuerOf(c);
943
+ if (!issuer) throw new LTVError(`${c.subjectCN}-\u0438\u0439\u043D \u043E\u043B\u0433\u043E\u0433\u0447 \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`);
944
+ let ok = false;
945
+ let freshErr;
946
+ const fr = i === 0 ? fresh : void 0;
947
+ for (const u of c.ocspServers) {
948
+ try {
949
+ const [der, resp] = await fetchOCSP(f, u, c, issuer, now, fr);
950
+ addTo(d.ocsps, der);
951
+ if (resp.certificate && !equal(resp.certificate.raw, issuer.raw)) addTo(d.certs, resp.certificate.raw);
952
+ ok = true;
953
+ break;
954
+ } catch (e) {
955
+ if (e instanceof NotFresh) freshErr = e;
956
+ }
957
+ }
958
+ for (const u of c.crlDPs) {
959
+ let der;
960
+ try {
961
+ der = await f.do("GET", u, "");
962
+ } catch {
963
+ continue;
964
+ }
965
+ if (await crlCovers(der, c, issuer, now)) {
966
+ addTo(d.crls, der);
967
+ ok = true;
968
+ }
969
+ }
970
+ if (!ok) {
971
+ if (freshErr) throw freshErr;
972
+ throw new LTVError(`${c.subjectCN}-\u0434 \u0445\u04AF\u0447\u0438\u043D\u0442\u044D\u0439 OCSP/CRL \u0430\u043B\u0433\u0430`);
973
+ }
974
+ if (i === 0 && freshErr && c.ocspServers.length > 0 && !await hasFreshOCSP(d.ocsps, c, issuer, fresh)) throw freshErr;
975
+ }
976
+ }
977
+ return d;
978
+ }
979
+ async function hasFreshOCSP(list, c, issuer, fresh) {
980
+ for (const der of list) {
981
+ try {
982
+ if (after((await parseOCSPForCert(der, c, issuer)).thisUpdate, fresh)) return true;
983
+ } catch {
984
+ }
985
+ }
986
+ return false;
987
+ }
988
+ var LTVError = class extends Error {
989
+ };
990
+ var OCSP_AFTER_TS_MS = 2e3;
991
+ var OCSP_WAIT_MAX_MS = 5e3;
992
+ var OCSP_RETRY_MS = 1e3;
993
+ async function collectLTVWithWait(f, now, sleep, genTime, roots, chains) {
994
+ let waited = 0;
995
+ const genSec = Math.floor(genTime.date.getTime() / 1e3) * 1e3;
996
+ let d = Math.min(genSec + OCSP_AFTER_TS_MS - now().getTime(), OCSP_WAIT_MAX_MS);
997
+ for (; ; ) {
998
+ if (d > 0) {
999
+ await sleep(d);
1000
+ waited += d;
1001
+ }
1002
+ try {
1003
+ return await collectLTV(f, now(), genTime, roots, chains);
1004
+ } catch (e) {
1005
+ if (!(e instanceof NotFresh) || waited + OCSP_RETRY_MS > OCSP_WAIT_MAX_MS) throw e;
1006
+ }
1007
+ d = OCSP_RETRY_MS;
1008
+ }
1009
+ }
1010
+
1011
+ export {
1012
+ enc,
1013
+ latin1,
1014
+ fromLatin1,
1015
+ concat,
1016
+ equal,
1017
+ toHex,
1018
+ fromHex,
1019
+ toB64,
1020
+ fromB64,
1021
+ ByteWriter,
1022
+ TAG,
1023
+ readNode,
1024
+ children,
1025
+ oidString,
1026
+ randomBytes,
1027
+ sha256,
1028
+ sha1,
1029
+ OID,
1030
+ parseCertificate,
1031
+ verifyCitizen,
1032
+ checkSignatureFrom,
1033
+ CLAIMED_ROLE_MAX_RUNES,
1034
+ signedAttributes,
1035
+ assembleCMS,
1036
+ parseSignedData,
1037
+ verifySignedData,
1038
+ timestampToken,
1039
+ ocspRequest,
1040
+ parseOCSPForCert,
1041
+ LTVError,
1042
+ collectLTVWithWait
1043
+ };