@@ -16,10 +16,6 @@ use crate::padding::PaddingScheme;
16
16
use crate :: raw:: { DecryptionPrimitive , EncryptionPrimitive } ;
17
17
use crate :: { oaep, pkcs1v15, pss} ;
18
18
19
- const MIN_PUB_EXPONENT : u64 = 2 ;
20
- const MAX_PUB_EXPONENT : u64 = ( 1 << 33 ) - 1 ;
21
- const MAX_MODULUS_BITS : usize = 16384 ;
22
-
23
19
pub trait PublicKeyParts {
24
20
/// Returns the modulus of the key.
25
21
fn n ( & self ) -> & BigUint ;
@@ -229,11 +225,27 @@ impl PublicKey for RsaPublicKey {
229
225
}
230
226
231
227
impl 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`].
233
241
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
+ }
236
244
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) ?;
237
249
Ok ( k)
238
250
}
239
251
}
@@ -336,10 +348,9 @@ impl RsaPrivateKey {
336
348
/// Get the public key from the private key, cloning `n` and `e`.
337
349
///
338
350
/// 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.
340
352
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 ( )
343
354
}
344
355
345
356
/// Performs some calculations to speed up private key operations.
@@ -409,7 +420,7 @@ impl RsaPrivateKey {
409
420
}
410
421
411
422
/// 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.
413
424
pub fn validate ( & self ) -> Result < ( ) > {
414
425
check_public ( self ) ?;
415
426
@@ -549,7 +560,13 @@ impl RsaPrivateKey {
549
560
/// Check that the public key is well formed and has an exponent within acceptable bounds.
550
561
#[ inline]
551
562
pub 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 {
553
570
return Err ( Error :: ModulusTooLarge ) ;
554
571
}
555
572
@@ -558,11 +575,11 @@ pub fn check_public(public_key: &impl PublicKeyParts) -> Result<()> {
558
575
. to_u64 ( )
559
576
. ok_or ( Error :: PublicExponentTooLarge ) ?;
560
577
561
- if e < MIN_PUB_EXPONENT {
578
+ if e < RsaPublicKey :: MIN_PUB_EXPONENT {
562
579
return Err ( Error :: PublicExponentTooSmall ) ;
563
580
}
564
581
565
- if e > MAX_PUB_EXPONENT {
582
+ if e > RsaPublicKey :: MAX_PUB_EXPONENT {
566
583
return Err ( Error :: PublicExponentTooLarge ) ;
567
584
}
568
585
@@ -601,6 +618,7 @@ mod tests {
601
618
602
619
use alloc:: string:: String ;
603
620
use digest:: { Digest , DynDigest } ;
621
+ use hex_literal:: hex;
604
622
use num_traits:: { FromPrimitive , ToPrimitive } ;
605
623
use rand_chacha:: {
606
624
rand_core:: { RngCore , SeedableRng } ,
@@ -801,6 +819,78 @@ mod tests {
801
819
. unwrap ( ) ;
802
820
}
803
821
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
+
804
894
fn get_private_key ( ) -> RsaPrivateKey {
805
895
// -----BEGIN RSA PRIVATE KEY-----
806
896
// MIIEpAIBAAKCAQEA05e4TZikwmE47RtpWoEG6tkdVTvwYEG2LT/cUKBB4iK49FKW
0 commit comments