Bug 30741

Summary: JMeter does not prompt for cert passwords
Product: JMeter - Now in Github Reporter: Andrew Bredhauer <andrew.r.bredhauer>
Component: MainAssignee: JMeter issues mailing list <issues>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P3    
Version: 1.9.1   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Andrew Bredhauer 2004-08-19 00:58:16 UTC
As we've recently migrated from Win NT to XP we've found a problem in JMeter 
when using SSL and client certs. Under NT when we selected a certificate using 
the SSL Manager JMeter would prompt us for the password to decrypt the 
contents of the cert. Under XP this no longer occurs and we get this stack 
trace in the jmeter.log file
08/16/2004 11:57:49 AM INFO  - jmeter.JMeter: Version 1.9.1 
08/16/2004 11:58:15 AM INFO  - jmeter.util: KeyStore Type: PKCS 12 
08/16/2004 11:58:15 AM ERROR - jmeter.util: Couldn't load keystore 
java.io.IOException: failed to decrypt safe contents entry
	at com.sun.net.ssl.internal.ssl.PKCS12KeyStore.engineLoad(DashoA6275)
	at java.security.KeyStore.load(KeyStore.java:652)
	at org.apache.jmeter.util.keystore.DefaultKeyStore.load
(DefaultKeyStore.java:84)
	at org.apache.jmeter.util.SSLManager.getKeyStore(SSLManager.java:206)
	at org.apache.jmeter.util.JsseSSLManager.getContext
(JsseSSLManager.java:208)
	at org.apache.jmeter.util.JsseSSLManager.<init>
