Skip to content

Commit d4b0faa

Browse files
committed
reformat
1 parent fdc0d23 commit d4b0faa

File tree

11 files changed

+348
-352
lines changed

11 files changed

+348
-352
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
/.vscode
1+
/.vscode
2+
/play

deno.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tls/keyexchange",
3-
"version": "0.2.5",
3+
"version": "0.2.6",
44
"exports": "./src/mod.ts",
55
"publish": {
66
"exclude": ["dist/"]
@@ -18,6 +18,6 @@
1818
"@tls/extension": "jsr:@tls/extension@^0.3.0",
1919
"@tls/handshake": "jsr:@tls/handshake@^0.0.5",
2020
"@tls/record": "jsr:@tls/record@^0.1.3",
21-
"@tls/struct": "jsr:@tls/struct@^0.3.7"
21+
"@tls/struct": "jsr:@tls/struct@^0.3.8"
2222
}
2323
}

deno.lock

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/clienthello.js

Lines changed: 104 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,131 @@
11
//@ts-self-types = "../type/clienthello.d.ts"
2-
import {
3-
Uint8, Uint16, Uint24, Version, Constrained, Cipher, Struct,
4-
Extension, ExtensionType,
5-
NamedGroupList, NamedGroup, RecordSizeLimit,
6-
KeyShareClientHello, SupportedVersions, ServerNameList, PskKeyExchangeModes,
7-
Cookie, Supported_signature_algorithms,
8-
HandshakeType,
9-
OfferedPsks,
10-
EarlyDataIndication,
11-
Padding,
12-
safeuint8array,
13-
Handshake,
14-
} from "./dep.ts"
2+
import { Cipher, Constrained, ContentType, Cookie, EarlyDataIndication, Extension, ExtensionType, HandshakeType, KeyShareClientHello, NamedGroupList, OfferedPsks, Padding, parseItems, PskKeyExchangeModes, RecordSizeLimit, safeuint8array, ServerNameList, Supported_signature_algorithms, SupportedVersions, Uint16, Uint24, Version } from "./dep.ts";
153

