From 5862a61d59d8975d4fb2eeeb2214882a66d32aff Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 11 Sep 2020 12:29:06 +0200 Subject: [PATCH] change encryption state of crypto_keys --- skeema/gradido_login/crypto_keys.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 1 + src/cpp/Crypto/KeyPairHedera.h | 3 + .../HTTPInterface/AdminHederaAccountPage.cpp | 139 ++++++++++++------ src/cpp/controller/CryptoKey.cpp | 30 ++++ src/cpp/controller/CryptoKey.h | 11 +- src/cpp/controller/HederaAccount.cpp | 62 ++++++-- src/cpp/controller/HederaAccount.h | 10 +- src/cpp/controller/HederaId.cpp | 10 ++ src/cpp/controller/HederaId.h | 2 + src/cpp/model/table/CryptoKey.cpp | 65 +++++++- src/cpp/model/table/CryptoKey.h | 9 ++ src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaId.cpp | 1 + src/cpp/model/table/ModelBase.cpp | 18 +++ src/cpp/model/table/ModelBase.h | 1 + src/cpsp/adminHederaAccount.cpsp | 101 +++++++++---- 17 files changed, 377 insertions(+), 89 deletions(-) diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index c79987755..1e5d6bad8 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,6 +1,6 @@ CREATE TABLE `crypto_keys` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `private_key` binary(80) NOT NULL, + `private_key` varbinary(80) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`), diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 62643cc99..e3a377864 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -184,6 +184,7 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr password) const; MemoryBin* getPrivateKeyCopy() const; + inline std::string getPrivateKeyHex(const Poco::AutoPtr password) const { if (!mPrivateKey) return "0x0"; return DataTypeConverter::binToHex(mPrivateKey); } protected: diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 54a416bef..3247e1130 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -51,40 +51,58 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); std::string action = ""; - std::string account_id_from_query; + Poco::AutoPtr query_hedera_account; + + // parsing get query params if(uri_query.size() >= 2) { if(uri_query[0].first == "action") { action = uri_query[0].second; } if(uri_query[1].first == "account_id") { + std::string account_id_from_query; + int account_id = 0; account_id_from_query = uri_query[1].second; - } - } - if(action == "updateBalance") { - int account_id = 0; - if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); - } else { - auto hedera_account = controller::HederaAccount::load("id", account_id); - if(!hedera_account.size() || hedera_account[0].isNull()) { - addError(new Error("Action Update Balance", "hedera id not found")); + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); } else { - hedera_time.reset(); - hedera_account[0]->hederaAccountGetBalance(user, this); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + auto hedera_accounts = controller::HederaAccount::load("id", account_id); + if(!hedera_accounts.size() || hedera_accounts[0].isNull()) { + addError(new Error("Action", "hedera account not found")); + } else { + query_hedera_account = hedera_accounts[0]; + } } } } - // add - else if(!form.empty()) { + // actions + if(!query_hedera_account.isNull()) + { + if(action == "updateBalance") + { + hedera_time.reset(); + query_hedera_account->hederaAccountGetBalance(user); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } + else if(action == "changeEncryption") + { + if(query_hedera_account->changeEncryption(user)) { + addNotification(new Success("Hedera Account", "success in changing encryption")); + } + } + } + else if(!form.empty()) // add + { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); auto numString = form.get("account-num", "0"); auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); auto publicKeyString = form.get("account-public-key", ""); auto networkTypeString = form.get("account-network-type", "0"); + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + int shardNum = 0; int realmNum = 0; int num = 0; @@ -144,7 +162,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user); + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); if(!crypto_key->getModel()->insertIntoDB(true)) { addError(new Error("DB Error", "Error saving crypto key in DB")); } @@ -152,15 +170,26 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request printf("crypto key found in db\n"); } if(0 == errorCount()) { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } } } @@ -169,7 +198,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request } } - + if(!query_hedera_account.isNull()) { + getErrors(query_hedera_account); + } // list accounts auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); @@ -231,7 +262,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; @@ -244,41 +275,63 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
Hedera Id
\t\t\t\n"; responseStream << "\t\t\t\t
Balance
\n"; responseStream << "\t\t\t\t
Server Type
\n"; + responseStream << "\t\t\t\t
Verschlüsselt?
\n"; responseStream << "\t\t\t\t
Last Updated
\n"; responseStream << "\t\t\t\t
Aktionen
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t"; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + std::string changeEncryption(""); + if(hedera_account_model->getUserId() == user->getModel()->getID()) { + changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); + } + //printf("change encryption: %s\n", changeEncryption.data()); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t
"; -#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
\n"; responseStream << "\t\t\t\t\t
"; -#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
\n"; - responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + if(changeEncryption != "") { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + } responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t"; -#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t\n"; @@ -287,7 +340,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t\n"; @@ -296,26 +349,28 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
\n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index aa8df1b8d..338ad05a4 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -113,8 +113,38 @@ namespace controller { return nullptr; } + return std::make_unique(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize()); } + bool CryptoKey::changeEncryption(Poco::AutoPtr user) + { + auto key_pair = getKeyPair(user); + if (!key_pair || !key_pair->hasPrivateKey()) { + addError(new Error("Crypto Key", "key pair or private key was null")); + return false; + } + auto model = getModel(); + auto mm = MemoryManager::getInstance(); + // update key type + model->changeKeyTypeToggleEncrypted(); + MemoryBin* private_key = nullptr; + if (model->isEncrypted()) { + private_key = key_pair->getCryptedPrivKey(user->getPassword()); + } + else { + private_key = key_pair->getPrivateKeyCopy(); + } + if (!private_key) { + addError(new Error("Crypto Key", " private_key not get")); + return false; + } + model->setPrivateKey(private_key); + // save changes into db + model->updatePrivkeyAndKeyType(); + + mm->releaseMemory(private_key); + return true; + } } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index ef48c88f1..ddd2a7435 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -9,9 +9,15 @@ #include "TableControllerBase.h" #include "User.h" + + namespace controller { - class CryptoKey : public TableControllerBase + + class HederaAccount; + + class CryptoKey : public TableControllerBase, public NotificationList { + friend HederaAccount; public: ~CryptoKey(); @@ -31,8 +37,11 @@ namespace controller { std::unique_ptr getKeyPair(Poco::AutoPtr user) const; std::unique_ptr getKeyPair() const; + protected: + + bool changeEncryption(Poco::AutoPtr user); CryptoKey(model::table::CryptoKey* dbModel); }; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index e4873ecf0..22a82c929 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -40,6 +40,20 @@ namespace controller { return resultVector; } + Poco::AutoPtr HederaAccount::load(Poco::AutoPtr hederaId) + { + if (!hederaId->isExistInDB()) return nullptr; + + auto db = new model::table::HederaAccount(); + auto result_count = db->loadFromDB("account_hedera_id", hederaId->getModel()->getID()); + if (1 == result_count) { + return new HederaAccount(db); + } + // maybe change later to using error manager and send email + printf("[HederaAccount::load] result_count not expected: %d\n", result_count); + return nullptr; + } + std::vector> HederaAccount::listAll() { auto db = new model::table::HederaAccount(); @@ -73,7 +87,13 @@ namespace controller { return resultVector; } - bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) + Poco::AutoPtr HederaAccount::getCryptoKey() const + { + auto model = getModel(); + return controller::CryptoKey::load(model->getCryptoKeyId()); + } + + bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -86,13 +106,13 @@ namespace controller { auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); if (crypto_key.isNull()) { - if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));} - else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); } + addError(new Error("Keys", "could not found crypto key for account")); + printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); return false; } auto hedera_key_pair = crypto_key->getKeyPair(user); if (!hedera_key_pair) { - if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));} + addError(new Error("Keys", "error decrypting private key")); printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); return false; } @@ -111,13 +131,8 @@ namespace controller { account_model->updateIntoDB("balance", response.getAccountBalance()); } else { - if (errorReceiver) { - errorReceiver->addError(new Error("Hedera", "Hedera request failed")); - errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); - } - else { - printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data()); - } + addError(new Error("Hedera", "Hedera request failed")); + addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); } //request.requestViaPHPRelay(query); } @@ -125,13 +140,32 @@ namespace controller { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } - if (errorReceiver) { - errorReceiver->getErrors(&request); - } + getErrors(&request); return false; } + bool HederaAccount::changeEncryption(Poco::AutoPtr user) + { + assert(!user.isNull() && user->getModel()); + auto model = getModel(); + assert(!model.isNull()); + + if (user->getModel()->getID() != model->getUserId()) { + addError(new Error("Hedera Account", "wrong user")); + return false; + } + auto crypto_key = controller::CryptoKey::load(model->getCryptoKeyId()); + if (crypto_key.isNull()) { + addError(new Error("Hedera Account", "couldn't find crypto key")); + return false; + } + bool result = crypto_key->changeEncryption(user); + getErrors(crypto_key); + return result; + + } + std::string HederaAccount::toShortSelectOptionName() { diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index a9a53d528..77f34aa87 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -8,9 +8,10 @@ #include "Poco/SharedPtr.h" #include "TableControllerBase.h" +#include "CryptoKey.h" namespace controller { - class HederaAccount : public TableControllerBase + class HederaAccount : public TableControllerBase, public NotificationList { public: ~HederaAccount(); @@ -18,6 +19,7 @@ namespace controller { static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); static std::vector> load(const std::string& fieldName, int fieldValue); + static Poco::AutoPtr load(Poco::AutoPtr hederaId); static std::vector> listAll(); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } @@ -25,11 +27,15 @@ namespace controller { std::string HederaAccount::toShortSelectOptionName(); inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::HederaAccount* getModel() const { return _getModel(); } inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); + Poco::AutoPtr getCryptoKey() const; + + bool hederaAccountGetBalance(Poco::AutoPtr user); + bool changeEncryption(Poco::AutoPtr user); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index ce171a7a8..de2cf1dfa 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -37,4 +37,14 @@ namespace controller { protoAccountId->set_realmnum(model->getRealmNum()); protoAccountId->set_accountnum(model->getNum()); } + + bool HederaId::isExistInDB() + { + auto model = getModel(); + if (model->getID() > 0) return true; + //std::vector loadFromDB(const std::vector& fieldNames, const std::vector& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0); + model->isExistInDB(); + return model->getID() != 0; + + } } \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index ae9296a43..1cf967927 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -20,6 +20,8 @@ namespace controller { static Poco::AutoPtr load(int id); + bool isExistInDB(); + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index a4f1034e3..f461edc02 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -1,5 +1,5 @@ #include "CryptoKey.h" -#include "../../lib/DataTypeConverter.h" + using namespace Poco::Data::Keywords; namespace model { @@ -51,6 +51,8 @@ namespace model { return ""; } + + bool CryptoKey::hasPrivateKeyEncrypted() const { const KeyType type = (KeyType)(mKeyType); @@ -70,6 +72,39 @@ namespace model { return false; } + void CryptoKey::setPrivateKey(const MemoryBin* privateKey) + { + if (!privateKey) { + mPrivateKey = Poco::Nullable(); + } + else { + mPrivateKey = Poco::Nullable(Poco::Data::BLOB(*privateKey, privateKey->size())); + } + + } + + bool CryptoKey::changeKeyTypeToggleEncrypted() + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + mKeyType = KEY_TYPE_ED25519_SODIUM_CLEAR; + return true; + } + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED) { + mKeyType = KEY_TYPE_ED25519_HEDERA_CLEAR; + return true; + } + if (type == KEY_TYPE_ED25519_SODIUM_CLEAR) { + mKeyType = KEY_TYPE_ED25519_SODIUM_ENCRYPTED; + return true; + } + if (type == KEY_TYPE_ED25519_HEDERA_CLEAR) { + mKeyType = KEY_TYPE_ED25519_HEDERA_ENCRYPTED; + return true; + } + return false; + } + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -103,5 +138,33 @@ namespace model { unlock(); return insert; } + + size_t CryptoKey::updatePrivkeyAndKeyType() + { + Poco::ScopedLock _lock(mWorkMutex); + if (mPrivateKey.isNull() || !mID) { + return 0; + } + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement update(session); + + update << "UPDATE " << getTableName() << " SET private_key = ?, crypto_key_type_id = ? where id = ?;", + use(mPrivateKey), use(mKeyType), use(mID); + + + size_t resultCount = 0; + try { + return update.execute(); + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "[updatePrivkeyAndKeyType] mysql error by update", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: \n", toString().data())); + } + //printf("data valid: %s\n", toString().data()); + return 0; + } + } } \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index c1fa0b66d..0dcbb618f 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -3,6 +3,7 @@ #include "ModelBase.h" #include "Poco/Types.h" +#include "../../lib/DataTypeConverter.h" namespace model { namespace table { @@ -27,13 +28,21 @@ namespace model { std::string toString(); inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + inline std::string getPublicKeyHexString() const { return DataTypeConverter::binToHex(mPublicKey); }; size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } bool hasPrivateKeyEncrypted() const; bool isEncrypted() const; + bool changeKeyTypeToggleEncrypted(); inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); } inline const std::vector& getPrivateKey() const { return mPrivateKey.value().content(); } + size_t updatePrivkeyAndKeyType(); + + //! \brief set encrypted private key + //! \param privateKey copy data, didn't move memory bin + void setPrivateKey(const MemoryBin* privateKey); + static const char* typeToString(KeyType type); protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 6b0d636a0..699330adf 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -35,6 +35,7 @@ namespace model { inline int getAccountHederaId() const { return mAccountHederaId; } inline int getCryptoKeyId() const { return mAccountKeyId; } + inline int getUserId() const { return mUserId; } inline Poco::UInt64 getBalance() { return mBalance; } inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index 9f26f05c5..d6ceb8cb7 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -55,6 +55,7 @@ namespace model { return mID; } + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index 7bb7301f6..49b470d7a 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -78,6 +78,24 @@ namespace model { return false; } + bool ModelBase::isExistInDB() + { + auto cm = ConnectionManager::getInstance(); + Poco::ScopedLock _lock(mWorkMutex); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement select = _loadIdFromDB(session); + try { + select.executeAsync(); + return select.wait() == 1; + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "mysql error by select id, check if exist in db", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: ", toString().data())); + } + return false; + } + bool ModelBase::deleteFromDB() { Poco::ScopedLock _lock(mWorkMutex); diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 62ff4958a..55ae0962a 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -40,6 +40,7 @@ namespace model { size_t loadFromDB(const std::string& fieldName, const T& fieldValue); template bool isExistInDB(const std::string& fieldName, const T& fieldValue); + bool isExistInDB(); template std::vector loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0); template diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 95d6992b7..b55701b1b 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -30,40 +30,58 @@ Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); std::string action = ""; - std::string account_id_from_query; + Poco::AutoPtr query_hedera_account; + + // parsing get query params if(uri_query.size() >= 2) { if(uri_query[0].first == "action") { action = uri_query[0].second; } if(uri_query[1].first == "account_id") { + std::string account_id_from_query; + int account_id = 0; account_id_from_query = uri_query[1].second; - } - } - if(action == "updateBalance") { - int account_id = 0; - if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); - } else { - auto hedera_account = controller::HederaAccount::load("id", account_id); - if(!hedera_account.size() || hedera_account[0].isNull()) { - addError(new Error("Action Update Balance", "hedera id not found")); + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); } else { - hedera_time.reset(); - hedera_account[0]->hederaAccountGetBalance(user, this); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + auto hedera_accounts = controller::HederaAccount::load("id", account_id); + if(!hedera_accounts.size() || hedera_accounts[0].isNull()) { + addError(new Error("Action", "hedera account not found")); + } else { + query_hedera_account = hedera_accounts[0]; + } } } } - // add - else if(!form.empty()) { + // actions + if(!query_hedera_account.isNull()) + { + if(action == "updateBalance") + { + hedera_time.reset(); + query_hedera_account->hederaAccountGetBalance(user); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } + else if(action == "changeEncryption") + { + if(query_hedera_account->changeEncryption(user)) { + addNotification(new Success("Hedera Account", "success in changing encryption")); + } + } + } + else if(!form.empty()) // add + { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); auto numString = form.get("account-num", "0"); auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); auto publicKeyString = form.get("account-public-key", ""); auto networkTypeString = form.get("account-network-type", "0"); + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + int shardNum = 0; int realmNum = 0; int num = 0; @@ -123,7 +141,7 @@ auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user); + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); if(!crypto_key->getModel()->insertIntoDB(true)) { addError(new Error("DB Error", "Error saving crypto key in DB")); } @@ -131,15 +149,26 @@ printf("crypto key found in db\n"); } if(0 == errorCount()) { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } } } @@ -148,7 +177,9 @@ } } - + if(!query_hedera_account.isNull()) { + getErrors(query_hedera_account); + } // list accounts auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); @@ -165,21 +196,33 @@
Hedera Id
Balance
Server Type
+
Verschlüsselt?
Last Updated
Aktionen
<% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + std::string changeEncryption(""); + if(hedera_account_model->getUserId() == user->getModel()->getID()) { + changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); + } + //printf("change encryption: %s\n", changeEncryption.data()); %>
<%= (*it)->getHederaId()->getModel()->toString() %>
<%= hedera_account_model->getBalanceDouble() %> hbar
<%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
+
<%= (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" %>
<%= hedera_account_model->getUpdatedString() %>
- + <% if(changeEncryption != "") { %> + + <% } %>
<% } %> @@ -195,6 +238,8 @@ + +