diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/fetch/22_http_client.js | 1 | ||||
-rw-r--r-- | ext/fetch/lib.rs | 40 | ||||
-rw-r--r-- | ext/net/02_tls.js | 5 | ||||
-rw-r--r-- | ext/net/lib.deno_net.d.ts | 17 | ||||
-rw-r--r-- | ext/net/ops_tls.rs | 40 | ||||
-rw-r--r-- | ext/tls/lib.rs | 12 | ||||
-rw-r--r-- | ext/websocket/lib.rs | 2 |
7 files changed, 59 insertions, 58 deletions
diff --git a/ext/fetch/22_http_client.js b/ext/fetch/22_http_client.js index 60b069aa7..592256c71 100644 --- a/ext/fetch/22_http_client.js +++ b/ext/fetch/22_http_client.js @@ -19,6 +19,7 @@ * @returns {HttpClient} */ function createHttpClient(options) { + options.caCerts ??= []; return new HttpClient(core.opSync("op_create_http_client", options)); } diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index 3085e7826..b422c2741 100644 --- a/ext/fetch/lib.rs +++ b/ext/fetch/lib.rs @@ -40,8 +40,6 @@ use serde::Serialize; use std::borrow::Cow; use std::cell::RefCell; use std::convert::From; -use std::fs::File; -use std::io::Read; use std::path::Path; use std::path::PathBuf; use std::pin::Pin; @@ -87,7 +85,7 @@ pub fn init<P: FetchPermissions + 'static>( create_http_client( user_agent.clone(), root_cert_store.clone(), - None, + vec![], proxy.clone(), unsafely_ignore_certificate_errors.clone(), client_cert_chain_and_key.clone(), @@ -465,13 +463,10 @@ impl HttpClientResource { } } -#[derive(Deserialize, Default, Debug)] +#[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] -#[serde(default)] pub struct CreateHttpClientOptions { - ca_stores: Option<Vec<String>>, - ca_file: Option<String>, - ca_data: Option<ByteString>, + ca_certs: Vec<String>, proxy: Option<Proxy>, cert_chain: Option<String>, private_key: Option<String>, @@ -485,11 +480,6 @@ pub fn op_create_http_client<FP>( where FP: FetchPermissions + 'static, { - if let Some(ca_file) = args.ca_file.clone() { - let permissions = state.borrow_mut::<FP>(); - permissions.check_read(&PathBuf::from(ca_file))?; - } - if let Some(proxy) = args.proxy.clone() { let permissions = state.borrow_mut::<FP>(); let url = Url::parse(&proxy.url)?; @@ -512,13 +502,16 @@ where }; let defaults = state.borrow::<HttpClientDefaults>(); - let cert_data = - get_cert_data(args.ca_file.as_deref(), args.ca_data.as_deref())?; + let ca_certs = args + .ca_certs + .into_iter() + .map(|cert| cert.into_bytes()) + .collect::<Vec<_>>(); let client = create_http_client( defaults.user_agent.clone(), defaults.root_cert_store.clone(), - cert_data, + ca_certs, args.proxy, defaults.unsafely_ignore_certificate_errors.clone(), client_cert_chain_and_key, @@ -527,18 +520,3 @@ where let rid = state.resource_table.add(HttpClientResource::new(client)); Ok(rid) } - -fn get_cert_data( - ca_file: Option<&str>, - ca_data: Option<&[u8]>, -) -> Result<Option<Vec<u8>>, AnyError> { - if let Some(ca_data) = ca_data { - Ok(Some(ca_data.to_vec())) - } else if let Some(ca_file) = ca_file { - let mut buf = Vec::new(); - File::open(ca_file)?.read_to_end(&mut buf)?; - Ok(Some(buf)) - } else { - Ok(None) - } -} diff --git a/ext/net/02_tls.js b/ext/net/02_tls.js index 343ec2e4f..9f8fb314c 100644 --- a/ext/net/02_tls.js +++ b/ext/net/02_tls.js @@ -28,6 +28,7 @@ hostname = "127.0.0.1", transport = "tcp", certFile = undefined, + caCerts = [], certChain = undefined, privateKey = undefined, }) { @@ -36,6 +37,7 @@ hostname, transport, certFile, + caCerts, certChain, privateKey, }); @@ -70,12 +72,13 @@ async function startTls( conn, - { hostname = "127.0.0.1", certFile } = {}, + { hostname = "127.0.0.1", certFile = undefined, caCerts = [] } = {}, ) { const res = await opStartTls({ rid: conn.rid, hostname, certFile, + caCerts, }); return new Conn(res.rid, res.remoteAddr, res.localAddr); } diff --git a/ext/net/lib.deno_net.d.ts b/ext/net/lib.deno_net.d.ts index dd2e4677d..45f1194fb 100644 --- a/ext/net/lib.deno_net.d.ts +++ b/ext/net/lib.deno_net.d.ts @@ -121,8 +121,18 @@ declare namespace Deno { /** A literal IP address or host name that can be resolved to an IP address. * If not specified, defaults to `127.0.0.1`. */ hostname?: string; - /** Server certificate file. */ + /** + * @deprecated This option is deprecated and will be removed in a future + * release. + * + * Server certificate file. + */ certFile?: string; + /** A list of root certificates that will be used in addition to the + * default root certificates to verify the peer's certificate. + * + * Must be in PEM format. */ + caCerts?: string[]; } /** Establishes a secure connection over TLS (transport layer security) using @@ -131,10 +141,11 @@ declare namespace Deno { * be used (see also https://github.com/ctz/webpki-roots for specifics) * * ```ts + * const caCert = await Deno.readTextFile("./certs/my_custom_root_CA.pem"); * const conn1 = await Deno.connectTls({ port: 80 }); - * const conn2 = await Deno.connectTls({ certFile: "./certs/my_custom_root_CA.pem", hostname: "192.0.2.1", port: 80 }); + * const conn2 = await Deno.connectTls({ caCerts: [caCert], hostname: "192.0.2.1", port: 80 }); * const conn3 = await Deno.connectTls({ hostname: "[2001:db8::1]", port: 80 }); - * const conn4 = await Deno.connectTls({ certFile: "./certs/my_custom_root_CA.pem", hostname: "golang.org", port: 80}); + * const conn4 = await Deno.connectTls({ caCerts: [caCert], hostname: "golang.org", port: 80}); * ``` * * Requires `allow-net` permission. diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs index 17367af54..d6618440f 100644 --- a/ext/net/ops_tls.rs +++ b/ext/net/ops_tls.rs @@ -649,6 +649,7 @@ pub struct ConnectTlsArgs { hostname: String, port: u16, cert_file: Option<String>, + ca_certs: Vec<String>, cert_chain: Option<String>, private_key: Option<String>, } @@ -658,6 +659,7 @@ pub struct ConnectTlsArgs { struct StartTlsArgs { rid: ResourceId, cert_file: Option<String>, + ca_certs: Vec<String>, hostname: String, } @@ -685,13 +687,16 @@ where } } - let ca_data = match cert_file { - Some(path) => { - let mut buf = Vec::new(); - File::open(path)?.read_to_end(&mut buf)?; - Some(buf) - } - _ => None, + let mut ca_certs = args + .ca_certs + .into_iter() + .map(|s| s.into_bytes()) + .collect::<Vec<_>>(); + + if let Some(path) = cert_file { + let mut buf = Vec::new(); + File::open(path)?.read_to_end(&mut buf)?; + ca_certs.push(buf); }; let hostname_dns = DNSNameRef::try_from_ascii_str(hostname) @@ -724,7 +729,7 @@ where let tls_config = Arc::new(create_client_config( root_cert_store, - ca_data, + ca_certs, unsafely_ignore_certificate_errors, )?); let tls_stream = @@ -786,13 +791,16 @@ where } } - let ca_data = match cert_file { - Some(path) => { - let mut buf = Vec::new(); - File::open(path)?.read_to_end(&mut buf)?; - Some(buf) - } - _ => None, + let mut ca_certs = args + .ca_certs + .into_iter() + .map(|s| s.into_bytes()) + .collect::<Vec<_>>(); + + if let Some(path) = cert_file { + let mut buf = Vec::new(); + File::open(path)?.read_to_end(&mut buf)?; + ca_certs.push(buf); }; let root_cert_store = state @@ -812,7 +820,7 @@ where let remote_addr = tcp_stream.peer_addr()?; let mut tls_config = create_client_config( root_cert_store, - ca_data, + ca_certs, unsafely_ignore_certificate_errors, )?; diff --git a/ext/tls/lib.rs b/ext/tls/lib.rs index 7632da5e6..076ef59fb 100644 --- a/ext/tls/lib.rs +++ b/ext/tls/lib.rs @@ -136,7 +136,7 @@ pub fn create_default_root_cert_store() -> RootCertStore { pub fn create_client_config( root_cert_store: Option<RootCertStore>, - ca_data: Option<Vec<u8>>, + ca_certs: Vec<Vec<u8>>, unsafely_ignore_certificate_errors: Option<Vec<String>>, ) -> Result<ClientConfig, AnyError> { let mut tls_config = ClientConfig::new(); @@ -144,11 +144,11 @@ pub fn create_client_config( tls_config.root_store = root_cert_store.unwrap_or_else(create_default_root_cert_store); - // If a custom cert is specified, add it to the store - if let Some(cert) = ca_data { + // If custom certs are specified, add them to the store + for cert in ca_certs { let reader = &mut BufReader::new(Cursor::new(cert)); // This function does not return specific errors, if it fails give a generic message. - if let Err(_err) = tls_config.root_store.add_pem_file(reader) { + if let Err(()) = tls_config.root_store.add_pem_file(reader) { return Err(anyhow!("Unable to add pem file to certificate store")); } } @@ -215,14 +215,14 @@ pub fn load_private_keys(bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> { pub fn create_http_client( user_agent: String, root_cert_store: Option<RootCertStore>, - ca_data: Option<Vec<u8>>, + ca_certs: Vec<Vec<u8>>, proxy: Option<Proxy>, unsafely_ignore_certificate_errors: Option<Vec<String>>, client_cert_chain_and_key: Option<(String, String)>, ) -> Result<Client, AnyError> { let mut tls_config = create_client_config( root_cert_store, - ca_data, + ca_certs, unsafely_ignore_certificate_errors, )?; diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index f9f11e591..dbb88dc8d 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -252,7 +252,7 @@ where Some("wss") => { let tls_config = create_client_config( root_cert_store, - None, + vec![], unsafely_ignore_certificate_errors, )?; let tls_connector = TlsConnector::from(Arc::new(tls_config)); |