Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / xmlsecurity / inc / xsecctl.hxx
blob9ddc22affbae5fb866856c2e289639ab47525b44
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>
44 #include <rtl/ref.hxx>
46 #include <cppuhelper/implbase.hxx>
48 #include <vector>
50 #define NS_XMLDSIG "http://www.w3.org/2000/09/xmldsig#"
51 #define NS_DC "http://purl.org/dc/elements/1.1/"
52 #define NS_XD "http://uri.etsi.org/01903/v1.3.2#"
53 #define NS_MDSSI "http://schemas.openxmlformats.org/package/2006/digital-signature"
55 #define ALGO_C14N "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
56 #define ALGO_RSASHA1 "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
57 #define ALGO_RSASHA256 "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
58 #define ALGO_XMLDSIGSHA1 "http://www.w3.org/2000/09/xmldsig#sha1"
59 #define ALGO_XMLDSIGSHA256 "http://www.w3.org/2001/04/xmlenc#sha256"
60 #define ALGO_RELATIONSHIP "http://schemas.openxmlformats.org/package/2006/RelationshipTransform"
62 class XSecParser;
63 class XMLDocumentWrapper_XmlSecImpl;
64 class SAXEventKeeperImpl;
65 class XMLSignatureHelper;
67 class InternalSignatureInformation
69 public:
70 SignatureInformation signatureInfor;
72 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > xReferenceResolvedListener;
74 ::std::vector< sal_Int32 > vKeeperIds;
76 InternalSignatureInformation(
77 sal_Int32 nId,
78 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > const & xListener)
79 :signatureInfor(nId)
81 xReferenceResolvedListener = xListener;
84 void addReference( SignatureReferenceType type, sal_Int32 digestID, const OUString& uri, sal_Int32 keeperId )
86 signatureInfor.vSignatureReferenceInfors.push_back(
87 SignatureReferenceInformation(type, digestID, uri));
88 vKeeperIds.push_back( keeperId );
92 class XSecController : public cppu::WeakImplHelper
94 css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener,
95 css::xml::crypto::sax::XSignatureCreationResultListener,
96 css::xml::crypto::sax::XSignatureVerifyResultListener
98 /****** XSecController.hxx/CLASS XSecController *******************************
100 * NAME
101 * XSecController -- the xml security framework controller
103 * FUNCTION
104 * Controls the whole xml security framework to create signatures or to
105 * verify signatures.
107 ******************************************************************************/
109 friend class XSecParser;
110 friend class OOXMLSecParser;
112 private:
113 css::uno::Reference< css::uno::XComponentContext> mxCtx;
116 * used to buffer SAX events
118 rtl::Reference<XMLDocumentWrapper_XmlSecImpl> m_xXMLDocumentWrapper;
121 * the SAX events keeper
123 rtl::Reference<SAXEventKeeperImpl> m_xSAXEventKeeper;
126 * the bridge component which creates/verifies signature
128 css::uno::Reference< css::xml::crypto::XXMLSignature > m_xXMLSignature;
131 * the Security Context
133 css::uno::Reference< css::xml::crypto::XXMLSecurityContext > m_xSecurityContext;
136 * the security id incrementer, in order to make any security id unique
137 * to the SAXEventKeeper.
138 * Because each XSecController has its own SAXEventKeeper, so this variable
139 * is not necessary to be static.
141 sal_Int32 m_nNextSecurityId;
144 * Signature information
146 std::vector< InternalSignatureInformation > m_vInternalSignatureInformations;
149 * the previous node on the SAX chain.
150 * The reason that use a Reference<XInterface> type variable
151 * is that the previous components are different when exporting
152 * and importing, and there is no other common interface they
153 * can provided.
155 css::uno::Reference< css::uno::XInterface > m_xPreviousNodeOnSAXChain;
157 * whether the previous node can provide an XInitialize interface,
158 * use this variable in order to typecast the XInterface to the
159 * correct interface type.
161 bool m_bIsPreviousNodeInitializable;
164 * the next node on the SAX chain.
165 * it can always provide an XDocumentHandler interface.
167 css::uno::Reference< css::xml::sax::XDocumentHandler > m_xNextNodeOnSAXChain;
170 * the ElementStackKeeper is used to reserve the key SAX events.
171 * when the SAXEventKeeper is chained on the SAX chain, it need
172 * first get all missed key SAX events in order to make sure the
173 * DOM tree it buffering has the same structure with the original
174 * document.
176 * For a given section of a SAX event stream, the key SAX events
177 * are the minimal SAX event subset of that section, which,
178 * combining with SAX events outside of this section, has the same
179 * structure with the original document.
181 * For example, sees the following dom fragment:
182 * <A>
183 * <B/>
184 * <C>
185 * <D>
186 * <E/>
187 * </D>
188 * </C>
189 * </A>
191 * If we consider the SAX event section from startElement(<A>) to
192 * startElement(<D>), then the key SAX events are:
194 * startElement(<A>), startElement(<C>), startElement(<D>)
196 * The startElement(<B>) and endElement(<B>) is ignored, because
197 * they are unimportant for the tree structure in this section.
199 * If we consider the SAX event section from startElement(<D>) to
200 * endElement(<A>), the key SAX events are:
202 * startElement(<D>), endElement(<D>), endElement(<C>),
203 * endElement(<A>).
205 css::uno::Reference< css::xml::crypto::sax::XElementStackKeeper > m_xElementStackKeeper;
208 * a flag representing whether the SAXEventKeeper is now on the
209 * SAX chain.
211 bool m_bIsSAXEventKeeperConnected;
214 * a flag representing whether it is collecting some element,
215 * which means that the SAXEventKeeper can't be chained off the
216 * SAX chain.
218 bool m_bIsCollectingElement;
221 * a flag representing whether the SAX event stream is blocking,
222 * which also means that the SAXEventKeeper can't be chained off
223 * the SAX chain.
225 bool m_bIsBlocking;
228 * a flag representing the current status of security related
229 * components.
233 * status of security related components
235 enum class InitializationState { UNINITIALIZED, INITIALIZED, FAILTOINITIALIZED } m_eStatusOfSecurityComponents;
238 * a flag representing whether the SAXEventKeeper need to be
239 * on the SAX chain all the time.
240 * This flag is used to the situation when creating signature.
242 bool m_bIsSAXEventKeeperSticky;
245 * the XSecParser which is used to parse the signature stream
247 css::uno::Reference<css::xml::sax::XDocumentHandler> m_xSecParser;
250 * the caller assigned signature id for the next signature in the
251 * signature stream
253 sal_Int32 m_nReservedSignatureId;
256 * representing whether to verify the current signature
258 bool m_bVerifyCurrentSignature;
260 public:
262 * An xUriBinding is provided to map Uris to XInputStream interfaces.
264 css::uno::Reference< css::xml::crypto::XUriBinding > m_xUriBinding;
266 private:
269 * Common methods
271 void createXSecComponent( );
272 int findSignatureInfor( sal_Int32 nSecurityId ) const;
273 bool chainOn( bool bRetrievingLastEvent );
274 void chainOff();
275 void checkChainingStatus();
276 void initializeSAXChain();
278 css::uno::Reference< css::io::XInputStream > getObjectInputStream( const OUString& objectURL );
280 //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const;
283 * For signature generation
285 static OUString createId();
286 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToWrite(
287 InternalSignatureInformation& signatureInfo,
288 sal_Int32 nStorageFormat,
289 bool bXAdESCompliantIfODF );
292 * For signature verification
294 void addSignature();
295 void switchGpgSignature();
296 void addReference(
297 const OUString& ouUri,
298 sal_Int32 nDigestID );
299 void addStreamReference(
300 const OUString& ouUri,
301 bool isBinary,
302 sal_Int32 nDigestID );
303 void setReferenceCount() const;
305 void setX509IssuerName( OUString& ouX509IssuerName );
306 void setX509SerialNumber( OUString& ouX509SerialNumber );
307 void setX509Certificate( OUString& ouX509Certificate );
308 void setSignatureValue( OUString& ouSignatureValue );
309 void setDigestValue( sal_Int32 nDigestID, OUString& ouDigestValue );
310 void setGpgKeyID( OUString& ouKeyID );
311 void setGpgCertificate( OUString& ouGpgCert );
312 void setGpgOwner( OUString& ouGpgOwner );
314 void setDate( OUString& ouDate );
315 void setDescription(const OUString& rDescription);
316 void setCertDigest(const OUString& rCertDigest);
318 public:
319 void setSignatureBytes(const css::uno::Sequence<sal_Int8>& rBytes);
321 private:
322 void setId( OUString& ouId );
323 void setPropertyId( OUString& ouPropertyId );
325 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToRead(
326 sal_Int32 nSecurityId );
328 public:
329 explicit XSecController(const css::uno::Reference<css::uno::XComponentContext>& rxCtx);
330 virtual ~XSecController() override;
332 sal_Int32 getNewSecurityId( );
334 void startMission( const css::uno::Reference<
335 css::xml::crypto::XUriBinding >& xUriBinding,
336 const css::uno::Reference<
337 css::xml::crypto::XXMLSecurityContext >& xSecurityContext );
339 void setSAXChainConnector(
340 const css::uno::Reference< css::lang::XInitialization >& xInitialization,
341 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
342 const css::uno::Reference< css::xml::crypto::sax::XElementStackKeeper >& xElementStackKeeper);
344 void clearSAXChainConnector();
345 void endMission();
347 SignatureInformation getSignatureInformation( sal_Int32 nSecurityId ) const;
348 SignatureInformations getSignatureInformations() const;
350 static void exportSignature(
351 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
352 const SignatureInformation& signatureInfo,
353 bool bXAdESCompliantIfODF );
357 * For signature generation
359 void signAStream( sal_Int32 securityId, const OUString& uri, bool isBinary, bool bXAdESCompliantIfODF);
362 /** sets data that describes the certificate.
364 It is absolutely necessary that the parameter ouX509IssuerName is set. It contains
365 the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find
366 the private key. Although issuer name and certificate should be sufficient to identify
367 the certificate the implementation in XMLSec is broken, both for Windows and mozilla.
368 The reason is that they use functions to find the certificate which take as parameter
369 the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes
370 are of type DirectoryName, which is a choice of 5 string types. This information is
371 not contained in the issuer string and while it is converted to the ASN.1 name the
372 conversion function must assume a particular type, which is often wrong. For example,
373 the Windows function CertStrToName will use a T.61 string if the string does not contain
374 special characters. So if the certificate uses simple characters but encodes the
375 issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded
376 ASN.1 name now contains different bytes which indicate the string type. The functions
377 for finding the certificate apparently use memcmp - hence they fail to find the
378 certificate.
380 void setX509Certificate(
381 sal_Int32 nSecurityId,
382 const OUString& ouX509IssuerName,
383 const OUString& ouX509SerialNumber,
384 const OUString& ouX509Cert,
385 const OUString& ouX509CertDigest);
387 void addEncapsulatedX509Certificate(const OUString& rEncapsulatedX509Certificate);
389 void setGpgCertificate(
390 sal_Int32 nSecurityId,
391 const OUString& ouCertDigest,
392 const OUString& ouCert,
393 const OUString& ouOwner);
395 void setDate(
396 sal_Int32 nSecurityId,
397 const css::util::DateTime& rDateTime );
398 void setDescription(sal_Int32 nSecurityId, const OUString& rDescription);
400 bool WriteSignature(
401 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
402 bool bXAdESCompliantIfODF);
405 * For signature verification
407 void collectToVerify( const OUString& referenceId );
408 void addSignature( sal_Int32 nSignatureId );
409 css::uno::Reference< css::xml::sax::XDocumentHandler > const & createSignatureReader(XMLSignatureHelper& rXMLSignatureHelper, sal_Int32 nType = 0);
410 void releaseSignatureReader();
412 public:
413 /* Interface methods */
416 * XSAXEventKeeperStatusChangeListener
418 virtual void SAL_CALL blockingStatusChanged( sal_Bool isBlocking ) override;
419 virtual void SAL_CALL collectionStatusChanged(
420 sal_Bool isInsideCollectedElement ) override;
421 virtual void SAL_CALL bufferStatusChanged( sal_Bool isBufferEmpty ) override;
424 * XSignatureCreationResultListener
426 virtual void SAL_CALL signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult ) override;
429 * XSignatureVerifyResultListener
431 virtual void SAL_CALL signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult ) override;
433 /// Writes XML elements inside a single OOXML signature's <Signature> element.
434 bool WriteOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler);
435 /// Exports an OOXML signature, called by WriteOOXMLSignature().
436 void exportOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation);
439 #endif
441 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */