<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>SAML2Utils.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> &gt; <a href="index.source.html" class="el_package">org.apache.rahas.impl.util</a> &gt; <span class="el_source">SAML2Utils.java</span></div><h1>SAML2Utils.java</h1><pre class="source lang-java linenums">/*
 * Copyright The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
 * 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 &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.rahas.impl.util;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.dom.DOMMetaFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.TrustException;
import org.apache.ws.security.*;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.util.Base64;
import org.apache.ws.security.util.UUIDGenerator;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SAMLVersion;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.*;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.io.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.List;

<span class="nc" id="L61">public class SAML2Utils {</span>

<span class="fc" id="L63">    private static final Log log = LogFactory.getLog(SAML2Utils.class);</span>

    public static Element getElementFromAssertion(XMLObject xmlObj) throws TrustException {
        try {
            
<span class="nc" id="L68">            MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory();</span>
<span class="nc" id="L69">            Marshaller marshaller = marshallerFactory.getMarshaller(xmlObj);</span>
<span class="nc" id="L70">            Element assertionElement = marshaller.marshall(xmlObj,</span>
                    ((DOMMetaFactory)OMAbstractFactory.getMetaFactory(OMAbstractFactory.FEATURE_DOM)).newDocumentBuilderFactory().newDocumentBuilder().newDocument());

<span class="nc" id="L73">            log.debug(&quot;DOM element is created successfully from the OpenSAML2 XMLObject&quot;);</span>
<span class="nc" id="L74">            return assertionElement;</span>

<span class="nc" id="L76">        } catch (Exception e) {</span>
<span class="nc" id="L77">            throw new TrustException(&quot;Error creating DOM object from the assertion&quot;, e);</span>
        }
    }

    /**
     * Extract certificates or the key available in the SAMLAssertion
     *
     * @param elem  The element to process.
     * @param crypto The crypto properties.
     * @param cb Callback class to get the Key
     * @return the SAML2 Key Info
     * @throws org.apache.ws.security.WSSecurityException If an error occurred while extracting KeyInfo.
     *
     */
    public static SAML2KeyInfo getSAML2KeyInfo(Element elem, Crypto crypto,
                                              CallbackHandler cb) throws WSSecurityException {
        Assertion assertion;

        //build the assertion by unmarhalling the DOM element.
        try {
<span class="nc" id="L97">            DefaultBootstrap.bootstrap();</span>

<span class="nc" id="L99">            String keyInfoElementString = elem.toString();</span>
<span class="nc" id="L100">            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();</span>
<span class="nc" id="L101">            documentBuilderFactory.setNamespaceAware(true);</span>
<span class="nc" id="L102">            DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();</span>
<span class="nc" id="L103">            Document document = docBuilder.parse(new ByteArrayInputStream(keyInfoElementString.trim().getBytes()));</span>
<span class="nc" id="L104">            Element element = document.getDocumentElement();</span>
<span class="nc" id="L105">            UnmarshallerFactory unmarshallerFactory = Configuration</span>
                    .getUnmarshallerFactory();
<span class="nc" id="L107">            Unmarshaller unmarshaller = unmarshallerFactory</span>
                    .getUnmarshaller(element);
<span class="nc" id="L109">            assertion = (Assertion) unmarshaller</span>
                    .unmarshall(element);
        }
<span class="nc" id="L112">        catch (ConfigurationException e) {</span>
<span class="nc" id="L113">            throw new WSSecurityException(</span>
                    WSSecurityException.FAILURE, &quot;Failure in bootstrapping&quot;, null, e);
<span class="nc" id="L115">        } catch (UnmarshallingException e) {</span>
<span class="nc" id="L116">            throw new WSSecurityException(</span>
                    WSSecurityException.FAILURE, &quot;Failure in unmarshelling the assertion&quot;, null, e);
<span class="nc" id="L118">        } catch (IOException e) {</span>
<span class="nc" id="L119">            throw new WSSecurityException(</span>
                    WSSecurityException.FAILURE, &quot;Failure in unmarshelling the assertion&quot;, null, e);
<span class="nc" id="L121">        } catch (SAXException e) {</span>
<span class="nc" id="L122">            throw new WSSecurityException(</span>
                    WSSecurityException.FAILURE, &quot;Failure in unmarshelling the assertion&quot;, null, e);
<span class="nc" id="L124">        } catch (ParserConfigurationException e) {</span>
<span class="nc" id="L125">            throw new WSSecurityException(</span>
                    WSSecurityException.FAILURE, &quot;Failure in unmarshelling the assertion&quot;, null, e);
<span class="nc" id="L127">        }</span>
<span class="nc" id="L128">        return getSAML2KeyInfo(assertion, crypto, cb);</span>

    }

    public static SAML2KeyInfo getSAML2KeyInfo(Assertion assertion, Crypto crypto,
                                               CallbackHandler cb) throws WSSecurityException {

        //First ask the cb whether it can provide the secret
<span class="nc" id="L136">        WSPasswordCallback pwcb = new WSPasswordCallback(assertion.getID(), WSPasswordCallback.CUSTOM_TOKEN);</span>
<span class="nc bnc" id="L137" title="All 2 branches missed.">        if (cb != null) {</span>
            try {
<span class="nc" id="L139">                cb.handle(new Callback[]{pwcb});</span>
<span class="nc" id="L140">            } catch (Exception e1) {</span>
<span class="nc" id="L141">                throw new WSSecurityException(WSSecurityException.FAILURE, &quot;noKey&quot;,</span>
                        new Object[]{assertion.getID()}, e1);
<span class="nc" id="L143">            }</span>
        }

<span class="nc" id="L146">        byte[] key = pwcb.getKey();</span>

<span class="nc bnc" id="L148" title="All 2 branches missed.">        if (key != null) {</span>
<span class="nc" id="L149">            return new SAML2KeyInfo(assertion, key);</span>
        } else {
            // if the cb fails to provide the secret.
            try {
                // extract the subject
<span class="nc" id="L154">                Subject samlSubject = assertion.getSubject();</span>
<span class="nc bnc" id="L155" title="All 2 branches missed.">                if (samlSubject == null) {</span>
<span class="nc" id="L156">                    throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                            &quot;invalidSAML2Token&quot;, new Object[]{&quot;for Signature (no Subject)&quot;});
                }

                // extract the subject confirmation element from the subject
<span class="nc" id="L161">                SubjectConfirmation subjectConf = samlSubject.getSubjectConfirmations().get(0);</span>
<span class="nc bnc" id="L162" title="All 2 branches missed.">                if (subjectConf == null) {</span>
<span class="nc" id="L163">                    throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                            &quot;invalidSAML2Token&quot;, new Object[]{&quot;for Signature (no Subject Confirmation)&quot;});
                }

                // Get the subject confirmation data, KeyInfoConfirmationDataType extends SubjectConfirmationData.
<span class="nc" id="L168">                SubjectConfirmationData scData = subjectConf.getSubjectConfirmationData();</span>
                
<span class="nc bnc" id="L170" title="All 2 branches missed.">                if (scData == null) {</span>
<span class="nc" id="L171">                    throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                            &quot;invalidSAML2Token&quot;, new Object[]{&quot;for Signature (no Subject Confirmation Data)&quot;});
                }

                // Get the SAML specific XML representation of the keyInfo object
