Fixed includes.
[bpdyndnsd] / src / util.cpp
1 /** @file
2  * @brief Util namespace header.
3  *
4  *
5  *
6  * @copyright Intra2net AG
7  * @license GPLv2
8 */
9
10 #include "util.h"
11
12 #include <sstream>
13 #include <openssl/evp.h>
14 #include <boost/algorithm/string.hpp>
15
16 namespace Util
17 {
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  */
23 std::string compute_md5_digest(std::string data) throw (std::invalid_argument)
24 {
25     // compute an MD5 digest.
26
27     EVP_MD_CTX mdctx;
28     const EVP_MD *md;
29     unsigned char md_value[EVP_MAX_MD_SIZE];
30     unsigned int md_len = 0;
31
32     // Add all digest algorithms to the internal table.
33     OpenSSL_add_all_digests();
34
35     // Get the md5 digest algorithm from the internal table.
36     md = EVP_get_digestbyname("md5");
37
38     // Test if md is initialized.
39     if ( (md == NULL) || (EVP_MD_size(md) == 0) )
40         throw std::invalid_argument("NULL pointer: md");
41
42     // Initalize digest content mdctx.
43     EVP_MD_CTX_init(&mdctx);
44
45     // Now we can call init_ex.
46     EVP_DigestInit_ex(&mdctx, md, NULL);
47
48     // Test if data is empty.
49     if ( data.empty() )
50         throw std::invalid_argument("Passed data is empty");
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.
56     EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
57
58     // Test if md_value is filled correctly and md_len is not zero.
59     if ( (md_len == 0) || (md_value == NULL) || (EVP_MD_CTX_size(&mdctx) == 0) )
60         throw std::invalid_argument("Retrieved invalid digest value");
61
62     // Internal cleanup of the digest content.
63     EVP_MD_CTX_cleanup(&mdctx);
64     EVP_cleanup();
65
66     // Convert md5 digest C string to hex.
67     std::ostringstream oss_digest_md5_hex;
68     for(unsigned int i = 0; i < md_len; ++i)
69     {
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.
72         oss_digest_md5_hex << std::hex << static_cast<unsigned short>(md_value[i]);
73     }
74
75     return oss_digest_md5_hex.str();
76 }
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  */
84 std::string parse_status_code(std::string data)
85 {
86     std::list<std::string> tokens;
87     boost::algorithm::split(tokens,data,boost::is_any_of(" "));
88     return tokens.front();
89 }
90 };