/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2011, Tomasz Sowa * All rights reserved. * */ #include #include "crypt.h" #include "utf8.h" #include "misc.h" #include "log.h" void Crypt::SetConfig(Config * pconfig) { config = pconfig; } void Crypt::TrimLastWhite(std::string & str) { if( str.empty() ) return; size_t i = str.size(); while( i > 0 && (IsWhite(str[i-1]) || str[i-1]==10) ) i -= 1; if( i < str.size() ) str.erase(i); } bool Crypt::Hash(int hash, const char * in, size_t inlen, std::string & out) { out.clear(); if( !config ) return false; run.Clear(); Ezc::WideToUTF8(config->opensll_path, command); run.Cmd(command); run.Par("dgst"); 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; } bool result = run.Go(in, inlen, out) == 0; TrimLastWhite(out); return result; } bool Crypt::Hash(int hash, const char * in, std::string & out) { size_t len = strlen(in); return Hash(hash, in, len, out); } bool Crypt::Hash(int hash, const std::string & in, std::string & out) { return Hash(hash, in.c_str(), in.size(), out); } bool Crypt::Hash(int hash, const wchar_t * in, size_t inlen, std::wstring & out) { Ezc::WideToUTF8(in, inlen, bufina); int res = Hash(hash, bufina.c_str(), bufina.size(), bufouta); // the output hash is not a UTF8 string // it consists only from ascii letters AssignString(bufouta, out); return res; } bool Crypt::Hash(int hash, const wchar_t * in, std::wstring & out) { size_t len = wcslen(in); return Hash(hash, in, len, out); } bool Crypt::Hash(int hash, const std::wstring & in, std::wstring & out) { return Hash(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(); Ezc::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) { Ezc::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_PLAIN ) { pass_org = up.pass; pass_salted = up.pass; pass_salted += salt; if( Hash(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_PLAIN; 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() ) { Ezc::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); }