2727use std:: ffi;
2828use std:: mem:: ManuallyDrop ;
2929use std:: ptr;
30+ use std:: ptr:: NonNull ;
3031use std:: slice;
3132
3233use std:: io:: Write ;
@@ -128,14 +129,15 @@ pub static QUICHE_EX_DATA_INDEX: LazyLock<c_int> = LazyLock::new(|| unsafe {
128129 SSL_get_ex_new_index ( 0 , ptr:: null ( ) , ptr:: null ( ) , ptr:: null ( ) , ptr:: null ( ) )
129130} ) ;
130131
131- pub struct Context ( * mut SSL_CTX ) ;
132+ pub struct Context ( NonNull < SSL_CTX > ) ;
132133
133134impl Context {
134135 // Note: some vendor-specific methods are implemented in the boringssl
135136 // submodule.
136137 pub fn new ( ) -> Result < Context > {
137138 unsafe {
138- let ctx_raw = SSL_CTX_new ( TLS_method ( ) ) ;
139+ let ctx_raw =
140+ NonNull :: new ( SSL_CTX_new ( TLS_method ( ) ) ) . ok_or ( Error :: TlsFail ) ?;
139141
140142 let mut ctx = Context ( ctx_raw) ;
141143
@@ -150,18 +152,23 @@ impl Context {
150152 #[ cfg( feature = "boringssl-boring-crate" ) ]
151153 pub fn from_boring (
152154 ssl_ctx_builder : boring:: ssl:: SslContextBuilder ,
153- ) -> Context {
155+ ) -> Result < Context > {
154156 use foreign_types_shared:: ForeignType ;
155157
156- let mut ctx = Context ( ssl_ctx_builder. build ( ) . into_ptr ( ) as _ ) ;
158+ let ctx_raw = NonNull :: new ( ssl_ctx_builder. build ( ) . into_ptr ( ) as _ )
159+ . ok_or ( Error :: TlsFail ) ?;
160+
161+ let mut ctx = Context ( ctx_raw) ;
157162 ctx. set_session_callback ( ) ;
158163
159- ctx
164+ Ok ( ctx)
160165 }
161166
162167 pub fn new_handshake ( & mut self ) -> Result < Handshake > {
163168 unsafe {
164- let ssl = SSL_new ( self . as_mut_ptr ( ) ) ;
169+ let ssl =
170+ NonNull :: new ( SSL_new ( self . as_mut_ptr ( ) ) ) . ok_or ( Error :: TlsFail ) ?;
171+
165172 Ok ( Handshake :: new ( ssl) )
166173 }
167174 }
@@ -330,15 +337,13 @@ impl Context {
330337 }
331338
332339 fn as_mut_ptr ( & mut self ) -> * mut SSL_CTX {
333- self . 0
340+ self . 0 . as_ptr ( )
334341 }
335342}
336343
337- // NOTE: These traits are not automatically implemented for Context due to the
338- // raw pointer it wraps. However, the underlying data is not aliased (as Context
339- // should be its only owner), and there is no interior mutability, as the
340- // pointer is not accessed directly outside of this module, and the Context
341- // object API should preserve Rust's borrowing guarantees.
344+ // These traits are not automatically implemented because NonNull does not
345+ // convey ownership. Context uniquely owns the underlying data, and its API
346+ // preserves Rust's borrowing guarantees.
342347unsafe impl Send for Context { }
343348unsafe impl Sync for Context { }
344349
@@ -349,8 +354,7 @@ impl Drop for Context {
349354}
350355
351356pub struct Handshake {
352- /// Raw pointer
353- ptr : * mut SSL ,
357+ ptr : NonNull < SSL > ,
354358 /// SSL_process_quic_post_handshake should be called when whenever
355359 /// SSL_provide_quic_data is called to process the provided data.
356360 provided_data_outstanding : bool ,
@@ -360,11 +364,13 @@ impl Handshake {
360364 // Note: some vendor-specific methods are implemented in the boringssl
361365 // submodule.
362366 #[ cfg( any( feature = "ffi" , feature = "boringssl-boring-crate" ) ) ]
363- pub unsafe fn from_ptr ( ssl : * mut c_void ) -> Handshake {
364- Handshake :: new ( ssl as * mut SSL )
367+ pub unsafe fn from_ptr ( ssl : * mut c_void ) -> Result < Handshake > {
368+ let ptr = NonNull :: new ( ssl. cast ( ) ) . ok_or ( Error :: TlsFail ) ?;
369+
370+ Ok ( Handshake :: new ( ptr) )
365371 }
366372
367- fn new ( ptr : * mut SSL ) -> Handshake {
373+ fn new ( ptr : NonNull < SSL > ) -> Handshake {
368374 Handshake {
369375 ptr,
370376 provided_data_outstanding : false ,
@@ -590,11 +596,11 @@ impl Handshake {
590596 }
591597
592598 fn as_ptr ( & self ) -> * const SSL {
593- self . ptr
599+ self . ptr . as_ptr ( )
594600 }
595601
596602 fn as_mut_ptr ( & mut self ) -> * mut SSL {
597- self . ptr
603+ self . ptr . as_ptr ( )
598604 }
599605
600606 fn map_result_ssl ( & mut self , bssl_result : c_int ) -> Result < ( ) > {
@@ -674,11 +680,9 @@ impl Handshake {
674680 }
675681}
676682
677- // NOTE: These traits are not automatically implemented for Handshake due to the
678- // raw pointer it wraps. However, the underlying data is not aliased (as
679- // Handshake should be its only owner), and there is no interior mutability, as
680- // the pointer is not accessed directly outside of this module, and the
681- // Handshake object API should preserve Rust's borrowing guarantees.
683+ // These traits are not automatically implemented because NonNull does not
684+ // convey ownership. Handshake uniquely owns the underlying data, and its API
685+ // preserves Rust's borrowing guarantees.
682686unsafe impl Send for Handshake { }
683687unsafe impl Sync for Handshake { }
684688
@@ -987,7 +991,13 @@ extern "C" fn select_alpn(
987991}
988992
989993extern "C" fn new_session ( ssl : * mut SSL , session : * mut SSL_SESSION ) -> c_int {
990- let ex_data = match ExData :: from_ssl_ptr ( ssl) {
994+ let ssl = match NonNull :: new ( ssl) {
995+ Some ( v) => v,
996+
997+ None => return 0 ,
998+ } ;
999+
1000+ let ex_data = match ExData :: from_ssl_ptr ( ssl. as_ptr ( ) ) {
9911001 Some ( v) => v,
9921002
9931003 None => return 0 ,
0 commit comments