<?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>STSClient.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.client</a> &gt; <span class="el_source">STSClient.java</span></div><h1>STSClient.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.client;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.util.base64.Base64Utils;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.OutInAxisOperation;
import org.apache.axis2.description.Parameter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.neethi.Assertion;
import org.apache.neethi.Policy;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.Token;
import org.apache.rahas.TokenStorage;
import org.apache.rahas.TrustException;
import org.apache.rahas.TrustUtil;
import org.apache.rahas.impl.util.CommonUtil;
import org.apache.ws.secpolicy.model.AlgorithmSuite;
import org.apache.ws.secpolicy.model.Binding;
import org.apache.ws.secpolicy.model.Trust10;
import org.apache.ws.secpolicy.model.Trust13;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.conversation.ConversationException;
import org.apache.ws.security.conversation.dkalgo.P_SHA1;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.util.UUIDGenerator;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.ws.security.util.XmlSchemaDateFormat;
import org.w3c.dom.Element;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class STSClient {

    private static final String RAMPART_POLICY = &quot;rampartPolicy&quot;;

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

    private String action;

    private OMElement rstTemplate;

<span class="fc" id="L84">    private int version = RahasConstants.VERSION_05_02;</span>

    private Options options;

    private Trust10 trust10;
    
    private Trust13 trust13;

    private AlgorithmSuite algorithmSuite;
    
<span class="fc" id="L94">    private ArrayList parameters = new ArrayList();</span>

    private byte[] requestorEntropy;

<span class="fc" id="L98">    private String addressingNs = AddressingConstants.Submission.WSA_NAMESPACE;</span>

    private int keySize;
    
<span class="fc" id="L102">    private String soapVersion = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;</span>

    /**
     * Life time in seconds
     * Default is 300 seconds (5 mins)
     */
<span class="fc" id="L108">    private int ttl = 300;</span>
    private Crypto crypto;
    private CallbackHandler cbHandler;
    private ConfigurationContext configCtx;

<span class="fc" id="L113">    public STSClient(ConfigurationContext configCtx) throws TrustException {</span>
<span class="pc bpc" id="L114" title="1 of 2 branches missed.">        if (configCtx != null) {</span>
<span class="fc" id="L115">            this.configCtx = configCtx;</span>
        } else {
<span class="nc" id="L117">            throw new TrustException(&quot;stsClientCfgCtxNull&quot;);</span>
        }
<span class="fc" id="L119">    }</span>

    public Token requestSecurityToken(Policy servicePolicy,
                                      String issuerAddress,
                                      Policy issuerPolicy,
                                      String appliesTo) throws TrustException {
        try {
<span class="fc" id="L126">            QName rstQn = new QName(&quot;requestSecurityToken&quot;);</span>

<span class="fc" id="L128">            ServiceClient client = getServiceClient(rstQn, issuerAddress);</span>
            
<span class="pc bpc" id="L130" title="1 of 2 branches missed.">            for (int i = 0; i &lt; parameters.size(); i++) {</span>
<span class="nc" id="L131">                Parameter param = (Parameter)parameters.get(i);</span>
<span class="nc" id="L132">                client.getAxisService().addParameter(param.getName(), param.getValue());</span>
            }
            
<span class="fc" id="L135">            client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);</span>
<span class="fc" id="L136">            client.getOptions().setSoapVersionURI(this.soapVersion);</span>

<span class="pc bpc" id="L138" title="1 of 2 branches missed.">            if(this.addressingNs != null) {</span>
<span class="fc" id="L139">                client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);</span>
            }
<span class="fc" id="L141">            client.engageModule(&quot;addressing&quot;);</span>
<span class="fc" id="L142">            client.engageModule(&quot;rampart&quot;);</span>

            //Process the STS and service policy policy
<span class="fc" id="L145">            this.processPolicy(issuerPolicy, servicePolicy);</span>
            
            try {
<span class="fc" id="L148">                OMElement response = client.sendReceive(rstQn,</span>
                                                        createIssueRequest(appliesTo));
    
<span class="fc" id="L151">                return processIssueResponse(version, response, issuerAddress);</span>
            } finally {
<span class="pc" id="L153">                client.cleanupTransport();</span>
            }
<span class="nc" id="L155">        } catch (AxisFault e) {</span>
<span class="nc" id="L156">            log.error(&quot;errorInObtainingToken&quot;, e);</span>
<span class="nc" id="L157">            throw new TrustException(&quot;errorInObtainingToken&quot;, new String[]{issuerAddress},e);</span>
        }
    }

    /**
     * Cancel a particular security token
     *
     * @param issuerAddress
     * @param tokenId
     * @return true is the Token was successfully canceled. False otherwise.
     * @throws TrustException
     */
    public boolean cancelToken(String issuerAddress,
                               String tokenId,
                               String action) throws TrustException {
        try {
<span class="nc" id="L173">            QName rstQn = new QName(&quot;cancelSecurityToken&quot;);</span>
<span class="nc" id="L174">            ServiceClient client = getServiceClient(rstQn, issuerAddress);</span>
<span class="nc bnc" id="L175" title="All 2 branches missed.">            if(action != null) {</span>
<span class="nc" id="L176">                client.getOptions().setAction(action);</span>
            }
            
<span class="nc" id="L179">            return processCancelResponse(client.sendReceive(rstQn,</span>
                                                            createCancelRequest(tokenId)));
<span class="nc" id="L181">        } catch (AxisFault e) {</span>
<span class="nc" id="L182">            log.error(&quot;errorInCancelingToken&quot;, e);</span>
<span class="nc" id="L183">            throw new TrustException(&quot;errorInCancelingToken&quot;, e);</span>
        }
    }
    
    public boolean validateToken(String tokenId,
                                 String issuerAddress,
                                 Policy issuerPolicy) throws TrustException {
        try {
<span class="nc" id="L191">            QName rstQn = new QName(&quot;requestSecurityToken&quot;);</span>
<span class="nc" id="L192">            String requestType =</span>
                    TrustUtil.getWSTNamespace(version) + RahasConstants.REQ_TYPE_VALIDATE;
            
<span class="nc" id="L195">            ServiceClient client = getServiceClient(rstQn, issuerAddress);</span>
            
<span class="nc" id="L197">            client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);</span>
<span class="nc" id="L198">            client.getOptions().setSoapVersionURI(this.soapVersion);</span>
<span class="nc bnc" id="L199" title="All 2 branches missed.">            if(this.addressingNs != null) {</span>
<span class="nc" id="L200">                client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);</span>
            }
