1313//! Note, that this module is available only in OpenSSL 3.* and
1414//! only internally for this crate.
1515
16- use crate :: bn:: BigNumRef ;
1716use crate :: error:: ErrorStack ;
17+ use crate :: util;
1818use crate :: { cvt, cvt_p} ;
19- use foreign_types:: { ForeignType , ForeignTypeRef } ;
20- use libc:: { c_char , c_uint, c_void} ;
19+ use foreign_types:: ForeignType ;
20+ use libc:: { c_uint, c_void} ;
2121use openssl_macros:: corresponds;
2222use std:: ffi:: CStr ;
2323use std:: marker:: PhantomData ;
24+ use std:: ptr;
2425
2526foreign_type_and_impl_send_sync ! {
2627 // This is the singular type, but it is always allocated
@@ -37,6 +38,29 @@ foreign_type_and_impl_send_sync! {
3738 pub struct OsslParamArrayRef ;
3839}
3940
41+ impl OsslParamArray {
42+ /// Locates the individual `OSSL_PARAM` element representing an
43+ /// octet string identified by the key in the `OsslParamArray`
44+ /// array and returns a reference to it.
45+ ///
46+ /// Combines OSSL_PARAM_locate and OSSL_PARAM_get_octet_string.
47+ #[ corresponds( OSSL_PARAM_get_octet_string ) ]
48+ #[ allow( dead_code) ] // TODO: remove when when used by ML-DSA / ML-KEM
49+ pub ( crate ) fn locate_octet_string < ' a > ( & ' a self , key : & CStr ) -> Result < & ' a [ u8 ] , ErrorStack > {
50+ unsafe {
51+ let param = cvt_p ( ffi:: OSSL_PARAM_locate ( self . as_ptr ( ) , key. as_ptr ( ) ) ) ?;
52+ let mut val: * const c_void = ptr:: null_mut ( ) ;
53+ let mut val_len: usize = 0 ;
54+ cvt ( ffi:: OSSL_PARAM_get_octet_string_ptr (
55+ param,
56+ & mut val,
57+ & mut val_len,
58+ ) ) ?;
59+ Ok ( util:: from_raw_parts ( val as * const u8 , val_len) )
60+ }
61+ }
62+ }
63+
4064foreign_type_and_impl_send_sync ! {
4165 type CType = ffi:: OSSL_PARAM_BLD ;
4266 fn drop = ffi:: OSSL_PARAM_BLD_free ;
@@ -82,39 +106,6 @@ impl<'a> OsslParamBuilder<'a> {
82106 }
83107 }
84108
85- /// Adds a `BigNum` to `OsslParamBuilder`.
86- #[ corresponds( OSSL_PARAM_BLD_push_BN ) ]
87- #[ allow( dead_code) ] // TODO: remove when when used by ML-DSA / ML-KEM
88- pub ( crate ) fn add_bn ( & mut self , key : & ' a CStr , bn : & ' a BigNumRef ) -> Result < ( ) , ErrorStack > {
89- unsafe {
90- cvt ( ffi:: OSSL_PARAM_BLD_push_BN (
91- self . as_ptr ( ) ,
92- key. as_ptr ( ) ,
93- bn. as_ptr ( ) ,
94- ) )
95- . map ( |_| ( ) )
96- }
97- }
98-
99- /// Adds a utf8 string to `OsslParamBuilder`.
100- #[ corresponds( OSSL_PARAM_BLD_push_utf8_string ) ]
101- #[ allow( dead_code) ] // TODO: remove when when used by ML-DSA / ML-KEM
102- pub ( crate ) fn add_utf8_string (
103- & mut self ,
104- key : & ' a CStr ,
105- buf : & ' a str ,
106- ) -> Result < ( ) , ErrorStack > {
107- unsafe {
108- cvt ( ffi:: OSSL_PARAM_BLD_push_utf8_string (
109- self . as_ptr ( ) ,
110- key. as_ptr ( ) ,
111- buf. as_ptr ( ) as * const c_char ,
112- buf. len ( ) ,
113- ) )
114- . map ( |_| ( ) )
115- }
116- }
117-
118109 /// Adds a octet string to `OsslParamBuilder`.
119110 #[ corresponds( OSSL_PARAM_BLD_push_octet_string ) ]
120111 #[ cfg_attr( any( not( ossl320) , osslconf = "OPENSSL_NO_ARGON2" ) , allow( dead_code) ) ]
@@ -153,3 +144,26 @@ impl<'a> OsslParamBuilder<'a> {
153144 self . builder . as_ptr ( )
154145 }
155146}
147+
148+ #[ cfg( test) ]
149+ mod tests {
150+ use super :: * ;
151+ #[ test]
152+ fn test_builder_locate_octet_string ( ) {
153+ let mut builder = OsslParamBuilder :: new ( ) . unwrap ( ) ;
154+ builder
155+ . add_octet_string ( CStr :: from_bytes_with_nul ( b"key1\0 " ) . unwrap ( ) , b"value1" )
156+ . unwrap ( ) ;
157+ let params = builder. to_param ( ) . unwrap ( ) ;
158+
159+ assert ! ( params
160+ . locate_octet_string( CStr :: from_bytes_with_nul( b"invalid\0 " ) . unwrap( ) )
161+ . is_err( ) ) ;
162+ assert_eq ! (
163+ params
164+ . locate_octet_string( CStr :: from_bytes_with_nul( b"key1\0 " ) . unwrap( ) )
165+ . unwrap( ) ,
166+ b"value1"
167+ ) ;
168+ }
169+ }
0 commit comments