xref: /trunk/main/xmlsecurity/source/helper/xsecparser.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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