summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/dts/lib.deno.unstable.d.ts33
-rw-r--r--cli/tests/unit/tls_test.ts75
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([