Commit e62cb2d3 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Rewrite the post-processing of external X.509 certificate imports

The main reason for the rewrite was that the call
KeyCache::mutableInstance()->refresh(keys);
clears the key cache and only adds the passed keys (i.e. the imported
X.509 certificates) to the key cache. In particular, this removed all
OpenPGP keys and all previously existing X.509 certificates from the
key cache. That was certainly not intended.

The new approach is a bit slower because it does an update for each
imported X.509 certificate instead of for all certificates with a single
keylisting.

This change also fixes a regression introduced with commit
0b7978d5
which performed the validation for external and local CMS imports.

GnuPG-bug-id: 5638
parent 53810860
......@@ -155,6 +155,14 @@ private:
std::vector<ImportResultData> m_results;
};
bool importFailed(const ImportResultData &r)
{
// ignore GPG_ERR_EOF error to handle the "failed" import of files
// without X.509 certificates by gpgsm gracefully
return r.result.error().code() != GPG_ERR_NO_ERROR
&& r.result.error().code() != GPG_ERR_EOF;
}
}
ImportCertificatesCommand::Private::Private(ImportCertificatesCommand *qq, KeyListController *c)
......@@ -514,35 +522,36 @@ static void handleOwnerTrust(const std::vector<ImportResultData> &results)
}
}
void ImportCertificatesCommand::Private::processResults()
static void validateImportedCertificate(const GpgME::Import &import)
{
if (const auto fpr = import.fingerprint()) {
auto key = KeyCache::instance()->findByFingerprint(fpr);
if (!key.isNull()) {
// this triggers a keylisting with validation for this certificate
key.update();
} else {
qCWarning(KLEOPATRA_LOG) << __func__ << "Certificate with fingerprint" << fpr << "not found";
}
}
}
static void handleExternalCMSImports(const std::vector<ImportResultData> &results)
{
QStringList fingerprints;
// For external CMS Imports we have to manually do a keylist
// with validation to get the intermediate and root ca imported
// automatically if trusted-certs and extra-certs are used.
for (const auto &r : results) {
const auto imports = r.result.imports();
for (const Import &import : imports) {
if (!import.fingerprint()) {
continue;
}
fingerprints << QString::fromLatin1(import.fingerprint());
if (r.protocol == GpgME::CMS && r.type == ImportType::External && !importFailed(r)) {
const auto imports = r.result.imports();
std::for_each(std::begin(imports), std::end(imports), &validateImportedCertificate);
}
}
auto job = QGpgME::smime()->keyListJob(false, true, true);
// Old connect here because of Windows.
connect(job, SIGNAL(result(GpgME::KeyListResult,std::vector<GpgME::Key>,QString,GpgME::Error)),
q, SLOT(keyListDone(GpgME::KeyListResult,std::vector<GpgME::Key>,QString,GpgME::Error)));
job->start(fingerprints, false);
}
void ImportCertificatesCommand::Private::keyListDone(const GpgME::KeyListResult &,
const std::vector<GpgME::Key> &keys,
const QString &, const GpgME::Error&)
void ImportCertificatesCommand::Private::processResults()
{
KeyCache::mutableInstance()->refresh(keys);
handleExternalCMSImports(results);
handleOwnerTrust(results);
showDetails(results);
......@@ -555,17 +564,6 @@ void ImportCertificatesCommand::Private::keyListDone(const GpgME::KeyListResult
finished();
}
namespace
{
bool importFailed(const ImportResultData &r)
{
// ignore GPG_ERR_EOF error to handle the "failed" import of files
// without X.509 certificates by gpgsm gracefully
return r.result.error().code() != GPG_ERR_NO_ERROR
&& r.result.error().code() != GPG_ERR_EOF;
}
}
void ImportCertificatesCommand::Private::tryToFinish()
{
......
......@@ -30,9 +30,6 @@ protected:
inline Private *d_func();
inline const Private *d_func() const;
Q_PRIVATE_SLOT(d_func(), void importResult(GpgME::ImportResult))
Q_PRIVATE_SLOT(d_func(), void keyListDone(GpgME::KeyListResult,
std::vector<GpgME::Key> keys,
QString, GpgME::Error))
protected:
explicit ImportCertificatesCommand(Private *pp);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment