Skip to content

Add more robust key processing: DSA#14992

Open
sjudson wants to merge 2 commits into
pyca:mainfrom
trail-of-forks:sj/robust-processing
Open

Add more robust key processing: DSA#14992
sjudson wants to merge 2 commits into
pyca:mainfrom
trail-of-forks:sj/robust-processing

Conversation

@sjudson

@sjudson sjudson commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

This PR adds more robust key processing for DSA. In particular:

  • a new check, check_dsa_public_numbers, is added to verify that for DSA the public y value both 1 < y < p and y ** q mod p = 1, as keys failing validation may be weak to forgery; and
  • both that new and existing checks on key structure are added to the PEM and DER load paths, alongside where they were already used for direct constructions.

@alex alex left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All the new vectors need to be documented in test-vectors.rst -- please split those out into their own PR.

For ease of review, I think it'd be best to split the actual changes into one PR per algorithm.

Comment thread src/rust/src/backend/dsa.rs Outdated
}

pub(crate) fn private_key_from_pkey(
_py: pyo3::Python<'_>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we don't need this arg, we can just drop it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Comment thread src/rust/src/backend/rsa.rs Outdated
Comment on lines +64 to +65
let numbers = key.public_numbers(py)?;
check_public_key_components(numbers.e.bind(py), numbers.n.bind(py))?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, ideally we wouldn't have to round trip via the public numbers to create a public key... is there some way to structure this to avoid that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@alex thoughts on this alternative? Modifies the existing check to work on bignums as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll leave this as the RSA PR btw, and split out the DH and DSA and vectors as requested

@sjudson sjudson force-pushed the sj/robust-processing branch from 85717cf to 2c0c828 Compare June 9, 2026 18:02
@sjudson sjudson force-pushed the sj/robust-processing branch from 2c0c828 to f231f16 Compare June 12, 2026 00:46
@sjudson sjudson changed the title Add more robust parameter and key processing for DH, DSA, and RSA Add more robust key processing: DSA Jun 12, 2026
@reaperhulk

Copy link
Copy Markdown
Member

If you load a private key (via DER/PEM) with bad public key values this will raise a ValueError when calling key.public_key(), which is not desirable. We should run checks for all the values on private loading.

@sjudson

sjudson commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

@reaperhulk updated to resolve this, and in a way consistent with your comment on #15015 as well: the validation has been moved down to the binding layer, where it is then applied across the various code paths so that there is a single consistent implementation.

However, this has broken one of the certbot-josepy downstream tests, which loads a 512-bit private key (expecting no error at the cryptography layer) and then rejects it. With the stricter validation, that key is now rejected on load.

Do you have a sense of how you'd prefer to proceed? Obviously one approach would be to accept being breaking here. I could also modify the validation to accept 512-bit key lengths, despite their insecure/legacy nature. Or even stronger I could drop the bitlength checks from the PEM/DER load paths (but leave them where they already exist) for maximal compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants