diff options
author | Sean Michael Wykes <sean.wykes@nascent.com.br> | 2021-08-25 09:25:12 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-25 14:25:12 +0200 |
commit | dccf4cbe36d66140f9e35a6ee755c3c440d745f9 (patch) | |
tree | af3114696f1649d77474f69cd3361d58aea34275 /cli | |
parent | 5d814a4c244d489b4ae51002a0cf1d3c2fe16058 (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.ts | 2 | ||||
-rw-r--r-- | cli/file_fetcher.rs | 1 | ||||
-rw-r--r-- | cli/http_util.rs | 17 | ||||
-rw-r--r-- | cli/tests/unit/fetch_test.ts | 80 |
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(); + }, +); |