cool#9992 lok doc sign: allow sign of macros & the document itself in one step
Sign a document with macros (via file -> digital signatures -> digital signatures), realize that you still get a warning on file open, sign the macros in the document (via tools -> macros -> digital signature), realize that you did this in the wrong order, so now you have to re-sign the doc content. The reason for this is that the macro signature only signs the macro parts of the document (so you can still edit the document and the signature is valid, as long as you don't touch macros), while the doc content signature signs everything, including the macro signature, so the order of the two matters. Solve this trouble by adding a new setting that allows doing the two signatures in one step. Do this by extending the doc content signing code with an optional pre-step that first signs the document macros. This is a bit tricky to do, since xmlsecurity/ gets an RW signature stream and a RO document storage from sfx2/, but transferring one more signature stream can solve this trouble. Other tricky parts of the change: 1) The crypto signing is always done by libxmlsec, so DigitalSignaturesDialog::SetScriptingSignatureStream() has to update the storage of the sign manager's sign helper, otherwise, the hashes in the macro signature will be empty. 2) Signing reads the RO storage, so normally the macro signature would not be part of the doc signature when creating both signatures inside a single dialog. (The storage is only committed after the dialog ends.) Fix this problem by extending DocumentSignatureManager::add() and UriBindingHelper::OpenInputStream() to provide kind of an overlay when xmlsecurity/ gets a script signature stream: this way the macro signature will be part of the doc signature while the dialog is in progress. No overlay is needed later, once both streams are committed to the storage on dialog end. Change-Id: Ic2728689997165595991d5ec59c7a2683286e22d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173263 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
This commit is contained in:
@@ -45,6 +45,11 @@ public:
|
|||||||
const std::function<void(bool)>& rCallback)
|
const std::function<void(bool)>& rCallback)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
|
/// Create a scripting signature before creating a document signature.
|
||||||
|
virtual void
|
||||||
|
SetSignScriptingContent(const css::uno::Reference<css::io::XStream>& xScriptingSignStream)
|
||||||
|
= 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~DigitalSignatures() noexcept = default;
|
~DigitalSignatures() noexcept = default;
|
||||||
};
|
};
|
||||||
|
@@ -2358,6 +2358,13 @@
|
|||||||
</info>
|
</info>
|
||||||
<value>true</value>
|
<value>true</value>
|
||||||
</prop>
|
</prop>
|
||||||
|
<prop oor:name="ImplicitScriptSign" oor:type="xs:boolean" oor:nillable="false">
|
||||||
|
<info>
|
||||||
|
<desc>Specifies whether to implicitly sign macros when adding the first signature
|
||||||
|
to an ODF document with macros.</desc>
|
||||||
|
</info>
|
||||||
|
<value>false</value>
|
||||||
|
</prop>
|
||||||
<prop oor:name="CertDir" oor:type="xs:string">
|
<prop oor:name="CertDir" oor:type="xs:string">
|
||||||
<info>
|
<info>
|
||||||
<desc>Contains the path to the users NSS certificate directory.</desc>
|
<desc>Contains the path to the users NSS certificate directory.</desc>
|
||||||
|
@@ -4439,12 +4439,39 @@ void SfxMedium::SignContents_Impl(weld::Window* pDialogParent,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Signing the entire document.
|
||||||
if (xMetaInf.is())
|
if (xMetaInf.is())
|
||||||
{
|
{
|
||||||
// ODF.
|
// ODF.
|
||||||
uno::Reference< io::XStream > xStream;
|
uno::Reference< io::XStream > xStream;
|
||||||
|
uno::Reference< io::XStream > xScriptingStream;
|
||||||
if (GetFilter() && GetFilter()->IsOwnFormat())
|
if (GetFilter() && GetFilter()->IsOwnFormat())
|
||||||
|
{
|
||||||
|
bool bImplicitScriptSign = officecfg::Office::Common::Security::Scripting::ImplicitScriptSign::get();
|
||||||
|
if (comphelper::LibreOfficeKit::isActive())
|
||||||
|
{
|
||||||
|
bImplicitScriptSign = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
OUString aDocSigName = xSigner->getDocumentContentSignatureDefaultStreamName();
|
||||||
|
bool bHasSignatures = xMetaInf->hasByName(aDocSigName);
|
||||||
|
|
||||||
|
// C.f. DocumentSignatureHelper::CreateElementList() for the
|
||||||
|
// DocumentSignatureMode::Macros case.
|
||||||
|
bool bHasMacros = xWriteableZipStor->hasByName(u"Basic"_ustr)
|
||||||
|
|| xWriteableZipStor->hasByName(u"Dialogs"_ustr)
|
||||||
|
|| xWriteableZipStor->hasByName(u"Scripts"_ustr);
|
||||||
|
|
||||||
xStream.set(xMetaInf->openStreamElement(xSigner->getDocumentContentSignatureDefaultStreamName(), embed::ElementModes::READWRITE), uno::UNO_SET_THROW);
|
xStream.set(xMetaInf->openStreamElement(xSigner->getDocumentContentSignatureDefaultStreamName(), embed::ElementModes::READWRITE), uno::UNO_SET_THROW);
|
||||||
|
if (bImplicitScriptSign && bHasMacros && !bHasSignatures)
|
||||||
|
{
|
||||||
|
xScriptingStream.set(
|
||||||
|
xMetaInf->openStreamElement(
|
||||||
|
xSigner->getScriptingContentSignatureDefaultStreamName(),
|
||||||
|
embed::ElementModes::READWRITE),
|
||||||
|
uno::UNO_SET_THROW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool bSuccess = false;
|
bool bSuccess = false;
|
||||||
auto onODFSignDocumentContentFinished = [this, xMetaInf, xWriteableZipStor]() {
|
auto onODFSignDocumentContentFinished = [this, xMetaInf, xWriteableZipStor]() {
|
||||||
@@ -4462,6 +4489,11 @@ void SfxMedium::SignContents_Impl(weld::Window* pDialogParent,
|
|||||||
xValidGraphic, xInvalidGraphic, aComment);
|
xValidGraphic, xInvalidGraphic, aComment);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (xScriptingStream.is())
|
||||||
|
{
|
||||||
|
xModelSigner->SetSignScriptingContent(xScriptingStream);
|
||||||
|
}
|
||||||
|
|
||||||
// Async, all code before return has to go into the callback.
|
// Async, all code before return has to go into the callback.
|
||||||
xModelSigner->SignDocumentContentAsync(GetZipStorageToSign_Impl(),
|
xModelSigner->SignDocumentContentAsync(GetZipStorageToSign_Impl(),
|
||||||
xStream, [onODFSignDocumentContentFinished, onSignDocumentContentFinished](bool bRet) {
|
xStream, [onODFSignDocumentContentFinished, onSignDocumentContentFinished](bool bRet) {
|
||||||
|
@@ -26,7 +26,10 @@
|
|||||||
#include <com/sun/star/xml/crypto/XUriBinding.hpp>
|
#include <com/sun/star/xml/crypto/XUriBinding.hpp>
|
||||||
|
|
||||||
namespace com::sun::star {
|
namespace com::sun::star {
|
||||||
namespace io { class XInputStream; }
|
namespace io {
|
||||||
|
class XStream;
|
||||||
|
class XInputStream;
|
||||||
|
}
|
||||||
namespace embed { class XStorage; }
|
namespace embed { class XStorage; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,16 +39,17 @@ class UriBindingHelper final : public cppu::WeakImplHelper< css::xml::crypto::XU
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
css::uno::Reference < css::embed::XStorage > mxStorage;
|
css::uno::Reference < css::embed::XStorage > mxStorage;
|
||||||
|
css::uno::Reference<css::io::XStream> mxScriptingSignatureStream;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UriBindingHelper();
|
UriBindingHelper();
|
||||||
explicit UriBindingHelper( const css::uno::Reference < css::embed::XStorage >& rxStorage );
|
explicit UriBindingHelper( const css::uno::Reference < css::embed::XStorage >& rxStorage, const css::uno::Reference<css::io::XStream>& xScriptingSignatureStream );
|
||||||
|
|
||||||
void SAL_CALL setUriBinding( const OUString& uri, const css::uno::Reference< css::io::XInputStream >& aInputStream ) override;
|
void SAL_CALL setUriBinding( const OUString& uri, const css::uno::Reference< css::io::XInputStream >& aInputStream ) override;
|
||||||
|
|
||||||
css::uno::Reference< css::io::XInputStream > SAL_CALL getUriBinding( const OUString& uri ) override;
|
css::uno::Reference< css::io::XInputStream > SAL_CALL getUriBinding( const OUString& uri ) override;
|
||||||
|
|
||||||
static css::uno::Reference < css::io::XInputStream > OpenInputStream( const css::uno::Reference < css::embed::XStorage >& rxStore, const OUString& rURI );
|
static css::uno::Reference < css::io::XInputStream > OpenInputStream( const css::uno::Reference < css::embed::XStorage >& rxStore, const OUString& rURI, const css::uno::Reference<css::io::XStream>& xScriptingSignatureStream );
|
||||||
};
|
};
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -39,6 +39,7 @@ class DigitalSignaturesDialog final : public weld::GenericDialogController
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
DocumentSignatureManager maSignatureManager;
|
DocumentSignatureManager maSignatureManager;
|
||||||
|
std::optional<DocumentSignatureManager> moScriptSignatureManager;
|
||||||
bool mbVerifySignatures;
|
bool mbVerifySignatures;
|
||||||
bool mbSignaturesChanged;
|
bool mbSignaturesChanged;
|
||||||
|
|
||||||
@@ -108,6 +109,7 @@ public:
|
|||||||
// Set the storage which should be signed or verified
|
// Set the storage which should be signed or verified
|
||||||
void SetStorage( const css::uno::Reference < css::embed::XStorage >& rxStore );
|
void SetStorage( const css::uno::Reference < css::embed::XStorage >& rxStore );
|
||||||
void SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream );
|
void SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream );
|
||||||
|
void SetScriptingSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream );
|
||||||
|
|
||||||
// Execute the dialog...
|
// Execute the dialog...
|
||||||
void beforeRun();
|
void beforeRun();
|
||||||
|
@@ -68,6 +68,7 @@ private:
|
|||||||
DocumentSignatureMode const meSignatureMode;
|
DocumentSignatureMode const meSignatureMode;
|
||||||
css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>> m_manifest;
|
css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>> m_manifest;
|
||||||
css::uno::Reference<css::io::XStream> mxSignatureStream;
|
css::uno::Reference<css::io::XStream> mxSignatureStream;
|
||||||
|
css::uno::Reference<css::io::XStream> mxScriptingSignatureStream;
|
||||||
css::uno::Reference<css::frame::XModel> mxModel;
|
css::uno::Reference<css::frame::XModel> mxModel;
|
||||||
rtl::Reference<utl::TempFileFastService> mxTempSignatureStream;
|
rtl::Reference<utl::TempFileFastService> mxTempSignatureStream;
|
||||||
/// Storage containing all OOXML signatures, unused for ODF.
|
/// Storage containing all OOXML signatures, unused for ODF.
|
||||||
@@ -126,6 +127,12 @@ public:
|
|||||||
{
|
{
|
||||||
mxSignatureStream = xSignatureStream;
|
mxSignatureStream = xSignatureStream;
|
||||||
}
|
}
|
||||||
|
css::uno::Reference<css::io::XStream> getSignatureStream() const { return mxSignatureStream; }
|
||||||
|
void setScriptingSignatureStream(
|
||||||
|
const css::uno::Reference<css::io::XStream>& xScriptingSignatureStream)
|
||||||
|
{
|
||||||
|
mxScriptingSignatureStream = xScriptingSignatureStream;
|
||||||
|
}
|
||||||
void setModel(const css::uno::Reference<css::frame::XModel>& xModel);
|
void setModel(const css::uno::Reference<css::frame::XModel>& xModel);
|
||||||
const css::uno::Reference<css::embed::XStorage>& getStore() const { return mxStore; }
|
const css::uno::Reference<css::embed::XStorage>& getStore() const { return mxStore; }
|
||||||
DocumentSignatureMode getSignatureMode() const { return meSignatureMode; }
|
DocumentSignatureMode getSignatureMode() const { return meSignatureMode; }
|
||||||
|
@@ -36,6 +36,7 @@ namespace com::sun::star {
|
|||||||
namespace io {
|
namespace io {
|
||||||
class XOutputStream;
|
class XOutputStream;
|
||||||
class XInputStream;
|
class XInputStream;
|
||||||
|
class XStream;
|
||||||
}
|
}
|
||||||
namespace embed { class XStorage; }
|
namespace embed { class XStorage; }
|
||||||
}
|
}
|
||||||
@@ -82,7 +83,7 @@ public:
|
|||||||
// Set the storage which should be used by the default UriBinding
|
// Set the storage which should be used by the default UriBinding
|
||||||
// Must be set before StartMission().
|
// Must be set before StartMission().
|
||||||
//sODFVersion indicates the ODF version
|
//sODFVersion indicates the ODF version
|
||||||
XMLSECURITY_DLLPUBLIC void SetStorage( const css::uno::Reference < css::embed::XStorage >& rxStorage, std::u16string_view sODFVersion );
|
XMLSECURITY_DLLPUBLIC void SetStorage( const css::uno::Reference < css::embed::XStorage >& rxStorage, std::u16string_view sODFVersion, const css::uno::Reference<css::io::XStream>& xScriptStream = css::uno::Reference<css::io::XStream>() );
|
||||||
|
|
||||||
// Argument for the Link is a uno::Reference< xml::sax::XAttributeList >*
|
// Argument for the Link is a uno::Reference< xml::sax::XAttributeList >*
|
||||||
// Return 1 to verify, 0 to skip.
|
// Return 1 to verify, 0 to skip.
|
||||||
|
BIN
xmlsecurity/qa/unit/signing/data/macro.odt
Normal file
BIN
xmlsecurity/qa/unit/signing/data/macro.odt
Normal file
Binary file not shown.
@@ -1149,6 +1149,68 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSignatureLineODF)
|
|||||||
CPPUNIT_ASSERT(xSignatureInfo[0].InvalidSignatureLineImage.is());
|
CPPUNIT_ASSERT(xSignatureInfo[0].InvalidSignatureLineImage.is());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPUNIT_TEST_FIXTURE(SigningTest, testImplicitScriptSign)
|
||||||
|
{
|
||||||
|
// Given an ODT file with macros, and two signature managers to create macro + doc signatures:
|
||||||
|
OUString aFileURL = createFileURL(u"macro.odt");
|
||||||
|
uno::Reference<embed::XStorage> xWriteableZipStor
|
||||||
|
= comphelper::OStorageHelper::GetStorageOfFormatFromURL(ZIP_STORAGE_FORMAT_STRING, aFileURL,
|
||||||
|
embed::ElementModes::READWRITE);
|
||||||
|
uno::Reference<embed::XStorage> xMetaInf
|
||||||
|
= xWriteableZipStor->openStorageElement(u"META-INF"_ustr, embed::ElementModes::READWRITE);
|
||||||
|
uno::Reference<io::XStream> xStream = xMetaInf->openStreamElement(
|
||||||
|
u"documentsignatures.xml"_ustr, embed::ElementModes::READWRITE);
|
||||||
|
uno::Reference<io::XStream> xScriptingStream
|
||||||
|
= xMetaInf->openStreamElement(u"macrosignatures.xml"_ustr, embed::ElementModes::READWRITE);
|
||||||
|
uno::Reference<embed::XStorage> xZipStor
|
||||||
|
= comphelper::OStorageHelper::GetStorageOfFormatFromURL(ZIP_STORAGE_FORMAT_STRING, aFileURL,
|
||||||
|
embed::ElementModes::READ);
|
||||||
|
DocumentSignatureManager aManager(m_xContext, DocumentSignatureMode::Content);
|
||||||
|
CPPUNIT_ASSERT(aManager.init());
|
||||||
|
aManager.setStore(xZipStor);
|
||||||
|
aManager.setSignatureStream(xStream);
|
||||||
|
aManager.getSignatureHelper().SetStorage(xZipStor, u"1.2", xScriptingStream);
|
||||||
|
DocumentSignatureManager aScriptManager(m_xContext, DocumentSignatureMode::Macros);
|
||||||
|
CPPUNIT_ASSERT(aScriptManager.init());
|
||||||
|
aScriptManager.setStore(xZipStor);
|
||||||
|
aScriptManager.getSignatureHelper().SetStorage(xZipStor, u"1.2");
|
||||||
|
aScriptManager.setSignatureStream(xScriptingStream);
|
||||||
|
uno::Reference<security::XCertificate> xCertificate
|
||||||
|
= getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::RSA);
|
||||||
|
if (!xCertificate.is())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// When adding those signatures and writing them to the streams from the read-write storage:
|
||||||
|
OUString aDescription;
|
||||||
|
sal_Int32 nSecurityId;
|
||||||
|
bool bAdESCompliant = true;
|
||||||
|
aScriptManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant);
|
||||||
|
aScriptManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
|
||||||
|
aScriptManager.write(bAdESCompliant);
|
||||||
|
aManager.setScriptingSignatureStream(xScriptingStream);
|
||||||
|
aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant);
|
||||||
|
aManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
|
||||||
|
aManager.write(bAdESCompliant);
|
||||||
|
|
||||||
|
// Then make sure both signatures are created correctly:
|
||||||
|
std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xScriptingStream, true));
|
||||||
|
xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get());
|
||||||
|
OUString aScriptDigest = getXPathContent(
|
||||||
|
pXmlDoc, "/odfds:document-signatures/dsig:Signature[1]/dsig:SignedInfo/"
|
||||||
|
"dsig:Reference[@URI='Basic/script-lc.xml']/dsig:DigestValue"_ostr);
|
||||||
|
// Without the accompanying fix in place, this test would have failed, the digest value was just a
|
||||||
|
// " " placeholder.
|
||||||
|
CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(1), aScriptDigest.getLength());
|
||||||
|
pStream = utl::UcbStreamHelper::CreateStream(xStream, true);
|
||||||
|
pXmlDoc = parseXmlStream(pStream.get());
|
||||||
|
// Without the accompanying fix in place, this test would have failed, the macro signature was
|
||||||
|
// not part of the signed data of the document signature.
|
||||||
|
assertXPath(pXmlDoc,
|
||||||
|
"/odfds:document-signatures/dsig:Signature[1]/dsig:SignedInfo/"
|
||||||
|
"dsig:Reference[@URI='META-INF/macrosignatures.xml']"_ostr,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_FEATURE_GPGVERIFY
|
#if HAVE_FEATURE_GPGVERIFY
|
||||||
/// Test a typical ODF where all streams are GPG-signed.
|
/// Test a typical ODF where all streams are GPG-signed.
|
||||||
CPPUNIT_TEST_FIXTURE(SigningTest, testODFGoodGPG)
|
CPPUNIT_TEST_FIXTURE(SigningTest, testODFGoodGPG)
|
||||||
|
@@ -70,6 +70,7 @@ class DocumentDigitalSignatures
|
|||||||
private:
|
private:
|
||||||
css::uno::Reference<css::uno::XComponentContext> mxCtx;
|
css::uno::Reference<css::uno::XComponentContext> mxCtx;
|
||||||
css::uno::Reference<css::awt::XWindow> mxParentWindow;
|
css::uno::Reference<css::awt::XWindow> mxParentWindow;
|
||||||
|
uno::Reference<io::XStream> mxScriptingSignStream;
|
||||||
|
|
||||||
/// will be set by XInitialization. If not we assume true. false means an earlier version (whatever that means,
|
/// will be set by XInitialization. If not we assume true. false means an earlier version (whatever that means,
|
||||||
/// this is a string, not a boolean).
|
/// this is a string, not a boolean).
|
||||||
@@ -221,6 +222,10 @@ public:
|
|||||||
void SignScriptingContentAsync(const css::uno::Reference<css::embed::XStorage>& xStorage,
|
void SignScriptingContentAsync(const css::uno::Reference<css::embed::XStorage>& xStorage,
|
||||||
const css::uno::Reference<css::io::XStream>& xSignStream,
|
const css::uno::Reference<css::io::XStream>& xSignStream,
|
||||||
const std::function<void(bool)>& rCallback) override;
|
const std::function<void(bool)>& rCallback) override;
|
||||||
|
|
||||||
|
/// See sfx2::DigitalSignatures::SetSignScriptingContent().
|
||||||
|
void SetSignScriptingContent(
|
||||||
|
const css::uno::Reference<css::io::XStream>& xScriptingSignStream) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -444,6 +449,7 @@ void DocumentDigitalSignatures::ImplViewSignatures(
|
|||||||
xSignaturesDialog->SetStorage(rxStorage);
|
xSignaturesDialog->SetStorage(rxStorage);
|
||||||
|
|
||||||
xSignaturesDialog->SetSignatureStream( xSignStream );
|
xSignaturesDialog->SetSignatureStream( xSignStream );
|
||||||
|
xSignaturesDialog->SetScriptingSignatureStream( mxScriptingSignStream );
|
||||||
|
|
||||||
xSignaturesDialog->beforeRun();
|
xSignaturesDialog->beforeRun();
|
||||||
weld::DialogController::runAsync(xSignaturesDialog, [xSignaturesDialog, rxStorage, xSignStream, rCallback] (sal_Int32 nRet) {
|
weld::DialogController::runAsync(xSignaturesDialog, [xSignaturesDialog, rxStorage, xSignStream, rCallback] (sal_Int32 nRet) {
|
||||||
@@ -849,6 +855,12 @@ void DocumentDigitalSignatures::SignScriptingContentAsync(
|
|||||||
ImplViewSignatures( rxStorage, xSignStream, DocumentSignatureMode::Macros, false, rCallback );
|
ImplViewSignatures( rxStorage, xSignStream, DocumentSignatureMode::Macros, false, rCallback );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocumentDigitalSignatures::SetSignScriptingContent(
|
||||||
|
const css::uno::Reference<css::io::XStream>& xScriptingSignStream)
|
||||||
|
{
|
||||||
|
mxScriptingSignStream = xScriptingSignStream;
|
||||||
|
}
|
||||||
|
|
||||||
sal_Bool DocumentDigitalSignatures::signPackageWithCertificate(
|
sal_Bool DocumentDigitalSignatures::signPackageWithCertificate(
|
||||||
css::uno::Reference<css::security::XCertificate> const& xCertificate,
|
css::uno::Reference<css::security::XCertificate> const& xCertificate,
|
||||||
css::uno::Reference<css::embed::XStorage> const& xStorage,
|
css::uno::Reference<css::embed::XStorage> const& xStorage,
|
||||||
|
@@ -311,7 +311,7 @@ void DigitalSignaturesDialog::SetStorage( const css::uno::Reference < css::embed
|
|||||||
|| !DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
|
|| !DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
|
||||||
|
|
||||||
maSignatureManager.setStore(rxStore);
|
maSignatureManager.setStore(rxStore);
|
||||||
maSignatureManager.getSignatureHelper().SetStorage( maSignatureManager.getStore(), m_sODFVersion);
|
maSignatureManager.getSignatureHelper().SetStorage( maSignatureManager.getStore(), m_sODFVersion, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream )
|
void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream )
|
||||||
@@ -319,6 +319,26 @@ void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference < cs
|
|||||||
maSignatureManager.setSignatureStream(rxStream);
|
maSignatureManager.setSignatureStream(rxStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DigitalSignaturesDialog::SetScriptingSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream )
|
||||||
|
{
|
||||||
|
if (!rxStream.is())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
|
||||||
|
moScriptSignatureManager.emplace(xContext, DocumentSignatureMode::Macros);
|
||||||
|
if (!moScriptSignatureManager->init())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
moScriptSignatureManager->setStore(maSignatureManager.getStore());
|
||||||
|
// This is the storage used by UriBindingHelper::getUriBinding().
|
||||||
|
moScriptSignatureManager->getSignatureHelper().SetStorage(maSignatureManager.getStore(), m_sODFVersion);
|
||||||
|
maSignatureManager.getSignatureHelper().SetStorage(maSignatureManager.getStore(), m_sODFVersion, rxStream);
|
||||||
|
moScriptSignatureManager->setSignatureStream(rxStream);
|
||||||
|
}
|
||||||
|
|
||||||
bool DigitalSignaturesDialog::canAddRemove()
|
bool DigitalSignaturesDialog::canAddRemove()
|
||||||
{
|
{
|
||||||
//FIXME: this func needs some cleanup, such as real split between
|
//FIXME: this func needs some cleanup, such as real split between
|
||||||
@@ -469,6 +489,23 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, weld::Button&, void)
|
|||||||
while (aChooser->run() == RET_OK)
|
while (aChooser->run() == RET_OK)
|
||||||
{
|
{
|
||||||
sal_Int32 nSecurityId;
|
sal_Int32 nSecurityId;
|
||||||
|
|
||||||
|
if (moScriptSignatureManager)
|
||||||
|
{
|
||||||
|
if (!moScriptSignatureManager->add(aChooser->GetSelectedCertificates()[0],
|
||||||
|
aChooser->GetSelectedSecurityContext(),
|
||||||
|
aChooser->GetDescription(), nSecurityId,
|
||||||
|
m_bAdESCompliant))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
moScriptSignatureManager->read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
|
||||||
|
moScriptSignatureManager->write(m_bAdESCompliant);
|
||||||
|
|
||||||
|
maSignatureManager.setScriptingSignatureStream(moScriptSignatureManager->getSignatureStream());
|
||||||
|
}
|
||||||
|
|
||||||
if (!maSignatureManager.add(aChooser->GetSelectedCertificates()[0], aChooser->GetSelectedSecurityContext(),
|
if (!maSignatureManager.add(aChooser->GetSelectedCertificates()[0], aChooser->GetSelectedSecurityContext(),
|
||||||
aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
|
aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
|
||||||
return;
|
return;
|
||||||
|
@@ -28,6 +28,8 @@
|
|||||||
#include <rtl/uri.hxx>
|
#include <rtl/uri.hxx>
|
||||||
#include <sal/log.hxx>
|
#include <sal/log.hxx>
|
||||||
|
|
||||||
|
#include <documentsignaturehelper.hxx>
|
||||||
|
|
||||||
using namespace com::sun::star;
|
using namespace com::sun::star;
|
||||||
|
|
||||||
// XUriBinding
|
// XUriBinding
|
||||||
@@ -36,9 +38,10 @@ UriBindingHelper::UriBindingHelper()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
UriBindingHelper::UriBindingHelper( const css::uno::Reference < css::embed::XStorage >& rxStorage )
|
UriBindingHelper::UriBindingHelper( const css::uno::Reference < css::embed::XStorage >& rxStorage, const uno::Reference<io::XStream>& xScriptingSignatureStream )
|
||||||
{
|
{
|
||||||
mxStorage = rxStorage;
|
mxStorage = rxStorage;
|
||||||
|
mxScriptingSignatureStream = xScriptingSignatureStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAL_CALL UriBindingHelper::setUriBinding( const OUString& /*uri*/, const uno::Reference< io::XInputStream >&)
|
void SAL_CALL UriBindingHelper::setUriBinding( const OUString& /*uri*/, const uno::Reference< io::XInputStream >&)
|
||||||
@@ -50,7 +53,7 @@ uno::Reference< io::XInputStream > SAL_CALL UriBindingHelper::getUriBinding( con
|
|||||||
uno::Reference< io::XInputStream > xInputStream;
|
uno::Reference< io::XInputStream > xInputStream;
|
||||||
if ( mxStorage.is() )
|
if ( mxStorage.is() )
|
||||||
{
|
{
|
||||||
xInputStream = OpenInputStream( mxStorage, uri );
|
xInputStream = OpenInputStream( mxStorage, uri, mxScriptingSignatureStream );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -60,7 +63,7 @@ uno::Reference< io::XInputStream > SAL_CALL UriBindingHelper::getUriBinding( con
|
|||||||
return xInputStream;
|
return xInputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno::Reference < embed::XStorage >& rxStore, const OUString& rURI )
|
uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno::Reference < embed::XStorage >& rxStore, const OUString& rURI, const css::uno::Reference<css::io::XStream>& xScriptingSignatureStream )
|
||||||
{
|
{
|
||||||
OSL_ASSERT(!rURI.isEmpty());
|
OSL_ASSERT(!rURI.isEmpty());
|
||||||
uno::Reference < io::XInputStream > xInStream;
|
uno::Reference < io::XInputStream > xInStream;
|
||||||
@@ -87,7 +90,23 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno
|
|||||||
|
|
||||||
uno::Reference< io::XStream > xStream;
|
uno::Reference< io::XStream > xStream;
|
||||||
if (!rxStore->hasByName(sName))
|
if (!rxStore->hasByName(sName))
|
||||||
SAL_WARN("xmlsecurity.helper", "expected stream, but not found: " << sName);
|
{
|
||||||
|
if (xScriptingSignatureStream.is() && sName == DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName())
|
||||||
|
{
|
||||||
|
xStream = xScriptingSignatureStream;
|
||||||
|
uno::Reference<io::XSeekable> xSeekable(xScriptingSignatureStream, uno::UNO_QUERY);
|
||||||
|
if (xSeekable.is())
|
||||||
|
{
|
||||||
|
// Cloned streams are always positioned at the start, do the same in the overlay
|
||||||
|
// case.
|
||||||
|
xSeekable->seek(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SAL_WARN("xmlsecurity.helper", "expected stream, but not found: " << sName);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
xStream = rxStore->cloneStreamElement( sName );
|
xStream = rxStore->cloneStreamElement( sName );
|
||||||
if ( !xStream.is() )
|
if ( !xStream.is() )
|
||||||
@@ -103,7 +122,7 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno
|
|||||||
|
|
||||||
OUString aElement = aURI.copy( nSepPos+1 );
|
OUString aElement = aURI.copy( nSepPos+1 );
|
||||||
uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aStoreName, embed::ElementModes::READ );
|
uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aStoreName, embed::ElementModes::READ );
|
||||||
xInStream = OpenInputStream( xSubStore, aElement );
|
xInStream = OpenInputStream( xSubStore, aElement, xScriptingSignatureStream );
|
||||||
}
|
}
|
||||||
return xInStream;
|
return xInStream;
|
||||||
}
|
}
|
||||||
|
@@ -436,6 +436,15 @@ bool DocumentSignatureManager::add(
|
|||||||
|
|
||||||
std::vector<OUString> aElements = DocumentSignatureHelper::CreateElementList(
|
std::vector<OUString> aElements = DocumentSignatureHelper::CreateElementList(
|
||||||
mxStore, meSignatureMode, DocumentSignatureAlgorithm::OOo3_2);
|
mxStore, meSignatureMode, DocumentSignatureAlgorithm::OOo3_2);
|
||||||
|
|
||||||
|
if (mxScriptingSignatureStream.is())
|
||||||
|
{
|
||||||
|
aElements.emplace_back(
|
||||||
|
u"META-INF/"_ustr
|
||||||
|
+ DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName());
|
||||||
|
std::sort(aElements.begin(), aElements.end());
|
||||||
|
}
|
||||||
|
|
||||||
DocumentSignatureHelper::AppendContentTypes(mxStore, aElements);
|
DocumentSignatureHelper::AppendContentTypes(mxStore, aElements);
|
||||||
|
|
||||||
for (OUString const& rUri : aElements)
|
for (OUString const& rUri : aElements)
|
||||||
|
@@ -70,10 +70,11 @@ XMLSignatureHelper::~XMLSignatureHelper()
|
|||||||
|
|
||||||
void XMLSignatureHelper::SetStorage(
|
void XMLSignatureHelper::SetStorage(
|
||||||
const Reference < css::embed::XStorage >& rxStorage,
|
const Reference < css::embed::XStorage >& rxStorage,
|
||||||
std::u16string_view sODFVersion)
|
std::u16string_view sODFVersion,
|
||||||
|
const css::uno::Reference<css::io::XStream>& xScriptStream)
|
||||||
{
|
{
|
||||||
SAL_WARN_IF( mxUriBinding.is(), "xmlsecurity.helper", "SetStorage - UriBinding already set!" );
|
SAL_WARN_IF( mxUriBinding.is(), "xmlsecurity.helper", "SetStorage - UriBinding already set!" );
|
||||||
mxUriBinding = new UriBindingHelper( rxStorage );
|
mxUriBinding = new UriBindingHelper( rxStorage, xScriptStream );
|
||||||
SAL_WARN_IF(!rxStorage.is(), "xmlsecurity.helper", "SetStorage - empty storage!");
|
SAL_WARN_IF(!rxStorage.is(), "xmlsecurity.helper", "SetStorage - empty storage!");
|
||||||
mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
|
mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user