You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2011/08/19 17:07:18 UTC

svn commit: r1159658 - in /webservices/wss4j/trunk/src: main/java/org/apache/ws/security/ main/java/org/apache/ws/security/message/ main/java/org/apache/ws/security/str/ test/java/org/apache/ws/security/message/token/

Author: coheigea
Date: Fri Aug 19 15:07:18 2011
New Revision: 1159658

URL: http://svn.apache.org/viewvc?rev=1159658&view=rev
Log:
[WSS-307] - Added support for signature verification using a Key Identifier to a Kerberos Token and added a test.

Modified:
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/BSPEnforcer.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/KerberosTest.java

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java?rev=1159658&r1=1159657&r2=1159658&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java Fri Aug 19 15:07:18 2011
@@ -237,6 +237,24 @@ public class WSDocInfo {
         }
         return null;
     }
+    
+    /**
+     * Get a list of WSSecurityEngineResults of the given Integer tag
+     */
+    public List<WSSecurityEngineResult> getResultsByTag(Integer tag) {
+        List<WSSecurityEngineResult> foundResults = new ArrayList<WSSecurityEngineResult>();
+        if (resultsList != null) {
+            for (WSSecurityEngineResult result : resultsList) {
+                if (result != null) {
+                    Integer resultTag = (Integer)result.get(WSSecurityEngineResult.TAG_ACTION);
+                    if (tag.intValue() == resultTag.intValue()) {
+                        foundResults.add(result);
+                    }
+                }
+            }
+        }
+        return resultsList;
+    }
 
     /**
      * @return the signature crypto class used to process

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java?rev=1159658&r1=1159657&r2=1159658&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java Fri Aug 19 15:07:18 2011
@@ -267,16 +267,20 @@ public class WSSecSignature extends WSSe
                 break;
                 
             case WSConstants.CUSTOM_KEY_IDENTIFIER:
-                secRef.setKeyIdentifier(customTokenValueType, customTokenId);
                 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
+                    secRef.setKeyIdentifier(customTokenValueType, customTokenId);
                     secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
+                    secRef.setKeyIdentifier(customTokenValueType, customTokenId);
                     secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
+                    secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
                     secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                 } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customTokenValueType)) {
+                    secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
                     secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
                 } else if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(customTokenValueType)) {
+                    secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
                     secRef.addTokenType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
                 } 
                 break;

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/BSPEnforcer.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/BSPEnforcer.java?rev=1159658&r1=1159657&r2=1159658&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/BSPEnforcer.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/BSPEnforcer.java Fri Aug 19 15:07:18 2011
@@ -22,6 +22,7 @@ package org.apache.ws.security.str;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.KerberosSecurity;
 import org.apache.ws.security.message.token.PKIPathSecurity;
 import org.apache.ws.security.message.token.SecurityTokenReference;
 import org.apache.ws.security.message.token.X509Security;
@@ -51,14 +52,10 @@ public final class BSPEnforcer {
         if (secRef.containsReference()) {
             // Check the ValueType attributes
             String valueType = secRef.getReference().getValueType();
-            if ((token instanceof X509Security) && !X509Security.X509_V3_TYPE.equals(valueType)) {
-                throw new WSSecurityException(
-                    WSSecurityException.INVALID_SECURITY_TOKEN, 
-                    "invalidValueType", 
-                    new Object[]{valueType}
-                );
-            } else if ((token instanceof PKIPathSecurity) 
-                && (!PKIPathSecurity.PKI_TYPE.equals(valueType))) {
+            if (((token instanceof X509Security) && !X509Security.X509_V3_TYPE.equals(valueType))
+                || ((token instanceof PKIPathSecurity) && !PKIPathSecurity.PKI_TYPE.equals(valueType))
+                || ((token instanceof KerberosSecurity) 
+                        && !WSConstants.WSS_GSS_KRB_V5_AP_REQ.equals(valueType))) {
                 throw new WSSecurityException(
                     WSSecurityException.INVALID_SECURITY_TOKEN, 
                     "invalidValueType", 
@@ -68,7 +65,8 @@ public final class BSPEnforcer {
         } else if (secRef.containsKeyIdentifier()) {
             String valueType = secRef.getKeyIdentifierValueType();
             if (!SecurityTokenReference.SKI_URI.equals(valueType) 
-                && !SecurityTokenReference.THUMB_URI.equals(valueType)) {
+                && !SecurityTokenReference.THUMB_URI.equals(valueType)
+                && !WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(valueType)) {
                 throw new WSSecurityException(
                     WSSecurityException.INVALID_SECURITY_TOKEN, 
                     "invalidValueType", 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java?rev=1159658&r1=1159657&r2=1159658&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java Fri Aug 19 15:07:18 2011
@@ -46,6 +46,7 @@ import org.w3c.dom.Element;
 import java.security.Principal;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -194,8 +195,7 @@ public class SignatureSTRParser implemen
                 }
                 String id = secRef.getKeyIdentifierValue();
                 secretKey = 
-                    getSecretKeyFromToken(id, SecurityTokenReference.ENC_KEY_SHA1_URI, 
-                                          data);
+                    getSecretKeyFromToken(id, SecurityTokenReference.ENC_KEY_SHA1_URI, data);
                 principal = new CustomTokenPrincipal(id);
             } else if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())
                 || WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
@@ -217,13 +217,7 @@ public class SignatureSTRParser implemen
                 publicKey = samlKi.getPublicKey();
                 principal = createPrincipalFromSAML(assertion);
             } else {
-                if (bspCompliant) {
-                    BSPEnforcer.checkBinarySecurityBSPCompliance(secRef, null);
-                }
-                X509Certificate[] foundCerts = secRef.getKeyIdentifier(crypto);
-                if (foundCerts != null) {
-                    certs = new X509Certificate[]{foundCerts[0]};
-                }
+                parseBSTKeyIdentifier(secRef, crypto, wsDocInfo, bspCompliant);
             }
         } else {
             throw new WSSecurityException(
@@ -335,6 +329,41 @@ public class SignatureSTRParser implemen
     }
     
     /**
+     * Parse the KeyIdentifier for a BinarySecurityToken
+     */
+    private void parseBSTKeyIdentifier(
+        SecurityTokenReference secRef,
+        Crypto crypto,
+        WSDocInfo wsDocInfo,
+        boolean bspCompliant
+    ) throws WSSecurityException {
+        if (bspCompliant) {
+            BSPEnforcer.checkBinarySecurityBSPCompliance(secRef, null);
+        }
+        String valueType = secRef.getKeyIdentifierValueType();
+        if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(valueType)) {
+            byte[] keyBytes = secRef.getSKIBytes();
+            List<WSSecurityEngineResult> resultsList = 
+                wsDocInfo.getResultsByTag(WSConstants.BST);
+            for (WSSecurityEngineResult bstResult : resultsList) {
+                BinarySecurity bstToken = 
+                    (BinarySecurity)bstResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+                byte[] tokenDigest = WSSecurityUtil.generateDigest(bstToken.getToken());
+                if (Arrays.equals(tokenDigest, keyBytes)) {
+                    secretKey = (byte[])bstResult.get(WSSecurityEngineResult.TAG_SECRET);
+                    principal = (Principal)bstResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+                    break;
+                }
+            }
+        } else {
+            X509Certificate[] foundCerts = secRef.getKeyIdentifier(crypto);
+            if (foundCerts != null) {
+                certs = new X509Certificate[]{foundCerts[0]};
+            }
+        }
+    }
+    
+    /**
      * Process a previous security result
      */
     private void processPreviousResult(

Modified: webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/KerberosTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/KerberosTest.java?rev=1159658&r1=1159657&r2=1159658&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/KerberosTest.java (original)
+++ webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/KerberosTest.java Fri Aug 19 15:07:18 2011
@@ -28,6 +28,7 @@ import org.apache.ws.security.common.SOA
 import org.apache.ws.security.message.WSSecEncrypt;
 import org.apache.ws.security.message.WSSecHeader;
 import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.util.Base64;
 import org.apache.ws.security.util.WSSecurityUtil;
 import org.apache.ws.security.validate.KerberosTokenValidator;
 import org.w3c.dom.Document;
@@ -186,6 +187,68 @@ public class KerberosTest extends org.ju
         assertTrue(principal.getName().contains("alice"));
     }
     
