comphelper/source/misc/storagehelper.cxx                          |   13 
 desktop/qa/desktop_lib/test_desktop_lib.cxx                       |    4 
 desktop/source/lib/init.cxx                                       |   69 +++
 include/LibreOfficeKit/LibreOfficeKit.h                           |   10 
 include/LibreOfficeKit/LibreOfficeKit.hxx                         |   19 
 include/comphelper/storagehelper.hxx                              |    3 
 include/sfx2/docfile.hxx                                          |   11 
 include/sfx2/objsh.hxx                                            |   12 
 offapi/com/sun/star/security/XDocumentDigitalSignatures.idl       |   12 
 sfx2/source/doc/docfile.cxx                                       |  150 
+++++++
 sfx2/source/doc/objserv.cxx                                       |  201 
+++++++---
 sfx2/source/doc/objxtor.cxx                                       |    1 
 sfx2/source/inc/objshimp.hxx                                      |    1 
 xmlsecurity/inc/documentsignaturemanager.hxx                      |    3 
 xmlsecurity/inc/xmlsignaturehelper.hxx                            |    1 
 xmlsecurity/inc/xsecctl.hxx                                       |    1 
 xmlsecurity/source/component/documentdigitalsignatures.cxx        |   47 ++
 xmlsecurity/source/component/documentdigitalsignatures.hxx        |    5 
 xmlsecurity/source/gpg/CertificateImpl.cxx                        |   16 
 xmlsecurity/source/gpg/CertificateImpl.hxx                        |    9 
 xmlsecurity/source/helper/documentsignaturemanager.cxx            |    6 
 xmlsecurity/source/helper/ooxmlsecexporter.cxx                    |    1 
 xmlsecurity/source/helper/xmlsignaturehelper.cxx                  |    5 
 xmlsecurity/source/helper/xsecctl.cxx                             |   22 +
 xmlsecurity/source/helper/xsecparser.cxx                          |   15 
 xmlsecurity/source/helper/xsecparser.hxx                          |    2 
 xmlsecurity/source/helper/xsecsign.cxx                            |   17 
 xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx |   19 
 xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx |    9 
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx         |   16 
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx         |    9 
 31 files changed, 642 insertions(+), 67 deletions(-)

New commits:
commit 11394fd76d4c5253afcb8e26ebd2de327111234d
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Mon Oct 15 10:09:15 2018 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Nov 8 14:10:00 2018 +0100

    lokit: add funct. to insert, sign and verify signature
    
    A lot of signing code paths trigger a GUI dialog (to select the
    certificate for example) which aren't acceptable when triggering
    through the LOKit. This code paths needed to be duplicated and
    reworked to not trigger any GUI action.
    
    Reviewed-on: https://gerrit.libreoffice.org/61780
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    (cherry picked from commit 23a2312344ac961ead9ee14140c0b3e879bb7a41)
    
    Conflicts:
            desktop/qa/desktop_lib/test_desktop_lib.cxx
            include/LibreOfficeKit/LibreOfficeKit.hxx
            include/sfx2/objsh.hxx
            sfx2/source/doc/docfile.cxx
            sfx2/source/doc/objserv.cxx
    
    Change-Id: I2f0d6038fb1bcd00adcdf86e432f9df8858cc21c

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx 
b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index b68073fd9a75..aea7dea4988f 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2300,10 +2300,12 @@ void DesktopLOKTest::testABI()
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(40), offsetof(struct 
_LibreOfficeKitDocumentClass, postWindowExtTextInputEvent));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(41), offsetof(struct 
_LibreOfficeKitDocumentClass, getPartInfo));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(42), offsetof(struct 
_LibreOfficeKitDocumentClass, paintWindowDPI));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(43), offsetof(struct 
_LibreOfficeKitDocumentClass, insertCertificate));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(44), offsetof(struct 
_LibreOfficeKitDocumentClass, getSignatureState));
 
     // Extending is fine, update this, and add new assert for the offsetof the
     // new method
-    CPPUNIT_ASSERT_EQUAL(documentClassOffset(43), sizeof(struct 
_LibreOfficeKitDocumentClass));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(45), sizeof(struct 
_LibreOfficeKitDocumentClass));
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index a8d5e87eed08..cb248891e498 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -72,6 +72,13 @@
 #include <com/sun/star/document/XRedlinesSupplier.hpp>
 #include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
 
+#include <com/sun/star/xml/crypto/SEInitializer.hpp>
+#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
+#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+
 #include <com/sun/star/linguistic2/LinguServiceManager.hpp>
 #include <com/sun/star/linguistic2/XSpellChecker.hpp>
 #include <com/sun/star/i18n/ScriptType.hpp>
@@ -687,6 +694,12 @@ static void doc_postWindow(LibreOfficeKitDocument* pThis, 
unsigned nLOKWindowId,
 
 static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart);
 
+static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
+                                  const unsigned char* pCertificateBinary,
+                                  const int pCertificateBinarySize);
+
+static int doc_getSignatureState(LibreOfficeKitDocument* pThis);
+
 LibLODocument_Impl::LibLODocument_Impl(const uno::Reference 
<css::lang::XComponent> &xComponent)
     : mxComponent(xComponent)
 {
@@ -745,6 +758,9 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference 
<css::lang::XCompone
 
         m_pDocumentClass->getPartInfo = doc_getPartInfo;
 
+        m_pDocumentClass->insertCertificate = doc_insertCertificate;
+        m_pDocumentClass->getSignatureState = doc_getSignatureState;
+
         gDocumentClass = m_pDocumentClass;
     }
     pClass = m_pDocumentClass.get();
@@ -3667,6 +3683,59 @@ static void doc_postWindow(LibreOfficeKitDocument* 
/*pThis*/, unsigned nLOKWindo
     }
 }
 
+// CERTIFICATE AND DOCUMENT SIGNING
+static bool doc_insertCertificate(LibreOfficeKitDocument* /*pThis*/, const 
unsigned char* pCertificateBinary, const int nCertificateBinarySize)
+{
+    if (!xContext.is())
+        return false;
+
+    uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = 
xml::crypto::SEInitializer::create(xContext);
+    uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext;
+    xSecurityContext = xSEInitializer->createSecurityContext(OUString());
+    if (!xSecurityContext.is())
+        return false;
+
+    uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment;
+    xSecurityEnvironment = xSecurityContext->getSecurityEnvironment();
+
+    uno::Sequence<sal_Int8> aCertificateSequence(nCertificateBinarySize);
+    std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, 
aCertificateSequence.begin());
+
+    uno::Reference<security::XCertificate> xCertificate = 
xSecurityEnvironment->createCertificateFromRaw(aCertificateSequence);
+
+    if (!xCertificate.is())
+        return false;
+
+    printf("CERTIFICATE\n\tIssuerName: %s \n\tSubjectName: %s\n\tPK %s\n\n",
+            xCertificate->getIssuerName().toUtf8().getStr(),
+            xCertificate->getSubjectName().toUtf8().getStr(),
+            xCertificate->getSubjectPublicKeyAlgorithm().toUtf8().getStr());
+
+    SfxObjectShell* pDoc = SfxObjectShell::Current();
+    if (!pDoc)
+        return false;
+
+    return pDoc->SignDocumentContentUsingCertificate(xCertificate);
+}
+
+static int doc_getSignatureState(LibreOfficeKitDocument* pThis)
+{
+    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+
+    if (!pDocument->mxComponent.is())
+        return int(SignatureState::UNKNOWN);
+
+    SfxBaseModel* pBaseModel = 
dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
+    if (!pBaseModel)
+        return int(SignatureState::UNKNOWN);
+
+    SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+    if (!pObjectShell)
+        return int(SignatureState::UNKNOWN);
+
+    return int(pObjectShell->GetDocumentSignatureState());
+}
+
 static char* lo_getError (LibreOfficeKit *pThis)
 {
     SolarMutexGuard aGuard;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h 
b/include/LibreOfficeKit/LibreOfficeKit.h
index f8021065af1e..fbbf1822e956 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -318,6 +318,16 @@ struct _LibreOfficeKitDocumentClass
                             const int width, const int height,
                             const double dpiscale);
 
+// CERTIFICATE AND SIGNING
+
+    /// @see lok::Document::insertCertificate().
+    bool (*insertCertificate) (LibreOfficeKitDocument* pThis,
+                                const unsigned char* pCertificateBinary,
+                                const int pCertificateBinarySize);
+
+    /// @see lok::Document::getSignatureState().
+    int (*getSignatureState) (LibreOfficeKitDocument* pThis);
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx 
b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 51d072331762..077490674f70 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -557,6 +557,25 @@ public:
         mpDoc->pClass->postWindowExtTextInputEvent(mpDoc, nWindowId, nType, 
pText);
     }
 
+    /**
+     *  Insert certificate (in binary form) to the certificate store.
+     */
+    bool insertCertificate(const unsigned char* pCertificateBinary,
+                           const int pCertificateBinarySize)
+    {
+        return mpDoc->pClass->insertCertificate(mpDoc, pCertificateBinary, 
pCertificateBinarySize);
+    }
+
+    /**
+     *  Verify signature of the document.
+     *
+     *  Check possible values in include/sfx2/signaturestate.hxx
+     */
+    int getSignatureState()
+    {
+        return mpDoc->pClass->getSignatureState(mpDoc);
+    }
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx
index 4eb3357fa6d5..c4aaa766ab98 100644
--- a/include/sfx2/docfile.hxx
+++ b/include/sfx2/docfile.hxx
@@ -269,6 +269,10 @@ public:
                       bool bScriptingContent, const OUString& aODFVersion,
                       bool bHasValidDocumentSignature);
 
