All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.wss.saml.assertion.saml20.jaxb20.Assertion Maven / Gradle / Ivy

There is a newer version: 4.0.3
Show newest version
/*
 * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/*
 * $Id: Assertion.java,v 1.2 2010-10-21 15:38:03 snajper Exp $
 */

package com.sun.xml.wss.saml.assertion.saml20.jaxb20;

import com.sun.xml.wss.core.SecurityTokenReference;
import com.sun.xml.wss.impl.dsig.WSSPolicyConsumerImpl;
import com.sun.xml.wss.saml.SAMLException;
import com.sun.xml.wss.saml.util.SAMLUtil;
import com.sun.xml.wss.saml.internal.saml20.jaxb20.AssertionType;
import com.sun.xml.wss.saml.internal.saml20.jaxb20.NameIDType;
import java.util.GregorianCalendar;
import jakarta.xml.bind.JAXBElement;

import javax.xml.datatype.DatatypeFactory;

import java.lang.reflect.Constructor;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;

import java.util.List;

import com.sun.xml.wss.logging.LogDomainConstants;
import com.sun.xml.wss.impl.XMLUtil;
import com.sun.xml.wss.impl.MessageConstants;
import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.core.reference.X509SubjectKeyIdentifier;
import com.sun.xml.wss.impl.misc.Base64;
import com.sun.xml.wss.saml.internal.saml20.jaxb20.AttributeStatementType;
import com.sun.xml.wss.saml.internal.saml20.jaxb20.AuthnStatementType;
import com.sun.xml.wss.saml.internal.saml20.jaxb20.AuthzDecisionStatementType;
import com.sun.xml.wss.saml.util.SAML20JAXBUtil;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import jakarta.xml.bind.JAXBContext;
import java.util.Set;
import java.util.Iterator;
import java.util.logging.Logger;

import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;
import jakarta.xml.soap.MessageFactory;
import jakarta.xml.soap.SOAPException;

//import com.sun.xml.wss.saml.Assertion20;
import org.w3c.dom.NodeList;

/**
 * This object stands for Assertion element. An Assertion is a package
 * of information that supplies one or more Statement made by an
 * issuer. There are three kinds of assertions Au
 * {@code
 * [java] 
 * [java] 
 * [java] 
 * [java]     CN=SAML User,OU=SU,O=SAML
 * User,L=Los Angeles,ST=CA,C=US
 * [java]     
 * [java]         urn:oasis:names:tc:SAML:1.0:cm:sender-vouches
 * [java]     
 * [java] 
 * [java] 
 * [java]     ATTRIBUTE1
 * [java] 
 * }
 * thentication, Authorization
 * Decision and Attribute assertion.
 */
public class Assertion extends AssertionType implements com.sun.xml.wss.saml.Assertion {
    
    private Element signedAssertion = null;
    private NameIDType issuerValue = null;
    private java.math.BigInteger majorValue = null;
    private java.math.BigInteger minorValue = null;
    //private Element processedAssertionElement = null;
    private List statementList = null;
    private String canonicalizationMethod = CanonicalizationMethod.EXCLUSIVE;
    private JAXBContext jc;
    /**
     * XML Information Set REC
     * all namespace attributes (including those named xmlns, 
     * whose [prefix] property has no value) have a namespace URI of http://www.w3.org/2000/xmlns/
     */
    public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/".intern();

    public Assertion(AssertionType assertion) {
        this.setID(assertion.getID());
        this.setIssueInstant(assertion.getIssueInstant());
        this.setIssuer(assertion.getIssuer());
        this.setAdvice(assertion.getAdvice());
        this.setConditions(assertion.getConditions());
        this.setSubject(assertion.getSubject());
        this.setVersion(assertion.getVersion());
        this.setSignature(assertion.getSignature());
        this.setStatement(assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement());
    }
    
    protected static final Logger log = Logger.getLogger(
            LogDomainConstants.WSS_API_DOMAIN,
            LogDomainConstants.WSS_API_DOMAIN_BUNDLE);
    
    public java.math.BigInteger getMajorVersion(){
        return this.majorValue;
    }
    
    public java.math.BigInteger getMinorVersion(){
        return this.minorValue;
    }
    
    public void setMajorVersion(java.math.BigInteger majorValue){
        this.majorValue = majorValue;
    }
    public void setMinorVersion(java.math.BigInteger minorValue){
        this.minorValue = minorValue;
    }
    
