@@ -67,6 +67,8 @@ let cmac_key = ctx.keygen().unwrap();
6767#[ cfg( not( any( boringssl, awslc) ) ) ]
6868use crate :: cipher:: CipherRef ;
6969use crate :: error:: ErrorStack ;
70+ #[ cfg( ossl300) ]
71+ use crate :: lib_ctx:: LibCtxRef ;
7072use crate :: md:: MdRef ;
7173use crate :: pkey:: { HasPrivate , HasPublic , Id , PKey , PKeyRef , Private } ;
7274use crate :: rsa:: Padding ;
@@ -81,6 +83,8 @@ use openssl_macros::corresponds;
8183use std:: convert:: TryFrom ;
8284#[ cfg( ossl320) ]
8385use std:: ffi:: CStr ;
86+ #[ cfg( ossl300) ]
87+ use std:: ffi:: CString ;
8488use std:: ptr;
8589
8690/// HKDF modes of operation.
@@ -156,6 +160,26 @@ impl PkeyCtx<()> {
156160 Ok ( PkeyCtx :: from_ptr ( ptr) )
157161 }
158162 }
163+
164+ /// Creates a new pkey context from the algorithm name.
165+ #[ corresponds( EVP_PKEY_CTX_new_from_name ) ]
166+ #[ cfg( ossl300) ]
167+ pub fn new_from_name (
168+ libctx : Option < & LibCtxRef > ,
169+ name : & str ,
170+ propquery : Option < & str > ,
171+ ) -> Result < Self , ErrorStack > {
172+ unsafe {
173+ let propquery = propquery. map ( |s| CString :: new ( s) . unwrap ( ) ) ;
174+ let name = CString :: new ( name) . unwrap ( ) ;
175+ let ptr = cvt_p ( ffi:: EVP_PKEY_CTX_new_from_name (
176+ libctx. map_or ( ptr:: null_mut ( ) , ForeignTypeRef :: as_ptr) ,
177+ name. as_ptr ( ) ,
178+ propquery. map_or ( ptr:: null_mut ( ) , |s| s. as_ptr ( ) ) ,
179+ ) ) ?;
180+ Ok ( PkeyCtx :: from_ptr ( ptr) )
181+ }
182+ }
159183}
160184
161185impl < T > PkeyCtxRef < T >
@@ -756,6 +780,20 @@ impl<T> PkeyCtxRef<T> {
756780 Ok ( ( ) )
757781 }
758782
783+ /// Generates a new public/private keypair.
784+ ///
785+ /// New OpenSSL 3.0 function, that should do the same thing as keygen()
786+ #[ corresponds( EVP_PKEY_generate ) ]
787+ #[ cfg( ossl300) ]
788+ #[ inline]
789+ pub fn generate ( & mut self ) -> Result < PKey < Private > , ErrorStack > {
790+ unsafe {
791+ let mut key = ptr:: null_mut ( ) ;
792+ cvt ( ffi:: EVP_PKEY_generate ( self . as_ptr ( ) , & mut key) ) ?;
793+ Ok ( PKey :: from_ptr ( key) )
794+ }
795+ }
796+
759797 /// Gets the nonce type for a private key context.
760798 ///
761799 /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
@@ -780,6 +818,14 @@ impl<T> PkeyCtxRef<T> {
780818 }
781819 Ok ( NonceType ( nonce_type) )
782820 }
821+
822+ /// Initializes a conversion from `OsslParam` to `PKey` on given `PkeyCtx`.
823+ #[ corresponds( EVP_PKEY_fromdata_init ) ]
824+ #[ cfg( ossl300) ]
825+ pub fn fromdata_init ( & mut self ) -> Result < ( ) , ErrorStack > {
826+ unsafe { cvt ( ffi:: EVP_PKEY_fromdata_init ( self . as_ptr ( ) ) ) ? } ;
827+ Ok ( ( ) )
828+ }
783829}
784830
785831#[ cfg( test) ]
@@ -1107,4 +1153,14 @@ mxJ7imIrEg9nIQ==
11071153 assert_eq ! ( output, expected_output) ;
11081154 assert ! ( ErrorStack :: get( ) . errors( ) . is_empty( ) ) ;
11091155 }
1156+
1157+ #[ test]
1158+ #[ cfg( ossl300) ]
1159+ fn test_pkeyctx_from_name ( ) {
1160+ let lib_ctx = crate :: lib_ctx:: LibCtx :: new ( ) . unwrap ( ) ;
1161+ let _: PkeyCtx < ( ) > = PkeyCtx :: new_from_name ( Some ( lib_ctx. as_ref ( ) ) , "RSA" , None ) . unwrap ( ) ;
1162+
1163+ /* no libctx is ok */
1164+ let _: PkeyCtx < ( ) > = PkeyCtx :: new_from_name ( None , "RSA" , None ) . unwrap ( ) ;
1165+ }
11101166}
0 commit comments