File indexing completed on 2025-01-12 04:19:47
0001 #include "mypgpkeycontext.h" 0002 #include "gpgop.h" 0003 #include "utils.h" 0004 #include <QDir> 0005 #include <QTemporaryFile> 0006 0007 using namespace QCA; 0008 0009 namespace gpgQCAPlugin { 0010 0011 MyPGPKeyContext::MyPGPKeyContext(Provider *p) 0012 : PGPKeyContext(p) 0013 { 0014 // zero out the props 0015 _props.isSecret = false; 0016 _props.inKeyring = true; 0017 _props.isTrusted = false; 0018 } 0019 0020 Provider::Context *MyPGPKeyContext::clone() const 0021 { 0022 return new MyPGPKeyContext(*this); 0023 } 0024 0025 const PGPKeyContextProps *MyPGPKeyContext::props() const 0026 { 0027 return &_props; 0028 } 0029 0030 QByteArray MyPGPKeyContext::toBinary() const 0031 { 0032 if (_props.inKeyring) { 0033 GpgOp gpg(find_bin()); 0034 gpg.setAsciiFormat(false); 0035 gpg.doExport(_props.keyId); 0036 gpg_waitForFinished(&gpg); 0037 gpg_keyStoreLog(gpg.readDiagnosticText()); 0038 if (!gpg.success()) 0039 return QByteArray(); 0040 return gpg.read(); 0041 } else 0042 return cacheExportBinary; 0043 } 0044 0045 ConvertResult MyPGPKeyContext::fromBinary(const QByteArray &a) 0046 { 0047 GpgOp::Key key; 0048 bool sec = false; 0049 0050 // temporary keyrings 0051 QString pubname, secname; 0052 0053 QTemporaryFile pubtmp(QDir::tempPath() + QLatin1String("/qca_gnupg_tmp.XXXXXX.gpg")); 0054 if (!pubtmp.open()) 0055 return ErrorDecode; 0056 0057 QTemporaryFile sectmp(QDir::tempPath() + QLatin1String("/qca_gnupg_tmp.XXXXXX.gpg")); 0058 if (!sectmp.open()) 0059 return ErrorDecode; 0060 0061 pubname = pubtmp.fileName(); 0062 secname = sectmp.fileName(); 0063 0064 // we turn off autoRemove so that we can close the files 0065 // without them getting deleted 0066 pubtmp.setAutoRemove(false); 0067 sectmp.setAutoRemove(false); 0068 pubtmp.close(); 0069 sectmp.close(); 0070 0071 // import key into temporary keyring 0072 GpgOp gpg(find_bin()); 0073 gpg.setKeyrings(pubname, secname); 0074 gpg.doImport(a); 0075 gpg_waitForFinished(&gpg); 0076 gpg_keyStoreLog(gpg.readDiagnosticText()); 0077 // comment this out. apparently gpg will report failure for 0078 // an import if there are trust issues, even though the 0079 // key actually did get imported 0080 /*if(!gpg.success()) 0081 { 0082 cleanup_temp_keyring(pubname); 0083 cleanup_temp_keyring(secname); 0084 return ErrorDecode; 0085 }*/ 0086 0087 // now extract the key from gpg like normal 0088 0089 // is it a public key? 0090 gpg.doPublicKeys(); 0091 gpg_waitForFinished(&gpg); 0092 gpg_keyStoreLog(gpg.readDiagnosticText()); 0093 if (!gpg.success()) { 0094 cleanup_temp_keyring(pubname); 0095 cleanup_temp_keyring(secname); 0096 return ErrorDecode; 0097 } 0098 0099 const GpgOp::KeyList pubkeys = gpg.keys(); 0100 if (!pubkeys.isEmpty()) { 0101 key = pubkeys.first(); 0102 } else { 0103 // is it a secret key? 0104 gpg.doSecretKeys(); 0105 gpg_waitForFinished(&gpg); 0106 gpg_keyStoreLog(gpg.readDiagnosticText()); 0107 if (!gpg.success()) { 0108 cleanup_temp_keyring(pubname); 0109 cleanup_temp_keyring(secname); 0110 return ErrorDecode; 0111 } 0112 0113 const GpgOp::KeyList seckeys = gpg.keys(); 0114 if (!seckeys.isEmpty()) { 0115 key = seckeys.first(); 0116 sec = true; 0117 } else { 0118 // no keys found 0119 cleanup_temp_keyring(pubname); 0120 cleanup_temp_keyring(secname); 0121 return ErrorDecode; 0122 } 0123 } 0124 0125 // export binary/ascii and cache 0126 0127 gpg.setAsciiFormat(false); 0128 gpg.doExport(key.keyItems.first().id); 0129 gpg_waitForFinished(&gpg); 0130 gpg_keyStoreLog(gpg.readDiagnosticText()); 0131 if (!gpg.success()) { 0132 cleanup_temp_keyring(pubname); 0133 cleanup_temp_keyring(secname); 0134 return ErrorDecode; 0135 } 0136 cacheExportBinary = gpg.read(); 0137 0138 gpg.setAsciiFormat(true); 0139 gpg.doExport(key.keyItems.first().id); 0140 gpg_waitForFinished(&gpg); 0141 gpg_keyStoreLog(gpg.readDiagnosticText()); 0142 if (!gpg.success()) { 0143 cleanup_temp_keyring(pubname); 0144 cleanup_temp_keyring(secname); 0145 return ErrorDecode; 0146 } 0147 cacheExportAscii = QString::fromLocal8Bit(gpg.read()); 0148 0149 // all done 0150 0151 cleanup_temp_keyring(pubname); 0152 cleanup_temp_keyring(secname); 0153 0154 set(key, sec, false, false); 0155 return ConvertGood; 0156 } 0157 0158 QString MyPGPKeyContext::toAscii() const 0159 { 0160 if (_props.inKeyring) { 0161 GpgOp gpg(find_bin()); 0162 gpg.setAsciiFormat(true); 0163 gpg.doExport(_props.keyId); 0164 gpg_waitForFinished(&gpg); 0165 gpg_keyStoreLog(gpg.readDiagnosticText()); 0166 if (!gpg.success()) 0167 return QString(); 0168 return QString::fromLocal8Bit(gpg.read()); 0169 } else { 0170 return cacheExportAscii; 0171 } 0172 } 0173 0174 ConvertResult MyPGPKeyContext::fromAscii(const QString &s) 0175 { 0176 // GnuPG does ascii/binary detection for imports, so for 0177 // simplicity we consider an ascii import to just be a 0178 // binary import that happens to be comprised of ascii 0179 return fromBinary(s.toLocal8Bit()); 0180 } 0181 0182 void MyPGPKeyContext::set(const GpgOp::Key &i, bool isSecret, bool inKeyring, bool isTrusted) 0183 { 0184 const GpgOp::KeyItem &ki = i.keyItems.first(); 0185 0186 _props.keyId = ki.id; 0187 _props.userIds = i.userIds; 0188 _props.isSecret = isSecret; 0189 _props.creationDate = ki.creationDate; 0190 _props.expirationDate = ki.expirationDate; 0191 _props.fingerprint = ki.fingerprint.toLower(); 0192 _props.inKeyring = inKeyring; 0193 _props.isTrusted = isTrusted; 0194 } 0195 0196 void MyPGPKeyContext::cleanup_temp_keyring(const QString &name) 0197 { 0198 QFile::remove(name); 0199 QFile::remove(name + QLatin1Char('~')); // remove possible backup file 0200 } 0201 0202 } // end namespace gpgQCAPlugin