Build errors with xmlsec off
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / KeyInfoImpl.cpp
1 /*
2 *  Copyright 2001-2006 Internet2
3  * 
4 * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * KeyInfoImpl.cpp
19  * 
20  * Implementation classes for KeyInfo schema
21  */
22
23 #include "internal.h"
24 #include "AbstractChildlessElement.h"
25 #include "AbstractComplexElement.h"
26 #include "AbstractElementProxy.h"
27 #include "AbstractSimpleElement.h"
28 #include "exceptions.h"
29 #include "io/AbstractXMLObjectMarshaller.h"
30 #include "io/AbstractXMLObjectUnmarshaller.h"
31 #include "signature/KeyInfo.h"
32 #include "util/XMLHelper.h"
33 #include "validation/AbstractValidatingXMLObject.h"
34
35 #include <xercesc/util/XMLUniDefs.hpp>
36
37 using namespace xmlsignature;
38 using namespace xmltooling;
39 using namespace std;
40
41 #if defined (_MSC_VER)
42     #pragma warning( push )
43     #pragma warning( disable : 4250 4251 )
44 #endif
45
46 namespace xmlsignature {
47     
48     class XMLTOOL_DLLLOCAL DSAKeyValueImpl : public DSAKeyValue,
49         public AbstractComplexElement,
50         public AbstractDOMCachingXMLObject,
51         public AbstractValidatingXMLObject,
52         public AbstractXMLObjectMarshaller,
53         public AbstractXMLObjectUnmarshaller
54     {
55     public:
56         virtual ~DSAKeyValueImpl() {}
57
58         DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
59             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
60             init();
61         }
62             
63         DSAKeyValueImpl(const DSAKeyValueImpl& src)
64                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
65             init();
66             if (src.getP())
67                 setP(src.getP()->cloneP());
68             if (src.getQ())
69                 setQ(src.getQ()->cloneQ());
70             if (src.getG())
71                 setG(src.getG()->cloneG());
72             if (src.getY())
73                 setY(src.getY()->cloneY());
74             if (src.getJ())
75                 setJ(src.getJ()->cloneJ());
76             if (src.getSeed())
77                 setSeed(src.getSeed()->cloneSeed());
78             if (src.getPgenCounter())
79                 setPgenCounter(src.getPgenCounter()->clonePgenCounter());
80         }
81         
82         void init() {
83             m_P=NULL;
84             m_Q=NULL;
85             m_G=NULL;
86             m_Y=NULL;
87             m_J=NULL;
88             m_Seed=NULL;
89             m_PgenCounter=NULL;
90             m_children.push_back(NULL);
91             m_children.push_back(NULL);
92             m_children.push_back(NULL);
93             m_children.push_back(NULL);
94             m_children.push_back(NULL);
95             m_children.push_back(NULL);
96             m_children.push_back(NULL);
97             m_pos_P=m_children.begin();
98             m_pos_Q=m_pos_P;
99             ++m_pos_Q;
100             m_pos_G=m_pos_Q;
101             ++m_pos_G;
102             m_pos_Y=m_pos_G;
103             ++m_pos_Y;
104             m_pos_J=m_pos_Y;
105             ++m_pos_J;
106             m_pos_Seed=m_pos_J;
107             ++m_pos_Seed;
108             m_pos_PgenCounter=m_pos_Seed;
109             ++m_pos_PgenCounter;
110         }
111         
112         IMPL_XMLOBJECT_CLONE(DSAKeyValue);
113         IMPL_XMLOBJECT_CHILD(P);
114         IMPL_XMLOBJECT_CHILD(Q);
115         IMPL_XMLOBJECT_CHILD(G);
116         IMPL_XMLOBJECT_CHILD(Y);
117         IMPL_XMLOBJECT_CHILD(J);
118         IMPL_XMLOBJECT_CHILD(Seed);
119         IMPL_XMLOBJECT_CHILD(PgenCounter);
120
121     protected:
122         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
123             PROC_XMLOBJECT_CHILD(P,XMLConstants::XMLSIG_NS);
124             PROC_XMLOBJECT_CHILD(Q,XMLConstants::XMLSIG_NS);
125             PROC_XMLOBJECT_CHILD(G,XMLConstants::XMLSIG_NS);
126             PROC_XMLOBJECT_CHILD(Y,XMLConstants::XMLSIG_NS);
127             PROC_XMLOBJECT_CHILD(J,XMLConstants::XMLSIG_NS);
128             PROC_XMLOBJECT_CHILD(Seed,XMLConstants::XMLSIG_NS);
129             PROC_XMLOBJECT_CHILD(PgenCounter,XMLConstants::XMLSIG_NS);
130             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
131         }
132     };
133
134     class XMLTOOL_DLLLOCAL RSAKeyValueImpl : public RSAKeyValue,
135         public AbstractComplexElement,
136         public AbstractDOMCachingXMLObject,
137         public AbstractValidatingXMLObject,
138         public AbstractXMLObjectMarshaller,
139         public AbstractXMLObjectUnmarshaller
140     {
141     public:
142         virtual ~RSAKeyValueImpl() {}
143
144         RSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
145                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
146             init();
147         }
148             
149         RSAKeyValueImpl(const RSAKeyValueImpl& src)
150                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
151             init();
152             if (src.getModulus())
153                 setModulus(src.getModulus()->cloneModulus());
154             if (src.getExponent())
155                 setExponent(src.getExponent()->cloneExponent());
156         }
157         
158         void init() {
159             m_Modulus=NULL;
160             m_Exponent=NULL;
161             m_children.push_back(NULL);
162             m_children.push_back(NULL);
163             m_pos_Modulus=m_children.begin();
164             m_pos_Exponent=m_pos_Modulus;
165             ++m_pos_Exponent;
166         }
167         
168         IMPL_XMLOBJECT_CLONE(RSAKeyValue);
169         IMPL_XMLOBJECT_CHILD(Modulus);
170         IMPL_XMLOBJECT_CHILD(Exponent);
171
172     protected:
173         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
174             PROC_XMLOBJECT_CHILD(Modulus,XMLConstants::XMLSIG_NS);
175             PROC_XMLOBJECT_CHILD(Exponent,XMLConstants::XMLSIG_NS);
176             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
177         }
178     };
179
180     class XMLTOOL_DLLLOCAL KeyValueImpl : public KeyValue,
181         public AbstractSimpleElement,
182         public AbstractComplexElement,
183         public AbstractDOMCachingXMLObject,
184         public AbstractValidatingXMLObject,
185         public AbstractXMLObjectMarshaller,
186         public AbstractXMLObjectUnmarshaller
187     {
188     public:
189         virtual ~KeyValueImpl() {}
190
191         KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
192                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
193             init();
194         }
195             
196         KeyValueImpl(const KeyValueImpl& src)
197                 : AbstractXMLObject(src), AbstractSimpleElement(src),
198                     AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
199             init();
200             if (src.getDSAKeyValue())
201                 setDSAKeyValue(src.getDSAKeyValue()->cloneDSAKeyValue());
202             if (src.getRSAKeyValue())
203                 setRSAKeyValue(src.getRSAKeyValue()->cloneRSAKeyValue());
204             if (src.getXMLObject())
205                 setXMLObject(src.getXMLObject()->clone());
206         }
207         
208         void init() {
209             m_DSAKeyValue=NULL;
210             m_RSAKeyValue=NULL;
211             m_XMLObject=NULL;
212             m_children.push_back(NULL);
213             m_children.push_back(NULL);
214             m_children.push_back(NULL);
215             m_pos_DSAKeyValue=m_children.begin();
216             m_pos_RSAKeyValue=m_pos_DSAKeyValue;
217             ++m_pos_RSAKeyValue;
218             m_pos_XMLObject=m_pos_RSAKeyValue;
219             ++m_pos_XMLObject;
220         }
221         
222         IMPL_XMLOBJECT_CLONE(KeyValue);
223         IMPL_XMLOBJECT_CHILD(DSAKeyValue);
224         IMPL_XMLOBJECT_CHILD(RSAKeyValue);
225         IMPL_XMLOBJECT_CHILD(XMLObject);
226         IMPL_XMLOBJECT_CONTENT;
227
228     protected:
229         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
230             PROC_XMLOBJECT_CHILD(DSAKeyValue,XMLConstants::XMLSIG_NS);
231             PROC_XMLOBJECT_CHILD(RSAKeyValue,XMLConstants::XMLSIG_NS);
232             
233             // Unknown child.
234             const XMLCh* nsURI=root->getNamespaceURI();
235             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
236                 setXMLObject(childXMLObject);
237             
238             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
239         }
240     };
241
242     class XMLTOOL_DLLLOCAL TransformImpl : public Transform,
243         public AbstractDOMCachingXMLObject,
244         public AbstractElementProxy,
245         public AbstractValidatingXMLObject,
246         public AbstractXMLObjectMarshaller,
247         public AbstractXMLObjectUnmarshaller
248     {
249     public:
250         virtual ~TransformImpl() {
251             XMLString::release(&m_Algorithm);
252         }
253
254         TransformImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
255             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Algorithm(NULL) {
256         }
257             
258         TransformImpl(const TransformImpl& src)
259                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractElementProxy(src),
260                     AbstractValidatingXMLObject(src), m_Algorithm(XMLString::replicate(src.m_Algorithm)) {
261             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
262                 if (*i) {
263                     XPath* x=dynamic_cast<XPath*>(*i);
264                     if (x) {
265                         getXPaths().push_back(x->cloneXPath());
266                         continue;
267                     }
268                     getXMLObjects().push_back((*i)->clone());
269                 }
270             }
271         }
272         
273         IMPL_XMLOBJECT_CLONE(Transform);
274         IMPL_XMLOBJECT_ATTRIB(Algorithm);
275         IMPL_XMLOBJECT_CHILDREN(XPath,m_children.end());
276         IMPL_XMLOBJECT_CONTENT;
277
278     protected:
279         void marshallAttributes(DOMElement* domElement) const {
280             MARSHALL_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM,NULL);
281         }
282
283         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
284             PROC_XMLOBJECT_CHILDREN(XPath,XMLConstants::XMLSIG_NS);
285             
286             // Unknown child.
287             const XMLCh* nsURI=root->getNamespaceURI();
288             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
289                 getXMLObjects().push_back(childXMLObject);
290             
291             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
292         }
293
294         void processAttribute(const DOMAttr* attribute) {
295             PROC_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM,NULL);
296         }
297     };
298
299     class XMLTOOL_DLLLOCAL TransformsImpl : public Transforms,
300         public AbstractComplexElement,
301         public AbstractDOMCachingXMLObject,
302         public AbstractValidatingXMLObject,
303         public AbstractXMLObjectMarshaller,
304         public AbstractXMLObjectUnmarshaller
305     {
306     public:
307         virtual ~TransformsImpl() {}
308
309         TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
310             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
311         }
312             
313         TransformsImpl(const TransformsImpl& src)
314                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
315             VectorOf(Transform) v=getTransforms();
316             for (vector<Transform*>::const_iterator i=src.m_Transforms.begin(); i!=src.m_Transforms.end(); i++) {
317                 if (*i) {
318                     v.push_back((*i)->cloneTransform());
319                 }
320             }
321         }
322         
323         IMPL_XMLOBJECT_CLONE(Transforms);
324         IMPL_XMLOBJECT_CHILDREN(Transform,m_children.end());
325
326     protected:
327         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
328             PROC_XMLOBJECT_CHILDREN(Transform,XMLConstants::XMLSIG_NS);
329             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
330         }
331     };
332
333     class XMLTOOL_DLLLOCAL RetrievalMethodImpl : public RetrievalMethod,
334         public AbstractComplexElement,
335         public AbstractDOMCachingXMLObject,
336         public AbstractValidatingXMLObject,
337         public AbstractXMLObjectMarshaller,
338         public AbstractXMLObjectUnmarshaller
339     {
340     public:
341         virtual ~RetrievalMethodImpl() {
342             XMLString::release(&m_URI);
343             XMLString::release(&m_Type);
344         }
345
346         RetrievalMethodImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
347             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
348             init();
349         }
350             
351         RetrievalMethodImpl(const RetrievalMethodImpl& src)
352                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
353             init();
354             setURI(getURI());
355             setType(getType());
356             if (src.getTransforms())
357                 setTransforms(src.getTransforms()->cloneTransforms());
358         }
359         
360         void init() {
361             m_URI=m_Type=NULL;
362             m_Transforms=NULL;
363             m_children.push_back(NULL);
364             m_pos_Transforms=m_children.begin();
365         }
366         
367         IMPL_XMLOBJECT_CLONE(RetrievalMethod);
368         IMPL_XMLOBJECT_ATTRIB(URI);
369         IMPL_XMLOBJECT_ATTRIB(Type);
370         IMPL_XMLOBJECT_CHILD(Transforms);
371
372     protected:
373         void marshallAttributes(DOMElement* domElement) const {
374             MARSHALL_XMLOBJECT_ATTRIB(URI,URI,NULL);
375             MARSHALL_XMLOBJECT_ATTRIB(Type,TYPE,NULL);
376         }
377
378         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
379             PROC_XMLOBJECT_CHILD(Transforms,XMLConstants::XMLSIG_NS);
380             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
381         }
382
383         void processAttribute(const DOMAttr* attribute) {
384             PROC_XMLOBJECT_ATTRIB(URI,URI,NULL);
385             PROC_XMLOBJECT_ATTRIB(Type,TYPE,NULL);
386         }
387     };
388
389     class XMLTOOL_DLLLOCAL X509IssuerSerialImpl : public X509IssuerSerial,
390         public AbstractComplexElement,
391         public AbstractDOMCachingXMLObject,
392         public AbstractValidatingXMLObject,
393         public AbstractXMLObjectMarshaller,
394         public AbstractXMLObjectUnmarshaller
395     {
396     public:
397         virtual ~X509IssuerSerialImpl() {}
398
399         X509IssuerSerialImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
400                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
401             init();
402         }
403             
404         X509IssuerSerialImpl(const X509IssuerSerialImpl& src)
405                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
406             init();
407             if (src.getX509IssuerName())
408                 setX509IssuerName(src.getX509IssuerName()->cloneX509IssuerName());
409             if (src.getX509SerialNumber())
410                 setX509SerialNumber(src.getX509SerialNumber()->cloneX509SerialNumber());
411         }
412         
413         void init() {
414             m_X509IssuerName=NULL;
415             m_X509SerialNumber=NULL;
416             m_children.push_back(NULL);
417             m_children.push_back(NULL);
418             m_pos_X509IssuerName=m_children.begin();
419             m_pos_X509SerialNumber=m_pos_X509IssuerName;
420             ++m_pos_X509SerialNumber;
421         }
422         
423         IMPL_XMLOBJECT_CLONE(X509IssuerSerial);
424         IMPL_XMLOBJECT_CHILD(X509IssuerName);
425         IMPL_XMLOBJECT_CHILD(X509SerialNumber);
426
427     protected:
428         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
429             PROC_XMLOBJECT_CHILD(X509IssuerName,XMLConstants::XMLSIG_NS);
430             PROC_XMLOBJECT_CHILD(X509SerialNumber,XMLConstants::XMLSIG_NS);
431             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
432         }
433     };
434
435     class XMLTOOL_DLLLOCAL X509DataImpl : public X509Data,
436         public AbstractComplexElement,
437         public AbstractDOMCachingXMLObject,
438         public AbstractValidatingXMLObject,
439         public AbstractXMLObjectMarshaller,
440         public AbstractXMLObjectUnmarshaller
441     {
442     public:
443         virtual ~X509DataImpl() {}
444
445         X509DataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
446             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
447         }
448             
449         X509DataImpl(const X509DataImpl& src)
450                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
451             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
452                 if (*i) {
453                     X509Certificate* xcert=dynamic_cast<X509Certificate*>(*i);
454                     if (xcert) {
455                         getX509Certificates().push_back(xcert->cloneX509Certificate());
456                         continue;
457                     }
458
459                     X509CRL* xcrl=dynamic_cast<X509CRL*>(*i);
460                     if (xcrl) {
461                         getX509CRLs().push_back(xcrl->cloneX509CRL());
462                         continue;
463                     }
464
465                     X509SubjectName* xsn=dynamic_cast<X509SubjectName*>(*i);
466                     if (xsn) {
467                         getX509SubjectNames().push_back(xsn->cloneX509SubjectName());
468                         continue;
469                     }
470
471                     X509IssuerSerial* xis=dynamic_cast<X509IssuerSerial*>(*i);
472                     if (xis) {
473                         getX509IssuerSerials().push_back(xis->cloneX509IssuerSerial());
474                         continue;
475                     }
476
477                     X509SKI* xski=dynamic_cast<X509SKI*>(*i);
478                     if (xski) {
479                         getX509SKIs().push_back(xski->cloneX509SKI());
480                         continue;
481                     }
482
483                     getXMLObjects().push_back((*i)->clone());
484                 }
485             }
486         }
487         
488         IMPL_XMLOBJECT_CLONE(X509Data);
489         IMPL_XMLOBJECT_CHILDREN(X509IssuerSerial,m_children.end());
490         IMPL_XMLOBJECT_CHILDREN(X509SKI,m_children.end());
491         IMPL_XMLOBJECT_CHILDREN(X509SubjectName,m_children.end());
492         IMPL_XMLOBJECT_CHILDREN(X509Certificate,m_children.end());
493         IMPL_XMLOBJECT_CHILDREN(X509CRL,m_children.end());
494         IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
495
496     protected:
497         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
498             PROC_XMLOBJECT_CHILDREN(X509IssuerSerial,XMLConstants::XMLSIG_NS);
499             PROC_XMLOBJECT_CHILDREN(X509SKI,XMLConstants::XMLSIG_NS);
500             PROC_XMLOBJECT_CHILDREN(X509SubjectName,XMLConstants::XMLSIG_NS);
501             PROC_XMLOBJECT_CHILDREN(X509Certificate,XMLConstants::XMLSIG_NS);
502             PROC_XMLOBJECT_CHILDREN(X509CRL,XMLConstants::XMLSIG_NS);
503             
504             // Unknown child.
505             const XMLCh* nsURI=root->getNamespaceURI();
506             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
507                 getXMLObjects().push_back(childXMLObject);
508             
509             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
510         }
511     };
512
513     class XMLTOOL_DLLLOCAL SPKIDataImpl : public SPKIData,
514         public AbstractComplexElement,
515         public AbstractDOMCachingXMLObject,
516         public AbstractValidatingXMLObject,
517         public AbstractXMLObjectMarshaller,
518         public AbstractXMLObjectUnmarshaller
519     {
520     public:
521         virtual ~SPKIDataImpl() {}
522
523         SPKIDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
524             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
525         }
526             
527         SPKIDataImpl(const SPKIDataImpl& src)
528                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
529             VectorOfPairs(SPKISexp,XMLObject) v=getSPKISexps();
530             for (vector< pair<SPKISexp*,XMLObject*> >::const_iterator i=src.m_SPKISexps.begin(); i!=src.m_SPKISexps.end(); i++) {
531                 if (i->first) {
532                     v.push_back(make_pair(i->first->cloneSPKISexp(),(i->second ? i->second->clone() : (XMLObject*)NULL)));
533                 }
534             }
535         }
536         
537         IMPL_XMLOBJECT_CLONE(SPKIData);
538
539     private:
540         vector< pair<SPKISexp*,XMLObject*> > m_SPKISexps;
541
542     public:
543         VectorOfPairs(SPKISexp,XMLObject) getSPKISexps() {
544             return VectorOfPairs(SPKISexp,XMLObject)(this, m_SPKISexps, &m_children, m_children.end());
545         }
546         
547         const vector< pair<SPKISexp*,XMLObject*> >& getSPKISexps() const {
548             return m_SPKISexps;
549         }
550         
551     protected:
552         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
553             if (XMLHelper::isNodeNamed(root,XMLConstants::XMLSIG_NS,SPKISexp::LOCAL_NAME)) {
554                 SPKISexp* typesafe=dynamic_cast<SPKISexp*>(childXMLObject);
555                 if (typesafe) {
556                     getSPKISexps().push_back(make_pair(typesafe,(XMLObject*)NULL));
557                     return;
558                 }
559             }
560
561             // Unknown child (has to be paired with the last SPKISexp processed.
562             const XMLCh* nsURI=root->getNamespaceURI();
563             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI) {
564                 // Update second half of pair in vector, then add to master list.
565                 if (m_SPKISexps.back().second==NULL) {
566                     m_SPKISexps.back().second=childXMLObject;
567                     m_children.push_back(childXMLObject);
568                 }
569                 else
570                     throw UnmarshallingException("Extension element must follow ds:SPKISexp element.");
571             }
572             
573             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
574         }
575     };
576
577     class XMLTOOL_DLLLOCAL PGPDataImpl : public PGPData,
578         public AbstractComplexElement,
579         public AbstractDOMCachingXMLObject,
580         public AbstractValidatingXMLObject,
581         public AbstractXMLObjectMarshaller,
582         public AbstractXMLObjectUnmarshaller
583     {
584     public:
585         virtual ~PGPDataImpl() {}
586
587         PGPDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
588                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
589             init();
590         }
591             
592         PGPDataImpl(const PGPDataImpl& src)
593                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
594             init();
595             if (src.getPGPKeyID())
596                 setPGPKeyID(src.getPGPKeyID()->clonePGPKeyID());
597             if (src.getPGPKeyPacket())
598                 setPGPKeyPacket(src.getPGPKeyPacket()->clonePGPKeyPacket());
599             VectorOf(XMLObject) v=getXMLObjects();
600             for (vector<XMLObject*>::const_iterator i=src.m_XMLObjects.begin(); i!=src.m_XMLObjects.end(); i++) {
601                 if (*i) {
602                     v.push_back((*i)->clone());
603                 }
604             }
605         }
606         
607         void init() {
608             m_PGPKeyID=NULL;
609             m_PGPKeyPacket=NULL;
610             m_children.push_back(NULL);
611             m_children.push_back(NULL);
612             m_pos_PGPKeyID=m_children.begin();
613             m_pos_PGPKeyPacket=m_pos_PGPKeyID;
614             ++m_pos_PGPKeyPacket;
615         }
616         
617         IMPL_XMLOBJECT_CLONE(PGPData);
618         IMPL_XMLOBJECT_CHILD(PGPKeyID);
619         IMPL_XMLOBJECT_CHILD(PGPKeyPacket);
620         IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
621
622     protected:
623         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
624             PROC_XMLOBJECT_CHILD(PGPKeyID,XMLConstants::XMLSIG_NS);
625             PROC_XMLOBJECT_CHILD(PGPKeyPacket,XMLConstants::XMLSIG_NS);
626
627             // Unknown child.
628             const XMLCh* nsURI=root->getNamespaceURI();
629             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
630                 getXMLObjects().push_back(childXMLObject);
631
632             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
633         }
634     };
635
636     class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo,
637         public AbstractComplexElement,
638         public AbstractSimpleElement,
639         public AbstractDOMCachingXMLObject,
640         public AbstractValidatingXMLObject,
641         public AbstractXMLObjectMarshaller,
642         public AbstractXMLObjectUnmarshaller
643     {
644     public:
645         virtual ~KeyInfoImpl() {
646             XMLString::release(&m_Id);
647         }
648
649         KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
650             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {
651         }
652             
653         KeyInfoImpl(const KeyInfoImpl& src)
654                 : AbstractXMLObject(src),
655                     AbstractSimpleElement(src),
656                     AbstractDOMCachingXMLObject(src),
657                     AbstractValidatingXMLObject(src),
658                     m_Id(XMLString::replicate(src.m_Id)) {
659
660             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
661                 if (*i) {
662                     X509Data* xd=dynamic_cast<X509Data*>(*i);
663                     if (xd) {
664                         getX509Datas().push_back(xd->cloneX509Data());
665                         continue;
666                     }
667
668                     KeyName* kn=dynamic_cast<KeyName*>(*i);
669                     if (kn) {
670                         getKeyNames().push_back(kn->cloneKeyName());
671                         continue;
672                     }
673
674                     KeyValue* kv=dynamic_cast<KeyValue*>(*i);
675                     if (kv) {
676                         getKeyValues().push_back(kv->cloneKeyValue());
677                         continue;
678                     }
679
680                     RetrievalMethod* rm=dynamic_cast<RetrievalMethod*>(*i);
681                     if (rm) {
682                         getRetrievalMethods().push_back(rm->cloneRetrievalMethod());
683                         continue;
684                     }
685
686                     MgmtData* md=dynamic_cast<MgmtData*>(*i);
687                     if (md) {
688                         getMgmtDatas().push_back(md->cloneMgmtData());
689                         continue;
690                     }
691
692                     SPKIData* sd=dynamic_cast<SPKIData*>(*i);
693                     if (sd) {
694                         getSPKIDatas().push_back(sd->cloneSPKIData());
695                         continue;
696                     }
697
698                     PGPData* pd=dynamic_cast<PGPData*>(*i);
699                     if (pd) {
700                         getPGPDatas().push_back(pd->clonePGPData());
701                         continue;
702                     }
703
704                     getXMLObjects().push_back((*i)->clone());
705                 }
706             }
707         }
708         
709         IMPL_XMLOBJECT_CLONE(KeyInfo);
710         IMPL_XMLOBJECT_ATTRIB(Id);
711         IMPL_XMLOBJECT_CHILDREN(KeyName,m_children.end());
712         IMPL_XMLOBJECT_CHILDREN(KeyValue,m_children.end());
713         IMPL_XMLOBJECT_CHILDREN(RetrievalMethod,m_children.end());
714         IMPL_XMLOBJECT_CHILDREN(X509Data,m_children.end());
715         IMPL_XMLOBJECT_CHILDREN(MgmtData,m_children.end());
716         IMPL_XMLOBJECT_CHILDREN(SPKIData,m_children.end());
717         IMPL_XMLOBJECT_CHILDREN(PGPData,m_children.end());
718         IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
719         IMPL_XMLOBJECT_CONTENT;
720
721     protected:
722         void marshallAttributes(DOMElement* domElement) const {
723             MARSHALL_XMLOBJECT_ID_ATTRIB(Id,ID,NULL);
724         }
725
726         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
727             PROC_XMLOBJECT_CHILDREN(X509Data,XMLConstants::XMLSIG_NS);
728             PROC_XMLOBJECT_CHILDREN(KeyName,XMLConstants::XMLSIG_NS);
729             PROC_XMLOBJECT_CHILDREN(KeyValue,XMLConstants::XMLSIG_NS);
730             PROC_XMLOBJECT_CHILDREN(RetrievalMethod,XMLConstants::XMLSIG_NS);
731             PROC_XMLOBJECT_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS);
732             PROC_XMLOBJECT_CHILDREN(SPKIData,XMLConstants::XMLSIG_NS);
733             PROC_XMLOBJECT_CHILDREN(PGPData,XMLConstants::XMLSIG_NS);
734             
735             // Unknown child.
736             const XMLCh* nsURI=root->getNamespaceURI();
737             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
738                 getXMLObjects().push_back(childXMLObject);
739             
740             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
741         }
742
743         void processAttribute(const DOMAttr* attribute) {
744             PROC_XMLOBJECT_ID_ATTRIB(Id,ID,NULL);
745         }
746     };
747     
748     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,KeyName);
749     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,MgmtData);
750     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Modulus);
751     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Exponent);
752     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Seed);
753     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PgenCounter);
754     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,P);
755     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Q);
756     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,G);
757     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Y);
758     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,J);
759     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,XPath);
760     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509IssuerName);
761     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509SerialNumber);
762     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509SKI);
763     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509SubjectName);
764     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509Certificate);
765     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509CRL);
766     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,SPKISexp);
767     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PGPKeyID);
768     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PGPKeyPacket);
769 };
770
771 #if defined (_MSC_VER)
772     #pragma warning( pop )
773 #endif
774
775 // Builder Implementations
776
777 IMPL_XMLOBJECTBUILDER(X509IssuerSerial);
778 IMPL_XMLOBJECTBUILDER(X509IssuerName);
779 IMPL_XMLOBJECTBUILDER(X509SerialNumber);
780 IMPL_XMLOBJECTBUILDER(X509SKI);
781 IMPL_XMLOBJECTBUILDER(X509SubjectName);
782 IMPL_XMLOBJECTBUILDER(X509Certificate);
783 IMPL_XMLOBJECTBUILDER(X509CRL);
784 IMPL_XMLOBJECTBUILDER(X509Data);
785 IMPL_XMLOBJECTBUILDER(XPath);
786 IMPL_XMLOBJECTBUILDER(Transform);
787 IMPL_XMLOBJECTBUILDER(Transforms);
788 IMPL_XMLOBJECTBUILDER(RetrievalMethod);
789 IMPL_XMLOBJECTBUILDER(KeyName);
790 IMPL_XMLOBJECTBUILDER(MgmtData);
791 IMPL_XMLOBJECTBUILDER(Modulus);
792 IMPL_XMLOBJECTBUILDER(Exponent);
793 IMPL_XMLOBJECTBUILDER(Seed);
794 IMPL_XMLOBJECTBUILDER(PgenCounter);
795 IMPL_XMLOBJECTBUILDER(P);
796 IMPL_XMLOBJECTBUILDER(Q);
797 IMPL_XMLOBJECTBUILDER(G);
798 IMPL_XMLOBJECTBUILDER(Y);
799 IMPL_XMLOBJECTBUILDER(J);
800 IMPL_XMLOBJECTBUILDER(DSAKeyValue);
801 IMPL_XMLOBJECTBUILDER(RSAKeyValue);
802 IMPL_XMLOBJECTBUILDER(KeyValue);
803 IMPL_XMLOBJECTBUILDER(KeyInfo);
804 IMPL_XMLOBJECTBUILDER(SPKISexp);
805 IMPL_XMLOBJECTBUILDER(SPKIData);
806 IMPL_XMLOBJECTBUILDER(PGPKeyID);
807 IMPL_XMLOBJECTBUILDER(PGPKeyPacket);
808 IMPL_XMLOBJECTBUILDER(PGPData);
809
810 // Unicode literals
811
812 const XMLCh KeyInfo::LOCAL_NAME[] =             UNICODE_LITERAL_7(K,e,y,I,n,f,o);
813 const XMLCh KeyInfo::TYPE_NAME[] =              UNICODE_LITERAL_11(K,e,y,I,n,f,o,T,y,p,e);
814 const XMLCh KeyInfo::ID_ATTRIB_NAME[] =         UNICODE_LITERAL_2(I,d);
815 const XMLCh KeyValue::LOCAL_NAME[] =            UNICODE_LITERAL_8(K,e,y,V,a,l,u,e);
816 const XMLCh KeyValue::TYPE_NAME[] =             UNICODE_LITERAL_12(K,e,y,V,a,l,u,e,T,y,p,e);
817 const XMLCh DSAKeyValue::LOCAL_NAME[] =         UNICODE_LITERAL_11(D,S,A,K,e,y,V,a,l,u,e);
818 const XMLCh DSAKeyValue::TYPE_NAME[] =          UNICODE_LITERAL_15(D,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
819 const XMLCh RSAKeyValue::LOCAL_NAME[] =         UNICODE_LITERAL_11(R,S,A,K,e,y,V,a,l,u,e);
820 const XMLCh RSAKeyValue::TYPE_NAME[] =          UNICODE_LITERAL_15(R,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
821 const XMLCh MgmtData::LOCAL_NAME[] =            UNICODE_LITERAL_8(M,g,m,t,D,a,t,a);
822 const XMLCh KeyName::LOCAL_NAME[] =             UNICODE_LITERAL_7(K,e,y,N,a,m,e);
823 const XMLCh Modulus::LOCAL_NAME[] =             UNICODE_LITERAL_7(M,o,d,u,l,u,s);
824 const XMLCh Exponent::LOCAL_NAME[] =            UNICODE_LITERAL_8(E,x,p,o,n,e,n,t);
825 const XMLCh Seed::LOCAL_NAME[] =                UNICODE_LITERAL_4(S,e,e,d);
826 const XMLCh PgenCounter::LOCAL_NAME[] =         UNICODE_LITERAL_11(P,g,e,n,C,o,u,n,t,e,r);
827 const XMLCh P::LOCAL_NAME[] =                   UNICODE_LITERAL_1(P);
828 const XMLCh Q::LOCAL_NAME[] =                   UNICODE_LITERAL_1(Q);
829 const XMLCh G::LOCAL_NAME[] =                   UNICODE_LITERAL_1(G);
830 const XMLCh Y::LOCAL_NAME[] =                   UNICODE_LITERAL_1(Y);
831 const XMLCh J::LOCAL_NAME[] =                   UNICODE_LITERAL_1(J);
832 const XMLCh XPath::LOCAL_NAME[] =               UNICODE_LITERAL_5(X,P,a,t,h);
833 const XMLCh Transform::LOCAL_NAME[] =           UNICODE_LITERAL_9(T,r,a,n,s,f,o,r,m);
834 const XMLCh Transform::TYPE_NAME[] =            UNICODE_LITERAL_13(T,r,a,n,s,f,o,r,m,T,y,p,e);
835 const XMLCh Transform::ALGORITHM_ATTRIB_NAME[] = UNICODE_LITERAL_9(A,l,g,o,r,i,t,h,m);
836 const XMLCh Transforms::LOCAL_NAME[] =          UNICODE_LITERAL_10(T,r,a,n,s,f,o,r,m,s);
837 const XMLCh Transforms::TYPE_NAME[] =           UNICODE_LITERAL_14(T,r,a,n,s,f,o,r,m,s,T,y,p,e);
838 const XMLCh RetrievalMethod::LOCAL_NAME[] =     UNICODE_LITERAL_15(R,e,t,r,i,e,v,a,l,M,e,t,h,o,d);
839 const XMLCh RetrievalMethod::TYPE_NAME[] =      UNICODE_LITERAL_19(R,e,t,r,i,e,v,a,l,M,e,t,h,o,d,T,y,p,e);
840 const XMLCh RetrievalMethod::URI_ATTRIB_NAME[] = UNICODE_LITERAL_3(U,R,I);
841 const XMLCh RetrievalMethod::TYPE_ATTRIB_NAME[] = UNICODE_LITERAL_4(T,y,p,e);
842 const XMLCh SPKISexp::LOCAL_NAME[] =            UNICODE_LITERAL_8(S,P,K,I,S,e,x,p);
843 const XMLCh SPKIData::LOCAL_NAME[] =            UNICODE_LITERAL_8(S,P,K,I,D,a,t,a);
844 const XMLCh SPKIData::TYPE_NAME[] =             UNICODE_LITERAL_12(S,P,K,I,D,a,t,a,T,y,p,e);
845 const XMLCh PGPKeyID::LOCAL_NAME[] =            UNICODE_LITERAL_8(P,G,P,K,e,y,I,D);
846 const XMLCh PGPKeyPacket::LOCAL_NAME[] =        UNICODE_LITERAL_12(P,G,P,K,e,y,P,a,c,k,e,t);
847 const XMLCh PGPData::LOCAL_NAME[] =             UNICODE_LITERAL_7(P,G,P,D,a,t,a);
848 const XMLCh PGPData::TYPE_NAME[] =              UNICODE_LITERAL_11(P,G,P,D,a,t,a,T,y,p,e);
849
850 #define XCH(ch) chLatin_##ch
851 #define XNUM(d) chDigit_##d
852
853 const XMLCh X509Data::LOCAL_NAME[] = {
854     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(D), XCH(a), XCH(t), XCH(a), chNull
855     };
856 const XMLCh X509Data::TYPE_NAME[] = {
857     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(D), XCH(a), XCH(t), XCH(a), XCH(T), XCH(y), XCH(p), XCH(e), chNull
858     };
859 const XMLCh X509IssuerSerial::LOCAL_NAME[] = {
860     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(I), XCH(s), XCH(s), XCH(u), XCH(e), XCH(r),
861     XCH(S), XCH(e), XCH(r), XCH(i), XCH(a), XCH(l), chNull
862     };
863 const XMLCh X509IssuerSerial::TYPE_NAME[] = {
864     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(I), XCH(s), XCH(s), XCH(u), XCH(e), XCH(r),
865     XCH(S), XCH(e), XCH(r), XCH(i), XCH(a), XCH(l), XCH(T), XCH(y), XCH(p), XCH(e), chNull
866     };
867 const XMLCh X509IssuerName::LOCAL_NAME[] = {
868     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(I), XCH(s), XCH(s), XCH(u), XCH(e), XCH(r),
869     XCH(N), XCH(a), XCH(m), XCH(e), chNull
870     };
871 const XMLCh X509SerialNumber::LOCAL_NAME[] = {
872     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(S), XCH(e), XCH(r), XCH(i), XCH(a), XCH(l),
873     XCH(N), XCH(u), XCH(m), XCH(b), XCH(e), XCH(r), chNull
874     };
875 const XMLCh X509SKI::LOCAL_NAME[] = { XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(S), XCH(K), XCH(I), chNull };
876 const XMLCh X509SubjectName::LOCAL_NAME[] = {
877     XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(S), XCH(u), XCH(b), XCH(j), XCH(e), XCH(c), XCH(t),
878     XCH(N), XCH(a), XCH(m), XCH(e), chNull
879     };
880 const XMLCh X509Certificate::LOCAL_NAME[] = {
881     XCH(X), XNUM(5), XNUM(0), XNUM(9),
882     XCH(C), XCH(e), XCH(r), XCH(t), XCH(i), XCH(f), XCH(i), XCH(c), XCH(a), XCH(t), XCH(e), chNull
883     };
884 const XMLCh X509CRL::LOCAL_NAME[] = { XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(C), XCH(R), XCH(L), chNull };
885