<?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>CommonUtil.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="right"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> &gt; <a href="index.html" class="el_package">org.apache.rahas.impl.util</a> &gt; <span class="el_source">CommonUtil.java</span></div><h1>CommonUtil.java</h1><pre class="source lang-java linenums">/*
 * Copyright 2004,2005 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.OMElement;
import org.apache.axiom.om.dom.DOMMetaFactory;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasData;
import org.apache.rahas.TrustException;
import org.apache.rahas.impl.SAMLTokenIssuerConfig;
import org.apache.rahas.impl.TokenIssuerUtil;
import org.apache.ws.security.*;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.components.crypto.CryptoType;
import org.apache.ws.security.handler.RequestData;
import org.apache.ws.security.message.WSSecEncryptedKey;
import org.apache.ws.security.processor.EncryptedKeyProcessor;
import org.apache.ws.security.util.Base64;
import org.apache.ws.security.util.Loader;
import org.apache.xml.security.utils.EncryptionConstants;
import org.opensaml.Configuration;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilder;
import org.opensaml.xml.encryption.EncryptedKey;
import org.opensaml.xml.signature.KeyInfo;
import org.opensaml.xml.signature.X509Data;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Properties;

import static org.apache.axiom.om.OMAbstractFactory.FEATURE_DOM;

/**
 * This class implements some utility methods common to SAML1 and SAML2.
 */
