summaryrefslogtreecommitdiffstats
path: root/security-utils/src/test/java/com
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2022-10-19 12:40:34 +0200
committerTor Brede Vekterli <vekterli@yahooinc.com>2022-10-19 12:40:34 +0200
commit82c8d614762c3e4bb0abc14148a1fba1ca3182e5 (patch)
treebcbd539039e4e0b3ed4c35f41959eecb54994fbd /security-utils/src/test/java/com
parent9bd0a86bba6280aded2ff575ba095a446d6aa4e7 (diff)
Add X25519 private to public key extraction and use for HPKE opening
Avoids the need to pass the full key pair when opening a sealed piece of ciphertext, since we can just extract the public key on-demand. Uses BouncyCastle X25519 utils under the hood.
Diffstat (limited to 'security-utils/src/test/java/com')
-rw-r--r--security-utils/src/test/java/com/yahoo/security/HpkeTest.java27
-rw-r--r--security-utils/src/test/java/com/yahoo/security/KeyUtilsTest.java13
2 files changed, 31 insertions, 9 deletions
diff --git a/security-utils/src/test/java/com/yahoo/security/HpkeTest.java b/security-utils/src/test/java/com/yahoo/security/HpkeTest.java
index 24944759c5c..4455eade7cd 100644
--- a/security-utils/src/test/java/com/yahoo/security/HpkeTest.java
+++ b/security-utils/src/test/java/com/yahoo/security/HpkeTest.java
@@ -9,6 +9,7 @@ import com.yahoo.security.hpke.Kem;
import org.junit.jupiter.api.Test;
import java.security.KeyPair;
+import java.security.interfaces.XECPrivateKey;
import java.security.interfaces.XECPublicKey;
import static com.yahoo.security.ArrayUtils.hex;
@@ -35,6 +36,14 @@ public class HpkeTest {
return new KeyPair(pub, priv);
}
+ private static XECPublicKey pk(KeyPair kp) {
+ return (XECPublicKey) kp.getPublic();
+ }
+
+ private static XECPrivateKey sk(KeyPair kp) {
+ return (XECPrivateKey) kp.getPrivate();
+ }
+
/**
* https://www.rfc-editor.org/rfc/rfc9180.html test vector
*
@@ -55,7 +64,7 @@ public class HpkeTest {
var ciphersuite = Ciphersuite.of(kem, Kdf.hkdfSha256(), Aead.aesGcm128());
var hpke = Hpke.of(ciphersuite);
- var s = hpke.sealBase((XECPublicKey) kpR.getPublic(), info, aad, pt);
+ var s = hpke.sealBase(pk(kpR), info, aad, pt);
// The "enc" output is the ephemeral public key
var expectedEnc = "37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431";
@@ -65,7 +74,7 @@ public class HpkeTest {
"6d8770ac83d07bea87e13c512a";
assertEquals(expectedCiphertext, hex(s.ciphertext()));
- byte[] openedPt = hpke.openBase(s.enc(), kpR, info, aad, s.ciphertext());
+ byte[] openedPt = hpke.openBase(s.enc(), sk(kpR), info, aad, s.ciphertext());
assertEquals(hex(pt), hex(openedPt));
}
@@ -78,12 +87,12 @@ public class HpkeTest {
var hpke = Hpke.of(Ciphersuite.defaultSuite());
- var s1 = hpke.sealBase((XECPublicKey) kpR.getPublic(), info, aad, pt);
- byte[] openedPt = hpke.openBase(s1.enc(), kpR, info, aad, s1.ciphertext());
+ var s1 = hpke.sealBase(pk(kpR), info, aad, pt);
+ byte[] openedPt = hpke.openBase(s1.enc(), sk(kpR), info, aad, s1.ciphertext());
assertEquals(hex(pt), hex(openedPt));
- var s2 = hpke.sealBase((XECPublicKey) kpR.getPublic(), info, aad, pt);
- openedPt = hpke.openBase(s2.enc(), kpR, info, aad, s2.ciphertext());
+ var s2 = hpke.sealBase(pk(kpR), info, aad, pt);
+ openedPt = hpke.openBase(s2.enc(), sk(kpR), info, aad, s2.ciphertext());
assertEquals(hex(pt), hex(openedPt));
assertNotEquals(hex(s1.enc()), hex(s2.enc())); // This is the ephemeral public key
@@ -97,13 +106,13 @@ public class HpkeTest {
var kpR = receiverRrfc9180TestVectorKeyPair();
var hpke = Hpke.of(Ciphersuite.defaultSuite());
- var s = hpke.sealBase((XECPublicKey) kpR.getPublic(), info, aad, pt);
+ var s = hpke.sealBase(pk(kpR), info, aad, pt);
byte[] badInfo = toUtf8Bytes("lesser info");
// TODO better exception classes! Triggers AEAD auth tag mismatch behind the scenes
- assertThrows(RuntimeException.class, () -> hpke.openBase(s.enc(), kpR, badInfo, aad, s.ciphertext()));
+ assertThrows(RuntimeException.class, () -> hpke.openBase(s.enc(), sk(kpR), badInfo, aad, s.ciphertext()));
byte[] badAad = toUtf8Bytes("non-groovy AAD");
- assertThrows(RuntimeException.class, () -> hpke.openBase(s.enc(), kpR, info, badAad, s.ciphertext()));
+ assertThrows(RuntimeException.class, () -> hpke.openBase(s.enc(), sk(kpR), info, badAad, s.ciphertext()));
}
}
diff --git a/security-utils/src/test/java/com/yahoo/security/KeyUtilsTest.java b/security-utils/src/test/java/com/yahoo/security/KeyUtilsTest.java
index fbf27b67f4b..97fd8ce9e41 100644
--- a/security-utils/src/test/java/com/yahoo/security/KeyUtilsTest.java
+++ b/security-utils/src/test/java/com/yahoo/security/KeyUtilsTest.java
@@ -170,4 +170,17 @@ public class KeyUtilsTest {
assertEquals(pubHex, xecHexFromPub(pub2));
}
+ @Test
+ void can_extract_public_key_from_x25519_private_key() {
+ var priv = xecPrivFromHex("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a");
+ var expectedPubHex = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a";
+ var pub = KeyUtils.extractX25519PublicKey(priv);
+ assertEquals(expectedPubHex, xecHexFromPub(pub));
+
+ priv = xecPrivFromHex("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb");
+ expectedPubHex = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f";
+ pub = KeyUtils.extractX25519PublicKey(priv);
+ assertEquals(expectedPubHex, xecHexFromPub(pub));
+ }
+
}