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]