+    SAL_DLLPRIVATE bool
+    SignDocumentContentUsingCertificate(bool bHasValidDocumentSignature,
+                 const css::uno::Reference<css::security::XCertificate>& 
xCertificate);
+
     // the following two methods must be used and make sense only during 
saving currently
     // TODO/LATER: in future the signature state should be controlled by the 
medium not by the document
     //             in this case the methods will be used generally, and might 
need to be renamed
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 72ff66e22660..af60902f8f5c 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -363,6 +363,9 @@ public:
     bool HasValidSignatures();
     SignatureState              GetDocumentSignatureState();
     void                        SignDocumentContent();
+
+    bool SignDocumentContentUsingCertificate(const 
css::uno::Reference<css::security::XCertificate>& xCertificate);
+
     void SignSignatureLine(const OUString& aSignatureLineId,
                            const 
css::uno::Reference<css::security::XCertificate> xCert);
     SignatureState              GetScriptingSignatureState();
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 6e0b45168ba5..97431ff3ed10 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -3575,6 +3575,123 @@ void SfxMedium::CreateTempFileNoCopy()
     CloseStorage();
 }
 
+bool SfxMedium::SignDocumentContentUsingCertificate(bool 
bHasValidDocumentSignature,
+                                                    const 
Reference<XCertificate>& xCertificate)
+{
+    bool bChanges = false;
+
+    if (IsOpen() || GetError())
+    {
+        SAL_WARN("sfx.doc", "The medium must be closed by the signer!");
+        return bChanges;
+    }
+
+    // The component should know if there was a valid document signature, since
+    // it should show a warning in this case
+    OUString 
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
+    uno::Reference< security::XDocumentDigitalSignatures > xSigner(
+        
security::DocumentDigitalSignatures::createWithVersionAndValidSignature(
+            comphelper::getProcessComponentContext(), aODFVersion, 
bHasValidDocumentSignature ) );
+
+    uno::Reference< embed::XStorage > xWriteableZipStor;
+
+    // we can reuse the temporary file if there is one already
+    CreateTempFile( false );
+    GetMedium_Impl();
+
+    try
+    {
+        if ( !pImpl->xStream.is() )
+            throw uno::RuntimeException();
+
+        bool bODF = GetFilter()->IsOwnFormat();
+        try
+        {
+            xWriteableZipStor = 
::comphelper::OStorageHelper::GetStorageOfFormatFromStream( 
ZIP_STORAGE_FORMAT_STRING, pImpl->xStream );
+        }
+        catch (const io::IOException& rException)
+        {
+            if (bODF)
+                SAL_WARN("sfx.doc", "ODF stream is not a zip storage: " << 
rException);
+        }
+
+        if ( !xWriteableZipStor.is() && bODF )
+            throw uno::RuntimeException();
+
+        uno::Reference< embed::XStorage > xMetaInf;
+        uno::Reference<container::XNameAccess> xNameAccess(xWriteableZipStor, 
uno::UNO_QUERY);
+        if (xNameAccess.is() && xNameAccess->hasByName("META-INF"))
+        {
+            xMetaInf = xWriteableZipStor->openStorageElement(
+                                            "META-INF",
+                                            embed::ElementModes::READWRITE );
+            if ( !xMetaInf.is() )
+                throw uno::RuntimeException();
+        }
+
+        {
+            if (xMetaInf.is())
+            {
+                // ODF.
+                uno::Reference< io::XStream > xStream;
+                if (GetFilter() && GetFilter()->IsOwnFormat())
+                    
xStream.set(xMetaInf->openStreamElement(xSigner->getDocumentContentSignatureDefaultStreamName(),
 embed::ElementModes::READWRITE), uno::UNO_SET_THROW);
+
+                bool bSuccess = 
xSigner->signDocumentWithCertificate(xCertificate, GetZipStorageToSign_Impl(), 
xStream);
+
+                if (bSuccess)
+                {
+                    uno::Reference< embed::XTransactedObject > xTransact( 
xMetaInf, uno::UNO_QUERY_THROW );
+                    xTransact->commit();
+                    xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
+                    xTransact->commit();
+
+                    // the temporary file has been written, commit it to the 
original file
+                    Commit();
+                    bChanges = true;
+                }
+            }
+            else if (xWriteableZipStor.is())
+            {
+                // OOXML.
+                uno::Reference<io::XStream> xStream;
+
+                    // We need read-write to be able to add the signature 
relation.
+                bool bSuccess =xSigner->signDocumentWithCertificate(
+                        xCertificate, 
GetZipStorageToSign_Impl(/*bReadOnly=*/false), xStream);
+
+                if (bSuccess)
+                {
+                    uno::Reference<embed::XTransactedObject> 
xTransact(xWriteableZipStor, uno::UNO_QUERY_THROW);
+                    xTransact->commit();
+
+                    // the temporary file has been written, commit it to the 
original file
+                    Commit();
+                    bChanges = true;
+                }
+            }
+            else
+            {
+                // Something not ZIP based: e.g. PDF.
+                std::unique_ptr<SvStream> 
pStream(utl::UcbStreamHelper::CreateStream(GetName(), StreamMode::READ | 
StreamMode::WRITE));
+                uno::Reference<io::XStream> xStream(new 
utl::OStreamWrapper(*pStream));
+                if (xSigner->signDocumentWithCertificate(xCertificate, 
uno::Reference<embed::XStorage>(), xStream))
+                    bChanges = true;
+            }
+        }
+    }
+    catch ( const uno::Exception& )
+    {
+        SAL_WARN( "sfx.doc", "Couldn't use signing functionality!" );
+    }
+
+    CloseAndRelease();
+
+    ResetError();
+
+    return bChanges;
+}
+
 bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, const 
OUString& aSignatureLineId,
                                   bool bScriptingContent, const OUString& 
aODFVersion,
                                   bool bHasValidDocumentSignature)
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index 37f6758f0018..8ac26b0f5623 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -1509,6 +1509,85 @@ void SfxObjectShell::SignDocumentContent()
     AfterSigning(bSignSuccess, false);
 }
 
+bool SfxObjectShell::SignDocumentContentUsingCertificate(const 
Reference<XCertificate>& xCertificate)
+{
+    // 1. PrepareForSigning
+
+    // check whether the document is signed
+    ImplGetSignatureState(false); // document signature
+    if (GetMedium() && GetMedium()->GetFilter() && 
GetMedium()->GetFilter()->IsOwnFormat())
+        ImplGetSignatureState( true ); // script signature
+    bool bHasSign = ( pImpl->nScriptingSignatureState != 
SignatureState::NOSIGNATURES || pImpl->nDocumentSignatureState != 
SignatureState::NOSIGNATURES );
+
+    // the target ODF version on saving (only valid when signing ODF of course)
+    SvtSaveOptions aSaveOpt;
+    SvtSaveOptions::ODFDefaultVersion nVersion = 
aSaveOpt.GetODFDefaultVersion();
+
+    // the document is not new and is not modified
+    OUString 
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
+
+    if (IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty()
+      || (GetMedium()->GetFilter()->IsOwnFormat() && aODFVersion != 
ODFVER_012_TEXT && !bHasSign))
+    {
+        if ( nVersion >= SvtSaveOptions::ODFVER_012 )
+        {
+            sal_uInt16 nId = SID_SAVEDOC;
+            if ( !GetMedium() || GetMedium()->GetName().isEmpty() )
+                nId = SID_SAVEASDOC;
+            SfxRequest aSaveRequest( nId, SfxCallMode::SLOT, GetPool() );
+            //ToDo: Review. We needed to call SetModified, otherwise the 
document would not be saved.
+            SetModified();
+            ExecFile_Impl( aSaveRequest );
+
+            // Check if it is stored a format which supports signing
+            if (GetMedium() && GetMedium()->GetFilter() && 
!GetMedium()->GetName().isEmpty()
+                && ((!GetMedium()->GetFilter()->IsOwnFormat()
+                     && !GetMedium()->GetFilter()->GetSupportsSigning())
+                    || (GetMedium()->GetFilter()->IsOwnFormat()
+                        && !GetMedium()->HasStorage_Impl())))
+            {
+                return false;
+            }
+        }
+        else
+        {
+            return false;
+        }
+
+        if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty() )
+            return false;
+    }
+
+    // the document is not modified currently, so it can not become modified 
after signing
+    pImpl->m_bAllowModifiedBackAfterSigning = false;
+    if ( IsEnableSetModified() )
+    {
+        EnableSetModified( false );
+        pImpl->m_bAllowModifiedBackAfterSigning = true;
+    }
+
+    // we have to store to the original document, the original medium should 
be closed for this time
+    bool bResult = ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium);
+    printf("ConnectTmpStorage_Impl %d\n", bResult);
+
+    if (!bResult)
+        return false;
+
+    GetMedium()->CloseAndRelease();
+
+    // 2. Check Read-Only
+    if (GetMedium()->IsOriginallyReadOnly())
+        return false;
+
+    // 3. Sign
+    bool bSignSuccess = 
GetMedium()->SignDocumentContentUsingCertificate(HasValidSignatures(), 
xCertificate);
+
+    // 4. AfterSigning
+    AfterSigning(bSignSuccess, false);
+
+    return true;
+}
+
 void SfxObjectShell::SignSignatureLine(const OUString& aSignatureLineId,
                                        const Reference<XCertificate> xCert)
 {
commit 32b4b5af622afbff622d2230aa92be1498ded331
Author:     Caolán McNamara <[email protected]>
AuthorDate: Sat May 19 21:23:48 2018 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Nov 8 14:09:59 2018 +0100

    coverity#1338604 Uninitialized scalar field
    
    Change-Id: I4c4c07db527ea2517ed809f693bde4af519e503e
    Reviewed-on: https://gerrit.libreoffice.org/54582
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Caolán McNamara <[email protected]>
    (cherry picked from commit 892306b5b73f22f887a512ab75ccee22e1985fa8)

diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx
index e1a130c7fc79..2f9eda7dcc87 100644
--- a/sfx2/source/doc/objxtor.cxx
+++ b/sfx2/source/doc/objxtor.cxx
@@ -251,6 +251,7 @@ SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& 
_rDocShell )
     ,m_nModifyPasswordHash( 0 )
     ,m_bModifyPasswordEntered( false )
     ,m_bSavingForSigning( false )
