Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 13A2F200CAD for ; Wed, 14 Jun 2017 04:33:10 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 12446160BEB; Wed, 14 Jun 2017 02:33:10 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 0B32C160BDC for ; Wed, 14 Jun 2017 04:33:08 +0200 (CEST) Received: (qmail 71571 invoked by uid 500); 14 Jun 2017 02:33:08 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 71561 invoked by uid 99); 14 Jun 2017 02:33:08 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 14 Jun 2017 02:33:08 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 0BDBBDFF15; Wed, 14 Jun 2017 02:33:07 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ffang@apache.org To: commits@cxf.apache.org Date: Wed, 14 Jun 2017 02:33:07 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cxf git commit: [CXF-7401]CXF http-jetty fails to get private key if the jks keystore file contains multiple private keys with different password archived-at: Wed, 14 Jun 2017 02:33:10 -0000 Repository: cxf Updated Branches: refs/heads/3.1.x-fixes 6ed365ef2 -> 07ee787c4 [CXF-7401]CXF http-jetty fails to get private key if the jks keystore file contains multiple private keys with different password (cherry picked from commit e877d30982ae970738495160090a8e948f33c199) Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a11b4b53 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a11b4b53 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a11b4b53 Branch: refs/heads/3.1.x-fixes Commit: a11b4b530f18d5d87e9bca3d7b2f6a71bcf0d00c Parents: 4fd67ac Author: Freeman Fang Authored: Tue Jun 13 16:36:37 2017 +0800 Committer: Freeman Fang Committed: Tue Jun 13 19:15:48 2017 +0800 ---------------------------------------------------------------------- .../jsse/MultiKeyPasswordKeyManager.java | 83 +++++++++++++++++++ .../jsse/TLSClientParametersConfig.java | 10 ++- .../jsse/TLSParameterJaxBUtils.java | 36 ++++++++ .../jsse/TLSServerParametersConfig.java | 10 ++- .../cxf/systest/https/conduit/jaxws-server.xml | 8 +- .../src/test/resources/keys/MultipleKeys.jks | Bin 0 -> 4391 bytes 6 files changed, 139 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/a11b4b53/core/src/main/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java b/core/src/main/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java new file mode 100644 index 0000000..c6dcbc9 --- /dev/null +++ b/core/src/main/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java @@ -0,0 +1,83 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.configuration.jsse; + +import java.net.Socket; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import javax.net.ssl.X509KeyManager; + +public class MultiKeyPasswordKeyManager implements X509KeyManager { + private final KeyStore mKeyStore; + private final String mKeyAlias; + private final String mKeyPassword; + + public MultiKeyPasswordKeyManager(KeyStore keystore, String keyAlias, String keyPassword) { + mKeyStore = keystore; + mKeyAlias = keyAlias; + mKeyPassword = keyPassword; + } + + public String[] getClientAliases(String keyType, Principal[] issuers) { + return new String[] { + mKeyAlias + }; + } + + public String[] getServerAliases(String keyType, Principal[] issuers) { + return new String[] { + mKeyAlias + }; + } + public X509Certificate[] getCertificateChain(String alias) { + Certificate[] chain = null; + try { + chain = mKeyStore.getCertificateChain(alias); + } catch (KeyStoreException kse) { + throw new RuntimeException(kse); + } + final X509Certificate[] certChain = new X509Certificate[chain.length]; + for (int i = 0; i < chain.length; i++) { + certChain[i] = (X509Certificate)chain[i]; + } + return certChain; + } + + public PrivateKey getPrivateKey(String alias) { + try { + return (PrivateKey)mKeyStore.getKey(alias, mKeyPassword.toCharArray()); + } catch (GeneralSecurityException gse) { + throw new RuntimeException(gse); + } + } + + public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { + return mKeyAlias; + } + + public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { + return mKeyAlias; + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/a11b4b53/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java index d39d526..2f920b6 100644 --- a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java +++ b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java @@ -108,8 +108,14 @@ public final class TLSClientParametersConfig { params.getSecureRandomParameters())); } if (params.isSetKeyManagers() && !usingDefaults) { - ret.setKeyManagers( - TLSParameterJaxBUtils.getKeyManagers(params.getKeyManagers())); + if (!params.isSetCertAlias()) { + ret.setKeyManagers( + TLSParameterJaxBUtils.getKeyManagers(params.getKeyManagers())); + } else { + ret.setKeyManagers( + TLSParameterJaxBUtils.getKeyManagers(params.getKeyManagers(), + params.getCertAlias())); + } } if (params.isSetTrustManagers() && !usingDefaults) { ret.setTrustManagers( http://git-wip-us.apache.org/repos/asf/cxf/blob/a11b4b53/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java index 7ab9391..475e195 100644 --- a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java +++ b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java @@ -297,6 +297,42 @@ public final class TLSParameterJaxBUtils { return fac.getKeyManagers(); } + + /** + * This method converts the JAXB KeyManagersType into a list of + * JSSE KeyManagers. + */ + public static KeyManager[] getKeyManagers(KeyManagersType kmc, String alias) + throws GeneralSecurityException, + IOException { + + KeyStore keyStore = getKeyStore(kmc.getKeyStore(), false); + + String alg = kmc.isSetFactoryAlgorithm() + ? kmc.getFactoryAlgorithm() + : KeyManagerFactory.getDefaultAlgorithm(); + + char[] keyPass = getKeyPassword(kmc); + + KeyManagerFactory fac = + kmc.isSetProvider() + ? KeyManagerFactory.getInstance(alg, kmc.getProvider()) + : KeyManagerFactory.getInstance(alg); + + try { + fac.init(keyStore, keyPass); + + return fac.getKeyManagers(); + } catch (java.security.UnrecoverableKeyException uke) { + //jsse has the restriction that different key in keystore + //cannot has different password, use MultiKeyPasswordKeyManager + //as fallback when this happen + MultiKeyPasswordKeyManager manager + = new MultiKeyPasswordKeyManager(keyStore, alias, + new String(keyPass)); + return new KeyManager[]{manager}; + } + } private static char[] getKeyPassword(KeyManagersType kmc) { char[] keyPass = kmc.isSetKeyPassword() http://git-wip-us.apache.org/repos/asf/cxf/blob/a11b4b53/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java index e4c4cad..9ca37aa 100644 --- a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java +++ b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java @@ -72,8 +72,14 @@ public class TLSServerParametersConfig this.setClientAuthentication(params.getClientAuthentication()); } if (params.isSetKeyManagers()) { - this.setKeyManagers( - TLSParameterJaxBUtils.getKeyManagers(params.getKeyManagers())); + if (!params.isSetCertAlias()) { + this.setKeyManagers( + TLSParameterJaxBUtils.getKeyManagers(params.getKeyManagers())); + } else { + this.setKeyManagers( + TLSParameterJaxBUtils.getKeyManagers(params.getKeyManagers(), + params.getCertAlias())); + } } if (params.isSetTrustManagers()) { this.setTrustManagers( http://git-wip-us.apache.org/repos/asf/cxf/blob/a11b4b53/systests/transports/src/test/resources/org/apache/cxf/systest/https/conduit/jaxws-server.xml ---------------------------------------------------------------------- diff --git a/systests/transports/src/test/resources/org/apache/cxf/systest/https/conduit/jaxws-server.xml b/systests/transports/src/test/resources/org/apache/cxf/systest/https/conduit/jaxws-server.xml index 2ded663..680af5f 100644 --- a/systests/transports/src/test/resources/org/apache/cxf/systest/https/conduit/jaxws-server.xml +++ b/systests/transports/src/test/resources/org/apache/cxf/systest/https/conduit/jaxws-server.xml @@ -49,8 +49,8 @@ under the License. - - + + @@ -65,8 +65,8 @@ under the License. - - + + http://git-wip-us.apache.org/repos/asf/cxf/blob/a11b4b53/testutils/src/test/resources/keys/MultipleKeys.jks ---------------------------------------------------------------------- diff --git a/testutils/src/test/resources/keys/MultipleKeys.jks b/testutils/src/test/resources/keys/MultipleKeys.jks new file mode 100644 index 0000000..9e6c477 Binary files /dev/null and b/testutils/src/test/resources/keys/MultipleKeys.jks differ