Repository: cxf Updated Branches: refs/heads/3.0.x-fixes 24be0b75a -> d435640fd
Support keys stored as SHA-1 digests in JWS headers Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/f1f87071 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/f1f87071 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/f1f87071 Branch: refs/heads/3.0.x-fixes Commit: f1f87071057fdb98e2d25d4f19b3a0f984e2e86f Parents: 24be0b7 Author: Colm O hEigeartaigh <[email protected]> Authored: Fri Oct 23 15:26:09 2015 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Fri Oct 23 17:29:39 2015 +0100 ---------------------------------------------------------------------- .../jose/common/KeyManagementUtils.java | 52 ++++++++++++++++++++ .../cxf/rs/security/jose/jws/JwsUtils.java | 10 ++++ 2 files changed, 62 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/f1f87071/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java index 04b56b4..c491712 100644 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java +++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java @@ -21,6 +21,7 @@ package org.apache.cxf.rs.security.jose.common; import java.io.InputStream; import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; @@ -45,6 +46,7 @@ import java.util.logging.Logger; import org.apache.cxf.Bus; import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.Base64Exception; import org.apache.cxf.common.util.Base64UrlUtility; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageUtils; @@ -390,4 +392,54 @@ public final class KeyManagementUtils { throw new JoseException(ex); } } + + public static X509Certificate getCertificateFromThumbprint(String thumbprint, + String digestAlgorithm, + Message m, + Properties props) { + KeyStore ks = loadPersistKeyStore(m, props); + if (ks == null || thumbprint == null) { + return null; + } + + try { + byte[] decodedThumbprint = Base64UrlUtility.decode(thumbprint); + + for (Enumeration<String> e = ks.aliases(); e.hasMoreElements();) { + String alias = e.nextElement(); + Certificate[] certs = ks.getCertificateChain(alias); + if (certs == null || certs.length == 0) { + // no cert chain, so lets check if getCertificate gives us a result. + Certificate cert = ks.getCertificate(alias); + if (cert != null) { + certs = new Certificate[]{cert}; + } + } + + if (certs != null && certs.length > 0 && certs[0] instanceof X509Certificate) { + X509Certificate x509cert = (X509Certificate) certs[0]; + byte[] data = + MessageDigestUtils.createDigest(x509cert.getEncoded(), digestAlgorithm); + + if (Arrays.equals(data, decodedThumbprint)) { + return x509cert; + } + } + } + } catch (KeyStoreException e) { + LOG.log(Level.WARNING, "X509Certificate can not be loaded: ", e); + throw new JoseException(e); + } catch (CertificateEncodingException e) { + LOG.log(Level.WARNING, "X509Certificate can not be loaded: ", e); + throw new JoseException(e); + } catch (NoSuchAlgorithmException e) { + LOG.log(Level.WARNING, "X509Certificate can not be loaded: ", e); + throw new JoseException(e); + } catch (Base64Exception e) { + LOG.log(Level.WARNING, "X509Certificate can not be loaded: ", e); + throw new JoseException(e); + } + + return null; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/f1f87071/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java index f5db51b..b3e0a99 100644 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java +++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java @@ -49,6 +49,7 @@ import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; import org.apache.cxf.rs.security.jose.jwk.JwkUtils; import org.apache.cxf.rs.security.jose.jwk.KeyOperation; import org.apache.cxf.rs.security.jose.jwk.KeyType; +import org.apache.cxf.rt.security.crypto.MessageDigestUtils; public final class JwsUtils { private static final Logger LOG = LogUtils.getL7dLogger(JwsUtils.class); @@ -346,6 +347,15 @@ public final class JwsUtils { KeyManagementUtils.validateCertificateChain(props, chain); return getPublicKeySignatureVerifier(chain.get(0).getPublicKey(), inHeaders.getSignatureAlgorithm()); + } else if (inHeaders.getHeader(JoseConstants.HEADER_X509_THUMBPRINT) != null) { + X509Certificate foundCert = + KeyManagementUtils.getCertificateFromThumbprint(inHeaders.getX509Thumbprint(), + MessageDigestUtils.ALGO_SHA_1, + m, props); + if (foundCert != null) { + return getPublicKeySignatureVerifier(foundCert.getPublicKey(), + inHeaders.getSignatureAlgorithm()); + } } }
