diff options
Diffstat (limited to '')
70 files changed, 3095 insertions, 2964 deletions
@@ -2,6 +2,9 @@ include/GpgFrontend.h include/GpgFrontendBuildInfo.h +#Vscode +.vscode/* + #CLion .idea/* diff --git a/CMakeLists.txt b/CMakeLists.txt index c6ad717a..77410d45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ IF (MINGW) set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static") include_directories( - include + ${CMAKE_CURRENT_SOURCE_DIR}/src /mingw64/include ) link_directories( @@ -117,7 +117,7 @@ if(APPLE) set(ENV{Qt5_DIR} /usr/local/opt/qt5/lib/cmake) include_directories( - include + ${CMAKE_CURRENT_SOURCE_DIR}/src /usr/local/include ) link_directories( @@ -136,7 +136,7 @@ if(LINUX) set(OS_PLATFORM 2) include_directories( - include + ${CMAKE_CURRENT_SOURCE_DIR}/src /usr/include /usr/local/include ) @@ -153,6 +153,10 @@ message(STATUS "OS_PLATFORM ${OS_PLATFORM}") find_package(Qt5 COMPONENTS Core Test Widgets PrintSupport Network LinguistTools REQUIRED) +# Basic Envirnoment Configure +set(BASIC_ENV_CONFIG 1) +set(QT_MOC_CONFIG 1) + if(FULL_APPLICATION_BUILD) message(STATUS "Build Full Application") set(QT_MOC_CONFIG 1) diff --git a/include/gpg/GpgConstants.h b/include/gpg/GpgConstants.h deleted file mode 100644 index b4ba0e3c..00000000 --- a/include/gpg/GpgConstants.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPG_CONSTANTS_H -#define GPG_CONSTANTS_H - -#include "GpgFrontend.h" - -const int RESTART_CODE = 1000; - -namespace GpgFrontend { - - using BypeArrayPtr = std::unique_ptr<QByteArray>; - using BypeArrayRef = QByteArray &; - - using GpgError = gpgme_error_t; - - using GpgEncrResult = std::unique_ptr<struct _gpgme_op_encrypt_result, std::function<void( - gpgme_encrypt_result_t)>>; - using GpgDecrResult = std::unique_ptr<struct _gpgme_op_decrypt_result, std::function<void( - gpgme_decrypt_result_t)>>; - using GpgSignResult = std::unique_ptr<struct _gpgme_op_sign_result, std::function<void( - gpgme_sign_result_t)>>; - using GpgVerifyResult = std::unique_ptr<struct _gpgme_op_verify_result, std::function<void( - gpgme_verify_result_t)>>; - - class GpgConstants { - public: - static const char *PGP_CRYPT_BEGIN; - static const char *PGP_CRYPT_END; - static const char *PGP_SIGNED_BEGIN; - static const char *PGP_SIGNED_END; - static const char *PGP_SIGNATURE_BEGIN; - static const char *PGP_SIGNATURE_END; - static const char *GPG_FRONTEND_SHORT_CRYPTO_HEAD; - }; -} - - - -#endif // GPG_CONSTANTS_H diff --git a/include/gpg/GpgContext.h b/include/gpg/GpgContext.h deleted file mode 100644 index 719cd1fe..00000000 --- a/include/gpg/GpgContext.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __SGPGMEPP_CONTEXT_H__ -#define __SGPGMEPP_CONTEXT_H__ - -#include "GpgFrontend.h" - -#include "GpgConstants.h" -#include "GpgGenKeyInfo.h" -#include "GpgModel.h" -#include "GpgInfo.h" -#include "GpgFunctionObject.h" - -using GpgKeyList = std::list<GpgFrontend::GpgKey>; - -class GpgImportedKey { -public: - QString fpr; - int importStatus; -}; - -typedef std::list<GpgImportedKey> GpgImportedKeyList; - -class GpgImportInformation { -public: - GpgImportInformation() = default; - - int considered = 0; - int no_user_id = 0; - int imported = 0; - int imported_rsa = 0; - int unchanged = 0; - int new_user_ids = 0; - int new_sub_keys = 0; - int new_signatures = 0; - int new_revocations = 0; - int secret_read = 0; - int secret_imported = 0; - int secret_unchanged = 0; - int not_imported = 0; - GpgImportedKeyList importedKeys; -}; - -namespace GpgFrontend { - - static gpgme_error_t check_gpg_error(gpgme_error_t err); - - static gpgme_error_t check_gpg_error(gpgme_error_t gpgmeError, const std::string &comment); - - /** - * Custom Encapsulation of GpgME APIs - */ - class GpgContext : public SingletonFunctionObject<GpgContext> { - - public: - - GpgContext(); - - ~GpgContext() override = default; - - [[nodiscard]] bool isGood() const; - - GpgImportInformation importKey(QByteArray inBuffer); - - [[nodiscard]] const GpgKeyList &getKeys() const; - - bool exportKeys(QStringList *uidList, QByteArray *outBuffer); - - bool exportKeys(const QVector<GpgKey> &keys, QByteArray &outBuffer); - - gpgme_error_t generateKey(GenKeyInfo *params); - - gpgme_error_t generateSubkey(const GpgKey &key, GenKeyInfo *params); - - const GpgInfo &getInfo() const { return info; } - - void deleteKeys(QStringList *uidList); - - void clearPasswordCache(); - - bool exportSecretKey(const GpgKey &key, QByteArray *outBuffer) const; - - void generateRevokeCert(const GpgKey &key, const QString &outputFileName); - - static bool checkIfKeyCanSign(const GpgKey &key); - - static bool checkIfKeyCanCert(const GpgKey &key); - - static bool checkIfKeyCanAuth(const GpgKey &key); - - static bool checkIfKeyCanEncr(const GpgKey &key); - - - /** - * @details If text contains PGP-message, put a linebreak before the message, - * so that gpgme can decrypt correctly - * - * @param in Pointer to the QBytearray to check. - */ - static void preventNoDataErr(QByteArray *in); - - static QString getGpgmeVersion(); - - /** - * @brief - * - * @param text - * @return \li 2, if the text is completly signed, - * \li 1, if the text is partially signed, - * \li 0, if the text is not signed at all. - */ - static int textIsSigned(const QByteArray &text); - - static QString beautifyFingerprint(QString fingerprint); - - operator gpgme_ctx_t() const { return _ctx_ref.get(); } - - signals: - - void signalKeyDBChanged(); - - void signalKeyUpdated(QString key_id); - - void signalKeyInfoChanged(); - - private slots: - - void slotRefreshKeyList(); - - void slotUpdateKeyList(const QString &key_id); - - private: - - GpgInfo info; - - using CtxRefHandler = std::unique_ptr<struct gpgme_context, std::function<void(gpgme_ctx_t)>>; - CtxRefHandler _ctx_ref = nullptr; - - gpgme_data_t in{}; - gpgme_error_t err; - bool debug; - bool good = true; - - QByteArray mPasswordCache; - QSettings settings; - GpgKeyList mKeyList; - - std::map<QString, GpgKey> mKeyMap; - - void fetch_keys(); - - static gpgme_error_t passphraseCb(void *hook, const char *uid_hint, - const char *passphrase_info, - int last_was_bad, int fd); - - gpgme_error_t passphrase(const char *uid_hint, - const char *passphrase_info, - int last_was_bad, int fd); - - void executeGpgCommand(const QStringList &arguments, const std::function<void(QProcess *)> &interactFunc); - - }; -} // namespace GpgME - -#endif // __SGPGMEPP_CONTEXT_H__ diff --git a/include/gpg/GpgFileOpera.h b/include/gpg/GpgFileOpera.h deleted file mode 100644 index e7ca0c8d..00000000 --- a/include/gpg/GpgFileOpera.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGFILEOPERA_H -#define GPGFRONTEND_GPGFILEOPERA_H - -#include "GpgFrontend.h" -#include "gpg/GpgContext.h" - -class GpgFileOpera { -public: - static gpgme_error_t encryptFile(GpgFrontend::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, - gpgme_encrypt_result_t *result); - - static gpgme_error_t decryptFile(GpgFrontend::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *result); - - static gpgme_error_t signFile(GpgFrontend::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, - gpgme_sign_result_t *result); - - static gpgme_error_t verifyFile(GpgFrontend::GpgContext *ctx, const QString &mPath, gpgme_verify_result_t *result); - - static gpg_error_t - encryptSignFile(GpgFrontend::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, gpgme_encrypt_result_t *encr_res, gpgme_sign_result_t *sign_res); - - static gpg_error_t decryptVerifyFile(GpgFrontend::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *decr_res, gpgme_verify_result_t *verify_res); - -}; - - -#endif //GPGFRONTEND_GPGFILEOPERA_H diff --git a/include/gpg/GpgGenKeyInfo.h b/include/gpg/GpgGenKeyInfo.h deleted file mode 100644 index a5936207..00000000 --- a/include/gpg/GpgGenKeyInfo.h +++ /dev/null @@ -1,199 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPG4USB_GPGGENKEYINFO_H -#define GPG4USB_GPGGENKEYINFO_H - -#include "GpgFrontend.h" - -class GenKeyInfo { - - bool subKey = true; - QString userid; - QString algo; - int keySize = 2048; - QDateTime expired = QDateTime::currentDateTime().addYears(2); - bool nonExpired = false; - - bool noPassPhrase = false; - bool allowNoPassPhrase = true; - - int suggestMaxKeySize = 1024; - int suggestSizeAdditionStep = 1024; - int suggestMinKeySize = 4096; - - QString passPhrase; - -public: - - static const QVector<QString> SupportedKeyAlgo; - - static const QVector<QString> SupportedSubkeyAlgo; - - [[nodiscard]] bool isSubKey() const { - return subKey; - } - - void setIsSubKey(bool m_sub_key) { - GenKeyInfo::subKey = m_sub_key; - } - - [[nodiscard]] const QString &getUserid() const { - return userid; - } - - void setUserid(const QString &m_userid) { - GenKeyInfo::userid = m_userid; - } - - [[nodiscard]] const QString &getAlgo() const { - return algo; - } - - void setAlgo(const QString &m_algo); - - [[nodiscard]] QString getKeySizeStr() const; - - [[nodiscard]] int getKeySize() const { - return keySize; - - } - - void setKeySize(int m_key_size); - - [[nodiscard]] const QDateTime &getExpired() const { - return expired; - } - - void setExpired(const QDateTime &m_expired); - - [[nodiscard]] bool isNonExpired() const { - return nonExpired; - } - - void setNonExpired(bool m_non_expired); - - [[nodiscard]] bool isNoPassPhrase() const { - return this->noPassPhrase; - } - - void setNonPassPhrase(bool m_non_pass_phrase) { - GenKeyInfo::noPassPhrase = m_non_pass_phrase; - } - - [[nodiscard]] bool isAllowSigning() const { - return allowSigning; - } - - [[nodiscard]] bool isAllowNoPassPhrase() const { - return allowNoPassPhrase; - } - - void setAllowSigning(bool m_allow_signing) { - if(allowChangeSigning) - GenKeyInfo::allowSigning = m_allow_signing; - } - - [[nodiscard]] bool isAllowEncryption() const { - return allowEncryption; - } - - void setAllowEncryption(bool m_allow_encryption); - - [[nodiscard]] bool isAllowCertification() const { - return allowCertification; - } - - void setAllowCertification(bool m_allow_certification); - - [[nodiscard]] bool isAllowAuthentication() const { - return allowAuthentication; - } - - void setAllowAuthentication(bool m_allow_authentication) { - if(allowChangeAuthentication) - GenKeyInfo::allowAuthentication = m_allow_authentication; - } - - [[nodiscard]] const QString &getPassPhrase() const { - return passPhrase; - } - - void setPassPhrase(const QString &m_pass_phrase) { - GenKeyInfo::passPhrase = m_pass_phrase; - } - - [[nodiscard]] bool isAllowChangeSigning() const { - return allowChangeSigning; - } - [[nodiscard]] bool isAllowChangeEncryption() const { - return allowChangeEncryption; - } - - [[nodiscard]] bool isAllowChangeCertification() const { - return allowChangeCertification; - } - - [[nodiscard]] bool isAllowChangeAuthentication() const { - return allowChangeAuthentication; - } - - [[nodiscard]] int getSuggestMaxKeySize() const { - return suggestMaxKeySize; - } - - [[nodiscard]] int getSuggestMinKeySize() const { - return suggestMinKeySize; - } - - [[nodiscard]] int getSizeChangeStep() const { - return suggestSizeAdditionStep; - } - - -private: - bool allowEncryption = true; - bool allowChangeEncryption = true; - - bool allowCertification = true; - bool allowChangeCertification = true; - - bool allowAuthentication = true; - bool allowChangeAuthentication = true; - - bool allowSigning = true; - bool allowChangeSigning = true; - - void reset_options(); - -public: - - explicit GenKeyInfo(bool m_is_sub_key = false) : subKey(m_is_sub_key) { - setAlgo("rsa"); - } - - -}; - -#endif //GPG4USB_GPGGENKEYINFO_H diff --git a/include/gpg/function/BasicOperator.h b/include/gpg/function/BasicOperator.h deleted file mode 100644 index 0e9f03bf..00000000 --- a/include/gpg/function/BasicOperator.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H -#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H - -#include "GpgFrontend.h" -#include "gpg/GpgConstants.h" -#include "gpg/GpgModel.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" - -namespace GpgFrontend { - - class BasicOperator : public SingletonFunctionObject<BasicOperator> { - public: - - gpg_error_t encrypt(std::vector<GpgKey> &keys, BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, - GpgEncrResult &result); - - gpgme_error_t encryptSign(std::vector<GpgKey> &keys, std::vector<GpgKey> &signers, BypeArrayRef in_buffer, - BypeArrayPtr &out_buffer, GpgEncrResult &encr_result, - GpgSignResult &sign_result); - - gpgme_error_t decrypt(BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, GpgDecrResult &result); - - gpgme_error_t - decryptVerify(BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, GpgDecrResult &decrypt_result, - GpgVerifyResult &verify_result); - - gpgme_error_t verify(BypeArrayRef in_buffer, BypeArrayRef sig_buffer, GpgVerifyResult &result) const; - - gpg_error_t - sign(KeyFprArgsList key_fprs, BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, gpgme_sig_mode_t mode, - GpgSignResult &result); - - void setSigners(KeyArgsList keys); - - std::unique_ptr<std::vector<GpgKey>> getSigners(); - - private: - - GpgContext &ctx = GpgContext::getInstance(); - - }; -} - - -#endif //GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H diff --git a/include/gpg/model/GpgKey.h b/include/gpg/model/GpgKey.h deleted file mode 100644 index 03029f69..00000000 --- a/include/gpg/model/GpgKey.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGKEY_H -#define GPGFRONTEND_GPGKEY_H - -#include "GpgUID.h" -#include "GpgSubKey.h" - -namespace GpgFrontend { - - class GpgKey { - public: - - [[nodiscard]] bool good() const { return _key_ref == nullptr; } - - [[nodiscard]] std::string id() const { return _key_ref->subkeys->keyid; } - - [[nodiscard]] std::string name() const { return _key_ref->uids->name; }; - - [[nodiscard]] std::string email() const { return _key_ref->uids->email; } - - [[nodiscard]] std::string comment() const { return _key_ref->uids->comment; } - - [[nodiscard]] std::string fpr() const { return _key_ref->fpr; } - - [[nodiscard]] std::string protocol() const { return gpgme_get_protocol_name(_key_ref->protocol); } - - [[nodiscard]] std::string owner_trust() const { - switch (_key_ref->owner_trust) { - case GPGME_VALIDITY_UNKNOWN: - return "Unknown"; - case GPGME_VALIDITY_UNDEFINED: - return "Undefined"; - case GPGME_VALIDITY_NEVER: - return "Never"; - case GPGME_VALIDITY_MARGINAL: - return "Marginal"; - case GPGME_VALIDITY_FULL: - return "FULL"; - case GPGME_VALIDITY_ULTIMATE: - return "Ultimate"; - } - } - - [[nodiscard]] std::string pubkey_algo() const { return gpgme_pubkey_algo_name(_key_ref->subkeys->pubkey_algo); } - - [[nodiscard]] QDateTime last_update() const { return QDateTime::fromTime_t(_key_ref->last_update); } - - [[nodiscard]] QDateTime expires() const { return QDateTime::fromTime_t(_key_ref->subkeys->expires); }; - - [[nodiscard]] QDateTime create_time() const { return QDateTime::fromTime_t(_key_ref->subkeys->timestamp); }; - - [[nodiscard]] unsigned int length() const { return _key_ref->subkeys->length; } - - - [[nodiscard]] bool can_encrypt() const { return _key_ref->can_encrypt; } - - [[nodiscard]] bool can_sign() const { return _key_ref->can_sign; } - - [[nodiscard]] bool canSignActual() const; - - [[nodiscard]] bool can_certify() const { return _key_ref->can_certify; } - - [[nodiscard]] bool can_authenticate() const { return _key_ref->can_authenticate; } - - bool canAuthActual() { - auto subkeys = subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool { - return subkey.secret() && subkey.can_authenticate() && !subkey.disabled() && !subkey.revoked() && !subkey.expired(); - })) - return true; - else return false; - } - - - [[nodiscard]] bool is_private_key() const { return _key_ref->secret; } - - [[nodiscard]] bool expired() const { return _key_ref->expired; } - - [[nodiscard]] bool revoked() const { return _key_ref->revoked; } - - [[nodiscard]] bool disabled() const { return _key_ref->disabled; } - - [[nodiscard]] bool has_master_key() const { return _key_ref->subkeys->secret; } - - [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> subKeys() const; - - [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> uids() const; - - explicit GpgKey() = default; - - explicit GpgKey(gpgme_key_t &&key); - - GpgKey(const gpgme_key_t &key) = delete; - - GpgKey(GpgKey &&k) noexcept; - - GpgKey &operator=(GpgKey &&k) noexcept; - - GpgKey &operator=(const gpgme_key_t &key) = delete; - - explicit operator gpgme_key_t() const { return _key_ref.get(); } - - private: - - using KeyRefHandler = std::unique_ptr<struct _gpgme_key, std::function<void(gpgme_key_t)>>; - - KeyRefHandler _key_ref; - }; - -} - - -#endif //GPGFRONTEND_GPGKEY_H diff --git a/include/gpg/model/GpgKeySignature.h b/include/gpg/model/GpgKeySignature.h deleted file mode 100644 index c35a7161..00000000 --- a/include/gpg/model/GpgKeySignature.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H -#define GPGFRONTEND_GPGKEYSIGNATURE_H - -#include "GpgFrontend.h" - -namespace GpgFrontend { - - class GpgKeySignature { - public: - - [[nodiscard]] bool revoked() const { return _signature_ref->revoked; } - [[nodiscard]] bool expired() const { return _signature_ref->expired; } - [[nodiscard]] bool invalid() const { return _signature_ref->invalid; } - [[nodiscard]] bool exportable() const { return _signature_ref->exportable; } - - [[nodiscard]] gpgme_error_t status() const { return _signature_ref->status; } - - [[nodiscard]] std::string keyid() const { return _signature_ref->keyid; } - [[nodiscard]] std::string pubkey_algo() const { return gpgme_pubkey_algo_name(_signature_ref->pubkey_algo); } - - [[nodiscard]] QDateTime create_time() const { return QDateTime::fromTime_t(_signature_ref->timestamp); } - [[nodiscard]] QDateTime expire_time() const { return QDateTime::fromTime_t(_signature_ref->expires); } - - [[nodiscard]] std::string uid() const { return _signature_ref->uid; } - [[nodiscard]] std::string name() const { return _signature_ref->name; } - [[nodiscard]] std::string email() const { return _signature_ref->email; } - [[nodiscard]] std::string comment() const { return _signature_ref->comment; } - - GpgKeySignature() = default; - - explicit GpgKeySignature(gpgme_key_sig_t sig); - - GpgKeySignature(GpgKeySignature &&) noexcept = default; - - GpgKeySignature(const GpgKeySignature &) = delete; - - GpgKeySignature &operator=(GpgKeySignature &&) noexcept = default; - - GpgKeySignature &operator=(const GpgKeySignature &) = delete; - - private: - - using KeySignatrueRefHandler = std::unique_ptr<struct _gpgme_key_sig, std::function<void(gpgme_key_sig_t)>>; - - KeySignatrueRefHandler _signature_ref = nullptr; - }; - -} - - -#endif //GPGFRONTEND_GPGKEYSIGNATURE_H diff --git a/include/gpg/model/GpgSubKey.h b/include/gpg/model/GpgSubKey.h deleted file mode 100644 index 7142a11f..00000000 --- a/include/gpg/model/GpgSubKey.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ -#ifndef GPGFRONTEND_GPGSUBKEY_H -#define GPGFRONTEND_GPGSUBKEY_H - -#include "GpgFrontend.h" - -namespace GpgFrontend { - - class GpgSubKey { - public: - - [[nodiscard]] QString id() const { return _subkey_ref->keyid; } - - [[nodiscard]] QString fpr() const { return _subkey_ref->fpr; } - - [[nodiscard]] QString pubkey_algo() const { return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo); } - - [[nodiscard]] unsigned int length() const { return _subkey_ref->length; } - - - [[nodiscard]] bool can_encrypt() const { return _subkey_ref->can_encrypt; } - - [[nodiscard]] bool can_sign() const { return _subkey_ref->can_sign; } - - [[nodiscard]] bool can_certify() const { return _subkey_ref->can_certify; } - - [[nodiscard]] bool can_authenticate() const { return _subkey_ref->can_authenticate; } - - - [[nodiscard]] bool is_private_key() const { return _subkey_ref->secret; } - - [[nodiscard]] bool expired() const { return _subkey_ref->expired; } - - [[nodiscard]] bool revoked() const { return _subkey_ref->revoked; } - - [[nodiscard]] bool disabled() const { return _subkey_ref->disabled; } - - [[nodiscard]] bool secret() const { return _subkey_ref->secret; } - - [[nodiscard]] bool is_cardkey() const { return _subkey_ref->is_cardkey; } - - [[nodiscard]] QDateTime timestamp() const { return QDateTime::fromTime_t(_subkey_ref->timestamp); } - - [[nodiscard]] QDateTime expires() const { return QDateTime::fromTime_t(_subkey_ref->expires); } - - GpgSubKey() = default; - - explicit GpgSubKey(gpgme_subkey_t subkey); - - GpgSubKey(GpgSubKey &&o) noexcept { swap(_subkey_ref, o._subkey_ref); } - - GpgSubKey(const GpgSubKey &) = delete; - - GpgSubKey &operator=(GpgSubKey &&o) noexcept { - swap(_subkey_ref, o._subkey_ref); - return *this; - }; - - GpgSubKey &operator=(const GpgSubKey &) = delete; - - private: - - using SubkeyRefHandler = std::unique_ptr<struct _gpgme_subkey, std::function<void(gpgme_subkey_t)>>; - - SubkeyRefHandler _subkey_ref = nullptr; - - }; - -} - - -#endif //GPGFRONTEND_GPGSUBKEY_H diff --git a/include/gpg/model/GpgUID.h b/include/gpg/model/GpgUID.h deleted file mode 100644 index 78fe3b05..00000000 --- a/include/gpg/model/GpgUID.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGUID_H -#define GPGFRONTEND_GPGUID_H - -#include <utility> - -#include "GpgFrontend.h" -#include "GpgKeySignature.h" - -namespace GpgFrontend { - - class GpgUID { - public: - - [[nodiscard]] QString name() const { return _uid_ref->name; } - - [[nodiscard]] QString email() const { return _uid_ref->email; } - - [[nodiscard]] QString comment() const { return _uid_ref->comment; } - - [[nodiscard]] QString uid() const { return _uid_ref->uid; } - - [[nodiscard]] QString hash() const { return _uid_ref->uidhash; } - - [[nodiscard]] bool revoked() const { return _uid_ref->revoked; } - - [[nodiscard]] bool invalid() const { return _uid_ref->invalid; } - - [[nodiscard]] std::unique_ptr<QVector<GpgKeySignature>> signatures() const { - auto sigs = std::make_unique<QVector<GpgKeySignature>>(); - auto sig_next = _uid_ref->signatures; - while (sig_next != nullptr) { - sigs->push_back(GpgKeySignature(sig_next)); - sig_next = sig_next->next; - } - return sigs; - } - - GpgUID() = default; - - explicit GpgUID(gpgme_user_id_t uid); - - GpgUID(GpgUID &&o) noexcept {swap(_uid_ref, o._uid_ref);} - - GpgUID(const GpgUID &) = delete; - - GpgUID& operator=(GpgUID &&o) noexcept { - swap(_uid_ref, o._uid_ref); - return *this; - } - - GpgUID& operator=(const GpgUID &) = delete; - - private: - - using UidRefHandler = std::unique_ptr<struct _gpgme_user_id, std::function<void(gpgme_user_id_t)>>; - - UidRefHandler _uid_ref = nullptr; - - }; - -} - -#endif //GPGFRONTEND_GPGUID_H
\ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 555e5b39..44eb370c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,8 +75,8 @@ endif() if(BASIC_ENV_CONFIG) # Set Build Information - configure_file(${CMAKE_SOURCE_DIR}/include/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/include/GpgFrontend.h @ONLY) - configure_file(${CMAKE_SOURCE_DIR}/include/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/include/GpgFrontendBuildInfo.h @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h @ONLY) endif() if(APPLICATION_BUILD) diff --git a/src/GpgFrontend.h b/src/GpgFrontend.h new file mode 100644 index 00000000..7115b493 --- /dev/null +++ b/src/GpgFrontend.h @@ -0,0 +1,54 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_H_IN +#define GPGFRONTEND_H_IN + +/** + * Platform Vars + */ +#define WINDOWS 0 +#define MACOS 1 +#define LINUX 2 + +#define OS_PLATFORM 2 + +/** + * Build Options Vars + */ +#define RELEASE 0 +#define DEBUG 1 + +/** + * Resources File(s) Path Vars + */ +#if OS_PLATFORM == MACOS && BUILD_FLAG == RELEASE +#define RESOURCE_DIR(appDir) (appDir + "/../Resources/") +#elif OS_PLATFORM == LINUX && BUILD_FLAG == RELEASE +#define RESOURCE_DIR(appDir) (appDir + "/../share/") +#else +#define RESOURCE_DIR(appDir) (appDir) +#endif + +#endif // GPGFRONTEND_H_IN diff --git a/include/GpgFrontend.h.in b/src/GpgFrontend.h.in index 78d3e44f..814e037f 100644 --- a/include/GpgFrontend.h.in +++ b/src/GpgFrontend.h.in @@ -26,32 +26,6 @@ #define GPGFRONTEND_H_IN /** - * STD Headers - */ -#include <iostream> -#include <string> -#include <cmath> -#include <clocale> -#include <cerrno> -#include <utility> -#include <list> -#include <span> -#include <mutex> - -/** - * QT Headers - */ -#include <QtCore> -#include <QtWidgets> -#include <QtNetwork/QtNetwork> -#include <QtPrintSupport/QtPrintSupport> - -/** - * GpgME Headers - */ -#include <gpgme.h> - -/** * Platform Vars */ #define WINDOWS 0 @@ -70,12 +44,11 @@ * Resources File(s) Path Vars */ #if OS_PLATFORM == MACOS && BUILD_FLAG == RELEASE -# define RESOURCE_DIR(appDir) (appDir + "/../Resources/") +#define RESOURCE_DIR(appDir) (appDir + "/../Resources/") #elif OS_PLATFORM == LINUX && BUILD_FLAG == RELEASE -# define RESOURCE_DIR(appDir) (appDir + "/../share/") +#define RESOURCE_DIR(appDir) (appDir + "/../share/") #else -# define RESOURCE_DIR(appDir) (appDir) +#define RESOURCE_DIR(appDir) (appDir) #endif - -#endif //GPGFRONTEND_H_IN +#endif // GPGFRONTEND_H_IN diff --git a/src/GpgFrontendBuildInfo.h b/src/GpgFrontendBuildInfo.h new file mode 100644 index 00000000..afc1b2c9 --- /dev/null +++ b/src/GpgFrontendBuildInfo.h @@ -0,0 +1,54 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_BUILD_INFO_H_IN +#define GPGFRONTEND_BUILD_INFO_H_IN + +/** + * Logic Version (*.*.*) + */ +#define VERSION_MAJOR 1 +#define VERSION_MINOR 3 +#define VERSION_PATCH 1 + +/** + * Code Version (According to Git) + */ +#define GIT_BRANCH_NAME "develop-core" +#define GIT_COMMIT_HASH "7b7dd67b99a758924e531a63efd25894a32a3298" + +/** + * Generated Information (According to CMake) + */ +#define PROJECT_NAME "GpgFrontend" +#define BUILD_VERSION "1.3.1_Linux-5.4.0-81-generic_x86_64_Debug" +#define GIT_VERSION "develop-core_7b7dd67b99a758924e531a63efd25894a32a3298" + +/** + * Build Information + */ +#define BUILD_FLAG 1 +#define BUILD_TIMESTAMP "2021-09-05 14:39:04" + +#endif // GPGFRONTEND_BUILD_INFO_H_IN diff --git a/include/GpgFrontendBuildInfo.h.in b/src/GpgFrontendBuildInfo.h.in index bf1d3f8a..bf1d3f8a 100644 --- a/include/GpgFrontendBuildInfo.h.in +++ b/src/GpgFrontendBuildInfo.h.in diff --git a/include/MainWindow.h b/src/MainWindow.h index 34a3130a..34a3130a 100644 --- a/include/MainWindow.h +++ b/src/MainWindow.h diff --git a/src/gpg/CMakeLists.txt b/src/gpg/CMakeLists.txt index 2eabceaf..6b767814 100644 --- a/src/gpg/CMakeLists.txt +++ b/src/gpg/CMakeLists.txt @@ -1,6 +1,7 @@ aux_source_directory(./result_analyse GPG_SOURCE) aux_source_directory(./gpg_context GPG_SOURCE) aux_source_directory(./function GPG_SOURCE) +aux_source_directory(./model GPG_SOURCE) aux_source_directory(. GPG_SOURCE) add_library(gpg_core STATIC ${GPG_SOURCE}) @@ -12,17 +13,13 @@ set(GPGME_LIB_DIR ${UTILS_DIR}/gpgme/lib) if (MINGW) message(STATUS "Link GPG Static Library For MINGW") target_link_libraries(gpg_core - gpgme gpg-error assuan - Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core - wsock32) + gpgme gpg-error assuan Qt5::Core wsock32) elseif(APPLE) message(STATUS "Link GPG Static Library For macOS") target_link_libraries(gpg_core - /usr/local/lib/libgpgme.a /usr/local/lib/libgpg-error.a /usr/local/lib/libassuan.a - Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core) + libgpgme.a libgpg-error.a libassuan.a Qt5::Core) else() message(STATUS "Link GPG Static Library For Unix") target_link_libraries(gpg_core - /usr/local/lib/libgpgme.a /usr/local/lib/libgpg-error.a /usr/local/lib/libassuan.a - Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core) + libgpgme.a libgpg-error.a libassuan.a Qt5::Core pthread) endif() diff --git a/src/gpg/GpgConstants.cpp b/src/gpg/GpgConstants.cpp index 1d59dab5..bf189342 100644 --- a/src/gpg/GpgConstants.cpp +++ b/src/gpg/GpgConstants.cpp @@ -24,11 +24,66 @@ #include "gpg/GpgConstants.h" -const char *GpgConstants::PGP_CRYPT_BEGIN = "-----BEGIN PGP MESSAGE-----"; -const char *GpgConstants::PGP_CRYPT_END = "-----END PGP MESSAGE-----"; -const char *GpgConstants::PGP_SIGNED_BEGIN = "-----BEGIN PGP SIGNED MESSAGE-----"; -const char *GpgConstants::PGP_SIGNED_END = "-----END PGP SIGNATURE-----"; -const char *GpgConstants::PGP_SIGNATURE_BEGIN = "-----BEGIN PGP SIGNATURE-----"; -const char *GpgConstants::PGP_SIGNATURE_END = "-----END PGP SIGNATURE-----"; -const char *GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD = "GpgF_Scpt://"; +const char *GpgFrontend::GpgConstants::PGP_CRYPT_BEGIN = + "-----BEGIN PGP MESSAGE-----"; +const char *GpgFrontend::GpgConstants::PGP_CRYPT_END = + "-----END PGP MESSAGE-----"; +const char *GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN = + "-----BEGIN PGP SIGNED MESSAGE-----"; +const char *GpgFrontend::GpgConstants::PGP_SIGNED_END = + "-----END PGP SIGNATURE-----"; +const char *GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN = + "-----BEGIN PGP SIGNATURE-----"; +const char *GpgFrontend::GpgConstants::PGP_SIGNATURE_END = + "-----END PGP SIGNATURE-----"; +const char *GpgFrontend::GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD = + "GpgF_Scpt://"; +gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err) { + // if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) { + if (gpg_err_code(err) != GPG_ERR_NO_ERROR) { + qDebug() << "[Error " << gpg_err_code(err) + << "] Source: " << gpgme_strsource(err) + << " Description: " << gpgme_strerror(err); + } + return err; +} + +// error-handling +gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err, + const std::string &comment) { + // if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) { + if (gpg_err_code(err) != GPG_ERR_NO_ERROR) { + qDebug() << "[Error " << gpg_err_code(err) + << "] Source: " << gpgme_strsource(err) + << " Description: " << gpgme_strerror(err) << " " + << comment.c_str(); + } + return err; +} + +std::string GpgFrontend::beautify_fingerprint(std::string fingerprint) { + uint len = fingerprint.size(); + if ((len > 0) && (len % 4 == 0)) + for (uint n = 0; 4 * (n + 1) < len; ++n) + fingerprint.insert(static_cast<int>(5u * n + 4u), " "); + return fingerprint; +} + +/* + * isSigned returns: + * - 0, if text isn't signed at all + * - 1, if text is partially signed + * - 2, if text is completly signed + */ +int GpgFrontend::text_is_signed(const QByteArray &text) { + if (text.trimmed().startsWith(GpgConstants::PGP_SIGNED_BEGIN) && + text.trimmed().endsWith(GpgConstants::PGP_SIGNED_END)) + return 2; + else if (text.contains(GpgConstants::PGP_SIGNED_BEGIN) && + text.contains(GpgConstants::PGP_SIGNED_END)) + return 1; + + else + return 0; +} diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h new file mode 100644 index 00000000..c3ef9041 --- /dev/null +++ b/src/gpg/GpgConstants.h @@ -0,0 +1,82 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPG_CONSTANTS_H +#define GPG_CONSTANTS_H + +#include "GpgFrontend.h" + +#include <QtCore> +#include <functional> + +#include <gpgme.h> +#include <memory> +#include <string> + +const int RESTART_CODE = 1000; + +namespace GpgFrontend { + +using BypeArrayPtr = std::unique_ptr<QByteArray>; +using StdBypeArrayPtr = std::unique_ptr<std::string>; +using BypeArrayRef = QByteArray &; + +using GpgError = gpgme_error_t; + +using GpgEncrResult = + std::unique_ptr<struct _gpgme_op_encrypt_result, + std::function<void(gpgme_encrypt_result_t)>>; +using GpgDecrResult = + std::unique_ptr<struct _gpgme_op_decrypt_result, + std::function<void(gpgme_decrypt_result_t)>>; +using GpgSignResult = std::unique_ptr<struct _gpgme_op_sign_result, + std::function<void(gpgme_sign_result_t)>>; +using GpgVerifyResult = + std::unique_ptr<struct _gpgme_op_verify_result, + std::function<void(gpgme_verify_result_t)>>; + +// Error Info Printer +GpgError check_gpg_error(GpgError err); + +GpgError check_gpg_error(GpgError gpgmeError, const std::string &comment); + +// Fingerprint +std::string beautify_fingerprint(std::string fingerprint); + +// Check +int text_is_signed(const QByteArray &text); + +class GpgConstants { +public: + static const char *PGP_CRYPT_BEGIN; + static const char *PGP_CRYPT_END; + static const char *PGP_SIGNED_BEGIN; + static const char *PGP_SIGNED_END; + static const char *PGP_SIGNATURE_BEGIN; + static const char *PGP_SIGNATURE_END; + static const char *GPG_FRONTEND_SHORT_CRYPTO_HEAD; +}; +} // namespace GpgFrontend + +#endif // GPG_CONSTANTS_H diff --git a/src/gpg/GpgContext.h b/src/gpg/GpgContext.h new file mode 100644 index 00000000..fc0b80e0 --- /dev/null +++ b/src/gpg/GpgContext.h @@ -0,0 +1,84 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __SGPGMEPP_CONTEXT_H__ +#define __SGPGMEPP_CONTEXT_H__ + +#include "GpgFunctionObject.h" +#include "GpgInfo.h" +#include "GpgModel.h" + +namespace GpgFrontend { + +/** + * Custom Encapsulation of GpgME APIs + */ +class GpgContext : public SingletonFunctionObject<GpgContext> { + +public: + GpgContext(); + + ~GpgContext() override = default; + + [[nodiscard]] bool good() const; + + bool exportKeys(const QVector<GpgKey> &keys, QByteArray &outBuffer); + + const GpgInfo &GetInfo() const { return info; } + + void clearPasswordCache(); + + /** + * @details If text contains PGP-message, put a linebreak before the message, + * so that gpgme can decrypt correctly + * + * @param in Pointer to the QBytearray to check. + */ + static void preventNoDataErr(QByteArray *in); + + static std::string getGpgmeVersion(); + + operator gpgme_ctx_t() const { return _ctx_ref.get(); } + +private: + GpgInfo info; + + using CtxRefHandler = + std::unique_ptr<struct gpgme_context, std::function<void(gpgme_ctx_t)>>; + CtxRefHandler _ctx_ref = nullptr; + + bool good_ = true; + + QByteArray mPasswordCache; + + static gpgme_error_t passphraseCb(void *hook, const char *uid_hint, + const char *passphrase_info, + int last_was_bad, int fd); + + gpgme_error_t passphrase(const char *uid_hint, const char *passphrase_info, + int last_was_bad, int fd); +}; +} // namespace GpgFrontend + +#endif // __SGPGMEPP_CONTEXT_H__ diff --git a/src/gpg/GpgFileOpera.cpp b/src/gpg/GpgFileOpera.cpp deleted file mode 100644 index 727bfb6f..00000000 --- a/src/gpg/GpgFileOpera.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ -#include "gpg/GpgFileOpera.h" - -gpgme_error_t GpgFileOpera::encryptFile(GpgFrontend::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, - gpgme_encrypt_result_t *result) { - - QFileInfo fileInfo(mPath); - - if (!fileInfo.isFile() || !fileInfo.isReadable()) - throw std::runtime_error("no permission"); - - QFile infile; - infile.setFileName(mPath); - if (!infile.open(QIODevice::ReadOnly)) - throw std::runtime_error("cannot open file"); - - QByteArray inBuffer = infile.readAll(); - auto outBuffer = QByteArray(); - infile.close(); - - auto error = ctx->encrypt(keys, inBuffer, &outBuffer, result); - - if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error; - - QFile outfile(mPath + ".asc"); - - if (!outfile.open(QFile::WriteOnly)) - throw std::runtime_error("cannot open file"); - - QDataStream out(&outfile); - out.writeRawData(outBuffer.data(), outBuffer.length()); - outfile.close(); - return error; -} - -gpgme_error_t GpgFileOpera::decryptFile(GpgFrontend::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *result) { - - QFileInfo fileInfo(mPath); - - if (!fileInfo.isFile() || !fileInfo.isReadable()) - throw std::runtime_error("no permission"); - - QFile infile; - infile.setFileName(mPath); - if (!infile.open(QIODevice::ReadOnly)) - throw std::runtime_error("cannot open file"); - - QByteArray inBuffer = infile.readAll(); - auto outBuffer = QByteArray(); - infile.close(); - - auto error = ctx->decrypt(inBuffer, &outBuffer, result); - - if (gpgme_err_code(error) != GPG_ERR_NO_ERROR) return error; - - QString outFileName, fileExtension = fileInfo.suffix(); - - if (fileExtension == "asc" || fileExtension == "gpg") { - int pos = mPath.lastIndexOf(QChar('.')); - outFileName = mPath.left(pos); - } else { - outFileName = mPath + ".out"; - } - - QFile outfile(outFileName); - - if (!outfile.open(QFile::WriteOnly)) - throw std::runtime_error("cannot open file"); - - QDataStream out(&outfile); - out.writeRawData(outBuffer.data(), outBuffer.length()); - outfile.close(); - - return error; -} - -gpgme_error_t GpgFileOpera::signFile(GpgFrontend::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, - gpgme_sign_result_t *result) { - - QFileInfo fileInfo(mPath); - - if (!fileInfo.isFile() || !fileInfo.isReadable()) - throw std::runtime_error("no permission"); - - QFile infile; - infile.setFileName(mPath); - if (!infile.open(QIODevice::ReadOnly)) - throw std::runtime_error("cannot open file"); - - - QByteArray inBuffer = infile.readAll(); - auto outBuffer = QByteArray(); - infile.close(); - - auto error = ctx->sign(keys, inBuffer, &outBuffer, GPGME_SIG_MODE_DETACH, result); - - if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error; - - QFile outfile(mPath + ".sig"); - - if (!outfile.open(QFile::WriteOnly)) - throw std::runtime_error("cannot open file"); - - QDataStream out(&outfile); - out.writeRawData(outBuffer.data(), outBuffer.length()); - outfile.close(); - - return error; -} - -gpgme_error_t GpgFileOpera::verifyFile(GpgFrontend::GpgContext *ctx, const QString &mPath, gpgme_verify_result_t *result) { - - qDebug() << "Verify File Path" << mPath; - - QFileInfo fileInfo(mPath); - - if (!fileInfo.isFile() || !fileInfo.isReadable()) - throw std::runtime_error("no permission"); - - QFile infile; - infile.setFileName(mPath); - if (!infile.open(QIODevice::ReadOnly)) - throw std::runtime_error("cannot open file"); - - QByteArray inBuffer = infile.readAll(); - - if(fileInfo.suffix() == "gpg") { - auto error = ctx->verify(&inBuffer, nullptr, result); - return error; - } - else { - QFile signFile; - signFile.setFileName(mPath + ".sig"); - if (!signFile.open(QIODevice::ReadOnly)) { - throw std::runtime_error("cannot open file"); - } - - auto signBuffer = signFile.readAll(); - infile.close(); - - auto error = ctx->verify(&inBuffer, &signBuffer, result); - return error; - } -} - -gpg_error_t GpgFileOpera::encryptSignFile(GpgFrontend::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, - gpgme_encrypt_result_t *encr_res, - gpgme_sign_result_t *sign_res) { - - qDebug() << "Encrypt Sign File Path" << mPath; - - QFileInfo fileInfo(mPath); - - if (!fileInfo.isFile() || !fileInfo.isReadable()) - throw std::runtime_error("no permission"); - - QFile infile; - infile.setFileName(mPath); - if (!infile.open(QIODevice::ReadOnly)) - throw std::runtime_error("cannot open file"); - - QByteArray inBuffer = infile.readAll(); - auto outBuffer = QByteArray(); - infile.close(); - - QVector<GpgKey> signerKeys; - - // TODO dealing with signer keys - auto error = ctx->encryptSign(keys, signerKeys, inBuffer, &outBuffer, encr_res, sign_res); - - if (gpg_err_code(error) != GPG_ERR_NO_ERROR) - return error; - - QFile outfile(mPath + ".gpg"); - - if (!outfile.open(QFile::WriteOnly)) - throw std::runtime_error("cannot open file"); - - QDataStream out(&outfile); - out.writeRawData(outBuffer.data(), outBuffer.length()); - outfile.close(); - - return error; -} - -gpg_error_t GpgFileOpera::decryptVerifyFile(GpgFrontend::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *decr_res, - gpgme_verify_result_t *verify_res) { - - qDebug() << "Decrypt Verify File Path" << mPath; - - QFileInfo fileInfo(mPath); - - if (!fileInfo.isFile() || !fileInfo.isReadable()) - throw std::runtime_error("no permission"); - - QFile infile; - infile.setFileName(mPath); - if (!infile.open(QIODevice::ReadOnly)) - throw std::runtime_error("cannot open file"); - - QByteArray inBuffer = infile.readAll(); - auto outBuffer = QByteArray(); - infile.close(); - - auto error = ctx->decryptVerify(inBuffer, &outBuffer, decr_res, verify_res); - if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error; - - QString outFileName, fileExtension = fileInfo.suffix(); - - if (fileExtension == "asc" || fileExtension == "gpg") { - int pos = mPath.lastIndexOf(QChar('.')); - outFileName = mPath.left(pos); - } else { - outFileName = mPath + ".out"; - } - - QFile outfile(outFileName); - - if (!outfile.open(QFile::WriteOnly)) - throw std::runtime_error("cannot open file"); - - QDataStream out(&outfile); - out.writeRawData(outBuffer.data(), outBuffer.length()); - outfile.close(); - - return error; -} diff --git a/include/gpg/GpgFunctionObject.h b/src/gpg/GpgFunctionObject.h index 22280706..0f772c92 100644 --- a/include/gpg/GpgFunctionObject.h +++ b/src/gpg/GpgFunctionObject.h @@ -25,46 +25,40 @@ #ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H #define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H -#include "GpgFrontend.h" +#include <memory> +#include <mutex> namespace GpgFrontend { - template<typename T> - class SingletonFunctionObject { - public: +template <typename T> class SingletonFunctionObject { +public: + static T &GetInstance() { + std::lock_guard<std::mutex> guard(_instance_mutex); + if (_instance == nullptr) + _instance = std::make_unique<T>(); + return *_instance; + } - static T &getInstance() { - std::lock_guard<std::mutex> guard(_instance_mutex); - if(_instance == nullptr) _instance = std::make_unique<T>(); - return *_instance; - } + SingletonFunctionObject(T &&) = delete; - SingletonFunctionObject(T&&) = delete; + SingletonFunctionObject(const T &) = delete; - SingletonFunctionObject(const T&) = delete; + void operator=(const T &) = delete; - void operator= (const T&) = delete; +protected: + SingletonFunctionObject() = default; - protected: + virtual ~SingletonFunctionObject() = default; - SingletonFunctionObject() = default; +private: + static std::mutex _instance_mutex; + static std::unique_ptr<T> _instance; +}; - virtual ~SingletonFunctionObject() = default; +template <typename T> std::mutex SingletonFunctionObject<T>::_instance_mutex; - private: +template <typename T> +std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr; - static std::mutex _instance_mutex; - static std::unique_ptr<T> _instance; - }; +} // namespace GpgFrontend - template<typename T> - std::mutex SingletonFunctionObject<T>::_instance_mutex; - - template<typename T> - std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr; - -} - - - - -#endif //GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H +#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H diff --git a/src/gpg/GpgGenKeyInfo.cpp b/src/gpg/GpgGenKeyInfo.cpp index 69da27e3..f4dc777a 100644 --- a/src/gpg/GpgGenKeyInfo.cpp +++ b/src/gpg/GpgGenKeyInfo.cpp @@ -23,150 +23,145 @@ */ #include "gpg/GpgGenKeyInfo.h" - -const QVector<QString> GenKeyInfo::SupportedKeyAlgo = { - "RSA", - "DSA", - "ED25519" -}; - -const QVector<QString> GenKeyInfo::SupportedSubkeyAlgo = { - "RSA", - "DSA", - "ED25519", - "ELG" -}; - -void GenKeyInfo::setAlgo(const QString &m_algo) { - - qDebug() << "set algo " << m_algo; - - reset_options(); - - if (!this->subKey) { - this->setAllowCertification(true); - } else { - this->setAllowCertification(false); - } - - this->allowChangeCertification = false; - - auto lower_algo = m_algo.toLower(); - - if(lower_algo == "rsa") { - /** - * RSA is the world’s premier asymmetric cryptographic algorithm, - * and is built on the difficulty of factoring extremely large composites. - * GnuPG supports RSA with key sizes of between 1024 and 4096 bits. - */ - suggestMinKeySize = 1024; - suggestMaxKeySize = 4096; - suggestSizeAdditionStep = 1024; - setKeySize(2048); - - } else if (lower_algo == "dsa") { - /** - * Algorithm (DSA) as a government standard for digital signatures. - * Originally, it supported key lengths between 512 and 1024 bits. - * Recently, NIST has declared 512-bit keys obsolete: - * now, DSA is available in 1024, 2048 and 3072-bit lengths. - */ - setAllowEncryption(false); - allowChangeEncryption = false; - - suggestMinKeySize = 1024; - suggestMaxKeySize = 3072; - suggestSizeAdditionStep = 1024; - setKeySize(2048); - - } else if (lower_algo == "ed25519") { - /** - * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths ranging from 1024 to 4096 bits. - */ - - setAllowEncryption(false); - allowChangeEncryption = false; - - suggestMinKeySize = -1; - suggestMaxKeySize = -1; - suggestSizeAdditionStep = -1; - setKeySize(-1); - } else if (lower_algo == "elg") { - /** - * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths ranging from 1024 to 4096 bits. - */ - - setAllowAuthentication(false); - allowChangeAuthentication = false; - - setAllowSigning(false); - allowChangeSigning = false; - - suggestMinKeySize = 1024; - suggestMaxKeySize = 4096; - suggestSizeAdditionStep = 1024; - setKeySize(2048); - } - GenKeyInfo::algo = lower_algo; +#include <string> +#include <vector> + +const std::vector<std::string> GpgFrontend::GenKeyInfo::SupportedKeyAlgo = { + "RSA", "DSA", "ED25519"}; + +const std::vector<std::string> GpgFrontend::GenKeyInfo::SupportedSubkeyAlgo = { + "RSA", "DSA", "ED25519", "ELG"}; + +void GpgFrontend::GenKeyInfo::setAlgo(const std::string &m_algo) { + + qDebug() << "set algo " << m_algo.c_str(); + + reset_options(); + + if (!this->subKey) { + this->setAllowCertification(true); + } else { + this->setAllowCertification(false); + } + + this->allowChangeCertification = false; + + std::string lower_algo; + std::transform(m_algo.begin(), m_algo.end(), lower_algo.begin(), + [](unsigned char c) { return std::tolower(c); }); + + if (lower_algo == "rsa") { + /** + * RSA is the world’s premier asymmetric cryptographic algorithm, + * and is built on the difficulty of factoring extremely large composites. + * GnuPG supports RSA with key sizes of between 1024 and 4096 bits. + */ + suggestMinKeySize = 1024; + suggestMaxKeySize = 4096; + suggestSizeAdditionStep = 1024; + setKeySize(2048); + + } else if (lower_algo == "dsa") { + /** + * Algorithm (DSA) as a government standard for digital signatures. + * Originally, it supported key lengths between 512 and 1024 bits. + * Recently, NIST has declared 512-bit keys obsolete: + * now, DSA is available in 1024, 2048 and 3072-bit lengths. + */ + setAllowEncryption(false); + allowChangeEncryption = false; + + suggestMinKeySize = 1024; + suggestMaxKeySize = 3072; + suggestSizeAdditionStep = 1024; + setKeySize(2048); + + } else if (lower_algo == "ed25519") { + /** + * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths + * ranging from 1024 to 4096 bits. + */ + + setAllowEncryption(false); + allowChangeEncryption = false; + + suggestMinKeySize = -1; + suggestMaxKeySize = -1; + suggestSizeAdditionStep = -1; + setKeySize(-1); + } else if (lower_algo == "elg") { + /** + * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths + * ranging from 1024 to 4096 bits. + */ + + setAllowAuthentication(false); + allowChangeAuthentication = false; + + setAllowSigning(false); + allowChangeSigning = false; + + suggestMinKeySize = 1024; + suggestMaxKeySize = 4096; + suggestSizeAdditionStep = 1024; + setKeySize(2048); + } + GenKeyInfo::algo = lower_algo; } -void GenKeyInfo::reset_options() { - - allowChangeEncryption = true; - setAllowEncryption(true); - - allowChangeCertification = true; - setAllowCertification(true); +void GpgFrontend::GenKeyInfo::reset_options() { - allowChangeSigning = true; - setAllowSigning(true); + allowChangeEncryption = true; + setAllowEncryption(true); - allowChangeAuthentication = true; - setAllowAuthentication(true); + allowChangeCertification = true; + setAllowCertification(true); + allowChangeSigning = true; + setAllowSigning(true); - passPhrase.clear(); + allowChangeAuthentication = true; + setAllowAuthentication(true); + passPhrase.clear(); } -QString GenKeyInfo::getKeySizeStr() const { - if(keySize > 0) { - return QString::number(keySize); - } - else { - return QString(); - } - +std::string GpgFrontend::GenKeyInfo::getKeySizeStr() const { + if (keySize > 0) { + return std::to_string(keySize); + } else { + return {}; + } } -void GenKeyInfo::setKeySize(int m_key_size) { - if (m_key_size < suggestMinKeySize || m_key_size > suggestMaxKeySize) { - return; - } - GenKeyInfo::keySize = m_key_size; +void GpgFrontend::GenKeyInfo::setKeySize(int m_key_size) { + if (m_key_size < suggestMinKeySize || m_key_size > suggestMaxKeySize) { + return; + } + GenKeyInfo::keySize = m_key_size; } -void GenKeyInfo::setExpired(const QDateTime &m_expired) { - auto current = QDateTime::currentDateTime(); - if (isNonExpired() && m_expired < current.addYears(2)) { - GenKeyInfo::expired = m_expired; - } +void GpgFrontend::GenKeyInfo::setExpired(const QDateTime &m_expired) { + auto current = QDateTime::currentDateTime(); + if (isNonExpired() && m_expired < current.addYears(2)) { + GenKeyInfo::expired = m_expired; + } } -void GenKeyInfo::setNonExpired(bool m_non_expired) { - if (!m_non_expired) { - this->expired = QDateTime(QDateTime::fromTime_t(0)); - } - GenKeyInfo::nonExpired = m_non_expired; +void GpgFrontend::GenKeyInfo::setNonExpired(bool m_non_expired) { + if (!m_non_expired) { + this->expired = QDateTime(QDateTime::fromTime_t(0)); + } + GenKeyInfo::nonExpired = m_non_expired; } -void GenKeyInfo::setAllowEncryption(bool m_allow_encryption) { - if(allowChangeEncryption) - GenKeyInfo::allowEncryption = m_allow_encryption; +void GpgFrontend::GenKeyInfo::setAllowEncryption(bool m_allow_encryption) { + if (allowChangeEncryption) + GenKeyInfo::allowEncryption = m_allow_encryption; } -void GenKeyInfo::setAllowCertification(bool m_allow_certification) { - if(allowChangeCertification) - GenKeyInfo::allowCertification = m_allow_certification; +void GpgFrontend::GenKeyInfo::setAllowCertification( + bool m_allow_certification) { + if (allowChangeCertification) + GenKeyInfo::allowCertification = m_allow_certification; } - diff --git a/src/gpg/GpgGenKeyInfo.h b/src/gpg/GpgGenKeyInfo.h new file mode 100644 index 00000000..7b830dd3 --- /dev/null +++ b/src/gpg/GpgGenKeyInfo.h @@ -0,0 +1,166 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPG4USB_GPGGENKEYINFO_H +#define GPG4USB_GPGGENKEYINFO_H + +#include <string> +#include <vector> + +#include <QtCore> + +namespace GpgFrontend { + +class GenKeyInfo { + + bool subKey = true; + std::string userid; + std::string algo; + int keySize = 2048; + QDateTime expired = QDateTime::currentDateTime().addYears(2); + bool nonExpired = false; + + bool noPassPhrase = false; + bool allowNoPassPhrase = true; + + int suggestMaxKeySize = 1024; + int suggestSizeAdditionStep = 1024; + int suggestMinKeySize = 4096; + + std::string passPhrase; + +public: + static const std::vector<std::string> SupportedKeyAlgo; + + static const std::vector<std::string> SupportedSubkeyAlgo; + + [[nodiscard]] bool isSubKey() const { return subKey; } + + void setIsSubKey(bool m_sub_key) { GenKeyInfo::subKey = m_sub_key; } + + [[nodiscard]] const std::string &getUserid() const { return userid; } + + void setUserid(const std::string &m_userid) { GenKeyInfo::userid = m_userid; } + + [[nodiscard]] const std::string &getAlgo() const { return algo; } + + void setAlgo(const std::string &m_algo); + + [[nodiscard]] std::string getKeySizeStr() const; + + [[nodiscard]] int getKeySize() const { return keySize; } + + void setKeySize(int m_key_size); + + [[nodiscard]] const QDateTime &getExpired() const { return expired; } + + void setExpired(const QDateTime &m_expired); + + [[nodiscard]] bool isNonExpired() const { return nonExpired; } + + void setNonExpired(bool m_non_expired); + + [[nodiscard]] bool isNoPassPhrase() const { return this->noPassPhrase; } + + void setNonPassPhrase(bool m_non_pass_phrase) { + GenKeyInfo::noPassPhrase = m_non_pass_phrase; + } + + [[nodiscard]] bool isAllowSigning() const { return allowSigning; } + + [[nodiscard]] bool isAllowNoPassPhrase() const { return allowNoPassPhrase; } + + void setAllowSigning(bool m_allow_signing) { + if (allowChangeSigning) + GenKeyInfo::allowSigning = m_allow_signing; + } + + [[nodiscard]] bool isAllowEncryption() const { return allowEncryption; } + + void setAllowEncryption(bool m_allow_encryption); + + [[nodiscard]] bool isAllowCertification() const { return allowCertification; } + + void setAllowCertification(bool m_allow_certification); + + [[nodiscard]] bool isAllowAuthentication() const { + return allowAuthentication; + } + + void setAllowAuthentication(bool m_allow_authentication) { + if (allowChangeAuthentication) + GenKeyInfo::allowAuthentication = m_allow_authentication; + } + + [[nodiscard]] const std::string &getPassPhrase() const { return passPhrase; } + + void setPassPhrase(const std::string &m_pass_phrase) { + GenKeyInfo::passPhrase = m_pass_phrase; + } + + [[nodiscard]] bool isAllowChangeSigning() const { return allowChangeSigning; } + [[nodiscard]] bool isAllowChangeEncryption() const { + return allowChangeEncryption; + } + + [[nodiscard]] bool isAllowChangeCertification() const { + return allowChangeCertification; + } + + [[nodiscard]] bool isAllowChangeAuthentication() const { + return allowChangeAuthentication; + } + + [[nodiscard]] int getSuggestMaxKeySize() const { return suggestMaxKeySize; } + + [[nodiscard]] int getSuggestMinKeySize() const { return suggestMinKeySize; } + + [[nodiscard]] int getSizeChangeStep() const { + return suggestSizeAdditionStep; + } + +private: + bool allowEncryption = true; + bool allowChangeEncryption = true; + + bool allowCertification = true; + bool allowChangeCertification = true; + + bool allowAuthentication = true; + bool allowChangeAuthentication = true; + + bool allowSigning = true; + bool allowChangeSigning = true; + + void reset_options(); + +public: + explicit GenKeyInfo(bool m_is_sub_key = false) : subKey(m_is_sub_key) { + setAlgo("rsa"); + } +}; + +} // namespace GpgFrontend + +#endif // GPG4USB_GPGGENKEYINFO_H diff --git a/include/gpg/GpgInfo.h b/src/gpg/GpgInfo.h index 914491dd..4c82897f 100644 --- a/include/gpg/GpgInfo.h +++ b/src/gpg/GpgInfo.h @@ -20,24 +20,22 @@ * The source code version of this software was modified and released * by Saturneric<[email protected]> starting on May 12, 2021. * -*/ + */ #ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H #define GPGFRONTEND_ZH_CN_TS_GPGINFO_H -#include "GpgFrontend.h" +#include <string> /** * Use to record some info about gnupg */ class GpgInfo { public: - - /** - * executable binary path of gnupg - */ - QString appPath; + /** + * executable binary path of gnupg + */ + std::string appPath; }; - -#endif //GPGFRONTEND_ZH_CN_TS_GPGINFO_H +#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H diff --git a/src/gpg/GpgKey.cpp b/src/gpg/GpgKey.cpp deleted file mode 100644 index 47cc32f1..00000000 --- a/src/gpg/GpgKey.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/model/GpgKey.h" - -GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : _key_ref(key, [&](gpgme_key_t key) { gpgme_key_release(key); }) {} - -GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { - swap(_key_ref, k._key_ref); -} - -GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept { - swap(_key_ref, k._key_ref); - return *this; -} - -std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>> GpgFrontend::GpgKey::subKeys() const { - auto p_keys = std::make_unique<std::vector<GpgSubKey>>(); - auto next = _key_ref->subkeys; - while (next != nullptr) { - p_keys->push_back(std::move(GpgSubKey(next))); - next = next->next; - } - return p_keys; -} - -std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::uids() const { - auto p_uids = std::make_unique<std::vector<GpgUID>>(); - auto uid_next = _key_ref->uids; - while (uid_next != nullptr) { - p_uids->push_back(std::move(GpgUID(uid_next))); - uid_next = uid_next->next; - } - return p_uids; -} - -bool GpgFrontend::GpgKey::canSignActual() const { - auto subkeys = subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool { - return subkey.secret() && subkey.can_sign() && !subkey.disabled() && !subkey.revoked() && !subkey.expired(); - })) - return true; - else return false; -} diff --git a/include/gpg/GpgModel.h b/src/gpg/GpgModel.h index c0cb7ec3..88241c23 100644 --- a/include/gpg/GpgModel.h +++ b/src/gpg/GpgModel.h @@ -25,22 +25,24 @@ #ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H #define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H +#include "gpg/model/GpgData.h" #include "gpg/model/GpgKey.h" -#include "gpg/model/GpgSubKey.h" -#include "gpg/model/GpgKeySignature.h" -#include "gpg/model/GpgUID.h" namespace GpgFrontend { - using KeyIdArgsList = std::span<std::string>; +using KeyIdArgsListPtr = std::unique_ptr<std::vector<std::string>>; - using KeyFprArgsList = std::span<std::string>; +using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>; - using KeyArgsList = std::span<GpgKey>; +using KeyArgsList = std::vector<GpgKey>; - using KeyPtr = std::unique_ptr<GpgKey>; +using KeyListPtr = std::unique_ptr<std::vector<GpgKey>>; - using KeyPtrArgsList = std::initializer_list<KeyPtr>; -} +using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>; -#endif //GPGFRONTEND_ZH_CN_TS_GPGMODEL_H +using KeyPtr = std::unique_ptr<GpgKey>; + +using KeyPtrArgsList = std::initializer_list<KeyPtr>; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_ZH_CN_TS_GPGMODEL_H diff --git a/src/gpg/function/BasicOperator.cpp b/src/gpg/function/BasicOperator.cpp index f81e9f71..c76f581a 100644 --- a/src/gpg/function/BasicOperator.cpp +++ b/src/gpg/function/BasicOperator.cpp @@ -25,230 +25,202 @@ #include "gpg/function/BasicOperator.h" #include "gpg/function/GpgKeyGetter.h" -/** - * Read gpgme-Data to QByteArray - * mainly from http://basket.kde.org/ (kgpgme.cpp) - */ -#define BUF_SIZE (32 * 1024) - -gpgme_error_t read_2_buffer(gpgme_data_t data_in, GpgFrontend::BypeArrayPtr &out_buffer) { - gpgme_off_t ret = gpgme_data_seek(data_in, 0, SEEK_SET); - gpgme_error_t err = gpg_error(GPG_ERR_NO_ERROR); - - if (ret) { - err = gpgme_err_code_from_errno(errno); - GpgFrontend::check_gpg_error(err, "failed data_seek data_in read_2_buffer"); - } else { - char buf[BUF_SIZE + 2]; - - while ((ret = gpgme_data_read(data_in, buf, BUF_SIZE)) > 0) { - const size_t size = out_buffer->size(); - out_buffer->resize(static_cast<int>(size + ret)); - memcpy(out_buffer->data() + size, buf, ret); - } - if (ret < 0) { - err = gpgme_err_code_from_errno(errno); - GpgFrontend::check_gpg_error(err, "failed data_read data_in read_2_buffer"); - } - } - return err; -} - -gpg_error_t GpgFrontend::BasicOperator::encrypt(std::vector<GpgKey> &keys, GpgFrontend::BypeArrayRef in_buffer, - GpgFrontend::BypeArrayPtr &out_buffer, - GpgFrontend::GpgEncrResult &result) { +GpgFrontend::GpgError GpgFrontend::BasicOperator::Encrypt( + std::vector<GpgKey> &keys, GpgFrontend::BypeArrayRef in_buffer, + GpgFrontend::BypeArrayPtr &out_buffer, GpgFrontend::GpgEncrResult &result) { - gpgme_data_t data_in = nullptr, data_out = nullptr; - out_buffer->resize(0); + // gpgme_encrypt_result_t e_result; + gpgme_key_t recipients[keys.size() + 1]; - // gpgme_encrypt_result_t e_result; - gpgme_key_t recipients[keys.size() + 1]; + int index = 0; + for (const auto &key : keys) + recipients[index++] = gpgme_key_t(key); - int index = 0; - for (const auto &key : keys) recipients[index++] = gpgme_key_t(key); + // Last entry data_in array has to be nullptr + recipients[keys.size()] = nullptr; - // Last entry data_in array has to be nullptr - recipients[keys.size()] = nullptr; + GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - gpgme_error_t err; + gpgme_error_t err = check_gpg_error(gpgme_op_encrypt( + ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); - // If the last parameter isnt 0, a private copy of data is made - check_gpg_error(gpgme_data_new_from_mem(&data_in, in_buffer.data(), in_buffer.size(), 1)); - check_gpg_error(gpgme_data_new(&data_out)); - err = check_gpg_error(gpgme_op_encrypt(ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); - check_gpg_error(read_2_buffer(data_out, out_buffer)); + auto temp_data_out = data_out.Read2Buffer(); + std::swap(temp_data_out, out_buffer); - if (data_in) gpgme_data_release(data_in); - if (data_out) gpgme_data_release(data_out); + auto temp_result = GpgEncrResult( + gpgme_op_encrypt_result(ctx), + [&](gpgme_encrypt_result_t res) { gpgme_result_unref(res); }); + std::swap(result, temp_result); - result = GpgEncrResult(gpgme_op_encrypt_result(ctx), [&](gpgme_encrypt_result_t res) { gpgme_result_unref(res); }); - return err; + return err; } -gpgme_error_t GpgFrontend::BasicOperator::decrypt(BypeArrayRef in_buffer, GpgFrontend::BypeArrayPtr &out_buffer, - GpgFrontend::GpgDecrResult &result) { - gpgme_data_t data_in = nullptr, data_out = nullptr; - out_buffer->resize(0); +GpgFrontend::GpgError +GpgFrontend::BasicOperator::Decrypt(BypeArrayRef in_buffer, + GpgFrontend::BypeArrayPtr &out_buffer, + GpgFrontend::GpgDecrResult &result) { - gpgme_error_t err; + gpgme_error_t err; - check_gpg_error(gpgme_data_new_from_mem(&data_in, in_buffer.data(), in_buffer.size(), 1)); - check_gpg_error(gpgme_data_new(&data_out)); - err = check_gpg_error(gpgme_op_decrypt(ctx, data_in, data_out)); - check_gpg_error(read_2_buffer(data_out, out_buffer)); + GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; + err = check_gpg_error(gpgme_op_decrypt(ctx, data_in, data_out)); - if (data_in) gpgme_data_release(data_in); - if (data_out) gpgme_data_release(data_out); + auto temp_data_out = data_out.Read2Buffer(); + std::swap(temp_data_out, out_buffer); - result = GpgDecrResult(gpgme_op_decrypt_result(ctx), [&](gpgme_decrypt_result_t res) { gpgme_result_unref(res); }); + auto temp_result = GpgDecrResult( + gpgme_op_decrypt_result(ctx), + [&](gpgme_decrypt_result_t res) { gpgme_result_unref(res); }); + std::swap(result, temp_result); - return err; + return err; } -gpgme_error_t GpgFrontend::BasicOperator::verify(QByteArray &in_buffer, QByteArray &sig_buffer, - GpgFrontend::GpgVerifyResult &result) const { - gpgme_data_t data_in; - gpgme_error_t err; - gpgme_verify_result_t m_result; +GpgFrontend::GpgError +GpgFrontend::BasicOperator::Verify(QByteArray &in_buffer, + BypeArrayPtr &sig_buffer, + GpgVerifyResult &result) const { + gpgme_error_t err; + gpgme_verify_result_t m_result; - check_gpg_error(gpgme_data_new_from_mem(&data_in, in_buffer.data(), in_buffer.size(), 1)); + GpgData data_in(in_buffer.data(), in_buffer.size()); - if (sig_buffer != nullptr) { - gpgme_data_t sig_data; - check_gpg_error(gpgme_data_new_from_mem(&sig_data, sig_buffer.data(), sig_buffer.size(), 1)); - err = check_gpg_error(gpgme_op_verify(ctx, sig_data, data_in, nullptr)); - } else - err = check_gpg_error(gpgme_op_verify(ctx, data_in, nullptr, data_in)); + if (sig_buffer != nullptr) { + GpgData sig_data(sig_buffer->data(), sig_buffer->size()); + err = check_gpg_error(gpgme_op_verify(ctx, sig_data, data_in, nullptr)); + } else + err = check_gpg_error(gpgme_op_verify(ctx, data_in, nullptr, data_in)); - result = GpgVerifyResult(gpgme_op_verify_result(ctx), [&](gpgme_verify_result_t res) { gpgme_result_unref(res); }); + auto temp_result = GpgVerifyResult( + gpgme_op_verify_result(ctx), + [&](gpgme_verify_result_t res) { gpgme_result_unref(res); }); + std::swap(result, temp_result); - return err; + return err; } -gpg_error_t -GpgFrontend::BasicOperator::sign(KeyFprArgsList key_fprs, BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, - gpgme_sig_mode_t mode, GpgSignResult &result) { - gpgme_error_t err; - gpgme_data_t data_in, data_out; +GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyArgsList &keys, + BypeArrayRef in_buffer, + BypeArrayPtr &out_buffer, + gpgme_sig_mode_t mode, + GpgSignResult &result) { + gpgme_error_t err; - out_buffer->resize(0); + // Set Singers of this opera + SetSigners(keys); - std::vector<GpgKey> keys; - auto &key_getter = GpgKeyGetter::getInstance(); + GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - for (const auto &key_fpr : key_fprs) - keys.push_back(key_getter.getKey(key_fpr)); + /** + `GPGME_SIG_MODE_NORMAL' + A normal signature is made, the output includes the plaintext + and the signature. - // Set Singers of this opera - setSigners(keys); + `GPGME_SIG_MODE_DETACH' + A detached signature is made. - check_gpg_error(gpgme_data_new_from_mem(&data_in, in_buffer.data(), in_buffer.size(), 1)); - check_gpg_error(gpgme_data_new(&data_out)); + `GPGME_SIG_MODE_CLEAR' + A clear text signature is made. The ASCII armor and text + mode settings of the context are ignored. + */ - /** - `GPGME_SIG_MODE_NORMAL' - A normal signature is made, the output includes the plaintext - and the signature. + err = check_gpg_error(gpgme_op_sign(ctx, data_in, data_out, mode)); - `GPGME_SIG_MODE_DETACH' - A detached signature is made. + auto temp_data_out = data_out.Read2Buffer(); + std::swap(temp_data_out, out_buffer); - `GPGME_SIG_MODE_CLEAR' - A clear text signature is made. The ASCII armor and text - mode settings of the context are ignored. - */ + auto temp_result = + GpgSignResult(gpgme_op_sign_result(ctx), + [&](gpgme_sign_result_t res) { gpgme_result_unref(res); }); - err = check_gpg_error(gpgme_op_sign(ctx, data_in, data_out, mode)); - check_gpg_error(read_2_buffer(data_out, out_buffer)); + std::swap(result, temp_result); - gpgme_data_release(data_in); - gpgme_data_release(data_out); - - result = GpgSignResult(gpgme_op_sign_result(ctx), [&](gpgme_sign_result_t res) { gpgme_result_unref(res); }); - - return err; + return err; } -gpgme_error_t -GpgFrontend::BasicOperator::decryptVerify(const BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, - GpgDecrResult &decrypt_result, GpgVerifyResult &verify_result) { - gpgme_error_t err; - gpgme_data_t data_in, data_out; - out_buffer->resize(0); +gpgme_error_t GpgFrontend::BasicOperator::DecryptVerify( + BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, + GpgDecrResult &decrypt_result, GpgVerifyResult &verify_result) { + gpgme_error_t err; - check_gpg_error(gpgme_data_new_from_mem(&data_in, in_buffer.data(), in_buffer.size(), 1)); - check_gpg_error(gpgme_data_new(&data_out)); - err = check_gpg_error(gpgme_op_decrypt_verify(ctx, data_in, data_out)); + GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - check_gpg_error(read_2_buffer(data_out, out_buffer)); + err = check_gpg_error(gpgme_op_decrypt_verify(ctx, data_in, data_out)); - if (data_in) gpgme_data_release(data_in); - if (data_out) gpgme_data_release(data_out); + auto temp_data_out = data_out.Read2Buffer(); + std::swap(temp_data_out, out_buffer); - decrypt_result = GpgDecrResult(gpgme_op_decrypt_result(ctx), - [&](gpgme_decrypt_result_t res) { gpgme_result_unref(res); }); - verify_result = GpgVerifyResult(gpgme_op_verify_result(ctx), - [&](gpgme_verify_result_t res) { gpgme_result_unref(res); }); + auto temp_decr_result = GpgDecrResult( + gpgme_op_decrypt_result(ctx), + [&](gpgme_decrypt_result_t res) { gpgme_result_unref(res); }); + std::swap(decrypt_result, temp_decr_result); + auto temp_verify_result = GpgVerifyResult( + gpgme_op_verify_result(ctx), + [&](gpgme_verify_result_t res) { gpgme_result_unref(res); }); + std::swap(verify_result, temp_verify_result); - return err; + return err; } -gpgme_error_t GpgFrontend::BasicOperator::encryptSign(std::vector<GpgKey> &keys, std::vector<GpgKey> &signers, - BypeArrayRef in_buffer, - BypeArrayPtr &out_buffer, GpgEncrResult &encr_result, - GpgSignResult &sign_result) { - gpgme_error_t err; - gpgme_data_t data_in, data_out; - out_buffer->resize(0); +gpgme_error_t GpgFrontend::BasicOperator::EncryptSign( + std::vector<GpgKey> &keys, std::vector<GpgKey> &signers, + BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, + GpgEncrResult &encr_result, GpgSignResult &sign_result) { + gpgme_error_t err; + SetSigners(signers); - setSigners(signers); + // gpgme_encrypt_result_t e_result; + gpgme_key_t recipients[keys.size() + 1]; - //gpgme_encrypt_result_t e_result; - gpgme_key_t recipients[keys.size() + 1]; + // set key for user + int index = 0; + for (const auto &key : keys) + recipients[index++] = gpgme_key_t(key); - // set key for user - int index = 0; - for (const auto &key : keys) recipients[index++] = gpgme_key_t(key); + // Last entry dataIn array has to be nullptr + recipients[keys.size()] = nullptr; - // Last entry dataIn array has to be nullptr - recipients[keys.size()] = nullptr; + GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - // If the last parameter isnt 0, a private copy of data is made - check_gpg_error(gpgme_data_new_from_mem(&data_in, in_buffer.data(), in_buffer.size(), 1)); - check_gpg_error(gpgme_data_new(&data_out)); - err = check_gpg_error(gpgme_op_encrypt_sign(ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); + // If the last parameter isnt 0, a private copy of data is made + err = check_gpg_error(gpgme_op_encrypt_sign( + ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); - check_gpg_error(read_2_buffer(data_out, out_buffer)); + auto temp_data_out = data_out.Read2Buffer(); + std::swap(temp_data_out, out_buffer); - if (data_in) gpgme_data_release(data_in); - if (data_out) gpgme_data_release(data_out); + auto temp_encr_result = GpgEncrResult( + gpgme_op_encrypt_result(ctx), + [&](gpgme_encrypt_result_t res) { gpgme_result_unref(res); }); + swap(encr_result, temp_encr_result); + auto temp_sign_result = + GpgSignResult(gpgme_op_sign_result(ctx), + [&](gpgme_sign_result_t res) { gpgme_result_unref(res); }); + swap(sign_result, temp_sign_result); - encr_result = GpgEncrResult(gpgme_op_encrypt_result(ctx), - [&](gpgme_encrypt_result_t res) { gpgme_result_unref(res); }); - sign_result = GpgSignResult(gpgme_op_sign_result(ctx), [&](gpgme_sign_result_t res) { gpgme_result_unref(res); }); - - return err; + return err; } -void GpgFrontend::BasicOperator::setSigners(KeyArgsList keys) { - gpgme_signers_clear(ctx); - for (const GpgKey &key : keys) { - if (key.canSignActual()) { - auto gpgmeError = gpgme_signers_add(ctx, gpgme_key_t(key)); - check_gpg_error(gpgmeError); - } +void GpgFrontend::BasicOperator::SetSigners(KeyArgsList &keys) { + gpgme_signers_clear(ctx); + for (const GpgKey &key : keys) { + if (key.CanSignActual()) { + auto gpgmeError = gpgme_signers_add(ctx, gpgme_key_t(key)); + check_gpg_error(gpgmeError); } - if (keys.size() != gpgme_signers_count(ctx)) - qDebug() << "No All Signers Added"; + } + if (keys.size() != gpgme_signers_count(ctx)) + qDebug() << "No All Signers Added"; } -std::unique_ptr<std::vector<GpgFrontend::GpgKey>> GpgFrontend::BasicOperator::getSigners() { - auto count = gpgme_signers_count(ctx); - auto signers = std::make_unique<std::vector<GpgKey>>(); - for (auto i = 0; i < count; i++) { - auto key = GpgKey(gpgme_signers_enum(ctx, i)); - signers->push_back(std::move(GpgKey(std::move(key)))); - } - return signers; +std::unique_ptr<std::vector<GpgFrontend::GpgKey>> +GpgFrontend::BasicOperator::GetSigners() { + auto count = gpgme_signers_count(ctx); + auto signers = std::make_unique<std::vector<GpgKey>>(); + for (auto i = 0; i < count; i++) { + auto key = GpgKey(gpgme_signers_enum(ctx, i)); + signers->push_back(std::move(GpgKey(std::move(key)))); + } + return signers; } diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h new file mode 100644 index 00000000..e5424ad2 --- /dev/null +++ b/src/gpg/function/BasicOperator.h @@ -0,0 +1,68 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H +#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H + +#include "gpg/GpgConstants.h" +#include "gpg/GpgContext.h" +#include "gpg/GpgFunctionObject.h" +#include "gpg/GpgModel.h" + +namespace GpgFrontend { + +class BasicOperator : public SingletonFunctionObject<BasicOperator> { +public: + gpg_error_t Encrypt(KeyArgsList &keys, BypeArrayRef in_buffer, + BypeArrayPtr &out_buffer, GpgEncrResult &result); + + gpgme_error_t EncryptSign(KeyArgsList &keys, KeyArgsList &signers, + BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, + GpgEncrResult &encr_result, + GpgSignResult &sign_result); + + gpgme_error_t Decrypt(BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, + GpgDecrResult &result); + + gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, BypeArrayPtr &out_buffer, + GpgDecrResult &decrypt_result, + GpgVerifyResult &verify_result); + + gpgme_error_t Verify(BypeArrayRef in_buffer, BypeArrayPtr &sig_buffer, + GpgVerifyResult &result) const; + + gpg_error_t Sign(KeyArgsList &key_fprs, BypeArrayRef in_buffer, + BypeArrayPtr &out_buffer, gpgme_sig_mode_t mode, + GpgSignResult &result); + + void SetSigners(KeyArgsList &keys); + + std::unique_ptr<KeyArgsList> GetSigners(); + +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H diff --git a/src/gpg/function/GpgCommandExecutor.cpp b/src/gpg/function/GpgCommandExecutor.cpp index 98743ed4..c36cb2b6 100644 --- a/src/gpg/function/GpgCommandExecutor.cpp +++ b/src/gpg/function/GpgCommandExecutor.cpp @@ -23,23 +23,27 @@ */ #include "gpg/function/GpgCommandExecutor.h" - -void GpgFrontend::GpgCommandExecutor::execute(const QStringList &arguments, - const std::function<void(QProcess *)> &interactFunc) { - QEventLoop looper; - auto *gpgProcess = new QProcess(&looper); - gpgProcess->setProcessChannelMode(QProcess::MergedChannels); - connect(gpgProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), &looper, &QEventLoop::quit); - connect(gpgProcess, &QProcess::errorOccurred, []() -> void { qDebug("Error in Process"); }); - connect(gpgProcess, &QProcess::errorOccurred, &looper, &QEventLoop::quit); - connect(gpgProcess, &QProcess::started, []() -> void { qDebug() << "Gpg Process Started Success"; }); - connect(gpgProcess, &QProcess::readyReadStandardOutput, [interactFunc, gpgProcess]() { - qDebug() << "Function Called"; - interactFunc(gpgProcess); - }); - gpgProcess->setProgram(ctx.getInfo().appPath); - gpgProcess->setArguments(arguments); - gpgProcess->start(); - looper.exec(); - +void GpgFrontend::GpgCommandExecutor::Execute( + const QStringList &arguments, + const std::function<void(QProcess *)> &interact_func) { + QEventLoop looper; + auto *gpg_process = new QProcess(&looper); + gpg_process->setProcessChannelMode(QProcess::MergedChannels); + connect(gpg_process, + qOverload<int, QProcess::ExitStatus>(&QProcess::finished), &looper, + &QEventLoop::quit); + connect(gpg_process, &QProcess::errorOccurred, + []() -> void { qDebug("Error in Process"); }); + connect(gpg_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit); + connect(gpg_process, &QProcess::started, + []() -> void { qDebug() << "Gpg Process Started Success"; }); + connect(gpg_process, &QProcess::readyReadStandardOutput, + [interact_func, gpg_process]() { + qDebug() << "Function Called"; + interact_func(gpg_process); + }); + gpg_process->setProgram(ctx.GetInfo().appPath.c_str()); + gpg_process->setArguments(arguments); + gpg_process->start(); + looper.exec(); } diff --git a/include/gpg/function/GpgCommandExecutor.h b/src/gpg/function/GpgCommandExecutor.h index 1e64390a..d347a601 100644 --- a/include/gpg/function/GpgCommandExecutor.h +++ b/src/gpg/function/GpgCommandExecutor.h @@ -25,22 +25,22 @@ #ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H #define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H -#include "GpgFrontend.h" #include "gpg/GpgContext.h" +#include "gpg/GpgFunctionObject.h" namespace GpgFrontend { - class GpgCommandExecutor : public QObject { - Q_OBJECT - public: - void execute(const QStringList &arguments, const std::function<void(QProcess *)> &interactFunc); +class GpgCommandExecutor : public QObject, + public SingletonFunctionObject<GpgCommandExecutor> { + Q_OBJECT +public: + void Execute(const QStringList &arguments, + const std::function<void(QProcess *)> &interact_func); - private: +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; - GpgContext &ctx = GpgContext::getInstance(); - }; +} // namespace GpgFrontend -} - - -#endif //GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H +#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H diff --git a/src/gpg/function/GpgFileOpera.cpp b/src/gpg/function/GpgFileOpera.cpp new file mode 100644 index 00000000..50e4e932 --- /dev/null +++ b/src/gpg/function/GpgFileOpera.cpp @@ -0,0 +1,262 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ +#include "gpg/function/GpgFileOpera.h" +#include "gpg/function/BasicOperator.h" +#include <memory> + +GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile( + KeyArgsList &keys, const std::string &path, GpgEncrResult &result) { + + QFileInfo file_info(path.c_str()); + + if (!file_info.isFile() || !file_info.isReadable()) + throw std::runtime_error("no permission"); + + QFile in_file(path.c_str()); + if (!in_file.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray in_buffer = in_file.readAll(); + auto out_buffer = std::make_unique<QByteArray>(); + in_file.close(); + + auto err = + BasicOperator::GetInstance().Encrypt(keys, in_buffer, out_buffer, result); + + if (gpg_err_code(err) != GPG_ERR_NO_ERROR) + return err; + + QFile out_file((path + ".asc").c_str()); + + if (!out_file.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&out_file); + out.writeRawData(out_buffer->data(), out_buffer->length()); + out_file.close(); + return err; +} + +GpgFrontend::GpgError +GpgFrontend::GpgFileOpera::DecryptFile(const QString &path, + GpgDecrResult &result) { + + QFileInfo file_info(path); + + if (!file_info.isFile() || !file_info.isReadable()) + throw std::runtime_error("no permission"); + + QFile in_file(path); + if (!in_file.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray in_buffer = in_file.readAll(); + auto out_buffer = std::make_unique<QByteArray>(); + in_file.close(); + + auto err = + BasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result); + + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + + QString out_file_name, file_extension = file_info.suffix(); + + if (file_extension == "asc" || file_extension == "gpg") { + int pos = path.lastIndexOf('.'); + out_file_name = path.left(pos); + } else + out_file_name = path + ".out"; + + QFile out_file(out_file_name); + + if (!out_file.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&out_file); + out.writeRawData(out_buffer->data(), out_buffer->length()); + out_file.close(); + + return err; +} + +gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyArgsList &keys, + const std::string &path, + GpgSignResult &result) { + + QFileInfo file_info(path.c_str()); + + if (!file_info.isFile() || !file_info.isReadable()) + throw std::runtime_error("no permission"); + + QFile in_file(path.c_str()); + if (!in_file.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray in_buffer = in_file.readAll(); + auto out_buffer = std::make_unique<QByteArray>(); + in_file.close(); + + auto err = BasicOperator::GetInstance().Sign(keys, in_buffer, out_buffer, + GPGME_SIG_MODE_DETACH, result); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + + QFile out_file((path + ".sig").c_str()); + + if (!out_file.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&out_file); + out.writeRawData(out_buffer->data(), out_buffer->length()); + out_file.close(); + + return err; +} + +gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(const std::string &path, + GpgVerifyResult &result) { + + qDebug() << "Verify File Path" << path.c_str(); + + QFileInfo file_info(path.c_str()); + + if (!file_info.isFile() || !file_info.isReadable()) + throw std::runtime_error("no permission"); + + QFile in_file(path.c_str()); + if (!in_file.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray in_buffer = in_file.readAll(); + std::unique_ptr<QByteArray> sign_buffer = nullptr; + + if (file_info.suffix() == "gpg") { + auto err = + BasicOperator::GetInstance().Verify(in_buffer, sign_buffer, result); + return err; + } else { + QFile sign_file; + sign_file.setFileName((path + ".sig").c_str()); + if (!sign_file.open(QIODevice::ReadOnly)) { + throw std::runtime_error("cannot open file"); + } + + auto sign_buffer = std::make_unique<QByteArray>(sign_file.readAll()); + in_file.close(); + + auto err = + BasicOperator::GetInstance().Verify(in_buffer, sign_buffer, result); + return err; + } +} + +// TODO + +gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile( + KeyArgsList &keys, const std::string &path, GpgEncrResult &encr_res, + GpgSignResult &sign_res) { + + qDebug() << "Encrypt Sign File Path" << path.c_str(); + + QFileInfo file_info(path.c_str()); + + if (!file_info.isFile() || !file_info.isReadable()) + throw std::runtime_error("no permission"); + + QFile in_file; + in_file.setFileName(path.c_str()); + if (!in_file.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray in_buffer = in_file.readAll(); + in_file.close(); + std::unique_ptr<QByteArray> out_buffer = nullptr; + + // TODO Fill the vector + std::vector<GpgKey> signerKeys; + + // TODO dealing with signer keys + auto err = BasicOperator::GetInstance().EncryptSign( + keys, signerKeys, in_buffer, out_buffer, encr_res, sign_res); + + if (gpg_err_code(err) != GPG_ERR_NO_ERROR) + return err; + + QFile out_file((path + ".gpg").c_str()); + + if (!out_file.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&out_file); + out.writeRawData(out_buffer->data(), out_buffer->length()); + out_file.close(); + + return err; +} + +gpg_error_t +GpgFrontend::GpgFileOpera::DecryptVerifyFile(const std::string &path, + GpgDecrResult &decr_res, + GpgVerifyResult &verify_res) { + + qDebug() << "Decrypt Verify File Path" << path.c_str(); + + QFileInfo file_info(path.c_str()); + + if (!file_info.isFile() || !file_info.isReadable()) + throw std::runtime_error("no permission"); + + QFile in_file; + in_file.setFileName(path.c_str()); + if (!in_file.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray in_buffer = in_file.readAll(); + in_file.close(); + std::unique_ptr<QByteArray> out_buffer = nullptr; + + auto err = BasicOperator::GetInstance().DecryptVerify(in_buffer, out_buffer, + decr_res, verify_res); + if (gpg_err_code(err) != GPG_ERR_NO_ERROR) + return err; + + std::string out_file_name, + file_extension = file_info.suffix().toUtf8().constData(); + + if (file_extension == "asc" || file_extension == "gpg") { + int pos = path.find_last_of('.'); + out_file_name = path.substr(0, pos); + } else + out_file_name = (path + ".out").c_str(); + + QFile out_file(out_file_name.c_str()); + + if (!out_file.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&out_file); + out.writeRawData(out_buffer->data(), out_buffer->length()); + out_file.close(); + + return err; +} diff --git a/src/gpg/function/GpgFileOpera.h b/src/gpg/function/GpgFileOpera.h new file mode 100644 index 00000000..1642a8eb --- /dev/null +++ b/src/gpg/function/GpgFileOpera.h @@ -0,0 +1,58 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGFILEOPERA_H +#define GPGFRONTEND_GPGFILEOPERA_H + +#include "gpg/GpgConstants.h" +#include "gpg/GpgContext.h" +#include "gpg/GpgModel.h" + +namespace GpgFrontend { + +class GpgFileOpera { +public: + GpgError EncryptFile(KeyArgsList &keys, const std::string &path, + GpgEncrResult &result); + + GpgError DecryptFile(const QString &path, GpgDecrResult &result); + + GpgError SignFile(KeyArgsList &keys, const std::string &path, + GpgSignResult &result); + + GpgError VerifyFile(const std::string &path, GpgVerifyResult &result); + + GpgError EncryptSignFile(KeyArgsList &keys, const std::string &path, + GpgEncrResult &encr_res, GpgSignResult &sign_res); + + GpgError DecryptVerifyFile(const std::string &path, GpgDecrResult &decr_res, + GpgVerifyResult &verify_res); + +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGFILEOPERA_H diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp index e4572290..4bea83f3 100644 --- a/src/gpg/function/GpgKeyGetter.cpp +++ b/src/gpg/function/GpgKeyGetter.cpp @@ -24,15 +24,46 @@ #include "gpg/function/GpgKeyGetter.h" +GpgFrontend::GpgKey && +GpgFrontend::GpgKeyGetter::GetKey(const std::string &fpr) { + gpgme_key_t _p_key; + gpgme_get_key(ctx, fpr.c_str(), &_p_key, 1); + return std::move(GpgKey(std::move(_p_key))); +} -GpgFrontend::GpgKey &&GpgFrontend::GpgKeyGetter::getKey(const std::string &fpr) { - gpgme_key_t _p_key; - gpgme_get_key(ctx, fpr.c_str(), &_p_key, 1); - return std::move(GpgKey(std::move(_p_key))); +GpgFrontend::GpgKey && +GpgFrontend::GpgKeyGetter::GetPubkey(const std::string &fpr) { + gpgme_key_t _p_key; + gpgme_get_key(ctx, fpr.c_str(), &_p_key, 0); + return std::move(GpgKey(std::move(_p_key))); } -GpgFrontend::GpgKey &&GpgFrontend::GpgKeyGetter::getPubkey(const std::string &fpr) { - gpgme_key_t _p_key; - gpgme_get_key(ctx, fpr.c_str(), &_p_key, 0); - return std::move(GpgKey(std::move(_p_key))); +GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::FetchKey() { + + gpgme_error_t err; + + qDebug() << "Clear List and Map"; + + KeyListPtr keys_list = std::make_unique<std::vector<GpgKey>>(); + + qDebug() << "Operate KeyList Start"; + + err = gpgme_op_keylist_start(ctx, nullptr, 0); + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); + + qDebug() << "Start Loop"; + + gpgme_key_t key; + while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { + keys_list->push_back(GpgKey(std::move(key))); + qDebug() << "Append Key" << keys_list->back().id().c_str(); + } + + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); + + err = gpgme_op_keylist_end(ctx); + + qDebug() << "Operate KeyList End"; + + return keys_list; } diff --git a/include/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h index 87307f1b..a848b2f8 100644 --- a/include/gpg/function/GpgKeyGetter.h +++ b/src/gpg/function/GpgKeyGetter.h @@ -25,31 +25,26 @@ #ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H #define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H -#include "GpgFrontend.h" -#include "gpg/GpgModel.h" #include "gpg/GpgContext.h" #include "gpg/GpgFunctionObject.h" +#include "gpg/GpgModel.h" namespace GpgFrontend { - class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter>{ - - public: - - GpgKey &&getKey(const std::string &fpr); - - GpgKey &&getPubkey(const std::string &fpr); - - GpgKeyGetter() = default; - - private: +class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { - GpgContext &ctx = GpgContext::getInstance(); +public: + GpgKey &&GetKey(const std::string &fpr); - }; -} + GpgKey &&GetPubkey(const std::string &fpr); + KeyListPtr FetchKey(); + GpgKeyGetter() = default; +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; +} // namespace GpgFrontend -#endif //GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H +#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExportor.cpp new file mode 100644 index 00000000..8c293617 --- /dev/null +++ b/src/gpg/function/GpgKeyImportExportor.cpp @@ -0,0 +1,124 @@ +#include "gpg/function/GpgKeyImportExportor.h" + +/** + * Import key pair + * @param inBuffer input byte array + * @return Import information + */ +GpgFrontend::GpgImportInformation +GpgFrontend::GpgKeyImportExportor::ImportKey(StdBypeArrayPtr in_buffer) { + auto import_information = std::make_unique<GpgImportInformation>(); + GpgData data_in(in_buffer->data(), in_buffer->size()); + auto err = gpgme_op_import(ctx, data_in); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + gpgme_import_result_t result; + + result = gpgme_op_import_result(ctx); + + if (result->unchanged) + import_information->unchanged = result->unchanged; + if (result->considered) + import_information->considered = result->considered; + if (result->no_user_id) + import_information->no_user_id = result->no_user_id; + if (result->imported) + import_information->imported = result->imported; + if (result->imported_rsa) + import_information->imported_rsa = result->imported_rsa; + if (result->unchanged) + import_information->unchanged = result->unchanged; + if (result->new_user_ids) + import_information->new_user_ids = result->new_user_ids; + if (result->new_sub_keys) + import_information->new_sub_keys = result->new_sub_keys; + if (result->new_signatures) + import_information->new_signatures = result->new_signatures; + if (result->new_revocations) + import_information->new_revocations = result->new_revocations; + if (result->secret_read) + import_information->secret_read = result->secret_read; + if (result->secret_imported) + import_information->secret_imported = result->secret_imported; + if (result->secret_unchanged) + import_information->secret_unchanged = result->secret_unchanged; + if (result->not_imported) + import_information->not_imported = result->not_imported; + + gpgme_result_unref(result); + + gpgme_import_status_t status = result->imports; + while (status != nullptr) { + GpgImportedKey key; + key.importStatus = static_cast<int>(status->status); + key.fpr = status->fpr; + import_information->importedKeys.emplace_back(key); + status = status->next; + } + return *import_information; +} + +/** + * Export Key + * @param uid_list key ids + * @param out_buffer output byte array + * @return if success + */ +bool GpgFrontend::GpgKeyImportExportor::ExportKeys( + KeyIdArgsListPtr &uid_list, BypeArrayPtr &out_buffer) const { + if (uid_list->empty()) + return false; + + // Alleviate another crash problem caused by an unknown array out-of-bounds + // access + for (int i = 0; i < uid_list->size(); i++) { + GpgData data_out; + auto err = gpgme_op_export(ctx, (*uid_list)[i].c_str(), 0, data_out); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + + qDebug() << "exportKeys read_bytes" + << gpgme_data_seek(data_out, 0, SEEK_END); + + auto temp_out_buffer = std::move(data_out.Read2Buffer()); + std::swap(out_buffer, temp_out_buffer); + } + + return true; +} + +/** + * Export keys + * @param keys keys used + * @param outBuffer output byte array + * @return if success + */ +bool GpgFrontend::GpgKeyImportExportor::ExportKeys( + KeyArgsList &keys, BypeArrayPtr &out_buffer) const { + KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>(); + for (const auto &key : keys) + key_ids->push_back(key.id()); + return ExportKeys(key_ids, out_buffer); +} + +/** + * Export the secret key of a key pair(including subkeys) + * @param key target key pair + * @param outBuffer output byte array + * @return if successful + */ +bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( + const GpgKey &key, BypeArrayPtr out_buffer) const { + + qDebug() << "Export Secret Key" << key.id().c_str(); + + gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr}; + + GpgData data_out; + + // export private key to outBuffer + gpgme_error_t error = + gpgme_op_export_keys(ctx, target_key, GPGME_EXPORT_MODE_SECRET, data_out); + + auto temp_out_buffer = std::move(data_out.Read2Buffer()); + std::swap(out_buffer, temp_out_buffer); + return true; +} diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExportor.h new file mode 100644 index 00000000..4eaba19b --- /dev/null +++ b/src/gpg/function/GpgKeyImportExportor.h @@ -0,0 +1,80 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef _GPGKEYIMPORTEXPORTOR_H +#define _GPGKEYIMPORTEXPORTOR_H + +#include "gpg/GpgConstants.h" +#include "gpg/GpgContext.h" +#include "gpg/GpgFunctionObject.h" +#include "gpg/GpgModel.h" + +namespace GpgFrontend { + +class GpgImportedKey { +public: + std::string fpr; + int importStatus; +}; + +typedef std::list<GpgImportedKey> GpgImportedKeyList; + +class GpgImportInformation { +public: + GpgImportInformation() = default; + + int considered = 0; + int no_user_id = 0; + int imported = 0; + int imported_rsa = 0; + int unchanged = 0; + int new_user_ids = 0; + int new_sub_keys = 0; + int new_signatures = 0; + int new_revocations = 0; + int secret_read = 0; + int secret_imported = 0; + int secret_unchanged = 0; + int not_imported = 0; + GpgImportedKeyList importedKeys; +}; + +class GpgKeyImportExportor + : public SingletonFunctionObject<GpgKeyImportExportor> { +public: + GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer); + + bool ExportKeys(KeyIdArgsListPtr &uid_list, BypeArrayPtr &out_buffer) const; + + bool ExportKeys(KeyArgsList &keys, BypeArrayPtr &outBuffer) const; + + bool ExportSecretKey(const GpgKey &key, BypeArrayPtr outBuffer) const; + +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; + +} // namespace GpgFrontend + +#endif // _GPGKEYIMPORTEXPORTOR_H
\ No newline at end of file diff --git a/src/gpg/function/GpgKeyManager.cpp b/src/gpg/function/GpgKeyManager.cpp index b27163c8..9e0f610e 100644 --- a/src/gpg/function/GpgKeyManager.cpp +++ b/src/gpg/function/GpgKeyManager.cpp @@ -22,55 +22,68 @@ * */ - #include "gpg/function/GpgKeyManager.h" -#include "gpg/function/GpgKeyGetter.h" #include "gpg/function/BasicOperator.h" +#include "gpg/function/GpgKeyGetter.h" -bool GpgFrontend::GpgKeyManager::signKey(const GpgFrontend::GpgKey &target, GpgFrontend::KeyArgsList &keys, - const QString &uid, std::unique_ptr<QDateTime> &expires) { - BasicOperator::getInstance().setSigners(keys); +bool GpgFrontend::GpgKeyManager::signKey(const GpgFrontend::GpgKey &target, + GpgFrontend::KeyArgsList &keys, + const QString &uid, + std::unique_ptr<QDateTime> &expires) { + BasicOperator::GetInstance().SetSigners(keys); - unsigned int flags = 0; + unsigned int flags = 0; - unsigned int expires_time_t = 0; - if (expires == nullptr) flags |= GPGME_KEYSIGN_NOEXPIRE; - else expires_time_t = QDateTime::currentDateTime().secsTo(*expires); + unsigned int expires_time_t = 0; + if (expires == nullptr) + flags |= GPGME_KEYSIGN_NOEXPIRE; + else + expires_time_t = QDateTime::currentDateTime().secsTo(*expires); - auto err = - check_gpg_error( - gpgme_op_keysign(ctx, gpgme_key_t(target), uid.toUtf8().constData(), expires_time_t, flags)); + auto err = check_gpg_error(gpgme_op_keysign(ctx, gpgme_key_t(target), + uid.toUtf8().constData(), + expires_time_t, flags)); - if (gpg_err_code(err) == GPG_ERR_NO_ERROR) return true; - else return false; + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) + return true; + else + return false; } -bool -GpgFrontend::GpgKeyManager::revSign(const GpgFrontend::GpgKey &key, const GpgFrontend::GpgKeySignature &signature) { - - auto &key_getter = GpgKeyGetter::getInstance(); - auto signing_key = key_getter.getKey(signature.keyid()); +bool GpgFrontend::GpgKeyManager::revSign( + const GpgFrontend::GpgKey &key, + const GpgFrontend::GpgKeySignature &signature) { - auto err = check_gpg_error(gpgme_op_revsig(ctx, gpgme_key_t(key), gpgme_key_t(signing_key), - signature.uid().data(), 0)); - if (gpg_err_code(err) == GPG_ERR_NO_ERROR) return true; - else return false; + auto &key_getter = GpgKeyGetter::GetInstance(); + auto signing_key = key_getter.GetKey(signature.keyid()); + auto err = check_gpg_error(gpgme_op_revsig(ctx, gpgme_key_t(key), + gpgme_key_t(signing_key), + signature.uid().data(), 0)); + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) + return true; + else + return false; } -bool GpgFrontend::GpgKeyManager::setExpire(const GpgFrontend::GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, - std::unique_ptr<QDateTime> &expires) { - unsigned long expires_time = 0; - if (expires != nullptr) { - qDebug() << "Expire Datetime" << expires->toString(); - expires_time = QDateTime::currentDateTime().secsTo(*expires); - } +bool GpgFrontend::GpgKeyManager::setExpire( + const GpgFrontend::GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, + std::unique_ptr<QDateTime> &expires) { + unsigned long expires_time = 0; + if (expires != nullptr) { + qDebug() << "Expire Datetime" << expires->toString(); + expires_time = QDateTime::currentDateTime().secsTo(*expires); + } - const char *sub_fprs = nullptr; + const char *sub_fprs = nullptr; - if (subkey != nullptr) sub_fprs = subkey->fpr().toUtf8().constData(); + if (subkey != nullptr) + sub_fprs = subkey->fpr().c_str(); - auto err = check_gpg_error(gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, sub_fprs, 0)); - if (gpg_err_code(err) == GPG_ERR_NO_ERROR) return true; - else return false; + auto err = check_gpg_error( + gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, sub_fprs, 0)); + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) + return true; + else + return false; } diff --git a/include/gpg/function/GpgKeyManager.h b/src/gpg/function/GpgKeyManager.h index 0c11e1dc..87557baf 100644 --- a/include/gpg/function/GpgKeyManager.h +++ b/src/gpg/function/GpgKeyManager.h @@ -22,41 +22,36 @@ * */ - #ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H #define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H -#include "GpgFrontend.h" -#include "gpg/GpgModel.h" #include "gpg/GpgContext.h" #include "gpg/GpgFunctionObject.h" +#include "gpg/GpgModel.h" namespace GpgFrontend { - class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { - public: - - /** - * Sign a key pair(actually a certain uid) - * @param target target key pair - * @param uid target - * @param expires expire date and time of the signature - * @return if successful - */ - bool signKey(const GpgKey &target, KeyArgsList &keys, const QString &uid, - std::unique_ptr<QDateTime> &expires); - - bool revSign(const GpgKey &key, const GpgKeySignature &signature); - - bool setExpire(const GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, std::unique_ptr<QDateTime> &expires); - - private: +class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { +public: + /** + * Sign a key pair(actually a certain uid) + * @param target target key pair + * @param uid target + * @param expires expire date and time of the signature + * @return if successful + */ + bool signKey(const GpgKey &target, KeyArgsList &keys, const QString &uid, + std::unique_ptr<QDateTime> &expires); - GpgContext &ctx = GpgContext::getInstance(); + bool revSign(const GpgKey &key, const GpgKeySignature &signature); - }; + bool setExpire(const GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, + std::unique_ptr<QDateTime> &expires); -} +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; +} // namespace GpgFrontend -#endif //GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H +#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp new file mode 100644 index 00000000..6eed26f1 --- /dev/null +++ b/src/gpg/function/GpgKeyOpera.cpp @@ -0,0 +1,191 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "gpg/function/GpgKeyOpera.h" +#include "gpg/GpgConstants.h" +#include "gpg/GpgGenKeyInfo.h" +#include "gpg/function/GpgCommandExecutor.h" + +/** + * Delete keys + * @param uidList key ids + */ +void GpgFrontend::GpgKeyOpera::DeleteKeys( + GpgFrontend::KeyIdArgsListPtr uid_list) { + + GpgError err; + gpgme_key_t key; + + for (const auto &tmp : *uid_list) { + + err = gpgme_op_keylist_start(ctx, tmp.c_str(), 0); + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); + + err = gpgme_op_keylist_next(ctx, &key); + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); + + err = gpgme_op_keylist_end(ctx); + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); + + err = gpgme_op_delete(ctx, key, 1); + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); + } +} + +/** + * Set the expire date and time of a key pair(actually the master key) or subkey + * @param key target key pair + * @param subkey null if master key + * @param expires date and time + * @return if successful + */ +void GpgFrontend::GpgKeyOpera::SetExpire(const GpgKey &key, + std::unique_ptr<GpgSubKey> &subkey, + std::unique_ptr<QDateTime> &expires) { + unsigned long expires_time = 0; + if (expires != nullptr) { + qDebug() << "Expire Datetime" << expires->toString(); + expires_time = QDateTime::currentDateTime().secsTo(*expires); + } + + const char *sub_fprs = nullptr; + + if (subkey != nullptr) + sub_fprs = subkey->fpr().c_str(); + + auto err = + gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, sub_fprs, 0); + + assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); +} + +/** + * Generate revoke cert of a key pair + * @param key target key pair + * @param outputFileName out file name(path) + * @return the process doing this job + */ +void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( + const GpgKey &key, const std::string &output_file_name) { + GpgCommandExecutor::GetInstance().Execute( + {"--command-fd", "0", "--status-fd", "1", "-o", output_file_name.c_str(), + "--gen-revoke", key.fpr().c_str()}, + [](QProcess *proc) -> void { + qDebug() << "Function Called" << proc; + // Code From Gpg4Win + while (proc->canReadLine()) { + const QString line = QString::fromUtf8(proc->readLine()).trimmed(); + if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) { + proc->write("y\n"); + } else if (line == + QLatin1String( + "[GNUPG:] GET_LINE ask_revocation_reason.code")) { + proc->write("0\n"); + } else if (line == + QLatin1String( + "[GNUPG:] GET_LINE ask_revocation_reason.text")) { + proc->write("\n"); + } else if (line == QLatin1String( + "[GNUPG:] GET_BOOL openfile.overwrite.okay")) { + // We asked before + proc->write("y\n"); + } else if (line == + QLatin1String( + "[GNUPG:] GET_BOOL ask_revocation_reason.okay")) { + proc->write("y\n"); + } + } + // Code From Gpg4Win + }); +} + +/** + * Generate a new key pair + * @param params key generation args + * @return error information + */ +GpgFrontend::GpgError +GpgFrontend::GpgKeyOpera::GenerateKey(std::unique_ptr<GenKeyInfo> params) { + + auto userid_utf8 = params->getUserid(); + const char *userid = userid_utf8.c_str(); + auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()); + const char *algo = algo_utf8.c_str(); + unsigned long expires = + QDateTime::currentDateTime().secsTo(params->getExpired()); + unsigned int flags = 0; + + if (!params->isSubKey()) + flags |= GPGME_CREATE_CERT; + if (params->isAllowEncryption()) + flags |= GPGME_CREATE_ENCR; + if (params->isAllowSigning()) + flags |= GPGME_CREATE_SIGN; + if (params->isAllowAuthentication()) + flags |= GPGME_CREATE_AUTH; + if (params->isNonExpired()) + flags |= GPGME_CREATE_NOEXPIRE; + if (params->isNoPassPhrase()) + flags |= GPGME_CREATE_NOPASSWD; + + auto err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); + return check_gpg_error(err); +} + +/** + * Generate a new subkey of a certain key pair + * @param key target key pair + * @param params opera args + * @return error info + */ +GpgFrontend::GpgError +GpgFrontend::GpgKeyOpera::GenerateSubkey(const GpgKey &key, + std::unique_ptr<GenKeyInfo> params) { + + if (!params->isSubKey()) + return GPG_ERR_CANCELED; + + auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()); + const char *algo = algo_utf8.c_str(); + unsigned long expires = + QDateTime::currentDateTime().secsTo(params->getExpired()); + unsigned int flags = 0; + + if (!params->isSubKey()) + flags |= GPGME_CREATE_CERT; + if (params->isAllowEncryption()) + flags |= GPGME_CREATE_ENCR; + if (params->isAllowSigning()) + flags |= GPGME_CREATE_SIGN; + if (params->isAllowAuthentication()) + flags |= GPGME_CREATE_AUTH; + if (params->isNonExpired()) + flags |= GPGME_CREATE_NOEXPIRE; + + flags |= GPGME_CREATE_NOPASSWD; + + auto err = + gpgme_op_createsubkey(ctx, gpgme_key_t(key), algo, 0, expires, flags); + return check_gpg_error(err); +}
\ No newline at end of file diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h new file mode 100644 index 00000000..06ca26bd --- /dev/null +++ b/src/gpg/function/GpgKeyOpera.h @@ -0,0 +1,54 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef _GPGKEYOPERA_H +#define _GPGKEYOPERA_H + +#include "gpg/GpgConstants.h" +#include "gpg/GpgContext.h" +#include "gpg/GpgModel.h" + +namespace GpgFrontend { +class GenKeyInfo; +class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { +public: + void DeleteKeys(KeyIdArgsListPtr uid_list); + + void SetExpire(const GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, + std::unique_ptr<QDateTime> &expires); + + void GenerateRevokeCert(const GpgKey &key, + const std::string &output_file_name); + + GpgFrontend::GpgError GenerateKey(std::unique_ptr<GenKeyInfo> params); + + GpgFrontend::GpgError GenerateSubkey(const GpgKey &key, + std::unique_ptr<GenKeyInfo> params); + +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; +} // namespace GpgFrontend + +#endif // _GPGKEYOPERA_H
\ No newline at end of file diff --git a/src/gpg/function/UidOperator.cpp b/src/gpg/function/UidOperator.cpp index 91fe70fe..937396d4 100644 --- a/src/gpg/function/UidOperator.cpp +++ b/src/gpg/function/UidOperator.cpp @@ -24,22 +24,35 @@ #include "gpg/function/UidOperator.h" -bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey &key, const GpgFrontend::GpgUID &uid) { - QString userid = QString("%1 (%3) <%2>").arg(uid.name(), uid.email(), uid.comment()); - auto err = gpgme_op_adduid(ctx, gpgme_key_t(key), userid.toUtf8().constData(), 0); - if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) return true; - else return false; +bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey &key, + const GpgFrontend::GpgUID &uid) { + QString userid = + QString("%1 (%3) <%2>") + .arg(uid.name().c_str(), uid.email().c_str(), uid.comment().c_str()); + auto err = + gpgme_op_adduid(ctx, gpgme_key_t(key), userid.toUtf8().constData(), 0); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) + return true; + else + return false; } -bool GpgFrontend::UidOperator::revUID(const GpgFrontend::GpgKey &key, const GpgFrontend::GpgUID &uid) { - auto err = check_gpg_error(gpgme_op_revuid(ctx, gpgme_key_t(key), uid.uid().toUtf8().constData(), 0)); - if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) return true; - else return false; +bool GpgFrontend::UidOperator::revUID(const GpgFrontend::GpgKey &key, + const GpgFrontend::GpgUID &uid) { + auto err = check_gpg_error( + gpgme_op_revuid(ctx, gpgme_key_t(key), uid.uid().c_str(), 0)); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) + return true; + else + return false; } -bool GpgFrontend::UidOperator::setPrimaryUID(const GpgFrontend::GpgKey &key, const GpgFrontend::GpgUID &uid) { - auto err = check_gpg_error(gpgme_op_set_uid_flag(ctx, gpgme_key_t(key), - uid.uid().toUtf8().constData(), "primary", nullptr)); - if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) return true; - else return false; +bool GpgFrontend::UidOperator::setPrimaryUID(const GpgFrontend::GpgKey &key, + const GpgFrontend::GpgUID &uid) { + auto err = check_gpg_error(gpgme_op_set_uid_flag( + ctx, gpgme_key_t(key), uid.uid().c_str(), "primary", nullptr)); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) + return true; + else + return false; } diff --git a/include/gpg/function/UidOperator.h b/src/gpg/function/UidOperator.h index 352f210e..d5bbcb3b 100644 --- a/include/gpg/function/UidOperator.h +++ b/src/gpg/function/UidOperator.h @@ -25,47 +25,41 @@ #ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H #define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H -#include "GpgFrontend.h" -#include "gpg/GpgModel.h" #include "gpg/GpgContext.h" +#include "gpg/GpgModel.h" namespace GpgFrontend { - class UidOperator { - public: - - /** - * create a new uid in certain key pair - * @param key target key pair - * @param uid uid args - * @return if successful - */ - bool addUID(const GpgKey &key, const GpgUID &uid); - - /** - * Revoke(Delete) UID from certain key pair - * @param key target key pair - * @param uid target uid - * @return if successful - */ - bool revUID(const GpgKey &key, const GpgUID &uid); - - - /** - * Set one of a uid of a key pair as primary - * @param key target key pair - * @param uid target uid - * @return if successful - */ - bool setPrimaryUID(const GpgKey &key, const GpgUID &uid); - - private: +class UidOperator { +public: + /** + * create a new uid in certain key pair + * @param key target key pair + * @param uid uid args + * @return if successful + */ + bool addUID(const GpgKey &key, const GpgUID &uid); - GpgContext &ctx = GpgContext::getInstance(); + /** + * Revoke(Delete) UID from certain key pair + * @param key target key pair + * @param uid target uid + * @return if successful + */ + bool revUID(const GpgKey &key, const GpgUID &uid); - }; + /** + * Set one of a uid of a key pair as primary + * @param key target key pair + * @param uid target uid + * @return if successful + */ + bool setPrimaryUID(const GpgKey &key, const GpgUID &uid); -} +private: + GpgContext &ctx = GpgContext::GetInstance(); +}; +} // namespace GpgFrontend -#endif //GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H +#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H diff --git a/src/gpg/gpg_context/GpgContext.cpp b/src/gpg/gpg_context/GpgContext.cpp index a892603c..a9b83d92 100644 --- a/src/gpg/gpg_context/GpgContext.cpp +++ b/src/gpg/gpg_context/GpgContext.cpp @@ -23,10 +23,9 @@ */ #include "gpg/GpgContext.h" -#include "ui/WaitingDialog.h" #include <functional> -#include <unistd.h> /* contains read/write */ +#include <unistd.h> /* contains read/write */ #ifdef _WIN32 @@ -34,248 +33,97 @@ #endif -#define INT2VOIDP(i) (void*)(uintptr_t)(i) +#define INT2VOIDP(i) (void *)(uintptr_t)(i) namespace GpgFrontend { - /** - * Constructor - * Set up gpgme-context, set paths to app-run path - */ - GpgContext::GpgContext() { - - gpgme_ctx_t _p_ctx; - err = gpgme_new(&_p_ctx); - check_gpg_error(err); - _ctx_ref = CtxRefHandler(_p_ctx, [&](gpgme_ctx_t ctx) { gpgme_release(ctx); }); - - gpgme_engine_info_t engineInfo; - engineInfo = gpgme_ctx_get_engine_info(*this); - - // Check ENV before running - bool check_pass = false, find_openpgp = false, find_gpgconf = false, find_assuan = false, find_cms = false; - while (engineInfo != nullptr) { - qDebug() << gpgme_get_protocol_name(engineInfo->protocol) << engineInfo->file_name << engineInfo->protocol - << engineInfo->home_dir << engineInfo->version; - if (engineInfo->protocol == GPGME_PROTOCOL_GPGCONF && strcmp(engineInfo->version, "1.0.0") != 0) - find_gpgconf = true; - if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP && strcmp(engineInfo->version, "1.0.0") != 0) - find_openpgp = true, info.appPath = engineInfo->file_name; - if (engineInfo->protocol == GPGME_PROTOCOL_CMS && strcmp(engineInfo->version, "1.0.0") != 0) - find_cms = true; - if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN) - find_assuan = true; - engineInfo = engineInfo->next; - } - - if (find_gpgconf && find_openpgp && find_cms && find_assuan) - check_pass = true; - - if (!check_pass) { - good = false; - return; - } else good = true; - - - /** Setting the output type must be done at the beginning */ - /** think this means ascii-armor --> ? */ - gpgme_set_armor(*this, 1) ; - // Speed up loading process - gpgme_set_offline(*this, 1); - /** passphrase-callback */ - gpgme_set_passphrase_cb(*this, passphraseCb, this); - - gpgme_set_keylist_mode(*this, - GPGME_KEYLIST_MODE_LOCAL - | GPGME_KEYLIST_MODE_WITH_SECRET - | GPGME_KEYLIST_MODE_SIGS - | GPGME_KEYLIST_MODE_SIG_NOTATIONS - | GPGME_KEYLIST_MODE_WITH_TOFU); - - /** check if app is called with -d from command line */ - if (qApp->arguments().contains("-d")) { - qDebug() << "gpgme_data_t debug on"; - debug = true; - } else debug = false; - - slotRefreshKeyList(); - } - - bool GpgContext::isGood() const { - return good; - } - - /** - * The Passphrase window, if not provided by env-Var GPG_AGENT_INFO - * originally copied from http://basket.kde.org/ (kgpgme.cpp), but modified - */ - gpgme_error_t GpgContext::passphraseCb(void *hook, const char *uid_hint, - const char *passphrase_info, - int last_was_bad, int fd) { - auto *gpg = static_cast<GpgContext *>(hook); - return gpg->passphrase(uid_hint, passphrase_info, last_was_bad, fd); - } - - gpgme_error_t GpgContext::passphrase(const char *uid_hint, - const char * /*passphrase_info*/, - int last_was_bad, int fd) { - - gpgme_error_t returnValue = GPG_ERR_CANCELED; - QString passwordDialogMessage; - QString gpgHint = QString::fromUtf8(uid_hint); - bool result; - -#ifdef _WIN32 - DWORD written; - auto hd = INT2VOIDP(fd); -#endif - - if (last_was_bad) { - passwordDialogMessage += "<i> Wrong password. </i><br><br>\n\n"; - clearPasswordCache(); - } - - /** if uid provided */ - if (!gpgHint.isEmpty()) { - // remove UID, leave only username & email - gpgHint.remove(0, gpgHint.indexOf(" ")); - passwordDialogMessage += "<b> Enter Password for </b><br>" + gpgHint + "<br>"; - } - - if (mPasswordCache.isEmpty()) { - QString password = QInputDialog::getText(QApplication::activeWindow(), "Enter Password", - passwordDialogMessage, QLineEdit::Password, - "", &result); - - if (result) mPasswordCache = password.toUtf8(); - } else result = true; - - if (result) { - -#ifndef _WIN32 - if (write(fd, mPasswordCache.data(), mPasswordCache.length()) == -1) qDebug() << "something is terribly broken"; -#else - WriteFile(hd, mPasswordCache.data(), mPasswordCache.length(), &written, 0); -#endif - returnValue = GPG_ERR_NO_ERROR; - } - -#ifndef _WIN32 - if (write(fd, "\n", 1) == -1) qDebug() << "something is terribly broken"; -#else - WriteFile(hd, "\n", 1, &written, nullptr); - - /* program will hang on cancel if hd not closed */ - if (!result) CloseHandle(hd); -#endif - - return returnValue; - } - - /** also from kgpgme.cpp, seems to clear password from mem */ - void GpgContext::clearPasswordCache() { - if (mPasswordCache.size() > 0) { - mPasswordCache.fill('\0'); - mPasswordCache.truncate(0); - } - } - - // error-handling - gpgme_error_t check_gpg_error(gpgme_error_t err, const QString &comment) { - //if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) { - if (gpg_err_code(err) != GPG_ERR_NO_ERROR) { - qDebug() << "[Error " << gpg_err_code(err) - << "] Source: " << gpgme_strsource(err) << " Description: " << gpgme_strerror(err); - } - return err; - } - - gpgme_error_t check_gpg_error(gpgme_error_t err) { - //if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) { - if (gpg_err_code(err) != GPG_ERR_NO_ERROR) { - qDebug() << "[Error " << gpg_err_code(err) - << "] Source: " << gpgme_strsource(err) << " Description: " << gpgme_strerror(err); - } - return err; - } - - /** return type should be gpgme_error_t*/ - - - - /* - * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace, - * GPGME doesn't recognise the Message as encrypted. This function adds '\n' - * before the PGP-Begin-Block, if missing. - */ - void GpgContext::preventNoDataErr(QByteArray *in) { - int block_start = in->indexOf(GpgConstants::PGP_CRYPT_BEGIN); - if (block_start > 0 && in->at(block_start - 1) != '\n') { - in->insert(block_start, '\n'); - } - block_start = in->indexOf(GpgConstants::PGP_SIGNED_BEGIN); - if (block_start > 0 && in->at(block_start - 1) != '\n') { - in->insert(block_start, '\n'); - } - } - - /* - * isSigned returns: - * - 0, if text isn't signed at all - * - 1, if text is partially signed - * - 2, if text is completly signed - */ - int GpgContext::textIsSigned(const QByteArray &text) { - if (text.trimmed().startsWith(GpgConstants::PGP_SIGNED_BEGIN) && - text.trimmed().endsWith(GpgConstants::PGP_SIGNED_END)) - return 2; - else if (text.contains(GpgConstants::PGP_SIGNED_BEGIN) && text.contains(GpgConstants::PGP_SIGNED_END)) - return 1; - - else return 0; - } - - QString GpgContext::beautifyFingerprint(QString fingerprint) { - uint len = fingerprint.length(); - if ((len > 0) && (len % 4 == 0)) - for (uint n = 0; 4 * (n + 1) < len; ++n) fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); - return fingerprint; - } - - void GpgContext::slotRefreshKeyList() { - qDebug() << "Refreshing Keys"; - this->fetch_keys(); - emit signalKeyInfoChanged(); - } - - QString GpgContext::getGpgmeVersion() { - return {gpgme_check_version(nullptr)}; - } - - const GpgKeyList &GpgContext::getKeys() const { - return mKeyList; - } - - void GpgContext::slotUpdateKeyList(const QString &key_id) { - auto it = mKeyMap.find(key_id); - if (it != mKeyMap.end()) { - gpgme_key_t new_key_ref; - - auto gpgmeErr = gpgme_get_key(*this, key_id.toUtf8().constData(), &new_key_ref, 0); +/** + * Constructor + * Set up gpgme-context, set paths to app-run path + */ +GpgContext::GpgContext() { + + gpgme_ctx_t _p_ctx; + auto err = gpgme_new(&_p_ctx); + check_gpg_error(err); + _ctx_ref = + CtxRefHandler(_p_ctx, [&](gpgme_ctx_t ctx) { gpgme_release(ctx); }); + + gpgme_engine_info_t engineInfo; + engineInfo = gpgme_ctx_get_engine_info(*this); + + // Check ENV before running + bool check_pass = false, find_openpgp = false, find_gpgconf = false, + find_assuan = false, find_cms = false; + while (engineInfo != nullptr) { + qDebug() << gpgme_get_protocol_name(engineInfo->protocol) + << engineInfo->file_name << engineInfo->protocol + << engineInfo->home_dir << engineInfo->version; + if (engineInfo->protocol == GPGME_PROTOCOL_GPGCONF && + strcmp(engineInfo->version, "1.0.0") != 0) + find_gpgconf = true; + if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP && + strcmp(engineInfo->version, "1.0.0") != 0) + find_openpgp = true, info.appPath = engineInfo->file_name; + if (engineInfo->protocol == GPGME_PROTOCOL_CMS && + strcmp(engineInfo->version, "1.0.0") != 0) + find_cms = true; + if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN) + find_assuan = true; + engineInfo = engineInfo->next; + } + + if (find_gpgconf && find_openpgp && find_cms && find_assuan) + check_pass = true; + + if (!check_pass) { + good_ = false; + return; + } else + good_ = true; + + /** Setting the output type must be done at the beginning */ + /** think this means ascii-armor --> ? */ + gpgme_set_armor(*this, 1); + // Speed up loading process + gpgme_set_offline(*this, 1); + + gpgme_set_keylist_mode( + *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET | + GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS | + GPGME_KEYLIST_MODE_WITH_TOFU); +} - if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) { - gpgmeErr = gpgme_get_key(*this, key_id.toUtf8().constData(), &new_key_ref, 1); +bool GpgContext::good() const { return good_; } - if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) - throw std::runtime_error("key_id not found in key database"); - } +/** also from kgpgme.cpp, seems to clear password from mem */ +void GpgContext::clearPasswordCache() { + if (mPasswordCache.size() > 0) { + mPasswordCache.fill('\0'); + mPasswordCache.truncate(0); + } +} - if (new_key_ref != nullptr) { - it->second = std::move(GpgKey(std::move(new_key_ref))); - emit signalKeyInfoChanged(); - } +/** return type should be gpgme_error_t*/ - } - } +/* + * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace, + * GPGME doesn't recognise the Message as encrypted. This function adds '\n' + * before the PGP-Begin-Block, if missing. + */ +void GpgContext::preventNoDataErr(QByteArray *in) { + int block_start = in->indexOf(GpgConstants::PGP_CRYPT_BEGIN); + if (block_start > 0 && in->at(block_start - 1) != '\n') { + in->insert(block_start, '\n'); + } + block_start = in->indexOf(GpgConstants::PGP_SIGNED_BEGIN); + if (block_start > 0 && in->at(block_start - 1) != '\n') { + in->insert(block_start, '\n'); + } +} +std::string GpgContext::getGpgmeVersion() { + return {gpgme_check_version(nullptr)}; } + +} // namespace GpgFrontend diff --git a/src/gpg/gpg_context/GpgContextKeyInfo.cpp b/src/gpg/gpg_context/GpgContextKeyInfo.cpp deleted file mode 100644 index 3fa6a23b..00000000 --- a/src/gpg/gpg_context/GpgContextKeyInfo.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/GpgContext.h" - -/** - * check if key can sign(actually) - * @param key target key - * @return if key sign - */ -bool GpgFrontend::GpgContext::checkIfKeyCanSign(const GpgKey &key) { - auto subkeys = key.subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool { - return subkey.secret() && subkey.can_sign() && !subkey.disabled() && !subkey.revoked() && !subkey.expired(); - })) - return true; - else return false; -} - -/** - * check if key can certify(actually) - * @param key target key - * @return if key certify - */ -bool GpgFrontend::GpgContext::checkIfKeyCanCert(const GpgKey &key) { - return key.has_master_key() && !key.expired() && !key.revoked() && !key.disabled(); -} - -/** - * check if key can authenticate(actually) - * @param key target key - * @return if key authenticate - */ -bool GpgFrontend::GpgContext::checkIfKeyCanAuth(const GpgKey &key) { - auto subkeys = key.subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool { - return subkey.secret() && subkey.can_authenticate() && !subkey.disabled() && !subkey.revoked() && !subkey.expired(); - })) - return true; - else return false; -} - -/** - * check if key can encrypt(actually) - * @param key target key - * @return if key encrypt - */ -bool GpgFrontend::GpgContext::checkIfKeyCanEncr(const GpgKey &key) { - auto subkeys = key.subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool { - return subkey.can_encrypt() && !subkey.disabled() && !subkey.revoked() && !subkey.expired(); - })) - return true; - else return false; -} diff --git a/src/gpg/gpg_context/GpgContextKeyOpera.cpp b/src/gpg/gpg_context/GpgContextKeyOpera.cpp deleted file mode 100644 index 63b266ca..00000000 --- a/src/gpg/gpg_context/GpgContextKeyOpera.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/GpgContext.h" - -/** - * Import key pair - * @param inBuffer input byte array - * @return Import information - */ -GpgImportInformation GpgFrontend::GpgContext::importKey(QByteArray inBuffer) { - auto *importInformation = new GpgImportInformation(); - err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); - check_gpg_error(err); - err = gpgme_op_import(*this, in); - gpgme_import_result_t result; - - result = gpgme_op_import_result(*this); - - if (result->unchanged) importInformation->unchanged = result->unchanged; - if (result->considered) importInformation->considered = result->considered; - if (result->no_user_id) importInformation->no_user_id = result->no_user_id; - if (result->imported) importInformation->imported = result->imported; - if (result->imported_rsa) importInformation->imported_rsa = result->imported_rsa; - if (result->unchanged) importInformation->unchanged = result->unchanged; - if (result->new_user_ids) importInformation->new_user_ids = result->new_user_ids; - if (result->new_sub_keys) importInformation->new_sub_keys = result->new_sub_keys; - if (result->new_signatures) importInformation->new_signatures = result->new_signatures; - if (result->new_revocations) importInformation->new_revocations = result->new_revocations; - if (result->secret_read) importInformation->secret_read = result->secret_read; - if (result->secret_imported) importInformation->secret_imported = result->secret_imported; - if (result->secret_unchanged) importInformation->secret_unchanged = result->secret_unchanged; - if (result->not_imported) importInformation->not_imported = result->not_imported; - - gpgme_import_status_t status = result->imports; - while (status != nullptr) { - GpgImportedKey key; - key.importStatus = static_cast<int>(status->status); - key.fpr = status->fpr; - importInformation->importedKeys.emplace_back(key); - status = status->next; - } - check_gpg_error(err); - emit signalKeyDBChanged(); - gpgme_data_release(in); - return *importInformation; -} - -/** - * Generate a new key pair - * @param params key generation args - * @return error information - */ -gpgme_error_t GpgFrontend::GpgContext::generateKey(GenKeyInfo *params) { - - auto userid_utf8 = params->getUserid().toUtf8(); - const char *userid = userid_utf8.constData(); - auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()).toUtf8(); - const char *algo = algo_utf8.constData(); - unsigned long expires = QDateTime::currentDateTime().secsTo(params->getExpired()); - unsigned int flags = 0; - - if (!params->isSubKey()) flags |= GPGME_CREATE_CERT; - if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR; - if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN; - if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH; - if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; - if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; - - err = gpgme_op_createkey(*this, userid, algo, 0, expires, nullptr, flags); - - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { - check_gpg_error(err); - return err; - } else { - emit signalKeyDBChanged(); - return err; - } -} - -/** - * Export Key - * @param uidList key ids - * @param outBuffer output byte array - * @return if success - */ -bool GpgFrontend::GpgContext::exportKeys(QStringList *uidList, QByteArray *outBuffer) { - gpgme_data_t dataOut = nullptr; - outBuffer->resize(0); - - if (uidList->count() == 0) { - QMessageBox::critical(nullptr, "Export Keys Error", "No Keys Selected"); - return false; - } - - // Alleviate another crash problem caused by an unknown array out-of-bounds access - gpgme_ctx_t ctx = create_ctx(); - - for (int i = 0; i < uidList->count(); i++) { - err = gpgme_data_new(&dataOut); - check_gpg_error(err); - - err = gpgme_op_export(ctx, uidList->at(i).toUtf8().constData(), 0, dataOut); - check_gpg_error(err); - - qDebug() << "exportKeys read_bytes" << gpgme_data_seek(dataOut, 0, SEEK_END); - - err = readToBuffer(dataOut, outBuffer); - check_gpg_error(err); - gpgme_data_release(dataOut); - } - - gpgme_release(ctx); - - return true; -} - -/** - * Get and store all key pairs info - */ -void GpgFrontend::GpgContext::fetch_keys() { - - gpgme_error_t gpgmeError; - - gpgme_key_t key; - - qDebug() << "Clear List and Map"; - - mKeyList.clear(); - mKeyMap.clear(); - - auto &keys = mKeyList; - auto &keys_map = mKeyMap; - - qDebug() << "Set Key Listing Mode"; - - gpgmeError = gpgme_set_keylist_mode(*this, - GPGME_KEYLIST_MODE_LOCAL - | GPGME_KEYLIST_MODE_WITH_SECRET - | GPGME_KEYLIST_MODE_SIGS - | GPGME_KEYLIST_MODE_SIG_NOTATIONS - | GPGME_KEYLIST_MODE_WITH_TOFU); - if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) { - check_gpg_error(gpgmeError); - return; - } - - qDebug() << "Operate KeyList Start"; - - gpgmeError = gpgme_op_keylist_start(*this, nullptr, 0); - if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) { - check_gpg_error(gpgmeError); - return; - } - - qDebug() << "Start Loop"; - - while ((gpgmeError = gpgme_op_keylist_next(*this, &key)) == GPG_ERR_NO_ERROR) { - if (!key->subkeys) - continue; - - qDebug() << "Append Key" << key->subkeys->keyid; - - keys.emplace_back(gpgme_key_t(key)); - keys_map.insert(keys.back().id(), &keys.back()); - gpgme_key_unref(key); - } - - - if (gpg_err_code(gpgmeError) != GPG_ERR_EOF) { - check_gpg_error(gpgmeError); - return; - } - - gpgmeError = gpgme_op_keylist_end(*this); - if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) { - check_gpg_error(gpgmeError); - return; - } - - qDebug() << "Operate KeyList End"; - - mKeyList = keys; -} - -/** - * Delete keys - * @param uidList key ids - */ -void GpgFrontend::GpgContext::deleteKeys(QStringList *uidList) { - - gpgme_error_t error; - gpgme_key_t key; - - for (const auto &tmp : *uidList) { - - error = gpgme_op_keylist_start(*this, tmp.toUtf8().constData(), 0); - if (error != GPG_ERR_NO_ERROR) { - check_gpg_error(error); - continue; - } - - error = gpgme_op_keylist_next(*this, &key); - if (error != GPG_ERR_NO_ERROR) { - check_gpg_error(error); - continue; - } - - error = gpgme_op_keylist_end(*this); - if (error != GPG_ERR_NO_ERROR) { - check_gpg_error(error); - continue; - } - - error = gpgme_op_delete(*this, key, 1); - if (error != GPG_ERR_NO_ERROR) { - check_gpg_error(error); - continue; - } - - } - emit signalKeyDBChanged(); -} - -/** - * Export keys - * @param keys keys used - * @param outBuffer output byte array - * @return if success - */ -bool GpgFrontend::GpgContext::exportKeys(const QVector <GpgKey> &keys, QByteArray &outBuffer) { - gpgme_data_t data_out = nullptr; - outBuffer.resize(0); - - if (keys.empty()) { - QMessageBox::critical(nullptr, "Export Keys Error", "No Keys Selected"); - return false; - } - - for (const auto &key : keys) { - err = gpgme_data_new(&data_out); - check_gpg_error(err); - - err = gpgme_op_export(*this, key.id().toUtf8().constData(), 0, data_out); - check_gpg_error(err); - - gpgme_data_seek(data_out, 0, SEEK_END); - - err = readToBuffer(data_out, &outBuffer); - check_gpg_error(err); - gpgme_data_release(data_out); - } - - return true; -} - -/** - * Set the expire date and time of a key pair(actually the master key) or subkey - * @param key target key pair - * @param subkey null if master key - * @param expires date and time - * @return if successful - */ -bool GpgFrontend::GpgContext::setExpire(const GpgKey &key, std::unique_ptr <GpgSubKey> &subkey, - std::unique_ptr <QDateTime> &expires) { - unsigned long expires_time = 0; - if (expires != nullptr) { - qDebug() << "Expire Datetime" << expires->toString(); - expires_time = QDateTime::currentDateTime().secsTo(*expires); - } - - const char *sub_fprs = nullptr; - - if (subkey != nullptr) sub_fprs = subkey->fpr().toUtf8().constData(); - - auto gpgmeError = gpgme_op_setexpire(*this, gpgme_key_t(key), - expires_time, sub_fprs, 0); - if (gpgmeError == GPG_ERR_NO_ERROR) { - emit signalKeyUpdated(key.id()); - return true; - } else { - check_gpg_error(gpgmeError); - return false; - } -} - -/** - * Export the secret key of a key pair(including subkeys) - * @param key target key pair - * @param outBuffer output byte array - * @return if successful - */ -bool GpgFrontend::GpgContext::exportSecretKey(const GpgKey &key, QByteArray *outBuffer) const { - qDebug() << "Export Secret Key" << key.id(); - gpgme_key_t target_key[2] = { - gpgme_key_t(key), - nullptr - }; - - gpgme_data_t dataOut; - gpgme_data_new(&dataOut); - - // export private key to outBuffer - gpgme_error_t error = gpgme_op_export_keys(*this, target_key, GPGME_EXPORT_MODE_SECRET, dataOut); - - if (gpgme_err_code(error) != GPG_ERR_NO_ERROR) { - check_gpg_error(error); - gpgme_data_release(dataOut); - return false; - } - - readToBuffer(dataOut, outBuffer); - gpgme_data_release(dataOut); - return true; -} - -/** - * Generate revoke cert of a key pair - * @param key target key pair - * @param outputFileName out file name(path) - * @return the process doing this job - */ -void GpgFrontend::GpgContext::generateRevokeCert(const GpgKey &key, const QString &outputFileName) { - executeGpgCommand({ - "--command-fd", - "0", - "--status-fd", - "1", - //"--no-tty", - "-o", - outputFileName, - "--gen-revoke", - key.fpr() - }, - [](QProcess *proc) -> void { - qDebug() << "Function Called" << proc; - // Code From Gpg4Win - while (proc->canReadLine()) { - const QString line = QString::fromUtf8(proc->readLine()).trimmed(); - if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) { - proc->write("y\n"); - } else if (line == QLatin1String( - "[GNUPG:] GET_LINE ask_revocation_reason.code")) { - proc->write("0\n"); - } else if (line == QLatin1String( - "[GNUPG:] GET_LINE ask_revocation_reason.text")) { - proc->write("\n"); - } else if (line == QLatin1String( - "[GNUPG:] GET_BOOL openfile.overwrite.okay")) { - // We asked before - proc->write("y\n"); - } else if (line == QLatin1String( - "[GNUPG:] GET_BOOL ask_revocation_reason.okay")) { - proc->write("y\n"); - } - } - // Code From Gpg4Win - } - ); -} diff --git a/src/gpg/gpg_context/GpgContextSubkeyOpera.cpp b/src/gpg/gpg_context/GpgContextSubkeyOpera.cpp deleted file mode 100644 index 7e73db18..00000000 --- a/src/gpg/gpg_context/GpgContextSubkeyOpera.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/GpgContext.h" - -/** - * Generate a new subkey of a certain key pair - * @param key target key pair - * @param params opera args - * @return error info - */ -gpgme_error_t GpgFrontend::GpgContext::generateSubkey(const GpgKey &key, GenKeyInfo *params) { - - if (!params->isSubKey()) return GPG_ERR_CANCELED; - - auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()).toUtf8(); - const char *algo = algo_utf8.constData(); - unsigned long expires = QDateTime::currentDateTime().secsTo(params->getExpired()); - unsigned int flags = 0; - - if (!params->isSubKey()) flags |= GPGME_CREATE_CERT; - if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR; - if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN; - if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH; - if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; - - flags |= GPGME_CREATE_NOPASSWD; - - - auto gpgmeError = gpgme_op_createsubkey(*this, gpgme_key_t(key), - algo, 0, expires, flags); - if (gpgme_err_code(gpgmeError) == GPG_ERR_NO_ERROR) { - emit signalKeyUpdated(key.id()); - return gpgmeError; - } else { - check_gpg_error(gpgmeError); - return gpgmeError; - } -} - diff --git a/src/gpg/model/GpgData.cpp b/src/gpg/model/GpgData.cpp new file mode 100644 index 00000000..52e9cf28 --- /dev/null +++ b/src/gpg/model/GpgData.cpp @@ -0,0 +1,77 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "gpg/model/GpgData.h" + +GpgFrontend::GpgData::GpgData() { + gpgme_data_t data; + + gpgme_error_t err = gpgme_data_new(&data); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + + data_ = std::unique_ptr<struct gpgme_data, std::function<void(gpgme_data_t)>>( + std::move(data), [](gpgme_data_t t) { gpgme_data_release(t); }); +} + +GpgFrontend::GpgData::GpgData(void *buffer, size_t size, bool copy) { + gpgme_data_t data; + + gpgme_error_t err = + gpgme_data_new_from_mem(&data, (const char *)buffer, size, copy); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + + data_ = std::unique_ptr<struct gpgme_data, std::function<void(gpgme_data_t)>>( + std::move(data), [](gpgme_data_t t) { gpgme_data_release(t); }); +} + +/** + * Read gpgme-Data to QByteArray + * mainly from http://basket.kde.org/ (kgpgme.cpp) + */ +#define BUF_SIZE (32 * 1024) + +GpgFrontend::BypeArrayPtr GpgFrontend::GpgData::Read2Buffer() { + gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET); + gpgme_error_t err = gpg_error(GPG_ERR_NO_ERROR); + + BypeArrayPtr out_buffer = std::make_unique<QByteArray>(); + + if (ret) { + err = gpgme_err_code_from_errno(errno); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + } else { + char buf[BUF_SIZE + 2]; + + while ((ret = gpgme_data_read(*this, buf, BUF_SIZE)) > 0) { + const size_t size = out_buffer->size(); + out_buffer->resize(static_cast<int>(size + ret)); + memcpy(out_buffer->data() + size, buf, ret); + } + if (ret < 0) { + err = gpgme_err_code_from_errno(errno); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + } + } + return std::move(out_buffer); +}
\ No newline at end of file diff --git a/src/gpg/model/GpgData.h b/src/gpg/model/GpgData.h new file mode 100644 index 00000000..cb0c4ffd --- /dev/null +++ b/src/gpg/model/GpgData.h @@ -0,0 +1,48 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef _GPGDATA_H +#define _GPGDATA_H + +#include "gpg/GpgConstants.h" + +namespace GpgFrontend { + +class GpgData { +public: + GpgData(); + + GpgData(void *buffer, size_t size, bool copy = true); + + operator gpgme_data_t() { return data_.get(); } + + BypeArrayPtr Read2Buffer(); + +private: + std::unique_ptr<struct gpgme_data, std::function<void(gpgme_data_t)>> data_; +}; + +} // namespace GpgFrontend + +#endif // _GPGDATA_H
\ No newline at end of file diff --git a/src/gpg/model/GpgKey.cpp b/src/gpg/model/GpgKey.cpp new file mode 100644 index 00000000..800c1c23 --- /dev/null +++ b/src/gpg/model/GpgKey.cpp @@ -0,0 +1,110 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "gpg/model/GpgKey.h" + +GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) + : _key_ref(std::move(key), + [&](gpgme_key_t key) { gpgme_key_release(key); }) {} + +GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(_key_ref, k._key_ref); } + +GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept { + swap(_key_ref, k._key_ref); + return *this; +} + +std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>> +GpgFrontend::GpgKey::subKeys() const { + auto p_keys = std::make_unique<std::vector<GpgSubKey>>(); + auto next = _key_ref->subkeys; + while (next != nullptr) { + p_keys->push_back(std::move(GpgSubKey(next))); + next = next->next; + } + return p_keys; +} + +std::unique_ptr<std::vector<GpgFrontend::GpgUID>> +GpgFrontend::GpgKey::uids() const { + auto p_uids = std::make_unique<std::vector<GpgUID>>(); + auto uid_next = _key_ref->uids; + while (uid_next != nullptr) { + p_uids->push_back(std::move(GpgUID(uid_next))); + uid_next = uid_next->next; + } + return p_uids; +} + +bool GpgFrontend::GpgKey::CanSignActual() const { + auto subkeys = subKeys(); + if (std::any_of(subkeys->begin(), subkeys->end(), + [](const GpgSubKey &subkey) -> bool { + return subkey.secret() && subkey.can_sign() && + !subkey.disabled() && !subkey.revoked() && + !subkey.expired(); + })) + return true; + else + return false; +} + +bool GpgFrontend::GpgKey::CanAuthActual() const { + auto subkeys = subKeys(); + if (std::any_of(subkeys->begin(), subkeys->end(), + [](const GpgSubKey &subkey) -> bool { + return subkey.secret() && subkey.can_authenticate() && + !subkey.disabled() && !subkey.revoked() && + !subkey.expired(); + })) + return true; + else + return false; +} + +/** + * check if key can certify(actually) + * @param key target key + * @return if key certify + */ +bool GpgFrontend::GpgKey::CanCertActual() const { + return has_master_key() && !expired() && !revoked() && !disabled(); +} + +/** + * check if key can encrypt(actually) + * @param key target key + * @return if key encrypt + */ +bool GpgFrontend::GpgKey::CanEncrActual() const { + auto subkeys = subKeys(); + if (std::any_of(subkeys->begin(), subkeys->end(), + [](const GpgSubKey &subkey) -> bool { + return subkey.can_encrypt() && !subkey.disabled() && + !subkey.revoked() && !subkey.expired(); + })) + return true; + else + return false; +} diff --git a/src/gpg/model/GpgKey.h b/src/gpg/model/GpgKey.h new file mode 100644 index 00000000..f34fece1 --- /dev/null +++ b/src/gpg/model/GpgKey.h @@ -0,0 +1,145 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGKEY_H +#define GPGFRONTEND_GPGKEY_H + +#include "GpgSubKey.h" +#include "GpgUID.h" + +namespace GpgFrontend { + +class GpgKey { +public: + [[nodiscard]] bool good() const { return _key_ref == nullptr; } + + [[nodiscard]] std::string id() const { return _key_ref->subkeys->keyid; } + + [[nodiscard]] std::string name() const { return _key_ref->uids->name; }; + + [[nodiscard]] std::string email() const { return _key_ref->uids->email; } + + [[nodiscard]] std::string comment() const { return _key_ref->uids->comment; } + + [[nodiscard]] std::string fpr() const { return _key_ref->fpr; } + + [[nodiscard]] std::string protocol() const { + return gpgme_get_protocol_name(_key_ref->protocol); + } + + [[nodiscard]] std::string owner_trust() const { + switch (_key_ref->owner_trust) { + case GPGME_VALIDITY_UNKNOWN: + return "Unknown"; + case GPGME_VALIDITY_UNDEFINED: + return "Undefined"; + case GPGME_VALIDITY_NEVER: + return "Never"; + case GPGME_VALIDITY_MARGINAL: + return "Marginal"; + case GPGME_VALIDITY_FULL: + return "FULL"; + case GPGME_VALIDITY_ULTIMATE: + return "Ultimate"; + } + } + + [[nodiscard]] std::string pubkey_algo() const { + return gpgme_pubkey_algo_name(_key_ref->subkeys->pubkey_algo); + } + + [[nodiscard]] QDateTime last_update() const { + return QDateTime::fromTime_t(_key_ref->last_update); + } + + [[nodiscard]] QDateTime expires() const { + return QDateTime::fromTime_t(_key_ref->subkeys->expires); + }; + + [[nodiscard]] QDateTime create_time() const { + return QDateTime::fromTime_t(_key_ref->subkeys->timestamp); + }; + + [[nodiscard]] unsigned int length() const { + return _key_ref->subkeys->length; + } + + [[nodiscard]] bool can_encrypt() const { return _key_ref->can_encrypt; } + + [[nodiscard]] bool CanEncrActual() const; + + [[nodiscard]] bool can_sign() const { return _key_ref->can_sign; } + + [[nodiscard]] bool CanSignActual() const; + + [[nodiscard]] bool can_certify() const { return _key_ref->can_certify; } + + [[nodiscard]] bool CanCertActual() const; + + [[nodiscard]] bool can_authenticate() const { + return _key_ref->can_authenticate; + } + + [[nodiscard]] bool CanAuthActual() const; + + [[nodiscard]] bool is_private_key() const { return _key_ref->secret; } + + [[nodiscard]] bool expired() const { return _key_ref->expired; } + + [[nodiscard]] bool revoked() const { return _key_ref->revoked; } + + [[nodiscard]] bool disabled() const { return _key_ref->disabled; } + + [[nodiscard]] bool has_master_key() const { + return _key_ref->subkeys->secret; + } + + [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> subKeys() const; + + [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> uids() const; + + explicit GpgKey() = default; + + explicit GpgKey(gpgme_key_t &&key); + + GpgKey(const gpgme_key_t &key) = delete; + + GpgKey(GpgKey &&k) noexcept; + + GpgKey &operator=(GpgKey &&k) noexcept; + + GpgKey &operator=(const gpgme_key_t &key) = delete; + + explicit operator gpgme_key_t() const { return _key_ref.get(); } + +private: + using KeyRefHandler = + std::unique_ptr<struct _gpgme_key, std::function<void(gpgme_key_t)>>; + + KeyRefHandler _key_ref; +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGKEY_H diff --git a/src/gpg/GpgKeySignature.cpp b/src/gpg/model/GpgKeySignature.cpp index d7e7c53e..d7e7c53e 100644 --- a/src/gpg/GpgKeySignature.cpp +++ b/src/gpg/model/GpgKeySignature.cpp diff --git a/src/gpg/model/GpgKeySignature.h b/src/gpg/model/GpgKeySignature.h new file mode 100644 index 00000000..c91ab794 --- /dev/null +++ b/src/gpg/model/GpgKeySignature.h @@ -0,0 +1,84 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H +#define GPGFRONTEND_GPGKEYSIGNATURE_H + +#include "gpg/GpgConstants.h" + +#include <string> + +namespace GpgFrontend { + +class GpgKeySignature { +public: + [[nodiscard]] bool revoked() const { return _signature_ref->revoked; } + [[nodiscard]] bool expired() const { return _signature_ref->expired; } + [[nodiscard]] bool invalid() const { return _signature_ref->invalid; } + [[nodiscard]] bool exportable() const { return _signature_ref->exportable; } + + [[nodiscard]] gpgme_error_t status() const { return _signature_ref->status; } + + [[nodiscard]] std::string keyid() const { return _signature_ref->keyid; } + [[nodiscard]] std::string pubkey_algo() const { + return gpgme_pubkey_algo_name(_signature_ref->pubkey_algo); + } + + [[nodiscard]] QDateTime create_time() const { + return QDateTime::fromTime_t(_signature_ref->timestamp); + } + [[nodiscard]] QDateTime expire_time() const { + return QDateTime::fromTime_t(_signature_ref->expires); + } + + [[nodiscard]] std::string uid() const { return _signature_ref->uid; } + [[nodiscard]] std::string name() const { return _signature_ref->name; } + [[nodiscard]] std::string email() const { return _signature_ref->email; } + [[nodiscard]] std::string comment() const { return _signature_ref->comment; } + + GpgKeySignature() = default; + + ~GpgKeySignature() = default; + + explicit GpgKeySignature(gpgme_key_sig_t sig); + + GpgKeySignature(GpgKeySignature &&) noexcept = default; + + GpgKeySignature(const GpgKeySignature &) = delete; + + GpgKeySignature &operator=(GpgKeySignature &&) noexcept = default; + + GpgKeySignature &operator=(const GpgKeySignature &) = delete; + +private: + using KeySignatrueRefHandler = + std::unique_ptr<struct _gpgme_key_sig, + std::function<void(gpgme_key_sig_t)>>; + + KeySignatrueRefHandler _signature_ref = nullptr; +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGKEYSIGNATURE_H diff --git a/src/gpg/GpgSubKey.cpp b/src/gpg/model/GpgSubKey.cpp index 87476d56..87476d56 100644 --- a/src/gpg/GpgSubKey.cpp +++ b/src/gpg/model/GpgSubKey.cpp diff --git a/src/gpg/model/GpgSubKey.h b/src/gpg/model/GpgSubKey.h new file mode 100644 index 00000000..e474f5a9 --- /dev/null +++ b/src/gpg/model/GpgSubKey.h @@ -0,0 +1,99 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ +#ifndef GPGFRONTEND_GPGSUBKEY_H +#define GPGFRONTEND_GPGSUBKEY_H + +#include "gpg/GpgConstants.h" + +#include <string> + +namespace GpgFrontend { + +class GpgSubKey { +public: + [[nodiscard]] std::string id() const { return _subkey_ref->keyid; } + + [[nodiscard]] std::string fpr() const { return _subkey_ref->fpr; } + + [[nodiscard]] std::string pubkey_algo() const { + return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo); + } + + [[nodiscard]] unsigned int length() const { return _subkey_ref->length; } + + [[nodiscard]] bool can_encrypt() const { return _subkey_ref->can_encrypt; } + + [[nodiscard]] bool can_sign() const { return _subkey_ref->can_sign; } + + [[nodiscard]] bool can_certify() const { return _subkey_ref->can_certify; } + + [[nodiscard]] bool can_authenticate() const { + return _subkey_ref->can_authenticate; + } + + [[nodiscard]] bool is_private_key() const { return _subkey_ref->secret; } + + [[nodiscard]] bool expired() const { return _subkey_ref->expired; } + + [[nodiscard]] bool revoked() const { return _subkey_ref->revoked; } + + [[nodiscard]] bool disabled() const { return _subkey_ref->disabled; } + + [[nodiscard]] bool secret() const { return _subkey_ref->secret; } + + [[nodiscard]] bool is_cardkey() const { return _subkey_ref->is_cardkey; } + + [[nodiscard]] QDateTime timestamp() const { + return QDateTime::fromTime_t(_subkey_ref->timestamp); + } + + [[nodiscard]] QDateTime expires() const { + return QDateTime::fromTime_t(_subkey_ref->expires); + } + + GpgSubKey() = default; + + explicit GpgSubKey(gpgme_subkey_t subkey); + + GpgSubKey(GpgSubKey &&o) noexcept { swap(_subkey_ref, o._subkey_ref); } + + GpgSubKey(const GpgSubKey &) = delete; + + GpgSubKey &operator=(GpgSubKey &&o) noexcept { + swap(_subkey_ref, o._subkey_ref); + return *this; + }; + + GpgSubKey &operator=(const GpgSubKey &) = delete; + +private: + using SubkeyRefHandler = std::unique_ptr<struct _gpgme_subkey, + std::function<void(gpgme_subkey_t)>>; + + SubkeyRefHandler _subkey_ref = nullptr; +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGSUBKEY_H diff --git a/src/gpg/GpgUID.cpp b/src/gpg/model/GpgUID.cpp index ae58daf1..ae58daf1 100644 --- a/src/gpg/GpgUID.cpp +++ b/src/gpg/model/GpgUID.cpp diff --git a/src/gpg/model/GpgUID.h b/src/gpg/model/GpgUID.h new file mode 100644 index 00000000..dbe084b8 --- /dev/null +++ b/src/gpg/model/GpgUID.h @@ -0,0 +1,81 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGUID_H +#define GPGFRONTEND_GPGUID_H + +#include "GpgKeySignature.h" + +namespace GpgFrontend { + +class GpgUID { +public: + [[nodiscard]] std::string name() const { return _uid_ref->name; } + + [[nodiscard]] std::string email() const { return _uid_ref->email; } + + [[nodiscard]] std::string comment() const { return _uid_ref->comment; } + + [[nodiscard]] std::string uid() const { return _uid_ref->uid; } + + [[nodiscard]] bool revoked() const { return _uid_ref->revoked; } + + [[nodiscard]] bool invalid() const { return _uid_ref->invalid; } + + [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> + signatures() const { + auto sigs = std::make_unique<std::vector<GpgKeySignature>>(); + auto sig_next = _uid_ref->signatures; + while (sig_next != nullptr) { + sigs->push_back(GpgKeySignature(sig_next)); + sig_next = sig_next->next; + } + return sigs; + } + + GpgUID() = default; + + explicit GpgUID(gpgme_user_id_t uid); + + GpgUID(GpgUID &&o) noexcept { swap(_uid_ref, o._uid_ref); } + + GpgUID(const GpgUID &) = delete; + + GpgUID &operator=(GpgUID &&o) noexcept { + swap(_uid_ref, o._uid_ref); + return *this; + } + + GpgUID &operator=(const GpgUID &) = delete; + +private: + using UidRefHandler = std::unique_ptr<struct _gpgme_user_id, + std::function<void(gpgme_user_id_t)>>; + + UidRefHandler _uid_ref = nullptr; +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGUID_H
\ No newline at end of file diff --git a/src/gpg/result_analyse/DecryptResultAnalyse.cpp b/src/gpg/result_analyse/DecryptResultAnalyse.cpp index 351045c9..c18a0111 100644 --- a/src/gpg/result_analyse/DecryptResultAnalyse.cpp +++ b/src/gpg/result_analyse/DecryptResultAnalyse.cpp @@ -22,65 +22,70 @@ * */ -#include "gpg/function/GpgKeyGetter.h" #include "gpg/result_analyse/DecryptResultAnalyse.h" +#include "gpg/function/GpgKeyGetter.h" -GpgFrontend::DecryptResultAnalyse::DecryptResultAnalyse(GpgError error, GpgDecrResult result) : error(error), result(std::move(result)) {} +GpgFrontend::DecryptResultAnalyse::DecryptResultAnalyse(GpgError error, + GpgDecrResult result) + : error(error), result(std::move(result)) {} void GpgFrontend::DecryptResultAnalyse::do_analyse() { - stream << tr("[#] Decrypt Operation "); + stream << tr("[#] Decrypt Operation ").constData(); - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { - stream << tr("[Success]") << Qt::endl; - } else { - stream << tr("[Failed] ") << gpgme_strerror(error) << Qt::endl; - setStatus(-1); - if (result != nullptr && result->unsupported_algorithm != nullptr) { - stream << "------------>" << Qt::endl; - stream << tr("Unsupported Algo: ") << result->unsupported_algorithm << Qt::endl; - } + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { + stream << tr("[Success]").constData() << std::endl; + } else { + stream << tr("[Failed] ").constData() << gpgme_strerror(error) << std::endl; + setStatus(-1); + if (result != nullptr && result->unsupported_algorithm != nullptr) { + stream << "------------>" << std::endl; + stream << tr("Unsupported Algo: ").constData() + << result->unsupported_algorithm << std::endl; } + } - if (result != nullptr && result->recipients != nullptr) { - stream << "------------>" << Qt::endl; - if (result->file_name != nullptr) { - stream << tr("File Name: ") << result->file_name << Qt::endl; - stream << Qt::endl; - } + if (result != nullptr && result->recipients != nullptr) { + stream << "------------>" << std::endl; + if (result->file_name != nullptr) { + stream << tr("File Name: ").constData() << result->file_name << std::endl; + stream << std::endl; + } - auto reci = result->recipients; - if (reci != nullptr) - stream << tr("Recipient(s): ") << Qt::endl; - while (reci != nullptr) { - print_reci(stream, reci); - reci = reci->next; - } - stream << "<------------" << Qt::endl; + auto reci = result->recipients; + if (reci != nullptr) + stream << tr("Recipient(s): ").constData() << std::endl; + while (reci != nullptr) { + print_reci(stream, reci); + reci = reci->next; } + stream << "<------------" << std::endl; + } - stream << Qt::endl; + stream << std::endl; } -bool GpgFrontend::DecryptResultAnalyse::print_reci(QTextStream &stream, gpgme_recipient_t reci) { - bool keyFound = true; - stream << QApplication::tr(" {>} Recipient: "); +bool GpgFrontend::DecryptResultAnalyse::print_reci(std::stringstream &stream, + gpgme_recipient_t reci) { + bool keyFound = true; + stream << tr(" {>} Recipient: ").constData(); - auto key = GpgFrontend::GpgKeyGetter::getInstance().getKey(reci->keyid); - if(key.good()) { - stream << key.name().c_str(); - if (!key.email().empty()) { - stream << "<" << key.email().c_str() << ">"; - } - } else { - stream << "<Unknown>"; - setStatus(0); - keyFound = false; + auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(reci->keyid); + if (key.good()) { + stream << key.name().c_str(); + if (!key.email().empty()) { + stream << "<" << key.email().c_str() << ">"; } + } else { + stream << "<Unknown>"; + setStatus(0); + keyFound = false; + } - stream << Qt::endl; + stream << std::endl; - stream << tr(" Keu ID: ") << key.id().c_str() << Qt::endl; - stream << tr(" Public Algo: ") << gpgme_pubkey_algo_name(reci->pubkey_algo) << Qt::endl; + stream << tr(" Keu ID: ").constData() << key.id().c_str() << std::endl; + stream << tr(" Public Algo: ").constData() + << gpgme_pubkey_algo_name(reci->pubkey_algo) << std::endl; - return keyFound; + return keyFound; } diff --git a/include/gpg/result_analyse/DecryptResultAnalyse.h b/src/gpg/result_analyse/DecryptResultAnalyse.h index f741ac99..c9696159 100644 --- a/include/gpg/result_analyse/DecryptResultAnalyse.h +++ b/src/gpg/result_analyse/DecryptResultAnalyse.h @@ -25,29 +25,26 @@ #ifndef GPGFRONTEND_DECRYPTRESULTANALYSE_H #define GPGFRONTEND_DECRYPTRESULTANALYSE_H -#include "gpg/GpgConstants.h" #include "ResultAnalyse.h" +#include "gpg/GpgConstants.h" namespace GpgFrontend { - class DecryptResultAnalyse : public ResultAnalyse { - Q_OBJECT - public: - explicit DecryptResultAnalyse(GpgError error, GpgDecrResult result); - - protected: - - void do_analyse() final; - - private: +class DecryptResultAnalyse : public ResultAnalyse { + Q_OBJECT +public: + explicit DecryptResultAnalyse(GpgError error, GpgDecrResult result); - bool print_reci(QTextStream &stream, gpgme_recipient_t reci); +protected: + void do_analyse() final; - GpgError error; - GpgDecrResult result; - }; +private: + bool print_reci(std::stringstream &stream, gpgme_recipient_t reci); -} + GpgError error; + GpgDecrResult result; +}; +} // namespace GpgFrontend -#endif //GPGFRONTEND_DECRYPTRESULTANALYSE_H +#endif // GPGFRONTEND_DECRYPTRESULTANALYSE_H diff --git a/src/gpg/result_analyse/EncryptResultAnalyse.cpp b/src/gpg/result_analyse/EncryptResultAnalyse.cpp index fd7faf59..898550fd 100644 --- a/src/gpg/result_analyse/EncryptResultAnalyse.cpp +++ b/src/gpg/result_analyse/EncryptResultAnalyse.cpp @@ -24,35 +24,38 @@ #include "gpg/result_analyse/EncryptResultAnalyse.h" -GpgFrontend::EncryptResultAnalyse::EncryptResultAnalyse(GpgError error, GpgEncrResult result) : error(error), result(std::move(result)) {} +GpgFrontend::EncryptResultAnalyse::EncryptResultAnalyse(GpgError error, + GpgEncrResult result) + : error(error), result(std::move(result)) {} void GpgFrontend::EncryptResultAnalyse::do_analyse() { - qDebug() << "Start Encrypt Result Analyse"; - - stream << "[#] Encrypt Operation "; - - if(gpgme_err_code(error) == GPG_ERR_NO_ERROR) - stream << "[Success]" << Qt::endl; - else { - stream << "[Failed] " << gpgme_strerror(error) << Qt::endl; - setStatus(-1); - } - - if(!~status) { - stream << "------------>" << Qt::endl; - if (result != nullptr) { - stream << tr("Invalid Recipients: ") << Qt::endl; - auto inv_reci = result->invalid_recipients; - while (inv_reci != nullptr) { - stream << tr("Fingerprint: ") << inv_reci->fpr << Qt::endl; - stream << tr("Reason: ") << gpgme_strerror(inv_reci->reason) << Qt::endl; - stream << Qt::endl; - - inv_reci = inv_reci->next; - } - } - stream << "<------------" << Qt::endl; + qDebug() << "Start Encrypt Result Analyse"; + + stream << "[#] Encrypt Operation "; + + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + stream << "[Success]" << std::endl; + else { + stream << "[Failed] " << gpgme_strerror(error) << std::endl; + setStatus(-1); + } + + if (!~status) { + stream << "------------>" << std::endl; + if (result != nullptr) { + stream << tr("Invalid Recipients: ").constData() << std::endl; + auto inv_reci = result->invalid_recipients; + while (inv_reci != nullptr) { + stream << tr("Fingerprint: ").constData() << inv_reci->fpr << std::endl; + stream << tr("Reason: ").constData() << gpgme_strerror(inv_reci->reason) + << std::endl; + stream << std::endl; + + inv_reci = inv_reci->next; + } } + stream << "<------------" << std::endl; + } - stream << Qt::endl; + stream << std::endl; } diff --git a/include/gpg/result_analyse/EncryptResultAnalyse.h b/src/gpg/result_analyse/EncryptResultAnalyse.h index 70e5a5e0..31b83753 100644 --- a/include/gpg/result_analyse/EncryptResultAnalyse.h +++ b/src/gpg/result_analyse/EncryptResultAnalyse.h @@ -25,29 +25,22 @@ #ifndef GPGFRONTEND_ENCRYPTRESULTANALYSE_H #define GPGFRONTEND_ENCRYPTRESULTANALYSE_H -#include "gpg/GpgConstants.h" #include "ResultAnalyse.h" +#include "gpg/GpgConstants.h" namespace GpgFrontend { - class EncryptResultAnalyse : public ResultAnalyse { - Q_OBJECT - public: - - explicit EncryptResultAnalyse(GpgError error, GpgEncrResult result); - - protected: - - void do_analyse() final; - - private: - - GpgError error; - GpgEncrResult result; - - }; -} - +class EncryptResultAnalyse : public ResultAnalyse { + Q_OBJECT +public: + explicit EncryptResultAnalyse(GpgError error, GpgEncrResult result); +protected: + void do_analyse() final; +private: + GpgError error; + GpgEncrResult result; +}; +} // namespace GpgFrontend -#endif //GPGFRONTEND_ENCRYPTRESULTANALYSE_H +#endif // GPGFRONTEND_ENCRYPTRESULTANALYSE_H diff --git a/src/gpg/result_analyse/ResultAnalyse.cpp b/src/gpg/result_analyse/ResultAnalyse.cpp index b1f2cef9..44e32e7b 100644 --- a/src/gpg/result_analyse/ResultAnalyse.cpp +++ b/src/gpg/result_analyse/ResultAnalyse.cpp @@ -24,23 +24,26 @@ #include "gpg/result_analyse/ResultAnalyse.h" -const QString &GpgFrontend::ResultAnalyse::getResultReport() { - if(!analysed_) do_analyse(); - return resultText; +const std::string GpgFrontend::ResultAnalyse::getResultReport() { + if (!analysed_) + do_analyse(); + return stream.str(); } int GpgFrontend::ResultAnalyse::getStatus() { - if(!analysed_) do_analyse(); - return status; + if (!analysed_) + do_analyse(); + return status; } void GpgFrontend::ResultAnalyse::setStatus(int mStatus) { - if(mStatus < status) status = mStatus; + if (mStatus < status) + status = mStatus; } void GpgFrontend::ResultAnalyse::analyse() { - if(!analysed_){ - do_analyse(); - analysed_ = true; - } + if (!analysed_) { + do_analyse(); + analysed_ = true; + } } diff --git a/include/gpg/result_analyse/ResultAnalyse.h b/src/gpg/result_analyse/ResultAnalyse.h index 0ee569c6..f10c1129 100644 --- a/include/gpg/result_analyse/ResultAnalyse.h +++ b/src/gpg/result_analyse/ResultAnalyse.h @@ -24,36 +24,35 @@ #ifndef GPGFRONTEND_RESULTANALYSE_H #define GPGFRONTEND_RESULTANALYSE_H -#include "GpgFrontend.h" +#include "gpg/GpgConstants.h" +#include <sstream> +#include <string> namespace GpgFrontend { - class ResultAnalyse : public QObject { - Q_OBJECT - public: - ResultAnalyse() = default; +class ResultAnalyse : public QObject { + Q_OBJECT +public: + ResultAnalyse() = default; - [[nodiscard]] const QString &getResultReport(); + [[nodiscard]] const std::string getResultReport(); - [[nodiscard]] int getStatus(); + [[nodiscard]] int getStatus(); - void analyse(); + void analyse(); - protected: +protected: + virtual void do_analyse() = 0; - virtual void do_analyse() = 0; + std::stringstream stream; - QString resultText; - QTextStream stream{&resultText}; + int status = 1; - int status = 1; + bool analysed_ = false; - bool analysed_ = false; + void setStatus(int mStatus); +}; - void setStatus(int mStatus); - }; +} // namespace GpgFrontend -} - - -#endif //GPGFRONTEND_RESULTANALYSE_H +#endif // GPGFRONTEND_RESULTANALYSE_H diff --git a/src/gpg/result_analyse/SignResultAnalyse.cpp b/src/gpg/result_analyse/SignResultAnalyse.cpp index ff7cd029..21e18bfa 100644 --- a/src/gpg/result_analyse/SignResultAnalyse.cpp +++ b/src/gpg/result_analyse/SignResultAnalyse.cpp @@ -22,78 +22,88 @@ * */ -#include "gpg/function/GpgKeyGetter.h" #include "gpg/result_analyse/SignResultAnalyse.h" +#include "gpg/function/GpgKeyGetter.h" -GpgFrontend::SignResultAnalyse::SignResultAnalyse(GpgError error, GpgSignResult result) : error(error), - result(std::move(result)) {} - +GpgFrontend::SignResultAnalyse::SignResultAnalyse(GpgError error, + GpgSignResult result) + : error(error), result(std::move(result)) {} void GpgFrontend::SignResultAnalyse::do_analyse() { - qDebug() << "Start Sign Result Analyse"; - - stream << tr("[#] Sign Operation "); - - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - stream << tr("[Success]") << Qt::endl; - else { - stream << tr("[Failed] ") << gpgme_strerror(error) << Qt::endl; - setStatus(-1); + qDebug() << "Start Sign Result Analyse"; + + stream << tr("[#] Sign Operation ").constData(); + + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + stream << tr("[Success]").constData() << std::endl; + else { + stream << tr("[Failed] ").constData() << gpgme_strerror(error) << std::endl; + setStatus(-1); + } + + if (result != nullptr && + (result->signatures != nullptr || result->invalid_signers != nullptr)) { + + qDebug() << "Sign Result Analyse Getting Result"; + stream << "------------>" << std::endl; + auto new_sign = result->signatures; + + while (new_sign != nullptr) { + stream << tr("[>] New Signature: ").constData() << std::endl; + + qDebug() << "Signers Fingerprint: " << new_sign->fpr; + + stream << tr(" Sign Mode: ").constData(); + if (new_sign->type == GPGME_SIG_MODE_NORMAL) + stream << tr("Normal").constData(); + else if (new_sign->type == GPGME_SIG_MODE_CLEAR) + stream << tr("Clear").constData(); + else if (new_sign->type == GPGME_SIG_MODE_DETACH) + stream << tr("Detach").constData(); + + stream << std::endl; + + auto singerKey = + GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr); + if (singerKey.good()) { + stream << tr(" Signer: ").constData() + << singerKey.uids()->front().uid() << std::endl; + } else { + stream << tr(" Signer: ").constData() << tr("<unknown>").constData() + << std::endl; + } + stream << tr(" Public Key Algo: ").constData() + << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl; + stream << tr(" Hash Algo: ").constData() + << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl; + stream + << tr(" Date & Time: ").constData() + << QDateTime::fromTime_t(new_sign->timestamp).toString().constData() + << std::endl; + + stream << std::endl; + + new_sign = new_sign->next; } - if (result != nullptr && (result->signatures != nullptr || result->invalid_signers != nullptr)) { - - qDebug() << "Sign Result Analyse Getting Result"; - stream << "------------>" << Qt::endl; - auto new_sign = result->signatures; - - while (new_sign != nullptr) { - stream << tr("[>] New Signature: ") << Qt::endl; - - qDebug() << "Signers Fingerprint: " << new_sign->fpr; - - stream << tr(" Sign Mode: "); - if (new_sign->type == GPGME_SIG_MODE_NORMAL) - stream << tr("Normal"); - else if (new_sign->type == GPGME_SIG_MODE_CLEAR) - stream << tr("Clear"); - else if (new_sign->type == GPGME_SIG_MODE_DETACH) - stream << tr("Detach"); - - stream << Qt::endl; - - auto singerKey = GpgFrontend::GpgKeyGetter::getInstance().getKey(new_sign->fpr); - if (singerKey.good()) { - stream << tr(" Signer: ") << singerKey.uids()->front().uid() << Qt::endl; - } else { - stream << tr(" Signer: ") << tr("<unknown>") << Qt::endl; - } - stream << tr(" Public Key Algo: ") << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << Qt::endl; - stream << tr(" Hash Algo: ") << gpgme_hash_algo_name(new_sign->hash_algo) << Qt::endl; - stream << tr(" Date & Time: ") << QDateTime::fromTime_t(new_sign->timestamp).toString() << Qt::endl; - - stream << Qt::endl; - - new_sign = new_sign->next; - } - - qDebug() << "Sign Result Analyse Getting Invalid Signer"; - - auto invalid_signer = result->invalid_signers; + qDebug() << "Sign Result Analyse Getting Invalid Signer"; - if (invalid_signer != nullptr) - stream << tr("Invalid Signers: ") << Qt::endl; + auto invalid_signer = result->invalid_signers; - while (invalid_signer != nullptr) { - setStatus(0); - stream << tr("[>] Signer: ") << Qt::endl; - stream << tr(" Fingerprint: ") << invalid_signer->fpr << Qt::endl; - stream << tr(" Reason: ") << gpgme_strerror(invalid_signer->reason) << Qt::endl; - stream << Qt::endl; + if (invalid_signer != nullptr) + stream << tr("Invalid Signers: ").constData() << std::endl; - invalid_signer = invalid_signer->next; - } - stream << "<------------" << Qt::endl; + while (invalid_signer != nullptr) { + setStatus(0); + stream << tr("[>] Signer: ").constData() << std::endl; + stream << tr(" Fingerprint: ").constData() << invalid_signer->fpr + << std::endl; + stream << tr(" Reason: ").constData() + << gpgme_strerror(invalid_signer->reason) << std::endl; + stream << std::endl; + invalid_signer = invalid_signer->next; } + stream << "<------------" << std::endl; + } }
\ No newline at end of file diff --git a/include/gpg/result_analyse/SignResultAnalyse.h b/src/gpg/result_analyse/SignResultAnalyse.h index c837e957..0d9eb3b6 100644 --- a/include/gpg/result_analyse/SignResultAnalyse.h +++ b/src/gpg/result_analyse/SignResultAnalyse.h @@ -25,31 +25,24 @@ #ifndef GPGFRONTEND_SIGNRESULTANALYSE_H #define GPGFRONTEND_SIGNRESULTANALYSE_H -#include "GpgFrontend.h" - #include "ResultAnalyse.h" -#include "gpg/GpgConstants.h" namespace GpgFrontend { - class SignResultAnalyse : public ResultAnalyse { - Q_OBJECT - public: - - explicit SignResultAnalyse(GpgError error, GpgSignResult result); - - protected: - - void do_analyse(); - +class SignResultAnalyse : public ResultAnalyse { + Q_OBJECT +public: + explicit SignResultAnalyse(GpgError error, GpgSignResult result); - private: - GpgError error; +protected: + void do_analyse(); - GpgSignResult result; +private: + GpgError error; - }; + GpgSignResult result; +}; -} +} // namespace GpgFrontend -#endif //GPGFRONTEND_SIGNRESULTANALYSE_H +#endif // GPGFRONTEND_SIGNRESULTANALYSE_H diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.cpp b/src/gpg/result_analyse/VerifyResultAnalyse.cpp index f794b31c..b807de53 100644 --- a/src/gpg/result_analyse/VerifyResultAnalyse.cpp +++ b/src/gpg/result_analyse/VerifyResultAnalyse.cpp @@ -22,148 +22,163 @@ * */ +#include "gpg/result_analyse/VerifyResultAnalyse.h" #include "GpgFrontend.h" +#include "gpg/GpgConstants.h" #include "gpg/function/GpgKeyGetter.h" -#include "gpg/result_analyse/VerifyResultAnalyse.h" -GpgFrontend::VerifyResultAnalyse::VerifyResultAnalyse(GpgError error, GpgVerifyResult result) : error(errror), result(std::move(result)) {} +GpgFrontend::VerifyResultAnalyse::VerifyResultAnalyse(GpgError error, + GpgVerifyResult result) + : error(error), result(std::move(result)) {} void GpgFrontend::VerifyResultAnalyse::do_analyse() { - qDebug() << "Verify Result Analyse Started"; + qDebug() << "Verify Result Analyse Started"; - stream << tr("[#] Verify Operation "); + stream << tr("[#] Verify Operation ").constData(); - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - stream << tr("[Success]") << Qt::endl; - else { - stream << tr("[Failed] ") << gpgme_strerror(error) << Qt::endl; - setStatus(-1); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + stream << tr("[Success]").constData() << std::endl; + else { + stream << tr("[Failed] ").constData() << gpgme_strerror(error) << std::endl; + setStatus(-1); + } + + if (result != nullptr && result->signatures) { + stream << "------------>" << std::endl; + auto sign = result->signatures; + + if (sign == nullptr) { + stream << "[>] Not Signature Found" << std::endl; + setStatus(0); + return; } + stream << "[>] Signed On " + << QDateTime::fromTime_t(sign->timestamp).toString().constData() + << std::endl; - if (result != nullptr && result->signatures) { - stream << "------------>" << Qt::endl; - auto sign = result->signatures; + stream << std::endl << "[>] Signatures:" << std::endl; - if (sign == nullptr) { - stream << "[>] Not Signature Found" << Qt::endl; - setStatus(0); - return; + bool canContinue = true; + + while (sign && canContinue) { + + switch (gpg_err_code(sign->status)) { + case GPG_ERR_BAD_SIGNATURE: + stream << tr("One or More Bad Signatures.").constData() << std::endl; + canContinue = false; + setStatus(-1); + break; + case GPG_ERR_NO_ERROR: + stream << tr("A ").constData(); + if (sign->summary & GPGME_SIGSUM_GREEN) { + stream << tr("Good ").constData(); + } + if (sign->summary & GPGME_SIGSUM_RED) { + stream << tr("Bad ").constData(); + } + if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) { + stream << tr("Expired ").constData(); + } + if (sign->summary & GPGME_SIGSUM_KEY_MISSING) { + stream << tr("Missing Key's ").constData(); + } + if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) { + stream << tr("Revoked Key's ").constData(); + } + if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) { + stream << tr("Expired Key's ").constData(); + } + if (sign->summary & GPGME_SIGSUM_CRL_MISSING) { + stream << tr("Missing CRL's ").constData(); } - stream << "[>] Signed On " << QDateTime::fromTime_t(sign->timestamp).toString() << Qt::endl; - - stream << Qt::endl << "[>] Signatures:" << Qt::endl; - - bool canContinue = true; - - while (sign && canContinue) { - - switch (gpg_err_code(sign->status)) { - case GPG_ERR_BAD_SIGNATURE: - stream << QApplication::tr("One or More Bad Signatures.") << Qt::endl; - canContinue = false; - setStatus(-1); - break; - case GPG_ERR_NO_ERROR: - stream << QApplication::tr("A "); - if (sign->summary & GPGME_SIGSUM_GREEN) { - stream << QApplication::tr("Good "); - } - if (sign->summary & GPGME_SIGSUM_RED) { - stream << QApplication::tr("Bad "); - } - if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) { - stream << QApplication::tr("Expired "); - } - if (sign->summary & GPGME_SIGSUM_KEY_MISSING) { - stream << QApplication::tr("Missing Key's "); - } - if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) { - stream << QApplication::tr("Revoked Key's "); - } - if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) { - stream << QApplication::tr("Expired Key's "); - } - if (sign->summary & GPGME_SIGSUM_CRL_MISSING) { - stream << QApplication::tr("Missing CRL's "); - } - - if (sign->summary & GPGME_SIGSUM_VALID) { - stream << QApplication::tr("Signature Fully Valid.") << Qt::endl; - } else { - stream << QApplication::tr("Signature Not Fully Valid.") << Qt::endl; - } - - if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) { - if (!print_signer(stream, sign)) setStatus(0); - } else { - stream << QApplication::tr("Key is NOT present with ID 0x") << QString(sign->fpr) << Qt::endl; - } - - setStatus(1); - - break; - case GPG_ERR_NO_PUBKEY: - stream << QApplication::tr("A signature could NOT be verified due to a Missing Key\n"); - setStatus(-1); - break; - case GPG_ERR_CERT_REVOKED: - stream << QApplication::tr( - "A signature is valid but the key used to verify the signature has been revoked\n"); - if (!print_signer(stream, sign)) { - setStatus(0); - } - setStatus(-1); - break; - case GPG_ERR_SIG_EXPIRED: - stream << QApplication::tr("A signature is valid but expired\n"); - if (!print_signer(stream, sign)) { - setStatus(0); - } - setStatus(-1); - break; - case GPG_ERR_KEY_EXPIRED: - stream << QApplication::tr( - "A signature is valid but the key used to verify the signature has expired.\n"); - if (!print_signer(stream, sign)) { - setStatus(0); - } - break; - case GPG_ERR_GENERAL: - stream << QApplication::tr( - "There was some other error which prevented the signature verification.\n"); - status = -1; - canContinue = false; - break; - default: - stream << QApplication::tr("Error for key with fingerprint ") << - GpgFrontend::GpgContext::beautifyFingerprint(QString(sign->fpr)); - setStatus(-1); - } - stream << Qt::endl; - sign = sign->next; + if (sign->summary & GPGME_SIGSUM_VALID) { + stream << tr("Signature Fully Valid.").constData() << std::endl; + } else { + stream << tr("Signature Not Fully Valid.").constData() << std::endl; } - stream << "<------------" << Qt::endl; - } -} + if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) { + if (!print_signer(stream, sign)) + setStatus(0); + } else { + stream << tr("Key is NOT present with ID 0x").constData() << sign->fpr + << std::endl; + } -bool GpgFrontend::VerifyResultAnalyse::print_signer(QTextStream &stream, gpgme_signature_t sign) { - bool keyFound = true; - auto key = GpgFrontend::GpgKeyGetter::getInstance().getKey(sign->fpr); + setStatus(1); - if (!key.good()) { - stream << tr(" Signed By: ") << tr("<unknown>") << Qt::endl; - setStatus(0); - keyFound = false; - } else { - stream << tr(" Signed By: ") << key.uids()->front().uid() << Qt::endl; + break; + case GPG_ERR_NO_PUBKEY: + stream << tr("A signature could NOT be verified due to a Missing Key\n") + .constData(); + setStatus(-1); + break; + case GPG_ERR_CERT_REVOKED: + stream << tr("A signature is valid but the key used to " + "verify the signature has been revoked\n") + .constData(); + if (!print_signer(stream, sign)) { + setStatus(0); + } + setStatus(-1); + break; + case GPG_ERR_SIG_EXPIRED: + stream << tr("A signature is valid but expired\n").constData(); + if (!print_signer(stream, sign)) { + setStatus(0); + } + setStatus(-1); + break; + case GPG_ERR_KEY_EXPIRED: + stream << tr("A signature is valid but the key used to " + "verify the signature has expired.\n") + .constData(); + if (!print_signer(stream, sign)) { + setStatus(0); + } + break; + case GPG_ERR_GENERAL: + stream << tr("There was some other error which prevented " + "the signature verification.\n") + .constData(); + status = -1; + canContinue = false; + break; + default: + stream << tr("Error for key with fingerprint ").constData() + << GpgFrontend::beautify_fingerprint(sign->fpr); + setStatus(-1); + } + stream << std::endl; + sign = sign->next; } - stream << tr(" Public Key Algo: ") << gpgme_pubkey_algo_name(sign->pubkey_algo) << Qt::endl; - stream << tr(" Hash Algo: ") << gpgme_hash_algo_name(sign->hash_algo) << Qt::endl; - stream << tr(" Date & Time: ") << QDateTime::fromTime_t(sign->timestamp).toString() << Qt::endl; - stream << Qt::endl; - return keyFound; + stream << "<------------" << std::endl; + } } +bool GpgFrontend::VerifyResultAnalyse::print_signer(std::stringstream &stream, + gpgme_signature_t sign) { + bool keyFound = true; + auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr); + + if (!key.good()) { + stream << tr(" Signed By: ").constData() << tr("<unknown>").constData() + << std::endl; + setStatus(0); + keyFound = false; + } else { + stream << tr(" Signed By: ").constData() << key.uids()->front().uid() + << std::endl; + } + stream << tr(" Public Key Algo: ").constData() + << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl; + stream << tr(" Hash Algo: ").constData() + << gpgme_hash_algo_name(sign->hash_algo) << std::endl; + stream << tr(" Date & Time: ").constData() + << QDateTime::fromTime_t(sign->timestamp).toString().constData() + << std::endl; + stream << std::endl; + return keyFound; +} diff --git a/include/gpg/result_analyse/VerifyResultAnalyse.h b/src/gpg/result_analyse/VerifyResultAnalyse.h index 8d80a1b6..30352bee 100644 --- a/include/gpg/result_analyse/VerifyResultAnalyse.h +++ b/src/gpg/result_analyse/VerifyResultAnalyse.h @@ -25,31 +25,25 @@ #ifndef GPGFRONTEND_VERIFYRESULTANALYSE_H #define GPGFRONTEND_VERIFYRESULTANALYSE_H -#include "gpg/GpgConstants.h" -#include "gpg/model/GpgKeySignature.h" - #include "ResultAnalyse.h" +#include "gpg/model/GpgKeySignature.h" namespace GpgFrontend { - class VerifyResultAnalyse : public ResultAnalyse{ - public: - - explicit VerifyResultAnalyse(GpgError error, GpgVerifyResult result); - - private: - - void do_analyse(); - - private: +class VerifyResultAnalyse : public ResultAnalyse { +public: + explicit VerifyResultAnalyse(GpgError error, GpgVerifyResult result); - bool print_signer(QTextStream &stream, gpgme_signature_t sign); +private: + void do_analyse(); - GpgError error; - GpgVerifyResult result; - }; +private: + bool print_signer(std::stringstream &stream, gpgme_signature_t sign); -} + GpgError error; + GpgVerifyResult result; +}; +} // namespace GpgFrontend -#endif //GPGFRONTEND_VERIFYRESULTANALYSE_H +#endif // GPGFRONTEND_VERIFYRESULTANALYSE_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ac16834d..0fba7b0d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,7 +13,7 @@ if(GPG_CORE) target_link_libraries(${AppName} gpg_core) endif() -target_link_libraries(${AppName} GTest::gtest GTest::gtest_main) +target_link_libraries(${AppName} gtest gtest_main) add_test(AllTestsInGpgFrontend ${AppName})
\ No newline at end of file diff --git a/test/GpgCoreTest.cpp b/test/GpgCoreTest.cpp index ecdd7279..c3cf86fb 100644 --- a/test/GpgCoreTest.cpp +++ b/test/GpgCoreTest.cpp @@ -23,11 +23,116 @@ */ #include <gtest/gtest.h> +#include <memory> -// Demonstrate some basic assertions. -TEST(HelloTest, GpgCoreTest) { - // Expect two strings not to be equal. - EXPECT_STRNE("hello", "world"); - // Expect equality. - EXPECT_EQ(7 * 6, 42); +#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyOpera.h" + +TEST(GpgKeyTest, GpgCoreTest) {} +class GpgCoreTest : public ::testing::Test { + +protected: + GpgFrontend::StdBypeArrayPtr secret_key_ = std::make_unique<std::string>( + "-----BEGIN PGP PRIVATE KEY BLOCK-----" + "lQVYBGE0XVEBDADHYmnEbRB8hxqyQmaLmIRU71PTMZc162qWoWTMaPd7a8gQcQwc" + "MUFYHp3mAmoHYUAKyT0lgpyj7UqGDdiAOt8z+nW6tR2Wu2xe6o0su/oK8qGtX37e" + "bexiWcsMftrk/uR+l2G7JcCKMTAszLbyDgg1IaJ/SaVicKaO1CRjD5ZlNa2IQVOG" + "bw0va1CevF6yw5rvc5r300p/kwcKX4taUyPaCT10ZxZnpZUhdsAIX5DfvWURoZ0q" + "jy4JdQFlufhPzSJZ2VoCXn37FeXwEz1Vm8VzyVV70pPWN5osMcNBsRO4nr8cYIxo" + "1PiErm3VdDUHPZ8dKKMlrLaGh3De3ohK47GSLDqBGg/FNnekRwNqBT+HLvfk5Kko" + "lNsC7eyRSagI7IRY+KgjKNpT/9QUGYP9llTonQ2V58XarDFDy8SU/3yOqWaeu0Op" + "A/fpqkp7JF3mGLXzKOZ4ueEOMkh+DsAOPTOQTcbYvnCz8jvHUPlSUqU1Y/7xU6BW" + "rzgqajU563xoxCMAEQEAAQAL/2IGy5NsP8fJsOFlbf9B/AW6KM9TuVEkLiJitSke" + "jlZa1mDnA5o0yTimzODR3QlF0fO7ntl7TsH1n0crNX9N8oEeqZUjCKob+Zrs3H3a" + "6YNKaRzRL5HyH173YLIDCGG/w91NVhpp5DDNIC9WcretGHHu2HKWZb5xPiJIwJ8H" + "gdy+uFOeMo+Mt8HRlDCG0lQ3gUwq3Uzsz9rLEZITCXNeHulK07EQId7RdPGf7afw" + "PE0UU8WIXLoY7PxvT0GRXjj11AheEGNHcebirHbgbLWoevY/+h+r/yAdRns+S2l+" + "PsShh6ki8bH7InI7L79v+021l89FfTZYixwscvwLBN4QWp6FLwqwDJjEHnZRxjCX" + "Y5v7j9gHhhyK2vNbwU1vx/drx/cllIHfYOVRoZtxaAnfW0u51x/uKTknHBoL1GvW" + "zrJHLMC4cHuPYAR6vS5sy7QcqVeB709mrTNVGHa0w6u4U8mlxpIQ/izdxy9k2sgV" + "OAfZMxojIehGymu7LP0DP+ElUQYA2Rr5l81OIO9JCA+pg6B4ZigGYMvGDnBv9kuy" + "lJWWV1O7jPMAfdK0lkehTpw/E4TkRk1t7PiQhXtGprYUAihdR2rx8DyDc438mhvw" + "aN95MURkZ0v9U+04tPzHg/OTfkhNs/C6KfCxYpZD6I8lMZyIXX0BcjBPgl62EQCX" + "QhU6zfF/1muGGQJ6tYvZ7Z/iMqwpqBzi0h5gCQcxSIhP4z8hdfT920LezUhibuqr" + "HrTisZ1rQPPOJ1TxZYwaqKDOUy/rBgDrGrV7Z3k7EaKPEbL/C38FtZT+ZDFGvvPs" + "4HVn/tRhVJPYsW5a0m6qSnd+NZqmKX2twv7IZK+DP3MQeNoJZj1MwDTW0lHDzNPp" + "Ey3fO6+R4oFY4QbBFAqXLLAviAtAigwNJ87lgieeW5SQKluHdC82nqVzVyh89XaM" + "nSe3niVtgIoimTELg5P5uWFcRA4dTENrSTuhKD09fzceSKlqrDVAmygwoQNuGr2t" + "00mT+5Mzctf1cogNvTxE9EfmpPQT5qkGAOoSeWmg5MTAOJsc+A7kzu47COqGsldZ" + "xejz9je45+XFRyE2ywH6EaJ8Fy8yzuLQVw8sRtCB/tC5nE5aKSlgwoJ0A1B8nLl9" + "ANCC3gszj3uGKkf3ITqggtojkrJSFv4kndOqWtBe7GlM1FDyaTS3Va72NqUVLGOo" + "tSVziTGqyXH90p52EKEffnl40/1AZjkRs6cQvvd0cGXoXodubRKm48CXOMJ+cXL5" + "a205komAn1las2wOheK2HNsUQpV87Atk1t1ctC1HcGdGcm9udGVuZFRlc3QgPGdw" + "Z2Zyb250ZW5kQGdwZ2Zyb250ZW5kLnB1Yj6JAdgEEwEIAEIWIQSUkHlbePiv6fk7" + "0JKBcEhZGCZh+wUCYTRdUQIbAwUJA8JKbwULCQgHAgMiAgEGFQoJCAsCBBYCAwEC" + "HgcCF4AACgkQgXBIWRgmYfsYpQwAow3gK+CGoyc/mQ60UbtCUlxJX6xN4palxY24" + "cc7rbBhBJgp4oomPSCjiZjs6Wdiwmm5tC8M4chvfJ2Aw2xHL7W4DrPykKkvrhbRw" + "S82eQyI3VMN6ED9EAGAmhaNME21gRvaUgI+qV7k753nqHTasXI2lB6UZryFbiPRH" + "3BIjPx7msSvNaukVoTvBpHJ/Z9/u4M6TQCCLpQOgHN+0JHW/87O9YTycdqePBVj+" + "pKEHJimebg2w8BWTYFpvusczlGcJdc97lXEV5gQTP/zq4SGNnvghlnjEFD7hRS/G" + "NwQCd7IL56koCxPgvdLLQPTlsLYYo0myJr0ePjdOQWg7heOfdywqBn1pbH9MqpiP" + "d5iNp9kDEAxnJ2H4ToeDF05hGdrfWr7G5yuGDTBiP4Rgr6DwE2gHN6ELzGMqH2Fg" + "9x2sWgf25Z3bocXIzhZLVqA/YWbGtJLDlHiWVhrG20edgpb/KsvJUVcpy6mIM57l" + "2Pk5LCmIZLdlsLY1Mx5IT5UDzUULnQVYBGE0XVEBDADS0miBA8Alwk2WCrF6vm1t" + "5H9nXguOBrTIGntxoLQoUVwB5Ei+7Nrb+c7Y6aMNyEW/Xno28jdsSSwtqbEt2VLb" + "rrshggqi4oPHDHu5qZUf/b3HNyNwJ6w1vdGryHVg/Vg5pKvyYveH/MVHunrCKUQ6" + "imP4lTg8qL6Igq/qD5bOg8582LAxHwsIznpLVEqgN2eO6EGirlvhw0Qyw+CHFJbf" + "bvyGyDcTRZPjOZRufDezsLvC30soL7ZQI6acX8Q18Hi6aXf4iAE2ZpPChzCBnFKw" + "VHfB/MB4zOpphDvxZF53j0p7bZuIoG/aItUHZogrtap0YR45AjMQkHLwIiihL4cd" + "CBxffooai10mW0gos/gutZfIxrrtGpURlSE18lICcFIYctSAt4gxIPpAVcN6bY/k" + "aIaKpvaMtoLuCeBXN6y0sV8vBiVxpvSUZTfzfeOki7CQctdhJPWAELNzzFXvFjyx" + "QHAkZgjNlft1zrOy7ODlXhNPRsFK3VwaZ6iE2f9Lr68AEQEAAQAL/1xpz1V+h2QF" + "4Gy9Ez9y6hUZ7J8rInWHiweMVEBi6ZYi0+ogX6MRwH5c6sc64zbPa4OPrpMXaiQV" + "j0AU+o3WjfOujGkL0A3GrW07k6C3LZ9wYxhIm0g2m86S/q4GmS2C4IGkJZuCtm7t" + "5qyimd0yqa3frCLzhktQzPSaFPLNEpZEQOeJNPLTYMrjd8g9ktjYcJS8Ssk9FRnJ" + "tsNqCaos5FXdGOUcLshL35/jRaWI3gHunt+1cgSTpZ9LgWVatW/PkNAmug3q94+M" + "67A4vsjdqWfezXaJcSfgdPc5b5cznJoqbXX9N+Q/SYMBgCOFfYbFQpWB6/wbJww/" + "Ibit5e2lD97Y4g2lO1QAJaDfvA/LCf49+SLmVN+rkYC+6Le7ygYFNRpvYik2NLY8" + "EnnvEacjPfkCz5BJtP8JTceba/KdCLZQ4FN/vwGl7ykH0oN5TYcVE4CnURzK6Y/2" + "jQ9tT+mKdDIpaNr7QCnCJcL2HFTOQ7IIHmhN6UJu3G9Uf5TfsdagwQYA14HVwvC2" + "K4xmW8I9pqKrru+K2+CjNX5KqOgYM9h3Lfg/1Kr+OSIVrPm7zoEHeGXxH4C5Z5EF" + "6eIB0QRgLbL0roS3dvxVF5cBdUbH5Ec/iOIlRD9RTO7QMW5dvHgr9/PWYs3znM+C" + "h8wMGJ5Y/xbtwPu3++hmwFd79ghl2K+Mdopq8hAHvPCJ5USPfTjBhRU9ntv4C75U" + "jBnzMGqN0Sbn9BLwmBx12jy8EMgcQovtUK9jeEjV/5WMeLgfBnjO1m31BgD6bzTP" + "Y3z+aHEm2sWkwXTEuaQQm6dWrvbMrAw1kbcdnPZCSieHCQesmVnogNU2LH61AXVy" + "NQ0lxVgHheC6rZHl2Eqv1whfmYVjCrC/jKSaokNjPdgSFl8tteZGm5FQto5j+lA9" + "KEW2A6d0MjcrYSN9mVuKUCii0x1YcxT+6kMAi0UvDzADzLkckNX8i47oMLR6lRMN" + "k6B/52EJ5tBBDzeu3rJWkeeZASNnWAKh1JQM6dplUXTO4SodJodXv0183JMF/A76" + "mVjZOT79SBImVTdQyp0WRhYxJJKVQ3q6fHC47igQypZtPy0Itn8Ll0fu6FTPbWJ7" + "Su/UuJKq/FDQ+jM/fhdZ7bfLsXssSl4opyBc1xtbDN0wdab1vy2OOgq1stdE2sr4" + "BX65rUbdflsBNf/YxX+NfAmP1h8YCvPxoIVZOVDCCvbf8K/jKvautLt2op/8wwUj" + "eHmkZSmBBWTKUdFlYD+T0IWe55lgvLWjrLGXnS41v0/a7WgYlOcgrZPI22qcQ+rT" + "iQG8BBgBCAAmFiEElJB5W3j4r+n5O9CSgXBIWRgmYfsFAmE0XVECGwwFCQPCSm8A" + "CgkQgXBIWRgmYftO8QwAxE+6jsIAlNzNKn9ScSuCBOPumtPzlAjADEymR3qxJ3N0" + "7qnzOD3dwwSsX8S5P/aMfUm9KPleYebTwZ/iMM7MBZcxrSPwOhO9i8tnRRCqppC0" + "EcSGSxDe5iP5xFiQkVvr524eVz04orW1ZgAwWh7L5m3GSjq5V77zUetOBHv9WAGL" + "sPOMQAMZUQavL370gxnttR7cn0Of9TM3Ia5L6p0Yi7PD0QztnkkczjaDySSFpxzS" + "XSTo+en5Nul0pY0kt/TBY7+il8lWxCUChEch/SAdnSocoYN+Bd1KQ/J+KUukl71m" + "ZHz67G9t1qso7IH0SksB0dSpxwhs645rG605DlJKnUHgtwE46nnwR22YolcTbTCh" + "tKmdMppPdabbL1gI/I+Jmh6Z+UDDKbl7uUKrz5vua/gxfySFqmNvcKO1ocjbKDcf" + "cqEh8fyKWtmiXrW2zzlszJVGJrpXDDpzgP7ZELGxhfZYFi8rMrSVKDwrpFZBSWMG" + "T2R+xoMRGcJJphKWpVjZ" + "=u+uG" + "-----END PGP PRIVATE KEY BLOCK-----"); + + GpgCoreTest() { + GpgFrontend::GpgKeyImportExportor::GetInstance().ImportKey( + std::move(this->secret_key_)); + } + + virtual ~GpgCoreTest() { + GpgFrontend::GpgKeyOpera::GetInstance().DeleteKeys( + std::move(std::make_unique<std::vector<std::string>>( + 1, "9490795B78F8AFE9F93BD09281704859182661FB"))); + } + + virtual void SetUp() {} + + virtual void TearDown() {} +}; + +TEST_F(GpgCoreTest, GpgKeyTest) { + // You can assume that the code in SetUp has been executed + // pFoo_->bar(...) + // The code in TearDown will be run after the end of this test } |