Skip to content

Commit 4967253

Browse files
committed
version 0.0.5 to include alert
1 parent f106c0b commit 4967253

File tree

9 files changed

+536
-3
lines changed

9 files changed

+536
-3
lines changed

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tls/enum",
3-
"version": "0.0.4",
3+
"version": "0.0.5",
44
"exports": "./src/mod.ts",
55
"publish": {
66
"exclude": ["dist/"]

src/alert.js

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// deno-lint-ignore-file no-slow-types
2+
// @ts-self-types="../type/alert.d.ts"
3+
4+
import { Enum } from "./enum.js";
5+
6+
/**
7+
* Represents alert levels in the protocol
8+
* @see https://datatracker.ietf.org/doc/html/rfc8446#section-6
9+
*/
10+
export class AlertLevel extends Enum {
11+
12+
/** @type {AlertLevel} warning level (1) */
13+
static WARNING = new AlertLevel('WARNING', 1);
14+
15+
/** @type {AlertLevel} fatal level (2) */
16+
static FATAL = new AlertLevel('FATAL', 2);
17+
18+
/**
19+
* check octet and return valid AlertLevel
20+
*
21+
* @static
22+
* @param {Uint8Array} octet
23+
* @returns {AlertLevel }
24+
*/
25+
static parse(octet) {
26+
return AlertLevel.fromValue(octet[0]) ?? Error(`Unknown ${octet[0]} AlertLevel type`);
27+
}
28+
29+
/**return 8 */
30+
get bit() { return 8 }
31+
}
32+
33+
34+
/**
35+
* Enum class representing various TLS alert descriptions based on RFC 8446.
36+
* @see https://datatracker.ietf.org/doc/html/rfc8446#section-6
37+
*/
38+
export class AlertDescription extends Enum {
39+
/**
40+
* This alert notifies the recipient that the sender will not send any more messages on this connection. Any data received after a closure alert has been received MUST be ignored.
41+
*/
42+
static CLOSE_NOTIFY = new AlertDescription("CLOSE_NOTIFY", 0);
43+
44+
/**
45+
* An inappropriate message (e.g., the wrong handshake message, premature Application Data, etc.) was received. This alert should never be observed in communication between proper implementations.
46+
*/
47+
static UNEXPECTED_MESSAGE = new AlertDescription("UNEXPECTED_MESSAGE", 10);
48+
49+
/**
50+
* This alert is returned if a record is received which cannot be deprotected. Because AEAD algorithms combine decryption and verification, this alert is used for all deprotection failures.
51+
*/
52+
static BAD_RECORD_MAC = new AlertDescription("BAD_RECORD_MAC", 20);
53+
54+
/**
55+
* A TLSCiphertext record was received that had a length more than 2^14 + 256 bytes or a record decrypted to a TLSPlaintext record with more than 2^14 bytes.
56+
*/
57+
static RECORD_OVERFLOW = new AlertDescription("RECORD_OVERFLOW", 22);
58+
59+
/**
60+
* Receipt of a 'handshake_failure' alert message indicates that the sender was unable to negotiate an acceptable set of security parameters given the options available.
61+
*/
62+
static HANDSHAKE_FAILURE = new AlertDescription("HANDSHAKE_FAILURE", 40);
63+
64+
/**
65+
* A certificate was corrupt or contained signatures that did not verify correctly.
66+
*/
67+
static BAD_CERTIFICATE = new AlertDescription("BAD_CERTIFICATE", 42);
68+
69+
/**
70+
* A certificate was of an unsupported type.
71+
*/
72+
static UNSUPPORTED_CERTIFICATE = new AlertDescription("UNSUPPORTED_CERTIFICATE", 43);
73+
74+
/**
75+
* A certificate was revoked by its signer.
76+
*/
77+
static CERTIFICATE_REVOKED = new AlertDescription("CERTIFICATE_REVOKED", 44);
78+
79+
/**
80+
* A certificate has expired or is not currently valid.
81+
*/
82+
static CERTIFICATE_EXPIRED = new AlertDescription("CERTIFICATE_EXPIRED", 45);
83+
84+
/**
85+
* Some other issue arose in processing the certificate, rendering it unacceptable.
86+
*/
87+
static CERTIFICATE_UNKNOWN = new AlertDescription("CERTIFICATE_UNKNOWN", 46);
88+
89+
/**
90+
* A field in the handshake was incorrect or inconsistent with other fields.
91+
*/
92+
static ILLEGAL_PARAMETER = new AlertDescription("ILLEGAL_PARAMETER", 47);
93+
94+
/**
95+
* A valid certificate chain or partial chain was received, but the CA certificate could not be located or matched with a known trust anchor.
96+
*/
97+
static UNKNOWN_CA = new AlertDescription("UNKNOWN_CA", 48);
98+
99+
/**
100+
* A valid certificate or PSK was received, but access control was applied, and the sender decided not to proceed with negotiation.
101+
*/
102+
static ACCESS_DENIED = new AlertDescription("ACCESS_DENIED", 49);
103+
104+
/**
105+
* A message could not be decoded because some field was out of range or the length of the message was incorrect.
106+
*/
107+
static DECODE_ERROR = new AlertDescription("DECODE_ERROR", 50);
108+
109+
/**
110+
* A handshake cryptographic operation failed, including verification or validation issues.
111+
*/
112+
static DECRYPT_ERROR = new AlertDescription("DECRYPT_ERROR", 51);
113+
114+
/**
115+
* The protocol version the peer has attempted to negotiate is recognized but not supported.
116+
*/
117+
static PROTOCOL_VERSION = new AlertDescription("PROTOCOL_VERSION", 70);
118+
119+
/**
120+
* A negotiation has failed because the server requires parameters more secure than those supported by the client.
121+
*/
122+
static INSUFFICIENT_SECURITY = new AlertDescription("INSUFFICIENT_SECURITY", 71);
123+
124+
/**
125+
* An internal error unrelated to the peer or protocol correctness makes it impossible to continue.
126+
*/
127+
static INTERNAL_ERROR = new AlertDescription("INTERNAL_ERROR", 80);
128+
129+
/**
130+
* Sent by a server in response to an invalid
131+
connection retry attempt from a client (see [RFC7507]).
132+
*/
133+
static INAPPROPRIATE_FALLBACK = new AlertDescription("INAPPROPRIATE_FALLBACK", 86)
134+
135+
/**
136+
* This alert notifies the recipient that the sender is canceling the handshake for reasons unrelated to a protocol failure.
137+
*/
138+
static USER_CANCELED = new AlertDescription("USER_CANCELED", 90);
139+
140+
/**
141+
* Sent when a mandatory extension for the negotiated TLS version or other parameters is missing.
142+
*/
143+
static MISSING_EXTENSION = new AlertDescription("MISSING_EXTENSION", 109);
144+
145+
/**
146+
* Sent when an extension is included in a message where it is prohibited.
147+
*/
148+
static UNSUPPORTED_EXTENSION = new AlertDescription("UNSUPPORTED_EXTENSION", 110);
149+
150+
/**
151+
* Sent when no server exists identified by the client-provided 'server_name' extension.
152+
*/
153+
static UNRECOGNIZED_NAME = new AlertDescription("UNRECOGNIZED_NAME", 112);
154+
155+
156+
/**
157+
* Sent by clients when an invalid or
158+
unacceptable OCSP response is provided by the server via the
159+
"status_request" extension (see [RFC6066]).
160+
*/
161+
static BAD_CERTIFICATE_STATUS_RESPONSE = new AlertDescription("BAD_CERTIFICATE_STATUS_RESPONSE", 113)
162+
163+
/**
164+
* Sent when PSK key establishment is desired, but no acceptable PSK identity is provided by the client.
165+
*/
166+
static UNKNOWN_PSK_IDENTITY = new AlertDescription("UNKNOWN_PSK_IDENTITY", 115);
167+
168+
/**
169+
* Sent when a client certificate is required but none was provided.
170+
*/
171+
static CERTIFICATE_REQUIRED = new AlertDescription("CERTIFICATE_REQUIRED", 116);
172+
173+
/**
174+
* Sent when the client advertises only unsupported protocols in the 'application_layer_protocol_negotiation' extension.
175+
*/
176+
static NO_APPLICATION_PROTOCOL = new AlertDescription("NO_APPLICATION_PROTOCOL", 120);
177+
static DECRYPTION_FAILED_RESERVED = new AlertDescription("DECRYPTION_FAILED_RESERVED", 21)
178+
static DECOMPRESSION_FAILURE_RESERVED = new AlertDescription("DECOMPRESSION_FAILURE_RESERVED", 30)
179+
static NO_CERTIFICATE_RESERVED = new AlertDescription("NO_CERTIFICATE_RESERVED", 41)
180+
static EXPORT_RESTRICTION_RESERVED = new AlertDescription("EXPORT_RESTRICTION_RESERVED", 60)
181+
static NO_RENEGOTIATION_RESERVED = new AlertDescription("NO_RENEGOTIATION_RESERVED", 100)
182+
static CERTIFICATE_UNOBTAINABLE_RESERVED = new AlertDescription("CERTIFICATE_UNOBTAINABLE_RESERVED", 111)
183+
static BAD_CERTIFICATE_HASH_VALUE_RESERVED = new AlertDescription("BAD_CERTIFICATE_HASH_VALUE_RESERVED", 114)
184+
185+
/**
186+
* check octet and return valid AlertDescription
187+
*
188+
* @static
189+
* @param {Uint8Array} octet
190+
* @returns {AlertDescription }
191+
*/
192+
static parse(octet) {
193+
return AlertDescription.fromValue(octet[0]) ?? Error(`Unknown ${octet[0]} AlertDescription type`);
194+
}
195+
196+
/**return 8 */
197+
get bit() { return 8 }
198+
199+
get level() {
200+
const warning = [
201+
0, // CLOSE_NOTIFY
202+
90, // USER_CANCELED
203+
21, // DECRYPTION_FAILED_RESERVED
204+
41, // NO_CERTIFICATE_RESERVED
205+
60, // EXPORT_RESTRICTION_RESERVED
206+
30, // DECOMPRESSION_FAILURE_RESERVED
207+
100, // NO_RENEGOTIATION_RESERVED
208+
111, // CERTIFICATE_UNOBTAINABLE_RESERVED
209+
114 // BAD_CERTIFICATE_HASH_VALUE_RESERVED
210+
]
211+
if(warning.includes(this.value))return AlertLevel.WARNING
212+
return AlertLevel.FATAL
213+
}
214+
}
215+
216+
//npx -p typescript tsc ./src/alert.js --declaration --allowJs --emitDeclarationOnly --lib ESNext --outDir ./dist

src/contentype.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// deno-lint-ignore-file no-slow-types
2+
// @ts-self-types="../type/contentype.d.ts"
3+
4+
import { Enum } from "./enum.js";
5+
6+
7+
/**
8+
* The higher-level protocol used to process the enclosed
9+
fragment
10+
* @see https://datatracker.ietf.org/doc/html/rfc8446#section-5.1
11+
* @export
12+
* @extends {Enum}
13+
*/
14+
export class ContentType extends Enum {
15+
static INVALID = new ContentType('INVALID', 0);
16+
static CHANGE_CIPHER_SPEC = new ContentType('CHANGE_CIPHER_SPEC', 20);
17+
static ALERT = new ContentType('ALERT', 21);
18+
static HANDSHAKE = new ContentType('HANDSHAKE', 22);
19+
static APPLICATION_DATA = new ContentType('APPLICATION_DATA', 23);
20+
/**
21+
* check octet and return valid ContentType
22+
*
23+
* @static
24+
* @param {Uint8Array} octet
25+
* @returns {ContentType }
26+
*/
27+
static parse(octet) {
28+
return ContentType.fromValue(octet[0]) ?? Error(`Unknown ${octet[0]} ContentType type`);
29+
}
30+
31+
/**return 8 */
32+
get bit() { return 8 }
33+
}
34+
35+
//npx -p typescript tsc ./src/contentype.js --declaration --allowJs --emitDeclarationOnly --lib ESNext --outDir ./dist

src/keyupdate.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// deno-lint-ignore-file no-slow-types
2+
// @ts-self-types="../type/keyupdate.d.ts"
3+
4+
import { Enum } from "./enum.js";
5+
6+
/**
7+
* KeyUpdateRequest - @see https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3
8+
* Indicates whether the recipient of the KeyUpdate
9+
should respond with its own KeyUpdate. If an implementation
10+
receives any other value, it MUST terminate the connection with an
11+
"illegal_parameter" alert.
12+
*/
13+
export class KeyUpdateRequest extends Enum {
14+
static UPDATE_NOT_REQUESTED = new KeyUpdateRequest('UPDATE_NOT_REQUESTED', 0);
15+
static UPDATE_REQUESTED = new KeyUpdateRequest('UPDATE_REQUESTED', 1);
16+
/**
17+
* check octet and return valid KeyUpdateRequest
18+
*
19+
* @static
20+
* @param {Uint8Array} octet
21+
* @returns {KeyUpdateRequest }
22+
*/
23+
static parse(octet) {
24+
return KeyUpdateRequest.fromValue(octet[0]) ?? Error(`Unknown ${octet[0]} KeyUpdateRequest type`);
25+
}
26+
27+
/**return 8 */
28+
get bit() { return 8 }
29+
30+
}
31+
32+
// npx -p typescript tsc ./src/keyupdate.js --declaration --allowJs --emitDeclarationOnly --lib ESNext --outDir ./dist

src/pskmode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// deno-lint-ignore-file no-slow-types
2-
// @ts-self-types="../type/namedgroup.d.ts"
2+
// @ts-self-types="../type/pskmode.d.ts"
33

44
import { Enum } from "./enum.js";
55

66
/**
7-
* Supported groups - @see https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.7.
7+
* PskKeyExchangeMode - @see https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2
88
*/
99
export class PskKeyExchangeMode extends Enum {
1010
/**psk_ke: PSK-only key establishment. In this mode, the server

test/alert_test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { AlertDescription } from "../src/alert.js";
2+
import { assertEquals } from "jsr:@std/assert";
3+
4+
Deno.test(
5+
"AlertDescription",
6+
() => {
7+
const tls13AlertDescriptionValues = [
8+
0, // CLOSE_NOTIFY
9+
10, // UNEXPECTED_MESSAGE
10+
20, // BAD_RECORD_MAC
11+
21, // DECRYPTION_FAILED_RESERVED
12+
22, // RECORD_OVERFLOW
13+
30, // DECOMPRESSION_FAILURE_RESERVED
14+
40, // HANDSHAKE_FAILURE
15+
41, // NO_CERTIFICATE_RESERVED
16+
42, // BAD_CERTIFICATE
17+
43, // UNSUPPORTED_CERTIFICATE
18+
44, // CERTIFICATE_REVOKED
19+
45, // CERTIFICATE_EXPIRED
20+
46, // CERTIFICATE_UNKNOWN
21+
47, // ILLEGAL_PARAMETER
22+
48, // UNKNOWN_CA
23+
49, // ACCESS_DENIED
24+
50, // DECODE_ERROR
25+
51, // DECRYPT_ERROR
26+
60, // EXPORT_RESTRICTION_RESERVED
27+
70, // PROTOCOL_VERSION
28+
71, // INSUFFICIENT_SECURITY
29+
80, // INTERNAL_ERROR
30+
86, // INAPPROPRIATE_FALLBACK
31+
90, // USER_CANCELED
32+
100, // NO_RENEGOTIATION_RESERVED
33+
109, // MISSING_EXTENSION
34+
110, // UNSUPPORTED_EXTENSION
35+
111, // CERTIFICATE_UNOBTAINABLE_RESERVED
36+
112, // UNRECOGNIZED_NAME
37+
113, // BAD_CERTIFICATE_STATUS_RESPONSE
38+
114, // BAD_CERTIFICATE_HASH_VALUE_RESERVED
39+
115, // UNKNOWN_PSK_IDENTITY
40+
116, // CERTIFICATE_REQUIRED
41+
120 // NO_APPLICATION_PROTOCOL
42+
];
43+
44+
assertEquals(AlertDescription.values().map(e => e.value).sort((a, b) => a - b), tls13AlertDescriptionValues);
45+
}
46+
)
47+

0 commit comments

Comments
 (0)