RFR: 8311170: Simplify and modernize equals and hashCode in security area [v11]
Sean Mullan
mullan at openjdk.org
Mon Jul 31 21:44:01 UTC 2023
On Fri, 28 Jul 2023 22:14:09 GMT, Pavel Rappo <prappo at openjdk.org> wrote:
>> Please review this PR to use modern APIs and language features to simplify `equals` and `hashCode` in security area.
>>
>> I understand that security area is sensitive and a non-expert, such as myself, should tread carefully; so below are my notes to assist the review.
>>
>> * Unlike `hashCode`, non-secure `equals` implementations are typically short-circuit. But because of "timing attacks", we seem to have specialized implementations, such as `java.security.MessageDigest.isEqual(byte[], byte[])` and a more general `sun.security.util.ByteArrays.isEqual(byte[], int, int, byte[], int, int)`. So while reviewing this PR, take an opportunity to audit the affected `equals` implementations: perhaps some of them need to become secure, not modern. I have no domain knowledge to tell those cases apart, I only note that those cases exist.
>>
>> * This PR sacrifices compatibility for pragmatism: it changes some `hashCode` implementations to produce different values than before to allow more utilization of methods from `Objects` and `Arrays`. To my mind, those changes are **benign**. If you disagree, I'd be happy to discuss that and/or retract the concerning part of the change.
>>
>> * BitArray could be a topic of its own, but I'll do my best to be concise.
>>
>> * Truth to be told, BitArray's `equals` and `hashCode` are not used anywhere in source, and `equals` is only used in one test. For that reason, I refrained from reimplementing internals of `BitArray` using more general `java.util.BitSet`: too much effort and risk for almost nothing.
>> * Speaking of `BitSet`-powered `BitArray`. Such an implementation is not for the faint of heart: there's too much impedance mismatch between data structures that those classes use to store bits. That said, for the sake of testing that it is possible and that I understand the `BitArray` correctly, I actually implemented it using `BitSet`. While that implementation is **NOT** part of this PR, you can have a look at it [here](https://cr.openjdk.org/~prappo/8311170/BitArray.java).
>>
>> * One suggestion to consider is to change this somewhat arcane piece in java.security.UnresolvedPermission.equals:
>>
>> // check certs
>> if (this.certs == null && that.certs != null ||
>> this.certs != null && that.certs == null ||
>> this.certs != null &&
>> this.certs.length != that.certs.length) {
>> return false;
>> }
>>
>> int i,j;
>> boolea...
>
> Pavel Rappo has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 20 commits:
>
> - Merge branch 'master' into 8311170
>
> # Conflicts:
> # src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
> - Feedback
> - Feedback
> - Feedback: avoid intermediate assignments
> - More previously missed cases
> - Fix: log hashCode as an unsigned long
>
> If they don't match, this test fails:
> test/jdk/jdk/security/logging/TestX509ValidationLog.java
> - Fix: match hashCode implementations
>
> hashCode in the included classes must match that of
> javax.crypto.spec.SecretKeySpec.hashCode.
>
> If they don't match, this test fails:
> test/jdk/javax/crypto/KeyGenerator/CompareKeys.java
> - Fix: revert short-circuiting when destroyed
>
> That change caused this test to fail:
> test/jdk/javax/security/auth/kerberos/KerberosHashEqualsTest.java
> - Much more cases: apologies for extra review work
> - Merge branch 'master' into 8311170
> - ... and 10 more: https://git.openjdk.org/jdk/compare/d6245b68...821f617f
src/java.base/share/classes/java/security/AccessControlContext.java line 1:
> 1: /*
Missing `@Override` on `equals`.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/14738#discussion_r1279910006
More information about the security-dev
mailing list