2024-01-01 14:58:21 -05:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2020-07-19 13:49:44 -04:00
|
|
|
|
2024-01-23 11:35:23 -05:00
|
|
|
import { core, internals, primordials } from "ext:core/mod.js";
|
2024-01-26 14:04:07 -05:00
|
|
|
const { internalRidSymbol } = core;
|
2024-01-26 17:46:46 -05:00
|
|
|
import {
|
2023-12-26 20:30:26 -05:00
|
|
|
op_net_accept_tls,
|
|
|
|
op_net_connect_tls,
|
2024-01-10 17:37:25 -05:00
|
|
|
op_net_listen_tls,
|
|
|
|
op_tls_handshake,
|
|
|
|
op_tls_start,
|
2024-01-26 17:46:46 -05:00
|
|
|
} from "ext:core/ops";
|
2024-01-10 17:37:25 -05:00
|
|
|
const {
|
|
|
|
Number,
|
2024-01-26 17:19:00 -05:00
|
|
|
ObjectDefineProperty,
|
2024-01-10 17:37:25 -05:00
|
|
|
TypeError,
|
|
|
|
} = primordials;
|
|
|
|
|
|
|
|
import { Conn, Listener } from "ext:deno_net/01_net.js";
|
2020-07-19 13:49:44 -04:00
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
class TlsConn extends Conn {
|
2024-01-24 16:12:10 -05:00
|
|
|
#rid = 0;
|
|
|
|
|
|
|
|
constructor(rid, remoteAddr, localAddr) {
|
|
|
|
super(rid, remoteAddr, localAddr);
|
2024-01-26 17:19:00 -05:00
|
|
|
ObjectDefineProperty(this, internalRidSymbol, {
|
|
|
|
enumerable: false,
|
|
|
|
value: rid,
|
|
|
|
});
|
2024-01-24 16:12:10 -05:00
|
|
|
this.#rid = rid;
|
|
|
|
}
|
|
|
|
|
|
|
|
get rid() {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.TlsConn.rid",
|
|
|
|
new Error().stack,
|
|
|
|
"Use `Deno.TlsConn` instance methods instead.",
|
|
|
|
);
|
|
|
|
return this.#rid;
|
|
|
|
}
|
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
handshake() {
|
2024-02-13 15:34:36 -05:00
|
|
|
return op_tls_handshake(this.#rid);
|
2021-10-26 16:27:47 -04:00
|
|
|
}
|
2023-02-07 14:22:46 -05:00
|
|
|
}
|
2021-10-26 16:27:47 -04:00
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
async function connectTls({
|
|
|
|
port,
|
|
|
|
hostname = "127.0.0.1",
|
|
|
|
transport = "tcp",
|
|
|
|
certFile = undefined,
|
|
|
|
caCerts = [],
|
|
|
|
certChain = undefined,
|
|
|
|
privateKey = undefined,
|
2024-02-18 09:30:58 -05:00
|
|
|
cert = undefined,
|
|
|
|
key = undefined,
|
2023-02-07 14:22:46 -05:00
|
|
|
alpnProtocols = undefined,
|
|
|
|
}) {
|
2024-01-23 11:35:23 -05:00
|
|
|
if (certFile !== undefined) {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.ConnectTlsOptions.certFile",
|
|
|
|
new Error().stack,
|
2024-02-18 09:30:58 -05:00
|
|
|
"Pass the cert file contents to the `Deno.ConnectTlsOptions.cert` option instead.",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (certChain !== undefined) {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.ConnectTlsOptions.certChain",
|
|
|
|
new Error().stack,
|
|
|
|
"Use the `Deno.ConnectTlsOptions.cert` option instead.",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (privateKey !== undefined) {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.ConnectTlsOptions.privateKey",
|
|
|
|
new Error().stack,
|
|
|
|
"Use the `Deno.ConnectTlsOptions.key` option instead.",
|
2024-01-23 11:35:23 -05:00
|
|
|
);
|
|
|
|
}
|
2023-02-07 14:22:46 -05:00
|
|
|
if (transport !== "tcp") {
|
|
|
|
throw new TypeError(`Unsupported transport: '${transport}'`);
|
2021-10-26 16:27:47 -04:00
|
|
|
}
|
2024-02-18 09:30:58 -05:00
|
|
|
if (certChain !== undefined && cert !== undefined) {
|
|
|
|
throw new TypeError(
|
|
|
|
"Cannot specify both `certChain` and `cert`",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (privateKey !== undefined && key !== undefined) {
|
|
|
|
throw new TypeError(
|
|
|
|
"Cannot specify both `privateKey` and `key`",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
cert ??= certChain;
|
|
|
|
key ??= privateKey;
|
2023-12-26 20:30:26 -05:00
|
|
|
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_tls(
|
2023-02-07 14:22:46 -05:00
|
|
|
{ hostname, port },
|
2024-02-18 09:30:58 -05:00
|
|
|
{ certFile, caCerts, cert, key, alpnProtocols },
|
2023-02-07 14:22:46 -05:00
|
|
|
);
|
|
|
|
localAddr.transport = "tcp";
|
|
|
|
remoteAddr.transport = "tcp";
|
|
|
|
return new TlsConn(rid, remoteAddr, localAddr);
|
|
|
|
}
|
2021-10-26 16:27:47 -04:00
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
class TlsListener extends Listener {
|
2024-01-24 17:50:33 -05:00
|
|
|
#rid = 0;
|
|
|
|
|
|
|
|
constructor(rid, addr) {
|
|
|
|
super(rid, addr);
|
2024-01-26 17:19:00 -05:00
|
|
|
ObjectDefineProperty(this, internalRidSymbol, {
|
|
|
|
enumerable: false,
|
|
|
|
value: rid,
|
|
|
|
});
|
2024-01-24 17:50:33 -05:00
|
|
|
this.#rid = rid;
|
|
|
|
}
|
|
|
|
|
|
|
|
get rid() {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.TlsListener.rid",
|
|
|
|
new Error().stack,
|
|
|
|
"Use `Deno.TlsListener` instance methods instead.",
|
|
|
|
);
|
|
|
|
return this.#rid;
|
|
|
|
}
|
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
async accept() {
|
2023-12-26 20:30:26 -05:00
|
|
|
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_accept_tls(
|
2024-01-24 17:50:33 -05:00
|
|
|
this.#rid,
|
2022-10-25 16:50:55 -04:00
|
|
|
);
|
|
|
|
localAddr.transport = "tcp";
|
|
|
|
remoteAddr.transport = "tcp";
|
|
|
|
return new TlsConn(rid, remoteAddr, localAddr);
|
2020-07-19 13:49:44 -04:00
|
|
|
}
|
2023-02-07 14:22:46 -05:00
|
|
|
}
|
2020-07-19 13:49:44 -04:00
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
function listenTls({
|
|
|
|
port,
|
|
|
|
cert,
|
|
|
|
certFile,
|
|
|
|
key,
|
|
|
|
keyFile,
|
|
|
|
hostname = "0.0.0.0",
|
|
|
|
transport = "tcp",
|
|
|
|
alpnProtocols = undefined,
|
|
|
|
reusePort = false,
|
|
|
|
}) {
|
|
|
|
if (transport !== "tcp") {
|
|
|
|
throw new TypeError(`Unsupported transport: '${transport}'`);
|
2020-07-19 13:49:44 -04:00
|
|
|
}
|
2024-01-23 11:35:23 -05:00
|
|
|
if (keyFile !== undefined) {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.ListenTlsOptions.keyFile",
|
|
|
|
new Error().stack,
|
|
|
|
"Pass the key file contents to the `Deno.ListenTlsOptions.key` option instead.",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (certFile !== undefined) {
|
|
|
|
internals.warnOnDeprecatedApi(
|
|
|
|
"Deno.ListenTlsOptions.certFile",
|
|
|
|
new Error().stack,
|
|
|
|
"Pass the cert file contents to the `Deno.ListenTlsOptions.cert` option instead.",
|
|
|
|
);
|
|
|
|
}
|
2024-01-10 17:37:25 -05:00
|
|
|
const { 0: rid, 1: localAddr } = op_net_listen_tls(
|
2023-07-25 02:26:18 -04:00
|
|
|
{ hostname, port: Number(port) },
|
2023-02-07 14:22:46 -05:00
|
|
|
{ cert, certFile, key, keyFile, alpnProtocols, reusePort },
|
|
|
|
);
|
|
|
|
return new TlsListener(rid, localAddr);
|
|
|
|
}
|
2020-07-19 13:49:44 -04:00
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
async function startTls(
|
|
|
|
conn,
|
|
|
|
{
|
|
|
|
hostname = "127.0.0.1",
|
|
|
|
caCerts = [],
|
2021-11-26 13:59:53 -05:00
|
|
|
alpnProtocols = undefined,
|
2023-02-07 14:22:46 -05:00
|
|
|
} = {},
|
|
|
|
) {
|
2024-02-13 15:34:36 -05:00
|
|
|
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_tls_start({
|
2024-01-26 14:04:07 -05:00
|
|
|
rid: conn[internalRidSymbol],
|
2023-02-07 14:22:46 -05:00
|
|
|
hostname,
|
|
|
|
caCerts,
|
|
|
|
alpnProtocols,
|
|
|
|
});
|
|
|
|
return new TlsConn(rid, remoteAddr, localAddr);
|
|
|
|
}
|
2020-07-19 13:49:44 -04:00
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
export { connectTls, listenTls, startTls, TlsConn, TlsListener };
|