1
1
use crate :: bn:: BigNumRef ;
2
2
use crate :: error:: ErrorStack ;
3
3
use crate :: { cvt, cvt_p} ;
4
- use foreign_types:: ForeignType ;
4
+ use foreign_types:: { ForeignType , ForeignTypeRef , Opaque } ;
5
5
use libc:: { c_char, c_void} ;
6
6
use openssl_macros:: corresponds;
7
7
use std:: ffi:: CStr ;
8
8
use std:: marker:: PhantomData ;
9
9
10
+ pub struct Params < ' a > ( * mut ffi:: OSSL_PARAM , PhantomData < & ' a ( ) > ) ;
11
+
12
+ impl < ' a > ForeignType for Params < ' a > {
13
+ type CType = ffi:: OSSL_PARAM ;
14
+ type Ref = ParamsRef < ' a > ;
15
+
16
+ #[ inline]
17
+ unsafe fn from_ptr ( ptr : * mut ffi:: OSSL_PARAM ) -> Params < ' a > {
18
+ Self ( ptr, PhantomData )
19
+ }
20
+
21
+ #[ inline]
22
+ fn as_ptr ( & self ) -> * mut ffi:: OSSL_PARAM {
23
+ self . 0
24
+ }
25
+ }
26
+
27
+ impl Drop for Params < ' _ > {
28
+ fn drop ( & mut self ) {
29
+ unsafe { ffi:: OSSL_PARAM_free ( self . 0 ) } ;
30
+ }
31
+ }
32
+
33
+ impl Clone for Params < ' _ > {
34
+ #[ inline]
35
+ fn clone ( & self ) -> Self {
36
+ Self ( unsafe { ffi:: OSSL_PARAM_dup ( self . 0 ) } , PhantomData )
37
+ }
38
+ }
39
+
40
+ impl < ' a > ToOwned for ParamsRef < ' a > {
41
+ type Owned = Params < ' a > ;
42
+
43
+ #[ inline]
44
+ fn to_owned ( & self ) -> Params < ' a > {
45
+ unsafe {
46
+ let handle: * mut ffi:: OSSL_PARAM = ffi:: OSSL_PARAM_dup ( self . as_ptr ( ) ) ;
47
+ ForeignType :: from_ptr ( handle)
48
+ }
49
+ }
50
+ }
51
+
52
+ impl < ' a > std:: ops:: Deref for Params < ' a > {
53
+ type Target = ParamsRef < ' a > ;
54
+
55
+ #[ inline]
56
+ fn deref ( & self ) -> & ParamsRef < ' a > {
57
+ unsafe { ParamsRef :: from_ptr ( self . as_ptr ( ) ) }
58
+ }
59
+ }
60
+
61
+ impl < ' a > std:: ops:: DerefMut for Params < ' a > {
62
+ #[ inline]
63
+ fn deref_mut ( & mut self ) -> & mut ParamsRef < ' a > {
64
+ unsafe { ParamsRef :: from_ptr_mut ( self . as_ptr ( ) ) }
65
+ }
66
+ }
67
+
68
+ impl < ' a > std:: borrow:: Borrow < ParamsRef < ' a > > for Params < ' a > {
69
+ #[ inline]
70
+ fn borrow ( & self ) -> & ParamsRef < ' a > {
71
+ self
72
+ }
73
+ }
74
+
75
+ impl < ' a > AsRef < ParamsRef < ' a > > for Params < ' a > {
76
+ #[ inline]
77
+ fn as_ref ( & self ) -> & ParamsRef < ' a > {
78
+ self
79
+ }
80
+ }
81
+
82
+ pub struct ParamsRef < ' a > ( Opaque , PhantomData < & ' a ( ) > ) ;
83
+
84
+ impl ForeignTypeRef for ParamsRef < ' _ > {
85
+ type CType = ffi:: OSSL_PARAM ;
86
+ }
87
+
88
+ unsafe impl Send for Params < ' _ > { }
89
+ unsafe impl Send for ParamsRef < ' _ > { }
90
+ unsafe impl Sync for Params < ' _ > { }
91
+ unsafe impl Sync for ParamsRef < ' _ > { }
92
+
93
+ impl < ' a > ParamsRef < ' a > {
94
+ /// Merges two `ParamsRef` objects into a new `Params` object.
95
+ #[ corresponds( OSSL_PARAM_merge ) ]
96
+ pub fn merge ( & self , other : & ParamsRef < ' a > ) -> Result < Params < ' a > , ErrorStack > {
97
+ cvt_p ( unsafe { ffi:: OSSL_PARAM_merge ( self . as_ptr ( ) , other. as_ptr ( ) ) } )
98
+ . map ( |p| unsafe { Params :: from_ptr ( p) } )
99
+ }
100
+
101
+ /// Locate a parameter by the given key.
102
+ #[ corresponds( OSSL_PARAM_locate_const ) ]
103
+ fn locate ( & self , key : & CStr ) -> Option < * const ffi:: OSSL_PARAM > {
104
+ let param = unsafe { ffi:: OSSL_PARAM_locate_const ( self . as_ptr ( ) , key. as_ptr ( ) ) } ;
105
+ if param. is_null ( ) {
106
+ None
107
+ } else {
108
+ Some ( param)
109
+ }
110
+ }
111
+ }
112
+
10
113
pub struct ParamBuilder < ' a > ( * mut ffi:: OSSL_PARAM_BLD , PhantomData < & ' a ( ) > ) ;
11
114
12
115
impl Drop for ParamBuilder < ' _ > {
@@ -28,13 +131,14 @@ impl<'a, 'b> ParamBuilder<'a> {
28
131
29
132
/// Push a BigNum parameter into the builder.
30
133
#[ corresponds[ OSSL_PARAM_BLD_push_BN ] ]
31
- pub fn push_bignum ( & mut self , key : & ' b CStr , bn : & ' a BigNumRef ) -> Result < ( ) , ErrorStack > {
32
- cvt ( unsafe { ffi:: OSSL_PARAM_BLD_push_BN ( self . 0 , key. as_ptr ( ) , bn. as_ptr ( ) ) } ) . map ( |_| ( ) )
134
+ pub fn push_bignum ( self , key : & ' b CStr , bn : & ' a BigNumRef ) -> Result < Self , ErrorStack > {
135
+ cvt ( unsafe { ffi:: OSSL_PARAM_BLD_push_BN ( self . 0 , key. as_ptr ( ) , bn. as_ptr ( ) ) } ) ?;
136
+ Ok ( self )
33
137
}
34
138
35
139
/// Push a UTF-8 String parameter into the builder.
36
140
#[ corresponds[ OSSL_PARAM_BLD_push_utf8_string ] ]
37
- pub fn push_utf_string ( & mut self , key : & ' b CStr , string : & ' a str ) -> Result < ( ) , ErrorStack > {
141
+ pub fn push_utf_string ( self , key : & ' b CStr , string : & ' a str ) -> Result < Self , ErrorStack > {
38
142
let value = string. as_bytes ( ) ;
39
143
cvt ( unsafe {
40
144
ffi:: OSSL_PARAM_BLD_push_utf8_string (
@@ -43,8 +147,8 @@ impl<'a, 'b> ParamBuilder<'a> {
43
147
value. as_ptr ( ) . cast :: < c_char > ( ) ,
44
148
value. len ( ) ,
45
149
)
46
- } )
47
- . map ( |_| ( ) )
150
+ } ) ? ;
151
+ Ok ( self )
48
152
}
49
153
50
154
/// Push a byte string parameter into the builder.
@@ -80,8 +184,9 @@ impl<'a, 'b> ParamBuilder<'a> {
80
184
81
185
/// Build a `Params` array from the builder consuming the builder.
82
186
#[ corresponds( OSSL_PARAM_BLD_to_param ) ]
83
- pub fn build ( self ) -> Result < * mut ffi:: OSSL_PARAM , ErrorStack > {
84
- cvt_p ( unsafe { ffi:: OSSL_PARAM_BLD_to_param ( self . 0 ) } )
187
+ pub fn build ( self ) -> Result < Params < ' b > , ErrorStack > {
188
+ let ptr = cvt_p ( unsafe { ffi:: OSSL_PARAM_BLD_to_param ( self . 0 ) } ) ?;
189
+ Ok ( unsafe { Params :: from_ptr ( ptr) } )
85
190
}
86
191
}
87
192
@@ -91,12 +196,10 @@ mod test {
91
196
use crate :: bn:: BigNum ;
92
197
use crate :: util:: c_str;
93
198
94
- fn assert_param ( params : * mut ffi:: OSSL_PARAM , key : & CStr , is_null : bool ) {
95
- let param = unsafe { ffi:: OSSL_PARAM_locate_const ( params, key. as_ptr ( ) ) } ;
96
- if is_null {
97
- assert ! ( param. is_null( ) , "Unexpectedly found param: {key:?}" ) ;
98
- } else {
99
- assert ! ( !param. is_null( ) , "Failed to find param: {key:?}" ) ;
199
+ fn assert_param ( params : & ParamsRef < ' _ > , key : & CStr , is_null : bool ) {
200
+ match params. locate ( key) {
201
+ Some ( _) => assert ! ( !is_null, "Unexpectedly found param: {key:?}" ) ,
202
+ None => assert ! ( is_null, "Failed to find param: {key:?}" ) ,
100
203
}
101
204
}
102
205
@@ -108,8 +211,8 @@ mod test {
108
211
. build ( )
109
212
. unwrap ( ) ;
110
213
111
- assert_param ( params, c_str ( b"nonce-type\0 " ) , false ) ;
112
- assert_param ( params, c_str ( b"group\0 " ) , true ) ;
214
+ assert_param ( & params, c_str ( b"nonce-type\0 " ) , false ) ;
215
+ assert_param ( & params, c_str ( b"group\0 " ) , true ) ;
113
216
}
114
217
115
218
#[ test]
@@ -120,39 +223,43 @@ mod test {
120
223
. build ( )
121
224
. unwrap ( ) ;
122
225
123
- assert_param ( params, c_str ( b"size\0 " ) , false ) ;
124
- assert_param ( params, c_str ( b"out\0 " ) , true ) ;
226
+ assert_param ( & params, c_str ( b"size\0 " ) , false ) ;
227
+ assert_param ( & params, c_str ( b"out\0 " ) , true ) ;
125
228
}
126
229
127
230
#[ test]
128
231
fn test_param_builder_bignum ( ) {
129
- let n = BigNum :: from_u32 ( 0xbc747fc5 ) . unwrap ( ) ;
130
- let e = BigNum :: from_u32 ( 0x10001 ) . unwrap ( ) ;
131
- let d = BigNum :: from_u32 ( 0x7b133399 ) . unwrap ( ) ;
232
+ let a = BigNum :: from_u32 ( 0x01 ) . unwrap ( ) ;
233
+ let b = BigNum :: from_u32 ( 0x02 ) . unwrap ( ) ;
234
+ let c = BigNum :: from_u32 ( 0x03 ) . unwrap ( ) ;
132
235
133
- let mut builder = ParamBuilder :: new ( ) ;
134
- builder. push_bignum ( c_str ( b"n\0 " ) , & n) . unwrap ( ) ;
135
- builder. push_bignum ( c_str ( b"e\0 " ) , & e) . unwrap ( ) ;
136
- builder. push_bignum ( c_str ( b"d\0 " ) , & d) . unwrap ( ) ;
137
- let params = builder. build ( ) . unwrap ( ) ;
236
+ let params = ParamBuilder :: new ( )
237
+ . push_bignum ( c_str ( b"a\0 " ) , & a)
238
+ . unwrap ( )
239
+ . push_bignum ( c_str ( b"b\0 " ) , & b)
240
+ . unwrap ( )
241
+ . push_bignum ( c_str ( b"c\0 " ) , & c)
242
+ . unwrap ( )
243
+ . build ( )
244
+ . unwrap ( ) ;
138
245
139
- for param in [ b"n \0 " , b"e\0 " , b"d \0 " ] {
140
- assert_param ( params, c_str ( param) , false ) ;
246
+ for param in [ b"a \0 " , b"e\0 " , b"c \0 " ] {
247
+ assert_param ( & params, c_str ( param) , false ) ;
141
248
}
142
249
143
- assert_param ( params, c_str ( b"group\0 " ) , true ) ;
250
+ assert_param ( & params, c_str ( b"group\0 " ) , true ) ;
144
251
}
145
252
146
253
#[ test]
147
254
fn test_param_builder_string ( ) {
148
- let mut builder = ParamBuilder :: new ( ) ;
149
- builder
255
+ let params = ParamBuilder :: new ( )
150
256
. push_utf_string ( c_str ( b"group\0 " ) , "primve256v1" )
257
+ . unwrap ( )
258
+ . build ( )
151
259
. unwrap ( ) ;
152
- let params = builder. build ( ) . unwrap ( ) ;
153
260
154
- assert_param ( params, c_str ( b"group\0 " ) , false ) ;
155
- assert_param ( params, c_str ( b"n\0 " ) , true ) ;
261
+ assert_param ( & params, c_str ( b"group\0 " ) , false ) ;
262
+ assert_param ( & params, c_str ( b"n\0 " ) , true ) ;
156
263
}
157
264
158
265
#[ test]
@@ -163,7 +270,42 @@ mod test {
163
270
. build ( )
164
271
. unwrap ( ) ;
165
272
166
- assert_param ( params, c_str ( b"pass\0 " ) , false ) ;
167
- assert_param ( params, c_str ( b"group\0 " ) , true ) ;
273
+ assert_param ( & params, c_str ( b"pass\0 " ) , false ) ;
274
+ assert_param ( & params, c_str ( b"group\0 " ) , true ) ;
275
+ }
276
+
277
+ #[ test]
278
+ fn test_merge ( ) {
279
+ let n = BigNum :: from_u32 ( 0xbc747fc5 ) . unwrap ( ) ;
280
+ let e = BigNum :: from_u32 ( 0x10001 ) . unwrap ( ) ;
281
+ let d = BigNum :: from_u32 ( 0x7b133399 ) . unwrap ( ) ;
282
+
283
+ let params1 = ParamBuilder :: new ( )
284
+ . push_bignum ( c_str ( b"n\0 " ) , & n)
285
+ . unwrap ( )
286
+ . build ( )
287
+ . unwrap ( ) ;
288
+ let params2 = ParamBuilder :: new ( )
289
+ . push_bignum ( c_str ( b"e\0 " ) , & e)
290
+ . unwrap ( )
291
+ . build ( )
292
+ . unwrap ( ) ;
293
+ let params3 = ParamBuilder :: new ( )
294
+ . push_bignum ( c_str ( b"d\0 " ) , & d)
295
+ . unwrap ( )
296
+ . build ( )
297
+ . unwrap ( ) ;
298
+
299
+ // Merge 1 & 2, d (added in 3) should not be present
300
+ let merged_params = params1. merge ( & params2) . unwrap ( ) ;
301
+ assert_param ( & merged_params, c_str ( b"n\0 " ) , false ) ;
302
+ assert_param ( & merged_params, c_str ( b"e\0 " ) , false ) ;
303
+ assert_param ( & merged_params, c_str ( b"d\0 " ) , true ) ;
304
+
305
+ // Merge 3 into 1+2, we should now have all params
306
+ let merged_params = merged_params. merge ( & params3) . unwrap ( ) ;
307
+ assert_param ( & merged_params, c_str ( b"n\0 " ) , false ) ;
308
+ assert_param ( & merged_params, c_str ( b"e\0 " ) , false ) ;
309
+ assert_param ( & merged_params, c_str ( b"e\0 " ) , false ) ;
168
310
}
169
311
}
0 commit comments