Author: ruchithf
Date: Sat Jul 14 02:24:25 2007
New Revision: 556250

URL: http://svn.apache.org/viewvc?view=rev&rev=556250
Log:
Added support to process and use custom tokens
Added support to process EncryptedData in the wsse:Security header itself - not 
referenced by any ref parts


Added:
    webservices/wss4j/trunk/src/org/apache/ws/security/CustomTokenPrincipal.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedDataProcessor.java
    webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java
Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
    webservices/wss4j/trunk/src/org/apache/ws/security/WSPasswordCallback.java
    webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java
    webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
    webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties
    
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKEncrypt.java
    webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecEncrypt.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/ReferenceListProcessor.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SAMLTokenProcessor.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
    webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java

Added: 
webservices/wss4j/trunk/src/org/apache/ws/security/CustomTokenPrincipal.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/CustomTokenPrincipal.java?view=auto&rev=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/CustomTokenPrincipal.java 
(added)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/CustomTokenPrincipal.java 
Sat Jul 14 02:24:25 2007
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ws.security;
+
+import org.w3c.dom.Element;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+public class CustomTokenPrincipal implements Principal, Serializable {
+
+
+    private Element tokenElement;
+    private String name;
+    private Object tokenObject;
+    
+    public Object getTokenObject() {
+        return tokenObject;
+    }
+
+    public void setTokenObject(Object tokenObject) {
+        this.tokenObject = tokenObject;
+    }
+
+    public CustomTokenPrincipal(String name) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return this.name;
+    }
+
+    public Element getTokenElement() {
+        return tokenElement;
+    }
+
+    public void setTokenElement(Element tokenElement) {
+        this.tokenElement = tokenElement;
+    }
+
+}

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java Sat Jul 
14 02:24:25 2007
@@ -74,6 +74,7 @@
     public static final String ENC_NS = "http://www.w3.org/2001/04/xmlenc#";;
     public static final String ENC_PREFIX = "xenc";
     public static final String ENC_KEY_LN = "EncryptedKey";
+    public static final String ENC_DATA_LN = "EncryptedData";
     public static final String REF_LIST_LN = "ReferenceList";
 
     /*
@@ -323,8 +324,8 @@
     public static final int EMBED_SECURITY_TOKEN_REF = 6;
     
     /**
-     * <code>UT_SIGNING</code> is used interally only to set a specific 
Signature
-     * behaviour.
+     * <code>UT_SIGNING</code> is used internally only to set a specific 
Signature
+     * behavior.
      * 
      * The signing token is constructed from values in the UsernameToken 
according
      * to WS-Trust specification.
@@ -341,10 +342,18 @@
      * 
      */
     public static final int THUMBPRINT_IDENTIFIER = 8;
+    
+    /**
+     * <code>CUSTOM_SYMM_SIGNING</code> is used internally only to set a 
+     * specific Signature behavior.
+     * 
+     * The signing key, reference id and value type are set externally. 
+     */
+    public static final int CUSTOM_SYMM_SIGNING = 9;
 
     /*
      * The following values are bits that can be combined to for a set.
-     * Be carefull when selecting new values.
+     * Be careful when selecting new values.
      */
     public static final int NO_SECURITY = 0;
     public static final int UT = 0x1; // perform UsernameToken
@@ -374,6 +383,11 @@
      */
     public static final int WSE_DERIVED_KEY_LEN = 16;
     public static final String LABEL_FOR_DERIVED_KEY = "WS-Security";
+    
+    /**
+     * WS-Trust namespace
+     */
+    public static final String WST_NS = 
"http://schemas.xmlsoap.org/ws/2005/02/trust";;
 
 }
 

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/WSPasswordCallback.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSPasswordCallback.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSPasswordCallback.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSPasswordCallback.java 
Sat Jul 14 02:24:25 2007
@@ -17,6 +17,8 @@
 
 package org.apache.ws.security;
 
