summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Luby <guibmacdev@gmail.com>2024-03-24 12:46:45 -0400
committerThorsten Behrens <thorsten.behrens@allotropia.de>2024-03-26 10:01:31 +0100
commit6a049e417b029f3733fcee05f99a3e8875aefdb8 (patch)
tree80d98c7940446aa6e3a42aae8ab141e50788ff5a
parenta3eefc0fbe7d9a9ed946979c97a41181cd043593 (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.cxx38
-rw-r--r--offapi/com/sun/star/security/XDocumentDigitalSignatures.idl6
-rw-r--r--sfx2/source/dialog/filedlghelper.cxx2
-rw-r--r--xmlsecurity/inc/strings.hrc1
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.cxx14
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,