#include "mypgpkeycontext.h" #include "gpgop.h" #include "utils.h" #include #include 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