+    ,m_bAllowModifiedBackAfterSigning( false )
 {
     SfxObjectShell* pDoc = &_rDocShell;
     SfxObjectShellArr_Impl &rArr = SfxGetpApp()->GetObjectShells_Impl();
commit a266cfa742f6b03ea38da7dda6229b6d3db0e391
Author:     Samuel Mehrbrodt <[email protected]>
AuthorDate: Thu May 17 11:10:34 2018 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Nov 8 13:58:57 2018 +0100

    Refactor SfxObjectShell sign methods
    
    for signature line signing
    
    Reviewed-on: https://gerrit.libreoffice.org/54473
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Samuel Mehrbrodt <[email protected]>
    (cherry picked from commit 0ca1659353cc9847f436280873e1047d2524395e)
    
    Conflicts:
            cui/source/dialogs/SignSignatureLineDialog.cxx
            sfx2/source/doc/objserv.cxx
    
    Change-Id: Iac4f3a248af53bdbf159e6e8d656e1dcbc3aacbf

diff --git a/comphelper/source/misc/storagehelper.cxx 
b/comphelper/source/misc/storagehelper.cxx
index 4551326b9b46..5905c7867aca 100644
--- a/comphelper/source/misc/storagehelper.cxx
+++ b/comphelper/source/misc/storagehelper.cxx
@@ -698,6 +698,19 @@ uno::Reference< io::XStream > 
OStorageHelper::GetStreamAtPackageURL(
     return nullptr;
 }
 
+OUString 
OStorageHelper::GetODFVersionFromStorage(uno::Reference<embed::XStorage> 
xStorage)
+{
+    OUString aODFVersion;
+    try
+    {
+        uno::Reference<beans::XPropertySet> xPropSet(xStorage, 
uno::UNO_QUERY_THROW);
+        xPropSet->getPropertyValue("Version") >>= aODFVersion;
+    }
+    catch (uno::Exception&)
+    {
+    }
+    return aODFVersion;
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/storagehelper.hxx 
b/include/comphelper/storagehelper.hxx
index 778fb1c8ea25..e8fcc0d11cb7 100644
--- a/include/comphelper/storagehelper.hxx
+++ b/include/comphelper/storagehelper.hxx
@@ -193,6 +193,9 @@ public:
         const css::uno::Reference< css::embed::XStorage > &xStorage,
         const OUString& rURL, sal_uInt32 const nOpenMode,
         LifecycleProxy const & rNastiness );
+
+    static OUString
+    GetODFVersionFromStorage(css::uno::Reference<css::embed::XStorage> 
xStorage);
 };
 
 }
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 5208e1a58184..72ff66e22660 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -205,6 +205,7 @@ private:
                                                   // sal_False := new object
     bool                        bIsInGenerateThumbnail; //optimize thumbnail 
generate and store procedure to improve odt saving performance, i120030
     bool                        mbAvoidRecentDocs; ///< Avoid adding to the 
recent documents list, if not necessary.
+    bool m_bAllowModifiedBackAfterSigning;
 
     enum TriState               {undefined, yes, no};
     TriState                    mbContinueImportOnFilterExceptions = 
undefined; // try to import as much as possible
@@ -356,11 +357,14 @@ public:
             css::uno::Reference<css::text::XTextRange> const& xInsertPosition);
     bool                        ExportTo( SfxMedium &rMedium );
 
-    // xmlsec05, check with SFX team
+    /** Returns to if preparing was succesful, else false. */
+    bool PrepareForSigning();
+    void AfterSigning(bool bSignSuccess, bool bSignScriptingContent);
+    bool HasValidSignatures();
     SignatureState              GetDocumentSignatureState();
     void                        SignDocumentContent();
-    void                        
SignDocumentContent(css::uno::Reference<css::security::XCertificate> xCert,
-                                                    const OUString& 
aSignatureLineId);
+    void SignSignatureLine(const OUString& aSignatureLineId,
+                           const 
css::uno::Reference<css::security::XCertificate> xCert);
     SignatureState              GetScriptingSignatureState();
     void                        SignScriptingContent();
     DECL_LINK(SignDocumentHandler, Button*, void);
@@ -743,10 +747,6 @@ public:
             const css::uno::Reference< 
css::security::XDocumentDigitalSignatures >& xSigner
                 = css::uno::Reference< 
css::security::XDocumentDigitalSignatures >() );
 
-    SAL_DLLPRIVATE void ImplSign(const 
css::uno::Reference<css::security::XCertificate> xCert
-                                 = 
css::uno::Reference<css::security::XCertificate>(),
-                                 const OUString& aSignatureLineId = 
OUString(), bool bScriptingContent = false);
-
     SAL_DLLPRIVATE bool QuerySaveSizeExceededModules_Impl( const 
css::uno::Reference< css::task::XInteractionHandler >& xHandler );
     SAL_DLLPRIVATE bool QueryAllowExoticFormat_Impl( const 
css::uno::Reference< css::task::XInteractionHandler >& xHandler,
                                                      const OUString& rURL,
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index e4c6b18986f0..37f6758f0018 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -62,6 +62,7 @@
 #include <unotools/saveopt.hxx>
 #include <svtools/asynclink.hxx>
 #include <comphelper/documentconstants.hxx>
+#include <comphelper/storagehelper.hxx>
 #include <tools/link.hxx>
 
 #include <sfx2/asyncfunc.hxx>
@@ -1360,8 +1361,7 @@ SignatureState SfxObjectShell::ImplGetSignatureState( 
bool bScriptingContent )
     return *pState;
 }
 
-void SfxObjectShell::ImplSign(Reference<XCertificate> xCert, const OUString& 
aSignatureLineId,
-                              bool bScriptingContent)
+bool SfxObjectShell::PrepareForSigning()
 {
     // Check if it is stored in OASIS format...
     if  (   GetMedium()
@@ -1374,7 +1374,7 @@ void SfxObjectShell::ImplSign(Reference<XCertificate> 
xCert, const OUString& aSi
     {
         // Only OASIS and OOo6.x formats will be handled further
         ScopedVclPtrInstance<MessageDialog>( nullptr, SfxResId( 
STR_INFO_WRONGDOCFORMAT ), VclMessageType::Info )->Execute();
-        return;
+        return false;
     }
 
     // check whether the document is signed
@@ -1396,19 +1396,7 @@ void SfxObjectShell::ImplSign(Reference<XCertificate> 
xCert, const OUString& aSi
     SvtSaveOptions::ODFDefaultVersion nVersion = 
aSaveOpt.GetODFDefaultVersion();
 
     // the document is not new and is not modified
-    OUString aODFVersion;
-    try
-    {
-        // check the ODF version of the document
-        // No idea what relevance this has if the document has not been loaded 
from ODF (or is not
-        // being saved to ODF)
-        uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), 
uno::UNO_QUERY_THROW );
-        xPropSet->getPropertyValue("Version") >>= aODFVersion;
-    }
-    catch( uno::Exception& )
-    {}
-
-    bool bNoSig = false;
+    OUString 
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
 
     if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty()
       || (aODFVersion != ODFVER_012_TEXT && !bHasSign) )
@@ -1436,7 +1424,7 @@ void SfxObjectShell::ImplSign(Reference<XCertificate> 
xCert, const OUString& aSi
                 {
                     // Only OASIS format will be handled further
                     ScopedVclPtrInstance<MessageDialog>( nullptr, SfxResId( 
STR_INFO_WRONGDOCFORMAT ), VclMessageType::Info )->Execute();
-                    return;
+                    return false;
                 }
             }
             else
@@ -1445,66 +1433,65 @@ void SfxObjectShell::ImplSign(Reference<XCertificate> 
xCert, const OUString& aSi
                 // digital signatures dialog
                 // If we have come here then the user denied to save.
                 if (!bHasSign)
-                    bNoSig = true;
+                    return false;
             }
         }
         else
         {
             ScopedVclPtrInstance<MessageDialog>(nullptr, 
SfxResId(STR_XMLSEC_ODF12_EXPECTED))->Execute();
-            return;
+            return false;
         }
 
         if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty() )
-            return;
+            return false;
     }
 
     // the document is not modified currently, so it can not become modified 