<span class="nc" id="L65">public class CommonUtil {</span>

<span class="fc" id="L67">    private static Log log = LogFactory.getLog(CommonUtil.class);</span>

    /**
     * This method creates a DOM compatible Axiom document.
     * @return DOM compatible Axiom document
     * @throws TrustException If an error occurred while creating the Document.
     */
    public static Document getOMDOMDocument() throws TrustException {
<span class="fc" id="L75">        DOMMetaFactory metaFactory = (DOMMetaFactory) OMAbstractFactory.getMetaFactory(FEATURE_DOM);</span>
<span class="fc" id="L76">            DocumentBuilderFactory dbf = metaFactory.newDocumentBuilderFactory();</span>
        try {
<span class="fc" id="L78">            return  dbf.newDocumentBuilder().newDocument();</span>
<span class="nc" id="L79">        } catch (ParserConfigurationException e) {</span>
<span class="nc" id="L80">            throw new TrustException(&quot;Error creating Axiom compatible DOM Document&quot;, e);</span>
        }
    }

    /**
     * Gets the certificates chain by alias. Always returns the first certificate if a certificate chain is found.
     * @param crypto Crypto to lookup certificate.
     * @param alias Alias name.
     * @return X509 certificate object.
     * @throws org.apache.rahas.TrustException If an error occurred
     *                              while retrieving the certificate or if no certificates are found for given alias.
     */
    public static X509Certificate getCertificateByAlias(Crypto crypto, String alias) throws TrustException {

<span class="fc" id="L94">        X509Certificate[] certificates = getCertificatesByAlias(crypto, alias);</span>

<span class="pc bpc" id="L96" title="1 of 2 branches missed.">        if (certificates == null) {</span>
<span class="nc" id="L97">            log.error(&quot;Unable to retrieve certificate for alias &quot; + alias);</span>
<span class="nc" id="L98">            throw new TrustException(&quot;issuerCertificateNotFound&quot;);</span>
        }

<span class="fc" id="L101">        return certificates[0];</span>
    }

    /**
     * Gets the certificates chain by alias. If no certificates are found return an empty array.
     * @param crypto Crypto to lookup certificate.
     * @param alias Alias name.
     * @return X509 certificates array.
     * @throws org.apache.rahas.TrustException If an error occurred
     *                                          while retrieving the certificate.
     */
    public static X509Certificate[] getCertificatesByAlias(Crypto crypto, String alias) throws TrustException {

        // TODO are we always looking up by alias ? Dont we need to lookup by any other attribute ?
<span class="fc" id="L115">        CryptoType type = new CryptoType(CryptoType.TYPE.ALIAS);</span>
<span class="fc" id="L116">        type.setAlias(alias);</span>

        try {
<span class="fc" id="L119">            X509Certificate[] certificates = crypto.getX509Certificates(type);</span>

<span class="pc bpc" id="L121" title="1 of 2 branches missed.">            if (certificates == null) {</span>
<span class="nc" id="L122">                log.debug(&quot;Unable to retrieve certificate for alias &quot; + alias);</span>
<span class="nc" id="L123">                return new X509Certificate[0];</span>
            }
<span class="fc" id="L125">            return certificates;</span>
<span class="nc" id="L126">        } catch (WSSecurityException e) {</span>
<span class="nc" id="L127">            log.error(&quot;Unable to retrieve certificate for alias &quot; + alias, e);</span>
<span class="nc" id="L128">            throw new TrustException(&quot;issuerCertificateNotFound&quot;, e);</span>
        }
    }

    /**
     * Decrypts the EncryptedKey element and returns the secret that was used.
     * @param callbackHandler Callback handler to pass to WSS4J framework.
     * @param crypto To get private key information.
     * @param encryptedKeyElement The encrypted Key element.
     * @return The secret as a byte stream.
     * @throws WSSecurityException If an error is occurred while decrypting the element.
     */
    public static byte[] getDecryptedBytes(CallbackHandler callbackHandler, Crypto crypto, Node encryptedKeyElement)
            throws WSSecurityException {

<span class="fc" id="L143">        EncryptedKeyProcessor encryptedKeyProcessor = new EncryptedKeyProcessor();</span>

<span class="fc" id="L145">        RequestData requestData = new RequestData();</span>
<span class="fc" id="L146">        requestData.setCallbackHandler(callbackHandler);</span>
<span class="fc" id="L147">        requestData.setDecCrypto(crypto);</span>

<span class="fc" id="L149">        final WSSConfig cfg = WSSConfig.getNewInstance();</span>
<span class="fc" id="L150">        requestData.setWssConfig(cfg);</span>

<span class="fc" id="L152">        WSDocInfo docInfo = new WSDocInfo(encryptedKeyElement.getOwnerDocument());</span>

        List&lt;WSSecurityEngineResult&gt; resultList;

<span class="fc" id="L156">        resultList = encryptedKeyProcessor.handleToken((Element) encryptedKeyElement, requestData, docInfo);</span>


<span class="fc" id="L159">        WSSecurityEngineResult wsSecurityEngineResult = resultList.get(0);</span>

<span class="fc" id="L161">        return (byte[]) wsSecurityEngineResult.get(WSSecurityEngineResult.TAG_SECRET);</span>
    }

    /**
     * Constructs crypto configuration based on the given properties. Provider is instantiated using
     * given class loader.
     * @param properties Crypto configuration properties.
     * @param classLoader Class loader used to create provider.
     * @return A crypto object.
     * @throws TrustException If an error occurred while creating the Crypto object.
     */
    public static Crypto getCrypto(Properties properties, ClassLoader classLoader) throws TrustException {
        try {
<span class="nc" id="L174">            return CryptoFactory.getInstance(properties, classLoader);</span>
<span class="nc" id="L175">        } catch (WSSecurityException e) {</span>
<span class="nc" id="L176">            log.error(&quot;An error occurred while loading crypto properties&quot;, e);</span>
<span class="nc" id="L177">            throw new TrustException(&quot;errorLoadingCryptoProperties&quot;, e);</span>

        }
    }

    /**
     * Constructs crypto configuration based on the given properties. Provider is instantiated using
     * given class loader.
     * @param propertiesFile Crypto configuration properties file name.
     * @param classLoader Class loader used to create provider.
     * @return A crypto object.
     * @throws TrustException If an error occurred while creating the Crypto object.
     */
    public static Crypto getCrypto(String propertiesFile, ClassLoader classLoader) throws TrustException {
        try {
<span class="nc" id="L192">            return CryptoFactory.getInstance(propertiesFile, classLoader);</span>
<span class="nc" id="L193">        } catch (WSSecurityException e) {</span>
<span class="nc" id="L194">            log.error(&quot;An error occurred while loading crypto properties with property file &quot; + propertiesFile, e);</span>
<span class="nc" id="L195">            throw new TrustException(&quot;errorLoadingCryptoProperties&quot;, new Object[]{propertiesFile}, e);</span>

        }
    }

    /**
     * Creates the token issuer configuration. The configuration is created in following order,
     * 1. Try create token configuration using configuration OMElement
     * 2. Try create token configuration using a configuration file name
     * 3. Try create token configuration using a parameter name in message context.
     * The issuer configuration would look like as follows,
     *
     *  &lt;saml-issuer-config&gt;
     *       &lt;issuerName&gt;Test_STS&lt;/issuerName&gt;
     *       &lt;issuerKeyAlias&gt;ip&lt;/issuerKeyAlias&gt;
     *       &lt;issuerKeyPassword&gt;password&lt;/issuerKeyPassword&gt;
     *       &lt;cryptoProperties&gt;
     *          &lt;crypto provider=&quot;org.apache.ws.security.components.crypto.Merlin&quot;&gt;
     *               &lt;property name=&quot;org.apache.ws.security.crypto.merlin.keystore.type&quot;&gt;JKS&lt;/property&gt;
     *               &lt;property name=&quot;org.apache.ws.security.crypto.merlin.file&quot;&gt;META-INF/rahas-sts.jks&lt;/property&gt;
     *               &lt;property name=&quot;org.apache.ws.security.crypto.merlin.keystore.password&quot;&gt;password&lt;/property&gt;
     *           &lt;/crypto&gt;
     *       &lt;/cryptoProperties&gt;
     *       &lt;timeToLive&gt;300000&lt;/timeToLive&gt;
     *       &lt;keySize&gt;256&lt;/keySize&gt;
     *       &lt;addRequestedAttachedRef /&gt;
     *       &lt;addRequestedUnattachedRef /&gt;
     *       &lt;keyComputation&gt;2&lt;/keyComputation&gt;
     *       &lt;proofKeyType&gt;BinarySecret&lt;/proofKeyType&gt;
     *       &lt;trusted-services&gt;
     *           &lt;service alias=&quot;bob&quot;&gt;http://localhost:8080/axis2/services/STS&lt;/service&gt;
     *       &lt;/trusted-services&gt;
     *   &lt;/saml-issuer-config&gt;
     *
     * @param configElement Configuration as an OMElement.
     * @param configFile Configuration as a file.
     * @param messageContextParameter Configuration as a message context parameter.
     * @return  Token issuer configuration as a SAMLTokenIssuerConfig object.
     * @throws TrustException If an error occurred while creating SAMLTokenIssuerConfig object.
     */
    public static SAMLTokenIssuerConfig getTokenIssuerConfiguration(OMElement configElement, String configFile,
                                                               Parameter messageContextParameter) throws TrustException {

        // First try using configuration element
<span class="fc" id="L239">        SAMLTokenIssuerConfig tokenIssuerConfiguration = createTokenIssuerConfiguration(configElement);</span>

<span class="fc bfc" id="L241" title="All 2 branches covered.">        if (tokenIssuerConfiguration == null) {</span>

            // Now try file
<span class="fc" id="L244">            tokenIssuerConfiguration = createTokenIssuerConfiguration(configFile);</span>

<span class="pc bpc" id="L246" title="1 of 2 branches missed.">            if (tokenIssuerConfiguration == null) {</span>

                // Finally try using the parameter
<span class="pc bpc" id="L249" title="1 of 2 branches missed.">                if (messageContextParameter != null) {</span>
<span class="fc" id="L250">                    tokenIssuerConfiguration = createTokenIssuerConfiguration(messageContextParameter);</span>
                }

<span class="fc" id="L253">                return tokenIssuerConfiguration;</span>
            } else {
<span class="nc" id="L255">                return tokenIssuerConfiguration;</span>
            }

        } else {
<span class="fc" id="L259">            return tokenIssuerConfiguration;</span>
        }
    }

    protected static SAMLTokenIssuerConfig createTokenIssuerConfiguration(OMElement configElement)
            throws TrustException {

<span class="fc bfc" id="L266" title="All 2 branches covered.">        if (configElement != null) {</span>

<span class="fc" id="L268">            log.debug(&quot;Creating token issuer configuration using OMElement&quot;);</span>

<span class="fc" id="L270">            return new SAMLTokenIssuerConfig(configElement</span>
                    .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
        }

<span class="fc" id="L274">        return null;</span>
    }

    protected static SAMLTokenIssuerConfig createTokenIssuerConfiguration(String configFile) throws TrustException {

<span class="fc bfc" id="L279" title="All 2 branches covered.">        if (configFile != null) {</span>

<span class="pc bpc" id="L281" title="1 of 2 branches missed.">            if (log.isDebugEnabled()) {</span>
<span class="nc" id="L282">                log.debug(&quot;Creating token issuer configuration using file &quot; + configFile);</span>
            }

<span class="fc" id="L285">            return new SAMLTokenIssuerConfig(configFile);</span>
        }

<span class="fc" id="L288">        return null;</span>
    }

    protected static SAMLTokenIssuerConfig createTokenIssuerConfiguration(Parameter messageContextParameter)
            throws TrustException {

<span class="pc bpc" id="L294" title="2 of 4 branches missed.">        if (messageContextParameter != null &amp;&amp; messageContextParameter.getParameterElement() != null) {</span>

<span class="fc" id="L296">            log.debug(&quot;Creating token issuer configuration using the config parameter&quot;);</span>

<span class="fc" id="L298">            return new SAMLTokenIssuerConfig(messageContextParameter</span>
                    .getParameterElement().getFirstChildWithName(
                            SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
        }

<span class="nc" id="L303">        return null;</span>
    }

    /**
     * Builds the requested XMLObject.
     *
     * @param objectQName name of the XMLObject
     * @return the build XMLObject
     * @throws org.apache.rahas.TrustException If unable to find the appropriate builder.
     */
    public static XMLObject buildXMLObject(QName objectQName) throws TrustException {
<span class="fc" id="L314">        XMLObjectBuilder builder = Configuration.getBuilderFactory().getBuilder(objectQName);</span>
<span class="fc bfc" id="L315" title="All 2 branches covered.">        if (builder == null) {</span>
<span class="fc" id="L316">            log.debug(&quot;Unable to find OpenSAML builder for object &quot; + objectQName);</span>
<span class="fc" id="L317">            throw new TrustException(&quot;builderNotFound&quot;,new Object[]{objectQName});</span>
        }
<span class="fc" id="L319">        return builder.buildObject(objectQName.getNamespaceURI(), objectQName.getLocalPart(), objectQName.getPrefix());</span>
    }

     /**
     * This method creates KeyInfo element of an assertion. This is a facade, in which it calls
     * to other helper methods to create KeyInfo. The TokenIssuer will call this method to
     * create the KeyInfo.
     * @param doc An Axiom based DOM Document.
     * @param data The ephemeral key which we use here need in encrypting the message also. Therefore
     *              we need to save the ephemeral key in RahasData passed here.
     * @param serviceCert Public key used to encrypt the assertion is extracted from this certificate.
     * @param keySize Size of the key to be used
     * @param crypto The relevant private key
     * @param keyComputation Key computation mechanism.
     * @return OpenSAML KeyInfo representation.
     * @throws WSSecurityException We use WSS4J to generate encrypted key. This exception will trigger if an
     *                      error occurs while generating the encrypted key.
     * @throws TrustException If an error occurred while creating KeyInfo object.
     */
    public static KeyInfo getSymmetricKeyBasedKeyInfo(Document doc,
                                                      RahasData data,
                                                      X509Certificate serviceCert,
                                                      int keySize,
                                                      Crypto crypto,
                                                      int keyComputation) throws WSSecurityException, TrustException {

<span class="fc" id="L345">        byte[] ephemeralKey = TokenIssuerUtil.getSharedSecret(</span>
                data, keyComputation, keySize);

<span class="fc" id="L348">        WSSecEncryptedKey encryptedKey = getSymmetricKeyBasedKeyInfoContent(doc, ephemeralKey, serviceCert, crypto);</span>

        // Extract the base64 encoded secret value
<span class="fc" id="L351">        byte[] tempKey = new byte[keySize / 8];</span>
<span class="fc" id="L352">        System.arraycopy(encryptedKey.getEphemeralKey(), 0, tempKey,</span>
                0, keySize / 8);


<span class="fc" id="L356">        data.setEphmeralKey(tempKey);</span>

<span class="fc" id="L358">        EncryptedKey samlEncryptedKey = SAMLUtils.createEncryptedKey(serviceCert, encryptedKey);</span>
<span class="fc" id="L359">        return SAMLUtils.createKeyInfo(samlEncryptedKey);</span>
    }

    static WSSecEncryptedKey getSymmetricKeyBasedKeyInfoContent(Document doc,
                                                                       byte[] ephemeralKey,
                                                                       X509Certificate serviceCert,
                                                                       Crypto crypto) throws WSSecurityException,
            TrustException {
        // Create the encrypted key
<span class="fc" id="L368">        WSSecEncryptedKey encryptedKeyBuilder = new WSSecEncryptedKey();</span>

        // Use thumbprint id
<span class="fc" id="L371">        encryptedKeyBuilder</span>
                .setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

        // SEt the encryption cert
<span class="fc" id="L375">        encryptedKeyBuilder.setUseThisCert(serviceCert);</span>

<span class="fc" id="L377">        encryptedKeyBuilder.setEphemeralKey(ephemeralKey);</span>

        // Set key encryption algo
<span class="fc" id="L380">        encryptedKeyBuilder</span>
                .setKeyEncAlgo(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);

        // Build
<span class="fc" id="L384">        encryptedKeyBuilder.prepare(doc, crypto);</span>

<span class="fc" id="L386">        return encryptedKeyBuilder;</span>
    }

    /**
     * Creates the certificate based KeyInfo object.
     * @param certificate The public key certificate used to create the KeyInfo object.
     * @return OpenSAML representation of KeyInfo object.
     * @throws TrustException If an error occurred while creating the KeyInfo
     */
    public static KeyInfo getCertificateBasedKeyInfo(X509Certificate certificate) throws TrustException {
<span class="fc" id="L396">        X509Data x509Data = CommonUtil.createX509Data(certificate);</span>
<span class="fc" id="L397">        return SAMLUtils.createKeyInfo(x509Data);</span>
    }

    /**
     * Creates the X509 data element in a SAML issuer token. Should create an element similar to following,
     * &lt;X509Data xmlns:xenc=&quot;http://www.w3.org/2001/04/xmlenc#&quot;
     *                         xmlns:ds=&quot;http://www.w3.org/2000/09/xmldsig#&quot;&gt;
     *   &lt;X509Certificate&gt;
     *       MIICNTCCAZ6gAwIB...
     *   &lt;/X509Certificate&gt;
     * &lt;/X509Data&gt;
     * @param clientCert Client certificate to be used when generating X509 data
     * @return  SAML X509Data representation.
     * @throws TrustException If an error occurred while creating X509Data and X509Certificate.
     */
    static X509Data createX509Data(X509Certificate clientCert) throws TrustException {

        byte[] clientCertBytes;
        try {
<span class="fc" id="L416">            clientCertBytes = clientCert.getEncoded();</span>
<span class="nc" id="L417">        } catch (CertificateEncodingException e) {</span>
<span class="nc" id="L418">            log.error(&quot;An error occurred while encoding certificate.&quot;, e);</span>
<span class="nc" id="L419">            throw new TrustException(&quot;An error occurred while encoding certificate.&quot;, e);</span>
<span class="fc" id="L420">        }</span>
<span class="fc" id="L421">        String base64Cert = Base64.encode(clientCertBytes);</span>

<span class="fc" id="L423">        org.opensaml.xml.signature.X509Certificate x509Certificate</span>
                = (org.opensaml.xml.signature.X509Certificate)CommonUtil.buildXMLObject
                (org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME);

<span class="fc" id="L427">        x509Certificate.setValue(base64Cert);</span>

<span class="fc" id="L429">        X509Data x509Data = (X509Data)CommonUtil.buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME);</span>
<span class="fc" id="L430">        x509Data.getX509Certificates().add(x509Certificate);</span>

<span class="fc" id="L432">        return x509Data;</span>
    }

    /**
     * Gets the SAML callback handler. First checks whether there is a registered callback handler in token
     * issuer configuration. If not this will check whether there is a callback class configured in token issuer
     * configuration. If class name is specified this method will create an object of the class and will return.
     * If class name is also not specified this method will return null.
     * @param tokenIssuerConfiguration The SAML token issuer configuration.
     * @param data The RahasData.
     * @return The SAMLCallbackHandler if configured in token issuer configuration, else null.
     * @throws TrustException If an error occurred while loading class from class loader
     */
    public static SAMLCallbackHandler getSAMLCallbackHandler(SAMLTokenIssuerConfig tokenIssuerConfiguration,
                                                                      RahasData data) throws TrustException {
<span class="fc bfc" id="L447" title="All 2 branches covered.">        if (tokenIssuerConfiguration.getCallbackHandler() != null) {</span>

<span class="fc" id="L449">            return tokenIssuerConfiguration.getCallbackHandler();</span>

<span class="pc bpc" id="L451" title="1 of 4 branches missed.">        } else if (tokenIssuerConfiguration.getCallbackHandlerName() != null</span>
                &amp;&amp; tokenIssuerConfiguration.getCallbackHandlerName().trim().length() &gt; 0) {

            SAMLCallbackHandler handler;
<span class="fc" id="L455">            MessageContext msgContext = data.getInMessageContext();</span>
<span class="fc" id="L456">            ClassLoader classLoader = msgContext.getAxisService().getClassLoader();</span>
            Class cbClass;
            try {
<span class="fc" id="L459">                cbClass = Loader.loadClass(classLoader, tokenIssuerConfiguration.getCallbackHandlerName());</span>
<span class="nc" id="L460">            } catch (ClassNotFoundException e) {</span>
<span class="nc" id="L461">                throw new TrustException(&quot;cannotLoadPWCBClass&quot;, new String[]{tokenIssuerConfiguration</span>
                        .getCallbackHandlerName()}, e);
<span class="fc" id="L463">            }</span>
            try {
<span class="fc" id="L465">                handler = (SAMLCallbackHandler) cbClass.newInstance();</span>
<span class="nc" id="L466">            } catch (java.lang.Exception e) {</span>
<span class="nc" id="L467">                throw new TrustException(&quot;cannotCreatePWCBInstance&quot;, new String[]{tokenIssuerConfiguration</span>
                        .getCallbackHandlerName()}, e);
<span class="fc" id="L469">            }</span>

<span class="fc" id="L471">            return handler;</span>
        }

<span class="fc" id="L474">        return null;</span>

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