Add option to disable tls verification in sock_connect

This commit is contained in:
kpcyrd
2019-07-26 20:00:52 +02:00
parent c8d0d0d610
commit 95f935a109
7 changed files with 77 additions and 2 deletions

View File

@@ -40,7 +40,7 @@ dirs = "2.0"
url = "1.7"
#chrootable-https = { path = "../chrootable-https" }
chrootable-https = "0.10"
rustls = "0.15"
rustls = { version="0.15", features=["dangerous_configuration"] }
webpki = "0.19"
webpki-roots = "0.16.0"
pem = "0.6.0"

View File

@@ -760,6 +760,10 @@ The following options are available:
Set to true to enable tls (certificates are validated)
``sni_value``
Instead of the host argument, use a custom string for the sni extension.
``disable_tls_verify``
**Danger**: disable tls verification. This disables all security on the
connection. Note that sn0int is still rather strict, you're going to run into
issues if you need support for insecure ciphers.
.. code-block:: lua

View File

@@ -0,0 +1,16 @@
-- Description: TODO your description here
-- Version: 0.1.0
-- License: GPL-3.0
function run()
sock = sock_connect('expired.badssl.com', 443, {})
if last_err() then return end
tls = sock_upgrade_tls(sock, {
sni_value='expired.badssl.com',
disable_tls_verify=true,
})
if last_err() then return end
info(tls)
end

17
modules/harness/tls.lua Normal file
View File

@@ -0,0 +1,17 @@
-- Description: TODO your description here
-- Version: 0.1.0
-- License: GPL-3.0
function run()
sock = sock_connect('badssl.com', 443, {})
if last_err() then return end
tls = sock_upgrade_tls(sock, {
sni_value='badssl.com',
})
if last_err() then return end
info(tls)
info(x509_parse_pem(tls['cert']))
end

View File

@@ -267,4 +267,18 @@ mod tests {
"#).expect("failed to load script");
script.test().expect("Script failed");
}
#[test]
#[ignore]
fn verify_tls_connect_insecure() {
let script = Script::load_unchecked(r#"
function run()
sock = sock_connect('expired.badssl.com', 443, {
tls=true,
disable_tls_verify=true,
})
end
"#).expect("failed to load script");
script.test().expect("Script failed");
}
}

View File

@@ -40,11 +40,12 @@ pub struct SocketOptions {
#[serde(default)]
pub tls: bool,
sni_value: Option<String>,
#[serde(default)]
disable_tls_verify: bool,
// TODO: enable_sni (default to true)
// TODO: cacert
// TODO: timeout
// TODO: tls_verify (default to true)
}
impl SocketOptions {

View File

@@ -5,6 +5,7 @@ use crate::json::LuaJsonValue;
use rustls::{self, ClientConfig, Session, ClientSession, RootCertStore};
use std::str;
use std::result;
use std::sync::Arc;
use std::net::TcpStream;
@@ -42,6 +43,12 @@ pub fn wrap(stream: TcpStream, host: &str, options: &SocketOptions) -> Result<(S
let mut config = ClientConfig::new();
config.root_store = anchors;
if options.disable_tls_verify {
info!("tls verification has been disabled");
config.dangerous()
.set_certificate_verifier(Arc::new(NoCertificateVerification {}));
}
let dns_name = if let Some(v) = &options.sni_value {
get_dns_name(&mut config, &v)
} else {
@@ -55,8 +62,10 @@ pub fn wrap(stream: TcpStream, host: &str, options: &SocketOptions) -> Result<(S
fn get_dns_name(config: &mut ClientConfig, host: &str) -> webpki::DNSName {
if let Ok(name) = webpki::DNSNameRef::try_from_ascii_str(&host) {
debug!("setting sni value to: {:?}", host);
name.to_owned()
} else {
debug!("sni extension has been disabled");
config.enable_sni = false;
webpki::DNSNameRef::try_from_ascii_str("invalid.com")
.unwrap()
@@ -65,6 +74,7 @@ fn get_dns_name(config: &mut ClientConfig, host: &str) -> webpki::DNSName {
}
fn setup(mut stream: TcpStream, mut session: ClientSession) -> Result<(Socket, TlsData)> {
info!("starting tls handshake");
if session.is_handshaking() {
session.complete_io(&mut stream)?;
}
@@ -93,7 +103,20 @@ fn setup(mut stream: TcpStream, mut session: ClientSession) -> Result<(Socket, T
tls.cert = tls.cert_chain.last()
.map(|x| x.to_owned());
info!("successfully established tls connection");
let stream = rustls::StreamOwned::new(session, stream);
let stream = Stream::Tls(stream);
Ok((Socket::new(stream), tls))
}
pub struct NoCertificateVerification {}
impl rustls::ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(&self,
_roots: &rustls::RootCertStore,
_presented_certs: &[rustls::Certificate],
_dns_name: webpki::DNSNameRef<'_>,
_ocsp: &[u8]) -> result::Result<rustls::ServerCertVerified, rustls::TLSError> {
Ok(rustls::ServerCertVerified::assertion())
}
}