after signing
-    bool bAllowModifiedBack = false;
+    pImpl->m_bAllowModifiedBackAfterSigning = false;
     if ( IsEnableSetModified() )
     {
         EnableSetModified( false );
-        bAllowModifiedBack = true;
+        pImpl->m_bAllowModifiedBackAfterSigning = true;
     }
 
     // we have to store to the original document, the original medium should 
be closed for this time
-    if ( !bNoSig
-      && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
+    if ( ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
     {
         GetMedium()->CloseAndRelease();
+        return true;
+    }
+    return false;
+}
 
-        bool bHasValidSignatures = pImpl->nDocumentSignatureState == 
SignatureState::OK
-            || pImpl->nDocumentSignatureState == SignatureState::NOTVALIDATED
-            || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK;
-
-        bool bSignSuccess = GetMedium()->SignContents_Impl(
-            xCert, aSignatureLineId, bScriptingContent, aODFVersion, 
bHasValidSignatures);
+void SfxObjectShell::AfterSigning(bool bSignSuccess, bool 
bSignScriptingContent)
+{
+    pImpl->m_bSavingForSigning = true;
+    DoSaveCompleted( GetMedium() );
+    pImpl->m_bSavingForSigning = false;
 
-        pImpl->m_bSavingForSigning = true;
-        DoSaveCompleted( GetMedium() );
-        pImpl->m_bSavingForSigning = false;
+    if ( bSignSuccess )
+    {
+        if ( bSignScriptingContent )
+            pImpl->nScriptingSignatureState = SignatureState::UNKNOWN; // 
Re-Check
 
-        if ( bSignSuccess )
-        {
-            if ( bScriptingContent )
-            {
-                pImpl->nScriptingSignatureState = SignatureState::UNKNOWN;// 
Re-Check
+        pImpl->nDocumentSignatureState = SignatureState::UNKNOWN; // Re-Check
 
-                // adding of scripting signature removes existing document 
signature
-                pImpl->nDocumentSignatureState = SignatureState::UNKNOWN;// 
Re-Check
-            }
-            else
-                pImpl->nDocumentSignatureState = SignatureState::UNKNOWN;// 
Re-Check
-
-            Invalidate( SID_SIGNATURE );
-            Invalidate( SID_MACRO_SIGNATURE );
-            Broadcast( SfxHint(SfxHintId::TitleChanged) );
-        }
+        Invalidate( SID_SIGNATURE );
+        Invalidate( SID_MACRO_SIGNATURE );
+        Broadcast( SfxHint(SfxHintId::TitleChanged) );
     }
 
-    if ( bAllowModifiedBack )
+    if ( pImpl->m_bAllowModifiedBackAfterSigning )
         EnableSetModified();
 }
 
+bool SfxObjectShell::HasValidSignatures()
+{
+    return pImpl->nDocumentSignatureState == SignatureState::OK
+           || pImpl->nDocumentSignatureState == SignatureState::NOTVALIDATED
+           || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK;
+}
+
 SignatureState SfxObjectShell::GetDocumentSignatureState()
 {
     return ImplGetSignatureState();
@@ -1512,13 +1499,27 @@ SignatureState 
SfxObjectShell::GetDocumentSignatureState()
 
 void SfxObjectShell::SignDocumentContent()
 {
-    ImplSign();
+    if (!PrepareForSigning())
+        return;
+
+    OUString 
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
+    bool bSignSuccess = GetMedium()->SignContents_Impl(
+        Reference<XCertificate>(), "", false, aODFVersion, 
HasValidSignatures());
+
+    AfterSigning(bSignSuccess, false);
 }
 
-void SfxObjectShell::SignDocumentContent(const Reference<XCertificate> xCert,
-                                         const OUString& aSignatureLineId)
+void SfxObjectShell::SignSignatureLine(const OUString& aSignatureLineId,
+                                       const Reference<XCertificate> xCert)
 {
-    ImplSign(xCert, aSignatureLineId);
+    if (!PrepareForSigning())
+        return;
+
+    OUString 
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
+    bool bSignSuccess = GetMedium()->SignContents_Impl(
+        xCert, aSignatureLineId, false, aODFVersion, HasValidSignatures());
+
+    AfterSigning(bSignSuccess, false);
 }
 
 SignatureState SfxObjectShell::GetScriptingSignatureState()
@@ -1528,7 +1529,14 @@ SignatureState 
SfxObjectShell::GetScriptingSignatureState()
 
 void SfxObjectShell::SignScriptingContent()
 {
-    ImplSign( Reference<XCertificate>(), OUString(), true );
+    if (!PrepareForSigning())
+        return;
+
+    OUString 
aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
+    bool bSignSuccess = GetMedium()->SignContents_Impl(
+        Reference<XCertificate>(), OUString(), true, aODFVersion, 
HasValidSignatures());
+
+    AfterSigning(bSignSuccess, true);
 }
 
 namespace
diff --git a/sfx2/source/inc/objshimp.hxx b/sfx2/source/inc/objshimp.hxx
index b47a49260d46..67628d5dbdb0 100644
--- a/sfx2/source/inc/objshimp.hxx
+++ b/sfx2/source/inc/objshimp.hxx
@@ -129,6 +129,7 @@ struct SfxObjectShell_Impl : public 
::sfx2::IMacroDocumentAccess
     bool                m_bModifyPasswordEntered;
     /// If true, then this is not a real save, just the signatures change.
     bool m_bSavingForSigning;
+    bool m_bAllowModifiedBackAfterSigning;
 
     SfxObjectShell_Impl( SfxObjectShell& _rDocShell );
     virtual ~SfxObjectShell_Impl();
commit f6c5c8b14bd47aa31a37801ca27294e156d92dbb
Author:     Samuel Mehrbrodt <[email protected]>
AuthorDate: Wed May 16 16:34:35 2018 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Nov 8 13:55:14 2018 +0100

    tdf#83877 Write SignatureLineId to ODF & OOXML signatures
    
    Reviewed-on: https://gerrit.libreoffice.org/54432
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Samuel Mehrbrodt <[email protected]>
    (cherry picked from commit 201321f648e82ecc610e7a3324a46248a19c1704)
    
    Conflicts:
            cui/source/dialogs/SignSignatureLineDialog.cxx
            xmlsecurity/source/component/documentdigitalsignatures.cxx
            xmlsecurity/source/helper/documentsignaturemanager.cxx
    
    Change-Id: I483a3b7895cdcb10ef9d6dacf167ed0f8db7e723

diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx
index 57c52b81cb95..4eb3357fa6d5 100644
--- a/include/sfx2/docfile.hxx
+++ b/include/sfx2/docfile.hxx
@@ -265,6 +265,7 @@ public:
 
     SAL_DLLPRIVATE bool
     SignContents_Impl(const css::uno::Reference<css::security::XCertificate> 
xCert,
+                      const OUString& aSignatureLineId,
                       bool bScriptingContent, const OUString& aODFVersion,
                       bool bHasValidDocumentSignature);
 
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 7263e78bdcbc..5208e1a58184 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -359,7 +359,8 @@ public:
     // xmlsec05, check with SFX team
     SignatureState              GetDocumentSignatureState();
     void                        SignDocumentContent();
-    void                        
SignDocumentContent(css::uno::Reference<css::security::XCertificate> xCert);
+    void                        
SignDocumentContent(css::uno::Reference<css::security::XCertificate> xCert,
+                                                    const OUString& 
aSignatureLineId);
     SignatureState              GetScriptingSignatureState();
     void                        SignScriptingContent();
     DECL_LINK(SignDocumentHandler, Button*, void);
@@ -742,9 +743,9 @@ public:
             const css::uno::Reference< 
css::security::XDocumentDigitalSignatures >& xSigner
                 = css::uno::Reference< 
css::security::XDocumentDigitalSignatures >() );
 
-    SAL_DLLPRIVATE void
-    ImplSign(const css::uno::Reference<css::security::XCertificate> xCert,
-             bool bScriptingContent = false);
+    SAL_DLLPRIVATE void ImplSign(const 
css::uno::Reference<css::security::XCertificate> xCert
+                                 = 
css::uno::Reference<css::security::XCertificate>(),
+                                 const OUString& aSignatureLineId = 
OUString(), bool bScriptingContent = false);
 
     SAL_DLLPRIVATE bool QuerySaveSizeExceededModules_Impl( const 
css::uno::Reference< css::task::XInteractionHandler >& xHandler );
     SAL_DLLPRIVATE bool QueryAllowExoticFormat_Impl( const 
css::uno::Reference< css::task::XInteractionHandler >& xHandler,
diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl 
b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
index 69d86af35a8a..d0bd80ca698b 100644
--- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
+++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
@@ -55,7 +55,8 @@ interface XDocumentDigitalSignatures : 
com::sun::star::uno::XInterface
      */
     boolean signDocumentContentWithCertificate( [in] 
::com::sun::star::embed::XStorage xStorage,
                                                 [in] 
::com::sun::star::io::XStream xSignStream,
-                                                [in] 
::com::sun::star::security::XCertificate xCertificate);
+                                                [in] 
::com::sun::star::security::XCertificate xCertificate,
+                                                [in] string signatureLineId);
 
     /** checks for digital signatures and their status.
 
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 2a679cd36bac..6e0b45168ba5 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -3575,8 +3575,9 @@ void SfxMedium::CreateTempFileNoCopy()
     CloseStorage();
 }
 
-bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, bool 
bScriptingContent,
-                                  const OUString& aODFVersion, bool 
bHasValidDocumentSignature)
+bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, const 
OUString& aSignatureLineId,
+                                  bool bScriptingContent, const OUString& 
aODFVersion,
+                                  bool bHasValidDocumentSignature)
 {
     bool bChanges = false;
 
@@ -3667,7 +3668,7 @@ bool SfxMedium::SignContents_Impl(const 
Reference<XCertificate> xCert, bool bScr
                         bool bSuccess = false;
                         if (xCert.is())
                             bSuccess = 
xSigner->signDocumentContentWithCertificate(
-                                GetZipStorageToSign_Impl(), xStream, xCert);
+                                GetZipStorageToSign_Impl(), xStream, xCert, 
aSignatureLineId);
                         else
                             bSuccess = 
xSigner->signDocumentContent(GetZipStorageToSign_Impl(),
                                                                     xStream);
@@ -3693,7 +3694,7 @@ bool SfxMedium::SignContents_Impl(const 
Reference<XCertificate> xCert, bool bScr
                         if (xCert.is())
                         {
                             bSuccess = 
xSigner->signDocumentContentWithCertificate(
-                                GetZipStorageToSign_Impl(), xStream, xCert);
+                                GetZipStorageToSign_Impl(/*bReadOnly=*/false), 
xStream, xCert, aSignatureLineId);
                         }
                         else
                         {
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index c8bc40e8bb19..e4c6b18986f0 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -1360,7 +1360,7 @@ SignatureState SfxObjectShell::ImplGetSignatureState( 
bool bScriptingContent )
     return *pState;
 }
 
