67 inline char Hex(
unsigned char c)
72 return char(c - 10 +
'A');
77 string BinToHex(
const string&
data)
80 ret.reserve(
data.size()*2);
82 ret += Hex((
unsigned char)((
unsigned char)(*c) >> 4));
83 ret += Hex((
unsigned char)((
unsigned char)(*c) & 0x0F));
91 string HexToBin(
const string&
hex)
95 ret.reserve(
hex.size()/2);
104 if (c1 < 0 || c2 < 0) {
106 "Invalid hexadecimal string format: " +
hex);
109 ret += char((c1 << 4) + c2);
116 const size_t kBlockTEA_KeySize = 4;
122 const size_t kResInfo_BlockSize = kBlockTEA_KeySize *
sizeof(
Int4) * 4;
123 const size_t kEncrypt_BlockSize = kBlockTEA_KeySize *
sizeof(
Int4);
127 string GenerateBinaryKey(
const string&
seed)
129 const unsigned char kBlockTEA_Salt[] = {
130 0x2A, 0x0C, 0x84, 0x24, 0x5B, 0x0D, 0x85, 0x26,
131 0x72, 0x40, 0xBC, 0x38, 0xD3, 0x43, 0x63, 0x9E,
132 0x8E, 0x56, 0xF9, 0xD7, 0x00
134 string hash =
seed + (
char*)kBlockTEA_Salt;
138 memcpy(digest + 16, kBlockTEA_Salt, 21);
143 for (
int i = 0;
i <
len;
i++) {
144 CalcMD5(digest, 36, (
unsigned char*)digest);
146 return string(digest, kBlockTEA_KeySize*
sizeof(
Int4));
150 string BlockTEA_Encode(
const string& password,
158 string BlockTEA_Decode(
const string& password,
168 inline string EncodeString(
const string& s,
const string& pwd)
170 return BinToHex(BlockTEA_Encode(pwd, s, kResInfo_BlockSize));
198 : m_FileName(filename)
206 while ( !
in.eof() ) {
210 if ( line.empty() )
continue;
220 string fname = new_name.empty() ?
m_FileName : new_name;
225 "Failed to save encrypted file.");
231 string enc = it->second.info ?
232 it->second.info->x_GetEncoded() : it->second.encoded;
243 const string& pwd)
const
249 if ( !it->second.info ) {
253 return *it->second.info;
262 if ( !res_info.
info ) {
266 return *res_info.
info;
285 if (
data.empty() ) {
287 "Empty source string.");
291 list<string>::iterator it;
292 string pwd, res_name, res_value, extra;
298 if ( it ==
split.end() ) {
301 "Missing password.");
306 if ( it ==
split.end() ) {
309 "Missing resource name.");
314 if ( it ==
split.end() ) {
317 "Missing main resource value.");
324 info.SetValue(res_value);
325 if ( it !=
split.end() ) {
326 info.GetExtraValues_NC().Parse(*it);
330 if (it !=
split.end()) {
333 "Unrecognized data found after extra values: " + *it +
"...");
342 while (
in.good() && !
in.eof() ) {
345 if ( line.empty() )
continue;
352 const string& res_name)
const
360 return BlockTEA_Encode(res_name, name_pwd, kResInfo_BlockSize);
387 if ( !enc.empty() ) {
388 string dec = BlockTEA_Decode(pwd, HexToBin(enc), kResInfo_BlockSize);
392 "Error decrypting resource info value.");
409 return *sEmptyResInfo;
421 return BinToHex(BlockTEA_Encode(
m_Password,
str, kResInfo_BlockSize));
469 "No encryption keys found.");
477 size_t domain_pos = encrypted_string.find(
'/');
478 if (domain_pos !=
NPOS) {
480 encrypted_string.substr(domain_pos + 1));
485 if ( keys.
empty() ) {
487 "No decryption keys found.");
490 return x_Decrypt(encrypted_string, keys);
495 const string& password)
497 if ( password.empty() ) {
499 "Encryption password can not be empty.");
501 return x_Encrypt(original_string, GenerateBinaryKey(password));
506 const string& password)
508 if ( password.empty() ) {
510 "Encryption password can not be empty.");
513 string key = GenerateBinaryKey(password);
518 return x_Decrypt(encrypted_string, keys);
523 const string& domain)
528 "No encryption keys found for domain " + domain);
536 const string& domain)
541 size_t domain_pos = encrypted_string.find(
'/');
542 if (domain_pos !=
NPOS) {
544 string domain2 = encrypted_string.substr(domain_pos + 1);
545 if (domain2 != domain) {
550 if ( keys.
empty() ) {
552 "No decryption keys found for domain " + domain);
555 return x_Decrypt(encrypted_string.substr(0, domain_pos), keys);
562 string key = GenerateBinaryKey(
seed);
570 if (
data.empty() ) {
575 size_t domain_pos =
data.find(
'/');
576 if (domain_pos ==
data.size() - 1) {
580 string encr =
data.substr(0, domain_pos);
588 if (version < '1' || version >
'2') {
594 if (encr.size() <= 34 || encr[33] !=
':' ||
595 (encr.size() - 34) % kEncrypt_BlockSize) {
598 for (
size_t pos = 1; pos < encr.size(); ++pos) {
600 if (pos == 33)
continue;
614 TKeyFiles::ResetDefault();
615 TKeyPaths::ResetDefault();
629 string files = TKeyFiles::GetDefault();
630 if ( files.empty() ) {
633 list<string> file_list;
636 ITERATE(list<string>, it, file_list) {
638 size_t home_pos = fname.find(
"$HOME");
658 return BinToHex(
string(
md5, 16));
666 if ( !
in.good() )
return first_key;
668 while (
in.good() && !
in.eof() ) {
674 if (s.empty() || s[0] ==
'#')
continue;
677 if (version < '1' || version >
'2') {
679 "Invalid or unsupported API version in encryption key.");
682 string checksum,
key;
684 checksum.size() != 33 ) {
686 "Invalid encryption key format in " << filename <<
", line " << line);
689 checksum = HexToBin(checksum.substr(1));
692 size_t sevpos =
key.find(
'/');
693 if (sevpos !=
NPOS) {
694 string sevname =
key.substr(sevpos + 1);
698 "Invalid key severity in " << filename <<
", line " << line);
704 if (
key.size() != 32) {
706 "Invalid key format in " << filename <<
", line " << line);
713 if (
string(
md5, 16) != checksum) {
714 ERR_POST(
Warning <<
"Invalid key checksum in " << filename <<
", line " << line);
718 if ( first_key.empty() ) {
737 ITERATE(list<string>, it, paths) {
744 if ( first_key.empty() ) {
747 if (!first_key.empty() && !keys) {
775 "Trying to decrypt an empty string.");
780 if (version < '1' || version >
'2') {
782 "Invalid or unsupported API version in the encrypted data.");
788 if (
data.size() < 34 ||
data[33] !=
':') {
790 "Invalid encrypted string format - missing key checksum.");
792 string checksum = HexToBin(
data.substr(1, 32));
794 if (key_it == keys.
end()) {
796 "No decryption key found for the checksum.");
798 string key = key_it->second.m_Key;
799 EDiagSev sev = key_it->second.m_Severity;
804 ", location=" << key_it->second.m_File <<
":" << key_it->second.m_Line);
825 static time_t tt = 0;
831 for (
size_t i = 0;
i <
sizeof(ttmp) && salt.size() <
kSaltLength; ++
i) {
832 salt += char(ttmp & 0xFF);
837 for (
size_t i = 0;
i <
sizeof(ntmp) && salt.size() <
kSaltLength; ++
i) {
838 salt += char(ntmp & 0xFF);
860 const Uint4 kBlockTEA_Delta = 0x9e3779b9;
862 typedef Int4 TBlockTEA_Key[kBlockTEA_KeySize];
864 #define TEA_MX ((z >> 5)^(y << 2)) + (((y >> 3)^(z << 4))^(sum^y)) + (key[(p & 3)^e]^z);
877 sum += kBlockTEA_Delta;
879 for (p = 0; p <
n - 1; p++) {
898 Uint4 sum = q*kBlockTEA_Delta;
901 for (p =
n - 1; p > 0; p--) {
907 sum -= kBlockTEA_Delta;
913 inline Int4 GetInt4LE(
const char* ptr)
915 #ifdef WORDS_BIGENDIAN
918 return *(
const Int4*)(ptr);
923 inline void PutInt4LE(
Int4 i,
char* ptr)
925 #ifdef WORDS_BIGENDIAN
936 void StringToInt4Array(
const string& src,
Int4* dst)
938 size_t len = src.size()/
sizeof(
Int4);
939 const char* p = src.c_str();
940 for (
size_t i = 0;
i <
len;
i++, p +=
sizeof(
Int4)) {
941 dst[
i] = GetInt4LE(p);
948 string Int4ArrayToString(
const Int4* src,
size_t len)
953 for (
size_t i = 0;
i <
len;
i++) {
954 PutInt4LE(src[
i],
buf);
973 _ASSERT(str_key.size() == kBlockTEA_KeySize*
sizeof(
Int4));
975 StringToInt4Array(str_key,
key);
981 size_t padlen = block_size - (src.size() % block_size);
982 string padded =
string(padlen,
char(padlen)) + src;
985 size_t buflen = padded.size() /
sizeof(
Int4);
987 StringToInt4Array(padded,
buf);
990 BlockTEA_Encode_In_Place(
buf, (
Int4)buflen,
key);
993 string ret = Int4ArrayToString(
buf, buflen);
1004 if ( src.empty() ) {
1009 _ASSERT(str_key.size() == kBlockTEA_KeySize*
sizeof(
Int4));
1011 StringToInt4Array(str_key,
key);
1013 _ASSERT(src.size() % block_size == 0);
1015 size_t buflen = src.size() /
sizeof(
Int4);
1017 StringToInt4Array(src,
buf);
1020 BlockTEA_Decode_In_Place(
buf, (
Int4)buflen,
key);
1023 string ret = Int4ArrayToString(
buf, buflen);
1027 size_t padlen = (size_t)ret[0];
1028 if (padlen >= ret.size()) {
1031 for (
size_t i = 0;
i < padlen;
i++) {
1032 if ((
size_t)ret[
i] != padlen) {
1037 return ret.substr((
size_t)ret[0], ret.size());
1048 union SUnionLenbuf {
1055 return (x << c) | (x >> (32 - c));
1063 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
1064 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
1065 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
1066 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
1069 const Uint4 k[64] = {
1070 3614090360U, 3905402710U, 606105819U, 3250441966U,
1071 4118548399U, 1200080426U, 2821735955U, 4249261313U,
1072 1770035416U, 2336552879U, 4294925233U, 2304563134U,
1073 1804603682U, 4254626195U, 2792965006U, 1236535329U,
1074 4129170786U, 3225465664U, 643717713U, 3921069994U,
1075 3593408605U, 38016083U, 3634488961U, 3889429448U,
1076 568446438U, 3275163606U, 4107603335U, 1163531501U,
1077 2850285829U, 4243563512U, 1735328473U, 2368359562U,
1078 4294588738U, 2272392833U, 1839030562U, 4259657740U,
1079 2763975236U, 1272893353U, 4139469664U, 3200236656U,
1080 681279174U, 3936430074U, 3572445317U, 76029189U,
1081 3654602809U, 3873151461U, 530742520U, 3299628645U,
1082 4096336452U, 1126891415U, 2878612391U, 4237533241U,
1083 1700485571U, 2399980690U, 4293915773U, 2240044497U,
1084 1873313359U, 4264355552U, 2734768916U, 1309151649U,
1085 4149444226U, 3174756917U, 718787259U, 3951481745U
1089 Uint4 h0 = 0x67452301;
1090 Uint4 h1 = 0xEFCDAB89;
1091 Uint4 h2 = 0x98BADCFE;
1092 Uint4 h3 = 0x10325476;
1100 if (padlen < 9) padlen += 64;
1103 buf.append(
string(padlen - 9, 0));
1106 #ifdef WORDS_BIGENDIAN
1111 buf.append(
lb.lenbuf, 8);
1113 const char* buf_start =
buf.c_str();
1114 const char* buf_end = buf_start +
len + padlen;
1116 for (
const char* p = buf_start; p < buf_end; p += 64) {
1119 for (
int i = 0;
i < 16;
i++) {
1120 w[
i] = (
Uint4)GetInt4LE(p +
i*4);
1132 for (
unsigned int i = 0;
i < 64;
i++) {
1134 f = (
b & c) | ((~
b) & d);
1138 f = (d &
b) | ((~d) & c);
1153 b += leftrotate((
a +
f + k[
i] + w[
g]),
r[
i]);
1164 PutInt4LE(h0, (
char*)digest);
1165 PutInt4LE(h1, (
char*)(digest + 4));
1166 PutInt4LE(h2, (
char*)(digest + 8));
1167 PutInt4LE(h3, (
char*)(digest + 12));
static void PutInt8(unsigned char *ptr, Int8 value)
static Int4 GetInt4(const unsigned char *ptr)
static void PutInt4(unsigned char *ptr, Int4 value)
Exception thrown by encryption classes.
static string x_AddSalt(const string &data, char version)
static string x_LoadKeys(const string &filename, TKeyMap *keys)
static bool IsEncrypted(const string &data)
Check if the string contains valid encrypted data.
static string x_Encrypt(const string &data, const string &key)
static string x_GetDomainKeys(const string &domain, TKeyMap *keys)
static string x_GetBinKeyChecksum(const string &key)
static CSafeStatic< CNcbiEncrypt::TKeyMap > s_KeyMap
static string x_RemoveSalt(const string &data, char version)
static string x_Decrypt(const string &data, const TKeyMap &keys)
static const char * GetVersion(void)
Get encryption API version.
static CSafeStatic< string > s_DefaultKey
static string GenerateKey(const string &seed)
Generate an encryption/decryption key from the seed string.
static void sx_InitKeyMap(void)
static volatile bool s_KeysInitialized
static string DecryptForDomain(const string &encrypted_string, const string &domain)
Decrypt data using domain key.
static string EncryptForDomain(const string &original_string, const string &domain)
Encrypt data using domain key.
static string Encrypt(const string &original_string)
Encrypt a string using key from the 1st line of the 1st NCBI keys file.
static string Decrypt(const string &encrypted_string)
Decrypt a string using the matching key found in the NCBI keys files.
static void Reload(void)
Re-read key file locations and domain paths, reload encryption keys.
Exception thrown by resource info classes.
CNcbiResourceInfo & GetResourceInfo_NC(const string &res_name, const string &pwd)
Get (or create) non-const resource info for the given name.
CNcbiResourceInfoFile(const string &filename)
Load resource-info file.
void DeleteResourceInfo(const string &res_name, const string &pwd)
Delete resource associated with the name.
void SaveFile(const string &new_name=kEmptyStr)
Save data to file.
string x_GetDataPassword(const string &name_pwd, const string &res_name) const
void ParsePlainTextFile(const string &filename)
Parse file containing source plaintext data, add (replace) all resources to the current file.
static string GetDefaultFileName(void)
Get default resource info file location (/etc/ncbi/.info).
const CNcbiResourceInfo & GetResourceInfo(const string &res_name, const string &pwd) const
Get read-only resource info for the given name.
CNcbiResourceInfo & AddResourceInfo(const string &plain_text)
Create new resource info from the string and return reference to the new CNcbiResourceInfo object or ...
Class for storing encrypted resource information.
CNcbiResourceInfo(void)
Create a new empty resource info.
bool x_IsEmpty(void) const
string x_GetEncoded(void) const
static CNcbiResourceInfo & GetEmptyResInfo(void)
T & Get(void)
Create the variable if not created yet, return the reference.
URL-decoder for string pairs parser.
URL-encoder for string pairs parser.
container_type::const_iterator const_iterator
container_type::iterator iterator
const_iterator end() const
const_iterator find(const key_type &key) const
The NCBI C++ standard methods for dealing with std::string.
std::ofstream out("events_result.xml")
main entry point for tests
static const char * str(char *buf, int n)
static void md5(const char *src, const char *out)
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
#define ERR_POST_ONCE(message)
Error posting only once during program execution.
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
EDiagSev
Severity level for the posted diagnostics.
static bool StrToSeverityLevel(const char *str_sev, EDiagSev &sev)
Get severity from string.
@ eDiag_Trace
Trace message.
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
void Warning(CExceptionArgs_Base &args)
static bool IsPathSeparator(const char c)
Check whether a character "c" is a path separator symbol specific for the current platform.
static string MakePath(const string &dir=kEmptyStr, const string &base=kEmptyStr, const string &ext=kEmptyStr)
Assemble a path from basic components.
static string ConcatPath(const string &first, const string &second)
Concatenate two parts of the path for the current OS.
static string GetHome(void)
Get user "home" directory.
void Reset(void)
Reset reference object.
@ eParam_NoThread
Do not use per-thread values.
int32_t Int4
4-byte (32-bit) signed integer
uint32_t Uint4
4-byte (32-bit) unsigned integer
uint64_t Uint8
8-byte (64-bit) unsigned integer
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
void Parse(const CTempString str, NStr::EMergeDelims merge_argsep=NStr::eMergeDelims)
Parse the string.
string Merge(void) const
Merge name-value pairs into a single string using the currently set separators and the provided encod...
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
void SetDecoder(IStringDecoder *decoder, EOwnership own=eTakeOwnership)
Set string decoder.
static string URLDecode(const CTempString str, EUrlDecode flag=eUrlDec_All)
URL-decode string.
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string (in-place)
void SetEncoder(IStringEncoder *encoder, EOwnership own=eTakeOwnership)
Set string encoder.
static int HexChar(char ch)
Convert character to integer.
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
static string URLEncode(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
URL-encode string.
static string TruncateSpaces(const string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
static void GetCurrentTimeT(time_t *sec, long *nanosec=0)
Get current UTC time in time_t format (with nanoseconds).
unsigned int
A callback function used to compare two keys in a database.
static void hex(unsigned char c)
const string version
version string
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
Front end for a platform-specific configuration summary.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Multi-threading – mutexes; rw-locks; semaphore.
std::istream & in(std::istream &in_, double &x_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
void split(std::vector< std::string > *strVec, const std::string &str_, const std::string &split_)
static const char * kResourceValueSeparator
DEFINE_STATIC_MUTEX(s_EncryptMutex)
NCBI_PARAM_DECL(string, NCBI_KEY, FILES)
const char * kKeysDomainPrefix
const char * kDefaultKeysPath
const char * kDefaultKeysFile
static const char * kParserSeparators
string x_BlockTEA_Encode(const string &str_key, const string &src, size_t block_size)
typedef NCBI_PARAM_TYPE(NCBI_KEY, FILES) TKeyFiles
NCBI_PARAM_DEF_EX(string, NCBI_KEY, FILES, "", eParam_NoThread, NCBI_KEY_FILES)
string x_BlockTEA_Decode(const string &str_key, const string &src, size_t block_size)
const char * kNcbiEncryptVersion
void CalcMD5(const char *data, size_t len, unsigned char *digest)
static const char * kResourceExtraSeparator
static const char * kDefaultResourceInfoPath
Defines NCBI C++ secure resources API.
static SLJIT_INLINE sljit_ins lb(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
CRef< CNcbiResourceInfo > info
int g(Seg_Gsm *spe, Seq_Mtf *psm, Thd_Gsm *tdg)