[Git][java-team/libscram-java][upstream] New upstream version 3.4

Christoph Berg (@myon) gitlab at salsa.debian.org
Sat Jun 13 13:34:30 BST 2026



Christoph Berg pushed to branch upstream at Debian Java Maintainers / libscram-java


Commits:
61a3d411 by Christoph Berg at 2026-06-13T14:33:21+02:00
New upstream version 3.4
- - - - -


25 changed files:

- .github/workflows/codeql.yml
- .github/workflows/maven.yml
- .github/workflows/scorecard.yml
- CHANGELOG.md
- checks/pmd-ruleset.xml
- coverage-report/pom.xml
- pom.xml
- scram-client/pom.xml
- scram-client/src/it/jpms-scram-client/pom.xml
- scram-client/src/main/java/com/ongres/scram/client/ClientFinalProcessor.java
- scram-client/src/main/java/com/ongres/scram/client/ScramClient.java
- scram-client/src/main/java/com/ongres/scram/client/ServerFirstProcessor.java
- scram-client/src/test/java/com/example/ChannelBindingNegotiationTest.java
- scram-client/src/test/java/com/example/ScramClientTest.java
- scram-client/src/test/java/com/ongres/scram/client/ScramBuilderTest.java
- scram-common/pom.xml
- scram-common/src/main/java/com/ongres/scram/common/CryptoUtil.java
- scram-common/src/main/java/com/ongres/scram/common/util/TlsServerEndpoint.java
- scram-common/src/test/java/com/ongres/scram/common/HiFunctionTest.java
- scram-common/src/test/java/com/ongres/scram/common/ScramFunctionsTest.java
- scram-common/src/test/java/com/ongres/scram/common/util/TlsServerEndpointTest.java
- + scram-common/src/test/resources/SHA224withRSA.pem
- + scram-common/src/test/resources/SHA512_224withRSA.pem
- + scram-common/src/test/resources/SHA512_256withRSA.pem
- scram-parent/pom.xml


Changes:

=====================================
.github/workflows/codeql.yml
=====================================
@@ -39,7 +39,7 @@ jobs:
           build-mode: manual # This mode only analyzes Java. Set this to 'autobuild' or 'manual' to analyze Kotlin too.
     steps:
     - name: Checkout repository
-      uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+      uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL


=====================================
.github/workflows/maven.yml
=====================================
@@ -16,7 +16,7 @@ jobs:
   build:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+    - uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
     - name: Set up JDK 21
       uses: actions/setup-java at be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
       with:
@@ -32,6 +32,6 @@ jobs:
     permissions:
       contents: write #required for POST snapshot API https://docs.github.com/en/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository
     steps:
-      - uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+      - uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
       - name: Update dependency graph
         uses: advanced-security/maven-dependency-submission-action at b275d12641ac2d2108b2cbb7598b154ad2f2cee8


=====================================
.github/workflows/scorecard.yml
=====================================
@@ -34,7 +34,7 @@ jobs:
 
     steps:
       - name: "Checkout code"
-        uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
         with:
           persist-credentials: false
 


=====================================
CHANGELOG.md
=====================================
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
 
 ## [Unreleased]
 
+## [3.4] - 2026-06-10
+
+### :bug: Bug Fixes
+
+- Resolve regression when passing pre-computed keys `.clientAndServerKey(clientKey, serverKey)`.
+
+### :rocket: New features
+
+- Introduces a static OID-to-Digest mapping table for `TlsServerEndpoint` to guarantee resolution when friendly algorithm names are unavailable or provider-specific.
+
 ## [3.3] - 2026-06-04
 
 ### :lock: Security
@@ -80,4 +90,5 @@ All notable changes to this project will be documented in this file.
 [3.1]: https://github.com/ongres/scram/compare/3.0...3.1
 [3.2]: https://github.com/ongres/scram/compare/3.1...3.2
 [3.3]: https://github.com/ongres/scram/compare/3.2...3.3
-[Unreleased]: https://github.com/ongres/scram/compare/3.3...main
+[3.4]: https://github.com/ongres/scram/compare/3.4...3.4
+[Unreleased]: https://github.com/ongres/scram/compare/3.4...main


=====================================
checks/pmd-ruleset.xml
=====================================
@@ -16,6 +16,7 @@
     <exclude name="AvoidReassigningLoopVariables" />
     <exclude name="AccessorClassGeneration" />
     <exclude name="ImplicitFunctionalInterface" />
+    <exclude name="AvoidUsingHardCodedIP" />
   </rule>
 
   <rule ref="category/java/errorprone.xml">
@@ -24,6 +25,12 @@
     <exclude name="AvoidFieldNameMatchingMethodName" />
   </rule>
 
+  <rule ref="category/java/errorprone.xml/AvoidDuplicateLiterals">
+    <properties>
+      <property name="maxDuplicateLiterals" value="6" />
+    </properties>
+  </rule>
+
   <rule ref="category/java/errorprone.xml/AssignmentInOperand">
     <properties>
       <property name="allowIncrementDecrement" value="true" />


=====================================
coverage-report/pom.xml
=====================================
@@ -5,7 +5,7 @@
   <parent>
     <groupId>com.ongres.scram</groupId>
     <artifactId>scram-parent</artifactId>
-    <version>3.3</version>
+    <version>3.4</version>
     <relativePath>../scram-parent/pom.xml</relativePath>
   </parent>
 


=====================================
pom.xml
=====================================
@@ -5,7 +5,7 @@
   <parent>
     <groupId>com.ongres.scram</groupId>
     <artifactId>scram-parent</artifactId>
-    <version>3.3</version>
+    <version>3.4</version>
     <relativePath>scram-parent/pom.xml</relativePath>
   </parent>
 


=====================================
scram-client/pom.xml
=====================================
@@ -5,7 +5,7 @@
   <parent>
     <groupId>com.ongres.scram</groupId>
     <artifactId>scram-parent</artifactId>
-    <version>3.3</version>
+    <version>3.4</version>
     <relativePath>../scram-parent/pom.xml</relativePath>
   </parent>
 


=====================================
scram-client/src/it/jpms-scram-client/pom.xml
=====================================
@@ -7,7 +7,7 @@
   <groupId>com.ongres.scram.it</groupId>
   <artifactId>jpms-scram-client</artifactId>
   <name>JPMS Scram Client</name>
-  <version>3.3</version>
+  <version>3.4</version>
 
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>


=====================================
scram-client/src/main/java/com/ongres/scram/client/ClientFinalProcessor.java
=====================================
@@ -8,6 +8,8 @@ package com.ongres.scram.client;
 import static com.ongres.scram.common.util.Preconditions.checkNotEmpty;
 import static com.ongres.scram.common.util.Preconditions.checkNotNull;
 