+import org.w3c.dom.Element;
+
 import javax.security.auth.callback.Callback;
 
 /**
@@ -70,14 +72,16 @@
     public static final int SIGNATURE = 3;
     public static final int KEY_NAME = 4;
     public static final int USERNAME_TOKEN_UNKNOWN = 5;
-    public final static int SECURITY_CONTEXT_TOKEN = 6; 
+    public final static int SECURITY_CONTEXT_TOKEN = 6;
+    public final static int CUSTOM_TOKEN = 7;
 
     private String identifier;
     private String password;
     private byte[] key;
     private int usage;
     private String passwordType;
-
+    private Element customToken;
+    
     /**
      * Constructor.
      *
@@ -168,5 +172,13 @@
        public String getPasswordType() {
                return passwordType;
        }
+
+    public Element getCustomToken() {
+        return customToken;
+    }
+
+    public void setCustomToken(Element customToken) {
+        this.customToken = customToken;
+    }
 }
 

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java Sat Jul 
14 02:24:25 2007
@@ -251,6 +251,8 @@
             name = 
"org.apache.ws.security.processor.SecurityContextTokenProcessor";
         } else if(el.equals(WSSecurityEngine.binaryToken)) {
             name = 
"org.apache.ws.security.processor.BinarySecurityTokenProcessor";
+        } else if(el.equals(WSSecurityEngine.ENCRYPTED_DATA)) {
+            name = "org.apache.ws.security.processor.EncryptedDataProcessor";
         }
 
         if (name != null) {

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java 
Sat Jul 14 02:24:25 2007
@@ -77,6 +77,11 @@
      */
     public static final QName ENCRYPTED_KEY = new QName(WSConstants.ENC_NS, 
WSConstants.ENC_KEY_LN);
     /**
+     * <code>xenc:EncryptedData</code> as defined by XML Encryption 
specification,
+     * enhanced by WS Security specification
+     */
+    public static final QName ENCRYPTED_DATA = new QName(WSConstants.ENC_NS, 
WSConstants.ENC_DATA_LN);
+    /**
      * <code>xenc:ReferenceList</code> as defined by XML Encryption 
specification,
      */
     public static final QName REFERENCE_LIST = new QName(WSConstants.ENC_NS, 
WSConstants.REF_LIST_LN);

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties Sat 
Jul 14 02:24:25 2007
@@ -66,6 +66,7 @@
 noSAMLdoc=Cannot convert SAML to DOM document
 invalidSAMLsecurity=SAML token security failure
 invalidData=Invalid data: {0}
+noKeyInSAMLToken=Provided SAML token does not contain a suitable key
 #
 decoding.divisible.four = It should be divisible by four
 decoding.general = Error while decoding

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKEncrypt.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKEncrypt.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKEncrypt.java 
(original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecDKEncrypt.java 
Sat Jul 14 02:24:25 2007
@@ -123,7 +123,7 @@
             String xencEncryptedDataId = "EncDataId-" + body.hashCode();
 
             /*
-             * Forth step: encrypt data, and set neccessary attributes in
+             * Forth step: encrypt data, and set necessary attributes in
              * xenc:EncryptedData
              */
             try {

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecEncrypt.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecEncrypt.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecEncrypt.java 
(original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecEncrypt.java 
Sat Jul 14 02:24:25 2007
@@ -71,6 +71,12 @@
     protected SecurityTokenReference securityTokenReference = null;
 
     /**
+     * Indicates whether to encrypt the symmetric key into an EncryptedKey 
+     * or not.
+     */
+    private boolean encryptSymmKey = true;
+
+    /**
      * Constructor.
      */
     public WSSecEncrypt() {
@@ -189,7 +195,7 @@
          * key (session key) for this Encrypt element. This key will be
          * encrypted using the public key of the receiver
          */
-
+        
         
         if(this.ephemeralKey == null) {
             if (symmetricKey == null) {
@@ -198,22 +204,31 @@
             } 
             this.ephemeralKey = this.symmetricKey.getEncoded();
         }
+        
+        if (this.symmetricKey == null) {
+
+            this.symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo,
+                    this.ephemeralKey);
+        }
+        
         /*
          * Get the certificate that contains the public key for the public key
          * algorithm that will encrypt the generated symmetric (session) key.
          */
-        X509Certificate remoteCert = null;
-        if (useThisCert != null) {
-            remoteCert = useThisCert;
-        } else {
-            X509Certificate[] certs = crypto.getCertificates(user);
-            if (certs == null || certs.length <= 0) {
-                throw new WSSecurityException(WSSecurityException.FAILURE,
-                        "invalidX509Data", new Object[] { "for Encryption" });
+        if(this.encryptSymmKey) {
+            X509Certificate remoteCert = null;
+            if (useThisCert != null) {
+                remoteCert = useThisCert;
+            } else {
+                X509Certificate[] certs = crypto.getCertificates(user);
+                if (certs == null || certs.length <= 0) {
+                    throw new WSSecurityException(WSSecurityException.FAILURE,
+                            "invalidX509Data", new Object[] { "for Encryption" 
});
+                }
+                remoteCert = certs[0];
             }
-            remoteCert = certs[0];
+            prepareInternal(this.ephemeralKey, remoteCert, crypto);
         }
-        prepareInternal(this.ephemeralKey, remoteCert, crypto);
     }
 
     /**
@@ -344,16 +359,8 @@
     public Element encryptForExternalRef(Element dataRef, Vector references)
             throws WSSecurityException {
 
-        KeyInfo keyInfo = new KeyInfo(document);
-        SecurityTokenReference secToken = new SecurityTokenReference(document);
-        Reference ref = new Reference(document);
-        ref.setURI("#" + encKeyId);
-        secToken.setReference(ref);
-
-        keyInfo.addUnknownElement(secToken.getElement());
-
         Vector encDataRefs = doEncryption(document, this.symmetricKey,
-                keyInfo, references);
+                references);
         Element referenceList = dataRef;
         if (referenceList == null) {
             referenceList = document.createElementNS(WSConstants.ENC_NS,
@@ -412,6 +419,7 @@
 
         Vector encDataRef = new Vector();
 
+        boolean cloneKeyInfo = false;
         for (int part = 0; part < references.size(); part++) {
             WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);
 
@@ -445,6 +453,16 @@
             boolean content = modifier.equals("Content") ? true : false;
             String xencEncryptedDataId = "EncDataId-" + body.hashCode();
 
+            if(keyInfo == null) {
+                cloneKeyInfo = true;
+                keyInfo = new KeyInfo(document);
+                SecurityTokenReference secToken = new 
SecurityTokenReference(document);
+                Reference ref = new Reference(document);
+                ref.setURI("#" + encKeyId);
+                secToken.setReference(ref);
+    
+                keyInfo.addUnknownElement(secToken.getElement());
+            }
             /*
              * Forth step: encrypt data, and set neccessary attributes in
              * xenc:EncryptedData
@@ -455,6 +473,9 @@
                 encData.setId(xencEncryptedDataId);
                 encData.setKeyInfo(keyInfo);
                 xmlCipher.doFinal(doc, body, content);
+                if(cloneKeyInfo) {
+                    keyInfo = null;
+                }
             } catch (Exception e2) {
                 throw new WSSecurityException(
                         WSSecurityException.FAILED_ENC_DEC, null, null, e2);
@@ -623,6 +644,14 @@
      */
     public void setSecurityTokenReference(SecurityTokenReference reference) {
         securityTokenReference = reference;
+    }
+
+    public boolean isEncryptSymmKey() {
+        return encryptSymmKey;
+    }
+
+    public void setEncryptSymmKey(boolean encryptSymmKey) {
+        this.encryptSymmKey = encryptSymmKey;
     }
 
 }

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java 
(original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/message/WSSecSignature.java 
Sat Jul 14 02:24:25 2007
@@ -111,6 +111,10 @@
 
        protected BinarySecurity bstToken = null;
 
+    private String customTokenValueType;
+
+    private String customTokenId;
+
        /**
         * Constructor.
         */
@@ -282,7 +286,8 @@
                 * parameters.
                 */
                X509Certificate[] certs = null;
-               if (keyIdentifierType != WSConstants.UT_SIGNING) {
+               if (keyIdentifierType != WSConstants.UT_SIGNING
+                && keyIdentifierType != WSConstants.CUSTOM_SYMM_SIGNING) {
                        certs = crypto.getCertificates(user);
                        if (certs == null || certs.length <= 0) {
                                throw new 
WSSecurityException(WSSecurityException.FAILURE,
@@ -409,6 +414,12 @@
                        secRef.setKeyIdentifierThumb(certs[0]);
                        break;
 
+               case WSConstants.CUSTOM_SYMM_SIGNING :
+            Reference refCust = new Reference(document);
+            refCust.setValueType(this.customTokenValueType);
+            refCust.setURI("#" + this.customTokenId);
+            secRef.setReference(refCust);
+                   break;
                default:
                        throw new 
WSSecurityException(WSSecurityException.FAILURE,
                                        "unsupportedKeyId");
@@ -423,7 +434,7 @@
         * The added references are signed when calling
         * <code>computeSignature()</code>. This method can be called several
         * times to add references as required. 
<code>addReferencesToSign()</code>
-        * can be called anytime after <code>prepare</code>.
+        * can be called any time after <code>prepare</code>.
         * 
         * @param references
         *            A vector containing <code>WSEncryptionPart</code> objects
@@ -448,7 +459,7 @@
                        String nmSpace = encPart.getNamespace();
 
                        /*
-                        * Set up the elements to sign. There are two resevered 
element
+                        * Set up the elements to sign. There are two reserved 
element
                         * names: "Token" and "STRTransform" "Token": Setup the 
Signature to
                         * either sign the information that points to the 
security token or
                         * the token itself. If its a direct reference sign the 
token,
@@ -653,7 +664,8 @@
        public void computeSignature() throws WSSecurityException {
                WSDocInfoStore.store(wsDocInfo);
                try {
-                       if (keyIdentifierType == WSConstants.UT_SIGNING) {
+                       if (keyIdentifierType == WSConstants.UT_SIGNING ||
+                               keyIdentifierType == 
WSConstants.CUSTOM_SYMM_SIGNING) {
                                sig.sign(sig.createSecretKey(secretKey));
                        } else {
                                sig.sign(crypto.getPrivateKey(user, password));
@@ -802,4 +814,18 @@
 
                return result;
        }
+
+    public void setSecretKey(byte[] secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    public void setCustomTokenValueType(String customTokenValueType) {
+        this.customTokenValueType = customTokenValueType;
+    }
+
+    public void setCustomTokenId(String customTokenId) {
+        this.customTokenId = customTokenId;
+    }
+       
+       
 }

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
 Sat Jul 14 02:24:25 2007
@@ -21,6 +21,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.util.DOM2Writer;
@@ -32,6 +33,9 @@
 import org.apache.xml.security.utils.Constants;
 import org.w3c.dom.*;
 
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateEncodingException;
@@ -143,7 +147,7 @@
      * @throws WSSecurityException When either no <code>Reference</code> 
element, or the found
      *                   reference contains no URI, or the referenced signing 
not found.
      */
-    public Element getTokenElement(Document doc, WSDocInfo docInfo)
+    public Element getTokenElement(Document doc, WSDocInfo docInfo, 
CallbackHandler cb)
             throws WSSecurityException {
         Reference ref = getReference();
         String uri = ref.getURI();
@@ -156,7 +160,8 @@
         }
         Element tokElement = null;
         String tmpS = WSConstants.WSS_SAML_NS + WSConstants.WSS_SAML_ASSERTION;
-        if (tmpS.equals(ref.getValueType())) {
+        String saml10 = WSConstants.WSS_SAML_NS + 
WSConstants.SAML_ASSERTION_ID;
+        if (tmpS.equals(ref.getValueType()) || 
saml10.equals(ref.getValueType())) {
             Element sa = docInfo.getAssertion();
             String saID = null;
             if (sa != null) {
@@ -167,9 +172,32 @@
             }
             String id = uri.substring(1);
             if (saID == null || !saID.equals(id)) {
-                throw new 
WSSecurityException(WSSecurityException.INVALID_SECURITY,
-                        "badReferenceURI",
-                        new Object[]{"uri:" + uri + ", saID: " + saID});
+                
+                if(cb != null) {
+                    //try to find a custom token
+                    WSPasswordCallback pwcb = new WSPasswordCallback(id,
+                            WSPasswordCallback.CUSTOM_TOKEN);
+                    try {
+                        cb.handle(new Callback[]{pwcb});
+                    } catch (Exception e) {
+                        throw new 
WSSecurityException(WSSecurityException.FAILURE,
+                                "noPassword", new Object[] { id });
+                    }
+                    
+                    Element assertionElem = pwcb.getCustomToken();
+                    if(assertionElem != null) {
+                        sa = (Element)doc.importNode(assertionElem, true);
+                    }
+                    else {
+                        throw new 
WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                            "badReferenceURI",
+                            new Object[]{"uri:" + uri + ", saID: " + saID});
+                    }
+                } else {
+                    throw new 
WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                            "badReferenceURI",
+                            new Object[]{"uri:" + uri + ", saID: " + saID});
+                }
             }
             tokElement = sa;
         } else {

Added: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedDataProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedDataProcessor.java?view=auto&rev=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedDataProcessor.java
 (added)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedDataProcessor.java
 Sat Jul 14 02:24:25 2007
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ws.security.processor;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.crypto.SecretKey;
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+
+import java.util.Vector;
+
+/**
+ * This will process incoming <code>xenc:EncryptedData</code> elements.
+ * This processor will not be invoked for encrypted content referenced by a 
+ * <code>xenc:ReferenceList</code>.
+ *
+ */
+public class EncryptedDataProcessor implements Processor {
+
+    
+    private byte[] symmKey;
+    
+    
+    public String getId() {
+        return null;
+    }
+
+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto,
+            CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults,
+            WSSConfig config) throws WSSecurityException {
+        Element kiElem = (Element)WSSecurityUtil.findElement(elem, "KeyInfo", 
WSConstants.SIG_NS);
+        
+        
+        NodeList children = kiElem.getChildNodes();
+        int len = children.getLength();
+        
+        for(int i = 0; i < len; i++) {
+            Node child = children.item(i);
+            if (child.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+            QName el = new QName(child.getNamespaceURI(), 
child.getLocalName());
+            if(el.equals(WSSecurityEngine.ENCRYPTED_KEY)) {
+                EncryptedKeyProcessor encrKeyProc = new 
EncryptedKeyProcessor();
+                encrKeyProc.handleToken((Element)child, crypto, decCrypto, cb, 
wsDocInfo, returnResults, config);
+                this.symmKey = encrKeyProc.getDecryptedBytes();
+                break;
+            }
+        }
+        
+        String encAlgo = X509Util.getEncAlgo(elem);
+        SecretKey key = WSSecurityUtil.prepareSecretKey(encAlgo, this.symmKey);
+        
+        // initialize Cipher ....
+        XMLCipher xmlCipher = null;
+        try {
+            xmlCipher = XMLCipher.getInstance(encAlgo);
+            xmlCipher.init(XMLCipher.DECRYPT_MODE, key);
+        } catch (XMLEncryptionException e1) {
+            throw new WSSecurityException(
+                    WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e1);
+        }
+        
+        Node previousSibling = elem.getPreviousSibling();
+
+        try {
+            xmlCipher.doFinal(elem.getOwnerDocument(), elem, false);
+        } catch (Exception e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    null, null, e);
+        }
+        
+        //GEt hold of the plain text element
+        Element decryptedElem = (Element)previousSibling.getNextSibling();
+        QName el = new QName(decryptedElem.getNamespaceURI(), decryptedElem
+                .getLocalName());
+        Processor proc = config.getProcessor(el);
+        proc.handleToken((Element) decryptedElem, crypto, decCrypto, cb,
+                wsDocInfo, returnResults, config);
+        wsDocInfo.setProcessor(proc);
+    }
+
+}

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java
 Sat Jul 14 02:24:25 2007
@@ -194,7 +194,7 @@
                         log.debug("KeyIdentifier Alias: " + alias);
                     }
                 } else if (secRef.containsReference()) {
-                    Element bstElement = secRef.getTokenElement(doc, null);
+                    Element bstElement = secRef.getTokenElement(doc, null, cb);
 
                     // at this point ... check token type: Binary
                     QName el =

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/ReferenceListProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/ReferenceListProcessor.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/ReferenceListProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/ReferenceListProcessor.java
 Sat Jul 14 02:24:25 2007
@@ -17,22 +17,28 @@
 
 package org.apache.ws.security.processor;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Vector;
 
 import javax.crypto.SecretKey;
+import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.message.token.Reference;
 import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.saml.SAMLKeyInfo;
+import org.apache.ws.security.saml.SAMLUtil;
 import org.apache.ws.security.util.WSSecurityUtil;
 import org.apache.xml.security.encryption.XMLCipher;
 import org.apache.xml.security.encryption.XMLEncryptionException;
@@ -62,7 +68,7 @@
                                        "noCallback");
                }
                wsDocInfo = wdi;
-               ArrayList uris = handleReferenceList((Element) elem, cb);
+               ArrayList uris = handleReferenceList((Element) elem, cb, 
crypto);
                returnResults.add(0, new 
WSSecurityEngineResult(WSConstants.ENCR, uris));
        }
 
@@ -76,8 +82,8 @@
         *            the callback handler to get the key for a key name stored 
if
         *            <code>KeyInfo</code> inside the encrypted data elements
         */
-       private ArrayList handleReferenceList(Element elem, CallbackHandler cb)
-                       throws WSSecurityException {
+       private ArrayList handleReferenceList(Element elem, CallbackHandler cb,
+               Crypto crypto) throws WSSecurityException {
 
                Document doc = elem.getOwnerDocument();
 
@@ -93,7 +99,7 @@
                        }
                        if (tmpE.getLocalName().equals("DataReference")) {
                                String dataRefURI = ((Element) 
tmpE).getAttribute("URI");
-                               decryptDataRefEmbedded(doc, dataRefURI, cb);
+                               decryptDataRefEmbedded(doc, dataRefURI, cb, 
crypto);
                 dataRefUris.add(dataRefURI.substring(1));
                        }
                }
@@ -101,7 +107,7 @@
        }
 
        public void decryptDataRefEmbedded(Document doc, String dataRefURI,
-                       CallbackHandler cb) throws WSSecurityException {
+                       CallbackHandler cb, Crypto crypto) throws 
WSSecurityException {
 
                if (log.isDebugEnabled()) {
                        log.debug("Found data reference: " + dataRefURI);
@@ -142,7 +148,7 @@
                if (secRefToken == null) {
                        symmetricKey = X509Util.getSharedKey(tmpE, symEncAlgo, 
cb);
                } else
-                       symmetricKey = getKeyFromReference(secRefToken, 
symEncAlgo);
+                       symmetricKey = getKeyFromReference(secRefToken, 
symEncAlgo, crypto, cb);
 
                // initialize Cipher ....
                XMLCipher xmlCipher = null;
@@ -196,10 +202,13 @@
         *            The element containg the STR
         * @param algorithm
         *            A string that identifies the symmetric decryption 
algorithm
+        * @param crypto Crypto instance to obtain key
+        * @param cb CAllback handler to obtain the key passwords
         * @return The secret key for the specified algorithm
         * @throws WSSecurityException
         */
-       private SecretKey getKeyFromReference(Element secRefToken, String 
algorithm)
+       private SecretKey getKeyFromReference(Element secRefToken, String 
algorithm,
+               Crypto crypto, CallbackHandler cb)
                        throws WSSecurityException {
 
                SecurityTokenReference secRef = new 
SecurityTokenReference(secRefToken);
@@ -210,9 +219,25 @@
                        String uri = reference.getURI();
                        String id = uri.substring(1);
                        Processor p = wsDocInfo.getProcessor(id);
-                       if (p == null || (!(p instanceof EncryptedKeyProcessor) 
&& !(p instanceof DerivedKeyTokenProcessor))) {
-                               throw new WSSecurityException(
+                       if (p == null
+                    || (!(p instanceof EncryptedKeyProcessor)
+                            && !(p instanceof DerivedKeyTokenProcessor) 
+                            && !(p instanceof SAMLTokenProcessor))) {
+                           
+                           //Try custom token
+                           WSPasswordCallback pwcb = new 
WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
+                           try {
+                    cb.handle(new Callback[]{pwcb});
+                } catch (Exception e) {
+                    throw new WSSecurityException(WSSecurityException.FAILURE,
+                            "noPassword", new Object[] { id });
+                }
+                           decryptedData = pwcb.getKey();
+                           
+                           if(decryptedData == null) {
+                               throw new WSSecurityException(
                                                
WSSecurityException.FAILED_ENC_DEC, "unsupportedKeyId");
+                           }
                        }
                        if(p instanceof EncryptedKeyProcessor) {
                        EncryptedKeyProcessor ekp = (EncryptedKeyProcessor) p;
@@ -220,6 +245,13 @@
             } else if(p instanceof DerivedKeyTokenProcessor) {
                 DerivedKeyTokenProcessor dkp = (DerivedKeyTokenProcessor) p;
                 decryptedData = 
dkp.getKeyBytes(WSSecurityUtil.getKeyLength(algorithm));
+            } else if(p instanceof SAMLTokenProcessor) {
+                SAMLTokenProcessor samlp = (SAMLTokenProcessor) p;
+                SAMLKeyInfo keyInfo = SAMLUtil.getSAMLKeyInfo(samlp
+                        .getSamlTokenElement(), crypto, cb);
+                //TODO Handle malformed SAML tokens where they don't have the 
+                //secret in them
+                decryptedData = keyInfo.getSecret();
             }
                } else {
                        throw new 
WSSecurityException(WSSecurityException.FAILED_ENC_DEC,

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SAMLTokenProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/SAMLTokenProcessor.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SAMLTokenProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SAMLTokenProcessor.java
 Sat Jul 14 02:24:25 2007
@@ -34,15 +34,20 @@
 
 public class SAMLTokenProcessor implements Processor {
     private static Log log = 
LogFactory.getLog(SAMLTokenProcessor.class.getName());
+    
+    private String id;
+    private Element samlTokenElement;
 
     public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, 
CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) 
throws WSSecurityException {
         if (log.isDebugEnabled()) {
             log.debug("Found SAML Assertion element");
         }
         SAMLAssertion assertion = handleSAMLToken((Element) elem);
+        this.id = assertion.getId();
         wsDocInfo.setAssertion((Element) elem);
         returnResults.add(0,
                 new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, 
assertion));
+        this.samlTokenElement = elem;
 
     }
 
@@ -65,12 +70,15 @@
         return assertion;
     }
 
-    /* (non-Javadoc)
-     * @see org.apache.ws.security.processor.Processor#getId()
-     * TODO The Id of a SAML token?
+    /**
+     * Return the id of the SAML token
      */
     public String getId() {
-       return null;
+       return this.id;
+    }
+
+    public Element getSamlTokenElement() {
+        return samlTokenElement;
     }
 
 }

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
 Sat Jul 14 02:24:25 2007
@@ -20,10 +20,12 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.CustomTokenPrincipal;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSDerivedKeyTokenPrincipal;
 import org.apache.ws.security.WSDocInfo;
 import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.WSSecurityEngineResult;
@@ -37,27 +39,30 @@
 import org.apache.ws.security.message.token.SecurityTokenReference;
 import org.apache.ws.security.message.token.UsernameToken;
 import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.saml.SAMLKeyInfo;
 import org.apache.ws.security.saml.SAMLUtil;
 import org.apache.ws.security.util.WSSecurityUtil;
 import org.apache.xml.security.exceptions.XMLSecurityException;
-
 import org.apache.xml.security.keys.KeyInfo;
 import org.apache.xml.security.signature.Reference;
 import org.apache.xml.security.signature.SignedInfo;
 import org.apache.xml.security.signature.XMLSignature;
 import org.apache.xml.security.signature.XMLSignatureException;
+import org.opensaml.SAMLAssertion;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import javax.xml.namespace.QName;
+import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+
 import java.security.Principal;
 import java.security.cert.CertificateExpiredException;
 import java.security.cert.CertificateNotYetValidException;
 import java.security.cert.X509Certificate;
-import java.util.Vector;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Vector;
 
 public class SignatureProcessor implements Processor {
     private static Log log = 
LogFactory.getLog(SignatureProcessor.class.getName());
@@ -78,7 +83,7 @@
         Principal lastPrincipalFound = null;
         try {
             lastPrincipalFound = verifyXMLSignature((Element) elem,
-                    crypto, returnCert, returnElements, protectedElements, 
signatureValue);
+                    crypto, returnCert, returnElements, protectedElements, 
signatureValue, cb);
         } catch (WSSecurityException ex) {
             throw ex;
         } finally {
@@ -129,6 +134,7 @@
      *                    the certificate
      * @param returnElements verifyXMLSignature adds the wsu:ID attribute 
values for
      *                              the signed elements to this Set
+     * @param cb CallbackHandler instance to extract key passwords
      * @return the subject principal of the validated X509 certificate (the
      *         authenticated subject). The calling function may use this
      *         principal for further authentication or authorization.
@@ -139,7 +145,8 @@
                                            X509Certificate[] returnCert,
                                            Set returnElements,
                                            Set protectedElements,
-                                           byte[][] signatureValue)
+                                           byte[][] signatureValue,
+                                           CallbackHandler cb)
             throws WSSecurityException {
         if (log.isDebugEnabled()) {
             log.debug("Verify XML Signature");
@@ -164,7 +171,9 @@
         byte[] secretKey = null;
         UsernameToken ut = null;
         DerivedKeyToken dkt = null;
-
+        SAMLKeyInfo samlKi = null;
+        String customTokenId = null;
+        
         if (info != null) {
             Node node = WSSecurityUtil.getDirectChild(info.getElement(),
                     SecurityTokenReference.SECURITY_TOKEN_REFERENCE,
@@ -186,7 +195,7 @@
 
             if (secRef.containsReference()) {
                 Element token = secRef.getTokenElement(elem.getOwnerDocument(),
-                        wsDocInfo);
+                        wsDocInfo, cb);
                 /*
                      * at this point check token type: UsernameToken, Binary, 
SAML
                      * Crypto required only for Binary and SAML
@@ -207,7 +216,8 @@
                         WSSecurityUtil.getKeyLength(signatureMethodURI);
                     
                     secretKey = dktProcessor.getKeyBytes(keyLength);
-                } else {
+                } 
+                else {
                     if (crypto == null) {
                         throw new 
WSSecurityException(WSSecurityException.FAILURE,
                                 "noSigCryptoFile");
@@ -217,12 +227,35 @@
                         certs = getCertificatesTokenReference((Element) token,
                                 crypto);
                     } else if (el.equals(WSSecurityEngine.SAML_TOKEN)) {
-                        certs = SAMLUtil.getCertificatesFromSAML((Element) 
token);
+                        samlKi = SAMLUtil.getSAMLKeyInfo(
+                                (Element) token, crypto, cb);
+                        
+                        certs = samlKi.getCerts();
+                        secretKey = samlKi.getSecret();
                     } else {
-                        throw new WSSecurityException(
-                                WSSecurityException.INVALID_SECURITY,
-                                "unsupportedKeyInfo", new Object[]{el
-                                .toString()});
+                        
+                        //Try custom token through callback handler
+                      //try to find a custom token
+                        String id = secRef
+                                .getReference().getURI().substring(1);
+                        WSPasswordCallback pwcb = new WSPasswordCallback(id,
+                                WSPasswordCallback.CUSTOM_TOKEN);
+                        try {
+                            cb.handle(new Callback[]{pwcb});
+                        } catch (Exception e) {
+                            throw new 
WSSecurityException(WSSecurityException.FAILURE,
+                                    "noPassword", new Object[] { id });
+                        }
+                        
+                        secretKey = pwcb.getKey();
+                        customTokenId = id;
+                        
+                        if(secretKey == null) {
+                            throw new WSSecurityException(
+                                    WSSecurityException.INVALID_SECURITY,
+                                    "unsupportedKeyInfo", new Object[]{el
+                                    .toString()});
+                        }
                     }
                 }
             } else if (secRef.containsX509Data() || 
secRef.containsX509IssuerSerial()) {
@@ -335,7 +368,16 @@
                     String basetokenId = 
dkt.getSecuityTokenReference().getReference().getURI().substring(1);
                     principal.setBasetokenId(basetokenId);
                     return principal;
-                } else {
+                } else if(samlKi != null) {
+                    final SAMLAssertion assertion = samlKi.getAssertion();
+                    CustomTokenPrincipal principal = new 
CustomTokenPrincipal(assertion.getId());
+                    principal.setTokenObject(assertion);
+                    return principal;
+                } else if(secretKey != null) {
+                    //This is the custom key scenario
+                    CustomTokenPrincipal principal = new 
CustomTokenPrincipal(customTokenId);
+                    return principal;
+                }else {
                     throw new WSSecurityException("Cannot determine 
principal");
                 }
             } else {

Added: webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java?view=auto&rev=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java 
(added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLKeyInfo.java 
Sat Jul 14 02:24:25 2007
@@ -0,0 +1,64 @@
+/*
+ * Copyright 20046,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ws.security.saml;
+
+import org.opensaml.SAMLAssertion;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * This holds key/cert information extracted from a SAML assertion
+ */
+public class SAMLKeyInfo {
+
+    /**
+     * Certificates
+     */
+    private X509Certificate[] certs;
+    
+    /**
+     * Key bytes (e.g.: held in an encrypted key)
+     */
+    private byte[] secret;
+    
+    /**
+     * SAMLAssertion
+     */
+    SAMLAssertion assertion;
+    
+    public SAMLKeyInfo(SAMLAssertion assertions, X509Certificate[] certs) {
+        this.certs = certs;
+        this.assertion = assertions;
+    }
+    
+    public SAMLKeyInfo(SAMLAssertion assertions, byte[] secret) {
+        this.secret = secret;
+        this.assertion = assertions;
+    }
+    
+    public X509Certificate[] getCerts() {
+        return certs;
+    }
+    public byte[] getSecret() {
+        return secret;
+    }
+
+    public SAMLAssertion getAssertion() {
+        return assertion;
+    }
+    
+}
\ No newline at end of file

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/SAMLUtil.java Sat 
Jul 14 02:24:25 2007
@@ -1,19 +1,33 @@
 package org.apache.ws.security.saml;
 
-import org.w3c.dom.Element;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.util.Base64;
 import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.keys.KeyInfo;
 import org.apache.xml.security.keys.content.X509Data;
 import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
-import org.apache.xml.security.exceptions.XMLSecurityException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.opensaml.SAMLAssertion;
+import org.opensaml.SAMLAttributeStatement;
+import org.opensaml.SAMLAuthenticationStatement;
 import org.opensaml.SAMLException;
-import org.opensaml.SAMLSubjectStatement;
 import org.opensaml.SAMLObject;
+import org.opensaml.SAMLStatement;
 import org.opensaml.SAMLSubject;
+import org.opensaml.SAMLSubjectStatement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
 
 import java.security.cert.X509Certificate;
 import java.util.Iterator;
@@ -24,6 +38,104 @@
 public class SAMLUtil {
     private static Log log = LogFactory.getLog(SAMLUtil.class.getName());
 
+    
+    
+    /**
+     * Extract certificates or the key available in the SAMLAssertion
+     * @param elem
+     * @return
+     * @throws WSSecurityException
+     */
+    public static SAMLKeyInfo getSAMLKeyInfo(Element elem, Crypto crypto,
+            CallbackHandler cb) throws WSSecurityException {
+        SAMLAssertion assertion;
+        try {
+            assertion = new SAMLAssertion(elem);
+            return getSAMLKeyInfo(assertion, crypto, cb);
+        } catch (SAMLException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "invalidSAMLToken", new Object[]{"for Signature (cannot 
parse)"});
+        }
+
+    }
+    
+    public static SAMLKeyInfo getSAMLKeyInfo(SAMLAssertion assertion, Crypto 
crypto,
+            CallbackHandler cb) throws WSSecurityException {
+        Iterator statements = assertion.getStatements();
+        while (statements.hasNext()) {
+            SAMLStatement stmt = (SAMLStatement) statements.next();
+            if (stmt instanceof SAMLAttributeStatement) {
+                SAMLAttributeStatement attrStmt = (SAMLAttributeStatement) 
stmt;
+                SAMLSubject samlSubject = attrStmt.getSubject();
+                Element kiElem = samlSubject.getKeyInfo();
+                
+                NodeList children = kiElem.getChildNodes();
+                int len = children.getLength();
+                
+                for(int i = 0; i < len; i++) {
+                    Node child = children.item(i);
+                    if (child.getNodeType() != Node.ELEMENT_NODE) {
+                        continue;
+                    }
+                    QName el = new QName(child.getNamespaceURI(), 
child.getLocalName());
+                    if(el.equals(WSSecurityEngine.ENCRYPTED_KEY)) {
+                        
+                        EncryptedKeyProcessor proc = new 
EncryptedKeyProcessor();
+                        proc.handleEncryptedKey((Element)child, cb, crypto, 
null);
+                        
+                        return new SAMLKeyInfo(assertion, 
proc.getDecryptedBytes());
+                    } else if(el.equals(new QName(WSConstants.WST_NS, 
"BinarySecret"))) {
+                        Text txt = (Text)child.getFirstChild();
+                        return new SAMLKeyInfo(assertion, 
Base64.decode(txt.getData()));
+                    }
+                }
+
+            } else if( stmt instanceof SAMLAuthenticationStatement) {
+                SAMLAuthenticationStatement authStmt = 
(SAMLAuthenticationStatement)stmt;
+                SAMLSubject samlSubj = authStmt.getSubject(); 
+                if (samlSubj == null) {
+                    throw new WSSecurityException(WSSecurityException.FAILURE,
+                            "invalidSAMLToken", new Object[]{"for Signature 
(no Subject)"});
+                }
+
+                Element e = samlSubj.getKeyInfo();
+                X509Certificate[] certs = null;
+                try {
+                    KeyInfo ki = new KeyInfo(e, null);
+
+                    if (ki.containsX509Data()) {
+                        X509Data data = ki.itemX509Data(0);
+                        XMLX509Certificate certElem = null;
+                        if (data != null && data.containsCertificate()) {
+                            certElem = data.itemCertificate(0);
+                        }
+                        if (certElem != null) {
+                            X509Certificate cert = 
certElem.getX509Certificate();
+                            certs = new X509Certificate[1];
+                            certs[0] = cert;
+                            return new SAMLKeyInfo(assertion, certs);
+                        }
+                    }
+
+                } catch (XMLSecurityException e3) {
+                    throw new WSSecurityException(WSSecurityException.FAILURE,
+                            "invalidSAMLsecurity",
+                            new Object[]{"cannot get certificate (key 
holder)"});
+                }
+                
+            } else {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "invalidSAMLsecurity",
+                        new Object[]{"cannot get certificate or key "});
+            }
+        }
+        
+        throw new WSSecurityException(WSSecurityException.FAILURE,
+                "invalidSAMLsecurity",
+                new Object[]{"cannot get certificate or key "});
+        
+    }
+    
     /**
      * Extracts the certificate(s) from the SAML token reference.
      * <p/>

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java?view=diff&rev=556250&r1=556249&r2=556250
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java 
(original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java 
Sat Jul 14 02:24:25 2007
@@ -272,7 +272,7 @@
             if (doDebug) {
                 log.debug("STR: Reference");
             }
-            tokElement = secRef.getTokenElement(doc, wsDocInfo);
+            tokElement = secRef.getTokenElement(doc, wsDocInfo, null);
         }
         /*
          * second case: IssuerSerial, lookup in keystore, wrap in BST according



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to