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 	throw (cssxs::SAXException, cssu::RuntimeException)
66 {
67 	m_bInX509IssuerName = false;
68 	m_bInX509SerialNumber = false;
69 	m_bInX509Certificate = false;
70 	m_bInSignatureValue = false;
71 	m_bInDigestValue = false;
72 	m_bInDate = false;
73 	//m_bInTime = false;
74 
75 	if (m_xNextHandler.is())
76 	{
77 		m_xNextHandler->startDocument();
78 	}
79 }
80 
endDocument()81 void SAL_CALL XSecParser::endDocument(  )
82 	throw (cssxs::SAXException, cssu::RuntimeException)
83 {
84 	if (m_xNextHandler.is())
85 	{
86 		m_xNextHandler->endDocument();
87 	}
88 }
89 
startElement(const rtl::OUString & aName,const cssu::Reference<cssxs::XAttributeList> & xAttribs)90 void SAL_CALL XSecParser::startElement(
91 	const rtl::OUString& aName,
92 	const cssu::Reference< cssxs::XAttributeList >& xAttribs )
93 	throw (cssxs::SAXException, cssu::RuntimeException)
94 {
95 	try
96 	{
97 		rtl::OUString ouIdAttr = getIdAttr(xAttribs);
98 		if (ouIdAttr != NULL)
99 		{
100 			m_pXSecController->collectToVerify( ouIdAttr );
101 		}
102 
103 		if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATURE)) )
104 		{
105 			m_pXSecController->addSignature();
106 			if (ouIdAttr != NULL)
107 			{
108 				m_pXSecController->setId( ouIdAttr );
109 			}
110 		}
111 		else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_REFERENCE)) )
112 		{
113 			rtl::OUString ouUri = xAttribs->getValueByName(rtl::OUString(RTL_ASCII_USTRINGPARAM(ATTR_URI)));
114 			DBG_ASSERT( ouUri != NULL, "URI == NULL" );
115 
116 			if (0 == ouUri.compareTo(rtl::OUString(RTL_ASCII_USTRINGPARAM(CHAR_FRAGMENT)),1))
117 			{
118 				/*
119 				* remove the first character '#' from the attribute value
120 				*/
121 				m_pXSecController->addReference( ouUri.copy(1) );
122 			}
123 			else
124 			{
125 				/*
126 				* remember the uri
127 				*/
128 				m_currentReferenceURI = ouUri;
129 				m_bReferenceUnresolved = true;
130 			}
131 		}
132 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_TRANSFORM)))
133 			{
134 			if ( m_bReferenceUnresolved )
135 			{
136 				rtl::OUString ouAlgorithm = xAttribs->getValueByName(rtl::OUString(RTL_ASCII_USTRINGPARAM(ATTR_ALGORITHM)));
137 
138 				if (ouAlgorithm != NULL && ouAlgorithm == rtl::OUString(RTL_ASCII_USTRINGPARAM(ALGO_C14N)))
139 				/*
140 				* a xml stream
141 				*/
142 				{
143 					m_pXSecController->addStreamReference( m_currentReferenceURI, sal_False);
144 					m_bReferenceUnresolved = false;
145 				}
146 			}
147 			}
148 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509ISSUERNAME)))
149 			{
150 			m_ouX509IssuerName = rtl::OUString::createFromAscii("");
151 			m_bInX509IssuerName = true;
152 			}
153 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509SERIALNUMBER)))
154 			{
155 			m_ouX509SerialNumber = rtl::OUString::createFromAscii("");
156 			m_bInX509SerialNumber = true;
157 			}
158 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509CERTIFICATE)))
159 			{
160 			m_ouX509Certificate = rtl::OUString::createFromAscii("");
161 			m_bInX509Certificate = true;
162 			}
163 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATUREVALUE)))
164 			{
165 			m_ouSignatureValue = rtl::OUString::createFromAscii("");
166         		m_bInSignatureValue = true;
167 			}
168 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_DIGESTVALUE)))
169 			{
170 			m_ouDigestValue = rtl::OUString::createFromAscii("");
171         		m_bInDigestValue = true;
172 			}
173 			else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATUREPROPERTY)) )
174 		{
175 			if (ouIdAttr != NULL)
176 			{
177 				m_pXSecController->setPropertyId( ouIdAttr );
178 			}
179 		}
180 			else if (aName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC))
181         				+rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":"))
182         				+rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(TAG_DATE)))
183 			{
184 			m_ouDate = rtl::OUString::createFromAscii("");
185         		m_bInDate = true;
186 			}
187 			/*
188 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_TIME)))
189 			{
190 			m_ouTime = rtl::OUString::createFromAscii("");
191         		m_bInTime = true;
192 			}
193 			*/
194 
195 		if (m_xNextHandler.is())
196 		{
197 			m_xNextHandler->startElement(aName, xAttribs);
198 		}
199 	}
200 	catch (cssu::Exception& )
201 	{//getCaughtException MUST be the first line in the catch block
202         cssu::Any exc =  cppu::getCaughtException();
203         throw cssxs::SAXException(
204 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
205                               "xmlsecurity: Exception in XSecParser::startElement")),
206             0, exc);
207 	}
208 	catch (...)
209 	{
210 		throw cssxs::SAXException(
211 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xmlsecurity: unexpected exception in XSecParser::startElement")), 0,
212 			cssu::Any());
213 	}
214 }
215 
endElement(const rtl::OUString & aName)216 void SAL_CALL XSecParser::endElement( const rtl::OUString& aName )
217 	throw (cssxs::SAXException, cssu::RuntimeException)
218 {
219 	try
220 	{
221         if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_DIGESTVALUE)))
222 			{
223         		m_bInDigestValue = false;
224 			}
225 		else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_REFERENCE)) )
226 		{
227 			if ( m_bReferenceUnresolved )
228 			/*
229 			* it must be a octet stream
230 			*/
231 			{
232 				m_pXSecController->addStreamReference( m_currentReferenceURI, sal_True);
233 				m_bReferenceUnresolved = false;
234 			}
235 
236 			m_pXSecController->setDigestValue( m_ouDigestValue );
237 		}
238 		else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNEDINFO)) )
239 		{
240 			m_pXSecController->setReferenceCount();
241 		}
242 		else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_SIGNATUREVALUE)) )
243 		{
244 			m_pXSecController->setSignatureValue( m_ouSignatureValue );
245         		m_bInSignatureValue = false;
246 		}
247 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509ISSUERNAME)))
248 			{
249 			m_pXSecController->setX509IssuerName( m_ouX509IssuerName );
250 			m_bInX509IssuerName = false;
251 			}
252 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509SERIALNUMBER)))
253 			{
254 			m_pXSecController->setX509SerialNumber( m_ouX509SerialNumber );
255 			m_bInX509SerialNumber = false;
256 			}
257 			else if (aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_X509CERTIFICATE)))
258 			{
259 			m_pXSecController->setX509Certificate( m_ouX509Certificate );
260 			m_bInX509Certificate = false;
261 			}
262 			else if (aName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC))
263         				+rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":"))
264         				+rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(TAG_DATE)))
265 		{
266 			m_pXSecController->setDate( m_ouDate );
267         		m_bInDate = false;
268 		}
269 		/*
270 		else if ( aName == rtl::OUString(RTL_ASCII_USTRINGPARAM(TAG_TIME)) )
271 		{
272 			m_pXSecController->setTime( m_ouTime );
273         		m_bInTime = false;
274 		}
275 		*/
276 
277 		if (m_xNextHandler.is())
278 		{
279 			m_xNextHandler->endElement(aName);
280 		}
281 	}
282 	catch (cssu::Exception& )
283 	{//getCaughtException MUST be the first line in the catch block
284         cssu::Any exc =  cppu::getCaughtException();
285         throw cssxs::SAXException(
286 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
287                               "xmlsecurity: Exception in XSecParser::endElement")),
288             0, exc);
289 	}
290 	catch (...)
291 	{
292 		throw cssxs::SAXException(
293 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xmlsecurity: unexpected exception in XSecParser::endElement")), 0,
294 			cssu::Any());
295 	}
296 }
297 
characters(const rtl::OUString & aChars)298 void SAL_CALL XSecParser::characters( const rtl::OUString& aChars )
299 	throw (cssxs::SAXException, cssu::RuntimeException)
300 {
301 	if (m_bInX509IssuerName)
302 	{
303 		m_ouX509IssuerName += aChars;
304 	}
305 	else if (m_bInX509SerialNumber)
306 	{
307 		m_ouX509SerialNumber += aChars;
308 	}
309 	else if (m_bInX509Certificate)
310 	{
311 		m_ouX509Certificate += aChars;
312 	}
313 	else if (m_bInSignatureValue)
314 	{
315 		m_ouSignatureValue += aChars;
316 	}
317 	else if (m_bInDigestValue)
318 	{
319 		m_ouDigestValue += aChars;
320 	}
321 	else if (m_bInDate)
322 	{
323 		m_ouDate += aChars;
324 	}
325 	/*
326 	else if (m_bInTime)
327 	{
328 		m_ouTime += aChars;
329 	}
330 	*/
331 
332 	if (m_xNextHandler.is())
333 	{
334 		m_xNextHandler->characters(aChars);
335         }
336 }
337 
ignorableWhitespace(const rtl::OUString & aWhitespaces)338 void SAL_CALL XSecParser::ignorableWhitespace( const rtl::OUString& aWhitespaces )
339 	throw (cssxs::SAXException, cssu::RuntimeException)
340 {
341 	if (m_xNextHandler.is())
342 	{
343 		m_xNextHandler->ignorableWhitespace( aWhitespaces );
344         }
345 }
346 
processingInstruction(const rtl::OUString & aTarget,const rtl::OUString & aData)347 void SAL_CALL XSecParser::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
348 	throw (cssxs::SAXException, cssu::RuntimeException)
349 {
350 	if (m_xNextHandler.is())
351 	{
352 		m_xNextHandler->processingInstruction(aTarget, aData);
353         }
354 }
355 
setDocumentLocator(const cssu::Reference<cssxs::XLocator> & xLocator)356 void SAL_CALL XSecParser::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
357 	throw (cssxs::SAXException, cssu::RuntimeException)
358 {
359 	if (m_xNextHandler.is())
360 	{
361 		m_xNextHandler->setDocumentLocator( xLocator );
362         }
363 }
364 
365 /*
366  * XInitialization
367  */
initialize(const cssu::Sequence<cssu::Any> & aArguments)368 void SAL_CALL XSecParser::initialize(
369 	const cssu::Sequence< cssu::Any >& aArguments )
370 	throw(cssu::Exception, cssu::RuntimeException)
371 {
372 	aArguments[0] >>= m_xNextHandler;
373 }
374