created crypto key in separate thread

This commit is contained in:
Dario 2019-09-28 13:33:30 +02:00
parent cf0e70ae07
commit d3b9352d51
12 changed files with 111 additions and 50 deletions

View File

@ -6,7 +6,7 @@
ObfusArray::ObfusArray(size_t size, const unsigned char * data) ObfusArray::ObfusArray(size_t size, const unsigned char * data)
: m_arraySize(0), m_offsetSize(0), m_dataSize(size), m_Data(nullptr) : m_arraySize(0), m_offsetSize(0), m_dataSize(size), m_Data(nullptr)
{ {
m_arraySize = size + randombytes_random() % (int)roundf(size*0.25f); m_arraySize = size + 2 + randombytes_random() % (int)roundf(size*0.25f);
m_Data = (unsigned char*)malloc(m_arraySize); m_Data = (unsigned char*)malloc(m_arraySize);
m_offsetSize = randombytes_random() % (int)roundf((m_arraySize - m_dataSize) * 0.8f); m_offsetSize = randombytes_random() % (int)roundf((m_arraySize - m_dataSize) * 0.8f);

View File

@ -160,6 +160,13 @@ public:
addError(new ParamError(__FUNCTION__, "invalid field index:", index)); addError(new ParamError(__FUNCTION__, "invalid field index:", index));
return MYSQL_ROW_TYPE_NONE; return MYSQL_ROW_TYPE_NONE;
} }
inline const char* getHeaderName(int index) {
if (index > 0 && index < mFieldCount) {
return mHeader[index].name.data();
}
addError(new ParamError(__FUNCTION__, "invalid field index:", index));
return nullptr;
}
inline bool addCellToCurrentRow(long value) { return addCellToCurrentRow(new MysqlTableCellInt(value)); } inline bool addCellToCurrentRow(long value) { return addCellToCurrentRow(new MysqlTableCellInt(value)); }
inline bool addCellToCurrentRow(const long long& value) { return addCellToCurrentRow(new MysqlTableCellLong(value)); } inline bool addCellToCurrentRow(const long long& value) { return addCellToCurrentRow(new MysqlTableCellLong(value)); }
inline bool addCellToCurrentRow(const char* string) { return addCellToCurrentRow(new MysqlTableCellString(string)); } inline bool addCellToCurrentRow(const char* string) { return addCellToCurrentRow(new MysqlTableCellString(string)); }

View File

@ -6,7 +6,7 @@
#include "sodium.h" #include "sodium.h"
Session::Session(int handle) Session::Session(int handle)
: mHandleId(handle) : mHandleId(handle), mSessionUser(nullptr)
{ {
} }
@ -60,9 +60,18 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
//mPassphrase = passphrase; //mPassphrase = passphrase;
}*/ }*/
//mSessionUser = new User(email.data(), name.data(), password.data(), passphrase.size() ? passphrase.data() : mPassphrase.data()); mSessionUser = new User(email.data(), name.data());
updateTimeout(); updateTimeout();
// create user crypto key
UniLib::controller::TaskPtr cryptoKeyTask(new UserCreateCryptoKey(mSessionUser, password, ServerConfig::g_CPUScheduler));
//cryptoKeyTask->scheduleTask(cryptoKeyTask);
// depends on crypto key
UniLib::controller::TaskPtr writeUserIntoDB(new UserWriteIntoDB(mSessionUser, ServerConfig::g_CPUScheduler, 1));
writeUserIntoDB->setParentTaskPtrInArray(cryptoKeyTask, 0);
writeUserIntoDB->scheduleTask(writeUserIntoDB);
// write user into db // write user into db
// generate and write email verification into db // generate and write email verification into db
// send email // send email

View File

