mirror of
https://github.com/QuasarApp/qca.git
synced 2025-04-27 20:14:32 +00:00
219 lines
4.7 KiB
C++
219 lines
4.7 KiB
C++
#include "mypgpkeycontext.h"
|
|
#include "utils.h"
|
|
#include "gpgop.h"
|
|
#include <QTemporaryFile>
|
|
#include <QDir>
|
|
|
|
using namespace QCA;
|
|
|
|
namespace gpgQCAPlugin
|
|
{
|
|
|
|
MyPGPKeyContext::MyPGPKeyContext(Provider *p)
|
|
: PGPKeyContext(p)
|
|
{
|
|
// zero out the props
|
|
_props.isSecret = false;
|
|
_props.inKeyring = true;
|
|
_props.isTrusted = false;
|
|
}
|
|
|
|
Provider::Context *MyPGPKeyContext::clone() const
|
|
{
|
|
return new MyPGPKeyContext(*this);
|
|
}
|
|
|
|
const PGPKeyContextProps *MyPGPKeyContext::props() const
|
|
{
|
|
return &_props;
|
|
}
|
|
|
|
QByteArray MyPGPKeyContext::toBinary() const
|
|
{
|
|
if(_props.inKeyring)
|
|
{
|
|
GpgOp gpg(find_bin());
|
|
gpg.setAsciiFormat(false);
|
|
gpg.doExport(_props.keyId);
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
if(!gpg.success())
|
|
return QByteArray();
|
|
return gpg.read();
|
|
}
|
|
else
|
|
return cacheExportBinary;
|
|
}
|
|
|
|
ConvertResult MyPGPKeyContext::fromBinary(const QByteArray &a)
|
|
{
|
|
GpgOp::Key key;
|
|
bool sec = false;
|
|
|
|
// temporary keyrings
|
|
QString pubname, secname;
|
|
|
|
QTemporaryFile pubtmp(QDir::tempPath() + QLatin1String("/qca_gnupg_tmp.XXXXXX.gpg"));
|
|
if(!pubtmp.open())
|
|
return ErrorDecode;
|
|
|
|
QTemporaryFile sectmp(QDir::tempPath() + QLatin1String("/qca_gnupg_tmp.XXXXXX.gpg"));
|
|
if(!sectmp.open())
|
|
return ErrorDecode;
|
|
|
|
pubname = pubtmp.fileName();
|
|
secname = sectmp.fileName();
|
|
|
|
// we turn off autoRemove so that we can close the files
|
|
// without them getting deleted
|
|
pubtmp.setAutoRemove(false);
|
|
sectmp.setAutoRemove(false);
|
|
pubtmp.close();
|
|
sectmp.close();
|
|
|
|
// import key into temporary keyring
|
|
GpgOp gpg(find_bin());
|
|
gpg.setKeyrings(pubname, secname);
|
|
gpg.doImport(a);
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
// comment this out. apparently gpg will report failure for
|
|
// an import if there are trust issues, even though the
|
|
// key actually did get imported
|
|
/*if(!gpg.success())
|
|
{
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
return ErrorDecode;
|
|
}*/
|
|
|
|
// now extract the key from gpg like normal
|
|
|
|
// is it a public key?
|
|
gpg.doPublicKeys();
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
if(!gpg.success())
|
|
{
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
return ErrorDecode;
|
|
}
|
|
|
|
const GpgOp::KeyList pubkeys = gpg.keys();
|
|
if(!pubkeys.isEmpty())
|
|
{
|
|
key = pubkeys.first();
|
|
}
|
|
else
|
|
{
|
|
// is it a secret key?
|
|
gpg.doSecretKeys();
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
if(!gpg.success())
|
|
{
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
return ErrorDecode;
|
|
}
|
|
|
|
const GpgOp::KeyList seckeys = gpg.keys();
|
|
if(!seckeys.isEmpty())
|
|
{
|
|
key = seckeys.first();
|
|
sec = true;
|
|
}
|
|
else
|
|
{
|
|
// no keys found
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
return ErrorDecode;
|
|
}
|
|
}
|
|
|
|
// export binary/ascii and cache
|
|
|
|
gpg.setAsciiFormat(false);
|
|
gpg.doExport(key.keyItems.first().id);
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
if(!gpg.success())
|
|
{
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
return ErrorDecode;
|
|
}
|
|
cacheExportBinary = gpg.read();
|
|
|
|
gpg.setAsciiFormat(true);
|
|
gpg.doExport(key.keyItems.first().id);
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
if(!gpg.success())
|
|
{
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
return ErrorDecode;
|
|
}
|
|
cacheExportAscii = QString::fromLocal8Bit(gpg.read());
|
|
|
|
// all done
|
|
|
|
cleanup_temp_keyring(pubname);
|
|
cleanup_temp_keyring(secname);
|
|
|
|
set(key, sec, false, false);
|
|
return ConvertGood;
|
|
}
|
|
|
|
QString MyPGPKeyContext::toAscii() const
|
|
{
|
|
if(_props.inKeyring)
|
|
{
|
|
GpgOp gpg(find_bin());
|
|
gpg.setAsciiFormat(true);
|
|
gpg.doExport(_props.keyId);
|
|
gpg_waitForFinished(&gpg);
|
|
gpg_keyStoreLog(gpg.readDiagnosticText());
|
|
if(!gpg.success())
|
|
return QString();
|
|
return QString::fromLocal8Bit(gpg.read());
|
|
}
|
|
else
|
|
{
|
|
return cacheExportAscii;
|
|
}
|
|
}
|
|
|
|
ConvertResult MyPGPKeyContext::fromAscii(const QString &s)
|
|
{
|
|
// GnuPG does ascii/binary detection for imports, so for
|
|
// simplicity we consider an ascii import to just be a
|
|
// binary import that happens to be comprised of ascii
|
|
return fromBinary(s.toLocal8Bit());
|
|
}
|
|
|
|
void MyPGPKeyContext::set(const GpgOp::Key &i, bool isSecret, bool inKeyring, bool isTrusted)
|
|
{
|
|
const GpgOp::KeyItem &ki = i.keyItems.first();
|
|
|
|
_props.keyId = ki.id;
|
|
_props.userIds = i.userIds;
|
|
_props.isSecret = isSecret;
|
|
_props.creationDate = ki.creationDate;
|
|
_props.expirationDate = ki.expirationDate;
|
|
_props.fingerprint = ki.fingerprint.toLower();
|
|
_props.inKeyring = inKeyring;
|
|
_props.isTrusted = isTrusted;
|
|
}
|
|
|
|
void MyPGPKeyContext::cleanup_temp_keyring(const QString &name)
|
|
{
|
|
QFile::remove(name);
|
|
QFile::remove(name + QLatin1Char('~')); // remove possible backup file
|
|
}
|
|
|
|
} // end namespace gpgQCAPlugin
|