This commit is contained in:
parent
40e942337f
commit
2126a142f4
4 changed files with 100 additions and 4 deletions
|
|
@ -168,7 +168,7 @@ impl MTPClient {
|
||||||
*/
|
*/
|
||||||
pub async fn connect(config: ClientConfig) -> Result<MTPConnection, CommunicationError> {
|
pub async fn connect(config: ClientConfig) -> Result<MTPConnection, CommunicationError> {
|
||||||
let (sender, receiver) =
|
let (sender, receiver) =
|
||||||
mtp_transport::connect(&config.url, config.server_cert(), Policy::default()).await?;
|
mtp_transport::connect(&config.url, config.server_cert(), config.policy).await?;
|
||||||
|
|
||||||
let version_str = format!("{}", PROTOCOL_VERSION);
|
let version_str = format!("{}", PROTOCOL_VERSION);
|
||||||
let mut ident = CommunicationValue::new(mtp_codec::CommunicationType::Identification)
|
let mut ident = CommunicationValue::new(mtp_codec::CommunicationType::Identification)
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ rustls = { version = "0.23.41" }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
rustls-native-certs = "0.8.4"
|
rustls-native-certs = "0.8.4"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
rcgen = "0.14"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rcgen = "0.14"
|
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "integration"
|
name = "integration"
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,65 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use mtp_common::CommunicationError;
|
use mtp_common::CommunicationError;
|
||||||
use rustls::{ClientConfig as RustlsClientConfig, RootCertStore, pki_types::pem::PemObject};
|
use rustls::{
|
||||||
|
ClientConfig as RustlsClientConfig, RootCertStore,
|
||||||
|
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
||||||
|
pki_types::{ServerName, UnixTime, pem::PemObject},
|
||||||
|
DigitallySignedStruct, SignatureScheme,
|
||||||
|
};
|
||||||
use wtransport::{ClientConfig, Endpoint};
|
use wtransport::{ClientConfig, Endpoint};
|
||||||
|
|
||||||
use crate::{ConnectionHandle, Policy, Receiver, Sender};
|
use crate::{ConnectionHandle, Policy, Receiver, Sender};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NoopCertVerifier;
|
||||||
|
|
||||||
|
impl ServerCertVerifier for NoopCertVerifier {
|
||||||
|
fn verify_server_cert(
|
||||||
|
&self,
|
||||||
|
_end_entity: &rustls::pki_types::CertificateDer<'_>,
|
||||||
|
_intermediates: &[rustls::pki_types::CertificateDer<'_>],
|
||||||
|
_server_name: &ServerName<'_>,
|
||||||
|
_ocsp_response: &[u8],
|
||||||
|
_now: UnixTime,
|
||||||
|
) -> Result<ServerCertVerified, rustls::Error> {
|
||||||
|
Ok(ServerCertVerified::assertion())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify_tls12_signature(
|
||||||
|
&self,
|
||||||
|
_message: &[u8],
|
||||||
|
_cert: &rustls::pki_types::CertificateDer<'_>,
|
||||||
|
_dss: &DigitallySignedStruct,
|
||||||
|
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||||
|
Ok(HandshakeSignatureValid::assertion())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify_tls13_signature(
|
||||||
|
&self,
|
||||||
|
_message: &[u8],
|
||||||
|
_cert: &rustls::pki_types::CertificateDer<'_>,
|
||||||
|
_dss: &DigitallySignedStruct,
|
||||||
|
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||||
|
Ok(HandshakeSignatureValid::assertion())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||||
|
vec![
|
||||||
|
SignatureScheme::RSA_PKCS1_SHA1,
|
||||||
|
SignatureScheme::RSA_PKCS1_SHA256,
|
||||||
|
SignatureScheme::RSA_PKCS1_SHA384,
|
||||||
|
SignatureScheme::RSA_PKCS1_SHA512,
|
||||||
|
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||||
|
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||||
|
SignatureScheme::RSA_PSS_SHA256,
|
||||||
|
SignatureScheme::RSA_PSS_SHA384,
|
||||||
|
SignatureScheme::RSA_PSS_SHA512,
|
||||||
|
SignatureScheme::ED25519,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn connect(
|
pub async fn connect(
|
||||||
url: &str,
|
url: &str,
|
||||||
server_cert: Option<Vec<u8>>,
|
server_cert: Option<Vec<u8>>,
|
||||||
|
|
@ -55,7 +109,30 @@ fn configure_client_with_cert(
|
||||||
client_config_from_roots(root_store, policy)
|
client_config_from_roots(root_store, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn client_config_insecure(policy: &Policy) -> Result<ClientConfig, CommunicationError> {
|
||||||
|
let mut tls_config = RustlsClientConfig::builder()
|
||||||
|
.dangerous()
|
||||||
|
.with_custom_certificate_verifier(Arc::new(NoopCertVerifier))
|
||||||
|
.with_no_client_auth();
|
||||||
|
|
||||||
|
tls_config.alpn_protocols = vec![b"h3".to_vec()];
|
||||||
|
|
||||||
|
Ok(ClientConfig::builder()
|
||||||
|
.with_bind_default()
|
||||||
|
.with_custom_tls(tls_config)
|
||||||
|
.keep_alive_interval(policy.keep_alive_interval)
|
||||||
|
.max_idle_timeout(policy.max_idle_timeout)
|
||||||
|
.map_err(|e| CommunicationError::Other(e.to_string()))?
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
|
||||||
fn configure_client_system_roots(policy: &Policy) -> Result<ClientConfig, CommunicationError> {
|
fn configure_client_system_roots(policy: &Policy) -> Result<ClientConfig, CommunicationError> {
|
||||||
|
// Check if insecure mode is enabled via env variable MTP_INSECURE
|
||||||
|
let insecure = std::env::var("MTP_INSECURE").is_ok();
|
||||||
|
if insecure {
|
||||||
|
// Insecure mode: skip certificate verification entirely
|
||||||
|
return client_config_insecure(policy);
|
||||||
|
}
|
||||||
let mut root_store = RootCertStore::empty();
|
let mut root_store = RootCertStore::empty();
|
||||||
|
|
||||||
// Load native certs
|
// Load native certs
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,16 @@ use std::net::{IpAddr, SocketAddr};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wtransport::{Connection as WTConnection, Endpoint, ServerConfig};
|
use wtransport::{Connection as WTConnection, Endpoint, ServerConfig};
|
||||||
|
|
||||||
|
fn generate_self_signed_cert() -> (Vec<u8>, Vec<u8>) {
|
||||||
|
let key_pair = rcgen::KeyPair::generate().unwrap();
|
||||||
|
let params =
|
||||||
|
rcgen::CertificateParams::new(vec!["localhost".into(), "127.0.0.1".into()]).unwrap();
|
||||||
|
let cert = params.self_signed(&key_pair).unwrap();
|
||||||
|
let cert_pem = cert.pem();
|
||||||
|
let key_pem = key_pair.serialize_pem();
|
||||||
|
(cert_pem.into_bytes(), key_pem.into_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Host {
|
pub struct Host {
|
||||||
incoming: tokio::sync::mpsc::Receiver<(Sender, Receiver)>,
|
incoming: tokio::sync::mpsc::Receiver<(Sender, Receiver)>,
|
||||||
local_addr: std::net::SocketAddr,
|
local_addr: std::net::SocketAddr,
|
||||||
|
|
@ -46,7 +56,16 @@ pub async fn host(
|
||||||
) -> Result<Host, CommunicationError> {
|
) -> Result<Host, CommunicationError> {
|
||||||
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||||
|
|
||||||
let server_config = configure_server(ip, port, cert_pem, key_pem, &policy).await?;
|
// When MTP_INSECURE is set, generate a self-signed cert so the host can
|
||||||
|
// run without externally-provided TLS credentials.
|
||||||
|
let is_insecure = std::env::var("MTP_INSECURE").is_ok();
|
||||||
|
let (use_cert_pem, use_key_pem) = if is_insecure {
|
||||||
|
generate_self_signed_cert()
|
||||||
|
} else {
|
||||||
|
(cert_pem, key_pem)
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_config = configure_server(ip, port, use_cert_pem, use_key_pem, &policy).await?;
|
||||||
let endpoint = Endpoint::server(server_config)
|
let endpoint = Endpoint::server(server_config)
|
||||||
.map_err(|e| CommunicationError::Other(format!("Endpoint creation failed: {}", e)))?;
|
.map_err(|e| CommunicationError::Other(format!("Endpoint creation failed: {}", e)))?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue