This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch coheigea/WSS-688 in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
commit 3df6939078b45293ae6849974a8370b7d598f00e Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Mon Oct 12 14:29:55 2026 +0100 WSS-688 - Signatures created with Merlin start being invalid after changing key-store a few times --- .../org/apache/wss4j/common/crypto/Merlin.java | 2 ++ .../org/apache/wss4j/common/crypto/MerlinTest.java | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java index e75628382..6483ff4da 100644 --- a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java +++ b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java @@ -404,6 +404,8 @@ public class Merlin extends CryptoBase { */ public void setKeyStore(KeyStore keyStore) { keystore = keyStore; + // Cached private keys are keyed by alias, so they are not valid for a different keystore + privateKeyCache.clear(); } /** diff --git a/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/MerlinTest.java b/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/MerlinTest.java index a53443f8b..19653ef1c 100644 --- a/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/MerlinTest.java +++ b/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/MerlinTest.java @@ -21,12 +21,17 @@ package org.apache.wss4j.common.crypto; import java.io.InputStream; import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; import org.apache.wss4j.common.util.Loader; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; /** @@ -77,6 +82,31 @@ public class MerlinTest { assertNotNull(pkcs12Crypto.getX509Certificates(cryptoType)); } + /** + * Replacing the keystore must not return a cached private key from the previous keystore + * for the same alias (WSS-688). + */ + @Test + public void testSetKeyStoreClearsPrivateKeyCache() throws Exception { + KeyStore firstKeyStore = loadKeyStore("keys/wss40.jks", "security"); + + // Put the wss40_server key under the "wss40" alias in a second keystore + KeyStore serverKeyStore = loadKeyStore("keys/wss40_server.jks", "security"); + PrivateKey serverKey = (PrivateKey)serverKeyStore.getKey("wss40_server", "security".toCharArray()); + Certificate[] serverChain = serverKeyStore.getCertificateChain("wss40_server"); + KeyStore secondKeyStore = KeyStore.getInstance("JKS"); + secondKeyStore.load(null, null); + secondKeyStore.setKeyEntry("wss40", serverKey, "security".toCharArray(), serverChain); + + Merlin crypto = new Merlin(); + crypto.setKeyStore(firstKeyStore); + PrivateKey firstKey = crypto.getPrivateKey("wss40", "security"); + assertNotEquals(serverKey, firstKey); + + crypto.setKeyStore(secondKeyStore); + assertEquals(serverKey, crypto.getPrivateKey("wss40", "security")); + } + private static KeyStore loadKeyStore(String path, String password) throws Exception { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); ClassLoader loader = Loader.getClassLoader(MerlinTest.class);
