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 15:45:33 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 7a4023d78 -> 540508c6e


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


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

Branch: refs/heads/master
Commit: 540508c6ef33e77a1b2270c24b954141f9564f92
Parents: 7a4023d
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 15:45:06 2014 +0000

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


http://git-wip-us.apache.org/repos/asf/cxf/blob/540508c6/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 954eafc..17f56ae 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
@@ -193,5 +193,20 @@ public interface STSPropertiesMBean {
      * @param samlRealmCodec the SAMLRealmCodec object to use.
      */
     void setSamlRealmCodec(SAMLRealmCodec samlRealmCodec);
+    
+    /**
+     * Get whether to validate a client Public Key or Certificate presented as part of a

+     * UseKey element. This is true 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 default), 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/540508c6/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 d5c8fb8..afa611b 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 = true;
 
     /**
      * Load the CallbackHandler, Crypto objects, if necessary.
@@ -409,4 +410,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/540508c6/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 bc8d433..188cb8f 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
@@ -164,6 +164,28 @@ 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 {
+                        stsProperties.getSignatureCrypto().verifyTrust(
+                            new X509Certificate[]{receivedKey.getX509Cert()}, false);
+                    } 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 {
+                        stsProperties.getSignatureCrypto().verifyTrust(receivedKey.getPublicKey());
+                    } 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/540508c6/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 15635d9..28b731b 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
@@ -479,7 +479,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);
@@ -971,6 +971,115 @@ 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.wss4j.crypto.provider", "org.apache.wss4j.common.crypto.Merlin"
+        );
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.password", "evespass");
+        properties.put("org.apache.wss4j.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 fail as the UseKey certificate is not trusted
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected as the UseKey certificate is not trusted");
+        } catch (STSException ex) {
+            // expected
+        }
+        
+        // Now allow non-trusted UseKey certificates...
+        stsProperties.setValidateUseKey(false);
+        response = issueOperation.issue(request, webServiceContext);
+        securityTokenResponse = response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+    }
+    
     /*
      * Create a security context object
      */
@@ -1005,9 +1114,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