Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Bound RsaPublicKey::new on 4096-bits; add ::new_large #171

Closed
wants to merge 2 commits into from

Conversation

tarcieri
Copy link
Member

NOTE: depends on #170

This commit fixes #166 by enforcing a 4096-bit upper limit by default, which prevents potential DoS by using maliciously large RSA keys.

The PKCS#1/PKCS#8 parsers use this API, limiting the size of keys parsed from these formats to 4096-bits.

An RsaPrivateKey::new_large constructor has been added which enforces the 16384-bit limit added in #170. This can be used for unusual applications that need to support larger keys.

RsaPrivateKey::from_components uses the ::new_large constructor, so private keys follow the 16384-bit limit only.

The RsaPrivateKey::MAX_SIZE and RsaPrivateKey::MAX_SIZE_LARGE inherent constants specify the maximum allowed sizes.

- Ensure modulus is 16384-bits or fewer. See #166
- Increase maximum public exponent. Closes #155
This commit fixes #166 by enforcing a 4096-bit upper limit by default,
which prevents potential DoS by using maliciously large RSA keys.

The PKCS#1/PKCS#8 parsers use this API, limiting the size of keys parsed
from these formats to 4096-bits.

An `RsaPrivateKey::new_large` constructor has been added which enforces
the 16384-bit limit added in #170. This can be used for unusual
applications that need to support larger keys.

`RsaPrivateKey::from_components` uses the `::new_large` constructor, so
private keys follow the 16384-bit limit only.

The `RsaPrivateKey::MAX_SIZE` and `RsaPrivateKey::MAX_SIZE_LARGE`
inherent constants specify the maximum allowed sizes.
@tarcieri tarcieri marked this pull request as draft July 30, 2022 23:33
Comment on lines +229 to +232
pub const MIN_PUB_EXPONENT: u64 = 2;

/// Maximum value of the public exponent `e`.
pub const MAX_PUB_EXPONENT: u64 = (1 << 33) - 1;
Copy link
Member Author

@tarcieri tarcieri Jul 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels a bit weird to make these pub as u64. I think it'd be nice to have access to them, but there is a mismatch between u64 here and BigUint when passed as a parameter.

Perhaps we should make e: u64 as well? (that can be done in a separate PR)

@aloucks
Copy link
Contributor

aloucks commented Aug 1, 2022

Having two APIs that are essentially the same thing feels a little clunky. Why not add a Limits struct and a Default as 4096?

Something like:

pub struct Limits {
  /// The maximum key size in bytes
  pub max_key_size: usize,
}

impl Default for Limits {
  fn default() -> Self {
    Limits { max_key_size: 4096 }
  }
}

pub fn new(n: BigUint, e: BigUint, limits: Limits) -> Result<Self> {
  // ...
}

@tarcieri
Copy link
Member Author

tarcieri commented Aug 1, 2022

That needlessly complicates the common-case API.

However, we could have two methods, where one is composed in terms of the other, e.g. new vs new_with_max_key_size

@tarcieri
Copy link
Member Author

tarcieri commented Aug 8, 2022

Closing in favor of #176

@tarcieri tarcieri closed this Aug 8, 2022
@tarcieri tarcieri deleted the large-public-key branch August 8, 2022 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Denial of Service (DoS) via Large Public Key
2 participants