@@ -71,6 +71,8 @@ use crate::error::ErrorStack;
71
71
use crate :: md:: MdRef ;
72
72
use crate :: nid:: Nid ;
73
73
#[ cfg( ossl300) ]
74
+ use crate :: params:: ParamsRef ;
75
+ #[ cfg( ossl300) ]
74
76
use crate :: pkey:: Public ;
75
77
use crate :: pkey:: { HasPrivate , HasPublic , Id , PKey , PKeyRef , Params , Private } ;
76
78
use crate :: rsa:: Padding ;
@@ -457,6 +459,31 @@ impl<T> PkeyCtxRef<T> {
457
459
Ok ( ( ) )
458
460
}
459
461
462
+ /// Prepares the context for creating a key from user data.
463
+ #[ corresponds( EVP_PKEY_fromdata_init ) ]
464
+ #[ inline]
465
+ #[ cfg( ossl300) ]
466
+ #[ allow( dead_code) ]
467
+ pub ( crate ) fn fromdata_init ( & mut self ) -> Result < ( ) , ErrorStack > {
468
+ cvt ( unsafe { ffi:: EVP_PKEY_fromdata_init ( self . as_ptr ( ) ) } ) . map ( |_| ( ) )
469
+ }
470
+
471
+ /// Convert a stack of Params into a PKey.
472
+ #[ corresponds( EVP_PKEY_fromdata ) ]
473
+ #[ inline]
474
+ #[ cfg( ossl300) ]
475
+ #[ allow( dead_code) ]
476
+ pub ( crate ) fn fromdata < K : Selection > (
477
+ & mut self ,
478
+ params : & ParamsRef < ' _ > ,
479
+ ) -> Result < PKey < K > , ErrorStack > {
480
+ let mut key_ptr = ptr:: null_mut ( ) ;
481
+ cvt ( unsafe {
482
+ ffi:: EVP_PKEY_fromdata ( self . as_ptr ( ) , & mut key_ptr, K :: SELECTION , params. as_ptr ( ) )
483
+ } ) ?;
484
+ Ok ( unsafe { PKey :: from_ptr ( key_ptr) } )
485
+ }
486
+
460
487
/// Sets which algorithm was used to compute the digest used in a
461
488
/// signature. With RSA signatures this causes the signature to be wrapped
462
489
/// in a `DigestInfo` structure. This is almost always what you want with
@@ -938,6 +965,18 @@ impl<T> PkeyCtxRef<T> {
938
965
}
939
966
}
940
967
968
+ /// Creates a new `PKey` from the given ID and parameters.
969
+ #[ cfg( ossl300) ]
970
+ #[ allow( dead_code) ]
971
+ pub ( crate ) fn pkey_from_params < K : Selection > (
972
+ id : Id ,
973
+ params : & ParamsRef < ' _ > ,
974
+ ) -> Result < PKey < K > , ErrorStack > {
975
+ let mut ctx = PkeyCtx :: new_id ( id) ?;
976
+ ctx. fromdata_init ( ) ?;
977
+ ctx. fromdata ( params)
978
+ }
979
+
941
980
#[ cfg( test) ]
942
981
mod test {
943
982
use super :: * ;
@@ -948,11 +987,17 @@ mod test {
948
987
use crate :: hash:: { hash, MessageDigest } ;
949
988
use crate :: md:: Md ;
950
989
use crate :: nid:: Nid ;
990
+ #[ cfg( ossl300) ]
991
+ use crate :: params:: ParamBuilder ;
951
992
use crate :: pkey:: PKey ;
952
993
use crate :: rsa:: Rsa ;
953
994
use crate :: sign:: Verifier ;
995
+ #[ cfg( ossl300) ]
996
+ use crate :: util:: c_str;
954
997
#[ cfg( not( boringssl) ) ]
955
998
use cfg_if:: cfg_if;
999
+ #[ cfg( ossl300) ]
1000
+ use std:: cmp:: Ordering ;
956
1001
957
1002
#[ test]
958
1003
fn rsa ( ) {
@@ -1324,4 +1369,30 @@ mxJ7imIrEg9nIQ==
1324
1369
assert_eq ! ( output, expected_output) ;
1325
1370
assert ! ( ErrorStack :: get( ) . errors( ) . is_empty( ) ) ;
1326
1371
}
1372
+
1373
+ #[ test]
1374
+ #[ cfg( ossl300) ]
1375
+ fn test_fromdata ( ) {
1376
+ let n = BigNum :: from_u32 ( 0xbc747fc5 ) . unwrap ( ) ;
1377
+ let e = BigNum :: from_u32 ( 0x10001 ) . unwrap ( ) ;
1378
+ let d = BigNum :: from_u32 ( 0x7b133399 ) . unwrap ( ) ;
1379
+
1380
+ let params = ParamBuilder :: new ( )
1381
+ . push_bignum ( c_str ( b"n\0 " ) , & n)
1382
+ . unwrap ( )
1383
+ . push_bignum ( c_str ( b"e\0 " ) , & e)
1384
+ . unwrap ( )
1385
+ . push_bignum ( c_str ( b"d\0 " ) , & d)
1386
+ . unwrap ( )
1387
+ . build ( )
1388
+ . unwrap ( ) ;
1389
+
1390
+ let pkey: PKey < Private > = pkey_from_params ( Id :: RSA , & params) . unwrap ( ) ;
1391
+
1392
+ let rsa = pkey. rsa ( ) . unwrap ( ) ;
1393
+
1394
+ assert_eq ! ( rsa. n( ) . ucmp( & n) , Ordering :: Equal ) ;
1395
+ assert_eq ! ( rsa. e( ) . ucmp( & e) , Ordering :: Equal ) ;
1396
+ assert_eq ! ( rsa. d( ) . ucmp( & d) , Ordering :: Equal ) ;
1397
+ }
1327
1398
}
0 commit comments