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
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?
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
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.
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.
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...
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.
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.
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...
No further comments, so assuming the problem is fixed in the forthcoming 2.1 If not, please re-open when 2.1 comes out.
This issue has been migrated to GitHub: https://github.com/apache/jmeter/issues/1429