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: AssertionBase.java,v 1.2 2008/06/25 05:47:31 qcheng Exp $
026 *
027 * Portions Copyrighted 2016 ForgeRock AS.
028 */
029
030  
031package com.sun.identity.saml.assertion;
032
033import static org.forgerock.openam.utils.Time.*;
034
035import com.sun.identity.shared.DateUtils;
036import com.sun.identity.saml.common.SAMLUtilsCommon;
037import com.sun.identity.saml.common.SAMLConstants;
038import com.sun.identity.saml.common.SAMLException;
039import com.sun.identity.saml.common.SAMLRequesterException;
040import com.sun.identity.saml.common.SAMLVersionMismatchException;
041import com.sun.identity.shared.xml.XMLUtils;
042import java.util.Set;
043import java.util.List;
044import java.util.Collections;
045import java.util.Iterator;
046import java.util.Date;
047import java.util.HashSet;
048import java.text.ParseException;
049import org.w3c.dom.Node;
050import org.w3c.dom.NodeList;
051import org.w3c.dom.Element;
052
053/**
054 *This object stands for <code>Assertion</code> element.An Assertion is a 
055 *package of information that supplies one or more <code>Statement</code> made 
056 *by an issuer. There are three kinds of assertionsL Authentication,  
057 *AuthorizationDecision and Attribute assertion.
058 *
059 *This class is an abstract base class for all Assertion implementations and
060 *encapsulates common functionality.
061 *
062 *@supported.all.api
063 */
064public abstract class AssertionBase {           
065    protected static SAMLConstants sc;
066
067    /**
068    The statements variable is a HashSet of all the stataments in this assertion
069    in the defined sequence
070    */
071    protected Set _statements = Collections.synchronizedSet(new HashSet());
072 
073    /**
074    This value specifies the SAML major version. Each assertion MUST specify 
075    the SAML major version identifier.The identifier for this version of SAML 
076    is 1. 
077    */  
078    protected  int _majorVersion = sc.ASSERTION_MAJOR_VERSION;
079   
080    /**
081    This value specifies the SAML minor version. Each assertion MUST specify 
082    the SAML minor version identifier. The identifier for this version of SAML 
083    is 0.
084    */
085    protected  int _minorVersion = sc.ASSERTION_MINOR_VERSION;
086   
087    /**
088    The _assertionID attribute specifies the assertion identifier.
089    */
090    protected AssertionIDReference _assertionID = null; 
091       
092    /**
093    The Issuer attribute specifies the issuer of the assertion by means of a 
094    string.
095    */
096    protected java.lang.String _issuer = null;
097    
098    /**
099    The IssueInstant attribute specifies the time instant of issue in Universal 
100    Coordinated Time.
101    */
102    protected java.util.Date _issueInstant;
103   
104    /**
105    The <code>Conditions</code> element specifies conditions that affect the 
106    validity of the asserted statement. 
107    */
108    protected Conditions _conditions;
109   
110    /**
111    The <code>Advice</code> element specifies additional information related 
112    to the assertion that may assist processing in certain situations but which 
113    can be ignored by applications that do not support its use. 
114    */
115    protected AdviceBase _advice;
116
117    protected String    xmlString       = null;
118    protected String    signatureString = null;
119    protected Element   signature       = null;
120    protected boolean   signed          = false;
121    protected boolean   valid           = true;
122    protected boolean   validationDone  = true; 
123
124    protected static final String ASSERTION_ID_ATTRIBUTE = "AssertionID";
125
126    /**
127     * Returns whether the object is signed or not.
128     * @return true if the object is signed; false otherwise.
129     */
130    public boolean isSigned() {
131        return signed;
132    }
133
134    /**
135     * Returns whether the signature on the object is valid or not.
136     * @return true if the signature on the object is valid; false otherwise.
137     */
138    public boolean isSignatureValid() {
139        return false;
140    }
141
142    /**
143     * Signs the Assertion.
144     * @exception SAMLException If it could not sign the Assertion.
145     */
146    public void signXML() throws SAMLException {
147        throw new UnsupportedOperationException();
148    }
149
150    /**
151     * Signs the Assertion.
152     *
153     * @param certAlias certification Alias used to sign Assertion.
154     * @exception SAMLException if it could not sign the Assertion.
155     */
156    public void signXML(String certAlias) throws SAMLException {
157        throw new UnsupportedOperationException();
158    }
159
160    /**
161     * Gets the Signature element of the Assertion.
162     * @return Element the Signature of the Assertion in DOM element.
163     */
164    public Element getSignature() {
165        return signature;
166    }
167    
168    /**
169     * Sets the signature for the Request 
170     * @param elem ds:Signature element
171     * @return A boolean value: true if the operation succeeds; false otherwise.
172     */
173    public boolean setSignature(Element elem) {
174        if (signed) {
175            return false;
176        }
177        if (elem == null) {
178            return false;
179        } else {
180            signature = elem;
181            signed = true;
182            signatureString = XMLUtils.print(elem); 
183            return true;
184        }
185    }
186
187    /**
188     * Creates appropriate Advice instance
189     * @param adviceElement the Advice Element
190     * @return the Advice instance
191     */
192    protected abstract AdviceBase createAdvice(Element adviceElement)
193        throws SAMLException;
194    
195    /**
196     * Create appropriate AuthorizationDecisionStatement instance
197     * @param authDecisionElement
198     *     the AuthorizationDecisionStatement Element
199     * @return AuthorizationDecisionStatement instance
200     */
201    protected abstract AuthorizationDecisionStatementBase
202        createAuthorizationDecisionStatement(Element authDecisionElement)
203        throws SAMLException;
204     
205    /**
206     * Creates appropriate AuthenticationStatement instance
207     * @param authenticationElement
208     *     the AuthenticationStatement Element
209     * @return AuthenticationStatement instance
210     */
211    protected abstract AuthenticationStatement
212        createAuthenticationStatement(Element authenticationElement)
213        throws SAMLException;
214     
215    /**
216     * Creates appropriate AttributeStatement instance
217     * @param attributeElement
218     *    the AttributeStatement Element
219     * @return AttributeStatement instance
220     */
221    protected abstract AttributeStatement
222        createAttributeStatement(Element attributeElement) throws SAMLException;
223
224    /**
225     * Creates appropriate AssertionIDReference instance
226     * @param assertionIDRefElement
227     *     the AssertionIDReference Element
228     * @return AssertionIDReference instance
229     */
230    protected abstract AssertionIDReference
231        createAssertionIDReference(Element assertionIDRefElement)
232        throws SAMLException;
233     
234    /**
235     * Creates appropriate AssertionIDReference instance
236     * @param assertionID
237     *     the AssertionID String
238     * @return AssertionIDReference instance
239     */
240    protected abstract AssertionIDReference
241        createAssertionIDReference(String assertionID) throws SAMLException;
242     
243    /**
244     * Creates appropriate Conditions instance
245     * @param conditionsElement
246     *     the Conditions Element
247     * @return Conditions instance
248     */
249    protected abstract Conditions
250        createConditions(Element conditionsElement) throws SAMLException;
251
252
253    /** 
254     *Default constructor, declaring protected to enable extensibility
255     */
256    protected AssertionBase() {}
257   
258    /**
259     * Contructor
260     * This constructor is used to build <code>Assertion</code> object from a
261     * block of existing XML that has already been built into a DOM.
262     *
263     * @param assertionElement A <code>org.w3c.dom.Element</code> representing 
264     *        DOM tree for <code>Assertion</code> object
265     * @exception SAMLException if it could not process the Element properly, 
266     *            implying that there is an error in the sender or in the
267     *            element definition.
268     */
269    public AssertionBase(org.w3c.dom.Element assertionElement) 
270        throws SAMLException 
271    {
272        Element elt = (Element) assertionElement;
273        String eltName = elt.getLocalName();
274        if (eltName == null)  {
275            if (SAMLUtilsCommon.debug.messageEnabled()) {
276                SAMLUtilsCommon.debug.message("Assertion: local name missing");
277            }
278            throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString
279                                        ("nullInput")) ;
280        }
281        if (!(eltName.equals("Assertion")))  {
282            if (SAMLUtilsCommon.debug.messageEnabled()) {
283                SAMLUtilsCommon.debug.message("Assertion: " +
284                                              "invalid root element");
285            }
286            throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString
287                ("invalidElement")+ ":"+eltName) ;   
288        }
289
290        String read = elt.getAttribute("Issuer");
291        if ((read == null) || (read.length() == 0)) {
292            if (SAMLUtilsCommon.debug.messageEnabled()) {
293                SAMLUtilsCommon.debug.message("Assertion: Issuer missing");
294            }
295            throw new SAMLRequesterException(
296                SAMLUtilsCommon.bundle.getString("missingAttribute") +
297                                                 ":Issuer");
298        } else  {
299            _issuer = read;
300        }
301
302        List signs = XMLUtils.getElementsByTagNameNS1(assertionElement,
303                                        SAMLConstants.XMLSIG_NAMESPACE_URI,
304                                        SAMLConstants.XMLSIG_ELEMENT_NAME);
305        int signsSize = signs.size();
306        if (signsSize == 1) {
307            // delay the signature validation till user call isSignatureValid()
308            xmlString = XMLUtils.print(assertionElement);
309            signed = true;
310            validationDone = false;
311        } else if (signsSize != 0) {
312            if (SAMLUtilsCommon.debug.messageEnabled()) {
313                SAMLUtilsCommon.debug.message("Assertion(Element): " +
314                     "included more than one Signature element.");
315            }
316            throw new SAMLRequesterException(
317                SAMLUtilsCommon.bundle.getString("moreElement"));
318        }
319
320        read = elt.getAttribute("MajorVersion");
321        if ((read == null) || (read.length() == 0)) {
322            if (SAMLUtilsCommon.debug.messageEnabled())  {
323                SAMLUtilsCommon.debug.message("Assertion: " +   
324                                              "MajorVersion missing");
325            }
326            throw new SAMLRequesterException(
327                    SAMLUtilsCommon.bundle.getString("missingAttribute")+":"+
328                        "MajorVersion");
329        }
330        else  {
331            int ver = 0;
332            try {
333                ver = Integer.parseInt(read);
334            } catch ( NumberFormatException ne ) {
335                SAMLUtilsCommon.debug.error(
336                        "Assertion: invalid integer in MajorVersion", ne);
337                throw new SAMLRequesterException(
338                        SAMLUtilsCommon.bundle.getString("invalidNumber")+":"+
339                        "MajorVersion");
340            }
341            if (ver != sc.ASSERTION_MAJOR_VERSION) {
342                if (ver < sc.ASSERTION_MAJOR_VERSION) {
343                    if (SAMLUtilsCommon.debug.messageEnabled())  {
344                        SAMLUtilsCommon.debug.message(
345                            "Assertion: MajorVersion too low");
346                    }
347                    throw new SAMLVersionMismatchException(
348                        SAMLUtilsCommon.bundle.getString(
349                        "assertionVersionTooLow")
350                        + ":"+"MajorVersion");
351                } else if (ver > sc.ASSERTION_MAJOR_VERSION) {
352                    if (SAMLUtilsCommon.debug.messageEnabled())  {
353                        SAMLUtilsCommon.debug.message(
354                            "Assertion: MajorVersion too high");
355                    }
356                    throw new SAMLVersionMismatchException(
357                        SAMLUtilsCommon.bundle.getString(
358                            "assertionVersionTooHigh")
359                            +":"+"MajorVersion");
360                } else {
361                    _minorVersion=Integer.parseInt(read);
362                }
363            }
364        }
365        read = elt.getAttribute("MinorVersion");
366        if ((read == null) || (read.length() == 0)) {
367            if (SAMLUtilsCommon.debug.messageEnabled()) 
368                SAMLUtilsCommon.debug.message(
369                    "Assertion: MinorVersion missing");
370            throw new SAMLRequesterException(
371                  SAMLUtilsCommon.bundle.getString("missingAttribute")
372                  +":"+"MinorVersion");
373        }
374        else  {
375            int ver = 0;
376            try {
377                ver = Integer.parseInt(read);
378            } catch ( NumberFormatException ne ) {
379                SAMLUtilsCommon.debug.error(
380                        "Assertion: invalid integer in MinorVersion", ne);
381                throw new SAMLRequesterException(
382                        SAMLUtilsCommon.bundle.getString("invalidNumber")
383                                    +":"+"MinorVersion");
384            }
385
386            if (ver < sc.ASSERTION_MINOR_VERSION_ZERO) {
387                if (SAMLUtilsCommon.debug.messageEnabled())  {
388                    SAMLUtilsCommon.debug.message(
389                        "Assertion: MinorVersion too low");
390                }
391                throw new SAMLVersionMismatchException(
392                        SAMLUtilsCommon.bundle.getString(
393                        "assertionVersionTooLow"));
394            } else if (ver > sc.ASSERTION_MINOR_VERSION_ONE) {
395                if (SAMLUtilsCommon.debug.messageEnabled())  {
396                    SAMLUtilsCommon.debug.message(
397                    "Assertion: MinorVersion too high");
398                }
399                throw new SAMLVersionMismatchException(
400                     SAMLUtilsCommon.bundle.getString("assertionVersionTooHigh")
401                     +":"+"MinorVersion");
402            } else {
403                _minorVersion=ver;
404            }
405        }
406        read = elt.getAttribute("AssertionID");
407        if ((read == null) || (read.length() == 0)) {
408            if (SAMLUtilsCommon.debug.messageEnabled()) 
409                SAMLUtilsCommon.debug.message("Assertion: AssertionID missing");
410            throw new SAMLRequesterException(
411                SAMLUtilsCommon.bundle.getString("missingAttribute")
412                +":"+"AssertionID");
413        }
414        else  {
415            _assertionID = createAssertionIDReference(read);
416        }
417
418        read = elt.getAttribute("IssueInstant");
419        if ((read == null) || (read.length() == 0)) {
420            if (SAMLUtilsCommon.debug.messageEnabled())  {
421                SAMLUtilsCommon.debug.message(
422                "Assertion: IssueInstant missing");
423            }
424            throw new SAMLRequesterException(
425                SAMLUtilsCommon.bundle.getString("missingAttribute")
426                +":"+"IssueInstant");
427        }
428        else  {
429            try {
430                _issueInstant = DateUtils.stringToDate(read);
431            } catch (ParseException pe) {
432                if (SAMLUtilsCommon.debug.messageEnabled()) 
433                    SAMLUtilsCommon.debug.message(
434                    "Assertion: could not parse IssueInstant", pe);
435               throw new SAMLRequesterException(
436                    SAMLUtilsCommon.bundle.getString(
437                    "wrongInput") + " " + pe.getMessage());
438            }
439        }
440        boolean statementFound = false;
441        NodeList nl = assertionElement.getChildNodes();
442        int length = nl.getLength();
443        for (int n=0; n<length; n++) {
444            Node child = (Node)nl.item(n);
445            if (child.getNodeType() != Node.ELEMENT_NODE) continue;
446            String childName = child.getLocalName();
447            if (childName.equals("Conditions"))
448                _conditions = createConditions((Element)child);
449            else if (childName.equals("Advice"))
450                _advice = createAdvice((Element)child);
451            else if (childName.equals("AuthenticationStatement")) {
452                _statements.add(createAuthenticationStatement((Element)child));
453                statementFound=true;
454            }
455            else if (childName.equals("AuthorizationDecisionStatement")) {
456                _statements.add(createAuthorizationDecisionStatement(
457                        (Element)child));
458                statementFound=true;
459            }
460            else if (childName.equals("AttributeStatement")) {
461                _statements.add(createAttributeStatement((Element)child));
462                statementFound=true;
463            }
464            else if (childName.equals("Signature")) {
465                signature = (Element) child;
466            }
467            else {
468                if (SAMLUtilsCommon.debug.messageEnabled()) {
469                    SAMLUtilsCommon.debug.message(
470                        "Assertion: invalid element in Assertion");
471                }
472                throw new SAMLRequesterException("invalidElement");
473            }
474        }
475        if (!statementFound) {
476            if (SAMLUtilsCommon.debug.messageEnabled()) {
477                SAMLUtilsCommon.debug.message(
478                    "Assertion: mandatory statement missing");
479            }
480            throw new SAMLRequesterException("missingStatement");
481        }
482            
483    } 
484   
485    /**
486     * Gets the validity of the assertion evaluating its conditions if
487     * specified.
488     *
489     * @return false if conditions is invalid based on it lying between
490     *         <code>NotBefore</code> (current time inclusive) and
491     *         <code>NotOnOrAfter</code> (current time exclusive) values 
492     *         and true otherwise or if no conditions specified.
493     */
494    public boolean isTimeValid() {
495        if (_conditions == null)  {
496            return true;
497        }
498        else  {
499            
500            return _conditions.checkDateValidity(currentTimeMillis());
501        }
502    }
503 
504    /**
505     *Contructor
506     *This constructor is used to populate the data members:
507     * <code>assertionID</code>, the issuer, time when assertion issued and a
508     * set of <code>Statement</code>(s) in the assertion.
509     *
510     * @param assertionID <code>assertionID</code> attribute contained within
511     *        this <code>Assertion</code> if null, an <code>assertionID</code>
512     *        is generated internally.
513     * @param issuer The issuer of this assertion.
514     * @param issueInstant time instant of the issue. It has type
515     *        <code>dateTime</code> which is built in to the W3C XML Schema
516     *        Types specification.if null, current time is used.
517     * @param statements set of <code>Statement</code> objects within this 
518     *        <code>Assertion</code>. It could be of type
519     *        <code>AuthenticationStatement</code>, 
520     *        <code>AuthorizationDecisionStatement</code> and
521     *        <code>AttributeStatement</code>. Each Assertion can have multiple
522     *        type of statements in it.
523     * @exception SAMLException if there is an error in processing input.
524     */
525    public AssertionBase(String assertionID,java.lang.String issuer, 
526        Date issueInstant,  Set statements) throws SAMLException
527    {
528        if ((issuer == null) || (issuer.length() == 0)) {
529            if (SAMLUtilsCommon.debug.messageEnabled())  {
530                SAMLUtilsCommon.debug.message(
531                "Assertion:  null input specified");
532            }
533            throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString(
534                "nullInput")) ;   
535        }
536        if (statements.size() == 0 ) {
537            if (SAMLUtilsCommon.debug.messageEnabled())  {
538                SAMLUtilsCommon.debug.message("Assertion:mandatory statement"
539                    + " missing");
540            }
541            throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString(
542                "missingStatement")) ;   
543        } else {
544            _statements.addAll(statements);
545        }
546        _assertionID = createAssertionIDReference(assertionID);
547        if (issuer != null) {
548            _issuer = issuer;
549        }
550        if (issueInstant != null)  {
551            _issueInstant = issueInstant;
552        }
553        else {
554            _issueInstant = newDate();
555        }
556    }
557
558    /**
559     * This constructor is used to populate the data members: the
560     * <code>assertionID</code>, the issuer, time when assertion issued, the 
561     * conditions when creating a new assertion and a set of
562     * <code>Statement</code>(s) in the assertion.
563     *
564     * @param assertionID <code>AssertionID</code> contained within this 
565     *        <code>Assertion</code> if null its generated internally.
566     * @param issuer The issuer of this assertion.
567     * @param issueInstant time instant of the issue. It has type
568     *        <code>dateTime</code> which is built in to the W3C XML Schema
569     *        Types specification. if null, current time is used.
570     * @param conditions <code>Conditions</code> under which the this 
571     *        <code>Assertion</code> is valid.
572     * @param statements Set of <code>Statement</code> objects within this 
573     *        <code>Assertion</code>. It could be of type
574     *        <code>AuthenticationStatement</code>,
575     *        <code>AuthorizationDecisionStatement</code> and 
576     *        <code>AttributeStatement</code>. Each Assertion can have multiple
577     *        type of statements in it.
578     * @exception SAMLException if there is an error in processing input.
579     */
580    public AssertionBase(String assertionID,java.lang.String issuer, 
581        Date issueInstant,  Conditions conditions, Set statements) 
582        throws SAMLException
583    {
584        if ((issuer == null) || (issuer.length() == 0) || (conditions == null))
585        {
586            if (SAMLUtilsCommon.debug.messageEnabled()) {
587                SAMLUtilsCommon.debug.message(
588                "Assertion:  null input specified");
589            }
590            throw new SAMLRequesterException(
591                SAMLUtilsCommon.bundle.getString("nullInput")) ;   
592        }
593        if (statements.size() == 0 ) {
594            if (SAMLUtilsCommon.debug.messageEnabled())  {
595                SAMLUtilsCommon.debug.message("Assertion:mandatory statement"
596                    + " missing");
597            }
598            throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString(
599                "missingStatement")) ;   
600        } else {
601            _statements.addAll(statements);
602        }
603        _assertionID = createAssertionIDReference(assertionID);
604        if (issuer != null)  {
605            _issuer = issuer;
606        }
607        if (issueInstant != null)  {
608            _issueInstant = issueInstant;
609        } else  {
610            _issueInstant = newDate();
611        }
612        if (conditions != null)  {
613            _conditions = conditions;
614        }
615    }
616   
617    /**
618     * This constructor is used to populate the data members: the 
619     * <code>ssertionID</code>, the issuer, time when assertion issued,
620     * the conditions when creating a new assertion , <code>Advice</code>
621     * applicable to this <code>Assertion</code> and a set of
622     * <code>Statement</code>(s) in the assertion.
623     *
624     * @param assertionID <code>AssertionID</code> object contained within this
625     *        <code>Assertion</code> if null its generated internally.
626     * @param issuer The issuer of this assertion.
627     * @param issueInstant Time instant of the issue. It has type
628     *        <code>dateTime</code> which is built in to the W3C XML Schema
629     *        Types specification. if null, current time is used.
630     * @param conditions <code>Conditions</code> under which the this 
631     *        <code>Assertion</code> is valid.
632     * @param advice <code>Advice</code> applicable for this
633     *        <code>Assertion</code>.
634     * @param statements Set of <code>Statement</code> objects within this 
635     *         <code>Assertion</code>. It could be of type
636     *         <code>AuthenticationStatement</code>,
637     *         <code>AuthorizationDecisionStatement</code> and 
638     *         <code>AttributeStatement</code>. Each Assertion can have
639     *         multiple type of statements in it.
640     * @exception SAMLException if there is an error in processing input.
641     */
642    public AssertionBase(String assertionID,java.lang.String issuer, 
643        Date issueInstant,  Conditions conditions, AdviceBase advice, 
644        Set statements) throws SAMLException
645    {
646        if ((issuer == null) || (issuer.length() == 0) || (conditions == null))
647        {
648            if (SAMLUtilsCommon.debug.messageEnabled()) {
649                SAMLUtilsCommon.debug.message(
650                "Assertion:  null input specified");
651            }
652            throw new SAMLRequesterException(
653                SAMLUtilsCommon.bundle.getString("nullInput")) ;   
654        }
655        if (statements.size() == 0 ) {
656            if (SAMLUtilsCommon.debug.messageEnabled())  {
657                SAMLUtilsCommon.debug.message("Assertion:mandatory statement"
658                    + " missing");
659            }
660            throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString(
661                "missingStatement")) ;   
662        } else {
663            _statements.addAll(statements);
664        }
665        _assertionID = createAssertionIDReference(assertionID);
666        if (issuer != null)  {
667            _issuer = issuer;
668        }
669        if (issueInstant != null)  {
670            _issueInstant = issueInstant;
671        } else  {
672            _issueInstant = newDate();
673        }
674        if (conditions != null)  {
675            _conditions = conditions;
676        }
677        if (advice != null)  {
678            _advice = advice;
679        }
680    }
681
682    /**
683     *Adds a statement to this <code>Assertion</code>
684     *@param statement <code>Statement</code> to be added
685     *@return boolean indicating success or failure of operation.
686     */
687    public boolean addStatement(Statement statement) {
688        if (signed) {
689            return false;
690        }
691        if (statement == null) {
692           return false;
693        }
694        _statements.add(statement);
695        return true;
696    }
697   
698    /**
699     *Set the time when the assertion was issued
700     *@param issueInstant : <code>java.util.Date</code> representing the time
701     *                      of the assertion 
702     *@return A boolean indicating the success of the operation.
703     */
704    protected boolean setIssueInstant(java.util.Date issueInstant) {
705        if (signed) {
706            return false;
707        }
708        if (issueInstant == null) {
709            return false;
710        }
711        _issueInstant = issueInstant;
712        return true; 
713    }
714      
715    /**
716     *Set the <code>AssertionID</code> for this assertion
717     *@param assertionID : a String representing id of this 
718     *                     assertion.
719     *@return A boolean indicating the success of the operation.
720     */
721    protected boolean setAssertionID(String assertionID) {
722        if (signed) {
723            return false;
724        }
725        if(assertionID == null) {
726            return false;
727        }
728        try {
729            _assertionID = createAssertionIDReference(assertionID);
730        } catch (Exception e ) {
731            if (SAMLUtilsCommon.debug.messageEnabled()) {
732                SAMLUtilsCommon.debug.message("Assertion: Exception in setting"
733                    + " assertion id: "+e.getMessage());
734            }
735            return false;
736        }
737        return true; 
738    }
739      
740    /**
741     *Sets the issuer for an assertion
742     *@param issuer : a string representing the issuer of the assertion 
743     *@return A boolean indicating the success of the operation.
744     */
745    protected boolean setIssuer(java.lang.String issuer) {
746        if (signed) {
747            return false;
748        }
749        if ((issuer == null) || (issuer.length() == 0)) {
750            return false;
751        }
752        _issuer = issuer;
753        return true; 
754    }
755      
756    /**
757     *Sets the advice for an assertion 
758     *@param advice : a linked list representing the advice information 
759     *@return A boolean indicating the success of the operation.
760     */
761    public boolean setAdvice(AdviceBase advice) {
762        if (signed) {
763            return false;
764        }
765        if (advice == null)  {
766            return false;
767        }
768        _advice = advice;
769        return true; 
770    }
771       
772    /**
773     *Sets the Conditions information for an assertion 
774     *@param conditions a linked list representing the conditions information 
775     *@return A boolean indicating the success of the operation.
776     */                  
777    public boolean setConditions(Conditions  conditions) {
778        if (signed) {
779            return false;
780        }
781        if ( conditions == null)  {
782            return false;
783        }
784        _conditions = conditions;
785        return true; 
786    }                                                                    
787   
788    /**
789     * Returns the minor version number of an assertion.
790     *
791     * @return The minor version number of an assertion.
792     */
793    public int getMinorVersion() {
794        return _minorVersion; 
795    }
796    
797    /**
798     * Sets the minor version number of an assertion.
799     *
800     * @param minorVersion minor version.
801     */
802    public void setMinorVersion(int minorVersion) {
803        this._minorVersion = minorVersion; 
804    }
805    
806    /**
807     * Returns the major version number of an assertion.
808     *
809     * @return The major version number of an assertion. 
810     */
811    public int getMajorVersion() {
812        return _majorVersion; 
813    }
814   
815    /**
816     * Sets the major version number of an assertion.
817     *
818     * @param majorVersion major version.
819     */
820    public void setMajorVersion(int majorVersion) {
821        this._majorVersion = majorVersion; 
822    }
823    
824    /**                 
825     * Returns the time when the assertion was issued.
826     *
827     * @return The time in <code>java.util.Date</code> format.
828     */
829    public Date getIssueInstant() {
830        return _issueInstant; 
831    }
832   
833    /**
834     * Returns the issuer of an assertion.
835     *
836     * @return The issuer of an assertion. 
837    */
838    public java.lang.String getIssuer() {
839        return _issuer; 
840    }
841
842    /**
843     * Returns the assertion ID.
844     *
845     * @return Assertion ID of the assertion.
846     */
847    public String getAssertionID() {
848        return _assertionID.getAssertionIDReference();
849    }
850      
851    /**
852     * Returns the conditions of an assertion.
853     *
854     * @return <code>Conditions</code> object containing conditions for an
855     *          assertion being valid.
856    */
857    public Conditions getConditions() {
858        return _conditions; 
859    }
860
861   
862    /**
863     * Returns a set of <code>Statement</code> contained within this assertion.
864     *
865     * @return a set of <code>Statement</code> contained within this assertion. 
866     */
867    public Set getStatement() {
868        return _statements;
869    }
870
871    /**
872     * Returns a String representation of the element.
873     *
874     * @return A string containing the valid XML for this element
875     *         By default name space name is prepended to the element name
876     *         example <code>&lt;saml:Assertion&gt;</code>.
877     */
878    public java.lang.String toString() {
879        // call toString() with includeNS true by default and declareNS false
880        String xml = this.toString(true, false);
881        return xml;
882    }
883
884    /**
885     * Returns a String representation of the <code>&lt;Assertion&gt;</code>
886     * element.
887     *
888     * @param includeNS if true prepends all elements by their Namespace 
889     *        name example <code>&lt;saml:Assertion&gt;</code>
890     * @param declareNS if true includes the namespace within the generated
891     *        XML.
892     * @return The valid XML for this element
893     */
894    public java.lang.String toString(boolean includeNS, boolean declareNS) {
895        if (signed && (xmlString != null)) {
896            return xmlString;
897        }
898
899        StringBuffer xml = new StringBuffer(3000);
900        String NS="";
901        String appendNS="";
902        if (declareNS) {
903            NS=SAMLConstants.assertionDeclareStr;
904        }
905        if (includeNS) {
906            appendNS="saml:";
907        }
908        String dateStr = null;
909        if (_issueInstant != null)  {
910            dateStr = DateUtils.toUTCDateFormat(_issueInstant);         
911        }
912
913        xml.append("<").append(appendNS).append("Assertion").append(" ").
914            append(NS).append(" ").append("MajorVersion").append("=\"").
915            append(_majorVersion).append("\"").append(" ").
916            append("MinorVersion").append("=\"").append(_minorVersion).
917            append("\"").append(" ").append("AssertionID=\"").
918            append(_assertionID.getAssertionIDReference()).append("\"").
919            append(" ").append("Issuer").append("=\"").append(_issuer).
920            append("\"").append(" ").append("IssueInstant").append("=\"").
921            append(dateStr).append("\"").
922            append(" ").append(">").append(sc.NL);
923        if (_conditions != null) {
924            xml.append(_conditions.toString(includeNS, false));
925        }
926        if (_advice != null) {
927            xml.append(_advice.toString(includeNS, false));
928        }
929        Iterator i = getStatement().iterator();
930        while (i.hasNext()) {
931           Statement st = (Statement)i.next();
932           xml.append(st.toString(includeNS, false));
933        }
934        if (signed && (signatureString != null)) {
935            xml.append(signatureString);
936        }
937        String o = SAMLUtilsCommon.makeEndElementTagXML("Assertion", includeNS);
938        xml.append(o);
939        return xml.toString();
940    }
941
942}