+    
+    /**
+     * Test using the KerberosSecurity class to retrieve a service ticket from a KDC, wrap it
+     * in a BinarySecurityToken, and use the session key to sign the SOAP Body.
+     */
+    @org.junit.Test
+    @org.junit.Ignore
+    public void testKerberosSignatureKI() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        KerberosSecurity bst = new KerberosSecurity(doc);
+        bst.retrieveServiceTicket("alice", null, "bob@service.ws.apache.org");
+        bst.setID("Id-" + bst.hashCode());
+        
+        WSSecSignature sign = new WSSecSignature();
+        sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
+        sign.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
+        sign.setCustomTokenValueType(WSConstants.WSS_KRB_KI_VALUE_TYPE);
+        
+        SecretKey secretKey = bst.getSecretKey();
+        byte[] keyData = secretKey.getEncoded();
+        sign.setSecretKey(keyData);
+        
+        byte[] digestBytes = WSSecurityUtil.generateDigest(bst.getToken());
+        sign.setCustomTokenId(Base64.encode(digestBytes));
+        
+        Document signedDoc = sign.build(doc, null, secHeader);
+        
+        WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(), bst.getElement());
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        // Configure the Validator
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        KerberosTokenValidator validator = new KerberosTokenValidator();
+        validator.setJaasLoginModuleName("bob");
+        validator.setServiceName("bob@service.ws.apache.org");
+        wssConfig.setValidator(WSSecurityEngine.BINARY_TOKEN, validator);
+        WSSecurityEngine secEngine = new WSSecurityEngine();
+        secEngine.setWssConfig(wssConfig);
+        
+        List<WSSecurityEngineResult> results = 
+            secEngine.processSecurityHeader(doc, null, null, null);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.BST);
+        BinarySecurity token =
+            (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+        assertTrue(token != null);
+        
+        Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+        assertTrue(principal instanceof KerberosPrincipal);
+        assertTrue(principal.getName().contains("alice"));
+    }
+    
+    
     /**
      * Test using the KerberosSecurity class to retrieve a service ticket from a KDC, wrap it
      * in a BinarySecurityToken, and use the session key to encrypt the SOAP Body.