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: FSNameRegistrationRequest.java,v 1.4 2008/06/25 05:46:44 qcheng Exp $
026 *
027 */
028
029package com.sun.identity.federation.message;
030
031import com.sun.identity.federation.common.FSUtils;
032import com.sun.identity.federation.common.IFSConstants;
033import com.sun.identity.federation.message.common.FSMsgException;
034import com.sun.identity.federation.message.common.IDPProvidedNameIdentifier;
035import com.sun.identity.federation.message.common.OldProvidedNameIdentifier;
036import com.sun.identity.federation.message.common.SPProvidedNameIdentifier;
037import com.sun.identity.saml.common.SAMLConstants;
038import com.sun.identity.saml.common.SAMLUtils;
039import com.sun.identity.saml.common.SAMLException;
040import com.sun.identity.saml.common.SAMLResponderException;
041import com.sun.identity.saml.protocol.AbstractRequest;
042import com.sun.identity.saml.xmlsig.XMLSignatureManager;
043import com.sun.identity.shared.DateUtils;
044import com.sun.identity.shared.encode.Base64;
045import com.sun.identity.shared.encode.URLEncDec;
046import com.sun.identity.shared.xml.XMLUtils;
047import java.util.ArrayList;
048import java.util.Collections;
049import java.util.Date;
050import java.util.Iterator;
051import java.util.List;
052import java.text.ParseException;
053import javax.servlet.http.HttpServletRequest;
054import org.w3c.dom.Element;
055import org.w3c.dom.Node;
056import org.w3c.dom.NodeList;
057import org.w3c.dom.Document;
058
059
060/**
061 * This class contains methods to create <code>NameRegistrationRequest</code>
062 * object.
063 *
064 * @supported.all.api
065 */
066
067public class FSNameRegistrationRequest extends AbstractRequest {
068    private String providerId;
069    private SPProvidedNameIdentifier spProvidedNameIdentifier;
070    private IDPProvidedNameIdentifier idpProvidedNameIdentifier;
071    private OldProvidedNameIdentifier oldProvidedNameIdentifier;
072    private String relayState = "";
073    protected String xmlString;
074    protected String signatureString;
075    protected String id;
076    protected int minorVersion = 0;
077
078    /** 
079     * Default Constructor.
080     */
081    
082    public FSNameRegistrationRequest() { 
083        setIssueInstant(new Date());
084    }
085        
086    /**
087     * Returns the value of <code>id</code> attribute.
088     *
089     * @return the value of <code>id</code> attribute.
090     * @see #setID(String)
091     */
092    public String getID(){
093        return id;
094    }
095    
096    /**
097     * Sets the value of <code>id</code> attribute.
098     *
099     * @param id the value of <code>id</code> attribute.
100     * @see #getID()
101     */
102    public void setID(String id){
103        this.id = id;
104    }
105    /**
106     * Returns the value of <code>RelayState</code> attribute.
107     *
108     * @return the value of <code>RelayState</code> attribute.
109     * @see #setRelayState(String)
110     */
111    
112    public String getRelayState(){
113        return relayState;
114    }
115    
116    /**
117     * Set the value of <code>RelayState</code> attribute.
118     *
119     * @param relayState the value of <code>RelayState</code> attribute.
120     * @see #getRelayState()
121     */
122    public void setRelayState(String relayState) {
123        this.relayState = relayState;
124    }
125
126   
127    /**
128     * Returns the signed <code>XML</code> string.
129     *
130     * @return the signed <code>XML</code> string.
131     */
132    public String getSignatureString(){
133        return signatureString;
134    }
135
136
137    /**
138     * Constructor creates the <code>FSNameRegistrationRequest</code>
139     * object.
140     *
141     * @param requestId the value of <code>RequestID</code> attribute.
142     * @param respondWiths the value of <code>RespondWiths</code> attribute.
143     * @param providerId the value of <code>ProviderID</code> attribute.
144     * @param spProvidedNameIdentifier the Service Provider 
145     *        <code>NameIdentifier</code>.
146     * @param idpProvidedNameIdentifier the Identity Provider 
147     *        <code>NameIdentifier</code>.
148     * @param oldProvidedNameIdentifier the Original Provider
149     *        <code>NameIdentifier</code>.
150     * @param relayState the value of <code>RelayState</code> attribute.
151     * @throws FSMsgException if there is an error creating this object.
152     */
153    public FSNameRegistrationRequest(
154        String requestId,
155        List respondWiths,
156        String providerId, 
157        SPProvidedNameIdentifier spProvidedNameIdentifier,
158        IDPProvidedNameIdentifier idpProvidedNameIdentifier,
159        OldProvidedNameIdentifier oldProvidedNameIdentifier,
160        String relayState) throws FSMsgException {
161     
162        int length = 0;
163        setIssueInstant(new Date());    
164        if ((respondWiths != null) &&
165            (respondWiths != Collections.EMPTY_LIST)) {
166            length = respondWiths.size();
167            for (int i = 0; i < length; i++) {
168                Object temp = respondWiths.get(i);
169                if (!(temp instanceof String)) {
170                    if (FSUtils.debug.messageEnabled()) {
171                        FSUtils.debug.message("NameRegistrationRequest: "
172                            + "wrong input for RespondWith");
173                    }
174                    throw new FSMsgException("wrongInput", null);
175                }
176            }
177            this.respondWiths = respondWiths;
178        }
179     
180        if ((requestId != null) && (requestId.length() != 0)) {
181            requestID = requestId;
182        } else {
183            // random generate one
184            requestID = SAMLUtils.generateID();
185            if (requestID == null) {
186                FSUtils.debug.error("FSNameRegistrationRequest: "
187                    + "couldn't generate RequestID.");
188                throw new FSMsgException("errorGenerateID", null);
189            }
190        }
191        this.providerId=providerId;
192        this.spProvidedNameIdentifier=spProvidedNameIdentifier;
193        this.idpProvidedNameIdentifier=idpProvidedNameIdentifier;
194        this.oldProvidedNameIdentifier=oldProvidedNameIdentifier;
195        this.relayState = relayState;
196    }
197    
198    /**
199     * Constructor creates <code>FSNameRegistrationRequest</code>> object
200     * from a Document Element.
201     *
202     * @param root the Document Element.
203     * @throws FSMsgException if there is an error creating
204     *         this object.
205     */
206    public FSNameRegistrationRequest(Element root) throws FSMsgException {        
207        String tag = null;
208        if (root == null) {
209            FSUtils.debug.message(
210                "FSNameRegistrationRequest(Element): null input.");
211            throw new FSMsgException("nullInput",null);
212        }
213        if (((tag = root.getLocalName()) == null) ||
214        (!tag.equals("RegisterNameIdentifierRequest"))) {
215            FSUtils.debug.message(
216                "FSNameRegistrationRequest(Element): wrong input");
217            throw new FSMsgException("wrongInput",null);
218        }
219        
220        // Attribute IssueInstant
221        String instantString = root.getAttribute(IFSConstants.ISSUE_INSTANT);
222        if ((instantString == null) || (instantString.length() == 0)) {
223             FSUtils.debug.error("FSNameRegistrationRequest(Element):" +
224             "missing IssueInstant");
225             String[] args = { IFSConstants.ISSUE_INSTANT };
226             throw new FSMsgException("missingAttribute",args);
227        } else {
228             try {
229                 issueInstant = DateUtils.stringToDate(instantString);
230             } catch (ParseException e) {
231                 FSUtils.debug.error(
232                    "FSNameRegistrationRequest(Element): " +
233                    "could not parse IssueInstant" , e);
234                 throw new FSMsgException("wrongInput",null);
235             }
236        }
237        
238        int length = 0;
239        id = root.getAttribute("id");
240        requestID = root.getAttribute("RequestID");
241        parseMajorVersion(root.getAttribute("MajorVersion"));
242        parseMinorVersion(root.getAttribute("MinorVersion"));
243        NodeList contentnl = root.getChildNodes();
244        Node child;
245        String nodeName;
246        length = contentnl.getLength();
247        for (int i = 0; i < length; i++) {
248            child = contentnl.item(i);
249            if ((nodeName = child.getLocalName()) != null) {
250                if (nodeName.equals("RespondWith")) {
251                    if (respondWiths == Collections.EMPTY_LIST) {
252                        respondWiths = new ArrayList();
253                    }
254                    respondWiths.add(
255                    XMLUtils.getElementValue((Element) child));
256                } else if (nodeName.equals(IFSConstants.SIGNATURE)) {
257                } else if (nodeName.equals("ProviderID")) {
258                    if (providerId != null) {
259                        if (FSUtils.debug.messageEnabled()) {
260                            FSUtils.debug.message(
261                                "FSNameRegistrationRequest(Element): "
262                                + "should contain only one ProviderID.");
263                        }
264                        throw new FSMsgException("wrongInput",null);
265                    }
266                    providerId = XMLUtils.getElementValue((Element) child);
267                }  else if (nodeName.equals("SPProvidedNameIdentifier")) {
268                    spProvidedNameIdentifier = 
269                        new SPProvidedNameIdentifier((Element) child);
270                } else if (nodeName.equals("IDPProvidedNameIdentifier")) {
271                    idpProvidedNameIdentifier = 
272                        new IDPProvidedNameIdentifier((Element) child);
273                } else if (nodeName.equals("OldProvidedNameIdentifier")) {
274                    oldProvidedNameIdentifier = 
275                        new OldProvidedNameIdentifier((Element) child);
276                }else if (nodeName.equals("RelayState")) {
277                    relayState = XMLUtils.getElementValue((Element) child);
278                }else {
279                    if (FSUtils.debug.messageEnabled()) {
280                        FSUtils.debug.message(
281                            "FSNameRegistrationRequest(Element): "
282                            + "invalid node" + nodeName);
283                    }
284                    throw new FSMsgException("wrongInput",null);
285                }
286            }
287        }
288        List signs = XMLUtils.getElementsByTagNameNS1(root,
289                                        SAMLConstants.XMLSIG_NAMESPACE_URI,
290                                        SAMLConstants.XMLSIG_ELEMENT_NAME);
291        int signsSize = signs.size();
292        if (signsSize == 1) {
293            Element elem = (Element)signs.get(0);
294            setSignature(elem);
295            xmlString = XMLUtils.print(root);
296            signed = true;
297        } else if (signsSize != 0) {
298            FSUtils.debug.error("FSNameRegistrationRequest(Element): " +
299            "included more than one Signature element.");
300            throw new FSMsgException( "moreElement",null);
301        }        
302        //end check for signature
303    }
304    
305    /**
306     * Returns the <code>MinorVersion</code>.
307     *
308     * @return the <code>MinorVersion</code>.
309     * @see #setMinorVersion(int)
310     */
311    public int getMinorVersion() {
312       return minorVersion;
313    }
314    
315    /**
316     * Sets the <code>MinorVersion</code>.
317     *
318     * @param version the <code>MinorVersion</code>.
319     * @see #getMinorVersion()
320     */
321    public void setMinorVersion(int version) {
322       minorVersion = version;
323    }
324
325    public static FSNameRegistrationRequest parseXML(String xml)
326        throws FSMsgException {
327        Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug);
328        if (doc == null) {
329            FSUtils.debug.error("FSNameRegistrationRequest.parseXML:Error " +
330            "while parsing input xml string");
331            throw new FSMsgException("parseError",null);
332        }
333        Element root = doc.getDocumentElement();
334        return new FSNameRegistrationRequest(root);
335    }
336
337    /**
338     * Returns a String representation of the Logout Response.
339     *
340     * @return a string containing the valid XML for this element
341     * @throws FSMsgException if there is an error converting
342     *         this object ot a string.
343     */
344    public String toXMLString() throws FSMsgException {
345        return toXMLString(true, true);
346    }
347
348    /**
349     * Returns a String representation of the Logout Response.
350     *
351     * @param includeNS : Determines whether or not the namespace qualifier
352     *        is prepended to the Element when converted
353     * @param declareNS : Determines whether or not the namespace is declared
354     *        within the Element.
355     * @return a string containing the valid XML for this element
356     * @throws FSMsgException if there is an error converting
357     *         this object ot a string.
358     */
359    public String toXMLString(boolean includeNS, boolean declareNS)
360        throws FSMsgException {
361        return toXMLString(includeNS, declareNS, false);
362    }
363    
364    /**
365     * Returns a String representation of the Logout Response.
366     *
367     * @param includeNS Determines whether or not the namespace qualifier
368     *        is prepended to the Element when converted
369     * @param declareNS Determines whether or not the namespace is declared
370     *        within the Element.
371     * @param includeHeader Determines whether the output include the xml
372     *        declaration header.
373     * @return a string containing the valid XML for this element
374     * @throws FSMsgException if there is an error converting
375     *        this object ot a string.
376     */
377    public String toXMLString(boolean includeNS,boolean declareNS,
378        boolean includeHeader) throws FSMsgException {
379        if((providerId == null) || (providerId.length() == 0)){
380            FSUtils.debug.error("FSNameRegistrationRequest.toXMLString: "
381                + "providerId is null in the request with requestId:" 
382                + requestID);
383            String[] args = { requestID };
384            throw new FSMsgException("nullProviderIdWRequestId",args);
385        }
386        if ((requestID == null) || (requestID.length() == 0)){
387            requestID = SAMLUtils.generateID();
388            if (requestID == null) {
389                FSUtils.debug.error("FSNameRegistrationRequest.toXMLString: "
390                    + "couldn't generate RequestID.");
391                throw new FSMsgException("errorGenerateID",null);
392            }
393        }
394        
395        StringBuffer xml = new StringBuffer(1000);
396        if (includeHeader) {
397            xml.append("<?xml version=\"1.0\" encoding=\"").
398            append(IFSConstants.DEFAULT_ENCODING).append("\" ?>\n");
399        }
400        String prefix = "";
401        String uri = "";
402        String uriSAML = "";
403        if (includeNS) {
404            prefix = IFSConstants.LIB_PREFIX;
405        }
406        if (declareNS) {
407            if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) {
408                uri = IFSConstants.LIB_12_NAMESPACE_STRING;
409            } else {
410                uri = IFSConstants.LIB_NAMESPACE_STRING;
411            }
412            uriSAML = IFSConstants.assertionDeclareStr;
413        }
414
415        String instantString = DateUtils.toUTCDateFormat(issueInstant);
416
417        if(requestID != null){
418           xml.append("<").append(prefix).
419           append("RegisterNameIdentifierRequest").
420           append(uri).append(uriSAML);
421           if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION && 
422              id != null && !(id.length() == 0)){
423              xml.append(" id=\"").append(id).append("\" ");
424           }
425           xml.append(" RequestID=\"").append(requestID).append("\" ").
426               append(" MajorVersion=\"").append(majorVersion).append("\" ").
427               append(" MinorVersion=\"").append(minorVersion).append("\" ").
428               append(" IssueInstant=\"").append(instantString).append("\"").
429               append(">");
430           if((respondWiths != null) && 
431               (respondWiths != Collections.EMPTY_LIST)) {
432                Iterator i = respondWiths.iterator();
433                while (i.hasNext()) {
434                    xml.append("<").append(prefix).append("RespondWith>").
435                    append((String) i.next()).append("</").append(prefix).
436                    append("RespondWith>");
437                }
438            }
439            if (signed) {
440                if (signatureString != null) {
441                    xml.append(signatureString);
442                } else if (signature != null) {
443                    signatureString = XMLUtils.print(signature);
444                    xml.append(signatureString);
445                }
446            }
447            
448            xml.append("<").append(prefix).append("ProviderID").append(">").
449            append(providerId).
450            append("</").append(prefix).append("ProviderID").append(">");
451            if(idpProvidedNameIdentifier != null && 
452               idpProvidedNameIdentifier.getName().length() != 0) {
453               xml.append(idpProvidedNameIdentifier.toXMLString());            
454            }
455            if(spProvidedNameIdentifier != null && 
456               spProvidedNameIdentifier.getName().length() != 0) {
457               xml.append(spProvidedNameIdentifier.toXMLString());
458            }
459            if(oldProvidedNameIdentifier != null && 
460               oldProvidedNameIdentifier.getName().length() != 0) {
461                xml.append(oldProvidedNameIdentifier.toXMLString());
462            }
463            if(relayState != null) {
464               xml.append("<").append(prefix).append("RelayState").append(">").
465                   append(relayState).append("</").append(prefix).
466                   append("RelayState").append(">");
467            }
468            xml.append("</").append(prefix).
469                append("RegisterNameIdentifierRequest>");
470        } else {
471            FSUtils.debug.error("FSNameRegistrationRequest.toString: " +
472            "requestID is null ");
473            throw new FSMsgException("nullRequestID",null);
474        }
475        
476        return xml.toString();
477    }
478
479    /**
480     * Returns the Identity Provider's <code>NameIdentifier</code>.
481     *
482     * @return the Identity Provider's <code>NameIdentifier</code>.
483     */
484    public IDPProvidedNameIdentifier getIDPProvidedNameIdentifier() {
485        return idpProvidedNameIdentifier;
486    }
487    
488    /**
489     * Returns the original <code>NameIdentifier</code>.
490     *
491     * @return the original <code>NameIdentifier</code>.
492     */
493    public OldProvidedNameIdentifier getOldProvidedNameIdentifier() {
494        return oldProvidedNameIdentifier;
495    }
496    
497    /**
498     * Returns the value of <code>ProviderID</code> attribute.
499     *
500     * @return the value of <code>ProviderID</code> attribute.
501     * @see #setProviderId(String).
502     */
503    public String getProviderId() {
504        return this.providerId;
505    }
506
507    /**
508     * Sets the Identity Provider's <code>NameIdentifier</code>.
509     *
510     * @param nameIdentifier the Identity Provider's
511     *        <code>NameIdentifier</code>.
512     * @see #getIDPProvidedNameIdentifier
513     */
514    public void setIDPProvidedNameIdentifier(
515        IDPProvidedNameIdentifier nameIdentifier) {
516        idpProvidedNameIdentifier=nameIdentifier;
517    }
518    
519    /**
520     * Sets the original <code>NameIdentifier</code>.
521     *
522     * @param nameIdentifier the original provider's
523     *        <code>NameIdentifier</code>.
524     * @see #getOldProvidedNameIdentifier
525     */
526    
527    public void setOldProvidedNameIdentifier(
528        OldProvidedNameIdentifier nameIdentifier) {
529        oldProvidedNameIdentifier=nameIdentifier;
530    }
531    /**
532     * Sets the Service Provider's <code>NameIdentifier</code>.
533     *
534     * @param nameIdentifier the Identity Provider's
535     *        <code>NameIdentifier</code>.
536     * @see #getSPProvidedNameIdentifier
537     */
538    public void setSPProvidedNameIdentifier(
539            SPProvidedNameIdentifier nameIdentifier) {
540        spProvidedNameIdentifier=nameIdentifier;
541    }
542
543    /**
544     * Sets the value of <code>ProviderID</code> attribute.
545     *
546     * @param providerId the value of <code>ProviderID</code> attribute.
547     */
548    public void setProviderId(String providerId) {
549        this.providerId = providerId;
550    }
551
552    /**
553     * Returns the <code>NameIdentifier</code> provided by
554     * the Service Provider.
555     *
556     * @return the <code>NameIdentifier</code> provided by
557     *         the Service Provider.
558     * @see #setSPProvidedNameIdentifier(SPProvidedNameIdentifier)
559     */
560    public SPProvidedNameIdentifier getSPProvidedNameIdentifier() {
561        return spProvidedNameIdentifier;
562    }
563
564    /**
565     * Returns a Base64 Encoded String.
566     *
567     * @return a Base64 Encoded String.
568     * @throws FSMsgException if there is an error encoding the string.
569     */
570    public String toBASE64EncodedString() throws FSMsgException {
571        if ((providerId == null) || (providerId.length() == 0)) {
572            FSUtils.debug.error(
573                "FSNameRegistrationRequest.toBASE64EncodedString: "
574                + "providerId is null in the request with requestId:" 
575                + requestID);
576            String[] args = { requestID };
577            throw new FSMsgException("nullProviderIdWRequestId",args);
578        }
579        if ((requestID == null) || (requestID.length() == 0)){
580            requestID = SAMLUtils.generateID();
581            if (requestID == null) {
582                FSUtils.debug.error(
583                    "FSNameRegistrationRequest.toBASE64EncodedString: "
584                    + "couldn't generate RequestID.");
585                throw new FSMsgException("errorGenerateID",null);
586            }
587        }
588        return Base64.encode(this.toXMLString().getBytes());        
589    }
590    
591    /**
592     * Sets the <code>MajorVersion</code> by parsing the version string.
593     *
594     * @param majorVer a String representing the <code>MajorVersion</code> to
595     *        be set.
596     * @throws FSMsgException on error.
597     */
598    private void parseMajorVersion(String majorVer) throws FSMsgException {
599        try {
600            majorVersion = Integer.parseInt(majorVer);
601        } catch (NumberFormatException e) {
602            if (FSUtils.debug.messageEnabled()) {
603                FSUtils.debug.message("FSNameRegistrationRequest(Element): "
604                    + "invalid MajorVersion", e);
605            }
606            throw new FSMsgException("wrongInput",null);
607        }
608        
609        if (majorVersion != SAMLConstants.PROTOCOL_MAJOR_VERSION) {
610            if (majorVersion > SAMLConstants.PROTOCOL_MAJOR_VERSION) {
611                if (FSUtils.debug.messageEnabled()) {
612                    FSUtils.debug.message("FSNameRegistrationRequest(Element): "
613                        + "MajorVersion of the RegisterNameIdentifierRequest"
614                        + "is too high.");
615                }
616                throw new FSMsgException("requestVersionTooHigh",null);
617            } else {
618                if (FSUtils.debug.messageEnabled()) {
619                    FSUtils.debug.message("FSNameRegistrationRequest(Element): "
620                        + "MajorVersion of the RegisterNameIdentifierRequest"
621                        + "is too low.");
622                }
623                throw new FSMsgException("requestVersionTooLow",null);
624            }
625        }
626    }
627    
628    /**
629     * Sets the <code>MinorVersion</code> by parsing the version string.
630     *
631     * @param minorVer a String representing the <code>MinorVersion</code> to
632     *        be set.
633     * @throws SAMLException when the version mismatchs.
634     */
635    private void parseMinorVersion(String minorVer) throws FSMsgException {
636        try {
637            minorVersion = Integer.parseInt(minorVer);
638        } catch (NumberFormatException e) {
639            if (FSUtils.debug.messageEnabled()) {
640                FSUtils.debug.message(
641                "FSNameRegis(Element): "
642                + "invalid MinorVersion", e);
643            }
644            throw new FSMsgException("wrongInput",null);
645        }
646
647        if (minorVersion > IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) {
648            FSUtils.debug.error("FSNameRegisNot(Element):MinorVersion of"
649            + " the Response is too high.");
650            throw new FSMsgException("responseVersionTooHigh",null);
651        } else if (minorVersion < IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) {
652            FSUtils.debug.error("FSNameRegis(Element):MinorVersion of"
653            + " the Response is too low.");
654            throw new FSMsgException("responseVersionTooLow",null);
655        }
656    }
657
658
659    public void signXML() {
660
661    }
662    /**
663     * Signs the <code>FSNameRegistrationRequest</code> object.
664     *
665     * @param certAlias the Certificate Alias.
666     * @throws SAMLException if this object cannot be signed.
667     */
668    public void signXML(String certAlias) throws SAMLException {
669        FSUtils.debug.message("FSNameRegistrationRequest.signXML: Called");
670        if (signed) {
671            if (FSUtils.debug.messageEnabled()) {
672                FSUtils.debug.message("FSNameRegistrationRequest.signXML: "
673                    + "the assertion is already signed.");
674            }
675            throw new SAMLResponderException(FSUtils.BUNDLE_NAME,
676                                             "alreadySigned",null);
677        }
678        if (certAlias == null || certAlias.length() == 0) {
679            throw new SAMLResponderException(FSUtils.BUNDLE_NAME,
680                "cannotFindCertAlias",null);
681        }
682        try{
683            XMLSignatureManager manager = XMLSignatureManager.getInstance();
684            if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) {
685                     signatureString = manager.signXML(
686                                         this.toXMLString(true, true), 
687                                         certAlias,null,IFSConstants.ID, 
688                                         this.id, false);
689            } else if (minorVersion == 
690                                   IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) {
691                    signatureString = manager.signXML(
692                                         this.toXMLString(true, true), 
693                                         certAlias,null,IFSConstants.REQUEST_ID, 
694                                         this.getRequestID(), false);
695            } else { 
696                    if (FSUtils.debug.messageEnabled()) { 
697                        FSUtils.debug.message("invalid minor version.");                 
698                    }
699            }
700                 
701            signature = 
702                XMLUtils.toDOMDocument(signatureString, FSUtils.debug)
703                        .getDocumentElement();
704            signed = true;
705            xmlString = this.toXMLString(true, true);      
706        } catch(Exception e){
707            throw new SAMLResponderException(
708                                  FSUtils.BUNDLE_NAME,"signFailed",null);
709        }
710    }
711
712    /**
713     * Sets the Signature.
714     *
715     * @param elem the Document Element.
716     * @return true if success otherwise false.
717     */
718    public boolean setSignature(Element elem) {
719        signatureString = XMLUtils.print(elem); 
720        return super.setSignature(elem); 
721    } 
722        
723    /**
724     * Returns an URL Encoded String.
725     *
726     * @return a url encoded query string.
727     * @throws FSMsgException if there is an error.
728     */
729    public String toURLEncodedQueryString() throws FSMsgException {
730        if((providerId == null) || (providerId.length() == 0)) {
731            FSUtils.debug.error("FSNameRegistrationRequest." +
732            "toURLEncodedQueryString: providerId is null in the request " +
733            "with requestId: " + requestID);
734            throw new FSMsgException("nullProviderID",null);
735         }
736         if((requestID == null) || (requestID.length() == 0)){
737             requestID = SAMLUtils.generateID();
738             if(requestID == null) {
739                 FSUtils.debug.error("FSNameRegistrationRequest." +
740                       "toURLEncodedQueryString: couldn't generate RequestID.");
741                 throw new FSMsgException("errorGenerateID",null);
742             }
743         }
744         StringBuffer urlEncodedAuthnReq = new StringBuffer(300);
745         urlEncodedAuthnReq.append("RequestID=").
746                 append(URLEncDec.encode(requestID)).
747                 append(IFSConstants.AMPERSAND);
748         urlEncodedAuthnReq.append("MajorVersion=").
749                 append(majorVersion).
750                 append(IFSConstants.AMPERSAND);
751         urlEncodedAuthnReq.append("MinorVersion=").
752                 append(minorVersion).
753                 append(IFSConstants.AMPERSAND);
754         urlEncodedAuthnReq.append("RelayState=").
755                 append(URLEncDec.encode(relayState)).
756                 append(IFSConstants.AMPERSAND);
757         
758         if (issueInstant != null){
759             urlEncodedAuthnReq.append("IssueInstant=")
760                               .append(URLEncDec.encode(
761                                      DateUtils.toUTCDateFormat(issueInstant)))
762                               .append(IFSConstants.AMPERSAND);
763         } else {
764             FSUtils.debug.error("FSNameRegistrationRequest."
765                     + "toURLEncodedQueryString: issueInstant missing");
766             String[] args = { IFSConstants.ISSUE_INSTANT };
767             throw new FSMsgException("missingAttribute",args);
768         }
769         if (providerId != null && providerId.length() > 0) {
770             urlEncodedAuthnReq.append("ProviderID=").
771                     append(URLEncDec.encode(providerId)).
772                     append(IFSConstants.AMPERSAND);
773         }
774    
775         if(spProvidedNameIdentifier != null) {
776             if (spProvidedNameIdentifier.getName() != null &&
777                     spProvidedNameIdentifier.getName().length() != 0) {
778                 urlEncodedAuthnReq.append("SPProvidedNameIdentifier=").
779                         append(URLEncDec.encode(
780                         spProvidedNameIdentifier.getName())).
781                         append(IFSConstants.AMPERSAND);
782             }
783
784             if(spProvidedNameIdentifier.getNameQualifier() != null &&
785                    spProvidedNameIdentifier.getNameQualifier().length() != 0) {
786                 urlEncodedAuthnReq.append("SPNameQualifier=").
787                         append(URLEncDec.encode(
788                         spProvidedNameIdentifier.getNameQualifier())).
789                         append(IFSConstants.AMPERSAND);
790             }
791              if (spProvidedNameIdentifier.getFormat() != null && 
792                 spProvidedNameIdentifier.getFormat().length() != 0) {
793                 urlEncodedAuthnReq.append("SPNameFormat=").
794                                    append(URLEncDec.encode(
795                                         spProvidedNameIdentifier.getFormat())).
796                                    append(IFSConstants.AMPERSAND); 
797              }
798         } 
799
800         if (oldProvidedNameIdentifier != null) {
801            if (oldProvidedNameIdentifier.getName() != null && 
802               oldProvidedNameIdentifier.getName().length() != 0) {
803               urlEncodedAuthnReq.append("OldProvidedNameIdentifier=").
804                                  append(URLEncDec.encode(
805                                      oldProvidedNameIdentifier.getName())).
806                                  append(IFSConstants.AMPERSAND);
807            }
808            if (oldProvidedNameIdentifier.getNameQualifier() != null && 
809                oldProvidedNameIdentifier.getNameQualifier().length() != 0) { 
810                urlEncodedAuthnReq.append("OldNameQualifier=").
811                                   append(URLEncDec.encode(
812                                 oldProvidedNameIdentifier.getNameQualifier())).
813                                   append(IFSConstants.AMPERSAND);  
814            }
815            if (oldProvidedNameIdentifier.getFormat() != null&& 
816                         oldProvidedNameIdentifier.getFormat().length() != 0) {
817                urlEncodedAuthnReq.append("OldNameFormat=").
818                                   append(URLEncDec.encode(
819                                        oldProvidedNameIdentifier.getFormat())).
820                                   append(IFSConstants.AMPERSAND); 
821            }
822         } 
823
824         if (idpProvidedNameIdentifier != null) {
825            if (idpProvidedNameIdentifier.getName() != null && 
826                idpProvidedNameIdentifier.getName().length() != 0){
827                urlEncodedAuthnReq.append("IDPProvidedNameIdentifier=").
828                                   append(URLEncDec.encode(
829                                         idpProvidedNameIdentifier.getName())).
830                                   append(IFSConstants.AMPERSAND);
831            }
832            if (idpProvidedNameIdentifier.getNameQualifier() != null && 
833                idpProvidedNameIdentifier.getNameQualifier().length() != 0) {
834                urlEncodedAuthnReq.append("IDPNameQualifier=").
835                                   append(URLEncDec.encode(
836                                idpProvidedNameIdentifier.getNameQualifier())).
837                                   append(IFSConstants.AMPERSAND);  
838            }
839            if(idpProvidedNameIdentifier.getFormat() != null&& 
840                idpProvidedNameIdentifier.getFormat().length() != 0) {
841                urlEncodedAuthnReq.append("IDPNameFormat=").
842                                   append(URLEncDec.encode(
843                                        idpProvidedNameIdentifier.getFormat())).
844                                   append(IFSConstants.AMPERSAND); 
845            }
846         } 
847         return urlEncodedAuthnReq.toString();   
848   }
849   
850    /**
851     * Returns <code>FSNameRegistrationRequest</code> object. The
852     * object is creating by parsing the <code>HttpServletRequest</code>
853     * object.
854     *
855     * @param request the <code>HttpServletRequest</code> object.
856     * @throws FSMsgException if there is an error
857     *         creating this object.
858     * @throws SAMLException if there is an error.
859     */
860    public static FSNameRegistrationRequest parseURLEncodedRequest(
861            HttpServletRequest request) throws FSMsgException, SAMLException {
862        FSNameRegistrationRequest retNameRegistrationRequest =
863                new FSNameRegistrationRequest();
864        try {
865            FSUtils.debug.message("checking minor version");
866            retNameRegistrationRequest.majorVersion =
867                    Integer.parseInt(request.getParameter("MajorVersion"));
868            retNameRegistrationRequest.minorVersion =
869                    Integer.parseInt(request.getParameter("MinorVersion"));
870        } catch(NumberFormatException ex){
871            FSUtils.debug.error("FSNameRegistrationRequest.parseURLEncoded" +
872                    "Request: Invalid versions", ex);
873            throw new FSMsgException("invalidNumber",null);
874        }
875        FSUtils.debug.message("checking RequestID");
876        if(request.getParameter("RequestID")!= null) {
877            retNameRegistrationRequest.requestID =
878                    request.getParameter("RequestID");
879        } else {
880            FSUtils.debug.error("FSNameRegistrationRequest.parseURLEncoded" +
881                    "Request: RequestID not found");
882            String[] args = { IFSConstants.REQUEST_ID };
883            throw new FSMsgException("missingAttribute",args);
884        }
885        FSUtils.debug.message("checking instantString");
886        String instantString = request.getParameter("IssueInstant");
887        FSUtils.debug.message("instantString : " + instantString);
888        if(instantString == null ||
889                instantString.length() == 0) {
890            FSUtils.debug.error("FSNameRegistrationRequest.parseURLEncoded" +
891                    "Request: IssueInstant not found");
892            String[] args = { IFSConstants.ISSUE_INSTANT };
893            throw new FSMsgException("missingAttribute",args);
894        }
895        try{
896            FSUtils.debug.message(
897                    "calling : DateUtils.stringToDate.issueInstant");
898            retNameRegistrationRequest.issueInstant =
899                    DateUtils.stringToDate(instantString);
900        } catch (ParseException e){
901            FSUtils.debug.error("FSNameRegistrationRequest.parseURLEncoded" +
902                    "Request: Can not parse IssueInstant", e);
903            throw new FSMsgException("parseError",null);
904        }
905        
906        if(request.getParameter("ProviderID")!= null){
907            retNameRegistrationRequest.providerId =
908                    request.getParameter("ProviderID");
909        } else {
910            FSUtils.debug.error("FSNameRegistrationRequest.parseURLEncoded" +
911                    "Request: Can not find ProviderID");
912            throw new FSMsgException("missingElement",null);
913        }
914        FSUtils.debug.message("start identifier processing");
915        String spNameFormat = "";
916        String spNameQualifier = "";
917        String spName = "";
918        
919        if(request.getParameter("SPNameFormat") != null) {
920            spNameFormat = request.getParameter("SPNameFormat");
921        }
922        
923        if(request.getParameter("SPNameQualifier") != null) {
924            spNameQualifier = request.getParameter("SPNameQualifier");
925        }
926        
927        if(request.getParameter("SPProvidedNameIdentifier") != null) {
928            spName = request.getParameter("SPProvidedNameIdentifier");
929        }
930        if(spName != null &&  !(spName.length() < 1)) {
931            retNameRegistrationRequest.setSPProvidedNameIdentifier(
932                new SPProvidedNameIdentifier(spName, spNameQualifier, 
933                                             spNameFormat));
934        }
935        
936        String idpNameFormat = null;
937        String idpNameQualifier = null;
938        String idpName = null;
939        
940        if (request.getParameter("IDPNameFormat") != null) {
941            idpNameFormat = request.getParameter("IDPNameFormat");
942        }
943        
944        if (request.getParameter("IDPNameQualifier") != null) {
945            idpNameQualifier = request.getParameter("IDPNameQualifier");
946        }
947        
948        if (request.getParameter("IDPProvidedNameIdentifier") != null) {
949            idpName = request.getParameter("IDPProvidedNameIdentifier");
950        }
951        if (idpName != null && !(idpName.length() < 1)) {
952            retNameRegistrationRequest.idpProvidedNameIdentifier =
953                    new IDPProvidedNameIdentifier(idpName, idpNameQualifier,
954                    idpNameFormat);
955        }
956        
957        String oldNameFormat = null;
958        String oldNameQualifier = null;
959        String oldName = null;
960        
961        if (request.getParameter("OldNameFormat") != null) {
962            oldNameFormat = request.getParameter("OldNameFormat");
963        }
964        
965        if (request.getParameter("OldNameQualifier") != null) {
966            oldNameQualifier = request.getParameter("OldNameQualifier");
967        }
968        
969        if (request.getParameter("OldProvidedNameIdentifier") != null) {
970            oldName = request.getParameter("OldProvidedNameIdentifier");
971        }
972        
973        if (oldName != null && !(oldName.length() < 1)) {
974            retNameRegistrationRequest.oldProvidedNameIdentifier =
975                    new OldProvidedNameIdentifier(oldName, oldNameQualifier,
976                    oldNameFormat);
977        }
978        
979        if(request.getParameter("RelayState") != null) {
980            retNameRegistrationRequest.relayState =
981                    request.getParameter("RelayState");
982        }
983        return retNameRegistrationRequest;
984    }
985}