diff options
author | Patrick Luby <guibmacdev@gmail.com> | 2024-03-24 12:46:45 -0400 |
---|---|---|
committer | Thorsten Behrens <thorsten.behrens@allotropia.de> | 2024-03-26 10:01:31 +0100 |
commit | 6a049e417b029f3733fcee05f99a3e8875aefdb8 (patch) | |
tree | 80d98c7940446aa6e3a42aae8ab141e50788ff5a | |
parent | a3eefc0fbe7d9a9ed946979c97a41181cd043593 (diff) |
tdf#160184 ask user if they want to trust an untrusted certificate
gpgme contexts uses the "auto" trust model by default which only
allows encrypting with keys that have their trust level set to
"Ultimate". The gpg command, however, gives the user the option
to encrypt with a certificate that has a lower trust level so
emulate that bahavior by asking the user if they want to trust
the certificate for just this operation only.
Also, abort saving if no certificates are selected which is an
indication that the user cancelled the Select Certificate dialog.
Change-Id: I20951b1e31b2dcf8adb82243742f8c00fbaca8c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165260
Tested-by: Jenkins
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
-rw-r--r-- | comphelper/source/misc/storagehelper.cxx | 38 | ||||
-rw-r--r-- | offapi/com/sun/star/security/XDocumentDigitalSignatures.idl | 6 | ||||
-rw-r--r-- | sfx2/source/dialog/filedlghelper.cxx | 2 | ||||
-rw-r--r-- | xmlsecurity/inc/strings.hrc | 1 | ||||
-rw-r--r-- | xmlsecurity/source/component/documentdigitalsignatures.cxx | 14 |
5 files changed, 56 insertions, 5 deletions
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx index 1d504cb91725..3812bf023915 100644 --- a/comphelper/source/misc/storagehelper.cxx +++ b/comphelper/source/misc/storagehelper.cxx @@ -476,13 +476,18 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat if (err) throw uno::RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol."); - ctx.reset( GpgME::Context::createForProtocol(GpgME::OpenPGP) ); - if (ctx == nullptr) - throw uno::RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol."); - ctx->setArmor(false); - + bool bResetContext = true; for (const auto & cert : xSignCertificates) { + if (bResetContext) + { + bResetContext = false; + ctx.reset( GpgME::Context::createForProtocol(GpgME::OpenPGP) ); + if (ctx == nullptr) + throw uno::RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol."); + ctx->setArmor(false); + } + uno::Sequence < sal_Int8 > aKeyID; if (cert.is()) aKeyID = cert->getSHA1Thumbprint(); @@ -504,6 +509,29 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat keys, plain, cipher, GpgME::Context::NoCompress); + // tdf#160184 ask user if they want to trust an untrusted certificate + // gpgme contexts uses the "auto" trust model by default which only + // allows encrypting with keys that have their trust level set to + // "Ultimate". The gpg command, however, gives the user the option + // to encrypt with a certificate that has a lower trust level so + // emulate that bahavior by asking the user if they want to trust + // the certificate for just this operation only. + if (crypt_res.error().code() == GPG_ERR_UNUSABLE_PUBKEY) + { + if (xSigner->trustUntrustedCertificate(cert)) + { + // Reset the trust model back to "auto" before processing + // the next certificate + bResetContext = true; + + ctx->setFlag("trust-model", "tofu+pgp"); + ctx->setFlag("tofu-default-policy", "unknown"); + crypt_res = ctx->encrypt( + keys, plain, + cipher, GpgME::Context::NoCompress); + } + } + off_t result = cipher.seek(0,SEEK_SET); (void) result; assert(result == 0); diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl index a90304313582..a32f77970996 100644 --- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl +++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl @@ -212,6 +212,12 @@ interface XDocumentDigitalSignatures : com::sun::star::uno::XInterface boolean signPackageWithCertificate([in] ::com::sun::star::security::XCertificate xCertificate, [in] ::com::sun::star::embed::XStorage xStorage, [in] ::com::sun::star::io::XStream xStream); + + /** queries the user if the want to trust an untrusted certificate. + + @since LibreOffice 24.2.3 + */ + boolean trustUntrustedCertificate([in] ::com::sun::star::security::XCertificate xCertificate); }; } ; } ; } ; } ; diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index 450eac25c047..2d352aef03d8 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -1571,6 +1571,8 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList, if ( aEncryptionData.hasElements() ) rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::Any( aEncryptionData) ) ); + else + return ERRCODE_ABORT; } } catch( const IllegalArgumentException& ){} diff --git a/xmlsecurity/inc/strings.hrc b/xmlsecurity/inc/strings.hrc index b450f885df6e..69b62a06dafe 100644 --- a/xmlsecurity/inc/strings.hrc +++ b/xmlsecurity/inc/strings.hrc @@ -65,5 +65,6 @@ #define STR_BROKEN_MACRO_CERTIFICATE_DATA NC_("STR_BROKEN_MACRO_CERTIFICATE_DATA", "Macro security problem!\n\nBroken certificate data: %{data}") #define STR_RELOAD_FILE_WARNING NC_("STR_RELOAD_FILE_WARNING", "Reload the file to apply the new macro security level") +#define STR_TRUST_UNTRUSTED_PUBKEY NC_("STR_TRUST_UNTRUSTED_PUBKEY", "The following OpenPGP public key is not trusted:\n\n%{data}\n\nDo you want to use this untrusted OpenPGP public key?") /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx index a06fcc81d128..f6ffd9a7566f 100644 --- a/xmlsecurity/source/component/documentdigitalsignatures.cxx +++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx @@ -201,6 +201,9 @@ public: css::uno::Reference<css::embed::XStorage> const& xStoragexStorage, css::uno::Reference<css::io::XStream> const& xStream) override; + sal_Bool SAL_CALL trustUntrustedCertificate( + css::uno::Reference<css::security::XCertificate> const& xCertificate) override; + sal_Bool SAL_CALL signScriptingContentWithCertificate( css::uno::Reference<css::security::XCertificate> const& xCertificate, css::uno::Reference<css::embed::XStorage> const& xStoragexStorage, @@ -840,6 +843,17 @@ sal_Bool DocumentDigitalSignatures::signPackageWithCertificate( DocumentSignatureMode::Package); } +sal_Bool DocumentDigitalSignatures::trustUntrustedCertificate( + css::uno::Reference<css::security::XCertificate> const& xCertificate) +{ + OUString aSubjectName(comphelper::xmlsec::GetContentPart(xCertificate->getSubjectName(), xCertificate->getCertificateKind())); + OUString aMsg(XsResId(STR_TRUST_UNTRUSTED_PUBKEY)); + aMsg = aMsg.replaceFirst("%{data}", aSubjectName); + std::unique_ptr<weld::MessageDialog> m_xQueryBox(Application::CreateMessageDialog(nullptr, VclMessageType::Error, VclButtonsType::YesNo, aMsg)); + m_xQueryBox->set_default_response(RET_NO); + return m_xQueryBox->run() == RET_YES; +} + sal_Bool DocumentDigitalSignatures::signScriptingContentWithCertificate( css::uno::Reference<css::security::XCertificate> const& xCertificate, css::uno::Reference<css::embed::XStorage> const& xStorage, |