Evolving macros, reduce casting in accessors, add const collection access.
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / KeyInfoImpl.cpp
1 /*\r
2 *  Copyright 2001-2006 Internet2\r
3  * \r
4 * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * XMLSecSignatureImpl.cpp\r
19  * \r
20  * Signature class for XMLSec-based signature-handling\r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "AbstractElementProxy.h"\r
25 #include "exceptions.h"\r
26 #include "io/AbstractXMLObjectMarshaller.h"\r
27 #include "io/AbstractXMLObjectUnmarshaller.h"\r
28 #include "signature/KeyInfo.h"\r
29 #include "util/XMLHelper.h"\r
30 #include "validation/AbstractValidatingXMLObject.h"\r
31 \r
32 #include <xercesc/util/XMLUniDefs.hpp>\r
33 \r
34 using namespace xmltooling;\r
35 using namespace std;\r
36 \r
37 #if defined (_MSC_VER)\r
38     #pragma warning( push )\r
39     #pragma warning( disable : 4250 4251 )\r
40 #endif\r
41 \r
42 namespace xmltooling {\r
43     \r
44     class XMLTOOL_DLLLOCAL RSAKeyValueImpl\r
45         : public RSAKeyValue,\r
46             public AbstractDOMCachingXMLObject,\r
47             public AbstractValidatingXMLObject,\r
48             public AbstractXMLObjectMarshaller,\r
49             public AbstractXMLObjectUnmarshaller\r
50     {\r
51     public:\r
52         virtual ~RSAKeyValueImpl() {}\r
53 \r
54         RSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
55             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {\r
56             init();\r
57         }\r
58             \r
59         RSAKeyValueImpl(const RSAKeyValueImpl& src)\r
60             : AbstractXMLObject(src),\r
61                 AbstractDOMCachingXMLObject(src),\r
62                 AbstractValidatingXMLObject(src) {\r
63             init();\r
64             setModulus(src.getModulus());\r
65             setExponent(src.getExponent());\r
66         }\r
67         \r
68         void init() {\r
69             m_Modulus=NULL;\r
70             m_Exponent=NULL;\r
71             m_children.push_back(NULL);\r
72             m_children.push_back(NULL);\r
73             m_pos_Modulus=m_children.begin();\r
74             m_pos_Exponent=m_children.begin();\r
75             m_pos_Exponent++;\r
76         }\r
77         \r
78         IMPL_XMLOBJECT_CLONE(RSAKeyValue);\r
79         IMPL_XMLOBJECT_CHILD(Modulus);\r
80         IMPL_XMLOBJECT_CHILD(Exponent);\r
81 \r
82     protected:\r
83         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {\r
84             PROC_XMLOBJECT_CHILD(Modulus,XMLConstants::XMLSIG_NS);\r
85             PROC_XMLOBJECT_CHILD(Exponent,XMLConstants::XMLSIG_NS);\r
86             \r
87             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString()));\r
88         }\r
89     };\r
90     \r
91     class XMLTOOL_DLLLOCAL KeyInfoImpl\r
92         : public KeyInfo,\r
93             public AbstractDOMCachingXMLObject,\r
94             public AbstractElementProxy,\r
95             public AbstractValidatingXMLObject,\r
96             public AbstractXMLObjectMarshaller,\r
97             public AbstractXMLObjectUnmarshaller\r
98     {\r
99     public:\r
100         virtual ~KeyInfoImpl() {}\r
101 \r
102         KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
103             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {\r
104         }\r
105             \r
106         KeyInfoImpl(const KeyInfoImpl& src)\r
107             : AbstractXMLObject(src),\r
108                 AbstractDOMCachingXMLObject(src),\r
109                 AbstractElementProxy(src),\r
110                 AbstractValidatingXMLObject(src),\r
111                 m_Id(XMLString::replicate(src.m_Id)) {\r
112                     \r
113             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {\r
114                 if (*i) {\r
115                     KeyName* kn=dynamic_cast<KeyName*>(*i);\r
116                     if (kn) {\r
117                         getKeyNames().push_back(kn->cloneKeyName());\r
118                         continue;\r
119                     }\r
120                     MgmtData* md=dynamic_cast<MgmtData*>(*i);\r
121                     if (md) {\r
122                         getMgmtDatas().push_back(md->cloneMgmtData());\r
123                         continue;\r
124                     }\r
125                     getXMLObjects().push_back((*i)->clone());\r
126                 }\r
127             }\r
128         }\r
129         \r
130         IMPL_XMLOBJECT_CLONE(KeyInfo);\r
131         IMPL_XMLOBJECT_ATTRIB(Id);\r
132         IMPL_XMLOBJECT_CHILDREN(KeyName,m_children.end());\r
133         IMPL_XMLOBJECT_CHILDREN(MgmtData,m_children.end());\r
134 \r
135     protected:\r
136         void marshallAttributes(DOMElement* domElement) const {\r
137             if(getId()) {\r
138                 domElement->setAttributeNS(NULL, ID_ATTRIB_NAME, getId());\r
139                 domElement->setIdAttributeNS(NULL, ID_ATTRIB_NAME);\r
140             }\r
141         }\r
142 \r
143         void marshallElementContent(DOMElement* domElement) const {\r
144             if(getTextContent()) {\r
145                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));\r
146             }\r
147         }\r
148 \r
149         void processElementContent(const XMLCh* elementContent) {\r
150             setTextContent(elementContent);\r
151         }\r
152 \r
153         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {\r
154             PROC_XMLOBJECT_CHILDREN(KeyName,XMLConstants::XMLSIG_NS);\r
155             PROC_XMLOBJECT_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS);\r
156             \r
157             // Unknown child.\r
158             const XMLCh* nsURI=childXMLObject->getElementQName().getNamespaceURI();\r
159             if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)\r
160                 getXMLObjects().push_back(childXMLObject);\r
161             \r
162             throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString()));\r
163         }\r
164 \r
165         void processAttribute(const DOMAttr* attribute) {\r
166             if (XMLHelper::isNodeNamed(attribute, NULL, ID_ATTRIB_NAME)) {\r
167                 setId(attribute->getValue());\r
168                 static_cast<DOMElement*>(attribute->getParentNode())->setIdAttributeNode(attribute);\r
169             }\r
170         }\r
171     };\r
172     \r
173     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,KeyName,Name);\r
174     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,MgmtData,Data);\r
175     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Modulus,Value);\r
176     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Exponent,Value);\r
177 };\r
178 \r
179 #if defined (_MSC_VER)\r
180     #pragma warning( pop )\r
181 #endif\r
182 \r
183 // Builder Implementations\r
184 \r
185 IMPL_XMLOBJECTBUILDER(KeyInfo);\r
186 IMPL_XMLOBJECTBUILDER(KeyName);\r
187 IMPL_XMLOBJECTBUILDER(MgmtData);\r
188 IMPL_XMLOBJECTBUILDER(Modulus);\r
189 IMPL_XMLOBJECTBUILDER(Exponent);\r
190 IMPL_XMLOBJECTBUILDER(RSAKeyValue);\r
191 \r
192 const XMLCh KeyInfo::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,I,n,f,o);\r
193 const XMLCh KeyInfo::TYPE_NAME[] =          UNICODE_LITERAL_11(K,e,y,I,n,f,o,T,y,p,e);\r
194 const XMLCh KeyInfo::ID_ATTRIB_NAME[] =     UNICODE_LITERAL_2(I,d);\r
195 const XMLCh MgmtData::LOCAL_NAME[] =        UNICODE_LITERAL_8(M,g,m,t,D,a,t,a);\r
196 const XMLCh KeyName::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,N,a,m,e);\r
197 const XMLCh Modulus::LOCAL_NAME[] =         UNICODE_LITERAL_7(M,o,d,u,l,u,s);\r
198 const XMLCh Exponent::LOCAL_NAME[] =        UNICODE_LITERAL_8(E,x,p,o,n,e,n,t);\r
199 const XMLCh RSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(R,S,A,K,e,y,V,a,l,u,e);\r
200 const XMLCh RSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(R,S,A,K,e,y,V,a,l,u,e,T,y,p,e);\r