-
Bug
-
Resolution: Fixed
-
P3
-
1.0.3
-
01
-
x86
-
windows_2000
Name: nt126004 Date: 07/19/2002
FULL PRODUCT VERSION :
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)
FULL OPERATING SYSTEM VERSION :
MS Windows 2000 Professional Service Pack 2
EXTRA RELEVANT SYSTEM CONFIGURATION :
This incident refers to JSSE 1.0.3 (not available for
selection in "Product Version")
A DESCRIPTION OF THE PROBLEM :
Unexpectedly receive a "untrusted server cert chain"
SSLException when connecting to a webserver. The
certificate on the webserver is not trusted but a custom
X509TrustManager should allow the connection to be made.
Using JSSE 1.0.2 either (global or domestic). My custom
X509TrustManager is correctly invoked from
com.sun.net.ssl.internal.JsseX509TrustManager.isServerTruste
d(). This obfuscated code calls my X509TrustManager's
isServerTrusted() method.
In JSSE 1.0.3, the same method unexpectedly calls my
X509TrustManager's isClientTrusted() method. I forced the
isClientTrusted() method to return true. This in order to
see if isClientTrusted was getting called in addition to
isServerTrusted(). isServerTrusted() was not called. The
SSL connection was successfully established.
REGRESSION. Last worked in version 1.0.2
EXPECTED VERSUS ACTUAL BEHAVIOR :
Forced an exception in my isXXXXTrusted methods to show
stack trace using JSSE 1.0.2 (expected result) and JSSE
1.0.3 (unexpected result).
Expected result (JSSE 1.0.2):
java.lang.Exception
at
com.symantec.management.security.CustomX509TrustManager.isSe
rverTrusted(CustomX509TrustManager.java:88)
at
com.sun.net.ssl.internal.ssl.JsseX509TrustManager.isServerTr
usted([DashoPro-V1.2-120198])
at com.sun.net.ssl.internal.ssl.ClientHandshaker.a
==> clip
Actual result (JSSE 1.0.3):
java.lang.Exception
at
com.symantec.management.security.CustomX509TrustManager.isCl
ientTrusted(CustomX509TrustManager.java:51)
at
com.sun.net.ssl.internal.ssl.JsseX509TrustManager.isServerTr
usted(DashoA6275)
==> clip
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.Exception
at
com.symantec.management.security.CustomX509TrustManager.isClientTrusted
(CustomX509TrustManager.java:51)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.isServerTrusted
(DashoA6275)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage
(DashoA6275)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(DashoA6275)
at java.io.OutputStream.write(OutputStream.java:61)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.doConnect
(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.NetworkClient.openServer
(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.HttpClient.l(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.HttpClient.<init>
(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.<init>
(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a(DashoA6275)
at com.sun.net.ssl.internal.www.protocol.https.HttpsClient.a(DashoA6275)
at
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.connect
(DashoA6275)
at Foo.main(Foo.java:119)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* Foo.java
*
* Created on March 4, 2002, 1:25 PM
*/
/**
*
* @author jallee
* @version
*/
import java.net.*;
import javax.net.*;
import java.io.*;
import java.security.*;
import com.sun.net.ssl.*;
import javax.net.ssl.*;
import javax.security.cert.*;
public class Foo
{
/** Creates new Foo */
public Foo()
{
}
private static Throwable initSSL()
{
// Install custom security provider
//Provider customProvider = new CustomSecurityProvider();
//java.security.Security.insertProviderAt(customProvider, 1);
// Set up JSSE in lieu of editing the java.security file for this VM
instance
java.security.Security.addProvider(new
com.sun.net.ssl.internal.ssl.Provider());
System.setProperty
("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
// Enable JSSE debugging messages
boolean debug = false;
if (debug)
System.setProperty("javax.net.debug", "all");
// Initialize the SunJSSE X509 TrustManagerFactory
TrustManagerFactory tmf = null;
String algorithm = "SunX509";
String provider = "SunJSSE";
try
{
tmf = TrustManagerFactory.getInstance(algorithm, provider);
tmf.init(null);
}
catch (java.security.NoSuchProviderException e)
{
System.err.println("NoSuchProviderException: " + e);
return e;
}
catch (java.security.NoSuchAlgorithmException e)
{
System.err.println("NoSuchAlgorithmException: " + e);
return e;
}
catch (java.security.KeyStoreException e)
{
System.err.println("KeyStoreException: " + e);
return e;
}
// Locate the standard X509TrustManager
X509TrustManager standardTrustManager = null;
TrustManager[] tma = tmf.getTrustManagers();
if (tma != null)
{
for (int i = 0; i < tma.length; ++i)
{
// Is this the X509 trust manager?
if (tma[i] instanceof X509TrustManager)
{
standardTrustManager = (X509TrustManager) tma[i];
break;
}
}
}
X509TrustManager customTrustManager = new CustomX509TrustManager
(standardTrustManager);
// Create an SSLContext
SSLContext sslContext = null;
try
{
sslContext = SSLContext.getInstance("SSL");
TrustManager[] trustManagers =
{customTrustManager};
sslContext.init(null, trustManagers, null);
}
catch (NoSuchAlgorithmException e)
{
System.err.println("NoSuchAlgorithmException: " + e);
return e;
}
catch (KeyManagementException e)
{
System.err.println("KeyManagementException: " + e);
return e;
}
// get SSLSocketFactory for our new context
SSLSocketFactory sslSocketFactoryInternal = sslContext.getSocketFactory
();
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactoryInternal);
return null;
}
public static void main(String[] args) throws Exception
{
try
{
initSSL();
// Use your own untrusted https server's ip address here.
System.out.println("You need to specify your own here.");
String host = "155.64.xxx.xxx"; // TODO: your untrusted source
InetAddress addr = InetAddress.getByName(host);
String strHostname = addr.getHostName();
System.out.println("Connecting to " + strHostname);
com.sun.net.ssl.HttpsURLConnection conn = null;
conn = (com.sun.net.ssl.HttpsURLConnection) (new URL
("https",host,443,"/")).openConnection();
// Custom hostname verification code is removed.
// This connection will always fail.
// Notice though that with JSSE 1.0.3 isClientTrusted() is called.
// With JSSE 1.0.2 isServerTrusted is called.
conn.connect();
System.out.println("connection open");
Thread.sleep(10 * 1000);
conn.disconnect();
System.out.println("connection closed");
}
catch (Throwable e)
{
System.out.println (e);
}
}
static class CustomX509TrustManager implements X509TrustManager
{
X509TrustManager realTrustManager = null;
public CustomX509TrustManager(X509TrustManager realTrustManager)
{
this.realTrustManager = realTrustManager;
}
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
System.out.println("CustomX509TrustManager.getAcceptedIssuers
()...");
if (realTrustManager == null)
return null;
return realTrustManager.getAcceptedIssuers();
}
public boolean isClientTrusted(java.security.cert.X509Certificate[]
chain)
{
try
{
throw new Exception();
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[]
chain)
{
try
{
throw new Exception();
}
catch (Exception e)
{
e.printStackTrace();
}
return true;
}
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Workaround: Implement the isClientTrusted and
isServerTrusted methods in custom X509TrustManager such
they can handle requests that are meant for each other.
Release Regression From : 1.0.2
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 153983)
======================================================================