[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