16-
export class ClientHello extends Struct {
17-
legacy_version;
18-
random; // offset 2, length 32
19-
legacy_session;// offset = 32, length = 1;
20-
cipher_suites; // offset = 33;
21-
legacy_compression_methods; // offset = 33 + cipher_suites.length
22-
extensions;
23-
ext = new Map;
24-
static fromHandShake(handshake) {
25-
const copy = Uint8Array.from(handshake);
26-
let offset = 0;
27-
const _type = HandshakeType.from(copy); offset += 1;
28-
const lengthOf = Uint24.from(copy.subarray(offset)).value; offset += 3;
29-
return ClientHello.from(copy.subarray(offset, offset + lengthOf));
4+
export class ClientHello extends Uint8Array {
5+
#version
6+
#random
7+
#legacy_session_id
8+
#ciphers
9+
#legacy_compression_methods
10+
#extensions
11+
static create(...args){
12+
return new ClientHello(...args)
3013
}
31-
static fromHandshake = ClientHello.fromHandShake
32-
static from(array) {
33-
const copy = Uint8Array.from(array);
34-
let offset = 0
35-
const legacy_version = Version.from(copy.subarray(offset)); offset += 2;
36-
const random = copy.subarray(offset, offset + 32); offset += 32;
37-
const legacy_session = Legacy_session_id.from(copy.subarray(offset)); offset += legacy_session.length;
38-
const cipher_suites = Cipher_suites.from(copy.subarray(offset)); offset += cipher_suites.length;
39-
const _legacy_compression_methods = Legacy_compression_methods.from(copy.subarray(offset)); offset += _legacy_compression_methods.length;
40-
const extensions = Extensions.from(copy.subarray(offset));
41-
return new ClientHello(legacy_version, random, legacy_session, cipher_suites, ...extensions.extensions)
14+
static from = ClientHello.create
15+
constructor(...args) {
16+
args = (args.at(0) instanceof Uint8Array)? sanitize(...args): args
17+
super(...args)
4218
}
43-
constructor(
44-
legacy_version = Version.legacy.protocolVersion(),
45-
random = crypto.getRandomValues(new Uint8Array(32)),
46-
legacy_session = new Legacy_session_id,
47-
cipher_suites = new Cipher_suites(Cipher.AES_128_GCM_SHA256, Cipher.AES_256_GCM_SHA384),
48-
...extensions
49-
) {
50-
51-
const legacy_compression_methods = new Legacy_compression_methods;
52-
53-
super(
54-
legacy_version instanceof Uint8Array ? legacy_version : legacy_version.Uint16,
55-
random,
56-
legacy_session,
57-
cipher_suites,
58-
legacy_compression_methods,
59-
Extensions.fromExtension(...extensions)
60-
)
61-
this.legacy_version = legacy_version;
62-
this.random = random;
63-
this.legacy_session = legacy_session;
64-
this.cipher_suites = cipher_suites;
65-
this.legacy_compression_methods = legacy_compression_methods
66-
let offset = legacy_version.length + random.length + legacy_session.length
67-
+ cipher_suites.length + legacy_compression_methods.length;
68-
this.extensions = extensions;
69-
for (const ex of extensions) {
70-
this.ext.set(ex.extension_type?.name, { pos: offset + 2, data: ex.extension_data });
71-
offset += ex.length;
19+
get version() {
20+
this.#version ||= Version.from(this.subarray(0, 2))
21+
return this.#version
22+
}
23+
get random() {
24+
this.#random ||= this.subarray(2, 34);
25+
return this.#random;
26+
}
27+
get legacy_session_id() {
28+
if (this.#legacy_session_id) return this.#legacy_session_id
29+
const lengthOf = this.at(34);
30+
if (lengthOf == 0) {
31+
this.#legacy_session_id = this.subarray(34, 35);
32+
} else {
33+
this.#legacy_session_id = this.subarray(35, 35 + lengthOf)
7234
}
35+
return this.#legacy_session_id
7336
}
74-
static fromServerName(serverName) {
75-
return new ClientHello(undefined, undefined, undefined, undefined,
76-
Uint8Array.of(
77-
0, 10, 0, 12, 0, 10, 0, 29, 0, 23, 0, 24, 0, 30, 0, 25, // ExtensionType.SUPPORTED_GROUPS.extension(NamedGroupList.default());
78-
0, 13, 0, 18, 0, 16, 8, 6, 8, 5, 8, 4, 8, 7, 8, 8, 6, 3, 5, 3, 4, 3, // ExtensionType.SIGNATURE_ALGORITHMS.extension(Supported_signature_algorithms.default());
79-
0, 43, 0, 3, 2, 3, 4, // ExtensionType.SUPPORTED_VERSIONS.extension(SupportedVersions.forClient_hello())
80-
0, 45, 0, 2, 1, 1 // ExtensionType.PSK_KEY_EXCHANGE_MODES.extension(PskKeyExchangeModes.default())
81-
),
82-
ExtensionType.SERVER_NAME.extension(ServerNameList.fromName(serverName)),
83-
ExtensionType.KEY_SHARE.extension(KeyShareClientHello.fromKeyShareEntries(
84-
NamedGroup.X25519.keyShareEntry(),
85-
NamedGroup.SECP256R1.keyShareEntry()
86-
))
87-
)
37+
get ciphers() {
38+
this.#ciphers ||= Cipher_suites.from(this.subarray(35 + this.at(34)));
39+
return this.#ciphers;
40+
}
41+
/**
42+
* For every TLS 1.3 ClientHello, this vector
43+
MUST contain exactly one byte, set to zero, which corresponds to
44+
the "null" compression method in prior versions of TLS. If a
45+
TLS 1.3 ClientHello is received with any other value in this
46+
field, the server MUST abort the handshake with an
47+
"illegal_parameter" alert.
48+
*/
49+
get legacy_compression_methods() {
50+
if (this.#legacy_compression_methods) return this.#legacy_compression_methods
51+
const offset = 34 + this.legacy_session_id.length + this.ciphers.length;
52+
this.#legacy_compression_methods ||= this.subarray(offset, offset + 2);
53+
return this.#legacy_compression_methods
54+
}
55+
get extensions() {
56+
if (this.#extensions) return this.#extensions;
57+
const copy = this.subarray(34 + this.legacy_session_id.length + this.ciphers.length + 2)
58+
const lengthOf = Uint16.from(copy).value;
59+
if (lengthOf < 8) throw TypeError(`Length min. 8 bytes`)
60+
if (lengthOf > 2 ** 16 - 2) throw TypeError(`Length max: ${2 ** 16 - 2}`)
61+
const output = new Map;
62+
let offset = 2;
63+
while (true) {
64+
const extension = Extension.from(copy.subarray(offset)); offset += extension.length
65+
parseExtension(extension);
66+
extension.extension_data.pos = offset + 2;
67+
output.set(extension.extension_type, extension.extension_data)
68+
if (offset >= lengthOf) break;
69+
if (offset >= copy.length) break;
70+
}
71+
this.#extensions ||= output;
72+
return this.#extensions;
8873
}
89-
90-
get handshake() { return new Handshake(HandshakeType.CLIENT_HELLO, this) }
91-
get record() { return this.handshake.record }
92-
9374
addBinders(binders) {
94-
const psk = this.ext.get('PRE_SHARED_KEY');
95-
const lengthOf = psk.data.length + binders.length;
75+
const psk = this.extensions.get(ExtensionType.PRE_SHARED_KEY);
76+
const lengthOf = psk.length + binders.length;
9677
const uint16 = Uint16.fromValue(lengthOf)
9778
const array = safeuint8array(this, binders);
9879
array.set(uint16, psk.pos + 2);
99-
return ClientHello.from(array)
80+
return new ClientHello(array)
10081
}
10182
binderPos() {
102-
const psk = this.ext.get('PRE_SHARED_KEY');
103-
return psk.pos + 4 + psk.data.identities.length
83+
const psk = this.extensions.get(ExtensionType.PRE_SHARED_KEY);
84+
return psk.pos + 4 + psk.identities.length
10485
}
10586
}
10687

107-
export class Cipher_suites extends Constrained {
108-
static from(array) {
109-
const copy = Uint8Array.from(array);
110-
const lengthOf = Uint16.from(copy).value;
111-
const ciphers = [];
112-
for (let offset = 2; offset < lengthOf + 2; offset += 2) {
113-
const cipher = Cipher.from(copy.subarray(offset));
114-
ciphers.push(cipher)
88+
function sanitize(...args) {
89+
try {
90+
if(Version.from(...args) instanceof Version) return args
91+
throw Error
92+
} catch (_error) {
93+
try {
94+
if(HandshakeType.from(args[0]) == HandshakeType.CLIENT_HELLO){
95+
const lengthOf = Uint24.from(args[0].subarray(1)).value;
96+
return [args[0].subarray(4, 4 + lengthOf)]
97+
}
98+
throw Error
99+
} catch (_error) {
100+
try {
101+
const contentType = ContentType.from(args[0]);
102+
const handshakeType = HandshakeType.from(args[0].subarray(5));
103+
const lengthOf = Uint24.from(args[0].subarray(6)).value;
104+
const conditions = [
105+
contentType == ContentType.HANDSHAKE,
106+
handshakeType == HandshakeType.CLIENT_HELLO
107+
]
108+
if(conditions.every(e=>e==true))return [args[0].subarray(9, 9 + lengthOf)]
109+
throw Error;
110+
} catch (error) {
111+
throw error;
112+
}
115113
}
116-
return new Cipher_suites(...ciphers)
117-
}
118-
constructor(...ciphers) {
119-
super(2, 2 ** 16 - 2, ...ciphers.map(e => e.Uint16))
120-
this.ciphers = new Set(ciphers);
121114
}
122115
}
123116

124-
class Extensions extends Constrained {
125-
static fromExtension(...extensions) { return new Extensions(...extensions) }
117+
//const test_0 = new ClientHello(HandshakeType.CLIENT_HELLO.Uint8)
118+
119+
export class Cipher_suites extends Constrained {
126120
static from(array) {
127121
const copy = Uint8Array.from(array);
128122
const lengthOf = Uint16.from(copy).value;
129-
const extensions = [];
130-
let offset = 2;
131-
//for (let offset = 2; offset < lengthOf + 2;) {
132-
while (true) {
133-
const extension = Extension.from(copy.subarray(offset)); offset += extension.length
134-
parseExtension(extension);
135-
extensions.push(extension)
136-
if (offset >= lengthOf) break;
137-
if (offset >= copy.length) break;
138-
}
139-
return new Extensions(...extensions)
123+
const ciphers = parseItems(copy, 2, lengthOf, Cipher);
124+
return new Cipher_suites(...ciphers)
140125
}
141-
constructor(...extensions) {
142-
super(8, 2 ** 16 - 1, ...extensions)
143-
this.extensions = extensions
126+
constructor(...ciphers) {
127+
super(2, 2 ** 16 - 2, ...ciphers.map(e => e.Uint16))
128+
this.ciphers = ciphers;
144129
}
145130
}
146131

@@ -185,28 +170,3 @@ function parseExtension(extension) {
185170
}
186171
}
187172

188-
class Legacy_session_id extends Constrained {
189-
static from(array) {
190-
const copy = Uint8Array.from(array);
191-
const lengthOf = Uint8.from(copy).value;
192-
if (lengthOf == 0) return new Legacy_session_id;
193-
return new Legacy_session_id(copy.subarray(1, 1 + lengthOf))
194-
}
195-
constructor(opaque = new Uint8Array) {
196-
super(0, 32, opaque)
197-
this.opaque = opaque
198-
}
199-
}
200-
201-
class Legacy_compression_methods extends Constrained {
202-
static from(array) {
203-
const copy = Uint8Array.from(array);
204-
const lengthOf = Uint8.from(copy).value;
205-
return new Legacy_compression_methods(copy.subarray(1, 1 + lengthOf))
206-
}
207-
constructor(opaque = Uint8Array.of(0)) {
208-
super(0, 2 ** 8 - 1, opaque)
209-
this.opaque = opaque
210-
}
211-
}
212-

src/dep.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
export * from "@tls/struct";
22
export * from "@tls/enum";
33
export * from "@tls/extension";
4-
export * from "@tls/handshake";
5-
export * from "@tls/record";

src/mod.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export { Cipher_suites, ClientHello } from "./clienthello.js";
2-
export { ServerHello } from "./serverhello.js";
1+
export * from "./clienthello.js";
2+
export * from "./serverhello.js";

0 commit comments

Comments
 (0)