mirror of
https://github.com/Noratrieb/tls.git
synced 2026-01-14 16:45:02 +01:00
expect byte test
This commit is contained in:
parent
57f6feb70a
commit
800ff88a6d
3 changed files with 84 additions and 14 deletions
27
src/lib.rs
27
src/lib.rs
|
|
@ -2,30 +2,31 @@ pub mod proto;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
io::{self, BufWriter, Read, Write},
|
io::{self, Read, Write},
|
||||||
net::TcpStream,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::proto::TLSPlaintext;
|
use crate::proto::TLSPlaintext;
|
||||||
|
|
||||||
type Result<T, E = Error> = std::result::Result<T, E>;
|
type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
||||||
pub struct ClientConnection {}
|
pub struct ClientConnection<W> {
|
||||||
|
_w: W,
|
||||||
|
}
|
||||||
|
|
||||||
impl ClientConnection {
|
impl<W: Read + Write> ClientConnection<W> {
|
||||||
pub fn establish(host: &str, port: u16) -> Result<Self> {
|
pub fn establish(w: W, host: &str) -> Result<Self> {
|
||||||
let _setup = ClientSetupConnection::establish(host, port)?;
|
let _setup = ClientSetupConnection::establish(w, host)?;
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClientSetupConnection {}
|
struct ClientSetupConnection<W> {
|
||||||
|
_w: W,
|
||||||
impl ClientSetupConnection {
|
}
|
||||||
fn establish(host: &str, port: u16) -> Result<Self> {
|
|
||||||
let mut stream = BufWriter::new(LoggingWriter(TcpStream::connect((host, port))?));
|
|
||||||
|
|
||||||
|
impl<W: Read + Write> ClientSetupConnection<W> {
|
||||||
|
fn establish(mut stream: W, host: &str) -> Result<Self> {
|
||||||
let secret = x25519_dalek::EphemeralSecret::random_from_rng(rand::thread_rng());
|
let secret = x25519_dalek::EphemeralSecret::random_from_rng(rand::thread_rng());
|
||||||
let public = x25519_dalek::PublicKey::from(&secret);
|
let public = x25519_dalek::PublicKey::from(&secret);
|
||||||
|
|
||||||
|
|
@ -82,7 +83,7 @@ impl ClientSetupConnection {
|
||||||
plaintext.write(&mut stream)?;
|
plaintext.write(&mut stream)?;
|
||||||
stream.flush()?;
|
stream.flush()?;
|
||||||
|
|
||||||
let out = proto::TLSPlaintext::read(stream.get_mut())?;
|
let out = proto::TLSPlaintext::read(&mut stream)?;
|
||||||
dbg!(&out);
|
dbg!(&out);
|
||||||
|
|
||||||
if matches!(out, TLSPlaintext::Handshake { handshake } if handshake.is_hello_retry_request())
|
if matches!(out, TLSPlaintext::Handshake { handshake } if handshake.is_hello_retry_request())
|
||||||
|
|
@ -125,7 +126,7 @@ impl From<ErrorKind> for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct LoggingWriter<W>(W);
|
pub struct LoggingWriter<W>(pub W);
|
||||||
|
|
||||||
impl<W: io::Write> io::Write for LoggingWriter<W> {
|
impl<W: io::Write> io::Write for LoggingWriter<W> {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
use std::net::TcpStream;
|
||||||
|
|
||||||
// An example program that makes a shitty HTTP/1.1 request.
|
// An example program that makes a shitty HTTP/1.1 request.
|
||||||
fn main() {
|
fn main() {
|
||||||
tls::ClientConnection::establish("nilstrieb.dev", 443).unwrap();
|
let conn = tls::LoggingWriter(TcpStream::connect(("nilstrieb.dev", 443)).unwrap());
|
||||||
|
tls::ClientConnection::establish(conn, "nilstrieb.dev").unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
66
tests/expect.rs
Normal file
66
tests/expect.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
struct ExpectServer {
|
||||||
|
expect: Vec<Expect>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExpectServer {
|
||||||
|
fn new(expect: Vec<Expect>) -> Self {
|
||||||
|
ExpectServer { expect }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Read for ExpectServer {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
let Some(Expect::Server(server)) = self.expect.first_mut() else {
|
||||||
|
panic!("Reading from server, but client input is expected");
|
||||||
|
};
|
||||||
|
|
||||||
|
let len = std::cmp::min(buf.len(), server.len());
|
||||||
|
buf[..len].copy_from_slice(&mut server[..len]);
|
||||||
|
server.rotate_left(len);
|
||||||
|
server.truncate(server.len() - len);
|
||||||
|
if server.is_empty() {
|
||||||
|
self.expect.remove(0);
|
||||||
|
}
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for ExpectServer {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
|
let Some(Expect::Client(client)) = self.expect.first_mut() else {
|
||||||
|
panic!("Writing as client, but should read instead");
|
||||||
|
};
|
||||||
|
|
||||||
|
let to_write = client
|
||||||
|
.get(..buf.len())
|
||||||
|
.expect("writing more bytes than expected");
|
||||||
|
assert_eq!(to_write, buf);
|
||||||
|
client.rotate_left(buf.len());
|
||||||
|
client.truncate(client.len() - buf.len());
|
||||||
|
if client.is_empty() {
|
||||||
|
self.expect.remove(0);
|
||||||
|
}
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Expect {
|
||||||
|
Server(Vec<u8>),
|
||||||
|
Client(Vec<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn connect() {
|
||||||
|
let mut expect = ExpectServer::new(vec![
|
||||||
|
Expect::Client(vec![0]), // TODO: do this
|
||||||
|
]);
|
||||||
|
|
||||||
|
let conn = tls::ClientConnection::establish(&mut expect, "example.com").unwrap();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue