mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
BREAKING(net): remove Deno.ConnectTlsOptions.{certChain,certFile,privateKey}
and Deno.ListenTlsOptions.certChain,certFile,keyFile}
(#25525)
Towards #22079
This commit is contained in:
parent
be0ba6d84f
commit
ace1202227
11 changed files with 29 additions and 516 deletions
4
cli/tsc/dts/lib.deno.ns.d.ts
vendored
4
cli/tsc/dts/lib.deno.ns.d.ts
vendored
|
@ -5356,7 +5356,7 @@ declare namespace Deno {
|
||||||
export function serve(
|
export function serve(
|
||||||
options:
|
options:
|
||||||
| ServeTcpOptions
|
| ServeTcpOptions
|
||||||
| (ServeTcpOptions & TlsCertifiedKeyOptions),
|
| (ServeTcpOptions & TlsCertifiedKeyPem),
|
||||||
handler: ServeHandler<Deno.NetAddr>,
|
handler: ServeHandler<Deno.NetAddr>,
|
||||||
): HttpServer<Deno.NetAddr>;
|
): HttpServer<Deno.NetAddr>;
|
||||||
/** Serves HTTP requests with the given option bag.
|
/** Serves HTTP requests with the given option bag.
|
||||||
|
@ -5413,7 +5413,7 @@ declare namespace Deno {
|
||||||
*/
|
*/
|
||||||
export function serve(
|
export function serve(
|
||||||
options:
|
options:
|
||||||
& (ServeTcpOptions | (ServeTcpOptions & TlsCertifiedKeyOptions))
|
& (ServeTcpOptions | (ServeTcpOptions & TlsCertifiedKeyPem))
|
||||||
& ServeInit<Deno.NetAddr>,
|
& ServeInit<Deno.NetAddr>,
|
||||||
): HttpServer<Deno.NetAddr>;
|
): HttpServer<Deno.NetAddr>;
|
||||||
|
|
||||||
|
|
2
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
2
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
|
@ -168,7 +168,7 @@ declare namespace Deno {
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export function createHttpClient(
|
export function createHttpClient(
|
||||||
options: CreateHttpClientOptions & TlsCertifiedKeyOptions,
|
options: CreateHttpClientOptions & TlsCertifiedKeyPem,
|
||||||
): HttpClient;
|
): HttpClient;
|
||||||
|
|
||||||
/** **UNSTABLE**: New API, yet to be vetted.
|
/** **UNSTABLE**: New API, yet to be vetted.
|
||||||
|
|
|
@ -13,7 +13,6 @@ import {
|
||||||
op_tls_handshake,
|
op_tls_handshake,
|
||||||
op_tls_key_null,
|
op_tls_key_null,
|
||||||
op_tls_key_static,
|
op_tls_key_static,
|
||||||
op_tls_key_static_from_file,
|
|
||||||
op_tls_start,
|
op_tls_start,
|
||||||
} from "ext:core/ops";
|
} from "ext:core/ops";
|
||||||
const {
|
const {
|
||||||
|
@ -50,45 +49,23 @@ async function connectTls({
|
||||||
alpnProtocols = undefined,
|
alpnProtocols = undefined,
|
||||||
keyFormat = undefined,
|
keyFormat = undefined,
|
||||||
cert = undefined,
|
cert = undefined,
|
||||||
certFile = undefined,
|
|
||||||
certChain = undefined,
|
|
||||||
key = undefined,
|
key = undefined,
|
||||||
keyFile = undefined,
|
|
||||||
privateKey = undefined,
|
|
||||||
}) {
|
}) {
|
||||||
if (transport !== "tcp") {
|
if (transport !== "tcp") {
|
||||||
throw new TypeError(`Unsupported transport: '${transport}'`);
|
throw new TypeError(`Unsupported transport: '${transport}'`);
|
||||||
}
|
}
|
||||||
let deprecatedCertFile = undefined;
|
|
||||||
|
|
||||||
// Deno.connectTls has an irregular option where you can just pass `certFile` and
|
|
||||||
// not `keyFile`. In this case it's used for `caCerts` rather than the client key.
|
|
||||||
if (certFile !== undefined && keyFile === undefined) {
|
|
||||||
internals.warnOnDeprecatedApi(
|
|
||||||
"Deno.ConnectTlsOptions.certFile",
|
|
||||||
new Error().stack,
|
|
||||||
"Pass the cert file's contents to the `Deno.ConnectTlsOptions.caCerts` option instead.",
|
|
||||||
);
|
|
||||||
|
|
||||||
deprecatedCertFile = certFile;
|
|
||||||
certFile = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keyPair = loadTlsKeyPair("Deno.connectTls", {
|
const keyPair = loadTlsKeyPair("Deno.connectTls", {
|
||||||
keyFormat,
|
keyFormat,
|
||||||
cert,
|
cert,
|
||||||
certFile,
|
|
||||||
certChain,
|
|
||||||
key,
|
key,
|
||||||
keyFile,
|
|
||||||
privateKey,
|
|
||||||
});
|
});
|
||||||
// TODO(mmastrac): We only expose this feature via symbol for now. This should actually be a feature
|
// TODO(mmastrac): We only expose this feature via symbol for now. This should actually be a feature
|
||||||
// in Deno.connectTls, however.
|
// in Deno.connectTls, however.
|
||||||
const serverName = arguments[0][serverNameSymbol] ?? null;
|
const serverName = arguments[0][serverNameSymbol] ?? null;
|
||||||
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_tls(
|
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_tls(
|
||||||
{ hostname, port },
|
{ hostname, port },
|
||||||
{ certFile: deprecatedCertFile, caCerts, alpnProtocols, serverName },
|
{ caCerts, alpnProtocols, serverName },
|
||||||
keyPair,
|
keyPair,
|
||||||
);
|
);
|
||||||
localAddr.transport = "tcp";
|
localAddr.transport = "tcp";
|
||||||
|
@ -137,10 +114,7 @@ function hasTlsKeyPairOptions(options) {
|
||||||
if (options[resolverSymbol] !== undefined) {
|
if (options[resolverSymbol] !== undefined) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return (options.cert !== undefined || options.key !== undefined ||
|
return (options.cert !== undefined || options.key !== undefined);
|
||||||
options.certFile !== undefined ||
|
|
||||||
options.keyFile !== undefined || options.privateKey !== undefined ||
|
|
||||||
options.certChain !== undefined);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,19 +124,8 @@ function hasTlsKeyPairOptions(options) {
|
||||||
function loadTlsKeyPair(api, {
|
function loadTlsKeyPair(api, {
|
||||||
keyFormat,
|
keyFormat,
|
||||||
cert,
|
cert,
|
||||||
certFile,
|
|
||||||
certChain,
|
|
||||||
key,
|
key,
|
||||||
keyFile,
|
|
||||||
privateKey,
|
|
||||||
}) {
|
}) {
|
||||||
if (internals.future) {
|
|
||||||
certFile = undefined;
|
|
||||||
certChain = undefined;
|
|
||||||
keyFile = undefined;
|
|
||||||
privateKey = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(mmastrac): remove this temporary symbol when the API lands
|
// TODO(mmastrac): remove this temporary symbol when the API lands
|
||||||
if (arguments[1][resolverSymbol] !== undefined) {
|
if (arguments[1][resolverSymbol] !== undefined) {
|
||||||
return createTlsKeyResolver(arguments[1][resolverSymbol]);
|
return createTlsKeyResolver(arguments[1][resolverSymbol]);
|
||||||
|
@ -173,68 +136,18 @@ function loadTlsKeyPair(api, {
|
||||||
throw new TypeError('If `keyFormat` is specified, it must be "pem"');
|
throw new TypeError('If `keyFormat` is specified, it must be "pem"');
|
||||||
}
|
}
|
||||||
|
|
||||||
function exclusive(a1, a1v, a2, a2v) {
|
if (cert !== undefined && key === undefined) {
|
||||||
if (a1v !== undefined && a2v !== undefined) {
|
throw new TypeError(
|
||||||
throw new TypeError(
|
`If \`cert\` is specified, \`key\` must be specified as well for \`${api}\`.`,
|
||||||
`Cannot specify both \`${a1}\` and \`${a2}\` for \`${api}\`.`,
|
);
|
||||||
);
|
}
|
||||||
}
|
if (cert === undefined && key !== undefined) {
|
||||||
|
throw new TypeError(
|
||||||
|
`If \`key\` is specified, \`cert\` must be specified as well for \`${api}\`.`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that only one pair is valid
|
if (cert !== undefined) {
|
||||||
exclusive("certChain", certChain, "cert", cert);
|
|
||||||
exclusive("certChain", certChain, "certFile", certFile);
|
|
||||||
exclusive("key", key, "keyFile", keyFile);
|
|
||||||
exclusive("key", key, "privateKey", privateKey);
|
|
||||||
|
|
||||||
function both(a1, a1v, a2, a2v) {
|
|
||||||
if (a1v !== undefined && a2v === undefined) {
|
|
||||||
throw new TypeError(
|
|
||||||
`If \`${a1}\` is specified, \`${a2}\` must be specified as well for \`${api}\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (a1v === undefined && a2v !== undefined) {
|
|
||||||
throw new TypeError(
|
|
||||||
`If \`${a2}\` is specified, \`${a1}\` must be specified as well for \`${api}\`.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pick one pair of cert/key, certFile/keyFile or certChain/privateKey
|
|
||||||
both("cert", cert, "key", key);
|
|
||||||
both("certFile", certFile, "keyFile", keyFile);
|
|
||||||
both("certChain", certChain, "privateKey", privateKey);
|
|
||||||
|
|
||||||
if (certFile !== undefined) {
|
|
||||||
internals.warnOnDeprecatedApi(
|
|
||||||
"Deno.TlsCertifiedKeyOptions.keyFile",
|
|
||||||
new Error().stack,
|
|
||||||
"Pass the key file's contents to the `Deno.TlsCertifiedKeyPem.key` option instead.",
|
|
||||||
);
|
|
||||||
internals.warnOnDeprecatedApi(
|
|
||||||
"Deno.TlsCertifiedKeyOptions.certFile",
|
|
||||||
new Error().stack,
|
|
||||||
"Pass the cert file's contents to the `Deno.TlsCertifiedKeyPem.cert` option instead.",
|
|
||||||
);
|
|
||||||
return op_tls_key_static_from_file(api, certFile, keyFile);
|
|
||||||
} else if (certChain !== undefined) {
|
|
||||||
if (api !== "Deno.connectTls") {
|
|
||||||
throw new TypeError(
|
|
||||||
`Invalid options 'certChain' and 'privateKey' for ${api}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
internals.warnOnDeprecatedApi(
|
|
||||||
"Deno.TlsCertifiedKeyOptions.privateKey",
|
|
||||||
new Error().stack,
|
|
||||||
"Use the `Deno.TlsCertifiedKeyPem.key` option instead.",
|
|
||||||
);
|
|
||||||
internals.warnOnDeprecatedApi(
|
|
||||||
"Deno.TlsCertifiedKeyOptions.certChain",
|
|
||||||
new Error().stack,
|
|
||||||
"Use the `Deno.TlsCertifiedKeyPem.cert` option instead.",
|
|
||||||
);
|
|
||||||
return op_tls_key_static(certChain, privateKey);
|
|
||||||
} else if (cert !== undefined) {
|
|
||||||
return op_tls_key_static(cert, key);
|
return op_tls_key_static(cert, key);
|
||||||
} else {
|
} else {
|
||||||
return op_tls_key_null();
|
return op_tls_key_null();
|
||||||
|
|
77
ext/net/lib.deno_net.d.ts
vendored
77
ext/net/lib.deno_net.d.ts
vendored
|
@ -232,16 +232,6 @@ declare namespace Deno {
|
||||||
options: UnixListenOptions & { transport: "unix" },
|
options: UnixListenOptions & { transport: "unix" },
|
||||||
): UnixListener;
|
): UnixListener;
|
||||||
|
|
||||||
/** Provides TLS certified keys, ie: a key that has been certified by a trusted certificate authority.
|
|
||||||
* A certified key generally consists of a private key and certificate part.
|
|
||||||
*
|
|
||||||
* @category Network
|
|
||||||
*/
|
|
||||||
export type TlsCertifiedKeyOptions =
|
|
||||||
| TlsCertifiedKeyPem
|
|
||||||
| TlsCertifiedKeyFromFile
|
|
||||||
| TlsCertifiedKeyConnectTls;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides certified key material from strings. The key material is provided in
|
* Provides certified key material from strings. The key material is provided in
|
||||||
* `PEM`-format (Privacy Enhanced Mail, https://www.rfc-editor.org/rfc/rfc1422) which can be identified by having
|
* `PEM`-format (Privacy Enhanced Mail, https://www.rfc-editor.org/rfc/rfc1422) which can be identified by having
|
||||||
|
@ -268,59 +258,6 @@ declare namespace Deno {
|
||||||
cert: string;
|
cert: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*
|
|
||||||
* @category Network
|
|
||||||
*/
|
|
||||||
export interface TlsCertifiedKeyFromFile {
|
|
||||||
/** Path to a file containing a PEM formatted CA certificate. Requires
|
|
||||||
* `--allow-read`.
|
|
||||||
*
|
|
||||||
* @tags allow-read
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*/
|
|
||||||
certFile: string;
|
|
||||||
/** Path to a file containing a private key file. Requires `--allow-read`.
|
|
||||||
*
|
|
||||||
* @tags allow-read
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*/
|
|
||||||
keyFile: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*
|
|
||||||
* @category Network
|
|
||||||
*/
|
|
||||||
export interface TlsCertifiedKeyConnectTls {
|
|
||||||
/**
|
|
||||||
* Certificate chain in `PEM` format.
|
|
||||||
*
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*/
|
|
||||||
certChain: string;
|
|
||||||
/**
|
|
||||||
* Private key in `PEM` format. RSA, EC, and PKCS8-format keys are supported.
|
|
||||||
*
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*/
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @category Network */
|
/** @category Network */
|
||||||
export interface ListenTlsOptions extends TcpListenOptions {
|
export interface ListenTlsOptions extends TcpListenOptions {
|
||||||
transport?: "tcp";
|
transport?: "tcp";
|
||||||
|
@ -349,7 +286,7 @@ declare namespace Deno {
|
||||||
* @category Network
|
* @category Network
|
||||||
*/
|
*/
|
||||||
export function listenTls(
|
export function listenTls(
|
||||||
options: ListenTlsOptions & TlsCertifiedKeyOptions,
|
options: ListenTlsOptions & TlsCertifiedKeyPem,
|
||||||
): TlsListener;
|
): TlsListener;
|
||||||
|
|
||||||
/** @category Network */
|
/** @category Network */
|
||||||
|
@ -430,16 +367,6 @@ declare namespace Deno {
|
||||||
*
|
*
|
||||||
* @default {"127.0.0.1"} */
|
* @default {"127.0.0.1"} */
|
||||||
hostname?: string;
|
hostname?: string;
|
||||||
/** Path to a file containing a PEM formatted list of root certificates that will
|
|
||||||
* be used in addition to the default root certificates to verify the peer's certificate. Requires
|
|
||||||
* `--allow-read`.
|
|
||||||
*
|
|
||||||
* @tags allow-read
|
|
||||||
* @deprecated This will be removed in Deno 2.0. See the
|
|
||||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
|
||||||
* for migration instructions.
|
|
||||||
*/
|
|
||||||
certFile?: string;
|
|
||||||
/** A list of root certificates that will be used in addition to the
|
/** A list of root certificates that will be used in addition to the
|
||||||
* default root certificates to verify the peer's certificate.
|
* default root certificates to verify the peer's certificate.
|
||||||
*
|
*
|
||||||
|
@ -493,7 +420,7 @@ declare namespace Deno {
|
||||||
* @category Network
|
* @category Network
|
||||||
*/
|
*/
|
||||||
export function connectTls(
|
export function connectTls(
|
||||||
options: ConnectTlsOptions & TlsCertifiedKeyOptions,
|
options: ConnectTlsOptions & TlsCertifiedKeyPem,
|
||||||
): Promise<TlsConn>;
|
): Promise<TlsConn>;
|
||||||
|
|
||||||
/** @category Network */
|
/** @category Network */
|
||||||
|
|
|
@ -115,7 +115,6 @@ deno_core::extension!(deno_net,
|
||||||
|
|
||||||
ops_tls::op_tls_key_null,
|
ops_tls::op_tls_key_null,
|
||||||
ops_tls::op_tls_key_static,
|
ops_tls::op_tls_key_static,
|
||||||
ops_tls::op_tls_key_static_from_file<P>,
|
|
||||||
ops_tls::op_tls_cert_resolver_create,
|
ops_tls::op_tls_cert_resolver_create,
|
||||||
ops_tls::op_tls_cert_resolver_poll,
|
ops_tls::op_tls_cert_resolver_poll,
|
||||||
ops_tls::op_tls_cert_resolver_resolve,
|
ops_tls::op_tls_cert_resolver_resolve,
|
||||||
|
|
|
@ -34,8 +34,6 @@ use deno_tls::new_resolver;
|
||||||
use deno_tls::rustls::pki_types::ServerName;
|
use deno_tls::rustls::pki_types::ServerName;
|
||||||
use deno_tls::rustls::ClientConnection;
|
use deno_tls::rustls::ClientConnection;
|
||||||
use deno_tls::rustls::ServerConfig;
|
use deno_tls::rustls::ServerConfig;
|
||||||
use deno_tls::webpki::types::CertificateDer;
|
|
||||||
use deno_tls::webpki::types::PrivateKeyDer;
|
|
||||||
use deno_tls::ServerConfigProvider;
|
use deno_tls::ServerConfigProvider;
|
||||||
use deno_tls::SocketUse;
|
use deno_tls::SocketUse;
|
||||||
use deno_tls::TlsKey;
|
use deno_tls::TlsKey;
|
||||||
|
@ -213,32 +211,6 @@ pub fn op_tls_key_static(
|
||||||
Ok(TlsKeysHolder::from(TlsKeys::Static(TlsKey(cert, key))))
|
Ok(TlsKeysHolder::from(TlsKeys::Static(TlsKey(cert, key))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Legacy op -- will be removed in Deno 2.0.
|
|
||||||
#[op2]
|
|
||||||
#[cppgc]
|
|
||||||
pub fn op_tls_key_static_from_file<NP>(
|
|
||||||
state: &mut OpState,
|
|
||||||
#[string] api: String,
|
|
||||||
#[string] cert_file: String,
|
|
||||||
#[string] key_file: String,
|
|
||||||
) -> Result<TlsKeysHolder, AnyError>
|
|
||||||
where
|
|
||||||
NP: NetPermissions + 'static,
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let permissions = state.borrow_mut::<NP>();
|
|
||||||
permissions.check_read(Path::new(&cert_file), &api)?;
|
|
||||||
permissions.check_read(Path::new(&key_file), &api)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cert = load_certs_from_file(&cert_file)?;
|
|
||||||
let key = load_private_keys_from_file(&key_file)?
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.unwrap();
|
|
||||||
Ok(TlsKeysHolder::from(TlsKeys::Static(TlsKey(cert, key))))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
pub fn op_tls_cert_resolver_create<'s>(
|
pub fn op_tls_cert_resolver_create<'s>(
|
||||||
scope: &mut v8::HandleScope<'s>,
|
scope: &mut v8::HandleScope<'s>,
|
||||||
|
@ -455,21 +427,6 @@ where
|
||||||
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_certs_from_file(
|
|
||||||
path: &str,
|
|
||||||
) -> Result<Vec<CertificateDer<'static>>, AnyError> {
|
|
||||||
let cert_file = File::open(path)?;
|
|
||||||
let reader = &mut BufReader::new(cert_file);
|
|
||||||
load_certs(reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_private_keys_from_file(
|
|
||||||
path: &str,
|
|
||||||
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
|
||||||
let key_bytes = std::fs::read(path)?;
|
|
||||||
load_private_keys(&key_bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ListenTlsArgs {
|
pub struct ListenTlsArgs {
|
||||||
|
|
|
@ -31,40 +31,6 @@ try {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this could throw with a `Deno.errors.NotFound` error if `keyFile` and
|
|
||||||
// `certFile` were used.
|
|
||||||
const conn1 = await Deno.connectTls({
|
|
||||||
port: tlsPort,
|
|
||||||
certFile: "foo",
|
|
||||||
keyFile: "foo",
|
|
||||||
});
|
|
||||||
conn1.close();
|
|
||||||
console.log("Deno.ConnectTlsOptions.(certFile|keyFile) do nothing");
|
|
||||||
|
|
||||||
// Note: this could throw with a `Deno.errors.InvalidData` error if `certChain`
|
|
||||||
// and `privateKey` were used.
|
|
||||||
const conn2 = await Deno.connectTls({
|
|
||||||
port: tlsPort,
|
|
||||||
certChain: "foo",
|
|
||||||
privateKey: "foo",
|
|
||||||
});
|
|
||||||
conn2.close();
|
|
||||||
console.log("Deno.ConnectTlsOptions.(certChain|privateKey) do nothing");
|
|
||||||
|
|
||||||
tlsListener.close();
|
tlsListener.close();
|
||||||
|
|
||||||
// Note: this could throw with a `Deno.errors.NotFound` error if `keyFile` and
|
|
||||||
// `certFile` were used.
|
|
||||||
try {
|
|
||||||
Deno.listenTls({ port: tlsPort, keyFile: "foo", certFile: "foo" });
|
|
||||||
} catch (error) {
|
|
||||||
if (
|
|
||||||
error instanceof Deno.errors.InvalidData &&
|
|
||||||
error.message ===
|
|
||||||
"Deno.listenTls requires a key: Error creating TLS certificate"
|
|
||||||
) {
|
|
||||||
console.log("Deno.ListenTlsOptions.(keyFile|certFile) do nothing");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.close();
|
self.close();
|
||||||
|
|
|
@ -2,6 +2,3 @@ window is undefined
|
||||||
Deno.Listener.prototype.rid is undefined
|
Deno.Listener.prototype.rid is undefined
|
||||||
Deno.TlsListener.prototype.rid is undefined
|
Deno.TlsListener.prototype.rid is undefined
|
||||||
Deno.FsFile constructor is illegal
|
Deno.FsFile constructor is illegal
|
||||||
Deno.ConnectTlsOptions.(certFile|keyFile) do nothing
|
|
||||||
Deno.ConnectTlsOptions.(certChain|privateKey) do nothing
|
|
||||||
Deno.ListenTlsOptions.(keyFile|certFile) do nothing
|
|
||||||
|
|
|
@ -25,9 +25,8 @@ Deno.test(
|
||||||
return keys[sni]!;
|
return keys[sni]!;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const listener = Deno.listenTls(
|
// @ts-ignore Trust me
|
||||||
<Deno.ListenTlsOptions & Deno.TlsCertifiedKeyConnectTls> opts,
|
const listener = Deno.listenTls(opts);
|
||||||
);
|
|
||||||
|
|
||||||
for (
|
for (
|
||||||
const server of ["server-1", "server-2", "fail-server-3", "fail-server-4"]
|
const server of ["server-1", "server-2", "fail-server-3", "fail-server-4"]
|
||||||
|
|
|
@ -67,112 +67,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { net: true, read: false }, ignore: DENO_FUTURE },
|
|
||||||
async function connectTLSCertFileNoReadPerm() {
|
|
||||||
await assertRejects(async () => {
|
|
||||||
await Deno.connectTls({
|
|
||||||
hostname: "deno.land",
|
|
||||||
port: 443,
|
|
||||||
certFile: "tests/testdata/tls/RootCA.crt",
|
|
||||||
});
|
|
||||||
}, Deno.errors.NotCapable);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
function listenTLSNonExistentCertKeyFiles() {
|
|
||||||
const options = {
|
|
||||||
hostname: "localhost",
|
|
||||||
port: 0,
|
|
||||||
certFile: "tests/testdata/tls/localhost.crt",
|
|
||||||
keyFile: "tests/testdata/tls/localhost.key",
|
|
||||||
};
|
|
||||||
|
|
||||||
assertThrows(() => {
|
|
||||||
Deno.listenTls({
|
|
||||||
...options,
|
|
||||||
certFile: "./non/existent/file",
|
|
||||||
});
|
|
||||||
}, Deno.errors.NotFound);
|
|
||||||
|
|
||||||
assertThrows(() => {
|
|
||||||
Deno.listenTls({
|
|
||||||
...options,
|
|
||||||
keyFile: "./non/existent/file",
|
|
||||||
});
|
|
||||||
}, Deno.errors.NotFound);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { net: true, read: false }, ignore: DENO_FUTURE },
|
|
||||||
function listenTLSNoReadPerm() {
|
|
||||||
assertThrows(() => {
|
|
||||||
Deno.listenTls({
|
|
||||||
hostname: "localhost",
|
|
||||||
port: 0,
|
|
||||||
certFile: "tests/testdata/tls/localhost.crt",
|
|
||||||
keyFile: "tests/testdata/tls/localhost.key",
|
|
||||||
});
|
|
||||||
}, Deno.errors.NotCapable);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{
|
|
||||||
permissions: { read: true, write: true, net: true },
|
|
||||||
ignore: DENO_FUTURE,
|
|
||||||
},
|
|
||||||
function listenTLSEmptyKeyFile() {
|
|
||||||
const options = {
|
|
||||||
hostname: "localhost",
|
|
||||||
port: 0,
|
|
||||||
certFile: "tests/testdata/tls/localhost.crt",
|
|
||||||
keyFile: "tests/testdata/tls/localhost.key",
|
|
||||||
};
|
|
||||||
|
|
||||||
const testDir = Deno.makeTempDirSync();
|
|
||||||
const keyFilename = testDir + "/key.pem";
|
|
||||||
Deno.writeFileSync(keyFilename, new Uint8Array([]), {
|
|
||||||
mode: 0o666,
|
|
||||||
});
|
|
||||||
|
|
||||||
assertThrows(() => {
|
|
||||||
Deno.listenTls({
|
|
||||||
...options,
|
|
||||||
keyFile: keyFilename,
|
|
||||||
});
|
|
||||||
}, Error);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, write: true, net: true } },
|
|
||||||
function listenTLSEmptyCertFile() {
|
|
||||||
const options = {
|
|
||||||
hostname: "localhost",
|
|
||||||
port: 0,
|
|
||||||
certFile: "tests/testdata/tls/localhost.crt",
|
|
||||||
keyFile: "tests/testdata/tls/localhost.key",
|
|
||||||
};
|
|
||||||
|
|
||||||
const testDir = Deno.makeTempDirSync();
|
|
||||||
const certFilename = testDir + "/cert.crt";
|
|
||||||
Deno.writeFileSync(certFilename, new Uint8Array([]), {
|
|
||||||
mode: 0o666,
|
|
||||||
});
|
|
||||||
|
|
||||||
assertThrows(() => {
|
|
||||||
Deno.listenTls({
|
|
||||||
...options,
|
|
||||||
certFile: certFilename,
|
|
||||||
});
|
|
||||||
}, Error);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { net: true } },
|
{ permissions: { net: true } },
|
||||||
async function startTlsWithoutExclusiveAccessToTcpConn() {
|
async function startTlsWithoutExclusiveAccessToTcpConn() {
|
||||||
|
@ -1147,22 +1041,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
async function connectTLSBadClientCertPrivateKey(): Promise<void> {
|
|
||||||
await assertRejects(async () => {
|
|
||||||
await Deno.connectTls({
|
|
||||||
hostname: "deno.land",
|
|
||||||
port: 443,
|
|
||||||
certChain: "bad data",
|
|
||||||
privateKey: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.key",
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}, Deno.errors.InvalidData);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
||||||
async function connectTLSBadCertKey(): Promise<void> {
|
async function connectTLSBadCertKey(): Promise<void> {
|
||||||
|
@ -1179,22 +1057,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
async function connectTLSBadPrivateKey(): Promise<void> {
|
|
||||||
await assertRejects(async () => {
|
|
||||||
await Deno.connectTls({
|
|
||||||
hostname: "deno.land",
|
|
||||||
port: 443,
|
|
||||||
certChain: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
privateKey: "bad data",
|
|
||||||
});
|
|
||||||
}, Deno.errors.InvalidData);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { read: true, net: true } },
|
{ permissions: { read: true, net: true } },
|
||||||
async function connectTLSBadKey(): Promise<void> {
|
async function connectTLSBadKey(): Promise<void> {
|
||||||
|
@ -1211,22 +1073,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
async function connectTLSNotPrivateKey(): Promise<void> {
|
|
||||||
await assertRejects(async () => {
|
|
||||||
await Deno.connectTls({
|
|
||||||
hostname: "deno.land",
|
|
||||||
port: 443,
|
|
||||||
certChain: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
privateKey: "",
|
|
||||||
});
|
|
||||||
}, Deno.errors.InvalidData);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
||||||
async function connectTLSNotKey(): Promise<void> {
|
async function connectTLSNotKey(): Promise<void> {
|
||||||
|
@ -1243,31 +1089,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
async function connectWithClientCert() {
|
|
||||||
// The test_server running on port 4552 responds with 'PASS' if client
|
|
||||||
// authentication was successful. Try it by running test_server and
|
|
||||||
// curl --key tests/testdata/tls/localhost.key \
|
|
||||||
// --cert tests/testdata/tls/localhost.crt \
|
|
||||||
// --cacert tests/testdata/tls/RootCA.crt https://localhost:4552/
|
|
||||||
const conn = await Deno.connectTls({
|
|
||||||
hostname: "localhost",
|
|
||||||
port: 4552,
|
|
||||||
certChain: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
privateKey: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.key",
|
|
||||||
),
|
|
||||||
caCerts: [Deno.readTextFileSync("tests/testdata/tls/RootCA.pem")],
|
|
||||||
});
|
|
||||||
const result = decoder.decode(await readAll(conn));
|
|
||||||
assertEquals(result, "PASS");
|
|
||||||
conn.close();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { read: true, net: true } },
|
{ permissions: { read: true, net: true } },
|
||||||
async function connectWithCert() {
|
async function connectWithCert() {
|
||||||
|
@ -1293,56 +1114,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
async function connectTlsConflictingCertOptions(): Promise<void> {
|
|
||||||
await assertRejects(
|
|
||||||
async () => {
|
|
||||||
await Deno.connectTls({
|
|
||||||
hostname: "deno.land",
|
|
||||||
port: 443,
|
|
||||||
cert: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
certChain: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
key: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.key",
|
|
||||||
),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
TypeError,
|
|
||||||
"Cannot specify both `certChain` and `cert`",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true }, ignore: DENO_FUTURE },
|
|
||||||
async function connectTlsConflictingKeyOptions(): Promise<void> {
|
|
||||||
await assertRejects(
|
|
||||||
async () => {
|
|
||||||
await Deno.connectTls({
|
|
||||||
hostname: "deno.land",
|
|
||||||
port: 443,
|
|
||||||
cert: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
privateKey: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.crt",
|
|
||||||
),
|
|
||||||
key: Deno.readTextFileSync(
|
|
||||||
"tests/testdata/tls/localhost.key",
|
|
||||||
),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
TypeError,
|
|
||||||
"Cannot specify both `key` and `privateKey` for `Deno.connectTls`.",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { read: true, net: true } },
|
{ permissions: { read: true, net: true } },
|
||||||
async function connectTLSCaCerts() {
|
async function connectTLSCaCerts() {
|
||||||
|
@ -1357,20 +1128,6 @@ Deno.test(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
{ permissions: { read: true, net: true } },
|
|
||||||
async function connectTLSCertFile() {
|
|
||||||
const conn = await Deno.connectTls({
|
|
||||||
hostname: "localhost",
|
|
||||||
port: 4557,
|
|
||||||
certFile: "tests/testdata/tls/RootCA.pem",
|
|
||||||
});
|
|
||||||
const result = decoder.decode(await readAll(conn));
|
|
||||||
assertEquals(result, "PASS");
|
|
||||||
conn.close();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ permissions: { read: true, net: true } },
|
{ permissions: { read: true, net: true } },
|
||||||
async function startTLSCaCerts() {
|
async function startTLSCaCerts() {
|
||||||
|
@ -1397,7 +1154,7 @@ Deno.test(
|
||||||
const connectPromise = Deno.connectTls({
|
const connectPromise = Deno.connectTls({
|
||||||
hostname,
|
hostname,
|
||||||
port,
|
port,
|
||||||
certFile: "tests/testdata/tls/RootCA.crt",
|
caCerts: [await Deno.readTextFile("tests/testdata/tls/RootCA.crt")],
|
||||||
});
|
});
|
||||||
const [conn1, conn2] = await Promise.all([acceptPromise, connectPromise]);
|
const [conn1, conn2] = await Promise.all([acceptPromise, connectPromise]);
|
||||||
listener.close();
|
listener.close();
|
||||||
|
@ -1615,8 +1372,8 @@ Deno.test(
|
||||||
Deno.listenTls({
|
Deno.listenTls({
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
port: 0,
|
port: 0,
|
||||||
certFile: "tests/testdata/tls/invalid.crt",
|
cert: Deno.readTextFileSync("tests/testdata/tls/invalid.crt"),
|
||||||
keyFile: "tests/testdata/tls/localhost.key",
|
key: Deno.readTextFileSync("tests/testdata/tls/localhost.key"),
|
||||||
});
|
});
|
||||||
}, Deno.errors.InvalidData);
|
}, Deno.errors.InvalidData);
|
||||||
},
|
},
|
||||||
|
@ -1629,21 +1386,21 @@ Deno.test(
|
||||||
Deno.listenTls({
|
Deno.listenTls({
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
port: 0,
|
port: 0,
|
||||||
certFile: "tests/testdata/tls/localhost.crt",
|
cert: Deno.readTextFileSync("tests/testdata/tls/localhost.crt"),
|
||||||
keyFile: "tests/testdata/tls/invalid.key",
|
key: Deno.readTextFileSync("tests/testdata/tls/invalid.key"),
|
||||||
});
|
});
|
||||||
}, Deno.errors.InvalidData);
|
}, Deno.errors.InvalidData);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
{ ignore: DENO_FUTURE, permissions: { net: true, read: true } },
|
{ permissions: { net: true, read: true } },
|
||||||
function listenTLSEcKey() {
|
function listenTLSEcKey() {
|
||||||
const listener = Deno.listenTls({
|
const listener = Deno.listenTls({
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
port: 0,
|
port: 0,
|
||||||
certFile: "tests/testdata/tls/localhost_ecc.crt",
|
cert: Deno.readTextFileSync("tests/testdata/tls/localhost_ecc.crt"),
|
||||||
keyFile: "tests/testdata/tls/localhost_ecc.key",
|
key: Deno.readTextFileSync("tests/testdata/tls/localhost_ecc.key"),
|
||||||
});
|
});
|
||||||
listener.close();
|
listener.close();
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,10 +10,8 @@ import * as stream from "node:stream";
|
||||||
const tlsTestdataDir = fromFileUrl(
|
const tlsTestdataDir = fromFileUrl(
|
||||||
new URL("../testdata/tls", import.meta.url),
|
new URL("../testdata/tls", import.meta.url),
|
||||||
);
|
);
|
||||||
const keyFile = join(tlsTestdataDir, "localhost.key");
|
const key = Deno.readTextFileSync(join(tlsTestdataDir, "localhost.key"));
|
||||||
const certFile = join(tlsTestdataDir, "localhost.crt");
|
const cert = Deno.readTextFileSync(join(tlsTestdataDir, "localhost.crt"));
|
||||||
const key = Deno.readTextFileSync(keyFile);
|
|
||||||
const cert = Deno.readTextFileSync(certFile);
|
|
||||||
const rootCaCert = Deno.readTextFileSync(join(tlsTestdataDir, "RootCA.pem"));
|
const rootCaCert = Deno.readTextFileSync(join(tlsTestdataDir, "RootCA.pem"));
|
||||||
|
|
||||||
for (
|
for (
|
||||||
|
|
Loading…
Reference in a new issue