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:
committed by
Samuel Mehrbrodt
parent
7c0a776f3a
commit
906e5d44f2
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user