Bug #66173 Getting "javax.net.ssl.SSLException: Unsupported record version Unknown-0.0"
Submitted: 3 Aug 2012 5:23 Modified: 25 May 2013 8:38
Reporter: Vishal Bansod Email Updates:
Status: No Feedback Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.1.21 OS:Any
Assigned to: Assigned Account CPU Architecture:Any
Tags: Connector/J, server, SSL

[3 Aug 2012 5:23] Vishal Bansod
Description:
I'm trying to connect to MySQL server using JDBC client using TLSv1. 

JDBC URL: 
jdbc:mysql://server_IP:3306/test?noDatetimeStringSync=true&useSSL=true 

MySQL server: 
5.5.25a community edition 

Connector Used: 
mysql-connector-java-5.1.21-bin.jar 

Certificates used: 
self signed certs created using OpenSSL on linux box 

Resulting exception: 
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 

The last packet successfully received from the server was 84 milliseconds ago. The last packet sent successfully to the server was 82 milliseconds ago. 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) 
at java.lang.reflect.Constructor.newInstance(Unknown Source) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117) 
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:105) 
at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:5126) 
at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1666) 
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1244) 
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2397) 
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2430) 
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2215) 
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:813) 
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) 
at java.lang.reflect.Constructor.newInstance(Unknown Source) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:399) 
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:334) 
. 
. 
. 
. 
. 
. 
. 
Caused by: javax.net.ssl.SSLException: Unsupported record version Unknown-0.0 
at com.sun.net.ssl.internal.ssl.InputRecord.readV3Record(Unknown Source) 
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.waitForClose(Unknown Source) 
at com.sun.net.ssl.internal.ssl.HandshakeOutStream.flush(Unknown Source) 
at com.sun.net.ssl.internal.ssl.Handshaker.sendChangeCipherSpec(Unknown Source) 
at com.sun.net.ssl.internal.ssl.ClientHandshaker.sendChangeCipherAndFinish(Unknown Source) 
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source) 
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source) 
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source) 
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source) 
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:90) 
... 37 more 

I have seen many bugs releted to this exception and many have status as fixed. But I'm still getting this exception. 

Here is the network log captured on MySQL server machine using MS Network Monitor 

mysqld.exe	164.99.135.140	164.99.135.57	TLS	TLS:TLS Rec Layer-1 HandShake: Client Hello.	{TLS:5458, SSLVersionSelector:5457, TCP:5454, IPv4:15} 
mysqld.exe	164.99.135.140	164.99.135.57	TLS	TLS:TLS Rec Layer-1 HandShake: Certificate. Client Key Exchange.	{TLS:5458, SSLVersionSelector:5457, TCP:5454, IPv4:15} 
mysqld.exe	164.99.135.140	164.99.135.57	TLS	TLS:TLS Rec Layer-1 HandShake: Certificate Verify.	{TLS:5458, SSLVersionSelector:5457, TCP:5454, IPv4:15} 
mysqld.exe	164.99.135.140	164.99.135.57	TLS	TLS:TLS Rec Layer-1 Cipher Change Spec	{TLS:5461, SSLVersionSelector:5460, TCP:5459, IPv4:15}

How to repeat:
1) Run Server with SSL enabled.
2) Import Server Certificate to client truststore.
3) Use JDBC client and connect using URL "jdbc:mysql://server_IP:3306/test?noDatetimeStringSync=true&useSSL=true"
[3 Aug 2012 5:27] Vishal Bansod
I have tried older version of MySQL server and older version of Connector/J but getting same exception.
[3 Aug 2012 6:06] Valeriy Kravchuk
What exact version of OpenSSL you had used to create this certificate? See bug #19705 also.
[3 Aug 2012 11:13] Vishal Bansod
OpenSSL 0.9.8j-fips 07 Jan 2009
[3 Aug 2012 17:57] Sveta Smirnova
Thank you for the feedback.

Can you connect to MySQL server with same SSL keys, but using MySQL command line client?

Please send us Java code you use to connect. I want to check how you point to SSL parameters.
[6 Aug 2012 7:05] Vishal Bansod
I tried following command to connect using mysql command line utility and I was able to connect

D:\MySQL\MySQL Server 5.5\bin>mysql -h localhost -u root -ppassword test --ssl=TRU
E  --ssl-ca=D:/newcerts/ca-cert.pem  --ssl-capath=D:/newcerts/  --ssl-cert=D:/ne
wcerts/server-cert.pem  --ssl-key=D:/newcerts/server-key.pem
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 5.5.25a MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
[6 Aug 2012 7:29] Vishal Bansod
JDBC code is very simple:

