Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
mmastrac committed Apr 25, 2024
1 parent d0c273f commit 4ba9036
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 91 deletions.
23 changes: 9 additions & 14 deletions cli/args/mod.rs
Expand Up @@ -14,7 +14,8 @@ use deno_ast::SourceMapOption;
use deno_core::resolve_url_or_path;
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
use deno_npm::NpmSystemInfo;
use deno_runtime::deno_tls::rustls::pki_types::CertificateDer;
use deno_runtime::deno_tls::create_default_root_cert_store;
use deno_runtime::deno_tls::create_platform_cert_store;
use deno_runtime::deno_tls::RootCertStoreProvider;
use deno_semver::npm::NpmPackageReqReference;
use indexmap::IndexMap;
Expand Down Expand Up @@ -45,12 +46,10 @@ use deno_core::serde_json;
use deno_core::url::Url;
use deno_runtime::deno_node::PackageJson;


use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_tls::rustls_pemfile;
use deno_runtime::deno_tls::webpki_roots;
use deno_runtime::inspector_server::InspectorServer;
use deno_runtime::permissions::PermissionsOptions;
use deno_terminal::colors;
use dotenvy::from_filename;
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -602,7 +601,6 @@ pub fn get_root_cert_store(
maybe_ca_stores: Option<Vec<String>>,
maybe_ca_data: Option<CaData>,
) -> Result<RootCertStore, RootCertStoreLoadError> {
let mut root_cert_store = RootCertStore::empty();
let ca_stores: Vec<String> = maybe_ca_stores
.or_else(|| {
let env_ca_store = env::var("DENO_TLS_CA_STORE").ok()?;
Expand All @@ -616,21 +614,18 @@ pub fn get_root_cert_store(
})
.unwrap_or_else(|| vec!["mozilla".to_string()]);

let mut root_cert_store = RootCertStore::empty();
for store in ca_stores.iter() {
match store.as_str() {
"mozilla" => {
for ta in webpki_roots::TLS_SERVER_ROOTS {
root_cert_store.add(CertificateDer::from(ta.spki));
}
root_cert_store
.roots
.extend(create_default_root_cert_store().roots);
}
"system" => {
unreachable!()
// let roots: Vec<deno_runtime::deno_tls::deno_native_certs::Certificate> = load_native_certs().expect("could not load platform certs");
// for root in roots {
// root_cert_store
// .add(&rustls::Certificate(root.0))
// .expect("Failed to add platform cert to root cert store");
// }
root_cert_store
.roots
.extend(create_platform_cert_store().roots);
}
_ => {
return Err(RootCertStoreLoadError::UnknownStore(store.clone()));
Expand Down
30 changes: 26 additions & 4 deletions ext/tls/lib.rs
@@ -1,15 +1,18 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

pub use deno_native_certs;
use deno_native_certs::load_native_certs;
pub use rustls;
use rustls::pki_types::CertificateDer;
use rustls::pki_types::Der;
use rustls::pki_types::PrivateKeyDer;
use rustls::pki_types::PrivatePkcs1KeyDer;
use rustls::pki_types::PrivatePkcs8KeyDer;
use rustls::pki_types::PrivateSec1KeyDer;
use rustls::pki_types::ServerName;
use rustls::pki_types::TrustAnchor;
pub use rustls_pemfile;
pub use rustls_tokio_stream;
pub use rustls_tokio_stream::*;
pub use webpki;
pub use webpki_roots;

Expand All @@ -24,7 +27,6 @@ use rustls::client::WebPkiServerVerifier;
use rustls::ClientConfig;
use rustls::DigitallySignedStruct;
use rustls::Error;
use rustls::RootCertStore;
use rustls_pemfile::certs;
use rustls_pemfile::ec_private_keys;
use rustls_pemfile::pkcs8_private_keys;
Expand All @@ -36,6 +38,9 @@ use std::io::Cursor;
use std::net::IpAddr;
use std::sync::Arc;

pub type Certificate = rustls::pki_types::CertificateDer<'static>;
pub type PrivateKey = rustls::pki_types::PrivateKeyDer<'static>;
pub type RootCertStore = rustls::RootCertStore;

/// Lazily resolves the root cert store.
///
Expand Down Expand Up @@ -179,10 +184,27 @@ pub struct BasicAuth {

pub fn create_default_root_cert_store() -> RootCertStore {
let mut root_cert_store = RootCertStore::empty();
// TODO(@justinmchase): Consider also loading the system keychain here
for ta in webpki_roots::TLS_SERVER_ROOTS {
root_cert_store.add(CertificateDer::from(ta.spki));
root_cert_store.roots.push(TrustAnchor {
name_constraints: ta.name_constraints.map(|x| Der::from(x).to_owned()),
subject: ta.subject.into(),
subject_public_key_info: ta.spki.into(),
});
}
debug_assert!(!root_cert_store.is_empty());
root_cert_store
}

pub fn create_platform_cert_store() -> RootCertStore {
let mut root_cert_store = RootCertStore::empty();
let roots: Vec<deno_native_certs::Certificate> =
load_native_certs().expect("could not load platform certs");
for root in roots {
root_cert_store
.add(Certificate::from(root.0))
.expect("Failed to add platform cert to root cert store");
}
debug_assert!(!root_cert_store.is_empty());
root_cert_store
}

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/cert_tests.rs
Expand Up @@ -3,7 +3,7 @@
use deno_tls::rustls;
use deno_tls::rustls::ClientConnection;
use deno_tls::rustls_pemfile;
use deno_tls::rustls_tokio_stream::TlsStream;
use deno_tls::TlsStream;
use std::io::BufReader;
use std::io::Cursor;
use std::io::Read;
Expand Down
2 changes: 1 addition & 1 deletion tests/util/server/Cargo.toml
Expand Up @@ -19,8 +19,8 @@ async-stream = "0.3.3"
base64.workspace = true
bytes.workspace = true
console_static_text.workspace = true
deno_unsync = "0"
deno_tls.workspace = true
deno_unsync = "0"
denokv_proto.workspace = true
fastwebsockets.workspace = true
flate2 = { workspace = true, features = ["default"] }
Expand Down
114 changes: 45 additions & 69 deletions tests/util/server/src/https.rs
@@ -1,14 +1,15 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use anyhow::anyhow;
use deno_tls::load_certs;
use deno_tls::load_private_keys;
use deno_tls::rustls;
use deno_tls::rustls::server::WebPkiClientVerifier;
use deno_tls::RootCertStore;
use deno_tls::TlsStream;
use futures::Stream;
use futures::StreamExt;
use deno_tls::rustls;
use deno_tls::rustls::pki_types::CertificateDer;
use deno_tls::rustls::pki_types::PrivateKeyDer;
use deno_tls::rustls::pki_types::PrivatePkcs1KeyDer;
use deno_tls::rustls_tokio_stream::TlsStream;
use deno_tls::rustls_pemfile;
use std::io;
use std::io::Read;
use std::num::NonZeroUsize;
use std::result::Result;
use std::sync::Arc;
Expand Down Expand Up @@ -70,73 +71,48 @@ pub fn get_tls_config(
let key_file = std::fs::File::open(key_path)?;
let ca_file = std::fs::File::open(ca_path)?;

let certs: Vec<CertificateDer> = {
let mut cert_reader = io::BufReader::new(cert_file);
rustls_pemfile::certs(&mut cert_reader)
.unwrap()
.into_iter()
.map(CertificateDer::from)
.collect()
};
fn err_map<E>(e: E) -> io::Error
where
E: Into<Box<dyn std::error::Error + Send + Sync>>,
{
io::Error::new(io::ErrorKind::InvalidData, e)
}

let certs =
load_certs(&mut io::BufReader::new(cert_file)).map_err(err_map)?;

let mut ca_cert_reader = io::BufReader::new(ca_file);
let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader)
.expect("Cannot load CA certificate")
.remove(0);
let ca_cert = load_certs(&mut ca_cert_reader).map_err(err_map)?.remove(0);

let mut key_reader = io::BufReader::new(key_file);
let key = {
let pkcs8_key = rustls_pemfile::pkcs8_private_keys(&mut key_reader)
.expect("Cannot load key file");
let rsa_key = rustls_pemfile::rsa_private_keys(&mut key_reader)
.expect("Cannot load key file");
if !pkcs8_key.is_empty() {
Some(pkcs8_key[0].clone())
} else if !rsa_key.is_empty() {
Some(rsa_key[0].clone())
} else {
None
let mut key = vec![];
key_reader.read_to_end(&mut key)?;
let key = load_private_keys(&key).map_err(err_map)?.remove(0);

let mut root_cert_store = RootCertStore::empty();
root_cert_store.add(ca_cert).unwrap();

// Allow (but do not require) client authentication.
let verifier = WebPkiClientVerifier::builder(root_cert_store.into())
.allow_unauthenticated()
.build()
.map_err(err_map)?;

let mut config = rustls::ServerConfig::builder()
.with_client_cert_verifier(verifier)
.with_single_cert(certs, key)
.map_err(|e| anyhow!("Error setting cert: {:?}", e))
.unwrap();

match http_versions {
SupportedHttpVersions::All => {
config.alpn_protocols = vec!["h2".into(), "http/1.1".into()];
}
};

match key {
Some(key) => {
let mut root_cert_store = rustls::RootCertStore::empty();
root_cert_store
.add(rustls::pki_types::CertificateDer::from(ca_cert))
.unwrap();

// Allow (but do not require) client authentication.

let mut config = rustls::ServerConfig::builder()
// .dangerous()
// .with_client_cert_verifier(Arc::new(
// rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(
// root_cert_store,
// ),
// ))
// .with_single_cert(certs, PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(key)))
// .map_err(|e| anyhow!("Error setting cert: {:?}", e))
// .unwrap();
.with_no_client_auth()
.with_single_cert(
certs,
PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(key)),
)
.unwrap();

match http_versions {
SupportedHttpVersions::All => {
config.alpn_protocols = vec!["h2".into(), "http/1.1".into()];
}
SupportedHttpVersions::Http1Only => {}
SupportedHttpVersions::Http2Only => {
config.alpn_protocols = vec!["h2".into()];
}
}

Ok(Arc::new(config))
SupportedHttpVersions::Http1Only => {}
SupportedHttpVersions::Http2Only => {
config.alpn_protocols = vec!["h2".into()];
}
None => Err(io::Error::new(io::ErrorKind::Other, "Cannot find key")),
}

Ok(Arc::new(config))
}
2 changes: 1 addition & 1 deletion tests/util/server/src/servers/grpc.rs
@@ -1,10 +1,10 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use deno_tls::TlsStream;
use futures::StreamExt;
use h2;
use hyper::header::HeaderName;
use hyper::header::HeaderValue;
use rustls_tokio_stream::TlsStream;
use tokio::net::TcpStream;
use tokio::task::LocalSet;

Expand Down
3 changes: 2 additions & 1 deletion tests/util/server/src/servers/hyper_utils.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use bytes::Bytes;
use deno_tls::TlsStream;
use futures::Future;
use futures::FutureExt;
use futures::Stream;
Expand Down Expand Up @@ -69,7 +70,7 @@ pub async fn run_server_with_acceptor<'a, A, F, S>(
error_msg: &'static str,
kind: ServerKind,
) where
A: Stream<Item = io::Result<rustls_tokio_stream::TlsStream>> + ?Sized,
A: Stream<Item = io::Result<TlsStream>> + ?Sized,
F: Fn(Request<hyper::body::Incoming>) -> S + Copy + 'static,
S: Future<Output = HandlerOutput> + 'static,
{
Expand Down

0 comments on commit 4ba9036

Please sign in to comment.