@@ -100,6 +100,49 @@ callback!(DbgCallback: Fn(i32, Cow<'_, str>, i32, Cow<'_, str>) -> ());
100
100
callback ! ( SniCallback : Fn ( & mut HandshakeContext , & [ u8 ] ) -> Result <( ) >) ;
101
101
callback ! ( CaCallback : Fn ( & MbedtlsList <Certificate >) -> Result <MbedtlsList <Certificate >>) ;
102
102
103
+
104
+ #[ repr( transparent) ]
105
+ pub struct NullTerminatedStrList {
106
+ c : Box < [ * mut i8 ] > ,
107
+ }
108
+
109
+ unsafe impl Send for NullTerminatedStrList { }
110
+ unsafe impl Sync for NullTerminatedStrList { }
111
+
112
+ impl NullTerminatedStrList {
113
+ pub fn new ( list : & [ & str ] ) -> Result < Self > {
114
+ let mut c = Vec :: with_capacity ( list. len ( ) + 1 ) ;
115
+
116
+ for s in list {
117
+ let cstr = :: std:: ffi:: CString :: new ( * s) . map_err ( |_| Error :: SslBadInputData ) ?;
118
+ c. push ( cstr. into_raw ( ) ) ;
119
+ }
120
+
121
+ c. push ( core:: ptr:: null_mut ( ) ) ;
122
+
123
+ Ok ( NullTerminatedStrList {
124
+ c : c. into_boxed_slice ( ) ,
125
+ } )
126
+ }
127
+
128
+ pub fn as_ptr ( & self ) -> * const * const u8 {
129
+ self . c . as_ptr ( ) as * const _
130
+ }
131
+ }
132
+
133
+ impl Drop for NullTerminatedStrList {
134
+ fn drop ( & mut self ) {
135
+ for i in self . c . iter ( ) {
136
+ unsafe {
137
+ if !( * i) . is_null ( ) {
138
+ let _ = :: std:: ffi:: CString :: from_raw ( * i) ;
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+
145
+
103
146
define ! (
104
147
#[ c_ty( ssl_config) ]
105
148
#[ repr( C ) ]
@@ -116,9 +159,7 @@ define!(
116
159
117
160
ciphersuites: Vec <Arc <Vec <c_int>>>,
118
161
curves: Option <Arc <Vec <ecp_group_id>>>,
119
-
120
- #[ allow( dead_code) ]
121
- dhm: Option <Arc <Dhm >>,
162
+ protocols: Option <Arc <NullTerminatedStrList >>,
122
163
123
164
verify_callback: Option <Arc <dyn VerifyCallback + ' static >>,
124
165
#[ cfg( feature = "std" ) ]
@@ -154,7 +195,7 @@ impl Config {
154
195
rng : None ,
155
196
ciphersuites : vec ! [ ] ,
156
197
curves : None ,
157
- dhm : None ,
198
+ protocols : None ,
158
199
verify_callback : None ,
159
200
#[ cfg( feature = "std" ) ]
160
201
dbg_callback : None ,
@@ -184,6 +225,20 @@ impl Config {
184
225
self . ciphersuites . push ( list) ;
185
226
}
186
227
228
+ /// Set the supported Application Layer Protocols.
229
+ ///
230
+ /// Each protocol name in the list must also be terminated with a null character (`\0`).
231
+ pub fn set_alpn_protocols ( & mut self , protocols : Arc < NullTerminatedStrList > ) -> Result < ( ) > {
232
+ unsafe {
233
+ ssl_conf_alpn_protocols ( & mut self . inner , protocols. as_ptr ( ) as * mut _ )
234
+ . into_result ( )
235
+ . map ( |_| ( ) ) ?;
236
+ }
237
+
238
+ self . protocols = Some ( protocols) ;
239
+ Ok ( ( ) )
240
+ }
241
+
187
242
pub fn set_ciphersuites_for_version ( & mut self , list : Arc < Vec < c_int > > , major : c_int , minor : c_int ) {
188
243
Self :: check_c_list ( & list) ;
189
244
unsafe { ssl_conf_ciphersuites_for_version ( self . into ( ) , list. as_ptr ( ) , major, minor) }
@@ -232,13 +287,13 @@ impl Config {
232
287
/// Takes both DER and PEM forms of FFDH parameters in `DHParams` format.
233
288
///
234
289
/// When calling on PEM-encoded data, `params` must be NULL-terminated
235
- pub fn set_dh_params ( & mut self , dhm : Arc < Dhm > ) -> Result < ( ) > {
290
+ pub fn set_dh_params ( & mut self , dhm : & Dhm ) -> Result < ( ) > {
236
291
unsafe {
292
+ // This copies the dhm parameters and does not store any pointer to it
237
293
ssl_conf_dh_param_ctx ( self . into ( ) , dhm. inner_ffi_mut ( ) )
238
294
. into_result ( )
239
295
. map ( |_| ( ) ) ?;
240
296
}
241
- self . dhm = Some ( dhm) ;
242
297
Ok ( ( ) )
243
298
}
244
299
@@ -316,12 +371,10 @@ impl Config {
316
371
// - We can pointer cast to it to allow storing additional objects.
317
372
//
318
373
let cb = & mut * ( closure as * mut F ) ;
319
- let context = UnsafeFrom :: from ( ctx) . unwrap ( ) ;
320
-
321
- let mut ctx = HandshakeContext :: init ( context) ;
374
+ let ctx = UnsafeFrom :: from ( ctx) . unwrap ( ) ;
322
375
323
376
let name = from_raw_parts ( name, name_len) ;
324
- match cb ( & mut ctx, name) {
377
+ match cb ( ctx, name) {
325
378
Ok ( ( ) ) => 0 ,
326
379
Err ( _) => -1 ,
327
380
}
0 commit comments