+import java.util.Arrays;
+
 import com.ongres.scram.common.ClientFinalMessage;
 import com.ongres.scram.common.ClientFirstMessage;
 import com.ongres.scram.common.ScramFunctions;
@@ -39,6 +41,9 @@ final class ClientFinalProcessor {
   private final ServerFirstMessage serverFirstMessage;
   private String authMessage;
 
+  /**
+   * Primary constructor utilizing pre-computed cryptographic keys.
+   */
   private ClientFinalProcessor(ScramMechanism scramMechanism, byte[] clientKey,
       byte[] storedKey, byte[] serverKey, ClientFirstMessage clientFirstMessage,
       ServerFirstMessage serverFirstMessage) {
@@ -50,12 +55,31 @@ final class ClientFinalProcessor {
     this.serverFirstMessage = serverFirstMessage;
   }
 
+  /**
+   * Constructs a processor using pre-computed Client and Server keys.
+   * The Stored Key is automatically derived.
+   *
+   * @param scramMechanism The SCRAM mechanism.
+   * @param clientKey The pre-computed client key material.
+   * @param serverKey The pre-computed server key material.
+   * @param clientFirstMessage The client-first-message contextual state.
+   * @param serverFirstMessage The server-first-message contextual state.
+   */
   ClientFinalProcessor(ScramMechanism scramMechanism, byte[] clientKey, byte[] serverKey,
       ClientFirstMessage clientFirstMessage, ServerFirstMessage serverFirstMessage) {
-    this(scramMechanism, clientKey, ScramFunctions.storedKey(scramMechanism, clientKey),
-        serverKey, clientFirstMessage, serverFirstMessage);
+    this(scramMechanism, clientKey.clone(), ScramFunctions.storedKey(scramMechanism, clientKey),
+        serverKey.clone(), clientFirstMessage, serverFirstMessage);
   }
 
+  /**
+   * Constructs a processor using a pre-computed salted password.
+   * Client, Server, and Stored keys are derived directly from the salted password.
+   *
+   * @param scramMechanism The SCRAM mechanism.
+   * @param saltedPassword The pre-computed salted password material.
+   * @param clientFirstMessage The client-first-message contextual state.
+   * @param serverFirstMessage The server-first-message contextual state.
+   */
   ClientFinalProcessor(ScramMechanism scramMechanism, byte[] saltedPassword,
       ClientFirstMessage clientFirstMessage, ServerFirstMessage serverFirstMessage) {
     this(
@@ -65,15 +89,40 @@ final class ClientFinalProcessor {
         clientFirstMessage, serverFirstMessage);
   }
 
+  /**
+   * Constructs a processor from raw credentials, performing PBKDF2 salt derivation.
+   *
+   * @param scramMechanism The SCRAM mechanism.
+   * @param stringPreparation The SASLprep normalization configuration rules.
+   * @param password The cleartext password array.
+   * @param salt The salt bytes received from the server.
+   * @param clientFirstMessage The client-first-message contextual state.
+   * @param serverFirstMessage The server-first-message contextual state.
+   */
   ClientFinalProcessor(ScramMechanism scramMechanism, StringPreparation stringPreparation,
       char[] password, byte[] salt, ClientFirstMessage clientFirstMessage,
       ServerFirstMessage serverFirstMessage) {
-    this(scramMechanism,
-        ScramFunctions.saltedPassword(scramMechanism, stringPreparation, password, salt,
-            serverFirstMessage.getIterationCount()),
-        clientFirstMessage, serverFirstMessage);
+    this.scramMechanism = scramMechanism;
+    this.clientFirstMessage = clientFirstMessage;
+    this.serverFirstMessage = serverFirstMessage;
+
+    byte[] saltedPassword = ScramFunctions.saltedPassword(
+        scramMechanism, stringPreparation, password, salt, serverFirstMessage.getIterationCount());
+    try {
+      this.clientKey = ScramFunctions.clientKey(scramMechanism, saltedPassword);
+      this.serverKey = ScramFunctions.serverKey(scramMechanism, saltedPassword);
+      this.storedKey = ScramFunctions.storedKey(scramMechanism, this.clientKey);
+    } finally {
+      // Wipe saltedPassword immediately
+      Arrays.fill(saltedPassword, (byte) 0);
+    }
   }
 
+  /**
+   * Generates and caches the authMessage metadata string required for signing logic if not already present.
+   *
+   * @param cbindData The channel binding payload data bytes.
+   */
   private void generateAndCacheAuthMessage(byte[] cbindData) {
     if (null == this.authMessage) {
       this.authMessage = ScramFunctions.authMessage(clientFirstMessage, serverFirstMessage, cbindData);
@@ -84,8 +133,8 @@ final class ClientFinalProcessor {
    * Generates the SCRAM representation of the client-final-message, including the given
    * channel-binding data.
    *
-   * @param cbindData The bytes of the channel-binding data
-   * @return The message
+   * @param cbindData The bytes of the channel-binding data, or null if no channel binding is utilized.
+   * @return The constructed ClientFinalMessage object.
    */
   @NotNull
   ClientFinalMessage clientFinalMessage(byte @Nullable [] cbindData) {
@@ -101,27 +150,36 @@ final class ClientFinalProcessor {
   }
 
   /**
-   * Receive and process the server-final-message. Server SCRAM signatures is verified.
+   * Receive and process the server-final-message. The server's signature is explicitly verified.
    *
-   * @param serverFinalMessage The received server-final-message
-   * @throws ScramParseException If the message is not a valid server-final-message
-   * @throws ScramServerErrorException If the server-final-message contained an error
-   * @throws ScramInvalidServerSignatureException If the server signature is invalid
-   * @throws IllegalArgumentException If the message is null or empty
+   * @param serverFinalMessage The received raw server-final-message text line string.
+   * @return The parsed and validated ServerFinalMessage instance representation.
+   * @throws ScramParseException If the string composition fails structure parsing rules.
+   * @throws ScramServerErrorException If the server-final-message contains an error attribute message.
+   * @throws ScramInvalidServerSignatureException If the verified computed signature fails validation matches.
+   * @throws IllegalArgumentException If the input parameter message value evaluates null or empty.
    */
   @NotNull
   ServerFinalMessage receiveServerFinalMessage(@NotNull String serverFinalMessage)
       throws ScramParseException, ScramServerErrorException, ScramInvalidServerSignatureException {
     checkNotEmpty(serverFinalMessage, "serverFinalMessage");
 
-    ServerFinalMessage message = ServerFinalMessage.parseFrom(serverFinalMessage);
-    if (message.isError()) {
-      throw new ScramServerErrorException(message.getServerError());
+    try {
+      ServerFinalMessage message = ServerFinalMessage.parseFrom(serverFinalMessage);
+      if (message.isError()) {
+        throw new ScramServerErrorException(message.getServerError());
+      }
+      if (!ScramFunctions.verifyServerSignature(
+          scramMechanism, serverKey, authMessage, message.getVerifier())) {
+        throw new ScramInvalidServerSignatureException("Invalid SCRAM server signature");
+      }
+      return message;
+    } finally {
+      // Wipe the sensitive data, even if an exception was thrown above
+      Arrays.fill(clientKey, (byte) 0);
+      Arrays.fill(storedKey, (byte) 0);
+      Arrays.fill(serverKey, (byte) 0);
     }
-    if (!ScramFunctions.verifyServerSignature(
-        scramMechanism, serverKey, authMessage, message.getVerifier())) {
-      throw new ScramInvalidServerSignatureException("Invalid SCRAM server signature");
-    }
-    return message;
   }
+
 }


=====================================
scram-client/src/main/java/com/ongres/scram/client/ScramClient.java
=====================================
@@ -13,6 +13,7 @@ import static com.ongres.scram.common.util.Preconditions.gt0;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.SecureRandom;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.function.Supplier;
@@ -486,7 +487,7 @@ public final class ScramClient implements MessageFlow {
         @NotNull Collection<@NotNull String> scramMechanisms) {
       checkNotNull(scramMechanisms, "scramMechanisms");
       checkArgument(!scramMechanisms.isEmpty(), "scramMechanisms");
-      this.scramMechanisms = scramMechanisms;
+      this.scramMechanisms = new ArrayList<>(scramMechanisms);
       return this;
     }
 
@@ -582,8 +583,8 @@ public final class ScramClient implements MessageFlow {
      * This method classifies SCRAM mechanisms by two properties: whether they support channel
      * binding; and a priority, which is higher for safer algorithms (like SHA-256 vs SHA-1).
      *
-     * @param channelBinding True to select {@code -PLUS} mechanisms.
      * @param scramMechanisms The mechanisms supported by the other peer
+     * @param channelBinding True to select {@code -PLUS} mechanisms.
      * @return The selected mechanism, or null if no mechanism matched
      */
     private static @Nullable ScramMechanism selectMechanism(


=====================================
scram-client/src/main/java/com/ongres/scram/client/ServerFirstProcessor.java
=====================================
@@ -7,7 +7,6 @@ package com.ongres.scram.client;
 
 import static com.ongres.scram.common.util.Preconditions.checkNotEmpty;
 import static com.ongres.scram.common.util.Preconditions.checkNotNull;
-import static java.nio.charset.StandardCharsets.UTF_8;
 
 import java.util.Base64;
 
@@ -56,7 +55,7 @@ final class ServerFirstProcessor {
         scramMechanism,
         stringPreparation,
         checkNotEmpty(password, "password"),
-        Base64.getDecoder().decode(serverFirstMessage.getSalt().getBytes(UTF_8)),
+        Base64.getDecoder().decode(serverFirstMessage.getSalt()),
         clientFirstMessage,
         serverFirstMessage);
   }


=====================================
scram-client/src/test/java/com/example/ChannelBindingNegotiationTest.java
=====================================
@@ -20,7 +20,6 @@ import com.ongres.scram.client.ScramClient;
 import com.ongres.scram.common.ClientFirstMessage;
 import com.ongres.scram.common.Gs2CbindFlag;
 import com.ongres.scram.common.Gs2Header;
-import com.ongres.scram.common.exception.ScramRuntimeException;
 import com.ongres.scram.common.util.TlsServerEndpoint;
 import org.jetbrains.annotations.NotNull;
 import org.junit.jupiter.api.DisplayName;


=====================================
scram-client/src/test/java/com/example/ScramClientTest.java
=====================================
@@ -7,12 +7,18 @@ package com.example;
 
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.util.Arrays;
 import java.util.Base64;
 
 import com.ongres.scram.client.ScramClient;
 import com.ongres.scram.common.ClientFinalMessage;
+import com.ongres.scram.common.ScramFunctions;
+import com.ongres.scram.common.ScramMechanism;
+import com.ongres.scram.common.StringPreparation;
+import com.ongres.scram.common.exception.ScramInvalidServerSignatureException;
+import com.ongres.scram.common.exception.ScramServerErrorException;
 import com.ongres.scram.common.util.TlsServerEndpoint;
 import org.junit.jupiter.api.Test;
 
@@ -110,4 +116,90 @@ class ScramClientTest {
         () -> scramSession.serverFinalMessage("v=sz/isCwVSUn/TBWeYABz6WaoZIcfsui9NPaJCoxxAjY="));
   }
 
+  @Test
+  void preComputedKeysTest() throws Exception {
+    ScramMechanism mechanism = ScramMechanism.SCRAM_SHA_256;
+    byte[] salt = Base64.getDecoder().decode("W22ZaJ0SNY7soEsUEjb6gQ==");
+    int iterationCount = 4096;
+
+    // Pre-computed clientKey/serverKey
+    byte[] saltedPassword = ScramFunctions.saltedPassword(
+        mechanism, StringPreparation.SASL_PREPARATION, "pencil".toCharArray(), salt, iterationCount);
+    byte[] clientKey = ScramFunctions.clientKey(mechanism, saltedPassword);
+    byte[] serverKey = ScramFunctions.serverKey(mechanism, saltedPassword);
+
+    // Initialize the client utilizing the optimized pre-computed keys tracking option
+    ScramClient scramSession = ScramClient.builder()
+        .advertisedMechanisms(Arrays.asList("SCRAM-SHA-256"))
+        .username("user")
+        .clientAndServerKey(clientKey, serverKey)
+        .nonceSupplier(() -> "rOprNGfwEbeRWgbNEkqO")
+        .build();
+
+    // Verify step processing yields identical proofs and matches execution vectors exactly
+    assertEquals("SCRAM-SHA-256", scramSession.getScramMechanism().getName());
+    assertEquals("n,,n=user,r=rOprNGfwEbeRWgbNEkqO", scramSession.clientFirstMessage().toString());
+
+    assertDoesNotThrow(
+        () -> scramSession.serverFirstMessage(
+            "r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,"
+                + "s=W22ZaJ0SNY7soEsUEjb6gQ==,"
+                + "i=4096"));
+
+    ClientFinalMessage clientFinalMessage = scramSession.clientFinalMessage();
+    assertEquals(
+        "c=biws,r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0"
+            + ",p=dHzbZapWIk4jUhN+Ute9ytag9zjfMHgsqmmiz7AndVQ=",
+        clientFinalMessage.toString());
+
+    assertDoesNotThrow(
+        () -> scramSession.serverFinalMessage("v=6rriTRBi23WpRR/wtup+mMhUZUn/dB5nLTJRsjl95G4="));
+  }
+
+  @Test
+  void throwScramInvalidServerSignatureException() {
+    ScramClient scramSession = ScramClient.builder()
+        .advertisedMechanisms(Arrays.asList("SCRAM-SHA-256"))
+        .username("postgres")
+        .password("pencil".toCharArray())
+        .channelBinding(TlsServerEndpoint.TLS_SERVER_END_POINT, CBIND_DATA)
+        .nonceSupplier(() -> "1q^MGrWUi{etW+H7(#k431kB")
+        .build();
+    scramSession.clientFirstMessage();
+
+    assertDoesNotThrow(
+        () -> scramSession.serverFirstMessage(
+            "r=1q^MGrWUi{etW+H7(#k431kBdAr3CWX7B6houDP4f7Z2XEpZ,"
+                + "s=Fgh8JU2AlRjBHUsIU/GgtQ==,"
+                + "i=10"));
+    scramSession.clientFinalMessage();
+
+    // The server returns an ivalid signature
+    assertThrows(ScramInvalidServerSignatureException.class,
+        () -> scramSession.serverFinalMessage("v=Fgh8JU2AlRjBHUsIU/GgtQ=="));
+  }
+
+  @Test
+  void throwScramServerErrorException() {
+    ScramClient scramSession = ScramClient.builder()
+        .advertisedMechanisms(Arrays.asList("SCRAM-SHA-256", "SCRAM-SHA-512"))
+        .username("postgres")
+        .password("pencil".toCharArray())
+        .channelBinding(TlsServerEndpoint.TLS_SERVER_END_POINT, CBIND_DATA)
+        .nonceSupplier(() -> "1q^MGrWUi{etW+H7(#k431kB")
+        .build();
+
+    scramSession.clientFirstMessage();
+    assertDoesNotThrow(
+        () -> scramSession.serverFirstMessage(
+            "r=1q^MGrWUi{etW+H7(#k431kBdAr3CWX7B6houDP4f7Z2XEpZ,"
+                + "s=Fgh8JU2AlRjBHUsIU/GgtQ==,"
+                + "i=10"));
+    scramSession.clientFinalMessage();
+
+    // Simulate that the server returns an error
+    assertThrows(ScramServerErrorException.class,
+        () -> scramSession.serverFinalMessage("e=invalid-proof"));
+  }
+
 }


=====================================
scram-client/src/test/java/com/ongres/scram/client/ScramBuilderTest.java
=====================================
@@ -9,15 +9,18 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.Arrays;
 import java.util.Base64;
+import java.util.Collection;
+import java.util.Collections;
 
 import com.ongres.scram.common.ClientFinalMessage;
+import com.ongres.scram.common.ClientFirstMessage;
 import com.ongres.scram.common.ScramFunctions;
 import com.ongres.scram.common.ScramMechanism;
 import com.ongres.scram.common.StringPreparation;
-import com.ongres.scram.common.exception.ScramRuntimeException;
 import org.junit.jupiter.api.Test;
 
 class ScramBuilderTest {
@@ -137,4 +140,50 @@ class ScramBuilderTest {
     assertEquals("Either a bare or -PLUS mechanism must be present", assertThrows.getMessage());
   }
 
+  @Test
+  void testSecureRandomAlgorithmProvider() {
+    assertDoesNotThrow(() -> ScramClient.builder()
+        .advertisedMechanisms(Arrays.asList("SCRAM-SHA-256"))
+        .username("user")
+        .password("pencil".toCharArray())
+        .secureRandomAlgorithmProvider("DRBG", null)
+        .build());
+  }
+
+  @Test
+  void testSecureRandomAlgorithmProviderThrows() {
+    assertThrows(IllegalArgumentException.class, () -> ScramClient.builder()
+        .advertisedMechanisms(Arrays.asList("SCRAM-SHA-256"))
+        .username("user")
+        .password("pencil".toCharArray())
+        .secureRandomAlgorithmProvider("DRBG", "invalid")
+        .build());
+  }
+
+  @Test
+  void testEmptyMechanisms() {
+    IllegalArgumentException assertThrows = assertThrows(IllegalArgumentException.class,
+        () -> ScramClient.builder()
+            .advertisedMechanisms(Arrays.asList())
+            .username("user")
+            .password("pencil".toCharArray())
+            .build());
+
+    assertEquals("Argument 'scramMechanisms' is not valid", assertThrows.getMessage());
+  }
+
+  @Test
+  void testAuthzid() {
+    ScramClient scramClient = ScramClient.builder()
+        .advertisedMechanisms(Arrays.asList("SCRAM-SHA-256"))
+        .username("user")
+        .password("pencil".toCharArray())
+        .authzid("postgres")
+        .build();
+
+    ClientFirstMessage clientFirstMessage = scramClient.clientFirstMessage();
+    assertEquals("postgres", clientFirstMessage.getGs2Header().getAuthzid());
+    assertTrue(clientFirstMessage.toString().startsWith("n,a=postgres,n=user"));
+  }
+
 }


=====================================
scram-common/pom.xml
=====================================
@@ -5,7 +5,7 @@
   <parent>
     <groupId>com.ongres.scram</groupId>
     <artifactId>scram-parent</artifactId>
-    <version>3.3</version>
+    <version>3.4</version>
     <relativePath>../scram-parent/pom.xml</relativePath>
   </parent>
 


=====================================
scram-common/src/main/java/com/ongres/scram/common/CryptoUtil.java
=====================================
@@ -225,7 +225,10 @@ final class CryptoUtil {
    * @throws IllegalArgumentException if the saltSize is not positive, or if random is null
    */
   static byte @NotNull [] salt(int saltSize, @NotNull SecureRandom random) {
-    gt0(saltSize, "saltSize");
+    if (saltSize < 2) {
+      // Errata-ID: 2652
+      throw new IllegalArgumentException("'saltSize' must be at least 2, was: " + saltSize);
+    }
     checkNotNull(random, "random");
     byte[] randomSalt = new byte[saltSize];
     random.nextBytes(randomSalt);


=====================================
scram-common/src/main/java/com/ongres/scram/common/util/TlsServerEndpoint.java
=====================================
@@ -13,7 +13,11 @@ import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.security.spec.PSSParameterSpec;
+import java.util.Collections;
 import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.jetbrains.annotations.NotNull;
 
@@ -30,6 +34,51 @@ public final class TlsServerEndpoint {
    */
   public static final String TLS_SERVER_END_POINT = "tls-server-end-point";
 
+  /**
+   * A static mapping of universally standard signature OIDs to their underlying digest algorithms.
+   * This guarantees resolution even if the JCE provider fails to provide a friendly string name.
+   */
+  private static final Map<String, String> OID_TO_DIGEST;
+
+  static {
+    ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
+    // OIDs associated with RSA Signatures
+    map.put("1.2.840.113549.1.1.4", "MD5"); // MD5withRSA
+    map.put("1.2.840.113549.1.1.5", "SHA-1"); // SHA1withRSA
+    map.put("1.2.840.113549.1.1.11", "SHA-256"); // SHA256withRSA
+    map.put("1.2.840.113549.1.1.12", "SHA-384"); // SHA384withRSA
+    map.put("1.2.840.113549.1.1.13", "SHA-512"); // SHA512withRSA
+    map.put("1.2.840.113549.1.1.14", "SHA-224"); // SHA224withRSA
+    map.put("1.2.840.113549.1.1.15", "SHA-512/224"); // SHA512/224withRSA
+    map.put("1.2.840.113549.1.1.16", "SHA-512/256"); // SHA512/256withRSA
+    map.put("2.16.840.1.101.3.4.3.13", "SHA3-224"); // SHA3-224withRSA
+    map.put("2.16.840.1.101.3.4.3.14", "SHA3-256"); // SHA3-256withRSA
+    map.put("2.16.840.1.101.3.4.3.15", "SHA3-384"); // SHA3-384withRSA
+    map.put("2.16.840.1.101.3.4.3.16", "SHA3-512"); // SHA3-512withRSA
+    // OIDs associated with ECDSA Signatures
+    map.put("1.2.840.10045.4.1", "SHA-1"); // SHA1withECDSA
+    map.put("1.2.840.10045.4.3.1", "SHA-224"); // SHA224withECDSA
+    map.put("1.2.840.10045.4.3.2", "SHA-256"); // SHA256withECDSA
+    map.put("1.2.840.10045.4.3.3", "SHA-384"); // SHA384withECDSA
+    map.put("1.2.840.10045.4.3.4", "SHA-512"); // SHA512withECDSA
+    map.put("2.16.840.1.101.3.4.3.9", "SHA3-224"); // SHA3-224withECDSA
+    map.put("2.16.840.1.101.3.4.3.10", "SHA3-256"); // SHA3-256withECDSA
+    map.put("2.16.840.1.101.3.4.3.11", "SHA3-384"); // SHA3-384withECDSA
+    map.put("2.16.840.1.101.3.4.3.12", "SHA3-512"); // SHA3-512withECDSA
+    // OIDs associated with DSA Signatures
+    map.put("1.2.840.10040.4.3", "SHA-1"); // SHA1withDSA
+    map.put("2.16.840.1.101.3.4.3.1", "SHA-224"); // SHA224withDSA
+    map.put("2.16.840.1.101.3.4.3.2", "SHA-256"); // SHA256withDSA
+    map.put("2.16.840.1.101.3.4.3.3", "SHA-384"); // SHA384withDSA
+    map.put("2.16.840.1.101.3.4.3.4", "SHA-512"); // SHA512withDSA
+    map.put("2.16.840.1.101.3.4.3.5", "SHA3-224"); // SHA3-224withDSA
+    map.put("2.16.840.1.101.3.4.3.6", "SHA3-256"); // SHA3-256withDSA
+    map.put("2.16.840.1.101.3.4.3.7", "SHA3-384"); // SHA3-384withDSA
+    map.put("2.16.840.1.101.3.4.3.8", "SHA3-512"); // SHA3-512withDSA
+
+    OID_TO_DIGEST = Collections.unmodifiableMap(map);
+  }
+
   private TlsServerEndpoint() {
     throw new IllegalStateException("Utility class");
   }
@@ -49,17 +98,22 @@ public final class TlsServerEndpoint {
    */
   private static MessageDigest getDigestAlgorithm(final X509Certificate serverCert)
       throws NoSuchAlgorithmException {
+
+    String sigAlgOID = serverCert.getSigAlgOID();
     String sigAlgName = serverCert.getSigAlgName();
-    if (sigAlgName == null) {
-      throw new NoSuchAlgorithmException("Certificate signature algorithm is null");
+    sigAlgName = sigAlgName != null ? sigAlgName.trim().toUpperCase(Locale.ROOT) : null;
+
+    // Guard against Pure Signatures (Ed25519 / Ed448)
+    if ("1.3.101.112".equals(sigAlgOID) || "1.3.101.113".equals(sigAlgOID)) { //NOPMD
+      throw new NoSuchAlgorithmException(
+          String.format(Locale.ROOT, "Could not determine server certificate signature algorithm. Name: %s, OID: %s",
+              serverCert.getSigAlgName(), sigAlgOID));
     }
-    // Normalize name to upper case
-    sigAlgName = sigAlgName.toUpperCase(Locale.ROOT);
 
-    String algorithmName;
+    String algorithmName = null;
 
     // Handle Parameterized Algorithms (Bury the hash in ASN.1 params)
-    if ("RSASSA-PSS".equals(sigAlgName)) {
+    if ("1.2.840.113549.1.1.10".equals(sigAlgOID) || "RSASSA-PSS".equals(sigAlgName)) {
       byte[] sigAlgParams = serverCert.getSigAlgParams();
       if (sigAlgParams == null) {
         throw new NoSuchAlgorithmException("RSASSA-PSS signature parameters are missing");
@@ -68,50 +122,58 @@ public final class TlsServerEndpoint {
         AlgorithmParameters params = AlgorithmParameters.getInstance("RSASSA-PSS");
         params.init(sigAlgParams);
         PSSParameterSpec spec = params.getParameterSpec(PSSParameterSpec.class);
-        algorithmName = spec.getDigestAlgorithm().toUpperCase(Locale.ROOT);
+        algorithmName = spec.getDigestAlgorithm().trim().toUpperCase(Locale.ROOT);
       } catch (IOException | GeneralSecurityException e) {
         throw new NoSuchAlgorithmException("Could not extract hash from RSASSA-PSS parameters", e);
       }
-    } else {
+    } else if (sigAlgOID != null && OID_TO_DIGEST.containsKey(sigAlgOID)) {
+      // Fast-Pass Exact OID Mapping
+      algorithmName = OID_TO_DIGEST.get(sigAlgOID);
+    } else if (sigAlgName != null) {
       // Handle Traditional Algorithms (Hash is explicitly in the name, e.g., "SHA256withRSA")
       int index = sigAlgName.indexOf("WITH");
       if (index > 0) {
-        algorithmName = sigAlgName.substring(0, index); // e.g., "SHA256" or "SHA3-512"
-      } else {
-        // Correctly mirrors PostgreSQL/OpenSSL behavior: Ed25519/Ed448 yield NID_undef.
-        // We must fail here because the Postgres server will also fail.
-        throw new NoSuchAlgorithmException(
-            "Could not determine server certificate signature algorithm: "
-                + serverCert.getSigAlgName());
+        // Extract hash from signature name e.g., "SHA256" or "SHA3-512"
+        algorithmName = sigAlgName.substring(0, index).trim().toUpperCase(Locale.ROOT);
       }
     }
 
+    if (algorithmName == null) {
+      throw new NoSuchAlgorithmException(
+          String.format(Locale.ROOT, "Could not determine server certificate signature algorithm. Name: %s, OID: %s",
+              serverCert.getSigAlgName(), sigAlgOID));
+    }
+
     // Normalize the hash name (Applies to both Traditional and RSASSA-PSS)
     switch (algorithmName) {
-      // Enforce RFC 5929 Mandatory Upgrades (MD5 or SHA-1 must become SHA-256)
+      // Enforce RFC 5929 Mandatory Upgrades to SHA-256
       case "MD5":
       case "SHA1":
       case "SHA-1":
       case "SHA256":
-      case "SHA-256":
         algorithmName = "SHA-256";
         break;
       case "SHA224":
-      case "SHA-224":
         algorithmName = "SHA-224";
         break;
       case "SHA384":
-      case "SHA-384":
         algorithmName = "SHA-384";
         break;
       case "SHA512":
-      case "SHA-512":
         algorithmName = "SHA-512";
         break;
+      case "SHA512/224":
+        algorithmName = "SHA-512/224";
+        break;
+      case "SHA512/256":
+        algorithmName = "SHA-512/256";
+        break;
       default:
-        // Pass-through for valid modern algorithms like SHA3-512
+        // Pass-through for valid modern/standardized names like:
+        // "SHA-512", "SHA-384", "SHA3-256", "SHA3-512", etc.
         break;
     }
+
     return MessageDigest.getInstance(algorithmName);
   }
 
@@ -151,7 +213,7 @@ public final class TlsServerEndpoint {
    * @return the hash of the TLS server's peer certificate
    * @throws CertificateEncodingException if an encoding error occurs
    * @throws NoSuchAlgorithmException if the required digest algorithm cannot be determined or is
-   *           unsupported by the underlying security provider
+   *         unsupported by the underlying security provider
    */
   public static byte @NotNull [] getChannelBindingHash(final @NotNull X509Certificate serverCert)
       throws CertificateEncodingException, NoSuchAlgorithmException {


=====================================
scram-common/src/test/java/com/ongres/scram/common/HiFunctionTest.java
=====================================
@@ -71,7 +71,7 @@ class HiFunctionTest {
   void testAlgorithmCorrectness(ScramMechanism mechanism, int pwLength, int iterations) {
     String hmacAlgorithm = mechanism.getHmacAlgorithmName();
     char[] password = StringPreparation.POSTGRESQL_PREPARATION.normalize(generateRandom(pwLength));
-    int randomSaltSize = ThreadLocalRandom.current().nextInt(1, 200);
+    int randomSaltSize = ThreadLocalRandom.current().nextInt(2, 200);
     byte[] salt = CryptoUtil.salt(randomSaltSize, SECURE_RANDOM);
     try {
       Mac mac = Mac.getInstance(hmacAlgorithm);


=====================================
scram-common/src/test/java/com/ongres/scram/common/ScramFunctionsTest.java
=====================================
@@ -6,11 +6,13 @@
 package com.ongres.scram.common;
 
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
 import java.util.Base64;
 import java.util.Locale;
 
@@ -266,4 +268,10 @@ class ScramFunctionsTest {
             com.ongres.scram.common.RfcExampleSha256.AUTH_MESSAGE,
             generateServerSignatureSha256()));
   }
+
+  @Test
+  void verifySaltHigherThan2() {
+    assertThrows(IllegalArgumentException.class, () -> ScramFunctions.salt(1, new SecureRandom()));
+    assertDoesNotThrow(() -> ScramFunctions.salt(2, new SecureRandom()));
+  }
 }


=====================================
scram-common/src/test/java/com/ongres/scram/common/util/TlsServerEndpointTest.java
=====================================
@@ -18,6 +18,7 @@ import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.Locale;
 import java.util.stream.Stream;
 
 import org.junit.jupiter.api.Assumptions;
@@ -38,10 +39,16 @@ class TlsServerEndpointTest {
             "MD5withRSA", "SHA-256"),
 
         // Standard explicit algorithms
+        Arguments.of(loadCertificate("/SHA224withRSA.pem"),
+            "SHA224withRSA", "SHA-224"),
         Arguments.of(loadCertificate("/SHA256withECDSA.pem"),
             "SHA256withECDSA", "SHA-256"),
         Arguments.of(loadCertificate("/SHA512withRSA.pem"),
             "SHA512withRSA", "SHA-512"),
+        Arguments.of(loadCertificate("/SHA512_224withRSA.pem"),
+            "SHA512/224withRSA", "SHA-512/224"),
+        Arguments.of(loadCertificate("/SHA512_256withRSA.pem"),
+            "SHA512/256withRSA", "SHA-512/256"),
 
         // Modern algorithms (Might be skipped on Java 8 if provider is missing)
         Arguments.of(loadCertificate("/SHA3-512withECDSA.pem"),
@@ -99,7 +106,9 @@ class TlsServerEndpointTest {
     NoSuchAlgorithmException exception = assertThrows(NoSuchAlgorithmException.class,
         () -> TlsServerEndpoint.getChannelBindingHash(cert));
 
-    assertEquals("Could not determine server certificate signature algorithm: " + sigAlg,
+    assertEquals(String.format(Locale.ROOT,
+        "Could not determine server certificate signature algorithm. Name: %s, OID: %s",
+        cert.getSigAlgName(), cert.getSigAlgOID()),
         exception.getMessage());
 
     // 2. Ensure the deprecated method swallows the exception and returns an empty array


=====================================
scram-common/src/test/resources/SHA224withRSA.pem
=====================================
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIFCTCCAvGgAwIBAgIUcucb0GrIXocdXzRx8icYhfpRbtwwDQYJKoZIhvcNAQEO
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDYwOTE0MTQyN1oXDTI3MDYw
+OTE0MTQyN1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEAtneKaUQ4FnIiynKeMc8hXbFhJb25/Ks1IlLnwoOskzUQ
+YKi0C4pYse5y9k4njII8co9yXSmrGv1syl+O1wdUE1WcWPW0ATi+zld4Ht/5yUr0
+21PGpmmZpZBR6vmBAwSDSd2gsvU+noo5eklXbksm++PYPMfXwNjo850jpyLM/Rhx
+c4NxeisBz+yYCX4SHXJ1DoITLoV8kvnIIoFSqEu3KB+RWKIqMhbz3guveaJoxISh
+gdcq3ICa9JnZqzuuKmM5JnPmdcgwcQ9Da/4cfLYFDWJZSSuxIim926ckO+Qq+mLD
+id2X7EtwEnn9HCBdhfMFktddxToiH1b2vC+UG7AX005SKKyBuk92F2TkEfWJarFx
+jQlQWzL16gIFDYOwxDG/PkRqG8hRab2/7hEQW3nTdfENCn7cCC7Now+Abe8ix3v+
+d5CVMz3LWQzpi2TVA58SLUYZ2Sl1KDJGPij7mMV5aOYZPdGh8t52YB3sh0iMT2Hm
+PH9keMEq0Q7vwVGKTcSLR0o4wq5c1RFveodCQcZdrT2tjtQ+jaTLeDNLQXrYKOUF
+lVWUG9BAof5rFgPQeLYafzT95aGTC7Kx2SOACDot9NYYh//xLKiAbI9wSpb+jXei
+RY1ksqv4lrEFHyKxfCDX4WrC6EpB12ZXcCmqBKlZizo+8CzGtMoqKpT/QGTQ7m8C
+AwEAAaNTMFEwHQYDVR0OBBYEFBEd2dhYQaCkJgdvnQ9wcPHJ/ASJMB8GA1UdIwQY
+MBaAFBEd2dhYQaCkJgdvnQ9wcPHJ/ASJMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQEOBQADggIBAJcVHB2k02hGvHXTf44PkE/R8BA7FFLaXdI2/uheOIrkw5PA
+f3OnvEYNbQcNR5oYVZTmzK9wrncNU85tv6mlr8/jWvr07VpA0gmJscIhM7EiWxlv
+UGSl8aOIYSiEiYAGtS0AuJCoFxMi6e5pwYY71jGKm/rRH9rbcEj/g2e/B/K8+Q9z
+ab0Sjwyd8BIEw7aC/02bPmzQTBbyMjDKSPIZf3+JYQRV4IynCRQBF5Hzesc4Mr49
+9oyILiBUfeN9U6g/RLctIRSHUTHOfB8qpyhBQzJf591t8ouU+6Z8QB3VjLBi3Y0h
+I+6QDx7NIXdQKf6NeDEUD61ujEtiLG4a+OGe0xrorPY832ywib1VmWlVTDwoER5w
+3chgHocUtkkk0AtAc57a79gLBmi4wh3OL1e+mLL8LEb/zi9iYN0BQJh7n+TU2/EW
+kIgavUtE0wZ1NayGi7822U81ecBCv+IgKo8f7qIx/E8HLu98B4ZPDdJt3NKZagFZ
+Q9HcrAJdbFRDf4OQstzWtHHIIFxyOsgrwogaAbn0K+jyBZdk1z80104LasrYIxqI
+qCYuYIoDi0DYrqXWDBF0EIXJWR/sv/L7R/0fKgu2CBZ9vNZFf2+aB/BEukUIOgOj
+s9Mppnid1XY6P6ELeil5HNpgWNe1deA1uc9wuBTIqrgJ8ANGZ5K4VFGNIouv
+-----END CERTIFICATE-----


=====================================
scram-common/src/test/resources/SHA512_224withRSA.pem
=====================================
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECTCCAnGgAwIBAgIUaO1+zQiRM2Ep2fHKuZMStFYhQ3kwDQYJKoZIhvcNAQEP
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDYwOTE0MTEzNloXDTI3MDYw
+OTE0MTEzNlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBojANBgkqhkiG9w0BAQEF
+AAOCAY8AMIIBigKCAYEA8XtXyigp1JIfDH+PirHnyv8HM/TKTdG46m0iSqkHt8+p
+eYArWCjnzD1n87cSidbHVTsAriFN8pmgNpNcbHc9+AYGQf60OcrK8LZhlbyemgYZ
+2fLmwWUNLQdVKe4L3C1td0XfPIzNrn2gO/BFPxZaPUy1QdAJSqryUhqBYi+DsaDN
+U+0GI4ttbDaSKIhy4GlRNlrb6FHxmqPqwbVmvVFj1XulIb8H8F0tozrKM3SnVTzO
+iiZKNzKMzcC0EkOzBb3ITdDwTBdSeo4Fz2bnl7cDsa4vDZDlq1xcg7Vx42g71IrB
+twPEgDuoW/G8QJKAugkp7iCQTu6suJUV3YKa5rnfM1oBx6kScjPgnu8cx9OmUNOA
+aBM5Zuu1CEv4Vfkb8Vmm1C4glyMnEkQA+Mq6jPAC7lClTB3JywzcB1ZD9uDlP1sN
+SrPNR2zpREPJ7V0KdSggPOkLZfbbpk3JgOp5BfCYxjKVQv2IV6yxq1cfYp2jl3Ez
+mr+UutoFa2aiiZ/UtT43AgMBAAGjUzBRMB0GA1UdDgQWBBQVSrM9kPNpnu2zXEgR
+Mq/iUOKdwzAfBgNVHSMEGDAWgBQVSrM9kPNpnu2zXEgRMq/iUOKdwzAPBgNVHRMB
+Af8EBTADAQH/MA0GCSqGSIb3DQEBDwUAA4IBgQAQpqMOXE5w4cmKM3mrHoucX1Vr
+FM007q0dtNTUd+e6jGWF9RhoK//Dmp774TzzdjU36goFfqynlkC4JbB642UkHX+S
+lpIph107kKWcEWMGa3alzA5wa1hiJjEQXXyzdB/2lG/aQ3wdiB5Xn1t4DCyf2SKr
+fU07fDL3iiA/fOxHJxOu2zedYgnlVbCHnHe4iDLbs9a3OFAfFNfrv7m+aPm+mOH4
+qJGObBH3KmZ956lt9t0VueCQI049q1sAtHDjICwaWYB69YS4bpo9wwLX1nQctKiK
+Wn2wFJOAgBmIg1htIiTHXysqP3yeHspYK/KpORh0DAhK1jrAcw41M3y253ARkdY3
+y8tJCWUxR8hdQ2bRP2KPk3GKQBlcWpx5BaL3jO49QT19+fRfPPA+iqiUXT/BR3cW
+gxlepq9/+GSwXgeLPS+K2cboiG0HAfTN1QBTyauIGBG6cpDuFIY+hNI1e4cpZtuI
+/x0C/ycX1EgfcaSn33ZjlNckDuWKScz1l6I9Hdo=
+-----END CERTIFICATE-----


=====================================
scram-common/src/test/resources/SHA512_256withRSA.pem
=====================================
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECTCCAnGgAwIBAgIUZVj8zRIzAWkZELs+CIymSJqFB0UwDQYJKoZIhvcNAQEQ
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDYwOTE0MTQzNloXDTI3MDYw
+OTE0MTQzNlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBojANBgkqhkiG9w0BAQEF
+AAOCAY8AMIIBigKCAYEAveh8zh2rT+xSmAlHy0lgk9FREctXBAiJxZRsA40/sj63
+r9lf09WUwSkcy5Jk9kewyMNhJTSY1NdynqlaQv8MaOhHBqf/iKc2YQ7T8xut416S
+koH8u2dEsOYlwDNMBYZsCiuVMkLr59vhsVizwiZ1A+27j10IZlA37Lnk8MYT4usL
+5mHw9EQkz45KvdJmbUYPdmNHPC3fXDpj35RyLrMoPKann/KUEgRiA7NdVhmHFqWQ
+x8IRA4cALagmPxjLyf1JBBShJ6FfFYO/5eNk/HhlSdQRdt39wxbwxVydJJTp9oeN
+M7EVTGx511Tmd2a3F4HLVii5uIr3L/gEnkR9994Cyw/ULd6HEOoeCfm/u1L1uPZR
+Gouv/xhf71sFSjLlChzis2mNuWBgAagU7OuoJBgRlJAUT+aGYfRhfcz1LAm8spzH
+I1dGPrzsgfhC/q5DacC/E5NsI/L/74yDsJldvqIb//gIH1VdCd2vQsWik1IMxDRP
+i7EQIJAOy0Yn0p6tcJDBAgMBAAGjUzBRMB0GA1UdDgQWBBThmLWtRksH3bSek9xV
+dFKvSX1tGjAfBgNVHSMEGDAWgBThmLWtRksH3bSek9xVdFKvSX1tGjAPBgNVHRMB
+Af8EBTADAQH/MA0GCSqGSIb3DQEBEAUAA4IBgQCqPU1BSSRIVIATVIPCcLv9pVrD
+HVbigXGwxNgrnWiNFCLAbRglknn98Uv0I+lKGrLgigVt6n1X7ZCKBJjNrgvdWwIa
+RL27BSV6Z21x+LZdSqETian1nc30MSn7jOIXwaUIRVhAnY5JH0VOXIe3RtIMfngq
+yFvCI58UXWmADJ3f7q3BP7jBu0Hlv4rZCTR2f1xBSS8jIVJYc/mPWyXMjaWYUp4C
+SMN+yr5TOX7YZqCC9eNpbc//BZhmyhCMZwfYa0UbFaAhHEefLsk9nHPB2IAZiPjZ
+DBiKXXGcy2LnI8yg4jGA7Evk7V3AzU1oI820SFCZUMrUVCP5vExVefYLYm18Gwvm
+XBPkHpzgZl69+mSSZwZBNo1nDwMBG6I2Gr4Bq/0dR1Hc5lUr178slE9DqZd/MSZr
++foK0B8nChgwfrl4PHByvVd68jkCPWLltERK4nGEsjsp/i+IswQbwFA+aiLuhy8P
+TFvKdTh9w2QfV4XF1Ux3f9lTvuveG9bD980JIJs=
+-----END CERTIFICATE-----


=====================================
scram-parent/pom.xml
=====================================
@@ -4,7 +4,7 @@
 
   <groupId>com.ongres.scram</groupId>
   <artifactId>scram-parent</artifactId>
-  <version>3.3</version>
+  <version>3.4</version>
   <packaging>pom</packaging>
 
   <name>SCRAM - Parent</name>
@@ -44,7 +44,7 @@
   <scm child.scm.connection.inherit.append.path="false" child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
     <connection>scm:git:https://github.com/ongres/scram.git</connection>
     <developerConnection>scm:git:git at github.com:ongres/scram.git</developerConnection>
-    <tag>3.3</tag>
+    <tag>3.4</tag>
     <url>https://github.com/ongres/scram</url>
   </scm>
 
@@ -63,7 +63,7 @@
     <maven.compiler.testSource>17</maven.compiler.testSource>
     <maven.compiler.testTarget>17</maven.compiler.testTarget>
     <maven.compiler.testRelease>17</maven.compiler.testRelease>
-    <project.build.outputTimestamp>2026-06-04T15:00:00Z</project.build.outputTimestamp>
+    <project.build.outputTimestamp>2026-06-10T16:50:00Z</project.build.outputTimestamp>
     <!-- Dependency versions -->
     <jetbrains-annotations.version>26.1.0</jetbrains-annotations.version>
     <junit5.version>6.1.0</junit5.version>
@@ -82,7 +82,7 @@
     <central-publishing-maven-plugin.version>0.10.0</central-publishing-maven-plugin.version>
     <invoker-plugin.version>3.10.1</invoker-plugin.version>
     <gpg-plugin.version>3.2.8</gpg-plugin.version>
-    <jacoco-plugin.verson>0.8.14</jacoco-plugin.verson>
+    <jacoco-plugin.verson>0.8.15</jacoco-plugin.verson>
     <flatten-maven-plugin.version>1.7.3</flatten-maven-plugin.version>
     <jdeps-plugin.version>3.2.0</jdeps-plugin.version>
     <sortpom-plugin.version>4.0.0</sortpom-plugin.version>
@@ -90,9 +90,9 @@
     <!-- Checkstyle, SpotBugs and PMD properties -->
     <checkstyle.version>13.5.0</checkstyle.version>
     <checkstyle-plugin.version>3.6.0</checkstyle-plugin.version>
-    <errorprone.version>2.49.0</errorprone.version>
-    <spotbugs.version>4.9.8</spotbugs.version>
-    <spotbugs-plugin.version>4.9.8.3</spotbugs-plugin.version>
+    <errorprone.version>2.50.0</errorprone.version>
+    <spotbugs.version>4.10.2</spotbugs.version>
+    <spotbugs-plugin.version>4.10.2.0</spotbugs-plugin.version>
     <findsecbugs.version>1.14.0</findsecbugs.version>
     <pmd.version>7.25.0</pmd.version>
     <pmd-plugin.version>3.28.0</pmd-plugin.version>



View it on GitLab: https://salsa.debian.org/java-team/libscram-java/-/commit/61a3d411302e7dc46ab256a24be3ca9f9f465f79

-- 
View it on GitLab: https://salsa.debian.org/java-team/libscram-java/-/commit/61a3d411302e7dc46ab256a24be3ca9f9f465f79
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20260613/b6360860/attachment.htm>


More information about the pkg-java-commits mailing list