(JsseSSLManager.java:136)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native 
Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance
(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance
(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
	at org.apache.jmeter.util.SSLManager.getInstance(SSLManager.java:318)
	at org.apache.jmeter.gui.action.SSLManagerCommand.sslManager
(SSLManagerCommand.java:152)
	at org.apache.jmeter.gui.action.SSLManagerCommand.doAction
(SSLManagerCommand.java:107)
	at org.apache.jmeter.gui.action.ActionRouter.performAction
(ActionRouter.java:118)
	at org.apache.jmeter.gui.action.ActionRouter.access$000
(ActionRouter.java:80)
	at org.apache.jmeter.gui.action.ActionRouter$1.run
(ActionRouter.java:99)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy
(EventDispatchThread.java:197)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy
(EventDispatchThread.java:150)
	at java.awt.EventDispatchThread.pumpEvents
(EventDispatchThread.java:144)
	at java.awt.EventDispatchThread.pumpEvents
(EventDispatchThread.java:136)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)

08/16/2004 11:58:15 AM INFO  - jmeter.util: JmeterKeyStore Location: 
C:\data\certificates\prod test\DXDVM1.p12 
08/16/2004 11:58:15 AM INFO  - jmeter.util: JmeterKeyStore type: class 
org.apache.jmeter.util.keystore.DefaultKeyStore 
08/16/2004 11:58:15 AM INFO  - jmeter.util: class 
org.apache.jmeter.util.keystore.DefaultKeyStore 
08/16/2004 11:58:15 AM INFO  - jmeter.util: KeyStore Type: JKS 
08/16/2004 11:58:15 AM INFO  - jmeter.util: TrustStore Location:  
08/16/2004 11:58:15 AM INFO  - jmeter.util: TrustStore type: class 
org.apache.jmeter.util.keystore.DefaultKeyStore 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_RSA_WITH_RC4_128_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_WITH_RC4_128_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_RSA_WITH_RC4_128_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_WITH_RC4_128_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_RSA_WITH_3DES_EDE_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_WITH_3DES_EDE_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_RSA_WITH_DES_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_WITH_DES_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_DHE_DSS_WITH_DES_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DHE_DSS_WITH_DES_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_RSA_EXPORT_WITH_RC4_40_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_EXPORT_WITH_RC4_40_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Default Cipher: 
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_WITH_NULL_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_RSA_WITH_NULL_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DH_anon_WITH_RC4_128_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DH_anon_WITH_DES_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 
08/16/2004 11:58:15 AM INFO  - jmeter.util: Supported Cipher: 
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA 
08/16/2004 11:58:15 AM INFO  - jmeter.util: JsseSSLManager installed 

We've found that by setting the value of the javax.net.ssl.keyStorePassword 
property in the jmeter.properties file that this allows JMeter to decrypt the 
cert but we have many certs with different passwords so this becomes painful 
very quickly.

Any ideas would be appreciated

Thanks

Andrew
Comment 1 Sebb 2004-08-22 21:32:25 UTC
Not sure if this will help you, but you can always define the value of
javax.net.ssl.keyStorePassword on the JMeter command line, using the -D or -J
flags; this saves having to edit the properties file.

By the way, are you using the same version of the JVM on XP as you were using on NT?

There is code in SSLManager.java (in 1.9.1) to prompt for a password, but as far
as I can see, it won't be invoked:

   this.defaultpw =
        JMeterUtils.getJMeterProperties().getProperty(
                 "javax.net.ssl.keyStorePassword",
                  "password");

    if (null == defaultpw)
    {
           // Code to prompt for password
    }

I don't see how defaultpw can ever be null ... so perhaps the prompting was
previously done by Java?
Comment 2 Andrew Bredhauer 2004-09-23 00:51:20 UTC
OK I've doen a bit more digging and found out that apparently we were 
previously using JMeter 1.8.1 which I've just checked and it prompts for the 
cert/keystore password on loading. Maybe this is some functionality that was 
dropped on the upgrade to 1.9 as it doesn't seem to prompt?

Andrew
Comment 3 Richard Cook 2004-09-23 21:12:00 UTC
This bug just bit me as well.  It looks like the "if" statement at
SSLManager.java:142 (in 2.0.1 source) should be omitted (along with its
associated brackets).  I have not tried recompiling with this change since the
javax.net.ssl.keyStorePassword workaround is adequate for my testing.  Maybe
someone else could try patching the source and recompiling to see if that fix
would be sufficient.
Comment 4 Sebb 2004-09-23 21:30:27 UTC
Duh! should have realised the problem earlier, which is actually in the previous
statement: 

this.defaultpw = JMeterUtils.getJMeterProperties().getProperty(
                            "javax.net.ssl.keyStorePassword",
                            "password");

This means that defaultpw will be set to "password" if the property is not
defined. [This is doubly odd, because defaultpw is already set where the
variable is declared!]

So the prompt for the password will never happen. Quite why that default was
added is not clear, but it does seem to have happened between 1.8 and 1.9.

I think the solution is to remove the outer if statement and the getProperty
entirely. I'll commit that to CVS 2.0 shortly.
Comment 5 Sebb 2004-09-23 21:56:09 UTC
Just spotted the setProperty() after the prompt - so the getProperty was needed
after all. Now checked in fix with just the default removed, which should sort
things, I hope...

There's a build in: http://cvs.apache.org/builds/jakarta-jmeter/nightly/ if you
want to try it out...
Comment 6 Andrew Bredhauer 2004-09-23 22:53:14 UTC
Thanks Sebb, I've given it a quick check and it seems to work. I'll pass it 
along to our testers to give it more of a thrashing. Note the nightly bin zip 
doesn't seem to include the various jar dependencies, not sure if this is by 
design or not.
Comment 7 Richard Cook 2004-09-23 22:59:22 UTC
I am unsure whether the fix you propose is best.  I cannot be sure from the
peculiar logic of the existing 2.0.1 code for SSLManager.java exactly what
behavior is desired.  Do we want an internal default password, "password", if
the user's input is null or zero-length?

The _right_ thing to do should be governed by the failure mode which ultimately
will occur if the password is wrong.  As it stands, the user is never prompted
for a password and presumably the internal default "password" is used.  This
seems to cause a null client certificate to be submitted to the server, leading
to a silent failure (unless one sets "-Djavax.net.debug=ssl" in which case you
get the rather unhelpful message "bad certificate").  One is left with little or
no clues as to what is failing, unless he notices that the password prompt that
should have occurred didn't.

If leaving the password null (in the absence of valid user input) leads to an
appropriate null-pointer exception, then that might be more helpful.  I cannot
imagine a situation where an internal default of "password" would be generally
useful, except to avoid generating such a null-pointer exception.

A more desireable scenario would be to somehow clue the user into the fact that
the password for his keystore is not working (either he entered it wrong or not
at all), and perhaps provide a means to correct the situation.  I have not
looked at the code to see where or how this might be accomplished.  If such a
feature is implemented, it will become entirely obvious what is best to do in
initializing the "javax.net.ssl.keyStorePassword" property.
Comment 8 Sebb 2004-09-24 10:08:42 UTC
Andrew: the jars are in the _lib zip file. I'll update the header to make this
clear.

Richard: 
the code uses the property "javax.net.ssl.keyStorePassword" to set defaultpw,
with no default. When a password is needed, and defaultpw is null, it checks the
property again (see below for why). At this point in 2.0.1, it would use
"password" if the property was not defined. In the latest code, if the property
is still not defined, it displays a dialogue to prompt for the password. 

The input from the user is then used to set defaultpw *and* the property - so
that other instances of the class will use that value, if any, as the default.
Once set, the defaultpw is not changed by the *current* instance.

All:
I've not done any SSL testing, so I don't know if it is helpful or not to save
the users response in the property.

Not sure what to do about dealing with incorrect passwords - is it always the
case that a user would want to correct an invalid password? 
[May also need to do some work on the non-GUI behaviour, when prompting is not
appropriate.]

AFAICS the current fix is an improvement, albeit minor...
Comment 9 Sebb 2005-07-11 00:36:02 UTC
No further comments, so assuming the problem is fixed in the forthcoming 2.1

If not, please re-open when 2.1 comes out.
Comment 10 The ASF infrastructure team 2022-09-24 20:37:33 UTC
This issue has been migrated to GitHub: https://github.com/apache/jmeter/issues/1429