summaryrefslogtreecommitdiff
path: root/ext/net/ops_tls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/net/ops_tls.rs')
-rw-r--r--ext/net/ops_tls.rs142
1 files changed, 79 insertions, 63 deletions
diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs
index e83173e90..874f795f2 100644
--- a/ext/net/ops_tls.rs
+++ b/ext/net/ops_tls.rs
@@ -12,9 +12,9 @@ use deno_core::error::bad_resource;
use deno_core::error::custom_error;
use deno_core::error::generic_error;
use deno_core::error::invalid_hostname;
-use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op2;
+use deno_core::v8;
use deno_core::AsyncRefCell;
use deno_core::AsyncResult;
use deno_core::CancelHandle;
@@ -31,7 +31,8 @@ use deno_tls::rustls::PrivateKey;
use deno_tls::rustls::ServerConfig;
use deno_tls::rustls::ServerName;
use deno_tls::SocketUse;
-use io::Read;
+use deno_tls::TlsKey;
+use deno_tls::TlsKeys;
use rustls_tokio_stream::TlsStreamRead;
use rustls_tokio_stream::TlsStreamWrite;
use serde::Deserialize;
@@ -43,9 +44,9 @@ use std::cell::RefCell;
use std::convert::From;
use std::convert::TryFrom;
use std::fs::File;
-use std::io;
use std::io::BufReader;
use std::io::ErrorKind;
+use std::io::Read;
use std::num::NonZeroUsize;
use std::path::Path;
use std::rc::Rc;
@@ -145,8 +146,6 @@ impl Resource for TlsStreamResource {
pub struct ConnectTlsArgs {
cert_file: Option<String>,
ca_certs: Vec<String>,
- cert: Option<String>,
- key: Option<String>,
alpn_protocols: Option<Vec<String>>,
}
@@ -160,6 +159,59 @@ pub struct StartTlsArgs {
}
#[op2]
+pub fn op_tls_key_null<'s>(
+ scope: &mut v8::HandleScope<'s>,
+) -> Result<v8::Local<'s, v8::Object>, AnyError> {
+ Ok(deno_core::cppgc::make_cppgc_object(scope, TlsKeys::Null))
+}
+
+#[op2]
+pub fn op_tls_key_static<'s>(
+ scope: &mut v8::HandleScope<'s>,
+ #[string] cert: String,
+ #[string] key: String,
+) -> Result<v8::Local<'s, v8::Object>, AnyError> {
+ let cert = load_certs(&mut BufReader::new(cert.as_bytes()))?;
+ let key = load_private_keys(key.as_bytes())?
+ .into_iter()
+ .next()
+ .unwrap();
+ Ok(deno_core::cppgc::make_cppgc_object(
+ scope,
+ TlsKeys::Static(TlsKey(cert, key)),
+ ))
+}
+
+/// Legacy op -- will be removed in Deno 2.0.
+#[op2]
+pub fn op_tls_key_static_from_file<'s, NP>(
+ state: &mut OpState,
+ scope: &mut v8::HandleScope<'s>,
+ #[string] api: String,
+ #[string] cert_file: String,
+ #[string] key_file: String,
+) -> Result<v8::Local<'s, v8::Object>, AnyError>
+where
+ NP: NetPermissions + 'static,
+{
+ {
+ let permissions = state.borrow_mut::<NP>();
+ permissions.check_read(Path::new(&cert_file), &api)?;
+ permissions.check_read(Path::new(&key_file), &api)?;
+ }
+
+ let cert = load_certs_from_file(&cert_file)?;
+ let key = load_private_keys_from_file(&key_file)?
+ .into_iter()
+ .next()
+ .unwrap();
+ Ok(deno_core::cppgc::make_cppgc_object(
+ scope,
+ TlsKeys::Static(TlsKey(cert, key)),
+ ))
+}
+
+#[op2]
#[serde]
pub fn op_tls_start<NP>(
state: Rc<RefCell<OpState>>,
@@ -251,6 +303,7 @@ pub async fn op_net_connect_tls<NP>(
state: Rc<RefCell<OpState>>,
#[serde] addr: IpAddr,
#[serde] args: ConnectTlsArgs,
+ #[cppgc] key_pair: &TlsKeys,
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError>
where
NP: NetPermissions + 'static,
@@ -297,18 +350,10 @@ where
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
- let cert_and_key = if args.cert.is_some() || args.key.is_some() {
- let cert = args
- .cert
- .ok_or_else(|| type_error("No certificate chain provided"))?;
- let key = args
- .key
- .ok_or_else(|| type_error("No private key provided"))?;
- Some((cert, key))
- } else {
- None
+ let cert_and_key = match key_pair {
+ TlsKeys::Null => None,
+ TlsKeys::Static(key) => Some(key.clone()),
};
-
let mut tls_config = create_client_config(
root_cert_store,
ca_certs,
@@ -373,12 +418,6 @@ impl Resource for TlsListenerResource {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListenTlsArgs {
- cert: Option<String>,
- // TODO(kt3k): Remove this option at v2.0.
- cert_file: Option<String>,
- key: Option<String>,
- // TODO(kt3k): Remove this option at v2.0.
- key_file: Option<String>,
alpn_protocols: Option<Vec<String>>,
reuse_port: bool,
}
@@ -389,6 +428,7 @@ pub fn op_net_listen_tls<NP>(
state: &mut OpState,
#[serde] addr: IpAddr,
#[serde] args: ListenTlsArgs,
+ #[cppgc] keys: &TlsKeys,
) -> Result<(ResourceId, IpAddr), AnyError>
where
NP: NetPermissions + 'static,
@@ -397,54 +437,30 @@ where
super::check_unstable(state, "Deno.listenTls({ reusePort: true })");
}
- let cert_file = args.cert_file.as_deref();
- let key_file = args.key_file.as_deref();
- let cert = args.cert.as_deref();
- let key = args.key.as_deref();
-
{
let permissions = state.borrow_mut::<NP>();
permissions
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenTls()")?;
- if let Some(path) = cert_file {
- permissions.check_read(Path::new(path), "Deno.listenTls()")?;
- }
- if let Some(path) = key_file {
- permissions.check_read(Path::new(path), "Deno.listenTls()")?;
- }
}
- let cert_chain = if cert_file.is_some() && cert.is_some() {
- return Err(generic_error("Both cert and certFile is specified. You can specify either one of them."));
- } else if let Some(path) = cert_file {
- load_certs_from_file(path)?
- } else if let Some(cert) = cert {
- load_certs(&mut BufReader::new(cert.as_bytes()))?
- } else {
- return Err(generic_error("`cert` is not specified."));
- };
- let key_der = if key_file.is_some() && key.is_some() {
- return Err(generic_error(
- "Both key and keyFile is specified. You can specify either one of them.",
- ));
- } else if let Some(path) = key_file {
- load_private_keys_from_file(path)?.remove(0)
- } else if let Some(key) = key {
- load_private_keys(key.as_bytes())?.remove(0)
- } else {
- return Err(generic_error("`key` is not specified."));
- };
-
- let mut tls_config = ServerConfig::builder()
+ let tls_config = ServerConfig::builder()
.with_safe_defaults()
- .with_no_client_auth()
- .with_single_cert(cert_chain, key_der)
- .map_err(|e| {
- custom_error(
- "InvalidData",
- format!("Error creating TLS certificate: {:?}", e),
- )
- })?;
+ .with_no_client_auth();
+
+ let mut tls_config = match keys {
+ TlsKeys::Null => {
+ unreachable!()
+ }
+ TlsKeys::Static(TlsKey(cert, key)) => {
+ tls_config.with_single_cert(cert.clone(), key.clone())
+ }
+ }
+ .map_err(|e| {
+ custom_error(
+ "InvalidData",
+ format!("Error creating TLS certificate: {:?}", e),
+ )
+ })?;
if let Some(alpn_protocols) = args.alpn_protocols {
tls_config.alpn_protocols =