ret = DriverManager.getConnection(dbUrl, user, pass);

dbUrl is what I mentioned in initial bug summary.

This is how I construct dbUrl for MySQL connection:

dbUrl = "jdbc:mysql://" + host + ":" + port + "/" + db + "?noDatetimeStringSync=true&useSSL=" +String.valueOf(isSSL)
[6 Aug 2012 7:36] Vishal Bansod
I'm using SunPKCS11 provider with NSS implementation underneath. I have also imported MySQL server's certificated to my application's truststore.

As I'm attempting to comply with FIPS 140-2, I have removed all weak providers.
[6 Aug 2012 8:40] Vishal Bansod
Please ignore SunPKCS11 provider case for now as I'm getting same issue even with default set of security providers.
[6 Aug 2012 12:14] Sveta Smirnova
Thank you for the feedback.

I don't see in your Java code where you pass SSL credentials. I only see useSSL=" +String.valueOf(isSSL) which should be converted to true, but no certificate information. Read at http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-using-ssl.html about parameters I am asking about.
[6 Aug 2012 12:28] Vishal Bansod
In case you are talking about 

-Djavax.net.ssl.keyStore=path_to_keystore_file
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=path_to_truststore_file
-Djavax.net.ssl.trustStorePassword=password

Those are properly set access keystore and truststore.
[6 Aug 2012 13:43] Valeriy Kravchuk
As it works with mysql command line client, I'd say we have a Connector/J bug here, if any.
[6 Aug 2012 14:25] Mark Matthews
More than likely this is a yassl bug in the server, Valeriy, or at least an incompatibility between yassl and Java's implementation of SSL which is tested for compliance against OpenSSL and other commercial SSL implementations (but not YASSL).

I'd be curious if this fails if the scenario is tested by the reporter with a server that uses OpenSSL as the SSL library, and not yassl.
[8 Aug 2012 10:55] Vishal Bansod
Mark,

Are you trying to say that, I have option to choose SSL provider while installing MySQL server and I should choose OpenSSL instead of YaSSL
[8 Aug 2012 16:09] Mark Matthews
You have an option when you *compile* mysql. Not install.
[13 Aug 2012 7:50] Vishal Bansod
I wrote a smaple program as:

import java.sql.DriverManager;
import java.sql.SQLException;

public class MySQLJDBC {

	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		Class.forName("com.mysql.jdbc.Driver");
		String m_host = "localhost";
		String m_port = "3306";
		String m_db = "test";
		boolean isSSL = true;
		String dbUrl = "jdbc:mysql://" + m_host + ":" + m_port + "/" + m_db + "?noDatetimeStringSync=true&requireSSL=true&useSSL=" +String.valueOf(isSSL);
		String m_user = "root";
		String m_pass = "pwd";
		System.setProperty("javax.net.ssl.keyStore","D:/mystore.jks");
		System.setProperty("javax.net.ssl.keyStorePassword","password");
		System.setProperty("javax.net.ssl.trustStore","D:/mystore.jks");
		System.setProperty("javax.net.ssl.trustStorePassword","password");
		DriverManager.getConnection(dbUrl, m_user, m_pass);
		System.out.println(System.getProperty("javax.net.ssl.keyStore"));
	}
}

I was NOT able to connect till I had a Private Key entry in keystore. I connected the moment I removed that entry and left only trust entries to be present in key/trust store
[25 Apr 2013 5:39] Alexander Soklakov
Hi Vishal,

The possible reason could be the way you prepare your keystore. Look, please, at Bug#68957 solution:

keytool -import -alias mysqlCACert -file ca-cert.pem -keystore truststore -storepass 111111

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -certfile client-cert.pem -name "Name" -out client.p12

keytool -importkeystore -srckeystore client.p12 -srcstoretype pkcs12 -destkeystore keystore
[26 May 2013 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[2 Feb 2018 16:09] Christopher Schultz
In case anyone runs across this bug like I did, my problem was that I had configured the client to *only* use TLSv1.2, while the server supported a different (maximum) version. Probably TLSv1.0.

Unfortunately, since MySQL doesn't really support TLS as usual, you can't really probe the server like you could with e.g. OpenSSL s_client or any other similar tool to check to see what protocols and cipher suites MySQL supports.