cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject git commit: Validate trust in a public key credential supplied for UseKey in the STS
Date Wed, 05 Mar 2014 16:15:58 GMT
Repository: cxf
Updated Branches:
  refs/heads/2.7.x-fixes 0b9b72228 -> 5b8daa322


Validate trust in a public key credential supplied for UseKey in the STS

Conflicts:
	services/sts/sts-core/src/main/java/org/apache/cxf/sts/STSPropertiesMBean.java


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5b8daa32
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5b8daa32
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5b8daa32

Branch: refs/heads/2.7.x-fixes
Commit: 5b8daa3229069f49907bd51cdcc45255cba1a492
Parents: 0b9b722
Author: Colm O hEigeartaigh <coheigea@apache.org>
Authored: Wed Mar 5 15:44:43 2014 +0000
Committer: Colm O hEigeartaigh <coheigea@apache.org>
Committed: Wed Mar 5 16:15:48 2014 +0000

----------------------------------------------------------------------
 .../org/apache/cxf/sts/STSPropertiesMBean.java  |  15 +++
 .../org/apache/cxf/sts/StaticSTSProperties.java |  20 ++++
 .../token/provider/DefaultSubjectProvider.java  |  28 +++++
 .../cxf/sts/operation/IssueSamlUnitTest.java    | 116 ++++++++++++++++++-
 4 files changed, 176 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/5b8daa32/services/sts/sts-core/src/main/java/org/apache/cxf/sts/STSPropertiesMBean.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/STSPropertiesMBean.java
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/STSPropertiesMBean.java
index 89439cb..3d0110b 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/STSPropertiesMBean.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/STSPropertiesMBean.java
@@ -195,4 +195,19 @@ public interface STSPropertiesMBean {
      */
     void setSamlRealmCodec(SAMLRealmCodec samlRealmCodec);
     
+    /**
+     * Get whether to validate a client Public Key or Certificate presented as part of a

+     * UseKey element. This is false by default.
+     */
+    boolean isValidateUseKey();
+    
+    /**
+     * Set whether to validate a client Public Key or Certificate presented as part of a

+     * UseKey element. If this is set to true, the public key must be trusted
+     * by the Signature Crypto of the STS.
+     * 
+     * @param validateUseKey whether to validate a client UseKey or not.
+     */
+    void setValidateUseKey(boolean validateUseKey);
+
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/5b8daa32/services/sts/sts-core/src/main/java/org/apache/cxf/sts/StaticSTSProperties.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/StaticSTSProperties.java
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/StaticSTSProperties.java
index 06486c7..a9da700 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/StaticSTSProperties.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/StaticSTSProperties.java
@@ -66,6 +66,7 @@ public class StaticSTSProperties implements STSPropertiesMBean {
     private RelationshipResolver relationshipResolver;
     private SAMLRealmCodec samlRealmCodec;
     private Bus bus;
+    private boolean validateUseKey;
 
 
 
@@ -411,4 +412,23 @@ public class StaticSTSProperties implements STSPropertiesMBean {
     public void setBus(Bus bus) {
         this.bus = bus;
     }
+    
+    /**
+     * Get whether to validate a client Public Key or Certificate presented as part of a

+     * UseKey element. This is true by default.
+     */
+    public boolean isValidateUseKey() {
+        return validateUseKey;
+    }
+    
+    /**
+     * Set whether to validate a client Public Key or Certificate presented as part of a

+     * UseKey element. If this is set to true (the default), the public key must be trusted
+     * by the Signature Crypto of the STS.
+     * 
+     * @param validateUseKey whether to validate a client UseKey or not.
+     */
+    public void setValidateUseKey(boolean validateUseKey) {
+        this.validateUseKey = validateUseKey;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/5b8daa32/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
index 4c4ccb7..cea3bdf 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
@@ -151,6 +151,34 @@ public class DefaultSubjectProvider implements SubjectProvider {
             }
         } else if (STSConstants.PUBLIC_KEY_KEYTYPE.equals(keyType)) {
             ReceivedKey receivedKey = keyRequirements.getReceivedKey();
+            
+            // Validate UseKey trust
+            if (stsProperties.isValidateUseKey() && stsProperties.getSignatureCrypto()
!= null) {
+                if (receivedKey.getX509Cert() != null) {
+                    try {
+                        if (!stsProperties.getSignatureCrypto().verifyTrust(
+                            new X509Certificate[]{receivedKey.getX509Cert()}, false)) {
+                            LOG.log(Level.FINE, "Error in trust validation of UseKey");
+                            throw new STSException("Error in trust validation of UseKey",
STSException.REQUEST_FAILED);
+                        }
+                    } catch (WSSecurityException e) {
+                        LOG.log(Level.FINE, "Error in trust validation of UseKey: ", e);
+                        throw new STSException("Error in trust validation of UseKey", STSException.REQUEST_FAILED);
+                    }
+                }
+                if (receivedKey.getPublicKey() != null) {
+                    try {
+                        if (!stsProperties.getSignatureCrypto().verifyTrust(receivedKey.getPublicKey()))
{
+                            LOG.log(Level.FINE, "Error in trust validation of UseKey");
+                            throw new STSException("Error in trust validation of UseKey",
STSException.REQUEST_FAILED);
+                        }
+                    } catch (WSSecurityException e) {
+                        LOG.log(Level.FINE, "Error in trust validation of UseKey: ", e);
+                        throw new STSException("Error in trust validation of UseKey", STSException.REQUEST_FAILED);
+                    }
+                }
+            }
+            
             KeyInfoBean keyInfo = createKeyInfo(receivedKey.getX509Cert(), receivedKey.getPublicKey());
             subjectBean.setKeyInfo(keyInfo);
         }

http://git-wip-us.apache.org/repos/asf/cxf/blob/5b8daa32/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
index bdd94bf..e6023ac 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
@@ -478,7 +478,7 @@ public class IssueSamlUnitTest extends org.junit.Assert {
         }
         
         // Now add UseKey
-        UseKeyType useKey = createUseKey(crypto);
+        UseKeyType useKey = createUseKey(crypto, "myclientkey");
         JAXBElement<UseKeyType> useKeyType = 
             new JAXBElement<UseKeyType>(QNameConstants.USE_KEY, UseKeyType.class, useKey);
         request.getAny().add(useKeyType);
@@ -966,6 +966,116 @@ public class IssueSamlUnitTest extends org.junit.Assert {
         assertTrue(tokenString.contains(WSConstants.C14N_EXCL_WITH_COMMENTS));
     }
     
+    /**
+     * Test to UseKey validation
+     */
+    @org.junit.Test
+    public void testUseKey() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new SAMLTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        STSPropertiesMBean stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(crypto);
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML2_TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        JAXBElement<String> keyType = 
+            new JAXBElement<String>(
+                QNameConstants.KEY_TYPE, String.class, STSConstants.PUBLIC_KEY_KEYTYPE
+            );
+        request.getAny().add(keyType);
+        
+        UseKeyType useKey = createUseKey(crypto, "myclientkey");
+        JAXBElement<UseKeyType> useKeyType = 
+            new JAXBElement<UseKeyType>(QNameConstants.USE_KEY, UseKeyType.class, useKey);
+        request.getAny().add(useKeyType);
+        
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        msgCtx.put(
+            SecurityContext.class.getName(), 
+            createSecurityContext(new CustomTokenPrincipal("alice"))
+        );
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        // Test the generated token.
+        Element assertion = null;
+        for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName()))
{
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                assertion = (Element)rstType.getAny();
+            }
+        }
+        
+        String tokenString = DOM2Writer.nodeToString(assertion);
+        assertTrue(tokenString.contains("AttributeStatement"));
+        assertTrue(tokenString.contains("alice"));
+        assertTrue(tokenString.contains(SAML2Constants.CONF_HOLDER_KEY));
+        
+        // Now remove the UseKey + send a non-trusted UseKey certificate
+        request.getAny().remove(useKeyType);
+        
+        Properties properties = new Properties();
+        properties.put(
+            "org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"
+        );
+        properties.put("org.apache.ws.security.crypto.merlin.keystore.password", "evespass");
+        properties.put("org.apache.ws.security.crypto.merlin.keystore.file", "eve.jks");
+        
+        useKey = createUseKey(CryptoFactory.getInstance(properties), "eve");
+        useKeyType = new JAXBElement<UseKeyType>(QNameConstants.USE_KEY, UseKeyType.class,
useKey);
+        request.getAny().add(useKeyType);
+        
+        // This should work as non-trusted certificates are allowed
+        response = issueOperation.issue(request, webServiceContext);
+        securityTokenResponse = response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+
+        // This should fail as the UseKey certificate is not trusted
+        stsProperties.setValidateUseKey(true);
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected as the UseKey certificate is not trusted");
+        } catch (STSException ex) {
+            // expected
+        }
+        
+    }
+    
     /*
      * Create a security context object
      */
@@ -1000,9 +1110,9 @@ public class IssueSamlUnitTest extends org.junit.Assert {
     /*
      * Mock up a UseKeyType object
      */
-    private UseKeyType createUseKey(Crypto crypto) throws Exception {
+    private UseKeyType createUseKey(Crypto crypto, String alias) throws Exception {
         CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
-        cryptoType.setAlias("myclientkey");
+        cryptoType.setAlias(alias);
         X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
         Document doc = DOMUtils.createDocument();
         Element x509Data = doc.createElementNS(WSConstants.SIG_NS, "ds:X509Data");


Mime
View raw message