@joclaim/tls 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +221 -0
  2. package/lib/crypto/common.d.ts +3 -0
  3. package/lib/crypto/common.js +26 -0
  4. package/lib/crypto/index.d.ts +3 -0
  5. package/lib/crypto/index.js +4 -0
  6. package/lib/crypto/insecure-rand.d.ts +1 -0
  7. package/lib/crypto/insecure-rand.js +9 -0
  8. package/lib/crypto/pure-js.d.ts +2 -0
  9. package/lib/crypto/pure-js.js +144 -0
  10. package/lib/crypto/webcrypto.d.ts +3 -0
  11. package/lib/crypto/webcrypto.js +310 -0
  12. package/lib/index.d.ts +4 -0
  13. package/lib/index.js +4 -0
  14. package/lib/make-tls-client.d.ts +74 -0
  15. package/lib/make-tls-client.js +657 -0
  16. package/lib/scripts/build-jsc.d.ts +1 -0
  17. package/lib/scripts/build-jsc.js +20 -0
  18. package/lib/scripts/ca-template.d.ts +5 -0
  19. package/lib/scripts/ca-template.js +6 -0
  20. package/lib/scripts/fallbacks/crypto.d.ts +4 -0
  21. package/lib/scripts/fallbacks/crypto.js +2 -0
  22. package/lib/scripts/handshake.d.ts +1 -0
  23. package/lib/scripts/handshake.js +61 -0
  24. package/lib/scripts/jsc.d.ts +28 -0
  25. package/lib/scripts/jsc.js +92 -0
  26. package/lib/scripts/update-ca-certs.d.ts +1 -0
  27. package/lib/scripts/update-ca-certs.js +29 -0
  28. package/lib/types/crypto.d.ts +62 -0
  29. package/lib/types/crypto.js +1 -0
  30. package/lib/types/index.d.ts +15 -0
  31. package/lib/types/index.js +4 -0
  32. package/lib/types/logger.d.ts +6 -0
  33. package/lib/types/logger.js +1 -0
  34. package/lib/types/tls.d.ts +141 -0
  35. package/lib/types/tls.js +1 -0
  36. package/lib/types/x509.d.ts +32 -0
  37. package/lib/types/x509.js +1 -0
  38. package/lib/utils/additional-root-cas.d.ts +1 -0
  39. package/lib/utils/additional-root-cas.js +197 -0
  40. package/lib/utils/client-hello.d.ts +23 -0
  41. package/lib/utils/client-hello.js +167 -0
  42. package/lib/utils/constants.d.ts +239 -0
  43. package/lib/utils/constants.js +244 -0
  44. package/lib/utils/decryption-utils.d.ts +64 -0
  45. package/lib/utils/decryption-utils.js +166 -0
  46. package/lib/utils/finish-messages.d.ts +11 -0
  47. package/lib/utils/finish-messages.js +49 -0
  48. package/lib/utils/generics.d.ts +35 -0
  49. package/lib/utils/generics.js +146 -0
  50. package/lib/utils/index.d.ts +18 -0
  51. package/lib/utils/index.js +18 -0
  52. package/lib/utils/key-share.d.ts +13 -0
  53. package/lib/utils/key-share.js +72 -0
  54. package/lib/utils/key-update.d.ts +2 -0
  55. package/lib/utils/key-update.js +14 -0
  56. package/lib/utils/logger.d.ts +2 -0
  57. package/lib/utils/logger.js +15 -0
  58. package/lib/utils/make-queue.d.ts +3 -0
  59. package/lib/utils/make-queue.js +22 -0
  60. package/lib/utils/mozilla-root-cas.d.ts +5 -0
  61. package/lib/utils/mozilla-root-cas.js +4459 -0
  62. package/lib/utils/packets.d.ts +51 -0
  63. package/lib/utils/packets.js +148 -0
  64. package/lib/utils/parse-alert.d.ts +7 -0
  65. package/lib/utils/parse-alert.js +28 -0
  66. package/lib/utils/parse-certificate.d.ts +29 -0
  67. package/lib/utils/parse-certificate.js +188 -0
  68. package/lib/utils/parse-client-hello.d.ts +11 -0
  69. package/lib/utils/parse-client-hello.js +39 -0
  70. package/lib/utils/parse-extensions.d.ts +11 -0
  71. package/lib/utils/parse-extensions.js +74 -0
  72. package/lib/utils/parse-server-hello.d.ts +10 -0
  73. package/lib/utils/parse-server-hello.js +52 -0
  74. package/lib/utils/session-ticket.d.ts +17 -0
  75. package/lib/utils/session-ticket.js +51 -0
  76. package/lib/utils/wrapped-record.d.ts +25 -0
  77. package/lib/utils/wrapped-record.js +191 -0
  78. package/lib/utils/x509.d.ts +5 -0
  79. package/lib/utils/x509.js +124 -0
  80. package/package.json +82 -0
