@@ -138,6 +138,34 @@ const CUSTOM_PK_INFO: pk_info_t = {
138138 }
139139} ;
140140
141+ /// RSA components for constructing a private key.
142+ pub enum RsaPrivateComponents < ' a > {
143+ WithPrimes {
144+ /// Private 1st prime
145+ p : & ' a Mpi ,
146+ /// Private 2nd prime
147+ q : & ' a Mpi ,
148+ /// Public exponent
149+ e : & ' a Mpi ,
150+ } ,
151+ WithPrivateExponent {
152+ /// Public modulus
153+ n : & ' a Mpi ,
154+ /// Private exponent
155+ d : & ' a Mpi ,
156+ /// Public exponent
157+ e : & ' a Mpi ,
158+ } ,
159+ }
160+
161+ /// RSA components for constructing a public key.
162+ pub struct RsaPublicComponents < ' a > {
163+ /// Public modulus
164+ pub n : & ' a Mpi ,
165+ /// Public exponent
166+ pub e : & ' a Mpi ,
167+ }
168+
141169// If this changes then certificate.rs unsafe code in public_key needs to also
142170// change.
143171define ! (
@@ -200,7 +228,7 @@ define!(
200228// - Only const access to context: eckey_check_pair, eckey_get_bitlen,
201229// eckey_can_do, eckey_check_pair
202230//
203- // - Const acccess / copies context to a stack based variable eckey_verify_wrap,
231+ // - Const access / copies context to a stack based variable eckey_verify_wrap,
204232// eckey_sign_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:251
205233// creates a stack ecdsa variable and uses ctx to initialize it. ctx is passed
206234// as 'key', a const pointer to mbedtls_ecdsa_from_keypair( &ecdsa, ctx )
@@ -348,7 +376,7 @@ Please use `private_from_ec_components_with_rng` instead."
348376 ///
349377 /// This function will return an error if:
350378 ///
351- /// * Fails to genearte `EcPoint` from given EcGroup in `curve`.
379+ /// * Fails to generate `EcPoint` from given EcGroup in `curve`.
352380 /// * The underlying C `mbedtls_pk_setup` function fails to set up the `Pk` context.
353381 /// * The `EcPoint::mul` function fails to generate the public key point.
354382 pub fn private_from_ec_components_with_rng < F : Random > ( mut curve : EcGroup , private_key : Mpi , rng : & mut F ) -> Result < Pk > {
@@ -376,6 +404,39 @@ Please use `private_from_ec_components_with_rng` instead."
376404 Ok ( ret)
377405 }
378406
407+ /// Construct a private key from RSA components.
408+ pub fn private_from_rsa_components ( components : RsaPrivateComponents < ' _ > ) -> Result < Pk > {
409+ let mut ret = Self :: init ( ) ;
410+ let ( n, p, q, d, e) = match components {
411+ RsaPrivateComponents :: WithPrimes { p, q, e } => ( None , Some ( p) , Some ( q) , None , Some ( e) ) ,
412+ RsaPrivateComponents :: WithPrivateExponent { n, d, e } => ( Some ( n) , None , None , Some ( d) , Some ( e) ) ,
413+ } ;
414+ let to_ptr = |mpi : Option < & Mpi > | match mpi {
415+ None => ptr:: null ( ) ,
416+ Some ( mpi) => mpi. handle ( ) ,
417+ } ;
418+ unsafe {
419+ pk_setup ( & mut ret. inner , pk_info_from_type ( Type :: Rsa . into ( ) ) ) . into_result ( ) ?;
420+ let ctx = ret. inner . pk_ctx as * mut rsa_context ;
421+ rsa_import ( ctx, to_ptr ( n) , to_ptr ( p) , to_ptr ( q) , to_ptr ( d) , to_ptr ( e) ) . into_result ( ) ?;
422+ rsa_complete ( ctx) . into_result ( ) ?;
423+ }
424+ Ok ( ret)
425+ }
426+
427+ /// Construct a public key from RSA components.
428+ pub fn public_from_rsa_components ( components : RsaPublicComponents < ' _ > ) -> Result < Pk > {
429+ let mut ret = Self :: init ( ) ;
430+ let RsaPublicComponents { n, e } = components;
431+ unsafe {
432+ pk_setup ( & mut ret. inner , pk_info_from_type ( Type :: Rsa . into ( ) ) ) . into_result ( ) ?;
433+ let ctx = ret. inner . pk_ctx as * mut rsa_context ;
434+ rsa_import ( ctx, n. handle ( ) , ptr:: null ( ) , ptr:: null ( ) , ptr:: null ( ) , e. handle ( ) ) . into_result ( ) ?;
435+ rsa_complete ( ctx) . into_result ( ) ?;
436+ }
437+ Ok ( ret)
438+ }
439+
379440 pub fn public_custom_algo ( algo_id : & [ u64 ] , pk : & [ u8 ] ) -> Result < Pk > {
380441 let mut ret = Self :: init ( ) ;
381442 unsafe {
@@ -1564,4 +1625,37 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi
15641625 assert_eq ! ( l. unwrap( ) , LEN ) ;
15651626 }
15661627 }
1628+
1629+ #[ test]
1630+ fn private_from_rsa_components_sanity ( ) {
1631+ let mut pk = Pk :: generate_rsa ( & mut crate :: test_support:: rand:: test_rng ( ) , 2048 , 0x10001 ) . unwrap ( ) ;
1632+ let components = RsaPrivateComponents :: WithPrimes {
1633+ p : & pk. rsa_private_prime1 ( ) . unwrap ( ) ,
1634+ q : & pk. rsa_private_prime2 ( ) . unwrap ( ) ,
1635+ e : & Mpi :: new ( pk. rsa_public_exponent ( ) . unwrap ( ) as _ ) . unwrap ( ) ,
1636+ } ;
1637+ let mut pk2 = Pk :: private_from_rsa_components ( components) . unwrap ( ) ;
1638+ assert_eq ! ( pk. write_private_der_vec( ) . unwrap( ) , pk2. write_private_der_vec( ) . unwrap( ) ) ;
1639+
1640+ let components = RsaPrivateComponents :: WithPrivateExponent {
1641+ n : & pk. rsa_public_modulus ( ) . unwrap ( ) ,
1642+ d : & pk. rsa_private_exponent ( ) . unwrap ( ) ,
1643+ e : & Mpi :: new ( pk. rsa_public_exponent ( ) . unwrap ( ) as _ ) . unwrap ( ) ,
1644+ } ;
1645+ let mut pk3 = Pk :: private_from_rsa_components ( components) . unwrap ( ) ;
1646+ assert_eq ! ( pk. write_private_der_vec( ) . unwrap( ) , pk3. write_private_der_vec( ) . unwrap( ) ) ;
1647+ }
1648+
1649+ #[ test]
1650+ fn public_from_rsa_components_sanity ( ) {
1651+ let mut pk = Pk :: generate_rsa ( & mut crate :: test_support:: rand:: test_rng ( ) , 2048 , 0x10001 ) . unwrap ( ) ;
1652+ let mut pk = Pk :: from_public_key ( & pk. write_public_der_vec ( ) . unwrap ( ) ) . unwrap ( ) ;
1653+
1654+ let components = RsaPublicComponents {
1655+ n : & pk. rsa_public_modulus ( ) . unwrap ( ) ,
1656+ e : & Mpi :: new ( pk. rsa_public_exponent ( ) . unwrap ( ) as _ ) . unwrap ( ) ,
1657+ } ;
1658+ let mut pk2 = Pk :: public_from_rsa_components ( components) . unwrap ( ) ;
1659+ assert_eq ! ( pk. write_public_der_vec( ) . unwrap( ) , pk2. write_public_der_vec( ) . unwrap( ) ) ;
1660+ }
15671661}
0 commit comments