<span class="nc" id="L202">            client.engageModule(&quot;addressing&quot;);</span>
<span class="nc" id="L203">            client.engageModule(&quot;rampart&quot;);</span>

<span class="nc" id="L205">            this.processPolicy(issuerPolicy, null);</span>
            
<span class="nc" id="L207">            OMElement response = client.sendReceive(rstQn,</span>
                                                    createValidateRequest(requestType,tokenId));
            
<span class="nc" id="L210">            return true;</span>
            
            
<span class="nc" id="L213">        } catch (AxisFault e) {</span>
<span class="nc" id="L214">            log.error(&quot;errorInValidatingToken&quot;, e);</span>
<span class="nc" id="L215">            throw new TrustException(&quot;errorInValidatingToken&quot;, new String[]{issuerAddress},e);</span>
        }
        
    }
    
    public boolean renewToken(String tokenId,
                              String issuerAddress,
                              Policy issuerPolicy) throws TrustException {
        
        try {
<span class="nc" id="L225">        QName rstQn = new QName(&quot;requestSecurityToken&quot;);</span>
        
<span class="nc" id="L227">        ServiceClient client = getServiceClient(rstQn, issuerAddress);</span>
        
<span class="nc" id="L229">        client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);</span>
<span class="nc" id="L230">        client.getOptions().setSoapVersionURI(this.soapVersion);</span>
<span class="nc bnc" id="L231" title="All 2 branches missed.">        if(this.addressingNs != null) {</span>
<span class="nc" id="L232">            client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);</span>
        }
<span class="nc" id="L234">        client.engageModule(&quot;addressing&quot;);</span>
<span class="nc" id="L235">        client.engageModule(&quot;rampart&quot;);</span>

<span class="nc" id="L237">        this.processPolicy(issuerPolicy, null);</span>
        
<span class="nc" id="L239">        String tokenType = RahasConstants.TOK_TYPE_SAML_10;</span>
        
<span class="nc" id="L241">        OMElement response = client.sendReceive(rstQn,</span>
                                                createRenewRequest(tokenType,tokenId));
        
<span class="nc" id="L244">        return true;</span>
        
<span class="nc" id="L246">        } catch (AxisFault e) {</span>
<span class="nc" id="L247">            log.error(&quot;errorInRenewingToken&quot;, e);</span>
<span class="nc" id="L248">            throw new TrustException(&quot;errorInRenewingToken&quot;, new String[]{issuerAddress},e); </span>
        }
        
    }

    /**
     * Renews the token referenced by the token id, updates the token store
     * @param tokenId
     * @param issuerAddress
     * @param issuerPolicy
     * @param store
     * @return status
     * @throws TrustException
     */
    public boolean renewToken(String tokenId,
                              String issuerAddress,
                              Policy issuerPolicy, TokenStorage store) throws TrustException {

        try {
<span class="nc" id="L267">            QName rstQn = new QName(&quot;requestSecurityToken&quot;);</span>

<span class="nc" id="L269">            ServiceClient client = getServiceClient(rstQn, issuerAddress);</span>

<span class="nc" id="L271">            client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);</span>
<span class="nc" id="L272">            client.getOptions().setSoapVersionURI(this.soapVersion);</span>
<span class="nc bnc" id="L273" title="All 2 branches missed.">            if (this.addressingNs != null) {</span>
<span class="nc" id="L274">                client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);</span>
            }
<span class="nc" id="L276">            client.engageModule(&quot;addressing&quot;);</span>
<span class="nc" id="L277">            client.engageModule(&quot;rampart&quot;);</span>

<span class="nc" id="L279">            this.processPolicy(issuerPolicy, null);</span>

<span class="nc" id="L281">            String tokenType = RahasConstants.TOK_TYPE_SAML_10;</span>

<span class="nc" id="L283">            OMElement response = client.sendReceive(rstQn,</span>
                    createRenewRequest(tokenType, tokenId));
<span class="nc" id="L285">            store.update(processRenewResponse(version, response, store, tokenId));</span>

<span class="nc" id="L287">            return true;</span>