<span class="nc" id="L176">                XMLObject KIElem = null;</span>
<span class="nc" id="L177">                List&lt;XMLObject&gt; scDataElements = scData.getOrderedChildren();</span>
<span class="nc bnc" id="L178" title="All 2 branches missed.">                for (XMLObject xmlObj : scDataElements) {</span>
<span class="nc bnc" id="L179" title="All 2 branches missed.">                    if (xmlObj instanceof org.opensaml.xml.signature.KeyInfo) {</span>
<span class="nc" id="L180">                        KIElem = xmlObj;</span>
<span class="nc" id="L181">                        break;</span>
                    }
<span class="nc" id="L183">                }</span>

                Element keyInfoElement;

                // Generate a DOM element from the XMLObject.
<span class="nc bnc" id="L188" title="All 2 branches missed.">                if (KIElem != null) {</span>

<span class="nc" id="L190">                    MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory();</span>
<span class="nc" id="L191">                    Marshaller marshaller = marshallerFactory.getMarshaller(KIElem);</span>
                    try {
<span class="nc" id="L193">                        keyInfoElement = marshaller.marshall(KIElem,</span>
                                ((DOMMetaFactory)OMAbstractFactory.getMetaFactory(OMAbstractFactory.FEATURE_DOM)).newDocumentBuilderFactory().newDocumentBuilder().newDocument());
<span class="nc" id="L195">                    } catch (ParserConfigurationException ex) {</span>
                        // We never get here
<span class="nc" id="L197">                        throw new Error(ex);</span>
<span class="nc" id="L198">                    }</span>

<span class="nc" id="L200">                } else {</span>
<span class="nc" id="L201">                    throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                            &quot;invalidSAML2Token&quot;, new Object[]{&quot;for Signature (no key info element)&quot;});
                }

