-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
None
-
7u45
-
windows_7
FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
This happens with jre 1.7.0_45.
This *does not* happen with jre 1.7.0_05.
This does happen with jre 1.6.0_35
I'm using "Apache/2.2.24 (Unix) DAV/2 PHP/5.3.26 mod_ssl/2.2.24 OpenSSL/0.9.8y" on Mac OS X 10.8.5 as the webserver. My config file looks like this
Listen 443
<VirtualHost *:443>
DocumentRoot /path/to/my_files/
SSLEngine on
SSLProtocol SSLv3
SSLCertificateFile /path/to/test.cert
SSLCertificateKeyFile /path/to/test.key
</VirtualHost>
This limits connections to be SSLv3 only. When run with jre 1.7.0_45 I get the following output:
java HttpsConnectionExample https://192.168.0.6/
Vendor 'Oracle Corporation' URL 'http://java.oracle.com/' Version '1.7.0_45'
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
I get similar output from jre 1.6.0_35:
java HttpsConnectionExample https://192.168.0.6/
Vendor 'Sun Microsystems Inc.' URL 'http://java.sun.com/' Version '1.6.0_35'
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(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 sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
However this works with jre 1.7.0_05:
java HttpsConnectionExample https://192.168.0.6:443/
Vendor 'Oracle Corporation' URL 'http://java.oracle.com/' Version '1.7.0_05'
Response Code: 200
I've taken and will try to attache wiresharks of the ssl traffic for each of the 3 jre versions I've run this against. I'm not an SSL expert, but I have noticed the version of the Client Hello seems to differ between jre versions:
1.7.0_45 -> SSLv3.
1.7.0_05 -> SSLv3.
1.6.0_35 -> SSLv2.
REGRESSION. Last worked in version 7u10
ADDITIONAL REGRESSION INFORMATION:
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile:
javac HttpsConnectionExample.java
run:
java HttpsConnectionExample https://ip-of-sslv3-only-webserver/
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
For my program to print:
Response Code: 200
ACTUAL -
I get the following exception:
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpsConnectionExample
{
private static void trustAllCertficates()
{
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return new java.security.cert.X509Certificate[0];
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException
{
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException
{
}
} };
try
{
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (Exception e)
{
e.printStackTrace();
}
}
static void logJavaInfo()
{
System.out.println("Vendor '" + System.getProperty("java.vendor") + "' " + "URL '"
+ System.getProperty("java.vendor.url") + "' " + "Version '"
+ System.getProperty("java.version") + "'");
}
private static void disableHostNameVerification()
{
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
});
}
public static void main(String[] args)
{
logJavaInfo();
trustAllCertficates(); // Mine is self signed
disableHostNameVerification(); // Mine is not for local host
try
{
if ( args.length > 1)
{
System.setProperty("https.protocols", "SSLv3");
}
final URL url = new URL(args[0]);
final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
System.out.println("Response Code: " + conn.getResponseCode());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I think this could be worked around by doing:
System.setProperty("https.protocols", "SSLv3");
Unfortunately my program is making http requests from multiple threads, so I wouldn't want to change this globally.
SUPPORT :
YES
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
This happens with jre 1.7.0_45.
This *does not* happen with jre 1.7.0_05.
This does happen with jre 1.6.0_35
I'm using "Apache/2.2.24 (Unix) DAV/2 PHP/5.3.26 mod_ssl/2.2.24 OpenSSL/0.9.8y" on Mac OS X 10.8.5 as the webserver. My config file looks like this
Listen 443
<VirtualHost *:443>
DocumentRoot /path/to/my_files/
SSLEngine on
SSLProtocol SSLv3
SSLCertificateFile /path/to/test.cert
SSLCertificateKeyFile /path/to/test.key
</VirtualHost>
This limits connections to be SSLv3 only. When run with jre 1.7.0_45 I get the following output:
java HttpsConnectionExample https://192.168.0.6/
Vendor 'Oracle Corporation' URL 'http://java.oracle.com/' Version '1.7.0_45'
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
I get similar output from jre 1.6.0_35:
java HttpsConnectionExample https://192.168.0.6/
Vendor 'Sun Microsystems Inc.' URL 'http://java.sun.com/' Version '1.6.0_35'
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(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 sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
However this works with jre 1.7.0_05:
java HttpsConnectionExample https://192.168.0.6:443/
Vendor 'Oracle Corporation' URL 'http://java.oracle.com/' Version '1.7.0_05'
Response Code: 200
I've taken and will try to attache wiresharks of the ssl traffic for each of the 3 jre versions I've run this against. I'm not an SSL expert, but I have noticed the version of the Client Hello seems to differ between jre versions:
1.7.0_45 -> SSLv3.
1.7.0_05 -> SSLv3.
1.6.0_35 -> SSLv2.
REGRESSION. Last worked in version 7u10
ADDITIONAL REGRESSION INFORMATION:
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile:
javac HttpsConnectionExample.java
run:
java HttpsConnectionExample https://ip-of-sslv3-only-webserver/
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
For my program to print:
Response Code: 200
ACTUAL -
I get the following exception:
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at HttpsConnectionExample.main(HttpsConnectionExample.java:86)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpsConnectionExample
{
private static void trustAllCertficates()
{
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return new java.security.cert.X509Certificate[0];
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException
{
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException
{
}
} };
try
{
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (Exception e)
{
e.printStackTrace();
}
}
static void logJavaInfo()
{
System.out.println("Vendor '" + System.getProperty("java.vendor") + "' " + "URL '"
+ System.getProperty("java.vendor.url") + "' " + "Version '"
+ System.getProperty("java.version") + "'");
}
private static void disableHostNameVerification()
{
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
});
}
public static void main(String[] args)
{
logJavaInfo();
trustAllCertficates(); // Mine is self signed
disableHostNameVerification(); // Mine is not for local host
try
{
if ( args.length > 1)
{
System.setProperty("https.protocols", "SSLv3");
}
final URL url = new URL(args[0]);
final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
System.out.println("Response Code: " + conn.getResponseCode());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I think this could be worked around by doing:
System.setProperty("https.protocols", "SSLv3");
Unfortunately my program is making http requests from multiple threads, so I wouldn't want to change this globally.
SUPPORT :
YES