-void SfxObjectShell::ImplSign(Reference<XCertificate> xCert,
+void SfxObjectShell::ImplSign(Reference<XCertificate> xCert, const OUString& 
aSignatureLineId,
                               bool bScriptingContent)
 {
     // Check if it is stored in OASIS format...
@@ -1477,7 +1477,7 @@ void SfxObjectShell::ImplSign(Reference<XCertificate> 
xCert,
             || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK;
 
         bool bSignSuccess = GetMedium()->SignContents_Impl(
-            xCert, bScriptingContent, aODFVersion, bHasValidSignatures);
+            xCert, aSignatureLineId, bScriptingContent, aODFVersion, 
bHasValidSignatures);
 
         pImpl->m_bSavingForSigning = true;
         DoSaveCompleted( GetMedium() );
@@ -1512,12 +1512,13 @@ SignatureState 
SfxObjectShell::GetDocumentSignatureState()
 
 void SfxObjectShell::SignDocumentContent()
 {
-    ImplSign(Reference<XCertificate>());
+    ImplSign();
 }
 
-void SfxObjectShell::SignDocumentContent(const Reference<XCertificate> xCert)
+void SfxObjectShell::SignDocumentContent(const Reference<XCertificate> xCert,
+                                         const OUString& aSignatureLineId)
 {
-    ImplSign(xCert);
+    ImplSign(xCert, aSignatureLineId);
 }
 
 SignatureState SfxObjectShell::GetScriptingSignatureState()
@@ -1527,7 +1528,7 @@ SignatureState 
SfxObjectShell::GetScriptingSignatureState()
 
 void SfxObjectShell::SignScriptingContent()
 {
-    ImplSign( Reference<XCertificate>(), true );
+    ImplSign( Reference<XCertificate>(), OUString(), true );
 }
 
 namespace
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx 
b/xmlsecurity/inc/documentsignaturemanager.hxx
index f1cc8293de42..bae54619cbd5 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -63,7 +63,8 @@ public:
     /// Add a new signature, using xCert as a signing certificate, and 
rDescription as description.
     bool add(const css::uno::Reference<css::security::XCertificate>& xCert,
              const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& 
xSecurityContext,
-             const OUString& rDescription, sal_Int32& nSecurityId, bool 
bAdESCompliant);
+             const OUString& rDescription, sal_Int32& nSecurityId, bool 
bAdESCompliant,
+             const OUString& rSignatureLineId = OUString());
     /// Remove signature at nPosition.
     void remove(sal_uInt16 nPosition);
     /// Read signatures from either a temp stream or the real storage.
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx 
b/xmlsecurity/inc/xmlsignaturehelper.hxx
index 6f9784f4a690..c665f5a56903 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -128,6 +128,7 @@ public:
 
     void        SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const 
tools::Time& rTime );
     void SetDescription(sal_Int32 nSecurityId, const OUString& rDescription);
+    void SetSignatureLineId(sal_Int32 nSecurityId, const OUString& 
rSignatureLineId);
 
     void        AddForSigning( sal_Int32 securityId, const OUString& uri, bool 
bBinary, bool bXAdESCompliantIfODF );
     bool        CreateAndWriteSignature( const css::uno::Reference< 
css::xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF 
);
diff --git a/xmlsecurity/inc/xsecctl.hxx b/xmlsecurity/inc/xsecctl.hxx
index cc3b11db80a7..5d8d85f9c93e 100644
--- a/xmlsecurity/inc/xsecctl.hxx
+++ b/xmlsecurity/inc/xsecctl.hxx
@@ -352,6 +352,7 @@ public:
         sal_Int32 nSecurityId,
         const css::util::DateTime& rDateTime );
     void setDescription(sal_Int32 nSecurityId, const OUString& rDescription);
