LibreOffice Module sfx2 (master) 1
DocumentSigner.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 */
10
12
13#include <tools/stream.hxx>
16
19
20#include <com/sun/star/embed/XStorage.hpp>
21#include <com/sun/star/embed/XTransactedObject.hpp>
22#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
23#include <com/sun/star/io/IOException.hpp>
24#include <com/sun/star/io/XStream.hpp>
25
26using namespace css;
27
28namespace sfx2
29{
30bool DocumentSigner::signDocument(uno::Reference<security::XCertificate> const& rxCertificate)
31{
32 std::unique_ptr<SvStream> pStream(
33 utl::UcbStreamHelper::CreateStream(m_aUrl, StreamMode::READ | StreamMode::WRITE));
34 uno::Reference<io::XStream> xInputStream(new utl::OStreamWrapper(std::move(pStream)));
35
36 bool bResult = false;
37 uno::Reference<embed::XStorage> xWriteableZipStore;
38 try
39 {
41 ZIP_STORAGE_FORMAT_STRING, xInputStream);
42 }
43 catch (const io::IOException&)
44 {
45 }
46
47 OUString aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(xWriteableZipStore));
48
49 uno::Reference<security::XDocumentDigitalSignatures> xSigner(
50 security::DocumentDigitalSignatures::createWithVersionAndValidSignature(
52 /*bHasValidDocumentSignature*/ true));
53
54 try
55 {
56 uno::Reference<embed::XStorage> xMetaInf;
57 if (xWriteableZipStore.is() && xWriteableZipStore->hasByName("META-INF"))
58 {
59 xMetaInf = xWriteableZipStore->openStorageElement("META-INF",
60 embed::ElementModes::READWRITE);
61 if (!xMetaInf.is())
62 throw uno::RuntimeException();
63 }
64 if (xMetaInf.is())
65 {
66 uno::Reference<embed::XStorage> xStorage
68 ZIP_STORAGE_FORMAT_STRING, xInputStream);
69
70 // ODF.
71 uno::Reference<io::XStream> xStream;
72 xStream.set(
73 xMetaInf->openStreamElement(xSigner->getDocumentContentSignatureDefaultStreamName(),
74 embed::ElementModes::READWRITE),
75 uno::UNO_SET_THROW);
76 bool bSuccess = xSigner->signDocumentWithCertificate(rxCertificate, xStorage, xStream);
77 if (bSuccess)
78 {
79 uno::Reference<embed::XTransactedObject> xTransact(xMetaInf, uno::UNO_QUERY_THROW);
80 xTransact->commit();
81 xTransact.set(xWriteableZipStore, uno::UNO_QUERY_THROW);
82 xTransact->commit();
83 bResult = true;
84 }
85 }
86 else if (xWriteableZipStore.is())
87 {
88 uno::Reference<embed::XStorage> xStorage
90 ZIP_STORAGE_FORMAT_STRING, xInputStream);
91
92 // OOXML.
93 uno::Reference<io::XStream> xStream;
94
95 // We need read-write to be able to add the signature relation.
96 bool bSuccess = xSigner->signDocumentWithCertificate(rxCertificate, xStorage, xStream);
97
98 if (bSuccess)
99 {
100 uno::Reference<embed::XTransactedObject> xTransact(xWriteableZipStore,
101 uno::UNO_QUERY_THROW);
102 xTransact->commit();
103 bResult = true;
104 }
105 }
106 else
107 {
108 // Something not ZIP based: e.g. PDF.
109 bResult = xSigner->signDocumentWithCertificate(
110 rxCertificate, uno::Reference<embed::XStorage>(), xInputStream);
111 }
112 }
113 catch (const uno::Exception&)
114 {
115 }
116 return bResult;
117}
118
119} // namespace sfx2
120
121/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
static OUString GetODFVersionFromStorage(const css::uno::Reference< css::embed::XStorage > &xStorage)
static css::uno::Reference< css::embed::XStorage > GetStorageOfFormatFromStream(const OUString &aFormat, const css::uno::Reference< css::io::XStream > &xStream, sal_Int32 nStorageMode=css::embed::ElementModes::READWRITE, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >(), bool bRepairStorage=false)
bool signDocument(css::uno::Reference< css::security::XCertificate > const &rxCertificate)
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
Reference< XComponentContext > getProcessComponentContext()
constexpr OUStringLiteral ZIP_STORAGE_FORMAT_STRING