@@ -16,10 +16,6 @@ use crate::padding::PaddingScheme;
1616use crate :: raw:: { DecryptionPrimitive , EncryptionPrimitive } ;
1717use crate :: { oaep, pkcs1v15, pss} ;
1818
19- const MIN_PUB_EXPONENT : u64 = 2 ;
20- const MAX_PUB_EXPONENT : u64 = ( 1 << 33 ) - 1 ;
21- const MAX_MODULUS_BITS : usize = 16384 ;
22-
2319pub trait PublicKeyParts {
2420 /// Returns the modulus of the key.
2521 fn n ( & self ) -> & BigUint ;
@@ -229,11 +225,27 @@ impl PublicKey for RsaPublicKey {
229225}
230226
231227impl RsaPublicKey {
232- /// Create a new key from its components.
228+ /// Minimum value of the public exponent `e`.
229+ pub const MIN_PUB_EXPONENT : u64 = 2 ;
230+
231+ /// Maximum value of the public exponent `e`.
232+ pub const MAX_PUB_EXPONENT : u64 = ( 1 << 33 ) - 1 ;
233+
234+ /// Maximum size of the modulus `n` in bits.
235+ pub const MAX_SIZE : usize = 4096 ;
236+
237+ /// Create a new public key from its components.
238+ ///
239+ /// This function accepts public keys with a modulus size up to 4096-bits,
240+ /// i.e. [`RsaPublicKey::MAX_SIZE`].
233241 pub fn new ( n : BigUint , e : BigUint ) -> Result < Self > {
234- let k = RsaPublicKey { n, e } ;
235- check_public ( & k ) ? ;
242+ Self :: new_with_max_size ( n, e, Self :: MAX_SIZE )
243+ }
236244
245+ /// Create a new public key from its components.
246+ pub fn new_with_max_size ( n : BigUint , e : BigUint , max_size : usize ) -> Result < Self > {
247+ let k = RsaPublicKey { n, e } ;
248+ check_public_with_max_size ( & k, max_size) ?;
237249 Ok ( k)
238250 }
239251}
@@ -336,10 +348,9 @@ impl RsaPrivateKey {
336348 /// Get the public key from the private key, cloning `n` and `e`.
337349 ///
338350 /// Generally this is not needed since `RsaPrivateKey` implements the `PublicKey` trait,
339- /// but it can occationally be useful to discard the private information entirely.
351+ /// but it can occasionally be useful to discard the private information entirely.
340352 pub fn to_public_key ( & self ) -> RsaPublicKey {
341- // Safe to unwrap since n and e are already verified.
342- RsaPublicKey :: new ( self . n ( ) . clone ( ) , self . e ( ) . clone ( ) ) . unwrap ( )
353+ self . pubkey_components . clone ( )
343354 }
344355
345356 /// Performs some calculations to speed up private key operations.
@@ -409,7 +420,7 @@ impl RsaPrivateKey {
409420 }
410421
411422 /// Performs basic sanity checks on the key.
412- /// Returns `Ok(())` if everything is good, otherwise an approriate error.
423+ /// Returns `Ok(())` if everything is good, otherwise an appropriate error.
413424 pub fn validate ( & self ) -> Result < ( ) > {
414425 check_public ( self ) ?;
415426
@@ -549,7 +560,13 @@ impl RsaPrivateKey {
549560/// Check that the public key is well formed and has an exponent within acceptable bounds.
550561#[ inline]
551562pub fn check_public ( public_key : & impl PublicKeyParts ) -> Result < ( ) > {
552- if public_key. n ( ) . bits ( ) > MAX_MODULUS_BITS {
563+ check_public_with_max_size ( public_key, RsaPublicKey :: MAX_SIZE )
564+ }
565+
566+ /// Check that the public key is well formed and has an exponent within acceptable bounds.
567+ #[ inline]
568+ fn check_public_with_max_size ( public_key : & impl PublicKeyParts , max_size : usize ) -> Result < ( ) > {
569+ if public_key. n ( ) . bits ( ) > max_size {
553570 return Err ( Error :: ModulusTooLarge ) ;
554571 }
555572
@@ -558,11 +575,11 @@ pub fn check_public(public_key: &impl PublicKeyParts) -> Result<()> {
558575 . to_u64 ( )
559576 . ok_or ( Error :: PublicExponentTooLarge ) ?;
560577
561- if e < MIN_PUB_EXPONENT {
578+ if e < RsaPublicKey :: MIN_PUB_EXPONENT {
562579 return Err ( Error :: PublicExponentTooSmall ) ;
563580 }
564581
565- if e > MAX_PUB_EXPONENT {
582+ if e > RsaPublicKey :: MAX_PUB_EXPONENT {
566583 return Err ( Error :: PublicExponentTooLarge ) ;
567584 }
568585
@@ -601,6 +618,7 @@ mod tests {
601618
602619 use alloc:: string:: String ;
603620 use digest:: { Digest , DynDigest } ;
621+ use hex_literal:: hex;
604622 use num_traits:: { FromPrimitive , ToPrimitive } ;
605623 use rand_chacha:: {
606624 rand_core:: { RngCore , SeedableRng } ,
@@ -801,6 +819,78 @@ mod tests {
801819 . unwrap ( ) ;
802820 }
803821
822+ #[ test]
823+ fn reject_oversized_private_key ( ) {
824+ // -----BEGIN PUBLIC KEY-----
825+ // MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAkMBiB8qsNVXAsJR6Xoto
826+ // H1r2rtZl/xzUK2tIfy99aPE489u+5tLxCQhQf+a89158vSDpr2/xwgK8w9u0Xpu2
827+ // m7XRKjVMS0Y6UIINFoeTc87rVXT92Scr47kNVcGmSFXez4BSDpS+LKpWwXN+0AQu
828+ // +cmcfdtsx2862iEbqQvq4PwKGQJOdOR0yldH8O4yeJK/buvIOXRHjb++vtQND/xi
829+ // bFGAcd9WJqvaOG7tclhbZ277mbO6ER+y9Lj7AyO8ywybWqNeHaVPHMysPhT7HUWI
830+ // 17m59i1OpuVwwEnvzDQQEUf9d5hUmkLYb5qQzuf6Ddnx/04QJCKAgkhyr9CXgnV6
831+ // vEZ3PKtpicCHRxk7eqTEmgBlgwqH5vflRFV1iywQMXJnuRhzWOQaXl/vb8v4HIvF
832+ // 4TatEZKqfzpbyScLIiYbPEAhHXKdZMd2zY8hkSbicifePApAZmuNpAxxJDZzphh7
833+ // r4lD6t8MPT/RUAdtrZfihqaBhduFI6YeVIy6emg05M6YWvlUyer7nYGaPRS1JqD4
834+ // 0v7xOtme5I8Qw6APiFPXhTqBK3occr7TgGb3V3lpC8Eq+esNHrji98R1fITkFXJW
835+ // KdFcTWjBghPxiobUzMCFUrPIDJcWXeBzrARAryU+hXjEiFfzluXrps0B7RJQ/rLD
836+ // LXeTn4vovUeHQVHa7YfoyWMy9pfqeVC+56LBK7SEIAvL0I3lrq5vIv+ZIuOAdbVg
837+ // JiRy8DneCOk2LP3RnA8M0HSevYW93DiC+4h/l4ntjjiOfi6yRVOZ8WbVyXZ/83j4
838+ // 6+pGWgvi0uMyb+btgOXjBQv7bGqdyHMc5Lqk5bF7ExETx51vKQMYCV4351caS6aX
839+ // q16lYZATHgbTADEAZHdroDMJB+HMQaze9O6qU5ZO8wxxAjw89xry0dnoOQD/yA4H
840+ // 7CRCo9vVDpV2hqIvHY9RI2T7cek28kmQpKvNvvK+ovmM138dHKViWULHk0fBRt7m
841+ // 4wQ+tiL2PmJ/Tr8g1gVhM6S9D1XdE9z0KeDnODCWn1Q8sx2G2ah4ynnYQURDWcwO
842+ // McAoP6bdJ7cCt+4F2tEsMPf4S/EwlnjvuNoQjvztxCPahYe9EnyggtQXyHJveIn7
843+ // gDJsP6b93VB6x4QbLy5ch4DUhqDWginuKVeo7CTgDkq03j/IEaS1BHwreSDQceny
844+ // +bYWONwV+4TMpGytKOHvU5288kmHbyZHdXuaXk8LLqbnqr30fa6Cbp4llCi9sH5a
845+ // Kmi5jxQfVTe+elkMs7oVsLsVgkZS6NqPcOuEckAFijNqG223+IJoqvifCzO5Bdcs
846+ // JTOLE+YaUYc8LUJwIaPykgcXmtMvQjeT8MCQ3aAlzkHfDpSvvICrXtqbGiaKolU6
847+ // mQIDAQAB
848+ // -----END PUBLIC KEY-----
849+
850+ let n = BigUint :: from_bytes_be ( & hex ! (
851+ "
852+ 90c06207caac3555c0b0947a5e8b681f5af6aed665ff1cd42b6b487f2f7d68f1
853+ 38f3dbbee6d2f10908507fe6bcf75e7cbd20e9af6ff1c202bcc3dbb45e9bb69b
854+ b5d12a354c4b463a50820d16879373ceeb5574fdd9272be3b90d55c1a64855de
855+ cf80520e94be2caa56c1737ed0042ef9c99c7ddb6cc76f3ada211ba90beae0fc
856+ 0a19024e74e474ca5747f0ee327892bf6eebc83974478dbfbebed40d0ffc626c
857+ 518071df5626abda386eed72585b676efb99b3ba111fb2f4b8fb0323bccb0c9b
858+ 5aa35e1da54f1cccac3e14fb1d4588d7b9b9f62d4ea6e570c049efcc34101147
859+ fd7798549a42d86f9a90cee7fa0dd9f1ff4e10242280824872afd09782757abc
860+ 46773cab6989c08747193b7aa4c49a0065830a87e6f7e54455758b2c10317267
861+ b9187358e41a5e5fef6fcbf81c8bc5e136ad1192aa7f3a5bc9270b22261b3c40
862+ 211d729d64c776cd8f219126e27227de3c0a40666b8da40c71243673a6187baf
863+ 8943eadf0c3d3fd150076dad97e286a68185db8523a61e548cba7a6834e4ce98
864+ 5af954c9eafb9d819a3d14b526a0f8d2fef13ad99ee48f10c3a00f8853d7853a
865+ 812b7a1c72bed38066f75779690bc12af9eb0d1eb8e2f7c4757c84e415725629
866+ d15c4d68c18213f18a86d4ccc08552b3c80c97165de073ac0440af253e8578c4
867+ 8857f396e5eba6cd01ed1250feb2c32d77939f8be8bd47874151daed87e8c963
868+ 32f697ea7950bee7a2c12bb484200bcbd08de5aeae6f22ff9922e38075b56026
869+ 2472f039de08e9362cfdd19c0f0cd0749ebd85bddc3882fb887f9789ed8e388e
870+ 7e2eb2455399f166d5c9767ff378f8ebea465a0be2d2e3326fe6ed80e5e3050b
871+ fb6c6a9dc8731ce4baa4e5b17b131113c79d6f290318095e37e7571a4ba697ab
872+ 5ea56190131e06d300310064776ba0330907e1cc41acdef4eeaa53964ef30c71
873+ 023c3cf71af2d1d9e83900ffc80e07ec2442a3dbd50e957686a22f1d8f512364
874+ fb71e936f24990a4abcdbef2bea2f98cd77f1d1ca5625942c79347c146dee6e3
875+ 043eb622f63e627f4ebf20d6056133a4bd0f55dd13dcf429e0e73830969f543c
876+ b31d86d9a878ca79d841444359cc0e31c0283fa6dd27b702b7ee05dad12c30f7
877+ f84bf1309678efb8da108efcedc423da8587bd127ca082d417c8726f7889fb80
878+ 326c3fa6fddd507ac7841b2f2e5c8780d486a0d68229ee2957a8ec24e00e4ab4
879+ de3fc811a4b5047c2b7920d071e9f2f9b61638dc15fb84cca46cad28e1ef539d
880+ bcf249876f2647757b9a5e4f0b2ea6e7aabdf47dae826e9e259428bdb07e5a2a
881+ 68b98f141f5537be7a590cb3ba15b0bb15824652e8da8f70eb847240058a336a
882+ 1b6db7f88268aaf89f0b33b905d72c25338b13e61a51873c2d427021a3f29207
883+ 179ad32f423793f0c090dda025ce41df0e94afbc80ab5eda9b1a268aa2553a99"
884+ ) ) ;
885+
886+ let e = BigUint :: from_u64 ( 65537 ) . unwrap ( ) ;
887+
888+ assert_eq ! (
889+ RsaPublicKey :: new( n, e) . err( ) . unwrap( ) ,
890+ Error :: ModulusTooLarge
891+ ) ;
892+ }
893+
804894 fn get_private_key ( ) -> RsaPrivateKey {
805895 // -----BEGIN RSA PRIVATE KEY-----
806896 // MIIEpAIBAAKCAQEA05e4TZikwmE47RtpWoEG6tkdVTvwYEG2LT/cUKBB4iK49FKW
0 commit comments