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

Improve SignatureException handling #320

Merged
merged 4 commits into from
Aug 15, 2023
Merged

Conversation

SalusaSecondus
Copy link
Contributor

Description of changes:

The JCA does not fully specify when SignatureException should be thrown but the ResetAfterException test from OpenJDK indicates that SignatureException should be thrown when validating a too-short signature. This PR modifies ACCP to throw an exception in this case and to always properly reset when exceptions are thrown.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@SalusaSecondus SalusaSecondus requested a review from a team as a code owner August 4, 2023 16:14
*/
@Test
public void rsaSignatureWrongLength() throws Exception {
final Signature signer = Signature.getInstance("SHA256withRSA", NATIVE_PROVIDER);
Copy link
Contributor

Choose a reason for hiding this comment

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

should we test this over ECDSA as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Somewhat covered by this, however I think that the new state probably always throws an exception for truncated signatures, so perhaps we should update it.

Comment on lines 642 to 643
* For better compatibility with the JDK, we want to throw SignatureException if the length of the
* signature is wrong.
Copy link
Contributor

@WillChilds-Klein WillChilds-Klein Aug 8, 2023

Choose a reason for hiding this comment

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

this may help with JDK compatibility, but it diverges from BC's behavior of returning false rather than throwing.

on one hand, BC's decision to simply return an opaque false leaks less information about the signature and is (IMO) more likely to be more compatible with a given application (presumably, all callers will handle false verify case correctly). on the other hand, SignatureException is a checked exception, so the compiler will force callers to handle it in some way (even if that is a generic catch (Exception e) { ... } with potentially incorrect handling logic).

hoping to have further discussion here with greg and the ACCP team on tradeoffs of favoring JDK compatibility vs. BC compatibility.

Copy link
Contributor Author

@SalusaSecondus SalusaSecondus Aug 9, 2023

Choose a reason for hiding this comment

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

In an ideal world, it would only be false or true, but unfortunately that isn't the world we're in.

We don't need to worry about "leaking information" because every piece of data handled here is public. (Signatures are considered public and public keys are used to validate them.) The concerns are complexity and compatibility.

Complexity: Developers already (unfortunately) need to handle SignatureException and this doesn't make things any worse for them.

Compatibility: The JDK's providers (and tests) define the standard through their behaviors. ACCP cannot match it perfectly, but it can try to minimize the differences. Given a choice between mutually exclusive options of "compatible with JDK providers" and "compatible with BC," I believe that ACCP should usually choose to be compatible with the JDK providers. (Obviously, there may be questions of security and correctness, but neither apply here.)

Finally, I believe it is a reasonably generalization to say "Teams use the JDK providers by default and might choose to use BC." This means that use of BC is more likely to be an intentional decision rather than using the JDK providers. So, if ACCP is being added, we shouldn't change how things work for teams which are just grabbing the default and not paying attention to the details. If a team has chosen to use BC then:

  • They are overriding ACCP (so these changes don't matter anyway), OR
  • They are making intentional decisions around their cryptography and so can be expected to make adjustments to their code if needed.

Truthfully, many teams use BC without thinking about it (either because of a dependency or just not understanding cryptographic code). But it remains true that using BC is more of a conscious choice than just sticking with the default.

Copy link
Contributor

Choose a reason for hiding this comment

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

ACCP-FIPS compatibility with BCFIPS is highly desirable. Customers that have FIPS requirements and want to switch to ACCP-FIPS for performance and still satisfy the FIPS requirements would have simpler transition.
P.S. we have just released ACCP-FIPS for experimental purposes. AWS-LC-FIPS is still waiting for it certificate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I still believe that my above positions hold the vast majority of the time.

Careful code needs to handle SignatureException (partially because it is a checked exception).

There is an interesting question as to whether there should be some way to tune ACCP's compatibility towards JDK or BC, but I think the answer there should remain "no."

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with @SalusaSecondus's points. The incompatibility introduced here is trivially resolved by the customers and returning more contextual information in our SignatureExceptions is more helpful than a boolean failure.

Copy link
Contributor

@amirhosv amirhosv Aug 10, 2023

Choose a reason for hiding this comment

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

@SalusaSecondus @geedo0 Sounds good to me.

Copy link
Contributor

@WillChilds-Klein WillChilds-Klein Aug 11, 2023

Choose a reason for hiding this comment

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

Regarding the tension between prioritizing JDK vs. BC compatibility, in my view it depends on:

  1. FIPS mode
  1. the nature/severity of the incompatibility

I agree that in non-FIPS mode, ACCP is more likely to replace default JDK providers. However, since BCFIPS is the only FIPS-approved JCA provider (as far as I know), I believe ACCP-FIPS is more likely to replace BCFIPS in migration use-cases. In other instances of incompatibility (not this PR, see below), this may warrant differentiating runtime behavior based on FIPS mode to honor the respective compatibility priorities.

For this case specifically, i think SignatureException being a checked exception should give us reasonable confidence that callers already handle it, and is thus unlikely to cause compatibility issues. If this were an unchecked exception, I don't think we could hold the same degree of confidence.

All this is to say, I'm also good with the new behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

Will's guideline is a great mechanism for deciding how incompatibilities should be handled.

geedo0
geedo0 previously approved these changes Aug 10, 2023
if (key_ instanceof RSAKey) {
final RSAKey rsaKey = (RSAKey) key_;
if (length != (rsaKey.getModulus().bitLength() + 7) / 8) {
throw new SignatureException("RSA Signature of invalid length.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be helpful to report the expected and received lengths?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whatever you prefer. I'm happy either way.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't block the merge over it, I'd only encourage it if you're pushing another rev anyway.

@amirhosv amirhosv merged commit 44a7892 into corretto:main Aug 15, 2023
6 checks passed
@SalusaSecondus SalusaSecondus deleted the sig_ex branch August 15, 2023 18:27
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.

4 participants