Skip to content

Commit ab0af53

Browse files
committed
rework CastPtr, CastConstPtr, BoxCastPtr, ArcCastPtr
This commit reworks the existing `CastPtr`, `CastConstPtr`, `BoxCastPtr`, and `ArcCastPtr` traits into a new `Castable` trait with an associated `Ownership`, constrained to be a type implementing the new `OwnershipMarker` trait. Three implementations of this `OwnershipMarker` trait are offered: `OwnershipBox`, `OwnershipArc` and `OwnershipRef`. The net result is that the type system is now able to enforce our invariant that a single `Castable` type can't be cast to a pointer of more than one type of ownership (e.g. both an `Arc` and a `Box`). We always implement a distinct type per-ownership model. Along the way crate-internal documentation for the traits and associated free-standing helper `fs`s were reworked for clarity/consistency.
1 parent 9cee787 commit ab0af53

File tree

6 files changed

+350
-223
lines changed

6 files changed

+350
-223
lines changed

src/acceptor.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use crate::io::{rustls_read_callback, CallbackReader, ReadCallback};
1111
use crate::rslice::{rustls_slice_bytes, rustls_str};
1212
use crate::server::rustls_server_config;
1313
use crate::{
14-
ffi_panic_boundary, rustls_result, try_arc_from_ptr, try_callback, try_mut_from_ptr,
15-
try_ref_from_ptr, BoxCastPtr, CastPtr,
14+
ffi_panic_boundary, free_box, rustls_result, set_boxed_mut_ptr, to_box, to_boxed_mut_ptr,
15+
try_arc_from_ptr, try_callback, try_mut_from_ptr, try_ref_from_ptr, Castable, OwnershipBox,
1616
};
1717
use rustls_result::NullParameter;
1818

@@ -42,12 +42,11 @@ pub struct rustls_acceptor {
4242
_private: [u8; 0],
4343
}
4444