<span class="nc" id="L289">        } catch (AxisFault e) {</span>
<span class="nc" id="L290">            log.error(&quot;errorInRenewingToken&quot;, e);</span>
<span class="nc" id="L291">            throw new TrustException(&quot;errorInRenewingToken&quot;, new String[]{issuerAddress}, e);</span>
        }

    }

    /**
     * Processes the response and update the token store
     * @param version
     * @param elem
     * @param store
     * @param id
     * @return
     * @throws TrustException
     */
    private Token processRenewResponse(int version, OMElement elem, TokenStorage store, String id) throws TrustException {
<span class="nc" id="L306">        OMElement rstr = elem;</span>
<span class="nc bnc" id="L307" title="All 2 branches missed.">        if (version == RahasConstants.VERSION_05_12) {</span>
            //The WS-SX result will be an RSTRC
<span class="nc" id="L309">            rstr = elem.getFirstElement();</span>
        }
        //get the corresponding WS-Trust NS
<span class="nc" id="L312">        String ns = TrustUtil.getWSTNamespace(version);</span>

        //Get the RequestedAttachedReference
<span class="nc" id="L315">        OMElement reqSecToken = rstr.getFirstChildWithName(new QName(</span>
                ns, RahasConstants.IssuanceBindingLocalNames.REQUESTED_SECURITY_TOKEN));

<span class="nc bnc" id="L318" title="All 2 branches missed.">        if (reqSecToken == null) {</span>
<span class="nc" id="L319">            throw new TrustException(&quot;reqestedSecTokMissing&quot;);</span>
        }

        //Extract the life-time element
<span class="nc" id="L323">        OMElement lifeTimeEle = rstr.getFirstChildWithName(new QName(</span>
                ns, RahasConstants.IssuanceBindingLocalNames.LIFETIME));

<span class="nc bnc" id="L326" title="All 2 branches missed.">        if (lifeTimeEle == null) {</span>
<span class="nc" id="L327">            throw new TrustException(&quot;lifeTimeElemMissing&quot;);</span>
        }

        //update the existing token
<span class="nc" id="L331">        OMElement tokenElem = reqSecToken.getFirstElement();</span>
<span class="nc" id="L332">        Token token = store.getToken(id);</span>
<span class="nc" id="L333">        token.setPreviousToken(token.getToken());</span>
<span class="nc" id="L334">        token.setToken(tokenElem);</span>
<span class="nc" id="L335">        token.setState(Token.RENEWED);</span>
<span class="nc" id="L336">        token.setExpires(extractExpiryDate(lifeTimeEle));</span>

<span class="nc" id="L338">        return token;</span>
    }

    /**
     * extracts the expiry date from the Lifetime element of the RSTR
     * @param lifetimeElem
     * @return
     * @throws TrustException
     */
    private Date extractExpiryDate(OMElement lifetimeElem) throws TrustException {
        try {
<span class="nc" id="L349">            DateFormat zulu = new XmlSchemaDateFormat();</span>

<span class="nc" id="L351">            OMElement expiresElem =</span>
                    lifetimeElem.getFirstChildWithName(new QName(WSConstants.WSU_NS,
                            WSConstants.EXPIRES_LN));
<span class="nc" id="L354">            Date expires = zulu.parse(expiresElem.getText());</span>
<span class="nc" id="L355">            return expires;</span>
<span class="nc" id="L356">        } catch (OMException e) {</span>
<span class="nc" id="L357">            throw new TrustException(&quot;lifeTimeProcessingError&quot;,</span>
                    new String[]{lifetimeElem.toString()}, e);
<span class="nc" id="L359">        } catch (ParseException e) {</span>
<span class="nc" id="L360">            throw new TrustException(&quot;lifeTimeProcessingError&quot;,</span>
                    new String[]{lifetimeElem.toString()}, e);
        }
    }


    private ServiceClient getServiceClient(QName rstQn,
                                           String issuerAddress) throws AxisFault {
<span class="fc" id="L368">        AxisService axisService =</span>
                new AxisService(&quot;SecurityTokenService&quot; + UUIDGenerator.getUUID());
<span class="fc" id="L370">        axisService.setClientSide(true);</span>
<span class="fc" id="L371">        AxisOperation operation = new OutInAxisOperation(rstQn);</span>
<span class="fc" id="L372">        axisService.addOperation(operation);</span>
<span class="fc" id="L373">        ServiceClient client = new ServiceClient(this.configCtx, axisService);</span>

<span class="fc bfc" id="L375" title="All 2 branches covered.">        if (this.options != null) {</span>
<span class="fc" id="L376">            client.setOptions(options);</span>
        }

        //Set the action
<span class="fc" id="L380">        client.getOptions().setAction(action);</span>
<span class="fc" id="L381">        client.getOptions().setTo(new EndpointReference(issuerAddress));</span>
<span class="fc" id="L382">        client.engageModule(&quot;rampart&quot;);</span>
<span class="fc" id="L383">        return client;</span>
    }

    /**
     * Processes the response from Token issuer.
     * @param version The supported version.
     * @param result Resulting token response from token issuer.
     * @param issuerAddress The respective token applying entity (as a url)
     * @return The issued token.
     * @throws TrustException If an error occurred while extracting token from response.
     */
    protected Token processIssueResponse(int version, OMElement result,
            String issuerAddress) throws TrustException {
<span class="fc" id="L396">        OMElement rstr = result;</span>

        /**
         * TODO :-
         * There are 3 mechanisms to establish a security context token.
         * They are,
         * 1. Security context token created by a security token service
         * 2. Security context token created by one of the communicating parties and propagated with a
         * message
         * 3. Security context token created through negotiation/exchanges
         *
         * As per now we are only supporting case 1. Therefore we always expect a
         * wst:RequestSecurityTokenResponseCollection in the incoming message.
         *
         * This only applies when we use specification http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512
         */

<span class="fc bfc" id="L413" title="All 2 branches covered.">        if (version == RahasConstants.VERSION_05_12) {</span>
            //The WS-SX result will be an RSTRC
<span class="fc" id="L415">            rstr = result.getFirstElement();</span>
        }

<span class="fc" id="L418">        String ns = TrustUtil.getWSTNamespace(version);</span>

        //Get the RequestedAttachedReference
<span class="fc" id="L421">        OMElement reqAttElem = rstr.getFirstChildWithName(new QName(</span>
                ns, RahasConstants.IssuanceBindingLocalNames.REQUESTED_ATTACHED_REFERENCE));
<span class="pc bpc" id="L423" title="1 of 2 branches missed.">        OMElement reqAttRef = reqAttElem == null ? null : reqAttElem.getFirstElement();</span>

        //Get the RequestedUnattachedReference
<span class="fc" id="L426">        OMElement reqUnattElem =</span>
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.IssuanceBindingLocalNames.
                                                             REQUESTED_UNATTACHED_REFERENCE));
<span class="pc bpc" id="L430" title="1 of 2 branches missed.">        OMElement reqUnattRef = reqUnattElem == null ? null : reqUnattElem.getFirstElement();</span>

        //Get the security token
<span class="fc" id="L433">        OMElement reqSecTok =</span>
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.IssuanceBindingLocalNames.
                                                             REQUESTED_SECURITY_TOKEN));
<span class="pc bpc" id="L437" title="1 of 2 branches missed.">        if (reqSecTok == null) {</span>
<span class="nc" id="L438">            throw new TrustException(&quot;reqestedSecTokMissing&quot;);</span>
        }

<span class="fc" id="L441">        OMElement tokenElem = reqSecTok.getFirstElement();</span>

<span class="fc" id="L443">        String id = this.findIdentifier(reqAttRef, reqUnattRef, tokenElem);</span>

<span class="pc bpc" id="L445" title="1 of 2 branches missed.">        if (id == null) {</span>
<span class="nc" id="L446">            throw new TrustException(&quot;cannotObtainTokenIdentifier&quot;);</span>
        }

<span class="fc" id="L449">        OMElement lifeTimeEle =</span>
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.IssuanceBindingLocalNames.
                                                             LIFETIME));

<span class="fc" id="L454">        Token token = new Token(id, tokenElem, lifeTimeEle);</span>
<span class="fc" id="L455">        token.setIssuerAddress(issuerAddress);</span>
<span class="fc" id="L456">        token.setAttachedReference(reqAttRef);</span>
<span class="fc" id="L457">        token.setUnattachedReference(reqUnattRef);</span>

        //Handle proof token
<span class="fc" id="L460">        OMElement rpt =</span>
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.LocalNames.
                                                             REQUESTED_PROOF_TOKEN));

<span class="fc" id="L465">        byte[] secret = null;</span>

<span class="fc bfc" id="L467" title="All 2 branches covered.">        if (rpt != null) {</span>
<span class="fc" id="L468">            OMElement child = rpt.getFirstElement();</span>
<span class="pc bpc" id="L469" title="1 of 2 branches missed.">            if (child == null) {</span>
<span class="nc" id="L470">                throw new TrustException(&quot;invalidRPT&quot;);</span>
            }
<span class="fc bfc" id="L472" title="All 2 branches covered.">            if (child.getQName().equals(new QName(ns,</span>
                                                  RahasConstants.LocalNames.
                                                          BINARY_SECRET))) {
                //First check for the binary secret
<span class="fc" id="L476">                String b64Secret = child.getText();</span>
<span class="fc" id="L477">                secret = Base64Utils.decode(b64Secret);</span>
<span class="pc bpc" id="L478" title="1 of 2 branches missed.">            } else if (child.getQName().equals(new QName(ns, WSConstants.ENC_KEY_LN))) {</span>

<span class="nc" id="L480">                Element domChild = (Element) new StAXOMBuilder(</span>
                        OMAbstractFactory.getMetaFactory(
                                OMAbstractFactory.FEATURE_DOM).getOMFactory(),
                        child.getXMLStreamReader()).getDocumentElement();

                try {
<span class="nc" id="L486">                    secret = CommonUtil.getDecryptedBytes(this.cbHandler, this.crypto, domChild);</span>
<span class="nc" id="L487">                } catch (WSSecurityException e) {</span>
<span class="nc" id="L488">                    log.error(&quot;Error decrypting encrypted key element&quot;, e);</span>
<span class="nc" id="L489">                    throw new TrustException(&quot;errorInProcessingEncryptedKey&quot;, e);</span>
<span class="nc" id="L490">                }</span>

<span class="pc bpc" id="L492" title="1 of 2 branches missed.">            } else if (child.getQName().equals(new QName(ns,</span>
                    RahasConstants.IssuanceBindingLocalNames.
                            COMPUTED_KEY))) {
                //Handle the computed key

                //Get service entropy
<span class="fc" id="L498">                OMElement serviceEntrElem = rstr</span>
                        .getFirstChildWithName(new QName(ns,
                                                         RahasConstants.IssuanceBindingLocalNames.
                                                                 ENTROPY));

<span class="fc" id="L503">                OMElement binSecElem = serviceEntrElem.getFirstElement();</span>

<span class="pc bpc" id="L505" title="3 of 6 branches missed.">                if (binSecElem != null &amp;&amp; binSecElem.getText() != null</span>
                    &amp;&amp; !&quot;&quot;.equals(binSecElem.getText().trim())) {

<span class="fc" id="L508">                    byte[] serviceEntr = Base64Utils.decode(binSecElem.getText());</span>

                    //Right now we only use PSHA1 as the computed key algo                    
<span class="fc" id="L511">                    P_SHA1 p_sha1 = new P_SHA1();</span>

<span class="pc bpc" id="L513" title="1 of 2 branches missed.">                    int length = (this.keySize &gt; 0) ? keySize</span>
                                 : this.algorithmSuite
                            .getMaximumSymmetricKeyLength();
                    try {
<span class="fc" id="L517">                        secret = p_sha1.createKey(this.requestorEntropy, serviceEntr, 0, length/8);</span>
<span class="nc" id="L518">                    } catch (ConversationException e) {</span>
<span class="nc" id="L519">                        throw new TrustException(&quot;keyDerivationError&quot;, e);</span>
<span class="fc" id="L520">                    }</span>
<span class="fc" id="L521">                } else {</span>
                    //Service entropy missing
<span class="nc" id="L523">                    throw new TrustException(&quot;serviceEntropyMissing&quot;);</span>
                }
            }

<span class="fc" id="L527">        } else {</span>
<span class="pc bpc" id="L528" title="1 of 2 branches missed.">            if (this.requestorEntropy != null) {</span>
                //Use requester entropy as the key
<span class="fc" id="L530">                secret = this.requestorEntropy;</span>
            }
        }
<span class="fc" id="L533">        token.setSecret(secret);</span>
<span class="fc" id="L534">        return token;</span>
    }

    private boolean processCancelResponse(OMElement response) {
        /*
        &lt;wst:RequestSecurityTokenResponse&gt;
            &lt;wst:RequestedTokenCancelled/&gt;
        &lt;/wst:RequestSecurityTokenResponse&gt;
        */
<span class="nc bnc" id="L543" title="All 2 branches missed.">        return response.</span>
                getFirstChildWithName(new QName(RahasConstants.
                        CancelBindingLocalNames.REQUESTED_TOKEN_CANCELED)) != null;
    }

    /**
     * Find the token identifier.
     *
     * @param reqAttRef
     * @param reqUnattRef
     * @param token
     * @return id
     */
    private String findIdentifier(OMElement reqAttRef,
                                  OMElement reqUnattRef,
                                  OMElement token) {
        String id;
<span class="pc bpc" id="L560" title="1 of 2 branches missed.">        if (reqAttRef != null) {</span>
            //First try the attached ref
<span class="fc" id="L562">            id = this.getIdFromSTR(reqAttRef);</span>
<span class="nc bnc" id="L563" title="All 2 branches missed.">        } else if (reqUnattRef != null) {</span>
            //then try the unattached ref
<span class="nc" id="L565">            id = this.getIdFromSTR(reqUnattRef);</span>
        } else {
            //Return wsu:Id of the token element
<span class="nc" id="L568">            id = token.getAttributeValue(new QName(WSConstants.WSU_NS, &quot;Id&quot;));</span>
<span class="nc bnc" id="L569" title="All 2 branches missed.">            if ( id == null )</span>
            {
                // If we are dealing with a SAML Assetion, look for AssertionID.
<span class="nc" id="L572">                id = token.getAttributeValue(new QName( &quot;AssertionID&quot;));</span>
            }
        }
<span class="fc" id="L575">        return id;</span>
    }


    /**
     * Process the given STR to find the id it refers to
     *
     * @param refElem
     * @return id
     */
    private String getIdFromSTR(OMElement refElem) {
        //ASSUMPTION:SecurityTokenReference/KeyIdentifier
<span class="fc" id="L587">        OMElement child = refElem.getFirstElement();</span>
<span class="pc bpc" id="L588" title="1 of 2 branches missed.">        if(child == null) {</span>
<span class="nc" id="L589">            return null;</span>
        }
        
<span class="pc bpc" id="L592" title="1 of 4 branches missed.">        if (child.getQName().equals(new QName(WSConstants.SIG_NS, &quot;KeyInfo&quot;)) ||</span>
                child.getQName().equals(new QName(WSConstants.WSSE_NS, &quot;KeyIdentifier&quot;))) {
<span class="fc" id="L594">            return child.getText();</span>
<span class="pc bpc" id="L595" title="1 of 2 branches missed.">        } else if(child.getQName().equals(Reference.TOKEN)) {</span>
<span class="fc" id="L596">            return child.getAttributeValue(new QName(&quot;URI&quot;));</span>
        } else {
<span class="nc" id="L598">            return null;</span>
        }

    }

    /**
     * Process the goven service policy and extract the info required to create
     * the RST.
     *
     * @param servicePolicy
     */
    private void processPolicy(Policy issuerPolicy, Policy servicePolicy) {
        //Get the policy assertions
        //Assumption: there's only one alternative

<span class="pc bpc" id="L613" title="1 of 2 branches missed.">        if (issuerPolicy != null) {</span>
<span class="fc" id="L614">            log.debug(&quot;Processing Issuer policy&quot;);</span>

<span class="fc" id="L616">            List issuerAssertions = (List) issuerPolicy.getAlternatives().next();</span>

<span class="fc bfc" id="L618" title="All 2 branches covered.">            for (Iterator iter = issuerAssertions.iterator(); iter.hasNext();) {</span>
<span class="fc" id="L619">                Assertion tempAssertion = (Assertion) iter.next();</span>
                //find the AlgorithmSuite assertion
<span class="fc bfc" id="L621" title="All 2 branches covered.">                if (tempAssertion instanceof Binding) {</span>

<span class="fc" id="L623">                    log.debug(&quot;Extracting algo suite from issuer policy binding&quot;);</span>

<span class="fc" id="L625">                    this.algorithmSuite = ((Binding) tempAssertion)</span>
                            .getAlgorithmSuite();
                }
<span class="fc" id="L628">            }</span>
        }

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

<span class="fc" id="L633">            log.debug(&quot;Processing service policy to find Trust10 assertion&quot;);</span>

<span class="fc" id="L635">            List assertions = (List) servicePolicy.getAlternatives().next();</span>

<span class="fc bfc" id="L637" title="All 2 branches covered.">            for (Iterator iter = assertions.iterator(); iter.hasNext();) {</span>
<span class="fc" id="L638">                Assertion tempAssertion = (Assertion) iter.next();</span>
                //find the Trust10 assertion
<span class="fc bfc" id="L640" title="All 2 branches covered.">                if (tempAssertion instanceof Trust10) {</span>
<span class="fc" id="L641">                    log.debug(&quot;Extracting Trust10 assertion from service policy&quot;);</span>
<span class="fc" id="L642">                    this.trust10 = (Trust10) tempAssertion;</span>
<span class="fc bfc" id="L643" title="All 2 branches covered.">                } else if (tempAssertion instanceof Trust13) {</span>
<span class="fc" id="L644">                    log.debug(&quot;Extracting Trust13 assertion from service policy&quot;);</span>
<span class="fc" id="L645">                    this.trust13 = (Trust13) tempAssertion;</span>
                }
<span class="fc" id="L647">            }</span>
        }
