2 * @brief Util namespace header.
6 * @copyright Intra2net AG
14 #include <openssl/evp.h>
15 #include <boost/algorithm/string.hpp>
20 * Computes a MD5 Digest from the given string and returns the HEX representation
21 * @param data The string to compute the md5 for
22 * @return The computed md5 in hex
24 std::string compute_md5_digest(std::string data)
26 // compute an MD5 digest.
30 unsigned char md_value[EVP_MAX_MD_SIZE];
31 unsigned int md_len = 0;
33 // Add all digest algorithms to the internal table.
34 OpenSSL_add_all_digests();
36 // Get the md5 digest algorithm from the internal table.
37 md = EVP_get_digestbyname("md5");
39 // Test if md is initialized.
40 if ( (md == NULL) || (EVP_MD_size(md) == 0) )
41 throw std::invalid_argument("NULL pointer: md");
43 // Initalize digest content mdctx.
44 EVP_MD_CTX_init(&mdctx);
46 // Now we can call init_ex.
47 if ( EVP_DigestInit_ex(&mdctx, md, NULL) == 0 )
49 EVP_MD_CTX_cleanup(&mdctx); /*lint !e534 */
50 EVP_cleanup(); /*lint !e534 */
51 throw std::invalid_argument("Could not set up digest context correctly");
54 // Test if data is empty.
57 EVP_MD_CTX_cleanup(&mdctx); /*lint !e534 */
58 EVP_cleanup(); /*lint !e534 */
59 throw std::invalid_argument("Passed data is empty");
62 // Hash the data. At this point data is not empty and &mdctx is initialized.
63 if ( EVP_DigestUpdate(&mdctx, data.c_str(), data.size()) == 0 )
65 EVP_MD_CTX_cleanup(&mdctx); /*lint !e534 */
66 EVP_cleanup(); /*lint !e534 */
67 throw std::invalid_argument("Could not hash data into digest context");
70 // Retrieve the digest value from &mdctx and place it in md_value.
71 if ( EVP_DigestFinal_ex(&mdctx, md_value, &md_len) == 0 )
73 EVP_MD_CTX_cleanup(&mdctx); /*lint !e534 */
74 EVP_cleanup(); /*lint !e534 */
75 throw std::invalid_argument("Could not retrieve digest value");
78 // Test if md_value is filled correctly and md_len is not zero.
79 if ( (md_len == 0) || (EVP_MD_CTX_size(&mdctx) == 0) )
81 EVP_MD_CTX_cleanup(&mdctx); /*lint !e534 */
82 EVP_cleanup(); /*lint !e534 */
83 throw std::invalid_argument("Retrieved invalid digest value");
86 // Internal cleanup of the digest content.
87 EVP_MD_CTX_cleanup(&mdctx); /*lint !e534 */
88 EVP_cleanup(); /*lint !e534 */
90 // Convert md5 digest C string to hex.
91 std::ostringstream oss_digest_md5_hex;
92 for(unsigned int i = 0; i < md_len; ++i)
94 // We have to do a static cast to an decimal representation, cause otherwise ostringstream would interpret
95 // the stream as a character and output the character representation of the hex value.
96 oss_digest_md5_hex << std::nouppercase << std::setw(2) << std::setfill('0')
97 << std::hex << static_cast<int>(static_cast<unsigned char>(md_value[i]));
100 return oss_digest_md5_hex.str();
105 * Get the status code from the given data.
106 * @param data The data containing the status code at front, limited by delimiter.
107 * @param delimiter The delimiter to use.
108 * @return The parsed status code
110 std::string parse_status_code(std::string data, std::string delimiter)
112 std::list<std::string> tokens;
113 boost::algorithm::split(tokens,data,boost::is_any_of(delimiter));
114 if ( tokens.empty() )
116 return tokens.front();