Repository: cxf Updated Branches: refs/heads/master 9eb8c6028 -> fc5acc612
[CXF-6279] Prototyping the initial X509 path validation code, validating it agaisnt the demo, to be enhanced at the later stage Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/fc5acc61 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/fc5acc61 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/fc5acc61 Branch: refs/heads/master Commit: fc5acc612e563d5e8d8607d0c98a61760d74ff47 Parents: 9eb8c60 Author: Sergey Beryozkin <[email protected]> Authored: Thu Mar 12 16:58:44 2015 +0000 Committer: Sergey Beryozkin <[email protected]> Committed: Thu Mar 12 16:58:44 2015 +0000 ---------------------------------------------------------------------- .../security/jose/jaxrs/KeyManagementUtils.java | 55 ++++++++++++++++---- .../cxf/rs/security/jose/jwe/JweUtils.java | 8 +++ .../cxf/rs/security/jose/jws/JwsUtils.java | 8 +++ 3 files changed, 60 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/fc5acc61/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java index a246a14..cad54f8 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java @@ -24,7 +24,15 @@ import java.security.KeyStore; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.cert.CertPath; +import java.security.cert.CertPathBuilder; +import java.security.cert.CertPathBuilderResult; +import java.security.cert.CertPathValidator; +import java.security.cert.CertStore; import java.security.cert.Certificate; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; @@ -36,6 +44,7 @@ import java.util.Properties; import org.apache.cxf.Bus; import org.apache.cxf.common.util.PropertyUtils; import org.apache.cxf.common.util.crypto.CryptoUtils; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.jaxrs.utils.ResourceUtils; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageUtils; @@ -237,12 +246,32 @@ public final class KeyManagementUtils { throw new SecurityException(ex); } } - //TODO: validate the chain return certs; } else { return null; } } + public static void validateCertificateChain(Properties storeProperties, List<X509Certificate> inCerts) { + KeyStore ks = loadPersistKeyStore(JAXRSUtils.getCurrentMessage(), storeProperties); + validateCertificateChain(ks, inCerts); + } + public static void validateCertificateChain(KeyStore ks, List<X509Certificate> inCerts) { + // Initial chain validation, to be enhanced as needed + try { + X509CertSelector certSelect = new X509CertSelector(); + certSelect.setCertificate((X509Certificate) inCerts.get(0)); + PKIXBuilderParameters pbParams = new PKIXBuilderParameters(ks, certSelect); + pbParams.addCertStore(CertStore.getInstance("Collection", + new CollectionCertStoreParameters(inCerts))); + pbParams.setMaxPathLength(-1); + pbParams.setRevocationEnabled(false); + CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); + CertPath certPath = buildResult.getCertPath(); + CertPathValidator.getInstance("PKIX").validate(certPath, pbParams); + } catch (Exception ex) { + throw new SecurityException(ex); + } + } public static X509Certificate[] toX509CertificateChainArray(List<String> base64EncodedChain) { List<X509Certificate> chain = toX509CertificateChain(base64EncodedChain); return chain == null ? null : chain.toArray(new X509Certificate[]{}); @@ -290,21 +319,25 @@ public final class KeyManagementUtils { return props; } public static RSAPrivateKey loadPrivateKey(Message m, Properties props, - List<X509Certificate> inCert, String keyOper) { - KeyStore keyStore = loadPersistKeyStore(m, props); + List<X509Certificate> inCerts, String keyOper) { + KeyStore ks = loadPersistKeyStore(m, props); + try { - Object[] inCertArray = inCert.toArray(); - // perhaps inCert properties can be optionally used as aliases - for (Enumeration<String> e = keyStore.aliases(); e.hasMoreElements();) { - String alias = e.nextElement(); - X509Certificate[] chain = loadX509CertificateOrChain(keyStore, alias); - if (chain != null && Arrays.equals(chain, inCertArray)) { - return loadPrivateKey(keyStore, m, props, keyOper, alias); + String alias = ks.getCertificateAlias(inCerts.get(0)); + if (alias != null) { + for (Enumeration<String> e = ks.aliases(); e.hasMoreElements();) { + String currentAlias = e.nextElement(); + X509Certificate[] currentCertArray = loadX509CertificateOrChain(ks, currentAlias); + if (currentCertArray != null) { + alias = currentAlias; + break; + } } } + return loadPrivateKey(ks, m, props, keyOper, alias); + } catch (Exception ex) { throw new SecurityException(ex); } - return null; } } http://git-wip-us.apache.org/repos/asf/cxf/blob/fc5acc61/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java index 5389205..95aa785 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java @@ -320,6 +320,7 @@ public final class JweUtils { //TODO: optionally validate inHeaders.getAlgorithm against a property in props // Supporting loading a private key via a certificate for now List<X509Certificate> chain = KeyManagementUtils.toX509CertificateChain(inHeaders.getX509Chain()); + KeyManagementUtils.validateCertificateChain(props, chain); RSAPrivateKey privateKey = KeyManagementUtils.loadPrivateKey(m, props, chain, JsonWebKey.KEY_OPER_DECRYPT); contentEncryptionAlgo = inHeaders.getContentEncryptionAlgorithm(); @@ -589,4 +590,11 @@ public final class JweUtils { private static JweHeaders toJweHeaders(String ct) { return new JweHeaders(Collections.<String, Object>singletonMap(JoseConstants.HEADER_CONTENT_TYPE, ct)); } + public static void validateJweCertificateChain(List<X509Certificate> certs) { + + Message m = JAXRSUtils.getCurrentMessage(); + Properties props = KeyManagementUtils.loadStoreProperties(m, true, + RSSEC_ENCRYPTION_IN_PROPS, RSSEC_ENCRYPTION_PROPS); + KeyManagementUtils.validateCertificateChain(props, certs); + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/fc5acc61/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java index 0727cc6..f66087f 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java @@ -260,6 +260,7 @@ public final class JwsUtils { return getSignatureVerifier(publicJwk, inHeaders.getAlgorithm()); } else if (inHeaders.getHeader(JoseConstants.HEADER_X509_CHAIN) != null) { List<X509Certificate> chain = KeyManagementUtils.toX509CertificateChain(inHeaders.getX509Chain()); + KeyManagementUtils.validateCertificateChain(props, chain); return getRSAKeySignatureVerifier((RSAPublicKey)chain.get(0).getPublicKey(), inHeaders.getAlgorithm()); } } @@ -323,4 +324,11 @@ public final class JwsUtils { jws.signWith(jwsSig); return jws.getSignedEncodedJws(); } + public static void validateJwsCertificateChain(List<X509Certificate> certs) { + + Message m = JAXRSUtils.getCurrentMessage(); + Properties props = KeyManagementUtils.loadStoreProperties(m, true, + RSSEC_SIGNATURE_IN_PROPS, RSSEC_SIGNATURE_PROPS); + KeyManagementUtils.validateCertificateChain(props, certs); + } }
