Skip to content

Commit

Permalink
Support native certs
Browse files Browse the repository at this point in the history
  • Loading branch information
justinmchase committed Jul 26, 2021
1 parent dfba7a2 commit a60f607
Show file tree
Hide file tree
Showing 23 changed files with 382 additions and 207 deletions.
64 changes: 59 additions & 5 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pin-project = "1.0.7"
regex = "1.4.3"
rand = { version = "0.8.4", features = [ "small_rng" ] }
ring = "0.16.20"
rustls-native-certs = "0.5.0"
rustyline = { version = "8.2.0", default-features = false }
rustyline-derive = "0.4.0"
semver-parser = "0.10.2"
Expand All @@ -91,6 +92,7 @@ tokio = { version = "1.8.1", features = ["full"] }
tokio-rustls = "0.22.0"
uuid = { version = "0.8.2", features = ["v4", "serde"] }
walkdir = "2.3.2"
webpki-roots = "0.21.1"

[target.'cfg(windows)'.dependencies]
fwdansi = "1.1.0"
Expand Down
12 changes: 9 additions & 3 deletions cli/file_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use crate::auth_tokens::AuthTokens;
use crate::colors;
use crate::http_cache::HttpCache;
use crate::http_util::create_http_client;
use crate::http_util::fetch_once;
use crate::http_util::FetchOnceArgs;
use crate::http_util::FetchOnceResult;
Expand All @@ -17,7 +16,9 @@ use deno_core::error::uri_error;
use deno_core::error::AnyError;
use deno_core::futures;
use deno_core::futures::future::FutureExt;
use deno_core::http::create_http_client;
use deno_core::parking_lot::Mutex;
use deno_core::rustls::RootCertStore;
use deno_core::ModuleSpecifier;
use deno_runtime::deno_fetch::reqwest;
use deno_runtime::deno_web::BlobStore;
Expand Down Expand Up @@ -220,7 +221,7 @@ impl FileFetcher {
http_cache: HttpCache,
cache_setting: CacheSetting,
allow_remote: bool,
ca_data: Option<Vec<u8>>,
root_store: Option<RootCertStore>,
blob_store: BlobStore,
) -> Result<Self, AnyError> {
Ok(Self {
Expand All @@ -229,7 +230,12 @@ impl FileFetcher {
cache: Default::default(),
cache_setting,
http_cache,
http_client: create_http_client(get_user_agent(), ca_data)?,
http_client: create_http_client(
get_user_agent(),
root_store,
None,
None,
)?,
blob_store,
})
}
Expand Down
6 changes: 6 additions & 0 deletions cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ pub struct Flags {
pub allow_read: Option<Vec<PathBuf>>,
pub allow_run: Option<Vec<String>>,
pub allow_write: Option<Vec<PathBuf>>,
pub location: Option<Url>,
pub cache_blocklist: Vec<String>,
pub ca_stores: Option<Vec<String>>,
pub ca_file: Option<String>,
pub cache_blocklist: Vec<String>,
pub cached_only: bool,
Expand Down Expand Up @@ -264,6 +267,9 @@ static ENV_VARIABLES_HELP: &str = r#"ENVIRONMENT VARIABLES:
hostnames to use when fetching remote modules from
private repositories
(e.g. "abcde12345@deno.land;54321edcba@github.com")
DENO_TLS_CA_STORE Comma-seperated list of order dependent certificate stores
(system, mozilla)
(defaults to mozilla)
DENO_CERT Load certificate authority from PEM encoded file
DENO_DIR Set the cache directory
DENO_INSTALL_ROOT Set deno install's output directory
Expand Down
39 changes: 10 additions & 29 deletions cli/http_util.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,18 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

use crate::auth_tokens::AuthToken;

use deno_core::error::generic_error;
use deno_core::error::AnyError;
use deno_core::url::Url;
use deno_runtime::deno_fetch::reqwest;
use deno_runtime::deno_fetch::reqwest::header::HeaderMap;
use deno_runtime::deno_fetch::reqwest::header::HeaderValue;
use deno_runtime::deno_fetch::reqwest::header::AUTHORIZATION;
use deno_runtime::deno_fetch::reqwest::header::IF_NONE_MATCH;
use deno_runtime::deno_fetch::reqwest::header::LOCATION;
use deno_runtime::deno_fetch::reqwest::header::USER_AGENT;
use deno_runtime::deno_fetch::reqwest::redirect::Policy;
use deno_runtime::deno_fetch::reqwest::Client;
use deno_runtime::deno_fetch::reqwest::StatusCode;
use log::debug;
use std::collections::HashMap;

/// Create new instance of async reqwest::Client. This client supports
/// proxies and doesn't follow redirects.
pub fn create_http_client(
user_agent: String,
ca_data: Option<Vec<u8>>,
) -> Result<Client, AnyError> {
let mut headers = HeaderMap::new();
headers.insert(USER_AGENT, user_agent.parse().unwrap());
let mut builder = Client::builder()
.redirect(Policy::none())
.default_headers(headers)
.use_rustls_tls();

if let Some(ca_data) = ca_data {
let cert = reqwest::Certificate::from_pem(&ca_data)?;
builder = builder.add_root_certificate(cert);
}

builder
.build()
.map_err(|e| generic_error(format!("Unable to build http client: {}", e)))
}

/// Construct the next uri based on base uri and location header fragment
/// See <https://tools.ietf.org/html/rfc3986#section-4.2>
fn resolve_url_from_location(base_url: &Url, location: &str) -> Url {
Expand Down Expand Up @@ -168,10 +140,11 @@ pub async fn fetch_once(
mod tests {
use super::*;
use crate::version;
use deno_core::http::create_http_client;
use std::fs::read;

fn create_test_client(ca_data: Option<Vec<u8>>) -> Client {
create_http_client("test_client".to_string(), ca_data).unwrap()
create_http_client("test_client".to_string(), None, ca_data, None).unwrap()
}

#[tokio::test]
Expand Down Expand Up @@ -362,6 +335,7 @@ mod tests {

let client = create_http_client(
version::get_user_agent(),
None,
Some(
read(
test_util::root_path()
Expand All @@ -371,6 +345,7 @@ mod tests {
)
.unwrap(),
),
None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
Expand Down Expand Up @@ -400,6 +375,7 @@ mod tests {
.unwrap();
let client = create_http_client(
version::get_user_agent(),
None,
Some(
read(
test_util::root_path()
Expand All @@ -409,6 +385,7 @@ mod tests {
)
.unwrap(),
),
None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
Expand Down Expand Up @@ -437,6 +414,7 @@ mod tests {
let url = Url::parse("https://localhost:5545/etag_script.ts").unwrap();
let client = create_http_client(
version::get_user_agent(),
None,
Some(
read(
test_util::root_path()
Expand All @@ -446,6 +424,7 @@ mod tests {
)
.unwrap(),
),
None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
Expand Down Expand Up @@ -488,6 +467,7 @@ mod tests {
.unwrap();
let client = create_http_client(
version::get_user_agent(),
None,
Some(
read(
test_util::root_path()
Expand All @@ -497,6 +477,7 @@ mod tests {
)
.unwrap(),
),
None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
Expand Down
4 changes: 2 additions & 2 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn create_web_worker_callback(
.log_level
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
ca_data: program_state.ca_data.clone(),
root_store: program_state.root_store.clone(),
user_agent: version::get_user_agent(),
seed: program_state.flags.seed,
module_loader,
Expand Down Expand Up @@ -188,7 +188,7 @@ pub fn create_main_worker(
.log_level
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
ca_data: program_state.ca_data.clone(),
root_store: program_state.root_store.clone(),
user_agent: version::get_user_agent(),
seed: program_state.flags.seed,
js_error_create_fn: Some(js_error_create_fn),
Expand Down
Loading

0 comments on commit a60f607

Please sign in to comment.