@ -20,7 +20,7 @@ void NewUser::run()
{ {
// create crypto key // create crypto key
if (!mUser->hasCryptoKey()) { if (!mUser->hasCryptoKey()) {
mUser->createCryptoKey(mUser->getEmail(), mPassword.data()); mUser->createCryptoKey(mPassword.data());
} }
// generate // generate
@ -45,20 +45,30 @@ void LoginUser::run()
} }
// ******************************************************************************* // -------------------------------------------------------------------------------------------------
User::User(const char* email, const char* name, const char* password) int UserCreateCryptoKey::run()
: mEmail(email), mFirstName(name), mCryptoKey(nullptr)
{ {
//crypto_shorthash_KEYBYTES mUser->createCryptoKey(mPassword);
//mPasswordHashed = printf("crypto key created\n");
crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); return 0;
} }
User::User(const char* email, const char* password) // -----------------------------------------------------------------------------------------------------
: mEmail(email)
int UserWriteIntoDB::run()
{ {
crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); return 0;
}
// *******************************************************************************
User::User(const char* email, const char* name)
: mEmail(email), mFirstName(name), mCryptoKey(nullptr)
{
//crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey);
memset(mPasswordHashed, 0, crypto_shorthash_BYTES);
} }
@ -97,14 +107,12 @@ std::string User::generateNewPassphrase(Mnemonic* word_source)
return phrase_buffer; return phrase_buffer;
} }
void User::createCryptoKey(const char* username, const char* password) void User::createCryptoKey(const std::string& password)
{ {
// TODO: put it in secure location // TODO: put it in secure location
static const unsigned char app_secret[] = { 0x21, 0xff, 0xbb, 0xc6, 0x16, 0xfe }; static const unsigned char app_secret[] = { 0x21, 0xff, 0xbb, 0xc6, 0x16, 0xfe };
size_t username_size = strlen(username);
size_t password_size = strlen(password);
sha_context context_sha512; sha_context context_sha512;
//unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE); //unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE);
if (SHA_512_SIZE < crypto_pwhash_SALTBYTES) { if (SHA_512_SIZE < crypto_pwhash_SALTBYTES) {
@ -113,21 +121,21 @@ void User::createCryptoKey(const char* username, const char* password)
} }
unsigned char hash512_salt[SHA_512_SIZE]; // need at least crypto_pwhash_SALTBYTES 16U unsigned char hash512_salt[SHA_512_SIZE]; // need at least crypto_pwhash_SALTBYTES 16U
sha512_init(&context_sha512); sha512_init(&context_sha512);
sha512_update(&context_sha512, (const unsigned char*)username, username_size); sha512_update(&context_sha512, (const unsigned char*)mEmail.data(), mEmail.size());
sha512_update(&context_sha512, app_secret, 6); sha512_update(&context_sha512, app_secret, 6);
sha512_final(&context_sha512, hash512_salt); sha512_final(&context_sha512, hash512_salt);
unsigned char* key = (unsigned char *)malloc(crypto_box_SEEDBYTES); // 32U unsigned char* key = (unsigned char *)malloc(crypto_box_SEEDBYTES); // 32U
if (crypto_pwhash(key, crypto_box_SEEDBYTES, password, password_size, hash512_salt, 2U, 8388608, 2) != 0) { if (crypto_pwhash(key, crypto_box_SEEDBYTES, password.data(), password.size(), hash512_salt, 10U, 33554432, 2) != 0) {
addError(new ParamError(__FUNCTION__, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno))); addError(new ParamError(__FUNCTION__, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno)));
//printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno)); //printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno));
//printf("pwd: %s\n", pwd); //printf("pwd: %s\n", pwd);
return ; return ;
} }
crypto_shorthash(mPasswordHashed, key, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey);
lock(); lock();
mCryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key); mCryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key);
unlock(); unlock();

View File

