summaryrefslogtreecommitdiff
path: root/ext/tls/lib.rs
diff options
context:
space:
mode:
authorAleksei Kosyrev <albnnc@gmail.com>2022-05-18 14:32:12 +0300
committerGitHub <noreply@github.com>2022-05-18 13:32:12 +0200
commit037466e9cdec913d0f146532fde28b26093267f1 (patch)
treec30c4aea060be94e3fcbc24b6723327e4b84379c /ext/tls/lib.rs
parent4d8261070095e49de68ca21ac3b564887039bd24 (diff)
fix(ext/tls): ability to ignore IP-address certificate errors (#14610)
Diffstat (limited to 'ext/tls/lib.rs')
-rw-r--r--ext/tls/lib.rs98
1 files changed, 80 insertions, 18 deletions
diff --git a/ext/tls/lib.rs b/ext/tls/lib.rs
index 66545ec7d..42ea5b05d 100644
--- a/ext/tls/lib.rs
+++ b/ext/tls/lib.rs
@@ -12,10 +12,12 @@ use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::Extension;
+use rustls::client::HandshakeSignatureValid;
use rustls::client::ServerCertVerified;
use rustls::client::ServerCertVerifier;
use rustls::client::StoresClientSessions;
use rustls::client::WebPkiVerifier;
+use rustls::internal::msgs::handshake::DigitallySignedStruct;
use rustls::Certificate;
use rustls::ClientConfig;
use rustls::Error;
@@ -38,6 +40,22 @@ pub fn init() -> Extension {
Extension::builder().build()
}
+struct DefaultSignatureVerification;
+
+impl ServerCertVerifier for DefaultSignatureVerification {
+ fn verify_server_cert(
+ &self,
+ _end_entity: &Certificate,
+ _intermediates: &[Certificate],
+ _server_name: &ServerName,
+ _scts: &mut dyn Iterator<Item = &[u8]>,
+ _ocsp_response: &[u8],
+ _now: SystemTime,
+ ) -> Result<ServerCertVerified, Error> {
+ Err(Error::General("Should not be used".to_string()))
+ }
+}
+
pub struct NoCertificateVerification(pub Vec<String>);
impl ServerCertVerifier for NoCertificateVerification {
@@ -50,28 +68,61 @@ impl ServerCertVerifier for NoCertificateVerification {
ocsp_response: &[u8],
now: SystemTime,
) -> Result<ServerCertVerified, Error> {
- if let ServerName::DnsName(dns_name) = server_name {
- let dns_name = dns_name.as_ref().to_owned();
- if self.0.is_empty() || self.0.contains(&dns_name) {
- Ok(ServerCertVerified::assertion())
- } else {
- let root_store = create_default_root_cert_store();
- let verifier = WebPkiVerifier::new(root_store, None);
- verifier.verify_server_cert(
- end_entity,
- intermediates,
- server_name,
- scts,
- ocsp_response,
- now,
- )
+ if self.0.is_empty() {
+ return Ok(ServerCertVerified::assertion());
+ }
+ let dns_name_or_ip_address = match server_name {
+ ServerName::DnsName(dns_name) => dns_name.as_ref().to_owned(),
+ ServerName::IpAddress(ip_address) => ip_address.to_string(),
+ _ => {
+ // NOTE(bartlomieju): `ServerName` is a non-exhaustive enum
+ // so we have this catch all errors here.
+ return Err(Error::General("Unknown `ServerName` variant".to_string()));
}
+ };
+ if self.0.contains(&dns_name_or_ip_address) {
+ Ok(ServerCertVerified::assertion())
} else {
- // NOTE(bartlomieju): `ServerName` is a non-exhaustive enum
- // so we have this catch all error here.
- Err(Error::General("Unknown `ServerName` variant".to_string()))
+ let root_store = create_default_root_cert_store();
+ let verifier = WebPkiVerifier::new(root_store, None);
+ verifier.verify_server_cert(
+ end_entity,
+ intermediates,
+ server_name,
+ scts,
+ ocsp_response,
+ now,
+ )
}
}
+
+ fn verify_tls12_signature(
+ &self,
+ message: &[u8],
+ cert: &rustls::Certificate,
+ dss: &DigitallySignedStruct,
+ ) -> Result<HandshakeSignatureValid, Error> {
+ if self.0.is_empty() {
+ return Ok(HandshakeSignatureValid::assertion());
+ }
+ filter_invalid_encoding_err(
+ DefaultSignatureVerification.verify_tls12_signature(message, cert, dss),
+ )
+ }
+
+ fn verify_tls13_signature(
+ &self,
+ message: &[u8],
+ cert: &rustls::Certificate,
+ dss: &DigitallySignedStruct,
+ ) -> Result<HandshakeSignatureValid, Error> {
+ if self.0.is_empty() {
+ return Ok(HandshakeSignatureValid::assertion());
+ }
+ filter_invalid_encoding_err(
+ DefaultSignatureVerification.verify_tls13_signature(message, cert, dss),
+ )
+ }
}
#[derive(Deserialize, Default, Debug, Clone)]
@@ -233,6 +284,17 @@ fn load_pkcs8_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
Ok(keys.into_iter().map(PrivateKey).collect())
}
+fn filter_invalid_encoding_err(
+ to_be_filtered: Result<HandshakeSignatureValid, Error>,
+) -> Result<HandshakeSignatureValid, Error> {
+ match to_be_filtered {
+ Err(Error::InvalidCertificateEncoding) => {
+ Ok(HandshakeSignatureValid::assertion())
+ }
+ res => res,
+ }
+}
+
pub fn load_private_keys(bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
let mut keys = load_rsa_keys(bytes)?;