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>
This commit is contained in:
Moritz Duge
2024-04-27 08:29:15 +02:00
committed by Samuel Mehrbrodt
parent 7c0a776f3a
commit 906e5d44f2
4 changed files with 37 additions and 32 deletions
+32 -28
View File
@@ -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
+2 -1
View File
@@ -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
@@ -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;
}
@@ -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();