<span class="fc" id="L649">    }</span>

    /**
     * This creates a request security token (RST) message.
     * @param appliesTo The address which token is applicable to.
     * @return The axiom object representation of RST.
     * @throws TrustException If an error occurred while creating the RST.
     */
    protected OMElement createIssueRequest(String appliesTo) throws TrustException {

<span class="fc" id="L659">        String requestType =</span>
                    TrustUtil.getWSTNamespace(version) + RahasConstants.REQ_TYPE_ISSUE;

<span class="pc bpc" id="L662" title="1 of 2 branches missed.">        if (log.isDebugEnabled()) {</span>
<span class="nc" id="L663">            log.debug(&quot;Creating request with request type: &quot; + requestType +</span>
                      &quot; and applies to: &quot; + appliesTo);
        }

<span class="fc" id="L667">        OMElement rst = TrustUtil.createRequestSecurityTokenElement(version);</span>

<span class="fc" id="L669">        TrustUtil.createRequestTypeElement(this.version, rst, requestType);</span>
<span class="fc bfc" id="L670" title="All 2 branches covered.">        if (appliesTo != null) {</span>
<span class="fc" id="L671">            TrustUtil.createAppliesToElement(rst, appliesTo, this.addressingNs);</span>
        }
<span class="fc" id="L673">        TrustUtil.createLifetimeElement(this.version, rst, this.ttl * 1000);</span>

        //Copy over the elements from the template
<span class="pc bpc" id="L676" title="1 of 2 branches missed.">        if (this.rstTemplate != null) {</span>

<span class="pc bpc" id="L678" title="1 of 2 branches missed.">            if (log.isDebugEnabled()) {</span>
<span class="nc" id="L679">                log.debug(&quot;Using RSTTemplate: &quot; + this.rstTemplate.toString());</span>
            }

<span class="fc" id="L682">            Iterator templateChildren = rstTemplate.getChildElements();</span>
<span class="fc bfc" id="L683" title="All 2 branches covered.">            while (templateChildren.hasNext()) {</span>
<span class="fc" id="L684">                OMElement child = (OMElement) templateChildren.next();</span>
<span class="fc" id="L685">                rst.addChild(child.cloneOMElement());</span>
                //Look for the key size element
<span class="fc bfc" id="L687" title="All 2 branches covered.">                if (child.getQName().equals(</span>
                        new QName(TrustUtil.getWSTNamespace(this.version),
                                  RahasConstants.IssuanceBindingLocalNames.KEY_SIZE))) {
<span class="fc" id="L690">                    log.debug(&quot;Extracting key size from the RSTTemplate: &quot;);</span>
<span class="pc bpc" id="L691" title="2 of 4 branches missed.">                    this.keySize =</span>
                            (child.getText() != null &amp;&amp; !&quot;&quot;.equals(child.getText())) ?
                            Integer.parseInt(child.getText()) :
                            -1;
<span class="pc bpc" id="L695" title="1 of 2 branches missed.">                    if (log.isDebugEnabled()) {</span>
<span class="nc" id="L696">                        log.debug(&quot;Key size from RSTTemplate: &quot; + this.keySize);</span>
                    }
                }
<span class="fc" id="L699">            }</span>
        }

        try {
            // Handle entropy
<span class="fc bfc" id="L704" title="All 2 branches covered.">            if (this.trust10 != null) {</span>

<span class="fc" id="L706">                log.debug(&quot;Processing Trust assertion&quot;);</span>

<span class="pc bpc" id="L708" title="1 of 2 branches missed.">                if (this.trust10.isRequireClientEntropy()) {</span>

<span class="fc" id="L710">                    log.debug(&quot;Requires client entropy&quot;);</span>

                    // setup requestor entropy
<span class="fc" id="L713">                    OMElement ent = TrustUtil.createEntropyElement(this.version, rst);</span>
<span class="fc" id="L714">                    OMElement binSec =</span>
                            TrustUtil.createBinarySecretElement(this.version,
                                                                ent,
                                                                RahasConstants.BIN_SEC_TYPE_NONCE);
<span class="fc" id="L718">                    this.requestorEntropy =</span>
                            WSSecurityUtil.generateNonce(this.algorithmSuite.
                                    getMaximumSymmetricKeyLength()/8);
<span class="fc" id="L721">                    binSec.setText(Base64Utils.encode(this.requestorEntropy));</span>

<span class="pc bpc" id="L723" title="1 of 2 branches missed.">                    if (log.isDebugEnabled()) {</span>
<span class="nc" id="L724">                        log.debug(&quot;Clien entropy : &quot; + Base64Utils.encode(this.requestorEntropy));</span>
                    }

                    // Add the ComputedKey element
<span class="fc" id="L728">                    TrustUtil.createComputedKeyAlgorithm(this.version, rst,</span>
                                                         RahasConstants.COMPUTED_KEY_PSHA1);
<span class="fc" id="L730">                }</span>
                
<span class="fc bfc" id="L732" title="All 2 branches covered.">            } else if (this.trust13 != null) {</span>
                
<span class="pc bpc" id="L734" title="1 of 2 branches missed.">                if (this.trust13.isRequireClientEntropy()) {</span>

<span class="fc" id="L736">                    log.debug(&quot;Requires client entropy&quot;);</span>

                    // setup requestor entropy
<span class="fc" id="L739">                    OMElement ent = TrustUtil.createEntropyElement(this.version, rst);</span>
<span class="fc" id="L740">                    OMElement binSec =</span>
                            TrustUtil.createBinarySecretElement(this.version,
                                                                ent,
                                                                RahasConstants.BIN_SEC_TYPE_NONCE);
<span class="fc" id="L744">                    this.requestorEntropy =</span>
                            WSSecurityUtil.generateNonce(this.algorithmSuite.
                                    getMaximumSymmetricKeyLength()/8);
<span class="fc" id="L747">                    binSec.setText(Base64Utils.encode(this.requestorEntropy));</span>

<span class="pc bpc" id="L749" title="1 of 2 branches missed.">                    if (log.isDebugEnabled()) {</span>
<span class="nc" id="L750">                        log.debug(&quot;Clien entropy : &quot; + Base64Utils.encode(this.requestorEntropy));</span>
                    }

                    // Add the ComputedKey element
<span class="fc" id="L754">                    TrustUtil.createComputedKeyAlgorithm(this.version, rst,</span>
                                                         RahasConstants.COMPUTED_KEY_PSHA1);
                }
                
            }
            
            
            
            
<span class="nc" id="L763">        } catch (Exception e) {</span>
<span class="nc" id="L764">            throw new TrustException(&quot;errorSettingUpRequestorEntropy&quot;, e);</span>
<span class="fc" id="L765">        }</span>

        
<span class="fc" id="L768">        return rst;</span>
        
    }
    
    private OMElement createValidateRequest(String requestType, String tokenId) throws TrustException {

<span class="nc bnc" id="L774" title="All 2 branches missed.">        if (log.isDebugEnabled()) {</span>
<span class="nc" id="L775">            log.debug(&quot;Creating request with request type: &quot; + requestType);</span>
        }

<span class="nc" id="L778">        OMElement rst = TrustUtil.createRequestSecurityTokenElement(version);</span>
        
<span class="nc" id="L780">        TrustUtil.createRequestTypeElement(this.version, rst, requestType);</span>
        
<span class="nc" id="L782">        OMElement tokenTypeElem = TrustUtil.createTokenTypeElement(this.version, rst);</span>
        
<span class="nc" id="L784">        String tokenType =</span>
            TrustUtil.getWSTNamespace(version) + RahasConstants.TOK_TYPE_STATUS;
        
<span class="nc" id="L787">        tokenTypeElem.setText(tokenType);</span>
        
<span class="nc" id="L789">        TokenStorage store = TrustUtil.getTokenStore(configCtx);</span>
        
<span class="nc" id="L791">        Token token = store.getToken(tokenId);</span>
        
<span class="nc bnc" id="L793" title="All 2 branches missed.">        if ( token != null) {            </span>
<span class="nc" id="L794">            OMElement str = token.getUnattachedReference();     </span>
            
<span class="nc bnc" id="L796" title="All 2 branches missed.">            if (str == null) {</span>
<span class="nc" id="L797">                str = token.getAttachedReference();</span>
            }
            
<span class="nc" id="L800">            TrustUtil.createValidateTargetElement(this.version, rst,str);</span>
            
            
<span class="nc" id="L803">        } else {</span>
<span class="nc" id="L804">            throw new TrustException(&quot;noToken&quot;,new String[]{tokenId});</span>
        }
              
<span class="nc" id="L807">        return rst;</span>
             
    }
    
    private OMElement createRenewRequest(String tokenType, String tokenId) throws TrustException {
        
<span class="nc" id="L813">        String requestType =</span>
            TrustUtil.getWSTNamespace(version) + RahasConstants.REQ_TYPE_RENEW;

<span class="nc bnc" id="L816" title="All 2 branches missed.">        if (log.isDebugEnabled()) {</span>
<span class="nc" id="L817">            log.debug(&quot;Creating request with request type: &quot; + requestType);</span>
        }

<span class="nc" id="L820">        OMElement rst = TrustUtil.createRequestSecurityTokenElement(version);</span>
        
<span class="nc" id="L822">        TrustUtil.createRequestTypeElement(this.version, rst, requestType);</span>
        
<span class="nc" id="L824">        OMElement tokenTypeElem = TrustUtil.createTokenTypeElement(version, rst);</span>
<span class="nc" id="L825">        tokenTypeElem.setText(tokenType);</span>
        
<span class="nc" id="L827">        TokenStorage store = TrustUtil.getTokenStore(configCtx);</span>
        
<span class="nc" id="L829">        Token token = store.getToken(tokenId);</span>
        
<span class="nc bnc" id="L831" title="All 2 branches missed.">        if ( token != null) {</span>
            
<span class="nc" id="L833">            OMElement str = token.getUnattachedReference();     </span>
            
<span class="nc bnc" id="L835" title="All 2 branches missed.">            if (str == null) {</span>
<span class="nc" id="L836">                str = token.getAttachedReference();</span>
            }
            
<span class="nc" id="L839">            TrustUtil.createRenewTargetElement(this.version, rst,str);</span>
            
            
<span class="nc" id="L842">        } else {</span>
<span class="nc" id="L843">            throw new TrustException(&quot;noToken&quot;,new String[]{tokenId});</span>
        }
        
<span class="nc" id="L846">        return rst;</span>
              
        
    }

    private OMElement createCancelRequest(String tokenId) throws TrustException {

<span class="nc" id="L853">        return TrustUtil.createCancelRequest(tokenId, version);</span>
    }

    /**
     * Set this to set the entropy configurations.
     * If this is provided in the given policy it will be overridden.
     *
     * @param trust10 The trust10 to set.
     */
    public void setTrust10(Trust10 trust10) {
<span class="nc" id="L863">        this.trust10 = trust10;</span>
<span class="nc" id="L864">    }</span>
    
    /**
     * Set this to set the entropy configurations.
     * If this is provided in the given policy it will be overridden.
     *
     * @param trust13 The trust13 to set.
     */
    public void setTrust13(Trust13 trust13) {
<span class="nc" id="L873">        this.trust13 = trust13;</span>
<span class="nc" id="L874">    }</span>

    /**
     * This can be used in the case where the AlgorithmSuite is not specified in
     * the given policy.
     * If the AlgorithmSuite exists in a binding in the policy then the value
     * set will be overridden.
     *
     * @param algorithmSuite The algorithmSuite to set.
     */
    public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
