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)
: 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_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));
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(const long long& value) { return addCellToCurrentRow(new MysqlTableCellLong(value)); }
inline bool addCellToCurrentRow(const char* string) { return addCellToCurrentRow(new MysqlTableCellString(string)); }

View File

@ -6,7 +6,7 @@
#include "sodium.h"
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;
}*/
//mSessionUser = new User(email.data(), name.data(), password.data(), passphrase.size() ? passphrase.data() : mPassphrase.data());
mSessionUser = new User(email.data(), name.data());
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
// generate and write email verification into db
// send email

View File

@ -20,7 +20,7 @@ void NewUser::run()
{
// create crypto key
if (!mUser->hasCryptoKey()) {
mUser->createCryptoKey(mUser->getEmail(), mPassword.data());
mUser->createCryptoKey(mPassword.data());
}
// generate
@ -45,20 +45,30 @@ void LoginUser::run()
}
// *******************************************************************************
// -------------------------------------------------------------------------------------------------
User::User(const char* email, const char* name, const char* password)
: mEmail(email), mFirstName(name), mCryptoKey(nullptr)
int UserCreateCryptoKey::run()
{
//crypto_shorthash_KEYBYTES
//mPasswordHashed =
crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey);
mUser->createCryptoKey(mPassword);
printf("crypto key created\n");
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;
}
void User::createCryptoKey(const char* username, const char* password)
void User::createCryptoKey(const std::string& password)
{
// TODO: put it in secure location
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;
//unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE);
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
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_final(&context_sha512, hash512_salt);
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)));
//printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno));
//printf("pwd: %s\n", pwd);
return ;
}
crypto_shorthash(mPasswordHashed, key, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey);
lock();
mCryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key);
unlock();

View File

@ -5,17 +5,20 @@
#include <string>
#include "ErrorList.h"
#include "Poco/Thread.h"
#include "../tasks/CPUTask.h"
class NewUser;
class UserCreateCryptoKey;
class User : public ErrorList
{
friend NewUser;
friend UserCreateCryptoKey;
public:
// new user
User(const char* email, const char* name, const char* password);
//User(const char* email, const char* name, const char* password);
// existing user
User(const char* email, const char* password);
User(const char* email, const char* name);
~User();
@ -24,9 +27,11 @@ public:
inline bool hasCryptoKey() { lock(); bool bRet = mCryptoKey != nullptr; unlock(); return bRet; }
inline const char* getEmail() { return mEmail.data(); }
inline const char* getName() { return mFirstName.data(); }
protected:
void createCryptoKey(const char* email, const char* password);
void createCryptoKey(const std::string& password);
inline void lock() { mWorkingMutex.lock(); }
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
{
public:

View File

@ -35,7 +35,9 @@ namespace UniLib {
const char* name = mWaitingTask->getName();
l->addTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder(), mWaitingTask->getResourceType(), mName.data(), name);
#endif
mWaitingTask->run();
if (!mWaitingTask->run()) {
mWaitingTask->setTaskFinished();
}
#ifdef _UNI_LIB_DEBUG
l->removeTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder());
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";};
//! \brief return true if task has finished, else false
//! automatic scheduling of task if he isn't finished and sheduled yet
virtual bool isTaskFinished() { return true; }
virtual void scheduleTask(TaskPtr own);
protected:

View File

@ -5,7 +5,7 @@ namespace UniLib {
namespace controller {
Task::Task()
: 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();
for(size_t i = 0; i < mParentTaskPtrArraySize; i++) {
TaskPtr task = mParentTaskPtrArray[i];
if (!task.isNull()) {
allFinished = false;
continue;
}
if(!task->isTaskFinished()) {
if (!task.isNull() && !task->isTaskFinished()) {
allFinished = false;
if(!task->isTaskSheduled())
mParentTaskPtrArray[i]->scheduleTask(mParentTaskPtrArray[i]);

View File

@ -65,8 +65,9 @@ namespace UniLib {
bool isAllParentsReady();
//! \brief return true if task has finished, else false
//! 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
//! \return if return 0, mark task as finished
virtual int run() = 0;
@ -102,11 +103,14 @@ namespace UniLib {
// for poco auto ptr
void duplicate();
void release();
inline void setTaskFinished() { lock(); mFinished = true; unlock(); }
protected:
// scheduling only once
inline bool isTaskSheduled() {return mTaskScheduled;}
inline void taskScheduled() {mTaskScheduled = true;}
bool mTaskScheduled;
Command* mFinishCommand;
private:
@ -114,6 +118,7 @@ namespace UniLib {
size_t mParentTaskPtrArraySize;
Poco::Mutex mWorkingMutex;
bool mDeleted;
bool mFinished;
// for poco auto ptr
int mReferenceCount;
#ifdef _UNI_LIB_DEBUG

View File

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

View File

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

View File

@ -1,29 +1,29 @@
#ifndef 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 "../MySQL/MysqlTable.h"
#include "Poco/Tuple.h"
class WriteIntoDBTask : public UniLib::controller::Task
class WriteIntoDBTask : public UniLib::controller::CPUTask
{
public:
//! \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 int run();
virtual const char* getResourceType() const { return "WriteIntoDBTask"; };
virtual bool isTaskFinished() { return true; }
protected:
private:
bool mFinished;
ConnectionType mConnectionType;
std::vector<MysqlTable*> mDataToInsert;
};