mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Transaction Roundtrip success
This commit is contained in:
parent
cd12c0fdbf
commit
0bb6332a13
@ -39,6 +39,7 @@ namespace ServerConfig {
|
||||
int g_SessionTimeout = SESSION_TIMEOUT_DEFAULT;
|
||||
std::string g_serverPath;
|
||||
std::string g_php_serverPath;
|
||||
std::string g_php_serverHost;
|
||||
Poco::Mutex g_TimeMutex;
|
||||
|
||||
bool loadMnemonicWordLists()
|
||||
@ -93,6 +94,7 @@ namespace ServerConfig {
|
||||
g_SessionTimeout = cfg.getInt("session.timeout", SESSION_TIMEOUT_DEFAULT);
|
||||
g_serverPath = cfg.getString("loginServer.path", "");
|
||||
g_php_serverPath = cfg.getString("phpServer.url", "");
|
||||
g_php_serverHost = cfg.getString("phpServer.host", "");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ namespace ServerConfig {
|
||||
extern int g_SessionTimeout;
|
||||
extern std::string g_serverPath;
|
||||
extern std::string g_php_serverPath;
|
||||
extern std::string g_php_serverHost;
|
||||
extern Poco::Mutex g_TimeMutex;
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include "../lib/ErrorList.h"
|
||||
#include "../proto/gradido/BasicTypes.pb.h"
|
||||
#include "../SingletonManager/MemoryManager.h"
|
||||
|
||||
class TransactionBase : public ErrorList
|
||||
{
|
||||
|
||||
@ -47,4 +47,5 @@ int TransactionCreation::prepare()
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,4 +11,4 @@ int TransactionTransfer::prepare()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ class TransactionTransfer : public TransactionBase
|
||||
public:
|
||||
TransactionTransfer(const std::string& memo, const model::messages::gradido::Transfer& protoTransfer);
|
||||
|
||||
int prepare();
|
||||
int prepare();
|
||||
|
||||
protected:
|
||||
const model::messages::gradido::Transfer& mProtoTransfer;
|
||||
|
||||
@ -49,6 +49,7 @@ int UserGenerateKeys::run()
|
||||
mKeys.generateFromPassphrase(mPassphrase.data(), &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]);
|
||||
|
||||
mUser->setPublicKeyHex(mKeys.getPubkeyHex());
|
||||
mUser->setPublicKey(mKeys.getPublicKey());
|
||||
if (mUser->hasCryptoKey()) {
|
||||
mUser->setPrivKey(mKeys.getPrivateKey());
|
||||
}
|
||||
@ -176,7 +177,7 @@ User::User(const char* email, const char* first_name, const char* last_name)
|
||||
: mState(USER_EMPTY), mDBId(0), mEmail(email), mFirstName(first_name), mLastName(last_name), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), mCryptoKey(nullptr),
|
||||
mReferenceCount(1)
|
||||
{
|
||||
|
||||
memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES);
|
||||
}
|
||||
// load from db
|
||||
User::User(const char* email)
|
||||
@ -187,6 +188,8 @@ User::User(const char* email)
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
Poco::Nullable<Poco::Data::BLOB> pubkey;
|
||||
Poco::Nullable<Poco::Data::BLOB> privkey;
|
||||
|
||||
@ -207,6 +210,12 @@ User::User(const char* email)
|
||||
|
||||
if (!pubkey.isNull()) {
|
||||
auto pubkey_value = pubkey.value();
|
||||
if (pubkey_value.size() == crypto_sign_PUBLICKEYBYTES) {
|
||||
memcpy(mPublicKey, pubkey_value.content().data(), crypto_sign_PUBLICKEYBYTES);
|
||||
}
|
||||
else {
|
||||
addError(new Error("User", "pubkey from db has other size as expected"));
|
||||
}
|
||||
size_t hexSize = pubkey_value.size() * 2 + 1;
|
||||
char* hexString = (char*)malloc(hexSize);
|
||||
memset(hexString, 0, hexSize);
|
||||
@ -234,6 +243,8 @@ User::User(int user_id)
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
Poco::Nullable<Poco::Data::BLOB> pubkey;
|
||||
Poco::Nullable<Poco::Data::BLOB> privkey;
|
||||
|
||||
@ -254,6 +265,12 @@ User::User(int user_id)
|
||||
|
||||
if (!pubkey.isNull()) {
|
||||
auto pubkey_value = pubkey.value();
|
||||
if (pubkey_value.size() == crypto_sign_PUBLICKEYBYTES) {
|
||||
memcpy(mPublicKey, pubkey_value.content().data(), crypto_sign_PUBLICKEYBYTES);
|
||||
}
|
||||
else {
|
||||
addError(new Error("User", "pubkey from db has other size as expected"));
|
||||
}
|
||||
size_t hexSize = pubkey_value.size() * 2 + 1;
|
||||
char* hexString = (char*)malloc(hexSize);
|
||||
memset(hexString, 0, hexSize);
|
||||
@ -283,6 +300,8 @@ User::User(const unsigned char* pubkey_array)
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
memcpy(mPublicKey, pubkey_array, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
Poco::Data::BLOB pubkey(pubkey_array, 32);
|
||||
Poco::Nullable<Poco::Data::BLOB> privkey;
|
||||
|
||||
@ -769,15 +788,19 @@ MemoryBin* User::sign(const unsigned char* message, size_t messageSize)
|
||||
//auto signBinBuffer = (unsigned char*)malloc(crypto_sign_BYTES);
|
||||
auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES);
|
||||
auto privKey = getPrivKey();
|
||||
size_t actualSignLength = 0;
|
||||
|
||||
crypto_sign_detached(*signBinBuffer, NULL, message, messageSize, *privKey);
|
||||
if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *privKey)) {
|
||||
addError(new Error("User::sign", "sign failed"));
|
||||
mm->releaseMemory(privKey);
|
||||
mm->releaseMemory(signBinBuffer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, *privKey) != 0) {
|
||||
if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) {
|
||||
// Incorrect signature!
|
||||
//printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__);
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new Error("User::sign", "sign verify failed"));
|
||||
em->sendErrorsAsEmail();
|
||||
addError(new Error("User::sign", "sign verify failed"));
|
||||
mm->releaseMemory(privKey);
|
||||
mm->releaseMemory(signBinBuffer);
|
||||
return nullptr;
|
||||
|
||||
@ -80,7 +80,9 @@ public:
|
||||
inline const char* getLastName() const { return mLastName.data(); }
|
||||
inline int getDBId() const { return mDBId; }
|
||||
inline std::string getPublicKeyHex() { lock(); std::string pubkeyHex = mPublicHex; unlock(); return pubkeyHex; }
|
||||
inline const unsigned char* getPublicKey() { return mPublicKey; }
|
||||
inline void setPublicKeyHex(const std::string& publicKeyHex) { lock(); mPublicHex = publicKeyHex; unlock(); }
|
||||
inline void setPublicKey(const unsigned char* key) { lock(); memcpy(mPublicKey, key, crypto_sign_PUBLICKEYBYTES); unlock();}
|
||||
|
||||
UserStates getUserState();
|
||||
|
||||
@ -134,6 +136,7 @@ private:
|
||||
passwordHashed mPasswordHashed;
|
||||
|
||||
std::string mPublicHex;
|
||||
unsigned char mPublicKey[crypto_sign_PUBLICKEYBYTES];
|
||||
MemoryBin* mPrivateKey;
|
||||
// TODO: insert created if necessary
|
||||
|
||||
|
||||
@ -87,6 +87,25 @@ std::string ProcessingTransaction::getMemo()
|
||||
return "<uninitalized>";
|
||||
}
|
||||
|
||||
std::string ProcessingTransaction::getBodyBytes()
|
||||
{
|
||||
lock();
|
||||
if (mTransactionBody.IsInitialized()) {
|
||||
auto size = mTransactionBody.ByteSize();
|
||||
//auto bodyBytesSize = MemoryManager::getInstance()->getFreeMemory(mProtoCreation.ByteSizeLong());
|
||||
std::string resultString(size, 0);
|
||||
if (!mTransactionBody.SerializeToString(&resultString)) {
|
||||
addError(new Error("TransactionCreation::getBodyBytes", "error serializing string"));
|
||||
unlock();
|
||||
return "";
|
||||
}
|
||||
unlock();
|
||||
return resultString;
|
||||
}
|
||||
unlock();
|
||||
return "<uninitalized>";
|
||||
}
|
||||
|
||||
TransactionCreation* ProcessingTransaction::getCreationTransaction()
|
||||
{
|
||||
return dynamic_cast<TransactionCreation*>(mTransactionSpecific);
|
||||
|
||||
@ -50,6 +50,7 @@ public:
|
||||
static HASH calculateHash(const std::string& proto_message_base64);
|
||||
inline HASH getHash() { mHashMutex.lock(); HASH hs = mHash; mHashMutex.unlock(); return hs; }
|
||||
|
||||
std::string ProcessingTransaction::getBodyBytes();
|
||||
|
||||
protected:
|
||||
TransactionType mType;
|
||||
|
||||
@ -3,6 +3,18 @@
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/MemoryManager.h"
|
||||
|
||||
#include "../proto/gradido/Transaction.pb.h"
|
||||
|
||||
#include "sodium.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include "Poco/Net/HTTPRequest.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
|
||||
SigningTransaction::SigningTransaction(Poco::AutoPtr<ProcessingTransaction> processingeTransaction, Poco::AutoPtr<User> user)
|
||||
: mProcessingeTransaction(processingeTransaction), mUser(user)
|
||||
{
|
||||
@ -15,33 +27,148 @@ SigningTransaction::~SigningTransaction()
|
||||
}
|
||||
|
||||
int SigningTransaction::run() {
|
||||
auto em = ErrorManager::getInstance();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
Error* transactionError = new Error("SigningTransaction start", mProcessingeTransaction->mProtoMessageBase64.data());
|
||||
|
||||
Error* transactionError = new Error("SigningTransaction", mProcessingeTransaction->mProtoMessageBase64.data());
|
||||
addError(transactionError);
|
||||
|
||||
//= new Error("SigningTransaction start", mProcessingeTransaction->g)
|
||||
if (mUser.isNull() || !mUser->hasCryptoKey()) {
|
||||
em->addError(transactionError);
|
||||
em->addError(new Error("SigningTransaction", "user hasn't crypto key or is null"));
|
||||
em->sendErrorsAsEmail();
|
||||
addError(new Error("SigningTransaction", "user hasn't crypto key or is null"));
|
||||
sendErrorsAsEmail();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//auto privKey = mUser->getPrivKey();
|
||||
if (!mUser->hasPrivKey()) {
|
||||
em->addError(transactionError);
|
||||
em->getErrors(mUser);
|
||||
em->addError(new Error("SigningTransaction", "couldn't get user priv key"));
|
||||
em->sendErrorsAsEmail();
|
||||
getErrors(mUser);
|
||||
addError(new Error("SigningTransaction", "couldn't get user priv key"));
|
||||
sendErrorsAsEmail();
|
||||
return -2;
|
||||
}
|
||||
// get body bytes
|
||||
model::messages::gradido::Transaction transaction;
|
||||
auto bodyBytes = transaction.mutable_bodybytes();
|
||||
*bodyBytes = mProcessingeTransaction->getBodyBytes();
|
||||
if (*bodyBytes == "") {
|
||||
getErrors(mProcessingeTransaction);
|
||||
sendErrorsAsEmail();
|
||||
return -3;
|
||||
}
|
||||
// sign
|
||||
auto sign = mUser->sign((const unsigned char*)bodyBytes->data(), bodyBytes->size());
|
||||
if (!sign) {
|
||||
getErrors(mUser);
|
||||
sendErrorsAsEmail();
|
||||
mm->releaseMemory(sign);
|
||||
return -4;
|
||||
}
|
||||
auto pubkeyHex = mUser->getPublicKeyHex();
|
||||
|
||||
// pubkey for signature
|
||||
/*auto pubkeyBin = mm->getFreeMemory(ed25519_pubkey_SIZE);
|
||||
size_t realBin = 0;
|
||||
if (sodium_hex2bin(*pubkeyBin, *pubkeyBin, pubkeyHex.data(), pubkeyHex.size(), nullptr, &realBin, nullptr)) {
|
||||
addError(new Error("SigningTransaction", "error in sodium_hex2bin"));
|
||||
sendErrorsAsEmail();
|
||||
mm->releaseMemory(pubkeyBin);
|
||||
mm->releaseMemory(sign);
|
||||
return -5;
|
||||
}
|
||||
*/
|
||||
// add to message
|
||||
auto sigMap = transaction.mutable_sigmap();
|
||||
auto sigPair = sigMap->add_sigpair();
|
||||
|
||||
//auto sign = mUser->sign(mProcessingeTransaction->)
|
||||
delete transactionError;
|
||||
//delete privKey;
|
||||
//mm->releaseMemory(privKey);
|
||||
auto pubkeyBytes = sigPair->mutable_pubkey();
|
||||
auto pubkeyBin = mUser->getPublicKey();
|
||||
*pubkeyBytes = std::string((const char*)pubkeyBin, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
|
||||
auto sigBytes = sigPair->mutable_ed25519();
|
||||
*sigBytes = std::string((char*)*sign, sign->size());
|
||||
mm->releaseMemory(sign);
|
||||
|
||||
|
||||
// finalize
|
||||
std::string finalTransactionBin = transaction.SerializeAsString();
|
||||
if (finalTransactionBin == "") {
|
||||
addError(new Error("SigningTransaction", "error serializing final transaction"));
|
||||
sendErrorsAsEmail();
|
||||
return -6;
|
||||
}
|
||||
|
||||
// finale to base64
|
||||
auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_ORIGINAL);
|
||||
auto finalBase64Bin = mm->getFreeMemory(finalBase64Size);
|
||||
if (!sodium_bin2base64(*finalBase64Bin, finalBase64Size, (const unsigned char*)finalTransactionBin.data(), finalTransactionBin.size(), sodium_base64_VARIANT_ORIGINAL)) {
|
||||
addError(new Error("SigningTransaction", "error convert final transaction to base64"));
|
||||
sendErrorsAsEmail();
|
||||
mm->releaseMemory(finalBase64Bin);
|
||||
return -7;
|
||||
}
|
||||
|
||||
// create json request
|
||||
|
||||
Poco::JSON::Object requestJson;
|
||||
requestJson.set("method", "putTransaction");
|
||||
requestJson.set("transaction", std::string((char*)*finalBase64Bin, finalBase64Size));
|
||||
printf("base64 transaction: %s\n", (char*)*finalBase64Bin);
|
||||
mm->releaseMemory(finalBase64Bin);
|
||||
|
||||
|
||||
//std::string request = requestJson.stringify();
|
||||
|
||||
// send post request via https
|
||||
// 443 = HTTPS Default
|
||||
// TODO: adding port into ServerConfig
|
||||
try {
|
||||
Poco::Net::HTTPSClientSession httpsClientSession(ServerConfig::g_php_serverHost, 443);
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/TransactionJsonRequestHandler");
|
||||
|
||||
request.setChunkedTransferEncoding(true);
|
||||
std::ostream& requestStream = httpsClientSession.sendRequest(request);
|
||||
requestJson.stringify(requestStream);
|
||||
|
||||
Poco::Net::HTTPResponse response;
|
||||
std::istream& request_stream = httpsClientSession.receiveResponse(response);
|
||||
|
||||
// debugging answer
|
||||
std::stringstream responseStringStream;
|
||||
for (std::string line; std::getline(request_stream, line); ) {
|
||||
responseStringStream << line << std::endl;
|
||||
}
|
||||
//printf("server response: %s\n", responseStringStream.str().data());
|
||||
FILE* f = fopen("response.html", "wt");
|
||||
std::string responseString = responseStringStream.str();
|
||||
fwrite(responseString.data(), 1, responseString.size(), f);
|
||||
fclose(f);
|
||||
|
||||
// extract parameter from request
|
||||
Poco::JSON::Parser jsonParser;
|
||||
Poco::Dynamic::Var parsedJson;
|
||||
try {
|
||||
parsedJson = jsonParser.parse(request_stream);
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
//printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data());
|
||||
addError(new ParamError("SigningTransaction", "error parsing request answer", ex.displayText().data()));
|
||||
sendErrorsAsEmail();
|
||||
return -9;
|
||||
}
|
||||
|
||||
if (parsedJson.isStruct()) {
|
||||
|
||||
}
|
||||
int zahl = 1;
|
||||
}
|
||||
catch (Poco::Exception& e) {
|
||||
addError(new ParamError("SigningTransaction", "connect error to php server", e.displayText().data()));
|
||||
sendErrorsAsEmail();
|
||||
return -8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user