From e333af0c8fbb8d69d79f420de01ce39dcade5930 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Thu, 24 Sep 2026 08:06:21 +0000
Subject: [PATCH] Keep PKCS5S2 usable on a FIPS-restricted JCE, and name the key wrapping property when the runtime has no RSA-OAEP (#1058)

---
 opendj-server-legacy/src/main/java/org/opends/server/tools/ConfigureDS.java |  130 +++++++++++++++++++++++++++++++++----------
 1 files changed, 99 insertions(+), 31 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/ConfigureDS.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/ConfigureDS.java
index 02efe2c..8df0c77 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/ConfigureDS.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/ConfigureDS.java
@@ -1208,45 +1208,36 @@
    */
   private void updateCryptoCipher() throws ConfigureDSException
   {
-    final CryptoManagerCfgDefn cryptoManager = CryptoManagerCfgDefn.getInstance();
-    final StringPropertyDefinition prop = cryptoManager.getKeyWrappingTransformationPropertyDefinition();
-    String defaultCipher = null;
-
-    final DefaultBehaviorProvider<?> p = prop.getDefaultBehaviorProvider();
-    if (p instanceof DefinedDefaultBehaviorProvider)
-    {
-      final Collection<?> defaultValues = ((DefinedDefaultBehaviorProvider<?>) p).getDefaultValues();
-      if (!defaultValues.isEmpty())
-      {
-        defaultCipher = defaultValues.iterator().next().toString();
-      }
-    }
-
+    final String defaultCipher = defaultKeyWrappingTransformation();
     if (defaultCipher != null)
     {
-      // Check that the default cipher is supported by the JVM.
+      final String cipher;
       try
       {
-        Cipher.getInstance(defaultCipher);
+        cipher = supportedKeyWrappingTransformation(defaultCipher);
       }
       catch (final GeneralSecurityException ex)
       {
-        // The cipher is not supported: try to find an alternative one.
-        final String alternativeCipher = getAlternativeCipher();
-        if (alternativeCipher != null)
+        // The default stays, and the server will refuse to start with it: there is no secure
+        // transformation to fall back to (#776), so the administrator has to choose one. Under
+        // setup this stream reaches the setup log only, and the installer gives the warning
+        // itself (see unsupportedKeyWrappingTransformationWarning()).
+        printWrappedText(err, unsupportedKeyWrappingTransformationWarning(defaultCipher, ex));
+        return;
+      }
+      if (!cipher.equals(defaultCipher))
+      {
+        try
         {
-          try
-          {
-            updateConfigEntryWithAttribute(
-                DN_CRYPTO_MANAGER,
-                ATTR_CRYPTO_CIPHER_KEY_WRAPPING_TRANSFORMATION,
-                CoreSchema.getDirectoryStringSyntax(),
-                alternativeCipher);
-          }
-          catch (final Exception e)
-          {
-            throw new ConfigureDSException(e, ERR_CONFIGDS_CANNOT_UPDATE_CRYPTO_MANAGER.get(e));
-          }
+          updateConfigEntryWithAttribute(
+              DN_CRYPTO_MANAGER,
+              ATTR_CRYPTO_CIPHER_KEY_WRAPPING_TRANSFORMATION,
+              CoreSchema.getDirectoryStringSyntax(),
+              cipher);
+        }
+        catch (final Exception e)
+        {
+          throw new ConfigureDSException(e, ERR_CONFIGDS_CANNOT_UPDATE_CRYPTO_MANAGER.get(e));
         }
       }
     }
@@ -1327,6 +1318,83 @@
   }
 
   /**
+   * Returns the warning to give when this Java runtime supports neither the default key wrapping
+   * transformation of the crypto manager nor an alternative to it: the server will then refuse to
+   * start until the administrator sets one. The installer calls this itself, since what
+   * {@code configMain} writes while it runs under setup reaches the setup log only.
+   *
+   * @return The warning, or {@code null} when the runtime supports a transformation.
+   */
+  public static LocalizableMessage unsupportedKeyWrappingTransformationWarning()
+  {
+    final String defaultCipher = defaultKeyWrappingTransformation();
+    if (defaultCipher == null)
+    {
+      return null;
+    }
+    try
+    {
+      supportedKeyWrappingTransformation(defaultCipher);
+      return null;
+    }
+    catch (final GeneralSecurityException ex)
+    {
+      return unsupportedKeyWrappingTransformationWarning(defaultCipher, ex);
+    }
+  }
+
+  private static LocalizableMessage unsupportedKeyWrappingTransformationWarning(
+      final String defaultCipher, final GeneralSecurityException ex)
+  {
+    return WARN_CONFIGDS_KEY_WRAPPING_TRANSFORMATION_UNSUPPORTED.get(defaultCipher, ex.getMessage());
+  }
+
+  /** Returns the default key wrapping transformation of the crypto manager, or {@code null}. */
+  private static String defaultKeyWrappingTransformation()
+  {
+    final StringPropertyDefinition prop =
+        CryptoManagerCfgDefn.getInstance().getKeyWrappingTransformationPropertyDefinition();
+    final DefaultBehaviorProvider<?> p = prop.getDefaultBehaviorProvider();
+    if (p instanceof DefinedDefaultBehaviorProvider)
+    {
+      final Collection<?> defaultValues = ((DefinedDefaultBehaviorProvider<?>) p).getDefaultValues();
+      if (!defaultValues.isEmpty())
+      {
+        return defaultValues.iterator().next().toString();
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns the key wrapping transformation this Java runtime supports: the default one when it
+   * does, otherwise the OAEP alternative of {@link #getAlternativeCipher()}.
+   *
+   * @param defaultCipher
+   *          The default key wrapping transformation of the crypto manager.
+   * @return The transformation to configure.
+   * @throws GeneralSecurityException
+   *           If the runtime supports neither, with the reason the default one is not.
+   */
+  static String supportedKeyWrappingTransformation(final String defaultCipher) throws GeneralSecurityException
+  {
+    try
+    {
+      Cipher.getInstance(defaultCipher);
+      return defaultCipher;
+    }
+    catch (final GeneralSecurityException ex)
+    {
+      final String alternativeCipher = getAlternativeCipher();
+      if (alternativeCipher == null)
+      {
+        throw ex;
+      }
+      return alternativeCipher;
+    }
+  }
+
+  /**
    * Returns a cipher that is supported by the JVM we are running at.
    * Returns <CODE>null</CODE> if no alternative cipher could be found.
    * @return a cipher that is supported by the JVM we are running at.

--
Gitblit v1.10.0