-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
does TLSAcceptor read early data? #70
Comments
I think you could use If you experiment and find that works a PR adding an example would be great 👍 |
I think I could try that. |
Early data reads must be handled separately from regular application data reads after the handshake completes. There are security implications for early data reads that require extra care. See RFC 8446 Appendix E.5 and RFC 8470 Section 3 for more information. |
I was writing a CTF challenge on this so that's why I'm interested 🙂 but after thinking about it I realize why it's better to always separate them
#[tokio::main]
async fn main() {
let certs = rustls_pemfile::certs(&mut std::fs::read("localhost.direct.crt").unwrap().as_slice())
.map(Result::unwrap)
.collect();
let key = rustls_pemfile::private_key(&mut std::fs::read("localhost.direct.key").unwrap().as_slice())
.unwrap()
.unwrap();
let tcp_listener = TcpListener::bind("0.0.0.0:8000").await.unwrap();
let server_config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)
.unwrap();
let tls_acceptor = TlsAcceptor::from(Arc::new(server_config));
let server_task = tokio::spawn(async move {
let (tcp_stream, _) = tcp_listener.accept().await.unwrap();
tls_acceptor.accept_with(tcp_stream, |connection| {
println!("{:?}", connection.early_data().is_some());
}).await.unwrap();
});
server_task.await.unwrap();
} If I run
|
Cool :-)
It should be appropriate to read early data here. You don't need to wait for the full handshake to complete, just for the peer to have sent a full client hello. I think the reason you always get let mut server_config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)
.unwrap();
server_config.max_early_data_size = xxxx;
I'm not sure off-hand. Someone more familiar with Tokio Rustls might have a better suggestion here. |
I use following code successfully, let mut stream = self.acceptor.accept(stream).await?;
let buf = if let Some(mut ed) = stream.get_mut().1.early_data() {
let mut buf = Vec::new();
ed.read_to_end(&mut buf)?;
Bytes::from(buf)
} else {
Bytes::new()
};
Ok(PeekableStream::new(stream, buf)) |
I have played around with this before.. Basically we have to start with something like this: diff --git i/src/common/handshake.rs w/src/common/handshake.rs
index d1272fd..dd75860 100644
--- i/src/common/handshake.rs
+++ w/src/common/handshake.rs
@@ -88,6 +88,12 @@ where
}
try_poll!(Pin::new(&mut tls_stream).poll_flush(cx));
+
+ if let Some(mut data) = session.early_data() {
+ let buf = Vec::new();
+ data.read_to_end(&mut buf).unwrap();
+ *state = TlsState::EarlyData(0, buf);
+ }
}
Poll::Ready(Ok(stream))
and then expose a way to read that early data to the application |
I think we can expose a |
hi, I was wondering if TLSAcceptor is able to read TLS1.3 early data? it looks like the early data test does not use TLSAcceptor
if so, is there a reason why?
The text was updated successfully, but these errors were encountered: