build fix
[LibreOffice.git] / xmlsecurity / source / helper / xsecparser.cxx
blobd4c9f9dcfe0da38ee0577e9a6348b6662143f42b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "xsecparser.hxx"
22 #include <cppuhelper/exc_hlp.hxx>
24 #include <string.h>
26 namespace cssu = com::sun::star::uno;
27 namespace cssxc = com::sun::star::xml::crypto;
28 namespace cssxs = com::sun::star::xml::sax;
30 XSecParser::XSecParser(XSecController* pXSecController,
31 const cssu::Reference< cssxs::XDocumentHandler >& xNextHandler)
32 : m_bInX509IssuerName(false)
33 , m_bInX509SerialNumber(false)
34 , m_bInX509Certificate(false)
35 , m_bInCertDigest(false)
36 , m_bInEncapsulatedX509Certificate(false)
37 , m_bInSigningTime(false)
38 , m_bInDigestValue(false)
39 , m_bInSignatureValue(false)
40 , m_bInDate(false)
41 , m_bInDescription(false)
42 , m_pXSecController(pXSecController)
43 , m_xNextHandler(xNextHandler)
44 , m_bReferenceUnresolved(false)
45 , m_nReferenceDigestID(cssxc::DigestID::SHA1)
49 OUString XSecParser::getIdAttr(const cssu::Reference< cssxs::XAttributeList >& xAttribs )
51 OUString ouIdAttr = xAttribs->getValueByName("id");
53 if (ouIdAttr.isEmpty())
55 ouIdAttr = xAttribs->getValueByName("Id");
58 return ouIdAttr;
62 * XDocumentHandler
64 void SAL_CALL XSecParser::startDocument( )
65 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
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_bInDescription = false;
75 if (m_xNextHandler.is())
77 m_xNextHandler->startDocument();
81 void SAL_CALL XSecParser::endDocument( )
82 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
84 if (m_xNextHandler.is())
86 m_xNextHandler->endDocument();
90 void SAL_CALL XSecParser::startElement(
91 const OUString& aName,
92 const cssu::Reference< cssxs::XAttributeList >& xAttribs )
93 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
95 try
97 OUString ouIdAttr = getIdAttr(xAttribs);
98 if (!ouIdAttr.isEmpty())
100 m_pXSecController->collectToVerify( ouIdAttr );
103 if ( aName == "Signature" )
105 m_pXSecController->addSignature();
106 if (!ouIdAttr.isEmpty())
108 m_pXSecController->setId( ouIdAttr );
111 else if ( aName == "Reference" )
113 OUString ouUri = xAttribs->getValueByName("URI");
114 SAL_WARN_IF( ouUri.isEmpty(), "xmlsecurity.helper", "URI is empty" );
115 if (ouUri.startsWith("#"))
118 * remove the first character '#' from the attribute value
120 m_pXSecController->addReference( ouUri.copy(1), m_nReferenceDigestID );
122 else
125 * remember the uri
127 m_currentReferenceURI = ouUri;
128 m_bReferenceUnresolved = true;
131 else if (aName == "DigestMethod")
133 OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
135 SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
136 if (!ouAlgorithm.isEmpty())
138 SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1 && ouAlgorithm != ALGO_XMLDSIGSHA256,
139 "xmlsecurity.helper", "Algorithm neither SHA1 or SHA256");
140 if (ouAlgorithm == ALGO_XMLDSIGSHA1)
141 m_nReferenceDigestID = cssxc::DigestID::SHA1;
142 else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
143 m_nReferenceDigestID = cssxc::DigestID::SHA256;
146 else if (aName == "Transform")
148 if ( m_bReferenceUnresolved )
150 OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
152 if (ouAlgorithm == ALGO_C14N)
154 * a xml stream
157 m_pXSecController->addStreamReference( m_currentReferenceURI, false, m_nReferenceDigestID );
158 m_bReferenceUnresolved = false;
162 else if (aName == "X509IssuerName")
164 m_ouX509IssuerName.clear();
165 m_bInX509IssuerName = true;
167 else if (aName == "X509SerialNumber")
169 m_ouX509SerialNumber.clear();
170 m_bInX509SerialNumber = true;
172 else if (aName == "X509Certificate")
174 m_ouX509Certificate.clear();
175 m_bInX509Certificate = true;
177 else if (aName == "SignatureValue")
179 m_ouSignatureValue.clear();
180 m_bInSignatureValue = true;
182 else if (aName == "DigestValue" && !m_bInCertDigest)
184 m_ouDigestValue.clear();
185 m_bInDigestValue = true;
187 else if (aName == "xd:CertDigest")
189 m_ouCertDigest.clear();
190 m_bInCertDigest = true;
192 // FIXME: Existing code here in xmlsecurity uses "xd" as the namespace prefix for XAdES,
193 // while the sample document attached to tdf#76142 uses "xades". So accept either here. Of
194 // course this is idiotic and wrong, the right thing would be to use a proper way to parse
195 // XML that would handle namespaces correctly. I have no idea how substantial re-plumbing of
196 // this code that would require.
197 else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate")
199 m_ouEncapsulatedX509Certificate.clear();
200 m_bInEncapsulatedX509Certificate = true;
202 else if (aName == "xd:SigningTime" || aName == "xades:SigningTime")
204 m_ouDate.clear();
205 m_bInSigningTime = true;
207 else if ( aName == "SignatureProperty" )
209 if (!ouIdAttr.isEmpty())
211 m_pXSecController->setPropertyId( ouIdAttr );
214 else if (aName == "dc:date")
216 if (m_ouDate.isEmpty())
217 m_bInDate = true;
219 else if (aName == "dc:description")
221 m_ouDescription.clear();
222 m_bInDescription = true;
225 if (m_xNextHandler.is())
227 m_xNextHandler->startElement(aName, xAttribs);
230 catch (cssu::Exception& )
231 {//getCaughtException MUST be the first line in the catch block
232 cssu::Any exc = cppu::getCaughtException();
233 throw cssxs::SAXException(
234 "xmlsecurity: Exception in XSecParser::startElement",
235 nullptr, exc);
237 catch (...)
239 throw cssxs::SAXException(
240 "xmlsecurity: unexpected exception in XSecParser::startElement", nullptr,
241 cssu::Any());
245 void SAL_CALL XSecParser::endElement( const OUString& aName )
246 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
250 if (aName == "DigestValue" && !m_bInCertDigest)
252 m_bInDigestValue = false;
254 else if ( aName == "Reference" )
256 if ( m_bReferenceUnresolved )
258 * it must be a octet stream
261 m_pXSecController->addStreamReference( m_currentReferenceURI, true, m_nReferenceDigestID );
262 m_bReferenceUnresolved = false;
265 m_pXSecController->setDigestValue( m_nReferenceDigestID, m_ouDigestValue );
267 else if ( aName == "SignedInfo" )
269 m_pXSecController->setReferenceCount();
271 else if ( aName == "SignatureValue" )
273 m_pXSecController->setSignatureValue( m_ouSignatureValue );
274 m_bInSignatureValue = false;
276 else if (aName == "X509IssuerName")
278 m_pXSecController->setX509IssuerName( m_ouX509IssuerName );
279 m_bInX509IssuerName = false;
281 else if (aName == "X509SerialNumber")
283 m_pXSecController->setX509SerialNumber( m_ouX509SerialNumber );
284 m_bInX509SerialNumber = false;
286 else if (aName == "X509Certificate")
288 m_pXSecController->setX509Certificate( m_ouX509Certificate );
289 m_bInX509Certificate = false;
291 else if (aName == "xd:CertDigest")
293 m_pXSecController->setCertDigest( m_ouCertDigest );
294 m_bInCertDigest = false;
296 else if (aName == "xd:EncapsulatedX509Certificate" || aName == "xades:EncapsulatedX509Certificate")
298 m_pXSecController->addEncapsulatedX509Certificate( m_ouEncapsulatedX509Certificate );
299 m_bInEncapsulatedX509Certificate = false;
301 else if (aName == "xd:SigningTime" || aName == "xades:SigningTime")
303 m_pXSecController->setDate( m_ouDate );
304 m_bInSigningTime = false;
306 else if (aName == "dc:date")
308 if (m_bInDate)
310 m_pXSecController->setDate( m_ouDate );
311 m_bInDate = false;
314 else if (aName == "dc:description")
316 m_pXSecController->setDescription( m_ouDescription );
317 m_bInDescription = false;
320 if (m_xNextHandler.is())
322 m_xNextHandler->endElement(aName);
325 catch (cssu::Exception& )
326 {//getCaughtException MUST be the first line in the catch block
327 cssu::Any exc = cppu::getCaughtException();
328 throw cssxs::SAXException(
329 "xmlsecurity: Exception in XSecParser::endElement",
330 nullptr, exc);
332 catch (...)
334 throw cssxs::SAXException(
335 "xmlsecurity: unexpected exception in XSecParser::endElement", nullptr,
336 cssu::Any());
340 void SAL_CALL XSecParser::characters( const OUString& aChars )
341 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
343 if (m_bInX509IssuerName)
345 m_ouX509IssuerName += aChars;
347 else if (m_bInX509SerialNumber)
349 m_ouX509SerialNumber += aChars;
351 else if (m_bInX509Certificate)
353 m_ouX509Certificate += aChars;
355 else if (m_bInSignatureValue)
357 m_ouSignatureValue += aChars;
359 else if (m_bInDigestValue && !m_bInCertDigest)
361 m_ouDigestValue += aChars;
363 else if (m_bInDate)
365 m_ouDate += aChars;
367 else if (m_bInDescription)
369 m_ouDescription += aChars;
371 else if (m_bInCertDigest)
373 m_ouCertDigest += aChars;
375 else if (m_bInEncapsulatedX509Certificate)
377 m_ouEncapsulatedX509Certificate += aChars;
379 else if (m_bInSigningTime)
381 m_ouDate += aChars;
384 if (m_xNextHandler.is())
386 m_xNextHandler->characters(aChars);
390 void SAL_CALL XSecParser::ignorableWhitespace( const OUString& aWhitespaces )
391 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
393 if (m_xNextHandler.is())
395 m_xNextHandler->ignorableWhitespace( aWhitespaces );
399 void SAL_CALL XSecParser::processingInstruction( const OUString& aTarget, const OUString& aData )
400 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
402 if (m_xNextHandler.is())
404 m_xNextHandler->processingInstruction(aTarget, aData);
408 void SAL_CALL XSecParser::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
409 throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
411 if (m_xNextHandler.is())
413 m_xNextHandler->setDocumentLocator( xLocator );
418 * XInitialization
420 void SAL_CALL XSecParser::initialize(
421 const cssu::Sequence< cssu::Any >& aArguments )
422 throw(cssu::Exception, cssu::RuntimeException, std::exception)
424 aArguments[0] >>= m_xNextHandler;
427 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */