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