summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorSean Michael Wykes <sean.wykes@nascent.com.br>2021-08-25 09:25:12 -0300
committerGitHub <noreply@github.com>2021-08-25 14:25:12 +0200
commitdccf4cbe36d66140f9e35a6ee755c3c440d745f9 (patch)
treeaf3114696f1649d77474f69cd3361d58aea34275 /cli
parent5d814a4c244d489b4ae51002a0cf1d3c2fe16058 (diff)
feat(fetch): mTLS client certificates for fetch() (#11721)
This commit adds support for specifying client certificates when using fetch, by means of `Deno.createHttpClient`.
Diffstat (limited to 'cli')
-rw-r--r--cli/dts/lib.deno.unstable.d.ts2
-rw-r--r--cli/file_fetcher.rs1
-rw-r--r--cli/http_util.rs17
-rw-r--r--cli/tests/unit/fetch_test.ts80
4 files changed, 98 insertions, 2 deletions
diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts
index 78f771ce1..ead4609c6 100644
--- a/cli/dts/lib.deno.unstable.d.ts
+++ b/cli/dts/lib.deno.unstable.d.ts
@@ -859,6 +859,8 @@ declare namespace Deno {
*/
caData?: string;
proxy?: Proxy;
+ certChain?: string;
+ privateKey?: string;
}
export interface Proxy {
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index 8fda66382..a1729825f 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -237,6 +237,7 @@ impl FileFetcher {
None,
None,
unsafely_ignore_certificate_errors,
+ None,
)?,
blob_store,
})
diff --git a/cli/http_util.rs b/cli/http_util.rs
index 46ec73cc7..61b1abcbe 100644
--- a/cli/http_util.rs
+++ b/cli/http_util.rs
@@ -144,8 +144,15 @@ mod tests {
use std::fs::read;
fn create_test_client(ca_data: Option<Vec<u8>>) -> Client {
- create_http_client("test_client".to_string(), None, ca_data, None, None)
- .unwrap()
+ create_http_client(
+ "test_client".to_string(),
+ None,
+ ca_data,
+ None,
+ None,
+ None,
+ )
+ .unwrap()
}
#[tokio::test]
@@ -340,6 +347,7 @@ mod tests {
),
None,
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
@@ -370,6 +378,7 @@ mod tests {
None,
None,
None,
+ None,
)
.unwrap();
@@ -402,6 +411,7 @@ mod tests {
None,
None,
None,
+ None,
)
.unwrap();
@@ -440,6 +450,7 @@ mod tests {
),
None,
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
@@ -480,6 +491,7 @@ mod tests {
),
None,
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
@@ -533,6 +545,7 @@ mod tests {
),
None,
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts
index 6e2b1a5d6..ed384dd4f 100644
--- a/cli/tests/unit/fetch_test.ts
+++ b/cli/tests/unit/fetch_test.ts
@@ -1211,3 +1211,83 @@ unitTest(
assertEquals(res.body, null);
},
);
+
+unitTest(
+ { perms: { read: true, net: true } },
+ async function fetchClientCertWrongPrivateKey(): Promise<void> {
+ await assertThrowsAsync(async () => {
+ const client = Deno.createHttpClient({
+ certChain: "bad data",
+ privateKey: await Deno.readTextFile(
+ "cli/tests/testdata/tls/localhost.key",
+ ),
+ });
+ await fetch("https://localhost:5552/fixture.json", {
+ client,
+ });
+ }, Deno.errors.InvalidData);
+ },
+);
+
+unitTest(
+ { perms: { read: true, net: true } },
+ async function fetchClientCertBadPrivateKey(): Promise<void> {
+ await assertThrowsAsync(async () => {
+ const client = Deno.createHttpClient({
+ certChain: await Deno.readTextFile(
+ "cli/tests/testdata/tls/localhost.crt",
+ ),
+ privateKey: "bad data",
+ });
+ await fetch("https://localhost:5552/fixture.json", {
+ client,
+ });
+ }, Deno.errors.InvalidData);
+ },
+);
+
+unitTest(
+ { perms: { read: true, net: true } },
+ async function fetchClientCertNotPrivateKey(): Promise<void> {
+ await assertThrowsAsync(async () => {
+ const client = Deno.createHttpClient({
+ certChain: await Deno.readTextFile(
+ "cli/tests/testdata/tls/localhost.crt",
+ ),
+ privateKey: "",
+ });
+ await fetch("https://localhost:5552/fixture.json", {
+ client,
+ });
+ }, Deno.errors.InvalidData);
+ },
+);
+
+unitTest(
+ { perms: { read: true, net: true } },
+ async function fetchCustomClientPrivateKey(): Promise<
+ void
+ > {
+ const data = "Hello World";
+ const client = Deno.createHttpClient({
+ certChain: await Deno.readTextFile(
+ "cli/tests/testdata/tls/localhost.crt",
+ ),
+ privateKey: await Deno.readTextFile(
+ "cli/tests/testdata/tls/localhost.key",
+ ),
+ caData: await Deno.readTextFile("cli/tests/testdata/tls/RootCA.crt"),
+ });
+ const response = await fetch("https://localhost:5552/echo_server", {
+ client,
+ method: "POST",
+ body: new TextEncoder().encode(data),
+ });
+ assertEquals(
+ response.headers.get("user-agent"),
+ `Deno/${Deno.version.deno}`,
+ );
+ await response.text();
+ client.close();
+ },
+);