mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
new passphrase generate code
This commit is contained in:
parent
fc22bbc1e0
commit
a7a1758db8
@ -6,7 +6,9 @@
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/ConnectionManager.h"
|
||||
|
||||
//#include "Poco/ISO8859_4Encoding.h"
|
||||
#include "Poco/Types.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
@ -39,46 +41,37 @@ KeyPair::~KeyPair()
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_source)
|
||||
std::string KeyPair::passphraseTransform(const std::string& passphrase, const Mnemonic* currentWordSource, const Mnemonic* targetWordSource)
|
||||
{
|
||||
if (!currentWordSource || !targetWordSource) {
|
||||
return "";
|
||||
}
|
||||
if (targetWordSource == currentWordSource) {
|
||||
return passphrase;
|
||||
}
|
||||
auto word_indices = createWordIndices(passphrase, currentWordSource);
|
||||
if (!word_indices) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return createClearPassphraseFromWordIndices(word_indices, targetWordSource);
|
||||
}
|
||||
|
||||
bool KeyPair::generateFromPassphrase(const char* passphrase, const Mnemonic* word_source)
|
||||
{
|
||||
auto er = ErrorManager::getInstance();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
// libsodium doc: https://libsodium.gitbook.io/doc/advanced/hmac-sha2
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||||
//crypto_auth_hmacsha512_keygen
|
||||
unsigned long word_indices[PHRASE_WORD_COUNT];
|
||||
memset(word_indices, 0, PHRASE_WORD_COUNT);
|
||||
|
||||
//DHASH key = DRMakeStringHash(passphrase);
|
||||
size_t pass_phrase_size = strlen(passphrase);
|
||||
std::string clearPassphrase = "";
|
||||
char acBuffer[STR_BUFFER_SIZE]; memset(acBuffer, 0, STR_BUFFER_SIZE);
|
||||
size_t buffer_cursor = 0;
|
||||
// get word indices for hmac key
|
||||
unsigned char word_cursor = 0;
|
||||
for (size_t i = 0; i <= pass_phrase_size; i++) {
|
||||
if (passphrase[i] == ' ' || passphrase[i] == '\0') {
|
||||
if(buffer_cursor < 3) continue;
|
||||
if (word_source->isWordExist(acBuffer)) {
|
||||
clearPassphrase += acBuffer;
|
||||
clearPassphrase += " ";
|
||||
word_indices[word_cursor] = word_source->getWordIndex(acBuffer);
|
||||
//printf("index for %s is: %hu\n", acBuffer, word_source->getWordIndex(acBuffer));
|
||||
}
|
||||
else {
|
||||
er->addError(new ParamError("KeyPair::generateFromPassphrase", "word didn't exist", acBuffer));
|
||||
er->sendErrorsAsEmail();
|
||||
return false;
|
||||
}
|
||||
|
||||
word_cursor++;
|
||||
memset(acBuffer, 0, STR_BUFFER_SIZE);
|
||||
buffer_cursor = 0;
|
||||
}
|
||||
else {
|
||||
acBuffer[buffer_cursor++] = passphrase[i];
|
||||
}
|
||||
|
||||
auto word_indices = createWordIndices(passphrase, word_source);
|
||||
if (!word_indices) {
|
||||
return false;
|
||||
}
|
||||
std::string clearPassphrase =
|
||||
createClearPassphraseFromWordIndices(word_indices, &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]);
|
||||
|
||||
|
||||
sha_context state;
|
||||
|
||||
unsigned char hash[SHA_512_SIZE];
|
||||
@ -92,6 +85,8 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
|
||||
sha512_final(&state, hash);
|
||||
//crypto_auth_hmacsha512_final(&state, hash);
|
||||
|
||||
mm->releaseMemory(word_indices);
|
||||
|
||||
// debug passphrase
|
||||
// printf("\passsphrase: <%s>\n", passphrase);
|
||||
//printf("word_indices: \n%s\n", getHex((unsigned char*)word_indices, sizeof(word_indices)).data());
|
||||
@ -111,8 +106,6 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
|
||||
public_key_t pbl_key_t;
|
||||
ed25519_derive_public_key(&prv_key_t, &pbl_key_t);
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
//memcpy(private_key, prv_key_t.data, 32);
|
||||
if (!mPrivateKey) {
|
||||
//delete mPrivateKey;
|
||||
@ -151,6 +144,70 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryBin* KeyPair::createWordIndices(const std::string& passphrase, const Mnemonic* word_source)
|
||||
{
|
||||
auto er = ErrorManager::getInstance();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
auto word_indices = mm->getFreeMemory(sizeof(Poco::UInt32) * PHRASE_WORD_COUNT);
|
||||
Poco::UInt32* word_indices_p = (Poco::UInt32*)(word_indices->data());
|
||||
unsigned long word_indices_old[PHRASE_WORD_COUNT] = { 0 };
|
||||
//memset(word_indices_old, 0, PHRASE_WORD_COUNT);// *sizeof(unsigned long));
|
||||
memset(*word_indices, 0, word_indices->size());
|
||||
|
||||
//DHASH key = DRMakeStringHash(passphrase);
|
||||
size_t pass_phrase_size = passphrase.size();
|
||||
|
||||
char acBuffer[STR_BUFFER_SIZE]; memset(acBuffer, 0, STR_BUFFER_SIZE);
|
||||
size_t buffer_cursor = 0;
|
||||
|
||||
// get word indices for hmac key
|
||||
unsigned char word_cursor = 0;
|
||||
for (auto it = passphrase.begin(); it != passphrase.end(); it++) {
|
||||
if (*it == ' ' || *it == '\0') {
|
||||
if (buffer_cursor < 3) continue;
|
||||
if (word_source->isWordExist(acBuffer)) {
|
||||
word_indices_p[word_cursor] = word_source->getWordIndex(acBuffer);
|
||||
word_indices_old[word_cursor] = word_source->getWordIndex(acBuffer);
|
||||
}
|
||||
else {
|
||||
er->addError(new ParamError("KeyPair::generateFromPassphrase", "word didn't exist", acBuffer));
|
||||
er->sendErrorsAsEmail();
|
||||
mm->releaseMemory(word_indices);
|
||||
return nullptr;
|
||||
}
|
||||
word_cursor++;
|
||||
memset(acBuffer, 0, STR_BUFFER_SIZE);
|
||||
buffer_cursor = 0;
|
||||
|
||||
}
|
||||
else {
|
||||
acBuffer[buffer_cursor++] = *it;
|
||||
}
|
||||
}
|
||||
if (memcmp(word_indices_p, word_indices_old, word_indices->size()) != 0) {
|
||||
|
||||
printf("not identical\n");
|
||||
memcpy(word_indices_p, word_indices_old, word_indices->size());
|
||||
}
|
||||
return word_indices;
|
||||
}
|
||||
|
||||
std::string KeyPair::createClearPassphraseFromWordIndices(MemoryBin* word_indices, const Mnemonic* word_source)
|
||||
{
|
||||
Poco::UInt32* word_indices_p = (Poco::UInt32*)word_indices->data();
|
||||
std::string clearPassphrase;
|
||||
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
|
||||
if (i * sizeof(Poco::UInt32) >= word_indices->size()) break;
|
||||
auto word = word_source->getWord(word_indices_p[i]);
|
||||
if (word) {
|
||||
clearPassphrase += word;
|
||||
clearPassphrase += " ";
|
||||
}
|
||||
}
|
||||
return clearPassphrase;
|
||||
}
|
||||
|
||||
std::string KeyPair::filterPassphrase(const std::string& passphrase)
|
||||
{
|
||||
std::string filteredPassphrase;
|
||||
|
||||
@ -23,8 +23,10 @@ public:
|
||||
KeyPair();
|
||||
~KeyPair();
|
||||
|
||||
bool generateFromPassphrase(const char* passphrase, Mnemonic* word_source);
|
||||
bool generateFromPassphrase(const char* passphrase, const Mnemonic* word_source);
|
||||
static std::string passphraseTransform(const std::string& passphrase, const Mnemonic* currentWordSource, const Mnemonic* targetWordSource);
|
||||
static std::string filterPassphrase(const std::string& passphrase);
|
||||
|
||||
std::string getPubkeyHex();
|
||||
bool savePrivKey(int userId);
|
||||
static std::string getHex(const unsigned char* data, Poco::UInt32 size);
|
||||
@ -37,6 +39,8 @@ public:
|
||||
protected:
|
||||
const MemoryBin* getPrivateKey() const { return mSodiumSecret; }
|
||||
|
||||
static MemoryBin* createWordIndices(const std::string& passphrase, const Mnemonic* word_source);
|
||||
static std::string createClearPassphraseFromWordIndices(MemoryBin* word_indices, const Mnemonic* word_source);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -30,9 +30,9 @@ public:
|
||||
|
||||
int init(void(*fill_words_func)(unsigned char*), unsigned int original_size, unsigned int compressed_size);
|
||||
|
||||
inline const char* getWord(unsigned int index) { Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); if (index < 2048 && index >= 0) return mWords[index]; return nullptr; }
|
||||
inline unsigned short getWordIndex(const char* word) { Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); DHASH word_hash = DRMakeStringHash(word); return mWordHashIndices.find(word_hash)->second; }
|
||||
inline bool isWordExist(const std::string& word) { Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); DHASH word_hash = DRMakeStringHash(word.data()); return mWordHashIndices.find(word_hash) != mWordHashIndices.end(); }
|
||||
inline const char* getWord(unsigned int index) const { if (index < 2048 && index >= 0) return mWords[index]; return nullptr; }
|
||||
inline unsigned short getWordIndex(const char* word) const { DHASH word_hash = DRMakeStringHash(word); return mWordHashIndices.find(word_hash)->second; }
|
||||
inline bool isWordExist(const std::string& word) const { DHASH word_hash = DRMakeStringHash(word.data()); return mWordHashIndices.find(word_hash) != mWordHashIndices.end(); }
|
||||
// using only for debugging
|
||||
std::string getCompleteWordList();
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "RegisterAdminPage.h"
|
||||
#include "DebugPassphrasePage.h"
|
||||
#include "AdminCheckUserBackup.h"
|
||||
#include "TranslatePassphrase.h"
|
||||
|
||||
#include "DecodeTransactionPage.h"
|
||||
|
||||
@ -121,7 +122,6 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (externReferer != "") {
|
||||
s->setLastReferer(externReferer);
|
||||
}
|
||||
|
||||
auto user = s->getUser();
|
||||
if (s->errorCount() || (!user.isNull() && user->errorCount())) {
|
||||
user->sendErrorsAsEmail();
|
||||
@ -134,6 +134,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
pageRequestHandler->setProfiler(timeUsed);
|
||||
return pageRequestHandler;
|
||||
}
|
||||
if (url_first_part == "/transform_passphrase") {
|
||||
auto pageRequestHandler = new TranslatePassphrase(s);
|
||||
pageRequestHandler->setProfiler(timeUsed);
|
||||
return pageRequestHandler;
|
||||
}
|
||||
if (s->getNewUser()->getModel()->getRole() == model::table::ROLE_ADMIN) {
|
||||
if (url_first_part == "/adminRegister") {
|
||||
auto pageRequestHandler = new RegisterAdminPage(s);
|
||||
|
||||
@ -38,6 +38,8 @@ public:
|
||||
inline size_t size() const { return static_cast<size_t>(mSize); }
|
||||
inline operator size_t() const { return static_cast<size_t>(mSize); }
|
||||
|
||||
inline unsigned char* data() { return mData; }
|
||||
|
||||
protected:
|
||||
MemoryBin(Poco::UInt32 size);
|
||||
~MemoryBin();
|
||||
|
||||
@ -926,13 +926,13 @@ bool Session::useOrGeneratePassphrase(const std::string& passphase)
|
||||
bool Session::generatePassphrase()
|
||||
{
|
||||
auto lang = getLanguage();
|
||||
if (lang == LANG_EN) {
|
||||
/*if (lang == LANG_EN) {
|
||||
mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]);
|
||||
}
|
||||
else {
|
||||
mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]);
|
||||
}
|
||||
|
||||
}*/
|
||||
mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]);
|
||||
updateState(SESSION_STATE_PASSPHRASE_GENERATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -551,6 +551,7 @@ bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSour
|
||||
std::istringstream iss(passphrase);
|
||||
std::vector<std::string> results(std::istream_iterator<std::string>{iss},
|
||||
std::istream_iterator<std::string>());
|
||||
|
||||
for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) {
|
||||
Mnemonic& m = ServerConfig::g_Mnemonic_WordLists[i];
|
||||
bool existAll = true;
|
||||
@ -569,6 +570,7 @@ bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSour
|
||||
if (wordSource) {
|
||||
*wordSource = &m;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ enum PageState
|
||||
//Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER];
|
||||
Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER];
|
||||
if(lang == LANG_DE) {
|
||||
wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER];
|
||||
//wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER];
|
||||
}
|
||||
|
||||
// remove old cookies if exist
|
||||
|
||||
@ -4,3 +4,86 @@
|
||||
<%@ header include="SessionHTTPRequestHandler.h" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page compressed="true" %>
|
||||
<%!
|
||||
#include "../Crypto/KeyPair.h"
|
||||
#include "../ServerConfig.h"
|
||||
%>
|
||||
<%%
|
||||
chooseLanguage(request);
|
||||
// variable needed for flags
|
||||
auto lang = mSession->getLanguage();
|
||||
auto uri_start = ServerConfig::g_serverPath;
|
||||
const char* pageName = gettext("Passphrase Transformieren");
|
||||
std::string passphrase;
|
||||
auto role = mSession->getNewUser()->getModel()->getRole();
|
||||
std::string inputPassphrase;
|
||||
|
||||
Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER];
|
||||
Mnemonic* targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER];
|
||||
if(lang == LANG_DE) {
|
||||
wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER];
|
||||
targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER];
|
||||
}
|
||||
|
||||
if(!form.empty())
|
||||
{
|
||||
|
||||
inputPassphrase = form.get("inputPassphrase", "");
|
||||
auto localPassphrase = KeyPair::filterPassphrase(inputPassphrase);
|
||||
if(localPassphrase != "" && !User::validatePassphrase(localPassphrase, &wordSource)) {
|
||||
addError(new Error(
|
||||
gettext("Fehler"),
|
||||
gettext("Diese Passphrase ist ungültig, bitte überprüfen oder neu generieren (lassen).")
|
||||
));
|
||||
} else {
|
||||
if(wordSource == &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]) {
|
||||
targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER];
|
||||
} else {
|
||||
targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER];
|
||||
}
|
||||
passphrase = KeyPair::passphraseTransform(localPassphrase, wordSource, targetSource);
|
||||
}
|
||||
|
||||
auto btnGenerate = form.get("btnGenerate", "");
|
||||
if("" != btnGenerate) {
|
||||
passphrase = mSession->generatePassphrase();
|
||||
}
|
||||
}
|
||||
%><%@ include file="login_header.cpsp" %><%@ include file="flags.cpsp" %>
|
||||
<div class="row mb-3" style="margin-top:70px;">
|
||||
<h2 class="mx-auto"><%= gettext("Passphrase umwandeln") %></h2>
|
||||
</div>
|
||||
<div class="item-wrapper">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-10 mx-auto">
|
||||
<div class="form-group row showcase_row_area">
|
||||
<div class="col-md-12 col-lg-12 ">
|
||||
<div class="alert alert-orange">
|
||||
<h5 class="alert-heading"><%= gettext("Was zu tun ist:") %></h5>
|
||||
<p><%= gettext("Kopiere/schreibe deine Passphrase in die Textbox und du bekommst sie in die jeweils andere Sprache umgewandelt.") %></p>
|
||||
<p><%= gettext("Du kannst mit beiden Varianten dein Konto wiederherstellen oder dein Passwort ändern.") %></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 col-md-12 mb-5">
|
||||
<form action="<%= uri_start %>/transform_passphrase">
|
||||
<div class="form-group row-showcase_row_area">
|
||||
<textarea name="inputPassphrase" cols="10" rows="5" id="inputPassphrase" class="form-control" placeholder="<%= gettext("deine Passphrase") %>"><%= inputPassphrase %></textarea>
|
||||
</div>
|
||||
<input name="btnTransform" type="submit" value="Umwandeln" class="btn btn btn-orange">
|
||||
<% if(controller::USER_ROLE_ADMIN == role) { %>
|
||||
<input name="btnGenerate" type="submit" value="Neue generieren" class="btn btn-secondary">
|
||||
<% } %>
|
||||
</form>
|
||||
</div>
|
||||
<% if(passphrase != "") { %>
|
||||
<div class="col-lg-12 col-md-12">
|
||||
<div class="alert alert-success">
|
||||
<h5 class="alert-heading">Umgewandelte Passphrase: </h5>
|
||||
<p><%= passphrase %></p>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%@ include file="footer_ripple.cpsp" %>
|
||||
Loading…
x
Reference in New Issue
Block a user