    public String getAssertionID(){
        return getID();
    }
    
    public String getSamlIssuer(){
        this.issuerValue = this.getIssuer();
        return issuerValue.getValue();
    }
    
    public String getIssueInstance(){
        if(this.issueInstant != null){
            return this.issueInstant.toString();
        }
        return null;
    }
    
    @Override
    public Conditions getConditions(){        
        Conditions cond = new Conditions(super.getConditions());        
        return cond;
    }
    
    @Override
    public Advice getAdvice(){
        Advice adv = new Advice(super.getAdvice());
        return adv;        
    }
        
    @Override
    public Subject getSubject(){       
        Subject subj = new Subject(super.getSubject());
        return subj;
    }
    
    /**
     * sign the saml assertion (Enveloped Signature)
     * @param pubKey PublicKey to be used for Signature verification
     * @param privKey PrivateKey to be used for Signature calculation
     */
    
    public Element sign(PublicKey pubKey, PrivateKey privKey) throws SAMLException {
        
        //Check if the signature is already calculated
        if ( signedAssertion != null) {
            return signedAssertion;
        }
        
        //Calculate the enveloped signature
        try {
            
            XMLSignatureFactory fac = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            return sign(fac.newDigestMethod(DigestMethod.SHA1,null),SignatureMethod.RSA_SHA1, pubKey,privKey);
            
        } catch (Exception ex) {
            // log here
            throw new SAMLException(ex);
        }
    }
    
    public Element sign(X509Certificate cert, PrivateKey privKey, boolean alwaysIncludeCert) throws SAMLException {
        //Check if the signature is already calculated
        if ( signedAssertion != null) {
            return signedAssertion;
        }
        
        //Calculate the enveloped signature
        try {
            
            XMLSignatureFactory fac = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            return sign(fac.newDigestMethod(DigestMethod.SHA1,null),SignatureMethod.RSA_SHA1, cert,privKey, alwaysIncludeCert);
            
        } catch (Exception ex) {
            // log here
            throw new SAMLException(ex);
        }
    }
    
    public Element sign(X509Certificate cert, PrivateKey privKey, boolean alwaysIncludeCert, String sigAlgorithm, String canonicalizationAlgorithm) throws SAMLException {
        //Check if the signature is already calculated
        if ( signedAssertion != null) {
            return signedAssertion;
        }

        if(sigAlgorithm == null){
            sigAlgorithm = SignatureMethod.RSA_SHA1;
        }
        
        if(canonicalizationAlgorithm != null){
            this.canonicalizationMethod = canonicalizationAlgorithm;
        }
        
        //Calculate the enveloped signature
        try {
            
            XMLSignatureFactory fac = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            return sign(fac.newDigestMethod(DigestMethod.SHA1,null),sigAlgorithm, cert,privKey, alwaysIncludeCert);
            
        } catch (Exception ex) {
            // log here
            throw new SAMLException(ex);
        }
    }
    
    public Element sign(X509Certificate cert, PrivateKey privKey) throws SAMLException {
        //Check if the signature is already calculated
        if ( signedAssertion != null) {
            return signedAssertion;
        }
        
        //Calculate the enveloped signature
        try {
            
            XMLSignatureFactory fac = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            return sign(fac.newDigestMethod(DigestMethod.SHA1,null),SignatureMethod.RSA_SHA1, cert,privKey);
            
        } catch (Exception ex) {
            // log here
            throw new SAMLException(ex);
        }
    }
    