<span class="nc" id="L885">        this.algorithmSuite = algorithmSuite;</span>
<span class="nc" id="L886">    }</span>

    /**
     * @param addressingNs The addressingNs to set.
     */
    public void setAddressingNs(String addressingNs) {
<span class="nc" id="L892">        this.addressingNs = addressingNs;</span>
<span class="nc" id="L893">    }</span>

    /**
     * @param ttl The ttl to set.
     */
    public void setTtl(int ttl) {
<span class="nc" id="L899">        this.ttl = ttl;</span>
<span class="nc" id="L900">    }</span>

    /**
     * Sets the crypto information required to process the RSTR.
     *
     * @param crypto    Crypto information
     * @param cbHandler Callback handler to provide the private key password to
     *                  decrypt
     */
    public void setCryptoInfo(Crypto crypto, CallbackHandler cbHandler) {
<span class="fc" id="L910">        this.crypto = crypto;</span>
<span class="fc" id="L911">        this.cbHandler = cbHandler;</span>
<span class="fc" id="L912">    }</span>

    /**
     * Sets the crypto information required to process the RSTR.
     *
     * @param crypto        The crypto information
     * @param privKeyPasswd Private key password to decrypt
     */
    public void setCryptoInfo(Crypto crypto, String privKeyPasswd) {
<span class="nc" id="L921">        this.crypto = crypto;</span>
<span class="nc" id="L922">        this.cbHandler = new CBHandler(privKeyPasswd);</span>
<span class="nc" id="L923">    }</span>

    /**
     * @param action The action to set.
     */
    public void setAction(String action) {
<span class="fc" id="L929">        this.action = action;</span>
<span class="fc" id="L930">    }</span>

    /**
     * @param options The options to set.
     */
    public void setOptions(Options options) {
<span class="fc" id="L936">        this.options = options;</span>
<span class="fc" id="L937">    }</span>

    /**
     * @param rstTemplate The rstTemplate to set.
     */
    public void setRstTemplate(OMElement rstTemplate) {
<span class="fc" id="L943">        this.rstTemplate = rstTemplate;</span>
<span class="fc" id="L944">    }</span>

    private static class CBHandler implements CallbackHandler {

        private String passwd;

<span class="nc" id="L950">        private CBHandler(String passwd) {</span>
<span class="nc" id="L951">            this.passwd = passwd;</span>
<span class="nc" id="L952">        }</span>

        public void handle(Callback[] cb) throws IOException,
                                                 UnsupportedCallbackException {
<span class="nc" id="L956">            ((WSPasswordCallback) cb[0]).setPassword(this.passwd);</span>
<span class="nc" id="L957">        }</span>

    }

    /**
     * @param version The version to set.
     */
    public void setVersion(int version) {
<span class="fc" id="L965">        this.version = version;</span>
<span class="fc" id="L966">    }</span>

    public void setSoapVersion(String soapVersion) {
<span class="fc" id="L969">        this.soapVersion = soapVersion;</span>
<span class="fc" id="L970">    }</span>
    
    public void addParameter(Parameter param) {
<span class="nc" id="L973">        parameters.add(param);</span>
<span class="nc" id="L974">    }</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>