mirror of
https://github.com/MercuryWorkshop/epoxy-tls.git
synced 2025-05-13 14:30:02 -04:00
fix certificate tampered
This commit is contained in:
parent
5aeea21d29
commit
7c02aecc27
3 changed files with 106 additions and 31 deletions
|
@ -201,6 +201,7 @@ cfg_if! {
|
||||||
pub user_agent: String,
|
pub user_agent: String,
|
||||||
#[wasm_bindgen(getter_with_clone)]
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
pub pem_files: Vec<String>,
|
pub pem_files: Vec<String>,
|
||||||
|
pub disable_certificate_validation: bool,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
@ -212,6 +213,7 @@ cfg_if! {
|
||||||
pub redirect_limit: usize,
|
pub redirect_limit: usize,
|
||||||
#[wasm_bindgen(getter_with_clone)]
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
pub user_agent: String,
|
pub user_agent: String,
|
||||||
|
pub disable_certificate_validation: bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,6 +236,7 @@ impl Default for EpoxyClientOptions {
|
||||||
user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36".to_string(),
|
user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36".to_string(),
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
pem_files: Vec::new(),
|
pem_files: Vec::new(),
|
||||||
|
disable_certificate_validation: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,9 +369,9 @@ impl EpoxyClient {
|
||||||
redirect_limit: options.redirect_limit,
|
redirect_limit: options.redirect_limit,
|
||||||
user_agent: options.user_agent,
|
user_agent: options.user_agent,
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
certs_tampered: !options.pem_files.is_empty(),
|
certs_tampered: options.disable_certificate_validation || !options.pem_files.is_empty(),
|
||||||
#[cfg(not(feature = "full"))]
|
#[cfg(not(feature = "full"))]
|
||||||
certs_tampered: false,
|
certs_tampered: options.disable_certificate_validation,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,10 +608,9 @@ impl EpoxyClient {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if self.certs_tampered {
|
if self.certs_tampered {
|
||||||
response.headers_mut().insert(
|
response
|
||||||
HeaderName::from_static("X-Epoxy-CertsTampered"),
|
.headers_mut()
|
||||||
HeaderValue::from_static("true"),
|
.insert("X-Epoxy-CertsTampered", HeaderValue::from_static("true"));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let response_headers: Array = response
|
let response_headers: Array = response
|
||||||
|
@ -688,11 +690,11 @@ impl EpoxyClient {
|
||||||
if jv.is_array() {
|
if jv.is_array() {
|
||||||
let arr = Array::from(&jv);
|
let arr = Array::from(&jv);
|
||||||
arr.push(&v);
|
arr.push(&v);
|
||||||
object_set(&raw_headers, &k, arr.into());
|
object_set(&raw_headers, k, arr.into());
|
||||||
} else if jv.is_truthy() {
|
} else if jv.is_truthy() {
|
||||||
object_set(&raw_headers, &k, Array::of2(&jv, &v).into());
|
object_set(&raw_headers, k, Array::of2(&jv, &v).into());
|
||||||
} else {
|
} else {
|
||||||
object_set(&raw_headers, &k, v);
|
object_set(&raw_headers, k, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
utils::define_property(&resp, "rawHeaders", raw_headers.into());
|
utils::define_property(&resp, "rawHeaders", raw_headers.into());
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::{io::ErrorKind, pin::Pin, sync::Arc, task::Poll};
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use futures_rustls::{
|
use futures_rustls::{
|
||||||
rustls::{ClientConfig, RootCertStore},
|
rustls::{crypto::ring::default_provider, ClientConfig, RootCertStore},
|
||||||
TlsConnector,
|
TlsConnector,
|
||||||
};
|
};
|
||||||
use futures_util::{
|
use futures_util::{
|
||||||
|
@ -20,7 +20,11 @@ use wisp_mux::{
|
||||||
ClientMux, MuxStreamAsyncRW, MuxStreamIo, StreamType,
|
ClientMux, MuxStreamAsyncRW, MuxStreamIo, StreamType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{console_log, utils::IgnoreCloseNotify, EpoxyClientOptions, EpoxyError};
|
use crate::{
|
||||||
|
console_log,
|
||||||
|
utils::{IgnoreCloseNotify, NoCertificateVerification},
|
||||||
|
EpoxyClientOptions, EpoxyError,
|
||||||
|
};
|
||||||
|
|
||||||
pub type ProviderUnencryptedStream = MuxStreamIo;
|
pub type ProviderUnencryptedStream = MuxStreamIo;
|
||||||
pub type ProviderUnencryptedAsyncRW = MuxStreamAsyncRW;
|
pub type ProviderUnencryptedAsyncRW = MuxStreamAsyncRW;
|
||||||
|
@ -60,6 +64,13 @@ impl StreamProvider {
|
||||||
wisp_generator: ProviderWispTransportGenerator,
|
wisp_generator: ProviderWispTransportGenerator,
|
||||||
options: &EpoxyClientOptions,
|
options: &EpoxyClientOptions,
|
||||||
) -> Result<Self, EpoxyError> {
|
) -> Result<Self, EpoxyError> {
|
||||||
|
let client_config = if options.disable_certificate_validation {
|
||||||
|
ClientConfig::builder()
|
||||||
|
.dangerous()
|
||||||
|
.with_custom_certificate_verifier(Arc::new(NoCertificateVerification::new(
|
||||||
|
default_provider(),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(feature = "full")] {
|
if #[cfg(feature = "full")] {
|
||||||
let pems: Result<Result<Vec<_>, webpki::Error>, std::io::Error> = options
|
let pems: Result<Result<Vec<_>, webpki::Error>, std::io::Error> = options
|
||||||
|
@ -77,9 +88,8 @@ impl StreamProvider {
|
||||||
let certstore = RootCertStore::from_iter(TLS_SERVER_ROOTS.iter().cloned());
|
let certstore = RootCertStore::from_iter(TLS_SERVER_ROOTS.iter().cloned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ClientConfig::builder().with_root_certificates(certstore)
|
||||||
let client_config = ClientConfig::builder()
|
}
|
||||||
.with_root_certificates(certstore)
|
|
||||||
.with_no_client_auth();
|
.with_no_client_auth();
|
||||||
let client_config = Arc::new(client_config);
|
let client_config = Arc::new(client_config);
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,21 @@ use std::{
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bytes::{buf::UninitSlice, BufMut, Bytes, BytesMut};
|
use bytes::{buf::UninitSlice, BufMut, Bytes, BytesMut};
|
||||||
use futures_rustls::TlsStream;
|
use futures_rustls::{
|
||||||
|
rustls::{
|
||||||
|
self,
|
||||||
|
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
||||||
|
crypto::{verify_tls12_signature, verify_tls13_signature, CryptoProvider},
|
||||||
|
DigitallySignedStruct, SignatureScheme,
|
||||||
|
},
|
||||||
|
TlsStream,
|
||||||
|
};
|
||||||
use futures_util::{ready, AsyncRead, AsyncWrite, Future, Stream, StreamExt, TryStreamExt};
|
use futures_util::{ready, AsyncRead, AsyncWrite, Future, Stream, StreamExt, TryStreamExt};
|
||||||
use http::{HeaderValue, Uri};
|
use http::{HeaderValue, Uri};
|
||||||
use hyper::{body::Body, rt::Executor};
|
use hyper::{body::Body, rt::Executor};
|
||||||
use js_sys::{Array, ArrayBuffer, JsString, Object, Uint8Array};
|
use js_sys::{Array, ArrayBuffer, JsString, Object, Uint8Array};
|
||||||
use pin_project_lite::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
|
use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
|
||||||
use send_wrapper::SendWrapper;
|
use send_wrapper::SendWrapper;
|
||||||
use wasm_bindgen::{prelude::*, JsCast, JsValue};
|
use wasm_bindgen::{prelude::*, JsCast, JsValue};
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
|
@ -300,6 +309,60 @@ impl AsyncWrite for IgnoreCloseNotify {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NoCertificateVerification(CryptoProvider);
|
||||||
|
|
||||||
|
impl NoCertificateVerification {
|
||||||
|
pub fn new(provider: CryptoProvider) -> Self {
|
||||||
|
Self(provider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServerCertVerifier for NoCertificateVerification {
|
||||||
|
fn verify_server_cert(
|
||||||
|
&self,
|
||||||
|
_end_entity: &CertificateDer<'_>,
|
||||||
|
_intermediates: &[CertificateDer<'_>],
|
||||||
|
_server_name: &ServerName<'_>,
|
||||||
|
_ocsp: &[u8],
|
||||||
|
_now: UnixTime,
|
||||||
|
) -> Result<ServerCertVerified, rustls::Error> {
|
||||||
|
Ok(ServerCertVerified::assertion())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify_tls12_signature(
|
||||||
|
&self,
|
||||||
|
message: &[u8],
|
||||||
|
cert: &CertificateDer<'_>,
|
||||||
|
dss: &DigitallySignedStruct,
|
||||||
|
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||||
|
verify_tls12_signature(
|
||||||
|
message,
|
||||||
|
cert,
|
||||||
|
dss,
|
||||||
|
&self.0.signature_verification_algorithms,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify_tls13_signature(
|
||||||
|
&self,
|
||||||
|
message: &[u8],
|
||||||
|
cert: &CertificateDer<'_>,
|
||||||
|
dss: &DigitallySignedStruct,
|
||||||
|
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||||
|
verify_tls13_signature(
|
||||||
|
message,
|
||||||
|
cert,
|
||||||
|
dss,
|
||||||
|
&self.0.signature_verification_algorithms,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||||
|
self.0.signature_verification_algorithms.supported_schemes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_redirect(code: u16) -> bool {
|
pub fn is_redirect(code: u16) -> bool {
|
||||||
[301, 302, 303, 307, 308].contains(&code)
|
[301, 302, 303, 307, 308].contains(&code)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue