10000 ENT-11101: Fix all crypto issues introduced by Java 17 upgrade by shamsasari · Pull Request #7675 · corda/corda · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

ENT-11101: Fix all crypto issues introduced by Java 17 upgrade #7675

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

Merged
merged 1 commit into from
Mar 5, 2024

Conversation

shamsasari
Copy link
Contributor
@shamsasari shamsasari commented Feb 21, 2024

The various crypto tests that were previously ignored have been re-enabled.

The abandoned i2p EdDSA library has been replaced with native support that was added in Java 15.

Java 17 (via the SunEC provider) does not support the secp256k1 curve (one of the two ECDSA curves supported in Corda). This would not normally have been an issue as secp256k1 is already taken care of by Bouncy Castle. However, this only works if the Crypto API is used or if ”BC” is explicitly specified as the provider (e.g. Signature.getInstance(“SHA256withECDSA”, “BC”)). If no provider is specified, which is what is more common, and actually what the Java docs recommend, then this doesn’t work as the SunEC provider is selected. To resolve this, a custom provider was created, installed just in front of SunEC, which “augments” SunEC by delegating to Bouncy Castle if keys or parameters for secp256k1 are encountered.

X509Utilities.createCertificate now calls X509Certificate.verify() to verify the created certificate, rather than using the Bouncy Castle API. This is more representative of how certificates will be verified (e.g. during SSL handshake) and weeds out other issues (such as unsupported curve error for secp256k1).

BCCryptoService has been renamed to DefaultCryptoService as it no longer explicitly uses Bouncy Castle but rather uses the installed security providers. This was done to fix a failing test. BCCryptoService was already relying on the installed providers in some places anyway.

The hack to get Corda SecureRandom working was also resolved. Also, as an added bonus, tests which ignored SPHINCS256_SHA256 have been reinstated.

Note, there is a slight inconsistency between how EdDSA and ECDSA keys are handled (and also RSA). For the later, Bouncy Castle is preferred, and methods such as toSupportedKey* will convert any JDK class to Bouncy Castle. For EdDSA the preference is the JDK (SunEC). However, this is simply a continuation of the previous preference of the i2p library over Bouncy Castle.

Copy link
@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

PR title failed to match regex -> ^((CORDA|AG|EG|ENT|INFRA|ES)-\d+)(.*)

@shamsasari shamsasari force-pushed the shams-remove-i2p branch 8 times, most recently from d6127e4 to 5c5361d Compare February 28, 2024 18:13
@shamsasari shamsasari changed the title WIP: Remove i2p ENT-11101: Fix all crypto issues introduced by Java 17 upgrade Feb 29, 2024
@github-actions github-actions bot dismissed their stale review February 29, 2024 09:45

All good!

@shamsasari shamsasari requested a review from adelel1 February 29, 2024 16:29
@shamsasari shamsasari marked this pull request as ready for review February 29, 2024 16:29
@shamsasari shamsasari requested a review from rick-r3 as a code owner February 29, 2024 16:30
@shamsasari
Copy link
Contributor Author

This supersedes #7600.

@shamsasari shamsasari force-pushed the shams-remove-i2p branch 2 times, most recently from f49fd67 to e390b16 Compare February 29, 2024 22:20
Comment on lines +142 to +147
// The default signature scheme, EDDSA_ED25519_SHA512, generates public keys which have a writeReplace method (EdDSAPublicKeyImpl).
// This is picked up by Quasar's custom ReplaceableObjectKryo, which will *always* use the writeReplace for serialisation, ignoring
// any Kryo serialisers that might have been configured. This thus means the deserialisation path does not go via
// Cryto.decodePublicKey, which interns the materialised PublicKey. To avoid all of this, and test the last assertion, we use
// ECDSA keys, whose implementation doesn't have a writeReplace method.
val keyPair = Crypto.generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256)
Copy link
Contributor Author
@shamsasari shamsasari Mar 1, 2024

Choose a reason for hiding this comment

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

@rick-r3 you will recall I had raised the issue with ReplaceObjectKryo and how it might force the end users to add --add-exports flags. I had a raised a PoC PR to look into this, with corresponding changes to the plugin.

I still feel this is something we should look into (if there's time).

Copy link
Contributor

Choose a reason for hiding this comment

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

That's unfortunate, but not a blocker. Will have to have a think about how we might work around it. I suppose a wrapper public key class of our own making would work (we might have to unwrap on entry to some of the crypto methods). Or we could poke something into FORBIDDEN_CLASSES in ReplaceObjectKryo - which is ugly - and/or try and make that extensible in our Quasar fork.

The various crypto tests that were previously ignored have been re-enabled.

The abandoned i2p EdDSA library has been replaced with native support that was added in Java 15.

Java 17 (via the `SunEC` provider) does not support the secp256k1 curve (one of the two ECDSA curves supported in Corda). This would not normally have been an issue as secp256k1 is already taken care of by Bouncy Castle. However, this only works if the `Crypto` API is used or if `”BC”` is explicitly specified as the provider (e.g. `Signature.getInstance(“SHA256withECDSA”, “BC”)`). If no provider is specified, which is what is more common, and actually what the Java docs recommend, then this doesn’t work as the `SunEC` provider is selected. To resolve this, a custom provider was created, installed just in front of `SunEC`, which “augments” `SunEC` by delegating to Bouncy Castle if keys or parameters for secp256k1 are encountered.

`X509Utilities.createCertificate` now calls `X509Certificate.verify()` to verify the created certificate, rather than using the Bouncy Castle API. This is more representative of how certificates will be verified (e.g. during SSL handshake) and weeds out other issues (such as unsupported curve error for secp256k1).

`BCCryptoService` has been renamed to `DefaultCryptoService` as it no longer explicitly uses Bouncy Castle but rather uses the installed security providers. This was done to fix a failing test. Further, `BCCryptoService` was already relying on the installed providers in some places.

The hack to get Corda `SecureRandom` working was also resolved. Also, as an added bonus, tests which ignored `SPHINCS256_SHA256` have been reinstated.

Note, there is a slightly inconsistency between how EdDSA and ECDSA keys are handled (and also RSA). For the later, Bouncy Castle is preferred, and methods such as `toSupportedKey*` will convert any JDK class to Bouncy Castle. For EdDSA the preference is the JDK (`SunEC`). However, this is simply a continuation of the previous preference of the i2p library over Bouncy Castle.
Copy link
Collaborator
@adelel1 adelel1 left a comment

Choose a reason for hiding this comment

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

Thanks for this PR!
LGTM

@rick-r3
Copy link
Contributor
rick-r3 commented Mar 5, 2024

I guess we have yet to see what the performance of the JDK implementation is like.

@adelel1 adelel1 merged commit 6bdad94 into release/os/4.12 Mar 5, 2024
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.

3 participants
0