/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2011-2018, 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 "crypt.h" #include "utf8/utf8.h" #include "log.h" #include "misc.h" namespace Winix { //void Crypt::SetConfig(Config * pconfig) //{ // config = pconfig; //} void Crypt::set_dependency(WinixBase * winix_base) { WinixBase::set_dependency(winix_base); run.set_dependency(winix_base); } char Crypt::ConvertToHexForm(int val) { if( val < 10 ) return val + '0'; return val - 10 + 'a'; } bool Crypt::HashBin(int hash, const char * in, size_t inlen, std::string & out) { out.clear(); if( !config ) return false; run.Clear(); run.set_dependency(this); PT::WideToUTF8(config->opensll_path, command); run.Cmd(command); run.Par("dgst"); run.Par("-binary"); switch(hash) { case WINIX_CRYPT_HASH_MD4: run.Par("-md4"); break; case WINIX_CRYPT_HASH_MD5: run.Par("-md5"); break; case WINIX_CRYPT_HASH_SHA1: run.Par("-sha1"); break; case WINIX_CRYPT_HASH_SHA224: run.Par("-sha224"); break; case WINIX_CRYPT_HASH_SHA256: run.Par("-sha256"); break; case WINIX_CRYPT_HASH_SHA384: run.Par("-sha384"); break; case WINIX_CRYPT_HASH_SHA512: run.Par("-sha512"); break; default: return false; } return run.Go(in, inlen, out) == 0; } bool Crypt::HashBin(int hash, const char * in, std::string & out) { size_t len = strlen(in); return HashBin(hash, in, len, out); } bool Crypt::HashBin(int hash, const std::string & in, std::string & out) { return HashBin(hash, in.c_str(), in.size(), out); } bool Crypt::HashBin(int hash, const wchar_t * in, size_t inlen, std::string & out) { PT::WideToUTF8(in, inlen, bufina); int res = HashBin(hash, bufina.c_str(), bufina.size(), out); bufina.clear(); return res; } bool Crypt::HashBin(int hash, const wchar_t * in, std::string & out) { size_t len = wcslen(in); return HashBin(hash, in, len, out); } bool Crypt::HashBin(int hash, const std::wstring & in, std::string & out) { return HashBin(hash, in.c_str(), in.size(), out); } bool Crypt::HashHex(int hash, const char * in, size_t inlen, std::string & out) { int res = HashBin(hash, in, inlen, out_temp); ConvertToHexForm(out_temp, out); out_temp.clear(); return res; } bool Crypt::HashHex(int hash, const char * in, std::string & out) { size_t len = strlen(in); return HashHex(hash, in, len, out); } bool Crypt::HashHex(int hash, const std::string & in, std::string & out) { return HashHex(hash, in.c_str(), in.size(), out); } bool Crypt::HashHex(int hash, const wchar_t * in, size_t inlen, std::wstring & out) { int res = HashBin(hash, in, inlen, out_temp); ConvertToHexForm(out_temp, out); out_temp.clear(); return res; } bool Crypt::HashHex(int hash, const wchar_t * in, std::wstring & out) { size_t len = wcslen(in); return HashHex(hash, in, len, out); } bool Crypt::HashHex(int hash, const std::wstring & in, std::wstring & out) { return HashHex(hash, in.c_str(), in.size(), out); } bool IsAllWhite(const char * str) { for( ; *str ; ++str) { if( !(IsWhite(*str) || *str==10) ) return false; } return true; } bool Crypt::RSA(bool encrypt, const char * keypath, const char * in, size_t inlen, std::string & out) { out.clear(); if( !config || IsAllWhite(keypath) ) return false; run.Clear(); PT::WideToUTF8(config->opensll_path, command); run.Cmd(command); run.Par("rsautl"); run.Par("-inkey"); run.Par(keypath); if(encrypt) run.Par("-encrypt"); else run.Par("-decrypt"); return run.Go(in, inlen, out) == 0; } bool Crypt::RSA(bool encrypt, const char * keypath, const std::string & in, std::string & out) { return RSA(encrypt, keypath, in.c_str(), in.size(), out); } bool Crypt::RSA(bool encrypt, const std::string & keypath, const std::string & in, std::string & out) { return RSA(encrypt, keypath.c_str(), in.c_str(), in.size(), out); } bool Crypt::RSA(bool encrypt, const wchar_t * keypath, const char * in, size_t inlen, std::string & out) { PT::WideToUTF8(keypath, keypatha); return RSA(encrypt, keypatha.c_str(), in, inlen, out); } bool Crypt::RSA(bool encrypt, const wchar_t * keypath, const std::string & in, std::string & out) { return RSA(encrypt, keypath, in.c_str(), in.size(), out); } bool Crypt::RSA(bool encrypt, const std::wstring & keypath, const std::string & in, std::string & out) { return RSA(encrypt, keypath.c_str(), in.c_str(), in.size(), out); } bool Crypt::PassHash(const std::wstring & salt, UserPass & up) { bool result = true; up.pass_hash_salted = false; if( up.pass_type != WINIX_CRYPT_HASH_NONE ) { pass_org = up.pass; pass_salted = up.pass; pass_salted += salt; if( HashHex(up.pass_type, pass_salted, up.pass) ) { if( !salt.empty() ) up.pass_hash_salted = true; } else { log << log1 << "Crypt: problem with generating a hash, the password will not be hashed" << logend; up.pass = pass_org; up.pass_type = WINIX_CRYPT_HASH_NONE; result = false; } ClearString(pass_salted); ClearString(pass_org); } return result; } bool Crypt::PassCrypt(const std::wstring & path_to_rsa_private_key, UserPass & up) { bool result = false; ClearString(up.pass_encrypted); if( !path_to_rsa_private_key.empty() ) { PT::WideToUTF8(up.pass, passa); if( RSA(true, path_to_rsa_private_key, passa, up.pass_encrypted) ) { result = true; } else { ClearString(up.pass_encrypted); log << log1 << "AddUser: problem with encrypting, the password will not be encrypted!" << logend; } ClearString(passa); } return result; } void Crypt::PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, UserPass & up) { PassHash(salt, up); PassCrypt(path_to_rsa_private_key, up); } void Crypt::PassHashCrypt(UserPass & up) { up.pass_type = config->pass_type; empty.clear(); if( config->pass_hash_use_salt && !config->pass_hash_salt.empty() ) PassHash(config->pass_hash_salt, up); else PassHash(empty, up); if( config->pass_use_rsa && !config->pass_rsa_private_key.empty() ) PassCrypt(config->pass_rsa_private_key, up); } } // namespace Winix