-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
1.4.0
-
x86
-
windows_nt
Name: nt126004 Date: 11/04/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
Also tested with:
* java 1.3.1-b24 & JSSE 1.0.2
* java 1.3.1-b24 & JSSE 1.0.3
* java 1.3.0-C & JSSE 1.0.2
* java 1.3.0-C & JSSE 1.0.3
FULL OPERATING SYSTEM VERSION :
Windows NT Version 4.0
(service packs: ?)
A DESCRIPTION OF THE PROBLEM :
Introduction
------------
We're talking about javax.net.ssl package here. According
to JSSE guide, "Whenever a default SSLSocketFactory or
SSLServerSocketFactory is created (via a call to
SSLSocketFactory.getDefault or
SSLServerSocketFactory.getDefault), and this default
SSLSocketFactory (or SSLServerSocketFactory) comes from the
JSSE reference implementation, a default SSLContext is
associated with the socket factory. (The default socket
factory will come from the JSSE implementation.)"
Later it is explained that the default SSLContext is
created using the default KeyManager, and: "If system
properties javax.net.ssl.keyStoreType and/or
javax.net.ssl.keyStorePassword are also specified, they are
treated as the default KeyManager keystore type and
password, respectively". The same applies to TrustManager.
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword",
keyPass);
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStoreType",
trustPass);
The bug
-------
This works fine in the first attempt; the keystore file and
the keystore password are correctly read from the
respective system properties, and the connection is
established. However, the second attempt will also work
*regardless* of first setting (in system properties) a
false keystore file and/or keystore password.
This works conversely too: If the first attempt fails
because of incorrect password, the second attempt will also
fail *regardless* of first setting (in system properties)
the correct keystore file and keystore password.
This applies to both keystores (tried PKCS12) and
truststores (tried JKS).
It seems SSLSocketFactory is caching the default Factory.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Reproducing
-----------
1. Create a keystore and assign it a password.
2. Assign the keystore filepath+name and the password to be
the default values:
System.setProperty("javax.net.ssl.keyStore",
keyStore);
System.setProperty
("javax.net.ssl.keyStorePassword", keyPass);
3. Make an SSL connection (this will work):
SSLSocketFactory factory = (SSLSocketFactory)
SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)
factory.createSocket(host, port);
4. Assign a false password to the keystore:
System.setProperty
("javax.net.ssl.keyStorePassword", "GARBAGE");
5. Repeat step 3. It will work though it should not.
Conversely, you may assign a false password in step 2, and
the correct one in step 4; in this case, both connections
will fail though the latter should not.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Please see "Reproducing".
ERROR MESSAGES/STACK TRACES THAT OCCUR :
If in the first attempt there is a false password and in the second attempt
there is a correct password, then both attempts will end up with:
-- in the case of keystore:
java.net.SocketException: Default SSL context init failed: failed to decrypt
safe contents entry
-- in the case of truststore:
java.net.SocketException: Default SSL context init failed: Keystore was
tampered with, or password was incorrect
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//import java.security.*;
import javax.net.ssl.*;
public class TestTool {
/**
* It is irrelevant whether the SSL provider has been set or not,
* or whether the HTTPS protocol handler has been set, or even
* what the keystore/truststore contains, since the bug is related
* to simply accessing to the keystore/truststore contents.
* Also, both keystore and truststore behave in similar fashion.
*/
public static void main(String[] args) {
//Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
//System.setProperty
("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
// reverse these lines to reproduce the effect in both ways:
connectJSSE("correctpassword");
connectJSSE("GARBAGE");
}
static void connectJSSE(String keyPass) {
System.setProperty("javax.net.ssl.trustStore", "my.trust.store");
System.setProperty("javax.net.ssl.trustStorePassword", keyPass);
SSLSocket sslSocket = null;
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault
();
try {
sslSocket = (SSLSocket)factory.createSocket("avantgo.com", 443);
System.out.println("Succeeded using truststore password: " +
System.getProperty("javax.net.ssl.trustStorePassword"));
}
catch (Exception e) {
System.out.println("Failed using truststore password: " +
System.getProperty("javax.net.ssl.trustStorePassword"));
System.out.println(e.toString());
}
}
}
---------- END SOURCE ----------
(Review ID: 159778)
======================================================================