<span class="nc bnc" id="L205" title="All 2 branches missed.">                AttributeStatement attrStmt = assertion.getAttributeStatements().size() != 0 ?</span>
                        assertion.getAttributeStatements().get(0) : null;
<span class="nc bnc" id="L207" title="All 2 branches missed.">                AuthnStatement authnStmt = assertion.getAuthnStatements().size() != 0 ?</span>
                        assertion.getAuthnStatements().get(0) : null;

                // if an attr stmt is present, then it has a symmetric key.
<span class="nc bnc" id="L211" title="All 2 branches missed.">                if (attrStmt != null) {</span>
<span class="nc" id="L212">                    NodeList children = keyInfoElement.getChildNodes();</span>
<span class="nc" id="L213">                    int len = children.getLength();</span>

<span class="nc bnc" id="L215" title="All 2 branches missed.">                    for (int i = 0; i &lt; len; i++) {</span>
<span class="nc" id="L216">                        Node child = children.item(i);</span>
<span class="nc bnc" id="L217" title="All 2 branches missed.">                        if (child.getNodeType() != Node.ELEMENT_NODE) {</span>
<span class="nc" id="L218">                            continue;</span>
                        }
<span class="nc" id="L220">                        QName el = new QName(child.getNamespaceURI(), child.getLocalName());</span>
<span class="nc bnc" id="L221" title="All 2 branches missed.">                        if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)) {</span>

<span class="nc" id="L223">                            byte[] secret = CommonUtil.getDecryptedBytes(cb, crypto, child);</span>

<span class="nc" id="L225">                            return new SAML2KeyInfo(assertion, secret);</span>
<span class="nc bnc" id="L226" title="All 2 branches missed.">                        } else if (el.equals(new QName(WSConstants.WST_NS, &quot;BinarySecret&quot;))) {</span>
<span class="nc" id="L227">                            Text txt = (Text) child.getFirstChild();</span>
<span class="nc" id="L228">                            return new SAML2KeyInfo(assertion, Base64.decode(txt.getData()));</span>
                        }
                    }

                }

                // If an authn stmt is present then it has a public key.
<span class="nc bnc" id="L235" title="All 2 branches missed.">                if (authnStmt != null) {</span>

                    X509Certificate[] certs;
                    try {
<span class="nc" id="L239">                        KeyInfo ki = new KeyInfo(keyInfoElement, null);</span>

<span class="nc bnc" id="L241" title="All 2 branches missed.">                        if (ki.containsX509Data()) {</span>
<span class="nc" id="L242">                            X509Data data = ki.itemX509Data(0);</span>
<span class="nc" id="L243">                            XMLX509Certificate certElem = null;</span>
<span class="nc bnc" id="L244" title="All 4 branches missed.">                            if (data != null &amp;&amp; data.containsCertificate()) {</span>
<span class="nc" id="L245">                                certElem = data.itemCertificate(0);</span>
                            }
<span class="nc bnc" id="L247" title="All 2 branches missed.">                            if (certElem != null) {</span>
<span class="nc" id="L248">                                X509Certificate cert = certElem.getX509Certificate();</span>
<span class="nc" id="L249">                                certs = new X509Certificate[1];</span>
<span class="nc" id="L250">                                certs[0] = cert;</span>
<span class="nc" id="L251">                                return new SAML2KeyInfo(assertion, certs);</span>
                            }
                        }

<span class="nc" id="L255">                    } catch (XMLSecurityException e3) {</span>
<span class="nc" id="L256">                        throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                                &quot;invalidSAMLsecurity&quot;,
                                new Object[]{&quot;cannot get certificate (key holder)&quot;}, e3);
<span class="nc" id="L259">                    }</span>

                }


