-
Notifications
You must be signed in to change notification settings - Fork 33
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
track upstream Rustls 0.22.x alpha changes. #341
Conversation
Tagged for early feedback, but there's no rush to review this. The upstream 0.22.0 release is a little bit out yet. |
Is the right way to handle the fallibility of the build() operation to rework this function to return a rustls_result and use an "out pointer arg" for the builder?
Yep, the pattern I've used is "rustls_result always gets the return
position if there is a possible error." Functions that can't error can
return a pointer for convenience.
And to refine on that a bit further: functions that can't error _for
reasons other than null inputs or internal panics_ can return a pointer for
convenience.
|
☑️ Thanks! I will fix that up. |
6e988af
to
0753268
Compare
Reworked the error handling, added a first pass at updated rustdoc comments. |
0753268
to
2dd24a5
Compare
🚧 Work in progress 🚧
|
adc4ebb
to
ce31cd5
Compare
I've paged back in some more of this context and I'm realizing there's a challenge / mis-design about how the
Those definitions seem potentially conflicting because the layout of an The tricky thing is that So, given a
So far, we've been allowing both, but I think in practice we should forbid (1) and always reconstruct the "real" type, to avoid confusion. In other words, The other thing to mention here is that the impl CastPtr for rustls_certified_key {
type RustType = CertifiedKey;
}
impl ArcCastPtr for rustls_certified_key {} That represents a C-side type of In this branch, the definition for impl CastPtr for rustls_client_cert_verifier {
type RustType = Arc<dyn ClientCertVerifier>;
}
impl ArcCastPtr for rustls_client_cert_verifier {} But ideally that should look like: impl CastPtr for rustls_client_cert_verifier {
type RustType = dyn ClientCertVerifier;
}
impl ArcCastPtr for rustls_client_cert_verifier {} The problem is, as you ran into: However, our implementations of pub(crate) trait CastPtr {
- type RustType;
+ type RustType: ?Sized; The deal is that type parameters and associated types are Adding the However, then we run into some other problems: Our We also run into this delightfully esoteric error message, which I vaguely see the direction of but don't really know how to fix:
I think the net result of all of this is that our best bet might be to double-indirect things: Give the C side a Below is a patch I was noodling on where I added the diff --git a/src/cipher.rs b/src/cipher.rs
index dce36138..43cdaed2 100644
--- a/src/cipher.rs
+++ b/src/cipher.rs
@@ -582,7 +582,7 @@ pub struct rustls_client_cert_verifier {
}
impl CastPtr for rustls_client_cert_verifier {
- type RustType = Arc<dyn ClientCertVerifier>;
+ type RustType = dyn ClientCertVerifier;
}
impl ArcCastPtr for rustls_client_cert_verifier {}
@@ -738,7 +738,7 @@ impl rustls_web_pki_client_cert_verifier_builder {
Err(e) => return error::map_verifier_builder_error(e),
};
- ArcCastPtr::set_mut_ptr(verifier_out, verifier);
+ ArcCastPtr::set_mut_ptr(verifier_out, verifier.as_ref());
rustls_result::Ok
}
diff --git a/src/lib.rs b/src/lib.rs
index 2c31dd10..75232a54 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -301,7 +301,7 @@ mod tests {
/// Implementing this is required in order to use `try_ref_from_ptr!` or
/// `try_mut_from_ptr!`.
pub(crate) trait CastPtr {
- type RustType;
+ type RustType: ?Sized;
fn cast_mut_ptr(ptr: *mut Self) -> *mut Self::RustType {
ptr as *mut _
@@ -311,7 +311,7 @@ pub(crate) trait CastPtr {
/// CastConstPtr represents a subset of CastPtr, for when we can only treat
/// something as a const (for instance when dealing with Arc).
pub(crate) trait CastConstPtr {
- type RustType;
+ type RustType: ?Sized;
fn cast_const_ptr(ptr: *const Self) -> *const Self::RustType {
ptr as *const _
@@ -324,6 +324,8 @@ pub(crate) trait CastConstPtr {
impl<T, R> CastConstPtr for T
where
T: CastPtr<RustType = R>,
+ T: ?Sized,
+ R: ?Sized,
{
type RustType = R;
}
@@ -331,7 +333,7 @@ where
// An implementation of BoxCastPtr means that when we give C code a pointer to the relevant type,
// it is actually a Box. At most one of BoxCastPtr or ArcCastPtr should be implemented for a given
// type.
-pub(crate) trait BoxCastPtr: CastPtr + Sized {
+pub(crate) trait BoxCastPtr: CastPtr {
fn to_box(ptr: *mut Self) -> Option<Box<Self::RustType>> {
if ptr.is_null() {
return None;
@@ -354,7 +356,7 @@ pub(crate) trait BoxCastPtr: CastPtr + Sized {
// An implementation of ArcCastPtr means that when we give C code a pointer to the relevant type,
// it is actually a Arc. At most one of BoxCastPtr or ArcCastPtr should be implemented for a given
// // type.
-pub(crate) trait ArcCastPtr: CastConstPtr + Sized {
+pub(crate) trait ArcCastPtr: CastConstPtr {
/// Sometimes we create an Arc, then call `into_raw` and return the resulting raw pointer
/// to C. C can then call rustls_server_session_new multiple times using that
/// same raw pointer. On each call, we need to reconstruct the Arc. But once we reconstruct the Arc,
diff --git a/src/server.rs b/src/server.rs
index bd0c1064..979f2699 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -166,7 +166,7 @@ impl rustls_server_config_builder {
) {
ffi_panic_boundary! {
let builder: &mut ServerConfigBuilder = try_mut_from_ptr!(builder);
- let verifier = try_ref_from_ptr!(verifier);
+ let verifier = try_arc_from_ptr!(verifier);
builder.verifier = verifier.clone();
}
} |
Thanks for the detailed reply. Complications abound 😵 It will take me a little bit to digest everything here. It's worrying that the mis-designed implementation "works". E.g. |
I took a crack at this. Here's what [the diff]f12aa12) entailed (writing this out to check my own understanding):
Separately, I had the same issue with the new
I think this avoids the issues you were highlighting 🤞 |
f0f97b1
to
50d163a
Compare
Yep, your summary all looks good. A couple of super pedantic points:
Really
I agree; I need to poke at it a bit more and see what the deal is, and if there's anything to improve in terms of detection. It's possible that we weren't exercising "interesting" code paths for |
Great, thanks for taking a look. I can work on tidying up the commit history now that it seems like we're stabilizing on an overall approach. I think there might also be one work item left to consider (maybe separate from this branch?): making
Should I give that a go?
Ah ok, good point (pun not intended 😆)
ACK ☑️
That would make sense 🤔 |
I looked back at one of the earlier revisions here: 6e988af. And it turns out you had already implemented the doubly-indirect solution we eventually landed on: allocate a impl CastPtr for rustls_client_cert_verifier {
type RustType = Arc<dyn ClientCertVerifier>;
}
impl BoxCastPtr for rustls_client_cert_verifier {} 6e988af#diff-48d27698cc708c7efe770fd897e4885efaa0a15cae30d54936068603ba03bbd9R170 let verifier: Arc<dyn ClientCertVerifier> = try_ref_from_ptr!(verifier).clone(); For more detail on what's happening in that line of code, it could be:
That's taking advantage of the fact that we can get infinitely many read-only references to the contents of a Box, even though we don't own the box. It's also taking advantage of the fact that an This could also have been:
In practice we only use Anyhow, long story short: the mis-design was that it was (and is) possible to implement BoxCastPtr::set_mut_ptr(verifier_out, verifier); Freed with: BoxCastPtr::to_box(verifier); And utilized with: let verifier: Arc<dyn ClientCertVerifier> = try_ref_from_ptr!(verifier).clone(); (that last one would have worked fine for Box or Arc). So I think we're all good here, with the main action item figuring out if we can use the type system or a lint to prevent implementing both conversion traits on a single type. |
50d163a
to
48d9e81
Compare
Rebased on I'll try to keep it up to date with the 0.22.x progress in the main Rustls repo. |
48d9e81
to
363c445
Compare
This commit removes the error handling related to certificate SCTs. The upstream Rustls project removed embedded SCT support in 0.22.x.
The upstream traits no longer have any default fn implementations, because they relied on webpki/*ring* and Rustls is making that optional. In this branch we're continuing to keep a webpki/*ring* dep. and so can reconstitute the default fns by deferring to the webpki impls as appropriate.
This commit updates several imports that were once provided when the `dangerous_configuration` feature was enabled to use their new homes in specific `danger` modules. The upstream feature flag was removed and these new `danger` modules are always available.
Both the `ALL_CIPHER_SUITES` and `DEFAULT_CIPHER_SUITES` symbols are now specific to a crypto provider. Since for the time being rustls-ffi will stick with using *ring* for the crypto provider this commit updates the imports to use the symbols provided by `rustls::crypto::ring` instead of the crate root.
This commit updates rustls-ffi to use the shared pki-types crate, similar to the upstream rustls projects.
0b7c359
to
49b4eb9
Compare
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.
This looks great. I'm inclined to go ahead and merge this to main, so we can iterate further (e.g. adding crypto providers) without you needing to constantly rebase. 0.22 is coming up soon, and if we really need to do another rustls-ffi release targeting 0.21, we can do it off of a branch. What do you think?
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 agree on merging this.
src/cipher.rs
Outdated
/// A root certificate store. | ||
/// <https://docs.rs/rustls/latest/rustls/struct.RootCertStore.html> | ||
pub struct rustls_root_cert_store { | ||
/// A `rustls_root_cert_store` being constructed. A builder can be modified by |
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.
paragraph break after headline?
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.
Fixed. Thanks!
Thanks for the reviews. Merging it sounds good to me. I'll address the two paragraph break items and then do that 👍 |
This commit implements a builder pattern for `root_cert_store` so that we can have a path to both a mutable root cert store while trust anchors are being added, and a const root cert store suitable for an `Arc` once completed.
This commit reworks the rustls-ffi API for client certificate validation to track the new builder based API that landed in Rustls rustls/rustls#1368
The upstream Rustls project has added `Debug` bounds to many traits. This commit updates rustls-ffi implementations to derive `Debug`, or implement it by hand, as required.
The upstream rustls crate moved the `cipher_suite` module and defines into provider specific packages. Since rustls-ffi is presently hardcoded to use the *ring*-based crypto provider this commit updates the cipher suite references to use `rustls::crypto::ring::cipher_suite` in place of `rustls::cipher_suite`.
This commit updates references to `ClientCertVerifierBuilderError` to track the upstream rename to `VerifierBuilderError`.
This re-export was removed and instead we need to use `rustls::crypto::ring::sign::any_supported_type` since this is a property of the *ring* specific crypto provider.
* Implement a builder pattern and built representation for the webpki server cert verifier. * Update the client config builder to consume a built server cert verifier. * Update the roots builder to support loading roots from a file in addition to pem buffer.
49b4eb9
to
0700a45
Compare
When CI finishes I'll squash merge this. Since the individual commits don't build/test cleanly this feels better than rebase merging for this situation. |
Description
This branch tracks the breaking API changes that have accrued in the upstream Rustls, Webpki and Rustls-pemfile repos for the pending 0.22.0 release.
I've chosen to try and break categories of changes into unique commits, but this means that intermediate commits won't build: they're all-or-nothing with the updated dependency versions.
TODO:
CastPtr
,CastConstPtr
,BoxCastPtr
,ArcCastPtr
#353