tdf#104310: Accept also x14-style dataValidations
[LibreOffice.git] / xmlsecurity / inc / xsecctl.hxx
blob8f9f1db5e259d1ad81082c720c228ab9c04e39c5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #ifndef INCLUDED_XMLSECURITY_SOURCE_HELPER_XSECCTL_HXX
21 #define INCLUDED_XMLSECURITY_SOURCE_HELPER_XSECCTL_HXX
23 #include <sigstruct.hxx>
25 #include <com/sun/star/uno/XComponentContext.hpp>
26 #include <com/sun/star/xml/sax/XParser.hpp>
27 #include <com/sun/star/lang/XInitialization.hpp>
28 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
29 #include <com/sun/star/xml/sax/XAttributeList.hpp>
30 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
31 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
32 #include <com/sun/star/xml/crypto/sax/XElementStackKeeper.hpp>
33 #include <com/sun/star/xml/crypto/sax/XSecuritySAXEventKeeper.hpp>
34 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedListener.hpp>
35 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeListener.hpp>
36 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultListener.hpp>
37 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultListener.hpp>
38 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp>
39 #include <com/sun/star/io/XOutputStream.hpp>
40 #include <com/sun/star/io/XInputStream.hpp>
41 #include <com/sun/star/embed/XStorage.hpp>
43 #include <rtl/ustrbuf.hxx>
45 #include <cppuhelper/implbase.hxx>
47 #include <vector>
49 #define NS_XMLDSIG "http://www.w3.org/2000/09/xmldsig#"
50 #define NS_DC "http://purl.org/dc/elements/1.1/"
51 #define NS_XD "http://uri.etsi.org/01903/v1.3.2#"
52 #define NS_MDSSI "http://schemas.openxmlformats.org/package/2006/digital-signature"
54 #define ALGO_C14N "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
55 #define ALGO_RSASHA1 "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
56 #define ALGO_RSASHA256 "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
57 #define ALGO_XMLDSIGSHA1 "http://www.w3.org/2000/09/xmldsig#sha1"
58 #define ALGO_XMLDSIGSHA256 "http://www.w3.org/2001/04/xmlenc#sha256"
59 #define ALGO_RELATIONSHIP "http://schemas.openxmlformats.org/package/2006/RelationshipTransform"
61 class XSecParser;
63 class InternalSignatureInformation
65 public:
66 SignatureInformation signatureInfor;
68 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > xReferenceResolvedListener;
70 ::std::vector< sal_Int32 > vKeeperIds;
72 InternalSignatureInformation(
73 sal_Int32 nId,
74 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > const & xListener)
75 :signatureInfor(nId)
77 xReferenceResolvedListener = xListener;
80 void addReference( SignatureReferenceType type, sal_Int32 digestID, const OUString& uri, sal_Int32 keeperId )
82 signatureInfor.vSignatureReferenceInfors.push_back(
83 SignatureReferenceInformation(type, digestID, uri));
84 vKeeperIds.push_back( keeperId );
88 class XSecController : public cppu::WeakImplHelper
90 css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener,
91 css::xml::crypto::sax::XSignatureCreationResultListener,
92 css::xml::crypto::sax::XSignatureVerifyResultListener
94 /****** XSecController.hxx/CLASS XSecController *******************************
96 * NAME
97 * XSecController -- the xml security framework controller
99 * FUNCTION
100 * Controls the whole xml security framework to create signatures or to
101 * verify signatures.
103 ******************************************************************************/
105 friend class XSecParser;
106 friend class OOXMLSecParser;
108 private:
109 css::uno::Reference< css::uno::XComponentContext> mxCtx;
112 * used to buffer SAX events
114 css::uno::Reference< css::xml::wrapper::XXMLDocumentWrapper > m_xXMLDocumentWrapper;
117 * the SAX events keeper
119 css::uno::Reference< css::xml::crypto::sax::XSecuritySAXEventKeeper > m_xSAXEventKeeper;
122 * the bridge component which creates/verifies signature
124 css::uno::Reference< css::xml::crypto::XXMLSignature > m_xXMLSignature;
127 * the Security Context
129 css::uno::Reference< css::xml::crypto::XXMLSecurityContext > m_xSecurityContext;
132 * the security id incrementer, in order to make any security id unique
133 * to the SAXEventKeeper.
134 * Because each XSecController has its own SAXEventKeeper, so this variable
135 * is not necessary to be static.
137 sal_Int32 m_nNextSecurityId;
140 * Signature information
142 std::vector< InternalSignatureInformation > m_vInternalSignatureInformations;
145 * the previous node on the SAX chain.
146 * The reason that use a Reference<XInterface> type variable
147 * is that the previous components are different when exporting
148 * and importing, and there is no other common interface they
149 * can provided.
151 css::uno::Reference< css::uno::XInterface > m_xPreviousNodeOnSAXChain;
153 * whether the previous node can provide an XInitialize interface,
154 * use this variable in order to typecast the XInterface to the
155 * correct interface type.
157 bool m_bIsPreviousNodeInitializable;
160 * the next node on the SAX chain.
161 * it can always provide an XDocumentHandler interface.
163 css::uno::Reference< css::xml::sax::XDocumentHandler > m_xNextNodeOnSAXChain;
166 * the ElementStackKeeper is used to reserve the key SAX events.
167 * when the SAXEventKeeper is chained on the SAX chain, it need
168 * first get all missed key SAX events in order to make sure the
169 * DOM tree it buffering has the same structure with the original
170 * document.
172 * For a given section of a SAX event stream, the key SAX events
173 * are the minimal SAX event subset of that section, which,
174 * combining with SAX events outside of this section, has the same
175 * structure with the original document.
177 * For example, sees the following dom fragment:
178 * <A>
179 * <B/>
180 * <C>
181 * <D>
182 * <E/>
183 * </D>
184 * </C>
185 * </A>
187 * If we consider the SAX event section from startElement(<A>) to
188 * startElement(<D>), then the key SAX events are:
190 * startElement(<A>), startElement(<C>), startElement(<D>)
192 * The startElement(<B>) and endElement(<B>) is ignored, because
193 * they are unimportant for the tree structure in this section.
195 * If we consider the SAX event section from startElement(<D>) to
196 * endElement(<A>), the key SAX events are:
198 * startElement(<D>), endElement(<D>), endElement(<C>),
199 * endElement(<A>).
201 css::uno::Reference< css::xml::crypto::sax::XElementStackKeeper > m_xElementStackKeeper;
204 * a flag representing whether the SAXEventKeeper is now on the
205 * SAX chain.
207 bool m_bIsSAXEventKeeperConnected;
210 * a flag representing whether it is collecting some element,
211 * which means that the SAXEventKeeper can't be chained off the
212 * SAX chain.
214 bool m_bIsCollectingElement;
217 * a flag representing whether the SAX event stream is blocking,
218 * which also means that the SAXEventKeeper can't be chained off
219 * the SAX chain.
221 bool m_bIsBlocking;
224 * a flag representing the current status of security related
225 * components.
229 * status of security related components
231 enum class InitializationState { UNINITIALIZED, INITIALIZED, FAILTOINITIALIZED } m_eStatusOfSecurityComponents;
234 * a flag representing whether the SAXEventKeeper need to be
235 * on the SAX chain all the time.
236 * This flag is used to the situation when creating signature.
238 bool m_bIsSAXEventKeeperSticky;
241 * the XSecParser which is used to parse the signature stream
243 css::uno::Reference<css::xml::sax::XDocumentHandler> m_xSecParser;
246 * the caller assigned signature id for the next signature in the
247 * signature stream
249 sal_Int32 m_nReservedSignatureId;
252 * representing whether to verify the current signature
254 bool m_bVerifyCurrentSignature;
257 * the type of signature to generate (from the css::xml::crypto::DigestID alternatives) when there is a choice,
258 * in practice currently SHA1 or SHA256 for ODF.
260 sal_Int32 m_nDigestID;
262 public:
264 * An xUriBinding is provided to map Uris to XInputStream interfaces.
266 css::uno::Reference< css::xml::crypto::XUriBinding > m_xUriBinding;
268 private:
271 * Common methods
273 void createXSecComponent( );
274 int findSignatureInfor( sal_Int32 nSecurityId ) const;
275 bool chainOn( bool bRetrievingLastEvent );
276 void chainOff();
277 void checkChainingStatus();
278 void initializeSAXChain();
280 css::uno::Reference< css::io::XInputStream > getObjectInputStream( const OUString& objectURL );
282 //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const;
285 * For signature generation
287 static OUString createId();
288 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToWrite(
289 InternalSignatureInformation& signatureInfo,
290 sal_Int32 nStorageFormat,
291 bool bXAdESCompliantIfODF );
294 * For signature verification
296 void addSignature();
297 void addReference(
298 const OUString& ouUri,
299 sal_Int32 nDigestID );
300 void addStreamReference(
301 const OUString& ouUri,
302 bool isBinary,
303 sal_Int32 nDigestID );
304 void setReferenceCount() const;
306 void setX509IssuerName( OUString& ouX509IssuerName );
307 void setX509SerialNumber( OUString& ouX509SerialNumber );
308 void setX509Certificate( OUString& ouX509Certificate );
309 void setSignatureValue( OUString& ouSignatureValue );
310 void setDigestValue( sal_Int32 nDigestID, OUString& ouDigestValue );
312 void setDate( OUString& ouDate );
313 void setDescription(const OUString& rDescription);
314 void setCertDigest(const OUString& rCertDigest);
316 public:
317 void setSignatureBytes(const css::uno::Sequence<sal_Int8>& rBytes);
319 private:
320 void setId( OUString& ouId );
321 void setPropertyId( OUString& ouPropertyId );
323 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToRead(
324 sal_Int32 nSecurityId );
326 public:
327 explicit XSecController(const css::uno::Reference<css::uno::XComponentContext>& rxCtx);
328 virtual ~XSecController() override;
330 sal_Int32 getNewSecurityId( );
332 void startMission( const css::uno::Reference<
333 css::xml::crypto::XUriBinding >& xUriBinding,
334 const css::uno::Reference<
335 css::xml::crypto::XXMLSecurityContext >& xSecurityContext );
337 void setSAXChainConnector(
338 const css::uno::Reference< css::lang::XInitialization >& xInitialization,
339 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
340 const css::uno::Reference< css::xml::crypto::sax::XElementStackKeeper >& xElementStackKeeper);
342 void clearSAXChainConnector();
343 void endMission();
345 SignatureInformation getSignatureInformation( sal_Int32 nSecurityId ) const;
346 SignatureInformations getSignatureInformations() const;
348 static void exportSignature(
349 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
350 const SignatureInformation& signatureInfo,
351 bool bXAdESCompliantIfODF );
355 * For signature generation
357 void signAStream( sal_Int32 securityId, const OUString& uri, const OUString& objectURL, bool isBinary, bool bXAdESCompliantIfODF);
360 /** sets data that describes the certificate.
362 It is absolutely necessary that the parameter ouX509IssuerName is set. It contains
363 the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find
364 the private key. Although issuer name and certificate should be sufficient to identify
365 the certificate the implementation in XMLSec is broken, both for Windows and mozilla.
366 The reason is that they use functions to find the certificate which take as parameter
367 the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes
368 are of type DirectoryName, which is a choice of 5 string types. This information is
369 not contained in the issuer string and while it is converted to the ASN.1 name the
370 conversion function must assume a particular type, which is often wrong. For example,
371 the Windows function CertStrToName will use a T.61 string if the string does not contain
372 special characters. So if the certificate uses simple characters but encodes the
373 issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded
374 ASN.1 name now contains different bytes which indicate the string type. The functions
375 for finding the certificate apparently use memcmp - hence they fail to find the
376 certificate.
378 void setX509Certificate(
379 sal_Int32 nSecurityId,
380 const OUString& ouX509IssuerName,
381 const OUString& ouX509SerialNumber,
382 const OUString& ouX509Cert,
383 const OUString& ouX509CertDigest);
385 void addEncapsulatedX509Certificate(const OUString& rEncapsulatedX509Certificate);
387 void setDate(
388 sal_Int32 nSecurityId,
389 const css::util::DateTime& rDateTime );
390 void setDescription(sal_Int32 nSecurityId, const OUString& rDescription);
392 bool WriteSignature(
393 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
394 bool bXAdESCompliantIfODF);
397 * For signature verification
399 void collectToVerify( const OUString& referenceId );
400 void addSignature( sal_Int32 nSignatureId );
401 css::uno::Reference< css::xml::sax::XDocumentHandler > const & createSignatureReader(sal_Int32 nType = 0);
402 void releaseSignatureReader();
404 public:
405 /* Interface methods */
408 * XSAXEventKeeperStatusChangeListener
410 virtual void SAL_CALL blockingStatusChanged( sal_Bool isBlocking )
411 throw (css::uno::RuntimeException, std::exception) override;
412 virtual void SAL_CALL collectionStatusChanged(
413 sal_Bool isInsideCollectedElement )
414 throw (css::uno::RuntimeException, std::exception) override;
415 virtual void SAL_CALL bufferStatusChanged( sal_Bool isBufferEmpty )
416 throw (css::uno::RuntimeException, std::exception) override;
419 * XSignatureCreationResultListener
421 virtual void SAL_CALL signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
422 throw (css::uno::RuntimeException, std::exception) override;
425 * XSignatureVerifyResultListener
427 virtual void SAL_CALL signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult )
428 throw (css::uno::RuntimeException, std::exception) override;
430 /// Writes XML elements inside a single OOXML signature's <Signature> element.
431 bool WriteOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler);
432 /// Exports an OOXML signature, called by WriteOOXMLSignature().
433 void exportOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation);
436 #endif
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */