001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: FSAuthnResponse.java,v 1.2 2008/06/25 05:46:43 qcheng Exp $
026 * Portions Copyrighted 2014 ForgeRock AS
027 */
028
029
030package com.sun.identity.federation.message;
031
032import com.sun.identity.federation.common.FSUtils;
033import com.sun.identity.federation.common.IFSConstants;
034import com.sun.identity.federation.message.common.FSMsgException;
035import com.sun.identity.saml.common.SAMLConstants;
036import com.sun.identity.saml.common.SAMLException;
037import com.sun.identity.saml.common.SAMLResponderException;
038import com.sun.identity.saml.common.SAMLVersionMismatchException;
039import com.sun.identity.saml.protocol.Response;
040import com.sun.identity.saml.protocol.Status;
041import com.sun.identity.saml.xmlsig.XMLSignatureManager;
042import com.sun.identity.shared.DateUtils;
043import com.sun.identity.shared.encode.Base64;
044import com.sun.identity.shared.xml.XMLUtils;
045import java.text.ParseException;
046import java.util.ArrayList;
047import java.util.Collections;
048import java.util.Date;
049import java.util.Iterator;
050import java.util.List;
051import org.w3c.dom.Document;
052import org.w3c.dom.Element;
053import org.w3c.dom.Node;
054import org.w3c.dom.NodeList;
055
056/**
057 * The class <code>FSAuthnResponse</code> creates and parses the
058 * Liberty Response. This class extends the <code>SAML</code>
059 * <code>Response</code>.
060 *
061 * @supported.all.api
062 * @deprecated since 12.0.0
063 */
064@Deprecated
065
066public class FSAuthnResponse extends Response {
067
068    private String providerId = null;
069    protected String    relayState      = null;
070    protected String consentURI = null;
071    protected int minorVersion = 0;
072    protected String id = null; 
073    protected Element domElement = null;
074    
075
076   /**
077    * Constructor to create <code>FSAuthnResponse</code> object.
078    *
079    * @param responseID value of the <code>ResponseID</code> attribute.
080    * @param inResponseTo value of the <code>inResponseTo</code> attribute.
081    * @param status the <code>Status</code> object.
082    * @param contents  List of Assertions in the response.
083    *                  It could be null when there are no Assertions.
084    * @param relayState value of the <code>RelayState</code> attribute.
085    * @throws FSMsgException on error.
086    * @throws SAMLException on error.
087    */
088    public FSAuthnResponse(String responseID,String inResponseTo,
089                           Status status, List contents, String relayState)
090                           throws SAMLException, FSMsgException {
091        super( responseID, inResponseTo, status, contents);
092        setIssueInstant(new Date());
093        this.relayState = relayState;
094    }
095
096   /**
097    * Creates <code>FSAuthnResponse</code> object from XML Schema.
098    *
099    * @param xml the XML Schema for this object.
100    * @throws <code>SAMLException</code> on error.
101    * @throws FSMsgException on error.
102    */
103    public static FSAuthnResponse parseAuthnResponseXML(
104        String xml) throws SAMLException, FSMsgException {
105        // parse the xml string
106        FSUtils.debug.message("FSAuthnResponse.parseAuthnResponseXML: Called");
107        Element root;
108        Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug);
109        if (doc == null) {
110           if (FSUtils.debug.messageEnabled()) {
111                    FSUtils.debug.message(
112                        "FSAuthnResponse.parseXML:Error "
113                        + "while parsing input xml string");
114                }
115           throw new FSMsgException("parseError",null);
116        }
117        root = doc.getDocumentElement();
118        return new FSAuthnResponse(root);
119    }
120
121    /**
122     * Constructor creates <code>FSAuthnResponse</code> object from
123     * Document Element.
124     *
125     * @param root the Document Element
126     * @throws SAMLException on error.
127     * @throws FSMsgException on error.
128     */
129    public FSAuthnResponse(Element root) throws SAMLException, FSMsgException {
130        // Make sure this is a Response
131        FSUtils.debug.message("FSAuthnResponse(Element): Called");
132        if (root == null) {
133            FSUtils.debug.message("FSAuthnResponse(Element): "
134                + "Input paramenter (root) is null");
135            throw new FSMsgException("nullInput",null);
136        }
137        String tag = null;
138        if (((tag = root.getLocalName()) == null) ||
139            (!tag.equals(IFSConstants.AUTHN_RESPONSE))) {
140            FSUtils.debug.message("FSAuthnResponse(Element): "
141                + "Root element name is not AuthnResponse");
142            throw new FSMsgException("wrongInput",null);
143        }
144        domElement = root;
145        consentURI = root.getAttribute(IFSConstants.CONSENT);
146
147        // Attribute ResponseID
148        id = root.getAttribute(IFSConstants.ID);
149        responseID = root.getAttribute(IFSConstants.RESPONSE_ID);
150        if ((responseID == null) || (responseID.length() == 0)) {
151            if (FSUtils.debug.messageEnabled()) {
152                FSUtils.debug.message("FSAuthnResponse(Element): "
153                    + "AuthnResponse doesn't have ResponseID attribute");
154            }
155            String[] args = { IFSConstants.RESPONSE_ID };
156            throw new FSMsgException("missingAttribute",args);
157        }
158
159        inResponseTo = root.getAttribute(IFSConstants.IN_RESPONSE_TO);
160        if (inResponseTo == null) {
161            if (FSUtils.debug.messageEnabled()) {
162                FSUtils.debug.message("FSAuthnResponse(Element): "
163                    + "AuthnResponse doesn't have InResponseTo attribute");
164            }            
165        }
166        
167        // Attribute IssueInstant
168        String instantString = root.getAttribute(IFSConstants.ISSUE_INSTANT);
169
170        if ((instantString == null) || (instantString.length() == 0)) {
171            FSUtils.debug.message("FSAuthnResponse(Element): "
172                                  + " missing IssueInstant");
173            String[] args = { IFSConstants.ISSUE_INSTANT };
174            throw new FSMsgException("missingAttribute",args);
175        } else {
176            try {
177                issueInstant = DateUtils.stringToDate(instantString);
178            } catch (ParseException e) {
179                FSUtils.debug.message(
180                    "FSAuthnResponse(Element): could not parse IssueInstant",e);
181                throw new FSMsgException("wrongInput",null);
182            }
183        }
184
185        parseMajorVersion(root.getAttribute(IFSConstants.MAJOR_VERSION));
186        parseMinorVersion(root.getAttribute(IFSConstants.MINOR_VERSION));
187        
188        setRecipient(root.getAttribute(IFSConstants.RECIPIENT));
189 
190        NodeList nl = root.getChildNodes();
191        Node child;
192        String childName;
193        int length = nl.getLength();
194        for (int i = 0; i < length; i++) {
195            child = nl.item(i);
196            if ((childName = child.getLocalName()) != null) {
197                if (childName.equals(IFSConstants.STATUS)) {
198                    if (status != null) {
199                        if (FSUtils.debug.messageEnabled()) {
200                            FSUtils.debug.message("FSAuthnResponse(Element): "
201                                + "included more than one <Status>");
202                        }
203                        throw new FSMsgException("moreElement",null);
204                    }
205                    status = new Status((Element) child);
206                } else if (childName.equals(IFSConstants.ASSERTION)) {
207                    if (assertions == Collections.EMPTY_LIST) {
208                        assertions = new ArrayList();
209                    }
210                    assertions.add(new FSAssertion((Element) child));
211                } else if (childName.equals(IFSConstants.RELAY_STATE)) {
212                    // make sure the providerId is not assigned already
213                    if (relayState != null) {
214                        if (FSUtils.debug.messageEnabled()) {
215                            FSUtils.debug.message("FSAuthnResponse(Element): "
216                                + "should contain only one RelayState.");
217                        } 
218                        throw new FSMsgException("wrongInput",null);
219                    }
220                    relayState = XMLUtils.getElementValue((Element) child);
221                } else if (childName.equals(IFSConstants.PROVIDER_ID)) {
222                    if (providerId != null && providerId.length() != 0) {
223                        if (FSUtils.debug.messageEnabled()) {
224                            FSUtils.debug.message("FSAuthnResponse(Element): "
225                                + "should contain only one ProviderID.");
226                        } 
227                        throw new FSMsgException("wrongInput",null);
228                    }
229                    providerId = XMLUtils.getElementValue((Element) child);
230                  } else {
231                    if (FSUtils.debug.messageEnabled()) {
232                        FSUtils.debug.message("FSAuthnResponse(Element): "
233                            + "included wrong element: " + childName);
234                    }
235                    throw new FSMsgException("wrongInput",null);
236                }
237            } // end if childName != null
238        } // end for loop
239
240        if (status == null) {
241            FSUtils.debug.message("FSAuthnResponse(Element): "
242                + "missing element <Status>.");
243            throw new FSMsgException("missingElement",null);
244        }
245        //check for signature
246        List signs = XMLUtils.getElementsByTagNameNS1(root,
247                                        SAMLConstants.XMLSIG_NAMESPACE_URI,
248                                        SAMLConstants.XMLSIG_ELEMENT_NAME);
249        int signsSize = signs.size();
250        if (signsSize == 1) {
251            Element elem = (Element)signs.get(0);
252            setSignature(elem);
253            xmlString = XMLUtils.print(root);
254            signed = true;
255        } else if (signsSize != 0) {
256            if (FSUtils.debug.messageEnabled()) {
257                FSUtils.debug.message("FSAuthnResponse(Element): "
258                    + "included more than one Signature element.");
259            }
260            throw new FSMsgException("moreElement",null);
261        }        
262        //end check for signature
263    }
264
265   /**
266    * Returns the value of the <code>id</code> attribute.
267    *
268    * @return the value of <code>id</code> attribute.
269    * @see #setID(String)
270    */
271    public String getID() {
272        return id;
273    }
274    
275    /**
276     * Sets the value of the <code>id</code> attribute.
277     *
278     * @param id the new value of <code>id</code> attribute.
279     * @see #getID
280     */
281    public void setID(String id) {
282        this.id = id;
283    }    
284    
285   /**
286    * Returns the <code>ProviderID</code> attribute value.
287    *
288    * @return value of the <code>ProviderID</code> attribute.
289    * @see #setProviderId(String)
290    */
291    public String getProviderId() {
292       return providerId;
293    }
294   
295    /**
296     * Sets the <code>ProviderID</code> attribute value.
297     *
298     * @param provId new value of <code>ProviderID</code> attribute.
299     * @see #getProviderId
300     */
301    public void setProviderId(String provId) {
302       providerId = provId;
303    }
304   
305   /**
306    * Returns a signed XML Representation of this object.
307    *
308    * @return a signed XML Representation of this object.
309    */
310    public String getSignedXMLString(){
311       return xmlString;
312    }
313   
314   /**
315    * Returns the Signature string.
316    *
317    * @return the Signature string.
318    */
319    public String getSignatureString(){
320       return signatureString;
321    }
322
323   /**
324    * Returns the value <code>MinorVersion</code> attribute.
325    *
326    * @return the value <code>MinorVersion</code> attribute.
327    * @see #setMinorVersion(int)
328    */
329    public int getMinorVersion() {
330       return minorVersion;
331    }
332
333   /**
334    * Returns the value of <code>MajorVersion</code> attribute.
335    *
336    * @param version the value of <code>MajorVersion</code> attribute.
337    * @see #getMinorVersion
338    */
339    public void setMinorVersion(int version) {
340       minorVersion = version;
341    }
342
343   /**
344    * Returns the value of the <code>consent</code> attribute.
345    *
346    * @return value of <code>consent</code> attribute.
347    * @see #setConsentURI(String)
348    */
349
350    public String getConsentURI() {
351       return consentURI;
352    }
353
354   /**
355    * Sets the value of the <code>consent</code> attribute.
356    *
357    * @param consent new value of <code>consent</code> attribute.
358    * @see #getConsentURI
359    */
360    public void setConsentURI(String consent) {
361       this.consentURI = consent;
362    }
363
364   /**
365    * Returns the Document Element for this object.
366    *
367    * @return the Document Element for this object.
368    */
369    public Element getDOMElement() {
370        return domElement;
371    }
372
373    /**
374     * Parses the input and sets the <code>MajorVersion</code>.
375     *
376     * @param majorVer value of <code>MajorVersion</code> attribute to be set.
377     * @throws FSMsgException on error.
378     * @throws SAMLException if the version is incorrect.
379     */
380    private void parseMajorVersion(String majorVer) 
381                 throws SAMLException, FSMsgException {
382        try {
383            majorVersion = Integer.parseInt(majorVer);
384        } catch (NumberFormatException e) {
385            if (FSUtils.debug.messageEnabled()) {
386                FSUtils.debug.message("FSAuthnResponse(Element): invalid "
387                    + "MajorVersion", e);
388            }
389            throw new FSMsgException("wrongInput",null);
390        }
391
392        if (majorVersion != SAMLConstants.PROTOCOL_MAJOR_VERSION) {
393            if (majorVersion > SAMLConstants.PROTOCOL_MAJOR_VERSION) {
394                if (FSUtils.debug.messageEnabled()) {
395                    FSUtils.debug.message(
396                        "FSAuthnResponse(Element):MajorVersion of"
397                        + " the Response is too high.");
398                }
399                throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME,
400                                                 "responseVersionTooHigh",null);
401            } else {
402                if (FSUtils.debug.messageEnabled()) {
403                    FSUtils.debug.message(
404                        "FSAuthnResponse(Element):MajorVersion of"
405                        + " the Response is too low.");
406                }
407                throw new SAMLVersionMismatchException(
408                    FSUtils.BUNDLE_NAME,"responseVersionTooLow",null);
409            }
410        }
411    }
412
413   /**
414    * Parses the input and set the <code>MinorVersion</code>.
415    *
416    * @param minorVer value of <code>MinorVersion</code> attribute to be set.
417    * @throws FSMsgException on error.
418    * @throws SAMLException if the version is incorrect.
419    */
420    private void parseMinorVersion(
421        String minorVer) throws SAMLException, FSMsgException {
422        try {
423            minorVersion = Integer.parseInt(minorVer);
424        } catch (NumberFormatException e) {
425            if (FSUtils.debug.messageEnabled()) {
426                FSUtils.debug.message("FSAuthnResponse(Element): invalid "
427                    + "MinorVersion", e);
428            }
429            throw new FSMsgException("wrongInput",null);
430        }
431
432        if (minorVersion > IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) {
433           if(FSUtils.debug.messageEnabled()) {
434              FSUtils.debug.message("FSAuthnResponse.checkMinorVersion:"+
435              " Minor Version of the AuthnResponse is too high.");
436           }
437           throw new FSMsgException("requestVersionTooHigh",null);
438        } else if (minorVersion < IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) {
439           if(FSUtils.debug.messageEnabled()) {
440              FSUtils.debug.message("FSAuthnResponse.checkMinorVersion:" +
441              " Minor Version of the AuthnResponse is too low.");
442           }
443           throw new FSMsgException("requestVersionTooLow",null);
444        }
445    }
446
447    /**
448     * Returns the <code>RelayState</code> attribute in the Response.
449     *
450     * @return the <code>RelayState</code> attribute in the Response.
451     */
452    public String getRelayState() {
453        return relayState;
454    }
455
456    /**
457     * Returns the string representation of this object.
458     * This method translates the response to an XML document string based on
459     * the Response schema described above.
460     *
461     * @return An XML String representing the response. NOTE: this is a
462     *                complete SAML response xml string with ResponseID,
463     *                MajorVersion, etc.
464     */
465    public String toXMLString()  throws FSMsgException {
466        return this.toXMLString(true, true);
467    }
468
469    /**
470     * Returns a String representation of the &lt;samlp:Response&gt; element.
471     *
472     * @param includeNS : Determines whether or not the namespace qualifier
473     *          is prepended to the Element when converted
474     * @param declareNS : Determines whether or not the namespace is declared
475     *          within the Element.
476     * @return A string containing the valid XML for this element
477     */   
478    public String toXMLString(boolean includeNS, boolean declareNS) 
479           throws FSMsgException {
480        return toXMLString(includeNS, declareNS, false);
481    }
482
483    /**
484     * Returns a String representation of the &lt;samlp:Response&gt; element.
485     *
486     * @param includeNS  Determines whether or not the namespace qualifier
487     *          is prepended to the Element when converted
488     * @param declareNS  Determines whether or not the namespace is declared
489     *          within the Element.
490     * @param includeHeader  Determines whether the output include the xml
491     *                declaration header.
492     * @return A string containing the valid XML for this element
493     */   
494    public String toXMLString(boolean includeNS,
495                        boolean declareNS,
496                        boolean includeHeader)  throws FSMsgException {
497        FSUtils.debug.message("FSAuthnResponse.toXMLString(3): Called");
498        
499        if((providerId == null) || (providerId.length() == 0)){
500            FSUtils.debug.error("FSAuthnResponse.toXMLString: "
501                + "providerId is null ");
502                throw new FSMsgException("nullProviderID",null);
503        }
504        
505        StringBuffer xml = new StringBuffer(300);
506        if (includeHeader) {
507            xml.append(IFSConstants.XML_PREFIX)
508               .append(SAMLConstants.DEFAULT_ENCODING).append("\" ?>\n")
509               .append(IFSConstants.QUOTE)
510               .append(IFSConstants.QUESTION_MARK)
511               .append(IFSConstants.RIGHT_ANGLE)
512               .append(IFSConstants.NL);
513        }
514        String prefixSAML = "";
515        String prefixLIB = "";
516        String prefixSAML_PROTOCOL = "";
517        String uriSAML_PROTOCOL = "";
518        String uriSAML = "";
519        String uriLIB = "";
520        String uriDS="";
521        String uriXSI="";
522        
523        if (includeNS) {
524            prefixLIB = IFSConstants.LIB_PREFIX;
525            prefixSAML = IFSConstants.ASSERTION_PREFIX;
526            prefixSAML_PROTOCOL = IFSConstants.PROTOCOL_PREFIX; 
527        }
528        if (declareNS) {
529            if(minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 
530               uriLIB = IFSConstants.LIB_12_NAMESPACE_STRING;
531            } else {
532               uriLIB = IFSConstants.LIB_NAMESPACE_STRING;
533            }
534            uriSAML = IFSConstants.assertionDeclareStr;
535            uriSAML_PROTOCOL = IFSConstants.PROTOCOL_NAMESPACE_STRING;
536            uriDS = IFSConstants.DSSAMLNameSpace;
537            uriXSI = IFSConstants.XSI_NAMESPACE_STRING;
538        }
539
540        String instantString = DateUtils.toUTCDateFormat(issueInstant);
541
542        if((responseID != null) && (inResponseTo != null)){
543            xml.append(IFSConstants.LEFT_ANGLE)
544               .append(prefixLIB)
545               .append(IFSConstants.AUTHN_RESPONSE)
546               .append(uriLIB)
547               .append(uriSAML)
548               .append(uriSAML_PROTOCOL)
549               .append(IFSConstants.SPACE)
550               .append(uriDS)
551               .append(IFSConstants.SPACE)
552               .append(uriXSI)
553               .append(IFSConstants.SPACE)
554               .append(IFSConstants.RESPONSE_ID)
555               .append(IFSConstants.EQUAL_TO)
556               .append(IFSConstants.QUOTE)
557               .append(responseID)
558               .append(IFSConstants.QUOTE)
559               .append(IFSConstants.SPACE);
560               
561                if ((inResponseTo != null) && (inResponseTo.length() != 0)) {
562                    xml.append(IFSConstants.SPACE)
563                       .append(IFSConstants.IN_RESPONSE_TO)
564                       .append(IFSConstants.EQUAL_TO)
565                       .append(IFSConstants.QUOTE)
566                       .append(inResponseTo)
567                       .append(IFSConstants.QUOTE);
568                }
569                if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION && 
570                    id != null && (id.length() > 0)) {
571                        xml.append(IFSConstants.SPACE)
572                           .append(IFSConstants.ID)
573                           .append(IFSConstants.EQUAL_TO)
574                           .append(IFSConstants.QUOTE)
575                           .append(id)
576                           .append(IFSConstants.QUOTE);
577                }
578                xml.append(IFSConstants.SPACE)
579                   .append(IFSConstants.MAJOR_VERSION) 
580                   .append(IFSConstants.EQUAL_TO)
581                   .append(IFSConstants.QUOTE)
582                   .append(majorVersion)
583                   .append(IFSConstants.QUOTE)
584                   .append(IFSConstants.SPACE)
585                   .append(IFSConstants.MINOR_VERSION) 
586                   .append(IFSConstants.EQUAL_TO)
587                   .append(IFSConstants.QUOTE)
588                   .append(minorVersion)
589                   .append(IFSConstants.QUOTE)
590                   .append(IFSConstants.SPACE)
591                   .append(IFSConstants.ISSUE_INSTANT)
592                   .append(IFSConstants.EQUAL_TO)
593                   .append(IFSConstants.QUOTE)
594                   .append(instantString)
595                   .append(IFSConstants.QUOTE);
596
597                if (consentURI != null) {
598                    xml.append(IFSConstants.SPACE)
599                       .append(IFSConstants.CONSENT)
600                       .append(IFSConstants.EQUAL_TO)
601                       .append(IFSConstants.QUOTE)
602                       .append(consentURI)
603                       .append(IFSConstants.QUOTE)
604                       .append(IFSConstants.SPACE);
605                }
606                if ((recipient != null) && (recipient.length() != 0)) {
607                    xml.append(IFSConstants.SPACE)
608                       .append(IFSConstants.RECIPIENT)
609                       .append(IFSConstants.EQUAL_TO)
610                       .append(IFSConstants.QUOTE)
611                       .append(recipient)
612                       .append(IFSConstants.QUOTE)
613                       .append(IFSConstants.SPACE);
614                }
615                xml.append(IFSConstants.RIGHT_ANGLE);
616        }
617
618        if (signed) {
619            if (signatureString != null && signatureString.length() != 0) {
620                xml.append(signatureString);
621            } else if (signature != null) {
622                signatureString = XMLUtils.print(signature);
623                xml.append(signatureString);
624            }
625        }
626        
627        if (status != null) {
628            xml.append(status.toString(includeNS, false));
629        }
630        
631        if ((assertions != null) && (assertions != Collections.EMPTY_LIST)) {
632            Iterator j = assertions.iterator();
633            while (j.hasNext()) {
634                xml.append(((FSAssertion) j.next())
635                                .toXMLString(true,declareNS));
636            }
637        }
638        
639        xml.append(IFSConstants.LEFT_ANGLE)
640           .append(prefixLIB)
641           .append(IFSConstants.PROVIDER_ID)
642           .append(IFSConstants.RIGHT_ANGLE)
643           .append(providerId)
644           .append(IFSConstants.START_END_ELEMENT)
645           .append(prefixLIB)
646           .append(IFSConstants.PROVIDER_ID)
647           .append(IFSConstants.RIGHT_ANGLE);
648        
649        if (relayState != null && relayState.length() != 0) {
650            xml.append(IFSConstants.LEFT_ANGLE)
651               .append(prefixLIB)
652               .append(IFSConstants.RELAY_STATE)
653               .append(IFSConstants.RIGHT_ANGLE)
654               .append(XMLUtils.escapeSpecialCharacters(relayState))
655               .append(IFSConstants.START_END_ELEMENT)
656               .append(prefixLIB)
657               .append(IFSConstants.RELAY_STATE)
658               .append(IFSConstants.RIGHT_ANGLE);
659        }     
660
661        xml.append(IFSConstants.START_END_ELEMENT)
662           .append(prefixLIB)
663           .append(IFSConstants.AUTHN_RESPONSE)
664           .append(IFSConstants.RIGHT_ANGLE)
665           .append(IFSConstants.NL);
666
667        return xml.toString();
668    }
669    
670   /**
671    * Returns <code>FSAutnResponse</code> object by parsing a 
672    * <code>Base64</code> encoding XML string.
673    *
674    *
675    * @param encodedRes the <code>Base64</code> encoded string.
676    * @return <code>FSAuthnResponse</code> object.
677    * @throws FSMsgException if there is an error parsing
678    *         the <code>Base64</code> encoded string.
679    * @throws SAMLException if there is an error creating
680    *         the <code>FSAuthnResponse</code> object.
681    */    
682    public static FSAuthnResponse parseBASE64EncodedString(String encodedRes)
683                                  throws FSMsgException, SAMLException {
684        FSUtils.debug.message(
685            "FSAuthnResponse.parseBASE64EncodedString: Called new");
686        if(encodedRes != null){
687            String decodedAuthnRes = new String(Base64.decode(encodedRes));
688            if (FSUtils.debug.messageEnabled()) {
689                FSUtils.debug.message(
690                    "FSAuthnResponse.parseBASE64EncodedString: "
691                    + "Decoded AuthnResponse message: \n"
692                    + decodedAuthnRes);
693            }
694            return parseAuthnResponseXML(decodedAuthnRes);
695        } else {
696            if (FSUtils.debug.messageEnabled()) {
697                    FSUtils.debug.message(
698                        "FSAuthnResponse.parseBASE64EncodedString: "
699                        + "null String passed in as argument.");
700                }
701                throw new FSMsgException("nullInput",null);
702        }
703    }
704    
705   /**
706    * Returns a <code>Base64</code> encoded string representing this
707    * object.
708    *
709    * @return a <code>Base64</code> encoded string representing this
710    *         object.
711    * @throws FSMsgException if there is an error creating
712    *         a <code>Base64</code> encoded string.
713    */
714    public String toBASE64EncodedString() throws FSMsgException  {
715        FSUtils.debug.message("FSAuthnResponse.toBASE64EncodedString: Called");
716        if ((responseID == null) || (responseID.length() == 0)){
717         responseID = FSUtils.generateID();
718            if (responseID == null) {
719                FSUtils.debug.error("FSAuthnResponse.toBASE64EncodedString: "
720                    + "couldn't generate ResponseID.");
721                throw new FSMsgException("errorGenerateID",null);
722            }
723        }
724        return Base64.encode(this.toXMLString(true, true).getBytes());
725    } 
726    
727    /**
728     * Signs the <code>Response</code>.
729     *
730     * @param certAlias the Certificate Alias
731     * @throws SAMLException if <code>Response</code>
732     *         cannot be signed.
733     */
734    public void signXML(String certAlias) throws SAMLException {
735        FSUtils.debug.message("FSAuthnResponse.signXML: Called");
736        if (signed) {
737            if (FSUtils.debug.messageEnabled()) {
738                FSUtils.debug.message(
739                    "FSAuthnResponse.signXML: the assertion is "
740                    + "already signed.");
741            }
742            throw new SAMLResponderException(
743                                  FSUtils.BUNDLE_NAME,"alreadySigned",null);
744        }
745        if (certAlias == null || certAlias.length() == 0) {
746            throw new SAMLResponderException(
747                FSUtils.BUNDLE_NAME,"cannotFindCertAlias",null);
748        }
749        try{
750            XMLSignatureManager manager = XMLSignatureManager.getInstance();
751            if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) {
752                signatureString = manager.signXML(this.toXMLString(true, true), 
753                                          certAlias, 
754                                          IFSConstants.DEF_SIG_ALGO, 
755                                          IFSConstants.ID, 
756                                          this.id, false);
757            } else if (minorVersion == 
758                          IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) {
759                  signatureString = manager.signXML(
760                                         this.toXMLString(true, true), 
761                                         certAlias, IFSConstants.DEF_SIG_ALGO,
762                                         IFSConstants.RESPONSE_ID, 
763                                         this.getResponseID(), false);
764            } else { 
765                if (FSUtils.debug.messageEnabled()) { 
766                    FSUtils.debug.message("invalid minor version.");                 
767                }
768            }  
769            signature = XMLUtils.toDOMDocument(signatureString, FSUtils.debug)
770                                               .getDocumentElement();
771            signed = true;
772            xmlString = this.toXMLString(true, true);      
773        } catch(Exception e) {
774            throw new SAMLResponderException(FSUtils.BUNDLE_NAME,
775                                             "signFailed",null);
776        }
777    }
778    
779   /**
780    * Sets the <code>Element</code> signature.
781    *
782    * @param elem the <code>Element</code> object
783    * @return true if signature is set otherwise false
784    */
785    public boolean setSignature(Element elem) {
786        signatureString = XMLUtils.print(elem); 
787        return super.setSignature(elem); 
788    }
789}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.