@ -5,17 +5,20 @@
#include <string> #include <string>
#include "ErrorList.h" #include "ErrorList.h"
#include "Poco/Thread.h" #include "Poco/Thread.h"
#include "../tasks/CPUTask.h"
class NewUser; class NewUser;
class UserCreateCryptoKey;
class User : public ErrorList class User : public ErrorList
{ {
friend NewUser; friend NewUser;
friend UserCreateCryptoKey;
public: public:
// new user // new user
User(const char* email, const char* name, const char* password); //User(const char* email, const char* name, const char* password);
// existing user // existing user
User(const char* email, const char* password); User(const char* email, const char* name);
~User(); ~User();
@ -25,8 +28,10 @@ public:
inline const char* getEmail() { return mEmail.data(); } inline const char* getEmail() { return mEmail.data(); }
inline const char* getName() { return mFirstName.data(); } inline const char* getName() { return mFirstName.data(); }
protected: protected:
void createCryptoKey(const char* email, const char* password); void createCryptoKey(const std::string& password);
inline void lock() { mWorkingMutex.lock(); } inline void lock() { mWorkingMutex.lock(); }
inline void unlock() { mWorkingMutex.unlock(); } inline void unlock() { mWorkingMutex.unlock(); }
@ -42,6 +47,33 @@ private:
}; };
class UserCreateCryptoKey : public UniLib::controller::CPUTask
{
public:
UserCreateCryptoKey(User* user, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler)
: UniLib::controller::CPUTask(cpuScheduler), mUser(user), mPassword(password) {}
virtual int run();
virtual const char* getResourceType() const { return "UserCreateCryptoKey"; };
private:
User* mUser;
std::string mPassword;
};
class UserWriteIntoDB : public UniLib::controller::CPUTask
{
public:
UserWriteIntoDB(User* user, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0)
: UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user) {}
virtual int run();
virtual const char* getResourceType() const { return "UserWriteIntoDB"; };
private:
User* mUser;
};
class NewUser : public Poco::Runnable class NewUser : public Poco::Runnable
{ {
public: public:

View File

@ -35,7 +35,9 @@ namespace UniLib {
const char* name = mWaitingTask->getName(); const char* name = mWaitingTask->getName();
l->addTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder(), mWaitingTask->getResourceType(), mName.data(), name); l->addTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder(), mWaitingTask->getResourceType(), mName.data(), name);
#endif #endif
mWaitingTask->run(); if (!mWaitingTask->run()) {
mWaitingTask->setTaskFinished();
}
#ifdef _UNI_LIB_DEBUG #ifdef _UNI_LIB_DEBUG
l->removeTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder()); l->removeTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder());
SpeedLog.writeToLog("%s used on thread: %s by Task: %s of: %s", SpeedLog.writeToLog("%s used on thread: %s by Task: %s of: %s",

View File

@ -55,7 +55,7 @@ namespace UniLib {
virtual const char* getResourceType() const {return "CPUTask";}; virtual const char* getResourceType() const {return "CPUTask";};
//! \brief return true if task has finished, else false //! \brief return true if task has finished, else false
//! automatic scheduling of task if he isn't finished and sheduled yet //! automatic scheduling of task if he isn't finished and sheduled yet
virtual bool isTaskFinished() { return true; }
virtual void scheduleTask(TaskPtr own); virtual void scheduleTask(TaskPtr own);
protected: protected:

View File

@ -5,7 +5,7 @@ namespace UniLib {
namespace controller { namespace controller {
Task::Task() Task::Task()
: mTaskScheduled(false), mFinishCommand(nullptr), mParentTaskPtrArray(nullptr), : mTaskScheduled(false), mFinishCommand(nullptr), mParentTaskPtrArray(nullptr),
mParentTaskPtrArraySize(0), mDeleted(false), mReferenceCount(1) mParentTaskPtrArraySize(0), mDeleted(false), mFinished(false), mReferenceCount(1)
{ {
} }
@ -32,11 +32,7 @@ namespace UniLib {
lock(); lock();
for(size_t i = 0; i < mParentTaskPtrArraySize; i++) { for(size_t i = 0; i < mParentTaskPtrArraySize; i++) {
TaskPtr task = mParentTaskPtrArray[i]; TaskPtr task = mParentTaskPtrArray[i];
if (!task.isNull()) { if (!task.isNull() && !task->isTaskFinished()) {
allFinished = false;
continue;
}
if(!task->isTaskFinished()) {
allFinished = false; allFinished = false;
if(!task->isTaskSheduled()) if(!task->isTaskSheduled())
mParentTaskPtrArray[i]->scheduleTask(mParentTaskPtrArray[i]); mParentTaskPtrArray[i]->scheduleTask(mParentTaskPtrArray[i]);

View File

@ -65,8 +65,9 @@ namespace UniLib {
bool isAllParentsReady(); bool isAllParentsReady();
//! \brief return true if task has finished, else false //! \brief return true if task has finished, else false
//! automatic scheduling of task if he isn't finished and sheduled yet //! automatic scheduling of task if he isn't finished and sheduled yet
virtual bool isTaskFinished() { return false; } virtual bool isTaskFinished() { lock(); bool ret = mFinished; unlock(); return ret; }
//! \brief called from task scheduler, maybe from another thread //! \brief called from task scheduler, maybe from another thread
//! \return if return 0, mark task as finished
virtual int run() = 0; virtual int run() = 0;
@ -102,11 +103,14 @@ namespace UniLib {
// for poco auto ptr // for poco auto ptr
void duplicate(); void duplicate();
void release(); void release();
inline void setTaskFinished() { lock(); mFinished = true; unlock(); }
protected: protected:
// scheduling only once // scheduling only once
inline bool isTaskSheduled() {return mTaskScheduled;} inline bool isTaskSheduled() {return mTaskScheduled;}
inline void taskScheduled() {mTaskScheduled = true;} inline void taskScheduled() {mTaskScheduled = true;}
bool mTaskScheduled; bool mTaskScheduled;
Command* mFinishCommand; Command* mFinishCommand;
private: private:
@ -114,6 +118,7 @@ namespace UniLib {
size_t mParentTaskPtrArraySize; size_t mParentTaskPtrArraySize;
Poco::Mutex mWorkingMutex; Poco::Mutex mWorkingMutex;
bool mDeleted; bool mDeleted;
bool mFinished;
// for poco auto ptr // for poco auto ptr
int mReferenceCount; int mReferenceCount;
#ifdef _UNI_LIB_DEBUG #ifdef _UNI_LIB_DEBUG

View File

@ -55,10 +55,8 @@ namespace UniLib {
while (true) { while (true) {
try { try {
semaphore.tryWait(100); semaphore.tryWait(100);
printf("[Thread::%s] end worker thread\n", __FUNCTION__); //printf("[Thread::%s] end worker thread\n", __FUNCTION__);
break; //break;
} catch (Poco::TimeoutException& e) {
if (exitCalled) return; if (exitCalled) return;
// Lock work mutex // Lock work mutex
threadLock(); threadLock();
@ -83,8 +81,9 @@ namespace UniLib {
return; return;
} }
} } catch (Poco::TimeoutException& e) {
catch (Poco::Exception& e) { printf("[Thread::%s] timeout exception\n", __FUNCTION__);
} catch (Poco::Exception& e) {
printf("[Thread::%s] exception: %s\n", __FUNCTION__, e.message().data()); printf("[Thread::%s] exception: %s\n", __FUNCTION__, e.message().data());
return; return;
} }

View File

@ -1,7 +1,7 @@
#include "WriteIntoDBTask.h" #include "WriteIntoDBTask.h"
WriteIntoDBTask::WriteIntoDBTask(ConnectionType type, std::vector<MysqlTable*> multipleData) WriteIntoDBTask::WriteIntoDBTask(ConnectionType type, std::vector<MysqlTable*> multipleData, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount/* = 0*/)
: mFinished(false), mConnectionType(type), mDataToInsert(multipleData) : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mConnectionType(type), mDataToInsert(multipleData)
{ {
} }
@ -26,7 +26,12 @@ int WriteIntoDBTask::run()
use(person.name), use(person.name),
use(person.address), use(person.address),
use(person.age);*/ use(person.age);*/
insert << "INSERT INTO " << tableName << "VALUES("; insert << "INSERT INTO " << tableName << " (";
for (int iField = 0; iField < (*it)->getFieldCount(); iField++) {
if (iField > 0) insert << ",";
insert << (*it)->getHeaderName(iField);
}
insert << ") VALUES(";
for (int iCell = 0; iCell < (*it)->getFieldCount(); iCell++) { for (int iCell = 0; iCell < (*it)->getFieldCount(); iCell++) {
if (iCell > 0) insert << ","; if (iCell > 0) insert << ",";
insert << "?"; insert << "?";
@ -34,10 +39,8 @@ int WriteIntoDBTask::run()
insert << ")"; insert << ")";
(*it)->connectToStatement(&insert); (*it)->connectToStatement(&insert);
insert.execute(); insert.execute();
} }
lock();
mFinished = true;
unlock();
return 0; return 0;
} }

View File

@ -1,29 +1,29 @@
#ifndef GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE #ifndef GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE
#define GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE #define GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE
#include "Task.h" #include "CPUTask.h"
#include "../SingletonManager/ConnectionManager.h" #include "../SingletonManager/ConnectionManager.h"
#include "../MySQL/MysqlTable.h" #include "../MySQL/MysqlTable.h"
#include "Poco/Tuple.h" #include "Poco/Tuple.h"
class WriteIntoDBTask : public UniLib::controller::Task class WriteIntoDBTask : public UniLib::controller::CPUTask
{ {
public: public:
//! \param multipleData clear table in deconstruction, call delete for every entry //! \param multipleData clear table in deconstruction, call delete for every entry
WriteIntoDBTask(ConnectionType type, std::vector<MysqlTable*> multipleData); WriteIntoDBTask(ConnectionType type, std::vector<MysqlTable*> multipleData, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0);
virtual ~WriteIntoDBTask(); virtual ~WriteIntoDBTask();
virtual int run(); virtual int run();
virtual const char* getResourceType() const { return "WriteIntoDBTask"; }; virtual const char* getResourceType() const { return "WriteIntoDBTask"; };
virtual bool isTaskFinished() { return true; }
protected: protected:
private: private:
bool mFinished;
ConnectionType mConnectionType; ConnectionType mConnectionType;
std::vector<MysqlTable*> mDataToInsert; std::vector<MysqlTable*> mDataToInsert;
}; };