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 # if (OPENSSL_VERSION_NUMBER < 0x10100000L)
95 EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
97 EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
100 uchar_arr ret(new unsigned char[EVP_MAX_MD_SIZE]);
102 OpenSSL_add_all_digests();
104 if(!(md = EVP_get_digestbyname(get_algo_name(algo))) ||
105 !EVP_DigestInit_ex(ctx.get(), md, NULL) ||
106 !EVP_DigestUpdate(ctx.get(), (char*)data.c_str(), data.length()) ||
107 !EVP_DigestFinal_ex(ctx.get(), ret.get(), &olen))
109 throw runtime_error(ERROR_MESSAGE);
112 return string(reinterpret_cast<char*>(ret.get()), olen);
115 // hash data in 64kB blocks
116 string I2n::hash_file(string filename, algorithm algo)
120 # if (OPENSSL_VERSION_NUMBER < 0x10100000L)
121 EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
123 EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
126 uchar_arr ret(new unsigned char[EVP_MAX_MD_SIZE]);
130 OpenSSL_add_all_digests();
132 char_arr buf(new char[buf_size]);
137 FILE* file = fopen (filename.c_str(), "r");
140 throw ios_base::failure("can't open file");
143 if(!(md = EVP_get_digestbyname(get_algo_name(algo))) ||
144 !EVP_DigestInit_ex(ctx.get(), md, NULL))
147 throw runtime_error(ERROR_MESSAGE);
154 memset(buf.get(), 0, sizeof(char) * buf_size);
156 read_bytes = fread (buf.get(), 1, buf_size, file);
161 throw runtime_error("Error while reading file: " + filename);
164 if (read_bytes && !EVP_DigestUpdate(ctx.get(), buf.get(), read_bytes))
167 throw runtime_error(ERROR_MESSAGE);
171 if (!EVP_DigestFinal_ex(ctx.get(), ret.get(), &olen))
174 throw runtime_error(ERROR_MESSAGE);
177 return string(encode_hex(reinterpret_cast<char*>(ret.get()), olen));