Skip to content

Commit

Permalink
fix: support "fetch" over HTTPS for IP addresses (#18499)
Browse files Browse the repository at this point in the history
This commit adds support for connecting to IP addresses over HTTPS.

This is done by updating "rustls" to "0.21.0" and other related crates.

Closes #7660
Closes #17967

---------

Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
  • Loading branch information
bartlomieju and littledivy committed May 17, 2023
1 parent 867a6d3 commit cb87cb0
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 46 deletions.
47 changes: 35 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ pretty_assertions = "=1.3.0"
rand = "=0.8.5"
regex = "^1.7.0"
lazy-regex = "2.5.0"
reqwest = { version = "0.11.11", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks"] }
reqwest = { version = "0.11.18", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks"] }
ring = "=0.16.20"
rusqlite = { version = "=0.28.0", features = ["unlock_notify", "bundled"] }
rustls = "0.20.5"
rustls = "0.21.0"
rustls-pemfile = "1.0.0"
serde = { version = "1.0.149", features = ["derive"] }
serde_bytes = "0.11"
Expand All @@ -136,7 +136,7 @@ thiserror = "1.0.40"
tokio = { version = "1.28.1", features = ["full"] }
tikv-jemallocator = "0.5.0"
tikv-jemalloc-sys = "0.5.3"
tokio-rustls = "0.23.3"
tokio-rustls = "0.24.0"
tokio-util = "0.7.4"
tower-lsp = { version = "=0.17.0", features = ["proposed"] }
url = { version = "2.3.1", features = ["serde", "expose_internals"] }
Expand Down
2 changes: 1 addition & 1 deletion cli/tests/testdata/cert/localhost_unsafe_ssl.ts.out
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
DANGER: TLS certificate validation is disabled for: deno.land
error: error sending request for url (https://localhost:5545/subdir/mod2.ts): error trying to connect: invalid peer certificate contents: invalid peer certificate: UnknownIssuer
error: error sending request for url (https://localhost:5545/subdir/mod2.ts): error trying to connect: invalid peer certificate: UnknownIssuer
at file:///[WILDCARD]/cafile_url_imports.ts:[WILDCARD]
5 changes: 4 additions & 1 deletion cli/tests/testdata/run/websocket_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ Deno.test("websocket error", async () => {
assert(err instanceof ErrorEvent);

// Error message got changed because we don't use warp in test_util
assertEquals(err.message, "InvalidData: received corrupt message");
assertEquals(
err.message,
"InvalidData: received corrupt message of type InvalidContentType",
);
promise1.resolve();
};
await promise1;
Expand Down
12 changes: 12 additions & 0 deletions cli/tests/unit/fetch_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,18 @@ Deno.test(
},
);

Deno.test(
{ permissions: { net: true, read: true } },
async function fetchSupportsHttpsOverIpAddress() {
const caCert = await Deno.readTextFile("cli/tests/testdata/tls/RootCA.pem");
const client = Deno.createHttpClient({ caCerts: [caCert] });
const res = await fetch("https://localhost:5546/http_version", { client });
assert(res.ok);
assertEquals(await res.text(), "HTTP/1.1");
client.close();
},
);

Deno.test(
{ permissions: { net: true, read: true } },
async function fetchSupportsHttp1Only() {
Expand Down
4 changes: 2 additions & 2 deletions cli/tests/unit/tls_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,7 @@ Deno.test(
await assertRejects(
() => conn.handshake(),
Deno.errors.InvalidData,
"BadCertificate",
"received fatal alert",
);
}
conn.close();
Expand Down Expand Up @@ -1368,7 +1368,7 @@ Deno.test(
await assertRejects(
() => tlsConn.handshake(),
Deno.errors.InvalidData,
"CertNotValidForName",
"NotValidForName",
);
tlsConn.close();
}
Expand Down
27 changes: 2 additions & 25 deletions ext/tls/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ pub use webpki_roots;
use deno_core::anyhow::anyhow;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;

use rustls::client::HandshakeSignatureValid;
use rustls::client::ServerCertVerified;
use rustls::client::ServerCertVerifier;
use rustls::client::StoresClientSessions;
use rustls::client::WebPkiVerifier;
use rustls::internal::msgs::handshake::DigitallySignedStruct;
use rustls::Certificate;
use rustls::ClientConfig;
use rustls::DigitallySignedStruct;
use rustls::Error;
use rustls::PrivateKey;
use rustls::RootCertStore;
Expand All @@ -27,7 +25,6 @@ use rustls_pemfile::certs;
use rustls_pemfile::pkcs8_private_keys;
use rustls_pemfile::rsa_private_keys;
use serde::Deserialize;
use std::collections::HashMap;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Cursor;
Expand Down Expand Up @@ -145,26 +142,6 @@ pub struct BasicAuth {
pub password: String,
}

#[derive(Default)]
struct ClientSessionMemoryCache(Mutex<HashMap<Vec<u8>, Vec<u8>>>);

impl StoresClientSessions for ClientSessionMemoryCache {
fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
self.0.lock().get(key).cloned()
}

fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool {
let mut sessions = self.0.lock();
// TODO(bnoordhuis) Evict sessions LRU-style instead of arbitrarily.
while sessions.len() >= 1024 {
let key = sessions.keys().next().unwrap().clone();
sessions.remove(&key);
}
sessions.insert(key, value);
true
}
}

pub fn create_default_root_cert_store() -> RootCertStore {
let mut root_cert_store = RootCertStore::empty();
// TODO(@justinmchase): Consider also loading the system keychain here
Expand Down Expand Up @@ -293,7 +270,7 @@ fn filter_invalid_encoding_err(
to_be_filtered: Result<HandshakeSignatureValid, Error>,
) -> Result<HandshakeSignatureValid, Error> {
match to_be_filtered {
Err(Error::InvalidCertificateEncoding) => {
Err(Error::InvalidCertificate(rustls::CertificateError::BadEncoding)) => {
Ok(HandshakeSignatureValid::assertion())
}
res => res,
Expand Down
4 changes: 2 additions & 2 deletions test_util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,11 +488,11 @@ async fn get_tls_config(

let mut config = rustls::ServerConfig::builder()
.with_safe_defaults()
.with_client_cert_verifier(
.with_client_cert_verifier(Arc::new(
rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(
root_cert_store,
),
)
))
.with_single_cert(certs, PrivateKey(key))
.map_err(|e| anyhow!("Error setting cert: {:?}", e))
.unwrap();
Expand Down

0 comments on commit cb87cb0

Please sign in to comment.