CXF-7084 - Dynamically load signature validation keys using KeyName. Thanks to Hugo Trippaers for the patch. This closes #177.
# Conflicts: # rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5c902609 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5c902609 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5c902609 Branch: refs/heads/3.1.x-fixes Commit: 5c9026090b50184a06842e5d25e98ab847a63545 Parents: a754efa Author: Colm O hEigeartaigh <[email protected]> Authored: Wed Mar 29 10:25:00 2017 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Wed Mar 29 10:26:20 2017 +0100 ---------------------------------------------------------------------- .../rs/security/xml/SignatureProperties.java | 16 ++++++++ .../rs/security/xml/XmlSecInInterceptor.java | 41 ++++++++++++++++++++ .../jaxrs/security/xml/JAXRSXmlSecTest.java | 2 +- .../systest/jaxrs/security/xml/stax-server.xml | 12 +++++- 4 files changed, 69 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/5c902609/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/SignatureProperties.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/SignatureProperties.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/SignatureProperties.java index 8c861ab..235d70e 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/SignatureProperties.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/SignatureProperties.java @@ -18,6 +18,8 @@ */ package org.apache.cxf.rs.security.xml; +import java.util.Map; + public class SignatureProperties { private String signatureAlgo; private String signatureDigestAlgo; @@ -25,6 +27,7 @@ public class SignatureProperties { private String signatureC14nTransform; private String signatureKeyIdType; private String signatureKeyName; + private Map<String, String> keyNameAliasMap; public void setSignatureAlgo(String signatureAlgo) { this.signatureAlgo = signatureAlgo; @@ -79,4 +82,17 @@ public class SignatureProperties { this.signatureKeyName = signatureKeyName; } + public Map<String, String> getKeyNameAliasMap() { + return keyNameAliasMap; + } + + /** + * Set the Signature KeyName alias lookup map. It is used on the receiving side for signature. + * It maps a KeyName to a key alias - so it allows us to associate a (e.g.) key alias in + * a keystore with a given KeyName contained in a KeyInfo structure of the Signature. + */ + public void setKeyNameAliasMap(Map<String, String> keyNameAliasMap) { + this.keyNameAliasMap = keyNameAliasMap; + } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/5c902609/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java index 3341793..0a98835 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -66,6 +67,7 @@ import org.apache.xml.security.stax.ext.InboundXMLSec; import org.apache.xml.security.stax.ext.XMLSec; import org.apache.xml.security.stax.ext.XMLSecurityConstants; import org.apache.xml.security.stax.ext.XMLSecurityProperties; +import org.apache.xml.security.stax.impl.securityToken.KeyNameSecurityToken; import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent; import org.apache.xml.security.stax.securityEvent.SecurityEvent; import org.apache.xml.security.stax.securityEvent.SecurityEventConstants; @@ -216,7 +218,19 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> imple if (certs != null && certs.length > 0) { properties.setSignatureVerificationKey(certs[0].getPublicKey()); } + } else if (sigCrypto != null && sigProps != null && sigProps.getKeyNameAliasMap() != null) { + Map<String, String> keyNameAliasMap = sigProps.getKeyNameAliasMap(); + for (Map.Entry<String, String> mapping: keyNameAliasMap.entrySet()) { + CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS); + cryptoType.setAlias(mapping.getValue()); + X509Certificate[] certs = sigCrypto.getX509Certificates(cryptoType); + if (certs != null && certs.length > 0) { + properties.addKeyNameMapping(mapping.getKey(), certs[0].getPublicKey()); + } + } } + + } protected SecurityEventListener configureSecurityEventListener( @@ -300,6 +314,10 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> imple SecurityToken token = event.getSecurityToken(); if (token != null) { X509Certificate[] certs = token.getX509Certificates(); + if (certs == null && token.getPublicKey() == null && token instanceof KeyNameSecurityToken) { + certs = getX509CertificatesForKeyName(sigCrypto, msg, (KeyNameSecurityToken)token); + } + PublicKey publicKey = token.getPublicKey(); X509Certificate cert = null; if (certs != null && certs.length > 0) { @@ -320,7 +338,30 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> imple } } } +<<<<<<< HEAD +======= + + private X509Certificate[] getX509CertificatesForKeyName(Crypto sigCrypto, Message msg, KeyNameSecurityToken token) + throws XMLSecurityException { + X509Certificate[] certs; + KeyNameSecurityToken keyNameSecurityToken = token; + String keyName = keyNameSecurityToken.getKeyName(); + String alias = null; + if (sigProps != null && sigProps.getKeyNameAliasMap() != null) { + alias = sigProps.getKeyNameAliasMap().get(keyName); + } + try { + certs = RSSecurityUtils.getCertificates(sigCrypto, alias); + } catch (Exception e) { + throw new XMLSecurityException("empty", new Object[] {"Error during Signature Trust " + + "validation"}); + } + return certs; + } + + +>>>>>>> 2ea81b5... CXF-7084 - Dynamically load signature validation keys using KeyName. protected void throwFault(String error, Exception ex) { LOG.warning(error); Response response = JAXRSUtils.toResponseBuilder(400).entity(error).build(); http://git-wip-us.apache.org/repos/asf/cxf/blob/5c902609/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java index 4bdf54f..e464a4c 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java @@ -424,7 +424,7 @@ public class JAXRSXmlSecTest extends AbstractBusClientServerTestBase { sigOutInterceptor.setKeyInfoMustBeAvailable(true); SignatureProperties sigProps = new SignatureProperties(); - sigProps.setSignatureKeyName("alice"); + sigProps.setSignatureKeyName("alice-kn"); sigProps.setSignatureKeyIdType("KeyName"); sigOutInterceptor.setSignatureProperties(sigProps); http://git-wip-us.apache.org/repos/asf/cxf/blob/5c902609/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml index 68816c0..b129ef3 100644 --- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml +++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml @@ -148,12 +148,22 @@ under the License. </jaxrs:properties> </jaxrs:server> + <util:map id="keyNameMap"> + <entry key="alice-kn" value="alice" /> + </util:map> + <bean id="keyNameSigProps" class="org.apache.cxf.rs.security.xml.SignatureProperties"> + <property name="keyNameAliasMap" ref="keyNameMap"/> + </bean> + <bean id="xmlSecInHandlerKeyName" class="org.apache.cxf.rs.security.xml.XmlSecInInterceptor"> + <property name="signatureProperties" ref="keyNameSigProps"/> + <property name="requireSignature" value="true"/> + </bean> <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-xmlsec-stax}/xmlsigkeyname"> <jaxrs:serviceBeans> <ref bean="serviceBean"/> </jaxrs:serviceBeans> <jaxrs:inInterceptors> - <ref bean="xmlSigInHandler"/> + <ref bean="xmlSecInHandlerKeyName"/> </jaxrs:inInterceptors> <jaxrs:outInterceptors> <ref bean="xmlSigOutHandler"/>
