Use internal MD5 calculation

This commit is contained in:
Tindy X
2020-06-30 21:53:37 +08:00
parent 3b58b04d63
commit 5aa47c7cf2
4 changed files with 876 additions and 0 deletions

View File

@@ -42,6 +42,7 @@ ADD_EXECUTABLE(subconverter
src/interfaces.cpp
src/logger.cpp
src/main.cpp
src/md5.cpp
src/misc.cpp
src/multithread.cpp
src/nodemanip.cpp

655
src/md5.cpp Normal file
View File

@@ -0,0 +1,655 @@
#include <cassert>
#include <cstring>
#include <iostream>
#include "md5.h"
namespace md5 {
/*
* T denotes the integer part of the i-th element of the function:
* T[i] = 4294967296 * abs(sin(i)), where i is in radians.
*/
const unsigned int T[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
};
/*
* Constants for the MD5 Transform routine as defined in RFC 1321
*/
const unsigned int S1[4] = {7, 12, 17, 22};
const unsigned int S2[4] = {5, 9, 14, 20};
const unsigned int S3[4] = {4, 11, 16, 23};
const unsigned int S4[4] = {6, 10, 15, 21};
/*
* Function to perform the cyclic left rotation of blocks of data
*/
inline unsigned int cyclic_left_rotate(unsigned int data, unsigned int shift_bits) {
return (data << shift_bits) | (data >> (32 - shift_bits));
}
inline unsigned int F(unsigned int x, unsigned int y, unsigned int z) {return (x & y) | (~x & z);};
inline unsigned int G(unsigned int x, unsigned int y, unsigned int z) {return (x & z) | (y & ~z);};
inline unsigned int H(unsigned int x, unsigned int y, unsigned int z) {return x ^ y ^ z;};
inline unsigned int I(unsigned int x, unsigned int y, unsigned int z) {return y ^ (x | ~z);};
inline void FF(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Xk, unsigned int s, unsigned int i) {
#if MD5_DEBUG
std::cout << "\nA: " << a << "\nB: " << b << "\nC: " << c << "\nD: " << d << "\nX[" << i << "]: " << Xk << "\ns: " << S1[s] << "\nT: " << T[i] << "\n";
#endif
a += F(b,c,d) + Xk + T[i];
a = cyclic_left_rotate(a, S1[s]);
a += b;
#if MD5_DEBUG
std::cout << "A = " << a << "\n";
#endif
};
inline void GG(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Xk, unsigned int s, unsigned int i) {
#if MD5_DEBUG
std::cout << "\nA: " << a << "\nB: " << b << "\nC: " << c << "\nD: " << d << "\nX[" << i - 16 << "]: " << Xk << "\ns: " << S2[s] << "\nT: " << T[i] << "\n";
#endif // MD5_DEBUG
a += G(b,c,d) + Xk + T[i];
a = cyclic_left_rotate(a, S2[s]);
a += b;
#if MD5_DEBUG
std::cout << "A = " << a << "\n";
#endif // MD5_DEBUG
};
inline void HH(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Xk, unsigned int s, unsigned int i) {
#if MD5_DEBUG
std::cout << "\nA: " << a << "\nB: " << b << "\nC: " << c << "\nD: " << d << "\nX[" << i - 32 << "]: " << Xk << "\ns: " << S3[s] << "\nT: " << T[i] << "\n";
#endif // MD5_DEBUG
a += H(b,c,d) + Xk + T[i];
a = cyclic_left_rotate(a, S3[s]);
a += b;
#if MD5_DEBUG
std::cout << "A = " << a << "\n";
#endif // MD5_DEBUG
};
inline void II(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Xk, unsigned int s, unsigned int i) {
#if MD5_DEBUG
std::cout << "\nA: " << a << "\nB: " << b << "\nC: " << c << "\nD: " << d << "\nX[" << i - 48 << "]: " << Xk << "\ns: " << S4[s] << "\nT: " << T[i] << "\n";
#endif // MD5_DEBUG
a += I(b,c,d) + Xk + T[i];
a = cyclic_left_rotate(a, S4[s]);
a += b;
#if MD5_DEBUG
std::cout << "A = " << a << "\n";
#endif // MD5_DEBUG
};
/*
* Define my endian-ness. Could not do in a portable manner using the
* include files -- grumble.
*/
#if MD5_BIG_ENDIAN
/*
* big endian - big is better
*/
#define MD5_SWAP(n) (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
/*
* little endian
*/
#define MD5_SWAP(n) (n)
#endif // MD5_BIG_ENDIAN
const char* HEX_STRING = "0123456789abcdef"; /* to convert to hex */
/****************************** Public Functions ******************************/
/*
* md5_t
*
* DESCRIPTION:
*
* Initialize structure containing state of MD5 computation. (RFC 1321,
* 3.3: Step 3). This is for progressive MD5 calculations only. If
* you have the complete string available, call it as below.
* process should be called for each bunch of bytes and after the
* last process call, finish should be called to get the signature.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* None.
*/
md5_t::md5_t() {
initialise();
}
/*
* md5_t
*
* DESCRIPTION:
*
* This function is used to calculate a MD5 signature for a buffer of
* bytes. If you only have part of a buffer that you want to process
* then md5_t, process, and finish should be used.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* buffer - A buffer of bytes whose MD5 signature we are calculating.
*
* input_length - The length of the buffer.
*
* signature - A 16 byte buffer that will contain the MD5 signature.
*/
md5_t::md5_t(const void* input, const unsigned int input_length, void* signature) {
/* initialize the computation context */
initialise();
/* process whole buffer but last input_length % MD5_BLOCK bytes */
process(input, input_length);
/* put result in desired memory area */
finish(signature);
}
/*
* process
*
* DESCRIPTION:
*
* This function is used to progressively calculate a MD5 signature some
* number of bytes at a time.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* buffer - A buffer of bytes whose MD5 signature we are calculating.
*
* input_length - The length of the buffer.
*/
void md5_t::process(const void* input, const unsigned int input_length) {
if (!finished) {
unsigned int processed = 0;
/*
* If we have any data stored from a previous call to process then we use these
* bytes first, and the new data is large enough to create a complete block then
* we process these bytes first.
*/
if (stored_size and input_length + stored_size >= md5::BLOCK_SIZE) {
unsigned char block[md5::BLOCK_SIZE];
memcpy(block, stored, stored_size);
memcpy(block + stored_size, input, md5::BLOCK_SIZE - stored_size);
processed = md5::BLOCK_SIZE - stored_size;
stored_size = 0;
process_block(block);
}
/*
* While there is enough data to create a complete block, process it.
*/
while (processed + md5::BLOCK_SIZE <= input_length) {
process_block((unsigned char*)input + processed);
processed += md5::BLOCK_SIZE;
}
/*
* If there are any unprocessed bytes left over that do not create a complete block
* then we store these bytes for processing next time.
*/
if (processed != input_length) {
memcpy(stored + stored_size, (char*)input + processed, input_length - processed);
stored_size += input_length - processed;
} else {
stored_size = 0;
}
} else {
// throw error when trying to process after completion?
}
}
/*
* finish
*
* DESCRIPTION:
*
* Finish a progressing MD5 calculation and copy the resulting MD5
* signature into the result buffer which should be 16 bytes
* (MD5_SIZE). After this call, the MD5 structure cannot process
* additional bytes.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature - A 16 byte buffer that will contain the MD5 signature.
*/
void md5_t::finish(void* signature_) {
if (!finished) {
if (message_length[0] + stored_size < message_length[0])
message_length[1]++;
message_length[0] += stored_size;
int pad = md5::BLOCK_SIZE - (sizeof(unsigned int) * 2) - stored_size;
if (pad <= 0)
pad += md5::BLOCK_SIZE;
/*
* Modified from a fixed array to this assignment and memset to be
* more flexible with block-sizes -- Gray 10/97.
*/
if (pad > 0) {
stored[stored_size] = 0x80;
if (pad > 1)
memset(stored + stored_size + 1, 0, pad - 1);
stored_size += pad;
}
/*
* Put the 64-bit file length in _bits_ (i.e. *8) at the end of the
* buffer. appears to be in beg-endian format in the buffer?
*/
unsigned int size_low = ((message_length[0] & 0x1FFFFFFF) << 3);
memcpy(stored + stored_size, &size_low, sizeof(unsigned int));
stored_size += sizeof(unsigned int);
/* shift the high word over by 3 and add in the top 3 bits from the low */
unsigned int size_high = (message_length[1] << 3) | ((message_length[0] & 0xE0000000) >> 29);
memcpy(stored + stored_size, &size_high, sizeof(unsigned int));
stored_size += sizeof(unsigned int);
/*
* process the last block of data.
* if the length of the message was already exactly sized, then we have
* 2 messages to process
*/
process_block(stored);
if (stored_size > md5::BLOCK_SIZE)
process_block(stored + md5::BLOCK_SIZE);
/* Arrange the results into a signature */
get_result(static_cast<void*>(signature));
/* store the signature into a readable sring */
sig_to_string(signature, str, MD5_STRING_SIZE);
if (signature_ != NULL) {
memcpy(signature_, static_cast<void*>(signature), MD5_SIZE);
}
finished = true;
} else {
// add error?
}
}
/*
* get_sig
*
* DESCRIPTION:
*
* Retrieves the previously calculated signature from the MD5 object.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature_ - A 16 byte buffer that will contain the MD5 signature.
*/
void md5_t::get_sig(void* signature_) {
if (finished) {
memcpy(signature_, signature, MD5_SIZE);
} else {
//error?
}
}
/*
* get_string
*
* DESCRIPTION:
*
* Retrieves the previously calculated signature from the MD5 object in
* printable format.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* str_ - a string of characters which should be at least 33 bytes long
* (2 characters per MD5 byte and 1 for the \0).
*/
void md5_t::get_string(void* str_) {
if (finished) {
memcpy(str_, str, MD5_STRING_SIZE);
} else {
// error?
}
}
/****************************** Private Functions ******************************/
/*
* initialise
*
* DESCRIPTION:
*
* Initialize structure containing state of MD5 computation. (RFC 1321,
* 3.3: Step 3).
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* None.
*/
void md5_t::initialise() {
/*
* ensures that unsigned int is 4 bytes on this platform, will need modifying
* if we are to use on a different sized platform.
*/
assert(MD5_SIZE == 16);
A = 0x67452301;
B = 0xefcdab89;
C = 0x98badcfe;
D = 0x10325476;
message_length[0] = 0;
message_length[1] = 0;
stored_size = 0;
finished = false;
}
/*
* process_block
*
* DESCRIPTION:
*
* Process a block of bytes into a MD5 state structure.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* buffer - A buffer of bytes whose MD5 signature we are calculating.
*
* input_length - The length of the buffer.
*/
void md5_t::process_block(const unsigned char* block) {
/* Process each 16-word block. */
/*
* we check for when the lower word rolls over, and increment the
* higher word. we do not need to worry if the higher word rolls over
* as only the two words we maintain are needed in the function later
*/
if (message_length[0] + md5::BLOCK_SIZE < message_length[0])
message_length[1]++;
message_length[0] += BLOCK_SIZE;
// Copy the block into X. */
unsigned int X[16];
for (unsigned int i = 0; i < 16; i++) {
memcpy(X + i, block + 4 * i, 4);
}
/* Save A as AA, B as BB, C as CC, and D as DD. */
unsigned int AA = A, BB = B, CC = C, DD = D;
/* Round 1
* Let [abcd k s i] denote the operation
* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
* Do the following 16 operations
* [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
* [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
* [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
* [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
*/
md5::FF(A, B, C, D, X[0 ], 0, 0 );
md5::FF(D, A, B, C, X[1 ], 1, 1 );
md5::FF(C, D, A, B, X[2 ], 2, 2 );
md5::FF(B, C, D, A, X[3 ], 3, 3 );
md5::FF(A, B, C, D, X[4 ], 0, 4 );
md5::FF(D, A, B, C, X[5 ], 1, 5 );
md5::FF(C, D, A, B, X[6 ], 2, 6 );
md5::FF(B, C, D, A, X[7 ], 3, 7 );
md5::FF(A, B, C, D, X[8 ], 0, 8 );
md5::FF(D, A, B, C, X[9 ], 1, 9 );
md5::FF(C, D, A, B, X[10], 2, 10);
md5::FF(B, C, D, A, X[11], 3, 11);
md5::FF(A, B, C, D, X[12], 0, 12);
md5::FF(D, A, B, C, X[13], 1, 13);
md5::FF(C, D, A, B, X[14], 2, 14);
md5::FF(B, C, D, A, X[15], 3, 15);
/* Round 2
* Let [abcd k s i] denote the operation
* a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
* Do the following 16 operations
* [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
* [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
* [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
* [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
*/
md5::GG(A, B, C, D, X[1 ], 0, 16);
md5::GG(D, A, B, C, X[6 ], 1, 17);
md5::GG(C, D, A, B, X[11], 2, 18);
md5::GG(B, C, D, A, X[0 ], 3, 19);
md5::GG(A, B, C, D, X[5 ], 0, 20);
md5::GG(D, A, B, C, X[10], 1, 21);
md5::GG(C, D, A, B, X[15], 2, 22);
md5::GG(B, C, D, A, X[4 ], 3, 23);
md5::GG(A, B, C, D, X[9 ], 0, 24);
md5::GG(D, A, B, C, X[14], 1, 25);
md5::GG(C, D, A, B, X[3 ], 2, 26);
md5::GG(B, C, D, A, X[8 ], 3, 27);
md5::GG(A, B, C, D, X[13], 0, 28);
md5::GG(D, A, B, C, X[2 ], 1, 29);
md5::GG(C, D, A, B, X[7 ], 2, 30);
md5::GG(B, C, D, A, X[12], 3, 31);
/* Round 3
* Let [abcd k s i] denote the operation
* a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
* Do the following 16 operations
* [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
* [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
* [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
* [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
*/
md5::HH(A, B, C, D, X[5 ], 0, 32);
md5::HH(D, A, B, C, X[8 ], 1, 33);
md5::HH(C, D, A, B, X[11], 2, 34);
md5::HH(B, C, D, A, X[14], 3, 35);
md5::HH(A, B, C, D, X[1 ], 0, 36);
md5::HH(D, A, B, C, X[4 ], 1, 37);
md5::HH(C, D, A, B, X[7 ], 2, 38);
md5::HH(B, C, D, A, X[10], 3, 39);
md5::HH(A, B, C, D, X[13], 0, 40);
md5::HH(D, A, B, C, X[0 ], 1, 41);
md5::HH(C, D, A, B, X[3 ], 2, 42);
md5::HH(B, C, D, A, X[6 ], 3, 43);
md5::HH(A, B, C, D, X[9 ], 0, 44);
md5::HH(D, A, B, C, X[12], 1, 45);
md5::HH(C, D, A, B, X[15], 2, 46);
md5::HH(B, C, D, A, X[2 ], 3, 47);
/* Round 4
* Let [abcd k s i] denote the operation
* a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
* Do the following 16 operations
* [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
* [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
* [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
* [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
*/
md5::II(A, B, C, D, X[0 ], 0, 48);
md5::II(D, A, B, C, X[7 ], 1, 49);
md5::II(C, D, A, B, X[14], 2, 50);
md5::II(B, C, D, A, X[5 ], 3, 51);
md5::II(A, B, C, D, X[12], 0, 52);
md5::II(D, A, B, C, X[3 ], 1, 53);
md5::II(C, D, A, B, X[10], 2, 54);
md5::II(B, C, D, A, X[1 ], 3, 55);
md5::II(A, B, C, D, X[8 ], 0, 56);
md5::II(D, A, B, C, X[15], 1, 57);
md5::II(C, D, A, B, X[6 ], 2, 58);
md5::II(B, C, D, A, X[13], 3, 59);
md5::II(A, B, C, D, X[4 ], 0, 60);
md5::II(D, A, B, C, X[11], 1, 61);
md5::II(C, D, A, B, X[2 ], 2, 62);
md5::II(B, C, D, A, X[9 ], 3, 63);
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
A += AA;
B += BB;
C += CC;
D += DD;
}
/*
* get_result
*
* DESCRIPTION:
*
* Copy the resulting MD5 signature into the first 16 bytes (MD5_SIZE)
* of the result buffer.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* result - A 16 byte buffer that will contain the MD5 signature.
*/
void md5_t::get_result(void *result) {
memcpy((char*)result, &A, sizeof(unsigned int));
memcpy((char*)result + sizeof(unsigned int), &B, sizeof(unsigned int));
memcpy((char*)result + 2 * sizeof(unsigned int), &C, sizeof(unsigned int));
memcpy((char*)result + 3 * sizeof(unsigned int), &D, sizeof(unsigned int));
}
/****************************** Exported Functions ******************************/
/*
* sig_to_string
*
* DESCRIPTION:
*
* Convert a MD5 signature in a 16 byte buffer into a hexadecimal string
* representation.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature_ - a 16 byte buffer that contains the MD5 signature.
*
* str_ - a string of charactes which should be at least 33 bytes long (2
* characters per MD5 byte and 1 for the \0).
*
* str_len - the length of the string.
*/
void sig_to_string(const void* signature_, char* str_, const int str_len) {
unsigned char* sig_p;
char* str_p;
char* max_p;
unsigned int high, low;
str_p = str_;
max_p = str_ + str_len;
for (sig_p = (unsigned char*)signature_; sig_p < (unsigned char*)signature_ + MD5_SIZE; sig_p++) {
high = *sig_p / 16;
low = *sig_p % 16;
/* account for 2 chars */
if (str_p + 1 >= max_p) {
break;
}
*str_p++ = md5::HEX_STRING[high];
*str_p++ = md5::HEX_STRING[low];
}
/* account for 2 chars */
if (str_p < max_p) {
*str_p++ = '\0';
}
}
/*
* sig_from_string
*
* DESCRIPTION:
*
* Convert a MD5 signature from a hexadecimal string representation into
* a 16 byte buffer.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature_ - A 16 byte buffer that will contain the MD5 signature.
*
* str_ - A string of charactes which _must_ be at least 32 bytes long (2
* characters per MD5 byte).
*/
void sig_from_string(void* signature_, const char* str_) {
unsigned char *sig_p;
const char *str_p;
char* hex;
unsigned int high, low, val;
hex = (char*)md5::HEX_STRING;
sig_p = static_cast<unsigned char*>(signature_);
for (str_p = str_; str_p < str_ + MD5_SIZE * 2; str_p += 2) {
high = strchr(hex, *str_p) - hex;
low = strchr(hex, *(str_p + 1)) - hex;
val = high * 16 + low;
*sig_p++ = val;
}
}
} // namespace md5

207
src/md5.h Normal file
View File

@@ -0,0 +1,207 @@
#ifndef __MD5_H__
#define __MD5_H__
/*
* Size of a standard MD5 signature in bytes. This definition is for
* external programs only. The MD5 routines themselves reference the
* signature as 4 unsigned 32-bit integers.
*/
const unsigned int MD5_SIZE = (4 * sizeof(unsigned int)); /* 16 */
const unsigned int MD5_STRING_SIZE = 2 * MD5_SIZE + 1; /* 33 */
namespace md5 {
/*
* The MD5 algorithm works on blocks of characters of 64 bytes. This
* is an internal value only and is not necessary for external use.
*/
const unsigned int BLOCK_SIZE = 64;
class md5_t {
public:
/*
* md5_t
*
* DESCRIPTION:
*
* Initialize structure containing state of MD5 computation. (RFC 1321,
* 3.3: Step 3). This is for progressive MD5 calculations only. If
* you have the complete string available, call it as below.
* process should be called for each bunch of bytes and after the last
* process call, finish should be called to get the signature.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* None.
*/
md5_t();
/*
* md5_t
*
* DESCRIPTION:
*
* This function is used to calculate a MD5 signature for a buffer of
* bytes. If you only have part of a buffer that you want to process
* then md5_t, process, and finish should be used.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* input - A buffer of bytes whose MD5 signature we are calculating.
*
* input_length - The length of the buffer.
*
* signature_ - A 16 byte buffer that will contain the MD5 signature.
*/
md5_t(const void* input, const unsigned int input_length, void* signature_ = NULL);
/*
* process
*
* DESCRIPTION:
*
* This function is used to progressively calculate an MD5 signature some
* number of bytes at a time.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* input - A buffer of bytes whose MD5 signature we are calculating.
*
* input_length - The length of the buffer.
*/
void process(const void* input, const unsigned int input_length);
/*
* finish
*
* DESCRIPTION:
*
* Finish a progressing MD5 calculation and copy the resulting MD5
* signature into the result buffer which should be 16 bytes
* (MD5_SIZE). After this call, the MD5 structure cannot be used
* to calculate a new md5, it can only return its signature.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature_ - A 16 byte buffer that will contain the MD5 signature.
*/
void finish(void* signature_ = NULL);
/*
* get_sig
*
* DESCRIPTION:
*
* Retrieves the previously calculated signature from the MD5 object.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature_ - A 16 byte buffer that will contain the MD5 signature.
*/
void get_sig(void* signature_);
/*
* get_string
*
* DESCRIPTION:
*
* Retrieves the previously calculated signature from the MD5 object in
* printable format.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* str_ - a string of characters which should be at least 33 bytes long
* (2 characters per MD5 byte and 1 for the \0).
*/
void get_string(void* str_);
private:
/* internal functions */
void initialise();
void process_block(const unsigned char*);
void get_result(void*);
unsigned int A; /* accumulator 1 */
unsigned int B; /* accumulator 2 */
unsigned int C; /* accumulator 3 */
unsigned int D; /* accumulator 4 */
unsigned int message_length[2]; /* length of data */
unsigned int stored_size; /* length of stored bytes */
unsigned char stored[md5::BLOCK_SIZE * 2]; /* stored bytes */
bool finished; /* object state */
char signature[MD5_SIZE]; /* stored signature */
char str[MD5_STRING_SIZE]; /* stored plain text hash */
};
/*
* sig_to_string
*
* DESCRIPTION:
*
* Convert a MD5 signature in a 16 byte buffer into a hexadecimal string
* representation.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature - a 16 byte buffer that contains the MD5 signature.
*
* str - a string of characters which should be at least 33 bytes long (2
* characters per MD5 byte and 1 for the \0).
*
* str_len - the length of the string.
*/
extern void sig_to_string(const void* signature, char* str, const int str_len);
/*
* sig_from_string
*
* DESCRIPTION:
*
* Convert a MD5 signature from a hexadecimal string representation into
* a 16 byte buffer.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature - A 16 byte buffer that will contain the MD5 signature.
*
* str - A string of charactes which _must_ be at least 32 bytes long (2
* characters per MD5 byte).
*/
extern void sig_from_string(void* signature, const char* str);
} // namespace md5
#endif /* ! __MD5_H__ */

View File

@@ -21,11 +21,14 @@ typedef jpcre2::select<char> jp;
#include <rapidjson/document.h>
/*
#ifdef USE_MBEDTLS
#include <mbedtls/md5.h>
#else
#include <openssl/md5.h>
#endif // USE_MBEDTLS
*/
#include "md5.h"
#include "misc.h"
@@ -768,6 +771,8 @@ std::string urlsafe_base64_encode(const std::string &string_to_encode)
std::string getMD5(const std::string &data)
{
std::string result;
/*
unsigned int i = 0;
unsigned char digest[16] = {};
@@ -793,6 +798,14 @@ std::string getMD5(const std::string &data)
snprintf(tmp, 3, "%02x", digest[i]);
result += tmp;
}
*/
char result_str[MD5_STRING_SIZE];
md5::md5_t md5;
md5.process(data.data(), data.size());
md5.finish();
md5.get_string(result_str);
result.assign(result_str);
return result;
}