2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
21 Hashing functions based upon openssl.
23 @copyright Intra2net AG
28 #include <openssl/evp.h>
33 #include <boost/shared_ptr.hpp>
37 #define buf_size (size_t)65536
44 const char* get_algo_name(algorithm algo)
53 return (char*)"sha256";
55 return (char*)"sha384";
57 return (char*)"sha512";
63 const string ERROR_MESSAGE = "Error while trying to hash the data";
64 } // eo anonymous namespace
66 string I2n::encode_hex(string data)
68 return encode_hex((char *)data.c_str(), data.size());
71 string I2n::encode_hex(char *data, unsigned int size)
75 for (unsigned int i = 0; i < size; i++)
76 out << hex << uppercase << setw(2) << setfill('0') << (int)(unsigned char)data[i];
81 // output: hex encoded hash
82 string I2n::hash_data(string data, algorithm algo)
84 return encode_hex(hash_data_raw(data, algo));
87 // output: raw binary hash
88 string I2n::hash_data_raw(string data, algorithm algo)
94 EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
96 uchar_arr ret(new unsigned char[EVP_MAX_MD_SIZE]);
98 OpenSSL_add_all_digests();
100 if(!(md = EVP_get_digestbyname(get_algo_name(algo))) ||
101 !EVP_DigestInit_ex(ctx.get(), md, NULL) ||
102 !EVP_DigestUpdate(ctx.get(), (char*)data.c_str(), data.length()) ||
103 !EVP_DigestFinal_ex(ctx.get(), ret.get(), &olen))
105 throw runtime_error(ERROR_MESSAGE);
108 return string(reinterpret_cast<char*>(ret.get()), olen);
111 // hash data in 64kB blocks
112 string I2n::hash_file(string filename, algorithm algo)
116 EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
118 uchar_arr ret(new unsigned char[EVP_MAX_MD_SIZE]);
122 OpenSSL_add_all_digests();
124 char_arr buf(new char[buf_size]);
129 FILE* file = fopen (filename.c_str(), "r");
132 throw ios_base::failure("can't open file");
135 if(!(md = EVP_get_digestbyname(get_algo_name(algo))) ||
136 !EVP_DigestInit_ex(ctx.get(), md, NULL))
139 throw runtime_error(ERROR_MESSAGE);
146 memset(buf.get(), 0, sizeof(char) * buf_size);
148 read_bytes = fread (buf.get(), 1, buf_size, file);
153 throw runtime_error("Error while reading file: " + filename);
156 if (read_bytes && !EVP_DigestUpdate(ctx.get(), buf.get(), read_bytes))
159 throw runtime_error(ERROR_MESSAGE);
163 if (!EVP_DigestFinal_ex(ctx.get(), ret.get(), &olen))
166 throw runtime_error(ERROR_MESSAGE);
169 return string(encode_hex(reinterpret_cast<char*>(ret.get()), olen));