summaryrefslogtreecommitdiffstats
path: root/security-utils
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2023-02-14 13:34:51 +0100
committerTor Brede Vekterli <vekterli@yahooinc.com>2023-02-14 13:34:51 +0100
commitecddf69fd08d050ca121c6123797a39b6f3e92bf (patch)
tree73ecfb71dfe418b9dbe42ba5093314812933566c /security-utils
parent0289e24dc20cd38f69de2dbdb01cb09e1d436501 (diff)
Use explicit `equals` and `hashCode` to use contents of arrays, not just refs
Also add a friendlier `toString()` that hex dumps the enc/ciphertext fields.
Diffstat (limited to 'security-utils')
-rw-r--r--security-utils/src/main/java/com/yahoo/security/SealedSharedKey.java35
-rw-r--r--security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java20
2 files changed, 55 insertions, 0 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/SealedSharedKey.java b/security-utils/src/main/java/com/yahoo/security/SealedSharedKey.java
index 99d07465812..20745ab4312 100644
--- a/security-utils/src/main/java/com/yahoo/security/SealedSharedKey.java
+++ b/security-utils/src/main/java/com/yahoo/security/SealedSharedKey.java
@@ -2,6 +2,10 @@
package com.yahoo.security;
import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Objects;
+
+import static com.yahoo.security.ArrayUtils.hex;
/**
* A SealedSharedKey represents the public part of a secure one-way ephemeral key exchange.
@@ -97,4 +101,35 @@ public record SealedSharedKey(int version, KeyId keyId, byte[] enc, byte[] ciphe
}
}
+ // Friendlier toString() with hex dump of enc/ciphertext fields
+ @Override
+ public String toString() {
+ return "SealedSharedKey{" +
+ "version=" + version +
+ ", keyId=" + keyId +
+ ", enc=" + hex(enc) +
+ ", ciphertext=" + hex(ciphertext) +
+ '}';
+ }
+
+ // Explicitly generated equals() and hashCode() to use _contents_ of
+ // enc/ciphertext arrays, and not just their refs.
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SealedSharedKey that = (SealedSharedKey) o;
+ return version == that.version && keyId.equals(that.keyId) &&
+ Arrays.equals(enc, that.enc) &&
+ Arrays.equals(ciphertext, that.ciphertext);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(version, keyId);
+ result = 31 * result + Arrays.hashCode(enc);
+ result = 31 * result + Arrays.hashCode(ciphertext);
+ return result;
+ }
+
}
diff --git a/security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java b/security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java
index 875877aed6a..26627e9a5fa 100644
--- a/security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java
+++ b/security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java
@@ -14,6 +14,7 @@ import java.util.Optional;
import static com.yahoo.security.ArrayUtils.hex;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class SharedKeyTest {
@@ -22,6 +23,25 @@ public class SharedKeyTest {
private static final KeyId KEY_ID_2 = KeyId.ofString("2");
@Test
+ void sealed_shared_key_uses_enc_and_ciphertext_contents_for_equals_and_hash_code() {
+ var tokenStr1 = "2qW20eDfgCxDVTJfLPzihhqV4i1Ma6QrvjdoU24Csf6W0iKbYmezchhxIGeI39WcHYDvbah5tfLoYZ69ofW40zy59Nm91tavFsA";
+ var tokenStr2 = "mjA83HYuulZW5SWV8FKz4m3b3m9zU8mTrX9n6iY4wZaA6ZNr8WnBZwOU4KQqhPCORPlzSYk4svlonzPZIb3Bjbqr2ePYKLOpdGhCO";
+ var token1a = SealedSharedKey.fromTokenString(tokenStr1);
+ var token1b = SealedSharedKey.fromTokenString(tokenStr1);
+ var token2a = SealedSharedKey.fromTokenString(tokenStr2);
+ var token2b = SealedSharedKey.fromTokenString(tokenStr2);
+ assertEquals(token1a, token1a); // trivial
+ assertEquals(token1a, token1b); // needs deep compare for array contents
+ assertEquals(token1b, token1a);
+ assertEquals(token2a, token2b);
+ assertNotEquals(token1a, token2a);
+
+ assertEquals(token1a.hashCode(), token1b.hashCode());
+ assertEquals(token2a.hashCode(), token2b.hashCode());
+ assertNotEquals(token1a.hashCode(), token2a.hashCode()); // ... with a very high probability
+ }
+
+ @Test
void generated_secret_key_is_128_bit_aes() {
var receiverKeyPair = KeyUtils.generateX25519KeyPair();
var shared = SharedKeyGenerator.generateForReceiverPublicKey(receiverKeyPair.getPublic(), KEY_ID_1);