Version 24.8.3.2, tag libreoffice-24.8.3.2
[LibreOffice.git] / xmlsecurity / inc / xsecctl.hxx
blob558301a796631d3608eba4fe0ab9a9df620a3d21
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 #pragma once
22 #include <svl/sigstruct.hxx>
24 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeListener.hpp>
25 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultListener.hpp>
26 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultListener.hpp>
28 #include <rtl/ref.hxx>
29 #include <cppuhelper/implbase.hxx>
31 #include <vector>
33 #include "UriBindingHelper.hxx"
35 namespace com::sun::star::embed { class XStorage; }
36 namespace com::sun::star::graphic { class XGraphic; }
37 namespace com::sun::star::io { class XInputStream; }
38 namespace com::sun::star::lang { class XInitialization; }
39 namespace com::sun::star::uno { class XComponentContext; }
40 namespace com::sun::star::xml::crypto { class XXMLSecurityContext; }
41 namespace com::sun::star::xml::crypto { class XXMLSignature; }
42 namespace com::sun::star::xml::crypto:: sax { class XReferenceResolvedListener; }
43 namespace com::sun::star::xml::sax { class XDocumentHandler; }
45 inline constexpr OUString NS_XMLDSIG = u"http://www.w3.org/2000/09/xmldsig#"_ustr;
46 inline constexpr OUString NS_DC = u"http://purl.org/dc/elements/1.1/"_ustr;
47 inline constexpr OUString NS_XD = u"http://uri.etsi.org/01903/v1.3.2#"_ustr;
48 inline constexpr OUString NS_MDSSI = u"http://schemas.openxmlformats.org/package/2006/digital-signature"_ustr;
49 inline constexpr OUString NS_LOEXT = u"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"_ustr;
51 inline constexpr OUString ALGO_C14N = u"http://www.w3.org/TR/2001/REC-xml-c14n-20010315"_ustr;
52 inline constexpr OUString ALGO_RSASHA1 = u"http://www.w3.org/2000/09/xmldsig#rsa-sha1"_ustr;
53 inline constexpr OUString ALGO_RSASHA256 = u"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"_ustr;
54 inline constexpr OUString ALGO_RSASHA512 = u"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"_ustr;
55 inline constexpr OUString ALGO_ECDSASHA1 = u"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"_ustr;
56 inline constexpr OUString ALGO_ECDSASHA256 = u"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"_ustr;
57 inline constexpr OUString ALGO_ECDSASHA512 = u"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"_ustr;
58 inline constexpr OUString ALGO_XMLDSIGSHA1 = u"http://www.w3.org/2000/09/xmldsig#sha1"_ustr;
59 inline constexpr OUString ALGO_XMLDSIGSHA256 = u"http://www.w3.org/2001/04/xmlenc#sha256"_ustr;
60 inline constexpr OUString ALGO_XMLDSIGSHA512 = u"http://www.w3.org/2001/04/xmlenc#sha512"_ustr;
61 inline constexpr OUString ALGO_RELATIONSHIP = u"http://schemas.openxmlformats.org/package/2006/RelationshipTransform"_ustr;
63 class XMLDocumentWrapper_XmlSecImpl;
64 class SAXEventKeeperImpl;
65 class XMLSignatureHelper;
66 namespace svl::crypto { enum class SignatureMethodAlgorithm; }
68 class InternalSignatureInformation
70 public:
71 SignatureInformation signatureInfor;
73 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > xReferenceResolvedListener;
75 ::std::vector< sal_Int32 > vKeeperIds;
77 InternalSignatureInformation(
78 sal_Int32 nId,
79 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > const & xListener)
80 :signatureInfor(nId)
82 xReferenceResolvedListener = xListener;
85 void addReference( SignatureReferenceType type, sal_Int32 digestID, const OUString& uri, sal_Int32 keeperId, const OUString& rType )
87 signatureInfor.vSignatureReferenceInfors.push_back(
88 SignatureReferenceInformation(type, digestID, uri, rType));
89 vKeeperIds.push_back( keeperId );
93 class XSecController final : public cppu::WeakImplHelper
95 css::xml::crypto::sax::XSAXEventKeeperStatusChangeListener,
96 css::xml::crypto::sax::XSignatureCreationResultListener,
97 css::xml::crypto::sax::XSignatureVerifyResultListener
99 /****** XSecController.hxx/CLASS XSecController *******************************
101 * NAME
102 * XSecController -- the xml security framework controller
104 * FUNCTION
105 * Controls the whole xml security framework to create signatures or to
106 * verify signatures.
108 ******************************************************************************/
110 friend class XSecParser;
111 friend class OOXMLSecParser;
113 private:
114 css::uno::Reference< css::uno::XComponentContext> mxCtx;
117 * used to buffer SAX events
119 rtl::Reference<XMLDocumentWrapper_XmlSecImpl> m_xXMLDocumentWrapper;
122 * the SAX events keeper
124 rtl::Reference<SAXEventKeeperImpl> m_xSAXEventKeeper;
127 * the bridge component which creates/verifies signature
129 css::uno::Reference< css::xml::crypto::XXMLSignature > m_xXMLSignature;
132 * the Security Context
134 css::uno::Reference< css::xml::crypto::XXMLSecurityContext > m_xSecurityContext;
137 * the security id incrementer, in order to make any security id unique
138 * to the SAXEventKeeper.
139 * Because each XSecController has its own SAXEventKeeper, so this variable
140 * is not necessary to be static.
142 sal_Int32 m_nNextSecurityId;
145 * Signature information
147 std::vector< InternalSignatureInformation > m_vInternalSignatureInformations;
150 * the previous node on the SAX chain.
151 * The reason that use a Reference<XInterface> type variable
152 * is that the previous components are different when exporting
153 * and importing, and there is no other common interface they
154 * can provided.
156 css::uno::Reference< css::uno::XInterface > m_xPreviousNodeOnSAXChain;
158 * whether the previous node can provide an XInitialize interface,
159 * use this variable in order to typecast the XInterface to the
160 * correct interface type.
162 bool m_bIsPreviousNodeInitializable;
165 * a flag representing whether the SAXEventKeeper is now on the
166 * SAX chain.
168 bool m_bIsSAXEventKeeperConnected;
171 * a flag representing whether it is collecting some element,
172 * which means that the SAXEventKeeper can't be chained off the
173 * SAX chain.
175 bool m_bIsCollectingElement;
178 * a flag representing whether the SAX event stream is blocking,
179 * which also means that the SAXEventKeeper can't be chained off
180 * the SAX chain.
182 bool m_bIsBlocking;
185 * a flag representing the current status of security related
186 * components.
190 * status of security related components
192 enum class InitializationState { UNINITIALIZED, INITIALIZED, FAILTOINITIALIZED } m_eStatusOfSecurityComponents;
195 * a flag representing whether the SAXEventKeeper need to be
196 * on the SAX chain all the time.
197 * This flag is used to the situation when creating signature.
199 bool m_bIsSAXEventKeeperSticky;
202 * the XSecParser which is used to parse the signature stream
204 css::uno::Reference<css::xml::sax::XDocumentHandler> m_xSecParser;
207 * the caller assigned signature id for the next signature in the
208 * signature stream
210 sal_Int32 m_nReservedSignatureId;
213 * representing whether to verify the current signature
215 bool m_bVerifyCurrentSignature;
218 * An xUriBinding is provided to map Uris to XInputStream interfaces.
220 rtl::Reference<UriBindingHelper> m_xUriBinding;
222 private:
225 * Common methods
227 void createXSecComponent( );
228 int findSignatureInfor( sal_Int32 nSecurityId ) const;
229 bool chainOn();
230 void chainOff();
231 void checkChainingStatus();
232 void initializeSAXChain();
234 css::uno::Reference< css::io::XInputStream > getObjectInputStream( const OUString& objectURL );
236 //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const;
239 * For signature generation
241 static OUString createId();
242 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToWrite(
243 InternalSignatureInformation& signatureInfo,
244 sal_Int32 nStorageFormat,
245 bool bXAdESCompliantIfODF );
248 * For signature verification
250 void addSignature();
251 /// Sets algorithm from <SignatureMethod Algorithm="...">.
252 void setSignatureMethod(svl::crypto::SignatureMethodAlgorithm eAlgorithmID);
253 void switchGpgSignature();
254 bool haveReferenceForId(std::u16string_view rId) const;
255 void addReference(
256 const OUString& ouUri,
257 sal_Int32 nDigestID,
258 const OUString& ouType );
259 void addStreamReference(
260 const OUString& ouUri,
261 bool isBinary,
262 sal_Int32 nDigestID );
263 void setReferenceCount() const;
265 void setX509Data(
266 std::vector<std::pair<OUString, OUString>> & rX509IssuerSerials,
267 std::vector<OUString> const& rX509Certificates);
268 void setX509CertDigest(
269 OUString const& rCertDigest, sal_Int32 const nReferenceDigestID,
270 std::u16string_view const& rX509IssuerName, std::u16string_view const& rX509SerialNumber);
272 void setSignatureValue( OUString const & ouSignatureValue );
273 void setDigestValue( sal_Int32 nDigestID, OUString const & ouDigestValue );
274 void setGpgKeyID( OUString const & ouKeyID );
275 void setGpgCertificate( OUString const & ouGpgCert );
276 void setGpgOwner( OUString const & ouGpgOwner );
278 void setDate(OUString const& rId, OUString const& ouDate);
279 void setDescription(OUString const& rId, OUString const& rDescription);
280 void setValidSignatureImage(std::u16string_view rValidSigImg);
281 void setInvalidSignatureImage(std::u16string_view rInvalidSigImg);
282 void setSignatureLineId(const OUString& rSignatureLineId);
284 public:
285 void setSignatureBytes(const css::uno::Sequence<sal_Int8>& rBytes);
287 private:
288 void setId( OUString const & ouId );
290 css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToRead(
291 sal_Int32 nSecurityId );
293 public:
294 explicit XSecController(css::uno::Reference<css::uno::XComponentContext> xCtx);
295 virtual ~XSecController() override;
297 sal_Int32 getNewSecurityId( );
299 void startMission(const rtl::Reference<UriBindingHelper>& xUriBinding, const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext);
301 void setSAXChainConnector(const css::uno::Reference< css::lang::XInitialization >& xInitialization);
303 void clearSAXChainConnector();
304 void endMission();
306 SignatureInformation getSignatureInformation( sal_Int32 nSecurityId ) const;
307 SignatureInformations getSignatureInformations() const;
308 /// only verify can figure out which X509Data is the signing certificate
309 void UpdateSignatureInformation(sal_Int32 nSecurityId,
310 std::vector<SignatureInformation::X509Data> && rDatas);
312 static void exportSignature(
313 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
314 const SignatureInformation& signatureInfo,
315 bool bXAdESCompliantIfODF );
319 * For signature generation
321 void signAStream( sal_Int32 securityId, const OUString& uri, bool isBinary, bool bXAdESCompliantIfODF);
324 /** sets data that describes the certificate.
326 It is absolutely necessary that the parameter ouX509IssuerName is set. It contains
327 the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find
328 the private key. Although issuer name and certificate should be sufficient to identify
329 the certificate the implementation in XMLSec is broken, both for Windows and mozilla.
330 The reason is that they use functions to find the certificate which take as parameter
331 the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes
332 are of type DirectoryName, which is a choice of 5 string types. This information is
333 not contained in the issuer string and while it is converted to the ASN.1 name the
334 conversion function must assume a particular type, which is often wrong. For example,
335 the Windows function CertStrToName will use a T.61 string if the string does not contain
336 special characters. So if the certificate uses simple characters but encodes the
337 issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded
338 ASN.1 name now contains different bytes which indicate the string type. The functions
339 for finding the certificate apparently use memcmp - hence they fail to find the
340 certificate.
342 void setX509Certificate(
343 sal_Int32 nSecurityId,
344 const OUString& ouX509IssuerName,
345 const OUString& ouX509SerialNumber,
346 const OUString& ouX509Cert,
347 const OUString& ouX509CertDigest,
348 svl::crypto::SignatureMethodAlgorithm eAlgorithmID);
350 void addEncapsulatedX509Certificate(const OUString& rEncapsulatedX509Certificate);
352 void setGpgCertificate(
353 sal_Int32 nSecurityId,
354 const OUString& ouCertDigest,
355 const OUString& ouCert,
356 const OUString& ouOwner);
358 void setDate(
359 sal_Int32 nSecurityId,
360 const css::util::DateTime& rDateTime );
361 void setDescription(sal_Int32 nSecurityId, const OUString& rDescription);
362 void setSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId);
363 void
364 setSignatureLineValidGraphic(sal_Int32 nSecurityId,
365 const css::uno::Reference<css::graphic::XGraphic>& xValidGraphic);
366 void setSignatureLineInvalidGraphic(
367 sal_Int32 nSecurityId, const css::uno::Reference<css::graphic::XGraphic>& xInvalidGraphic);
369 bool WriteSignature(
370 const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
371 bool bXAdESCompliantIfODF);
374 * For signature verification
376 void collectToVerify( std::u16string_view referenceId );
377 void addSignature( sal_Int32 nSignatureId );
378 css::uno::Reference< css::xml::sax::XDocumentHandler > const & createSignatureReader(XMLSignatureHelper& rXMLSignatureHelper, sal_Int32 nType = 0);
379 void releaseSignatureReader();
381 public:
382 /* Interface methods */
385 * XSAXEventKeeperStatusChangeListener
387 virtual void SAL_CALL blockingStatusChanged( sal_Bool isBlocking ) override;
388 virtual void SAL_CALL collectionStatusChanged(
389 sal_Bool isInsideCollectedElement ) override;
390 virtual void SAL_CALL bufferStatusChanged( sal_Bool isBufferEmpty ) override;
393 * XSignatureCreationResultListener
395 virtual void SAL_CALL signatureCreated( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult ) override;
398 * XSignatureVerifyResultListener
400 virtual void SAL_CALL signatureVerified( sal_Int32 securityId, css::xml::crypto::SecurityOperationStatus nResult ) override;
402 /// Writes XML elements inside a single OOXML signature's <Signature> element.
403 bool WriteOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler);
404 /// Exports an OOXML signature, called by WriteOOXMLSignature().
405 void exportOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation);
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */