Author: dimuthul
Date: Thu Feb 21 06:28:46 2008
New Revision: 13999

Log:

Adding token issuer with my local changes.



Added:
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/IssuerCertificateUtil.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenConsumer.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenVerifier.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialImpl.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialUtil.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML1TokenHolder.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML2TokenHolder.java
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/TokenHolder.java
Modified:
   
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties

Modified: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
==============================================================================
--- 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
    (original)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
    Thu Feb 21 06:28:46 2008
@@ -1,3 +1,4 @@
+errorReadingFromKeyInfo = Error reading key info from message : {0} : {1}
 credentialIsNull = Cannot find the key to validate Signature.
 signingCertNull = Signing certificate cannot be null of whitelist, blacklist 
and cert-validity
 errorValidatingIssuerPolicy = Error validating issuer policy

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/IssuerCertificateUtil.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/IssuerCertificateUtil.java
 Thu Feb 21 06:28:46 2008
@@ -0,0 +1,132 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.ws.security.components.crypto.X509NameTokenizer;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+
+public class IssuerCertificateUtil {
+
+    /**
+     * This method checks whether the certificate is present in the 
certificate store
+     */
+    public static boolean checkSystemStoree(X509Certificate signedCert,
+            KeyStore trustStore, KeyStore systemStore) throws Exception {
+
+        boolean isCertValid = false;
+
+        String certIssuerName = signedCert.getIssuerDN().getName();
+
+        // validity period
+        signedCert.checkValidity();
+
+        // is Trusted? checking in System store.
+        try {
+            isCertValid = systemStore.containsAlias(certIssuerName);
+        } catch (Exception e) {
+            throw new RelyingPartyException("errorLoadingTrustedKeystore", e);
+        }
+
+        return isCertValid;
+
+    }
+
+    /**
+     * Performs the black list check
+     * @param blackList Array of Lists. One Array element contains the 
Issuer's cert DN
+     * @param cert
+     * @return
+     * @throws RelyingPartyException
+     */
+    public static boolean doBlackListCheck(List[] blackList,
+            X509Certificate cert) throws RelyingPartyException {
+        boolean isGreenLight = true;
+
+        if (cert == null) {
+            throw new RelyingPartyException("noCertInToken");
+        }
+
+        if (blackList == null) {
+            isGreenLight = true;
+        } else {
+            String value = cert.getIssuerDN().getName();
+            List certDN = getDNOfIssuer(value);
+            for (int i = 0; i < blackList.length; i++) {
+                List issuerDN = blackList[i];
+                if (certDN.equals(issuerDN)) {
+                    isGreenLight = false;
+                    break;
+                }
+            }
+        }
+
+        return isGreenLight;
+    }
+
+    /**
+     * Do a white list check
+     * 
+     * @param whiteList Array of Lists. One Array element contains the 
Issuer's cert DN
+     * @param cert
+     * @return
+     * @throws RelyingPartyException
+     */
+    public static boolean doWhiteListCheck(List[] whiteList,
+            X509Certificate cert) throws RelyingPartyException {
+        boolean isGreenLight = false;
+
+        if (cert == null) {
+            throw new RelyingPartyException("noCertInToken");
+        }
+        if (whiteList != null) {
+            String inString = cert.getIssuerDN().getName();
+            List certDN = getDNOfIssuer(inString);
+            for (int i = 0; i < whiteList.length; i++) {
+                List issuerDN = whiteList[i];
+                if (certDN.equals(issuerDN)) {
+                    isGreenLight = true;
+                    break;
+                }
+            }
+        }
+        return isGreenLight;
+    }
+
+    /**
+     * Retrieves the CN of the subject of the given Certificate
+     * @param cert
+     * @return
+     */
+    public static String getCNOfSubject(X509Certificate cert) {
+        String dn = cert.getIssuerDN().getName();
+        if (dn.contains("CN=")) {
+            int beginIndex = dn.indexOf("CN=");
+            int endIndex = dn.indexOf(",", beginIndex);
+            String name = dn.substring(beginIndex + 3, endIndex).trim();
+            return name;
+        }
+        return null;
+    }
+
+    /**
+     * Retrieves the DN Of Issuer
+     * @param inString
+     * @return
+     */
+    public static List getDNOfIssuer(String inString) {
+
+        X509NameTokenizer nmTokens = new X509NameTokenizer(inString);
+        List lst = new ArrayList();
+
+        while (nmTokens.hasMoreTokens()) {
+            lst.add(nmTokens.nextToken());
+        }
+        Collections.sort(lst);
+        return lst;
+    }
+
+}

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenConsumer.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenConsumer.java
     Thu Feb 21 06:28:46 2008
@@ -0,0 +1,234 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.io.StringReader;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.Base64;
+import org.apache.ws.security.util.DOM2Writer;
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.xml.ConfigurationException;
+import org.w3c.dom.Element;
+import org.wso2.solutions.identity.IdentityConstants;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+import org.wso2.solutions.identity.relyingparty.TokenVerifierConstants;
+import org.wso2.solutions.identity.relyingparty.servletfilter.RelyingPartyData;
+
+public class SAMLTokenConsumer {
+
+    private static SAMLTokenConsumer consumer = null;
+
+    static {
+        try {
+            DefaultBootstrap.bootstrap();
+        } catch (ConfigurationException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    private SAMLTokenConsumer() {
+
+    }
+
+    /**
+     * Returns the SAMLTokenConsuer
+     * 
+     * @return
+     */
+    public static SAMLTokenConsumer getInstance() {
+        if (consumer == null) {
+            consumer = new SAMLTokenConsumer();
+        }
+        return consumer;
+    }
+
+    /**
+     * The control flow is 1) Verify 2) Validate policies 3) Inject parameters
+     * into the HttpServletRequest
+     * 
+     * @param request
+     * @param xmlToken
+     * @param data
+     * @throws RelyingPartyException
+     */
+    public void setInfocardSessionAttributes(HttpServletRequest request,
+            String xmlToken, RelyingPartyData data)
+            throws RelyingPartyException {
+        SAMLTokenVerifier verifier = new SAMLTokenVerifier();
+
+        Element plainTokenElem = verifier.decryptToken(xmlToken, data
+                .getPrivateKey());
+
+        boolean isAllSuccess = false;
+
+        if (verifier.verifyDecryptedToken(plainTokenElem, data)) {
+            if (validateIssuerInfoPolicy(verifier, data)) {
+                isAllSuccess = true;
+            }
+        }
+
+        if (isAllSuccess == false) {
+            injectDataToRequestOnFailure(verifier, request);
+        } else {
+            injectDataToRequestOnSuccess(verifier, request);
+        }
+
+    }
+
+    /**
+     * Validates issuer info
+     * 
+     * @param verifier
+     * @return Whether issue validation successful or not.
+     * @throws Exception
+     */
+    protected boolean validateIssuerInfoPolicy(SAMLTokenVerifier verifier,
+            RelyingPartyData data) throws RelyingPartyException {
+        boolean validated = false;
+        String issuerName = verifier.getIssuerName();
+        String issuerPolicy = data.getIssuerPolicy();
+        String validatePolicy = data.getValidatePolicy();
+
+        try {
+            if (IdentityConstants.SELF_ISSUED_ISSUER.equals(issuerName)) {
+
+                if (issuerPolicy == null
+                        || issuerPolicy
+                                .equals(TokenVerifierConstants.SELF_ONLY)
+                        || issuerPolicy
+                                
.equals(TokenVerifierConstants.SELF_AND_MANGED)) {
+                    validated = true;
+                }
+            } else if (issuerPolicy.equals(TokenVerifierConstants.SELF_ONLY)) {
+                // not a self issued card when self only
+                validated = false;
+            } else {
+                validated = true;
+            }
+        } catch (Exception e) {
+            throw new RelyingPartyException("errorValidatingIssuerPolicy", e);
+        }
+
+        return validated;
+    }
+
+    /**
+     * When the data token is invalid, this method injects invalid status
+     * message.
+     * 
+     * @param verifier
+     * @param request
+     */
+    protected void injectDataToRequestOnFailure(SAMLTokenVerifier verifier,
+            ServletRequest request) {
+
+        request.setAttribute(TokenVerifierConstants.SERVLET_ATTR_STATE,
+                TokenVerifierConstants.STATE_FAILURE);
+    }
+
+    /**
+     * When the token is valid this method injects valid states message
+     * 
+     * @param verifier
+     * @param request
+     * @throws RelyingPartyException
+     */
+    protected void injectDataToRequestOnSuccess(SAMLTokenVerifier verifier,
+            ServletRequest request) throws RelyingPartyException {
+
+        request.setAttribute(TokenVerifierConstants.SERVLET_ATTR_STATE,
+                TokenVerifierConstants.STATE_SUCCESS);
+
+        String issuerInfo = getIssuerInfoString(verifier);
+        if (issuerInfo != null) {
+            request
+                    .setAttribute(TokenVerifierConstants.ISSUER_INFO,
+                            issuerInfo);
+        }
+
+        Iterator propertyEntry = verifier.getAttributeTable().entrySet()
+                .iterator();
+        while (propertyEntry.hasNext()) {
+            Entry entry = (Entry) propertyEntry.next();
+            String key = (String) entry.getKey();
+            String value = (String) entry.getValue();
+            request.setAttribute(key, value);
+        }
+
+    }
+
+    protected String getIssuerInfoString(SAMLTokenVerifier verifier)
+            throws RelyingPartyException {
+        String issuerInfo = null;
+        OMFactory factory = OMAbstractFactory.getOMFactory();
+        OMNamespace ns = factory.createOMNamespace(TokenVerifierConstants.NS,
+                TokenVerifierConstants.PREFIX);
+
+        List certficates = verifier.getCertificates();
+        Element keyInfo = verifier.getKeyInfoElement();
+        OMElement certificates;
+        OMElement omKeyInfo;
+        try {
+            Iterator ite = certficates.iterator();
+            boolean siginingSet = false;
+            certificates = null;
+            OMElement certElem = null;
+            while (ite.hasNext()) {
+                X509Certificate cert = (X509Certificate) ite.next();
+                byte[] encodedCert = cert.getEncoded();
+                String base64Encoded = Base64.encode(encodedCert);
+                if (certificates == null) {
+                    certificates = factory.createOMElement(
+                            TokenVerifierConstants.LN_CERTIFICATES, ns);
+                }
+
+                certElem = factory.createOMElement(
+                        TokenVerifierConstants.LN_CERTIFICATE, ns);
+                if (siginingSet == false) {
+                    certElem.addAttribute(
+                            TokenVerifierConstants.LN_SIGNING_CERT, "true",
+                            null);
+                    siginingSet = true;
+                }
+                certElem.setText(base64Encoded);
+                certificates.addChild(certElem);
+            }
+
+            omKeyInfo = null;
+            if (keyInfo != null) {
+                String value = DOM2Writer.nodeToString(keyInfo);
+                XMLStreamReader parser = XMLInputFactory.newInstance()
+                        .createXMLStreamReader(new StringReader(value));
+                StAXOMBuilder builder = new StAXOMBuilder(parser);
+                omKeyInfo = builder.getDocumentElement();
+
+            }
+        } catch (Exception e) {
+            throw new RelyingPartyException("errorBuildingIssuerInfo");
+        }
+
+        if (certificates != null) {
+            issuerInfo = certificates.toString();
+        }
+
+        if (omKeyInfo != null) {
+            issuerInfo = issuerInfo + omKeyInfo.toString();
+        }
+
+        return issuerInfo;
+    }
+
+}

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenVerifier.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenVerifier.java
     Thu Feb 21 06:28:46 2008
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2005-2007 WSO2, Inc. (http://wso2.com)
+ *
+ * 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.wso2.solutions.identity.relyingparty.saml;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URI;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.crypto.SecretKey;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.Init;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.utils.EncryptionConstants;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureValidator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.wso2.solutions.identity.IdentityConstants;
+import org.wso2.solutions.identity.i18n.Messages;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+import org.wso2.solutions.identity.relyingparty.TokenVerifierConstants;
+import org.wso2.solutions.identity.relyingparty.saml.tokens.SAML1TokenHolder;
+import org.wso2.solutions.identity.relyingparty.saml.tokens.SAML2TokenHolder;
+import org.wso2.solutions.identity.relyingparty.saml.tokens.TokenHolder;
+import org.wso2.solutions.identity.relyingparty.servletfilter.RelyingPartyData;
+
+/**
+ * A SAML token is sent to a web application in a CardSpace login attempt and
+ * this can be used for decryption and verification of those tokens.
+ */
+public class SAMLTokenVerifier {
+
+    private static Log log = LogFactory.getLog(SAMLTokenVerifier.class);
+
+    private static Messages messages = Messages
+            .getInstance(TokenVerifierConstants.RESOURCES);
+
+    private Hashtable attributeTable = new Hashtable();
+
+    private List certificates = new ArrayList();
+
+    private Element keyInfoElement = null;
+
+    private String issuerName = null;
+
+    private boolean isMultipleValues = false;
+
+    private X509Certificate signingCert = null;
+
+    static {
+        Init.init();
+    }
+
+    /**
+     * Decrypt the given token (as a <code>java.lang.String</code> with the
+     * given private key.
+     * 
+     * @param token
+     *            Serialized SAML token
+     * @param serviceKey
+     *            Private key to be used for decryption.
+     * @return Decrypted SAML token element.
+     * @throws RelyingPartyException
+     */
+    public Element decryptToken(String token, PrivateKey serviceKey)
+            throws RelyingPartyException {
+
+        try {
+
+            if (log.isDebugEnabled()) {
+                log.debug(messages.getMessage("receivedEncryuptedToken",
+                        new String[] { token }));
+            }
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(token
+                    .getBytes());
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            dbf.setNamespaceAware(true);
+            Document doc = dbf.newDocumentBuilder().parse(bais);
+            Element encryptedTokenElem = doc.getDocumentElement();
+
+            // Decrypt element
+            return this.decryptElement(serviceKey, encryptedTokenElem);
+
+        } catch (Exception e) {
+            throw new RelyingPartyException("verificationFailure", e);
+        }
+
+    }
+
+    /**
+     * This method performs two actions 1) Decrypt the token 2) Verify the 
token
+     * 
+     * @param decryptedElem
+     *            SAML token element
+     * @return true if verification is successful and false if unsuccessful.
+     * @throws SAMLException
+     */
+    public boolean verifyDecryptedToken(Element decryptedElem,
+            RelyingPartyData rpData) throws RelyingPartyException {
+
+        boolean isValid = true;
+        if (log.isDebugEnabled()) {
+            log.debug(messages.getMessage("verifyingDecryptedToken"));
+        }
+
+        if (log.isDebugEnabled()) {
+            try {
+                String val = DOM2Writer.nodeToString(decryptedElem);
+                log.debug(val);
+                FileWriter writer = new FileWriter(new File("last_msg.xml"));
+                writer.write(val.toCharArray());
+                writer.flush();
+                writer.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        try {
+
+            String version = decryptedElem.getNamespaceURI();
+            TokenHolder holder = null;
+            if (version.equals(IdentityConstants.SAML10_URL)
+                    || version.equals(IdentityConstants.SAML11_URL)) {
+                holder = new SAML1TokenHolder();
+            } else if (version.equals(IdentityConstants.SAML20_URL)) {
+                holder = new SAML2TokenHolder();
+            }
+
+            holder.createToken(decryptedElem);
+            issuerName = holder.getIssuerName();
+            if (issuerName == null) {
+                throw new RelyingPartyException("issuerIsNull");
+            }
+
+            Signature sig = holder.getSAMLSignature();
+            X509CredentialImpl credential = null;
+
+            if (issuerName.equals(IdentityConstants.SELF_ISSUED_ISSUER)) {
+                credential = (X509CredentialImpl) X509CredentialUtil
+                        .loadCredentialFromSignature(sig);
+                this.keyInfoElement = sig.getKeyInfo().getDOM();
+            } else {
+
+                String alias = null;
+                URI uri = new URI(issuerName);
+                alias = uri.getHost();
+
+                KeyStore trustStore = rpData.getTrustStore();
+                KeyStore systemStore = rpData.getSystemStore();
+
+                credential = (X509CredentialImpl) X509CredentialUtil
+                        .loadCredentialFromTrustStore(alias, trustStore);
+
+                String validationPolicy = rpData.getValidatePolicy();
+
+                boolean isLoadedFromMessage = false;
+                if (credential == null) {
+                    credential = (X509CredentialImpl) X509CredentialUtil
+                            .loadCredentialFromSignature(sig);
+
+                    if (credential == null)
+                        throw new RelyingPartyException("credentialIsNull");
+
+                    isLoadedFromMessage = true;
+                }
+
+                this.signingCert = credential.getSigningCert();
+
+                if (!validationPolicy
+                        .equals(TokenVerifierConstants.PROMISCUOUS)) {
+
+                    if (signingCert == null)
+                        throw new RelyingPartyException("signingCertNull");
+
+                    /*
+                     * do certificate validation for blacklist, whitelist and
+                     * cert-validity
+                     */
+
+                    signingCert.checkValidity();
+
+                    if (isLoadedFromMessage) {
+                        if (!IssuerCertificateUtil.checkSystemStoree(
+                                signingCert, trustStore, systemStore)) {
+                            isValid = false;
+                        }
+                    }
+
+                    if (validationPolicy
+                            .equals(TokenVerifierConstants.BLACK_LIST)) {
+                        if (!IssuerCertificateUtil.doBlackListCheck(rpData
+                                .getBlackList(), signingCert)) {
+                            isValid = false;
+                        }
+                    }
+
+                    if (validationPolicy
+                            .equals(TokenVerifierConstants.WHITE_LIST)) {
+                        if (!IssuerCertificateUtil.doWhiteListCheck(rpData
+                                .getWhiteList(), signingCert)) {
+                            isValid = false;
+                        }
+                    }
+                }
+            }
+
+            if (isValid) {
+                SignatureValidator validator = new SignatureValidator(
+                        credential);
+                validator.validate(sig);
+                holder.populateAttributeTable(this.attributeTable);
+            }
+
+        } catch (Exception e) {
+            log.debug(e);
+            throw new RelyingPartyException("errorInTokenVerification",
+                    new Object[] { e.getMessage() });
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug(messages.getMessage("verifyingDecryptedTokenDone"));
+        }
+
+        // everything is fine :D
+        return isValid;
+    }
+
+    private Element decryptElement(PrivateKey privKey, Element encryptedToken)
+            throws Exception {
+
+        if (log.isDebugEnabled()) {
+            log.debug(messages.getMessage("decryptingToken"));
+        }
+
+        Element kiElem = (Element) encryptedToken.getElementsByTagNameNS(
+                WSConstants.SIG_NS, "KeyInfo").item(0);
+        Element encrKeyElem = (Element) kiElem.getElementsByTagNameNS(
+                WSConstants.ENC_NS, EncryptionConstants._TAG_ENCRYPTEDKEY)
+                .item(0);
+
+        EncryptedKeyProcessor encrKeyProcessor = new EncryptedKeyProcessor();
+        encrKeyProcessor.handleEncryptedKey(encrKeyElem, privKey);
+
+        SecretKey secretKey = WSSecurityUtil.prepareSecretKey(
+                EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
+                encrKeyProcessor.getDecryptedBytes());
+
+        XMLCipher cipher = XMLCipher.getInstance();
+        cipher.init(XMLCipher.DECRYPT_MODE, secretKey);
+
+        Document doc = cipher.doFinal(encryptedToken.getOwnerDocument(),
+                encryptedToken);
+        if (log.isDebugEnabled()) {
+            log.debug(messages.getMessage("decryptingTokenDone"));
+        }
+
+        return doc.getDocumentElement();
+    }
+
+    public X509Certificate getSigningCert() {
+        return signingCert;
+    }
+
+    /**
+     * Returns the list of attributes extracted from the 
SAMLAttributeStatements
+     * in the verified SAML assertion.
+     * 
+     * @return List of attributes as a <code>java.util.Hashtable</code>
+     */
+    public Hashtable getAttributeTable() {
+        return attributeTable;
+    }
+
+    public List getCertificates() {
+        return certificates;
+    }
+
+    public Element getKeyInfoElement() {
+        return keyInfoElement;
+    }
+
+    public String getIssuerName() {
+        return issuerName;
+    }
+
+    public void setIssuerName(String issuer) {
+        this.issuerName = issuer;
+    }
+
+    public boolean isMultipleValues() {
+        return isMultipleValues;
+    }
+
+    public void setMultipleValues(boolean isMultipleValues) {
+        this.isMultipleValues = isMultipleValues;
+    }
+
+}
\ No newline at end of file

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialImpl.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialImpl.java
    Thu Feb 21 06:28:46 2008
@@ -0,0 +1,113 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.Collection;
+
+import javax.crypto.SecretKey;
+
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.credential.CredentialContextSet;
+import org.opensaml.xml.security.credential.UsageType;
+import org.opensaml.xml.security.x509.X509Credential;
+
+/**
+ * X509Credential implementation for signature verification of self issued 
tokens.
+ * The key is constructed from modulus and exponent
+ */
+public class X509CredentialImpl implements X509Credential {
+
+    private PublicKey publicKey = null;
+    private X509Certificate signingCert = null;
+
+    //cert chain
+
+    /**
+     * The key is constructed form modulus and exponent.
+     * @param modulus
+     * @param publicExponent
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeySpecException
+     */
+    public X509CredentialImpl(BigInteger modulus, BigInteger publicExponent)
+            throws NoSuchAlgorithmException, InvalidKeySpecException {
+        RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        publicKey = keyFactory.generatePublic(spec);
+    }
+
+    public X509CredentialImpl(X509Certificate cert) {
+        publicKey = cert.getPublicKey();
+        signingCert = cert;
+    }
+
+    /**
+     * Retrieves the publicKey
+     */
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
+
+    public X509Certificate getSigningCert() {
+        return signingCert;
+    }
+
+    // ********** Not implemented 
**************************************************************
+    public X509Certificate getEntityCertificate() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+    
+    public Collection<X509CRL> getCRLs() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Collection<X509Certificate> getEntityCertificateChain() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public CredentialContextSet getCredentalContextSet() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Class<? extends Credential> getCredentialType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getEntityId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Collection<String> getKeyNames() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public PrivateKey getPrivateKey() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public SecretKey getSecretKey() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public UsageType getUsageType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialUtil.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialUtil.java
    Thu Feb 21 06:28:46 2008
@@ -0,0 +1,116 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertificateFactory;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.xml.security.utils.Base64;
+import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.signature.Exponent;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.signature.KeyValue;
+import org.opensaml.xml.signature.Modulus;
+import org.opensaml.xml.signature.RSAKeyValue;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.X509Certificate;
+import org.opensaml.xml.signature.X509Data;
+import org.w3c.dom.Element;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+
+/**
+ * This class creates the X509CredentialImpl that is needed to 
+ * verify the signature.
+ *
+ */
+public class X509CredentialUtil {
+
+    public static KeyStore systemKeyStore = null;
+
+    /**
+     * Creates the X509Credential from the TrustStore certificate.
+     */
+    public static X509Credential loadCredentialFromTrustStore(String alias,
+            KeyStore trustStore) throws RelyingPartyException {
+        X509Credential credential = null;
+        java.security.cert.X509Certificate cert = null;
+        try {
+            if (trustStore.containsAlias(alias)) {
+                cert = (java.security.cert.X509Certificate) trustStore
+                        .getCertificate(alias);
+                credential = new X509CredentialImpl(cert);
+            }
+        } catch (KeyStoreException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return credential;
+    }
+
+    /**
+     * Creates the certificate from the KeyInfo element. 
+     */
+    public static X509Credential loadCredentialFromSignature(Signature 
signature)
+            throws RelyingPartyException {
+        X509Credential credential = null;
+        KeyInfo kinfo = signature.getKeyInfo();
+
+        if (kinfo == null) {
+            return null;
+        }
+
+        List<X509Data> dataList = kinfo.getX509Datas();
+        List<KeyValue> keyValueList = kinfo.getKeyValues();
+
+        try {
+            if (dataList.size() > 0) {
+                if (dataList.size() > 1) {
+                    throw new RelyingPartyException("invalidKeyValueCount");
+                }
+                X509Data data = dataList.get(0);
+                List<X509Certificate> certList = data.getX509Certificates();
+                Iterator ite = certList.iterator();
+                while (ite.hasNext()) {
+                    X509Certificate certElem = (X509Certificate) ite.next();
+                    String certValue = certElem.getValue();
+                    byte[] certInBytes = Base64.decode(certValue);
+                    ByteArrayInputStream bis = new 
ByteArrayInputStream(certInBytes);
+                    CertificateFactory factory = CertificateFactory
+                            .getInstance("X509");
+                    java.security.cert.X509Certificate x509Cert = 
(java.security.cert.X509Certificate) factory
+                            .generateCertificate(bis);
+                    credential = new X509CredentialImpl(x509Cert);
+                }
+            } else if (keyValueList.size() > 0) {
+                if (keyValueList.size() > 1) {
+                    throw new RelyingPartyException("invalidKeyValueCount");
+                }
+
+                KeyValue val = (KeyValue) keyValueList.get(0);
+                RSAKeyValue rsaKey = val.getRSAKeyValue();
+
+                Element elem = rsaKey.getDOM();
+
+                Element modElem = (Element) elem.getElementsByTagName(
+                        Modulus.DEFAULT_ELEMENT_LOCAL_NAME).item(0);
+                Element expElem = (Element) elem.getElementsByTagName(
+                        Exponent.DEFAULT_ELEMENT_LOCAL_NAME).item(0);
+
+                BigInteger mod = Base64.decodeBigIntegerFromElement(modElem);
+                BigInteger exp = Base64.decodeBigIntegerFromElement(expElem);
+                credential = new X509CredentialImpl(mod, exp);
+            } else {
+               assert false : "unknown key info";
+            }
+        } catch (Exception e) {
+            throw new RelyingPartyException("errorReadingFromKeyInfo", 
+                    new Object[]{e.getClass(), e.getMessage()});
+        }
+
+        return credential;
+    }
+
+}

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML1TokenHolder.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML1TokenHolder.java
       Thu Feb 21 06:28:46 2008
@@ -0,0 +1,108 @@
+package org.wso2.solutions.identity.relyingparty.saml.tokens;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.opensaml.saml1.core.Assertion;
+import org.opensaml.saml1.core.Attribute;
+import org.opensaml.saml1.core.AttributeStatement;
+import org.opensaml.xml.Configuration;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.signature.Signature;
+import org.w3c.dom.Element;
+
+public class SAML1TokenHolder implements TokenHolder {
+
+    private Assertion assertion = null;
+
+    private boolean isMultipleValues = false;
+
+    private static Log log = LogFactory.getLog(SAML1TokenHolder.class);
+
+    /**
+     * Creates the SAML object from the element This method must be called 
first
+     * 
+     * @param elem
+     * @throws UnmarshallingException
+     *             If the token creation fails
+     */
+    public void createToken(Element elem) throws UnmarshallingException {
+        UnmarshallerFactory unmarshallerFactory = Configuration
+                .getUnmarshallerFactory();
+        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(elem);
+
+        assertion = (Assertion) unmarshaller.unmarshall(elem);
+    }
+
+    /**
+     * @return the SAML signature.
+     */
+    public Signature getSAMLSignature() {
+        return assertion.getSignature();
+    }
+
+    /**
+     * Issuer of the SAML token
+     * 
+     * @return
+     */
+    public String getIssuerName() {
+        return assertion.getIssuer();
+    }
+
+    /**
+     * Populates the attributes.
+     * 
+     * @param attributeTable
+     */
+    public void populateAttributeTable(Map attributeTable) {
+        Iterator statements = assertion.getAttributeStatements().iterator();
+        while (statements.hasNext()) {
+            AttributeStatement stmt = (AttributeStatement) statements.next();
+            Iterator attrs = stmt.getAttributes().iterator();
+            while (attrs.hasNext()) {
+                Attribute attr = (Attribute) attrs.next();
+                String name = attr.getAttributeNamespace() + "/"
+                        + attr.getAttributeName();
+
+                List lst = attr.getAttributeValues();
+                Iterator ite = lst.iterator();
+                int count = 0;
+                StringBuffer buff = new StringBuffer();
+                while (ite.hasNext()) {
+                    Object obj = ite.next();
+                    if (obj instanceof XSString) {
+                        buff.append(((XSString) obj).getValue());
+                    } else if (obj instanceof XSAny) {
+                        XSAny any = (XSAny) obj;
+                        String value = any.getTextContent();
+                        buff.append(value);
+                    }
+                    buff.append(",");
+                    count++;
+                }
+
+                if (buff.length() > 1) {
+                    buff.deleteCharAt(buff.length() - 1);
+                }
+
+                String value = buff.toString();
+
+                if (count > 1) {
+                    isMultipleValues = true;
+                }
+
+                attributeTable.put(name, value);
+            }
+        }
+
+    }
+
+}

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML2TokenHolder.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML2TokenHolder.java
       Thu Feb 21 06:28:46 2008
@@ -0,0 +1,109 @@
+package org.wso2.solutions.identity.relyingparty.saml.tokens;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeStatement;
+import org.opensaml.xml.Configuration;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.signature.Signature;
+import org.w3c.dom.Element;
+
+public class SAML2TokenHolder implements TokenHolder {
+
+    private Assertion assertion = null;
+
+    private boolean isMultipleValues = false;
+
+    private static Log log = LogFactory.getLog(SAML1TokenHolder.class);
+
+    /**
+     * Creates the SAML object from the element This method must be called 
first
+     * 
+     * @param elem
+     * @throws UnmarshallingException
+     *             If the token creation fails
+     */
+    public void createToken(Element elem) throws UnmarshallingException {
+        UnmarshallerFactory unmarshallerFactory = Configuration
+                .getUnmarshallerFactory();
+        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(elem);
+
+        assertion = (Assertion) unmarshaller.unmarshall(elem);
+    }
+
+    /**
+     * @return the SAML signature.
+     */
+    public Signature getSAMLSignature() {
+        return assertion.getSignature();
+    }
+
+    /**
+     * Issuer of the SAML token
+     * 
+     * @return
+     */
+    public String getIssuerName() {
+        return assertion.getIssuer().getValue();
+    }
+
+    /**
+     * Populates the attributes.
+     * 
+     * @param attributeTable
+     */
+    public void populateAttributeTable(Map attributeTable) {
+        Iterator statements = assertion.getAttributeStatements().iterator();
+        while (statements.hasNext()) {
+            AttributeStatement stmt = (AttributeStatement) statements.next();
+            Iterator attrs = stmt.getAttributes().iterator();
+            while (attrs.hasNext()) {
+                Attribute attr = (Attribute) attrs.next();
+                String attrNamesapce = attr.getNameFormat();
+                String attrName = attr.getName();
+                String name = attrNamesapce + "/" + attrName;
+
+                List lst = attr.getAttributeValues();
+                Iterator ite = lst.iterator();
+                int count = 0;
+                StringBuffer buff = new StringBuffer();
+                while (ite.hasNext()) {
+                    Object obj = ite.next();
+                    if (obj instanceof XSString) {
+                        buff.append(((XSString) obj).getValue());
+                    } else if (obj instanceof XSAny) {
+                        XSAny any = (XSAny) obj;
+                        String value = any.getTextContent();
+                        buff.append(value);
+                    }
+                    buff.append(",");
+                    count++;
+                }
+
+                if (buff.length() > 1) {
+                    buff.deleteCharAt(buff.length() - 1);
+                }
+
+                String value = buff.toString();
+
+                if (count > 1) {
+                    isMultipleValues = true;
+                }
+
+                attributeTable.put(name, value);
+            }
+        }
+
+    }
+
+}

Added: 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/TokenHolder.java
==============================================================================
--- (empty file)
+++ 
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/TokenHolder.java
    Thu Feb 21 06:28:46 2008
@@ -0,0 +1,39 @@
+package org.wso2.solutions.identity.relyingparty.saml.tokens;
+
+import java.util.Map;
+
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.signature.Signature;
+import org.w3c.dom.Element;
+
+public interface TokenHolder {
+
+    /**
+     * Creates the SAML object from the element This method must be called 
first
+     * 
+     * @param elem
+     * @throws UnmarshallingException
+     *             If the token creation fails
+     */
+    public void createToken(Element elem) throws UnmarshallingException;
+
+    /**
+     * @return the SAML signature.
+     */
+    public Signature getSAMLSignature();
+
+    /**
+     * Populates the attributes.
+     * 
+     * @param attributeTable
+     */
+    public void populateAttributeTable(Map attributeTable);
+
+    /**
+     * Issuer of the SAML token
+     * 
+     * @return
+     */
+    public String getIssuerName();
+
+}

_______________________________________________
Identity-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/identity-dev

Reply via email to