1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <sfx2/DocumentSigner.hxx>
13 #include <tools/stream.hxx>
14 #include <unotools/ucbstreamhelper.hxx>
15 #include <unotools/streamwrap.hxx>
17 #include <comphelper/storagehelper.hxx>
18 #include <comphelper/processfactory.hxx>
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>
30 bool DocumentSigner::signDocument(uno::Reference
<security::XCertificate
> const& rxCertificate
)
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
)));
37 uno::Reference
<embed::XStorage
> xWriteableZipStore
;
40 xWriteableZipStore
= comphelper::OStorageHelper::GetStorageOfFormatFromStream(
41 ZIP_STORAGE_FORMAT_STRING
, xInputStream
);
43 catch (const io::IOException
&)
47 OUString
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(xWriteableZipStore
));
49 uno::Reference
<security::XDocumentDigitalSignatures
> xSigner(
50 security::DocumentDigitalSignatures::createWithVersionAndValidSignature(
51 comphelper::getProcessComponentContext(), aODFVersion
,
52 /*bHasValidDocumentSignature*/ true));
56 uno::Reference
<embed::XStorage
> xMetaInf
;
57 if (xWriteableZipStore
.is() && xWriteableZipStore
->hasByName("META-INF"))
59 xMetaInf
= xWriteableZipStore
->openStorageElement("META-INF",
60 embed::ElementModes::READWRITE
);
62 throw uno::RuntimeException();
66 uno::Reference
<embed::XStorage
> xStorage
67 = comphelper::OStorageHelper::GetStorageOfFormatFromStream(
68 ZIP_STORAGE_FORMAT_STRING
, xInputStream
);
71 uno::Reference
<io::XStream
> xStream
;
73 xMetaInf
->openStreamElement(xSigner
->getDocumentContentSignatureDefaultStreamName(),
74 embed::ElementModes::READWRITE
),
76 bool bSuccess
= xSigner
->signDocumentWithCertificate(rxCertificate
, xStorage
, xStream
);
79 uno::Reference
<embed::XTransactedObject
> xTransact(xMetaInf
, uno::UNO_QUERY_THROW
);
81 xTransact
.set(xWriteableZipStore
, uno::UNO_QUERY_THROW
);
86 else if (xWriteableZipStore
.is())
88 uno::Reference
<embed::XStorage
> xStorage
89 = comphelper::OStorageHelper::GetStorageOfFormatFromStream(
90 ZIP_STORAGE_FORMAT_STRING
, xInputStream
);
93 uno::Reference
<io::XStream
> xStream
;
95 // We need read-write to be able to add the signature relation.
96 bool bSuccess
= xSigner
->signDocumentWithCertificate(rxCertificate
, xStorage
, xStream
);
100 uno::Reference
<embed::XTransactedObject
> xTransact(xWriteableZipStore
,
101 uno::UNO_QUERY_THROW
);
108 // Something not ZIP based: e.g. PDF.
109 bResult
= xSigner
->signDocumentWithCertificate(
110 rxCertificate
, uno::Reference
<embed::XStorage
>(), xInputStream
);
113 catch (const uno::Exception
&)
121 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */