diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/dts/lib.deno.unstable.d.ts | 33 | ||||
-rw-r--r-- | cli/tests/unit/tls_test.ts | 75 |
2 files changed, 108 insertions, 0 deletions
diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index ddf597a0a..fd62a9486 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -935,6 +935,29 @@ declare namespace Deno { certChain?: string; /** PEM formatted (RSA or PKCS8) private key of client certificate. */ privateKey?: string; + /** **UNSTABLE**: new API, yet to be vetted. + * + * Application-Layer Protocol Negotiation (ALPN) protocols supported by + * the client. If not specified, no ALPN extension will be included in the + * TLS handshake. + */ + alpnProtocols?: string[]; + } + + export interface TlsHandshakeInfo { + /** **UNSTABLE**: new API, yet to be vetted. + * + * Contains the ALPN protocol selected during negotiation with the server. + * If no ALPN protocol selected, returns `null`. + */ + alpnProtocol: string | null; + } + + export interface TlsConn extends Conn { + /** Runs the client or server handshake protocol to completion if that has + * not happened yet. Calling this method is optional; the TLS handshake + * will be completed automatically as soon as data is sent or received. */ + handshake(): Promise<TlsHandshakeInfo>; } /** **UNSTABLE** New API, yet to be vetted. @@ -964,6 +987,16 @@ declare namespace Deno { alpnProtocols?: string[]; } + export interface StartTlsOptions { + /** **UNSTABLE**: new API, yet to be vetted. + * + * Application-Layer Protocol Negotiation (ALPN) protocols to announce to + * the client. If not specified, no ALPN extension will be included in the + * TLS handshake. + */ + alpnProtocols?: string[]; + } + /** **UNSTABLE**: New API should be tested first. * * Acquire an advisory file-system lock for the provided file. `exclusive` diff --git a/cli/tests/unit/tls_test.ts b/cli/tests/unit/tls_test.ts index 4062ef504..7e6d68900 100644 --- a/cli/tests/unit/tls_test.ts +++ b/cli/tests/unit/tls_test.ts @@ -244,6 +244,49 @@ async function tlsPair(): Promise<[Deno.Conn, Deno.Conn]> { return endpoints; } +async function tlsAlpn( + useStartTls: boolean, +): Promise<[Deno.TlsConn, Deno.TlsConn]> { + const port = getPort(); + const listener = Deno.listenTls({ + hostname: "localhost", + port, + certFile: "cli/tests/testdata/tls/localhost.crt", + keyFile: "cli/tests/testdata/tls/localhost.key", + alpnProtocols: ["deno", "rocks"], + }); + + const acceptPromise = listener.accept(); + + const caCerts = [Deno.readTextFileSync("cli/tests/testdata/tls/RootCA.pem")]; + const clientAlpnProtocols = ["rocks", "rises"]; + let endpoints: [Deno.TlsConn, Deno.TlsConn]; + + if (!useStartTls) { + const connectPromise = Deno.connectTls({ + hostname: "localhost", + port, + caCerts, + alpnProtocols: clientAlpnProtocols, + }); + endpoints = await Promise.all([acceptPromise, connectPromise]); + } else { + const client = await Deno.connect({ + hostname: "localhost", + port, + }); + const connectPromise = Deno.startTls(client, { + hostname: "localhost", + caCerts, + alpnProtocols: clientAlpnProtocols, + }); + endpoints = await Promise.all([acceptPromise, connectPromise]); + } + + listener.close(); + return endpoints; +} + async function sendThenCloseWriteThenReceive( conn: Deno.Conn, chunkCount: number, @@ -307,6 +350,38 @@ async function receiveThenSend( Deno.test( { permissions: { read: true, net: true } }, + async function tlsServerAlpnListenConnect() { + const [serverConn, clientConn] = await tlsAlpn(false); + const [serverHS, clientHS] = await Promise.all([ + serverConn.handshake(), + clientConn.handshake(), + ]); + assertStrictEquals(serverHS.alpnProtocol, "rocks"); + assertStrictEquals(clientHS.alpnProtocol, "rocks"); + + serverConn.close(); + clientConn.close(); + }, +); + +Deno.test( + { permissions: { read: true, net: true } }, + async function tlsServerAlpnListenStartTls() { + const [serverConn, clientConn] = await tlsAlpn(true); + const [serverHS, clientHS] = await Promise.all([ + serverConn.handshake(), + clientConn.handshake(), + ]); + assertStrictEquals(serverHS.alpnProtocol, "rocks"); + assertStrictEquals(clientHS.alpnProtocol, "rocks"); + + serverConn.close(); + clientConn.close(); + }, +); + +Deno.test( + { permissions: { read: true, net: true } }, async function tlsServerStreamHalfCloseSendOneByte() { const [serverConn, clientConn] = await tlsPair(); await Promise.all([ |