/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2014-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include "sessionidmanager.h" #include "space/spaceparser.h" #include "utf8/utf8.h" #include "date/date.h" #include "misc.h" #include "convert/text.h" namespace Winix { SessionIdManager::SessionIdManager() { algorithm_type = ALGORITHM_MULTIPLE_KEYS; key_tab_size = 0; key_index = 0; last_key_generated = 0; key_renew_time = 60; was_inited = false; } 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); aes1.resize(key_tab_size); aes2.resize(key_tab_size); key_file_name = keys_file; ReadKeysFromFile(key_file_name); } 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; if( key_renew_time < 10 ) key_renew_time = 10; time_t one_month = 60 * 60 * 24 * 31; if( key_renew_time > one_month ) key_renew_time = one_month; } void SessionIdManager::ReadKey(const wchar_t * name, pt::Space & space, std::vector & dest_key) { std::vector keys; std::string key_ascii, key_base64_decoded; space.to_list(name, keys); for(size_t i=0 ; i= 256 ) key_index = 0; if( date.Parse(space.to_wstr(L"last_key_generated", L"0")) ) last_key_generated = date.ToTime(); ReadKey(L"key_tab1", space, key_tab1); ReadKey(L"key_tab2", space, key_tab2); InitializeAesKeys(); } else { log << log1 << "SIM: I cannot read the session keys from: " << file << logend; } return status == pt::SpaceParser::ok; } bool SessionIdManager::ReadKeysFromFile(const std::wstring & file) { return ReadKeysFromFile(file.c_str()); } void SessionIdManager::SaveKeysToFile(std::vector & keys) { out_file << "(\n"; for(size_t i=0 ; i= key_tab_size ) key_index = 0; log << log2 << "SIM: generating new AES keys with index: " << key_index << logend; GenerateKeys(key_index, cur_utc_time); } } void SessionIdManager::RandPadding(size_t & pad_top_size, char & pad_top_value, size_t & pad_bottom_size, char & pad_bottom_value) { pad_top_size = (std::rand() * 5) / RAND_MAX; // multiply by 5 (not by 4) if( pad_top_size > 4 ) pad_top_size = 4; pad_top_size += 5; // now pad_top_size is from <5;9> pad_top_value = (char)std::rand(); pad_bottom_size = 14 - pad_top_size; // pad_bottom_size is from <5;9> too pad_bottom_value = (char)std::rand(); } void SessionIdManager::AppendSum(std::string & str) { int s = 0; for(size_t i=0 ; i 9 ) return false; for(size_t i=0 ; i