45-
impl CastPtr for rustls_acceptor {
45+
impl Castable for rustls_acceptor {
46+
type Ownership = OwnershipBox;
4647
type RustType = Acceptor;
4748
}
4849

49-
impl BoxCastPtr for rustls_acceptor {}
50-
5150
/// A parsed ClientHello produced by a rustls_acceptor. It is used to check
5251
/// server name indication (SNI), ALPN protocols, signature schemes, and
5352
/// cipher suites. It can be combined with a rustls_server_config to build a
@@ -56,12 +55,11 @@ pub struct rustls_accepted {
5655
_private: [u8; 0],
5756
}
5857

59-
impl CastPtr for rustls_accepted {
58+
impl Castable for rustls_accepted {
59+
type Ownership = OwnershipBox;
6060
type RustType = Option<Accepted>;
6161
}
6262

63-
impl BoxCastPtr for rustls_accepted {}
64-
6563
impl rustls_acceptor {
6664
/// Create and return a new rustls_acceptor.
6765
///
@@ -70,7 +68,7 @@ impl rustls_acceptor {
7068
#[no_mangle]
7169
pub extern "C" fn rustls_acceptor_new() -> *mut rustls_acceptor {
7270
ffi_panic_boundary! {
73-
BoxCastPtr::to_mut_ptr(Acceptor::default())
71+
to_boxed_mut_ptr(Acceptor::default())
7472
}
7573
}
7674

@@ -84,7 +82,7 @@ impl rustls_acceptor {
8482
#[no_mangle]
8583
pub extern "C" fn rustls_acceptor_free(acceptor: *mut rustls_acceptor) {
8684
ffi_panic_boundary! {
87-
BoxCastPtr::to_box(acceptor);
85+
to_box(acceptor);
8886
}
8987
}
9088

@@ -185,7 +183,7 @@ impl rustls_acceptor {
185183
Ok(None) => rustls_result::AcceptorNotReady,
186184
Err(e) => map_error(e),
187185
Ok(Some(accepted)) => {
188-
BoxCastPtr::set_mut_ptr(out_accepted, Some(accepted));
186+
set_boxed_mut_ptr(out_accepted, Some(accepted));
189187
rustls_result::Ok
190188
}
191189
}
@@ -408,7 +406,7 @@ impl rustls_accepted {
408406
match accepted.into_connection(config) {
409407
Ok(built) => {
410408
let wrapped = crate::connection::Connection::from_server(built);
411-
BoxCastPtr::set_mut_ptr(out_conn, wrapped);
409+
set_boxed_mut_ptr(out_conn, wrapped);
412410
rustls_result::Ok
413411
},
414412
Err(e) => map_error(e),
@@ -426,7 +424,7 @@ impl rustls_accepted {
426424
#[no_mangle]
427425
pub extern "C" fn rustls_accepted_free(accepted: *mut rustls_accepted) {
428426
ffi_panic_boundary! {
429-
BoxCastPtr::to_box(accepted);
427+
free_box(accepted);
430428
}
431429
}
432430
}

src/cipher.rs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ use rustls_pemfile::{certs, crls, pkcs8_private_keys, rsa_private_keys};
1818
use crate::error::{map_error, rustls_result};
1919
use crate::rslice::{rustls_slice_bytes, rustls_str};
2020
use crate::{
21-
ffi_panic_boundary, try_box_from_ptr, try_mut_from_ptr, try_ref_from_ptr, try_slice,
22-
ArcCastPtr, BoxCastPtr, CastConstPtr, CastPtr,
21+
ffi_panic_boundary, free_arc, to_arc_const_ptr, to_boxed_mut_ptr, try_box_from_ptr,
22+
try_mut_from_ptr, try_ref_from_ptr, try_slice, Castable, OwnershipArc, OwnershipBox,
23+
OwnershipRef,
2324
};
2425
use rustls_result::{AlreadyUsed, NullParameter};
2526

@@ -33,7 +34,8 @@ pub struct rustls_certificate {
3334
_private: [u8; 0],
3435
}
3536

36-
impl CastPtr for rustls_certificate {
37+
impl Castable for rustls_certificate {
38+
type Ownership = OwnershipRef;
3739
type RustType = Certificate;
3840
}
3941

@@ -66,7 +68,8 @@ pub struct rustls_supported_ciphersuite {
6668
_private: [u8; 0],
6769
}
6870

69-
impl CastPtr for rustls_supported_ciphersuite {
71+
impl Castable for rustls_supported_ciphersuite {
72+
type Ownership = OwnershipRef;
7073
type RustType = SupportedCipherSuite;
7174
}
7275

@@ -262,12 +265,11 @@ pub struct rustls_certified_key {
262265
_private: [u8; 0],
263266
}
264267

265-
impl CastPtr for rustls_certified_key {
268+
impl Castable for rustls_certified_key {
269+
type Ownership = OwnershipArc;
266270
type RustType = CertifiedKey;
267271
}
268272

269-
impl ArcCastPtr for rustls_certified_key {}
270-
271273
impl rustls_certified_key {
272274
/// Build a `rustls_certified_key` from a certificate chain and a private key.
273275
/// `cert_chain` must point to a buffer of `cert_chain_len` bytes, containing
@@ -366,7 +368,7 @@ impl rustls_certified_key {
366368
} else {
367369
new_key.ocsp = None;
368370
}
369-
*cloned_key_out = ArcCastPtr::to_const_ptr(new_key);
371+
*cloned_key_out = to_arc_const_ptr(new_key);
370372
rustls_result::Ok
371373
}
372374
}
@@ -380,7 +382,7 @@ impl rustls_certified_key {
380382
#[no_mangle]
381383
pub extern "C" fn rustls_certified_key_free(key: *const rustls_certified_key) {
382384
ffi_panic_boundary! {
383-
rustls_certified_key::free(key);
385+
free_arc(key);
384386
}
385387
}
386388

@@ -443,12 +445,11 @@ pub struct rustls_root_cert_store {
443445
_private: [u8; 0],
444446
}
445447

446-
impl CastPtr for rustls_root_cert_store {
448+
impl Castable for rustls_root_cert_store {
449+
type Ownership = OwnershipBox;
447450
type RustType = RootCertStore;
448451
}
449452

450-
impl BoxCastPtr for rustls_root_cert_store {}
451-
452453
impl rustls_root_cert_store {
453454
/// Create a rustls_root_cert_store. Caller owns the memory and must
454455
/// eventually call rustls_root_cert_store_free. The store starts out empty.
@@ -458,7 +459,7 @@ impl rustls_root_cert_store {
458459
pub extern "C" fn rustls_root_cert_store_new() -> *mut rustls_root_cert_store {
459460
ffi_panic_boundary! {
460461
let store = rustls::RootCertStore::empty();
461-
BoxCastPtr::to_mut_ptr(store)
462+
to_boxed_mut_ptr(store)
462463
}
463464
}
464465

@@ -517,14 +518,13 @@ pub struct rustls_allow_any_authenticated_client_builder {
517518
_private: [u8; 0],
518519
}
519520

520-
impl CastPtr for rustls_allow_any_authenticated_client_builder {
521-
// NOTE: contained value is consumed even on error, so this can contain None. but the caller
521+
impl Castable for rustls_allow_any_authenticated_client_builder {
522+
type Ownership = OwnershipBox;
523+
// NOTE: contained value is consumed even on error, so this can contain None, but the caller
522524
// still needs to free it
523525
type RustType = Option<AllowAnyAuthenticatedClient>;
524526
}
525527

526-
impl BoxCastPtr for rustls_allow_any_authenticated_client_builder {}
527-
528528
impl rustls_allow_any_authenticated_client_builder {
529529
/// Create a new allow any authenticated client certificate verifier builder using the root store.
530530
///
@@ -542,7 +542,7 @@ impl rustls_allow_any_authenticated_client_builder {
542542
ffi_panic_boundary! {
543543
let store: &RootCertStore = try_ref_from_ptr!(store);
544544
let client_cert_verifier = Some(AllowAnyAuthenticatedClient::new(store.clone()));
545-
BoxCastPtr::to_mut_ptr(client_cert_verifier)
545+
to_boxed_mut_ptr(client_cert_verifier)
546546
}
547547
}
548548

@@ -604,12 +604,11 @@ pub struct rustls_allow_any_authenticated_client_verifier {
604604
_private: [u8; 0],
605605
}
606606

607-
impl CastConstPtr for rustls_allow_any_authenticated_client_verifier {
607+
impl Castable for rustls_allow_any_authenticated_client_verifier {
608+
type Ownership = OwnershipArc;
608609
type RustType = AllowAnyAuthenticatedClient;
609610
}
610611

611-
impl ArcCastPtr for rustls_allow_any_authenticated_client_verifier {}
612-
613612
impl rustls_allow_any_authenticated_client_verifier {
614613
/// Create a new allow any authenticated client certificate verifier from a builder.
615614
///
@@ -649,7 +648,7 @@ impl rustls_allow_any_authenticated_client_verifier {
649648
verifier: *const rustls_allow_any_authenticated_client_verifier,
650649
) {
651650
ffi_panic_boundary! {
652-
rustls_allow_any_authenticated_client_verifier::free(verifier);
651+
free_arc(verifier);
653652
}
654653
}
655654
}
@@ -661,14 +660,13 @@ pub struct rustls_allow_any_anonymous_or_authenticated_client_builder {
661660
_private: [u8; 0],
662661
}
663662

664-
impl CastPtr for rustls_allow_any_anonymous_or_authenticated_client_builder {
665-
// NOTE: contained value is consumed even on error, so this can contain None. but the caller
663+
impl Castable for rustls_allow_any_anonymous_or_authenticated_client_builder {
664+
type Ownership = OwnershipBox;
665+
// NOTE: contained value is consumed even on error, so this can contain None, but the caller
666666
// still needs to free it
667667
type RustType = Option<AllowAnyAnonymousOrAuthenticatedClient>;
668668
}
669669

670-
impl BoxCastPtr for rustls_allow_any_anonymous_or_authenticated_client_builder {}
671-
672670
impl rustls_allow_any_anonymous_or_authenticated_client_builder {
673671
/// Create a new allow any anonymous or authenticated client certificate verifier builder
674672
/// using the root store.
@@ -688,7 +686,7 @@ impl rustls_allow_any_anonymous_or_authenticated_client_builder {
688686
ffi_panic_boundary! {
689687
let store: &RootCertStore = try_ref_from_ptr!(store);
690688
let client_cert_verifier = Some(AllowAnyAnonymousOrAuthenticatedClient::new(store.clone()));
691-
BoxCastPtr::to_mut_ptr(client_cert_verifier)
689+
to_boxed_mut_ptr(client_cert_verifier)
692690
}
693691
}
694692

@@ -753,12 +751,11 @@ pub struct rustls_allow_any_anonymous_or_authenticated_client_verifier {
753751
_private: [u8; 0],
754752
}
755753

756-
impl CastConstPtr for rustls_allow_any_anonymous_or_authenticated_client_verifier {
754+
impl Castable for rustls_allow_any_anonymous_or_authenticated_client_verifier {
755+
type Ownership = OwnershipArc;
757756
type RustType = AllowAnyAnonymousOrAuthenticatedClient;
758757
}
759758

760-
impl ArcCastPtr for rustls_allow_any_anonymous_or_authenticated_client_verifier {}
761-
762759
impl rustls_allow_any_anonymous_or_authenticated_client_verifier {
763760
/// Create a new allow any anonymous or authenticated client certificate verifier builder
764761
/// from the builder.
@@ -799,7 +796,7 @@ impl rustls_allow_any_anonymous_or_authenticated_client_verifier {
799796
verifier: *const rustls_allow_any_anonymous_or_authenticated_client_verifier,
800797
) {
801798
ffi_panic_boundary! {
802-
rustls_allow_any_anonymous_or_authenticated_client_verifier::free(verifier);
799+
free_arc(verifier);
803800
}
804801
}
805802
}

src/client.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ use crate::error::{self, rustls_result};
2121
use crate::rslice::NulByte;
2222
use crate::rslice::{rustls_slice_bytes, rustls_slice_slice_bytes, rustls_str};
2323
use crate::{
24-
ffi_panic_boundary, try_arc_from_ptr, try_box_from_ptr, try_mut_from_ptr, try_ref_from_ptr,
25-
try_slice, userdata_get, ArcCastPtr, BoxCastPtr, CastConstPtr, CastPtr,
24+
ffi_panic_boundary, free_arc, free_box, set_boxed_mut_ptr, to_arc_const_ptr, to_boxed_mut_ptr,
25+
try_arc_from_ptr, try_box_from_ptr, try_mut_from_ptr, try_ref_from_ptr, try_slice,
26+
userdata_get, Castable, OwnershipArc, OwnershipBox,
2627
};
2728

2829
/// A client config being constructed. A builder can be modified by,
@@ -47,12 +48,11 @@ pub(crate) struct ClientConfigBuilder {
4748
cert_resolver: Option<Arc<dyn rustls::client::ResolvesClientCert>>,
4849
}
4950

50-
impl CastPtr for rustls_client_config_builder {
51+
impl Castable for rustls_client_config_builder {
52+
type Ownership = OwnershipBox;
5153
type RustType = ClientConfigBuilder;
5254
}
5355

54-
impl BoxCastPtr for rustls_client_config_builder {}
55-
5656
/// A client config that is done being constructed and is now read-only.
5757
/// Under the hood, this object corresponds to an `Arc<ClientConfig>`.
5858
/// <https://docs.rs/rustls/latest/rustls/struct.ClientConfig.html>
@@ -63,12 +63,11 @@ pub struct rustls_client_config {
6363
_private: [u8; 0],
6464
}
6565

66-
impl CastConstPtr for rustls_client_config {
66+
impl Castable for rustls_client_config {
67+
type Ownership = OwnershipArc;
6768
type RustType = ClientConfig;
6869
}
6970

70-
impl ArcCastPtr for rustls_client_config {}
71-
7271
struct NoneVerifier;
7372

7473
impl ServerCertVerifier for NoneVerifier {
@@ -106,7 +105,7 @@ impl rustls_client_config_builder {
106105
alpn_protocols: vec![],
107106
enable_sni: true,
108107
};
109-
BoxCastPtr::to_mut_ptr(builder)
108+
to_boxed_mut_ptr(builder)
110109
}
111110
}
112111

@@ -169,7 +168,7 @@ impl rustls_client_config_builder {
169168
enable_sni: true,
170169
};
171170

172-
BoxCastPtr::set_mut_ptr(builder_out, config_builder);
171+
set_boxed_mut_ptr(builder_out, config_builder);
173172
rustls_result::Ok
174173
}
175174
}
@@ -492,7 +491,7 @@ impl rustls_client_config_builder {
492491
};
493492
config.alpn_protocols = builder.alpn_protocols;
494493
config.enable_sni = builder.enable_sni;
495-
ArcCastPtr::to_const_ptr(config)
494+
to_arc_const_ptr(config)
496495
}
497496
}
498497

@@ -504,7 +503,7 @@ impl rustls_client_config_builder {
504503
#[no_mangle]
505504
pub extern "C" fn rustls_client_config_builder_free(config: *mut rustls_client_config_builder) {
506505
ffi_panic_boundary! {
507-
BoxCastPtr::to_box(config);
506+
free_box(config);
508507
}
509508
}
510509
}
@@ -519,7 +518,7 @@ impl rustls_client_config {
519518
#[no_mangle]
520519
pub extern "C" fn rustls_client_config_free(config: *const rustls_client_config) {
521520
ffi_panic_boundary! {
522-
rustls_client_config::free(config);
521+
free_arc(config);
523522
}
524523
}
525524

@@ -561,7 +560,7 @@ impl rustls_client_config {
561560
// to the caller. After this point, we must return rustls_result::Ok so the
562561
// caller knows it is responsible for this memory.
563562
let c = Connection::from_client(client);
564-
BoxCastPtr::set_mut_ptr(conn_out, c);
563+
set_boxed_mut_ptr(conn_out, c);
565564
rustls_result::Ok
566565
}
567566
}

0 commit comments

Comments
 (0)