9
9
use core:: result:: Result as StdResult ;
10
10
11
11
#[ cfg( feature = "std" ) ]
12
- use {
13
- std:: io:: { Read , Write , Result as IoResult , Error as IoError } ,
14
- std:: sync:: Arc ,
15
- } ;
12
+ use std:: sync:: Arc ;
16
13
17
- use mbedtls_sys:: types:: raw_types:: { c_int, c_uchar, c_void} ;
18
- use mbedtls_sys:: types:: size_t;
14
+ use mbedtls_sys:: types:: raw_types:: { c_int, c_void} ;
19
15
use mbedtls_sys:: * ;
20
16
21
17
#[ cfg( not( feature = "std" ) ) ]
@@ -25,94 +21,9 @@ use crate::error::{Error, Result, IntoResult};
25
21
use crate :: pk:: Pk ;
26
22
use crate :: private:: UnsafeFrom ;
27
23
use crate :: ssl:: config:: { Config , Version , AuthMode } ;
24
+ use crate :: ssl:: io:: IoCallbackUnsafe ;
28
25
use crate :: x509:: { Certificate , Crl , VerifyError } ;
29
26
30
- pub trait IoCallback {
31
- unsafe extern "C" fn call_recv ( user_data : * mut c_void , data : * mut c_uchar , len : size_t ) -> c_int where Self : Sized ;
32
- unsafe extern "C" fn call_send ( user_data : * mut c_void , data : * const c_uchar , len : size_t ) -> c_int where Self : Sized ;
33
- fn data_ptr ( & mut self ) -> * mut c_void ;
34
- }
35
-
36
- #[ cfg( feature = "std" ) ]
37
- impl < IO : Read + Write > IoCallback for IO {
38
- unsafe extern "C" fn call_recv ( user_data : * mut c_void , data : * mut c_uchar , len : size_t ) -> c_int {
39
- let len = if len > ( c_int:: max_value ( ) as size_t ) {
40
- c_int:: max_value ( ) as size_t
41
- } else {
42
- len
43
- } ;
44
- match ( & mut * ( user_data as * mut IO ) ) . read ( :: core:: slice:: from_raw_parts_mut ( data, len) ) {
45
- Ok ( i) => i as c_int ,
46
- Err ( _) => :: mbedtls_sys:: ERR_NET_RECV_FAILED ,
47
- }
48
- }
49
-
50
- unsafe extern "C" fn call_send ( user_data : * mut c_void , data : * const c_uchar , len : size_t ) -> c_int {
51
- let len = if len > ( c_int:: max_value ( ) as size_t ) {
52
- c_int:: max_value ( ) as size_t
53
- } else {
54
- len
55
- } ;
56
- match ( & mut * ( user_data as * mut IO ) ) . write ( :: core:: slice:: from_raw_parts ( data, len) ) {
57
- Ok ( i) => i as c_int ,
58
- Err ( _) => :: mbedtls_sys:: ERR_NET_SEND_FAILED ,
59
- }
60
- }
61
-
62
- fn data_ptr ( & mut self ) -> * mut c_void {
63
- self as * mut IO as * mut _
64
- }
65
- }
66
-
67
- #[ cfg( feature = "std" ) ]
68
- pub struct ConnectedUdpSocket {
69
- socket : std:: net:: UdpSocket ,
70
- }
71
-
72
- #[ cfg( feature = "std" ) ]
73
- impl ConnectedUdpSocket {
74
- pub fn connect < A : std:: net:: ToSocketAddrs > ( socket : std:: net:: UdpSocket , addr : A ) -> StdResult < Self , ( IoError , std:: net:: UdpSocket ) > {
75
- match socket. connect ( addr) {
76
- Ok ( _) => Ok ( ConnectedUdpSocket {
77
- socket,
78
- } ) ,
79
- Err ( e) => Err ( ( e, socket) ) ,
80
- }
81
- }
82
- }
83
-
84
- #[ cfg( feature = "std" ) ]
85
- impl IoCallback for ConnectedUdpSocket {
86
- unsafe extern "C" fn call_recv ( user_data : * mut c_void , data : * mut c_uchar , len : size_t ) -> c_int {
87
- let len = if len > ( c_int:: max_value ( ) as size_t ) {
88
- c_int:: max_value ( ) as size_t
89
- } else {
90
- len
91
- } ;
92
- match ( & mut * ( user_data as * mut ConnectedUdpSocket ) ) . socket . recv ( :: core:: slice:: from_raw_parts_mut ( data, len) ) {
93
- Ok ( i) => i as c_int ,
94
- Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: WouldBlock => 0 ,
95
- Err ( _) => :: mbedtls_sys:: ERR_NET_RECV_FAILED ,
96
- }
97
- }
98
-
99
- unsafe extern "C" fn call_send ( user_data : * mut c_void , data : * const c_uchar , len : size_t ) -> c_int {
100
- let len = if len > ( c_int:: max_value ( ) as size_t ) {
101
- c_int:: max_value ( ) as size_t
102
- } else {
103
- len
104
- } ;
105
- match ( & mut * ( user_data as * mut ConnectedUdpSocket ) ) . socket . send ( :: core:: slice:: from_raw_parts ( data, len) ) {
106
- Ok ( i) => i as c_int ,
107
- Err ( _) => :: mbedtls_sys:: ERR_NET_SEND_FAILED ,
108
- }
109
- }
110
-
111
- fn data_ptr ( & mut self ) -> * mut c_void {
112
- self as * mut ConnectedUdpSocket as * mut c_void
113
- }
114
- }
115
-
116
27
pub trait TimerCallback : Send + Sync {
117
28
unsafe extern "C" fn set_timer (
118
29
p_timer : * mut c_void ,
@@ -261,8 +172,13 @@ impl<T> Context<T> {
261
172
}
262
173
}
263
174
264
- impl < T : IoCallback > Context < T > {
265
- pub fn establish ( & mut self , io : T , hostname : Option < & str > ) -> Result < ( ) > {
175
+ impl < T > Context < T > {
176
+ /// Establish a TLS session on the given `io`.
177
+ ///
178
+ /// Upon succesful return, the context can be communicated with using the
179
+ /// `std::io::Read` and `std::io::Write` traits if `io` implements those as
180
+ /// well, and using the `mbedtls::ssl::io::Io` trait otherwise.
181
+ pub fn establish < IoType > ( & mut self , io : T , hostname : Option < & str > ) -> Result < ( ) > where T : IoCallbackUnsafe < IoType > {
266
182
unsafe {
267
183
let mut io = Box :: new ( io) ;
268
184
ssl_session_reset ( self . into ( ) ) . into_result ( ) ?;
@@ -292,7 +208,7 @@ impl<T> Context<T> {
292
208
/// Try to complete the handshake procedure to set up a (D)TLS connection
293
209
///
294
210
/// In general, this should not be called directly. Instead, [`establish`](Context::establish)
295
- /// should be used which properly sets up the [`IoCallback `] and resets any previous sessions.
211
+ /// should be used which properly sets up the [`IoCallbackUnsafe `] and resets any previous sessions.
296
212
///
297
213
/// This should only be used directly if the handshake could not be completed successfully in
298
214
/// `establish`, i.e.:
@@ -483,16 +399,14 @@ impl<T> Context<T> {
483
399
pub fn set_client_transport_id_once ( & mut self , info : & [ u8 ] ) {
484
400
self . client_transport_id = Some ( info. into ( ) ) ;
485
401
}
486
- }
487
402
488
- impl < T : IoCallback > Context < T > {
489
- pub fn recv ( & mut self , buf : & mut [ u8 ] ) -> Result < usize > {
403
+ pub ( super ) fn recv ( & mut self , buf : & mut [ u8 ] ) -> Result < usize > {
490
404
unsafe {
491
405
ssl_read ( self . into ( ) , buf. as_mut_ptr ( ) , buf. len ( ) ) . into_result ( ) . map ( |r| r as usize )
492
406
}
493
407
}
494
408
495
- pub fn send ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
409
+ pub ( super ) fn send ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
496
410
unsafe {
497
411
ssl_write ( self . into ( ) , buf. as_ptr ( ) , buf. len ( ) ) . into_result ( ) . map ( |w| w as usize )
498
412
}
@@ -508,40 +422,6 @@ impl<T> Drop for Context<T> {
508
422
}
509
423
}
510
424
511
- #[ cfg( feature = "std" ) ]
512
- /// Implements [`std::io::Read`] whenever T implements `Read`, too. This ensures that
513
- /// `Read`, which is designated for byte-oriented sources, is only implemented when the
514
- /// underlying [`IoCallback`] is byte-oriented, too. Specifically, this means that it is implemented
515
- /// for `Context<TcpStream>`, i.e. TLS connections but not for DTLS connections.
516
- impl < T : IoCallback + Read > Read for Context < T > {
517
- fn read ( & mut self , buf : & mut [ u8 ] ) -> IoResult < usize > {
518
- match self . recv ( buf) {
519
- Err ( Error :: SslPeerCloseNotify ) => Ok ( 0 ) ,
520
- Err ( e) => Err ( crate :: private:: error_to_io_error ( e) ) ,
521
- Ok ( i) => Ok ( i) ,
522
- }
523
- }
524
- }
525
-
526
- #[ cfg( feature = "std" ) ]
527
- /// Implements [`std::io::Write`] whenever T implements `Write`, too. This ensures that
528
- /// `Write`, which is designated for byte-oriented sinks, is only implemented when the
529
- /// underlying [`IoCallback`] is byte-oriented, too. Specifically, this means that it is implemented
530
- /// for `Context<TcpStream>`, i.e. TLS connections but not for DTLS connections.
531
- impl < T : IoCallback + Write > Write for Context < T > {
532
- fn write ( & mut self , buf : & [ u8 ] ) -> IoResult < usize > {
533
- match self . send ( buf) {
534
- Err ( Error :: SslPeerCloseNotify ) => Ok ( 0 ) ,
535
- Err ( e) => Err ( crate :: private:: error_to_io_error ( e) ) ,
536
- Ok ( i) => Ok ( i) ,
537
- }
538
- }
539
-
540
- fn flush ( & mut self ) -> IoResult < ( ) > {
541
- Ok ( ( ) )
542
- }
543
- }
544
-
545
425
//
546
426
// Class exists only during SNI callback that is configured from Config.
547
427
// SNI Callback must provide input whose lifetime exceeds the SNI closure to avoid memory corruptions.
0 commit comments