Moved signature classes into own namespace.
[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 "AbstractElementProxy.h"
25 #include "exceptions.h"
26 #include "io/AbstractXMLObjectMarshaller.h"
27 #include "io/AbstractXMLObjectUnmarshaller.h"
28 #include "signature/KeyInfo.h"
29 #include "util/XMLHelper.h"
30 #include "validation/AbstractValidatingXMLObject.h"
31
32 #include <xercesc/util/XMLUniDefs.hpp>
33
34 using namespace xmlsignature;
35 using namespace xmltooling;
36 using namespace std;
37
38 #if defined (_MSC_VER)
39     #pragma warning( push )
40     #pragma warning( disable : 4250 4251 )
41 #endif
42
43 namespace xmlsignature {
44     
45     class XMLTOOL_DLLLOCAL DSAKeyValueImpl : public DSAKeyValue,
46         public AbstractDOMCachingXMLObject,
47         public AbstractValidatingXMLObject,
48         public AbstractXMLObjectMarshaller,
49         public AbstractXMLObjectUnmarshaller
50     {
51     public:
52         virtual ~DSAKeyValueImpl() {}
53
54         DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
55             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
56             init();
57         }
58             
59         DSAKeyValueImpl(const DSAKeyValueImpl& src)
60                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
61             init();
62             setP(src.getP());
63             setQ(src.getQ());
64             setG(src.getG());
65             setY(src.getY());
66             setJ(src.getJ());
67             setSeed(src.getSeed());
68             setPgenCounter(src.getPgenCounter());
69         }
70         
71         void init() {
72             m_P=NULL;
73             m_Q=NULL;
74             m_G=NULL;
75             m_Y=NULL;
76             m_J=NULL;
77             m_Seed=NULL;
78             m_PgenCounter=NULL;
79             m_children.push_back(NULL);
80             m_children.push_back(NULL);
81             m_children.push_back(NULL);
82             m_children.push_back(NULL);
83             m_children.push_back(NULL);
84             m_children.push_back(NULL);
85             m_children.push_back(NULL);
86             m_pos_P=m_children.begin();
87             m_pos_Q=m_pos_P;
88             ++m_pos_Q;
89             m_pos_G=m_pos_Q;
90             ++m_pos_G;
91             m_pos_Y=m_pos_G;
92             ++m_pos_Y;
93             m_pos_J=m_pos_Y;
94             ++m_pos_J;
95             m_pos_Seed=m_pos_J;
96             ++m_pos_Seed;
97             m_pos_PgenCounter=m_pos_Seed;
98             ++m_pos_PgenCounter;
99         }
100         
101         IMPL_XMLOBJECT_CLONE(DSAKeyValue);
102         IMPL_XMLOBJECT_CHILD(P);
103         IMPL_XMLOBJECT_CHILD(Q);
104         IMPL_XMLOBJECT_CHILD(G);
105         IMPL_XMLOBJECT_CHILD(Y);
106         IMPL_XMLOBJECT_CHILD(J);
107         IMPL_XMLOBJECT_CHILD(Seed);
108         IMPL_XMLOBJECT_CHILD(PgenCounter);
109
110     protected:
111         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
112             PROC_XMLOBJECT_CHILD(P,XMLConstants::XMLSIG_NS);
113             PROC_XMLOBJECT_CHILD(Q,XMLConstants::XMLSIG_NS);
114             PROC_XMLOBJECT_CHILD(G,XMLConstants::XMLSIG_NS);
115             PROC_XMLOBJECT_CHILD(Y,XMLConstants::XMLSIG_NS);
116             PROC_XMLOBJECT_CHILD(J,XMLConstants::XMLSIG_NS);
117             PROC_XMLOBJECT_CHILD(Seed,XMLConstants::XMLSIG_NS);
118             PROC_XMLOBJECT_CHILD(PgenCounter,XMLConstants::XMLSIG_NS);
119             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
120         }
121     };
122
123     class XMLTOOL_DLLLOCAL RSAKeyValueImpl : public RSAKeyValue,
124         public AbstractDOMCachingXMLObject,
125         public AbstractValidatingXMLObject,
126         public AbstractXMLObjectMarshaller,
127         public AbstractXMLObjectUnmarshaller
128     {
129     public:
130         virtual ~RSAKeyValueImpl() {}
131
132         RSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
133                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
134             init();
135         }
136             
137         RSAKeyValueImpl(const RSAKeyValueImpl& src)
138                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
139             init();
140             setModulus(src.getModulus());
141             setExponent(src.getExponent());
142         }
143         
144         void init() {
145             m_Modulus=NULL;
146             m_Exponent=NULL;
147             m_children.push_back(NULL);
148             m_children.push_back(NULL);
149             m_pos_Modulus=m_children.begin();
150             m_pos_Exponent=m_pos_Modulus;
151             ++m_pos_Exponent;
152         }
153         
154         IMPL_XMLOBJECT_CLONE(RSAKeyValue);
155         IMPL_XMLOBJECT_CHILD(Modulus);
156         IMPL_XMLOBJECT_CHILD(Exponent);
157
158     protected:
159         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
160             PROC_XMLOBJECT_CHILD(Modulus,XMLConstants::XMLSIG_NS);
161             PROC_XMLOBJECT_CHILD(Exponent,XMLConstants::XMLSIG_NS);
162             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
163         }
164     };
165
166     class XMLTOOL_DLLLOCAL KeyValueImpl : public KeyValue,
167         public AbstractDOMCachingXMLObject,
168         public AbstractValidatingXMLObject,
169         public AbstractXMLObjectMarshaller,
170         public AbstractXMLObjectUnmarshaller
171     {
172     public:
173         virtual ~KeyValueImpl() {}
174
175         KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
176                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
177             init();
178         }
179             
180         KeyValueImpl(const KeyValueImpl& src)
181                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
182             init();
183             setDSAKeyValue(src.getDSAKeyValue());
184             setRSAKeyValue(src.getRSAKeyValue());
185             setXMLObject(src.getXMLObject());
186             setTextContent(src.getTextContent());
187         }
188         
189         void init() {
190             m_TextContent=NULL;
191             m_DSAKeyValue=NULL;
192             m_RSAKeyValue=NULL;
193             m_XMLObject=NULL;
194             m_children.push_back(NULL);
195             m_children.push_back(NULL);
196             m_children.push_back(NULL);
197             m_pos_DSAKeyValue=m_children.begin();
198             m_pos_RSAKeyValue=m_pos_DSAKeyValue;
199             ++m_pos_RSAKeyValue;
200             m_pos_XMLObject=m_pos_RSAKeyValue;
201             ++m_pos_XMLObject;
202         }
203         
204         IMPL_XMLOBJECT_CLONE(KeyValue);
205         IMPL_XMLOBJECT_CHILD(DSAKeyValue);
206         IMPL_XMLOBJECT_CHILD(RSAKeyValue);
207         IMPL_XMLOBJECT_CHILD(XMLObject);
208         IMPL_XMLOBJECT_CONTENT(TextContent);
209
210     protected:
211         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
212             PROC_XMLOBJECT_CHILD(DSAKeyValue,XMLConstants::XMLSIG_NS);
213             PROC_XMLOBJECT_CHILD(RSAKeyValue,XMLConstants::XMLSIG_NS);
214             
215             // Unknown child.
216             const XMLCh* nsURI=root->getNamespaceURI();
217             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
218                 setXMLObject(childXMLObject);
219             
220             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
221         }
222     };
223
224     class XMLTOOL_DLLLOCAL TransformImpl : public Transform,
225         public AbstractDOMCachingXMLObject,
226         public AbstractElementProxy,
227         public AbstractValidatingXMLObject,
228         public AbstractXMLObjectMarshaller,
229         public AbstractXMLObjectUnmarshaller
230     {
231     public:
232         virtual ~TransformImpl() {}
233
234         TransformImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
235             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Algorithm(NULL) {
236         }
237             
238         TransformImpl(const TransformImpl& src)
239                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractElementProxy(src),
240                     AbstractValidatingXMLObject(src), m_Algorithm(XMLString::replicate(src.m_Algorithm)) {
241             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
242                 if (*i) {
243                     XPath* x=dynamic_cast<XPath*>(*i);
244                     if (x) {
245                         getXPaths().push_back(x->cloneXPath());
246                         continue;
247                     }
248                     getXMLObjects().push_back((*i)->clone());
249                 }
250             }
251         }
252         
253         IMPL_XMLOBJECT_CLONE(Transform);
254         IMPL_XMLOBJECT_ATTRIB(Algorithm);
255         IMPL_XMLOBJECT_CHILDREN(XPath,m_children.end());
256
257     protected:
258         void marshallAttributes(DOMElement* domElement) const {
259             MARSHALL_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM,NULL);
260         }
261
262         void marshallElementContent(DOMElement* domElement) const {
263             if(getTextContent()) {
264                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
265             }
266         }
267
268         void processElementContent(const XMLCh* elementContent) {
269             setTextContent(elementContent);
270         }
271
272         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
273             PROC_XMLOBJECT_CHILDREN(XPath,XMLConstants::XMLSIG_NS);
274             
275             // Unknown child.
276             const XMLCh* nsURI=root->getNamespaceURI();
277             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
278                 getXMLObjects().push_back(childXMLObject);
279             
280             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
281         }
282
283         void processAttribute(const DOMAttr* attribute) {
284             PROC_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM,NULL);
285         }
286     };
287
288     class XMLTOOL_DLLLOCAL TransformsImpl : public Transforms,
289         public AbstractDOMCachingXMLObject,
290         public AbstractValidatingXMLObject,
291         public AbstractXMLObjectMarshaller,
292         public AbstractXMLObjectUnmarshaller
293     {
294     public:
295         virtual ~TransformsImpl() {}
296
297         TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
298             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
299         }
300             
301         TransformsImpl(const TransformsImpl& src)
302                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
303             VectorOf(Transform) v=getTransforms();
304             for (vector<Transform*>::const_iterator i=src.m_Transforms.begin(); i!=src.m_Transforms.end(); i++) {
305                 if (*i) {
306                     v.push_back((*i)->cloneTransform());
307                 }
308             }
309         }
310         
311         IMPL_XMLOBJECT_CLONE(Transforms);
312         IMPL_XMLOBJECT_CHILDREN(Transform,m_children.end());
313
314     protected:
315         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
316             PROC_XMLOBJECT_CHILDREN(Transform,XMLConstants::XMLSIG_NS);
317             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
318         }
319     };
320
321     class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo,
322         public AbstractDOMCachingXMLObject,
323         public AbstractElementProxy,
324         public AbstractValidatingXMLObject,
325         public AbstractXMLObjectMarshaller,
326         public AbstractXMLObjectUnmarshaller
327     {
328     public:
329         virtual ~KeyInfoImpl() {}
330
331         KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
332             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {
333         }
334             
335         KeyInfoImpl(const KeyInfoImpl& src)
336                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractElementProxy(src),
337                     AbstractValidatingXMLObject(src), m_Id(XMLString::replicate(src.m_Id)) {
338             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
339                 if (*i) {
340                     KeyName* kn=dynamic_cast<KeyName*>(*i);
341                     if (kn) {
342                         getKeyNames().push_back(kn->cloneKeyName());
343                         continue;
344                     }
345                     KeyValue* kv=dynamic_cast<KeyValue*>(*i);
346                     if (kv) {
347                         getKeyValues().push_back(kv->cloneKeyValue());
348                         continue;
349                     }
350                     MgmtData* md=dynamic_cast<MgmtData*>(*i);
351                     if (md) {
352                         getMgmtDatas().push_back(md->cloneMgmtData());
353                         continue;
354                     }
355                     getXMLObjects().push_back((*i)->clone());
356                 }
357             }
358         }
359         
360         IMPL_XMLOBJECT_CLONE(KeyInfo);
361         IMPL_XMLOBJECT_ATTRIB(Id);
362         IMPL_XMLOBJECT_CHILDREN(KeyName,m_children.end());
363         IMPL_XMLOBJECT_CHILDREN(KeyValue,m_children.end());
364         IMPL_XMLOBJECT_CHILDREN(MgmtData,m_children.end());
365
366     protected:
367         void marshallAttributes(DOMElement* domElement) const {
368             MARSHALL_XMLOBJECT_ID_ATTRIB(Id,ID,NULL);
369         }
370
371         void marshallElementContent(DOMElement* domElement) const {
372             if(getTextContent()) {
373                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
374             }
375         }
376
377         void processElementContent(const XMLCh* elementContent) {
378             setTextContent(elementContent);
379         }
380
381         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
382             PROC_XMLOBJECT_CHILDREN(KeyName,XMLConstants::XMLSIG_NS);
383             PROC_XMLOBJECT_CHILDREN(KeyValue,XMLConstants::XMLSIG_NS);
384             PROC_XMLOBJECT_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS);
385             
386             // Unknown child.
387             const XMLCh* nsURI=root->getNamespaceURI();
388             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
389                 getXMLObjects().push_back(childXMLObject);
390             
391             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
392         }
393
394         void processAttribute(const DOMAttr* attribute) {
395             PROC_XMLOBJECT_ID_ATTRIB(Id,ID,NULL);
396         }
397     };
398     
399     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,KeyName,Name);
400     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,MgmtData,Data);
401     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Modulus,Value);
402     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Exponent,Value);
403     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Seed,Value);
404     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PgenCounter,Value);
405     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,P,Value);
406     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Q,Value);
407     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,G,Value);
408     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Y,Value);
409     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,J,Value);
410     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,XPath,Expression);
411 };
412
413 #if defined (_MSC_VER)
414     #pragma warning( pop )
415 #endif
416
417 // Builder Implementations
418
419 IMPL_XMLOBJECTBUILDER(XPath);
420 IMPL_XMLOBJECTBUILDER(Transform);
421 IMPL_XMLOBJECTBUILDER(Transforms);
422 IMPL_XMLOBJECTBUILDER(KeyName);
423 IMPL_XMLOBJECTBUILDER(MgmtData);
424 IMPL_XMLOBJECTBUILDER(Modulus);
425 IMPL_XMLOBJECTBUILDER(Exponent);
426 IMPL_XMLOBJECTBUILDER(Seed);
427 IMPL_XMLOBJECTBUILDER(PgenCounter);
428 IMPL_XMLOBJECTBUILDER(P);
429 IMPL_XMLOBJECTBUILDER(Q);
430 IMPL_XMLOBJECTBUILDER(G);
431 IMPL_XMLOBJECTBUILDER(Y);
432 IMPL_XMLOBJECTBUILDER(J);
433 IMPL_XMLOBJECTBUILDER(DSAKeyValue);
434 IMPL_XMLOBJECTBUILDER(RSAKeyValue);
435 IMPL_XMLOBJECTBUILDER(KeyValue);
436 IMPL_XMLOBJECTBUILDER(KeyInfo);
437
438 const XMLCh KeyInfo::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,I,n,f,o);
439 const XMLCh KeyInfo::TYPE_NAME[] =          UNICODE_LITERAL_11(K,e,y,I,n,f,o,T,y,p,e);
440 const XMLCh KeyInfo::ID_ATTRIB_NAME[] =     UNICODE_LITERAL_2(I,d);
441 const XMLCh KeyValue::LOCAL_NAME[] =        UNICODE_LITERAL_8(K,e,y,V,a,l,u,e);
442 const XMLCh KeyValue::TYPE_NAME[] =         UNICODE_LITERAL_12(K,e,y,V,a,l,u,e,T,y,p,e);
443 const XMLCh DSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(D,S,A,K,e,y,V,a,l,u,e);
444 const XMLCh DSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(D,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
445 const XMLCh RSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(R,S,A,K,e,y,V,a,l,u,e);
446 const XMLCh RSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(R,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
447 const XMLCh MgmtData::LOCAL_NAME[] =        UNICODE_LITERAL_8(M,g,m,t,D,a,t,a);
448 const XMLCh KeyName::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,N,a,m,e);
449 const XMLCh Modulus::LOCAL_NAME[] =         UNICODE_LITERAL_7(M,o,d,u,l,u,s);
450 const XMLCh Exponent::LOCAL_NAME[] =        UNICODE_LITERAL_8(E,x,p,o,n,e,n,t);
451 const XMLCh Seed::LOCAL_NAME[] =            UNICODE_LITERAL_4(S,e,e,d);
452 const XMLCh PgenCounter::LOCAL_NAME[] =     UNICODE_LITERAL_11(P,g,e,n,C,o,u,n,t,e,r);
453 const XMLCh P::LOCAL_NAME[] =               UNICODE_LITERAL_1(P);
454 const XMLCh Q::LOCAL_NAME[] =               UNICODE_LITERAL_1(Q);
455 const XMLCh G::LOCAL_NAME[] =               UNICODE_LITERAL_1(G);
456 const XMLCh Y::LOCAL_NAME[] =               UNICODE_LITERAL_1(Y);
457 const XMLCh J::LOCAL_NAME[] =               UNICODE_LITERAL_1(J);
458 const XMLCh XPath::LOCAL_NAME[] =           UNICODE_LITERAL_5(X,P,a,t,h);
459 const XMLCh Transform::LOCAL_NAME[] =       UNICODE_LITERAL_9(T,r,a,n,s,f,o,r,m);
460 const XMLCh Transform::TYPE_NAME[] =        UNICODE_LITERAL_13(T,r,a,n,s,f,o,r,m,T,y,p,e);
461 const XMLCh Transform::ALGORITHM_ATTRIB_NAME[] = UNICODE_LITERAL_9(A,l,g,o,r,i,t,h,m);
462 const XMLCh Transforms::LOCAL_NAME[] =      UNICODE_LITERAL_10(T,r,a,n,s,f,o,r,m,s);
463 const XMLCh Transforms::TYPE_NAME[] =       UNICODE_LITERAL_14(T,r,a,n,s,f,o,r,m,s,T,y,p,e);