@@ -0,0 +1,310 @@
1
+ import { cbc as aesCbc } from '@noble/ciphers/aes';
2
+ import { chacha20poly1305 } from '@noble/ciphers/chacha';
3
+ import { ECDSASigValue } from '@peculiar/asn1-ecc';
4
+ import { AsnParser } from '@peculiar/asn1-schema';
5
+ import { webcrypto } from 'crypto';
6
+ import { PKCS1_KEM } from 'micro-rsa-dsa-dh/rsa.js';
7
+ import { asciiToUint8Array, concatenateUint8Arrays } from "../utils/generics.js";
8
+ import { parseRsaPublicKeyFromAsn1 } from "./common.js";
9
+ const subtle = webcrypto.subtle;
10
+ const X25519_PRIVATE_KEY_DER_PREFIX = new Uint8Array([
11
+ 48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32
12
+ ]);
13
+ const P384_PRIVATE_KEY_DER_PREFIX = new Uint8Array([
14
+ 0x30, 0x81, 0xb6, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x04, 0x81, 0x9e, 0x30, 0x81, 0x9b, 0x02, 0x01, 0x01, 0x04, 0x30
15
+ ]);
16
+ const P256_PRIVATE_KEY_DER_PREFIX = new Uint8Array([
17
+ 0x30, 0x81, 0xb6, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x04, 0x81, 0x9e, 0x30, 0x81, 0x9b, 0x02, 0x01, 0x01, 0x04, 0x30
18
+ ]);
19
+ const SHARED_KEY_LEN_MAP = {
20
+ 'X25519': 32,
21
+ 'P-384': 48,
22
+ 'P-256': 32,
23
+ };
24
+ const AUTH_TAG_BYTE_LENGTH = 16;
25
+ export const webcryptoCrypto = {
26
+ importKey(alg, raw, ...args) {
27
+ let subtleArgs;
28
+ let keyUsages;
29
+ let keyType = 'raw';
30
+ switch (alg) {
31
+ case 'AES-256-GCM':
32
+ case 'AES-128-GCM':
33
+ subtleArgs = {
34
+ name: 'AES-GCM',
35
+ length: alg === 'AES-256-GCM' ? 256 : 128
36
+ };
37
+ keyUsages = ['encrypt', 'decrypt'];
38
+ break;
39
+ case 'AES-128-CBC':
40
+ subtleArgs = {
41
+ name: 'AES-CBC',
42
+ length: 128
43
+ };
44
+ keyUsages = ['encrypt', 'decrypt'];
45
+ break;
46
+ case 'CHACHA20-POLY1305':
47
+ // chaCha20 is not supported by webcrypto
48
+ // so we "fake" create a key
49
+ return raw;
50
+ case 'SHA-1':
51
+ case 'SHA-256':
52
+ case 'SHA-384':
53
+ subtleArgs = {
54
+ name: 'HMAC',
55
+ hash: { name: alg }
56
+ };
57
+ keyUsages = ['sign', 'verify'];
58
+ break;
59
+ case 'P-384':
60
+ case 'P-256':
61
+ subtleArgs = {
62
+ name: 'ECDH',
63
+ namedCurve: alg,
64
+ };
65
+ keyUsages = [];
66
+ if (args[0] === 'private') {
67
+ keyUsages = ['deriveBits'];
68
+ keyType = 'pkcs8';
69
+ const prefix = alg === 'P-256'
70
+ ? P256_PRIVATE_KEY_DER_PREFIX
71
+ : P384_PRIVATE_KEY_DER_PREFIX;
72
+ raw = concatenateUint8Arrays([
73
+ prefix,
74
+ raw
75
+ ]);
76
+ }
77
+ break;
78
+ case 'X25519':
79
+ subtleArgs = { name: 'X25519' };
80
+ keyUsages = [];
81
+ if (args[0] === 'private') {
82
+ keyUsages = ['deriveBits'];
83
+ keyType = 'pkcs8';
84
+ raw = concatenateUint8Arrays([
85
+ X25519_PRIVATE_KEY_DER_PREFIX,
86
+ raw
87
+ ]);
88
+ }
89
+ break;
90
+ case 'RSA-PSS-SHA256':
91
+ keyType = 'spki';
92
+ keyUsages = ['verify'];
93
+ subtleArgs = {
94
+ name: 'RSA-PSS',
95
+ hash: 'SHA-256'
96
+ };
97
+ break;
98
+ case 'RSA-PKCS1-SHA512':
99
+ case 'RSA-PKCS1-SHA256':
100
+ case 'RSA-PKCS1-SHA384':
101
+ case 'RSA-PKCS1-SHA1':
102
+ keyType = 'spki';
103
+ keyUsages = ['verify'];
104
+ subtleArgs = {
105
+ name: 'RSASSA-PKCS1-v1_5',
106
+ hash: getHashAlgorithm(alg),
107
+ };
108
+ break;
109
+ case 'RSA-PCKS1_5':
110
+ return parseRsaPublicKeyFromAsn1(raw);
111
+ case 'ECDSA-SECP256R1-SHA256':
112
+ case 'ECDSA-SECP256R1-SHA384':
113
+ case 'ECDSA-SECP384R1-SHA384':
114
+ case 'ECDSA-SECP384R1-SHA256':
115
+ keyType = 'spki';
116
+ keyUsages = ['verify'];
117
+ subtleArgs = {
118
+ name: 'ECDSA',
119
+ namedCurve: alg.includes('P256') ? 'P-256' : 'P-384',
120
+ };
121
+ break;
122
+ default:
123
+ throw new Error(`Unsupported algorithm ${alg}`);
124
+ }
125
+ return subtle
126
+ .importKey(keyType, raw, subtleArgs, true, keyUsages);
127
+ },
128
+ async exportKey(key) {
129
+ // handle ChaCha20-Poly1305, RSA-PCKS1_5
130
+ // as that's already a Uint8Array
131
+ if (key instanceof Uint8Array) {
132
+ return key;
133
+ }
134
+ if (key.type === 'private'
135
+ && (key.algorithm.name === 'X25519'
136
+ || key.algorithm.name === 'ECDH')) {
137
+ const form = toUint8Array(await subtle.exportKey('pkcs8', key));
138
+ const algPrefix = key.algorithm.name === 'X25519'
139
+ ? X25519_PRIVATE_KEY_DER_PREFIX
140
+ : P384_PRIVATE_KEY_DER_PREFIX;
141
+ return form.slice(algPrefix.length);
142
+ }
143
+ return toUint8Array(await subtle.exportKey('raw', key));
144
+ },
145
+ async generateKeyPair(alg) {
146
+ let genKeyArgs;
147
+ switch (alg) {
148
+ case 'P-384':
149
+ case 'P-256':
150
+ genKeyArgs = {
151
+ name: 'ECDH',
152
+ namedCurve: alg,
153
+ };
154
+ break;
155
+ case 'X25519':
156
+ genKeyArgs = { name: 'X25519' };
157
+ break;
158
+ default:
159
+ throw new Error(`Unsupported algorithm ${alg}`);
160
+ }
161
+ const keyPair = await subtle.generateKey(genKeyArgs, true, ['deriveBits']);
162
+ return {
163
+ pubKey: keyPair.publicKey,
164
+ privKey: keyPair.privateKey,
165
+ };
166
+ },
167
+ async calculateSharedSecret(alg, privateKey, publicKey) {
168
+ const genKeyName = alg === 'X25519' ? 'X25519' : 'ECDH';
169
+ const key = await subtle.deriveBits({ name: genKeyName, public: publicKey }, privateKey, 8 * SHARED_KEY_LEN_MAP[alg]);
170
+ return toUint8Array(key);
171
+ },
172
+ randomBytes(length) {
173
+ const buffer = new Uint8Array(length);
174
+ return webcrypto.getRandomValues(buffer);
175
+ },
176
+ asymmetricEncrypt(cipherSuite, { publicKey, data }) {
177
+ if (cipherSuite !== 'RSA-PCKS1_5') {
178
+ throw new Error(`Unsupported cipher suite ${cipherSuite}`);
179
+ }
180
+ return PKCS1_KEM.encrypt(publicKey, data);
181
+ },
182
+ async encrypt(cipherSuite, { iv, data, key }) {
183
+ const name = cipherSuite === 'AES-128-CBC' ? 'AES-CBC' : '';
184
+ return toUint8Array(await subtle.encrypt({ name, iv }, key, data))
185
+ .slice(0, data.length);
186
+ },
187
+ async decrypt(cipherSuite, { key, iv, data }) {
188
+ if (cipherSuite !== 'AES-128-CBC') {
189
+ throw new Error(`Unsupported cipher suite: ${cipherSuite}`);
190
+ }
191
+ const rawKey = key instanceof Uint8Array
192
+ ? key
193
+ : await this.exportKey(key);
194
+ const cipher = aesCbc(rawKey, iv, { disablePadding: true });
195
+ const decrypted = cipher.decrypt(data);
196
+ return decrypted;
197
+ },
198
+ async authenticatedEncrypt(cipherSuite, { iv, aead, key, data }) {
199
+ let ciphertext;
200
+ if (cipherSuite === 'CHACHA20-POLY1305') {
201
+ const rawKey = key instanceof Uint8Array
202
+ ? key
203
+ : await this.exportKey(key);
204
+ const cipher = chacha20poly1305(rawKey, iv, aead);
205
+ ciphertext = cipher.encrypt(data);
206
+ }
207
+ else {
208
+ ciphertext = toUint8Array(await subtle.encrypt({ name: 'AES-GCM', iv, additionalData: aead }, key, data));
209
+ }
210
+ return {
211
+ ciphertext: ciphertext.slice(0, -AUTH_TAG_BYTE_LENGTH),
212
+ authTag: ciphertext.slice(-AUTH_TAG_BYTE_LENGTH),
213
+ };
214
+ },
215
+ async authenticatedDecrypt(cipherSuite, { iv, aead, key, data, authTag }) {
216
+ if (!authTag) {
217
+ throw new Error('authTag is required');
218
+ }
219
+ const ciphertext = concatenateUint8Arrays([data, authTag]);
220
+ let plaintext;
221
+ if (cipherSuite === 'CHACHA20-POLY1305') {
222
+ const rawKey = key instanceof Uint8Array
223
+ ? key
224
+ : await this.exportKey(key);
225
+ const cipher = chacha20poly1305(rawKey, iv, aead);
226
+ plaintext = cipher.decrypt(ciphertext);
227
+ }
228
+ else {
229
+ plaintext = toUint8Array(await subtle.decrypt({ name: 'AES-GCM', iv, additionalData: aead }, key, ciphertext));
230
+ }
231
+ return { plaintext };
232
+ },
233
+ async verify(alg, { data, signature, publicKey }) {
234
+ let verifyArgs;
235
+ switch (alg) {
236
+ case 'RSA-PSS-SHA256':
237
+ verifyArgs = { name: 'RSA-PSS', saltLength: 32 };
238
+ break;
239
+ case 'RSA-PKCS1-SHA512':
240
+ case 'RSA-PKCS1-SHA256':
241
+ case 'RSA-PKCS1-SHA384':
242
+ case 'RSA-PKCS1-SHA1':
243
+ verifyArgs = { name: 'RSASSA-PKCS1-v1_5' };
244
+ break;
245
+ case 'ECDSA-SECP256R1-SHA256':
246
+ case 'ECDSA-SECP256R1-SHA384':
247
+ case 'ECDSA-SECP384R1-SHA256':
248
+ case 'ECDSA-SECP384R1-SHA384':
249
+ signature = convertASN1toRS(signature);
250
+ verifyArgs = { name: 'ECDSA', hash: getHashAlgorithm(alg) };
251
+ break;
252
+ default:
253
+ throw new Error(`Unsupported algorithm ${alg}`);
254
+ }
255
+ return subtle.verify(verifyArgs, publicKey, signature, data);
256
+ },
257
+ async hash(alg, data) {
258
+ return toUint8Array(await subtle.digest(alg, data));
259
+ },
260
+ async hmac(alg, key, data) {
261
+ return toUint8Array(await subtle.sign({ name: 'HMAC', hash: alg }, key, data));
262
+ },
263
+ // extract & expand logic referenced from:
264
+ // https://github.com/futoin/util-js-hkdf/blob/master/hkdf.js
265
+ async extract(alg, hashLength, ikm, salt) {
266
+ salt = typeof salt === 'string' ? asciiToUint8Array(salt) : salt;
267
+ if (!salt.length) {
268
+ salt = new Uint8Array(hashLength);
269
+ }
270
+ const key = await this.importKey(alg, salt);
271
+ return this.hmac(alg, key, ikm);
272
+ },
273
+ };
274
+ function toUint8Array(buffer) {
275
+ return new Uint8Array(buffer);
276
+ }
277
+ // mostly from ChatGPT
278
+ function convertASN1toRS(signatureBytes) {
279
+ const data = AsnParser.parse(signatureBytes, ECDSASigValue);
280
+ const r = cleanBigNum(new Uint8Array(data.r));
281
+ const s = cleanBigNum(new Uint8Array(data.s));
282
+ return concatenateUint8Arrays([r, s]);
283
+ }
284
+ function cleanBigNum(bn) {
285
+ if (bn.length > 32 && bn[0] === 0) {
286
+ bn = bn.slice(1);
287
+ }
288
+ else if (bn.length < 32) {
289
+ bn = concatenateUint8Arrays([
290
+ new Uint8Array(32 - bn.length).fill(0),
291
+ bn
292
+ ]);
293
+ }
294
+ return bn;
295
+ }
296
+ function getHashAlgorithm(sig) {
297
+ if (sig.endsWith('SHA256')) {
298
+ return 'SHA-256';
299
+ }
300
+ else if (sig.endsWith('SHA384')) {
301
+ return 'SHA-384';
302
+ }
303
+ else if (sig.endsWith('SHA512')) {
304
+ return 'SHA-512';
305
+ }
306
+ else if (sig.endsWith('SHA1')) {
307
+ return 'SHA-1';
308
+ }
309
+ throw new Error(`Unsupported signature algorithm: ${sig}`);
310
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './make-tls-client.ts';
2
+ export * from './crypto/index.ts';
3
+ export * from './types/index.ts';
4
+ export * from './utils/index.ts';
package/lib/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./make-tls-client.js";
2
+ export * from "./crypto/index.js";
3
+ export * from "./types/index.js";
4
+ export * from "./utils/index.js";
@@ -0,0 +1,74 @@
1
+ import type { TLSClientOptions, TLSHandshakeOptions, TLSKeyType, TLSPacketWithType, TLSSessionTicket } from './types/index.ts';
2
+ export declare function makeTLSClient({ host, verifyServerCertificate, rootCAs, logger: _logger, cipherSuites, namedCurves, supportedProtocolVersions, signatureAlgorithms, applicationLayerProtocols, fetchCertificateBytes, write, onRead, onApplicationData, onSessionTicket, onTlsEnd, onHandshake, onRecvCertificates }: TLSClientOptions): {
3
+ getMetadata(): {
4
+ cipherSuite: "TLS_CHACHA20_POLY1305_SHA256" | "TLS_AES_256_GCM_SHA384" | "TLS_AES_128_GCM_SHA256" | "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" | "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" | "TLS_RSA_WITH_AES_128_GCM_SHA256" | "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" | "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" | undefined;
5
+ keyType: TLSKeyType | undefined;
6
+ version: "TLS1_3" | "TLS1_2" | undefined;
7
+ selectedAlpn: string | undefined;
8
+ };
9
+ hasEnded(): boolean;
10
+ /**
11
+ * Get the current traffic keys
12
+ */
13
+ getKeys(): {
14
+ recordSendCount: number;
15
+ recordRecvCount: number;
16
+ type: "TLS1_3";
17
+ masterSecret: Uint8Array<ArrayBufferLike>;
18
+ clientSecret: Uint8Array<ArrayBuffer>;
19
+ serverSecret: Uint8Array<ArrayBuffer>;
20
+ clientEncKey: unknown;
21
+ serverEncKey: unknown;
22
+ clientIv: Uint8Array<ArrayBuffer>;
23
+ serverIv: Uint8Array<ArrayBuffer>;
24
+ } | {
25
+ recordSendCount: number;
26
+ recordRecvCount: number;
27
+ type: "TLS1_2";
28
+ masterSecret: Uint8Array<ArrayBuffer>;
29
+ clientMacKey: unknown;
30
+ serverMacKey: unknown;
31
+ clientEncKey: unknown;
32
+ serverEncKey: unknown;
33
+ clientIv: Uint8Array<ArrayBuffer>;
34
+ serverIv: Uint8Array<ArrayBuffer>;
35
+ serverSecret: Uint8Array<ArrayBuffer>;
36
+ clientSecret: Uint8Array<ArrayBuffer>;
37
+ } | undefined;
38
+ /**
39
+ * Session ID used to connect to the server
40
+ */
41
+ getSessionId(): Uint8Array<ArrayBufferLike>;
42
+ isHandshakeDone(): boolean;
43
+ getPskFromTicket(ticket: TLSSessionTicket): Promise<{
44
+ identity: Uint8Array<ArrayBufferLike>;
45
+ ticketAge: number;
46
+ finishKey: unknown;
47
+ resumeMasterSecret: Uint8Array<ArrayBuffer>;
48
+ earlySecret: Uint8Array<ArrayBufferLike>;
49
+ cipherSuite: "TLS_CHACHA20_POLY1305_SHA256" | "TLS_AES_256_GCM_SHA384" | "TLS_AES_128_GCM_SHA256" | "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" | "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" | "TLS_RSA_WITH_AES_128_GCM_SHA256" | "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" | "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
50
+ }>;
51
+ /**
52
+ * Start the handshake with the server
53
+ */
54
+ startHandshake(opts?: TLSHandshakeOptions): Promise<void>;
55
+ /**
56
+ * Handle bytes received from the server.
57
+ * Could be a complete or partial TLS packet
58
+ */
59
+ handleReceivedBytes(data: Uint8Array): Promise<void>;
60
+ /**
61
+ * Handle a complete TLS packet received
62
+ * from the server
63
+ */
64
+ handleReceivedPacket: (pkt: TLSPacketWithType) => Promise<unknown>;
65
+ /**
66
+ * Utilise the KeyUpdate handshake message to update
67
+ * the traffic keys. Available only in TLS 1.3
68
+ * @param requestUpdateFromServer should the server be requested to
69
+ * update its keys as well
70
+ */
71
+ updateTrafficKeys(requestUpdateFromServer?: boolean): Promise<void>;
72
+ write(data: Uint8Array): Promise<void>;
73
+ end: (error?: Error) => Promise<void>;
74
+ };