lemon-tls 0.7.0 → 0.10.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 +258 -20
- package/index.cjs +9 -7
- package/index.d.ts +323 -23
- package/index.js +126 -0
- package/package.json +39 -6
- package/src/compat.js +325 -46
- package/src/crypto.js +19 -0
- package/src/dtls_session.js +141 -17
- package/src/dtls_socket.js +32 -0
- package/src/node_options.js +138 -0
- package/src/record.js +192 -57
- package/src/secure_context.js +63 -4
- package/src/session/cert_compression.js +157 -0
- package/src/session/ecdh.js +237 -10
- package/src/session/ech.js +715 -0
- package/src/session/hpke.js +414 -0
- package/src/session/message.js +39 -4
- package/src/session/signing.js +56 -3
- package/src/session/ticket.js +38 -25
- package/src/tls_session.js +2835 -205
- package/src/tls_socket.js +839 -148
- package/src/utils.js +68 -1
- package/src/wire.js +148 -9
- package/types/crypto.d.ts +40 -0
- package/types/record.d.ts +40 -0
- package/types/session.d.ts +3 -0
- package/types/wire.d.ts +62 -0
package/src/utils.js
CHANGED
|
@@ -125,10 +125,77 @@ function timingSafeEqualU8(a, b) {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Parse an X509Certificate DN string into the object shape Node's certificate
|
|
130
|
+
* objects use.
|
|
131
|
+
*
|
|
132
|
+
* crypto.X509Certificate gives `subject`/`issuer` as newline-separated
|
|
133
|
+
* "KEY=value" text, but Node documents them on a certificate object as objects
|
|
134
|
+
* keyed by RDN type: { C, ST, L, O, OU, CN }. Passing the raw string through
|
|
135
|
+
* meant tls.checkServerIdentity() — which reads cert.subject.CN — could never
|
|
136
|
+
* find a Common Name, so any certificate without a SAN was rejected outright
|
|
137
|
+
* even when its CN matched. The exported identity check did not work against
|
|
138
|
+
* this library's own getPeerCertificate() output, which is exactly the pairing
|
|
139
|
+
* Node documents.
|
|
140
|
+
*
|
|
141
|
+
* A type may legitimately repeat (OU is the common case); Node represents a
|
|
142
|
+
* repeat as an array and a single occurrence as a plain string.
|
|
143
|
+
*
|
|
144
|
+
* Idempotent: an already-parsed object is returned unchanged, so callers can
|
|
145
|
+
* pass either form.
|
|
146
|
+
*/
|
|
147
|
+
function parseDN(dn) {
|
|
148
|
+
if (dn == null) return {};
|
|
149
|
+
if (typeof dn === 'object') return dn;
|
|
150
|
+
let out = {};
|
|
151
|
+
let lines = String(dn).split('\n');
|
|
152
|
+
for (let i = 0; i < lines.length; i++) {
|
|
153
|
+
let line = lines[i];
|
|
154
|
+
if (!line) continue;
|
|
155
|
+
let eq = line.indexOf('=');
|
|
156
|
+
if (eq < 1) continue;
|
|
157
|
+
let k = line.slice(0, eq).trim();
|
|
158
|
+
let v = line.slice(eq + 1);
|
|
159
|
+
if (!Object.prototype.hasOwnProperty.call(out, k)) out[k] = v;
|
|
160
|
+
else if (Array.isArray(out[k])) out[k].push(v);
|
|
161
|
+
else out[k] = [out[k], v];
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* A certificate (DER) as node:tls's getPeerCertificate() describes it:
|
|
168
|
+
* subject and issuer as RDN objects, the SAN string, the validity dates,
|
|
169
|
+
* fingerprints, serial, and the raw DER. One place for TLSSocket, the
|
|
170
|
+
* session's identity check and anything above (QUIC) — they built it
|
|
171
|
+
* apiece. Unparseable: just { raw }.
|
|
172
|
+
*/
|
|
173
|
+
function certificateObject(der) {
|
|
174
|
+
if (!der) return null;
|
|
175
|
+
try {
|
|
176
|
+
let x = new crypto.X509Certificate(der);
|
|
177
|
+
return {
|
|
178
|
+
subject: parseDN(x.subject),
|
|
179
|
+
issuer: parseDN(x.issuer),
|
|
180
|
+
subjectaltname: x.subjectAltName,
|
|
181
|
+
valid_from: x.validFrom,
|
|
182
|
+
valid_to: x.validTo,
|
|
183
|
+
fingerprint: x.fingerprint,
|
|
184
|
+
fingerprint256: x.fingerprint256,
|
|
185
|
+
serialNumber: x.serialNumber,
|
|
186
|
+
raw: der
|
|
187
|
+
};
|
|
188
|
+
} catch (e) {
|
|
189
|
+
return { raw: der };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
128
193
|
export {
|
|
194
|
+
certificateObject,
|
|
129
195
|
concatUint8Arrays,
|
|
130
196
|
arraybufferEqual,
|
|
131
197
|
arraysEqual,
|
|
132
198
|
uint8Equal,
|
|
133
|
-
timingSafeEqualU8
|
|
199
|
+
timingSafeEqualU8,
|
|
200
|
+
parseDN
|
|
134
201
|
};
|
package/src/wire.js
CHANGED
|
@@ -54,6 +54,14 @@ const TLS_CONTENT_TYPE = {
|
|
|
54
54
|
APPLICATION_DATA: 23
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
// The largest one handshake message may be, as its header declares it, or a
|
|
58
|
+
// CompressedCertificate decompressed to. OpenSSL allows a ClientHello of
|
|
59
|
+
// 128 KB and certificate chains up to 100 KB (max_cert_list); QUIC's CRYPTO
|
|
60
|
+
// buffer in QUICO is 64 KB. The 24-bit length would allow 16 MB — memory a
|
|
61
|
+
// peer could make us hold, or inflate a few hundred bytes into, before it
|
|
62
|
+
// has proven anything. A maxHandshakeSize below it lowers it.
|
|
63
|
+
const HANDSHAKE_MESSAGE_MAX = 128 * 1024;
|
|
64
|
+
|
|
57
65
|
const TLS_ALERT_LEVEL = {
|
|
58
66
|
WARNING: 1,
|
|
59
67
|
FATAL: 2
|
|
@@ -75,12 +83,14 @@ const TLS_ALERT = {
|
|
|
75
83
|
PROTOCOL_VERSION: 70,
|
|
76
84
|
INSUFFICIENT_SECURITY: 71,
|
|
77
85
|
INTERNAL_ERROR: 80,
|
|
86
|
+
INAPPROPRIATE_FALLBACK: 86, // RFC 7507 (TLS_FALLBACK_SCSV)
|
|
78
87
|
USER_CANCELED: 90,
|
|
79
88
|
MISSING_EXTENSION: 109,
|
|
80
89
|
UNSUPPORTED_EXTENSION: 110,
|
|
81
90
|
UNRECOGNIZED_NAME: 112,
|
|
82
91
|
CERTIFICATE_REQUIRED: 116,
|
|
83
|
-
NO_APPLICATION_PROTOCOL: 120
|
|
92
|
+
NO_APPLICATION_PROTOCOL: 120,
|
|
93
|
+
ECH_REQUIRED: 121
|
|
84
94
|
};
|
|
85
95
|
|
|
86
96
|
const TLS_MESSAGE_TYPE = {
|
|
@@ -97,6 +107,8 @@ const TLS_MESSAGE_TYPE = {
|
|
|
97
107
|
CLIENT_KEY_EXCHANGE: 16,
|
|
98
108
|
FINISHED: 20,
|
|
99
109
|
KEY_UPDATE: 24,
|
|
110
|
+
CERTIFICATE_STATUS: 22, // RFC 6066 §8 (TLS 1.2: the stapled OCSP response)
|
|
111
|
+
COMPRESSED_CERTIFICATE: 25, // RFC 8879
|
|
100
112
|
MESSAGE_HASH: 254 // HRR flow marker
|
|
101
113
|
};
|
|
102
114
|
|
|
@@ -113,6 +125,7 @@ const TLS_EXT = {
|
|
|
113
125
|
MAX_FRAGMENT_LENGTH: 1,
|
|
114
126
|
STATUS_REQUEST: 5,
|
|
115
127
|
SUPPORTED_GROUPS: 10,
|
|
128
|
+
EC_POINT_FORMATS: 11,
|
|
116
129
|
SIGNATURE_ALGORITHMS: 13,
|
|
117
130
|
USE_SRTP: 14,
|
|
118
131
|
HEARTBEAT: 15,
|
|
@@ -122,6 +135,7 @@ const TLS_EXT = {
|
|
|
122
135
|
SERVER_CERT_TYPE: 20,
|
|
123
136
|
PADDING: 21,
|
|
124
137
|
EXTENDED_MASTER_SECRET: 23,
|
|
138
|
+
COMPRESS_CERTIFICATE: 27, // RFC 8879
|
|
125
139
|
SESSION_TICKET: 35,
|
|
126
140
|
PRE_SHARED_KEY: 41,
|
|
127
141
|
EARLY_DATA: 42,
|
|
@@ -304,6 +318,7 @@ let exts = {};
|
|
|
304
318
|
exts.SERVER_NAME = { encode: null, decode: null };
|
|
305
319
|
exts.SUPPORTED_VERSIONS = { encode: null, decode: null };
|
|
306
320
|
exts.SUPPORTED_GROUPS = { encode: null, decode: null };
|
|
321
|
+
exts.EC_POINT_FORMATS = { encode: null, decode: null };
|
|
307
322
|
exts.SIGNATURE_ALGORITHMS = { encode: null, decode: null };
|
|
308
323
|
exts.PSK_KEY_EXCHANGE_MODES = { encode: null, decode: null };
|
|
309
324
|
exts.KEY_SHARE = { encode: null, decode: null };
|
|
@@ -313,6 +328,47 @@ exts.RENEGOTIATION_INFO = { encode: null, decode: null };
|
|
|
313
328
|
exts.SESSION_TICKET = { encode: null, decode: null };
|
|
314
329
|
exts.EXTENDED_MASTER_SECRET = { encode: null, decode: null };
|
|
315
330
|
exts.CERTIFICATE_AUTHORITIES = { encode: null, decode: null };
|
|
331
|
+
exts.COMPRESS_CERTIFICATE = { encode: null, decode: null };
|
|
332
|
+
exts.STATUS_REQUEST = { encode: null, decode: null };
|
|
333
|
+
|
|
334
|
+
/* ---------------------- STATUS_REQUEST (5) ---------------------- */
|
|
335
|
+
// RFC 6066 §8. Three places, three bodies:
|
|
336
|
+
// ClientHello: CertificateStatusRequest — status_type ocsp(1),
|
|
337
|
+
// responder_id_list<0..2^16-1>, request_extensions<0..2^16-1>
|
|
338
|
+
// ServerHello (1.2): empty — "a CertificateStatus message follows"
|
|
339
|
+
// CertificateEntry (1.3, RFC 8446 §4.4.2.1): CertificateStatus itself
|
|
340
|
+
// Encoded from { ocsp: true } (the request with empty lists, as every
|
|
341
|
+
// browser sends it) or a raw body; decoded to { status_type } or {} when
|
|
342
|
+
// empty. Unknown status types are not an error: the server just does not
|
|
343
|
+
// answer them.
|
|
344
|
+
exts.STATUS_REQUEST.encode = function (value) {
|
|
345
|
+
if (value instanceof Uint8Array) return value;
|
|
346
|
+
if (value && value.ocsp) return new Uint8Array([1, 0, 0, 0, 0]);
|
|
347
|
+
return new Uint8Array(0);
|
|
348
|
+
};
|
|
349
|
+
exts.STATUS_REQUEST.decode = function (data) {
|
|
350
|
+
if (data.length === 0) return {};
|
|
351
|
+
return { status_type: data[0] };
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/* ---------------------- COMPRESS_CERTIFICATE (27) ---------------------- */
|
|
355
|
+
// RFC 8879 §3: CertificateCompressionAlgorithm algorithms<2..2^8-2> — a
|
|
356
|
+
// one-byte length, then 16-bit codes.
|
|
357
|
+
exts.COMPRESS_CERTIFICATE.encode = function (value) {
|
|
358
|
+
let list = Array.isArray(value) ? value : [];
|
|
359
|
+
let out = new Uint8Array(1 + list.length * 2);
|
|
360
|
+
out[0] = list.length * 2;
|
|
361
|
+
for (let i = 0; i < list.length; i++) w_u16(out, 1 + i * 2, list[i]);
|
|
362
|
+
return out;
|
|
363
|
+
};
|
|
364
|
+
exts.COMPRESS_CERTIFICATE.decode = function (data) {
|
|
365
|
+
if (data.length < 1) throw parseError('compress_certificate: empty');
|
|
366
|
+
let n = data[0];
|
|
367
|
+
if (n < 2 || n % 2 !== 0 || 1 + n !== data.length) throw parseError('compress_certificate: bad length');
|
|
368
|
+
let out = [];
|
|
369
|
+
for (let i = 1; i < 1 + n; i += 2) out.push((data[i] << 8) | data[i + 1]);
|
|
370
|
+
return out;
|
|
371
|
+
};
|
|
316
372
|
|
|
317
373
|
/* ---------------------- CERTIFICATE_AUTHORITIES (47) ---------------------- */
|
|
318
374
|
// RFC 8446 §4.2.4: DistinguishedName authorities<3..2^16-1> — the list is
|
|
@@ -527,6 +583,24 @@ exts.SUPPORTED_GROUPS.decode = function (data) {
|
|
|
527
583
|
return out; // array of named groups
|
|
528
584
|
};
|
|
529
585
|
|
|
586
|
+
/* ---------------------------- EC_POINT_FORMATS (11) ---------------------------- */
|
|
587
|
+
// RFC 8422 §5.1.2: ECPointFormat ec_point_format_list<1..2^8-1>, one byte per
|
|
588
|
+
// format. 0 is uncompressed — the only format TLS 1.2 still uses, and the one
|
|
589
|
+
// every list must contain.
|
|
590
|
+
exts.EC_POINT_FORMATS.encode = function (value) {
|
|
591
|
+
let formats = Array.isArray(value) && value.length > 0 ? value : [0];
|
|
592
|
+
return veclen(1, new Uint8Array(formats));
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
exts.EC_POINT_FORMATS.decode = function (data) {
|
|
596
|
+
let off = 0;
|
|
597
|
+
let list;
|
|
598
|
+
[list, off] = readVec(data, off, 1);
|
|
599
|
+
if (off !== data.length) throw parseError('trailing data after ec_point_formats');
|
|
600
|
+
if (list.length === 0) throw parseError('empty ec_point_formats list');
|
|
601
|
+
return Array.from(list); // array of point formats
|
|
602
|
+
};
|
|
603
|
+
|
|
530
604
|
/* -------------------------- SIGNATURE_ALGORITHMS (13) -------------------------- */
|
|
531
605
|
exts.SIGNATURE_ALGORITHMS.encode = function (value) {
|
|
532
606
|
// A codec encodes what it is handed; the set of signature schemes is policy
|
|
@@ -723,7 +797,16 @@ exts.KEY_SHARE.encode = function (value) {
|
|
|
723
797
|
return veclen(2, concatUint8Arrays(parts));
|
|
724
798
|
};
|
|
725
799
|
|
|
726
|
-
|
|
800
|
+
// `kind` — the message the extension is in ('client_hello', 'server_hello';
|
|
801
|
+
// parse_hello passes it) — decides the form; the three forms cannot be told
|
|
802
|
+
// apart by length. An empty client_shares, which RFC 8446 §4.2.8 allows ("in
|
|
803
|
+
// order to request group selection from the server, at the cost of an
|
|
804
|
+
// additional round trip"), is two bytes [00 00]: read as a HelloRetryRequest's
|
|
805
|
+
// NamedGroup it became a share for group 0x0000, refused illegal_parameter
|
|
806
|
+
// (not in supported_groups) — where the client asked for a HelloRetryRequest.
|
|
807
|
+
// Scanners enumerate a server's groups exactly so; every probe failed.
|
|
808
|
+
exts.KEY_SHARE.decode = function (data, kind) {
|
|
809
|
+
if (kind === 'client_hello') return decode_client_shares(data);
|
|
727
810
|
// HelloRetryRequest form: just NamedGroup (2 bytes, no key_exchange)
|
|
728
811
|
if (data.length === 2) {
|
|
729
812
|
let g, off = 0;
|
|
@@ -747,12 +830,17 @@ exts.KEY_SHARE.decode = function (data) {
|
|
|
747
830
|
}
|
|
748
831
|
}
|
|
749
832
|
|
|
750
|
-
|
|
833
|
+
return decode_client_shares(data);
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
// ClientHello form: vector<2> of KeyShareEntry, exactly filling the extension.
|
|
837
|
+
function decode_client_shares(data) {
|
|
751
838
|
let off2 = 0;
|
|
752
839
|
let listBytes;
|
|
753
840
|
[listBytes, off2] = r_u16(data, off2);
|
|
754
841
|
|
|
755
842
|
let end = off2 + listBytes;
|
|
843
|
+
if (end !== data.length) throw parseError('key_share: client_shares length does not match the extension');
|
|
756
844
|
let out = [];
|
|
757
845
|
|
|
758
846
|
while (off2 < end) {
|
|
@@ -767,9 +855,10 @@ exts.KEY_SHARE.decode = function (data) {
|
|
|
767
855
|
|
|
768
856
|
out.push({ group: g2, key_exchange: ke2 });
|
|
769
857
|
}
|
|
858
|
+
if (off2 !== end) throw parseError('key_share: an entry overruns client_shares');
|
|
770
859
|
|
|
771
860
|
return out; // array of entries
|
|
772
|
-
}
|
|
861
|
+
}
|
|
773
862
|
|
|
774
863
|
/* ------------------------------------ ALPN (16) ----------------------------------- */
|
|
775
864
|
exts.ALPN.encode = function (value) {
|
|
@@ -949,7 +1038,7 @@ function build_extensions(list) {
|
|
|
949
1038
|
* CertificateRequest) → use parse_extension_list().
|
|
950
1039
|
* Both share this core so the duplicate/overflow rules apply identically.
|
|
951
1040
|
*/
|
|
952
|
-
function parse_extension_list(buf) {
|
|
1041
|
+
function parse_extension_list(buf, kind) {
|
|
953
1042
|
let off = 0;
|
|
954
1043
|
let out = [];
|
|
955
1044
|
let seen = {}; // RFC 8446 §4.2: "There MUST NOT be more than one extension of the same type"
|
|
@@ -986,7 +1075,7 @@ function parse_extension_list(buf) {
|
|
|
986
1075
|
|
|
987
1076
|
let name = ext_name_by_code(t);
|
|
988
1077
|
let dec = exts[name] && exts[name].decode;
|
|
989
|
-
let val = dec ? dec(d) : null;
|
|
1078
|
+
let val = dec ? dec(d, kind) : null;
|
|
990
1079
|
|
|
991
1080
|
out.push({ type: t, name: name, data: d, value: val });
|
|
992
1081
|
}
|
|
@@ -998,7 +1087,7 @@ function parse_extension_list(buf) {
|
|
|
998
1087
|
* Parse a length-prefixed extensions vector that ENDS the enclosing structure.
|
|
999
1088
|
* `buf` must START with the 2-byte vector length and contain nothing after it.
|
|
1000
1089
|
*/
|
|
1001
|
-
function parse_extensions(buf) {
|
|
1090
|
+
function parse_extensions(buf, kind) {
|
|
1002
1091
|
let off = 0;
|
|
1003
1092
|
let n;
|
|
1004
1093
|
[n, off] = r_u16(buf, off);
|
|
@@ -1010,7 +1099,7 @@ function parse_extensions(buf) {
|
|
|
1010
1099
|
if (end > buf.length) throw parseError('extensions vector length exceeds body');
|
|
1011
1100
|
if (end < buf.length) throw parseError('trailing data after extensions vector');
|
|
1012
1101
|
|
|
1013
|
-
return parse_extension_list(buf.subarray(off, end));
|
|
1102
|
+
return parse_extension_list(buf.subarray(off, end), kind);
|
|
1014
1103
|
}
|
|
1015
1104
|
|
|
1016
1105
|
|
|
@@ -1158,7 +1247,7 @@ function parse_hello(params) {
|
|
|
1158
1247
|
let extensions = [];
|
|
1159
1248
|
if (body.length > off) {
|
|
1160
1249
|
let extRaw = body.subarray(off);
|
|
1161
|
-
extensions = parse_extensions(extRaw);
|
|
1250
|
+
extensions = parse_extensions(extRaw, type);
|
|
1162
1251
|
}
|
|
1163
1252
|
|
|
1164
1253
|
// --- version תמיד ערך יחיד ---
|
|
@@ -1262,6 +1351,51 @@ function build_certificate(params) {
|
|
|
1262
1351
|
}
|
|
1263
1352
|
}
|
|
1264
1353
|
|
|
1354
|
+
/* ------------------------ CompressedCertificate ------------------------ */
|
|
1355
|
+
// RFC 8879 §4: algorithm (u16), uncompressed_length (u24),
|
|
1356
|
+
// compressed_certificate_message<1..2^24-1> (u24-prefixed).
|
|
1357
|
+
/**
|
|
1358
|
+
* CertificateStatus (RFC 6066 §8): status_type ocsp(1), then the DER OCSP
|
|
1359
|
+
* response as an opaque<1..2^24-1>. The body of the TLS 1.2 handshake
|
|
1360
|
+
* message, and of the status_request extension in a TLS 1.3 CertificateEntry.
|
|
1361
|
+
*/
|
|
1362
|
+
function build_certificate_status(response) {
|
|
1363
|
+
let r = toU8(response);
|
|
1364
|
+
let out = new Uint8Array(4 + r.length);
|
|
1365
|
+
out[0] = 1;
|
|
1366
|
+
out[1] = (r.length >>> 16) & 0xff; out[2] = (r.length >>> 8) & 0xff; out[3] = r.length & 0xff;
|
|
1367
|
+
out.set(r, 4);
|
|
1368
|
+
return out;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
/** CertificateStatus → { status_type, response }; decode_error on a bad length. */
|
|
1372
|
+
function parse_certificate_status(body) {
|
|
1373
|
+
if (body.length < 4) throw parseError('CertificateStatus: too short');
|
|
1374
|
+
let len = (body[1] << 16) | (body[2] << 8) | body[3];
|
|
1375
|
+
if (len === 0 || 4 + len !== body.length) throw parseError('CertificateStatus: bad length');
|
|
1376
|
+
return { status_type: body[0], response: body.slice(4) };
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
function build_compressed_certificate(params) {
|
|
1380
|
+
let data = params.compressed;
|
|
1381
|
+
let out = new Uint8Array(2 + 3 + 3 + data.length);
|
|
1382
|
+
let o = 0;
|
|
1383
|
+
o = w_u16(out, o, params.algorithm);
|
|
1384
|
+
out[o++] = (params.uncompressed_length >>> 16) & 0xff; out[o++] = (params.uncompressed_length >>> 8) & 0xff; out[o++] = params.uncompressed_length & 0xff;
|
|
1385
|
+
out[o++] = (data.length >>> 16) & 0xff; out[o++] = (data.length >>> 8) & 0xff; out[o++] = data.length & 0xff;
|
|
1386
|
+
out.set(data, o);
|
|
1387
|
+
return out;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
function parse_compressed_certificate(body) {
|
|
1391
|
+
if (body.length < 8) throw parseError('CompressedCertificate: truncated');
|
|
1392
|
+
let algorithm = (body[0] << 8) | body[1];
|
|
1393
|
+
let uncompressed_length = (body[2] << 16) | (body[3] << 8) | body[4];
|
|
1394
|
+
let n = (body[5] << 16) | (body[6] << 8) | body[7];
|
|
1395
|
+
if (n < 1 || 8 + n !== body.length) throw parseError('CompressedCertificate: bad length');
|
|
1396
|
+
return { algorithm: algorithm, uncompressed_length: uncompressed_length, compressed: body.subarray(8) };
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1265
1399
|
function parse_certificate(body) {
|
|
1266
1400
|
// always returns:
|
|
1267
1401
|
// {
|
|
@@ -1932,6 +2066,7 @@ function parse_hello_verify_request(body) {
|
|
|
1932
2066
|
|
|
1933
2067
|
/* ================================ Exports ================================= */
|
|
1934
2068
|
export {
|
|
2069
|
+
HANDSHAKE_MESSAGE_MAX,
|
|
1935
2070
|
TLS_VERSION,
|
|
1936
2071
|
DTLS_VERSION,
|
|
1937
2072
|
is_tls13_wire,
|
|
@@ -1967,6 +2102,10 @@ export {
|
|
|
1967
2102
|
|
|
1968
2103
|
build_certificate,
|
|
1969
2104
|
parse_certificate,
|
|
2105
|
+
build_compressed_certificate,
|
|
2106
|
+
parse_compressed_certificate,
|
|
2107
|
+
build_certificate_status,
|
|
2108
|
+
parse_certificate_status,
|
|
1970
2109
|
|
|
1971
2110
|
build_certificate_verify,
|
|
1972
2111
|
parse_certificate_verify,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// lemon-tls/crypto — Key schedule primitives: HKDF, the TLS 1.3 secrets, exporters, cipher-suite tables.
|
|
2
|
+
// Low-level: typed loosely; see the source for each signature.
|
|
3
|
+
|
|
4
|
+
export declare const DEFAULT_CIPHER_SUITES_TLS12: any;
|
|
5
|
+
export declare const DEFAULT_CIPHER_SUITES_TLS13: any;
|
|
6
|
+
export declare const LABEL_PREFIX_DTLS13: string;
|
|
7
|
+
export declare const LABEL_PREFIX_TLS13: string;
|
|
8
|
+
export declare const TLS_CIPHER_SUITES: any;
|
|
9
|
+
export declare function build_cert_verify_tbs(...args: any[]): any;
|
|
10
|
+
export declare function build_cert_verify_tbs_with_hash(...args: any[]): any;
|
|
11
|
+
export declare function build_hkdf_label(...args: any[]): any;
|
|
12
|
+
export declare function compute_psk_binder(...args: any[]): any;
|
|
13
|
+
export declare function default_cipher_suites(...args: any[]): any;
|
|
14
|
+
export declare function derive_app_traffic_secrets(...args: any[]): any;
|
|
15
|
+
export declare function derive_app_traffic_secrets_with_hash(...args: any[]): any;
|
|
16
|
+
export declare function derive_binder_key(...args: any[]): any;
|
|
17
|
+
export declare function derive_client_early_traffic_secret(...args: any[]): any;
|
|
18
|
+
export declare function derive_exporter_master_secret_with_hash(...args: any[]): any;
|
|
19
|
+
export declare function derive_handshake_traffic_secrets(...args: any[]): any;
|
|
20
|
+
export declare function derive_handshake_traffic_secrets_psk(...args: any[]): any;
|
|
21
|
+
export declare function derive_handshake_traffic_secrets_psk_with_hash(...args: any[]): any;
|
|
22
|
+
export declare function derive_handshake_traffic_secrets_with_hash(...args: any[]): any;
|
|
23
|
+
export declare function derive_psk(...args: any[]): any;
|
|
24
|
+
export declare function derive_resumption_master_secret(...args: any[]): any;
|
|
25
|
+
export declare function derive_resumption_master_secret_with_hash(...args: any[]): any;
|
|
26
|
+
export declare function derive_sn_key(...args: any[]): any;
|
|
27
|
+
export declare function getHashFn(...args: any[]): any;
|
|
28
|
+
export declare function getHashLen(...args: any[]): any;
|
|
29
|
+
export declare function get_handshake_finished(...args: any[]): any;
|
|
30
|
+
export declare function get_handshake_finished_with_hash(...args: any[]): any;
|
|
31
|
+
export declare function hkdf_expand(...args: any[]): any;
|
|
32
|
+
export declare function hkdf_expand_label(...args: any[]): any;
|
|
33
|
+
export declare function hkdf_extract(...args: any[]): any;
|
|
34
|
+
export declare function hmac(...args: any[]): any;
|
|
35
|
+
export declare function is_usable_cipher_suite(...args: any[]): any;
|
|
36
|
+
export declare function suite_matches_version(...args: any[]): any;
|
|
37
|
+
export declare function tls12_exporter(...args: any[]): any;
|
|
38
|
+
export declare function tls12_prf(...args: any[]): any;
|
|
39
|
+
export declare function tls13_exporter(...args: any[]): any;
|
|
40
|
+
export declare function tls_derive_from_master_secret_tls12(...args: any[]): any;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// lemon-tls/record — The record layer: AEAD keys and nonces, encrypt/decrypt for TLS and DTLS records.
|
|
2
|
+
// Low-level: typed loosely; see the source for each signature.
|
|
3
|
+
|
|
4
|
+
export declare const CT: any;
|
|
5
|
+
export declare function aesEcbEncrypt(...args: any[]): any;
|
|
6
|
+
export declare function buildAad12(...args: any[]): any;
|
|
7
|
+
export declare function buildDtlsAad12(...args: any[]): any;
|
|
8
|
+
export declare function buildDtlsAck(...args: any[]): any;
|
|
9
|
+
export declare function buildDtlsPlaintext(...args: any[]): any;
|
|
10
|
+
export declare function buildEncryptedDtls12(...args: any[]): any;
|
|
11
|
+
export declare function buildEncryptedDtls13(...args: any[]): any;
|
|
12
|
+
export declare function buildUnifiedHdr(...args: any[]): any;
|
|
13
|
+
export declare function decrypt12(...args: any[]): any;
|
|
14
|
+
export declare function decryptDtls12(...args: any[]): any;
|
|
15
|
+
export declare function decryptEncryptedDtls13(...args: any[]): any;
|
|
16
|
+
export declare function decryptRecord(...args: any[]): any;
|
|
17
|
+
export declare function decryptRecordWithAadView(...args: any[]): any;
|
|
18
|
+
export declare function deriveKeys(...args: any[]): any;
|
|
19
|
+
export declare function deriveKeys12(...args: any[]): any;
|
|
20
|
+
export declare function encrypt12(...args: any[]): any;
|
|
21
|
+
export declare function encryptCompleteRecord12(...args: any[]): any;
|
|
22
|
+
export declare function encryptCompleteRecord13(...args: any[]): any;
|
|
23
|
+
export declare function encryptDtls12(...args: any[]): any;
|
|
24
|
+
export declare function encryptRecord(...args: any[]): any;
|
|
25
|
+
export declare function getAeadAlgo(...args: any[]): any;
|
|
26
|
+
export declare function getChachaNonce12(...args: any[]): any;
|
|
27
|
+
export declare function getNonce(...args: any[]): any;
|
|
28
|
+
export declare function getNonce12(...args: any[]): any;
|
|
29
|
+
export declare function getNonceInto(...args: any[]): any;
|
|
30
|
+
export declare function isUnifiedHdr(...args: any[]): any;
|
|
31
|
+
export declare function maskRecordNumber(...args: any[]): any;
|
|
32
|
+
export declare function parseDtlsAck(...args: any[]): any;
|
|
33
|
+
export declare function parseDtlsDatagram(...args: any[]): any;
|
|
34
|
+
export declare function parseDtlsPlaintext(...args: any[]): any;
|
|
35
|
+
export declare function parseInnerPlaintext(...args: any[]): any;
|
|
36
|
+
export declare function parseUnifiedHdr(...args: any[]): any;
|
|
37
|
+
export declare function reconstructDtlsSeq(...args: any[]): any;
|
|
38
|
+
export declare function resolveReadEpoch(...args: any[]): any;
|
|
39
|
+
export declare function seqToBytes(...args: any[]): any;
|
|
40
|
+
export declare function writeRecord(...args: any[]): any;
|
package/types/wire.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// lemon-tls/wire — TLS and DTLS messages: parse_* and build_* for each handshake message, and the codes (TLS_EXT, TLS_ALERT, …).
|
|
2
|
+
// Low-level: typed loosely; see the source for each signature.
|
|
3
|
+
|
|
4
|
+
export declare const DTLS_VERSION: any;
|
|
5
|
+
export declare const HANDSHAKE_MESSAGE_MAX: number;
|
|
6
|
+
export declare const TLS13_HRR_RANDOM: any;
|
|
7
|
+
export declare const TLS_ALERT: any;
|
|
8
|
+
export declare const TLS_ALERT_LEVEL: any;
|
|
9
|
+
export declare const TLS_CONTENT_TYPE: any;
|
|
10
|
+
export declare const TLS_EXT: any;
|
|
11
|
+
export declare const TLS_MESSAGE_TYPE: any;
|
|
12
|
+
export declare const TLS_VERSION: any;
|
|
13
|
+
export declare function build_certificate(...args: any[]): any;
|
|
14
|
+
export declare function build_certificate_request(...args: any[]): any;
|
|
15
|
+
export declare function build_certificate_status(...args: any[]): any;
|
|
16
|
+
export declare function build_certificate_verify(...args: any[]): any;
|
|
17
|
+
export declare function build_client_key_exchange_ecdhe(...args: any[]): any;
|
|
18
|
+
export declare function build_client_key_exchange_rsa(...args: any[]): any;
|
|
19
|
+
export declare function build_compressed_certificate(...args: any[]): any;
|
|
20
|
+
export declare function build_dtls_handshake(...args: any[]): any;
|
|
21
|
+
export declare function build_extensions(...args: any[]): any;
|
|
22
|
+
export declare function build_hello(...args: any[]): any;
|
|
23
|
+
export declare function build_hello_retry_request(...args: any[]): any;
|
|
24
|
+
export declare function build_hello_verify_request(...args: any[]): any;
|
|
25
|
+
export declare function build_key_update(...args: any[]): any;
|
|
26
|
+
export declare function build_message(...args: any[]): any;
|
|
27
|
+
export declare function build_new_session_ticket(...args: any[]): any;
|
|
28
|
+
export declare function build_new_session_ticket_tls12(...args: any[]): any;
|
|
29
|
+
export declare function build_server_ecdh_params(...args: any[]): any;
|
|
30
|
+
export declare function build_server_key_exchange_ecdhe(...args: any[]): any;
|
|
31
|
+
export declare const exts: any;
|
|
32
|
+
export declare function is_tls12_wire(...args: any[]): any;
|
|
33
|
+
export declare function is_tls13_wire(...args: any[]): any;
|
|
34
|
+
export declare function parse_certificate(...args: any[]): any;
|
|
35
|
+
export declare function parse_certificate_request(...args: any[]): any;
|
|
36
|
+
export declare function parse_certificate_status(...args: any[]): any;
|
|
37
|
+
export declare function parse_certificate_verify(...args: any[]): any;
|
|
38
|
+
export declare function parse_client_key_exchange_ecdhe(...args: any[]): any;
|
|
39
|
+
export declare function parse_client_key_exchange_rsa(...args: any[]): any;
|
|
40
|
+
export declare function parse_compressed_certificate(...args: any[]): any;
|
|
41
|
+
export declare function parse_dtls_handshake(...args: any[]): any;
|
|
42
|
+
export declare function parse_extension_list(...args: any[]): any;
|
|
43
|
+
export declare function parse_extensions(...args: any[]): any;
|
|
44
|
+
export declare function parse_hello(...args: any[]): any;
|
|
45
|
+
export declare function parse_hello_verify_request(...args: any[]): any;
|
|
46
|
+
export declare function parse_key_update(...args: any[]): any;
|
|
47
|
+
export declare function parse_message(...args: any[]): any;
|
|
48
|
+
export declare function parse_new_session_ticket(...args: any[]): any;
|
|
49
|
+
export declare function parse_new_session_ticket_tls12(...args: any[]): any;
|
|
50
|
+
export declare function parse_server_key_exchange(...args: any[]): any;
|
|
51
|
+
export declare function r_bytes(...args: any[]): any;
|
|
52
|
+
export declare function r_u16(...args: any[]): any;
|
|
53
|
+
export declare function r_u24(...args: any[]): any;
|
|
54
|
+
export declare function r_u8(...args: any[]): any;
|
|
55
|
+
export declare function readVec(...args: any[]): any;
|
|
56
|
+
export declare function veclen(...args: any[]): any;
|
|
57
|
+
export declare function w_bytes(...args: any[]): any;
|
|
58
|
+
export declare function w_u16(...args: any[]): any;
|
|
59
|
+
export declare function w_u24(...args: any[]): any;
|
|
60
|
+
export declare function w_u48(...args: any[]): any;
|
|
61
|
+
export declare function w_u64(...args: any[]): any;
|
|
62
|
+
export declare function w_u8(...args: any[]): any;
|