summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Duge <moritz.duge@allotropia.de>2024-04-26 10:07:54 +0200
committerSamuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>2024-04-27 08:29:15 +0200
commit906e5d44f26e97830c0d005c12521a22002c01b5 (patch)
treec0267c4f7e4a65763364d24e302b4575307c3ee6
parent7c0a776f3a26adc3e83d304990b05133d77d05a8 (diff)
Lazy load additional GPG key data.
Change-Id: I7f52b318b083535422202dacbee928333cb3ac78 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166639 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
-rw-r--r--xmlsecurity/source/gpg/CertificateImpl.cxx60
-rw-r--r--xmlsecurity/source/gpg/CertificateImpl.hxx3
-rw-r--r--xmlsecurity/source/gpg/SecurityEnvironment.cxx4
-rw-r--r--xmlsecurity/source/gpg/SecurityEnvironment.hxx2
4 files changed, 37 insertions, 32 deletions
diff --git a/xmlsecurity/source/gpg/CertificateImpl.cxx b/xmlsecurity/source/gpg/CertificateImpl.cxx
index 697b2d67c6f8..894c924a9840 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -119,6 +119,36 @@ Reference< XCertificateExtension > SAL_CALL CertificateImpl::findCertificateExte
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getEncoded()
{
+ if (m_aBits.hasElements())
+ return m_aBits;
+
+ // lazy init: extract key data, store into m_aBits
+ GpgME::Data data_out;
+ m_pContext->setArmor(false); // caller will base64-encode anyway
+ GpgME::Error err = m_pContext->exportPublicKeys( // "exportPublicKeys" is slow!
+ m_pKey.primaryFingerprint(),
+ data_out,
+ officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
+ ? GpgME::Context::ExportMinimal : 0
+ );
+
+ if (err)
+ throw RuntimeException("The GpgME library failed to retrieve the public key");
+
+ off_t result = data_out.seek(0,SEEK_SET);
+ (void) result;
+ assert(result == 0);
+ int len=0, curr=0; char buf;
+ while( (curr=data_out.read(&buf, 1)) )
+ len += curr;
+
+ // write bits to sequence of bytes
+ m_aBits.realloc(len);
+ result = data_out.seek(0,SEEK_SET);
+ assert(result == 0);
+ if( data_out.read(m_aBits.getArray(), len) != len )
+ throw RuntimeException("The GpgME library failed to read the key");
+
// Export key to base64Empty for gpg
return m_aBits;
}
@@ -190,36 +220,10 @@ sal_Int32 SAL_CALL CertificateImpl::getCertificateUsage()
return KeyUsage::DIGITAL_SIGNATURE | KeyUsage::NON_REPUDIATION | KeyUsage::KEY_ENCIPHERMENT | KeyUsage::DATA_ENCIPHERMENT;
}
-void CertificateImpl::setCertificate(GpgME::Context* ctx, const GpgME::Key& key)
+void CertificateImpl::setCertificate(std::shared_ptr<GpgME::Context> ctx, const GpgME::Key& key)
{
m_pKey = key;
-
- // extract key data, store into m_aBits
- GpgME::Data data_out;
- ctx->setArmor(false); // caller will base64-encode anyway
- GpgME::Error err = ctx->exportPublicKeys(
- key.primaryFingerprint(),
- data_out,
- officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
- ? GpgME::Context::ExportMinimal : 0
- );
-
- if (err)
- throw RuntimeException("The GpgME library failed to retrieve the public key");
-
- off_t result = data_out.seek(0,SEEK_SET);
- (void) result;
- assert(result == 0);
- int len=0, curr=0; char buf;
- while( (curr=data_out.read(&buf, 1)) )
- len += curr;
-
- // write bits to sequence of bytes
- m_aBits.realloc(len);
- result = data_out.seek(0,SEEK_SET);
- assert(result == 0);
- if( data_out.read(m_aBits.getArray(), len) != len )
- throw RuntimeException("The GpgME library failed to read the key");
+ m_pContext = ctx;
}
const GpgME::Key* CertificateImpl::getCertificate() const
diff --git a/xmlsecurity/source/gpg/CertificateImpl.hxx b/xmlsecurity/source/gpg/CertificateImpl.hxx
index b0856ca0109f..d15dec47a058 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.hxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.hxx
@@ -36,6 +36,7 @@ class CertificateImpl : public cppu::WeakImplHelper< css::security::XCertificate
{
private:
GpgME::Key m_pKey;
+ std::shared_ptr<GpgME::Context> m_pContext;
css::uno::Sequence< sal_Int8 > m_aBits;
public:
@@ -81,7 +82,7 @@ public:
virtual css::security::CertificateKind SAL_CALL getCertificateKind() override;
// Helper methods
- void setCertificate(GpgME::Context* ctx, const GpgME::Key& key);
+ void setCertificate(std::shared_ptr<GpgME::Context> ctx, const GpgME::Key& key);
const GpgME::Key* getCertificate() const;
// XServiceInfo
diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.cxx b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
index db36415591ff..1fed32d5399e 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.cxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
@@ -119,7 +119,7 @@ Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getCertificatesIm
int i = 0;
for (auto const& key : keyList) {
rtl::Reference<CertificateImpl> xCert = new CertificateImpl();
- xCert->setCertificate(m_ctx.get(),key);
+ xCert->setCertificate(m_ctx, key);
xCertificateSequenceRange[i++] = xCert; // fills xCertificateSequence
}
@@ -154,7 +154,7 @@ Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString
break;
if (!k.isInvalid() && strcmp(k.primaryFingerprint(), reinterpret_cast<const char*>(strKeyId)) == 0) {
rtl::Reference<CertificateImpl> xCert = new CertificateImpl();
- xCert->setCertificate(m_ctx.get(), k);
+ xCert->setCertificate(m_ctx, k);
m_ctx->endKeyListing();
return xCert;
}
diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.hxx b/xmlsecurity/source/gpg/SecurityEnvironment.hxx
index 0c530c671596..60b5e862387a 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.hxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.hxx
@@ -24,7 +24,7 @@ namespace GpgME { class Context; }
class SecurityEnvironmentGpg : public cppu::WeakImplHelper< css::xml::crypto::XSecurityEnvironment >
{
- std::unique_ptr<GpgME::Context> m_ctx;
+ std::shared_ptr<GpgME::Context> m_ctx;
public:
SecurityEnvironmentGpg();