1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlsecurity.hxx"
26
27 #include "xsecparser.hxx"
28 #include <tools/debug.hxx>
29 #include "cppuhelper/exc_hlp.hxx"
30
31 #include <string.h>
32
33 namespace cssu = com::sun::star::uno;
34 namespace cssxs = com::sun::star::xml::sax;
35
36 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
37
XSecParser(XSecController * pXSecController,const cssu::Reference<cssxs::XDocumentHandler> & xNextHandler)38 XSecParser::XSecParser(
39 XSecController* pXSecController,
40 const cssu::Reference< cssxs::XDocumentHandler >& xNextHandler )
41 : m_pXSecController(pXSecController),
42 m_xNextHandler(xNextHandler),
43 m_bReferenceUnresolved(false)
44 {
45 }
46
getIdAttr(const cssu::Reference<cssxs::XAttributeList> & xAttribs)47 rtl::OUString XSecParser::getIdAttr(const cssu::Reference< cssxs::XAttributeList >& xAttribs )
48 {
49 rtl::OUString ouIdAttr = xAttribs->getValueByName(
50 rtl::OUString(RTL_ASCII_USTRINGPARAM("id")));
51
52 if (ouIdAttr == NULL)
53 {
54 ouIdAttr = xAttribs->getValueByName(
55 rtl::OUString(RTL_ASCII_USTRINGPARAM("Id")));
56 }
57
58 return ouIdAttr;
59 }
60
61 /*
62 * XDocumentHandler
63 */
startDocument()64 void SAL_CALL XSecParser::startDocument( )
65 {
66 m_bInX509IssuerName = false;
67 m_bInX509SerialNumber = false;
68 m_bInX509Certificate = false;
69 m_bInSignatureValue = false;
70 m_bInDigestValue = false;
71 m_bInDate = false;
72 //m_bInTime = false;
73
74 if (m_xNextHandler.is())
75 {
76 m_xNextHandler->startDocument();
77 }
78 }
79
endDocument()80 void SAL_CALL XSecParser::endDocument( )
81 {
82 if (m_xNextHandler.is())
83 {
84 m_xNextHandler->endDocument();
85 }
86 }
87
startElement(const rtl::OUString & aName,const cssu::Reference<cssxs::XAttributeList> & xAttribs)88 void SAL_CALL XSecParser::startElement(
89 const rtl::OUString& aName,
90 const cssu::Reference< cssxs::XAttributeList >& xAttribs )
91 {
92 try
93 {
94 rtl::OUString ouIdAttr = getIdAttr(xAttribs);
95 if (ouIdAttr != NULL)
96 {
97 m_pXSecController->collectToVerify( ouIdAttr );
98 }
99
100 if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATURE)) )
101 {
102 m_pXSecController->addSignature();
103 if (ouIdAttr != NULL)
104 {
105 m_pXSecController->setId( ouIdAttr );
106 }
107 }
108 else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_REFERENCE)) )
109 {
110 rtl::OUString ouUri = xAttribs->getValueByName(rtl::OUString(RTL_ASCII_USTRINGPARAM(ATTR_URI)));
111 DBG_ASSERT( ouUri != NULL, "URI == NULL" );
112
113 if (0 == ouUri.compareTo(rtl::OUString(RTL_ASCII_USTRINGPARAM(CHAR_FRAGMENT)),1))
114 {
115 /*
116 * remove the first character '#' from the attribute value
117 */
118 m_pXSecController->addReference( ouUri.copy(1) );
119 }
120 else
121 {
122 /*
123 * remember the uri
124 */
125 m_currentReferenceURI = ouUri;
126 m_bReferenceUnresolved = true;
127 }
128 }
129 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_TRANSFORM)))
130 {
131 if ( m_bReferenceUnresolved )
132 {
133 rtl::OUString ouAlgorithm = xAttribs->getValueByName(rtl::OUString(RTL_ASCII_USTRINGPARAM(ATTR_ALGORITHM)));
134
135 if (ouAlgorithm != NULL && ouAlgorithm == rtl::OUString(RTL_ASCII_USTRINGPARAM(ALGO_C14N)))
136 /*
137 * a xml stream
138 */
139 {
140 m_pXSecController->addStreamReference( m_currentReferenceURI, sal_False);
141 m_bReferenceUnresolved = false;
142 }
143 }
144 }
145 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509ISSUERNAME)))
146 {
147 m_ouX509IssuerName = rtl::OUString::createFromAscii("");
148 m_bInX509IssuerName = true;
149 }
150 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509SERIALNUMBER)))
151 {
152 m_ouX509SerialNumber = rtl::OUString::createFromAscii("");
153 m_bInX509SerialNumber = true;
154 }
155 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509CERTIFICATE)))
156 {
157 m_ouX509Certificate = rtl::OUString::createFromAscii("");
158 m_bInX509Certificate = true;
159 }
160 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATUREVALUE)))
161 {
162 m_ouSignatureValue = rtl::OUString::createFromAscii("");
163 m_bInSignatureValue = true;
164 }
165 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_DIGESTVALUE)))
166 {
167 m_ouDigestValue = rtl::OUString::createFromAscii("");
168 m_bInDigestValue = true;
169 }
170 else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATUREPROPERTY)) )
171 {
172 if (ouIdAttr != NULL)
173 {
174 m_pXSecController->setPropertyId( ouIdAttr );
175 }
176 }
177 else if (aName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC))
178 +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":"))
179 +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(TAG_DATE)))
180 {
181 m_ouDate = rtl::OUString::createFromAscii("");
182 m_bInDate = true;
183 }
184 /*
185 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_TIME)))
186 {
187 m_ouTime = rtl::OUString::createFromAscii("");
188 m_bInTime = true;
189 }
190 */
191
192 if (m_xNextHandler.is())
193 {
194 m_xNextHandler->startElement(aName, xAttribs);
195 }
196 }
197 catch (cssu::Exception& )
198 {//getCaughtException MUST be the first line in the catch block
199 cssu::Any exc = cppu::getCaughtException();
200 throw cssxs::SAXException(
201 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
202 "xmlsecurity: Exception in XSecParser::startElement")),
203 0, exc);
204 }
205 catch (...)
206 {
207 throw cssxs::SAXException(
208 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xmlsecurity: unexpected exception in XSecParser::startElement")), 0,
209 cssu::Any());
210 }
211 }
212
endElement(const rtl::OUString & aName)213 void SAL_CALL XSecParser::endElement( const rtl::OUString& aName )
214 {
215 try
216 {
217 if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_DIGESTVALUE)))
218 {
219 m_bInDigestValue = false;
220 }
221 else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_REFERENCE)) )
222 {
223 if ( m_bReferenceUnresolved )
224 /*
225 * it must be a octet stream
226 */
227 {
228 m_pXSecController->addStreamReference( m_currentReferenceURI, sal_True);
229 m_bReferenceUnresolved = false;
230 }
231
232 m_pXSecController->setDigestValue( m_ouDigestValue );
233 }
234 else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNEDINFO)) )
235 {
236 m_pXSecController->setReferenceCount();
237 }
238 else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATUREVALUE)) )
239 {
240 m_pXSecController->setSignatureValue( m_ouSignatureValue );
241 m_bInSignatureValue = false;
242 }
243 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509ISSUERNAME)))
244 {
245 m_pXSecController->setX509IssuerName( m_ouX509IssuerName );
246 m_bInX509IssuerName = false;
247 }
248 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509SERIALNUMBER)))
249 {
250 m_pXSecController->setX509SerialNumber( m_ouX509SerialNumber );
251 m_bInX509SerialNumber = false;
252 }
253 else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509CERTIFICATE)))
254 {
255 m_pXSecController->setX509Certificate( m_ouX509Certificate );
256 m_bInX509Certificate = false;
257 }
258 else if (aName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC))
259 +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":"))
260 +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(TAG_DATE)))
261 {
262 m_pXSecController->setDate( m_ouDate );
263 m_bInDate = false;
264 }
265 /*
266 else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_TIME)) )
267 {
268 m_pXSecController->setTime( m_ouTime );
269 m_bInTime = false;
270 }
271 */
272
273 if (m_xNextHandler.is())
274 {
275 m_xNextHandler->endElement(aName);
276 }
277 }
278 catch (cssu::Exception& )
279 {//getCaughtException MUST be the first line in the catch block
280 cssu::Any exc = cppu::getCaughtException();
281 throw cssxs::SAXException(
282 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
283 "xmlsecurity: Exception in XSecParser::endElement")),
284 0, exc);
285 }
286 catch (...)
287 {
288 throw cssxs::SAXException(
289 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xmlsecurity: unexpected exception in XSecParser::endElement")), 0,
290 cssu::Any());
291 }
292 }
293
characters(const rtl::OUString & aChars)294 void SAL_CALL XSecParser::characters( const rtl::OUString& aChars )
295 {
296 if (m_bInX509IssuerName)
297 {
298 m_ouX509IssuerName += aChars;
299 }
300 else if (m_bInX509SerialNumber)
301 {
302 m_ouX509SerialNumber += aChars;
303 }
304 else if (m_bInX509Certificate)
305 {
306 m_ouX509Certificate += aChars;
307 }
308 else if (m_bInSignatureValue)
309 {
310 m_ouSignatureValue += aChars;
311 }
312 else if (m_bInDigestValue)
313 {
314 m_ouDigestValue += aChars;
315 }
316 else if (m_bInDate)
317 {
318 m_ouDate += aChars;
319 }
320 /*
321 else if (m_bInTime)
322 {
323 m_ouTime += aChars;
324 }
325 */
326
327 if (m_xNextHandler.is())
328 {
329 m_xNextHandler->characters(aChars);
330 }
331 }
332
ignorableWhitespace(const rtl::OUString & aWhitespaces)333 void SAL_CALL XSecParser::ignorableWhitespace( const rtl::OUString& aWhitespaces )
334 {
335 if (m_xNextHandler.is())
336 {
337 m_xNextHandler->ignorableWhitespace( aWhitespaces );
338 }
339 }
340
processingInstruction(const rtl::OUString & aTarget,const rtl::OUString & aData)341 void SAL_CALL XSecParser::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
342 {
343 if (m_xNextHandler.is())
344 {
345 m_xNextHandler->processingInstruction(aTarget, aData);
346 }
347 }
348
setDocumentLocator(const cssu::Reference<cssxs::XLocator> & xLocator)349 void SAL_CALL XSecParser::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
350 {
351 if (m_xNextHandler.is())
352 {
353 m_xNextHandler->setDocumentLocator( xLocator );
354 }
355 }
356
357 /*
358 * XInitialization
359 */
initialize(const cssu::Sequence<cssu::Any> & aArguments)360 void SAL_CALL XSecParser::initialize(
361 const cssu::Sequence< cssu::Any >& aArguments )
362 {
363 aArguments[0] >>= m_xNextHandler;
364 }
365