diff --git a/src/main.rs b/src/main.rs index b1d3d34..5909cad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,12 @@ -use std::str::FromStr; +use std::{ + io::{Read, Write}, + net::TcpStream, + str::FromStr, + sync::Arc, +}; use anyhow::{bail, Result}; +use rustls::{ClientConfig, ClientConnection, OwnedTrustAnchor, RootCertStore, StreamOwned}; use trust_dns_resolver::{ config::{ResolverConfig, ResolverOpts}, Resolver, @@ -12,6 +18,25 @@ fn main() -> Result<()> { dbg!(port); dbg!(host); + let (port, host) = (443, "example.com".to_owned()); + + let tls_conf = Arc::new(make_tls_config()); + let mut tls_conn = make_tls_connection(tls_conf, &host, port)?; + + tls_conn.write_all( + concat!( + "GET / HTTP/1.1\r\n", + "Host: example.com\r\n", + "Connection: close\r\n", + "\r\n" + ) + .as_bytes(), + )?; + + let mut pt = Vec::new(); + tls_conn.read_to_end(&mut pt)?; + println!("{}", String::from_utf8(pt)?); + Ok(()) } @@ -41,3 +66,35 @@ fn make_dns_client() -> Result { ResolverOpts::default(), )?) } + +fn make_tls_config() -> ClientConfig { + let mut root_store = RootCertStore::empty(); + root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| { + OwnedTrustAnchor::from_subject_spki_name_constraints( + ta.subject, + ta.spki, + ta.name_constraints, + ) + })); + let config = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store) + .with_no_client_auth(); + + config +} + +fn make_tls_connection( + config: Arc, + server: &str, + port: u16, +) -> Result { + let server_name = server.try_into()?; + + let conn = ClientConnection::new(config, server_name)?; + let sock = TcpStream::connect((server, port))?; + + let stream = StreamOwned::new(conn, sock); + + Ok(stream) +}