cui/source/dialogs/SignSignatureLineDialog.cxx | 2 include/sfx2/digitalsignatures.hxx | 8 +++ include/svx/signaturelinehelper.hxx | 3 - sd/source/ui/func/fuconrec.cxx | 1 sd/source/ui/view/drviewse.cxx | 31 +++++++++++++ svx/sdi/svx.sdi | 2 svx/source/dialog/signaturelinehelper.cxx | 9 ++- xmlsecurity/source/component/documentdigitalsignatures.cxx | 29 ++++++++---- 8 files changed, 71 insertions(+), 14 deletions(-)
New commits: commit 0cc0896b212b0d1fded8d999b980f18f0379e6e0 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Jan 3 13:44:59 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jan 6 13:02:15 2025 +0100 cool#10630 lok doc sign: fix Impress sign line when picking a certificate Once .uno:InsertSignatureLine gets dispatched, a visual signature placeholder gets inserted, then a certificate picker shows up, but no certificates are visible in the list. The first problem is that .uno:InsertSignatureLine needs to take sign key/cert parameters in DrawViewShell::FuPermanent() (similar to .uno:Signature), so it can learn what certificate to use for signing. The second problem is that once that sign cert is attached to the view, the cert chooser for signature lines were not taking the sign cert from the view in DocumentDigitalSignatures::chooseCertificatesImpl() -- this needs routing the info about the current view from sd/ (where we still have that info) to xmlsecurity/. With this, a LOK client dispatching .uno:InsertSignatureLine with the 2 new parameters set can insert a signature line, it'll show up, but the subsequent .uno:Signature dispatch still needs fixing up. (Currently it wants to "save" the modified PDF, while it should just sign.) Change-Id: Ie536842152ef097aa6959c67916f2beb6d356e4a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179819 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/cui/source/dialogs/SignSignatureLineDialog.cxx b/cui/source/dialogs/SignSignatureLineDialog.cxx index a58e9298054d..a1cf837c107c 100644 --- a/cui/source/dialogs/SignSignatureLineDialog.cxx +++ b/cui/source/dialogs/SignSignatureLineDialog.cxx @@ -158,7 +158,7 @@ IMPL_LINK_NOARG(SignSignatureLineDialog, chooseCertificate, weld::Button&, void) return; Reference<XCertificate> xSignCertificate - = svx::SignatureLineHelper::getSignatureCertificate(pShell, m_xDialog.get()); + = svx::SignatureLineHelper::getSignatureCertificate(pShell, nullptr, m_xDialog.get()); if (xSignCertificate.is()) { diff --git a/include/sfx2/digitalsignatures.hxx b/include/sfx2/digitalsignatures.hxx index fe5f2bc97874..7778f5e1fb89 100644 --- a/include/sfx2/digitalsignatures.hxx +++ b/include/sfx2/digitalsignatures.hxx @@ -15,6 +15,7 @@ #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/security/XCertificate.hpp> +#include <com/sun/star/security/CertificateKind.hpp> #include <sal/types.h> @@ -56,6 +57,13 @@ public: SetSignScriptingContent(const css::uno::Reference<css::io::XStream>& xScriptingSignStream) = 0; + /// View-aware replacement for selectSigningCertificateWithType(). + virtual css::uno::Reference<css::security::XCertificate> + SelectSigningCertificateWithType(SfxViewShell* pViewShell, + const css::security::CertificateKind certificateKind, + OUString& rDescription) + = 0; + protected: ~DigitalSignatures() noexcept = default; }; diff --git a/include/svx/signaturelinehelper.hxx b/include/svx/signaturelinehelper.hxx index 9a10a09a29ce..e8105a37bd7f 100644 --- a/include/svx/signaturelinehelper.hxx +++ b/include/svx/signaturelinehelper.hxx @@ -26,6 +26,7 @@ class Window; } class SdrView; class SfxObjectShell; +class SfxViewShell; namespace svx::SignatureLineHelper { @@ -39,7 +40,7 @@ SVX_DLLPUBLIC OUString getSignatureImage(const OUString& rType = OUString()); * Choose a signature for signature line purposes. */ SVX_DLLPUBLIC css::uno::Reference<css::security::XCertificate> -getSignatureCertificate(SfxObjectShell* pShell, weld::Window* pParent); +getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, weld::Window* pParent); /** * Get a signer name out of a certificate. diff --git a/sd/source/ui/func/fuconrec.cxx b/sd/source/ui/func/fuconrec.cxx index 45abc8058d82..5cbdb1e82596 100644 --- a/sd/source/ui/func/fuconrec.cxx +++ b/sd/source/ui/func/fuconrec.cxx @@ -514,6 +514,7 @@ void FuConstructRectangle::Deactivate() uno::Reference<security::XCertificate> xCertificate = svx::SignatureLineHelper::getSignatureCertificate(mpViewShell->GetObjectShell(), + mpViewShell->GetViewShell(), mpViewShell->GetFrameWeld()); if (!xCertificate.is()) { diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx index 9a7c8df31f7a..ea2f65a01c00 100644 --- a/sd/source/ui/view/drviewse.cxx +++ b/sd/source/ui/view/drviewse.cxx @@ -98,6 +98,7 @@ #include <basegfx/utils/zoomtools.hxx> #include <officecfg/Office/Draw.hxx> #include <officecfg/Office/Impress.hxx> +#include <sfx2/lokhelper.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -455,6 +456,36 @@ void DrawViewShell::FuPermanent(SfxRequest& rReq) case SID_CONNECTOR_LINES_CIRCLES: case SID_INSERT_SIGNATURELINE: { + if (nSId == SID_INSERT_SIGNATURELINE) + { + // See if a signing cert is passed as a parameter: if so, parse that. + std::string aSignatureCert; + std::string aSignatureKey; + const SfxStringItem* pSignatureCert = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pSignatureCert) + { + aSignatureCert = pSignatureCert->GetValue().toUtf8(); + } + const SfxStringItem* pSignatureKey = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pSignatureKey) + { + aSignatureKey = pSignatureKey->GetValue().toUtf8(); + } + + SfxViewFrame* pFrame = GetFrame(); + SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : nullptr; + if (pViewShell) + { + uno::Reference<security::XCertificate> xSigningCertificate; + if (!aSignatureCert.empty() && !aSignatureKey.empty()) + { + xSigningCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); + } + // Always set the signing certificate, to clear data from a previous dispatch. + pViewShell->SetSigningCertificate(xSigningCertificate); + } + } + bCreateDirectly = comphelper::LibreOfficeKit::isActive(); bRectangle = true; SetCurrentFunction( FuConstructRectangle::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) ); diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi index 70dc6c4423fa..449cd55d36d9 100644 --- a/svx/sdi/svx.sdi +++ b/svx/sdi/svx.sdi @@ -12416,7 +12416,7 @@ SfxVoidItem AnchorMenu SID_ANCHOR_MENU ] SfxVoidItem InsertSignatureLine SID_INSERT_SIGNATURELINE -() +(SfxStringItem SignatureCert FN_PARAM_1, SfxStringItem SignatureKey FN_PARAM_2) [ AutoUpdate = FALSE, FastCall = FALSE, diff --git a/svx/source/dialog/signaturelinehelper.cxx b/svx/source/dialog/signaturelinehelper.cxx index 52fb02c80e87..e079d62d5631 100644 --- a/svx/source/dialog/signaturelinehelper.cxx +++ b/svx/source/dialog/signaturelinehelper.cxx @@ -33,6 +33,7 @@ #include <unotools/streamwrap.hxx> #include <unotools/syslocale.hxx> #include <vcl/weld.hxx> +#include <sfx2/digitalsignatures.hxx> using namespace com::sun::star; @@ -57,8 +58,8 @@ OUString getSignatureImage(const OUString& rType) return OUString::fromUtf8(svg); } -uno::Reference<security::XCertificate> getSignatureCertificate(SfxObjectShell* pShell, - weld::Window* pParent) +uno::Reference<security::XCertificate> +getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, weld::Window* pParent) { if (!pShell) { @@ -91,8 +92,10 @@ uno::Reference<security::XCertificate> getSignatureCertificate(SfxObjectShell* p { certificateKind = security::CertificateKind_X509; } + auto xModelSigner = dynamic_cast<sfx2::DigitalSignatures*>(xSigner.get()); + assert(xModelSigner); uno::Reference<security::XCertificate> xSignCertificate - = xSigner->selectSigningCertificateWithType(certificateKind, aDescription); + = xModelSigner->SelectSigningCertificateWithType(pViewShell, certificateKind, aDescription); return xSignCertificate; } diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx index 541748fc7c73..6d8291c7bf83 100644 --- a/xmlsecurity/source/component/documentdigitalsignatures.cxx +++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx @@ -99,7 +99,7 @@ private: DocumentSignatureMode eMode); css::uno::Sequence<css::uno::Reference<css::security::XCertificate>> - chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const CertificateChooserUserAction eAction, + chooseCertificatesImpl(SfxViewShell* pViewShell, std::map<OUString, OUString>& rProperties, const CertificateChooserUserAction eAction, const CertificateKind certificateKind=CertificateKind_NONE); bool @@ -207,6 +207,12 @@ public: /// See sfx2::DigitalSignatures::SetSignScriptingContent(). void SetSignScriptingContent( const css::uno::Reference<css::io::XStream>& xScriptingSignStream) override; + + /// See sfx2::DigitalSignatures::SelectSigningCertificateWithType(). + css::uno::Reference<css::security::XCertificate> + SelectSigningCertificateWithType(SfxViewShell* pViewShell, + const css::security::CertificateKind certificateKind, + OUString& rDescription) override; }; } @@ -639,7 +645,8 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted( } uno::Sequence<Reference<css::security::XCertificate>> -DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, +DocumentDigitalSignatures::chooseCertificatesImpl(SfxViewShell* pViewShell, + std::map<OUString, OUString>& rProperties, const CertificateChooserUserAction eAction, const CertificateKind certificateKind) { @@ -654,7 +661,7 @@ DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, OUString>& xSecContexts.push_back(aSignatureManager.getGpgSecurityContext()); } - std::shared_ptr<CertificateChooser> aChooser = CertificateChooser::getInstance(Application::GetFrameWeld(mxParentWindow), nullptr, std::move(xSecContexts), eAction); + std::shared_ptr<CertificateChooser> aChooser = CertificateChooser::getInstance(Application::GetFrameWeld(mxParentWindow), pViewShell, std::move(xSecContexts), eAction); if (aChooser->run() != RET_OK) return { Reference< css::security::XCertificate >(nullptr) }; @@ -674,7 +681,7 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertif Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseSigningCertificate(OUString& rDescription) { std::map<OUString, OUString> aProperties; - Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( aProperties, CertificateChooserUserAction::Sign )[0]; + Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( nullptr, aProperties, CertificateChooserUserAction::Sign )[0]; rDescription = aProperties[u"Description"_ustr]; return xCert; } @@ -682,7 +689,7 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseSignin Reference< css::security::XCertificate > DocumentDigitalSignatures::selectSigningCertificate(OUString& rDescription) { std::map<OUString, OUString> aProperties; - Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( aProperties, CertificateChooserUserAction::SelectSign )[0]; + Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( nullptr, aProperties, CertificateChooserUserAction::SelectSign )[0]; rDescription = aProperties[u"Description"_ustr]; return xCert; } @@ -690,10 +697,16 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::selectSignin Reference<css::security::XCertificate> DocumentDigitalSignatures::selectSigningCertificateWithType(const CertificateKind certificateKind, OUString& rDescription) +{ + return SelectSigningCertificateWithType(nullptr, certificateKind, rDescription); +} + +Reference<css::security::XCertificate> +DocumentDigitalSignatures::SelectSigningCertificateWithType(SfxViewShell* pViewShell, const CertificateKind certificateKind, OUString& rDescription) { std::map<OUString, OUString> aProperties; Reference<css::security::XCertificate> xCert - = chooseCertificatesImpl(aProperties, CertificateChooserUserAction::SelectSign, certificateKind)[0]; + = chooseCertificatesImpl(pViewShell, aProperties, CertificateChooserUserAction::SelectSign, certificateKind)[0]; rDescription = aProperties[u"Description"_ustr]; return xCert; } @@ -703,7 +716,7 @@ DocumentDigitalSignatures::chooseEncryptionCertificate(const CertificateKind cer { std::map<OUString, OUString> aProperties; uno::Sequence< Reference< css::security::XCertificate > > aCerts= - chooseCertificatesImpl( aProperties, CertificateChooserUserAction::Encrypt , certificateKind ); + chooseCertificatesImpl( nullptr, aProperties, CertificateChooserUserAction::Encrypt , certificateKind ); if (aCerts.getLength() == 1 && !aCerts[0].is()) // our error case contract is: empty sequence, so map that! return uno::Sequence< Reference< css::security::XCertificate > >(); @@ -714,7 +727,7 @@ DocumentDigitalSignatures::chooseEncryptionCertificate(const CertificateKind cer css::uno::Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificateWithProps(Sequence<css::beans::PropertyValue>& rProperties) { std::map<OUString, OUString> aProperties; - auto xCert = chooseCertificatesImpl( aProperties, CertificateChooserUserAction::Sign )[0]; + auto xCert = chooseCertificatesImpl( nullptr, aProperties, CertificateChooserUserAction::Sign )[0]; std::vector<css::beans::PropertyValue> vec; vec.reserve(aProperties.size());