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: Message.java,v 1.3 2008/06/25 05:47:22 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.liberty.ws.soapbinding; 
031
032import java.lang.Object;
033import java.io.InputStream;
034import java.io.ByteArrayInputStream;
035import java.io.ByteArrayOutputStream;
036import java.io.StringReader;
037
038import java.util.ArrayList;
039import java.util.Iterator;
040
041import java.security.cert.X509Certificate;
042import org.w3c.dom.Document;
043import org.w3c.dom.Element;
044import org.w3c.dom.Node;
045import org.w3c.dom.NodeList;
046
047import java.util.List;
048import javax.xml.soap.SOAPMessage;
049import javax.xml.bind.JAXBContext;
050import javax.xml.bind.JAXBException;
051import javax.xml.bind.Marshaller;
052import javax.xml.bind.Unmarshaller;
053import javax.xml.transform.stream.StreamSource;
054import com.sun.identity.liberty.ws.common.wsse.BinarySecurityToken;
055import com.sun.identity.liberty.ws.common.wsse.WSSEConstants;
056import com.sun.identity.liberty.ws.security.SecurityAssertion;
057import com.sun.identity.liberty.ws.security.SecurityUtils;
058import com.sun.identity.saml.common.SAMLConstants;
059import com.sun.identity.saml.common.SAMLException;
060import com.sun.identity.saml.common.SAMLUtils;
061import com.sun.identity.shared.xml.XMLUtils;
062
063/**
064 * The <code>Message</code> class is used by web service client and server to
065 * construct request or response. It will be sent over the SOAP connection.
066 * The <code>Message</code> contains SOAP headers and bodies. The SOAP binding
067 * defines the following headers: <code>CorrelationHeader</code>,
068 * <code>ProviderHeader</code>, <code>ConsentHeader</code>,
069 * <code>UsageDirectiveHeader</code>, <code>ProcessingContextHeader</code>
070 * and <code>ServiceInstanceUpdateHeader</code>.
071 * The first 2 are required and the others are optional.
072 * Signing is mandatory for <code>CorrelationHeader</code> and SOAP Body
073 * element which is the parent of the bodies. Other headers are optional,
074 * so each header needs to have a flag to specify whether it needs to be
075 * signed or not. For each header that needs to be signed, it must have an
076 * id attribute in the top element. The constuctor will take a SAML assertion
077 * or cert alias in order to sign.
078 * 
079 * @supported.all.api
080 */
081public class Message {
082
083    /**
084     * anonymous profile is specified.
085     */
086    public static final int ANONYMOUS  = 0;
087
088    /**
089     * X509 Token profile is specified.
090     */
091    public static final int X509_TOKEN = 1;
092
093    /**
094     * SAML Token profile is specified.
095     */
096    public static final int SAML_TOKEN = 2;
097
098    /**
099     * Bearer Token profile is specified.
100     */
101    public static final int BEARER_TOKEN = 3;
102
103    /**
104     * Authentication mechanism "urn:liberty:security:2003-08:null:null"
105     */
106    public static final String NULL_NULL =
107                       "urn:liberty:security:2003-08:null:null";
108
109    /**
110     * Authentication mechanism "urn:liberty:security:2003-08:null:X509"
111     */
112    public static final String NULL_X509 =
113                       "urn:liberty:security:2003-08:null:X509";
114
115    /**
116     * Authentication mechanism "urn:liberty:security:2003-08:null:SAML"
117     */
118    public static final String NULL_SAML =
119                       "urn:liberty:security:2003-08:null:SAML";
120
121    /**
122     * Authentication mechanism "urn:liberty:security:2004-04:null:Bearer"
123     */
124    public static final String NULL_BEARER =
125                       "urn:liberty:security:2004-04:null:Bearer";
126
127    /**
128     * Authentication mechanism "urn:liberty:security:2003-08:TLS:null"
129     */
130    public static final String TLS_NULL =
131                       "urn:liberty:security:2003-08:TLS:null";
132
133    /**
134     * Authentication mechanism "urn:liberty:security:2003-08:TLS:X509"
135     */
136    public static final String TLS_X509 =
137                       "urn:liberty:security:2003-08:TLS:X509";
138
139    /**
140     * Authentication mechanism "urn:liberty:security:2003-08:TLS:SAML"
141     */
142    public static final String TLS_SAML =
143                       "urn:liberty:security:2003-08:TLS:SAML";
144
145    /**
146     * Authentication mechanism "urn:liberty:security:2004-04:TLS:Bearer"
147     */
148    public static final String TLS_BEARER =
149                       "urn:liberty:security:2004-04:TLS:Bearer";
150
151    /**
152     * Authentication mechanism "urn:liberty:security:2003-08:ClientTLS:null"
153     */
154    public static final String CLIENT_TLS_NULL =
155                       "urn:liberty:security:2003-08:ClientTLS:null";
156
157    /**
158     * Authentication mechanism "urn:liberty:security:2003-08:ClientTLS:X509"
159     */
160    public static final String CLIENT_TLS_X509 =
161                       "urn:liberty:security:2003-08:ClientTLS:X509";
162
163    /**
164     * Authentication mechanism "urn:liberty:security:2003-08:ClientTLS:SAML"
165     */
166    public static final String CLIENT_TLS_SAML =
167                       "urn:liberty:security:2003-08:ClientTLS:SAML";
168
169    /**
170     * Authentication mechanism "urn:liberty:security:2004-04:ClientTLS:Bearer"
171     */
172    public static final String CLIENT_TLS_BEARER =
173                       "urn:liberty:security:2004-04:ClientTLS:Bearer";
174
175    /**
176     * Authentication mechanism "urn:liberty:security:2005-02:null:X509"
177     */
178    public static final String NULL_X509_WSF11 =
179                       "urn:liberty:security:2005-02:null:X509";
180
181    /**
182     * Authentication mechanism "urn:liberty:security:2005-02:TLS:X509"
183     */
184    public static final String TLS_X509_WSF11 =
185                       "urn:liberty:security:2005-02:TLS:X509";
186
187    /**
188     * Authentication mechanism "urn:liberty:security:2005-02:ClientTLS:X509"
189     */
190    public static final String CLIENT_TLS_X509_WSF11 =
191                       "urn:liberty:security:2005-02:ClientTLS:X509";
192
193    /**
194     * Authentication mechanism "urn:liberty:security:2005-02:null:SAML"
195     */
196    public static final String NULL_SAML_WSF11 =
197                       "urn:liberty:security:2005-02:null:SAML";
198
199    /**
200     * Authentication mechanism "urn:liberty:security:2005-02:TLS:SAML"
201     */
202    public static final String TLS_SAML_WSF11 =
203                       "urn:liberty:security:2005-02:TLS:SAML";
204
205    /**
206     * Authentication mechanism "urn:liberty:security:2005-02:ClientTLS:SAML"
207     */
208    public static final String CLIENT_TLS_SAML_WSF11 =
209                       "urn:liberty:security:2005-02:ClientTLS:SAML";
210
211
212    /**
213     * Authentication mechanism "urn:liberty:security:2005-02:null:Bearer"
214     */
215    public static final String NULL_BEARER_WSF11 =
216                       "urn:liberty:security:2005-02:null:Bearer";
217
218    /**
219     * Authentication mechanism "urn:liberty:security:2005-02:TLS:Bearer"
220     */
221    public static final String TLS_BEARER_WSF11 =
222                       "urn:liberty:security:2005-02:TLS:Bearer";
223
224    /**
225     * Authentication mechanism "urn:liberty:security:2005-02:ClientTLS:Bearer"
226     */
227    public static final String CLIENT_TLS_BEARER_WSF11 =
228                       "urn:liberty:security:2005-02:ClientTLS:Bearer";
229
230    private int securityProfileType = ANONYMOUS;
231    private CorrelationHeader correlationHeader = null;
232    private ConsentHeader consentHeader = null;
233    private List usageDirectiveHeaders = null;
234    private ProviderHeader providerHeader = null;
235    private ProcessingContextHeader processingContextHeader = null;
236    private ServiceInstanceUpdateHeader serviceInstanceUpdateHeader = null;
237    private List soapHeaders = null;
238    private List soapBodies = null;
239    private List securityHeaders = null;
240    private List signingIds = null;
241    private SOAPFault soapFault = null;
242    private String ipAddress = null;
243    private String protocol = "http";
244    private SecurityAssertion assertion = null;
245    private BinarySecurityToken binarySecurityToken = null;
246    private X509Certificate certificate = null;
247    private X509Certificate messageCertificate = null;
248    private Object token = null;
249    private String bodyId = null;
250    private boolean clientAuthentication = false;
251    private String authenticationMechanism = null;
252    private Document doc = null;
253    private String wsfVersion = SOAPBindingConstants.WSF_11_VERSION;
254
255    /**
256     * Default Constructor.
257     */
258    public Message() {
259        correlationHeader = new CorrelationHeader();
260        securityProfileType = ANONYMOUS;
261    }
262
263    /**
264     * The default constructor uses default cert alias defined in AMConfig for
265     * signing.
266     *
267     * @param providerHeader <code>ProviderHeader</code>.
268     * @throws SOAPBindingException if provider header is null.
269     */
270    public Message(ProviderHeader providerHeader) throws SOAPBindingException {
271        correlationHeader = new CorrelationHeader();
272        this.providerHeader = providerHeader;
273        securityProfileType = ANONYMOUS;
274    }
275
276    /**
277     * This constructor takes a SAML assertion for signing.
278     *
279     * @param providerHeader <code>ProviderHeader</code>
280     * @param assertion a SAML assertion
281     * @throws SOAPBindingException if an error occurs while processing
282     *                                 the SAML assertion or the provider
283     *                                 header is null
284     */
285    public Message(ProviderHeader providerHeader,SecurityAssertion assertion)
286                   throws SOAPBindingException {
287        if (assertion == null) {
288            throw new SOAPBindingException(
289                    Utils.bundle.getString("SAMLAssertionNull"));
290        }
291        
292        this.assertion = assertion;
293        
294        if (assertion.isBearer()) {
295            securityProfileType = BEARER_TOKEN;
296        } else {
297            securityProfileType = SAML_TOKEN;
298            messageCertificate =
299                    (X509Certificate)SecurityUtils.getCertificate(assertion);
300        }
301        
302        correlationHeader = new CorrelationHeader();
303        this.providerHeader = providerHeader;
304    }
305
306    /**
307     * This constructor takes a binary security token for signing.
308     *
309     * @param providerHeader <code>ProviderHeader</code>
310     * @param token a binary security token
311     * @throws SOAPBindingException if an error occurs while processing
312     *                                 the token or the provider header is null
313     */
314    public Message(ProviderHeader providerHeader, BinarySecurityToken token)
315                   throws SOAPBindingException {
316        if (token == null) {
317            throw new SOAPBindingException(
318                    Utils.bundle.getString("binarySecurityTokenNull"));
319        }
320        binarySecurityToken = token;
321        wsfVersion = binarySecurityToken.getWSFVersion();
322        messageCertificate =
323            (X509Certificate)SecurityUtils.getCertificate(binarySecurityToken);
324        correlationHeader = new CorrelationHeader();
325        this.providerHeader = providerHeader;
326        securityProfileType = X509_TOKEN;
327    }
328
329    /**
330     * This constructor is to create a SOAP fault message.
331     *
332     * @param soapFault <code>SOAPFault</code>
333     */
334    public Message( SOAPFault soapFault) {
335        this.soapFault = soapFault;
336        correlationHeader = new CorrelationHeader();
337    }
338
339    /**
340     * This constructor takes an InputStream.
341     *
342     * @param inputStream an InputStream
343     * @throws SOAPBindingException if an error occurs while parsing the input.
344     */
345    public Message(InputStream inputStream) throws SOAPBindingException {
346        try {
347            doc = XMLUtils.toDOMDocument(inputStream, Utils.debug);
348            parseDocument(doc);
349        } catch (Exception ex) {
350            Utils.debug.error("Message:Message", ex);
351            throw new SOAPBindingException(ex.getMessage());
352        }
353    }
354
355    /**
356     * This constructor takes a SOAP message which is received from a SOAP
357     * connection.
358     *
359     * @param  soapMessage a SOAP message
360     * @throws SOAPBindingException if an error occurs while parsing the
361     *         SOAP message
362     */
363    public Message(SOAPMessage soapMessage)
364           throws SOAPBindingException,SOAPFaultException {
365        try {
366            ByteArrayOutputStream bop = new ByteArrayOutputStream();
367            soapMessage.writeTo(bop);
368            ByteArrayInputStream bin =
369                    new ByteArrayInputStream(bop.toByteArray());
370            doc = XMLUtils.toDOMDocument(bin, Utils.debug);
371            parseDocument(doc);
372        } catch (Exception ex) {
373            Utils.debug.error("Message:Message", ex);
374            throw new SOAPBindingException(ex.getMessage());
375        }
376    }
377
378    /**
379     * Gets security profile type. Possible values are ANONYMOUS, X509_TOKEN
380     * and SAML_TOKEN.
381     *
382     * @return the Security Profile type
383     */
384    public int getSecurityProfileType() {
385        return securityProfileType;
386    }
387
388    /**
389     * Sets security profile type. 
390     *
391     * @param profileType Profile Type. Possible values are ANONYMOUS,
392     *               X509_TOKEN , SAML_TOKEN and BEARER_TOKEN
393     */
394    public void setSecurityProfileType(int profileType) {
395        securityProfileType = profileType;
396    }
397
398    /**
399     * Sets a binary security token for this message.
400     *
401     * @param binaryToken a binary security token
402     */
403    public void setBinarySecurityToken(BinarySecurityToken binaryToken) {
404        binarySecurityToken = binaryToken;
405        messageCertificate = 
406            (X509Certificate)SecurityUtils.getCertificate(binarySecurityToken);
407    }
408
409    /**
410     * Gets authentication mechanism. 
411     * Possible values are NULL_NULL,NULL_X509, NULL_SAML, TLS_NULL,
412     * TLS_X509, TLS_SAML, CLIENT_TLS_NULL,CLIENT_TLS_X509, CLIENT_TLS_SAML, 
413     * NULL_BEAER, TLS_BEARER, and CLIENT_TLS_BEARER.
414     *
415     * @return an authentication mechanism
416     */
417    public String getAuthenticationMechanism() {
418        if (authenticationMechanism != null) {
419            return authenticationMechanism;
420        }
421
422        if (protocol.equalsIgnoreCase("https")) {
423            if (certificate == null) {
424                switch (securityProfileType) {
425                    case X509_TOKEN:
426                        if(SOAPBindingConstants.WSF_11_VERSION.equals(
427                                                wsfVersion)) {
428                           authenticationMechanism = TLS_X509_WSF11;
429                        } else {
430                           authenticationMechanism = TLS_X509;
431                        }
432                        return authenticationMechanism;
433                    case SAML_TOKEN:
434                        if(SOAPBindingConstants.WSF_11_VERSION.equals(
435                                                wsfVersion)) {
436                           authenticationMechanism = TLS_SAML_WSF11;
437                        } else {
438                           authenticationMechanism = TLS_SAML;
439                        }
440                        return authenticationMechanism;
441                    case BEARER_TOKEN:
442                        if(SOAPBindingConstants.WSF_11_VERSION.equals(
443                                                wsfVersion)) {
444                           authenticationMechanism = TLS_BEARER_WSF11;
445                        } else {
446                           authenticationMechanism = TLS_BEARER;
447                        }
448                        return authenticationMechanism;
449                    default:
450                        authenticationMechanism = TLS_NULL;
451                        return authenticationMechanism;
452                }
453            } else {
454                switch (securityProfileType) {
455                    case X509_TOKEN:
456                        if(SOAPBindingConstants.WSF_11_VERSION.equals(
457                                                wsfVersion)) {
458                           authenticationMechanism = CLIENT_TLS_X509_WSF11;
459                        } else {
460                           authenticationMechanism = CLIENT_TLS_X509;
461                        }
462                        return authenticationMechanism;
463                    case SAML_TOKEN:
464                        if(SOAPBindingConstants.WSF_11_VERSION.equals(
465                                                wsfVersion)) {
466                           authenticationMechanism = CLIENT_TLS_SAML_WSF11;
467                        } else {
468                           authenticationMechanism = CLIENT_TLS_SAML;
469                        }
470                        return authenticationMechanism;
471                    case BEARER_TOKEN:
472                        if(SOAPBindingConstants.WSF_11_VERSION.equals(
473                                                wsfVersion)) {
474                           authenticationMechanism = CLIENT_TLS_BEARER_WSF11;
475                        } else {
476                           authenticationMechanism = CLIENT_TLS_BEARER;
477                        }
478                        return authenticationMechanism;
479                    default:
480                        authenticationMechanism = CLIENT_TLS_NULL;
481                        return authenticationMechanism;
482                }
483            }
484        } else {
485            switch (securityProfileType) {
486                case X509_TOKEN:
487                    if(SOAPBindingConstants.WSF_11_VERSION.equals(
488                                            wsfVersion)) {
489                       authenticationMechanism = NULL_X509_WSF11;
490                    } else {
491                       authenticationMechanism = NULL_X509;
492                    }
493                    return authenticationMechanism;
494                case SAML_TOKEN:
495                    if(SOAPBindingConstants.WSF_11_VERSION.equals(
496                                            wsfVersion)) {
497                       authenticationMechanism = NULL_SAML_WSF11;
498                    } else {
499                       authenticationMechanism = NULL_SAML;
500                    }
501                    return authenticationMechanism;
502                case BEARER_TOKEN:
503                    if(SOAPBindingConstants.WSF_11_VERSION.equals(
504                                            wsfVersion)) {
505                       authenticationMechanism = NULL_BEARER_WSF11;
506                    } else {
507                       authenticationMechanism = NULL_BEARER;
508                    }
509                    return authenticationMechanism;
510                default:
511                    authenticationMechanism = NULL_NULL;
512                    return authenticationMechanism;
513            }
514        }
515    }
516
517    /**
518     * Returns a boolean flag to determine if this Message will be sent to
519     *         a server that requires client authentication.
520     *
521     * @return true if this Message will be sent to a server that
522     *         requires client authentication
523     */
524    public boolean isClientAuthentication() {
525        return clientAuthentication;
526    }
527
528    /**
529     * Returns the <code>CorrelationHeader</code>.
530     *
531     * @return the <code>CorrelationHeader</code>.
532     */
533    public CorrelationHeader getCorrelationHeader() {
534        return correlationHeader;
535    }
536
537    /**
538     * Returns the <code>ConsentHeader</code>.
539     *
540     * @return the <code>ConsentHeader</code>.
541     */
542    public ConsentHeader getConsentHeader() {
543        return consentHeader;
544    }
545
546    /**
547     * Returns a list of <code>UsageDirectiveHeader</code>.
548     *
549     * @return a list of <code>UsageDirectiveHeader</code>.
550     */
551    public List getUsageDirectiveHeaders() {
552        return usageDirectiveHeaders;
553    }
554
555    /**
556     * Returns the <code>ProviderHeader</code>.
557     *
558     * @return the <code>ProviderHeader</code>.
559     */
560    public ProviderHeader getProviderHeader() {
561        return providerHeader;
562    }
563
564    /**
565     * Returns the <code>ProcessingContextHeader</code>.
566     *
567     * @return the <code>ProcessingContextHeader</code>.
568     */
569    public ProcessingContextHeader getProcessingContextHeader() {
570        return processingContextHeader;
571    }
572
573    /**
574     * Returns the <code>ServiceInstanceUpdateHeader</code>.
575     *
576     * @return the <code>ServiceInstanceUpdateHeader</code>.
577     */
578    public ServiceInstanceUpdateHeader getServiceInstanceUpdateHeader() {
579        return serviceInstanceUpdateHeader;
580    }
581
582    /**
583     * Returns a list of SOAP headers except  <code>CorrelationHeader</code>,
584     * <code>ConsentHeader</code>, <code>UsageDirectiveHeader</code> and
585     * <code>Security</code> header. Each entry will be a 
586     * <code>org.w3c.dom.Element</code>.
587     *
588     * @return a list of SOAP headers
589     */
590    public List getOtherSOAPHeaders() {
591        return soapHeaders;
592    }
593
594    /**
595     * Returns the <code>SOAPFault</code>.
596     *
597     * @return the <code>SOAPFault</code>.
598     */
599    public SOAPFault getSOAPFault() {
600        return soapFault;
601    }
602
603    /**
604     * Returns a list of SOAP bodies.
605     * Each entry will be a <code>org.w3c.dom.Element</code>.
606     *
607     * @return a list of SOAP bodies
608     */
609    public List getBodies() {
610        return soapBodies;
611    }
612
613    /**
614     * Returns a list of SOAP bodies.
615     * Each entry will be a <code>org.w3c.dom.Element</code> with specified
616     * namespace URI and local name.
617     *
618     * @param namespaceURI namspace URI
619     * @param localName local name
620     * @return a list of SOAP bodies
621     */
622    public List getBodies( String namespaceURI, String localName) {
623        ArrayList bodies = new ArrayList();
624        if (soapBodies != null && !soapBodies.isEmpty()) {
625            Iterator iter = soapBodies.iterator();
626            while(iter.hasNext()) {
627                Element bodyE = (Element)iter.next();
628                String ln = bodyE.getLocalName();
629                String ns = bodyE.getNamespaceURI();
630                if (((ns == null && namespaceURI == null) ||
631                        (ns != null && ns.equals(namespaceURI))) &&
632                        ln.equals(localName)) {
633                    bodies.add(bodyE);
634                }
635            }
636        }
637        return soapBodies;
638    }
639
640    /**
641     * Returns a list of security header except the SAML assertion used in
642     * SAML token profile or the binary security token used in X509 token
643     * profile. Each entry will be a <code>org.w3c.dom.Element</code>.
644     *
645     * @return a list of security headers
646     */
647    public List getOtherSecurityHeaders() {
648        return securityHeaders;
649    }
650
651    /**
652     * Returns the SAML assertion used for signing.
653     *
654     * @return the SAML assertion.
655     */
656    public SecurityAssertion getAssertion() {
657        return assertion;
658    }
659
660    /**
661     * Returns a binary security token used for signing.
662     *
663     * @return a binary security token.
664     */
665    public BinarySecurityToken getBinarySecurityToken() {
666        return binarySecurityToken;
667    }
668
669    /**
670     * Returns the X509 certificate used in client authentication.
671     *
672     * @return a X509 certificate
673     */
674    public X509Certificate getPeerCertificate() {
675        return certificate;
676    }
677
678    /**
679     * Returns the X509 certificate used in message level authentication.
680     *
681     * @return a X509 certificate.
682     */
683    public X509Certificate getMessageCertificate() {
684        return messageCertificate;
685    }
686
687    /**
688     * Returns a token for the sender of this Message.
689     *
690     * @return a token Object.
691     */
692    public Object getToken() {
693        return token;
694    }
695
696    /**
697     * Returns the IP address of remote site of the SOAP connection.
698     *
699     * @return a IP address
700     */
701    public String getIPAddress() {
702        return ipAddress;
703    }
704
705    /**
706     * Returns a list of id's for signing.
707     *
708     * @return a list of id's for signing.
709     */
710    public List getSigningIds() {
711        List ids = new  ArrayList();
712        ids.add(correlationHeader.getId());
713        if (consentHeader != null) {
714            String id = consentHeader.getId();
715            if (id != null) {
716                ids.add(id);
717            }
718        }
719        if (usageDirectiveHeaders != null &&
720            !usageDirectiveHeaders.isEmpty()) {
721            Iterator iter = usageDirectiveHeaders.iterator();
722            while(iter.hasNext()) {
723                String id = ((UsageDirectiveHeader)iter.next()).getId();
724                if (id != null) {
725                    ids.add(id);
726                }
727            }
728        }
729        if (providerHeader != null) {
730            String id = providerHeader.getId();
731            if (id != null) {
732                ids.add(id);
733            }
734        }
735        if (processingContextHeader != null) {
736            String id = processingContextHeader.getId();
737            if (id != null) {
738                ids.add(id);
739            }
740        }
741        if (serviceInstanceUpdateHeader != null) {
742            String id = serviceInstanceUpdateHeader.getId();
743            if (id != null) {
744                ids.add(id);
745            }
746        }
747        if (signingIds != null && !signingIds.isEmpty()) {
748            ids.addAll(signingIds);
749        }
750        if (bodyId == null) {
751            bodyId = SAMLUtils.generateID();
752        }
753        ids.add(bodyId);
754        return ids;
755    }
756
757    /**
758     * Sets the <code>CorrelationHeader</code>.
759     *
760     * @param correlationHeader <code>CorrelationHeader</code>
761     */
762    public void setCorrelationHeader(CorrelationHeader correlationHeader) {
763        if (correlationHeader != null) {
764            this.correlationHeader = correlationHeader;
765        }
766    }
767
768    /**
769     * Sets <code>ConsentHeader</code>.
770     *
771     * @param consentHeader the <code>ConsentHeader</code>.
772     */
773    public void setConsentHeader(ConsentHeader consentHeader) {
774        this.consentHeader = consentHeader;
775    }
776
777    /**
778     * Sets a list of <code>UsageDirectiveHeader</code>.
779     *
780     * @param usageDirectiveHeaders a list of <code>UsageDirectiveHeader</code>.
781     */
782    public void setUsageDirectiveHeaders(List usageDirectiveHeaders) {
783        this.usageDirectiveHeaders = usageDirectiveHeaders;
784    }
785
786    /**
787     * Sets <code>ProviderHeader</code> if it is not null.
788     *
789     * @param providerHeader the <code>ProviderHeader</code>.
790     */
791    public void setProviderHeader(ProviderHeader providerHeader) {
792        this.providerHeader = providerHeader;
793    }
794
795    /**
796     * Sets the <code>ProcessingContextHeader</code>.
797     *
798     * @param processingContextHeader <code>ProcessingContextHeader</code>
799     */
800    public void setProcessingContextHeader(
801                  ProcessingContextHeader processingContextHeader) {
802        this.processingContextHeader = processingContextHeader;
803    }
804
805    /**
806     * Sets the <code>ServiceInstanceUpdateHeader</code>.
807     *
808     * @param serviceInstanceUpdateHeader
809     *        the <code>ServiceInstanceUpdateHeader</code>
810     */
811    public void setServiceInstanceUpdateHeader(
812               ServiceInstanceUpdateHeader serviceInstanceUpdateHeader) {
813        this.serviceInstanceUpdateHeader = serviceInstanceUpdateHeader;
814    }
815
816    /**
817     * Sets a list of SOAP headers except  <code>CorrelationHeader</code>,
818     * <code>ConsentHeader</code>, <code>UsageDirectiveHeader</code> and
819     * 'Security' header. Each entry will be a <code>org.w3c.dom.Element</code>.
820     *
821     * @param headers a list of SOAP headers.
822     * @param signingIds a list of values of <code>id</code> attribute for 
823     *        signing
824     */
825    public void setOtherSOAPHeaders(List headers, List signingIds) {
826        soapHeaders = headers;
827        this.signingIds = signingIds;
828    }
829
830    /**
831     * Sets a SOAP header except  <code>CorrelationHeader</code>,
832     * <code>ConsentHeader</code> and <code>UsageDirectiveHeader</code>.
833     *
834     * @param header a <code>org.w3c.dom.Element</code>
835     * @param signingId the value of <code>id</code> attribute for signing.
836     *        A value null value for this attribute is assumed as no signing.
837     */
838    public void setOtherSOAPHeader(Element header, String signingId) {
839        soapHeaders = new ArrayList(1);
840        soapHeaders.add(header);
841        if (signingId != null) {
842            signingIds = new ArrayList(1);
843            signingIds.add(signingId);
844        }
845    }
846
847    /**
848     * Sets a list of security headers.  Each entry will be a
849     * <code>org.w3c.dom.Element</code>.
850     *
851     * @param headers a list of security headers.
852     */
853    public void setOtherSecurityHeaders(List headers) {
854        securityHeaders = headers;
855    }
856
857    /**
858     * Sets a security header.
859     *
860     * @param header the security header element.
861     */
862    public void setOtherSecurityHeader(Element header) {
863        securityHeaders = new ArrayList(1);
864        securityHeaders.add(header);
865    }
866
867    /**
868     * Sets the <code>SOAPFault</code>.
869     *
870     * @param soapFault the <code>SOAPFault</code>.
871     */
872    public void setSOAPFault(SOAPFault soapFault) {
873        this.soapFault = soapFault;
874    }
875
876    /**
877     * Sets a list of SOAP bodies. Each entry will be a
878     * <code>org.w3c.dom.Element</code>. To send a SOAP Fault, please use
879     * method <code>setSOAPFault</code>.
880     *
881     * @param bodies a list of SOAP bodies.
882     */
883    public void setSOAPBodies(List bodies) {
884        soapBodies = bodies;
885    }
886
887    /**
888     * Sets a SOAP body. To send a SOAP Fault, please use method
889     * <code>setSOAPFault</code>.
890     *
891     * @param body a <code>org.w3c.dom.Element</code>
892     */
893    public void setSOAPBody(Element body) {
894        soapBodies = new ArrayList(1);
895        soapBodies.add(body);
896    }
897
898    /**
899     * Sets the IP address of remote site of the SOAP connection.
900     *
901     * @param ipAddress a IP address
902     */
903    void setIPAddress( String ipAddress) {
904        this.ipAddress = ipAddress;
905    }
906
907    /**
908     * Sets the protocol value . The expected
909     * value is either http or https.
910     *
911     * @param protocol the protocol value.
912     */
913    void setProtocol( String protocol) {
914        if (protocol == null) {
915            this.protocol = "http";
916        } else {
917            this.protocol = protocol;
918        }
919    }
920
921    /**
922     * Sets the X509 certificate used in client authentication.
923     *
924     * @param cert a X509 certificate
925     */
926    void setPeerCertificate(X509Certificate cert) {
927        certificate = cert;
928        clientAuthentication = (certificate != null);
929    }
930    
931    /**
932     * Sets a boolean flag. If the flag is true, this Message will be sent to
933     * a server that requires client authentication.
934     *
935     * @param clientAuthentication a boolean flag
936     */
937    public void setClientAuthentication( boolean clientAuthentication) {
938        this.clientAuthentication = clientAuthentication;
939    }
940
941    /**
942     * Sets a token for the sender of this Message. The accual type
943     * will be the same as the type of the Object retured from
944     * <code>WebServiceAuthenticator.authenticate</code>.
945     *
946     * @param Object a token Object
947     */
948    void setToken( Object token) {
949        this.token = token;
950    }
951
952    /**
953     * Returns the SOAP message in String format.
954     *
955     * @return the SOAP message in String format.
956     */
957    public String toString() {
958        try {
959            return XMLUtils.print(toDocument(true).getDocumentElement());
960        } catch (Exception ex) {
961            Utils.debug.error("Message.toString", ex);
962            return "";
963        }
964    }
965
966    /**
967     * Returns the SOAP message in <code>org.w3c.dom.Document</code> format.
968     *
969     * @return the SOAP message in <code>org.w3c.dom.Document</code> format.
970     * @throws SOAPBindingException if an error occurs while constructing
971     *                                 a document.
972     */
973    public Document toDocument() throws SOAPBindingException {
974        return toDocument(false);
975    }
976
977    /**
978     * Returns the SOAP message in <code>org.w3c.dom.Document</code> format.
979     *
980     * @param refresh true to reconstruct a document, false to reuse a
981     *                previous document. If previous document doesn't exist,
982     *                it will construct a new document.
983     * @return the SOAP message in <code>org.w3c.dom.Document</code> format.
984     * @throws SOAPBindingException if an error occurs while constructing
985     *                                 the <code>org.w3c.dom.Document</code>.
986     */
987    public Document toDocument( boolean refresh) throws SOAPBindingException {
988        if (!refresh && doc != null) {
989            return doc;
990        }
991
992        try {
993            doc = XMLUtils.newDocument();
994        } catch (Exception ex) {
995            Utils.debug.error("Message:toDocument", ex);
996            throw new SOAPBindingException(ex.getMessage());
997        }
998
999        String wsseNS = WSSEConstants.NS_WSSE_WSF11;
1000        String wsuNS = WSSEConstants.NS_WSU_WSF11;
1001        if(SOAPBindingConstants.WSF_10_VERSION.equals(wsfVersion)) {
1002           wsseNS = WSSEConstants.NS_WSSE;
1003           wsuNS = WSSEConstants.NS_WSU;
1004        }
1005
1006        Element envelopeE = doc.createElementNS(SOAPBindingConstants.NS_SOAP,
1007                                           SOAPBindingConstants.PTAG_ENVELOPE);
1008        envelopeE.setAttributeNS(SOAPBindingConstants.NS_XML,
1009                                 SOAPBindingConstants.XMLNS_SOAP,
1010                                 SOAPBindingConstants.NS_SOAP);
1011        envelopeE.setAttributeNS(SOAPBindingConstants.NS_XML,
1012                                 SOAPBindingConstants.XMLNS_SOAP_BINDING,
1013                                 SOAPBindingConstants.NS_SOAP_BINDING);
1014        envelopeE.setAttributeNS(SOAPBindingConstants.NS_XML,
1015                                 SOAPBindingConstants.XMLNS_SOAP_BINDING_11,
1016                                 SOAPBindingConstants.NS_SOAP_BINDING_11);
1017        envelopeE.setAttributeNS(SOAPBindingConstants.NS_XML,
1018                                 WSSEConstants.TAG_XML_WSU,
1019                                 wsuNS);
1020        doc.appendChild(envelopeE);
1021        Element headerE = doc.createElementNS(SOAPBindingConstants.NS_SOAP,
1022                                             SOAPBindingConstants.PTAG_HEADER);
1023        envelopeE.appendChild(headerE);
1024        if (correlationHeader != null) {
1025            correlationHeader.addToParent(headerE);
1026        }
1027        if (consentHeader != null) {
1028            consentHeader.addToParent(headerE);
1029        }
1030        if (usageDirectiveHeaders != null &&
1031            !usageDirectiveHeaders.isEmpty()) {
1032            Iterator iter = usageDirectiveHeaders.iterator();
1033            while(iter.hasNext()) {
1034                ((UsageDirectiveHeader)iter.next()).addToParent(headerE);
1035            }
1036        }
1037
1038        if (providerHeader != null) {
1039            providerHeader.addToParent(headerE);
1040        }
1041
1042        if (processingContextHeader != null) {
1043            processingContextHeader.addToParent(headerE);
1044        }
1045
1046        if (serviceInstanceUpdateHeader != null) {
1047            serviceInstanceUpdateHeader.addToParent(headerE);
1048        }
1049
1050        if (soapHeaders != null && !soapHeaders.isEmpty()) {
1051            if (Utils.debug.messageEnabled()) {
1052                Utils.debug.message("Message.toDocument: adding headers ");
1053            }
1054            Iterator iter = soapHeaders.iterator();
1055            while(iter.hasNext()) {
1056                Element soapHeaderE = (Element)iter.next();
1057                headerE.appendChild(doc.importNode(soapHeaderE, true));
1058            }
1059        }
1060
1061        boolean hasSecurityHeaders = 
1062                (securityHeaders != null && !securityHeaders.isEmpty());
1063        if (securityProfileType != ANONYMOUS || hasSecurityHeaders) {
1064            if (Utils.debug.messageEnabled()) {
1065                Utils.debug.message(
1066                    "Message.toDocument: adding security headers ");
1067            }
1068
1069            Element securityE = doc.createElementNS(wsseNS,
1070                WSSEConstants.TAG_WSSE + ":" + WSSEConstants.TAG_SECURITYT);
1071            securityE.setAttributeNS(SOAPBindingConstants.NS_XML,
1072                WSSEConstants.TAG_XML_WSSE, wsseNS);
1073            headerE.appendChild(securityE);
1074
1075            if (assertion != null) {
1076                Document assertionDoc =
1077                        XMLUtils.toDOMDocument(assertion.toString(true, true),
1078                                               Utils.debug);
1079                if (assertionDoc == null) {
1080                    String msg =
1081                        Utils.bundle.getString("cannotProcessSAMLAssertion");
1082                    Utils.debug.error("Message.Message: " + msg);
1083                    throw new SOAPBindingException(msg);
1084                }
1085                Element assertionE = assertionDoc.getDocumentElement();
1086                securityE.appendChild(doc.importNode(assertionE, true));
1087            } else if (binarySecurityToken != null) {
1088                Document bstDoc =
1089                        XMLUtils.toDOMDocument(binarySecurityToken.toString(),
1090                                               Utils.debug);
1091                if (bstDoc == null) {
1092                    String msg = Utils.bundle.getString(
1093                                     "cannotProcessBinarySecurityToken");
1094                    Utils.debug.error("Message.Message: " + msg);
1095                    throw new SOAPBindingException(msg);
1096                }
1097                Element binarySecurityTokenE = bstDoc.getDocumentElement();
1098                securityE.appendChild(doc.importNode(binarySecurityTokenE,
1099                                                     true));
1100            }
1101
1102            if (hasSecurityHeaders) {
1103                Iterator iter = securityHeaders.iterator();
1104                while(iter.hasNext()) {
1105                    securityE.appendChild(doc.importNode((Node)iter.next(),
1106                                                         true));
1107                }
1108            }
1109        }
1110
1111        Element bodyE = null;
1112        if (soapFault != null) {
1113            if (Utils.debug.messageEnabled()) {
1114                Utils.debug.message("Message.toDocument: adding soapFault ");
1115            }
1116
1117            bodyE = doc.createElementNS(SOAPBindingConstants.NS_SOAP,
1118                                        SOAPBindingConstants.PTAG_BODY);
1119            envelopeE.appendChild(bodyE);
1120            soapFault.addToParent(bodyE);
1121        }
1122
1123        if (soapBodies != null && !soapBodies.isEmpty()){
1124
1125            if (Utils.debug.messageEnabled()) {
1126                Utils.debug.message("Message.toDocument: adding bodies ");
1127            }
1128
1129            if (bodyE == null) {
1130                bodyE = doc.createElementNS(SOAPBindingConstants.NS_SOAP,
1131                                            SOAPBindingConstants.PTAG_BODY);
1132                bodyE.setAttributeNS(SOAPBindingConstants.NS_XML,
1133                    SOAPBindingConstants.XMLNS_SOAP,
1134                    SOAPBindingConstants.NS_SOAP);
1135                envelopeE.appendChild(bodyE);
1136            }
1137
1138            Iterator iter = soapBodies.iterator();
1139            while(iter.hasNext()) {
1140                Element soapBodyE = (Element)iter.next();
1141                bodyE.appendChild(doc.importNode(soapBodyE, true));
1142            }
1143
1144            if (bodyId == null) {
1145                bodyId = SAMLUtils.generateID();
1146            }
1147            if (SOAPBindingConstants.WSF_10_VERSION.equals(wsfVersion)) {
1148                bodyE.setAttributeNS(null, SOAPBindingConstants.ATTR_id,
1149                    bodyId);
1150            } else {
1151                bodyE.setAttributeNS(wsuNS, WSSEConstants.WSU_ID, bodyId);
1152            }
1153        }
1154
1155        return doc;
1156    }
1157
1158    /**
1159     * Returns the SOAP message in SOAPMessage format.
1160     *
1161     * @return the SOAP message in SOAPMessage format.
1162     * @throws SOAPBindingException if an error occurs while converting
1163     *                              this object to a SOAP message.
1164     */
1165    SOAPMessage toSOAPMessage() throws SOAPBindingException {
1166        return Utils.DocumentToSOAPMessage(toDocument(true));
1167    }
1168
1169    /**
1170     * Parses a <code>org.w3c.dom.Document</code> to construct this object.
1171     *
1172     * @param doc a <code>org.w3c.dom.Document</code>.
1173     * @throws SOAPBindingException if an error occurs while parsing
1174     *                              the document
1175     */
1176    private void parseDocument( Document doc) throws SOAPBindingException {
1177        Element envelopeE = doc.getDocumentElement();
1178
1179        if (Utils.debug.messageEnabled()) {
1180            Utils.debug.message("Message.parseDocument: doc = " +
1181                                XMLUtils.print(envelopeE));
1182        }
1183
1184        NodeList nl = envelopeE.getChildNodes();
1185        int length = nl.getLength();
1186
1187        if (length == 0) {
1188            String msg = Utils.bundle.getString("soapEnvelopeMissingChildren");
1189            Utils.debug.error("Message.parseDocument: " + msg);
1190            throw new SOAPBindingException(msg);
1191        }
1192
1193        Element headerE = null;
1194        Element bodyE = null;
1195        for(int i = 0; i < length; i++) {
1196            Node child = nl.item(i);
1197            if (child.getNodeType() == Node.ELEMENT_NODE) {
1198                Element element = (Element)child;
1199                String localName = element.getLocalName();
1200                String namespaceURI = element.getNamespaceURI();
1201
1202                if (SOAPBindingConstants.NS_SOAP.equals(namespaceURI)) {
1203                    if (SOAPBindingConstants.TAG_HEADER.equals(localName)) {
1204                        headerE = element;
1205                    } else if(SOAPBindingConstants.TAG_BODY.equals(localName)){
1206                        bodyE = element;
1207                    }
1208                }
1209            }
1210        }
1211
1212        Element securityE = null;
1213        soapHeaders = new ArrayList();
1214        // parsing Header element
1215        if (headerE != null) {
1216            nl = headerE.getChildNodes();
1217            length = nl.getLength();
1218            for (int i = 0; i < length; i++) {
1219                Node child = nl.item(i);
1220                if (child.getNodeType() == Node.ELEMENT_NODE) {
1221                    Element element = (Element)child;
1222                    String localName = element.getLocalName();
1223                    String ns = element.getNamespaceURI();
1224
1225                    if (SOAPBindingConstants.NS_SOAP_BINDING.equals(ns)) {
1226                        if (SOAPBindingConstants.TAG_CORRELATION
1227                                                .equals(localName)) {
1228                            correlationHeader = new CorrelationHeader(element);
1229                        } else if (SOAPBindingConstants.TAG_CONSENT
1230                                                       .equals(localName)) {
1231                            consentHeader = new ConsentHeader(element);
1232                        } else if(SOAPBindingConstants.TAG_USAGE_DIRECTIVE
1233                                                      .equals(localName)){
1234                            if (usageDirectiveHeaders == null) {
1235                                usageDirectiveHeaders = new ArrayList();
1236                            }
1237                            usageDirectiveHeaders.add(
1238                                    new UsageDirectiveHeader(element));
1239                        } else if (SOAPBindingConstants.TAG_PROVIDER
1240                                                       .equals(localName)) {
1241                            providerHeader = new ProviderHeader(element);
1242                        } else if (SOAPBindingConstants.TAG_PROCESSING_CONTEXT
1243                                                       .equals(localName)) {
1244                            processingContextHeader =
1245                                new ProcessingContextHeader(element);
1246                        } else {
1247                            soapHeaders.add(element);
1248                        }
1249                    } else if (SOAPBindingConstants.NS_SOAP_BINDING_11
1250                                                   .equals(ns) &&
1251                               SOAPBindingConstants
1252                                                 .TAG_SERVICE_INSTANCE_UPDATE
1253                                                 .equals(localName)) {
1254
1255                        serviceInstanceUpdateHeader =
1256                                new ServiceInstanceUpdateHeader(element);
1257                    } else if (WSSEConstants.NS_WSSE.equals(ns) ||
1258                        WSSEConstants.NS_WSSE_WSF11.equals(ns)) {
1259                        if (WSSEConstants.TAG_SECURITYT.equals(localName)) {
1260                            securityE = element;
1261                        } else {
1262                            soapHeaders.add(element);
1263                        }
1264                    } else {
1265                        soapHeaders.add(element);
1266                    }
1267                }
1268            }
1269            parseSecurityElement(securityE);
1270        }
1271
1272        if (soapHeaders.isEmpty()) {
1273            soapHeaders = null;
1274        }
1275
1276        // parsing Body element
1277
1278        if (bodyE != null) {
1279            nl = bodyE.getChildNodes();
1280            length = nl.getLength();
1281            for(int i = 0; i < length; i++) {
1282                Node child = nl.item(i);
1283                if (child.getNodeType() == Node.ELEMENT_NODE) {
1284                    Element childE = (Element)child;
1285                    String localName = childE.getLocalName();
1286                    String ns = childE.getNamespaceURI();
1287                    if (soapFault == null &&
1288                        SOAPBindingConstants.NS_SOAP.equals(ns) &&
1289                        SOAPBindingConstants.TAG_FAULT.equals(localName)) {
1290                        soapFault = new SOAPFault(childE);
1291                    } else {
1292                        if (soapBodies == null) {
1293                            soapBodies = new ArrayList();
1294                        }
1295                        soapBodies.add(child);
1296                    }
1297                }
1298            }
1299        }
1300
1301    }
1302
1303    /**
1304     * Sets security profile type by parsing a security element.
1305     *
1306     * @param se a security element
1307     * @throws SOAPBindingException if an error occurs while parsing
1308     *                              the security element
1309     */
1310    private void parseSecurityElement(Element securityE)
1311    throws SOAPBindingException {
1312        if (securityE == null) {
1313            securityProfileType = ANONYMOUS;
1314            return;
1315        }
1316
1317        String wsseNS = securityE.getNamespaceURI();
1318        if (wsseNS == null) {
1319            securityProfileType = ANONYMOUS;
1320            return;
1321        }
1322        String wsuNS = null;
1323        if (wsseNS.equals(WSSEConstants.NS_WSSE_WSF11)) {
1324            wsfVersion = SOAPBindingConstants.WSF_11_VERSION;
1325            wsuNS = WSSEConstants.NS_WSU_WSF11;
1326
1327        } else if(wsseNS.equals(WSSEConstants.NS_WSSE)) {
1328            wsfVersion = SOAPBindingConstants.WSF_10_VERSION;
1329            wsuNS = WSSEConstants.NS_WSU;
1330
1331        } else {
1332            securityProfileType = ANONYMOUS;
1333            return;
1334        }
1335
1336        NodeList nl = securityE.getElementsByTagNameNS(wsseNS,
1337            SAMLConstants.TAG_SECURITYTOKENREFERENCE);
1338
1339        Element securityTokenRefE = null;
1340        String uri = null;
1341        if (nl != null && nl.getLength() > 0) {
1342            securityTokenRefE = (Element)nl.item(0);
1343            List list = XMLUtils.getElementsByTagNameNS1(securityTokenRefE,
1344                wsseNS, SAMLConstants.TAG_REFERENCE);
1345            if (!list.isEmpty()) {
1346                Element referenceE = (Element)list.get(0);
1347                uri = XMLUtils.getNodeAttributeValue(referenceE,
1348                        SAMLConstants.TAG_URI);
1349                if (uri != null && uri.length() > 1 && uri.startsWith("#")) {
1350                    uri = uri.substring(1);
1351                } else {
1352                    String msg = Utils.bundle.getString("invalidReferenceURI");
1353                    Utils.debug.error("Message.parseSecurityElement: " + msg);
1354                    throw new SOAPBindingException(msg);
1355                }
1356                if (Utils.debug.messageEnabled()) {
1357                    Utils.debug.message("Message.parseSecurityElement: " +
1358                            "SecurityTokenReference Reference URI = " + uri);
1359                }
1360            }
1361        }
1362        
1363        securityProfileType = ANONYMOUS;
1364        securityHeaders = new ArrayList();
1365        nl = securityE.getChildNodes();
1366        int length = nl.getLength();
1367        for(int i = 0; i < length; i++) {
1368            Node child = nl.item(i);
1369            if (child.getNodeType() == Node.ELEMENT_NODE) {
1370                String localName = child.getLocalName();
1371                String ns = child.getNamespaceURI();
1372                
1373                if (securityProfileType != ANONYMOUS) {
1374                    securityHeaders.add(child);
1375                    continue;
1376                }
1377                
1378                if (SAMLConstants.BINARYSECURITYTOKEN.equals(localName) &&
1379                    wsseNS.equals(ns)) {
1380                    
1381                    Element binarySecurityTokenE = (Element)child;
1382                    String valuetype = XMLUtils.getNodeAttributeValue(
1383                            binarySecurityTokenE,
1384                            "ValueType");
1385                    Utils.debug.message("ValueType: "+valuetype);
1386                    if ((valuetype != null) &&
1387                            valuetype.endsWith("ServiceSessionContext")) {
1388                        securityHeaders.add(child);
1389                        continue;
1390                    }
1391                    if (uri != null) {
1392                        String id = XMLUtils.getNodeAttributeValueNS(
1393                            binarySecurityTokenE, wsuNS, SAMLConstants.TAG_ID);
1394                        if (!uri.equals(id)) {
1395                            securityHeaders.add(child);
1396                            continue;
1397                        }
1398                    }
1399                    
1400                    try {
1401                        binarySecurityToken =
1402                                new BinarySecurityToken(binarySecurityTokenE);
1403                        messageCertificate =
1404                                (X509Certificate)SecurityUtils.getCertificate(
1405                                binarySecurityToken);
1406                    } catch (Exception ex) {
1407                        String msg = Utils.bundle.getString(
1408                                "cannotProcessBinarySecurityToken");
1409                        Utils.debug.error("Message.parseSecurityElement: "+
1410                                msg);
1411                        throw new SOAPBindingException(msg);
1412                    }
1413                    if (Utils.debug.messageEnabled()) {
1414                        Utils.debug.message("Message.parseSecurityElement:" +
1415                                " found binary security token");
1416                    }
1417                    securityProfileType = X509_TOKEN;
1418                } else if (SAMLConstants.TAG_ASSERTION.equals(localName) &&
1419                        SAMLConstants.assertionSAMLNameSpaceURI.equals(ns)){
1420                    
1421                    Element assertionE = (Element)child;
1422                    
1423                    if (uri != null) {
1424                        String assertionID = XMLUtils.getNodeAttributeValue(
1425                                assertionE,
1426                                SAMLConstants.TAG_ASSERTION_ID);
1427                        if (!uri.equals(assertionID)) {
1428                            securityHeaders.add(child);
1429                            continue;
1430                        }
1431                    }
1432                    
1433                    try {
1434                        assertion = new SecurityAssertion(assertionE);
1435                    } catch (SAMLException ex) {
1436                        String msg = Utils.bundle.getString(
1437                                "cannotProcessSAMLAssertion");
1438                        Utils.debug.error("Message.parseSecurityElement: " +
1439                                msg);
1440                        throw new SOAPBindingException(msg);
1441                    }
1442                    if (Utils.debug.messageEnabled()) {
1443                        Utils.debug.message("Message.parseSecurityElement:" +
1444                                " found security assertion, " +
1445                                "isBearer = " +
1446                                assertion.isBearer());
1447                    }
1448                    
1449                    if (assertion.isBearer()) {
1450                        securityProfileType = BEARER_TOKEN;
1451                    } else {
1452                        securityProfileType = SAML_TOKEN;
1453                        messageCertificate =
1454                                (X509Certificate)SecurityUtils.getCertificate(
1455                                assertion);
1456                    }
1457                } else {
1458                    securityHeaders.add(child);
1459                }
1460            }
1461        }
1462        if (securityHeaders.isEmpty()) {
1463            securityHeaders = null;
1464        }
1465    }
1466
1467    /**
1468     * Returns the web services version of the message.
1469     *
1470     * @return the web services version.
1471     */
1472    public String
1473    getWSFVersion()
1474    {
1475        return wsfVersion;
1476    }
1477
1478    /**
1479     * Sets the web services version to the message.
1480     *
1481     * @param version the web services framework version.
1482     */
1483    public void
1484    setWSFVersion(String version)
1485    {
1486       this.wsfVersion = version;
1487    }
1488}