diff options
Diffstat (limited to 'packet-detector/src/bin/tls_client.rs')
| -rw-r--r-- | packet-detector/src/bin/tls_client.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/packet-detector/src/bin/tls_client.rs b/packet-detector/src/bin/tls_client.rs new file mode 100644 index 0000000..6098172 --- /dev/null +++ b/packet-detector/src/bin/tls_client.rs | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | //! mTLS test client | ||
| 2 | |||
| 3 | use std::sync::Arc; | ||
| 4 | use packet_detector::tls_util::LoggingVerifier; | ||
| 5 | use rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName}; | ||
| 6 | use rustls::version::TLS12; | ||
| 7 | use rustls::ClientConfig; | ||
| 8 | use tokio::io::{AsyncReadExt, AsyncWriteExt}; | ||
| 9 | use tokio::net::TcpStream; | ||
| 10 | use tokio_rustls::TlsConnector; | ||
| 11 | |||
| 12 | const CERT: &str = "client_cert.pem"; | ||
| 13 | const KEY: &str = "client_key.pem"; | ||
| 14 | |||
| 15 | fn load_creds() -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>), Box<dyn std::error::Error>> { | ||
| 16 | let cert_pem = std::fs::read_to_string(CERT)?; | ||
| 17 | let key_pem = std::fs::read_to_string(KEY)?; | ||
| 18 | let certs = rustls_pemfile::certs(&mut cert_pem.as_bytes()).collect::<Result<Vec<_>, _>>()?; | ||
| 19 | let key = rustls_pemfile::private_key(&mut key_pem.as_bytes())?.ok_or("No key")?; | ||
| 20 | Ok((certs, key)) | ||
| 21 | } | ||
| 22 | |||
| 23 | #[tokio::main] | ||
| 24 | async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
| 25 | rustls::crypto::ring::default_provider().install_default().ok(); | ||
| 26 | |||
| 27 | let host = std::env::args().nth(1).unwrap_or_else(|| "127.0.0.1".into()); | ||
| 28 | let port: u16 = std::env::args().nth(2).and_then(|s| s.parse().ok()).unwrap_or(8443); | ||
| 29 | |||
| 30 | let (certs, key) = load_creds()?; | ||
| 31 | println!("Connecting to {}:{} with client cert", host, port); | ||
| 32 | |||
| 33 | let config = ClientConfig::builder_with_protocol_versions(&[&TLS12]) | ||
| 34 | .dangerous() | ||
| 35 | .with_custom_certificate_verifier(Arc::new(LoggingVerifier)) | ||
| 36 | .with_client_auth_cert(certs, key)?; | ||
| 37 | |||
| 38 | let stream = TcpStream::connect(format!("{}:{}", host, port)).await?; | ||
| 39 | let mut tls = TlsConnector::from(Arc::new(config)) | ||
| 40 | .connect(ServerName::try_from(host.clone())?, stream).await?; | ||
| 41 | println!("TLS handshake complete!"); | ||
| 42 | |||
| 43 | let req = format!("GET / HTTP/1.1\r\nHost: {}\r\nConnection: close\r\n\r\n", host); | ||
| 44 | tls.write_all(req.as_bytes()).await?; | ||
| 45 | |||
| 46 | let mut resp = Vec::new(); | ||
| 47 | tls.read_to_end(&mut resp).await?; | ||
| 48 | println!("\n{}", String::from_utf8_lossy(&resp)); | ||
| 49 | |||
| 50 | Ok(()) | ||
| 51 | } | ||
