@php-wasm/web 1.0.4 → 1.0.6
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/index.js +2399 -234
- package/lib/index.d.ts +2 -0
- package/lib/load-runtime.d.ts +2 -2
- package/lib/tcp-over-fetch-websocket.d.ts +108 -0
- package/lib/tls/1_2/connection.d.ts +194 -0
- package/lib/tls/1_2/prf.d.ts +7 -0
- package/lib/tls/1_2/types.d.ts +223 -0
- package/lib/tls/certificates.d.ts +199 -0
- package/lib/tls/cipher-suites.d.ts +210 -0
- package/lib/tls/extensions/0_server_name.d.ts +33 -0
- package/lib/tls/extensions/10_supported_groups.d.ts +44 -0
- package/lib/tls/extensions/11_ec_point_formats.d.ts +45 -0
- package/lib/tls/extensions/13_signature_algorithms.d.ts +74 -0
- package/lib/tls/extensions/parse-extensions.d.ts +66 -0
- package/lib/tls/extensions/types.d.ts +62 -0
- package/lib/tls/utils.d.ts +28 -0
- package/package.json +6 -6
- package/php/asyncify/7_0_33/php_7_0.wasm +0 -0
- package/php/asyncify/7_1_30/php_7_1.wasm +0 -0
- package/php/asyncify/7_2_34/php_7_2.wasm +0 -0
- package/php/asyncify/7_3_33/php_7_3.wasm +0 -0
- package/php/asyncify/7_4_33/php_7_4.wasm +0 -0
- package/php/asyncify/8_0_30/php_8_0.wasm +0 -0
- package/php/asyncify/8_1_23/php_8_1.wasm +0 -0
- package/php/asyncify/8_2_10/php_8_2.wasm +0 -0
- package/php/asyncify/8_3_0/php_8_3.wasm +0 -0
- package/php/asyncify/php_7_0.js +3 -3
- package/php/asyncify/php_7_1.js +3 -3
- package/php/asyncify/php_7_2.js +3 -3
- package/php/asyncify/php_7_3.js +3 -3
- package/php/asyncify/php_7_4.js +3 -3
- package/php/asyncify/php_8_0.js +3 -3
- package/php/asyncify/php_8_1.js +3 -3
- package/php/asyncify/php_8_2.js +3 -3
- package/php/asyncify/php_8_3.js +3 -3
- package/php/jspi/7_0_33/php_7_0.wasm +0 -0
- package/php/jspi/7_1_30/php_7_1.wasm +0 -0
- package/php/jspi/7_2_34/php_7_2.wasm +0 -0
- package/php/jspi/7_3_33/php_7_3.wasm +0 -0
- package/php/jspi/7_4_33/php_7_4.wasm +0 -0
- package/php/jspi/8_0_30/php_8_0.wasm +0 -0
- package/php/jspi/8_1_23/php_8_1.wasm +0 -0
- package/php/jspi/8_2_10/php_8_2.wasm +0 -0
- package/php/jspi/8_3_0/php_8_3.wasm +0 -0
- package/php/jspi/php_7_0.js +2 -2
- package/php/jspi/php_7_1.js +2 -2
- package/php/jspi/php_7_2.js +2 -2
- package/php/jspi/php_7_3.js +2 -2
- package/php/jspi/php_7_4.js +2 -2
- package/php/jspi/php_8_0.js +2 -2
- package/php/jspi/php_8_1.js +2 -2
- package/php/jspi/php_8_2.js +2 -2
- package/php/jspi/php_8_3.js +2 -2
package/index.js
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
import { PHPResponse as
|
|
2
|
-
import * as
|
|
3
|
-
import { jspi as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { journalFSEvents as
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
return new Proxy(
|
|
11
|
-
get: (i,
|
|
1
|
+
import { PHPResponse as we, LatestSupportedPHPVersion as Le, loadPHPRuntime as me, FSHelpers as B, __private__dont__use as k } from "@php-wasm/universal";
|
|
2
|
+
import * as E from "comlink";
|
|
3
|
+
import { jspi as ye } from "wasm-feature-detect";
|
|
4
|
+
import { logger as b } from "@php-wasm/logger";
|
|
5
|
+
import { Semaphore as ge, joinPaths as se } from "@php-wasm/util";
|
|
6
|
+
import { journalFSEvents as Ke } from "@php-wasm/fs-journal";
|
|
7
|
+
function _t(s, e = void 0) {
|
|
8
|
+
ie();
|
|
9
|
+
const t = s instanceof Worker ? s : E.windowEndpoint(s, e), r = E.wrap(t), n = x(r);
|
|
10
|
+
return new Proxy(n, {
|
|
11
|
+
get: (i, _) => _ === "isConnected" ? async () => {
|
|
12
12
|
for (; ; )
|
|
13
13
|
try {
|
|
14
|
-
await
|
|
14
|
+
await Ie(r.isConnected(), 200);
|
|
15
15
|
break;
|
|
16
16
|
} catch {
|
|
17
17
|
}
|
|
18
|
-
} :
|
|
18
|
+
} : r[_]
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
async function
|
|
22
|
-
return new Promise((
|
|
23
|
-
setTimeout(
|
|
21
|
+
async function Ie(s, e) {
|
|
22
|
+
return new Promise((t, r) => {
|
|
23
|
+
setTimeout(r, e), s.then(t);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
let
|
|
30
|
-
const i = new Promise((c,
|
|
31
|
-
|
|
32
|
-
}),
|
|
33
|
-
get: (c,
|
|
26
|
+
function at(s, e) {
|
|
27
|
+
ie();
|
|
28
|
+
const t = Promise.resolve();
|
|
29
|
+
let r, n;
|
|
30
|
+
const i = new Promise((c, S) => {
|
|
31
|
+
r = c, n = S;
|
|
32
|
+
}), _ = x(s), a = new Proxy(_, {
|
|
33
|
+
get: (c, S) => S === "isConnected" ? () => t : S === "isReady" ? () => i : S in c ? c[S] : e == null ? void 0 : e[S]
|
|
34
34
|
});
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
typeof window < "u" ?
|
|
38
|
-
), [n, a
|
|
39
|
-
}
|
|
40
|
-
let
|
|
41
|
-
function
|
|
42
|
-
if (
|
|
35
|
+
return E.expose(
|
|
36
|
+
a,
|
|
37
|
+
typeof window < "u" ? E.windowEndpoint(self.parent) : void 0
|
|
38
|
+
), [r, n, a];
|
|
39
|
+
}
|
|
40
|
+
let F = !1;
|
|
41
|
+
function ie() {
|
|
42
|
+
if (F)
|
|
43
43
|
return;
|
|
44
|
-
|
|
45
|
-
canHandle: (
|
|
46
|
-
serialize: (
|
|
44
|
+
F = !0, E.transferHandlers.set("EVENT", {
|
|
45
|
+
canHandle: (t) => t instanceof CustomEvent,
|
|
46
|
+
serialize: (t) => [
|
|
47
47
|
{
|
|
48
|
-
detail:
|
|
48
|
+
detail: t.detail
|
|
49
49
|
},
|
|
50
50
|
[]
|
|
51
51
|
],
|
|
52
|
-
deserialize: (
|
|
53
|
-
}),
|
|
54
|
-
canHandle: (
|
|
55
|
-
serialize(
|
|
56
|
-
const { port1:
|
|
57
|
-
return
|
|
52
|
+
deserialize: (t) => t
|
|
53
|
+
}), E.transferHandlers.set("FUNCTION", {
|
|
54
|
+
canHandle: (t) => typeof t == "function",
|
|
55
|
+
serialize(t) {
|
|
56
|
+
const { port1: r, port2: n } = new MessageChannel();
|
|
57
|
+
return E.expose(t, r), [n, [n]];
|
|
58
58
|
},
|
|
59
|
-
deserialize(
|
|
60
|
-
return
|
|
59
|
+
deserialize(t) {
|
|
60
|
+
return t.start(), E.wrap(t);
|
|
61
61
|
}
|
|
62
|
-
}),
|
|
63
|
-
canHandle: (
|
|
64
|
-
serialize(
|
|
65
|
-
return [
|
|
62
|
+
}), E.transferHandlers.set("PHPResponse", {
|
|
63
|
+
canHandle: (t) => typeof t == "object" && t !== null && "headers" in t && "bytes" in t && "errors" in t && "exitCode" in t && "httpStatusCode" in t,
|
|
64
|
+
serialize(t) {
|
|
65
|
+
return [t.toRawData(), []];
|
|
66
66
|
},
|
|
67
|
-
deserialize(
|
|
68
|
-
return
|
|
67
|
+
deserialize(t) {
|
|
68
|
+
return we.fromRawData(t);
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
return
|
|
71
|
+
const s = E.transferHandlers.get("throw"), e = s == null ? void 0 : s.serialize;
|
|
72
|
+
s.serialize = ({ value: t }) => {
|
|
73
|
+
const r = e({ value: t });
|
|
74
|
+
return t.response && (r[0].value.response = t.response), t.source && (r[0].value.source = t.source), r;
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
return new Proxy(
|
|
79
|
-
get(
|
|
80
|
-
switch (typeof t
|
|
77
|
+
function x(s) {
|
|
78
|
+
return new Proxy(s, {
|
|
79
|
+
get(e, t) {
|
|
80
|
+
switch (typeof e[t]) {
|
|
81
81
|
case "function":
|
|
82
|
-
return (...
|
|
82
|
+
return (...r) => e[t](...r);
|
|
83
83
|
case "object":
|
|
84
|
-
return t
|
|
84
|
+
return e[t] === null ? e[t] : x(e[t]);
|
|
85
85
|
case "undefined":
|
|
86
86
|
case "number":
|
|
87
87
|
case "string":
|
|
88
|
-
return t
|
|
88
|
+
return e[t];
|
|
89
89
|
default:
|
|
90
|
-
return
|
|
90
|
+
return E.proxy(e[t]);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
async function
|
|
96
|
-
if (await
|
|
97
|
-
switch (
|
|
95
|
+
async function De(s = Le) {
|
|
96
|
+
if (await ye())
|
|
97
|
+
switch (s) {
|
|
98
98
|
case "8.3":
|
|
99
99
|
return await import("./jspi/php_8_3.js");
|
|
100
100
|
case "8.2":
|
|
@@ -115,7 +115,7 @@ async function M(r = b) {
|
|
|
115
115
|
return await import("./jspi/php_7_0.js");
|
|
116
116
|
}
|
|
117
117
|
else
|
|
118
|
-
switch (
|
|
118
|
+
switch (s) {
|
|
119
119
|
case "8.3":
|
|
120
120
|
return await import("./asyncify/php_8_3.js");
|
|
121
121
|
case "8.2":
|
|
@@ -135,11 +135,2171 @@ async function M(r = b) {
|
|
|
135
135
|
case "7.0":
|
|
136
136
|
return await import("./asyncify/php_7_0.js");
|
|
137
137
|
}
|
|
138
|
-
throw new Error(`Unsupported PHP version ${
|
|
138
|
+
throw new Error(`Unsupported PHP version ${s}`);
|
|
139
|
+
}
|
|
140
|
+
function p(s) {
|
|
141
|
+
return Object.fromEntries(Object.entries(s).map(([e, t]) => [t, e]));
|
|
142
|
+
}
|
|
143
|
+
function h(s) {
|
|
144
|
+
let e = 0;
|
|
145
|
+
s.forEach((n) => e += n.length);
|
|
146
|
+
const t = new Uint8Array(e);
|
|
147
|
+
let r = 0;
|
|
148
|
+
return s.forEach((n) => {
|
|
149
|
+
t.set(n, r), r += n.length;
|
|
150
|
+
}), t;
|
|
151
|
+
}
|
|
152
|
+
function P(s) {
|
|
153
|
+
return h(s.map((e) => new Uint8Array(e))).buffer;
|
|
154
|
+
}
|
|
155
|
+
function I(s) {
|
|
156
|
+
return new Uint8Array([s >> 8 & 255, s & 255]);
|
|
157
|
+
}
|
|
158
|
+
function m(s) {
|
|
159
|
+
return new Uint8Array([
|
|
160
|
+
s >> 16 & 255,
|
|
161
|
+
s >> 8 & 255,
|
|
162
|
+
s & 255
|
|
163
|
+
]);
|
|
164
|
+
}
|
|
165
|
+
function G(s) {
|
|
166
|
+
const e = new ArrayBuffer(8);
|
|
167
|
+
return new DataView(e).setBigUint64(0, BigInt(s), !1), new Uint8Array(e);
|
|
168
|
+
}
|
|
169
|
+
class g {
|
|
170
|
+
constructor(e) {
|
|
171
|
+
this.buffer = e, this.offset = 0, this.view = new DataView(e);
|
|
172
|
+
}
|
|
173
|
+
readUint8() {
|
|
174
|
+
const e = this.view.getUint8(this.offset);
|
|
175
|
+
return this.offset += 1, e;
|
|
176
|
+
}
|
|
177
|
+
readUint16() {
|
|
178
|
+
const e = this.view.getUint16(this.offset);
|
|
179
|
+
return this.offset += 2, e;
|
|
180
|
+
}
|
|
181
|
+
readUint32() {
|
|
182
|
+
const e = this.view.getUint32(this.offset);
|
|
183
|
+
return this.offset += 4, e;
|
|
184
|
+
}
|
|
185
|
+
readUint8Array(e) {
|
|
186
|
+
const t = this.buffer.slice(this.offset, this.offset + e);
|
|
187
|
+
return this.offset += e, new Uint8Array(t);
|
|
188
|
+
}
|
|
189
|
+
isFinished() {
|
|
190
|
+
return this.offset >= this.buffer.byteLength;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
class v {
|
|
194
|
+
constructor(e) {
|
|
195
|
+
this.offset = 0, this.buffer = new ArrayBuffer(e), this.uint8Array = new Uint8Array(this.buffer), this.view = new DataView(this.buffer);
|
|
196
|
+
}
|
|
197
|
+
writeUint8(e) {
|
|
198
|
+
this.view.setUint8(this.offset, e), this.offset += 1;
|
|
199
|
+
}
|
|
200
|
+
writeUint16(e) {
|
|
201
|
+
this.view.setUint16(this.offset, e), this.offset += 2;
|
|
202
|
+
}
|
|
203
|
+
writeUint32(e) {
|
|
204
|
+
this.view.setUint32(this.offset, e), this.offset += 4;
|
|
205
|
+
}
|
|
206
|
+
writeUint8Array(e) {
|
|
207
|
+
this.uint8Array.set(e, this.offset), this.offset += e.length;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const R = {
|
|
211
|
+
server_name: 0,
|
|
212
|
+
max_fragment_length: 1,
|
|
213
|
+
client_certificate_url: 2,
|
|
214
|
+
trusted_ca_keys: 3,
|
|
215
|
+
truncated_hmac: 4,
|
|
216
|
+
status_request: 5,
|
|
217
|
+
user_mapping: 6,
|
|
218
|
+
client_authz: 7,
|
|
219
|
+
server_authz: 8,
|
|
220
|
+
cert_type: 9,
|
|
221
|
+
supported_groups: 10,
|
|
222
|
+
ec_point_formats: 11,
|
|
223
|
+
srp: 12,
|
|
224
|
+
signature_algorithms: 13,
|
|
225
|
+
use_srtp: 14,
|
|
226
|
+
heartbeat: 15,
|
|
227
|
+
application_layer_protocol_negotiation: 16,
|
|
228
|
+
status_request_v2: 17,
|
|
229
|
+
signed_certificate_timestamp: 18,
|
|
230
|
+
client_certificate_type: 19,
|
|
231
|
+
server_certificate_type: 20,
|
|
232
|
+
padding: 21,
|
|
233
|
+
encrypt_then_mac: 22,
|
|
234
|
+
extended_master_secret: 23,
|
|
235
|
+
token_binding: 24,
|
|
236
|
+
cached_info: 25,
|
|
237
|
+
tls_its: 26,
|
|
238
|
+
compress_certificate: 27,
|
|
239
|
+
record_size_limit: 28,
|
|
240
|
+
pwd_protect: 29,
|
|
241
|
+
pwo_clear: 30,
|
|
242
|
+
password_salt: 31,
|
|
243
|
+
ticket_pinning: 32,
|
|
244
|
+
tls_cert_with_extern_psk: 33,
|
|
245
|
+
delegated_credential: 34,
|
|
246
|
+
session_ticket: 35,
|
|
247
|
+
TLMSP: 36,
|
|
248
|
+
TLMSP_proxying: 37,
|
|
249
|
+
TLMSP_delegate: 38,
|
|
250
|
+
supported_ekt_ciphers: 39,
|
|
251
|
+
pre_shared_key: 41,
|
|
252
|
+
early_data: 42,
|
|
253
|
+
supported_versions: 43,
|
|
254
|
+
cookie: 44,
|
|
255
|
+
psk_key_exchange_modes: 45,
|
|
256
|
+
reserved: 46,
|
|
257
|
+
certificate_authorities: 47,
|
|
258
|
+
oid_filters: 48,
|
|
259
|
+
post_handshake_auth: 49,
|
|
260
|
+
signature_algorithms_cert: 50,
|
|
261
|
+
key_share: 51,
|
|
262
|
+
transparency_info: 52,
|
|
263
|
+
connection_id: 54
|
|
264
|
+
}, We = p(R), _e = {
|
|
265
|
+
host_name: 0
|
|
266
|
+
}, be = p(_e);
|
|
267
|
+
class ae {
|
|
268
|
+
static decodeFromClient(e) {
|
|
269
|
+
const t = new DataView(e.buffer);
|
|
270
|
+
let r = 0;
|
|
271
|
+
const n = t.getUint16(r);
|
|
272
|
+
r += 2;
|
|
273
|
+
const i = [];
|
|
274
|
+
for (; r < n + 2; ) {
|
|
275
|
+
const _ = e[r];
|
|
276
|
+
r += 1;
|
|
277
|
+
const a = t.getUint16(r);
|
|
278
|
+
r += 2;
|
|
279
|
+
const c = e.slice(r, r + a);
|
|
280
|
+
switch (r += a, _) {
|
|
281
|
+
case _e.host_name:
|
|
282
|
+
i.push({
|
|
283
|
+
name_type: be[_],
|
|
284
|
+
name: {
|
|
285
|
+
host_name: new TextDecoder().decode(c)
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
throw new Error(`Unsupported name type ${_}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return { server_name_list: i };
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Encode the server_name extension
|
|
297
|
+
*
|
|
298
|
+
* +------------------------------------+
|
|
299
|
+
* | Extension Type (server_name) [2B] |
|
|
300
|
+
* | 0x00 0x00 |
|
|
301
|
+
* +------------------------------------+
|
|
302
|
+
* | Extension Length [2B] |
|
|
303
|
+
* | 0x00 0x00 |
|
|
304
|
+
* +------------------------------------+
|
|
305
|
+
*/
|
|
306
|
+
static encodeForClient(e) {
|
|
307
|
+
if (e != null && e.server_name_list.length)
|
|
308
|
+
throw new Error(
|
|
309
|
+
"Encoding non-empty lists for ClientHello is not supported yet. Only empty lists meant for ServerHello are supported today."
|
|
310
|
+
);
|
|
311
|
+
const t = new v(4);
|
|
312
|
+
return t.writeUint16(R.server_name), t.writeUint16(0), t.uint8Array;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const oe = {
|
|
316
|
+
TLS1_CK_PSK_WITH_RC4_128_SHA: 138,
|
|
317
|
+
TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA: 139,
|
|
318
|
+
TLS1_CK_PSK_WITH_AES_128_CBC_SHA: 140,
|
|
319
|
+
TLS1_CK_PSK_WITH_AES_256_CBC_SHA: 141,
|
|
320
|
+
TLS1_CK_DHE_PSK_WITH_RC4_128_SHA: 142,
|
|
321
|
+
TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA: 143,
|
|
322
|
+
TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA: 144,
|
|
323
|
+
TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA: 145,
|
|
324
|
+
TLS1_CK_RSA_PSK_WITH_RC4_128_SHA: 146,
|
|
325
|
+
TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA: 147,
|
|
326
|
+
TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA: 148,
|
|
327
|
+
TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA: 149,
|
|
328
|
+
TLS1_CK_PSK_WITH_AES_128_GCM_SHA256: 168,
|
|
329
|
+
TLS1_CK_PSK_WITH_AES_256_GCM_SHA384: 169,
|
|
330
|
+
TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256: 170,
|
|
331
|
+
TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384: 171,
|
|
332
|
+
TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256: 172,
|
|
333
|
+
TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384: 173,
|
|
334
|
+
TLS1_CK_PSK_WITH_AES_128_CBC_SHA256: 174,
|
|
335
|
+
TLS1_CK_PSK_WITH_AES_256_CBC_SHA384: 175,
|
|
336
|
+
TLS1_CK_PSK_WITH_NULL_SHA256: 176,
|
|
337
|
+
TLS1_CK_PSK_WITH_NULL_SHA384: 177,
|
|
338
|
+
TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256: 178,
|
|
339
|
+
TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384: 179,
|
|
340
|
+
TLS1_CK_DHE_PSK_WITH_NULL_SHA256: 180,
|
|
341
|
+
TLS1_CK_DHE_PSK_WITH_NULL_SHA384: 181,
|
|
342
|
+
TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256: 182,
|
|
343
|
+
TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384: 183,
|
|
344
|
+
TLS1_CK_RSA_PSK_WITH_NULL_SHA256: 184,
|
|
345
|
+
TLS1_CK_RSA_PSK_WITH_NULL_SHA384: 185,
|
|
346
|
+
TLS1_CK_PSK_WITH_NULL_SHA: 44,
|
|
347
|
+
TLS1_CK_DHE_PSK_WITH_NULL_SHA: 45,
|
|
348
|
+
TLS1_CK_RSA_PSK_WITH_NULL_SHA: 46,
|
|
349
|
+
TLS1_CK_RSA_WITH_AES_128_SHA: 47,
|
|
350
|
+
TLS1_CK_DH_DSS_WITH_AES_128_SHA: 48,
|
|
351
|
+
TLS1_CK_DH_RSA_WITH_AES_128_SHA: 49,
|
|
352
|
+
TLS1_CK_DHE_DSS_WITH_AES_128_SHA: 50,
|
|
353
|
+
TLS1_CK_DHE_RSA_WITH_AES_128_SHA: 51,
|
|
354
|
+
TLS1_CK_ADH_WITH_AES_128_SHA: 52,
|
|
355
|
+
TLS1_CK_RSA_WITH_AES_256_SHA: 53,
|
|
356
|
+
TLS1_CK_DH_DSS_WITH_AES_256_SHA: 54,
|
|
357
|
+
TLS1_CK_DH_RSA_WITH_AES_256_SHA: 55,
|
|
358
|
+
TLS1_CK_DHE_DSS_WITH_AES_256_SHA: 56,
|
|
359
|
+
TLS1_CK_DHE_RSA_WITH_AES_256_SHA: 57,
|
|
360
|
+
TLS1_CK_ADH_WITH_AES_256_SHA: 58,
|
|
361
|
+
TLS1_CK_RSA_WITH_NULL_SHA256: 59,
|
|
362
|
+
TLS1_CK_RSA_WITH_AES_128_SHA256: 60,
|
|
363
|
+
TLS1_CK_RSA_WITH_AES_256_SHA256: 61,
|
|
364
|
+
TLS1_CK_DH_DSS_WITH_AES_128_SHA256: 62,
|
|
365
|
+
TLS1_CK_DH_RSA_WITH_AES_128_SHA256: 63,
|
|
366
|
+
TLS1_CK_DHE_DSS_WITH_AES_128_SHA256: 64,
|
|
367
|
+
TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA: 65,
|
|
368
|
+
TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: 66,
|
|
369
|
+
TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: 67,
|
|
370
|
+
TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: 68,
|
|
371
|
+
TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: 69,
|
|
372
|
+
TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA: 70,
|
|
373
|
+
TLS1_CK_DHE_RSA_WITH_AES_128_SHA256: 103,
|
|
374
|
+
TLS1_CK_DH_DSS_WITH_AES_256_SHA256: 104,
|
|
375
|
+
TLS1_CK_DH_RSA_WITH_AES_256_SHA256: 105,
|
|
376
|
+
TLS1_CK_DHE_DSS_WITH_AES_256_SHA256: 106,
|
|
377
|
+
TLS1_CK_DHE_RSA_WITH_AES_256_SHA256: 107,
|
|
378
|
+
TLS1_CK_ADH_WITH_AES_128_SHA256: 108,
|
|
379
|
+
TLS1_CK_ADH_WITH_AES_256_SHA256: 109,
|
|
380
|
+
TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA: 132,
|
|
381
|
+
TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: 133,
|
|
382
|
+
TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: 134,
|
|
383
|
+
TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: 135,
|
|
384
|
+
TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: 136,
|
|
385
|
+
TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA: 137,
|
|
386
|
+
TLS1_CK_RSA_WITH_SEED_SHA: 150,
|
|
387
|
+
TLS1_CK_DH_DSS_WITH_SEED_SHA: 151,
|
|
388
|
+
TLS1_CK_DH_RSA_WITH_SEED_SHA: 152,
|
|
389
|
+
TLS1_CK_DHE_DSS_WITH_SEED_SHA: 153,
|
|
390
|
+
TLS1_CK_DHE_RSA_WITH_SEED_SHA: 154,
|
|
391
|
+
TLS1_CK_ADH_WITH_SEED_SHA: 155,
|
|
392
|
+
TLS1_CK_RSA_WITH_AES_128_GCM_SHA256: 156,
|
|
393
|
+
TLS1_CK_RSA_WITH_AES_256_GCM_SHA384: 157,
|
|
394
|
+
TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256: 158,
|
|
395
|
+
TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384: 159,
|
|
396
|
+
TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256: 160,
|
|
397
|
+
TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384: 161,
|
|
398
|
+
TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256: 162,
|
|
399
|
+
TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384: 163,
|
|
400
|
+
TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256: 164,
|
|
401
|
+
TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384: 165,
|
|
402
|
+
TLS1_CK_ADH_WITH_AES_128_GCM_SHA256: 166,
|
|
403
|
+
TLS1_CK_ADH_WITH_AES_256_GCM_SHA384: 167,
|
|
404
|
+
TLS1_CK_RSA_WITH_AES_128_CCM: 49308,
|
|
405
|
+
TLS1_CK_RSA_WITH_AES_256_CCM: 49309,
|
|
406
|
+
TLS1_CK_DHE_RSA_WITH_AES_128_CCM: 49310,
|
|
407
|
+
TLS1_CK_DHE_RSA_WITH_AES_256_CCM: 49311,
|
|
408
|
+
TLS1_CK_RSA_WITH_AES_128_CCM_8: 49312,
|
|
409
|
+
TLS1_CK_RSA_WITH_AES_256_CCM_8: 49313,
|
|
410
|
+
TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8: 49314,
|
|
411
|
+
TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8: 49315,
|
|
412
|
+
TLS1_CK_PSK_WITH_AES_128_CCM: 49316,
|
|
413
|
+
TLS1_CK_PSK_WITH_AES_256_CCM: 49317,
|
|
414
|
+
TLS1_CK_DHE_PSK_WITH_AES_128_CCM: 49318,
|
|
415
|
+
TLS1_CK_DHE_PSK_WITH_AES_256_CCM: 49319,
|
|
416
|
+
TLS1_CK_PSK_WITH_AES_128_CCM_8: 49320,
|
|
417
|
+
TLS1_CK_PSK_WITH_AES_256_CCM_8: 49321,
|
|
418
|
+
TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8: 49322,
|
|
419
|
+
TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8: 49323,
|
|
420
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM: 49324,
|
|
421
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM: 49325,
|
|
422
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8: 49326,
|
|
423
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8: 49327,
|
|
424
|
+
TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256: 186,
|
|
425
|
+
TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: 187,
|
|
426
|
+
TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: 188,
|
|
427
|
+
TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: 189,
|
|
428
|
+
TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: 190,
|
|
429
|
+
TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256: 191,
|
|
430
|
+
TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256: 192,
|
|
431
|
+
TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: 193,
|
|
432
|
+
TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: 194,
|
|
433
|
+
TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: 195,
|
|
434
|
+
TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: 196,
|
|
435
|
+
TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256: 197,
|
|
436
|
+
TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA: 49153,
|
|
437
|
+
TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA: 49154,
|
|
438
|
+
TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA: 49155,
|
|
439
|
+
TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA: 49156,
|
|
440
|
+
TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA: 49157,
|
|
441
|
+
TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA: 49158,
|
|
442
|
+
TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA: 49159,
|
|
443
|
+
TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA: 49160,
|
|
444
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: 49161,
|
|
445
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: 49162,
|
|
446
|
+
TLS1_CK_ECDH_RSA_WITH_NULL_SHA: 49163,
|
|
447
|
+
TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA: 49164,
|
|
448
|
+
TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA: 49165,
|
|
449
|
+
TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA: 49166,
|
|
450
|
+
TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA: 49167,
|
|
451
|
+
TLS1_CK_ECDHE_RSA_WITH_NULL_SHA: 49168,
|
|
452
|
+
TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA: 49169,
|
|
453
|
+
TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA: 49170,
|
|
454
|
+
TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA: 49171,
|
|
455
|
+
TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA: 49172,
|
|
456
|
+
TLS1_CK_ECDH_anon_WITH_NULL_SHA: 49173,
|
|
457
|
+
TLS1_CK_ECDH_anon_WITH_RC4_128_SHA: 49174,
|
|
458
|
+
TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA: 49175,
|
|
459
|
+
TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA: 49176,
|
|
460
|
+
TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA: 49177,
|
|
461
|
+
TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA: 49178,
|
|
462
|
+
TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: 49179,
|
|
463
|
+
TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: 49180,
|
|
464
|
+
TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA: 49181,
|
|
465
|
+
TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: 49182,
|
|
466
|
+
TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: 49183,
|
|
467
|
+
TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA: 49184,
|
|
468
|
+
TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: 49185,
|
|
469
|
+
TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: 49186,
|
|
470
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256: 49187,
|
|
471
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384: 49188,
|
|
472
|
+
TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256: 49189,
|
|
473
|
+
TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384: 49190,
|
|
474
|
+
TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256: 49191,
|
|
475
|
+
TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384: 49192,
|
|
476
|
+
TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256: 49193,
|
|
477
|
+
TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384: 49194,
|
|
478
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 49195,
|
|
479
|
+
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 49196,
|
|
480
|
+
TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: 49197,
|
|
481
|
+
TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: 49198,
|
|
482
|
+
TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256: 49199,
|
|
483
|
+
TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384: 49200,
|
|
484
|
+
TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256: 49201,
|
|
485
|
+
TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384: 49202,
|
|
486
|
+
TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA: 49203,
|
|
487
|
+
TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: 49204,
|
|
488
|
+
TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA: 49205,
|
|
489
|
+
TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA: 49206,
|
|
490
|
+
TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256: 49207,
|
|
491
|
+
TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384: 49208,
|
|
492
|
+
TLS1_CK_ECDHE_PSK_WITH_NULL_SHA: 49209,
|
|
493
|
+
TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256: 49210,
|
|
494
|
+
TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384: 49211,
|
|
495
|
+
TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: 49266,
|
|
496
|
+
TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: 49267,
|
|
497
|
+
TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: 49268,
|
|
498
|
+
TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: 49269,
|
|
499
|
+
TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: 49270,
|
|
500
|
+
TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: 49271,
|
|
501
|
+
TLS1_CK_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: 49272,
|
|
502
|
+
TLS1_CK_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: 49273,
|
|
503
|
+
TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256: 49300,
|
|
504
|
+
TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384: 49301,
|
|
505
|
+
TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: 49302,
|
|
506
|
+
TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: 49303,
|
|
507
|
+
TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: 49304,
|
|
508
|
+
TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: 49305,
|
|
509
|
+
TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: 49306,
|
|
510
|
+
TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: 49307,
|
|
511
|
+
TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305: 52392,
|
|
512
|
+
TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: 52393,
|
|
513
|
+
TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305: 52394,
|
|
514
|
+
TLS1_CK_PSK_WITH_CHACHA20_POLY1305: 52395,
|
|
515
|
+
TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305: 52396,
|
|
516
|
+
TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305: 52397,
|
|
517
|
+
TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305: 52398
|
|
518
|
+
}, j = p(oe), ce = {
|
|
519
|
+
secp256r1: 23,
|
|
520
|
+
secp384r1: 24,
|
|
521
|
+
secp521r1: 25,
|
|
522
|
+
x25519: 29,
|
|
523
|
+
x448: 30
|
|
524
|
+
}, $ = p(ce);
|
|
525
|
+
class Se {
|
|
526
|
+
/**
|
|
527
|
+
* +--------------------------------------------------+
|
|
528
|
+
* | Payload Length [2B] |
|
|
529
|
+
* +--------------------------------------------------+
|
|
530
|
+
* | Supported Groups List Length [2B] |
|
|
531
|
+
* +--------------------------------------------------+
|
|
532
|
+
* | Supported Group 1 [2B] |
|
|
533
|
+
* +--------------------------------------------------+
|
|
534
|
+
* | Supported Group 2 [2B] |
|
|
535
|
+
* +--------------------------------------------------+
|
|
536
|
+
* | ... |
|
|
537
|
+
* +--------------------------------------------------+
|
|
538
|
+
* | Supported Group n [2B] |
|
|
539
|
+
* +--------------------------------------------------+
|
|
540
|
+
*/
|
|
541
|
+
static decodeFromClient(e) {
|
|
542
|
+
const t = new g(e.buffer);
|
|
543
|
+
t.readUint16();
|
|
544
|
+
const r = [];
|
|
545
|
+
for (; !t.isFinished(); ) {
|
|
546
|
+
const n = t.readUint16();
|
|
547
|
+
n in $ && r.push($[n]);
|
|
548
|
+
}
|
|
549
|
+
return r;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* +--------------------------------------------------+
|
|
553
|
+
* | Extension Type (supported_groups) [2B] |
|
|
554
|
+
* | 0x00 0x0A |
|
|
555
|
+
* +--------------------------------------------------+
|
|
556
|
+
* | Extension Length [2B] |
|
|
557
|
+
* +--------------------------------------------------+
|
|
558
|
+
* | Selected Group [2B] |
|
|
559
|
+
* +--------------------------------------------------+
|
|
560
|
+
*/
|
|
561
|
+
static encodeForClient(e) {
|
|
562
|
+
const t = new v(6);
|
|
563
|
+
return t.writeUint16(R.supported_groups), t.writeUint16(2), t.writeUint16(ce[e]), t.uint8Array;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
const Ce = {
|
|
567
|
+
uncompressed: 0,
|
|
568
|
+
ansiX962_compressed_prime: 1,
|
|
569
|
+
ansiX962_compressed_char2: 2
|
|
570
|
+
}, V = p(Ce);
|
|
571
|
+
class le {
|
|
572
|
+
/**
|
|
573
|
+
* +--------------------------------------------------+
|
|
574
|
+
* | Payload Length [2B] |
|
|
575
|
+
* +--------------------------------------------------+
|
|
576
|
+
* | EC Point Formats Length [1B] |
|
|
577
|
+
* +--------------------------------------------------+
|
|
578
|
+
* | EC Point Format 1 [1B] |
|
|
579
|
+
* +--------------------------------------------------+
|
|
580
|
+
* | EC Point Format 2 [1B] |
|
|
581
|
+
* +--------------------------------------------------+
|
|
582
|
+
* | ... |
|
|
583
|
+
* +--------------------------------------------------+
|
|
584
|
+
* | EC Point Format n [1B] |
|
|
585
|
+
* +--------------------------------------------------+
|
|
586
|
+
*/
|
|
587
|
+
static decodeFromClient(e) {
|
|
588
|
+
const t = new g(e.buffer), r = t.readUint8(), n = [];
|
|
589
|
+
for (let i = 0; i < r; i++) {
|
|
590
|
+
const _ = t.readUint8();
|
|
591
|
+
_ in V && n.push(V[_]);
|
|
592
|
+
}
|
|
593
|
+
return n;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Encode the ec_point_formats extension
|
|
597
|
+
*
|
|
598
|
+
* +--------------------------------------------------+
|
|
599
|
+
* | Extension Type (ec_point_formats) [2B] |
|
|
600
|
+
* | 0x00 0x0B |
|
|
601
|
+
* +--------------------------------------------------+
|
|
602
|
+
* | Body Length [2B] |
|
|
603
|
+
* +--------------------------------------------------+
|
|
604
|
+
* | EC Point Format Length [1B] |
|
|
605
|
+
* +--------------------------------------------------+
|
|
606
|
+
* | EC Point Format [1B] |
|
|
607
|
+
* +--------------------------------------------------+
|
|
608
|
+
*/
|
|
609
|
+
static encodeForClient(e) {
|
|
610
|
+
const t = new v(6);
|
|
611
|
+
return t.writeUint16(R.ec_point_formats), t.writeUint16(2), t.writeUint8(1), t.writeUint8(Ce[e]), t.uint8Array;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
const N = {
|
|
615
|
+
anonymous: 0,
|
|
616
|
+
rsa: 1,
|
|
617
|
+
dsa: 2,
|
|
618
|
+
ecdsa: 3
|
|
619
|
+
}, z = p(N), O = {
|
|
620
|
+
none: 0,
|
|
621
|
+
md5: 1,
|
|
622
|
+
sha1: 2,
|
|
623
|
+
sha224: 3,
|
|
624
|
+
sha256: 4,
|
|
625
|
+
sha384: 5,
|
|
626
|
+
sha512: 6
|
|
627
|
+
}, Y = p(O);
|
|
628
|
+
class Ae {
|
|
629
|
+
/**
|
|
630
|
+
* Binary layout:
|
|
631
|
+
*
|
|
632
|
+
* +------------------------------------+
|
|
633
|
+
* | Payload Length [2B] |
|
|
634
|
+
* +------------------------------------+
|
|
635
|
+
* | Hash Algorithm 1 [1B] |
|
|
636
|
+
* | Signature Algorithm 1 [1B] |
|
|
637
|
+
* +------------------------------------+
|
|
638
|
+
* | Hash Algorithm 2 [1B] |
|
|
639
|
+
* | Signature Algorithm 2 [1B] |
|
|
640
|
+
* +------------------------------------+
|
|
641
|
+
* | ... |
|
|
642
|
+
* +------------------------------------+
|
|
643
|
+
*/
|
|
644
|
+
static decodeFromClient(e) {
|
|
645
|
+
const t = new g(e.buffer);
|
|
646
|
+
t.readUint16();
|
|
647
|
+
const r = [];
|
|
648
|
+
for (; !t.isFinished(); ) {
|
|
649
|
+
const n = t.readUint8(), i = t.readUint8();
|
|
650
|
+
if (!z[i]) {
|
|
651
|
+
b.warn(`Unknown signature algorithm: ${i}`);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
if (!Y[n]) {
|
|
655
|
+
b.warn(`Unknown hash algorithm: ${n}`);
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
r.push({
|
|
659
|
+
algorithm: z[i],
|
|
660
|
+
hash: Y[n]
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
return r;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* +--------------------------------------------------+
|
|
667
|
+
* | Extension Type (signature_algorithms) [2B] |
|
|
668
|
+
* | 0x00 0x0D |
|
|
669
|
+
* +--------------------------------------------------+
|
|
670
|
+
* | Body Length [2B] |
|
|
671
|
+
* +--------------------------------------------------+
|
|
672
|
+
* | Hash Algorithm [1B] |
|
|
673
|
+
* | Signature Algorithm [1B] |
|
|
674
|
+
* +--------------------------------------------------+
|
|
675
|
+
*/
|
|
676
|
+
static encodeforClient(e, t) {
|
|
677
|
+
const r = new v(6);
|
|
678
|
+
return r.writeUint16(R.signature_algorithms), r.writeUint16(2), r.writeUint8(O[e]), r.writeUint8(N[t]), r.uint8Array;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
const J = {
|
|
682
|
+
server_name: ae,
|
|
683
|
+
signature_algorithms: Ae,
|
|
684
|
+
supported_groups: Se,
|
|
685
|
+
ec_point_formats: le
|
|
686
|
+
};
|
|
687
|
+
function Re(s) {
|
|
688
|
+
const e = new g(s.buffer), t = [];
|
|
689
|
+
for (; !e.isFinished(); ) {
|
|
690
|
+
const r = e.offset, n = e.readUint16(), i = We[n], _ = e.readUint16(), a = e.readUint8Array(_);
|
|
691
|
+
if (!(i in J))
|
|
692
|
+
continue;
|
|
693
|
+
const c = J[i];
|
|
694
|
+
t.push({
|
|
695
|
+
type: i,
|
|
696
|
+
data: c.decodeFromClient(a),
|
|
697
|
+
raw: s.slice(r, r + 4 + _)
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
return t;
|
|
701
|
+
}
|
|
702
|
+
async function M(s, e, t, r) {
|
|
703
|
+
const n = P([e, t]), i = await crypto.subtle.importKey(
|
|
704
|
+
"raw",
|
|
705
|
+
s,
|
|
706
|
+
{ name: "HMAC", hash: { name: "SHA-256" } },
|
|
707
|
+
!1,
|
|
708
|
+
["sign"]
|
|
709
|
+
);
|
|
710
|
+
let _ = n;
|
|
711
|
+
const a = [];
|
|
712
|
+
for (; P(a).byteLength < r; ) {
|
|
713
|
+
_ = await X(i, _);
|
|
714
|
+
const S = P([_, n]), l = await X(i, S);
|
|
715
|
+
a.push(l);
|
|
716
|
+
}
|
|
717
|
+
return P(a).slice(0, r);
|
|
718
|
+
}
|
|
719
|
+
async function X(s, e) {
|
|
720
|
+
return await crypto.subtle.sign(
|
|
721
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
722
|
+
s,
|
|
723
|
+
e
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
var ue = /* @__PURE__ */ ((s) => (s[s.Null = 0] = "Null", s[s.Deflate = 1] = "Deflate", s))(ue || {});
|
|
727
|
+
const Pe = {
|
|
728
|
+
Warning: 1,
|
|
729
|
+
Fatal: 2
|
|
730
|
+
}, he = p(Pe), Be = {
|
|
731
|
+
CloseNotify: 0,
|
|
732
|
+
UnexpectedMessage: 10,
|
|
733
|
+
BadRecordMac: 20,
|
|
734
|
+
DecryptionFailed: 21,
|
|
735
|
+
RecordOverflow: 22,
|
|
736
|
+
DecompressionFailure: 30,
|
|
737
|
+
HandshakeFailure: 40,
|
|
738
|
+
NoCertificate: 41,
|
|
739
|
+
BadCertificate: 42,
|
|
740
|
+
UnsupportedCertificate: 43,
|
|
741
|
+
CertificateRevoked: 44,
|
|
742
|
+
CertificateExpired: 45,
|
|
743
|
+
CertificateUnknown: 46,
|
|
744
|
+
IllegalParameter: 47,
|
|
745
|
+
UnknownCa: 48,
|
|
746
|
+
AccessDenied: 49,
|
|
747
|
+
DecodeError: 50,
|
|
748
|
+
DecryptError: 51,
|
|
749
|
+
ExportRestriction: 60,
|
|
750
|
+
ProtocolVersion: 70,
|
|
751
|
+
InsufficientSecurity: 71,
|
|
752
|
+
InternalError: 80,
|
|
753
|
+
UserCanceled: 90,
|
|
754
|
+
NoRenegotiation: 100,
|
|
755
|
+
UnsupportedExtension: 110
|
|
756
|
+
}, He = p(Be), C = {
|
|
757
|
+
ChangeCipherSpec: 20,
|
|
758
|
+
Alert: 21,
|
|
759
|
+
Handshake: 22,
|
|
760
|
+
ApplicationData: 23
|
|
761
|
+
};
|
|
762
|
+
var d = /* @__PURE__ */ ((s) => (s[s.HelloRequest = 0] = "HelloRequest", s[s.ClientHello = 1] = "ClientHello", s[s.ServerHello = 2] = "ServerHello", s[s.Certificate = 11] = "Certificate", s[s.ServerKeyExchange = 12] = "ServerKeyExchange", s[s.CertificateRequest = 13] = "CertificateRequest", s[s.ServerHelloDone = 14] = "ServerHelloDone", s[s.CertificateVerify = 15] = "CertificateVerify", s[s.ClientKeyExchange = 16] = "ClientKeyExchange", s[s.Finished = 20] = "Finished", s))(d || {});
|
|
763
|
+
const Ue = {
|
|
764
|
+
/**
|
|
765
|
+
* Indicates the elliptic curve domain parameters are
|
|
766
|
+
* conveyed verbosely, and the underlying finite field is a prime
|
|
767
|
+
* field.
|
|
768
|
+
*/
|
|
769
|
+
ExplicitPrime: 1,
|
|
770
|
+
/**
|
|
771
|
+
* Indicates the elliptic curve domain parameters are
|
|
772
|
+
* conveyed verbosely, and the underlying finite field is a
|
|
773
|
+
* characteristic-2 field.
|
|
774
|
+
*/
|
|
775
|
+
ExplicitChar2: 2,
|
|
776
|
+
/**
|
|
777
|
+
* Indicates that a named curve is used. This option
|
|
778
|
+
* SHOULD be used when applicable.
|
|
779
|
+
*/
|
|
780
|
+
NamedCurve: 3
|
|
781
|
+
/**
|
|
782
|
+
* Values 248 through 255 are reserved for private use.
|
|
783
|
+
*/
|
|
784
|
+
}, ve = {
|
|
785
|
+
sect163k1: 1,
|
|
786
|
+
sect163r1: 2,
|
|
787
|
+
sect163r2: 3,
|
|
788
|
+
sect193r1: 4,
|
|
789
|
+
sect193r2: 5,
|
|
790
|
+
sect233k1: 6,
|
|
791
|
+
sect233r1: 7,
|
|
792
|
+
sect239k1: 8,
|
|
793
|
+
sect283k1: 9,
|
|
794
|
+
sect283r1: 10,
|
|
795
|
+
sect409k1: 11,
|
|
796
|
+
sect409r1: 12,
|
|
797
|
+
secp256k1: 22,
|
|
798
|
+
secp256r1: 23,
|
|
799
|
+
secp384r1: 24,
|
|
800
|
+
secp521r1: 25,
|
|
801
|
+
arbitrary_explicit_prime_curves: 65281,
|
|
802
|
+
arbitrary_explicit_char2_curves: 65282
|
|
803
|
+
};
|
|
804
|
+
class Z extends Error {
|
|
805
|
+
}
|
|
806
|
+
const U = new Uint8Array([3, 3]), Me = crypto.subtle.generateKey(
|
|
807
|
+
{
|
|
808
|
+
name: "ECDH",
|
|
809
|
+
namedCurve: "P-256"
|
|
810
|
+
// Use secp256r1 curve
|
|
811
|
+
},
|
|
812
|
+
!0,
|
|
813
|
+
// Extractable
|
|
814
|
+
["deriveKey", "deriveBits"]
|
|
815
|
+
// Key usage
|
|
816
|
+
);
|
|
817
|
+
class xe {
|
|
818
|
+
constructor() {
|
|
819
|
+
this.receivedRecordSequenceNumber = 0, this.sentRecordSequenceNumber = 0, this.closed = !1, this.receivedBytesBuffer = new Uint8Array(), this.receivedTLSRecords = [], this.partialTLSMessages = {}, this.handshakeMessages = [], this.MAX_CHUNK_SIZE = 1024 * 16, this.clientEnd = {
|
|
820
|
+
// We don't need to chunk the encrypted data.
|
|
821
|
+
// OpenSSL already done that for us.
|
|
822
|
+
upstream: new TransformStream(),
|
|
823
|
+
downstream: new TransformStream()
|
|
824
|
+
}, this.clientDownstreamWriter = this.clientEnd.downstream.writable.getWriter(), this.clientUpstreamReader = this.clientEnd.upstream.readable.getReader(), this.serverEnd = {
|
|
825
|
+
upstream: new TransformStream(),
|
|
826
|
+
/**
|
|
827
|
+
* Chunk the data before encrypting it. The
|
|
828
|
+
* TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite
|
|
829
|
+
* only supports up to 16KB of data per record.
|
|
830
|
+
*
|
|
831
|
+
* This will spread some messages across multiple records,
|
|
832
|
+
* but TLS supports it so that's fine.
|
|
833
|
+
*/
|
|
834
|
+
downstream: Ne(this.MAX_CHUNK_SIZE)
|
|
835
|
+
}, this.serverUpstreamWriter = this.serverEnd.upstream.writable.getWriter();
|
|
836
|
+
const e = this;
|
|
837
|
+
this.serverEnd.downstream.readable.pipeTo(
|
|
838
|
+
new WritableStream({
|
|
839
|
+
async write(t) {
|
|
840
|
+
await e.writeTLSRecord(
|
|
841
|
+
C.ApplicationData,
|
|
842
|
+
t
|
|
843
|
+
);
|
|
844
|
+
},
|
|
845
|
+
async abort(t) {
|
|
846
|
+
e.clientDownstreamWriter.releaseLock(), e.clientEnd.downstream.writable.abort(t), e.close();
|
|
847
|
+
},
|
|
848
|
+
close() {
|
|
849
|
+
e.close();
|
|
850
|
+
}
|
|
851
|
+
})
|
|
852
|
+
).catch(() => {
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Marks this connections as closed and closes all the associated
|
|
857
|
+
* streams.
|
|
858
|
+
*/
|
|
859
|
+
async close() {
|
|
860
|
+
if (!this.closed) {
|
|
861
|
+
this.closed = !0;
|
|
862
|
+
try {
|
|
863
|
+
await this.clientDownstreamWriter.close();
|
|
864
|
+
} catch {
|
|
865
|
+
}
|
|
866
|
+
try {
|
|
867
|
+
await this.clientUpstreamReader.cancel();
|
|
868
|
+
} catch {
|
|
869
|
+
}
|
|
870
|
+
try {
|
|
871
|
+
await this.serverUpstreamWriter.close();
|
|
872
|
+
} catch {
|
|
873
|
+
}
|
|
874
|
+
try {
|
|
875
|
+
await this.clientEnd.upstream.readable.cancel();
|
|
876
|
+
} catch {
|
|
877
|
+
}
|
|
878
|
+
try {
|
|
879
|
+
await this.clientEnd.downstream.writable.close();
|
|
880
|
+
} catch {
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* TLS handshake as per RFC 5246.
|
|
886
|
+
*
|
|
887
|
+
* https://datatracker.ietf.org/doc/html/rfc5246#section-7.4
|
|
888
|
+
*/
|
|
889
|
+
async TLSHandshake(e, t) {
|
|
890
|
+
const r = await this.readNextHandshakeMessage(
|
|
891
|
+
d.ClientHello
|
|
892
|
+
);
|
|
893
|
+
if (!r.body.cipher_suites.length)
|
|
894
|
+
throw new Error(
|
|
895
|
+
"Client did not propose any supported cipher suites."
|
|
896
|
+
);
|
|
897
|
+
const n = crypto.getRandomValues(new Uint8Array(32));
|
|
898
|
+
await this.writeTLSRecord(
|
|
899
|
+
C.Handshake,
|
|
900
|
+
K.serverHello(
|
|
901
|
+
r.body,
|
|
902
|
+
n,
|
|
903
|
+
ue.Null
|
|
904
|
+
)
|
|
905
|
+
), await this.writeTLSRecord(
|
|
906
|
+
C.Handshake,
|
|
907
|
+
K.certificate(t)
|
|
908
|
+
);
|
|
909
|
+
const i = await Me, _ = r.body.random, a = await K.ECDHEServerKeyExchange(
|
|
910
|
+
_,
|
|
911
|
+
n,
|
|
912
|
+
i,
|
|
913
|
+
e
|
|
914
|
+
);
|
|
915
|
+
await this.writeTLSRecord(C.Handshake, a), await this.writeTLSRecord(
|
|
916
|
+
C.Handshake,
|
|
917
|
+
K.serverHelloDone()
|
|
918
|
+
);
|
|
919
|
+
const c = await this.readNextHandshakeMessage(
|
|
920
|
+
d.ClientKeyExchange
|
|
921
|
+
);
|
|
922
|
+
await this.readNextMessage(C.ChangeCipherSpec), this.sessionKeys = await this.deriveSessionKeys({
|
|
923
|
+
clientRandom: _,
|
|
924
|
+
serverRandom: n,
|
|
925
|
+
serverPrivateKey: i.privateKey,
|
|
926
|
+
clientPublicKey: await crypto.subtle.importKey(
|
|
927
|
+
"raw",
|
|
928
|
+
c.body.exchange_keys,
|
|
929
|
+
{ name: "ECDH", namedCurve: "P-256" },
|
|
930
|
+
!1,
|
|
931
|
+
[]
|
|
932
|
+
)
|
|
933
|
+
}), await this.readNextHandshakeMessage(d.Finished), await this.writeTLSRecord(
|
|
934
|
+
C.ChangeCipherSpec,
|
|
935
|
+
K.changeCipherSpec()
|
|
936
|
+
), await this.writeTLSRecord(
|
|
937
|
+
C.Handshake,
|
|
938
|
+
await K.createFinishedMessage(
|
|
939
|
+
this.handshakeMessages,
|
|
940
|
+
this.sessionKeys.masterSecret
|
|
941
|
+
)
|
|
942
|
+
), this.handshakeMessages = [], this.pollForClientMessages();
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Derives the session keys from the random values and the
|
|
946
|
+
* pre-master secret – as per RFC 5246.
|
|
947
|
+
*/
|
|
948
|
+
async deriveSessionKeys({
|
|
949
|
+
clientRandom: e,
|
|
950
|
+
serverRandom: t,
|
|
951
|
+
serverPrivateKey: r,
|
|
952
|
+
clientPublicKey: n
|
|
953
|
+
}) {
|
|
954
|
+
const i = await crypto.subtle.deriveBits(
|
|
955
|
+
{
|
|
956
|
+
name: "ECDH",
|
|
957
|
+
public: n
|
|
958
|
+
},
|
|
959
|
+
r,
|
|
960
|
+
256
|
|
961
|
+
// Length of the derived secret (256 bits for P-256)
|
|
962
|
+
), _ = new Uint8Array(
|
|
963
|
+
await M(
|
|
964
|
+
i,
|
|
965
|
+
new TextEncoder().encode("master secret"),
|
|
966
|
+
h([e, t]),
|
|
967
|
+
48
|
|
968
|
+
)
|
|
969
|
+
), a = await M(
|
|
970
|
+
_,
|
|
971
|
+
new TextEncoder().encode("key expansion"),
|
|
972
|
+
h([t, e]),
|
|
973
|
+
// Client key, server key, client IV, server IV
|
|
974
|
+
16 + 16 + 4 + 4
|
|
975
|
+
), c = new g(a), S = c.readUint8Array(16), l = c.readUint8Array(16), A = c.readUint8Array(4), u = c.readUint8Array(4);
|
|
976
|
+
return {
|
|
977
|
+
masterSecret: _,
|
|
978
|
+
clientWriteKey: await crypto.subtle.importKey(
|
|
979
|
+
"raw",
|
|
980
|
+
S,
|
|
981
|
+
{ name: "AES-GCM" },
|
|
982
|
+
!1,
|
|
983
|
+
["encrypt", "decrypt"]
|
|
984
|
+
),
|
|
985
|
+
serverWriteKey: await crypto.subtle.importKey(
|
|
986
|
+
"raw",
|
|
987
|
+
l,
|
|
988
|
+
{ name: "AES-GCM" },
|
|
989
|
+
!1,
|
|
990
|
+
["encrypt", "decrypt"]
|
|
991
|
+
),
|
|
992
|
+
clientIV: A,
|
|
993
|
+
serverIV: u
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
async readNextHandshakeMessage(e) {
|
|
997
|
+
const t = await this.readNextMessage(C.Handshake);
|
|
998
|
+
if (t.msg_type !== e)
|
|
999
|
+
throw new Error(`Expected ${e} message`);
|
|
1000
|
+
return t;
|
|
1001
|
+
}
|
|
1002
|
+
async readNextMessage(e) {
|
|
1003
|
+
let t, r = !1;
|
|
1004
|
+
do
|
|
1005
|
+
t = await this.readNextTLSRecord(e), r = await this.accumulateUntilMessageIsComplete(
|
|
1006
|
+
t
|
|
1007
|
+
);
|
|
1008
|
+
while (r === !1);
|
|
1009
|
+
const n = f.TLSMessage(
|
|
1010
|
+
t.type,
|
|
1011
|
+
r
|
|
1012
|
+
);
|
|
1013
|
+
return t.type === C.Handshake && this.handshakeMessages.push(t.fragment), n;
|
|
1014
|
+
}
|
|
1015
|
+
async readNextTLSRecord(e) {
|
|
1016
|
+
for (; ; ) {
|
|
1017
|
+
for (let i = 0; i < this.receivedTLSRecords.length; i++) {
|
|
1018
|
+
const _ = this.receivedTLSRecords[i];
|
|
1019
|
+
if (_.type === C.Alert)
|
|
1020
|
+
throw new Error(
|
|
1021
|
+
`Alert message received: ${he[_.fragment[0]]} ${He[_.fragment[1]]}`
|
|
1022
|
+
);
|
|
1023
|
+
if (_.type === e)
|
|
1024
|
+
return this.receivedTLSRecords.splice(i, 1), this.sessionKeys && _.type !== C.ChangeCipherSpec && (_.fragment = await this.decryptData(
|
|
1025
|
+
_.type,
|
|
1026
|
+
_.fragment
|
|
1027
|
+
)), _;
|
|
1028
|
+
}
|
|
1029
|
+
const t = await this.pollBytes(5), r = t[3] << 8 | t[4], n = {
|
|
1030
|
+
type: t[0],
|
|
1031
|
+
version: {
|
|
1032
|
+
major: t[1],
|
|
1033
|
+
minor: t[2]
|
|
1034
|
+
},
|
|
1035
|
+
length: r,
|
|
1036
|
+
fragment: await this.pollBytes(r)
|
|
1037
|
+
};
|
|
1038
|
+
this.receivedTLSRecords.push(n);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Returns the requested number of bytes from the client.
|
|
1043
|
+
* Waits for the bytes to arrive if necessary.
|
|
1044
|
+
*/
|
|
1045
|
+
async pollBytes(e) {
|
|
1046
|
+
for (; this.receivedBytesBuffer.length < e; ) {
|
|
1047
|
+
const { value: r, done: n } = await this.clientUpstreamReader.read();
|
|
1048
|
+
if (n)
|
|
1049
|
+
throw await this.close(), new Z("TLS connection closed");
|
|
1050
|
+
if (this.receivedBytesBuffer = h([
|
|
1051
|
+
this.receivedBytesBuffer,
|
|
1052
|
+
r
|
|
1053
|
+
]), this.receivedBytesBuffer.length >= e)
|
|
1054
|
+
break;
|
|
1055
|
+
await new Promise((i) => setTimeout(i, 100));
|
|
1056
|
+
}
|
|
1057
|
+
const t = this.receivedBytesBuffer.slice(0, e);
|
|
1058
|
+
return this.receivedBytesBuffer = this.receivedBytesBuffer.slice(e), t;
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Listens for all incoming messages and passes them to the
|
|
1062
|
+
* server handler.
|
|
1063
|
+
*/
|
|
1064
|
+
async pollForClientMessages() {
|
|
1065
|
+
try {
|
|
1066
|
+
for (; ; ) {
|
|
1067
|
+
const e = await this.readNextMessage(
|
|
1068
|
+
C.ApplicationData
|
|
1069
|
+
);
|
|
1070
|
+
this.serverUpstreamWriter.write(e.body);
|
|
1071
|
+
}
|
|
1072
|
+
} catch (e) {
|
|
1073
|
+
if (e instanceof Z)
|
|
1074
|
+
return;
|
|
1075
|
+
throw e;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Decrypts data in a TLS 1.2-compliant manner using
|
|
1080
|
+
* the AES-GCM algorithm.
|
|
1081
|
+
*/
|
|
1082
|
+
async decryptData(e, t) {
|
|
1083
|
+
const r = this.sessionKeys.clientIV, n = t.slice(0, 8), i = new Uint8Array([...r, ...n]), _ = await crypto.subtle.decrypt(
|
|
1084
|
+
{
|
|
1085
|
+
name: "AES-GCM",
|
|
1086
|
+
iv: i,
|
|
1087
|
+
additionalData: new Uint8Array([
|
|
1088
|
+
...G(this.receivedRecordSequenceNumber),
|
|
1089
|
+
e,
|
|
1090
|
+
...U,
|
|
1091
|
+
// Payload length without IV and tag
|
|
1092
|
+
...I(t.length - 8 - 16)
|
|
1093
|
+
]),
|
|
1094
|
+
tagLength: 128
|
|
1095
|
+
},
|
|
1096
|
+
this.sessionKeys.clientWriteKey,
|
|
1097
|
+
// Payload without the explicit IV
|
|
1098
|
+
t.slice(8)
|
|
1099
|
+
);
|
|
1100
|
+
return ++this.receivedRecordSequenceNumber, new Uint8Array(_);
|
|
1101
|
+
}
|
|
1102
|
+
async accumulateUntilMessageIsComplete(e) {
|
|
1103
|
+
this.partialTLSMessages[e.type] = h([
|
|
1104
|
+
this.partialTLSMessages[e.type] || new Uint8Array(),
|
|
1105
|
+
e.fragment
|
|
1106
|
+
]);
|
|
1107
|
+
const t = this.partialTLSMessages[e.type];
|
|
1108
|
+
switch (e.type) {
|
|
1109
|
+
case C.Handshake: {
|
|
1110
|
+
if (t.length < 4)
|
|
1111
|
+
return !1;
|
|
1112
|
+
const r = t[1] << 8 | t[2];
|
|
1113
|
+
if (t.length < 3 + r)
|
|
1114
|
+
return !1;
|
|
1115
|
+
break;
|
|
1116
|
+
}
|
|
1117
|
+
case C.Alert: {
|
|
1118
|
+
if (t.length < 2)
|
|
1119
|
+
return !1;
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
case C.ChangeCipherSpec:
|
|
1123
|
+
case C.ApplicationData:
|
|
1124
|
+
break;
|
|
1125
|
+
default:
|
|
1126
|
+
throw new Error(`TLS: Unsupported record type ${e.type}`);
|
|
1127
|
+
}
|
|
1128
|
+
return delete this.partialTLSMessages[e.type], t;
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Passes a TLS record to the client.
|
|
1132
|
+
*
|
|
1133
|
+
* Accepts unencrypted data and ensures it gets encrypted
|
|
1134
|
+
* if needed before sending it to the client. The encryption
|
|
1135
|
+
* only kicks in after the handshake is complete.
|
|
1136
|
+
*/
|
|
1137
|
+
async writeTLSRecord(e, t) {
|
|
1138
|
+
e === C.Handshake && this.handshakeMessages.push(t), this.sessionKeys && e !== C.ChangeCipherSpec && (t = await this.encryptData(e, t));
|
|
1139
|
+
const r = U, n = t.length, i = new Uint8Array(5);
|
|
1140
|
+
i[0] = e, i[1] = r[0], i[2] = r[1], i[3] = n >> 8 & 255, i[4] = n & 255;
|
|
1141
|
+
const _ = h([i, t]);
|
|
1142
|
+
this.clientDownstreamWriter.write(_);
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Encrypts data in a TLS 1.2-compliant manner using
|
|
1146
|
+
* the AES-GCM algorithm.
|
|
1147
|
+
*/
|
|
1148
|
+
async encryptData(e, t) {
|
|
1149
|
+
const r = this.sessionKeys.serverIV, n = crypto.getRandomValues(new Uint8Array(8)), i = new Uint8Array([...r, ...n]), _ = new Uint8Array([
|
|
1150
|
+
...G(this.sentRecordSequenceNumber),
|
|
1151
|
+
e,
|
|
1152
|
+
...U,
|
|
1153
|
+
// Payload length without IV and tag
|
|
1154
|
+
...I(t.length)
|
|
1155
|
+
]), a = await crypto.subtle.encrypt(
|
|
1156
|
+
{
|
|
1157
|
+
name: "AES-GCM",
|
|
1158
|
+
iv: i,
|
|
1159
|
+
additionalData: _,
|
|
1160
|
+
tagLength: 128
|
|
1161
|
+
},
|
|
1162
|
+
this.sessionKeys.serverWriteKey,
|
|
1163
|
+
t
|
|
1164
|
+
);
|
|
1165
|
+
return ++this.sentRecordSequenceNumber, h([
|
|
1166
|
+
n,
|
|
1167
|
+
new Uint8Array(a)
|
|
1168
|
+
]);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
class f {
|
|
1172
|
+
static TLSMessage(e, t) {
|
|
1173
|
+
switch (e) {
|
|
1174
|
+
case C.Handshake:
|
|
1175
|
+
return f.clientHandshake(t);
|
|
1176
|
+
case C.Alert:
|
|
1177
|
+
return f.alert(t);
|
|
1178
|
+
case C.ChangeCipherSpec:
|
|
1179
|
+
return f.changeCipherSpec();
|
|
1180
|
+
case C.ApplicationData:
|
|
1181
|
+
return f.applicationData(t);
|
|
1182
|
+
default:
|
|
1183
|
+
throw new Error(`TLS: Unsupported TLS record type ${e}`);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Parses the cipher suites from the server hello message.
|
|
1188
|
+
*
|
|
1189
|
+
* The cipher suites are encoded as a list of 2-byte values.
|
|
1190
|
+
*
|
|
1191
|
+
* Binary layout:
|
|
1192
|
+
*
|
|
1193
|
+
* +----------------------------+
|
|
1194
|
+
* | Cipher Suites Length | 2 bytes
|
|
1195
|
+
* +----------------------------+
|
|
1196
|
+
* | Cipher Suite 1 | 2 bytes
|
|
1197
|
+
* +----------------------------+
|
|
1198
|
+
* | Cipher Suite 2 | 2 bytes
|
|
1199
|
+
* +----------------------------+
|
|
1200
|
+
* | ... |
|
|
1201
|
+
* +----------------------------+
|
|
1202
|
+
* | Cipher Suite n | 2 bytes
|
|
1203
|
+
* +----------------------------+
|
|
1204
|
+
*
|
|
1205
|
+
* The full list of supported cipher suites values is available at:
|
|
1206
|
+
*
|
|
1207
|
+
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
|
|
1208
|
+
*/
|
|
1209
|
+
static parseCipherSuites(e) {
|
|
1210
|
+
const t = new g(e);
|
|
1211
|
+
t.readUint16();
|
|
1212
|
+
const r = [];
|
|
1213
|
+
for (; !t.isFinished(); ) {
|
|
1214
|
+
const n = t.readUint16();
|
|
1215
|
+
n in j && r.push(j[n]);
|
|
1216
|
+
}
|
|
1217
|
+
return r;
|
|
1218
|
+
}
|
|
1219
|
+
static applicationData(e) {
|
|
1220
|
+
return {
|
|
1221
|
+
type: C.ApplicationData,
|
|
1222
|
+
body: e
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
static changeCipherSpec() {
|
|
1226
|
+
return {
|
|
1227
|
+
type: C.ChangeCipherSpec,
|
|
1228
|
+
body: new Uint8Array()
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
static alert(e) {
|
|
1232
|
+
return {
|
|
1233
|
+
type: C.Alert,
|
|
1234
|
+
level: he[e[0]],
|
|
1235
|
+
description: He[e[1]]
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
static clientHandshake(e) {
|
|
1239
|
+
const t = e[0], r = e[1] << 16 | e[2] << 8 | e[3], n = e.slice(4);
|
|
1240
|
+
let i;
|
|
1241
|
+
switch (t) {
|
|
1242
|
+
case d.HelloRequest:
|
|
1243
|
+
i = f.clientHelloRequestPayload();
|
|
1244
|
+
break;
|
|
1245
|
+
case d.ClientHello:
|
|
1246
|
+
i = f.clientHelloPayload(n);
|
|
1247
|
+
break;
|
|
1248
|
+
case d.ClientKeyExchange:
|
|
1249
|
+
i = f.clientKeyExchangePayload(n);
|
|
1250
|
+
break;
|
|
1251
|
+
case d.Finished:
|
|
1252
|
+
i = f.clientFinishedPayload(n);
|
|
1253
|
+
break;
|
|
1254
|
+
default:
|
|
1255
|
+
throw new Error(`Invalid handshake type ${t}`);
|
|
1256
|
+
}
|
|
1257
|
+
return {
|
|
1258
|
+
type: C.Handshake,
|
|
1259
|
+
msg_type: t,
|
|
1260
|
+
length: r,
|
|
1261
|
+
body: i
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
static clientHelloRequestPayload() {
|
|
1265
|
+
return {};
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Offset Size Field
|
|
1269
|
+
* (bytes) (bytes)
|
|
1270
|
+
* +------+------+---------------------------+
|
|
1271
|
+
* | 0000 | 1 | Handshake Type (1 = ClientHello)
|
|
1272
|
+
* +------+------+---------------------------+
|
|
1273
|
+
* | 0001 | 3 | Length of ClientHello
|
|
1274
|
+
* +------+------+---------------------------+
|
|
1275
|
+
* | 0004 | 2 | Protocol Version
|
|
1276
|
+
* +------+------+---------------------------+
|
|
1277
|
+
* | 0006 | 32 | Client Random
|
|
1278
|
+
* | | | (4 bytes timestamp +
|
|
1279
|
+
* | | | 28 bytes random)
|
|
1280
|
+
* +------+------+---------------------------+
|
|
1281
|
+
* | 0038 | 1 | Session ID Length
|
|
1282
|
+
* +------+------+---------------------------+
|
|
1283
|
+
* | 0039 | 0+ | Session ID (variable)
|
|
1284
|
+
* | | | (0-32 bytes)
|
|
1285
|
+
* +------+------+---------------------------+
|
|
1286
|
+
* | 003A*| 2 | Cipher Suites Length
|
|
1287
|
+
* +------+------+---------------------------+
|
|
1288
|
+
* | 003C*| 2+ | Cipher Suites
|
|
1289
|
+
* | | | (2 bytes each)
|
|
1290
|
+
* +------+------+---------------------------+
|
|
1291
|
+
* | xxxx | 1 | Compression Methods Length
|
|
1292
|
+
* +------+------+---------------------------+
|
|
1293
|
+
* | xxxx | 1+ | Compression Methods
|
|
1294
|
+
* | | | (1 byte each)
|
|
1295
|
+
* +------+------+---------------------------+
|
|
1296
|
+
* | xxxx | 2 | Extensions Length
|
|
1297
|
+
* +------+------+---------------------------+
|
|
1298
|
+
* | xxxx | 2 | Extension Type
|
|
1299
|
+
* +------+------+---------------------------+
|
|
1300
|
+
* | xxxx | 2 | Extension Length
|
|
1301
|
+
* +------+------+---------------------------+
|
|
1302
|
+
* | xxxx | v | Extension Data
|
|
1303
|
+
* +------+------+---------------------------+
|
|
1304
|
+
* | | | (Additional extensions...)
|
|
1305
|
+
* +------+------+---------------------------+
|
|
1306
|
+
*/
|
|
1307
|
+
static clientHelloPayload(e) {
|
|
1308
|
+
const t = new g(e.buffer), r = {
|
|
1309
|
+
client_version: t.readUint8Array(2),
|
|
1310
|
+
/**
|
|
1311
|
+
* Technically this consists of a GMT timestamp
|
|
1312
|
+
* and 28 random bytes, but we don't need to
|
|
1313
|
+
* parse this further.
|
|
1314
|
+
*/
|
|
1315
|
+
random: t.readUint8Array(32)
|
|
1316
|
+
}, n = t.readUint8();
|
|
1317
|
+
r.session_id = t.readUint8Array(n);
|
|
1318
|
+
const i = t.readUint16();
|
|
1319
|
+
r.cipher_suites = f.parseCipherSuites(
|
|
1320
|
+
t.readUint8Array(i).buffer
|
|
1321
|
+
);
|
|
1322
|
+
const _ = t.readUint8();
|
|
1323
|
+
r.compression_methods = t.readUint8Array(
|
|
1324
|
+
_
|
|
1325
|
+
);
|
|
1326
|
+
const a = t.readUint16();
|
|
1327
|
+
return r.extensions = Re(
|
|
1328
|
+
t.readUint8Array(a)
|
|
1329
|
+
), r;
|
|
1330
|
+
}
|
|
1331
|
+
/**
|
|
1332
|
+
* Binary layout:
|
|
1333
|
+
*
|
|
1334
|
+
* +------------------------------------+
|
|
1335
|
+
* | ECDH Client Public Key Length [1B] |
|
|
1336
|
+
* +------------------------------------+
|
|
1337
|
+
* | ECDH Client Public Key [variable]|
|
|
1338
|
+
* +------------------------------------+
|
|
1339
|
+
*/
|
|
1340
|
+
static clientKeyExchangePayload(e) {
|
|
1341
|
+
return {
|
|
1342
|
+
// Skip the first byte, which is the length of the public key
|
|
1343
|
+
exchange_keys: e.slice(1, e.length)
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
static clientFinishedPayload(e) {
|
|
1347
|
+
return {
|
|
1348
|
+
verify_data: e
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
function Ne(s) {
|
|
1353
|
+
return new TransformStream({
|
|
1354
|
+
transform(e, t) {
|
|
1355
|
+
for (; e.length > 0; )
|
|
1356
|
+
t.enqueue(e.slice(0, s)), e = e.slice(s);
|
|
1357
|
+
}
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
class K {
|
|
1361
|
+
static certificate(e) {
|
|
1362
|
+
const t = [];
|
|
1363
|
+
for (const i of e)
|
|
1364
|
+
t.push(m(i.byteLength)), t.push(new Uint8Array(i));
|
|
1365
|
+
const r = h(t), n = new Uint8Array([
|
|
1366
|
+
...m(r.byteLength),
|
|
1367
|
+
...r
|
|
1368
|
+
]);
|
|
1369
|
+
return new Uint8Array([
|
|
1370
|
+
d.Certificate,
|
|
1371
|
+
...m(n.length),
|
|
1372
|
+
...n
|
|
1373
|
+
]);
|
|
1374
|
+
}
|
|
1375
|
+
/*
|
|
1376
|
+
* Byte layout of the ServerKeyExchange message:
|
|
1377
|
+
*
|
|
1378
|
+
* +-----------------------------------+
|
|
1379
|
+
* | ServerKeyExchange Message |
|
|
1380
|
+
* +-----------------------------------+
|
|
1381
|
+
* | Handshake type (1 byte) |
|
|
1382
|
+
* +-----------------------------------+
|
|
1383
|
+
* | Length (3 bytes) |
|
|
1384
|
+
* +-----------------------------------+
|
|
1385
|
+
* | Curve Type (1 byte) |
|
|
1386
|
+
* +-----------------------------------+
|
|
1387
|
+
* | Named Curve (2 bytes) |
|
|
1388
|
+
* +-----------------------------------+
|
|
1389
|
+
* | EC Point Format (1 byte) |
|
|
1390
|
+
* +-----------------------------------+
|
|
1391
|
+
* | Public Key Length (1 byte) |
|
|
1392
|
+
* +-----------------------------------+
|
|
1393
|
+
* | Public Key (variable) |
|
|
1394
|
+
* +-----------------------------------+
|
|
1395
|
+
* | Signature Algorithm (2 bytes) |
|
|
1396
|
+
* +-----------------------------------+
|
|
1397
|
+
* | Signature Length (2 bytes) |
|
|
1398
|
+
* +-----------------------------------+
|
|
1399
|
+
* | Signature (variable) |
|
|
1400
|
+
* +-----------------------------------+
|
|
1401
|
+
*
|
|
1402
|
+
* @param clientRandom - 32 bytes from ClientHello
|
|
1403
|
+
* @param serverRandom - 32 bytes from ServerHello
|
|
1404
|
+
* @param ecdheKeyPair - ECDHE key pair
|
|
1405
|
+
* @param rsaPrivateKey - RSA private key for signing
|
|
1406
|
+
* @returns
|
|
1407
|
+
*/
|
|
1408
|
+
static async ECDHEServerKeyExchange(e, t, r, n) {
|
|
1409
|
+
const i = new Uint8Array(
|
|
1410
|
+
await crypto.subtle.exportKey("raw", r.publicKey)
|
|
1411
|
+
), _ = new Uint8Array([
|
|
1412
|
+
// Curve type (1 byte)
|
|
1413
|
+
Ue.NamedCurve,
|
|
1414
|
+
// Curve name (2 bytes)
|
|
1415
|
+
...I(ve.secp256r1),
|
|
1416
|
+
// Public key length (1 byte)
|
|
1417
|
+
i.byteLength,
|
|
1418
|
+
// Public key (65 bytes, uncompressed format)
|
|
1419
|
+
...i
|
|
1420
|
+
]), a = await crypto.subtle.sign(
|
|
1421
|
+
{
|
|
1422
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
1423
|
+
hash: "SHA-256"
|
|
1424
|
+
},
|
|
1425
|
+
n,
|
|
1426
|
+
new Uint8Array([...e, ...t, ..._])
|
|
1427
|
+
), c = new Uint8Array(a), S = new Uint8Array([
|
|
1428
|
+
O.sha256,
|
|
1429
|
+
N.rsa
|
|
1430
|
+
]), l = new Uint8Array([
|
|
1431
|
+
..._,
|
|
1432
|
+
...S,
|
|
1433
|
+
...I(c.length),
|
|
1434
|
+
...c
|
|
1435
|
+
]);
|
|
1436
|
+
return new Uint8Array([
|
|
1437
|
+
d.ServerKeyExchange,
|
|
1438
|
+
...m(l.length),
|
|
1439
|
+
...l
|
|
1440
|
+
]);
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* +------------------------------------+
|
|
1444
|
+
* | Content Type (Handshake) [1B] |
|
|
1445
|
+
* | 0x16 |
|
|
1446
|
+
* +------------------------------------+
|
|
1447
|
+
* | Version (TLS 1.2) [2B] |
|
|
1448
|
+
* | 0x03 0x03 |
|
|
1449
|
+
* +------------------------------------+
|
|
1450
|
+
* | Length [2B] |
|
|
1451
|
+
* +------------------------------------+
|
|
1452
|
+
* | Handshake Type (ServerHello) [1B] |
|
|
1453
|
+
* | 0x02 |
|
|
1454
|
+
* +------------------------------------+
|
|
1455
|
+
* | Handshake Length [3B] |
|
|
1456
|
+
* +------------------------------------+
|
|
1457
|
+
* | Server Version [2B] |
|
|
1458
|
+
* +------------------------------------+
|
|
1459
|
+
* | Server Random [32B] |
|
|
1460
|
+
* +------------------------------------+
|
|
1461
|
+
* | Session ID Length [1B] |
|
|
1462
|
+
* +------------------------------------+
|
|
1463
|
+
* | Session ID [0-32B] |
|
|
1464
|
+
* +------------------------------------+
|
|
1465
|
+
* | Cipher Suite [2B] |
|
|
1466
|
+
* +------------------------------------+
|
|
1467
|
+
* | Compression Method [1B] |
|
|
1468
|
+
* +------------------------------------+
|
|
1469
|
+
* | Extensions Length [2B] |
|
|
1470
|
+
* +------------------------------------+
|
|
1471
|
+
* | Extension: ec_point_formats |
|
|
1472
|
+
* | Type (0x00 0x0B) [2B] |
|
|
1473
|
+
* | Length [2B] |
|
|
1474
|
+
* | EC Point Formats Length [1B] |
|
|
1475
|
+
* | EC Point Format [1B] |
|
|
1476
|
+
* +------------------------------------+
|
|
1477
|
+
* | Other Extensions... |
|
|
1478
|
+
* +------------------------------------+
|
|
1479
|
+
*/
|
|
1480
|
+
static serverHello(e, t, r) {
|
|
1481
|
+
const n = e.extensions.map((a) => {
|
|
1482
|
+
switch (a.type) {
|
|
1483
|
+
case "server_name":
|
|
1484
|
+
return ae.encodeForClient();
|
|
1485
|
+
case "supported_groups":
|
|
1486
|
+
return Se.encodeForClient(
|
|
1487
|
+
"secp256r1"
|
|
1488
|
+
);
|
|
1489
|
+
case "ec_point_formats":
|
|
1490
|
+
return le.encodeForClient(
|
|
1491
|
+
"uncompressed"
|
|
1492
|
+
);
|
|
1493
|
+
case "signature_algorithms":
|
|
1494
|
+
return Ae.encodeforClient(
|
|
1495
|
+
"sha256",
|
|
1496
|
+
"rsa"
|
|
1497
|
+
);
|
|
1498
|
+
}
|
|
1499
|
+
}).filter((a) => a !== void 0), i = h(n), _ = new Uint8Array([
|
|
1500
|
+
// Version field – 0x03, 0x03 means TLS 1.2
|
|
1501
|
+
...U,
|
|
1502
|
+
...t,
|
|
1503
|
+
e.session_id.length,
|
|
1504
|
+
...e.session_id,
|
|
1505
|
+
...I(oe.TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
|
|
1506
|
+
r,
|
|
1507
|
+
// Extensions length (2 bytes)
|
|
1508
|
+
...I(i.length),
|
|
1509
|
+
...i
|
|
1510
|
+
]);
|
|
1511
|
+
return new Uint8Array([
|
|
1512
|
+
d.ServerHello,
|
|
1513
|
+
...m(_.length),
|
|
1514
|
+
..._
|
|
1515
|
+
]);
|
|
1516
|
+
}
|
|
1517
|
+
static serverHelloDone() {
|
|
1518
|
+
return new Uint8Array([d.ServerHelloDone, ...m(0)]);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Server finished message.
|
|
1522
|
+
* The structure is defined in:
|
|
1523
|
+
* https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.9
|
|
1524
|
+
*
|
|
1525
|
+
* struct {
|
|
1526
|
+
* opaque verify_data[verify_data_length];
|
|
1527
|
+
* } Finished;
|
|
1528
|
+
*
|
|
1529
|
+
* verify_data
|
|
1530
|
+
* PRF(master_secret, finished_label, Hash(handshake_messages))
|
|
1531
|
+
* [0..verify_data_length-1];
|
|
1532
|
+
*
|
|
1533
|
+
* finished_label
|
|
1534
|
+
* For Finished messages sent by the client, the string
|
|
1535
|
+
* "client finished". For Finished messages sent by the server,
|
|
1536
|
+
* the string "server finished".
|
|
1537
|
+
*/
|
|
1538
|
+
static async createFinishedMessage(e, t) {
|
|
1539
|
+
const r = await crypto.subtle.digest(
|
|
1540
|
+
"SHA-256",
|
|
1541
|
+
h(e)
|
|
1542
|
+
), n = new Uint8Array(
|
|
1543
|
+
await M(
|
|
1544
|
+
t,
|
|
1545
|
+
new TextEncoder().encode("server finished"),
|
|
1546
|
+
r,
|
|
1547
|
+
// verify_data length. TLS 1.2 specifies 12 bytes for verify_data
|
|
1548
|
+
12
|
|
1549
|
+
)
|
|
1550
|
+
);
|
|
1551
|
+
return new Uint8Array([
|
|
1552
|
+
d.Finished,
|
|
1553
|
+
...m(n.length),
|
|
1554
|
+
...n
|
|
1555
|
+
]);
|
|
1556
|
+
}
|
|
1557
|
+
static changeCipherSpec() {
|
|
1558
|
+
return new Uint8Array([1]);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
function Oe(s, e) {
|
|
1562
|
+
return qe.generateCertificate(s, e);
|
|
1563
|
+
}
|
|
1564
|
+
function ot(s) {
|
|
1565
|
+
return `-----BEGIN CERTIFICATE-----
|
|
1566
|
+
${fe(
|
|
1567
|
+
de(s.buffer)
|
|
1568
|
+
)}
|
|
1569
|
+
-----END CERTIFICATE-----`;
|
|
1570
|
+
}
|
|
1571
|
+
async function ct(s) {
|
|
1572
|
+
const e = await crypto.subtle.exportKey("pkcs8", s);
|
|
1573
|
+
return `-----BEGIN PRIVATE KEY-----
|
|
1574
|
+
${fe(
|
|
1575
|
+
de(e)
|
|
1576
|
+
)}
|
|
1577
|
+
-----END PRIVATE KEY-----`;
|
|
1578
|
+
}
|
|
1579
|
+
class qe {
|
|
1580
|
+
static async generateCertificate(e, t) {
|
|
1581
|
+
const r = await crypto.subtle.generateKey(
|
|
1582
|
+
{
|
|
1583
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
1584
|
+
hash: "SHA-256",
|
|
1585
|
+
modulusLength: 2048,
|
|
1586
|
+
publicExponent: new Uint8Array([1, 0, 1])
|
|
1587
|
+
},
|
|
1588
|
+
!0,
|
|
1589
|
+
// extractable
|
|
1590
|
+
["sign", "verify"]
|
|
1591
|
+
), n = await this.signingRequest(
|
|
1592
|
+
e,
|
|
1593
|
+
r.publicKey
|
|
1594
|
+
), i = await this.sign(
|
|
1595
|
+
n,
|
|
1596
|
+
(t == null ? void 0 : t.privateKey) ?? r.privateKey
|
|
1597
|
+
);
|
|
1598
|
+
return {
|
|
1599
|
+
keyPair: r,
|
|
1600
|
+
certificate: i,
|
|
1601
|
+
tbsCertificate: n,
|
|
1602
|
+
tbsDescription: e
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
static async sign(e, t) {
|
|
1606
|
+
const r = await crypto.subtle.sign(
|
|
1607
|
+
{
|
|
1608
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
1609
|
+
hash: "SHA-256"
|
|
1610
|
+
},
|
|
1611
|
+
t,
|
|
1612
|
+
e.buffer
|
|
1613
|
+
);
|
|
1614
|
+
return o.sequence([
|
|
1615
|
+
new Uint8Array(e.buffer),
|
|
1616
|
+
this.signatureAlgorithm("sha256WithRSAEncryption"),
|
|
1617
|
+
o.bitString(new Uint8Array(r))
|
|
1618
|
+
]);
|
|
1619
|
+
}
|
|
1620
|
+
static async signingRequest(e, t) {
|
|
1621
|
+
const r = [];
|
|
1622
|
+
return e.keyUsage && r.push(this.keyUsage(e.keyUsage)), e.extKeyUsage && r.push(this.extKeyUsage(e.extKeyUsage)), e.subjectAltNames && r.push(this.subjectAltName(e.subjectAltNames)), e.nsCertType && r.push(this.nsCertType(e.nsCertType)), e.basicConstraints && r.push(
|
|
1623
|
+
this.basicConstraints(e.basicConstraints)
|
|
1624
|
+
), o.sequence([
|
|
1625
|
+
this.version(e.version),
|
|
1626
|
+
this.serialNumber(e.serialNumber),
|
|
1627
|
+
this.signatureAlgorithm(e.signatureAlgorithm),
|
|
1628
|
+
this.distinguishedName(e.issuer ?? e.subject),
|
|
1629
|
+
this.validity(e.validity),
|
|
1630
|
+
this.distinguishedName(e.subject),
|
|
1631
|
+
await this.subjectPublicKeyInfo(t),
|
|
1632
|
+
this.extensions(r)
|
|
1633
|
+
]);
|
|
1634
|
+
}
|
|
1635
|
+
static version(e = 2) {
|
|
1636
|
+
return o.ASN1(
|
|
1637
|
+
160,
|
|
1638
|
+
o.integer(new Uint8Array([e]))
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
static serialNumber(e = crypto.getRandomValues(new Uint8Array(4))) {
|
|
1642
|
+
return o.integer(e);
|
|
1643
|
+
}
|
|
1644
|
+
static signatureAlgorithm(e = "sha256WithRSAEncryption") {
|
|
1645
|
+
return o.sequence([
|
|
1646
|
+
o.objectIdentifier(w(e)),
|
|
1647
|
+
o.null()
|
|
1648
|
+
]);
|
|
1649
|
+
}
|
|
1650
|
+
static async subjectPublicKeyInfo(e) {
|
|
1651
|
+
return new Uint8Array(await crypto.subtle.exportKey("spki", e));
|
|
1652
|
+
}
|
|
1653
|
+
static extensions(e) {
|
|
1654
|
+
return o.ASN1(163, o.sequence(e));
|
|
1655
|
+
}
|
|
1656
|
+
static distinguishedName(e) {
|
|
1657
|
+
const t = [];
|
|
1658
|
+
for (const [r, n] of Object.entries(e)) {
|
|
1659
|
+
const i = [
|
|
1660
|
+
o.objectIdentifier(w(r))
|
|
1661
|
+
];
|
|
1662
|
+
switch (r) {
|
|
1663
|
+
case "countryName":
|
|
1664
|
+
i.push(o.printableString(n));
|
|
1665
|
+
break;
|
|
1666
|
+
default:
|
|
1667
|
+
i.push(o.utf8String(n));
|
|
1668
|
+
}
|
|
1669
|
+
t.push(o.set([o.sequence(i)]));
|
|
1670
|
+
}
|
|
1671
|
+
return o.sequence(t);
|
|
1672
|
+
}
|
|
1673
|
+
static validity(e) {
|
|
1674
|
+
return o.sequence([
|
|
1675
|
+
o.ASN1(
|
|
1676
|
+
H.UTCTime,
|
|
1677
|
+
new TextEncoder().encode(
|
|
1678
|
+
ee((e == null ? void 0 : e.notBefore) ?? /* @__PURE__ */ new Date())
|
|
1679
|
+
)
|
|
1680
|
+
),
|
|
1681
|
+
o.ASN1(
|
|
1682
|
+
H.UTCTime,
|
|
1683
|
+
new TextEncoder().encode(
|
|
1684
|
+
ee(
|
|
1685
|
+
(e == null ? void 0 : e.notAfter) ?? Fe(/* @__PURE__ */ new Date(), 10)
|
|
1686
|
+
)
|
|
1687
|
+
)
|
|
1688
|
+
)
|
|
1689
|
+
]);
|
|
1690
|
+
}
|
|
1691
|
+
static basicConstraints({
|
|
1692
|
+
ca: e = !0,
|
|
1693
|
+
pathLenConstraint: t = void 0
|
|
1694
|
+
}) {
|
|
1695
|
+
const r = [o.boolean(e)];
|
|
1696
|
+
return t !== void 0 && r.push(
|
|
1697
|
+
o.integer(new Uint8Array([t]))
|
|
1698
|
+
), o.sequence([
|
|
1699
|
+
o.objectIdentifier(w("basicConstraints")),
|
|
1700
|
+
o.octetString(o.sequence(r))
|
|
1701
|
+
]);
|
|
1702
|
+
}
|
|
1703
|
+
static keyUsage(e) {
|
|
1704
|
+
const t = new Uint8Array([0]);
|
|
1705
|
+
return e != null && e.digitalSignature && (t[0] |= 1), e != null && e.nonRepudiation && (t[0] |= 2), e != null && e.keyEncipherment && (t[0] |= 4), e != null && e.dataEncipherment && (t[0] |= 8), e != null && e.keyAgreement && (t[0] |= 16), e != null && e.keyCertSign && (t[0] |= 32), e != null && e.cRLSign && (t[0] |= 64), e != null && e.encipherOnly && (t[0] |= 128), e != null && e.decipherOnly && (t[0] |= 64), o.sequence([
|
|
1706
|
+
o.objectIdentifier(w("keyUsage")),
|
|
1707
|
+
o.boolean(!0),
|
|
1708
|
+
// Critical
|
|
1709
|
+
o.octetString(o.bitString(t))
|
|
1710
|
+
]);
|
|
1711
|
+
}
|
|
1712
|
+
static extKeyUsage(e = {}) {
|
|
1713
|
+
return o.sequence([
|
|
1714
|
+
o.objectIdentifier(w("extKeyUsage")),
|
|
1715
|
+
o.boolean(!0),
|
|
1716
|
+
// Critical
|
|
1717
|
+
o.octetString(
|
|
1718
|
+
o.sequence(
|
|
1719
|
+
Object.entries(e).map(([t, r]) => r ? o.objectIdentifier(
|
|
1720
|
+
w(t)
|
|
1721
|
+
) : o.null())
|
|
1722
|
+
)
|
|
1723
|
+
)
|
|
1724
|
+
]);
|
|
1725
|
+
}
|
|
1726
|
+
static nsCertType(e) {
|
|
1727
|
+
const t = new Uint8Array([0]);
|
|
1728
|
+
return e.client && (t[0] |= 1), e.server && (t[0] |= 2), e.email && (t[0] |= 4), e.objsign && (t[0] |= 8), e.sslCA && (t[0] |= 16), e.emailCA && (t[0] |= 32), e.objCA && (t[0] |= 64), o.sequence([
|
|
1729
|
+
o.objectIdentifier(w("nsCertType")),
|
|
1730
|
+
o.octetString(t)
|
|
1731
|
+
]);
|
|
1732
|
+
}
|
|
1733
|
+
static subjectAltName(e) {
|
|
1734
|
+
var i, _;
|
|
1735
|
+
const t = ((i = e.dnsNames) == null ? void 0 : i.map((a) => {
|
|
1736
|
+
const c = o.ia5String(a);
|
|
1737
|
+
return o.contextSpecific(2, c);
|
|
1738
|
+
})) || [], r = ((_ = e.ipAddresses) == null ? void 0 : _.map((a) => {
|
|
1739
|
+
const c = o.ia5String(a);
|
|
1740
|
+
return o.contextSpecific(7, c);
|
|
1741
|
+
})) || [], n = o.octetString(
|
|
1742
|
+
o.sequence([...t, ...r])
|
|
1743
|
+
);
|
|
1744
|
+
return o.sequence([
|
|
1745
|
+
o.objectIdentifier(w("subjectAltName")),
|
|
1746
|
+
o.boolean(!0),
|
|
1747
|
+
n
|
|
1748
|
+
]);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
const ke = {
|
|
1752
|
+
// Algorithm OIDs
|
|
1753
|
+
"1.2.840.113549.1.1.1": "rsaEncryption",
|
|
1754
|
+
"1.2.840.113549.1.1.4": "md5WithRSAEncryption",
|
|
1755
|
+
"1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
|
|
1756
|
+
"1.2.840.113549.1.1.7": "RSAES-OAEP",
|
|
1757
|
+
"1.2.840.113549.1.1.8": "mgf1",
|
|
1758
|
+
"1.2.840.113549.1.1.9": "pSpecified",
|
|
1759
|
+
"1.2.840.113549.1.1.10": "RSASSA-PSS",
|
|
1760
|
+
"1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
|
|
1761
|
+
"1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
|
|
1762
|
+
"1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
|
|
1763
|
+
"1.3.101.112": "EdDSA25519",
|
|
1764
|
+
"1.2.840.10040.4.3": "dsa-with-sha1",
|
|
1765
|
+
"1.3.14.3.2.7": "desCBC",
|
|
1766
|
+
"1.3.14.3.2.26": "sha1",
|
|
1767
|
+
"1.3.14.3.2.29": "sha1WithRSASignature",
|
|
1768
|
+
"2.16.840.1.101.3.4.2.1": "sha256",
|
|
1769
|
+
"2.16.840.1.101.3.4.2.2": "sha384",
|
|
1770
|
+
"2.16.840.1.101.3.4.2.3": "sha512",
|
|
1771
|
+
"2.16.840.1.101.3.4.2.4": "sha224",
|
|
1772
|
+
"2.16.840.1.101.3.4.2.5": "sha512-224",
|
|
1773
|
+
"2.16.840.1.101.3.4.2.6": "sha512-256",
|
|
1774
|
+
"1.2.840.113549.2.2": "md2",
|
|
1775
|
+
"1.2.840.113549.2.5": "md5",
|
|
1776
|
+
// pkcs#7 content types
|
|
1777
|
+
"1.2.840.113549.1.7.1": "data",
|
|
1778
|
+
"1.2.840.113549.1.7.2": "signedData",
|
|
1779
|
+
"1.2.840.113549.1.7.3": "envelopedData",
|
|
1780
|
+
"1.2.840.113549.1.7.4": "signedAndEnvelopedData",
|
|
1781
|
+
"1.2.840.113549.1.7.5": "digestedData",
|
|
1782
|
+
"1.2.840.113549.1.7.6": "encryptedData",
|
|
1783
|
+
// pkcs#9 oids
|
|
1784
|
+
"1.2.840.113549.1.9.1": "emailAddress",
|
|
1785
|
+
"1.2.840.113549.1.9.2": "unstructuredName",
|
|
1786
|
+
"1.2.840.113549.1.9.3": "contentType",
|
|
1787
|
+
"1.2.840.113549.1.9.4": "messageDigest",
|
|
1788
|
+
"1.2.840.113549.1.9.5": "signingTime",
|
|
1789
|
+
"1.2.840.113549.1.9.6": "counterSignature",
|
|
1790
|
+
"1.2.840.113549.1.9.7": "challengePassword",
|
|
1791
|
+
"1.2.840.113549.1.9.8": "unstructuredAddress",
|
|
1792
|
+
"1.2.840.113549.1.9.14": "extensionRequest",
|
|
1793
|
+
"1.2.840.113549.1.9.20": "friendlyName",
|
|
1794
|
+
"1.2.840.113549.1.9.21": "localKeyId",
|
|
1795
|
+
"1.2.840.113549.1.9.22.1": "x509Certificate",
|
|
1796
|
+
// pkcs#12 safe bags
|
|
1797
|
+
"1.2.840.113549.1.12.10.1.1": "keyBag",
|
|
1798
|
+
"1.2.840.113549.1.12.10.1.2": "pkcs8ShroudedKeyBag",
|
|
1799
|
+
"1.2.840.113549.1.12.10.1.3": "certBag",
|
|
1800
|
+
"1.2.840.113549.1.12.10.1.4": "crlBag",
|
|
1801
|
+
"1.2.840.113549.1.12.10.1.5": "secretBag",
|
|
1802
|
+
"1.2.840.113549.1.12.10.1.6": "safeContentsBag",
|
|
1803
|
+
// password-based-encryption for pkcs#12
|
|
1804
|
+
"1.2.840.113549.1.5.13": "pkcs5PBES2",
|
|
1805
|
+
"1.2.840.113549.1.5.12": "pkcs5PBKDF2",
|
|
1806
|
+
"1.2.840.113549.1.12.1.1": "pbeWithSHAAnd128BitRC4",
|
|
1807
|
+
"1.2.840.113549.1.12.1.2": "pbeWithSHAAnd40BitRC4",
|
|
1808
|
+
"1.2.840.113549.1.12.1.3": "pbeWithSHAAnd3-KeyTripleDES-CBC",
|
|
1809
|
+
"1.2.840.113549.1.12.1.4": "pbeWithSHAAnd2-KeyTripleDES-CBC",
|
|
1810
|
+
"1.2.840.113549.1.12.1.5": "pbeWithSHAAnd128BitRC2-CBC",
|
|
1811
|
+
"1.2.840.113549.1.12.1.6": "pbewithSHAAnd40BitRC2-CBC",
|
|
1812
|
+
// hmac OIDs
|
|
1813
|
+
"1.2.840.113549.2.7": "hmacWithSHA1",
|
|
1814
|
+
"1.2.840.113549.2.8": "hmacWithSHA224",
|
|
1815
|
+
"1.2.840.113549.2.9": "hmacWithSHA256",
|
|
1816
|
+
"1.2.840.113549.2.10": "hmacWithSHA384",
|
|
1817
|
+
"1.2.840.113549.2.11": "hmacWithSHA512",
|
|
1818
|
+
// symmetric key algorithm oids
|
|
1819
|
+
"1.2.840.113549.3.7": "des-EDE3-CBC",
|
|
1820
|
+
"2.16.840.1.101.3.4.1.2": "aes128-CBC",
|
|
1821
|
+
"2.16.840.1.101.3.4.1.22": "aes192-CBC",
|
|
1822
|
+
"2.16.840.1.101.3.4.1.42": "aes256-CBC",
|
|
1823
|
+
// certificate issuer/subject OIDs
|
|
1824
|
+
"2.5.4.3": "commonName",
|
|
1825
|
+
"2.5.4.4": "surname",
|
|
1826
|
+
"2.5.4.5": "serialNumber",
|
|
1827
|
+
"2.5.4.6": "countryName",
|
|
1828
|
+
"2.5.4.7": "localityName",
|
|
1829
|
+
"2.5.4.8": "stateOrProvinceName",
|
|
1830
|
+
"2.5.4.9": "streetAddress",
|
|
1831
|
+
"2.5.4.10": "organizationName",
|
|
1832
|
+
"2.5.4.11": "organizationalUnitName",
|
|
1833
|
+
"2.5.4.12": "title",
|
|
1834
|
+
"2.5.4.13": "description",
|
|
1835
|
+
"2.5.4.15": "businessCategory",
|
|
1836
|
+
"2.5.4.17": "postalCode",
|
|
1837
|
+
"2.5.4.42": "givenName",
|
|
1838
|
+
"1.3.6.1.4.1.311.60.2.1.2": "jurisdictionOfIncorporationStateOrProvinceName",
|
|
1839
|
+
"1.3.6.1.4.1.311.60.2.1.3": "jurisdictionOfIncorporationCountryName",
|
|
1840
|
+
// X.509 extension OIDs
|
|
1841
|
+
"2.16.840.1.113730.1.1": "nsCertType",
|
|
1842
|
+
"2.16.840.1.113730.1.13": "nsComment",
|
|
1843
|
+
"2.5.29.14": "subjectKeyIdentifier",
|
|
1844
|
+
"2.5.29.15": "keyUsage",
|
|
1845
|
+
"2.5.29.17": "subjectAltName",
|
|
1846
|
+
"2.5.29.18": "issuerAltName",
|
|
1847
|
+
"2.5.29.19": "basicConstraints",
|
|
1848
|
+
"2.5.29.31": "cRLDistributionPoints",
|
|
1849
|
+
"2.5.29.32": "certificatePolicies",
|
|
1850
|
+
"2.5.29.35": "authorityKeyIdentifier",
|
|
1851
|
+
"2.5.29.37": "extKeyUsage",
|
|
1852
|
+
// extKeyUsage purposes
|
|
1853
|
+
"1.3.6.1.4.1.11129.2.4.2": "timestampList",
|
|
1854
|
+
"1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
|
|
1855
|
+
"1.3.6.1.5.5.7.3.1": "serverAuth",
|
|
1856
|
+
"1.3.6.1.5.5.7.3.2": "clientAuth",
|
|
1857
|
+
"1.3.6.1.5.5.7.3.3": "codeSigning",
|
|
1858
|
+
"1.3.6.1.5.5.7.3.4": "emailProtection",
|
|
1859
|
+
"1.3.6.1.5.5.7.3.8": "timeStamping"
|
|
1860
|
+
};
|
|
1861
|
+
function w(s) {
|
|
1862
|
+
for (const [e, t] of Object.entries(ke))
|
|
1863
|
+
if (t === s)
|
|
1864
|
+
return e;
|
|
1865
|
+
throw new Error(`OID not found for name: ${s}`);
|
|
1866
|
+
}
|
|
1867
|
+
const Q = 32, H = {
|
|
1868
|
+
EOC: 0,
|
|
1869
|
+
Boolean: 1,
|
|
1870
|
+
Integer: 2,
|
|
1871
|
+
BitString: 3,
|
|
1872
|
+
OctetString: 4,
|
|
1873
|
+
Null: 5,
|
|
1874
|
+
OID: 6,
|
|
1875
|
+
ObjectDescriptor: 7,
|
|
1876
|
+
External: 8,
|
|
1877
|
+
Real: 9,
|
|
1878
|
+
// float
|
|
1879
|
+
Enumeration: 10,
|
|
1880
|
+
PDV: 11,
|
|
1881
|
+
Utf8String: 12,
|
|
1882
|
+
RelativeOID: 13,
|
|
1883
|
+
Sequence: 16 | Q,
|
|
1884
|
+
Set: 17 | Q,
|
|
1885
|
+
NumericString: 18,
|
|
1886
|
+
PrintableString: 19,
|
|
1887
|
+
T61String: 20,
|
|
1888
|
+
VideotexString: 21,
|
|
1889
|
+
IA5String: 22,
|
|
1890
|
+
UTCTime: 23,
|
|
1891
|
+
GeneralizedTime: 24,
|
|
1892
|
+
GraphicString: 25,
|
|
1893
|
+
VisibleString: 26,
|
|
1894
|
+
GeneralString: 28,
|
|
1895
|
+
UniversalString: 29,
|
|
1896
|
+
CharacterString: 30,
|
|
1897
|
+
BMPString: 31,
|
|
1898
|
+
Constructor: 32,
|
|
1899
|
+
Context: 128
|
|
1900
|
+
};
|
|
1901
|
+
class o {
|
|
1902
|
+
// Helper functions for ASN.1 DER encoding
|
|
1903
|
+
static length_(e) {
|
|
1904
|
+
if (e < 128)
|
|
1905
|
+
return new Uint8Array([e]);
|
|
1906
|
+
{
|
|
1907
|
+
let t = e;
|
|
1908
|
+
const r = [];
|
|
1909
|
+
for (; t > 0; )
|
|
1910
|
+
r.unshift(t & 255), t >>= 8;
|
|
1911
|
+
const n = r.length, i = new Uint8Array(1 + n);
|
|
1912
|
+
i[0] = 128 | n;
|
|
1913
|
+
for (let _ = 0; _ < n; _++)
|
|
1914
|
+
i[_ + 1] = r[_];
|
|
1915
|
+
return i;
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
static ASN1(e, t) {
|
|
1919
|
+
const r = o.length_(t.length), n = new Uint8Array(1 + r.length + t.length);
|
|
1920
|
+
return n[0] = e, n.set(r, 1), n.set(t, 1 + r.length), n;
|
|
1921
|
+
}
|
|
1922
|
+
static integer(e) {
|
|
1923
|
+
if (e[0] > 127) {
|
|
1924
|
+
const t = new Uint8Array(e.length + 1);
|
|
1925
|
+
t[0] = 0, t.set(e, 1), e = t;
|
|
1926
|
+
}
|
|
1927
|
+
return o.ASN1(H.Integer, e);
|
|
1928
|
+
}
|
|
1929
|
+
static bitString(e) {
|
|
1930
|
+
const t = new Uint8Array([0]), r = new Uint8Array(t.length + e.length);
|
|
1931
|
+
return r.set(t), r.set(e, t.length), o.ASN1(H.BitString, r);
|
|
1932
|
+
}
|
|
1933
|
+
static octetString(e) {
|
|
1934
|
+
return o.ASN1(H.OctetString, e);
|
|
1935
|
+
}
|
|
1936
|
+
static null() {
|
|
1937
|
+
return o.ASN1(H.Null, new Uint8Array(0));
|
|
1938
|
+
}
|
|
1939
|
+
static objectIdentifier(e) {
|
|
1940
|
+
const t = e.split(".").map(Number), n = [t[0] * 40 + t[1]];
|
|
1941
|
+
for (let i = 2; i < t.length; i++) {
|
|
1942
|
+
let _ = t[i];
|
|
1943
|
+
const a = [];
|
|
1944
|
+
do
|
|
1945
|
+
a.unshift(_ & 127), _ >>= 7;
|
|
1946
|
+
while (_ > 0);
|
|
1947
|
+
for (let c = 0; c < a.length - 1; c++)
|
|
1948
|
+
a[c] |= 128;
|
|
1949
|
+
n.push(...a);
|
|
1950
|
+
}
|
|
1951
|
+
return o.ASN1(H.OID, new Uint8Array(n));
|
|
1952
|
+
}
|
|
1953
|
+
static utf8String(e) {
|
|
1954
|
+
const t = new TextEncoder().encode(e);
|
|
1955
|
+
return o.ASN1(H.Utf8String, t);
|
|
1956
|
+
}
|
|
1957
|
+
static printableString(e) {
|
|
1958
|
+
const t = new TextEncoder().encode(e);
|
|
1959
|
+
return o.ASN1(H.PrintableString, t);
|
|
1960
|
+
}
|
|
1961
|
+
static sequence(e) {
|
|
1962
|
+
return o.ASN1(H.Sequence, h(e));
|
|
1963
|
+
}
|
|
1964
|
+
static set(e) {
|
|
1965
|
+
return o.ASN1(H.Set, h(e));
|
|
1966
|
+
}
|
|
1967
|
+
static ia5String(e) {
|
|
1968
|
+
const t = new TextEncoder().encode(e);
|
|
1969
|
+
return o.ASN1(H.IA5String, t);
|
|
1970
|
+
}
|
|
1971
|
+
static contextSpecific(e, t, r = !1) {
|
|
1972
|
+
const n = (r ? 160 : 128) | e;
|
|
1973
|
+
return o.ASN1(n, t);
|
|
1974
|
+
}
|
|
1975
|
+
static boolean(e) {
|
|
1976
|
+
return o.ASN1(
|
|
1977
|
+
H.Boolean,
|
|
1978
|
+
new Uint8Array([e ? 255 : 0])
|
|
1979
|
+
);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
function de(s) {
|
|
1983
|
+
return btoa(String.fromCodePoint(...new Uint8Array(s)));
|
|
1984
|
+
}
|
|
1985
|
+
function fe(s) {
|
|
1986
|
+
var e;
|
|
1987
|
+
return ((e = s.match(/.{1,64}/g)) == null ? void 0 : e.join(`
|
|
1988
|
+
`)) || s;
|
|
1989
|
+
}
|
|
1990
|
+
function ee(s) {
|
|
1991
|
+
const e = s.getUTCFullYear().toString().substr(2), t = W(s.getUTCMonth() + 1), r = W(s.getUTCDate()), n = W(s.getUTCHours()), i = W(s.getUTCMinutes()), _ = W(s.getUTCSeconds());
|
|
1992
|
+
return `${e}${t}${r}${n}${i}${_}Z`;
|
|
1993
|
+
}
|
|
1994
|
+
function W(s) {
|
|
1995
|
+
return s.toString().padStart(2, "0");
|
|
1996
|
+
}
|
|
1997
|
+
function Fe(s, e) {
|
|
1998
|
+
const t = new Date(s);
|
|
1999
|
+
return t.setUTCFullYear(t.getUTCFullYear() + e), t;
|
|
2000
|
+
}
|
|
2001
|
+
const Ge = (s) => ({
|
|
2002
|
+
websocket: {
|
|
2003
|
+
url: (e, t, r) => `ws://playground.internal/?${new URLSearchParams({
|
|
2004
|
+
host: t,
|
|
2005
|
+
port: r
|
|
2006
|
+
}).toString()}`,
|
|
2007
|
+
subprotocol: "binary",
|
|
2008
|
+
decorator: () => class extends je {
|
|
2009
|
+
constructor(e, t) {
|
|
2010
|
+
super(e, t, {
|
|
2011
|
+
CAroot: s.CAroot
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
class je {
|
|
2018
|
+
constructor(e, t, { CAroot: r, outputType: n = "messages" } = {}) {
|
|
2019
|
+
this.url = e, this.options = t, this.CONNECTING = 0, this.OPEN = 1, this.CLOSING = 2, this.CLOSED = 3, this.readyState = this.CONNECTING, this.binaryType = "blob", this.bufferedAmount = 0, this.extensions = "", this.protocol = "ws", this.host = "", this.port = 0, this.listeners = /* @__PURE__ */ new Map(), this.clientUpstream = new TransformStream(), this.clientUpstreamWriter = this.clientUpstream.writable.getWriter(), this.clientDownstream = new TransformStream(), this.fetchInitiated = !1, this.bufferedBytesFromClient = new Uint8Array(0);
|
|
2020
|
+
const i = new URL(e);
|
|
2021
|
+
this.host = i.searchParams.get("host"), this.port = parseInt(i.searchParams.get("port"), 10), this.binaryType = "arraybuffer", this.CAroot = r, n === "messages" && this.clientDownstream.readable.pipeTo(
|
|
2022
|
+
new WritableStream({
|
|
2023
|
+
write: (_) => {
|
|
2024
|
+
this.emit("message", { data: _ });
|
|
2025
|
+
},
|
|
2026
|
+
abort: () => {
|
|
2027
|
+
this.emit("error", new Error("ECONNREFUSED")), this.close();
|
|
2028
|
+
},
|
|
2029
|
+
close: () => {
|
|
2030
|
+
this.close();
|
|
2031
|
+
}
|
|
2032
|
+
})
|
|
2033
|
+
).catch(() => {
|
|
2034
|
+
}), this.readyState = this.OPEN, this.emit("open");
|
|
2035
|
+
}
|
|
2036
|
+
on(e, t) {
|
|
2037
|
+
this.addEventListener(e, t);
|
|
2038
|
+
}
|
|
2039
|
+
once(e, t) {
|
|
2040
|
+
const r = (n) => {
|
|
2041
|
+
t(n), this.removeEventListener(e, r);
|
|
2042
|
+
};
|
|
2043
|
+
this.addEventListener(e, r);
|
|
2044
|
+
}
|
|
2045
|
+
addEventListener(e, t) {
|
|
2046
|
+
this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t);
|
|
2047
|
+
}
|
|
2048
|
+
removeListener(e, t) {
|
|
2049
|
+
this.removeEventListener(e, t);
|
|
2050
|
+
}
|
|
2051
|
+
removeEventListener(e, t) {
|
|
2052
|
+
const r = this.listeners.get(e);
|
|
2053
|
+
r && r.delete(t);
|
|
2054
|
+
}
|
|
2055
|
+
emit(e, t = {}) {
|
|
2056
|
+
e === "message" ? this.onmessage(t) : e === "close" ? this.onclose(t) : e === "error" ? this.onerror(t) : e === "open" && this.onopen(t);
|
|
2057
|
+
const r = this.listeners.get(e);
|
|
2058
|
+
if (r)
|
|
2059
|
+
for (const n of r)
|
|
2060
|
+
n(t);
|
|
2061
|
+
}
|
|
2062
|
+
// Default event handlers that can be overridden by the user
|
|
2063
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2064
|
+
onclose(e) {
|
|
2065
|
+
}
|
|
2066
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2067
|
+
onerror(e) {
|
|
2068
|
+
}
|
|
2069
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2070
|
+
onmessage(e) {
|
|
2071
|
+
}
|
|
2072
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2073
|
+
onopen(e) {
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Emscripten calls this method whenever the WASM module
|
|
2077
|
+
* writes bytes to the TCP socket.
|
|
2078
|
+
*/
|
|
2079
|
+
send(e) {
|
|
2080
|
+
if (!(this.readyState === this.CLOSING || this.readyState === this.CLOSED) && (this.clientUpstreamWriter.write(new Uint8Array(e)), !this.fetchInitiated))
|
|
2081
|
+
switch (this.bufferedBytesFromClient = h([
|
|
2082
|
+
this.bufferedBytesFromClient,
|
|
2083
|
+
new Uint8Array(e)
|
|
2084
|
+
]), Ve(this.port, this.bufferedBytesFromClient)) {
|
|
2085
|
+
case !1:
|
|
2086
|
+
return;
|
|
2087
|
+
case "other":
|
|
2088
|
+
this.emit("error", new Error("Unsupported protocol")), this.close();
|
|
2089
|
+
break;
|
|
2090
|
+
case "tls":
|
|
2091
|
+
this.fetchOverTLS(), this.fetchInitiated = !0;
|
|
2092
|
+
break;
|
|
2093
|
+
case "http":
|
|
2094
|
+
this.fetchOverHTTP(), this.fetchInitiated = !0;
|
|
2095
|
+
break;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
async fetchOverTLS() {
|
|
2099
|
+
if (!this.CAroot)
|
|
2100
|
+
throw new Error(
|
|
2101
|
+
"TLS protocol is only supported when the TCPOverFetchWebsocket is instantiated with a CAroot"
|
|
2102
|
+
);
|
|
2103
|
+
const e = await Oe(
|
|
2104
|
+
{
|
|
2105
|
+
subject: {
|
|
2106
|
+
commonName: this.host,
|
|
2107
|
+
organizationName: this.host,
|
|
2108
|
+
countryName: "US"
|
|
2109
|
+
},
|
|
2110
|
+
issuer: this.CAroot.tbsDescription.subject
|
|
2111
|
+
},
|
|
2112
|
+
this.CAroot.keyPair
|
|
2113
|
+
), t = new xe();
|
|
2114
|
+
this.clientUpstream.readable.pipeTo(t.clientEnd.upstream.writable).catch(() => {
|
|
2115
|
+
}), t.clientEnd.downstream.readable.pipeTo(this.clientDownstream.writable).catch(() => {
|
|
2116
|
+
}), await t.TLSHandshake(e.keyPair.privateKey, [
|
|
2117
|
+
e.certificate,
|
|
2118
|
+
this.CAroot.certificate
|
|
2119
|
+
]);
|
|
2120
|
+
const r = await y.parseHttpRequest(
|
|
2121
|
+
t.serverEnd.upstream.readable,
|
|
2122
|
+
this.host,
|
|
2123
|
+
"https"
|
|
2124
|
+
);
|
|
2125
|
+
try {
|
|
2126
|
+
await y.fetchRawResponseBytes(r).pipeTo(
|
|
2127
|
+
t.serverEnd.downstream.writable
|
|
2128
|
+
);
|
|
2129
|
+
} catch {
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
async fetchOverHTTP() {
|
|
2133
|
+
const e = await y.parseHttpRequest(
|
|
2134
|
+
this.clientUpstream.readable,
|
|
2135
|
+
this.host,
|
|
2136
|
+
"http"
|
|
2137
|
+
);
|
|
2138
|
+
try {
|
|
2139
|
+
await y.fetchRawResponseBytes(e).pipeTo(
|
|
2140
|
+
this.clientDownstream.writable
|
|
2141
|
+
);
|
|
2142
|
+
} catch {
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
close() {
|
|
2146
|
+
this.emit("message", { data: new Uint8Array(0) }), this.readyState = this.CLOSING, this.emit("close"), this.readyState = this.CLOSED;
|
|
2147
|
+
}
|
|
139
2148
|
}
|
|
140
|
-
const
|
|
2149
|
+
const $e = [
|
|
2150
|
+
"GET",
|
|
2151
|
+
"POST",
|
|
2152
|
+
"HEAD",
|
|
2153
|
+
"PATCH",
|
|
2154
|
+
"OPTIONS",
|
|
2155
|
+
"DELETE",
|
|
2156
|
+
"PUT",
|
|
2157
|
+
"TRACE"
|
|
2158
|
+
];
|
|
2159
|
+
function Ve(s, e) {
|
|
2160
|
+
if (e.length < 8)
|
|
2161
|
+
return !1;
|
|
2162
|
+
if (s === 443 && e[0] === C.Handshake && // TLS versions between 1.0 and 1.2
|
|
2163
|
+
e[1] === 3 && e[2] >= 1 && e[2] <= 3)
|
|
2164
|
+
return "tls";
|
|
2165
|
+
const r = new TextDecoder("latin1", {
|
|
2166
|
+
fatal: !0
|
|
2167
|
+
}).decode(e);
|
|
2168
|
+
return $e.some(
|
|
2169
|
+
(i) => r.startsWith(i + " ")
|
|
2170
|
+
) ? "http" : "other";
|
|
2171
|
+
}
|
|
2172
|
+
class y {
|
|
2173
|
+
/**
|
|
2174
|
+
* Streams a HTTP response including the status line and headers.
|
|
2175
|
+
*/
|
|
2176
|
+
static fetchRawResponseBytes(e) {
|
|
2177
|
+
return new ReadableStream({
|
|
2178
|
+
async start(t) {
|
|
2179
|
+
var _;
|
|
2180
|
+
let r;
|
|
2181
|
+
try {
|
|
2182
|
+
r = await fetch(e), t.enqueue(y.headersAsBytes(r));
|
|
2183
|
+
} catch (a) {
|
|
2184
|
+
t.error(a);
|
|
2185
|
+
return;
|
|
2186
|
+
}
|
|
2187
|
+
const n = (_ = r.body) == null ? void 0 : _.getReader();
|
|
2188
|
+
if (!n) {
|
|
2189
|
+
t.close();
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
const i = new TextEncoder();
|
|
2193
|
+
for (; ; ) {
|
|
2194
|
+
const { done: a, value: c } = await n.read();
|
|
2195
|
+
if (c && (t.enqueue(
|
|
2196
|
+
i.encode(`${c.length.toString(16)}\r
|
|
2197
|
+
`)
|
|
2198
|
+
), t.enqueue(c), t.enqueue(i.encode(`\r
|
|
2199
|
+
`))), a) {
|
|
2200
|
+
t.enqueue(i.encode(`0\r
|
|
2201
|
+
\r
|
|
2202
|
+
`)), t.close();
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
});
|
|
2208
|
+
}
|
|
2209
|
+
static headersAsBytes(e) {
|
|
2210
|
+
const t = `HTTP/1.1 ${e.status} ${e.statusText}`, r = {};
|
|
2211
|
+
e.headers.forEach((_, a) => {
|
|
2212
|
+
r[a.toLowerCase()] = _;
|
|
2213
|
+
}), delete r["content-length"], r["transfer-encoding"] = "chunked";
|
|
2214
|
+
const n = [];
|
|
2215
|
+
for (const [_, a] of Object.entries(r))
|
|
2216
|
+
n.push(`${_}: ${a}`);
|
|
2217
|
+
const i = [t, ...n].join(`\r
|
|
2218
|
+
`) + `\r
|
|
2219
|
+
\r
|
|
2220
|
+
`;
|
|
2221
|
+
return new TextEncoder().encode(i);
|
|
2222
|
+
}
|
|
2223
|
+
/**
|
|
2224
|
+
* Parses a raw, streamed HTTP request into a Request object
|
|
2225
|
+
* with known headers and a readable body stream.
|
|
2226
|
+
*/
|
|
2227
|
+
static async parseHttpRequest(e, t, r) {
|
|
2228
|
+
let n = new Uint8Array(0), i = !1, _ = -1;
|
|
2229
|
+
const a = e.getReader();
|
|
2230
|
+
for (; _ === -1; ) {
|
|
2231
|
+
const { done: D, value: L } = await a.read();
|
|
2232
|
+
if (D) {
|
|
2233
|
+
i = !0;
|
|
2234
|
+
break;
|
|
2235
|
+
}
|
|
2236
|
+
n = h([n, L]), _ = ze(
|
|
2237
|
+
n,
|
|
2238
|
+
new Uint8Array([13, 10, 13, 10])
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
a.releaseLock();
|
|
2242
|
+
const c = n.slice(0, _), S = y.parseRequestHeaders(c), l = n.slice(
|
|
2243
|
+
_ + 4
|
|
2244
|
+
/* Skip \r\n\r\n */
|
|
2245
|
+
);
|
|
2246
|
+
let A;
|
|
2247
|
+
if (S.method !== "GET") {
|
|
2248
|
+
const D = e.getReader();
|
|
2249
|
+
A = new ReadableStream({
|
|
2250
|
+
async start(L) {
|
|
2251
|
+
l.length > 0 && L.enqueue(l), i && L.close();
|
|
2252
|
+
},
|
|
2253
|
+
async pull(L) {
|
|
2254
|
+
const { done: pe, value: q } = await D.read();
|
|
2255
|
+
if (q && L.enqueue(q), pe) {
|
|
2256
|
+
L.close();
|
|
2257
|
+
return;
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
});
|
|
2261
|
+
}
|
|
2262
|
+
const u = S.headers.get("Host") ?? t, T = new URL(S.path, r + "://" + u);
|
|
2263
|
+
return T.pathname = S.path, new Request(T.toString(), {
|
|
2264
|
+
method: S.method,
|
|
2265
|
+
headers: S.headers,
|
|
2266
|
+
body: A,
|
|
2267
|
+
// In Node.js, duplex: 'half' is required when
|
|
2268
|
+
// the body stream is provided.
|
|
2269
|
+
// @ts-expect-error
|
|
2270
|
+
duplex: "half"
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
static parseRequestHeaders(e) {
|
|
2274
|
+
const t = new TextDecoder().decode(e), r = t.split(`
|
|
2275
|
+
`)[0], [n, i] = r.split(" "), _ = new Headers();
|
|
2276
|
+
for (const a of t.split(`\r
|
|
2277
|
+
`).slice(1)) {
|
|
2278
|
+
if (a === "")
|
|
2279
|
+
break;
|
|
2280
|
+
const [c, S] = a.split(": ");
|
|
2281
|
+
_.set(c, S);
|
|
2282
|
+
}
|
|
2283
|
+
return { method: n, path: i, headers: _ };
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
function ze(s, e) {
|
|
2287
|
+
const t = s.length, r = e.length, n = t - r;
|
|
2288
|
+
for (let i = 0; i <= n; i++) {
|
|
2289
|
+
let _ = !0;
|
|
2290
|
+
for (let a = 0; a < r; a++)
|
|
2291
|
+
if (s[i + a] !== e[a]) {
|
|
2292
|
+
_ = !1;
|
|
2293
|
+
break;
|
|
2294
|
+
}
|
|
2295
|
+
if (_)
|
|
2296
|
+
return i;
|
|
2297
|
+
}
|
|
2298
|
+
return -1;
|
|
2299
|
+
}
|
|
2300
|
+
const Ye = () => ({
|
|
141
2301
|
websocket: {
|
|
142
|
-
decorator: (
|
|
2302
|
+
decorator: (s) => class extends s {
|
|
143
2303
|
constructor() {
|
|
144
2304
|
try {
|
|
145
2305
|
super();
|
|
@@ -152,153 +2312,155 @@ const I = () => ({
|
|
|
152
2312
|
}
|
|
153
2313
|
}
|
|
154
2314
|
});
|
|
155
|
-
async function
|
|
2315
|
+
async function Ct(s, e = {}) {
|
|
156
2316
|
var n;
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
2317
|
+
const t = await De(s);
|
|
2318
|
+
(n = e.onPhpLoaderModuleLoaded) == null || n.call(e, t);
|
|
2319
|
+
const r = e.tcpOverFetch ? Ge(e.tcpOverFetch) : Ye();
|
|
2320
|
+
return await me(t, {
|
|
2321
|
+
...e.emscriptenOptions || {},
|
|
2322
|
+
...r
|
|
161
2323
|
});
|
|
162
2324
|
}
|
|
163
|
-
function
|
|
164
|
-
window.addEventListener("message", (
|
|
165
|
-
|
|
166
|
-
}), window.addEventListener("message", (
|
|
167
|
-
var
|
|
168
|
-
|
|
2325
|
+
function lt(s, e) {
|
|
2326
|
+
window.addEventListener("message", (t) => {
|
|
2327
|
+
t.source === s.contentWindow && (e && t.origin !== e || typeof t.data != "object" || t.data.type !== "relay" || window.parent.postMessage(t.data, "*"));
|
|
2328
|
+
}), window.addEventListener("message", (t) => {
|
|
2329
|
+
var r;
|
|
2330
|
+
t.source === window.parent && (typeof t.data != "object" || t.data.type !== "relay" || (r = s == null ? void 0 : s.contentWindow) == null || r.postMessage(t.data));
|
|
169
2331
|
});
|
|
170
2332
|
}
|
|
171
|
-
async function
|
|
172
|
-
const
|
|
173
|
-
return new Promise((
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
`WebWorker failed to load at ${
|
|
2333
|
+
async function At(s) {
|
|
2334
|
+
const e = new Worker(s, { type: "module" });
|
|
2335
|
+
return new Promise((t, r) => {
|
|
2336
|
+
e.onerror = (i) => {
|
|
2337
|
+
const _ = new Error(
|
|
2338
|
+
`WebWorker failed to load at ${s}. ${i.message ? `Original error: ${i.message}` : ""}`
|
|
177
2339
|
);
|
|
178
|
-
|
|
2340
|
+
_.filename = i.filename, r(_);
|
|
179
2341
|
};
|
|
180
|
-
function
|
|
181
|
-
i.data === "worker-script-started" && (e
|
|
2342
|
+
function n(i) {
|
|
2343
|
+
i.data === "worker-script-started" && (t(e), e.removeEventListener("message", n));
|
|
182
2344
|
}
|
|
183
|
-
|
|
2345
|
+
e.addEventListener("message", n);
|
|
184
2346
|
});
|
|
185
2347
|
}
|
|
186
|
-
function
|
|
187
|
-
return
|
|
188
|
-
...
|
|
2348
|
+
function ut(s, e = { initialSync: {} }) {
|
|
2349
|
+
return e = {
|
|
2350
|
+
...e,
|
|
189
2351
|
initialSync: {
|
|
190
|
-
...
|
|
191
|
-
direction:
|
|
2352
|
+
...e.initialSync,
|
|
2353
|
+
direction: e.initialSync.direction ?? "opfs-to-memfs"
|
|
192
2354
|
}
|
|
193
|
-
}, async function(
|
|
194
|
-
return
|
|
195
|
-
n,
|
|
2355
|
+
}, async function(t, r, n) {
|
|
2356
|
+
return e.initialSync.direction === "opfs-to-memfs" ? (B.fileExists(r, n) && B.rmdir(r, n), B.mkdir(r, n), await Je(r, s, n)) : await Ee(
|
|
196
2357
|
r,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
2358
|
+
s,
|
|
2359
|
+
n,
|
|
2360
|
+
e.initialSync.onProgress
|
|
2361
|
+
), Ze(t, s, n);
|
|
200
2362
|
};
|
|
201
2363
|
}
|
|
202
|
-
async function
|
|
203
|
-
|
|
204
|
-
const
|
|
2364
|
+
async function Je(s, e, t) {
|
|
2365
|
+
B.mkdir(s, t);
|
|
2366
|
+
const r = new ge({
|
|
205
2367
|
concurrency: 40
|
|
206
|
-
}),
|
|
207
|
-
[
|
|
2368
|
+
}), n = [], i = [
|
|
2369
|
+
[e, t]
|
|
208
2370
|
];
|
|
209
2371
|
for (; i.length > 0; ) {
|
|
210
|
-
const [
|
|
211
|
-
for await (const c of
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
|
|
2372
|
+
const [_, a] = i.pop();
|
|
2373
|
+
for await (const c of _.values()) {
|
|
2374
|
+
const S = r.run(async () => {
|
|
2375
|
+
const l = se(
|
|
2376
|
+
a,
|
|
215
2377
|
c.name
|
|
216
2378
|
);
|
|
217
2379
|
if (c.kind === "directory") {
|
|
218
2380
|
try {
|
|
219
|
-
|
|
220
|
-
} catch (
|
|
221
|
-
if ((
|
|
222
|
-
throw
|
|
2381
|
+
s.mkdir(l);
|
|
2382
|
+
} catch (A) {
|
|
2383
|
+
if ((A == null ? void 0 : A.errno) !== 20)
|
|
2384
|
+
throw b.error(A), A;
|
|
223
2385
|
}
|
|
224
|
-
i.push([c,
|
|
2386
|
+
i.push([c, l]);
|
|
225
2387
|
} else if (c.kind === "file") {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
2388
|
+
const A = await c.getFile(), u = new Uint8Array(await A.arrayBuffer());
|
|
2389
|
+
s.createDataFile(
|
|
2390
|
+
a,
|
|
229
2391
|
c.name,
|
|
230
|
-
|
|
2392
|
+
u,
|
|
231
2393
|
!0,
|
|
232
2394
|
!0,
|
|
233
2395
|
!0
|
|
234
2396
|
);
|
|
235
2397
|
}
|
|
236
|
-
|
|
2398
|
+
n.splice(n.indexOf(S), 1);
|
|
237
2399
|
});
|
|
238
|
-
|
|
2400
|
+
n.push(S);
|
|
239
2401
|
}
|
|
240
|
-
for (; i.length === 0 &&
|
|
241
|
-
await Promise.any(
|
|
2402
|
+
for (; i.length === 0 && n.length > 0; )
|
|
2403
|
+
await Promise.any(n);
|
|
242
2404
|
}
|
|
243
2405
|
}
|
|
244
|
-
async function
|
|
245
|
-
|
|
246
|
-
const
|
|
247
|
-
async function i(
|
|
2406
|
+
async function Ee(s, e, t, r) {
|
|
2407
|
+
s.mkdirTree(t);
|
|
2408
|
+
const n = [];
|
|
2409
|
+
async function i(l, A) {
|
|
248
2410
|
await Promise.all(
|
|
249
|
-
|
|
250
|
-
(
|
|
251
|
-
).map(async (
|
|
252
|
-
const
|
|
253
|
-
if (
|
|
254
|
-
|
|
2411
|
+
s.readdir(l).filter(
|
|
2412
|
+
(u) => u !== "." && u !== ".."
|
|
2413
|
+
).map(async (u) => {
|
|
2414
|
+
const T = se(l, u);
|
|
2415
|
+
if (!Xe(s, T)) {
|
|
2416
|
+
n.push([A, T, u]);
|
|
255
2417
|
return;
|
|
256
2418
|
}
|
|
257
|
-
const D = await
|
|
2419
|
+
const D = await A.getDirectoryHandle(u, {
|
|
258
2420
|
create: !0
|
|
259
2421
|
});
|
|
260
|
-
return await i(
|
|
2422
|
+
return await i(T, D);
|
|
261
2423
|
})
|
|
262
2424
|
);
|
|
263
2425
|
}
|
|
264
|
-
await i(
|
|
265
|
-
let
|
|
266
|
-
const
|
|
2426
|
+
await i(t, e);
|
|
2427
|
+
let _ = 0;
|
|
2428
|
+
const a = r && et(r, 100), c = 100, S = /* @__PURE__ */ new Set();
|
|
267
2429
|
try {
|
|
268
|
-
for (const [
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
2430
|
+
for (const [l, A, u] of n) {
|
|
2431
|
+
const T = Te(
|
|
2432
|
+
l,
|
|
2433
|
+
u,
|
|
2434
|
+
s,
|
|
2435
|
+
A
|
|
274
2436
|
).then(() => {
|
|
275
|
-
|
|
276
|
-
files:
|
|
277
|
-
total:
|
|
2437
|
+
_++, S.delete(T), a == null || a({
|
|
2438
|
+
files: _,
|
|
2439
|
+
total: n.length
|
|
278
2440
|
});
|
|
279
2441
|
});
|
|
280
|
-
|
|
281
|
-
files:
|
|
282
|
-
total:
|
|
2442
|
+
S.add(T), S.size >= c && (await Promise.race(S), a == null || a({
|
|
2443
|
+
files: _,
|
|
2444
|
+
total: n.length
|
|
283
2445
|
}));
|
|
284
2446
|
}
|
|
285
2447
|
} finally {
|
|
286
|
-
await Promise.allSettled(
|
|
2448
|
+
await Promise.allSettled(S);
|
|
287
2449
|
}
|
|
288
2450
|
}
|
|
289
|
-
function
|
|
290
|
-
return
|
|
2451
|
+
function Xe(s, e) {
|
|
2452
|
+
return s.isDir(s.lookupPath(e, { follow: !0 }).node.mode);
|
|
291
2453
|
}
|
|
292
|
-
async function
|
|
293
|
-
let
|
|
2454
|
+
async function Te(s, e, t, r) {
|
|
2455
|
+
let n;
|
|
294
2456
|
try {
|
|
295
|
-
|
|
2457
|
+
n = t.readFile(r, {
|
|
296
2458
|
encoding: "binary"
|
|
297
2459
|
});
|
|
298
2460
|
} catch {
|
|
299
2461
|
return;
|
|
300
2462
|
}
|
|
301
|
-
const i = await
|
|
2463
|
+
const i = await s.getFileHandle(e, { create: !0 }), _ = i.createWritable !== void 0 ? (
|
|
302
2464
|
// Google Chrome, Firefox, probably more browsers
|
|
303
2465
|
await i.createWritable()
|
|
304
2466
|
) : (
|
|
@@ -306,125 +2468,128 @@ async function C(r, t, e, n) {
|
|
|
306
2468
|
await i.createSyncAccessHandle()
|
|
307
2469
|
);
|
|
308
2470
|
try {
|
|
309
|
-
await
|
|
2471
|
+
await _.truncate(0), await _.write(n);
|
|
310
2472
|
} finally {
|
|
311
|
-
await
|
|
2473
|
+
await _.close();
|
|
312
2474
|
}
|
|
313
2475
|
}
|
|
314
|
-
function
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
}), i = new
|
|
318
|
-
async function
|
|
319
|
-
const
|
|
2476
|
+
function Ze(s, e, t) {
|
|
2477
|
+
const r = [], n = Ke(s, t, (a) => {
|
|
2478
|
+
r.push(a);
|
|
2479
|
+
}), i = new Qe(s, e, t);
|
|
2480
|
+
async function _() {
|
|
2481
|
+
const a = await s.semaphore.acquire();
|
|
320
2482
|
try {
|
|
321
|
-
for (;
|
|
322
|
-
await i.processEntry(
|
|
2483
|
+
for (; r.length; )
|
|
2484
|
+
await i.processEntry(r.shift());
|
|
323
2485
|
} finally {
|
|
324
|
-
|
|
2486
|
+
a();
|
|
325
2487
|
}
|
|
326
2488
|
}
|
|
327
|
-
return
|
|
328
|
-
|
|
2489
|
+
return s.addEventListener("request.end", _), function() {
|
|
2490
|
+
n(), s.removeEventListener("request.end", _);
|
|
329
2491
|
};
|
|
330
2492
|
}
|
|
331
|
-
class
|
|
332
|
-
constructor(
|
|
333
|
-
this.php =
|
|
2493
|
+
class Qe {
|
|
2494
|
+
constructor(e, t, r) {
|
|
2495
|
+
this.php = e, this.opfs = t, this.memfsRoot = te(r);
|
|
334
2496
|
}
|
|
335
|
-
toOpfsPath(
|
|
336
|
-
return
|
|
2497
|
+
toOpfsPath(e) {
|
|
2498
|
+
return te(e.substring(this.memfsRoot.length));
|
|
337
2499
|
}
|
|
338
|
-
async processEntry(
|
|
339
|
-
if (!
|
|
2500
|
+
async processEntry(e) {
|
|
2501
|
+
if (!e.path.startsWith(this.memfsRoot) || e.path === this.memfsRoot)
|
|
340
2502
|
return;
|
|
341
|
-
const
|
|
342
|
-
if (
|
|
2503
|
+
const t = this.toOpfsPath(e.path), r = await ne(this.opfs, t), n = re(t);
|
|
2504
|
+
if (n)
|
|
343
2505
|
try {
|
|
344
|
-
if (
|
|
2506
|
+
if (e.operation === "DELETE")
|
|
345
2507
|
try {
|
|
346
|
-
await
|
|
2508
|
+
await r.removeEntry(n, {
|
|
347
2509
|
recursive: !0
|
|
348
2510
|
});
|
|
349
2511
|
} catch {
|
|
350
2512
|
}
|
|
351
|
-
else if (
|
|
352
|
-
|
|
2513
|
+
else if (e.operation === "CREATE")
|
|
2514
|
+
e.nodeType === "directory" ? await r.getDirectoryHandle(n, {
|
|
353
2515
|
create: !0
|
|
354
|
-
}) : await
|
|
2516
|
+
}) : await r.getFileHandle(n, {
|
|
355
2517
|
create: !0
|
|
356
2518
|
});
|
|
357
|
-
else if (
|
|
358
|
-
await
|
|
2519
|
+
else if (e.operation === "WRITE")
|
|
2520
|
+
await Te(
|
|
2521
|
+
r,
|
|
359
2522
|
n,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
t.path
|
|
2523
|
+
this.php[k].FS,
|
|
2524
|
+
e.path
|
|
363
2525
|
);
|
|
364
|
-
else if (
|
|
365
|
-
const i = this.toOpfsPath(
|
|
2526
|
+
else if (e.operation === "RENAME" && e.toPath.startsWith(this.memfsRoot)) {
|
|
2527
|
+
const i = this.toOpfsPath(e.toPath), _ = await ne(
|
|
366
2528
|
this.opfs,
|
|
367
2529
|
i
|
|
368
|
-
),
|
|
369
|
-
if (
|
|
370
|
-
const c = await
|
|
371
|
-
|
|
2530
|
+
), a = re(i);
|
|
2531
|
+
if (e.nodeType === "directory") {
|
|
2532
|
+
const c = await _.getDirectoryHandle(
|
|
2533
|
+
n,
|
|
372
2534
|
{
|
|
373
2535
|
create: !0
|
|
374
2536
|
}
|
|
375
2537
|
);
|
|
376
|
-
await
|
|
377
|
-
this.php[
|
|
2538
|
+
await Ee(
|
|
2539
|
+
this.php[k].FS,
|
|
378
2540
|
c,
|
|
379
|
-
|
|
380
|
-
), await
|
|
2541
|
+
e.toPath
|
|
2542
|
+
), await r.removeEntry(n, {
|
|
381
2543
|
recursive: !0
|
|
382
2544
|
});
|
|
383
2545
|
} else
|
|
384
|
-
(await
|
|
2546
|
+
(await r.getFileHandle(n)).move(_, a);
|
|
385
2547
|
}
|
|
386
2548
|
} catch (i) {
|
|
387
|
-
throw
|
|
2549
|
+
throw b.log({ entry: e, name: n }), b.error(i), i;
|
|
388
2550
|
}
|
|
389
2551
|
}
|
|
390
2552
|
}
|
|
391
|
-
function
|
|
392
|
-
return
|
|
2553
|
+
function te(s) {
|
|
2554
|
+
return s.replace(/\/$/, "").replace(/\/\/+/g, "/");
|
|
393
2555
|
}
|
|
394
|
-
function
|
|
395
|
-
return
|
|
2556
|
+
function re(s) {
|
|
2557
|
+
return s.substring(s.lastIndexOf("/") + 1);
|
|
396
2558
|
}
|
|
397
|
-
async function
|
|
398
|
-
const
|
|
399
|
-
if (!
|
|
400
|
-
return
|
|
401
|
-
const
|
|
402
|
-
let
|
|
403
|
-
for (let i = 0; i <
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
return
|
|
408
|
-
}
|
|
409
|
-
function
|
|
410
|
-
let
|
|
411
|
-
return function(...
|
|
412
|
-
|
|
413
|
-
const
|
|
414
|
-
if (
|
|
415
|
-
const c = Math.max(0,
|
|
416
|
-
|
|
417
|
-
|
|
2559
|
+
async function ne(s, e) {
|
|
2560
|
+
const t = e.replace(/^\/+|\/+$/g, "").replace(/\/+/, "/");
|
|
2561
|
+
if (!t)
|
|
2562
|
+
return s;
|
|
2563
|
+
const r = t.split("/");
|
|
2564
|
+
let n = s;
|
|
2565
|
+
for (let i = 0; i < r.length - 1; i++) {
|
|
2566
|
+
const _ = r[i];
|
|
2567
|
+
n = await n.getDirectoryHandle(_, { create: !0 });
|
|
2568
|
+
}
|
|
2569
|
+
return n;
|
|
2570
|
+
}
|
|
2571
|
+
function et(s, e) {
|
|
2572
|
+
let t = 0, r, n;
|
|
2573
|
+
return function(..._) {
|
|
2574
|
+
n = _;
|
|
2575
|
+
const a = Date.now() - t;
|
|
2576
|
+
if (r === void 0) {
|
|
2577
|
+
const c = Math.max(0, e - a);
|
|
2578
|
+
r = setTimeout(() => {
|
|
2579
|
+
r = void 0, t = Date.now(), s(...n);
|
|
418
2580
|
}, c);
|
|
419
2581
|
}
|
|
420
2582
|
};
|
|
421
2583
|
}
|
|
422
2584
|
export {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
2585
|
+
ot as certificateToPEM,
|
|
2586
|
+
_t as consumeAPI,
|
|
2587
|
+
ut as createDirectoryHandleMountHandler,
|
|
2588
|
+
at as exposeAPI,
|
|
2589
|
+
Oe as generateCertificate,
|
|
2590
|
+
De as getPHPLoaderModule,
|
|
2591
|
+
Ct as loadWebRuntime,
|
|
2592
|
+
ct as privateKeyToPEM,
|
|
2593
|
+
lt as setupPostMessageRelay,
|
|
2594
|
+
At as spawnPHPWorkerThread
|
|
430
2595
|
};
|