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/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