This is an automated email from the ASF dual-hosted git repository.

vavrtom pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git


The following commit(s) were added to refs/heads/main by this push:
     new de2c34734a QPID-8678 - [Broker-J] Broker REST API returns certificate 
details for truststores but not keystores (#248)
de2c34734a is described below

commit de2c34734ae6ec5cf9c4a50f736880a1fb12a2e6
Author: Daniil Kirilyuk <[email protected]>
AuthorDate: Mon Sep 30 10:04:34 2024 +0200

    QPID-8678 - [Broker-J] Broker REST API returns certificate details for 
truststores but not keystores (#248)
---
 .../qpid/server/security/AbstractKeyStore.java     |   8 +-
 .../qpid/server/security/FileKeyStoreImpl.java     |   4 +-
 .../qpid/server/security/FileTrustStoreImpl.java   |   2 +-
 .../qpid/server/security/NonJavaKeyStoreImpl.java  |   6 +
 .../transport/network/security/ssl/SSLUtil.java    |   4 +-
 .../AutoGeneratedSelfSignedKeyStoreTest.java       | 124 +++++++++++++++++++++
 .../qpid/server/security/FileKeyStoreTest.java     |  47 +++++---
 .../qpid/server/security/FileTrustStoreTest.java   |  34 +-----
 .../qpid/server/security/KeyStoreTestHelper.java   |  29 +++++
 .../qpid/server/security/NonJavaKeyStoreTest.java  |  34 ++++--
 10 files changed, 229 insertions(+), 63 deletions(-)

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 abstract class AbstractKeyStore<X extends 
AbstractKeyStore<X>>
     @Override
     public List<CertificateDetails> getCertificateDetails()
     {
-        Collection<Certificate> certificates = getCertificates();
+        final Collection<Certificate> 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<FileKeyStoreImpl> impleme
         Handler.register();
     }
 
-
     @ManagedObjectFactoryConstructor
     public FileKeyStoreImpl(Map<String, Object> attributes, Broker<?> broker)
     {
         super(attributes, broker);
     }
 
-
     @Override
     public void onValidate()
     {
@@ -137,7 +135,7 @@ public class FileKeyStoreImpl extends 
AbstractKeyStore<FileKeyStoreImpl> impleme
     {
         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 @@ public class FileTrustStoreImpl extends 
AbstractTrustStore<FileTrustStoreImpl> i
         {
             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 @@ public class NonJavaKeyStoreImpl extends 
AbstractKeyStore<NonJavaKeyStoreImpl> i
         final Collection<Certificate> certificates = _certificates;
         return certificates == null ? List.of() : certificates;
     }
+
+    @Override
+    public List<CertificateDetails> 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 class SSLUtil
         };
     }
 
-    public static Map<String, Certificate> getCertificates(final KeyStore ks) 
throws KeyStoreException
+    public static Map<String, Certificate> getCertificates(final KeyStore ks, 
final boolean keyCertificates) throws KeyStoreException
     {
         final Map<String ,Certificate> certificates = new HashMap<>();
         final Enumeration<String> 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> 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<String, Object> 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<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -81,7 +81,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreWithAliasFromFile_Success() throws Exception
+    void testCreateKeyStoreWithAliasFromFile_Success() throws Exception
     {
         final Path keyStoreFile = 
TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -97,7 +97,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreFromFile_WrongPassword() throws Exception
+    void testCreateKeyStoreFromFile_WrongPassword() throws Exception
     {
         final Path keyStoreFile = 
TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -109,7 +109,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @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 class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreFromFile_NonKeyAlias() throws Exception
+    void testCreateKeyStoreFromFile_NonKeyAlias() throws Exception
     {
         final Path keyStoreFile = 
TLS_RESOURCE.createSelfSignedTrustStore(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -138,7 +138,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreFromDataUrl_Success() throws Exception
+    void testCreateKeyStoreFromDataUrl_Success() throws Exception
     {
         final String keyStoreAsDataUrl = 
TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -153,7 +153,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreWithAliasFromDataUrl_Success() throws 
Exception
+    void testCreateKeyStoreWithAliasFromDataUrl_Success() throws Exception
     {
         final String keyStoreAsDataUrl = 
TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -169,7 +169,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreFromDataUrl_WrongPassword() throws Exception
+    void testCreateKeyStoreFromDataUrl_WrongPassword() throws Exception
     {
         final String keyStoreAsDataUrl = 
TLS_RESOURCE.createSelfSignedKeyStoreAsDataUrl(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -181,7 +181,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testCreateKeyStoreFromDataUrl_BadKeystoreBytes()
+    void testCreateKeyStoreFromDataUrl_BadKeystoreBytes()
     {
         final String keyStoreAsDataUrl = 
DataUrlUtils.getDataUrlForBytes("notatruststore".getBytes());
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -193,7 +193,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @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 class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testEmptyKeystoreRejected() throws Exception
+    void testEmptyKeystoreRejected() throws Exception
     {
         final Path keyStoreFile = TLS_RESOURCE.createKeyStore();
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -220,7 +220,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testKeystoreWithNoPrivateKeyRejected() throws Exception
+    void testKeystoreWithNoPrivateKeyRejected() throws Exception
     {
         final Path keyStoreFile = 
TLS_RESOURCE.createSelfSignedTrustStore(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, 
getTestName(),
@@ -233,7 +233,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @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 class FileKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testUpdateKeyStore_Success() throws Exception
+    void testUpdateKeyStore_Success() throws Exception
     {
         final Path keyStoreFile = 
TLS_RESOURCE.createSelfSignedKeyStore(DN_FOO);
         final Map<String, Object> attributes = Map.of(FileKeyStore.NAME, NAME,
@@ -276,7 +276,7 @@ public class FileKeyStoreTest extends UnitTestBase
     }
 
     @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 class FileKeyStoreTest extends UnitTestBase
         assertEquals(DN_BAR, certificate2.getIssuerName());
     }
 
+    @Test
+    void privateKeyEntryCertificate() throws Exception
+    {
+        final Path keyStoreFile = 
TLS_RESOURCE.createSelfSignedKeyStoreWithCertificate(DN_FOO);
+        final Map<String, Object> 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> 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<String, Object> 
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.assertThrows;
 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.CertificateExpiredException;
 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 class FileTrustStoreTest extends UnitTestBase
         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 class FileTrustStoreTest extends UnitTestBase
         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 @@ public class FileTrustStoreTest extends UnitTestBase
         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<String> 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 @@ package org.apache.qpid.server.security;
 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 class KeyStoreTestHelper
         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<String> 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.CertificateEncodingException;
 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 class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @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 class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @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 @@ public class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @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 class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @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 class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @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 @@ public class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void 
testCreationOfKeyStoreWithNonMatchingPrivateKeyAndCertificate()throws Exception
+    void testCreationOfKeyStoreWithNonMatchingPrivateKeyAndCertificate()throws 
Exception
     {
         final KeyCertificatePair keyCertPair2 = 
generateSelfSignedCertificate();
         final Map<String,Object> attributes = Map.of(NonJavaKeyStore.NAME, 
NAME,
@@ -192,7 +193,7 @@ public class NonJavaKeyStoreTest extends UnitTestBase
     }
 
     @Test
-    public void testUpdateKeyStoreToNonMatchingCertificate()throws Exception
+    void testUpdateKeyStoreToNonMatchingCertificate()throws Exception
     {
         final Map<String,Object> attributes = Map.of(NonJavaKeyStore.NAME, 
getTestName(),
                 NonJavaKeyStore.PRIVATE_KEY_URL, 
getPrivateKeyAsDataUrl(_keyCertPair.getPrivateKey()),
@@ -201,12 +202,25 @@ public class NonJavaKeyStoreTest extends UnitTestBase
         final KeyStore<?> trustStore = createTestKeyStore(attributes);
         final KeyCertificatePair keyCertPair2 = 
generateSelfSignedCertificate();
         final String certUrl = 
getCertificateAsDataUrl(keyCertPair2.getCertificate());
+        final Map<String,Object> 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<String,Object> 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> certificateDetails = 
keyStore.getCertificateDetails();
+
+        assertEquals(1, certificateDetails.size(), "Unexpected number of 
certificates");
+    }
+
     @SuppressWarnings("unchecked")
     private KeyStore<?> createTestKeyStore(final Map<String, Object> 
attributes)
     {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to