SET(cpp_sources
cron.cpp
+ crypto.cpp
daemonfunc.cpp
filefunc.cpp
i18n.cpp
SET(cpp_headers
cron.hpp
+ crypto.hxx
daemonfunc.hpp
exception.hxx
filefunc.hxx
--- /dev/null
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/**
+ Hashing functions based upon openssl.
+
+ @copyright Intra2net AG
+*/
+
+using namespace std;
+
+#include <openssl/evp.h>
+#include <sstream>
+#include <iomanip>
+#include <string>
+#include <string.h>
+#include <boost/shared_ptr.hpp>
+#include <stdexcept>
+#include "crypto.hxx"
+
+#define buf_size (size_t)65536
+
+
+using namespace I2n;
+
+namespace
+{
+const char* get_algo_name(algorithm algo)
+{
+ switch (algo)
+ {
+ case MD5:
+ return (char*)"md5";
+ case SHA1:
+ return (char*)"sha1";
+ case SHA256:
+ return (char*)"sha256";
+ case SHA384:
+ return (char*)"sha384";
+ case SHA512:
+ return (char*)"sha512";
+ default:
+ return NULL;
+ }
+}
+
+const string ERROR_MESSAGE = "Error while trying to hash the data";
+} // eo anonymous namespace
+
+string I2n::encode_hex(string data)
+{
+ return encode_hex((char *)data.c_str(), data.size());
+}
+
+string I2n::encode_hex(char *data, unsigned int size)
+{
+ ostringstream out;
+
+ for (unsigned int i = 0; i < size; i++)
+ out << hex << uppercase << setw(2) << setfill('0') << (int)(unsigned char)data[i];
+
+ return out.str();
+}
+
+// output: hex encoded hash
+string I2n::hash_data(string data, algorithm algo)
+{
+ return encode_hex(hash_data_raw(data, algo));
+}
+
+// output: raw binary hash
+string I2n::hash_data_raw(string data, algorithm algo)
+{
+ unsigned int olen;
+
+ const EVP_MD *md;
+
+ EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
+
+ uchar_arr ret(new unsigned char[EVP_MAX_MD_SIZE]);
+
+ OpenSSL_add_all_digests();
+
+ if(!(md = EVP_get_digestbyname(get_algo_name(algo))) ||
+ !EVP_DigestInit_ex(ctx.get(), md, NULL) ||
+ !EVP_DigestUpdate(ctx.get(), (char*)data.c_str(), data.length()) ||
+ !EVP_DigestFinal_ex(ctx.get(), ret.get(), &olen))
+ {
+ throw runtime_error(ERROR_MESSAGE);
+ }
+
+ return string(reinterpret_cast<char*>(ret.get()), olen);
+}
+
+// hash data in 64kB blocks
+string I2n::hash_file(string filename, algorithm algo)
+{
+ const EVP_MD *md;
+
+ EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
+
+ uchar_arr ret(new unsigned char[EVP_MAX_MD_SIZE]);
+
+ unsigned int olen;
+
+ OpenSSL_add_all_digests();
+
+ char_arr buf(new char[buf_size]);
+
+ if (!buf)
+ throw bad_alloc();
+
+ FILE* file = fopen (filename.c_str(), "r");
+ if (!file)
+ {
+ throw ios_base::failure("can't open file");
+ }
+
+ if(!(md = EVP_get_digestbyname(get_algo_name(algo))) ||
+ !EVP_DigestInit_ex(ctx.get(), md, NULL))
+ {
+ fclose(file);
+ throw runtime_error(ERROR_MESSAGE);
+ }
+
+ int read_bytes;
+
+ while (!feof(file))
+ {
+ memset(buf.get(), 0, sizeof(char) * buf_size);
+
+ read_bytes = fread (buf.get(), 1, buf_size, file);
+
+ if (ferror(file))
+ {
+ fclose(file);
+ throw runtime_error("Error while reading file: " + filename);
+ }
+
+ if (read_bytes && !EVP_DigestUpdate(ctx.get(), buf.get(), read_bytes))
+ {
+ fclose(file);
+ throw runtime_error(ERROR_MESSAGE);
+ }
+ }
+
+ if (!EVP_DigestFinal_ex(ctx.get(), ret.get(), &olen))
+ {
+ fclose(file);
+ throw runtime_error(ERROR_MESSAGE);
+ }
+
+ return string(encode_hex(reinterpret_cast<char*>(ret.get()), olen));
+}
--- /dev/null
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/**
+ Hashing functions based upon openssl.
+
+ @copyright Intra2net AG
+*/
+
+#ifndef CRYPTO_HXX
+#define CRYPTO_HXX
+
+
+#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+using namespace std;
+#endif
+
+#include <openssl/evp.h>
+#include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace I2n {
+
+enum algorithm { NONE=0, MD5=1, SHA1=2, SHA256=8, SHA384=9, SHA512=10 };
+
+// output: hex encoded hash
+string hash_data(string data, algorithm algo=SHA1);
+
+// output: raw binary hash
+string hash_data_raw(string data, algorithm algo=SHA1);
+
+// hash data in 64kB blocks
+string hash_file(string filename, algorithm algo=SHA1);
+
+string encode_hex(string data);
+
+string encode_hex(char *data, unsigned int size);
+
+typedef boost::shared_array<char> char_arr;
+
+typedef boost::shared_array<unsigned char> uchar_arr;
+
+typedef boost::shared_ptr<EVP_MD_CTX> EVP_MD_CTX_Ptr;
+}; // eo I2n namespace
+
+#endif /* [CRYPTO_HXX] */
test_timefunc.cpp
test_tmpfstream.cpp
test_tribool.cpp
+ test_crypto.cpp
)
if (IMAP_UTF7_SUPPORT)
SET(cpp_sources stringfunc_imaputf7.cpp ${cpp_sources})
--- /dev/null
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/**
+ tests for the module "crypto"
+
+ @copyright Intra2net AG
+*/
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+#include <vector>
+#include <tmpfstream.hpp>
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "crypto.hxx"
+
+using namespace std;
+using namespace I2n;
+
+
+class TestCryptoFixture
+{
+protected:
+
+ char* Filename;
+
+ tmpfstream Tempfile;
+
+ void write_tempfile()
+ {
+ string tmpfile_name = "/tmp/libi2ncommon_test_crypto_XXXXXX";
+ Tempfile.open(tmpfile_name);
+ Tempfile << "Long Data and or Password";
+ Tempfile.close();
+
+ Filename = (char*)Tempfile.get_tmp_filename().c_str();
+ }
+
+public:
+ TestCryptoFixture()
+ {
+ write_tempfile();
+ }
+
+ ~TestCryptoFixture()
+ {
+ Tempfile.unlink();
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(Crypto, TestCryptoFixture)
+
+BOOST_AUTO_TEST_CASE(CheckHashMD5)
+{
+ const string hash = hash_data("Long Data and or Password",
+ MD5);
+ BOOST_CHECK_EQUAL(hash, string("E5952C81BBD04F9CB748433B9431F674"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashSHA1)
+{
+ const string hash = hash_data("Long Data and or Password",
+ SHA1);
+ BOOST_CHECK_EQUAL(hash, string("5935A22DAA087672FE2EA0E4485D58BC77E6068D"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashSHA256)
+{
+ const string hash = hash_data("Long Data and or Password",
+ SHA256);
+ BOOST_CHECK_EQUAL(hash, string("6D7F287A7E01ADF1A66C19D61C8D5A3BD68C1F"
+ "10565A6D37A5920B09152D62CE"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashSHA384)
+{
+ const string hash = hash_data("Long Data and or Password",
+ SHA384);
+ BOOST_CHECK_EQUAL(hash, string("1D879CCDFF4E50C32318A1F0FB8AF8A0B"
+ "150432CECAF41E5C7C0C75688E1F776"
+ "14CA70407A9BC97FDD1CEC4CF291B66B"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashSHA512)
+{
+ const string hash = hash_file(Filename,
+ SHA512);
+ BOOST_CHECK_EQUAL(hash, string("CBD561B4D1E13C08672CBCCAC855FAC3F4"
+ "7672548D0B61B0BB201017E4D93B239E"
+ "969DB3588F1466F34FB27A7D0AEFE203"
+ "594808E16659BEDD4B25F34EC46CDB"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashFileMD5)
+{
+ const string hash = hash_file(Filename,
+ MD5);
+ BOOST_CHECK_EQUAL(hash, string("E5952C81BBD04F9CB748433B9431F674"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashFileSHA1)
+{
+ const string hash = hash_file(Filename,
+ SHA1);
+ BOOST_CHECK_EQUAL(hash, string("5935A22DAA087672FE2EA0E4485D58BC77E6068D"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashFileSHA256)
+{
+ const string hash = hash_file(Filename,
+ SHA256);
+ BOOST_CHECK_EQUAL(hash, string("6D7F287A7E01ADF1A66C19D61C8D5A3BD68C1F"
+ "10565A6D37A5920B09152D62CE"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashFileSHA384)
+{
+ const string hash = hash_file(Filename,
+ SHA384);
+ BOOST_CHECK_EQUAL(hash, string("1D879CCDFF4E50C32318A1F0FB8AF8A0B"
+ "150432CECAF41E5C7C0C75688E1F776"
+ "14CA70407A9BC97FDD1CEC4CF291B66B"));
+}
+
+BOOST_AUTO_TEST_CASE(CheckHashFileSHA512)
+{
+ const string hash = hash_file(Filename,
+ SHA512);
+ BOOST_CHECK_EQUAL(hash, string("CBD561B4D1E13C08672CBCCAC855FAC3F4"
+ "7672548D0B61B0BB201017E4D93B239E"
+ "969DB3588F1466F34FB27A7D0AEFE203"
+ "594808E16659BEDD4B25F34EC46CDB"));
+}
+
+BOOST_AUTO_TEST_SUITE_END()