You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Frank Taffelt <Fr...@interface-projects.de> on 2017/06/30 12:43:34 UTC

Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Hi all,

while playing with some ssl setups i stumbled upon the following behaviour that seems like bug to me ?
As long as all keyentries in a keystore have the same password all is fine. Using entries with different password tomcat doesnt startup.

For testing:
At first create 2 different keystores (same.jks and different.jks) having each 2 entries:

# create 2 entries with same keypass for each entry
keytool -genkeypair -alias tomcat1 -storepass storepass  -keystore same.jks  -keyalg RSA -keypass keypass  -ext san=dns:tomcat1 -dname CN=tomcat1
keytool -genkeypair -alias tomcat2 -storepass storepass  -keystore same.jks  -keyalg RSA -keypass keypass  -ext san=dns:tomcat2 -dname CN=tomcat2

# create 2 entries with different keypass for each entry
keytool -genkeypair -alias tomcat1 -storepass storepass  -keystore different.jks  -keyalg RSA -keypass tomcat1  -ext san=dns:tomcat1 -dname CN=tomcat1
keytool -genkeypair -alias tomcat2 -storepass storepass  -keystore different.jks  -keyalg RSA -keypass tomcat2  -ext san=dns:tomcat2 -dname CN=tomcat2

setup a SSL Connector to use that keystore:

<Connector
  port="443"
  URIEncoding="UTF-8"
  scheme="https" 
  secure="true" 
  SSLEnabled="true"
 >
		
<SSLHostConfig  
  ciphers="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA" 
  protocols="all">

<!-- doesn't work, use keypass for alias tomcat2 -->
<Certificate 
  certificateKeystoreFile="different.jks"
  certificateKeystorePassword="storepass"
  certificateKeyAlias="tomcat2"
  certificateKeystoreType="JKS"
  certificateKeyPassword="tomcat2"
  type="RSA"
/>

<!-- working config -->
<!--
<Certificate 
  certificateKeystoreFile="same.jks"
  certificateKeystorePassword="storepass"
  certificateKeyAlias="tomcat2"
  certificateKeystoreType="JKS"
  certificateKeyPassword="keypass"
  type="RSA"
/>
-->
</SSLHostConfig>

using the config snippet tomcat fails on startup with the following excpetion:
java.lang.IllegalArgumentException: java.security.UnrecoverableKeyException: Cannot recover key
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:982)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:244)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:620)
        at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:66)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:997)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:607)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:630)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494)
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
        at sun.security.provider.KeyProtector.recover(KeyProtector.java:328)
        at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:146)
        at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:56)
        at sun.security.provider.KeyStoreDelegator.engineGetKey(KeyStoreDelegator.java:96)
        at sun.security.provider.JavaKeyStore$DualFormatJKS.engineGetKey(JavaKeyStore.java:70)
        at java.security.KeyStore.getKey(KeyStore.java:1023)
        at sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:133)
        at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
        at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256)
        at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:216)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:112)
        ... 20 more
		

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Frank Taffelt <Fr...@interface-projects.de>.
Hi Christopher,

> > # create 2 entries with different keypass for each entry keytool
> > -genkeypair -alias tomcat1 -storepass storepass  -keystore
> > different.jks  -keyalg RSA -keypass tomcat1  -ext san=dns:tomcat1
> > -dname CN=tomcat1 keytool -genkeypair -alias tomcat2 -storepass
> > storepass  -keystore different.jks  -keyalg RSA -keypass tomcat2 -ext
> > san=dns:tomcat2 -dname CN=tomcat2
> 
> What is the password for the keystore itself?

my password for the keystore has the value storepass.

> 
> > setup a SSL Connector to use that keystore:
> >
> > <Connector port="443" URIEncoding="UTF-8" scheme="https"
> > secure="true" SSLEnabled="true"
> >>
> >  <SSLHostConfig
> > ciphers="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA"
> > protocols="all">
> >
> > <!-- doesn't work, use keypass for alias tomcat2 --> <Certificate
> > certificateKeystoreFile="different.jks"
> > certificateKeystorePassword="storepass"
> > certificateKeyAlias="tomcat2" certificateKeystoreType="JKS"
> > certificateKeyPassword="tomcat2" type="RSA" />
> 
> ... and why don't you have the keystore password set, here? Or did you just
> use "changeit"?

in the attribute certificateKeystorePassword i'm using the value storepass. IMHO the password is given.

Frank

Re: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Frank,

On 6/30/17 8:43 AM, Frank Taffelt wrote:
> Hi all,
> 
> while playing with some ssl setups i stumbled upon the following
> behaviour that seems like bug to me ? As long as all keyentries in
> a keystore have the same password all is fine. Using entries with
> different password tomcat doesnt startup.
> 
> For testing: At first create 2 different keystores (same.jks and
> different.jks) having each 2 entries:
> 
> # create 2 entries with same keypass for each entry keytool
> -genkeypair -alias tomcat1 -storepass storepass  -keystore same.jks
> -keyalg RSA -keypass keypass  -ext san=dns:tomcat1 -dname
> CN=tomcat1 keytool -genkeypair -alias tomcat2 -storepass storepass
> -keystore same.jks  -keyalg RSA -keypass keypass  -ext
> san=dns:tomcat2 -dname CN=tomcat2
> 
> # create 2 entries with different keypass for each entry keytool
> -genkeypair -alias tomcat1 -storepass storepass  -keystore
> different.jks  -keyalg RSA -keypass tomcat1  -ext san=dns:tomcat1
> -dname CN=tomcat1 keytool -genkeypair -alias tomcat2 -storepass
> storepass  -keystore different.jks  -keyalg RSA -keypass tomcat2
> -ext san=dns:tomcat2 -dname CN=tomcat2

What is the password for the keystore itself?

> setup a SSL Connector to use that keystore:
> 
> <Connector port="443" URIEncoding="UTF-8" scheme="https" 
> secure="true" SSLEnabled="true"
>> 
>  <SSLHostConfig 
> ciphers="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA" 
> protocols="all">
> 
> <!-- doesn't work, use keypass for alias tomcat2 --> <Certificate 
> certificateKeystoreFile="different.jks" 
> certificateKeystorePassword="storepass" 
> certificateKeyAlias="tomcat2" certificateKeystoreType="JKS" 
> certificateKeyPassword="tomcat2" type="RSA" />

... and why don't you have the keystore password set, here? Or did you
just use "changeit"?

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJZVoa1AAoJEBzwKT+lPKRYQXMP/0QBF/wO8y3yYnJprjKDxy5i
JXI8KdEQoYfYS3JccIoBOZu684+IWKvGI2BKVqJl9cGw2jygpO0MURhUZ8UkMqhO
vyk1dX8TNmFFmdSMohR6fB0aOsf+y+RD7IqhXNRLTM/eYEJoCjtRu3eGXGVNsxyJ
yOBO2SOzKotuo/zANeSr2mQ9P2cuV9WriixdPeA1X4/4Dn30RbiIGka3b7MClvLl
fnl6c3gCcxs0CoGSnt5DevJPv3SiIUn3YAyrWLMvgUYY9k6kYRdnRc/e/mfrM02f
NTWH7JE/Jt7vZaM/ITVkfz0xJTgBMqK4Upflq2Vk3gniQgNtPWGOSsd0o4lSNTC7
xrK7mgtt1zPol5HgaYGYWAsj1QLMTQ+i6hkx1CaF0XMgoR+oGkdUZyy2GIZSkNTq
OpIRSXEg2JhU/Hkr1YkCUP62sf3mlczQGR5A3LQSXWxKmAiRMZRkSJrTV/74GKDi
jY3fwbZPHJfWLXK09/cvbacX0+xhUMNgdolEjtemnWOXypnBNs8uA9XS6MCpfH/M
op+xzvaTcQN8Bof8O/BVwmPyPdnu+/3uvxdKM/0U24W9RXFCVfXt6UYLuxre28pw
QkJcu9D1b5w82VbvXRoR1Cl/DXa5Jbls1sHge3i+7rSJWTsFNz76rw6HfdH20beE
bVPQwviGYAzH5wYhgxQz
=xLoF
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Mark Thomas <ma...@apache.org>.
On 05/07/17 11:47, Frank Taffelt wrote:
>> I don't think that will work because you can't read the key out of the
>> keystore.
> 
> The keystore API has the getKey(alias,keypass) method that should give you the key. copying the entry could be:
> 
> KeyStore newks = KeyStore.getInstance("JKS");
> newks.load(null, null);
> newks.setKeyEntry(alias,  ks.getKey(alias, keypass), keypass, ks.getCertificateChain(alias));

Neat. Thanks works nicely.

Fix committed for 9.0.x and 8.5.x

You also get your name in the commit log and the change log.

http://svn.apache.org/viewvc?rev=1800867&view=rev
http://svn.apache.org/viewvc?rev=1800868&view=rev

Thanks,

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Frank Taffelt <Fr...@interface-projects.de>.
> I don't think that will work because you can't read the key out of the
> keystore.

The keystore API has the getKey(alias,keypass) method that should give you the key. copying the entry could be:

KeyStore newks = KeyStore.getInstance("JKS");
newks.load(null, null);
newks.setKeyEntry(alias,  ks.getKey(alias, keypass), keypass, ks.getCertificateChain(alias));

hth,
Frank

Re: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Mark Thomas <ma...@apache.org>.
On 04/07/2017 07:32, Frank Taffelt wrote:
> Hi Thomas,
> 
>> By far the simplest solution is to have one keystore per private key.
> 
> so maybe this could go into the docs section.

Updated. Will be included in the next release (not the one currently
being voted on).

>> I find the JSSE API tricky to navigate at the best of times so it is possible
>> I have missed something. If I have, feel free to point me in the right
>> direction. Better yet, provide some code that shows how to use
>> KeyManagerFactory with a keystore that has multiple keys each with a different
>> password.
> 
> yes, i also wondered on the API of KMF having only one password on the init method. Could creating a runtime inmemory keystore with the keyentry from the original keystore help?

I don't think that will work because you can't read the key out of the
keystore.

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Frank Taffelt <Fr...@interface-projects.de>.
Hi Thomas,

> By far the simplest solution is to have one keystore per private key.

so maybe this could go into the docs section.

> I find the JSSE API tricky to navigate at the best of times so it is possible
> I have missed something. If I have, feel free to point me in the right
> direction. Better yet, provide some code that shows how to use
> KeyManagerFactory with a keystore that has multiple keys each with a different
> password.

yes, i also wondered on the API of KMF having only one password on the init method. Could creating a runtime inmemory keystore with the keyentry from the original keystore help?

thanks,
Frank


Re: Tomcat 8.5.16 - can't use Java keystore with multiple entries having different keypass for each entry?

Posted by Mark Thomas <ma...@apache.org>.
On 30/06/17 13:43, Frank Taffelt wrote:
> Hi all,
> 
> while playing with some ssl setups i stumbled upon the following behaviour that seems like bug to me ?
> As long as all keyentries in a keystore have the same password all is fine. Using entries with different password tomcat doesnt startup.

Thanks for the test case. It might look like just a few lines but it
saves a huge amount of time for anyone that wants to try to reproduce
what you are seeing.

I can reproduce this behaviour.

This is a limitation of the default KeyManager implementation provided
by default in Oracle JREs. The default implementation provided is
SunX509 and that explicitly only supports one key password for the
entire keystore.

As far as I can tell, there aren't any alternative implementations
provided that support multiple keys with different passwords.

In theory, if an alternative provider were available that supported
different key passwords, Tomcat could configure it appropriately
although the implementation might get interesting.

By far the simplest solution is to have one keystore per private key.

I find the JSSE API tricky to navigate at the best of times so it is
possible I have missed something. If I have, feel free to point me in
the right direction. Better yet, provide some code that shows how to use
KeyManagerFactory with a keystore that has multiple keys each with a
different password.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org