@@ -67,7 +67,10 @@ let cmac_key = ctx.keygen().unwrap();
67
67
#[ cfg( not( boringssl) ) ]
68
68
use crate :: cipher:: CipherRef ;
69
69
use crate :: error:: ErrorStack ;
70
+ #[ cfg( ossl300) ]
71
+ use crate :: lib_ctx:: LibCtxRef ;
70
72
use crate :: md:: MdRef ;
73
+ #[ cfg( ossl300) ]
71
74
use crate :: pkey:: { HasPrivate , HasPublic , Id , PKey , PKeyRef , Private } ;
72
75
use crate :: rsa:: Padding ;
73
76
use crate :: sign:: RsaPssSaltlen ;
@@ -81,6 +84,8 @@ use openssl_macros::corresponds;
81
84
use std:: convert:: TryFrom ;
82
85
#[ cfg( ossl320) ]
83
86
use std:: ffi:: CStr ;
87
+ #[ cfg( ossl300) ]
88
+ use std:: ffi:: CString ;
84
89
use std:: ptr;
85
90
86
91
/// HKDF modes of operation.
@@ -156,6 +161,26 @@ impl PkeyCtx<()> {
156
161
Ok ( PkeyCtx :: from_ptr ( ptr) )
157
162
}
158
163
}
164
+
165
+ /// Creates a new pkey context from the algorithm name.
166
+ #[ corresponds( EVP_PKEY_CTX_new_from_name ) ]
167
+ #[ cfg( ossl300) ]
168
+ pub fn new_from_name (
169
+ libctx : Option < & LibCtxRef > ,
170
+ name : & str ,
171
+ propquery : Option < & str > ,
172
+ ) -> Result < Self , ErrorStack > {
173
+ unsafe {
174
+ let propquery = propquery. map ( |s| CString :: new ( s) . unwrap ( ) ) ;
175
+ let name = CString :: new ( name) . unwrap ( ) ;
176
+ let ptr = cvt_p ( ffi:: EVP_PKEY_CTX_new_from_name (
177
+ libctx. map_or ( ptr:: null_mut ( ) , ForeignTypeRef :: as_ptr) ,
178
+ name. as_ptr ( ) ,
179
+ propquery. map_or ( ptr:: null_mut ( ) , |s| s. as_ptr ( ) ) ,
180
+ ) ) ?;
181
+ Ok ( PkeyCtx :: from_ptr ( ptr) )
182
+ }
183
+ }
159
184
}
160
185
161
186
impl < T > PkeyCtxRef < T >
@@ -756,6 +781,20 @@ impl<T> PkeyCtxRef<T> {
756
781
Ok ( ( ) )
757
782
}
758
783
784
+ /// Generates a new public/private keypair.
785
+ ///
786
+ /// New OpenSSL 3.0 function, that should do the same thing as keygen()
787
+ #[ corresponds( EVP_PKEY_generate ) ]
788
+ #[ cfg( ossl300) ]
789
+ #[ inline]
790
+ pub fn generate ( & mut self ) -> Result < PKey < Private > , ErrorStack > {
791
+ unsafe {
792
+ let mut key = ptr:: null_mut ( ) ;
793
+ cvt ( ffi:: EVP_PKEY_generate ( self . as_ptr ( ) , & mut key) ) ?;
794
+ Ok ( PKey :: from_ptr ( key) )
795
+ }
796
+ }
797
+
759
798
/// Gets the nonce type for a private key context.
760
799
///
761
800
/// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
@@ -780,6 +819,14 @@ impl<T> PkeyCtxRef<T> {
780
819
}
781
820
Ok ( NonceType ( nonce_type) )
782
821
}
822
+
823
+ /// Initializes a conversion from `OsllParam` to `PKey` on given `PkeyCtx`.
824
+ #[ corresponds( EVP_PKEY_fromdata_init ) ]
825
+ #[ cfg( ossl300) ]
826
+ pub fn fromdata_init ( & mut self ) -> Result < ( ) , ErrorStack > {
827
+ unsafe { cvt ( ffi:: EVP_PKEY_fromdata_init ( self . as_ptr ( ) ) ) ? } ;
828
+ Ok ( ( ) )
829
+ }
783
830
}
784
831
785
832
#[ cfg( test) ]
@@ -1107,4 +1154,14 @@ mxJ7imIrEg9nIQ==
1107
1154
assert_eq ! ( output, expected_output) ;
1108
1155
assert ! ( ErrorStack :: get( ) . errors( ) . is_empty( ) ) ;
1109
1156
}
1157
+
1158
+ #[ test]
1159
+ #[ cfg( ossl300) ]
1160
+ fn test_pkeyctx_from_name ( ) {
1161
+ let lib_ctx = crate :: lib_ctx:: LibCtx :: new ( ) . unwrap ( ) ;
1162
+ let _: PkeyCtx < ( ) > = PkeyCtx :: new_from_name ( Some ( lib_ctx. as_ref ( ) ) , "RSA" , None ) . unwrap ( ) ;
1163
+
1164
+ /* no libctx is ok */
1165
+ let _: PkeyCtx < ( ) > = PkeyCtx :: new_from_name ( None , "RSA" , None ) . unwrap ( ) ;
1166
+ }
1110
1167
}
0 commit comments