lemon-tls 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +431 -119
- package/index.cjs +28 -0
- package/index.d.ts +283 -0
- package/index.js +70 -18
- package/lemontls.svg +1 -1
- package/package.json +120 -62
- package/src/compat.js +235 -0
- package/src/crypto.js +580 -0
- package/src/record.js +232 -0
- package/{secure_context.js → src/secure_context.js} +196 -196
- package/src/session/ecdh.js +85 -0
- package/src/session/message.js +203 -0
- package/src/session/signing.js +129 -0
- package/src/tls_session.js +2282 -0
- package/src/tls_socket.js +877 -0
- package/{utils.js → src/utils.js} +100 -88
- package/{wire.js → src/wire.js} +1523 -1668
- package/crypto.js +0 -391
- package/tls_server.js +0 -0
- package/tls_session.js +0 -1440
- package/tls_socket.js +0 -453
package/crypto.js
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
concatUint8Arrays
|
|
4
|
-
} from './utils.js';
|
|
5
|
-
|
|
6
|
-
import { hmac as nobleHmac } from '@noble/hashes/hmac.js';
|
|
7
|
-
import { hkdf, extract as hkdf_extract_noble, expand as hkdf_expand_noble } from '@noble/hashes/hkdf.js';
|
|
8
|
-
import { sha256, sha384 } from '@noble/hashes/sha2.js';
|
|
9
|
-
|
|
10
|
-
import { p256 } from '@noble/curves/nist.js';
|
|
11
|
-
import { ed25519, x25519 } from '@noble/curves/ed25519.js';
|
|
12
|
-
|
|
13
|
-
var nobleHashes = {
|
|
14
|
-
hmac: nobleHmac,
|
|
15
|
-
hkdf: hkdf,
|
|
16
|
-
hkdf_extract: hkdf_extract_noble,
|
|
17
|
-
hkdf_expand: hkdf_expand_noble,
|
|
18
|
-
sha256: sha256,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var TLS_CIPHER_SUITES = {
|
|
24
|
-
// ----------------------
|
|
25
|
-
// TLS 1.3 (RFC 8446)
|
|
26
|
-
// ----------------------
|
|
27
|
-
0x1301: { // TLS_AES_128_GCM_SHA256
|
|
28
|
-
tls: 13,
|
|
29
|
-
kex: 'TLS13',
|
|
30
|
-
sig: 'TLS13',
|
|
31
|
-
cipher: 'AES_128_GCM',
|
|
32
|
-
aead: true,
|
|
33
|
-
keylen: 16,
|
|
34
|
-
ivlen: 12,
|
|
35
|
-
hash: 'sha256'
|
|
36
|
-
},
|
|
37
|
-
0x1302: { // TLS_AES_256_GCM_SHA384
|
|
38
|
-
tls: 13,
|
|
39
|
-
kex: 'TLS13',
|
|
40
|
-
sig: 'TLS13',
|
|
41
|
-
cipher: 'AES_256_GCM',
|
|
42
|
-
aead: true,
|
|
43
|
-
keylen: 32,
|
|
44
|
-
ivlen: 12,
|
|
45
|
-
hash: 'sha384'
|
|
46
|
-
},
|
|
47
|
-
0x1303: { // TLS_CHACHA20_POLY1305_SHA256
|
|
48
|
-
tls: 13,
|
|
49
|
-
kex: 'TLS13',
|
|
50
|
-
sig: 'TLS13',
|
|
51
|
-
cipher: 'CHACHA20_POLY1305',
|
|
52
|
-
aead: true,
|
|
53
|
-
keylen: 32,
|
|
54
|
-
ivlen: 12,
|
|
55
|
-
hash: 'sha256'
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
// ----------------------
|
|
59
|
-
// TLS 1.2 AEAD (GCM / CHACHA20)
|
|
60
|
-
// ----------------------
|
|
61
|
-
0xC02F: { // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
|
62
|
-
tls: 12,
|
|
63
|
-
kex: 'ECDHE_RSA',
|
|
64
|
-
sig: 'RSA',
|
|
65
|
-
cipher: 'AES_128_GCM',
|
|
66
|
-
aead: true,
|
|
67
|
-
keylen: 16,
|
|
68
|
-
fixed_ivlen: 4,
|
|
69
|
-
record_ivlen: 8,
|
|
70
|
-
ivlen: 12,
|
|
71
|
-
hash: 'sha256'
|
|
72
|
-
},
|
|
73
|
-
0xC030: { // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
74
|
-
tls: 12,
|
|
75
|
-
kex: 'ECDHE_RSA',
|
|
76
|
-
sig: 'RSA',
|
|
77
|
-
cipher: 'AES_256_GCM',
|
|
78
|
-
aead: true,
|
|
79
|
-
keylen: 32,
|
|
80
|
-
fixed_ivlen: 4,
|
|
81
|
-
record_ivlen: 8,
|
|
82
|
-
ivlen: 12,
|
|
83
|
-
hash: 'sha384'
|
|
84
|
-
},
|
|
85
|
-
0xC02B: { // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
|
86
|
-
tls: 12,
|
|
87
|
-
kex: 'ECDHE_ECDSA',
|
|
88
|
-
sig: 'ECDSA',
|
|
89
|
-
cipher: 'AES_128_GCM',
|
|
90
|
-
aead: true,
|
|
91
|
-
keylen: 16,
|
|
92
|
-
fixed_ivlen: 4,
|
|
93
|
-
record_ivlen: 8,
|
|
94
|
-
ivlen: 12,
|
|
95
|
-
hash: 'sha256'
|
|
96
|
-
},
|
|
97
|
-
0xC02C: { // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
|
98
|
-
tls: 12,
|
|
99
|
-
kex: 'ECDHE_ECDSA',
|
|
100
|
-
sig: 'ECDSA',
|
|
101
|
-
cipher: 'AES_256_GCM',
|
|
102
|
-
aead: true,
|
|
103
|
-
keylen: 32,
|
|
104
|
-
fixed_ivlen: 4,
|
|
105
|
-
record_ivlen: 8,
|
|
106
|
-
ivlen: 12,
|
|
107
|
-
hash: 'sha384'
|
|
108
|
-
},
|
|
109
|
-
0xCCA8: { // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
|
110
|
-
tls: 12,
|
|
111
|
-
kex: 'ECDHE_RSA',
|
|
112
|
-
sig: 'RSA',
|
|
113
|
-
cipher: 'CHACHA20_POLY1305',
|
|
114
|
-
aead: true,
|
|
115
|
-
keylen: 32,
|
|
116
|
-
fixed_ivlen: 4,
|
|
117
|
-
record_ivlen: 8,
|
|
118
|
-
ivlen: 12,
|
|
119
|
-
hash: 'sha256'
|
|
120
|
-
},
|
|
121
|
-
0xCCA9: { // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
|
122
|
-
tls: 12,
|
|
123
|
-
kex: 'ECDHE_ECDSA',
|
|
124
|
-
sig: 'ECDSA',
|
|
125
|
-
cipher: 'CHACHA20_POLY1305',
|
|
126
|
-
aead: true,
|
|
127
|
-
keylen: 32,
|
|
128
|
-
fixed_ivlen: 4,
|
|
129
|
-
record_ivlen: 8,
|
|
130
|
-
ivlen: 12,
|
|
131
|
-
hash: 'sha256'
|
|
132
|
-
},
|
|
133
|
-
0xCCAA: { // TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
|
134
|
-
tls: 12,
|
|
135
|
-
kex: 'DHE_RSA',
|
|
136
|
-
sig: 'RSA',
|
|
137
|
-
cipher: 'CHACHA20_POLY1305',
|
|
138
|
-
aead: true,
|
|
139
|
-
keylen: 32,
|
|
140
|
-
fixed_ivlen: 4,
|
|
141
|
-
record_ivlen: 8,
|
|
142
|
-
ivlen: 12,
|
|
143
|
-
hash: 'sha256'
|
|
144
|
-
},
|
|
145
|
-
0x009C: { // TLS_RSA_WITH_AES_128_GCM_SHA256
|
|
146
|
-
tls: 12,
|
|
147
|
-
kex: 'RSA',
|
|
148
|
-
sig: 'RSA',
|
|
149
|
-
cipher: 'AES_128_GCM',
|
|
150
|
-
aead: true,
|
|
151
|
-
keylen: 16,
|
|
152
|
-
fixed_ivlen: 4,
|
|
153
|
-
record_ivlen: 8,
|
|
154
|
-
ivlen: 12,
|
|
155
|
-
hash: 'sha256'
|
|
156
|
-
},
|
|
157
|
-
0x009D: { // TLS_RSA_WITH_AES_256_GCM_SHA384
|
|
158
|
-
tls: 12,
|
|
159
|
-
kex: 'RSA',
|
|
160
|
-
sig: 'RSA',
|
|
161
|
-
cipher: 'AES_256_GCM',
|
|
162
|
-
aead: true,
|
|
163
|
-
keylen: 32,
|
|
164
|
-
fixed_ivlen: 4,
|
|
165
|
-
record_ivlen: 8,
|
|
166
|
-
ivlen: 12,
|
|
167
|
-
hash: 'sha384'
|
|
168
|
-
},
|
|
169
|
-
|
|
170
|
-
// ----------------------
|
|
171
|
-
// TLS 1.2 CBC (Legacy)
|
|
172
|
-
// ----------------------
|
|
173
|
-
0xC013: { // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
|
174
|
-
tls: 12,
|
|
175
|
-
kex: 'ECDHE_RSA',
|
|
176
|
-
sig: 'RSA',
|
|
177
|
-
cipher: 'AES_128_CBC',
|
|
178
|
-
aead: false,
|
|
179
|
-
keylen: 16,
|
|
180
|
-
ivlen: 16,
|
|
181
|
-
mac: 'sha1',
|
|
182
|
-
maclen: 20,
|
|
183
|
-
hash: 'sha256'
|
|
184
|
-
},
|
|
185
|
-
0xC014: { // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
|
186
|
-
tls: 12,
|
|
187
|
-
kex: 'ECDHE_RSA',
|
|
188
|
-
sig: 'RSA',
|
|
189
|
-
cipher: 'AES_256_CBC',
|
|
190
|
-
aead: false,
|
|
191
|
-
keylen: 32,
|
|
192
|
-
ivlen: 16,
|
|
193
|
-
mac: 'sha1',
|
|
194
|
-
maclen: 20,
|
|
195
|
-
hash: 'sha256'
|
|
196
|
-
},
|
|
197
|
-
0x003C: { // TLS_RSA_WITH_AES_128_CBC_SHA256
|
|
198
|
-
tls: 12,
|
|
199
|
-
kex: 'RSA',
|
|
200
|
-
sig: 'RSA',
|
|
201
|
-
cipher: 'AES_128_CBC',
|
|
202
|
-
aead: false,
|
|
203
|
-
keylen: 16,
|
|
204
|
-
ivlen: 16,
|
|
205
|
-
mac: 'sha256',
|
|
206
|
-
maclen: 32,
|
|
207
|
-
hash: 'sha256'
|
|
208
|
-
},
|
|
209
|
-
0x003D: { // TLS_RSA_WITH_AES_256_CBC_SHA256
|
|
210
|
-
tls: 12,
|
|
211
|
-
kex: 'RSA',
|
|
212
|
-
sig: 'RSA',
|
|
213
|
-
cipher: 'AES_256_CBC',
|
|
214
|
-
aead: false,
|
|
215
|
-
keylen: 32,
|
|
216
|
-
ivlen: 16,
|
|
217
|
-
mac: 'sha256',
|
|
218
|
-
maclen: 32,
|
|
219
|
-
hash: 'sha256'
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
// --- Hash helpers: מקבלים מחרוזת ומחזירים פונקציית hash + outputLen ---
|
|
228
|
-
function getHashFn(hashName) {
|
|
229
|
-
if (hashName === 'sha256') return sha256;
|
|
230
|
-
if (hashName === 'sha384') return sha384;
|
|
231
|
-
throw new Error('Unsupported hash: ' + hashName);
|
|
232
|
-
}
|
|
233
|
-
function getHashLen(hashName) {
|
|
234
|
-
var fn = getHashFn(hashName);
|
|
235
|
-
return fn.outputLen|0;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// --- HMAC (עם noble) ---
|
|
239
|
-
function hmac(hashName, keyU8, dataU8) {
|
|
240
|
-
var hashFn = getHashFn(hashName);
|
|
241
|
-
return nobleHmac(hashFn, keyU8, dataU8); // Uint8Array
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// --- HKDF wrappers (hash כמחרוזת) ---
|
|
245
|
-
function hkdf_extract(hashName, saltU8, ikmU8) {
|
|
246
|
-
var hashFn = getHashFn(hashName);
|
|
247
|
-
// extract(hash, ikm, salt?)
|
|
248
|
-
return hkdf_extract_noble(hashFn, ikmU8, saltU8);
|
|
249
|
-
}
|
|
250
|
-
function hkdf_expand(hashName, prkU8, infoU8, length) {
|
|
251
|
-
var hashFn = getHashFn(hashName);
|
|
252
|
-
// expand(hash, prk, info, length)
|
|
253
|
-
return hkdf_expand_noble(hashFn, prkU8, infoU8, length|0);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// --- TLS 1.3 label builder ---
|
|
257
|
-
function build_hkdf_label(label, context, length) {
|
|
258
|
-
var prefix = 'tls13 ';
|
|
259
|
-
var enc = new TextEncoder();
|
|
260
|
-
var full = enc.encode(prefix + label);
|
|
261
|
-
var info = new Uint8Array(2 + 1 + full.length + 1 + context.length);
|
|
262
|
-
|
|
263
|
-
// length (2 bytes BE)
|
|
264
|
-
info[0] = (length >>> 8) & 0xff;
|
|
265
|
-
info[1] = (length ) & 0xff;
|
|
266
|
-
|
|
267
|
-
// label
|
|
268
|
-
info[2] = full.length;
|
|
269
|
-
info.set(full, 3);
|
|
270
|
-
|
|
271
|
-
// context
|
|
272
|
-
var ofs = 3 + full.length;
|
|
273
|
-
info[ofs] = context.length;
|
|
274
|
-
info.set(context, ofs + 1);
|
|
275
|
-
|
|
276
|
-
return info;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function hkdf_expand_label(hashName, secret, label, context, length) {
|
|
280
|
-
var info = build_hkdf_label(label, context, length|0);
|
|
281
|
-
return hkdf_expand(hashName, secret, info, length|0);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// --- TLS 1.3: derive handshake secrets ---
|
|
285
|
-
function derive_handshake_traffic_secrets(hashName, shared_secret, transcript) {
|
|
286
|
-
var hashFn = getHashFn(hashName);
|
|
287
|
-
|
|
288
|
-
var hashLen = hashFn.outputLen|0;
|
|
289
|
-
|
|
290
|
-
var empty = new Uint8Array(0);
|
|
291
|
-
var zeros = new Uint8Array(hashLen); // "zeros" כ־salt בגודל hashLen
|
|
292
|
-
|
|
293
|
-
// early_secret = HKDF-Extract(zeros, PSK=empty) כשאין PSK
|
|
294
|
-
var early_secret = hkdf_extract(hashName, empty, zeros);
|
|
295
|
-
|
|
296
|
-
// derived_secret = HKDF-Expand-Label(early_secret, "derived", Hash(""), Hash.length)
|
|
297
|
-
var h_empty = hashFn(empty);
|
|
298
|
-
var derived_secret = hkdf_expand_label(hashName, early_secret, 'derived', h_empty, hashLen);
|
|
299
|
-
|
|
300
|
-
// handshake_secret = HKDF-Extract(derived_secret, shared_secret)
|
|
301
|
-
var handshake_secret = hkdf_extract(hashName, derived_secret, shared_secret);
|
|
302
|
-
|
|
303
|
-
// transcript_hash עד הנקודה הנוכחית
|
|
304
|
-
|
|
305
|
-
var transcript_hash = hashFn(transcript);
|
|
306
|
-
|
|
307
|
-
// תנועת handshake
|
|
308
|
-
var client_handshake_traffic_secret = hkdf_expand_label(hashName, handshake_secret, 'c hs traffic', transcript_hash, hashLen);
|
|
309
|
-
var server_handshake_traffic_secret = hkdf_expand_label(hashName, handshake_secret, 's hs traffic', transcript_hash, hashLen);
|
|
310
|
-
|
|
311
|
-
return {
|
|
312
|
-
handshake_secret: handshake_secret,
|
|
313
|
-
client_handshake_traffic_secret: client_handshake_traffic_secret,
|
|
314
|
-
server_handshake_traffic_secret: server_handshake_traffic_secret,
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// --- TLS 1.3: derive application secrets ---
|
|
319
|
-
function derive_app_traffic_secrets(hashName, handshake_secret, transcript) {
|
|
320
|
-
var hashFn = getHashFn(hashName);
|
|
321
|
-
var hashLen = hashFn.outputLen|0;
|
|
322
|
-
|
|
323
|
-
var empty = new Uint8Array(0);
|
|
324
|
-
var zeros = new Uint8Array(hashLen);
|
|
325
|
-
|
|
326
|
-
// derived_secret = HKDF-Expand-Label(handshake_secret, "derived", Hash(""), Hash.length)
|
|
327
|
-
var h_empty = hashFn(empty);
|
|
328
|
-
var derived_secret = hkdf_expand_label(hashName, handshake_secret, 'derived', h_empty, hashLen);
|
|
329
|
-
|
|
330
|
-
// master_secret = HKDF-Extract(derived_secret, zeros)
|
|
331
|
-
var master_secret = hkdf_extract(hashName, derived_secret, zeros);
|
|
332
|
-
|
|
333
|
-
// hash של ה־transcript (עד Finished של ה־server בד"כ)
|
|
334
|
-
var transcript_hash = hashFn(transcript);
|
|
335
|
-
|
|
336
|
-
// תנועת application
|
|
337
|
-
var client_app_traffic_secret = hkdf_expand_label(hashName, master_secret, 'c ap traffic', transcript_hash, hashLen);
|
|
338
|
-
var server_app_traffic_secret = hkdf_expand_label(hashName, master_secret, 's ap traffic', transcript_hash, hashLen);
|
|
339
|
-
|
|
340
|
-
return {
|
|
341
|
-
client_app_traffic_secret: client_app_traffic_secret,
|
|
342
|
-
server_app_traffic_secret: server_app_traffic_secret,
|
|
343
|
-
master_secret: master_secret
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
function build_cert_verify_tbs(hashName, isServer, transcript){
|
|
349
|
-
if(isServer){
|
|
350
|
-
var label = new TextEncoder().encode("TLS 1.3, server CertificateVerify");
|
|
351
|
-
}else{
|
|
352
|
-
var label = new TextEncoder().encode("TLS 1.3, client CertificateVerify");
|
|
353
|
-
}
|
|
354
|
-
var separator = new Uint8Array([0x00]);
|
|
355
|
-
var padding = new Uint8Array(64).fill(0x20);
|
|
356
|
-
|
|
357
|
-
var hashFn = getHashFn(hashName);
|
|
358
|
-
var transcript_hash = hashFn(transcript);
|
|
359
|
-
|
|
360
|
-
return concatUint8Arrays([padding, label, separator, transcript_hash]);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
function get_handshake_finished(hashName, traffic_secret, transcript) {
|
|
365
|
-
var hashFn = getHashFn(hashName);
|
|
366
|
-
var hashLen = hashFn.outputLen|0;
|
|
367
|
-
|
|
368
|
-
var empty = new Uint8Array(0);
|
|
369
|
-
|
|
370
|
-
var finished_key = hkdf_expand_label(hashName, traffic_secret, 'finished', empty, hashLen);
|
|
371
|
-
var transcript_hash = hashFn(transcript);
|
|
372
|
-
var verify_data=hmac(hashName, finished_key, transcript_hash);
|
|
373
|
-
|
|
374
|
-
return verify_data;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// --- Exports ---
|
|
378
|
-
export {
|
|
379
|
-
TLS_CIPHER_SUITES,
|
|
380
|
-
getHashFn,
|
|
381
|
-
getHashLen,
|
|
382
|
-
hmac,
|
|
383
|
-
hkdf_extract,
|
|
384
|
-
hkdf_expand,
|
|
385
|
-
build_hkdf_label,
|
|
386
|
-
hkdf_expand_label,
|
|
387
|
-
derive_handshake_traffic_secrets,
|
|
388
|
-
derive_app_traffic_secrets,
|
|
389
|
-
build_cert_verify_tbs,
|
|
390
|
-
get_handshake_finished
|
|
391
|
-
};
|
package/tls_server.js
DELETED
|
File without changes
|