diff --git a/winixd/core/sessionidmanager.cpp b/winixd/core/sessionidmanager.cpp index b281b85..49939f5 100644 --- a/winixd/core/sessionidmanager.cpp +++ b/winixd/core/sessionidmanager.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014-2021, Tomasz Sowa + * Copyright (c) 2014-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,7 @@ #include "utf8/utf8.h" #include "date/date.h" #include "misc.h" +#include "convert/text.h" namespace Winix @@ -48,8 +49,8 @@ namespace Winix SessionIdManager::SessionIdManager() { - algorithm_type = 'a'; - key_tab_size = 256; + algorithm_type = ALGORITHM_MULTIPLE_KEYS; + key_tab_size = 0; key_index = 0; last_key_generated = 0; key_renew_time = 60; @@ -57,9 +58,12 @@ SessionIdManager::SessionIdManager() } -void SessionIdManager::Init(const std::wstring & keys_file) + +void SessionIdManager::InitMultipleKeys(const std::wstring & keys_file) { + algorithm_type = ALGORITHM_MULTIPLE_KEYS; was_inited = true; + key_tab_size = 256; key_tab1.resize(key_tab_size); key_tab2.resize(key_tab_size); @@ -72,6 +76,57 @@ void SessionIdManager::Init(const std::wstring & keys_file) } +bool SessionIdManager::InitSingleKeys(const std::wstring & key1, const std::wstring & key2) +{ + algorithm_type = ALGORITHM_SINGLE_KEYS; + key_tab_size = 1; + + key_tab1.resize(key_tab_size); + key_tab2.resize(key_tab_size); + + aes1.resize(key_tab_size); + aes2.resize(key_tab_size); + + was_inited = true; + was_inited = was_inited && InitializeKey(key1, key_tab1); + was_inited = was_inited && InitializeKey(key2, key_tab2); + + if( was_inited ) + { + InitializeAesKeys(); + } + + return was_inited; +} + + +bool SessionIdManager::IsInitialized() +{ + return was_inited; +} + + +bool SessionIdManager::InitializeKey(const std::wstring & key, std::vector & key_tab) +{ + if( key.size() == 16 * 2 || key.size() == 24 * 2 || key.size() == 32 * 2 ) + { + if( !pt::hex_string_to_bytes(key, key_tab[0]) ) + { + log << log1 << "SIM: an incorrect character in a key, expected a hex digits in the range 0-9 or a-f" << logend; + } + } + else + { + log << log1 << "SIM: provided key has size: " << key.size() + << ", expected size is 16, 24 or 32 bytes (written as two hex digits each)" << logend; + return false; + } + + return true; +} + + + void SessionIdManager::SetKeyRenewTime(time_t renew_time) { key_renew_time = renew_time; @@ -400,6 +455,7 @@ return true; } + bool SessionIdManager::EncodeToken(size_t id, unsigned int index, time_t cur_utc_time, std::wstring & token) { size_t pad_top_size; @@ -413,10 +469,14 @@ char pad_bottom_value; if( !was_inited ) return false; - CheckKeys(cur_utc_time); + if( algorithm_type == ALGORITHM_MULTIPLE_KEYS ) + { + CheckKeys(cur_utc_time); + } + RandPadding(pad_top_size, pad_top_value, pad_bottom_size, pad_bottom_value); - string_token += algorithm_type; + string_token += GetAlgoritmTypeAsString(); string_token += (unsigned char)key_index; string_token += pad_top_value; string_token += pad_bottom_value; @@ -553,6 +613,17 @@ return false; } +char SessionIdManager::GetAlgoritmTypeAsString() +{ + if( algorithm_type == ALGORITHM_MULTIPLE_KEYS ) + return 'a'; + + if( algorithm_type == ALGORITHM_SINGLE_KEYS ) + return 'b'; + + return 'a'; +} + } // namespace Winix diff --git a/winixd/core/sessionidmanager.h b/winixd/core/sessionidmanager.h index eaaf819..5f77ef6 100644 --- a/winixd/core/sessionidmanager.h +++ b/winixd/core/sessionidmanager.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014-2018, Tomasz Sowa + * Copyright (c) 2014-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -83,21 +83,54 @@ public: SessionIdManager(); /* - * initialization + * we are using keys stored in a file + * those keys are automatically generated + * this is the default algorithm + */ + static const int ALGORITHM_MULTIPLE_KEYS = 1; + + /* + * we use only two keys + * those keys you have to provide + */ + static const int ALGORITHM_SINGLE_KEYS = 2; + + /* + * initialization for ALGORITHM_MULTIPLE_KEYS algorithm * this method takes about 1MB memory more (for AES key expansions) * if you do not need the session cookie to be enrypted then don't call this method * */ - void Init(const std::wstring & keys_file); + void InitMultipleKeys(const std::wstring & keys_file); + + + /* + * initialization for ALGORITHM_SINGLE_KEYS algorithm + * keys should be provided as 16*2 or 24*2 or 32*2 hexadecimal characters + * + */ + bool InitSingleKeys(const std::wstring & key1, const std::wstring & key2); + + + /* + * true if the object is correctly initialized + * + */ + bool IsInitialized(); + /* * how often a new AES key pairs should be generated + * used with ALGORITHM_MULTIPLE_KEYS algorithm */ void SetKeyRenewTime(time_t renew_time); /* * encode/decode the session cookie - * make sure the Init() method is called first + * make sure InitMultipleKeys() or InitSingleKeys() method is called first + * + * for ALGORITHM_SINGLE_KEYS algorithm the cur_utc_time parameter is ignored + * */ bool EncodeToken(size_t id, unsigned int index, time_t cur_utc_time, std::wstring & token); bool DecodeToken(const std::wstring & token, size_t & id, unsigned int & index); @@ -106,7 +139,7 @@ public: private: bool was_inited; - char algorithm_type; + int algorithm_type; std::string string_token, string_token_base64; std::vector key_tab1, key_tab2; size_t key_index; @@ -120,6 +153,7 @@ private: std::string file_name_ascii; std::vector aes1, aes2; + bool InitializeKey(const std::wstring & key, std::vector & key_tab); bool ReadKeysFromFile(const wchar_t * file); bool ReadKeysFromFile(const std::wstring & file); bool SaveKeysToFile(const wchar_t * file); @@ -142,6 +176,7 @@ private: bool CheckControlSums(const char * str); void InitializeAesKeys(size_t index); bool DecodeAES(const char * str, size_t key); + char GetAlgoritmTypeAsString(); template void Append(std::string & str, Value val); diff --git a/winixd/core/sessionmanager.cpp b/winixd/core/sessionmanager.cpp index 5852598..d1d17c8 100644 --- a/winixd/core/sessionmanager.cpp +++ b/winixd/core/sessionmanager.cpp @@ -108,7 +108,7 @@ void SessionManager::InitBanList() void SessionManager::InitCookieEncoding() { if( config->session_cookie_encode && !config->session_keys_file.empty() ) - session_id_manager.Init(config->session_keys_file); + session_id_manager.InitMultipleKeys(config->session_keys_file); session_id_manager.SetKeyRenewTime(config->session_key_renew_time); }