diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java b/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java index fb5179acb2..3aeacba5a6 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java +++ b/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java @@ -197,13 +197,13 @@ public int getCertificateExpiryCheckFrequency() @Override public List getCertificateDetails() { - Collection certificates = getCertificates(); + final Collection certificates = getCertificates(); if (!certificates.isEmpty()) { return certificates.stream() - .filter(cert -> cert instanceof X509Certificate) - .map(x509cert -> new CertificateDetailsImpl((X509Certificate) x509cert)) - .collect(Collectors.toList()); + .filter(X509Certificate.class::isInstance) + .map(x509cert -> new CertificateDetailsImpl((X509Certificate) x509cert)) + .collect(Collectors.toList()); } return Collections.emptyList(); } diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java index eca153f4e4..16c05801ab 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java +++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java @@ -90,14 +90,12 @@ public class FileKeyStoreImpl extends AbstractKeyStore impleme Handler.register(); } - @ManagedObjectFactoryConstructor public FileKeyStoreImpl(Map attributes, Broker broker) { super(attributes, broker); } - @Override public void onValidate() { @@ -137,7 +135,7 @@ private void initialize() { try { - _certificates = Collections.unmodifiableMap(SSLUtil.getCertificates(getInitializedKeyStore(this))); + _certificates = Collections.unmodifiableMap(SSLUtil.getCertificates(getInitializedKeyStore(this), true)); } catch (GeneralSecurityException | IOException e) { diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java index f6e9c7bd0a..81738c696c 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java +++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java @@ -295,7 +295,7 @@ protected void initialize() { final KeyStore ts = initializeKeyStore(this); trustManagers = createTrustManagers(ts); - certificates = Collections.unmodifiableMap(SSLUtil.getCertificates(ts)); + certificates = Collections.unmodifiableMap(SSLUtil.getCertificates(ts, false)); } catch (Exception e) { diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java index 9b80fdf0e7..502227034c 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java +++ b/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java @@ -322,4 +322,10 @@ protected Collection getCertificates() final Collection certificates = _certificates; return certificates == null ? List.of() : certificates; } + + @Override + public List getCertificateDetails() + { + return _certificate == null ? List.of() : List.of(new CertificateDetailsImpl(_certificate)); + } } diff --git a/broker-core/src/main/java/org/apache/qpid/server/transport/network/security/ssl/SSLUtil.java b/broker-core/src/main/java/org/apache/qpid/server/transport/network/security/ssl/SSLUtil.java index 65a4fc4eeb..2f1f05a1ee 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/transport/network/security/ssl/SSLUtil.java +++ b/broker-core/src/main/java/org/apache/qpid/server/transport/network/security/ssl/SSLUtil.java @@ -932,14 +932,14 @@ public X509Certificate getCertificate() }; } - public static Map getCertificates(final KeyStore ks) throws KeyStoreException + public static Map getCertificates(final KeyStore ks, final boolean keyCertificates) throws KeyStoreException { final Map certificates = new HashMap<>(); final Enumeration aliases = ks.aliases(); while (aliases.hasMoreElements()) { final String alias = aliases.nextElement(); - if (ks.isCertificateEntry(alias)) + if ((keyCertificates && ks.isKeyEntry(alias)) || (!keyCertificates && ks.isCertificateEntry(alias))) { certificates.put(alias, ks.getCertificate(alias)); } diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreTest.java new file mode 100644 index 0000000000..32e3a5c101 --- /dev/null +++ b/broker-core/src/test/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreTest.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.qpid.server.security; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPublicKey; +import java.util.Base64; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.KeyManager; + +import org.junit.jupiter.api.Test; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.BrokerTestHelper; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.test.utils.UnitTestBase; + +class AutoGeneratedSelfSignedKeyStoreTest extends UnitTestBase +{ + private static final Broker BROKER = BrokerTestHelper.createBrokerMock(); + private static final ConfiguredObjectFactory FACTORY = BrokerModel.getInstance().getObjectFactory(); + private static final String NAME = "myKeyStore"; + + private final AutoGeneratedSelfSignedKeyStore _keyStore = createAutoGeneratedSelfSignedKeyStore(); + + @Test + void creation() throws Exception + { + final KeyManager[] keyManager = _keyStore.getKeyManagers(); + + assertNotNull(keyManager); + assertEquals(1, keyManager.length, "Unexpected number of key managers"); + assertNotNull(keyManager[0], "Key manager unexpected null"); + } + + @Test + void regenerate() + { + final String privateKey = _keyStore.getEncodedPrivateKey(); + final String certificate = _keyStore.getEncodedCertificate(); + + assertNotNull(privateKey); + assertNotNull(certificate); + + _keyStore.regenerateCertificate(); + + final String regeneratedPrivateKey = _keyStore.getEncodedPrivateKey(); + final String regeneratedCertificate = _keyStore.getEncodedCertificate(); + + assertNotNull(regeneratedPrivateKey); + assertNotNull(regeneratedCertificate); + + assertNotEquals(privateKey, regeneratedPrivateKey, "Regenerated private key shouldn't be equal to the original private key"); + assertNotEquals(certificate, regeneratedCertificate, "Regenerated certificate shouldn't be equal to the original certificate"); + } + + @Test + void privateKeyEntryCertificate() + { + final List certificateDetails = _keyStore.getCertificateDetails(); + + assertEquals(1, certificateDetails.size(), "Unexpected number of certificates"); + assertEquals("myKeyStore", certificateDetails.get(0).getAlias(), "Unexpected alias name"); + } + + @Test + void content() throws Exception + { + try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) + { + _keyStore.getCertificate().write(baos); + + final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + final X509Certificate certificate = (X509Certificate) certFactory + .generateCertificate(new ByteArrayInputStream(baos.toByteArray())); + final String encodedCertificate = new String(Base64.getEncoder().encode(certificate.getEncoded()), StandardCharsets.UTF_8); + + assertEquals("X.509", certificate.getType(), "Certificate type mismatch"); + assertTrue(_keyStore.getSignatureAlgorithm().equalsIgnoreCase(certificate.getSigAlgName()), + "Certificate signature algorithm mismatch"); + assertInstanceOf(RSAPublicKey.class, certificate.getPublicKey(), "Key class mismatch"); + assertEquals(_keyStore.getKeyLength(), ((RSAPublicKey) certificate.getPublicKey()).getModulus().bitLength(), "Key length mismatch"); + assertEquals(_keyStore.getEncodedCertificate(), encodedCertificate, "Certificate content mismatch"); + } + } + + private AutoGeneratedSelfSignedKeyStore createAutoGeneratedSelfSignedKeyStore() + { + final Map attributes = Map.of(AutoGeneratedSelfSignedKeyStore.NAME, NAME, + AutoGeneratedSelfSignedKeyStore.TYPE, "AutoGeneratedSelfSigned"); + return (AutoGeneratedSelfSignedKeyStore) FACTORY.create(KeyStore.class, attributes, BROKER); + } +} diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java index 3e4d06a741..0aa43dd85b 100644 --- a/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java +++ b/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java @@ -65,7 +65,7 @@ public class FileKeyStoreTest extends UnitTestBase private static final String SECRET_KEY_ALIAS = "secret-key-alias"; @Test - public void testCreateKeyStoreFromFile_Success() throws Exception + void testCreateKeyStoreFromFile_Success() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -81,7 +81,7 @@ public void testCreateKeyStoreFromFile_Success() throws Exception } @Test - public void testCreateKeyStoreWithAliasFromFile_Success() throws Exception + void testCreateKeyStoreWithAliasFromFile_Success() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -97,7 +97,7 @@ public void testCreateKeyStoreWithAliasFromFile_Success() throws Exception } @Test - public void testCreateKeyStoreFromFile_WrongPassword() throws Exception + void testCreateKeyStoreFromFile_WrongPassword() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -109,7 +109,7 @@ public void testCreateKeyStoreFromFile_WrongPassword() throws Exception } @Test - public void testCreateKeyStoreFromFile_UnknownAlias() throws Exception + void testCreateKeyStoreFromFile_UnknownAlias() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO); final String unknownAlias = TLS_RESOURCE.getPrivateKeyAlias() + "_"; @@ -124,7 +124,7 @@ public void testCreateKeyStoreFromFile_UnknownAlias() throws Exception } @Test - public void testCreateKeyStoreFromFile_NonKeyAlias() throws Exception + void testCreateKeyStoreFromFile_NonKeyAlias() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedTrustStore(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -138,7 +138,7 @@ public void testCreateKeyStoreFromFile_NonKeyAlias() throws Exception } @Test - public void testCreateKeyStoreFromDataUrl_Success() throws Exception + void testCreateKeyStoreFromDataUrl_Success() throws Exception { final String keyStoreAsDataUrl = TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -153,7 +153,7 @@ public void testCreateKeyStoreFromDataUrl_Success() throws Exception } @Test - public void testCreateKeyStoreWithAliasFromDataUrl_Success() throws Exception + void testCreateKeyStoreWithAliasFromDataUrl_Success() throws Exception { final String keyStoreAsDataUrl = TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -169,7 +169,7 @@ public void testCreateKeyStoreWithAliasFromDataUrl_Success() throws Exception } @Test - public void testCreateKeyStoreFromDataUrl_WrongPassword() throws Exception + void testCreateKeyStoreFromDataUrl_WrongPassword() throws Exception { final String keyStoreAsDataUrl = TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -181,7 +181,7 @@ public void testCreateKeyStoreFromDataUrl_WrongPassword() throws Exception } @Test - public void testCreateKeyStoreFromDataUrl_BadKeystoreBytes() + void testCreateKeyStoreFromDataUrl_BadKeystoreBytes() { final String keyStoreAsDataUrl = DataUrlUtils.getDataUrlForBytes("notatruststore".getBytes()); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -193,7 +193,7 @@ public void testCreateKeyStoreFromDataUrl_BadKeystoreBytes() } @Test - public void testCreateKeyStoreFromDataUrl_UnknownAlias() throws Exception + void testCreateKeyStoreFromDataUrl_UnknownAlias() throws Exception { final String keyStoreAsDataUrl = TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO); final String unknownAlias = TLS_RESOURCE.getPrivateKeyAlias() + "_"; @@ -208,7 +208,7 @@ public void testCreateKeyStoreFromDataUrl_UnknownAlias() throws Exception } @Test - public void testEmptyKeystoreRejected() throws Exception + void testEmptyKeystoreRejected() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createKeyStore(); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -220,7 +220,7 @@ public void testEmptyKeystoreRejected() throws Exception } @Test - public void testKeystoreWithNoPrivateKeyRejected() throws Exception + void testKeystoreWithNoPrivateKeyRejected() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedTrustStore(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, getTestName(), @@ -233,7 +233,7 @@ public void testKeystoreWithNoPrivateKeyRejected() throws Exception } @Test - public void testSymmetricKeysIgnored() throws Exception + void testSymmetricKeysIgnored() throws Exception { final String keyStoreType = "jceks"; // or jks final Path keyStoreFile = createSelfSignedKeyStoreWithSecretKeyAndCertificate(keyStoreType, DN_FOO); @@ -246,7 +246,7 @@ public void testSymmetricKeysIgnored() throws Exception } @Test - public void testUpdateKeyStore_Success() throws Exception + void testUpdateKeyStore_Success() throws Exception { final Path keyStoreFile = TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO); final Map attributes = Map.of(FileKeyStore.NAME, NAME, @@ -276,7 +276,7 @@ public void testUpdateKeyStore_Success() throws Exception } @Test - public void testReloadKeystore() throws Exception + void testReloadKeystore() throws Exception { final Path keyStorePath = TLS_RESOURCE.createSelfSignedKeyStoreWithCertificate(DN_FOO); final Path keyStorePath2 = TLS_RESOURCE.createSelfSignedKeyStoreWithCertificate(DN_BAR); @@ -295,6 +295,23 @@ public void testReloadKeystore() throws Exception assertEquals(DN_BAR, certificate2.getIssuerName()); } + @Test + void privateKeyEntryCertificate() throws Exception + { + final Path keyStoreFile = TLS_RESOURCE.createSelfSignedKeyStoreWithCertificate(DN_FOO); + final Map attributes = Map.of(FileKeyStore.NAME, getTestName(), + FileKeyStore.PASSWORD, TLS_RESOURCE.getSecret(), + FileKeyStore.STORE_URL, keyStoreFile.toFile().getAbsolutePath(), + FileKeyStore.KEY_STORE_TYPE, TLS_RESOURCE.getKeyStoreType()); + final FileKeyStore keyStore = createFileKeyStore(attributes); + final List certificateDetails = keyStore.getCertificateDetails(); + + final int keyCertificates = KeyStoreTestHelper + .getNumberOfCertificates(keyStoreFile, "PKCS12", TLS_RESOURCE.getSecret().toCharArray(), true); + assertEquals(keyCertificates, certificateDetails.size(), "Unexpected number of certificates"); + assertEquals("private-key-alias", certificateDetails.get(0).getAlias(), "Unexpected alias name"); + } + @SuppressWarnings("unchecked") private FileKeyStore createFileKeyStore(final Map attributes) { diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java index 2182bc241d..c42cd82f51 100644 --- a/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java +++ b/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java @@ -27,8 +27,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeFalse; -import java.io.FileInputStream; -import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -39,7 +37,6 @@ import java.security.cert.X509Certificate; import java.time.Instant; import java.time.temporal.ChronoUnit; -import java.util.Enumeration; import java.util.Map; import java.util.Objects; @@ -358,8 +355,9 @@ public void testSymmetricKeyEntryIgnored() throws Exception final FileTrustStore trustStore = createFileTrustStore(attributes); final Certificate[] certificates = trustStore.getCertificates(); - assertEquals(getNumberOfCertificates(keyStoreFile, keyStoreType), (long) certificates.length, - "Unexpected number of certificates"); + final int numberOfCertificates = KeyStoreTestHelper + .getNumberOfCertificates(keyStoreFile, keyStoreType, TLS_RESOURCE.getSecret().toCharArray(), false); + assertEquals(numberOfCertificates, (long) certificates.length, "Unexpected number of certificates"); } @Test @@ -373,8 +371,9 @@ public void testPrivateKeyEntryIgnored() throws Exception final FileTrustStore trustStore = createFileTrustStore(attributes); final Certificate[] certificates = trustStore.getCertificates(); - assertEquals(getNumberOfCertificates(keyStoreFile, TLS_RESOURCE.getKeyStoreType()), (long) certificates.length, - "Unexpected number of certificates"); + final int numberOfCertificates = KeyStoreTestHelper + .getNumberOfCertificates(keyStoreFile, "PKCS12", TLS_RESOURCE.getSecret().toCharArray(), false); + assertEquals(numberOfCertificates, (long) certificates.length, "Unexpected number of certificates"); } @Test @@ -415,27 +414,6 @@ private X509Certificate getCertificate(final FileTrustStore trustStore) return (X509Certificate) certificate; } - private int getNumberOfCertificates(Path keystore, String type) throws Exception - { - final KeyStore ks = KeyStore.getInstance(type); - try (final InputStream is = new FileInputStream(keystore.toFile())) - { - ks.load(is, TLS_RESOURCE.getSecret().toCharArray()); - } - - int result = 0; - final Enumeration aliases = ks.aliases(); - while (aliases.hasMoreElements()) - { - final String alias = aliases.nextElement(); - if (ks.isCertificateEntry(alias)) - { - result++; - } - } - return result; - } - private Path createTrustStoreWithExpiredCertificate() throws Exception { final Instant from = Instant.now().minus(10, ChronoUnit.DAYS); diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/KeyStoreTestHelper.java b/broker-core/src/test/java/org/apache/qpid/server/security/KeyStoreTestHelper.java index 28acb13b88..9ae632744d 100644 --- a/broker-core/src/test/java/org/apache/qpid/server/security/KeyStoreTestHelper.java +++ b/broker-core/src/test/java/org/apache/qpid/server/security/KeyStoreTestHelper.java @@ -22,6 +22,11 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.file.Path; +import java.security.KeyStore; +import java.util.Enumeration; import java.util.Map; import org.apache.qpid.server.configuration.IllegalConfigurationException; @@ -43,4 +48,28 @@ public static void checkExceptionThrownDuringKeyStoreCreation(final ConfiguredOb final String message = thrown.getMessage(); assertTrue(message.contains(expectedExceptionMessage), "Exception text not as expected:" + message); } + + public static int getNumberOfCertificates(final Path keystore, + final String type, + final char[] password, + final boolean keyCertificates) throws Exception + { + final KeyStore ks = KeyStore.getInstance(type); + try (final InputStream is = new FileInputStream(keystore.toFile())) + { + ks.load(is, password); + } + + int result = 0; + final Enumeration aliases = ks.aliases(); + while (aliases.hasMoreElements()) + { + final String alias = aliases.nextElement(); + if ((keyCertificates && ks.isKeyEntry(alias)) || (!keyCertificates && ks.isCertificateEntry(alias))) + { + result++; + } + } + return result; + } } diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java index 4610baa218..77941525af 100644 --- a/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java +++ b/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java @@ -38,6 +38,7 @@ import java.security.cert.X509Certificate; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -90,7 +91,7 @@ public void setUp() throws Exception } @Test - public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDERFormat() throws Exception + void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDERFormat() throws Exception { final Path privateKeyFile = TLS_RESOURCE.savePrivateKeyAsDer(_keyCertPair.getPrivateKey()); final Path certificateFile = TLS_RESOURCE.saveCertificateAsDer(_keyCertPair.getCertificate()); @@ -98,7 +99,7 @@ public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDERFormat } @Test - public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInPEMFormat() throws Exception + void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInPEMFormat() throws Exception { final Path privateKeyFile = TLS_RESOURCE.savePrivateKeyAsPem(_keyCertPair.getPrivateKey()); final Path certificateFile = TLS_RESOURCE.saveCertificateAsPem(_keyCertPair.getCertificate()); @@ -120,7 +121,7 @@ private void assertCreationOfTrustStoreFromValidPrivateKeyAndCertificate(Path pr } @Test - public void testCreationOfTrustStoreFromValidPrivateKeyAndInvalidCertificate()throws Exception + void testCreationOfTrustStoreFromValidPrivateKeyAndInvalidCertificate()throws Exception { final Path privateKeyFile = TLS_RESOURCE.savePrivateKeyAsPem(_keyCertPair.getPrivateKey()); final Path certificateFile = TLS_RESOURCE.createFile(".cer"); @@ -134,7 +135,7 @@ public void testCreationOfTrustStoreFromValidPrivateKeyAndInvalidCertificate()th } @Test - public void testCreationOfTrustStoreFromInvalidPrivateKeyAndValidCertificate()throws Exception + void testCreationOfTrustStoreFromInvalidPrivateKeyAndValidCertificate()throws Exception { final Path privateKeyFile = TLS_RESOURCE.createFile(".pk"); final Path certificateFile = TLS_RESOURCE.saveCertificateAsPem(_keyCertPair.getCertificate()); @@ -149,14 +150,14 @@ public void testCreationOfTrustStoreFromInvalidPrivateKeyAndValidCertificate()th } @Test - public void testExpiryCheckingFindsExpired() throws Exception + void testExpiryCheckingFindsExpired() throws Exception { doCertExpiryChecking(1); verify(_messageLogger, times(1)).message(argThat(new LogMessageArgumentMatcher())); } @Test - public void testExpiryCheckingIgnoresValid() throws Exception + void testExpiryCheckingIgnoresValid() throws Exception { doCertExpiryChecking(-1); verify(_messageLogger, never()).message(argThat(new LogMessageArgumentMatcher())); @@ -179,7 +180,7 @@ private void doCertExpiryChecking(final int expiryOffset) throws Exception } @Test - public void testCreationOfKeyStoreWithNonMatchingPrivateKeyAndCertificate()throws Exception + void testCreationOfKeyStoreWithNonMatchingPrivateKeyAndCertificate()throws Exception { final KeyCertificatePair keyCertPair2 = generateSelfSignedCertificate(); final Map attributes = Map.of(NonJavaKeyStore.NAME, NAME, @@ -192,7 +193,7 @@ NonJavaKeyStore.CERTIFICATE_URL, getCertificateAsDataUrl(keyCertPair2.getCertifi } @Test - public void testUpdateKeyStoreToNonMatchingCertificate()throws Exception + void testUpdateKeyStoreToNonMatchingCertificate()throws Exception { final Map attributes = Map.of(NonJavaKeyStore.NAME, getTestName(), NonJavaKeyStore.PRIVATE_KEY_URL, getPrivateKeyAsDataUrl(_keyCertPair.getPrivateKey()), @@ -201,12 +202,25 @@ NonJavaKeyStore.CERTIFICATE_URL, getCertificateAsDataUrl(_keyCertPair.getCertifi final KeyStore trustStore = createTestKeyStore(attributes); final KeyCertificatePair keyCertPair2 = generateSelfSignedCertificate(); final String certUrl = getCertificateAsDataUrl(keyCertPair2.getCertificate()); + final Map newAttributes = Map.of("certificateUrl", certUrl); - assertThrows(IllegalConfigurationException.class, - () -> trustStore.setAttributes(Map.of("certificateUrl", certUrl)), + assertThrows(IllegalConfigurationException.class, () -> trustStore.setAttributes(newAttributes), "Created key store from invalid certificate"); } + @Test + void privateKeyEntryCertificate() throws Exception + { + final Map attributes = Map.of(NonJavaKeyStore.NAME, getTestName(), + NonJavaKeyStore.PRIVATE_KEY_URL, getPrivateKeyAsDataUrl(_keyCertPair.getPrivateKey()), + NonJavaKeyStore.CERTIFICATE_URL, getCertificateAsDataUrl(_keyCertPair.getCertificate()), + NonJavaKeyStore.TYPE, NON_JAVA_KEY_STORE); + final KeyStore keyStore = createTestKeyStore(attributes); + final List certificateDetails = keyStore.getCertificateDetails(); + + assertEquals(1, certificateDetails.size(), "Unexpected number of certificates"); + } + @SuppressWarnings("unchecked") private KeyStore createTestKeyStore(final Map attributes) {