<span class="nc" id="L264">                throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                        &quot;invalidSAMLsecurity&quot;,
                        new Object[]{&quot;cannot get certificate or key &quot;});

<span class="nc" id="L268">            } catch (MarshallingException e) {</span>
<span class="nc" id="L269">                throw new WSSecurityException(WSSecurityException.FAILURE,</span>
                        &quot;Failed marshalling the SAML Assertion&quot;, null, e);
            }
        }
    }

      /**
     * Get the subject confirmation method of a SAML 2.0 assertion
     *
     * @param assertion SAML 2.0 assertion
     * @return Subject Confirmation method
     */
    public static String getSAML2SubjectConfirmationMethod(Assertion assertion) {
<span class="nc" id="L282">        String subjectConfirmationMethod = RahasConstants.SAML20_SUBJECT_CONFIRMATION_HOK;</span>
<span class="nc" id="L283">        List&lt;SubjectConfirmation&gt; subjectConfirmations = assertion.getSubject().getSubjectConfirmations();</span>
<span class="nc bnc" id="L284" title="All 2 branches missed.">        if (subjectConfirmations.size() &gt; 0) {</span>
<span class="nc" id="L285">            subjectConfirmationMethod = subjectConfirmations.get(0).getMethod();</span>
        }
<span class="nc" id="L287">        return subjectConfirmationMethod;</span>
    }


    public static Assertion createAssertion() throws TrustException {
        try {
<span class="fc" id="L293">            Assertion assertion = (Assertion)CommonUtil.buildXMLObject(Assertion.DEFAULT_ELEMENT_NAME);</span>
<span class="fc" id="L294">            assertion.setVersion(SAMLVersion.VERSION_20);</span>

            // Set an UUID as the ID of an assertion
<span class="fc" id="L297">            assertion.setID(UUIDGenerator.getUUID());</span>
<span class="fc" id="L298">            return assertion;</span>
<span class="nc" id="L299">        } catch (TrustException e) {</span>
<span class="nc" id="L300">            throw new TrustException(&quot;Unable to create an Assertion object&quot;, e);</span>
        }
    }

    public static Issuer createIssuer(String issuerName) throws TrustException {
        try {
<span class="fc" id="L306">            Issuer issuer = (Issuer)CommonUtil.buildXMLObject(Issuer.DEFAULT_ELEMENT_NAME);</span>
<span class="fc" id="L307">            issuer.setValue(issuerName);</span>
<span class="fc" id="L308">            return issuer;</span>
<span class="nc" id="L309">        } catch (TrustException e) {</span>
<span class="nc" id="L310">            throw new TrustException(&quot;Unable to create an Issuer object&quot;, e);</span>
        }
    }

    public static Conditions createConditions(DateTime creationTime, DateTime expirationTime) throws TrustException {
        try {
<span class="fc" id="L316">            Conditions conditions = (Conditions)CommonUtil.buildXMLObject(Conditions.DEFAULT_ELEMENT_NAME);</span>
<span class="fc" id="L317">            conditions.setNotBefore(creationTime);</span>
<span class="fc" id="L318">            conditions.setNotOnOrAfter(expirationTime);</span>
<span class="fc" id="L319">            return conditions;</span>
<span class="nc" id="L320">        } catch (TrustException e) {</span>
<span class="nc" id="L321">            throw new TrustException(&quot;Unable to create an Conditions object&quot;);</span>
        }
    }

/**
     * Create named identifier.
     * @param principalName Name of the subject.
     * @param format Format of the subject, whether it is an email, uid etc ...
     * @return The NamedIdentifier object.
     * @throws org.apache.rahas.TrustException If unable to find the builder.
     */
    public static NameID createNamedIdentifier(String principalName, String format) throws TrustException{

<span class="fc" id="L334">        NameID nameId = (NameID)CommonUtil.buildXMLObject(NameID.DEFAULT_ELEMENT_NAME);</span>
<span class="fc" id="L335">        nameId.setValue(principalName);</span>
<span class="fc" id="L336">        nameId.setFormat(format);</span>

<span class="fc" id="L338">        return nameId;</span>
    }


}


</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.5.201505241946</span></div></body></html>