Package com.sun.xml.wss.saml.util

Source Code of com.sun.xml.wss.saml.util.SAMLUtil$DSigResolver

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.xml.wss.saml.util;


import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
import com.sun.xml.stream.buffer.stax.StreamWriterBufferCreator;
import com.sun.xml.wss.WSITXMLFactory;
import com.sun.xml.wss.impl.SecurableSoapMessage;
import com.sun.xml.wss.logging.LogDomainConstants;
import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.impl.MessageConstants;
import com.sun.xml.wss.impl.dsig.WSSPolicyConsumerImpl;
import com.sun.xml.wss.logging.saml.LogStringsMessages;
import java.text.ParseException;
import java.util.Date;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBContext;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import com.sun.xml.wss.util.DateUtils;
import java.lang.reflect.Constructor;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.xml.crypto.Data;
import javax.xml.crypto.NodeSetData;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.URIReference;
import javax.xml.crypto.URIReferenceException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import org.w3c.dom.NamedNodeMap;

public class SAMLUtil {
    private static Logger logger = Logger.getLogger(LogDomainConstants.SAML_API_DOMAIN,
            LogDomainConstants.SAML_API_DOMAIN_BUNDLE);     
   
    public static Element locateSamlAssertion(String assertionId,Document soapDocument)
    throws XWSSecurityException {
       
        //System.out.println("\n\n--------SOAP DOCUMENT : " + soapDocument + "--------\n\n");
       
        NodeList nodeList = null;
       
//        try {
          nodeList = soapDocument.getElementsByTagNameNS(MessageConstants.SAML_v1_0_NS, MessageConstants.SAML_ASSERTION_LNAME);
          if((nodeList.item(0)) == null ){
              nodeList = soapDocument.getElementsByTagNameNS(MessageConstants.SAML_v2_0_NS,
                    MessageConstants.SAML_ASSERTION_LNAME);
          }
       
        int nodeListLength = nodeList.getLength();
        if (nodeListLength == 0) {
                logger.log(Level.SEVERE,LogStringsMessages.WSS_001_SAML_ASSERTION_NOT_FOUND(assertionId));
            throw SecurableSoapMessage.newSOAPFaultException(
                    MessageConstants.WSSE_SECURITY_TOKEN_UNAVAILABLE,
                    "Referenced Security Token could not be retrieved",
                    null);
            //throw new XWSSecurityException(
            //"No SAML Assertion found with  AssertionID:" + assertionId );
        }
       
        for (int i=0; i<nodeListLength; i++) {
            Element assertion = (Element) nodeList.item(i);
            String  aId = assertion.getAttribute(MessageConstants.SAML_ASSERTIONID_LNAME);
            String id = assertion.getAttribute(MessageConstants.SAML_ID_LNAME);
            if (aId.equals(assertionId) || id.equals(assertionId)) {
                //return  XMLUtil.convertToSoapElement(soapDocument, assertion);
                return assertion;
            }
        }
            logger.log(Level.SEVERE,LogStringsMessages.WSS_001_SAML_ASSERTION_NOT_FOUND(assertionId));
        throw SecurableSoapMessage.newSOAPFaultException(
                MessageConstants.WSSE_SECURITY_TOKEN_UNAVAILABLE,
                "Referenced Security Token could not be retrieved",
                null);
        //throw new XWSSecurityException("Could not locate SAML assertion with AssertionId:" + assertionId);
    }
   
    public static Element toElement(Node doc, Object element) throws XWSSecurityException{
        return toElement(doc, element, null);
    }

    public static Element toElement(Node doc, Object element,JAXBContext jcc) throws XWSSecurityException{
       
        DOMResult result = null;
        Document document = null;
        //TODO : If DOC is SUPPLIED then this code is not working
        if ( doc != null) {
           
            result = new DOMResult(doc);
        } else {
           
            try {
                DocumentBuilderFactory factory = WSITXMLFactory.createDocumentBuilderFactory(WSITXMLFactory.DISABLE_SECURE_PROCESSING);
                DocumentBuilder builder = factory.newDocumentBuilder();
                document = builder.newDocument();
            } catch (Exception ex) {
                logger.log(Level.SEVERE, LogStringsMessages.WSS_002_FAILED_CREATE_DOCUMENT(), ex);
                throw new XWSSecurityException("Unable to create Document : " + ex.getMessage());
            }
            result = new DOMResult(document);
        }
       
        try {
            JAXBContext jc = jcc;
            if (jc == null) {
                if (System.getProperty("com.sun.xml.wss.saml.binding.jaxb") == null) {
                    if (element instanceof com.sun.xml.wss.saml.assertion.saml20.jaxb20.Assertion) {
                        jc = SAML20JAXBUtil.getJAXBContext();
                    } else {
                        jc = SAMLJAXBUtil.getJAXBContext();
                    }
                } else {
                    jc = SAMLJAXBUtil.getJAXBContext();
                }
            }
           
            Marshaller m = jc.createMarshaller();
           
            if (element == null){
                if (logger.isLoggable(Level.FINE)) {
                    logger.log(Level.FINE,"Element is Null in SAMLUtil.toElement()");
                }
            }
           
            m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new WSSNamespacePrefixMapper());
            m.marshal(element, result);           
           
        } catch (Exception ex) {
            logger.log(Level.SEVERE,LogStringsMessages.WSS_003_FAILEDTO_MARSHAL(), ex);
            throw new XWSSecurityException("Not able to Marshal " + element.getClass().getName() +
                ", got exception: " + ex.getMessage());
        }
       
        if ( doc != null) {
            //return ((Document)doc).getDocumentElement();
           
           
            if (doc.getNodeType() == Node.ELEMENT_NODE) {
                if (doc.getFirstChild().getNamespaceURI().equals(MessageConstants.SAML_v2_0_NS)){
                    Element el = (Element)((Element)doc).getElementsByTagNameNS(MessageConstants.SAML_v2_0_NS, "Assertion").item(0);
                    return el;
                }else{
                    Element el = (Element)((Element)doc).getElementsByTagNameNS(MessageConstants.SAML_v1_0_NS, "Assertion").item(0);
                    return el;
                }
            } else {
                if (doc.getFirstChild().getNamespaceURI().equals(MessageConstants.SAML_v2_0_NS)){
                    Element el = (Element)((Document)doc).getElementsByTagNameNS(MessageConstants.SAML_v2_0_NS,"Assertion").item(0);
                    return el;
                }else{
                    Element el = (Element)((Document)doc).getElementsByTagNameNS(MessageConstants.SAML_v1_0_NS,"Assertion").item(0);
                    return el;
                }
            }
           
        } else {
            if (document.getFirstChild().getNamespaceURI().equals(MessageConstants.SAML_v2_0_NS)){
                Element el = (Element)document.getElementsByTagNameNS(MessageConstants.SAML_v2_0_NS, "Assertion").item(0);
                return el;           
            }else{
                Element el = (Element)document.getElementsByTagNameNS(MessageConstants.SAML_v1_0_NS, "Assertion").item(0);
                return el;           
            }
        }
    }
   
    public static Element createSAMLAssertion(XMLStreamReader reader) throws XWSSecurityException,XMLStreamException{
        XMLOutputFactory xof = XMLOutputFactory.newInstance();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();       
        MutableXMLStreamBuffer buffer = new MutableXMLStreamBuffer();
        StreamWriterBufferCreator bCreator = new StreamWriterBufferCreator(buffer);
        Document doc = null;       
        try{                               
            XMLStreamWriter writer = xof.createXMLStreamWriter(baos);
            XMLStreamWriter writer_tmp = (XMLStreamWriter)bCreator;
            while(!(XMLStreamReader.END_DOCUMENT == reader.getEventType())){
                com.sun.xml.ws.security.opt.impl.util.StreamUtil.writeCurrentEvent(reader, writer_tmp);
                reader.next();
            }
            buffer.writeToXMLStreamWriter(writer);
            writer.close();
            try {
                baos.close();
            } catch (IOException ex) {
                throw new XWSSecurityException("Error occurred while trying to convert SAMLAssertion stream into DOM Element", ex);
            }
            DocumentBuilderFactory dbf = WSITXMLFactory.createDocumentBuilderFactory(WSITXMLFactory.DISABLE_SECURE_PROCESSING);
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();           
            doc = db.parse(new ByteArrayInputStream(baos.toByteArray()));
            return  doc.getDocumentElement();   
        } catch(XMLStreamException xe){
            throw new XMLStreamException("Error occurred while trying to convert SAMLAssertion stream into DOM Element", xe);
        }catch(Exception xe){
            throw new XWSSecurityException("Error occurred while trying to convert SAMLAssertion stream into DOM Element", xe);
        }
    }   
   
    public static boolean validateTimeInConditionsStatement(Element samlAssertion) throws XWSSecurityException {
    
        Date _notBefore=null;
        Date  _notOnOrAfter=null;
       
        NodeList nl = samlAssertion.getElementsByTagNameNS(samlAssertion.getNamespaceURI(), "Conditions");
        Node conditionsElement = null;
        if (nl != null && nl.getLength() > 0) {
            conditionsElement = nl.item(0);
        } else {
            //no conditions stmt
            logger.log(Level.INFO, "No Conditions Element found in SAML Assertion");
            return true;
        }
        Element elt = (Element)conditionsElement;
        String eltName = elt.getLocalName();
        if (eltName == null)  {
            throw new XWSSecurityException("Internal Error: LocalName of Conditions Element found Null") ;
        }
        if (!(eltName.equals("Conditions")))  {
            throw new XWSSecurityException("Internal Error: LocalName of Conditions Element found to be :" + eltName) ;
        }
       
        String dt = elt.getAttribute("NotBefore");
        if ((dt != null) && (!dt.equals("")))  {
            try {
                _notBefore = DateUtils.stringToDate(dt);
            } catch (ParseException pe) {
               throw new XWSSecurityException(pe);
            }
                                                                                                                                                            
        }
        dt = elt.getAttribute("NotOnOrAfter");
        if ((dt != null) && (!dt.equals("")))  {
            try {
                _notOnOrAfter = DateUtils.stringToDate(
                            elt.getAttribute("NotOnOrAfter"));
            } catch (ParseException pe) {
               throw new XWSSecurityException(pe);
            }
        }
       
        long someTime = System.currentTimeMillis();
       
        if (_notBefore == null ) {
            if (_notOnOrAfter == null) {
                return true;
            } else {
                if (someTime < _notOnOrAfter.getTime()) {
                    return true;
                }
            }
        } else if (_notOnOrAfter == null ) {
            if (someTime >= _notBefore.getTime()) {
                return true;
            }
        } else if ((someTime >= _notBefore.getTime()) &&
            (someTime < _notOnOrAfter.getTime()))
        {
            return true;
        }
        return false;
    }

    public static boolean verifySignature(Element samlAssertion, PublicKey pubKey)throws XWSSecurityException {
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            String id = samlAssertion.getAttribute("ID");
            if (id == null || id.length() < 1){
                id = samlAssertion.getAttribute("AssertionID");
            }
            map.put(id, samlAssertion);
            NodeList nl = samlAssertion.getElementsByTagNameNS(MessageConstants.DSIG_NS, "Signature");

            //verify the signature inside the SAML assertion
            if (nl.getLength() == 0) {
                throw new XWSSecurityException("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 XWSSecurityException(ex);
        }
    }

    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<Object> nodeSet = new HashSet<Object>();
                    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<Object> 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<nl.getLength();i++) {
                            result.add(nl.item(i));
                        }
                    }
                    //no return keep working
                case Node.DOCUMENT_NODE:
                    for (Node r=rootNode.getFirstChild();r!=null;r=r.getNextSibling()){
                        if (r.getNodeType()==Node.TEXT_NODE) {
                            result.add(r);
                            while ((r!=null) && (r.getNodeType()==Node.TEXT_NODE)) {
                                r=r.getNextSibling();
                            }
                            if (r==null)
                                return;
                        }
                        toNodeSet(r,result);
                    }
                    return;
                case Node.COMMENT_NODE:
                    return;
                case Node.DOCUMENT_TYPE_NODE:
                    return;
                default:
                    result.add(rootNode);
            }
            return;
        }
    }
}
TOP

Related Classes of com.sun.xml.wss.saml.util.SAMLUtil$DSigResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.