xmlsecurity/source/gpg/CertificateImpl.cxx     |   60 +++++++++++++------------
 xmlsecurity/source/gpg/CertificateImpl.hxx     |    3 -
 xmlsecurity/source/gpg/SecurityEnvironment.cxx |    4 -
 xmlsecurity/source/gpg/SecurityEnvironment.hxx |    2 
 4 files changed, 37 insertions(+), 32 deletions(-)

New commits:
commit 906e5d44f26e97830c0d005c12521a22002c01b5
Author:     Moritz Duge <moritz.d...@allotropia.de>
AuthorDate: Fri Apr 26 10:07:54 2024 +0200
Commit:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
CommitDate: Sat Apr 27 08:29:15 2024 +0200

    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.mehrbr...@allotropia.de>

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();

Reply via email to