quarkus: Failure during connection to MYSQL on FIPS-compliant host

Describe the bug

I have an application, which uses quarkus-hibernate-orm-panache and quarkus-jdbc-mysql to connect to MYSQL instance. When I run the application ( or integration test) on a RHEL machine with enabled FIPS mode, connection fails.

Expected behavior

Application should establish the connection successfully.

Actual behavior

WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread) HHH000342: Could not obtain connection to query metadata: java.sql.SQLException: Cannot find any provider supporting RSA/ECB/OAEPWithSHA-1AndMGF1Padding
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828)
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:448)
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241)
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
	at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:226)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:536)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:517)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:75)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1126)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.mysql.cj.exceptions.RSAException: Cannot find any provider supporting RSA/ECB/OAEPWithSHA-1AndMGF1Padding
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
	at com.mysql.cj.protocol.ExportControlled.encryptWithRSAPublicKey(ExportControlled.java:691)
	at com.mysql.cj.protocol.a.authentication.Sha256PasswordPlugin.encryptPassword(Sha256PasswordPlugin.java:181)
	at com.mysql.cj.protocol.a.authentication.Sha256PasswordPlugin.encryptPassword(Sha256PasswordPlugin.java:171)
	at com.mysql.cj.protocol.a.authentication.CachingSha2PasswordPlugin.encryptPassword(CachingSha2PasswordPlugin.java:162)
	at com.mysql.cj.protocol.a.authentication.CachingSha2PasswordPlugin.nextAuthenticationStep(CachingSha2PasswordPlugin.java:142)
	at com.mysql.cj.protocol.a.authentication.CachingSha2PasswordPlugin.nextAuthenticationStep(CachingSha2PasswordPlugin.java:49)
	at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:447)
	at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:212)
	at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1433)
	at com.mysql.cj.NativeSession.connect(NativeSession.java:133)
	at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818)
	... 11 more
Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/OAEPWithSHA-1AndMGF1Padding
	at java.base/javax.crypto.Cipher.getInstance(Cipher.java:565)
	at com.mysql.cj.protocol.ExportControlled.encryptWithRSAPublicKey(ExportControlled.java:687)
	... 22 more
Caused by: javax.crypto.NoSuchPaddingException: Unsupported padding OAEPWithSHA-1AndMGF1Padding
	at jdk.crypto.cryptoki/sun.security.pkcs11.P11RSACipher.engineSetPadding(P11RSACipher.java:137)
	at java.base/javax.crypto.Cipher$Transform.setModePadding(Cipher.java:391)
	at java.base/javax.crypto.Cipher.getInstance(Cipher.java:558)
	... 23 more

How to Reproduce?

  1. git clone git@github.com:fedinskiy/reproducer.git -b mysql-fips
  2. in a separate console:
docker run \
-e MYSQL_USER=user \
-e MYSQL_PASSWORD=user \
-e MYSQL_ROOT_PASSWORD=user \
-e MYSQL_DATABASE=mydb \
-e MARIADB_USER=user \
-e MARIADB_PASSWORD=user \
-e MARIADB_ROOT_PASSWORD=user \
-e MARIADB_DATABASE=mydb \
-e ssl_fips_mode=ON \
-p 3306:3306 \
registry.access.redhat.com/rhscl/mysql-80-rhel7:latest
  1. mvn clean package -Dquarkus.platform.version=3.0.1.Final -DskipTests
  2. cp -r target/quarkus-app/ .
  3. java -jar quarkus-app/quarkus-run.jar — this robustly fails. The same can be reproduced for Native mode:
  4. mvn clean package -Pnative -DskipTests -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=registry.access.redhat.com/quarkus/mandrel-22-rhel8:22.3
  5. target/code-with-quarkus-1.0.0-SNAPSHOT-runner Surprisingly, if we run native binary, which was built without support for native mode, then the connection starts working:
  6. mvn clean package -Dquarkus.platform.version=3.0.1.Final -DskipTests -Pnative
  7. target/code-with-quarkus-1.0.0-SNAPSHOT-runner — this succeeds
  8. java -jar quarkus-app/quarkus-run.jar — now this also succeeds, unless we restart the db

Output of uname -a or ver

4.18.0-425.19.2.el8_7.x86_64

Output of java -version

11.0.18, vendor: Red Hat, Inc

GraalVM version (if different from Java)

No response

Quarkus version or git rev

3.0.1.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)

Additional information

$ cat /proc/sys/crypto/fips_enabled
1

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 39 (38 by maintainers)

Most upvoted comments

For example CachingSha2PasswordPlugin is also included in the MySQL JDBC driver and it does override the password encryption cypher to use RSA/ECB/PKCS1Padding ; would that suffice?

@Sanne yes. RSA/ECB/PKCS1Padding is known to work on FIPS as well as non-fips. So it would be a good choice to use by default (or document to use that one over the upstream default). See #32910 (comment)

ok great. We shouldn’t change the default, this is a matter of documentation and testing the configurations.

@fedinskiy Please update the description of this issue that it doesn’t matter whether or not it’s JVM or native (as we’ve shown that a fips enabled native image fails the same way as JVM mode).

(I only see now that @machi1990 had provided very similar information, sorry for the noise!)

In regards to support concerns of such an approach… yes I wouldn’t expect end users to need to provide a custom plugin. I expect choosing one of the provided ones should work, failing that we could provide a custom plugin to be included within Quarkus and supported (but I’d be very surprised for this to be necessary).