4141//! ```
4242#![ allow( clippy:: missing_safety_doc) ]
4343use crate :: bio:: { MemBio , MemBioSlice } ;
44+ #[ cfg( ossl300) ]
45+ use crate :: bn:: BigNumRef ;
4446#[ cfg( ossl110) ]
4547use crate :: cipher:: CipherRef ;
4648use crate :: dh:: Dh ;
@@ -51,10 +53,14 @@ use crate::error::ErrorStack;
5153use crate :: pkey_ctx:: PkeyCtx ;
5254use crate :: rsa:: Rsa ;
5355use crate :: symm:: Cipher ;
56+ #[ cfg( ossl300) ]
57+ use crate :: util:: ForeignTypeRefExt ;
5458use crate :: util:: { invoke_passwd_cb, CallbackState } ;
5559use crate :: { cvt, cvt_p} ;
5660use cfg_if:: cfg_if;
5761use foreign_types:: { ForeignType , ForeignTypeRef } ;
62+ #[ cfg( ossl300) ]
63+ use libc:: c_char;
5864use libc:: { c_int, c_long} ;
5965use openssl_macros:: corresponds;
6066use std:: convert:: { TryFrom , TryInto } ;
@@ -207,6 +213,43 @@ impl<T> PKeyRef<T> {
207213 pub fn size ( & self ) -> usize {
208214 unsafe { ffi:: EVP_PKEY_size ( self . as_ptr ( ) ) as usize }
209215 }
216+
217+ /// Returns the BigNum value associated with the given key name.
218+ #[ corresponds( EVP_PKEY_get_bn_param ) ]
219+ #[ cfg( ossl300) ]
220+ pub fn get_bn_param ( & self , key : & str ) -> Result < & BigNumRef , ErrorStack > {
221+ let key = CString :: new ( key) . unwrap ( ) ;
222+ let mut value = ptr:: null_mut ( ) ;
223+ unsafe {
224+ cvt ( ffi:: EVP_PKEY_get_bn_param (
225+ self . as_ptr ( ) ,
226+ key. as_ptr ( ) ,
227+ & mut value,
228+ ) ) ?;
229+ Ok ( BigNumRef :: from_const_ptr ( value) )
230+ }
231+ }
232+
233+ /// Returns the String value associated with the given key name.
234+ #[ corresponds( EVP_PKEY_get_utf8_string_param ) ]
235+ #[ cfg( ossl300) ]
236+ pub fn get_utf8_string_param ( & self , key : & str ) -> Result < String , ErrorStack > {
237+ const VALUE_LEN : usize = 4096 ;
238+ let key = CString :: new ( key) . unwrap ( ) ;
239+ let mut value_buf: Vec < u8 > = vec ! [ 0 ; VALUE_LEN ] ;
240+ let mut out_len: usize = 0 ;
241+ unsafe {
242+ cvt ( ffi:: EVP_PKEY_get_utf8_string_param (
243+ self . as_ptr ( ) ,
244+ key. as_ptr ( ) ,
245+ value_buf. as_mut_ptr ( ) . cast :: < c_char > ( ) ,
246+ VALUE_LEN ,
247+ & mut out_len,
248+ ) ) ?;
249+ }
250+ value_buf. truncate ( out_len) ;
251+ Ok ( String :: from_utf8 ( value_buf) . unwrap ( ) )
252+ }
210253}
211254
212255impl < T > PKeyRef < T >
@@ -916,11 +959,15 @@ impl<T> TryFrom<PKey<T>> for Dh<T> {
916959
917960#[ cfg( test) ]
918961mod tests {
962+ #[ cfg( ossl300) ]
963+ use std:: cmp:: Ordering ;
919964 use std:: convert:: TryInto ;
920965
921966 #[ cfg( not( boringssl) ) ]
922967 use crate :: dh:: Dh ;
923968 use crate :: dsa:: Dsa ;
969+ #[ cfg( ossl300) ]
970+ use crate :: ec:: EcGroup ;
924971 use crate :: ec:: EcKey ;
925972 use crate :: error:: Error ;
926973 use crate :: nid:: Nid ;
@@ -1219,4 +1266,32 @@ mod tests {
12191266 assert ! ( !pkey1. public_eq( & pkey2) ) ;
12201267 assert ! ( Error :: get( ) . is_none( ) ) ;
12211268 }
1269+
1270+ #[ cfg( ossl300) ]
1271+ #[ test]
1272+ fn test_get_bn_param ( ) {
1273+ let rsa = Rsa :: generate ( 2048 ) . unwrap ( ) ;
1274+ let pkey = PKey :: from_rsa ( rsa. clone ( ) ) . unwrap ( ) ;
1275+ assert_eq ! (
1276+ pkey. get_bn_param( "n" ) . unwrap( ) . ucmp( rsa. n( ) ) ,
1277+ Ordering :: Equal
1278+ ) ;
1279+ assert_eq ! (
1280+ pkey. get_bn_param( "d" ) . unwrap( ) . ucmp( rsa. d( ) ) ,
1281+ Ordering :: Equal
1282+ ) ;
1283+ }
1284+
1285+ #[ cfg( ossl300) ]
1286+ #[ test]
1287+ fn test_get_utf8_string_param ( ) {
1288+ let group = EcGroup :: from_curve_name ( Nid :: X9_62_PRIME256V1 ) . unwrap ( ) ;
1289+ let ec = EcKey :: generate ( & group) . unwrap ( ) ;
1290+ let pkey = PKey :: from_ec_key ( ec. clone ( ) ) . unwrap ( ) ;
1291+
1292+ assert_eq ! (
1293+ pkey. get_utf8_string_param( "group" ) . unwrap( ) ,
1294+ String :: from( "prime256v1" )
1295+ ) ;
1296+ }
12221297}
0 commit comments