[CONJ-452] serverSslCert=----BEGIN CERTIFICATE Not Compatible with Google App Engine Created: 2017-04-06  Updated: 2017-05-26  Resolved: 2017-05-10

Status: Closed
Project: MariaDB Connector/J
Component/s: Other, TLS
Affects Version/s: 1.5.6
Fix Version/s: 1.6.0, 2.0.1

Type: Bug Priority: Critical
Reporter: Robert Dyas Assignee: Diego Dupin
Resolution: Fixed Votes: 0
Labels: None
Environment:

Google Cloud App Engine



 Description   

It appears that using the serverSslCert=-----BEGIN CERTIFICATE type of syntax (i.e. specifying it inline which we need to do) causes a write to the keyStore.

Google App Engine runs on a read-only file system, so no writes are allowed. I suspect this is why the connection fails. Is there some way to work around this? Possibly not write it to the trust store?

The exception backtrace looks like this:

 
java.sql.SQLNonTransientConnectionException: Failed to store certificate from serverSslCert into a keyStore
	at org.mariadb.jdbc.internal.util.ExceptionMapper.get(ExceptionMapper.java:132)
	at org.mariadb.jdbc.internal.util.ExceptionMapper.getException(ExceptionMapper.java:101)
	at org.mariadb.jdbc.internal.util.ExceptionMapper.throwException(ExceptionMapper.java:91)
	at org.mariadb.jdbc.Driver.connect(Driver.java:109)
	at java.sql.DriverManager.getConnection(DriverManager.java:571)
	at java.sql.DriverManager.getConnection(DriverManager.java:215)
	at com.parasql.schema.TransactionSet.openConnection(TransactionSet.java:272)



 Comments   
Comment by Robert Dyas [ 2017-04-26 ]

Any update as to if this can be fixed?

Comment by Diego Dupin [ 2017-04-27 ]

Issue reproduced.
Depending on certificate, regex that parse connection url may parse certificate wrongly.
That is not specifically an Google Cloud App Engine issue, but a general use of serverSslCert.

priority will then be change to critical.

Comment by Diego Dupin [ 2017-04-27 ]

for documentation, error is :

java.sql.SQLNonTransientConnectionException: Failed to store certificate from serverSslCert into a keyStore
 
	at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:156)
	at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:118)
	at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.throwException(ExceptionMapper.java:92)
	at org.mariadb.jdbc.Driver.connect(Driver.java:108)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:270)
	at org.mariadb.jdbc.Testt.testt(Testt.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.sql.SQLException: Failed to store certificate from serverSslCert into a keyStore
	at org.mariadb.jdbc.internal.protocol.tls.MariaDbX509TrustManager.<init>(MariaDbX509TrustManager.java:148)
	at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.getSslSocketFactory(AbstractConnectProtocol.java:251)
	at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:669)
	at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:390)
	at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1019)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mariadb.jdbc.internal.logging.ProtocolLoggingProxy.invoke(ProtocolLoggingProxy.java:112)
	at com.sun.proxy.$Proxy4.connectWithoutProxy(Unknown Source)
	at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:481)
	at org.mariadb.jdbc.Driver.connect(Driver.java:103)
	... 25 more
Caused by: java.security.cert.CertificateException: java.io.IOException: Incomplete data
	at sun.security.provider.X509Factory.engineGenerateCertificates(X509Factory.java:358)
	at java.security.cert.CertificateFactory.generateCertificates(CertificateFactory.java:462)
	at org.mariadb.jdbc.internal.protocol.tls.MariaDbX509TrustManager.<init>(MariaDbX509TrustManager.java:140)
	... 37 more
Caused by: java.io.IOException: Incomplete data
	at sun.security.provider.X509Factory.readOneBlock(X509Factory.java:586)
	at sun.security.provider.X509Factory.parseX509orPKCS7Cert(X509Factory.java:449)
	at sun.security.provider.X509Factory.engineGenerateCertificates(X509Factory.java:356)
	... 39 more

Comment by Diego Dupin [ 2017-04-28 ]

That issue will be corrected in next release.

Btw, reading Google App Engine documentation, it seems it require mutual authentication (client certificat + client private key too).

It seems it would be better to provide a keystore to provide all certificates/private key in a file protected with a password, but i don't know if gae permit it. If not, actual version of the driver permit setting server certificat by option, but not client (only keystore is actually possible).

Can you confirm my assumption (mutual authentication mandatory if SSL is enabled, and that no keystore can be used) ?

Comment by Robert Dyas [ 2017-04-28 ]

#1 App Engine Std only supports Java 1.7 currently, so your connector 1.6 release for the jvm7 is great.

#2 Mutual auth is only needed when connecting to Google Cloud SQL from non-app engine. Not required from App Engine. But this is not the use case that is giving us problems....

#3 The use case that is giving us problems is App Engine Std --> Google Compute Engine (running MariaDb server). This communication currently must go over an External IP address, so must be secured. However this does NOT require mutual auth. So long as we can specify the server CA we are good!

Note that GAE Std never allows writing to disk in any form.

Comment by Robert Dyas [ 2017-05-26 ]

Just to confirm back, the fix in 1.6.0 works great!

Generated at Thu Feb 08 03:15:46 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.