diff --git a/pom.xml b/pom.xml
index 873fc0f0b..c77338e90 100644
--- a/pom.xml
+++ b/pom.xml
@@ -281,6 +281,18 @@
2.0.3
true
+
+
+ org.bouncycastle
+ bcpkix-jdk18on
+ 1.78.1
+
+
+
+
+
+
+
org.osgi
@@ -413,6 +425,22 @@
true
+
+ compile-java-15
+ compile
+
+ compile
+
+
+ 15
+
+ 15
+
+ ${project.basedir}/src/main/java15
+
+ true
+
+
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java b/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java
index 16f54d767..32aa74466 100644
--- a/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java
+++ b/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java
@@ -337,8 +337,9 @@ public void authenticationHandler(Credential credential, HostAddress hostAddress
throw context
.getExceptionFactory()
.create(
- "Self signed certificates. Either set sslMode=trust, use password with a MitM-Proof authentication plugin or"
- + " provide server certificate to client",
+ "Self signed certificates. Either set sslMode=trust, use password with a"
+ + " MitM-Proof authentication plugin or provide server certificate to"
+ + " client",
"08000");
}
}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java b/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java
index 7c849a4c3..bbd07cf86 100644
--- a/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java
+++ b/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java
@@ -206,7 +206,7 @@ public boolean binaryProtocol() {
}
public String description() {
- return "BULK: " +command;
+ return "BULK: " + command;
}
public void setPrepareResult(PrepareResultPacket prepareResult) {
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPlugin.java
index 4b1eaa824..32623a906 100644
--- a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPlugin.java
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPlugin.java
@@ -7,7 +7,6 @@
import java.security.*;
import java.security.spec.*;
import java.sql.SQLException;
-import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
@@ -22,10 +21,10 @@
public class ParsecPasswordPlugin implements AuthenticationPlugin {
private static byte[] pkcs8Ed25519header =
- new byte[] {
- 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04,
- 0x20
- };
+ new byte[] {
+ 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04,
+ 0x20
+ };
private String authenticationData;
private byte[] seed;
private byte[] salt;
@@ -55,7 +54,7 @@ public ParsecPasswordPlugin(String authenticationData, byte[] seed) {
* @throws IOException if socket error
*/
public ReadableByteBuf process(Writer out, Reader in, Context context)
- throws SQLException, IOException {
+ throws SQLException, IOException {
// request ext-salt
out.writeEmptyPacket();
@@ -77,7 +76,7 @@ public ReadableByteBuf process(Writer out, Reader in, Context context)
salt = new byte[buf.readableBytes()];
buf.readBytes(salt);
char[] password =
- this.authenticationData == null ? new char[0] : this.authenticationData.toCharArray();
+ this.authenticationData == null ? new char[0] : this.authenticationData.toCharArray();
KeyFactory ed25519KeyFactory;
Signature ed25519Signature;
@@ -93,9 +92,9 @@ public ReadableByteBuf process(Writer out, Reader in, Context context)
ed25519Signature = Signature.getInstance("Ed25519", "BC");
} catch (NoSuchAlgorithmException | NoSuchProviderException ee) {
throw new SQLException(
- "Parsec authentication not available. Either use Java 15+ or add BouncyCastle"
- + " dependency",
- e);
+ "Parsec authentication not available. Either use Java 15+ or add BouncyCastle"
+ + " dependency",
+ e);
}
}
@@ -107,23 +106,14 @@ public ReadableByteBuf process(Writer out, Reader in, Context context)
// create a PKCS8 ED25519 private key with raw secret
PKCS8EncodedKeySpec keySpec =
- new PKCS8EncodedKeySpec(combineArray(pkcs8Ed25519header, derivedKey));
+ new PKCS8EncodedKeySpec(combineArray(pkcs8Ed25519header, derivedKey));
PrivateKey privateKey = ed25519KeyFactory.generatePrivate(keySpec);
- KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519");
- keyPairGenerator.initialize(
- new NamedParameterSpec("Ed25519"), new StaticSecureRandom(derivedKey));
- byte[] spki =
- keyPairGenerator
- .generateKeyPair()
- .getPublic()
- .getEncoded(); // public key in SPKI format; the last 32 bytes are the raw public key
- byte[] rawPublicKey =
- Arrays.copyOfRange(spki, spki.length - 32, spki.length); // 32 bytes raw public key
+ byte[] rawPublicKey = ParsecPasswordPluginTool.process(derivedKey);
hash =
- combineArray(
- combineArray(new byte[] {(byte) 'P', (byte) iterations}, salt), rawPublicKey);
+ combineArray(
+ combineArray(new byte[] {(byte) 'P', (byte) iterations}, salt), rawPublicKey);
// generate client nonce
byte[] clientScramble = new byte[32];
@@ -143,27 +133,15 @@ public ReadableByteBuf process(Writer out, Reader in, Context context)
return in.readReusablePacket();
} catch (NoSuchAlgorithmException
- | InvalidKeySpecException
- | InvalidKeyException
- | InvalidAlgorithmParameterException
- | SignatureException e) {
+ | InvalidKeySpecException
+ | InvalidKeyException
+ | InvalidAlgorithmParameterException
+ | SignatureException e) {
// not expected
throw new SQLException("Error during parsec authentication", e);
}
}
- private class StaticSecureRandom extends SecureRandom {
- private byte[] privateKey;
-
- public StaticSecureRandom(byte[] privateKey) {
- this.privateKey = privateKey;
- }
-
- public void nextBytes(byte[] bytes) {
- System.arraycopy(privateKey, 0, bytes, 0, privateKey.length);
- }
- }
-
public boolean isMitMProof() {
return true;
}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPluginTool.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPluginTool.java
new file mode 100644
index 000000000..b2dc6dc72
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPluginTool.java
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2024 MariaDB Corporation Ab
+package org.mariadb.jdbc.plugin.authentication.standard;
+
+import java.io.IOException;
+import java.security.*;
+import java.sql.SQLException;
+import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
+import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
+
+/** Parsec password plugin utility */
+public class ParsecPasswordPluginTool {
+
+ public static byte[] process(byte[] rawPrivateKey)
+ throws SQLException,
+ IOException,
+ InvalidAlgorithmParameterException,
+ NoSuchAlgorithmException {
+ Ed25519PrivateKeyParameters privateKeyRebuild =
+ new Ed25519PrivateKeyParameters(rawPrivateKey, 0);
+ Ed25519PublicKeyParameters publicKeyRebuild = privateKeyRebuild.generatePublicKey();
+ return publicKeyRebuild.getEncoded();
+ }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java
index 23dfdc577..6e1722cdb 100644
--- a/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java
+++ b/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java
@@ -5,7 +5,6 @@
import java.io.*;
import java.net.URI;
-import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
diff --git a/src/main/java15/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPluginTool.java b/src/main/java15/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPluginTool.java
new file mode 100644
index 000000000..ad20976a1
--- /dev/null
+++ b/src/main/java15/org/mariadb/jdbc/plugin/authentication/standard/ParsecPasswordPluginTool.java
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2024 MariaDB Corporation Ab
+package org.mariadb.jdbc.plugin.authentication.standard;
+
+import java.io.IOException;
+import java.security.*;
+import java.security.spec.NamedParameterSpec;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+/** Parsec password plugin utility*/
+public class ParsecPasswordPluginTool {
+
+ public static byte[] process(byte[] rawPrivateKey)
+ throws SQLException, IOException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
+
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519");
+ keyPairGenerator.initialize(NamedParameterSpec.ED25519, new StaticSecureRandom(rawPrivateKey));
+
+ // public key in SPKI format; the last 32 bytes are the raw public key
+ byte[] spki =
+ keyPairGenerator
+ .generateKeyPair()
+ .getPublic()
+ .getEncoded();
+ byte[] rawPublicKey =
+ Arrays.copyOfRange(spki, spki.length - 32, spki.length);
+ return rawPublicKey;
+ }
+
+ private static class StaticSecureRandom extends SecureRandom {
+ private byte[] privateKey;
+
+ public StaticSecureRandom(byte[] privateKey) {
+ this.privateKey = privateKey;
+ }
+
+ public void nextBytes(byte[] bytes) {
+ System.arraycopy(privateKey, 0, bytes, 0, privateKey.length);
+ }
+ }
+}
diff --git a/src/main/java9/module-info.java b/src/main/java9/module-info.java
index 5f51b8977..ecaad2b34 100644
--- a/src/main/java9/module-info.java
+++ b/src/main/java9/module-info.java
@@ -6,6 +6,7 @@
requires transitive java.naming;
requires transitive java.security.jgss;
requires transitive jdk.net;
+
requires static waffle.jna;
requires static software.amazon.awssdk.services.rds;
requires static software.amazon.awssdk.regions;
@@ -13,6 +14,7 @@
requires static com.sun.jna;
requires static com.sun.jna.platform;
requires static org.slf4j;
+ requires static org.bouncycastle.pkix;
exports org.mariadb.jdbc;
exports org.mariadb.jdbc.client;
diff --git a/src/test/java/org/mariadb/jdbc/integration/SslTest.java b/src/test/java/org/mariadb/jdbc/integration/SslTest.java
index 1e6e6171d..26cb5bf43 100644
--- a/src/test/java/org/mariadb/jdbc/integration/SslTest.java
+++ b/src/test/java/org/mariadb/jdbc/integration/SslTest.java
@@ -615,7 +615,7 @@ public void trustStoreParameter() throws Throwable {
if (caCertPath != null) {
try (InputStream inStream2 = new File(caCertPath).toURI().toURL().openStream()) {
CertificateFactory cf2 = CertificateFactory.getInstance("X.509");
- Collection extends Certificate> caCertList = cf.generateCertificates(inStream);
+ Collection extends Certificate> caCertList = cf2.generateCertificates(inStream2);
for (Iterator extends Certificate> iter = caCertList.iterator(); iter.hasNext(); ) {
certs.add(iter.next());
}