More sample objects and macros.
[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 xmltooling;
35 using namespace std;
36
37 #if defined (_MSC_VER)
38     #pragma warning( push )
39     #pragma warning( disable : 4250 4251 )
40 #endif
41
42 namespace xmltooling {
43     
44     class XMLTOOL_DLLLOCAL DSAKeyValueImpl : public DSAKeyValue,
45         public AbstractDOMCachingXMLObject,
46         public AbstractValidatingXMLObject,
47         public AbstractXMLObjectMarshaller,
48         public AbstractXMLObjectUnmarshaller
49     {
50     public:
51         virtual ~DSAKeyValueImpl() {}
52
53         DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
54             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
55             init();
56         }
57             
58         DSAKeyValueImpl(const DSAKeyValueImpl& src)
59                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
60             init();
61             setP(src.getP());
62             setQ(src.getQ());
63             setG(src.getG());
64             setY(src.getY());
65             setJ(src.getJ());
66             setSeed(src.getSeed());
67             setPgenCounter(src.getPgenCounter());
68         }
69         
70         void init() {
71             m_P=NULL;
72             m_Q=NULL;
73             m_G=NULL;
74             m_Y=NULL;
75             m_J=NULL;
76             m_Seed=NULL;
77             m_PgenCounter=NULL;
78             m_children.push_back(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_pos_P=m_children.begin();
86             m_pos_Q=m_pos_P;
87             ++m_pos_Q;
88             m_pos_G=m_pos_Q;
89             ++m_pos_G;
90             m_pos_Y=m_pos_G;
91             ++m_pos_Y;
92             m_pos_J=m_pos_Y;
93             ++m_pos_J;
94             m_pos_Seed=m_pos_J;
95             ++m_pos_Seed;
96             m_pos_PgenCounter=m_pos_Seed;
97             ++m_pos_PgenCounter;
98         }
99         
100         IMPL_XMLOBJECT_CLONE(DSAKeyValue);
101         IMPL_XMLOBJECT_CHILD(P);
102         IMPL_XMLOBJECT_CHILD(Q);
103         IMPL_XMLOBJECT_CHILD(G);
104         IMPL_XMLOBJECT_CHILD(Y);
105         IMPL_XMLOBJECT_CHILD(J);
106         IMPL_XMLOBJECT_CHILD(Seed);
107         IMPL_XMLOBJECT_CHILD(PgenCounter);
108
109     protected:
110         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
111             PROC_XMLOBJECT_CHILD(P,XMLConstants::XMLSIG_NS);
112             PROC_XMLOBJECT_CHILD(Q,XMLConstants::XMLSIG_NS);
113             PROC_XMLOBJECT_CHILD(G,XMLConstants::XMLSIG_NS);
114             PROC_XMLOBJECT_CHILD(Y,XMLConstants::XMLSIG_NS);
115             PROC_XMLOBJECT_CHILD(J,XMLConstants::XMLSIG_NS);
116             PROC_XMLOBJECT_CHILD(Seed,XMLConstants::XMLSIG_NS);
117             PROC_XMLOBJECT_CHILD(PgenCounter,XMLConstants::XMLSIG_NS);
118             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
119         }
120     };
121
122     class XMLTOOL_DLLLOCAL RSAKeyValueImpl : public RSAKeyValue,
123         public AbstractDOMCachingXMLObject,
124         public AbstractValidatingXMLObject,
125         public AbstractXMLObjectMarshaller,
126         public AbstractXMLObjectUnmarshaller
127     {
128     public:
129         virtual ~RSAKeyValueImpl() {}
130
131         RSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
132                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
133             init();
134         }
135             
136         RSAKeyValueImpl(const RSAKeyValueImpl& src)
137                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
138             init();
139             setModulus(src.getModulus());
140             setExponent(src.getExponent());
141         }
142         
143         void init() {
144             m_Modulus=NULL;
145             m_Exponent=NULL;
146             m_children.push_back(NULL);
147             m_children.push_back(NULL);
148             m_pos_Modulus=m_children.begin();
149             m_pos_Exponent=m_pos_Modulus;
150             ++m_pos_Exponent;
151         }
152         
153         IMPL_XMLOBJECT_CLONE(RSAKeyValue);
154         IMPL_XMLOBJECT_CHILD(Modulus);
155         IMPL_XMLOBJECT_CHILD(Exponent);
156
157     protected:
158         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
159             PROC_XMLOBJECT_CHILD(Modulus,XMLConstants::XMLSIG_NS);
160             PROC_XMLOBJECT_CHILD(Exponent,XMLConstants::XMLSIG_NS);
161             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
162         }
163     };
164
165     class XMLTOOL_DLLLOCAL KeyValueImpl : public KeyValue,
166         public AbstractDOMCachingXMLObject,
167         public AbstractValidatingXMLObject,
168         public AbstractXMLObjectMarshaller,
169         public AbstractXMLObjectUnmarshaller
170     {
171     public:
172         virtual ~KeyValueImpl() {}
173
174         KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
175                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
176             init();
177         }
178             
179         KeyValueImpl(const KeyValueImpl& src)
180                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
181             init();
182             setDSAKeyValue(src.getDSAKeyValue());
183             setRSAKeyValue(src.getRSAKeyValue());
184             setXMLObject(src.getXMLObject());
185             setTextContent(src.getTextContent());
186         }
187         
188         void init() {
189             m_TextContent=NULL;
190             m_DSAKeyValue=NULL;
191             m_RSAKeyValue=NULL;
192             m_XMLObject=NULL;
193             m_children.push_back(NULL);
194             m_children.push_back(NULL);
195             m_children.push_back(NULL);
196             m_pos_DSAKeyValue=m_children.begin();
197             m_pos_RSAKeyValue=m_pos_DSAKeyValue;
198             ++m_pos_RSAKeyValue;
199             m_pos_XMLObject=m_pos_RSAKeyValue;
200             ++m_pos_XMLObject;
201         }
202         
203         IMPL_XMLOBJECT_CLONE(KeyValue);
204         IMPL_XMLOBJECT_CHILD(DSAKeyValue);
205         IMPL_XMLOBJECT_CHILD(RSAKeyValue);
206         IMPL_XMLOBJECT_CHILD(XMLObject);
207         IMPL_XMLOBJECT_CONTENT(TextContent);
208
209     protected:
210         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
211             PROC_XMLOBJECT_CHILD(DSAKeyValue,XMLConstants::XMLSIG_NS);
212             PROC_XMLOBJECT_CHILD(RSAKeyValue,XMLConstants::XMLSIG_NS);
213             
214             // Unknown child.
215             const XMLCh* nsURI=root->getNamespaceURI();
216             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
217                 setXMLObject(childXMLObject);
218             
219             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
220         }
221     };
222     
223     class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo,
224         public AbstractDOMCachingXMLObject,
225         public AbstractElementProxy,
226         public AbstractValidatingXMLObject,
227         public AbstractXMLObjectMarshaller,
228         public AbstractXMLObjectUnmarshaller
229     {
230     public:
231         virtual ~KeyInfoImpl() {}
232
233         KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
234             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {
235         }
236             
237         KeyInfoImpl(const KeyInfoImpl& src)
238                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractElementProxy(src),
239                     AbstractValidatingXMLObject(src), m_Id(XMLString::replicate(src.m_Id)) {
240             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
241                 if (*i) {
242                     KeyName* kn=dynamic_cast<KeyName*>(*i);
243                     if (kn) {
244                         getKeyNames().push_back(kn->cloneKeyName());
245                         continue;
246                     }
247                     KeyValue* kv=dynamic_cast<KeyValue*>(*i);
248                     if (kv) {
249                         getKeyValues().push_back(kv->cloneKeyValue());
250                         continue;
251                     }
252                     MgmtData* md=dynamic_cast<MgmtData*>(*i);
253                     if (md) {
254                         getMgmtDatas().push_back(md->cloneMgmtData());
255                         continue;
256                     }
257                     getXMLObjects().push_back((*i)->clone());
258                 }
259             }
260         }
261         
262         IMPL_XMLOBJECT_CLONE(KeyInfo);
263         IMPL_XMLOBJECT_ATTRIB(Id);
264         IMPL_XMLOBJECT_CHILDREN(KeyName,m_children.end());
265         IMPL_XMLOBJECT_CHILDREN(KeyValue,m_children.end());
266         IMPL_XMLOBJECT_CHILDREN(MgmtData,m_children.end());
267
268     protected:
269         void marshallAttributes(DOMElement* domElement) const {
270             if(getId()) {
271                 domElement->setAttributeNS(NULL, ID_ATTRIB_NAME, getId());
272                 domElement->setIdAttributeNS(NULL, ID_ATTRIB_NAME);
273             }
274         }
275
276         void marshallElementContent(DOMElement* domElement) const {
277             if(getTextContent()) {
278                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
279             }
280         }
281
282         void processElementContent(const XMLCh* elementContent) {
283             setTextContent(elementContent);
284         }
285
286         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
287             PROC_XMLOBJECT_CHILDREN(KeyName,XMLConstants::XMLSIG_NS);
288             PROC_XMLOBJECT_CHILDREN(KeyValue,XMLConstants::XMLSIG_NS);
289             PROC_XMLOBJECT_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS);
290             
291             // Unknown child.
292             const XMLCh* nsURI=root->getNamespaceURI();
293             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
294                 getXMLObjects().push_back(childXMLObject);
295             
296             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
297         }
298
299         void processAttribute(const DOMAttr* attribute) {
300             if (XMLHelper::isNodeNamed(attribute, NULL, ID_ATTRIB_NAME)) {
301                 setId(attribute->getValue());
302                 static_cast<DOMElement*>(attribute->getParentNode())->setIdAttributeNode(attribute);
303             }
304         }
305     };
306     
307     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,KeyName,Name);
308     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,MgmtData,Data);
309     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Modulus,Value);
310     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Exponent,Value);
311     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Seed,Value);
312     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PgenCounter,Value);
313     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,P,Value);
314     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Q,Value);
315     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,G,Value);
316     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Y,Value);
317     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,J,Value);
318 };
319
320 #if defined (_MSC_VER)
321     #pragma warning( pop )
322 #endif
323
324 // Builder Implementations
325
326 IMPL_XMLOBJECTBUILDER(KeyName);
327 IMPL_XMLOBJECTBUILDER(MgmtData);
328 IMPL_XMLOBJECTBUILDER(Modulus);
329 IMPL_XMLOBJECTBUILDER(Exponent);
330 IMPL_XMLOBJECTBUILDER(Seed);
331 IMPL_XMLOBJECTBUILDER(PgenCounter);
332 IMPL_XMLOBJECTBUILDER(P);
333 IMPL_XMLOBJECTBUILDER(Q);
334 IMPL_XMLOBJECTBUILDER(G);
335 IMPL_XMLOBJECTBUILDER(Y);
336 IMPL_XMLOBJECTBUILDER(J);
337 IMPL_XMLOBJECTBUILDER(DSAKeyValue);
338 IMPL_XMLOBJECTBUILDER(RSAKeyValue);
339 IMPL_XMLOBJECTBUILDER(KeyValue);
340 IMPL_XMLOBJECTBUILDER(KeyInfo);
341
342 const XMLCh KeyInfo::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,I,n,f,o);
343 const XMLCh KeyInfo::TYPE_NAME[] =          UNICODE_LITERAL_11(K,e,y,I,n,f,o,T,y,p,e);
344 const XMLCh KeyInfo::ID_ATTRIB_NAME[] =     UNICODE_LITERAL_2(I,d);
345 const XMLCh KeyValue::LOCAL_NAME[] =        UNICODE_LITERAL_8(K,e,y,V,a,l,u,e);
346 const XMLCh KeyValue::TYPE_NAME[] =         UNICODE_LITERAL_12(K,e,y,V,a,l,u,e,T,y,p,e);
347 const XMLCh DSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(D,S,A,K,e,y,V,a,l,u,e);
348 const XMLCh DSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(D,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
349 const XMLCh RSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(R,S,A,K,e,y,V,a,l,u,e);
350 const XMLCh RSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(R,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
351 const XMLCh MgmtData::LOCAL_NAME[] =        UNICODE_LITERAL_8(M,g,m,t,D,a,t,a);
352 const XMLCh KeyName::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,N,a,m,e);
353 const XMLCh Modulus::LOCAL_NAME[] =         UNICODE_LITERAL_7(M,o,d,u,l,u,s);
354 const XMLCh Exponent::LOCAL_NAME[] =        UNICODE_LITERAL_8(E,x,p,o,n,e,n,t);
355 const XMLCh Seed::LOCAL_NAME[] =            UNICODE_LITERAL_4(S,e,e,d);
356 const XMLCh PgenCounter::LOCAL_NAME[] =     UNICODE_LITERAL_11(P,g,e,n,C,o,u,n,t,e,r);
357 const XMLCh P::LOCAL_NAME[] =               UNICODE_LITERAL_1(P);
358 const XMLCh Q::LOCAL_NAME[] =               UNICODE_LITERAL_1(Q);
359 const XMLCh G::LOCAL_NAME[] =               UNICODE_LITERAL_1(G);
360 const XMLCh Y::LOCAL_NAME[] =               UNICODE_LITERAL_1(Y);
361 const XMLCh J::LOCAL_NAME[] =               UNICODE_LITERAL_1(J);