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/server/tools/InstallDSArgumentParser.java |   65 ++++++++++++++++++++++++++++++++
 1 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDSArgumentParser.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDSArgumentParser.java
index f46da3c..f406843 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDSArgumentParser.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDSArgumentParser.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2008-2010 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.server.tools;
 
@@ -20,6 +21,7 @@
 import static com.forgerock.opendj.cli.CliMessages.INFO_JMXPORT_PLACEHOLDER;
 import static com.forgerock.opendj.cli.CliMessages.INFO_KEYSTORE_PWD_FILE_PLACEHOLDER;
 import static com.forgerock.opendj.cli.CliMessages.INFO_NUM_ENTRIES_PLACEHOLDER;
+import static com.forgerock.opendj.cli.CliMessages.INFO_PATH_PLACEHOLDER;
 import static com.forgerock.opendj.cli.CliMessages.INFO_PORT_PLACEHOLDER;
 import static com.forgerock.opendj.cli.CliMessages.INFO_ROOT_USER_PWD_FILE_PLACEHOLDER;
 import static com.forgerock.opendj.cli.CommonArguments.*;
@@ -28,6 +30,7 @@
 
 import static org.opends.messages.ToolMessages.*;
 
+import java.io.File;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -94,6 +97,8 @@
   StringArgument    directoryManagerDNArg;
   private StringArgument directoryManagerPwdStringArg;
   StringArgument    useJavaKeyStoreArg;
+  BooleanArgument   useKeyStoreForReplicationArg;
+  StringArgument    replicationCaCertFileArg;
   StringArgument    useJCEKSArg;
   StringArgument    usePkcs12Arg;
   private StringArgument keyStorePasswordArg;
@@ -396,6 +401,20 @@
                     .buildArgument();
     addDefaultArgument(certNicknameArg);
 
+    useKeyStoreForReplicationArg =
+            BooleanArgument.builder("useKeyStoreForReplication")
+                    .description(INFO_INSTALLDS_DESCRIPTION_USE_KEYSTORE_FOR_REPLICATION.get())
+                    .buildArgument();
+    addArgument(useKeyStoreForReplicationArg);
+
+    replicationCaCertFileArg =
+            StringArgument.builder("replicationCaCertFile")
+                    .description(INFO_INSTALLDS_DESCRIPTION_REPLICATION_CA_CERT_FILE.get())
+                    .multiValued()
+                    .valuePlaceholder(INFO_PATH_PLACEHOLDER.get())
+                    .buildArgument();
+    addArgument(replicationCaCertFileArg);
+
     connectTimeoutArg = connectTimeOutArgument();
     addArgument(connectTimeoutArg);
 
@@ -658,6 +677,52 @@
             enableStartTLSArg.getLongIdentifier()));
       }
     }
+
+    checkReplicationCertificateArguments(errorMessages);
+  }
+
+  /**
+   * Checks the arguments which provision the trust store used for server to server
+   * communication.  The key pair presented on the replication port is copied out of an
+   * existing key store, so there has to be one, and its private key has to be readable:
+   * neither a certificate generated by the installer nor a key held in a PKCS#11 token
+   * qualifies.
+   * @param errorMessages the list of messages to which we add the error messages
+   * describing the problems encountered during the execution of the checking.
+   */
+  private void checkReplicationCertificateArguments(Collection<LocalizableMessage> errorMessages)
+  {
+    if (useKeyStoreForReplicationArg.isPresent()
+        && !useJavaKeyStoreArg.isPresent()
+        && !useJCEKSArg.isPresent()
+        && !usePkcs12Arg.isPresent()
+        && !useBcfksArg.isPresent())
+    {
+      errorMessages.add(ERR_INSTALLDS_REPLICATION_KEYSTORE_REQUIRED.get(
+          useKeyStoreForReplicationArg.getLongIdentifier(),
+          useJavaKeyStoreArg.getLongIdentifier(),
+          useJCEKSArg.getLongIdentifier(),
+          usePkcs12Arg.getLongIdentifier(),
+          useBcfksArg.getLongIdentifier()));
+    }
+
+    if (replicationCaCertFileArg.isPresent())
+    {
+      if (!useKeyStoreForReplicationArg.isPresent())
+      {
+        errorMessages.add(ERR_INSTALLDS_REPLICATION_CA_CERT_FILE_REQUIRES.get(
+            replicationCaCertFileArg.getLongIdentifier(),
+            useKeyStoreForReplicationArg.getLongIdentifier()));
+      }
+      for (String path : replicationCaCertFileArg.getValues())
+      {
+        final File certFile = new File(path);
+        if (!certFile.exists() || !certFile.isFile())
+        {
+          errorMessages.add(ERR_INSTALLDS_REPLICATION_CA_CERT_FILE_INVALID.get(path));
+        }
+      }
+    }
   }
 
   /**

--
Gitblit v1.10.0