11#![ forbid( unsafe_op_in_unsafe_fn) ]
22
3+ use super :: {
4+ AlpnError , ClientHello , PrivateKeyMethod , PrivateKeyMethodError , SelectCertError , SniError ,
5+ Ssl , SslAlert , SslContext , SslContextRef , SslRef , SslSession , SslSessionRef ,
6+ SslSignatureAlgorithm , SESSION_CTX_INDEX ,
7+ } ;
8+ use crate :: error:: ErrorStack ;
39use crate :: ffi;
10+ use crate :: x509:: { X509StoreContext , X509StoreContextRef } ;
411use foreign_types:: ForeignType ;
512use foreign_types:: ForeignTypeRef ;
613use libc:: c_char;
@@ -12,19 +19,7 @@ use std::slice;
1219use std:: str;
1320use std:: sync:: Arc ;
1421
15- use crate :: error:: ErrorStack ;
16- use crate :: ssl:: AlpnError ;
17- use crate :: ssl:: { ClientHello , SelectCertError } ;
18- use crate :: ssl:: {
19- SniError , Ssl , SslAlert , SslContext , SslContextRef , SslRef , SslSession , SslSessionRef ,
20- SESSION_CTX_INDEX ,
21- } ;
22- use crate :: x509:: { X509StoreContext , X509StoreContextRef } ;
23-
24- pub ( super ) unsafe extern "C" fn raw_verify < F > (
25- preverify_ok : c_int ,
26- x509_ctx : * mut ffi:: X509_STORE_CTX ,
27- ) -> c_int
22+ pub extern "C" fn raw_verify < F > ( preverify_ok : c_int , x509_ctx : * mut ffi:: X509_STORE_CTX ) -> c_int
2823where
2924 F : Fn ( bool , & mut X509StoreContextRef ) -> bool + ' static + Sync + Send ,
3025{
@@ -372,3 +367,93 @@ where
372367
373368 callback ( ssl, line) ;
374369}
370+
371+ pub ( super ) unsafe extern "C" fn raw_sign < M > (
372+ ssl : * mut ffi:: SSL ,
373+ out : * mut u8 ,
374+ out_len : * mut usize ,
375+ max_out : usize ,
376+ signature_algorithm : u16 ,
377+ in_ : * const u8 ,
378+ in_len : usize ,
379+ ) -> ffi:: ssl_private_key_result_t
380+ where
381+ M : PrivateKeyMethod ,
382+ {
383+ // SAFETY: boring provides valid inputs.
384+ let input = unsafe { slice:: from_raw_parts ( in_, in_len) } ;
385+
386+ let signature_algorithm = SslSignatureAlgorithm ( signature_algorithm) ;
387+
388+ let callback = |method : & M , ssl : & mut _ , output : & mut _ | {
389+ method. sign ( ssl, input, signature_algorithm, output)
390+ } ;
391+
392+ // SAFETY: boring provides valid inputs.
393+ unsafe { raw_private_key_callback ( ssl, out, out_len, max_out, callback) }
394+ }
395+
396+ pub ( super ) unsafe extern "C" fn raw_decrypt < M > (
397+ ssl : * mut ffi:: SSL ,
398+ out : * mut u8 ,
399+ out_len : * mut usize ,
400+ max_out : usize ,
401+ in_ : * const u8 ,
402+ in_len : usize ,
403+ ) -> ffi:: ssl_private_key_result_t
404+ where
405+ M : PrivateKeyMethod ,
406+ {
407+ // SAFETY: boring provides valid inputs.
408+ let input = unsafe { slice:: from_raw_parts ( in_, in_len) } ;
409+
410+ let callback = |method : & M , ssl : & mut _ , output : & mut _ | method. decrypt ( ssl, input, output) ;
411+
412+ // SAFETY: boring provides valid inputs.
413+ unsafe { raw_private_key_callback ( ssl, out, out_len, max_out, callback) }
414+ }
415+
416+ pub ( super ) unsafe extern "C" fn raw_complete < M > (
417+ ssl : * mut ffi:: SSL ,
418+ out : * mut u8 ,
419+ out_len : * mut usize ,
420+ max_out : usize ,
421+ ) -> ffi:: ssl_private_key_result_t
422+ where
423+ M : PrivateKeyMethod ,
424+ {
425+ // SAFETY: boring provides valid inputs.
426+ unsafe { raw_private_key_callback :: < M > ( ssl, out, out_len, max_out, M :: complete) }
427+ }
428+
429+ unsafe fn raw_private_key_callback < M > (
430+ ssl : * mut ffi:: SSL ,
431+ out : * mut u8 ,
432+ out_len : * mut usize ,
433+ max_out : usize ,
434+ callback : impl FnOnce ( & M , & mut SslRef , & mut [ u8 ] ) -> Result < usize , PrivateKeyMethodError > ,
435+ ) -> ffi:: ssl_private_key_result_t
436+ where
437+ M : PrivateKeyMethod ,
438+ {
439+ // SAFETY: boring provides valid inputs.
440+ let ssl = unsafe { SslRef :: from_ptr_mut ( ssl) } ;
441+ let output = unsafe { slice:: from_raw_parts_mut ( out, max_out) } ;
442+ let out_len = unsafe { & mut * out_len } ;
443+
444+ let ssl_context = ssl. ssl_context ( ) . to_owned ( ) ;
445+ let method = ssl_context
446+ . ex_data ( SslContext :: cached_ex_index :: < M > ( ) )
447+ . expect ( "BUG: private key method missing" ) ;
448+
449+ match callback ( method, ssl, output) {
450+ Ok ( written) => {
451+ assert ! ( written <= max_out) ;
452+
453+ * out_len = written;
454+
455+ ffi:: ssl_private_key_result_t:: ssl_private_key_success
456+ }
457+ Err ( err) => err. 0 ,
458+ }
459+ }
0 commit comments