+    void setSignatureLineId(sal_Int32 nSecurityId, const OUString& 
rSignatureLineId);
 
     bool WriteSignature(
         const css::uno::Reference< css::xml::sax::XDocumentHandler >& 
xDocumentHandler,
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx 
b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index eee5a09952e6..5f0f2bb201f3 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -125,7 +125,7 @@ sal_Bool DocumentDigitalSignatures::signDocumentContent(
 sal_Bool DocumentDigitalSignatures::signDocumentContentWithCertificate(
     const Reference<css::embed::XStorage>& rxStorage,
     const Reference<css::io::XStream>& xSignStream,
-    const Reference<css::security::XCertificate>& xCertificate)
+    const Reference<css::security::XCertificate>& xCertificate, const 
OUString& aSignatureLineId)
 {
     OSL_ENSURE(!m_sODFVersion.isEmpty(),
                "DocumentDigitalSignatures: ODF Version not set, assuming 
minimum 1.2");
@@ -149,8 +149,8 @@ sal_Bool 
DocumentDigitalSignatures::signDocumentContentWithCertificate(
 
     sal_Int32 nSecurityId;
     OUString aDescription("");
-    bool bSuccess
-        = aSignatureManager.add(xCertificate, xSecurityContext, aDescription, 
nSecurityId, true);
+    bool bSuccess = aSignatureManager.add(xCertificate, xSecurityContext, 
aDescription, nSecurityId,
+                                          true, aSignatureLineId);
     if (!bSuccess)
         return false;
 
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx 
b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index 72ac2ced5014..8a3d0468d85b 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -89,7 +89,8 @@ public:
     sal_Bool SAL_CALL signDocumentContentWithCertificate(
         const css::uno::Reference<css::embed::XStorage>& Storage,
         const css::uno::Reference<css::io::XStream>& xSignStream,
-        const css::uno::Reference<css::security::XCertificate>& xCertificate) 
override;
+        const css::uno::Reference<css::security::XCertificate>& xCertificate,
+        const OUString& rSignatureLineId) override;
     css::uno::Sequence< css::security::DocumentSignatureInformation > SAL_CALL 
verifyDocumentContentSignatures( const css::uno::Reference< 
css::embed::XStorage >& xStorage, const css::uno::Reference< 
css::io::XInputStream >& xSignInStream ) override;
     void SAL_CALL showDocumentContentSignatures( const css::uno::Reference< 
css::embed::XStorage >& xStorage, const css::uno::Reference< 
css::io::XInputStream >& xSignInStream ) override;
     OUString SAL_CALL getDocumentContentSignatureDefaultStreamName(  ) 
override;
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx 
b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 45787b190311..218360d2f60c 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -257,7 +257,8 @@ bool DocumentSignatureManager::add(const 
uno::Reference<security::XCertificate>&
                                    const 
uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext,
                                    const OUString& rDescription,
                                    sal_Int32& nSecurityId,
-                                   bool bAdESCompliant)
+                                   bool bAdESCompliant,
+                                   const OUString& rSignatureLineId)
 {
     if (!xCert.is())
     {
@@ -364,6 +365,9 @@ bool DocumentSignatureManager::add(const 
uno::Reference<security::XCertificate>&
     maSignatureHelper.SetDateTime(nSecurityId, Date(Date::SYSTEM), 
tools::Time(tools::Time::SYSTEM));
     maSignatureHelper.SetDescription(nSecurityId, rDescription);
 
+    if (!rSignatureLineId.isEmpty())
+        maSignatureHelper.SetSignatureLineId(nSecurityId, rSignatureLineId);
+
     // We open a signature stream in which the existing and the new
     //signature is written. ImplGetSignatureInformation (later in this 
function) will
     //then read the stream an will fill  maCurrentSignatureInformations. The 
final signature
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx 
b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 87f94958629c..9ce056d5a868 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -351,6 +351,7 @@ void OOXMLSecExporter::Impl::writeSignatureInfo()
     m_xDocumentHandler->startElement("SignatureInfoV1", 
uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
 
     m_xDocumentHandler->startElement("SetupId", 
uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
+    m_xDocumentHandler->characters(m_rInformation.ouSignatureLineId);
     m_xDocumentHandler->endElement("SetupId");
     m_xDocumentHandler->startElement("SignatureText", 
uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
     m_xDocumentHandler->endElement("SignatureText");
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx 
b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index 0f7630171285..33406fe2a829 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -146,6 +146,11 @@ void XMLSignatureHelper::SetDescription(sal_Int32 
nSecurityId, const OUString& r
     mpXSecController->setDescription(nSecurityId, rDescription);
 }
 
+void XMLSignatureHelper::SetSignatureLineId(sal_Int32 nSecurityId, const 
OUString& rSignatureLineId)
+{
+    mpXSecController->setSignatureLineId(nSecurityId, rSignatureLineId);
+}
+
 void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& 
uri, bool bBinary, bool bXAdESCompliantIfODF )
 {
     mpXSecController->signAStream( nSecurityId, uri, bBinary, 
bXAdESCompliantIfODF );
diff --git a/xmlsecurity/source/helper/xsecctl.cxx 
b/xmlsecurity/source/helper/xsecctl.cxx
index 96d04436341f..cbff47dc75c3 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -833,6 +833,28 @@ void XSecController::exportSignature(
                         "dc:date");
                 }
                 xDocumentHandler->endElement( "SignatureProperty" );
+
+                if (!signatureInfo.ouSignatureLineId.isEmpty())
+                {
+                    pAttributeList = new SvXMLAttributeList();
+                    pAttributeList->AddAttribute(
+                        "xmlns:loext",
+                        
"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0");
+                    pAttributeList->AddAttribute("Target", "#" + 
signatureInfo.ouSignatureId);
+
+                    xDocumentHandler->startElement(
+                        "SignatureProperty",
+                        
cssu::Reference<cssxs::XAttributeList>(pAttributeList));
+                    {
+                        // Write SignatureLineId element
+                        xDocumentHandler->startElement(
+                            "loext:SignatureLineId",
+                            cssu::Reference<cssxs::XAttributeList>(new 
SvXMLAttributeList()));
+                        
xDocumentHandler->characters(signatureInfo.ouSignatureLineId);
+                        xDocumentHandler->endElement("loext:SignatureLineId");
+                    }
+                    xDocumentHandler->endElement("SignatureProperty");
+                }
             }
 
             // Write signature description.
diff --git a/xmlsecurity/source/helper/xsecparser.cxx 
b/xmlsecurity/source/helper/xsecparser.cxx
index 50c13dc95bee..b33a11f5cf36 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -44,6 +44,7 @@ XSecParser::XSecParser(XMLSignatureHelper& 
rXMLSignatureHelper,
     , m_bInSignatureValue(false)
     , m_bInDate(false)
     , m_bInDescription(false)
+    , m_bInSignatureLineId(false)
     , m_pXSecController(pXSecController)
     , m_bReferenceUnresolved(false)
     , m_nReferenceDigestID(cssxc::DigestID::SHA1)
@@ -252,6 +253,11 @@ void SAL_CALL XSecParser::startElement(
             m_ouDescription.clear();
             m_bInDescription = true;
         }
+        else if (aName == "loext:SignatureLineId")
+        {
+            m_ouSignatureLineId.clear();
+            m_bInSignatureLineId = true;
+        }
 
         if (m_xNextHandler.is())
         {
@@ -361,6 +367,11 @@ void SAL_CALL XSecParser::endElement( const OUString& 
aName )
             m_pXSecController->setDescription( m_ouDescription );
             m_bInDescription = false;
         }
+        else if (aName == "loext:SignatureLineId")
+        {
+            m_pXSecController->setSignatureLineId( m_ouSignatureLineId );
+            m_bInSignatureLineId = false;
+        }
 
         if (m_xNextHandler.is())
         {
@@ -436,6 +447,10 @@ void SAL_CALL XSecParser::characters( const OUString& 
aChars )
     {
         m_ouDate += aChars;
     }
+    else if (m_bInSignatureLineId)
+    {
+        m_ouSignatureLineId += aChars;
+    }
 
     if (m_xNextHandler.is())
     {
diff --git a/xmlsecurity/source/helper/xsecparser.hxx 
b/xmlsecurity/source/helper/xsecparser.hxx
index 8376a48b69cd..e1c4515ce941 100644
--- a/xmlsecurity/source/helper/xsecparser.hxx
+++ b/xmlsecurity/source/helper/xsecparser.hxx
@@ -67,6 +67,7 @@ private:
     OUString m_ouDate;
     /// Characters of a <dc:description> element, as just read from XML.
     OUString m_ouDescription;
+    OUString m_ouSignatureLineId;
 
     /*
      * whether inside a particular element
@@ -84,6 +85,7 @@ private:
     bool m_bInSignatureValue;
     bool m_bInDate;
     bool m_bInDescription;
+    bool m_bInSignatureLineId;
 
     /*
      * the XSecController collaborating with XSecParser
diff --git a/xmlsecurity/source/helper/xsecsign.cxx 
b/xmlsecurity/source/helper/xsecsign.cxx
index b5e50f3c8bf0..701ce84d1989 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -288,6 +288,23 @@ void XSecController::setDescription(sal_Int32 nSecurityId, 
const OUString& rDesc
     }
 }
 
+void XSecController::setSignatureLineId(sal_Int32 nSecurityId, const OUString& 
rSignatureLineId)
+{
+    int nIndex = findSignatureInfor(nSecurityId);
+
+    if (nIndex == -1)
+    {
+        InternalSignatureInformation aInformation(nSecurityId, nullptr);
+        aInformation.signatureInfor.ouSignatureLineId = rSignatureLineId;
+        m_vInternalSignatureInformations.push_back(aInformation);
+    }
+    else
+    {
+        SignatureInformation& rInformation = 
m_vInternalSignatureInformations[nIndex].signatureInfor;
+        rInformation.ouSignatureLineId = rSignatureLineId;
+    }
+}
+
 bool XSecController::WriteSignature(
     const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
     bool bXAdESCompliantIfODF )
commit a797afa58cd441cb7de5e1fe2845c3eff2e9001b
Author:     Samuel Mehrbrodt <[email protected]>
AuthorDate: Fri Apr 20 12:19:12 2018 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Nov 8 13:49:09 2018 +0100

    Sign Signature Line
    
    This adds a new context menu entry "Sign Signature Line" to signature lines.
    You can directly sign the document from there.
    
    Still missing is the updating of the graphic to reflect the valid/invalid
    signature state.
    
    Reviewed-on: https://gerrit.libreoffice.org/53778
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Samuel Mehrbrodt <[email protected]>
    (cherry picked from commit 86e8cfdd54ac1b9413f0c86cbc23a80162806685)
    
    Conflicts:
            cui/source/dialogs/SignSignatureLineDialog.cxx
            xmlsecurity/source/component/documentdigitalsignatures.cxx
    
    Change-Id: Ib8bc8c57f9d5370a10e379f86f9e41e57c715e3f

diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx
index 468e11dd2e7b..57c52b81cb95 100644
--- a/include/sfx2/docfile.hxx
+++ b/include/sfx2/docfile.hxx
@@ -35,6 +35,7 @@
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/ucb/XContent.hpp>
 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
 #include <com/sun/star/task/XInteractionHandler.hpp>
 #include <com/sun/star/embed/XStorage.hpp>
 #include <com/sun/star/beans/PropertyValue.hpp>
@@ -262,7 +263,10 @@ public:
                              const INetURLObject& aDest,
                              const css::uno::Reference< 
css::ucb::XCommandEnvironment >& xComEnv );
 
-    SAL_DLLPRIVATE bool SignContents_Impl( bool bScriptingContent, const 
OUString& aODFVersion, bool bHasValidDocumentSignature );
+    SAL_DLLPRIVATE bool
+    SignContents_Impl(const css::uno::Reference<css::security::XCertificate> 
xCert,
+                      bool bScriptingContent, const OUString& aODFVersion,
+                      bool bHasValidDocumentSignature);
 
     // the following two methods must be used and make sense only during 
saving currently
     // TODO/LATER: in future the signature state should be controlled by the 
medium not by the document
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index a17583b31c01..7263e78bdcbc 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -359,6 +359,7 @@ public:
     // xmlsec05, check with SFX team
     SignatureState              GetDocumentSignatureState();
     void                        SignDocumentContent();
+    void                        
SignDocumentContent(css::uno::Reference<css::security::XCertificate> xCert);
     SignatureState              GetScriptingSignatureState();
     void                        SignScriptingContent();
     DECL_LINK(SignDocumentHandler, Button*, void);
@@ -741,7 +742,10 @@ public:
             const css::uno::Reference< 
css::security::XDocumentDigitalSignatures >& xSigner
                 = css::uno::Reference< 
css::security::XDocumentDigitalSignatures >() );
 
-    SAL_DLLPRIVATE void ImplSign( bool bScriptingContent = false );
+    SAL_DLLPRIVATE void
+    ImplSign(const css::uno::Reference<css::security::XCertificate> xCert,
+             bool bScriptingContent = false);
+
     SAL_DLLPRIVATE bool QuerySaveSizeExceededModules_Impl( const 
css::uno::Reference< css::task::XInteractionHandler >& xHandler );
     SAL_DLLPRIVATE bool QueryAllowExoticFormat_Impl( const 
css::uno::Reference< css::task::XInteractionHandler >& xHandler,
                                                      const OUString& rURL,
diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl 
b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
index 4d51192c557f..69d86af35a8a 100644
--- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
+++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
@@ -46,6 +46,17 @@ interface XDocumentDigitalSignatures : 
com::sun::star::uno::XInterface
     boolean signDocumentContent( [in] ::com::sun::star::embed::XStorage 
xStorage,
                                  [in] ::com::sun::star::io::XStream 
xSignStream);
 
+    /** Signs the content of the document including text and pictures
+        using the given XCertificate
+
+       Macros will not be signed.
+
+       @since LibreOffice 6.1
+     */
+    boolean signDocumentContentWithCertificate( [in] 
::com::sun::star::embed::XStorage xStorage,
+                                                [in] 
::com::sun::star::io::XStream xSignStream,
+                                                [in] 
::com::sun::star::security::XCertificate xCertificate);
+
     /** checks for digital signatures and their status.
 
         <p>Only document content will be checked.</p>
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index c79e2246eae4..2a679cd36bac 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -66,6 +66,7 @@
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
 #include <o3tl/make_unique.hxx>
 #include <tools/urlobj.hxx>
 #include <tools/fileutil.hxx>
@@ -135,6 +136,7 @@ using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::ucb;
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::security;
 
 namespace {
 
@@ -3573,7 +3575,8 @@ void SfxMedium::CreateTempFileNoCopy()
     CloseStorage();
 }
 
-bool SfxMedium::SignContents_Impl( bool bScriptingContent, const OUString& 
aODFVersion, bool bHasValidDocumentSignature )
+bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, bool 
bScriptingContent,
+                                  const OUString& aODFVersion, bool 
bHasValidDocumentSignature)
 {
     bool bChanges = false;
 
@@ -3661,7 +3664,15 @@ bool SfxMedium::SignContents_Impl( bool 
bScriptingContent, const OUString& aODFV
                         if (GetFilter() && GetFilter()->IsOwnFormat())
                             
xStream.set(xMetaInf->openStreamElement(xSigner->getDocumentContentSignatureDefaultStreamName(),
 embed::ElementModes::READWRITE), uno::UNO_SET_THROW);
 
-                        if ( xSigner->signDocumentContent( 
GetZipStorageToSign_Impl(), xStream ) )
+                        bool bSuccess = false;
+                        if (xCert.is())
+                            bSuccess = 
xSigner->signDocumentContentWithCertificate(
+                                GetZipStorageToSign_Impl(), xStream, xCert);
+                        else
+                            bSuccess = 
xSigner->signDocumentContent(GetZipStorageToSign_Impl(),
+                                                                    xStream);
+
+                        if (bSuccess)
                         {
                             uno::Reference< embed::XTransactedObject > 
xTransact( xMetaInf, uno::UNO_QUERY_THROW );
                             xTransact->commit();
@@ -3677,8 +3688,21 @@ bool SfxMedium::SignContents_Impl( bool 
bScriptingContent, const OUString& aODFV
                     {
                         // OOXML.
                         uno::Reference<io::XStream> xStream;
-                        // We need read-write to be able to add the signature 
relation.
-                        if 
(xSigner->signDocumentContent(GetZipStorageToSign_Impl(/*bReadOnly=*/false), 
xStream))
+
+                        bool bSuccess = false;
+                        if (xCert.is())
+                        {
+                            bSuccess = 
xSigner->signDocumentContentWithCertificate(
+                                GetZipStorageToSign_Impl(), xStream, xCert);
+                        }
+                        else
+                        {
+                            // We need read-write to be able to add the 
signature relation.
+                            bSuccess =xSigner->signDocumentContent(
+                                GetZipStorageToSign_Impl(/*bReadOnly=*/false), 
xStream);
+                        }
+
+                        if (bSuccess)
                         {
                             uno::Reference<embed::XTransactedObject> 
xTransact(xWriteableZipStor, uno::UNO_QUERY_THROW);
                             xTransact->commit();
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index 10517e6d2866..c8bc40e8bb19 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -33,6 +33,7 @@
 #include <com/sun/star/container/XNameAccess.hpp>
 #include <com/sun/star/document/XCmisDocument.hpp>
 #include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
 #include <com/sun/star/task/ErrorCodeIOException.hpp>
 #include <com/sun/star/task/InteractionHandler.hpp>
 #include <com/sun/star/task/XStatusIndicator.hpp>
@@ -113,6 +114,7 @@ using namespace ::com::sun::star::awt;
 using namespace ::com::sun::star::container;
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::security;
 using namespace ::com::sun::star::task;
 
 #define SfxObjectShell
@@ -1358,7 +1360,8 @@ SignatureState SfxObjectShell::ImplGetSignatureState( 
bool bScriptingContent )
     return *pState;
 }
 
-void SfxObjectShell::ImplSign( bool bScriptingContent )
+void SfxObjectShell::ImplSign(Reference<XCertificate> xCert,
+                              bool bScriptingContent)
 {
     // Check if it is stored in OASIS format...
     if  (   GetMedium()
@@ -1469,21 +1472,18 @@ void SfxObjectShell::ImplSign( bool bScriptingContent )
     {
         GetMedium()->CloseAndRelease();
 
-        // We sign only ODF1.2, that means that if this point has been reached,
-        // the ODF1.2 signing process should be used.
-        // This code still might be called to show the signature of ODF1.1 
document.
-        bool bSigned = GetMedium()->SignContents_Impl(
-            bScriptingContent,
-            aODFVersion,
-            pImpl->nDocumentSignatureState == SignatureState::OK
+        bool bHasValidSignatures = pImpl->nDocumentSignatureState == 
SignatureState::OK
             || pImpl->nDocumentSignatureState == SignatureState::NOTVALIDATED
-            || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK);
+            || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK;
+
+        bool bSignSuccess = GetMedium()->SignContents_Impl(
+            xCert, bScriptingContent, aODFVersion, bHasValidSignatures);
 
         pImpl->m_bSavingForSigning = true;
         DoSaveCompleted( GetMedium() );
         pImpl->m_bSavingForSigning = false;
 
-        if ( bSigned )
+        if ( bSignSuccess )
         {
             if ( bScriptingContent )
             {
@@ -1512,7 +1512,12 @@ SignatureState 
SfxObjectShell::GetDocumentSignatureState()
 
 void SfxObjectShell::SignDocumentContent()
 {
-    ImplSign();
+    ImplSign(Reference<XCertificate>());
+}
+
+void SfxObjectShell::SignDocumentContent(const Reference<XCertificate> xCert)
+{
+    ImplSign(xCert);
 }
 
 SignatureState SfxObjectShell::GetScriptingSignatureState()
@@ -1522,7 +1527,7 @@ SignatureState 
SfxObjectShell::GetScriptingSignatureState()
 
 void SfxObjectShell::SignScriptingContent()
 {
-    ImplSign( true );
+    ImplSign( Reference<XCertificate>(), true );
 }
 
 namespace
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx 
b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index e49c11e0eef7..eee5a09952e6 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -47,10 +47,12 @@
 #include <comphelper/sequence.hxx>
 #include <cppuhelper/supportsservice.hxx>
 #include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
 
 using namespace css;
 using namespace css::uno;
+using namespace css::lang;
 using namespace css::xml::crypto;
 
 DocumentDigitalSignatures::DocumentDigitalSignatures( const Reference< 
XComponentContext >& rxCtx ):
@@ -120,6 +122,51 @@ sal_Bool DocumentDigitalSignatures::signDocumentContent(
     return ImplViewSignatures( rxStorage, xSignStream, 
DocumentSignatureMode::Content, false );
 }
 
+sal_Bool DocumentDigitalSignatures::signDocumentContentWithCertificate(
+    const Reference<css::embed::XStorage>& rxStorage,
+    const Reference<css::io::XStream>& xSignStream,
+    const Reference<css::security::XCertificate>& xCertificate)
+{
+    OSL_ENSURE(!m_sODFVersion.isEmpty(),
+               "DocumentDigitalSignatures: ODF Version not set, assuming 
minimum 1.2");
+
+    DocumentSignatureManager aSignatureManager(mxCtx, 
DocumentSignatureMode::Content);
+
+    if (!aSignatureManager.init())
+        return false;
+
+    aSignatureManager.mxStore = rxStorage;
+    aSignatureManager.maSignatureHelper.SetStorage(rxStorage, m_sODFVersion);
+    aSignatureManager.mxSignatureStream = xSignStream;
+
+    Reference<XXMLSecurityContext> xSecurityContext;
+    Reference<XServiceInfo> xServiceInfo(xCertificate, UNO_QUERY);
+    if (xServiceInfo->getImplementationName()
+        == "com.sun.star.xml.security.gpg.XCertificate_GpgImpl")
+        xSecurityContext = aSignatureManager.getGpgSecurityContext();
+    else
+        xSecurityContext = aSignatureManager.getSecurityContext();
+
+    sal_Int32 nSecurityId;
+    OUString aDescription("");
+    bool bSuccess
+        = aSignatureManager.add(xCertificate, xSecurityContext, aDescription, 
nSecurityId, true);
+    if (!bSuccess)
+        return false;
+
+    // Need to have this to verify the signature
+    aSignatureManager.read(/*bUseTempStream=*/true, 
/*bCacheLastSignature=*/false);
+    aSignatureManager.write(true);
+
+    if (rxStorage.is() && !xSignStream.is())
+    {
+        uno::Reference<embed::XTransactedObject> xTrans(rxStorage, 
uno::UNO_QUERY);
+        xTrans->commit();
+    }
+
+    return true;
+}
+
 Sequence< css::security::DocumentSignatureInformation >
 DocumentDigitalSignatures::verifyDocumentContentSignatures(
     const Reference< css::embed::XStorage >& rxStorage,
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx 
b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index a3064eb1e206..72ac2ced5014 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -86,6 +86,10 @@ public:
 
     // XDocumentDigitalSignatures
     sal_Bool SAL_CALL signDocumentContent( const css::uno::Reference< 
css::embed::XStorage >& xStorage, const css::uno::Reference< css::io::XStream 
>& xSignStream ) override;
+    sal_Bool SAL_CALL signDocumentContentWithCertificate(
+        const css::uno::Reference<css::embed::XStorage>& Storage,
+        const css::uno::Reference<css::io::XStream>& xSignStream,
+        const css::uno::Reference<css::security::XCertificate>& xCertificate) 
override;
     css::uno::Sequence< css::security::DocumentSignatureInformation > SAL_CALL 
verifyDocumentContentSignatures( const css::uno::Reference< 
css::embed::XStorage >& xStorage, const css::uno::Reference< 
css::io::XInputStream >& xSignInStream ) override;
     void SAL_CALL showDocumentContentSignatures( const css::uno::Reference< 
css::embed::XStorage >& xStorage, const css::uno::Reference< 
css::io::XInputStream >& xSignInStream ) override;
     OUString SAL_CALL getDocumentContentSignatureDefaultStreamName(  ) 
override;
diff --git a/xmlsecurity/source/gpg/CertificateImpl.cxx 
b/xmlsecurity/source/gpg/CertificateImpl.cxx
index c831011ca50e..81dafbe9e472 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -13,6 +13,7 @@
 
 #include <comphelper/servicehelper.hxx>
 #include <comphelper/sequence.hxx>
+#include <cppuhelper/supportsservice.hxx>
 
 #include <com/sun/star/security/KeyUsage.hpp>
 #include <officecfg/Office/Common.hxx>
@@ -246,4 +247,19 @@ const GpgME::Key* CertificateImpl::getCertificate() const
     return &m_pKey;
 }
 
+/* XServiceInfo */
+OUString SAL_CALL CertificateImpl::getImplementationName()
+{
+    return OUString("com.sun.star.xml.security.gpg.XCertificate_GpgImpl");
+}
+
+/* XServiceInfo */
+sal_Bool SAL_CALL CertificateImpl::supportsService(const OUString& serviceName)
+{
+    return cppu::supportsService(this, serviceName);
+}
+
+/* XServiceInfo */
+Sequence<OUString> SAL_CALL CertificateImpl::getSupportedServiceNames() { 
return { OUString() }; }
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/gpg/CertificateImpl.hxx 
b/xmlsecurity/source/gpg/CertificateImpl.hxx
index 63cddc6dc7b9..eaf81bd3f37f 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.hxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.hxx
@@ -21,6 +21,7 @@
 #include <com/sun/star/uno/Exception.hpp>
 #include <com/sun/star/uno/RuntimeException.hpp>
 #include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
 #include <com/sun/star/uno/SecurityException.hpp>
 #include <com/sun/star/security/CertificateKind.hpp>
@@ -29,7 +30,8 @@
 #include <key.h>
 
 class CertificateImpl : public cppu::WeakImplHelper< 
css::security::XCertificate,
-                                                     css::lang::XUnoTunnel >,
+                                                     css::lang::XUnoTunnel,
+                                                     css::lang::XServiceInfo >,
                         public xmlsecurity::Certificate
 {
 private:
@@ -84,6 +86,11 @@ public:
     // Helper methods
     void setCertificate(GpgME::Context* ctx, const GpgME::Key& key);
     const GpgME::Key* getCertificate() const;
+
+    // XServiceInfo
+    virtual OUString SAL_CALL getImplementationName() override;
+    virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 
override;
+    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() 
override;
 } ;
 
 #endif // INCLUDED_XMLSECURITY_SOURCE_GPG_X509CERTIFICATE_HXX
diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx 
b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
index 07a769ac99cf..23b2fdb2d56a 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
@@ -22,6 +22,7 @@
 #include <sal/config.h>
 #include <comphelper/servicehelper.hxx>
 #include <comphelper/windowserrorstring.hxx>
+#include <cppuhelper/supportsservice.hxx>
 #include "x509certificate_mscryptimpl.hxx"
 #include <certificateextension_xmlsecimpl.hxx>
 #include "sanextension_mscryptimpl.hxx"
@@ -648,4 +649,22 @@ sal_Int32 SAL_CALL 
X509Certificate_MSCryptImpl::getCertificateUsage(  )
     return usage;
 }
 
+/* XServiceInfo */
+OUString SAL_CALL X509Certificate_MSCryptImpl::getImplementationName()
+{
+    return OUString("com.sun.star.xml.security.gpg.XCertificate_MsCryptImpl");
+}
+
+/* XServiceInfo */
+sal_Bool SAL_CALL X509Certificate_MSCryptImpl::supportsService(const OUString& 
serviceName)
+{
+    return cppu::supportsService(this, serviceName);
+}
+
+/* XServiceInfo */
+Sequence<OUString> SAL_CALL 
X509Certificate_MSCryptImpl::getSupportedServiceNames()
+{
+    return { OUString() };
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx 
b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx
index 94d53529bf21..4526dd827aef 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx
@@ -37,6 +37,7 @@
 #include <cppuhelper/implbase.hxx>
 #include <com/sun/star/uno/Exception.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/uno/SecurityException.hpp>
 #include <com/sun/star/security/CertificateKind.hpp>
 #include <com/sun/star/security/XCertificate.hpp>
@@ -44,7 +45,8 @@
 
 class X509Certificate_MSCryptImpl : public ::cppu::WeakImplHelper<
     css::security::XCertificate ,
-    css::lang::XUnoTunnel > , public xmlsecurity::Certificate
+    css::lang::XUnoTunnel,
+    css::lang::XServiceInfo > , public xmlsecurity::Certificate
 {
     private:
         const CERT_CONTEXT* m_pCertContext ;
@@ -90,6 +92,11 @@ class X509Certificate_MSCryptImpl : public 
::cppu::WeakImplHelper<
         const CERT_CONTEXT* getMswcryCert() const ;
         /// @throws css::uno::RuntimeException
         void setRawCert( css::uno::Sequence< sal_Int8 > const & rawCert ) ;
+
+        // XServiceInfo
+        virtual OUString SAL_CALL getImplementationName() override;
+        virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 
override;
+        virtual css::uno::Sequence<OUString> SAL_CALL 
getSupportedServiceNames() override;
 } ;
 
 #endif // 
INCLUDED_XMLSECURITY_SOURCE_XMLSEC_MSCRYPT_X509CERTIFICATE_MSCRYPTIMPL_HXX
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx 
b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
index 48ca392864ec..941f8364f237 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
@@ -28,6 +28,7 @@
 
 #include <sal/config.h>
 #include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
 #include <rtl/ref.hxx>
 #include "x509certificate_nssimpl.hxx"
 
@@ -492,4 +493,19 @@ sal_Int32 SAL_CALL 
X509Certificate_NssImpl::getCertificateUsage(  )
     return usage;
 }
 
+/* XServiceInfo */
+OUString SAL_CALL X509Certificate_NssImpl::getImplementationName()
+{
+    return OUString("com.sun.star.xml.security.gpg.XCertificate_NssImpl");
+}
+
+/* XServiceInfo */
+sal_Bool SAL_CALL X509Certificate_NssImpl::supportsService(const OUString& 
serviceName)
+{
+    return cppu::supportsService(this, serviceName);
+}
+
+/* XServiceInfo */
+Sequence<OUString> SAL_CALL 
X509Certificate_NssImpl::getSupportedServiceNames() { return { OUString() }; }
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx 
b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
index 8f22a8f37363..5c5794342c62 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
@@ -26,6 +26,7 @@
 #include <cppuhelper/implbase.hxx>
 #include <com/sun/star/uno/Exception.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/uno/SecurityException.hpp>
 #include <com/sun/star/security/CertificateKind.hpp>
 #include <com/sun/star/security/XCertificate.hpp>
@@ -35,7 +36,8 @@
 
 class X509Certificate_NssImpl : public ::cppu::WeakImplHelper<
     css::security::XCertificate ,
-    css::lang::XUnoTunnel > , public xmlsecurity::Certificate
+    css::lang::XUnoTunnel,
+    css::lang::XServiceInfo > , public xmlsecurity::Certificate
 {
     private:
         CERTCertificate* m_pCert ;
@@ -90,6 +92,11 @@ class X509Certificate_NssImpl : public 
::cppu::WeakImplHelper<
         const CERTCertificate* getNssCert() const ;
         /// @throws css::uno::RuntimeException
         void setRawCert( const css::uno::Sequence< sal_Int8 >& rawCert ) ;
+
+        // XServiceInfo
+        virtual OUString SAL_CALL getImplementationName() override;
+        virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 
override;
+        virtual css::uno::Sequence<OUString> SAL_CALL 
getSupportedServiceNames() override;
 } ;
 
 #endif // INCLUDED_XMLSECURITY_SOURCE_XMLSEC_NSS_X509CERTIFICATE_NSSIMPL_HXX
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to