Joe Luo created CXF-7401:
----------------------------

             Summary: CXF http-jetty failed to get private key if the jks 
keystore file contains multiple private keys with different password 
                 Key: CXF-7401
                 URL: https://issues.apache.org/jira/browse/CXF-7401
             Project: CXF
          Issue Type: Bug
          Components: Transports
    Affects Versions: 3.1.5
            Reporter: Joe Luo


I have a camel-cxf endpoint and it uses http-jetty transport over SSL 
connection. However, the JKS keystore I used contains multiple private keys and 
each of them has different password. 
{code}
$ keytool -list -keystore jboss.keystore.jks
Enter keystore password:  

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 3 entries

jboss, 08-Jun-2017, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 
55:2F:EC:00:58:3C:C0:0C:A2:04:7C:46:BC:71:86:B2:A6:3B:21:01
client, 08-Jun-2017, trustedCertEntry, 
Certificate fingerprint (SHA1): 
E2:29:BE:E9:74:BE:5F:58:C1:59:C0:CE:AA:1C:BF:29:93:94:5A:A9
test, 08-Jun-2017, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 
60:58:4F:7C:A4:58:D4:60:C0:B4:07:17:D5:CF:B0:78:E6:9D:C4:6B
{code}

So the keystore jboss.keystore.jks has a store password "secret" and if both 
private key alias "jboss" and private key alias "test" have the same password, 
say "changit", then it worked fine.   

Here was my http-jetty transport configuration:
{code}
<httpj:engine-factory>
        <httpj:engine port="9001">
            <httpj:tlsServerParameters>
                <sec:certAlias>jboss</sec:certAlias>
                <sec:keyManagers keyPassword="changit">
                    <sec:keyStore type="JKS" password="secret"
                         file="src/main/resources/keys/jboss.keystore.jks"/>
                </sec:keyManagers>
                <sec:trustManagers>
                    <sec:keyStore type="JKS" password="secret"
                         file="src/main/resources/keys/jboss.keystore.jks"/>
                </sec:trustManagers>
                <sec:cipherSuitesFilter>
                    <sec:include>.*_EXPORT_.*</sec:include>
                    <sec:include>.*_EXPORT1024_.*</sec:include>
                    <sec:include>.*_WITH_DES_.*</sec:include>
                    <sec:include>.*_WITH_AES_.*</sec:include>
                    <sec:include>.*_WITH_NULL_.*</sec:include>
                    <sec:exclude>.*_DH_anon_.*</sec:exclude>
                </sec:cipherSuitesFilter>
                <sec:clientAuthentication want="true" required="true"/>
            </httpj:tlsServerParameters>
        </httpj:engine>
    </httpj:engine-factory>
{code}

However, if I the two private keys have different key password, for instance, 
if I change the private key "test" key password from the "changit" to 
"password", which is different from the password of the private key "jboss", 
then I am getting following error when I tried to start it:
{code}
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.cxf.configuration.jsse.TLSParameterJaxBUtils.getKeyManagers(TLSParameterJaxBUtils.java:272)
        at 
org.apache.cxf.configuration.jsse.TLSServerParametersConfig.<init>(TLSServerParametersConfig.java:75)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at 
org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
...
{code}

The JIRA https://issues.apache.org/jira/browse/CXF-4204 introduced the feature 
to allow specifying the cert alias name in TLSServerParameters. But even with 
the <sec:certAlias> element specified in my http-jetty transport configuration, 
it still fails. 



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to