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/README.md +432 -122
- package/index.cjs +28 -0
- package/index.d.ts +283 -0
- package/index.js +70 -15
- 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 +61 -0
- package/src/session/message.js +203 -0
- package/src/session/signing.js +129 -0
- package/src/tls_session.js +2204 -0
- package/src/tls_socket.js +877 -0
- package/{utils.js → src/utils.js} +100 -87
- package/{wire.js → src/wire.js} +1499 -1672
- package/crypto.js +0 -383
- package/tls_server.js +0 -0
- package/tls_session.js +0 -1441
- package/tls_socket.js +0 -456
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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="
|
|
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.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"type": "
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
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
|
+
}
|