allow the SessionIdManager to use only two keys

This commit is contained in:
Tomasz Sowa 2022-07-26 05:18:42 +02:00
parent 522b57ade4
commit 2e8f4d1a26
3 changed files with 118 additions and 12 deletions

View File

@ -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<std::string> & 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

View File

@ -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<std::string> key_tab1, key_tab2;
size_t key_index;
@ -120,6 +153,7 @@ private:
std::string file_name_ascii;
std::vector<Tito::AES> aes1, aes2;
bool InitializeKey(const std::wstring & key, std::vector<std::string> & 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<typename Value>
void Append(std::string & str, Value val);

View File

@ -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);
}