    /**
     * sign the saml assertion (Enveloped Signature)
     * @param digestMethod DigestMethod to be used
     * @param signatureMethod SignatureMethod to be used.
     * @param pubKey PublicKey to be used for Signature verification
     * @param privKey PrivateKey to be used for Signature calculation
     */
    @SuppressWarnings("unchecked")
    public Element sign(DigestMethod digestMethod, String signatureMethod,PublicKey pubKey, PrivateKey privKey) throws SAMLException {
        
        //Check if the signature is already calculated
        if ( signedAssertion != null) {
            return signedAssertion;
            //return;
        }
        
        //Calculate the enveloped signature
        try {
            
            
            XMLSignatureFactory fac = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            ArrayList transformList = new ArrayList();
            
            Transform tr1 = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
            Transform tr2 = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);
            transformList.add(tr1);
            transformList.add(tr2);
            
            String uri = "#" + this.getID();
            Reference ref = fac.newReference(uri,digestMethod,transformList, null, null);
            
            // Create the SignedInfo
            SignedInfo si = fac.newSignedInfo
                    (fac.newCanonicalizationMethod
                    (CanonicalizationMethod.EXCLUSIVE,(C14NMethodParameterSpec) null),
                    fac.newSignatureMethod(signatureMethod, null),
                    Collections.singletonList(ref));
            
            // Create a KeyValue containing the DSA PublicKey that was generated
            KeyInfoFactory kif = fac.getKeyInfoFactory();
            KeyValue kv = kif.newKeyValue(pubKey);
            
            // Create a KeyInfo and add the KeyValue to it
            KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
            
            // Instantiate the document to be signed
            Document doc =  XMLUtil.newDocument();
            
            //Document document;
            
            //Element assertionElement = this.toElement(doc);
            Element assertionElement = this.toElement(doc);
            //try {
            //    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //    DocumentBuilder builder = factory.newDocumentBuilder();
            //    document = builder.newDocument();
            //} catch (Exception ex) {
            //    throw new XWSSecurityException("Unable to create Document : " + ex.getMessage());
            //}
            
            //document.appendChild(assertionElement);
            //doc.appendChild(assertionElement);
            
            // Create a DOMSignContext and specify the DSA PrivateKey and
            // location of the resulting XMLSignature's parent element
            
            DOMSignContext dsc = null;
            KeySelector ks = KeySelector.singletonKeySelector(privKey);
            NodeList nl = assertionElement.getElementsByTagNameNS(assertionElement.getNamespaceURI(), "Issuer");
            Node issuer = null;
            if (nl != null && nl.getLength() > 0) {
                issuer = nl.item(0);
            }
            Node nextSibling = (issuer != null) ? issuer.getNextSibling():null;
            if (nextSibling != null) {
                dsc = new DOMSignContext(ks, assertionElement, nextSibling);
            } else {
                dsc = new DOMSignContext(privKey, assertionElement);
            }
            HashMap map = new HashMap();
            map.put(this.getID(),assertionElement);

            dsc.setURIDereferencer(new DSigResolver(map,assertionElement));
            XMLSignature signature = fac.newXMLSignature(si, ki);
            dsc.putNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", "ds");
            
            // Marshal, generate (and sign) the enveloped signature
            signature.sign(dsc);
            
            signedAssertion = assertionElement;
            return assertionElement;
        } catch (Exception ex) {
            // log here
            throw new SAMLException(ex);
        }
        //return signedAssertion;
    }
    @SuppressWarnings("unchecked")
    public Element sign(DigestMethod digestMethod, String signatureMethod, X509Certificate cert, PrivateKey privKey, boolean includeCert) throws SAMLException {
        //Check if the signature is already calculated
        if ( signedAssertion != null) {
            return signedAssertion;
            //return;
        }
        
        //Calculate the enveloped signature
        try {
            XMLSignatureFactory fac = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            ArrayList transformList = new ArrayList();
            
            Transform tr1 = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
            Transform tr2 = fac.newTransform(canonicalizationMethod, (TransformParameterSpec) null);
            transformList.add(tr1);
            transformList.add(tr2);
            
            String uri = "#" + this.getID();
            Reference ref = fac.newReference(uri,digestMethod,transformList, null, null);
            
            // Create the SignedInfo
            SignedInfo si = fac.newSignedInfo
                    (fac.newCanonicalizationMethod
                    (canonicalizationMethod,
                    (C14NMethodParameterSpec) null),
                    fac.newSignatureMethod(signatureMethod, null),
                    Collections.singletonList(ref));
            
            // Instantiate the document to be signed
            Document doc = MessageFactory.newInstance().createMessage().getSOAPPart();
            KeyInfoFactory kif = fac.getKeyInfoFactory();
            KeyInfo ki = null;
            if (!includeCert){
                byte[] skid = X509SubjectKeyIdentifier.getSubjectKeyIdentifier(cert);
                if (skid != null){
                    X509SubjectKeyIdentifier keyIdentifier = new X509SubjectKeyIdentifier(doc);
                    keyIdentifier.setCertificate(cert);
                    keyIdentifier.setReferenceValue(Base64.encode(skid));
                    SecurityTokenReference str = new SecurityTokenReference();
                    str.setReference(keyIdentifier);
                    DOMStructure domKeyInfo = new DOMStructure(str.getAsSoapElement());
                    ki = kif.newKeyInfo(Collections.singletonList(domKeyInfo));
                }
            }
            
            if (ki == null){
                  X509Data x509Data = kif.newX509Data(Collections.singletonList(cert));
                  ki = kif.newKeyInfo(Collections.singletonList(x509Data));
            }
           /* KeyIdentifier kid = new KeyIdentifierImpl(MessageConstants.X509SubjectKeyIdentifier_NS, MessageConstants.MessageConstants.BASE64_ENCODING_NS);
            kid.setValue(Base64.encode(X509SubjectKeyIdentifier.getSubjectKeyIdentifier(cert)));
            SecurityTokenReference str = new SecurityTokenReferenceImpl(kid);*/  
            Element assertionElement = this.toElement(doc);
            //try {
            //    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //    DocumentBuilder builder = factory.newDocumentBuilder();
            //    document = builder.newDocument();
            //} catch (Exception ex) {
            //    throw new XWSSecurityException("Unable to create Document : " + ex.getMessage());
            //}
            //document.appendChild(assertionElement);
            //doc.appendChild(assertionElement);
            
            
            
            // Create a DOMSignContext and specify the DSA PrivateKey and
            // location of the resulting XMLSignature's parent element
            DOMSignContext dsc = null;
            KeySelector ks = KeySelector.singletonKeySelector(privKey);
            NodeList nl = assertionElement.getElementsByTagNameNS(assertionElement.getNamespaceURI(), "Issuer");
            Node issuer = null;
            if (nl != null && nl.getLength() > 0) {
                issuer = nl.item(0);
            }
            Node nextSibling = (issuer != null) ? issuer.getNextSibling():null;
            if (nextSibling != null) {
                dsc = new DOMSignContext(ks, assertionElement, nextSibling);
            } else {
                dsc = new DOMSignContext(privKey, assertionElement);
            }
            HashMap map = new HashMap();
            map.put(this.getID(),assertionElement);
            
            dsc.setURIDereferencer(new DSigResolver(map,assertionElement));
            XMLSignature signature = fac.newXMLSignature(si, ki);
            dsc.putNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", "ds");
            
            // Marshal, generate (and sign) the enveloped signature
            signature.sign(dsc);
            
            signedAssertion = assertionElement;
            return assertionElement;
        } catch (XWSSecurityException ex) {
            throw new SAMLException(ex);
        } catch (MarshalException ex) {
            throw new SAMLException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new SAMLException(ex);
        } catch (SOAPException ex) {
            throw new SAMLException(ex);
        } catch (XMLSignatureException ex) {
            throw new SAMLException(ex);
        } catch (InvalidAlgorithmParameterException ex) {
            throw new SAMLException(ex);
        }
    }
    
    public Element sign(DigestMethod digestMethod, String signatureMethod, X509Certificate cert, PrivateKey privKey) throws SAMLException {
        return sign(digestMethod, signatureMethod, cert, privKey, false);
    }
    
    public Element toElement(Node doc) throws XWSSecurityException {
        if ( signedAssertion == null) {
            signedAssertion = SAMLUtil.toElement(doc, this,jc);
            if (signedAssertion == null ){
                return signedAssertion;
            }
            if ( System.getProperty("com.sun.xml.wss.saml.binding.jaxb") == null) {
                signedAssertion.setAttributeNS(XMLNS_URI, "xmlns:xs", MessageConstants.XSD_NS);
            }
        }
        return signedAssertion;
    }
    
    public boolean isSigned() {
        return signature != null?true:false;
    }
    
    /**
     * This constructor is used to build Assertion object from a
     * block of existing XML that has already been built into a DOM.
     *
     * @param element A org.w3c.dom.Element representing
     *        DOM tree for Assertion object
     * @exception SAMLException if it could not process the Element properly,
     *            implying that there is an error in the sender or in the
     *            element definition.
     */
    public static Assertion fromElement(org.w3c.dom.Element element)
    throws SAMLException {
        try {
            JAXBContext jc = SAML20JAXBUtil.getJAXBContext();
            
            jakarta.xml.bind.Unmarshaller u = jc.createUnmarshaller();
            Object el = u.unmarshal(element);
            //return new Assertion((AssertionType)u.unmarshal(element));
            return new Assertion((AssertionType)((JAXBElement)el).getValue());
        } catch ( Exception ex) {
            // log here
            throw new SAMLException(ex);
        }
    }
    @SuppressWarnings("unchecked")
    private void setStatement(List statement) {
        this.statementOrAuthnStatementOrAuthzDecisionStatement = statement;
    }
    
    public String getType() {
        return MessageConstants.SAML_v2_0_NS;
    }
    
    public Object getTokenValue() {

        try {
            Document doc = XMLUtil.newDocument();
            return this.toElement(doc);
        } catch (ParserConfigurationException ex) {            
        } catch (XWSSecurityException ex) {
        }
        return null;
    }
    
    /**
     * This constructor is used to populate the data members: the
     * assertionID, the issuer, time when assertion issued,
     * the conditions when creating a new assertion , Advice
     * applicable to this Assertion and a set of
     * Statement(s) in the assertion.
     *
     * @param assertionID AssertionID object contained within this
     *        Assertion if null its generated internally.
     * @param issuer The issuer of this assertion.
     * @param issueInstant Time instant of the issue. It has type
     *        dateTime which is built in to the W3C XML Schema
     *        Types specification. if null, current time is used.
     * @param conditions Conditions under which the this
     *        Assertion is valid.
     * @param advice Advice applicable for this
     *        Assertion.
     * @param statements List of Statement objects within this
     *         Assertion. It could be of type
     *         AuthenticationStatement,
     *         AuthorizationDecisionStatement and
     *         AttributeStatement. Each Assertion can have
     *         multiple type of statements in it.
     * @exception SAMLException if there is an error in processing input.
     */
    public Assertion(
            String assertionID, NameID issuer, GregorianCalendar issueInstant,
            Conditions conditions, Advice advice, Subject subject, List statements)
            throws SAMLException {
        if ( assertionID != null)
            setID(assertionID);
        
        if ( issuer != null)
            setIssuer(issuer);
        
        if ( issueInstant != null) {
            try {
                DatatypeFactory factory = DatatypeFactory.newInstance();
                setIssueInstant(factory.newXMLGregorianCalendar(issueInstant));
            } catch (Exception e) {
                //ignore
            }
        }
        
        if ( conditions != null)
            setConditions(conditions);
        
        if ( advice != null)
            setAdvice(advice);
        
        if ( statements != null)
            setStatement(statements);
        
        if ( subject != null)
            setSubject(subject);
        
        setVersion("2.0");
    }
    /**
     * This constructor is used to populate the data members: the
     * assertionID, the issuer, time when assertion issued,
     * the conditions when creating a new assertion , Advice
     * applicable to this Assertion ,a set of
     * Statement(s) and a JAXBContext for  the assertion.
     *
     * @param assertionID AssertionID object contained within this
     *        Assertion if null its generated internally.
     * @param issuer The issuer of this assertion.
     * @param issueInstant Time instant of the issue. It has type
     *        dateTime which is built in to the W3C XML Schema
     *        Types specification. if null, current time is used.
     * @param conditions Conditions under which the this
     *        Assertion is valid.
     * @param advice Advice applicable for this
     *        Assertion.
     * @param statements List of Statement objects within this
     *         Assertion. It could be of type
     *         AuthenticationStatement,
     *         AuthorizationDecisionStatement and
     *         AttributeStatement. Each Assertion can have
     *         multiple type of statements in it.
     * @param jcc JAXBContext to be used for marshaling and unmarshalling the asertions.
     * @exception SAMLException if there is an error in processing input.
     */
    public Assertion(
            String assertionID, NameID issuer, GregorianCalendar issueInstant,
            Conditions conditions, Advice advice, Subject subject, List statements,JAXBContext jcc)
            throws SAMLException {
        
          this( assertionID,  issuer,  issueInstant,
             conditions,  advice,  subject,  statements);
          jc=jcc;
   }
    @SuppressWarnings("unchecked")
    private static class DSigResolver implements URIDereferencer{
        //TODO : Convert DSigResolver to singleton class.
        Element elem = null;
        Map map = null;
        Class _nodeSetClass = null;
        String optNSClassName = "org.apache.jcp.xml.dsig.internal.dom.DOMSubTreeData";
        Constructor _constructor = null;
        Boolean  _false = Boolean.valueOf(false);
        DSigResolver(Map map,Element elem){
            this.elem = elem;
            this.map = map;
            init();
        }
        
        void init(){
            try{
                _nodeSetClass = Class.forName(optNSClassName);
                _constructor = _nodeSetClass.getConstructor(new Class [] {org.w3c.dom.Node.class,boolean.class});
            }catch(LinkageError le){
                // logger.log (Level.FINE,"Not able load JSR 105 RI specific NodeSetData class ",le);
            }catch(ClassNotFoundException cne){
                // logger.log (Level.FINE,"Not able load JSR 105 RI specific NodeSetData class ",cne);
            }catch(NoSuchMethodException ne){
                
            }
        }
        public Data dereference(URIReference uriRef, XMLCryptoContext context) throws URIReferenceException {
            try{
                String uri = null;
                uri = uriRef.getURI();
                return dereferenceURI(uri,context);
            }catch(Exception ex){
                // log here
                throw new URIReferenceException(ex);
            }
        }
        Data dereferenceURI(String uri, XMLCryptoContext context) throws URIReferenceException{
            if(uri.charAt(0) == '#'){
                uri =  uri.substring(1,uri.length());
                Element el = elem.getOwnerDocument().getElementById(uri);
                if(el == null){
                    el = (Element)map.get(uri);
                }
                
                if(_constructor != null){
                    try{
                        return (Data)_constructor.newInstance(new Object[] {el,_false});
                    }catch(Exception ex){
                        // TODO: igonore this ?
                        ex.printStackTrace();
                    }
                }else{
                    final HashSet nodeSet = new HashSet();
                    toNodeSet(el,nodeSet);
                    return new NodeSetData(){
                        public Iterator iterator(){
                            return nodeSet.iterator();
                        }
                    };
                }
                
            }
            
            return null;
            //throw new URIReferenceException("Resource "+uri+" was not found");
        }
        
        void toNodeSet(final Node rootNode,final Set result){
            switch (rootNode.getNodeType()) {
                case Node.ELEMENT_NODE:
                    result.add(rootNode);
                    Element el=(Element)rootNode;
                    if (el.hasAttributes()) {
                        NamedNodeMap nl = ((Element)rootNode).getAttributes();
                        for (int i=0;i getStatements() {
        if(statementList == null){
            statementList = new ArrayList();
        }else{
            return statementList;
        }
        List list = super.getStatementOrAuthnStatementOrAuthzDecisionStatement();
        Iterator ite = list.iterator();
        
        while (ite.hasNext()) {
            Object object = ite.next();
            if (object instanceof AttributeStatementType) {
                AttributeStatement attStmt = new AttributeStatement((AttributeStatementType) object);
                statementList.add(attStmt);
            } else if (object instanceof AuthnStatementType) {
                AuthnStatement authStmt = new AuthnStatement((AuthnStatementType) object);
                statementList.add(authStmt);
            } else if (object instanceof AuthzDecisionStatementType) {
                AuthzDecisionStatement authDesStmt = new AuthzDecisionStatement((AuthzDecisionStatementType) object);
                statementList.add(authDesStmt);
            }else if((object instanceof AttributeStatement) ||
                  (object instanceof AuthnStatement) ||
                     (object instanceof AuthzDecisionStatement)){
                statementList = list;
                return statementList;
            }
        }
        return statementList;
    }
    @SuppressWarnings("unchecked")
    public boolean verifySignature(PublicKey pubKey) throws SAMLException {
        try {
            Document doc = XMLUtil.newDocument();
            Element samlAssertion = this.toElement(doc);
            HashMap map = new HashMap();
            map.put(this.getID(), samlAssertion);
            NodeList nl = samlAssertion.getElementsByTagNameNS(MessageConstants.DSIG_NS, "Signature");
            //verify the signature inside the SAML assertion
            if (nl.getLength() == 0) {
                throw new SAMLException("Unsigned SAML Assertion encountered while verifying the SAML signature");
            }
            Element signElement = (Element) nl.item(0);
            DOMValidateContext validationContext = new DOMValidateContext(pubKey, signElement);
            XMLSignatureFactory signatureFactory = WSSPolicyConsumerImpl.getInstance().getSignatureFactory();
            // unmarshal the XMLSignature
            XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(validationContext);            
            validationContext.setURIDereferencer(new DSigResolver(map, samlAssertion));
            boolean coreValidity = xmlSignature.validate(validationContext);
            return coreValidity;
        } catch (Exception ex) {
            throw new SAMLException(ex);
        }
    }
}