lemon-tls 0.1.0 → 0.2.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.
package/index.d.ts ADDED
@@ -0,0 +1,283 @@
1
+ /// <reference types="node" />
2
+
3
+ import { Duplex } from 'node:stream';
4
+ import { EventEmitter } from 'node:events';
5
+ import type { Server as NetServer } from 'node:net';
6
+
7
+ // ======================== Types ========================
8
+
9
+ export interface SecureContext {
10
+ certificateChain: Array<{ cert: Buffer }>;
11
+ privateKey: any;
12
+ }
13
+
14
+ export interface CipherInfo {
15
+ name: string;
16
+ standardName: string;
17
+ version: string;
18
+ }
19
+
20
+ export interface PeerCertificate {
21
+ subject: string;
22
+ issuer: string;
23
+ subjectaltname?: string;
24
+ valid_from: string;
25
+ valid_to: string;
26
+ fingerprint: string;
27
+ fingerprint256: string;
28
+ serialNumber: string;
29
+ raw: Buffer;
30
+ }
31
+
32
+ export interface EphemeralKeyInfo {
33
+ type: 'X25519' | 'ECDH' | 'DH';
34
+ name?: string;
35
+ size: number;
36
+ }
37
+
38
+ export interface JA3Result {
39
+ hash: string;
40
+ raw: string;
41
+ }
42
+
43
+ export interface NegotiationResult {
44
+ version: number | null;
45
+ versionName: string | null;
46
+ cipher: number | null;
47
+ cipherName: string | null;
48
+ group: number | null;
49
+ groupName: string | null;
50
+ signatureAlgorithm: number | null;
51
+ alpn: string | null;
52
+ sni: string | null;
53
+ resumed: boolean;
54
+ helloRetried: boolean;
55
+ handshakeDuration: number | null;
56
+ }
57
+
58
+ export interface SessionTicketData {
59
+ ticket: Buffer;
60
+ ticket_nonce: Buffer;
61
+ psk: Buffer;
62
+ cipher: number;
63
+ lifetime: number;
64
+ age_add: number;
65
+ maxEarlyDataSize: number;
66
+ }
67
+
68
+ export interface CertificateCallbackInfo {
69
+ servername: string | null;
70
+ version: number | null;
71
+ ciphers: number[];
72
+ sigalgs: number[];
73
+ groups: number[];
74
+ alpns: string[];
75
+ }
76
+
77
+ // ======================== TLSSocket Options ========================
78
+
79
+ export interface TLSSocketOptions {
80
+ isServer?: boolean;
81
+ servername?: string;
82
+ SNICallback?: (servername: string, cb: (err: Error | null, ctx: SecureContext | null) => void) => void;
83
+ minVersion?: 'TLSv1.2' | 'TLSv1.3';
84
+ maxVersion?: 'TLSv1.2' | 'TLSv1.3';
85
+ ALPNProtocols?: string[];
86
+ rejectUnauthorized?: boolean;
87
+ ca?: Buffer | string;
88
+ ticketKeys?: Buffer;
89
+ session?: SessionTicketData;
90
+ requestCert?: boolean;
91
+ cert?: Buffer | string;
92
+ key?: Buffer | string;
93
+
94
+ // LemonTLS-only options
95
+ noTickets?: boolean;
96
+ signatureAlgorithms?: number[];
97
+ groups?: number[];
98
+ prioritizeChaCha?: boolean;
99
+ maxRecordSize?: number;
100
+ allowedCipherSuites?: number[];
101
+ pins?: string[];
102
+ handshakeTimeout?: number;
103
+ maxHandshakeSize?: number;
104
+ certificateCallback?: (info: CertificateCallbackInfo, cb: (err: Error | null, ctx: SecureContext | null) => void) => void;
105
+ customExtensions?: Array<{ type: number; data: Uint8Array }>;
106
+ }
107
+
108
+ // ======================== TLSSocket ========================
109
+
110
+ export class TLSSocket extends Duplex {
111
+ constructor(transport: Duplex | null, options: TLSSocketOptions);
112
+
113
+ // Node.js compatible
114
+ getProtocol(): string | null;
115
+ getCipher(): CipherInfo | null;
116
+ getPeerCertificate(): PeerCertificate | null;
117
+ isSessionReused(): boolean;
118
+ getFinished(): Buffer | null;
119
+ getPeerFinished(): Buffer | null;
120
+ exportKeyingMaterial(length: number, label: string, context: Buffer): Buffer;
121
+ getEphemeralKeyInfo(): EphemeralKeyInfo;
122
+ disableRenegotiation(): void;
123
+ setServername(name: string): void;
124
+ setSocket(transport: Duplex): void;
125
+
126
+ readonly isResumed: boolean;
127
+ readonly authorized: boolean;
128
+ readonly authorizationError: string | null;
129
+ readonly alpnProtocol: string | false;
130
+ readonly encrypted: boolean;
131
+
132
+ // LemonTLS-only
133
+ getSession(): TLSSession;
134
+ readonly handshakeDuration: number | null;
135
+ getJA3(): JA3Result | null;
136
+ getSharedSecret(): Buffer | null;
137
+ getNegotiationResult(): NegotiationResult | null;
138
+ rekeySend(): void;
139
+ rekeyBoth(): void;
140
+
141
+ // Events
142
+ on(event: 'secureConnect', listener: () => void): this;
143
+ on(event: 'data', listener: (data: Buffer) => void): this;
144
+ on(event: 'session', listener: (data: SessionTicketData) => void): this;
145
+ on(event: 'keyUpdate', listener: (direction: 'send' | 'receive') => void): this;
146
+ on(event: 'keylog', listener: (line: Buffer) => void): this;
147
+ on(event: 'clienthello', listener: (raw: Buffer, parsed: any) => void): this;
148
+ on(event: 'handshakeMessage', listener: (type: string, raw: Buffer, parsed: any) => void): this;
149
+ on(event: 'certificateRequest', listener: (msg: any) => void): this;
150
+ on(event: 'error', listener: (err: Error) => void): this;
151
+ on(event: 'close', listener: () => void): this;
152
+ on(event: string, listener: (...args: any[]) => void): this;
153
+ }
154
+
155
+ // ======================== TLSSession ========================
156
+
157
+ export interface TLSSessionOptions {
158
+ isServer?: boolean;
159
+ servername?: string;
160
+ ALPNProtocols?: string[];
161
+ SNICallback?: (servername: string, cb: (err: Error | null, ctx: SecureContext | null) => void) => void;
162
+ ticketKeys?: Buffer;
163
+ session?: SessionTicketData;
164
+ psk?: any;
165
+ rejectUnauthorized?: boolean;
166
+ ca?: Buffer | string;
167
+ noTickets?: boolean;
168
+ maxHandshakeSize?: number;
169
+ customExtensions?: Array<{ type: number; data: Uint8Array }>;
170
+ requestCert?: boolean;
171
+ cert?: Buffer | string;
172
+ key?: Buffer | string;
173
+ }
174
+
175
+ export interface TrafficSecrets {
176
+ isServer: boolean;
177
+ version: number | null;
178
+ cipher: number | null;
179
+ localAppSecret: Uint8Array | null;
180
+ remoteAppSecret: Uint8Array | null;
181
+ masterSecret: Uint8Array | null;
182
+ localRandom: Uint8Array | null;
183
+ remoteRandom: Uint8Array | null;
184
+ }
185
+
186
+ export interface HandshakeSecrets {
187
+ localSecret: Uint8Array | null;
188
+ remoteSecret: Uint8Array | null;
189
+ cipher: number | null;
190
+ }
191
+
192
+ export class TLSSession extends EventEmitter {
193
+ constructor(options: TLSSessionOptions);
194
+
195
+ readonly isServer: boolean;
196
+ readonly isResumed: boolean;
197
+ readonly handshakeDuration: number | null;
198
+ readonly authorized: boolean;
199
+ readonly authorizationError: string | null;
200
+ readonly context: any;
201
+
202
+ message(data: Uint8Array | Buffer): void;
203
+ set_context(options: Record<string, any>): void;
204
+ close(): void;
205
+ sendAlert(level: number, description: number): void;
206
+
207
+ getVersion(): number | null;
208
+ getCipher(): number | null;
209
+ getALPN(): string | null;
210
+ getPeerCertificate(): Array<{ cert: Buffer }> | null;
211
+ getTrafficSecrets(): TrafficSecrets;
212
+ getHandshakeSecrets(): HandshakeSecrets;
213
+ exportKeyingMaterial(length: number, label: string, context: Uint8Array): Uint8Array;
214
+ getFinished(): Buffer | null;
215
+ getPeerFinished(): Buffer | null;
216
+ getSharedSecret(): Buffer | null;
217
+ getNegotiationResult(): NegotiationResult;
218
+ getJA3(): JA3Result | null;
219
+ requestKeyUpdate(requestPeer?: boolean): void;
220
+
221
+ // Events
222
+ on(event: 'message', listener: (epoch: number, seq: number, type: string, data: Uint8Array) => void): this;
223
+ on(event: 'hello', listener: () => void): this;
224
+ on(event: 'secureConnect', listener: () => void): this;
225
+ on(event: 'session', listener: (data: SessionTicketData) => void): this;
226
+ on(event: 'psk', listener: (identity: Buffer, callback: (result: { psk: Buffer; cipher: number } | null) => void) => void): this;
227
+ on(event: 'keyUpdate', listener: (info: { direction: 'send' | 'receive'; secret: Uint8Array }) => void): this;
228
+ on(event: 'clienthello', listener: (raw: Buffer, parsed: any) => void): this;
229
+ on(event: 'handshakeMessage', listener: (type: string, raw: Buffer, parsed: any) => void): this;
230
+ on(event: 'certificateRequest', listener: (msg: any) => void): this;
231
+ on(event: 'error', listener: (err: Error) => void): this;
232
+ on(event: string, listener: (...args: any[]) => void): this;
233
+ }
234
+
235
+ // ======================== Module Functions ========================
236
+
237
+ export function createSecureContext(options: { key: Buffer | string; cert: Buffer | string }): SecureContext;
238
+ export function connect(port: number, host: string, options?: TLSSocketOptions, callback?: () => void): TLSSocket;
239
+ export function connect(options: TLSSocketOptions & { port: number; host?: string }, callback?: () => void): TLSSocket;
240
+ export function createServer(options: TLSSocketOptions & { key?: Buffer | string; cert?: Buffer | string }, connectionListener?: (socket: TLSSocket) => void): NetServer;
241
+ export function getCiphers(): string[];
242
+
243
+ export const DEFAULT_MIN_VERSION: string;
244
+ export const DEFAULT_MAX_VERSION: string;
245
+
246
+ // ======================== Submodules ========================
247
+
248
+ export declare const crypto: {
249
+ TLS_CIPHER_SUITES: Record<number, any>;
250
+ getHashFn: (name: string) => any;
251
+ getHashLen: (name: string) => number;
252
+ hkdf_extract: (hash: string, salt: Uint8Array, ikm: Uint8Array) => Uint8Array;
253
+ hkdf_expand: (hash: string, prk: Uint8Array, info: Uint8Array, length: number) => Uint8Array;
254
+ hkdf_expand_label: (hash: string, secret: Uint8Array, label: string, context: Uint8Array, length: number) => Uint8Array;
255
+ hmac: (hash: string, key: Uint8Array, data: Uint8Array) => Uint8Array;
256
+ };
257
+
258
+ export declare const wire: any;
259
+ export declare const record: {
260
+ getAeadAlgo: (cipher: number) => string;
261
+ deriveKeys: (secret: Uint8Array, cipher: number) => { key: Uint8Array; iv: Uint8Array };
262
+ getNonce: (iv: Uint8Array, seq: number) => Uint8Array;
263
+ encryptRecord: (contentType: number, plaintext: Uint8Array, key: Uint8Array, nonce: Uint8Array, algo: string) => Uint8Array;
264
+ decryptRecord: (ciphertext: Uint8Array, key: Uint8Array, nonce: Uint8Array, algo: string) => Uint8Array;
265
+ };
266
+
267
+ // ======================== Default Export ========================
268
+
269
+ declare const _default: {
270
+ TLSSocket: typeof TLSSocket;
271
+ TLSSession: typeof TLSSession;
272
+ createSecureContext: typeof createSecureContext;
273
+ connect: typeof connect;
274
+ createServer: typeof createServer;
275
+ getCiphers: typeof getCiphers;
276
+ DEFAULT_MIN_VERSION: string;
277
+ DEFAULT_MAX_VERSION: string;
278
+ crypto: typeof crypto;
279
+ wire: typeof wire;
280
+ record: typeof record;
281
+ };
282
+
283
+ export default _default;
package/index.js CHANGED
@@ -1,15 +1,70 @@
1
-
2
- var TLSSession = require('./tls_session');
3
- var TLSSocket = require('./tls_socket');
4
- var createSecureContext = require('./secure_context');
5
- //var {createServer} = require('./tls_server');
6
- //var constants = require('./constants');
7
-
8
- module.exports = {
9
- TLSSession: TLSSession,
10
- TLSSocket: TLSSocket,
11
- createSecureContext: createSecureContext,
12
- //createServer: createServer
13
- //DEFAULT_CIPHERS: constants.DEFAULT_CIPHERS,
14
- //DEFAULT_SIGALGS: constants.DEFAULT_SIGALGS
15
- };
1
+ import TLSSession from './src/tls_session.js';
2
+ import TLSSocket from './src/tls_socket.js';
3
+ import createSecureContext from './src/secure_context.js';
4
+ import {
5
+ TLS_CIPHER_SUITES,
6
+ getHashFn,
7
+ getHashLen,
8
+ hkdf_extract,
9
+ hkdf_expand,
10
+ hkdf_expand_label,
11
+ hmac,
12
+ } from './src/crypto.js';
13
+ import * as wire from './src/wire.js';
14
+ import * as record from './src/record.js';
15
+ import {
16
+ connect,
17
+ createServer,
18
+ getCiphers,
19
+ DEFAULT_MIN_VERSION,
20
+ DEFAULT_MAX_VERSION,
21
+ } from './src/compat.js';
22
+
23
+ /**
24
+ * Crypto primitives for QUIC and custom transport consumers.
25
+ */
26
+ var crypto = {
27
+ TLS_CIPHER_SUITES,
28
+ getHashFn,
29
+ getHashLen,
30
+ hkdf_extract,
31
+ hkdf_expand,
32
+ hkdf_expand_label,
33
+ hmac,
34
+ };
35
+
36
+ export {
37
+ TLSSocket,
38
+ TLSSession,
39
+ createSecureContext,
40
+ connect,
41
+ createServer,
42
+ getCiphers,
43
+ DEFAULT_MIN_VERSION,
44
+ DEFAULT_MAX_VERSION,
45
+ crypto,
46
+ wire,
47
+ record,
48
+ };
49
+
50
+ /**
51
+ * Default export — Node.js tls API compatible.
52
+ *
53
+ * Usage:
54
+ * import tls from 'lemon-tls';
55
+ * tls.connect(443, 'example.com', { ... });
56
+ * tls.createServer({ key, cert }, (socket) => { ... });
57
+ */
58
+ export default {
59
+ TLSSocket,
60
+ TLSSession,
61
+ createSecureContext,
62
+ connect,
63
+ createServer,
64
+ getCiphers,
65
+ DEFAULT_MIN_VERSION,
66
+ DEFAULT_MAX_VERSION,
67
+ crypto,
68
+ wire,
69
+ record,
70
+ };
package/lemontls.svg CHANGED
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="993" height="200" stroke="none" stroke-linecap="round" stroke-linejoin="round" fill="#fff" fill-rule="evenodd"><g fill-rule="nonzero"><path d="M172.4 56.8v85.4c0 5.2-2.7 10-7 12.6l-72.6 42.8c-4.3 2.5-9.4 2.5-13.6 0L6.5 154.8c-4.3-2.6-7-7.4-7-12.6V56.8c0-5.2 2.7-10 7-12.6L79.2 1.4c4.2-2.5 9.3-2.5 13.6 0l72.6 42.8c4.3 2.6 7 7.4 7 12.6z" fill="#4f4f4f"/><path d="M94.5 35C86 41.6 86.8 49.2 87 55.8l2.4-.3-.1-3c.5 0 1-.2 1.6-.3 11.7-5.5 6.4-25 6.4-25C97.3 30 90 33.5 85 37c-4.7 3.5-4.8 9-3.8 11.2 1 1.5 2.2 2.6 3.8 3C84 40 94.5 35 94.5 35z" fill="#65cd76"/><path d="M86 55.4c-5.2.1-9.3 3-10.3 6.6-2.8 10.4-26.2 14.3-26.2 45.5s23.4 35 26.2 45.5c1 3.7 5 6.5 10.3 6.6 5.2-.1 9.3-2.8 10.3-6.6 2.8-10.4 26.2-14.3 26.2-45.5S99 72.4 96.2 62c-1-3.7-5-6.5-10.3-6.6zM66.6 91c-5 8-5 25 0 33 .6 1 .5 2.3-.4 3.2-.1.1-.4.2-.5.4-1.2.6-2.7.3-3.5-1a44 44 0 0 1 0-38.3c.8-1.2 2.3-1.6 3.5-1 1.2.8 1.6 2.3.8 3.5z" fill="#ffed24"/></g><path d="M240.7 147.3h46.6V172h-75V28.3h28.3v119zm131.5-31v7.4h-49.6q0 12.3 3 19.5 1 2.5 3.6 5 2.7 2.6 5.6 2.6 3 0 7.2-5 4.3-5 6.7-12l21.2 15q-5.6 10.3-17 18-11.4 7.6-18.3 7.6-7 0-20.2-11-13.3-11-16-17-3-6-3-30 0-24 3-30 2.8-6 16-17 13.2-11 19.4-11 6 0 19.3 11 13.3 10.8 16 17 3 6 3 29.6zm-49.6-12H346q-.7-10.8-2.2-13.6-1.5-2.8-4.7-5.4-3.2-2.7-6-2.7-2.7 0-6.2 5.4-3.5 5.5-4.3 16.3zm143.6-11.6v79.2h-27V95.5q0-3.5-3.7-7.3-3.7-3.8-6.3-3.8-2.5 0-8.3 5v82.4h-27V101q0-10.5-2.5-16.3-2.5-5.7-7.8-10L406 59q6.7 5.7 10 11.7 13.3-12 18.5-12 3 0 10 4.5 7 4.5 12.7 11 16.2-15.4 22.5-15.4 6.3 0 19 11.4 12.6 11.4 12.6 22.4v39.6q0 10.5 2.4 16.2 2.5 5.8 7.8 10l-22.5 16q-14.8-11.7-14.8-33.3V95.5q0-3.5-3.7-7.3-3.7-3.8-6-3.8-2.4 0-8.8 5.2.5 2 .5 3zm121.5 71.6q-12.6 10-18.5 10-6 0-18.6-10-12.6-10-15.5-15-4.3-7.6-4.3-33 0-25.2 4.3-32.6 3-5 15.5-15 12.6-10 18.6-10 6 0 18.5 10 12.6 10 15.5 15 4.3 7.4 4.3 32.6 0 25.3-4.3 33-3 5-15.5 15zM564 147.6q3.2 3 5 3 1.8 0 5-3 3.2-3 4.6-5.5 2.7-4.5 2.7-25.5 0-21-2.7-25.6-1.4-2.5-4.6-5.5-3.2-3-5-3-2 0-5 3-3 3-4.6 5.5-2.7 4.5-2.7 25.4 0 21 2.7 25.7 1.5 2.4 4.6 5.5zM654 93v78.7h-27V101q0-10.5-2.5-16.3-2.5-5.7-7.8-10L639.3 59q7.6 6.2 11.2 14.2 15.2-14.4 21.5-14.4 6.2 0 18.8 11.4 12.7 11.4 12.7 22.4v39.6q0 10.5 2.4 16.2 2.5 5.8 7.8 10l-22.5 15.8q-14.8-11.7-14.8-33.3V95.5q0-3.5-3.7-7.3-3.7-3.8-7-3.8-3.2 0-11.8 8.7z" fill="#4f4f4f"/><path d="M737.3 28.3H819V53h-26.6v119H764V53h-26.7V28.3zm115.4 119h46.6V172h-75V28.3h28.3v119zm52.8-10.7l22.8-15.6q3.2 9.6 10.4 17.6 7.2 8 10.2 8 3 0 6.3-2 3.4-2 5.3-4 2.6-3.3 2.6-10.3 0-7-3.2-8.6-4-3.5-16-9.2-11.8-5.8-22-12.4-10-6.7-12.8-13-2.8-6.3-2.8-16.5 0-10 4.5-17.7 4-6 17.5-16.5 13.3-10.6 19.7-10.6 11.2 0 25.8 11.8 14.6 11.8 18.5 26l-22.8 15.8q-3.3-9.6-10.5-17.7-7-8-10-8-3 0-6.5 1.8-3.5 2-5.6 4.7-2.2 2.7-2.2 9.4 0 6.7 4 9 3.3 3 15 9 30 16.4 35.3 26.7 2.2 3.7 2.2 14.7 0 11-4.5 18.5-4 6-17.4 16.5-13.3 10.6-19.7 10.6-11.3 0-25.8-11.8-14.6-11.8-18.5-26z" fill="#838383"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="661" height="142" stroke="#000" stroke-linecap="round" stroke-linejoin="round" fill="#fff" fill-rule="evenodd"><defs><linearGradient id="A" x1="50%" y1="0%" x2="50%" y2="100%"><stop offset="0%" stop-color="#fed43e"/><stop offset="100%" stop-color="#ffb700"/></linearGradient></defs><g fill="url(#A)" stroke="none"><path d="M118 129.4V49.7h21V109h33.4v20.4H118z"/><path d="M233.8 98.8v4h-37.5q0 6.6 2.4 10 2.5 3.3 7.7 3.3 4.7 0 7-2.4 2.2-2.4 2.2-6.5h18.3q0 11-7 17.4-7 6.3-20.2 6.3-14 0-21.5-8-7.7-8-7.7-24 0-15.8 7.5-24 7.5-8 20.6-8 13.7 0 21 8 7.2 8 7.2 24zm-37.4-7h18.4q0-4.7-2.2-7.5-2.3-2.8-6.2-2.8-9 0-10 10.3z"/><path d="M326.2 89.7v39.7h-19v-37q0-4-1.5-6.3-1.6-2.4-4.4-2.4-3.3 0-5.4 2.8-2 2.8-2 6.8v36H275v-37q0-4-1.6-6.3-1.6-2.4-4.4-2.4-3.3 0-5.4 2.8-2 2.8-2 6.8v36h-18.8V68.2h15.4l1.3 9q2.8-4.8 7.5-7.7 4.7-2.8 10-2.8 11.2 0 15 10.5 3-4.8 7.5-7.7 4.6-2.8 9.6-2.8 8.5 0 12.8 6 4.3 6 4.3 17z"/><path d="M363.3 66.8q13.2 0 20.7 8.2 7.5 8 7.5 23.8 0 15.6-7.5 23.8-7.5 8.2-20.7 8.2-13 0-20.6-8.2-7.5-8-7.5-23.8 0-15.8 7.5-24 7.5-8 20.6-8zM354 95.5v6.6q0 13 9.3 13 9.4 0 9.4-13v-6.6q0-13-9.4-13-9.3 0-9.3 13z"/><path d="M452.5 89.7v39.7h-19v-37q0-4-1.6-6.3-1.7-2.4-4.7-2.4-3.5 0-5.7 2.8-2.2 2.8-2.2 6.8v36h-18.8V68.2H416l1.3 9.3q3-5 7.7-7.8 4.7-3 10-3 8.7 0 13 6 4.4 6 4.4 17z"/></g><g fill="#2e3a41"><path d="M529 70h-21.3v59.3h-21V70h-21.4V49.7H529V70zm9.5 59.4V49.7h21V109H593v20.4h-54.3zM657.7 73v1.4h-19.5V74q0-3.5-2-5.8-2-2.3-6.4-2.3-4 0-6.3 1.5-2.3 1.5-2.3 3.7 0 3 3 4.6 3 1.5 9.7 3.2 8 2 13 4 5 2 9 7 3.7 4.8 3.8 13.2 0 14-7.8 21-7.8 6.8-20.8 6.8-15.3 0-23.7-6.3-8.5-6.2-8.5-22h19.8q0 6 2.5 8 2.6 2 8 2 4 0 6.6-1 2.6-1 2.6-4.2 0-3-3-4.4-3-1.4-9.4-3-8-2-13.2-4.3-5.2-2.3-9-7.5-4-5.2-4-14 0-13 8.3-19.3 8.3-6.2 21-6.2 12.5 0 20.5 6.2 8 6.2 8.2 18.4z" stroke="none"/><path d="M42.6-.3c-4.3.3-7 1-11.5 3.6-1.8 1-5.8 4.8-7.3 7-1.3 2-3 5.6-3.4 7.2-.1.7-.4 2-.5 2.5-.4 1.7-.4 16.6 0 17 .2.1.5 0 .7-.2l1.7-1 2.3-1.3 2.2-1.3c2.4-1.2 2.5-1.6 2.5-6.4 0-5.6.7-8 3.2-11.3 1.8-2.4 4-3.8 7.6-5 2-.7 8-.8 10-.1l3.2 1.4c.1.1.8.6 1.5 1 1.3 1 3.4 3 4 4 .1.3.4.8.5 1 1.4 2.5 1.8 4.5 2 10l.2 4 1 .7c.5.4 1.3 1 1.7 1l1.2.6c.2.2.6.4.8.5a9 9 0 0 1 1.4.7c1.7 1.2 2.6 1.5 3 1.2a85 85 0 0 0 .1-8.9c-.1-8.5-.2-8.7-1-10.7l-1-2.7c-.1-.3-.3-.7-.5-1-.4-.4-1-1.4-1.3-2-.3-.8-2-2.7-3.5-4.3S58 2.6 57.3 2.6c-.2 0-.6-.2-.8-.5-.2-.2-.6-.4-1-.4-.2 0-.6-.2-.8-.3-.3-.4-1.5-.7-4.6-1.4-3-.6-3.8-.6-7.6-.3z" stroke="none" fill-rule="nonzero"/></g><path d="M87.7 20.4c-.2.1-.7.3-1 .3a17 17 0 0 0-6.7 2.6c-1.2 1-3 3-3.5 4-.3.6-.7 1.3-.8 1.6-.1.2-.3 1-.4 1.7 0 .6-.2 1.3-.3 1.3-.4.3-.2 4.8.3 6l.4 1.3h3.2c3.8-.1 5.4-.4 8.4-2C88.7 36.6 92 33 92 32c0-.2.1-.3.2-.3s.2-.1.2-.3.4-1.3 1-2.6c.2-.4.4-1.2.5-2 0-.6.2-1.2.3-1.4.1-.1.3-1.2.4-2.5l.1-2.2-1-.3c-1-.4-5.5-.5-6-.2z" fill="#00991a" fill-rule="nonzero" stroke="none"/><path d="M39.6 29l-5 3-3 2c-.3.1-1 .5-1.5 1s-1.3.8-1.4.8c-.4 0-3 1.6-4.4 2.6a21 21 0 0 1-2.2 1.4l-9.4 5.7C8.6 48.7 5.2 53 3 58 1.7 60.4 1.5 61 1 63.2c-.1.5-.3 1-.4 1.2-.2.2-.5 2-.8 4-.7 5.3-.5 21.5.4 26.5.7 4 1.4 6.6 2 7 .1.1.2.6.2 1s.2 1 .5 1.5l1.8 3.8 2 3.5c.3.3.6.6.6.7 0 .3 2 3 2.7 4l7.4 7.4c3.6 2.8 5.7 4.2 6.4 4.6l1.7 1c.5.4 1 .7 1.2.7.1 0 1 .6 2.2 1.3 1 .8 2 1.4 2.3 1.4.1 0 .4.2.6.4.2.3.8.8 1.3 1.2a50 50 0 0 1 4.2 3.1c4.6 3.6 4.8 3.7 7.8 3.7 1.8 0 2.7-.2 3.2-.5.4-.3 1-.6 1.5-.6.4-.1 1.5-.8 2.3-1.6l3-2.5c3.4-2.7 4.3-3.4 7.7-5.4l2.4-1.6 2-1.3c.2 0 .5-.2.8-.5.3-.4.7-.6 1-.6a42 42 0 0 0 8.3-7.2c2.5-2.6 5.4-6.5 5.4-7.2 0-.2.2-.5.5-.7a51 51 0 0 0 5.7-13.9c.2-.7.4-2 .6-3 .6-2.4.6-3.3.8-13l-.7-16-.6-2.7c-1-5-4.3-10-8.6-14.4C78 46 76.7 45 73 42.7l-5.5-3.3c-.4-.3-1.3-.8-2-1.2l-6-3.7c-.2-.2-.6-.3-.8-.3s-1-.4-1.5-1c-.5-.5-1.2-1-1.5-1s-.6-.1-.6-.3c0-.3-4-2.8-6.2-3.8-1-.5-2-.6-4-.6-2.6 0-2.7.1-5.2 1.3z" fill="url(#A)" fill-rule="nonzero" stroke="none"/><g fill="#2e3a41"><circle cx="46.6" cy="75.8" stroke="none" r="11.4"/><path stroke="none" d="M40.6 70.6h12v29.2h-12z"/><ellipse cx="46.6" cy="99.5" rx="6" ry="6.2" stroke="none"/></g></svg>
package/package.json CHANGED
@@ -1,62 +1,120 @@
1
- {
2
- "name": "lemon-tls",
3
- "version": "0.1.0",
4
- "description": "JavaScript TLS 1.3/1.2 implementation for Node.js, with full control over cryptographic keys and record layer",
5
- "main": "index.js",
6
- "type": "commonjs",
7
- "keywords": [
8
- "openssl",
9
- "boringssl",
10
- "cryptlib",
11
- "rustls",
12
- "low-level",
13
- "https",
14
- "ssl",
15
- "tls",
16
- "tls13",
17
- "tls12",
18
- "nodejs",
19
- "javascript",
20
- "crypto",
21
- "x509",
22
- "handshake",
23
- "alpn",
24
- "sni",
25
- "hkdf",
26
- "aead",
27
- "quic",
28
- "http3",
29
- "dtls",
30
- "sctp",
31
- "secure",
32
- "network",
33
- "backend",
34
- "server"
35
- ],
36
- "author": "colocohen",
37
- "license": "Apache-2.0",
38
- "repository": {
39
- "type": "git",
40
- "url": "https://github.com/colocohen/lemon-tls.git"
41
- },
42
- "bugs": {
43
- "url": "https://github.com/colocohen/lemon-tls/issues"
44
- },
45
- "homepage": "https://github.com/colocohen/lemon-tls",
46
- "funding": [
47
- {
48
- "type": "github",
49
- "url": "https://github.com/sponsors/colocohen"
50
- },
51
- {
52
- "type": "opencollective",
53
- "url": "https://opencollective.com/colocohen"
54
- }
55
- ],
56
- "dependencies": {
57
- "@noble/curves": "^2.0.0",
58
- "@noble/hashes": "^2.0.0",
59
- "@stablelib/aes": "^2.0.1",
60
- "@stablelib/gcm": "^2.0.1"
61
- }
62
- }
1
+ {
2
+ "name": "lemon-tls",
3
+ "version": "0.2.0",
4
+ "description": "Zero-dependency TLS 1.3/1.2 implementation for Node.js full control over cryptographic keys, record layer, and handshake. Drop-in replacement for node:tls with advanced options impossible in OpenSSL.",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "types": "index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./index.d.ts",
11
+ "import": "./index.js",
12
+ "require": "./index.cjs",
13
+ "default": "./index.js"
14
+ },
15
+ "./wire": "./src/wire.js",
16
+ "./crypto": "./src/crypto.js",
17
+ "./record": "./src/record.js",
18
+ "./session": "./src/tls_session.js"
19
+ },
20
+ "scripts": {
21
+ "test": "node tests/test_all.js",
22
+ "test:https": "node tests/test_https.js",
23
+ "test:compat": "node tests/test_compat.js",
24
+ "test:all": "node tests/test_all.js && node tests/test_compat.js"
25
+ },
26
+ "files": [
27
+ "index.js",
28
+ "index.cjs",
29
+ "index.d.ts",
30
+ "src/",
31
+ "README.md",
32
+ "LICENSE",
33
+ "lemontls.svg"
34
+ ],
35
+ "engines": {
36
+ "node": ">=16.0.0"
37
+ },
38
+ "keywords": [
39
+ "tls",
40
+ "tls13",
41
+ "tls12",
42
+ "tls-1.3",
43
+ "tls-1.2",
44
+ "ssl",
45
+ "https",
46
+ "secure",
47
+ "crypto",
48
+ "cryptography",
49
+ "encryption",
50
+ "handshake",
51
+ "x509",
52
+ "certificate",
53
+ "mtls",
54
+ "mutual-tls",
55
+ "client-certificate",
56
+ "psk",
57
+ "session-resumption",
58
+ "session-tickets",
59
+ "key-update",
60
+ "hello-retry-request",
61
+ "hkdf",
62
+ "aead",
63
+ "aes-gcm",
64
+ "chacha20",
65
+ "chacha20-poly1305",
66
+ "x25519",
67
+ "p256",
68
+ "ecdhe",
69
+ "rsa-pss",
70
+ "ecdsa",
71
+ "sni",
72
+ "alpn",
73
+ "ja3",
74
+ "ja3-fingerprint",
75
+ "fingerprint",
76
+ "certificate-pinning",
77
+ "keylog",
78
+ "wireshark",
79
+ "quic",
80
+ "http3",
81
+ "dtls",
82
+ "record-layer",
83
+ "pure-javascript",
84
+ "zero-dependencies",
85
+ "no-openssl",
86
+ "no-native",
87
+ "nodejs",
88
+ "node",
89
+ "javascript",
90
+ "security",
91
+ "network",
92
+ "protocol",
93
+ "drop-in-replacement"
94
+ ],
95
+ "author": "colocohen",
96
+ "license": "Apache-2.0",
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "https://github.com/colocohen/lemon-tls.git"
100
+ },
101
+ "bugs": {
102
+ "url": "https://github.com/colocohen/lemon-tls/issues"
103
+ },
104
+ "homepage": "https://github.com/colocohen/lemon-tls#readme",
105
+ "funding": [
106
+ {
107
+ "type": "github",
108
+ "url": "https://github.com/sponsors/colocohen"
109
+ },
110
+ {
111
+ "type": "opencollective",
112
+ "url": "https://opencollective.com/colocohen"
113
+ },
114
+ {
115
+ "type": "buymeacoffee",
116
+ "url": "https://buymeacoffee.com/colocohen"
117
+ }
118
+ ],
119
+ "dependencies": {}
120
+ }