Skip to content

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

Merged
merged 25 commits into from
Mar 25, 2025

Conversation

taikulawo
Copy link
Contributor

@taikulawo taikulawo commented Jan 15, 2025

close #2437

@WesleyRosenblum
Copy link
Contributor

Hi WeiChao. Are you still planning to work on this?

@taikulawo
Copy link
Contributor Author

sure, this is initial implementation, Is it right way fix this issue?

Copy link
Contributor

@camshaft camshaft left a 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.

@@ -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>>) {}
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -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>> =
Copy link
Contributor

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?

Copy link
Contributor Author

@taikulawo taikulawo Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@taikulawo
Copy link
Contributor Author

taikulawo commented Feb 21, 2025

Does you add take_application_context on s2n-tls or me?

@taikulawo taikulawo requested a review from camshaft February 23, 2025 10:34
@camshaft
Copy link
Contributor

camshaft commented Mar 3, 2025

Does you add take_application_context on s2n-tls or me?

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 :)

@taikulawo
Copy link
Contributor Author

Sure, I will do. but let me try #2446 (comment) first :)

@taikulawo
Copy link
Contributor Author

Hi, I want to merge this PR now.
We don't need to add API on s2n-tls. We have write a new TLS provider, replace in with_tls(new_server).

It's good to see s2n-quic has so flexible API. In new provider, we pre-parse client hello before do real TLS handshake.

After this PR get merged, following issue can be closed.

#2446
#2437

@taikulawo
Copy link
Contributor Author

@camshaft Hi, I have fixed CI issue, could you re-run it?

@taikulawo
Copy link
Contributor Author

fixed

Copy link
Contributor

@camshaft camshaft left a 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

@taikulawo taikulawo requested a review from camshaft March 25, 2025 03:58
use core::{mem::size_of, task::Poll};

#[derive(Debug)]
pub struct Endpoint(pub UserProvidedTlsContext);
Copy link
Contributor

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>>

Copy link
Contributor Author

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

Copy link
Contributor Author

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

@taikulawo taikulawo requested a review from camshaft March 25, 2025 05:04
@taikulawo taikulawo changed the title Access application context from tls connection Allow pass TLS context from third-party TLS provider to application layer Mar 25, 2025
Copy link
Contributor

@camshaft camshaft left a 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>);
Copy link
Contributor

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.

@@ -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>>);
Copy link
Contributor

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.

Comment on lines 172 to 185
/// 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`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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.

@taikulawo taikulawo requested a review from camshaft March 25, 2025 16:15
@camshaft camshaft merged commit f091f44 into aws:main Mar 25, 2025
116 checks passed
@taikulawo taikulawo deleted the app-context branch April 1, 2025 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Connection allow get/set context data to control ClientHelloCallback
3 participants