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: FSAssertion.java,v 1.2 2008/06/25 05:46:43 qcheng Exp $
026 *
027 * Portions Copyrighted 2014-2016 ForgeRock AS.
028 */
029
030
031package com.sun.identity.federation.message;
032
033import static org.forgerock.openam.utils.Time.*;
034
035import com.sun.identity.federation.common.FSUtils;
036import com.sun.identity.federation.common.IFSConstants;
037import com.sun.identity.federation.message.common.FSMsgException;
038import com.sun.identity.saml.assertion.Advice;
039import com.sun.identity.saml.assertion.Assertion;
040import com.sun.identity.saml.assertion.AttributeStatement;
041import com.sun.identity.saml.assertion.AuthorizationDecisionStatement;
042import com.sun.identity.saml.assertion.Conditions;
043import com.sun.identity.saml.assertion.Statement;
044import com.sun.identity.saml.common.SAMLConstants;
045import com.sun.identity.saml.common.SAMLException;
046import com.sun.identity.saml.common.SAMLResponderException;
047import com.sun.identity.saml.common.SAMLVersionMismatchException;
048import com.sun.identity.saml.xmlsig.XMLSignatureManager;
049import com.sun.identity.liberty.ws.security.SecurityAssertion;
050import com.sun.identity.shared.DateUtils;
051import com.sun.identity.shared.xml.XMLUtils;
052import java.text.ParseException;
053import java.util.ArrayList;
054import java.util.Date;
055import java.util.Iterator;
056import java.util.List;
057import java.util.Set;
058import org.w3c.dom.Element;
059import org.w3c.dom.Node;
060import org.w3c.dom.NodeList;
061
062/**
063 * The class <code>FSAssertion</code> creates and parses Liberty
064 * <code>Assertion</code> during the Single Sign-On process.
065 * This class extends from SAML Assertion.
066 *
067 * @supported.all.api
068 * @deprecated since 12.0.0
069 */
070@Deprecated
071public class FSAssertion extends Assertion {
072    
073    /**
074     * The Document Element of this object.
075     */
076    private Element domElement;
077    
078    /**
079     * The <code>SAMLConstants</code> object.
080     */
081    static SAMLConstants sc;
082    
083    /**
084     * The value of the <code>id</code> attribute in the <code>Assertion</code>.
085     */
086    protected String id;
087    
088    /**
089     * The value of the <code>MinorVersion</Version> attribute in
090     * the <code>Assertion</code>.
091     */
092    protected int minorVersion = IFSConstants.FF_11_ASSERTION_MINOR_VERSION;
093    
094    /**
095     * List of Security <code>Assertions</code>.
096     */
097    private List securityAssertions;
098    
099    /**
100     * The value of the <code>InResponseTo</code> attribute in the
101     * <code>Assertion</code>.
102     */
103    protected String inResponseTo ;
104    
105    /**
106     * Constructor to create an <code>FSAssertion</code> object
107     * from the Document Element.
108     *
109     * @param assertionElement the <code>Assertion</code> Document Element.
110     * @throws FSMsgException if the document element is null
111     *         or cannot be retrieved.
112     * @throws SAMLException if the SAML Assertion version is
113     *         incorrect
114     */
115    public FSAssertion(Element assertionElement )
116    throws FSMsgException, SAMLException {
117        FSUtils.debug.message("FSAssertion(Element):  Called");
118        Element elt = (Element) assertionElement;
119        String eltName = elt.getLocalName();
120        if (eltName == null)  {
121            if (FSUtils.debug.messageEnabled()) {
122                FSUtils.debug.message("FSAssertion: local name missing");
123            }
124            throw new FSMsgException("nullInput", null) ;
125        }
126        if (!(eltName.equals(IFSConstants.ASSERTION)))  {
127            if (FSUtils.debug.messageEnabled()) {
128                FSUtils.debug.message("FSAssertion: invalid root element");
129            }
130            String[] args = { eltName };
131            throw new FSMsgException("invalidElement" , args) ;
132        }
133        domElement = assertionElement;
134        id = elt.getAttribute(IFSConstants.ID);
135        String read = elt.getAttribute(IFSConstants.MAJOR_VERSION);
136        if ((read == null) || (read.length() == 0)) {
137            if (FSUtils.debug.messageEnabled()) {
138                FSUtils.debug.message("FSAssertion: MajorVersion missing");
139            }
140            String[] args = { "MajorVersion" };
141            throw new FSMsgException("missingAttribute", args);
142        } else  {
143            int ver = 0;
144            try {
145                ver = Integer.parseInt(read);
146            } catch ( NumberFormatException ne ) {
147                FSUtils.debug.error("FSAssertion: invalid integer " +
148                        "in MajorVersion", ne);
149                throw new FSMsgException("invalidNumber",null);
150            }
151            if (ver != sc.ASSERTION_MAJOR_VERSION) {
152                if(ver < sc.ASSERTION_MAJOR_VERSION) {
153                    FSUtils.debug.error("FSAssertion: MajorVersion too low");
154                    throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME,
155                            "assertionVersionTooLow",null);
156                } else if (ver > sc.ASSERTION_MAJOR_VERSION) {
157                    FSUtils.debug.error("FSAssertion: MajorVersion too high");
158                    throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME,
159                            "assertionVersionTooHigh",null);
160                }
161            }
162        }
163        read = elt.getAttribute(IFSConstants.MINOR_VERSION);
164        if ((read == null) || (read.length() == 0)) {
165            FSUtils.debug.error("FSAssertion: MinorVersion missing");
166            String[] args = { "MinorVersion" };
167            throw new FSMsgException("missingAttribute",args);
168        } else  {
169            try {
170                minorVersion = Integer.parseInt(read);
171            } catch ( NumberFormatException ne ) {
172                FSUtils.debug.error(
173                        "FSAssertion: invalid integer in MinorVersion", ne);
174                throw new FSMsgException("invalidNumber",null);
175            }
176            if (minorVersion < IFSConstants.FF_11_ASSERTION_MINOR_VERSION) {
177                FSUtils.debug.error("FSAssertion: MinorVersion too low");
178                throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME,
179                        "assertionVersionTooLow",null);
180            } else if (minorVersion >
181                    IFSConstants.FF_12_POST_ASSERTION_MINOR_VERSION) {
182                FSUtils.debug.error("FSAssertion: MinorVersion too high");
183                throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME,
184                        "assertionMinorVersionTooHigh",null);
185            }
186        }
187        read = elt.getAttribute(IFSConstants.ASSERTION_ID);
188        if ((read == null) || (read.length() == 0)) {
189            if (FSUtils.debug.messageEnabled()) {
190                FSUtils.debug.message("FSAssertion: AssertionID missing");
191            }
192            String[] args = { IFSConstants.ASSERTION_ID };
193            throw new FSMsgException("missingAttribute",args);
194        } else {
195            setAssertionID(read);
196        }
197        read = elt.getAttribute(IFSConstants.ISSUER);
198        if ((read == null) || (read.length() == 0)) {
199            if (FSUtils.debug.messageEnabled()) {
200                FSUtils.debug.message("FSAssertion: Issuer missing");
201            }
202            String[] args = { IFSConstants.ISSUER };
203            throw new FSMsgException("missingAttribute",args);
204        } else {
205            setIssuer(read);
206        }
207        read = elt.getAttribute(IFSConstants.IN_RESPONSE_TO);
208        if ((read == null) || (read.length() == 0)) {
209            if (FSUtils.debug.messageEnabled())  {
210                FSUtils.debug.message("FSAssertion: InResponseTo missing");
211            }
212            String[] args = { IFSConstants.IN_RESPONSE_TO };
213            throw new FSMsgException("missingAttribute",args);
214        } else  {
215            inResponseTo = read;
216        }
217        read = elt.getAttribute(IFSConstants.ISSUE_INSTANT);
218        if ((read == null) || (read.length() == 0)) {
219            if (FSUtils.debug.messageEnabled())  {
220                FSUtils.debug.message("FSAssertion: IssueInstant missing");
221            }
222            String[] args = { IFSConstants.ISSUE_INSTANT };
223            throw new FSMsgException("missingAttribute",args);
224        } else  {
225            try {
226                setIssueInstant(DateUtils.stringToDate(read));
227            } catch (ParseException pe) {
228                FSUtils.debug.message(
229                        "FSAssertion: could not parse IssueInstant", pe);
230                throw new FSMsgException("wrongInput",null);
231            }
232        }
233        boolean statementFound = false;
234        NodeList nl = assertionElement.getChildNodes();
235        int length = nl.getLength();
236        for (int n=0; n<length; n++) {
237            Node child = (Node)nl.item(n);
238            if (child.getNodeType() != Node.ELEMENT_NODE) continue;
239            String childName = child.getLocalName();
240            if (childName.equals(IFSConstants.CONDITIONS)){
241                setConditions(new Conditions((Element)child));
242            } else if (childName.equals(IFSConstants.ADVICE)){
243                /**
244                 * The SAML Advice could not parse this advice as it does not
245                 * anything about Resource Access Statement. Hence commenting
246                 * the following and parsing in this assertion only. Currently
247                 * the FSAssertion does not have any advice element besides for
248                 * the credential.
249                 */
250                parseAdvice((Element)child);
251            } else if (childName.equals(IFSConstants.AUTHENTICATIONSTATEMENT)) {
252                addStatement(new FSAuthenticationStatement((Element)child));
253                statementFound=true;
254            } else if (childName.equals(IFSConstants.AUTHZDECISIONSTATEMENT)) {
255                addStatement(new AuthorizationDecisionStatement(
256                        (Element)child));
257                statementFound=true;
258            } else if (childName.equals(IFSConstants.ATTRIBUTESTATEMENT)) {
259                addStatement(new AttributeStatement((Element)child));
260                statementFound=true;
261            } else if (childName.equals(IFSConstants.SIGNATURE)) {
262                if (FSUtils.debug.messageEnabled()) {
263                    FSUtils.debug.message("FSAssertion: Signature found");
264                }
265            } else {
266                if (FSUtils.debug.messageEnabled()) {
267                    FSUtils.debug.message(
268                            "FSAssertion: invalid element in Assertion");
269                }
270                throw new FSMsgException("invalidElement", null);
271            }
272        }
273        //check for signature
274        List signs = XMLUtils.getElementsByTagNameNS1(assertionElement,
275                SAMLConstants.XMLSIG_NAMESPACE_URI,
276                SAMLConstants.XMLSIG_ELEMENT_NAME);
277        int signsSize = signs.size();
278        if (signsSize == 1) {
279            Element elem = (Element)signs.get(0);
280            setSignature(elem);
281            xmlString = XMLUtils.print(assertionElement);
282            signed = true;
283        } else if (signsSize != 0) {
284            if (FSUtils.debug.messageEnabled()) {
285                FSUtils.debug.message("FSAssertion(Element): included more than"
286                        + " one Signature element.");
287            }
288            throw new FSMsgException("moreElement", null);
289        }
290        //end check for signature
291        if (!statementFound) {
292            if (FSUtils.debug.messageEnabled()) {
293                FSUtils.debug.message("Assertion: mandatory statement missing");
294            }
295            throw new FSMsgException("missingStatement",null);
296        }
297        FSUtils.debug.message("FSAssertion(Element): leaving");
298    }
299    
300    /**
301     * Constructor to create <code>FSAssertion</code> object.
302     *
303     * @param assertionID the <code>AssertionID</code> element.
304     * @param issuer the <code>Issuer</code> element.
305     * @param issueInstant the <code>IssueInstant</code> element.
306     * @param statements the <code>Statement</code> elements.
307     *        List of statements that need to be added in assertion.
308     * @param inResponseTo value of <code>InResponseTo</code> attribute in the
309     *        assertion.
310     * @throws FSMsgException if the document element is null
311     *         or cannot be retrieved.
312     * @throws SAMLException if the SAML Assertion version is
313     *         incorrect.
314     */
315    public FSAssertion(String assertionID,String issuer,Date issueInstant,
316            Set statements,String inResponseTo)
317            throws FSMsgException, SAMLException {
318        super(assertionID, issuer, issueInstant, statements);
319        this.inResponseTo = inResponseTo;
320    }
321    
322    /**
323     * Constructor to create <code>FSAssertion</code> object.
324     *
325     * @param assertionID the <code>AssertionID</code> element.
326     * @param issuer the <code>Issuer</code> element.
327     * @param issueInstant the <code>IssueInstant</code> element.
328     * @param conditions the <code>Conditions</code> object.
329     * @param statements the <code>Statement</code> elements.
330     *        List of statements that need to be added in assertion.
331     * @param inResponseTo value of <code>InResponseTo</code> attribute in
332     *        the assertion.
333     * @throws FSMsgException if the document element is null
334     *         or cannot be retrieved.
335     * @throws SAMLException if the SAML Assertion version is
336     *         incorrect.
337     */
338    public FSAssertion(String assertionID,String issuer,Date issueInstant,
339            Conditions conditions,Set statements,String inResponseTo)
340            throws FSMsgException, SAMLException {
341        super(assertionID, issuer, issueInstant, conditions, statements);
342        this.inResponseTo = inResponseTo;
343    }
344    
345    /**
346     * Constructor to create an <code>FSAssertion</code> object.
347     *
348     * @param assertionID the <code>AssertionID</code> element.
349     * @param issuer the <code>Issuer</code> element.
350     * @param issueInstant the <code>IssueInstant</code> element.
351     * @param conditions the <code>Conditions</code> object.
352     * @param advice the <code>Advice</code> object.
353     * @param statements the <code>Statement</code> elements.
354     *        List of statements that need to be added in assertion.
355     * @param inResponseTo value of <code>InResponseTo</code> attribute
356     *        in the assertion.
357     * @throws FSMsgException if the document element is null
358     *         or cannot be retrieved.
359     * @throws SAMLException if the SAML Assertion version is
360     *         incorrect.
361     */
362    public FSAssertion(String assertionID,String issuer,Date issueInstant,
363            Conditions conditions,Advice advice,Set statements,
364            String inResponseTo)
365            throws FSMsgException, SAMLException {
366        super(assertionID, issuer, issueInstant,conditions, advice, statements);
367        this.inResponseTo = inResponseTo;
368    }
369    
370    /**
371     * Returns value of <code>id</code> attribute.
372     *
373     * @return value of <code>id</code> attribute.
374     * @see #setID(String)
375     */
376    public String getID(){
377        return id;
378    }
379    
380    /**
381     * Sets  value of <code>id<code> attribute.
382     *
383     * @param id value of <code>id</code> attribute.
384     * @see #getID
385     */
386    public void setID(String id){
387        this.id = id;
388    }
389    
390    /**
391     * Returns the <code>MinorVersion</code> attribute.
392     *
393     * @return the <code>MinorVersion</code> attribute.
394     * @see #setMinorVersion(int)
395     */
396    public int getMinorVersion() {
397        return minorVersion;
398    }
399    
400    /**
401     * Sets the <code>MinorVersion</code> attribute.
402     *
403     * @param version the <code>MinorVersion</code> attribute.
404     * @see #getMinorVersion
405     */
406    public void setMinorVersion(int version) {
407        minorVersion = version;
408    }
409    
410    /**
411     * Returns the Document Element for this object.
412     *
413     * @return the Document Element for this object.
414     */
415    public Element getDOMElement() {
416        return domElement;
417    }
418    
419    /**
420     * Returns the value of <code>InResponseTo</code> attribute.
421     *
422     * @return the value of <code>InResponseTo</code> attribute.
423     * @see #setInResponseTo(String)
424     */
425    public String getInResponseTo() {
426        return inResponseTo;
427    }
428    
429    /**
430     * Sets the value of <code>InResponseTo</code> attribute.
431     *
432     * @param inResponseTo value of <code>InResponseTo</code> attribute.
433     * @see #getInResponseTo
434     */
435    public void setInResponseTo(String inResponseTo) {
436        this.inResponseTo = inResponseTo;
437    }
438    
439    /**
440     * Returns Signed XML String.
441     *
442     * @return Signed XML String.
443     */
444    public String getSignedXMLString(){
445        return xmlString;
446    }
447    
448    /**
449     * Returns the <code>Signature</code> string.
450     *
451     * @return the <code>Signature</code> string.
452     */
453    public String getSignatureString(){
454        return signatureString;
455    }
456    
457    /**
458     * Checks validity of time in the assertion.
459     *
460     * @return true if time is valid otherwise false.
461     */
462    public boolean isTimeValid() {
463        boolean isTimeValid = true;
464        Conditions conditions = getConditions();
465        if (conditions != null)  {
466            isTimeValid = conditions.checkDateValidity(
467                    currentTimeMillis());
468        }
469        return isTimeValid;
470    }
471    
472    /**
473     * Adds the <code>Statement</code> object to the
474     * Statment's object Set.
475     *
476     * @param statement the <code>Statement</code> object.
477     * @return false if statement is null else true.
478     */
479    public boolean addStatement(Statement statement) {
480        boolean addedStmt = false;
481        if (statement != null) {
482            super.addStatement(statement);
483            addedStmt = true;
484        }
485        return addedStmt;
486    }
487    
488    /**
489     * Returns a <code>XML</code> String representation of this object.
490     *
491     * @return a String representation of this Object.
492     * @throws FSMsgException if there is an error creating
493     *         the <code>XML</code> string.
494     */
495    
496    public String toXMLString() throws FSMsgException {
497        return this.toXMLString(true, true);
498    }
499    
500    /**
501     * Returns a <code>XML</code> String representation of this object.
502     *
503     * @param includeNS determines whether or not the namespace qualifier is
504     *                prepended to the Element when converted
505     * @param declareNS determines whether or not the namespace is declared
506     *                within the Element.
507     * @return a string containing the valid <code>XML</code> for this object.
508     * @throws FSMsgException if there is an error creating
509     *         the <code>XML</code> string.
510     */
511    
512    public java.lang.String toXMLString(boolean includeNS,boolean declareNS)
513    throws FSMsgException {
514        StringBuffer xml = new StringBuffer(3000);
515        String NS="";
516        String appendNS="";
517        String libNS="";
518        String libAppendNS="";
519        String uriXSI="";
520        if (declareNS) {
521            NS=sc.assertionDeclareStr;
522            if(minorVersion == IFSConstants.FF_12_POST_ASSERTION_MINOR_VERSION
523                    || minorVersion ==
524                    IFSConstants.FF_12_ART_ASSERTION_MINOR_VERSION) {
525                libNS = IFSConstants.LIB_12_NAMESPACE_STRING;
526            } else {
527                libNS = IFSConstants.LIB_NAMESPACE_STRING;
528            }
529            uriXSI = IFSConstants.XSI_NAMESPACE_STRING;
530        }
531        if (includeNS) {
532            appendNS= SAMLConstants.ASSERTION_PREFIX;
533            libAppendNS = IFSConstants.LIB_PREFIX;
534        }
535        String dateStr = null;
536        if (getIssueInstant() != null)  {
537            dateStr = DateUtils.toUTCDateFormat(getIssueInstant());
538        }
539        xml.append(IFSConstants.LEFT_ANGLE)
540        .append(appendNS).append(IFSConstants.ASSERTION)
541        .append(IFSConstants.SPACE)
542        .append(NS).append(IFSConstants.SPACE).append(uriXSI)
543        .append(IFSConstants.SPACE).append(libNS)
544        .append(IFSConstants.SPACE);
545        
546        if (minorVersion == IFSConstants.FF_11_ASSERTION_MINOR_VERSION &&
547                id != null && !(id.length() == 0)) {
548            xml.append(IFSConstants.SPACE).append(IFSConstants.ID)
549            .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
550            .append(id).append(IFSConstants.QUOTE)
551            .append(IFSConstants.SPACE);
552        }
553        xml.append(IFSConstants.MAJOR_VERSION)
554        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
555        .append(getMajorVersion()).append(IFSConstants.QUOTE)
556        .append(IFSConstants.SPACE).append(IFSConstants.MINOR_VERSION)
557        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
558        .append(minorVersion).append(IFSConstants.QUOTE)
559        .append(IFSConstants.SPACE).append(IFSConstants.ASSERTION_ID)
560        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
561        .append(getAssertionID()).append(IFSConstants.QUOTE)
562        .append(IFSConstants.SPACE).append(IFSConstants.ISSUER)
563        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
564        .append(getIssuer()).append(IFSConstants.QUOTE)
565        .append(IFSConstants.SPACE).append(IFSConstants.ISSUE_INSTANT)
566        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
567        .append(dateStr).append(IFSConstants.QUOTE)
568        .append(IFSConstants.SPACE).append(IFSConstants.IN_RESPONSE_TO)
569        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
570        .append(inResponseTo).append(IFSConstants.QUOTE)
571        .append(IFSConstants.SPACE)
572        .append(IFSConstants.XSI_TYPE)
573        .append(IFSConstants.EQUAL_TO).append(IFSConstants.QUOTE)
574        .append(libAppendNS)
575        .append(IFSConstants.ASSERTION_TYPE).append(IFSConstants.QUOTE)
576        .append(IFSConstants.RIGHT_ANGLE).append(sc.NL);
577        
578        if (getConditions() != null) {
579            xml.append(getConditions().toString(includeNS, false));
580        }
581        if (getAdvice() != null) {
582            xml.append(getAdvice().toString(includeNS, false));
583        }
584        
585        Iterator i = getStatement().iterator();
586        while (i.hasNext()) {
587            Statement st = (Statement)i.next();
588            if(st instanceof FSAuthenticationStatement){
589                xml.append(((FSAuthenticationStatement)st).toXMLString(
590                        includeNS, false));
591            } else if(st instanceof AttributeStatement) {
592                xml.append(((AttributeStatement)st).toString(includeNS, false));
593            }
594        }
595        if (signed) {
596            if (signatureString != null) {
597                xml.append(signatureString);
598            } else if (signature != null) {
599                signatureString = XMLUtils.print(signature);
600                xml.append(signatureString);
601            }
602        }
603        xml.append(IFSConstants.START_END_ELEMENT)
604        .append(appendNS).append(IFSConstants.ASSERTION)
605        .append(IFSConstants.RIGHT_ANGLE)
606        .append(IFSConstants.NL);
607        
608        return xml.toString();
609    }
610    
611    /**
612     * Signs the <code>Assertion</code>.
613     *
614     * @param certAlias the alias/name of the certificate.
615     * @throws SAMLException if <code>FSAssertion</code>
616     *            cannot be signed.
617     */
618    public void signXML(String certAlias) throws SAMLException {
619        FSUtils.debug.message("FSAssertion.signXML: Called");
620        if (signed) {
621            if (FSUtils.debug.messageEnabled()) {
622                FSUtils.debug.message("FSAssertion.signXML: the assertion is "
623                        + "already signed.");
624            }
625            throw new SAMLResponderException(
626                    FSUtils.BUNDLE_NAME,"alreadySigned",null);
627        }
628        if (certAlias == null || certAlias.length() == 0) {
629            throw new SAMLResponderException(FSUtils.BUNDLE_NAME,
630                    "cannotFindCertAlias",null);
631        }
632        
633        try {
634            XMLSignatureManager manager = XMLSignatureManager.getInstance();
635            if (minorVersion == IFSConstants.FF_11_ASSERTION_MINOR_VERSION) {
636                signatureString = manager.signXML(this.toXMLString(true, true),
637                        certAlias, (String) null,
638                        IFSConstants.ID, this.id,
639                        false);
640            } else if (minorVersion ==
641                    IFSConstants.FF_12_POST_ASSERTION_MINOR_VERSION
642                    || minorVersion ==
643                    IFSConstants.FF_12_ART_ASSERTION_MINOR_VERSION) {
644                signatureString =
645                        manager.signXML(this.toXMLString(true, true),
646                        certAlias, (String) null,
647                        IFSConstants.ASSERTION_ID,
648                        this.getAssertionID(), false);
649            } else {
650                if (FSUtils.debug.messageEnabled()) {
651                    FSUtils.debug.message("invalid minor version.");
652                }
653            }
654            signature = XMLUtils.toDOMDocument(signatureString, FSUtils.debug)
655            .getDocumentElement();
656            signed = true;
657            xmlString = this.toXMLString(true, true);
658        } catch(Exception e){
659            FSUtils.debug.message(" Exception :" + e.getMessage());
660            throw new SAMLResponderException(e);
661        }
662    }
663    
664    /**
665     * Sets the <code>Element's</code> signature.
666     *
667     * @param elem the <code>Element</code> object
668     * @return true if signature is set otherwise false
669     */
670    public boolean setSignature(Element elem) {
671        signatureString = XMLUtils.print(elem);
672        return super.setSignature(elem);
673    }
674    
675    /**
676     * Parses the advice element to extract the Security <code>Assertion</code>.
677     *
678     * @param element the <code>Advice</code> Element.
679     */
680    public void parseAdvice(Element element) {
681        NodeList nl = element.getChildNodes();
682        int length = nl.getLength();
683        for (int n=0; n<length; n++) {
684            Node child = (Node)nl.item(n);
685            if (child.getNodeType() != Node.ELEMENT_NODE) {
686                continue;
687            }
688            String childName = child.getLocalName();
689            if (childName.equals("Assertion")) {
690                try {
691                    if (securityAssertions == null) {
692                        securityAssertions = new ArrayList();
693                    }
694                    securityAssertions.add(
695                            new SecurityAssertion((Element)child));
696                } catch (Exception ex) {
697                    FSUtils.debug.error("FSAssertion.parseAdvice: Error in" +
698                            "parsing security assertion", ex);
699                }
700            }
701        }
702        if ((securityAssertions != null) && (!securityAssertions.isEmpty())) {
703            _advice = new Advice(null, securityAssertions, null);
704        }
705    }
706    
707    /**
708     * Returns the discovery service credentials from the boot strap.
709     *
710     * @return the discovery service credentials from the boot strap.
711     */
712    public List getDiscoveryCredential() {
713        return securityAssertions;
714    }
715}