Commit | Line | Data |
---|---|---|
a78b44b5 | 1 | /** @file |
ca5d6889 | 2 | * @brief Util namespace header. |
a78b44b5 BS |
3 | * |
4 | * | |
5 | * | |
6 | * @copyright Intra2net AG | |
7 | * @license GPLv2 | |
8 | */ | |
9 | ||
10 | #include "util.h" | |
11 | ||
a2f5be94 | 12 | #include <sstream> |
a78b44b5 | 13 | #include <openssl/evp.h> |
ca5d6889 | 14 | #include <boost/algorithm/string.hpp> |
a78b44b5 | 15 | |
ca5d6889 BS |
16 | namespace Util |
17 | { | |
a78b44b5 BS |
18 | /** |
19 | * Computes a MD5 Digest from the given string and returns the HEX representation | |
20 | * @param data The string to compute the md5 for | |
21 | * @return The computed md5 in hex | |
22 | */ | |
ca5d6889 | 23 | std::string compute_md5_digest(std::string data) throw (std::invalid_argument) |
a78b44b5 BS |
24 | { |
25 | // compute an MD5 digest. | |
26 | ||
a78b44b5 BS |
27 | EVP_MD_CTX mdctx; |
28 | const EVP_MD *md; | |
29 | unsigned char md_value[EVP_MAX_MD_SIZE]; | |
a2f5be94 | 30 | unsigned int md_len = 0; |
a78b44b5 | 31 | |
a2f5be94 | 32 | // Add all digest algorithms to the internal table. |
a78b44b5 BS |
33 | OpenSSL_add_all_digests(); |
34 | ||
a2f5be94 | 35 | // Get the md5 digest algorithm from the internal table. |
a78b44b5 BS |
36 | md = EVP_get_digestbyname("md5"); |
37 | ||
a2f5be94 BS |
38 | // Test if md is initialized. |
39 | if ( (md == NULL) || (EVP_MD_size(md) == 0) ) | |
ca5d6889 | 40 | throw std::invalid_argument("NULL pointer: md"); |
a2f5be94 BS |
41 | |
42 | // Initalize digest content mdctx. | |
a78b44b5 | 43 | EVP_MD_CTX_init(&mdctx); |
a2f5be94 BS |
44 | |
45 | // Now we can call init_ex. | |
a78b44b5 | 46 | EVP_DigestInit_ex(&mdctx, md, NULL); |
a2f5be94 BS |
47 | |
48 | // Test if data is empty. | |
49 | if ( data.empty() ) | |
ca5d6889 | 50 | throw std::invalid_argument("Passed data is empty"); |
a2f5be94 BS |
51 | |
52 | // Hash the data. At this point data is not empty and &mdctx is initialized. | |
53 | EVP_DigestUpdate(&mdctx, data.c_str(), data.size()); | |
54 | ||
55 | // Retrieve the digest value from &mdctx and place it in md_value. | |
a78b44b5 | 56 | EVP_DigestFinal_ex(&mdctx, md_value, &md_len); |
a78b44b5 | 57 | |
a2f5be94 | 58 | // Test if md_value is filled correctly and md_len is not zero. |
1f0d13b9 | 59 | if ( (md_len == 0) || (EVP_MD_CTX_size(&mdctx) == 0) ) |
ca5d6889 | 60 | throw std::invalid_argument("Retrieved invalid digest value"); |
a2f5be94 BS |
61 | |
62 | // Internal cleanup of the digest content. | |
63 | EVP_MD_CTX_cleanup(&mdctx); | |
64 | EVP_cleanup(); | |
a78b44b5 | 65 | |
a2f5be94 | 66 | // Convert md5 digest C string to hex. |
ca5d6889 | 67 | std::ostringstream oss_digest_md5_hex; |
a2f5be94 | 68 | for(unsigned int i = 0; i < md_len; ++i) |
a78b44b5 | 69 | { |
a2f5be94 BS |
70 | // We have to do a static cast to an decimal representation, cause otherwise ostringstream would interpret |
71 | // the stream as a character and output the character representation of the hex value. | |
ca5d6889 | 72 | oss_digest_md5_hex << std::hex << static_cast<unsigned short>(md_value[i]); |
a78b44b5 BS |
73 | } |
74 | ||
a2f5be94 | 75 | return oss_digest_md5_hex.str(); |
a78b44b5 | 76 | } |
52e7ca71 BS |
77 | |
78 | ||
79 | /** | |
80 | * Get the status code from the given data. | |
81 | * @param data The data containing the status code at front, limited by " ". | |
82 | * @return The parsed status code. | |
83 | */ | |
ca5d6889 | 84 | std::string parse_status_code(std::string data) |
52e7ca71 | 85 | { |
ca5d6889 BS |
86 | std::list<std::string> tokens; |
87 | boost::algorithm::split(tokens,data,boost::is_any_of(" ")); | |
52e7ca71 BS |
88 | return tokens.front(); |
89 | } | |
ca5d6889 | 90 | }; |