summaryrefslogtreecommitdiffstats
path: root/security-utils
diff options
context:
space:
mode:
Diffstat (limited to 'security-utils')
-rw-r--r--security-utils/src/main/java/com/yahoo/security/SharedKeyGenerator.java16
-rw-r--r--security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java16
2 files changed, 28 insertions, 4 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/SharedKeyGenerator.java b/security-utils/src/main/java/com/yahoo/security/SharedKeyGenerator.java
index 8a1a7dd3688..66a87a94707 100644
--- a/security-utils/src/main/java/com/yahoo/security/SharedKeyGenerator.java
+++ b/security-utils/src/main/java/com/yahoo/security/SharedKeyGenerator.java
@@ -62,10 +62,7 @@ public class SharedKeyGenerator {
public static SecretSharedKey generateForReceiverPublicKey(PublicKey receiverPublicKey, KeyId keyId) {
var secretKey = generateRandomSecretAesKey();
- // We protect the integrity of the key ID by passing it as AAD.
- var sealed = HPKE.sealBase((XECPublicKey) receiverPublicKey, EMPTY_BYTES, keyId.asBytes(), secretKey.getEncoded());
- var sealedSharedKey = new SealedSharedKey(keyId, sealed.enc(), sealed.ciphertext());
- return new SecretSharedKey(secretKey, sealedSharedKey);
+ return internalSealSecretKeyForReceiver(secretKey, receiverPublicKey, keyId);
}
public static SecretSharedKey fromSealedKey(SealedSharedKey sealedKey, PrivateKey receiverPrivateKey) {
@@ -74,6 +71,17 @@ public class SharedKeyGenerator {
return new SecretSharedKey(new SecretKeySpec(secretKeyBytes, "AES"), sealedKey);
}
+ public static SecretSharedKey reseal(SecretSharedKey secret, PublicKey receiverPublicKey, KeyId keyId) {
+ return internalSealSecretKeyForReceiver(secret.secretKey(), receiverPublicKey, keyId);
+ }
+
+ private static SecretSharedKey internalSealSecretKeyForReceiver(SecretKey secretKey, PublicKey receiverPublicKey, KeyId keyId) {
+ // We protect the integrity of the key ID by passing it as AAD.
+ var sealed = HPKE.sealBase((XECPublicKey) receiverPublicKey, EMPTY_BYTES, keyId.asBytes(), secretKey.getEncoded());
+ var sealedSharedKey = new SealedSharedKey(keyId, sealed.enc(), sealed.ciphertext());
+ return new SecretSharedKey(secretKey, sealedSharedKey);
+ }
+
// A given key+IV pair can only be used for one single encryption session, ever.
// Since our keys are intended to be inherently single-use, we can satisfy that
// requirement even with a fixed IV. This avoids the need for explicitly including
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 4e64bc3e9aa..23e22345cc6 100644
--- a/security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java
+++ b/security-utils/src/test/java/com/yahoo/security/SharedKeyTest.java
@@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
public class SharedKeyTest {
private static final KeyId KEY_ID_1 = KeyId.ofString("1");
+ private static final KeyId KEY_ID_2 = KeyId.ofString("2");
@Test
void generated_secret_key_is_128_bit_aes() {
@@ -45,6 +46,21 @@ public class SharedKeyTest {
}
@Test
+ void secret_key_can_be_resealed_for_another_receiver() {
+ var originalReceiverKp = KeyUtils.generateX25519KeyPair();
+ var secondaryReceiverKp = KeyUtils.generateX25519KeyPair();
+ var myShared = SharedKeyGenerator.generateForReceiverPublicKey(originalReceiverKp.getPublic(), KEY_ID_1);
+ var theirShared = SharedKeyGenerator.reseal(myShared, secondaryReceiverKp.getPublic(), KEY_ID_2);
+
+ var publicToken = theirShared.sealedSharedKey().toTokenString();
+ var theirSealed = SealedSharedKey.fromTokenString(publicToken);
+ assertEquals(KEY_ID_2, theirSealed.keyId());
+ theirShared = SharedKeyGenerator.fromSealedKey(theirSealed, secondaryReceiverKp.getPrivate());
+ // Should be same internal secret key
+ assertArrayEquals(myShared.secretKey().getEncoded(), theirShared.secretKey().getEncoded());
+ }
+
+ @Test
void token_v1_representation_is_stable() {
var receiverPrivate = KeyUtils.fromBase58EncodedX25519PrivateKey("GFg54SaGNCmcSGufZCx68SKLGuAFrASoDeMk3t5AjU6L");
var receiverPublic = KeyUtils.fromBase58EncodedX25519PublicKey( "5drrkakYLjYSBpr5Haknh13EiCYL36ndMzK4gTJo6pwh");