From 70d9a179cdd8d975b44e1815c249e20d9f91097f Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 16 Sep 2026 08:10:15 +0000
Subject: [PATCH] [#912] Provision the ads-truststore from an existing key store at setup time (#984)
---
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java | 94 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java b/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java
index 661af28..91a495e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java
@@ -1214,19 +1214,27 @@
*/
private void configureServer() throws ApplicationException
{
- notifyListeners(getFormattedWithPoints(INFO_PROGRESS_CONFIGURING.get()));
copyTemplateInstance();
writeOpenDSJavaHome();
writeHostName();
checkAbort();
+ final SecurityOptions sec = getUserData().getSecurityOptions();
+ if (sec.getReplicationUsesKeyStore())
+ {
+ // Before the configuration and the certificates are written: the provisioning
+ // refuses key stores and certificate files it cannot use, and a refusal then
+ // leaves the configuration as the template had it.
+ provisionAdsTrustStore(sec);
+ }
+
+ notifyListeners(getFormattedWithPoints(INFO_PROGRESS_CONFIGURING.get()));
List<String> argList = CollectionUtils.newArrayList(
"-c", getConfigurationFile(),
"-h", getUserData().getHostName(),
"-p", String.valueOf(getUserData().getServerPort()),
"--adminConnectorPort", String.valueOf(getUserData().getAdminConnectorPort()));
- final SecurityOptions sec = getUserData().getSecurityOptions();
// TODO: even if the user does not configure SSL maybe we should choose
// a secure port that is not being used and that we can actually use.
if (sec.getEnableSSL())
@@ -1241,6 +1249,7 @@
}
addCertificateArguments(sec, argList);
+ addAdsCertificateArguments(sec, argList);
// For the moment do not enable JMX
if (getUserData().getServerJMXPort() > 0)
{
@@ -1341,6 +1350,47 @@
configureCertificate(sec);
}
+ /**
+ * Provisions the trust store used for server to server communication from the key store
+ * the server certificate comes from. Replication reads both the key pair it presents on
+ * its port and the certificates it trusts there from that trust store, and from nowhere
+ * else, so the key pair has to be copied into it while the server is stopped: the
+ * nickname to present is read once, when the crypto manager is created at startup.
+ *
+ * @param sec
+ * the security options holding the key store to provision the trust store from.
+ * @throws ApplicationException
+ * if the trust store cannot be provisioned.
+ */
+ private void provisionAdsTrustStore(SecurityOptions sec) throws ApplicationException
+ {
+ notifyListeners(getFormattedWithPoints(INFO_PROGRESS_UPDATING_ADS_TRUSTSTORE.get()));
+ final CertificateManager keyStore = new CertificateManager(
+ sec.getKeystorePath(), keyStoreTypeOf(sec), sec.getKeystorePassword());
+ new AdsTrustStoreProvisioner(getAdsTrustStorePath(), getAdsTrustStorePinPath())
+ .provision(keyStore, sec.getAliasesToUse(), sec.getReplicationCaCertFiles());
+ notifyListeners(getFormattedDoneWithLineBreak());
+ }
+
+ /** Returns the key store type of the provided security options, as CertificateManager names it. */
+ private static String keyStoreTypeOf(SecurityOptions sec)
+ {
+ switch (sec.getCertificateType())
+ {
+ case JKS:
+ return CertificateManager.KEY_STORE_TYPE_JKS;
+ case JCEKS:
+ return CertificateManager.KEY_STORE_TYPE_JCEKS;
+ case PKCS12:
+ return CertificateManager.KEY_STORE_TYPE_PKCS12;
+ case BCFKS:
+ return CertificateManager.KEY_STORE_TYPE_BCFKS;
+ default:
+ throw new IllegalStateException(
+ "No key store to read a key pair from: " + sec.getCertificateType());
+ }
+ }
+
private void configureCertificate(SecurityOptions sec) throws ApplicationException
{
try
@@ -1545,6 +1595,24 @@
}
}
+ /**
+ * Adds the certificate nicknames the crypto manager is to present on the replication
+ * port. The property is read once, when the crypto manager is created, so it is written
+ * to the configuration before the server is started for the first time rather than set
+ * with dsconfig afterwards.
+ */
+ private static void addAdsCertificateArguments(SecurityOptions sec, List<String> argList)
+ {
+ if (sec.getReplicationUsesKeyStore())
+ {
+ for (String alias : sec.getAliasesToUse())
+ {
+ argList.add("--adsCertNickName");
+ argList.add(alias);
+ }
+ }
+ }
+
private static void addCertificateArguments(List<String> argList, SecurityOptions sec,
Collection<String> aliasesInKeyStore, String keyStoreDN, String trustStoreDN)
{
@@ -4122,6 +4190,28 @@
return getPath2("keystore.pin");
}
+ /**
+ * Returns the path of the trust store used for server to server communication, the one
+ * the replication port reads its key pair and its trusted certificates from.
+ *
+ * @return the path of the ads-truststore.
+ */
+ private String getAdsTrustStorePath()
+ {
+ return getPath2("ads-truststore");
+ }
+
+ /**
+ * Returns the path of the file holding the PIN of the trust store used for server to
+ * server communication.
+ *
+ * @return the path of the ads-truststore PIN file.
+ */
+ private String getAdsTrustStorePinPath()
+ {
+ return getPath2("ads-truststore.pin");
+ }
+
private String getPath2(String relativePath)
{
String parentFile = getPath(getInstancePath(), Installation.CONFIG_PATH_RELATIVE);
--
Gitblit v1.10.0