diff options
-rw-r--r-- | comphelper/source/misc/storagehelper.cxx | 13 | ||||
-rw-r--r-- | include/sal/log-areas.dox | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/security/XDocumentDigitalSignatures.idl | 2 | ||||
-rw-r--r-- | sfx2/source/dialog/filedlghelper.cxx | 22 | ||||
-rw-r--r-- | xmlsecurity/inc/certificatechooser.hxx | 2 | ||||
-rw-r--r-- | xmlsecurity/source/component/documentdigitalsignatures.cxx | 30 | ||||
-rw-r--r-- | xmlsecurity/source/component/documentdigitalsignatures.hxx | 4 | ||||
-rw-r--r-- | xmlsecurity/source/dialogs/certificatechooser.cxx | 38 | ||||
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 2 |
9 files changed, 82 insertions, 32 deletions
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx index a05fb1358f3f..7fa46554b595 100644 --- a/comphelper/source/misc/storagehelper.cxx +++ b/comphelper/source/misc/storagehelper.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_gpgme.h> + #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp> #include <com/sun/star/embed/XEncryptionProtectedStorage.hpp> @@ -459,6 +461,9 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat uno::Sequence< uno::Reference< security::XCertificate > > xSignCertificates= xSigner->chooseEncryptionCertificate(); + if (!xSignCertificates.hasElements()) + return uno::Sequence< beans::NamedValue >(); // user cancelled + // generate one encrypted key entry for each recipient // --------------------------------------------------- @@ -478,13 +483,13 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat { uno::Sequence < sal_Int8 > aKeyID; if (pCerts->is()) - aKeyID = (*pCerts)->getSHA256Thumbprint(); + aKeyID = (*pCerts)->getSHA1Thumbprint(); std::vector<GpgME::Key> keys; keys.push_back( ctx->key( reinterpret_cast<const char*>(aKeyID.getConstArray()), - err, true)); + err, false)); // ctx is setup now, let's encrypt the lot! GpgME::Data plain( @@ -504,7 +509,9 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat len += curr; if(crypt_res.error() || !len) - throw uno::RuntimeException("The GpgME library failed to encrypt."); + throw lang::IllegalArgumentException( + "Not a suitable key, or failed to encrypt.", + css::uno::Reference<css::uno::XInterface>(), i); uno::Sequence < sal_Int8 > aCipherValue(len); result = cipher.seek(0,SEEK_SET); diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index 1df274126d87..3858ea12175b 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -94,6 +94,7 @@ certain functionality. @li @c comphelper @li @c comphelper.backupfilehelper @li @c comphelper.container - EmbeddedObjectContainer +@li @c comphelper.crypto @section cppu diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl index 85507940d316..519f77cb62dd 100644 --- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl +++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl @@ -148,7 +148,7 @@ interface XDocumentDigitalSignatures : com::sun::star::uno::XInterface @since LibreOffice 6.0 */ - com::sun::star::security::XCertificate chooseEncryptionCertificate( [out] string Description ); + sequence< com::sun::star::security::XCertificate > chooseEncryptionCertificate( ); /** This method shows the CertificateChooser dialog, used by document and PDF signing Shows only private certificates and returns usage string in addition to description. diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index 3393046a66bd..6e997d92ebc5 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -1521,8 +1521,26 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList, bool bGpg = false; if ( ( aValue >>= bGpg ) && bGpg ) { - // ask for a key - rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreateGpgPackageEncryptionData() ) ) ); + uno::Sequence< beans::NamedValue > aEncryptionData; + while(true) + { + try + { + // ask for keys + aEncryptionData = ::comphelper::OStorageHelper::CreateGpgPackageEncryptionData(); + break; // user cancelled or we've some keys now + } + catch( const IllegalArgumentException& ) + { + ScopedVclPtrInstance< MessageDialog > aBox( + mpPreferredParentWindow, + SfxResId(RID_SVXSTR_INCORRECT_PASSWORD)); + aBox->Execute(); + } + } + + if ( aEncryptionData.hasElements() ) + rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData) ) ); } } catch( const IllegalArgumentException& ){} diff --git a/xmlsecurity/inc/certificatechooser.hxx b/xmlsecurity/inc/certificatechooser.hxx index 3834dfb111a1..2ae3c1822b1f 100644 --- a/xmlsecurity/inc/certificatechooser.hxx +++ b/xmlsecurity/inc/certificatechooser.hxx @@ -92,7 +92,7 @@ public: short Execute() override; - css::uno::Reference< css::security::XCertificate > GetSelectedCertificate(); + css::uno::Sequence<css::uno::Reference< css::security::XCertificate > > GetSelectedCertificates(); css::uno::Reference< css::xml::crypto::XXMLSecurityContext > GetSelectedSecurityContext(); /// Gets the description string provided when selecting the certificate. OUString GetDescription(); diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx index bc52bdb30ff1..9d1244973de7 100644 --- a/xmlsecurity/source/component/documentdigitalsignatures.cxx +++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx @@ -456,7 +456,7 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted( return bFound; } -Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificateImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction) +uno::Sequence< Reference< css::security::XCertificate > > DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction) { std::vector< Reference< css::xml::crypto::XXMLSecurityContext > > xSecContexts; @@ -468,17 +468,17 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertif ScopedVclPtrInstance< CertificateChooser > aChooser(nullptr, mxCtx, xSecContexts, eAction); + uno::Sequence< Reference< css::security::XCertificate > > xCerts(1); + xCerts[0] = Reference< css::security::XCertificate >(nullptr); + if (aChooser->Execute() != RET_OK) - return Reference< css::security::XCertificate >(nullptr); + return xCerts; - Reference< css::security::XCertificate > xCert = aChooser->GetSelectedCertificate(); + xCerts = aChooser->GetSelectedCertificates(); rProperties["Description"] = aChooser->GetDescription(); rProperties["Usage"] = aChooser->GetUsageText(); - if ( !xCert.is() ) - return Reference< css::security::XCertificate >(nullptr); - - return xCert; + return xCerts; } Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificate(OUString& rDescription) @@ -489,23 +489,27 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertif Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseSigningCertificate(OUString& rDescription) { std::map<OUString, OUString> aProperties; - Reference< css::security::XCertificate > xCert = chooseCertificateImpl( aProperties, UserAction::Sign ); + Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( aProperties, UserAction::Sign )[0]; rDescription = aProperties["Description"]; return xCert; } -Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseEncryptionCertificate(OUString& rDescription) +css::uno::Sequence< Reference< css::security::XCertificate > > DocumentDigitalSignatures::chooseEncryptionCertificate() { std::map<OUString, OUString> aProperties; - Reference< css::security::XCertificate > xCert = chooseCertificateImpl( aProperties, UserAction::Encrypt ); - rDescription = aProperties["Description"]; - return xCert; + uno::Sequence< Reference< css::security::XCertificate > > aCerts= + chooseCertificatesImpl( aProperties, UserAction::Encrypt ); + if (aCerts.getLength() == 1 && !aCerts[0].is()) + // our error case contract is: empty sequence, so map that! + return uno::Sequence< Reference< css::security::XCertificate > >(); + else + return aCerts; } css::uno::Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificateWithProps(Sequence<::com::sun::star::beans::PropertyValue>& rProperties) { std::map<OUString, OUString> aProperties; - auto xCert = chooseCertificateImpl( aProperties, UserAction::Sign ); + auto xCert = chooseCertificatesImpl( aProperties, UserAction::Sign )[0]; std::vector<css::beans::PropertyValue> vec; for (const auto& pair : aProperties) diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx b/xmlsecurity/source/component/documentdigitalsignatures.hxx index 2dbc55685929..9ef24ab36e5e 100644 --- a/xmlsecurity/source/component/documentdigitalsignatures.hxx +++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx @@ -63,7 +63,7 @@ private: /// @throws css::uno::RuntimeException css::uno::Sequence< css::security::DocumentSignatureInformation > ImplVerifySignatures( const css::uno::Reference< css::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< css::io::XInputStream >& xSignStream, DocumentSignatureMode eMode ); - css::uno::Reference< css::security::XCertificate > chooseCertificateImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction); + css::uno::Sequence< css::uno::Reference< css::security::XCertificate > > chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction); public: explicit DocumentDigitalSignatures( const css::uno::Reference< css::uno::XComponentContext>& rxCtx ); @@ -106,7 +106,7 @@ public: css::uno::Reference< css::security::XCertificate > SAL_CALL chooseCertificate(OUString& rDescription) override; css::uno::Reference< css::security::XCertificate > SAL_CALL chooseSigningCertificate(OUString& rDescription) override; - css::uno::Reference< css::security::XCertificate > SAL_CALL chooseEncryptionCertificate(OUString& rDescription) override; + css::uno::Sequence<css::uno::Reference< css::security::XCertificate > > SAL_CALL chooseEncryptionCertificate() override; css::uno::Reference< css::security::XCertificate > SAL_CALL chooseCertificateWithProps(css::uno::Sequence<::com::sun::star::beans::PropertyValue>& Properties) override; }; diff --git a/xmlsecurity/source/dialogs/certificatechooser.cxx b/xmlsecurity/source/dialogs/certificatechooser.cxx index 08a897f9f0ba..a334e0250225 100644 --- a/xmlsecurity/source/dialogs/certificatechooser.cxx +++ b/xmlsecurity/source/dialogs/certificatechooser.cxx @@ -228,15 +228,33 @@ void CertificateChooser::ImplInitialize() } -uno::Reference< css::security::XCertificate > CertificateChooser::GetSelectedCertificate() +uno::Sequence<uno::Reference< css::security::XCertificate > > CertificateChooser::GetSelectedCertificates() { + std::vector< uno::Reference< css::security::XCertificate > > aRet; SvTreeListEntry* pSel = m_pCertLB->FirstSelected(); - if( !pSel ) - return uno::Reference< css::security::XCertificate >(); - UserData* userData = static_cast<UserData*>(pSel->GetUserData()); - uno::Reference<security::XCertificate> xCert = userData->xCertificate; - return xCert; + if (meAction == UserAction::Encrypt) + { + // for encryption, multiselection is enabled + while(pSel) + { + UserData* userData = static_cast<UserData*>(pSel->GetUserData()); + aRet.push_back( userData->xCertificate ); + pSel = m_pCertLB->NextSelected(pSel); + } + } + else + { + uno::Reference< css::security::XCertificate > xCert; + if( pSel ) + { + UserData* userData = static_cast<UserData*>(pSel->GetUserData()); + xCert = userData->xCertificate; + } + aRet.push_back( xCert ); + } + + return comphelper::containerToSequence(aRet); } uno::Reference<xml::crypto::XXMLSecurityContext> CertificateChooser::GetSelectedSecurityContext() @@ -257,13 +275,15 @@ OUString CertificateChooser::GetDescription() OUString CertificateChooser::GetUsageText() { - uno::Reference<css::security::XCertificate> xCert = GetSelectedCertificate(); - return xCert.is() ? UsageInClearText(xCert->getCertificateUsage()) : OUString(); + uno::Sequence< uno::Reference<css::security::XCertificate> > xCerts = + GetSelectedCertificates(); + return (xCerts.hasElements() && xCerts[0].is()) ? + UsageInClearText(xCerts[0]->getCertificateUsage()) : OUString(); } IMPL_LINK_NOARG(CertificateChooser, CertificateHighlightHdl, SvTreeListBox*, void) { - bool bEnable = GetSelectedCertificate().is(); + bool bEnable = m_pCertLB->GetSelectionCount() > 0; m_pViewBtn->Enable( bEnable ); m_pOKBtn->Enable( bEnable ); m_pDescriptionED->Enable(bEnable); diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index 42ca15d05faf..195c74ec5c3e 100644 --- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx +++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx @@ -406,7 +406,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void) if ( aChooser->Execute() == RET_OK ) { sal_Int32 nSecurityId; - if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetSelectedSecurityContext(), + if (!maSignatureManager.add(aChooser->GetSelectedCertificates()[0], aChooser->GetSelectedSecurityContext(), aChooser->GetDescription(), nSecurityId, m_bAdESCompliant)) return; mbSignaturesChanged = true; |