-
Notifications
You must be signed in to change notification settings - Fork 128
Allow pass TLS context from third-party TLS provider to application layer #2448
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
Conversation
Hi WeiChao. Are you still planning to work on this? |
sure, this is initial implementation, Is it right way fix this issue? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good! We'll need to get the s2n-tls method merged and released before merging this though.
quic/s2n-quic-core/src/crypto/tls.rs
Outdated
@@ -130,6 +130,8 @@ pub trait Context<Crypto: crate::crypto::CryptoSuite> { | |||
//# peer's Finished message. | |||
fn on_handshake_complete(&mut self) -> Result<(), crate::transport::Error>; | |||
|
|||
/// Transfer application context from TLS connection to quic connection | |||
fn on_application_context(&mut self, _context: Option<Box<dyn Any + Send + Sync>>) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can leave out the default impl here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
quic/s2n-quic-tls/src/session.rs
Outdated
@@ -155,6 +156,10 @@ impl tls::Session for Session { | |||
context.on_tls_exporter_ready(self)?; | |||
self.handshake_complete = true; | |||
} | |||
// TODO Add new s2n-tls new api, take and put in quic::connection | |||
let ctx: Option<Box<dyn Any + Send + Sync>> = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need a 'static
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any already has 'static https://doc.rust-lang.org/std/any/trait.Any.html
Does you add |
I won't have time for the next few weeks, unfortunately. If you want to take a stab at it, that would definitely help get this through :) |
Sure, I will do. but let me try #2446 (comment) first :) |
Hi, I want to merge this PR now. It's good to see After this PR get merged, following issue can be closed. |
@camshaft Hi, I have fixed CI issue, could you re-run it? |
fixed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're up for it, I think we also need a test for this feature just to make sure it works right now and to prevent regressions in the future. I think the simplest approach is to extend the null TLS provider to take a context as part of its construction and show that everything gets threaded through all the way. You can add your test in
https://github.com/aws/s2n-quic/blob/main/quic/s2n-quic/src/tests/no_tls.rs
use core::{mem::size_of, task::Poll}; | ||
|
||
#[derive(Debug)] | ||
pub struct Endpoint(pub UserProvidedTlsContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a new endpoint just for this. I think it would be better to have the existing null TLS provider take an Option<Box<dyn Any>>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need clone it(new_server_session
take &mut self
), But Clone isn't dyn compatible, Box<dyn Any + Clone> don't works
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rewrite to use generic over T, you can decide accept generic or keep original
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting close! Just a few more changes :)
|
||
#[derive(Debug)] | ||
pub struct Endpoint(()); | ||
pub struct Endpoint<T = ()>(pub Option<T>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not to make this public but have it be passed in a Endpoint::new
function. That will allow us to add new fields, if needed, in the future.
quic/s2n-quic-core/src/crypto/tls.rs
Outdated
@@ -130,6 +130,9 @@ pub trait Context<Crypto: crate::crypto::CryptoSuite> { | |||
//# peer's Finished message. | |||
fn on_handshake_complete(&mut self) -> Result<(), crate::transport::Error>; | |||
|
|||
/// Set TLS context and transfer from TLS provider to application layer. | |||
#[cfg(feature = "alloc")] | |||
fn on_tls_context(&mut self, _context: Option<alloc::boxed::Box<dyn Any + Send>>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking through everything, is there a reason this isn't just Box<dyn Any + send>
instead of Option<...>
. I think it would be better to only call this method if there is a context available.
/// Take TLS context came from TLS layer to application layer. | ||
/// | ||
/// Calling it a second time will always return None so applications should store it somewhere. | ||
/// | ||
/// # Example | ||
/// It's useful when you implement your own TLS provider. Some HTTP/3 server need more | ||
/// information from TLS layer to decide which configuration to apply, So you can | ||
/// | ||
/// 1. Create own TLS provider, in that, parse TLS manually, set tls context by | ||
/// `context.on_tls_context(Box::new(MyContext{}))` | ||
/// 2. After `let connection = server.accept().await` returned, take | ||
/// context by `connection.take_tls_context()`. | ||
/// | ||
/// And then do your rest works. For more usage, see `tests/tls_context.rs` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Take TLS context came from TLS layer to application layer. | |
/// | |
/// Calling it a second time will always return None so applications should store it somewhere. | |
/// | |
/// # Example | |
/// It's useful when you implement your own TLS provider. Some HTTP/3 server need more | |
/// information from TLS layer to decide which configuration to apply, So you can | |
/// | |
/// 1. Create own TLS provider, in that, parse TLS manually, set tls context by | |
/// `context.on_tls_context(Box::new(MyContext{}))` | |
/// 2. After `let connection = server.accept().await` returned, take | |
/// context by `connection.take_tls_context()`. | |
/// | |
/// And then do your rest works. For more usage, see `tests/tls_context.rs` | |
/// Takes the context provided by the TLS provider. | |
/// | |
/// This functionality is useful when you need to pass information from the TLS provider to the | |
/// application. This could include things like certificate information or application-specific data. | |
/// | |
/// Calling this function a second time will always return `None` so applications should | |
/// store the context elsewhere if it is needed in multiple locations. |
close #2437