00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_MD5.hpp"
00038 #include "OW_String.hpp"
00039 #include "OW_ExceptionIds.hpp"
00040
00041 #include <string.h>
00042
00043 #ifdef OW_WIN32
00044 #pragma warning (push)
00045 #pragma warning (disable: 4355)
00046 #endif
00047
00048 namespace OW_NAMESPACE
00049 {
00050
00051 const int MD5HASHHEXLEN = 32;
00052
00053 OW_DEFINE_EXCEPTION_WITH_ID(MD5);
00055 MD5OStreamBase::MD5OStreamBase(MD5* md5): _buf(md5) {}
00057 MD5StreamBuffer::MD5StreamBuffer(MD5* md5): _md5(md5) {}
00059 int
00060 MD5StreamBuffer::overflow(int c)
00061 {
00062 unsigned char lc = c;
00063 MD5::MD5Update(&(_md5->m_ctx), &lc, 1);
00064 return c;
00065 }
00067 std::streamsize
00068 MD5StreamBuffer::xsputn(const char* s, std::streamsize num)
00069 {
00070 MD5::MD5Update(&(_md5->m_ctx),
00071 reinterpret_cast<const unsigned char*>(s), num);
00072 return num;
00073 }
00075 MD5::MD5()
00076 : MD5OStreamBase(this), std::ostream(&_buf), m_ctx(), m_finished(false)
00077 {
00078 MD5Init(&m_ctx);
00079 }
00081 void
00082 MD5::init(const String& input)
00083 {
00084 m_finished = false;
00085 MD5Init(&m_ctx);
00086 update(input);
00087 }
00089 MD5::MD5(const String& input)
00090 : MD5OStreamBase(this), std::ostream(&_buf), m_ctx(), m_finished(false)
00091 {
00092 MD5Init(&m_ctx);
00093 update(input);
00094 }
00096 void
00097 MD5::update(const String& input)
00098 {
00099 if (m_finished)
00100 {
00101 OW_THROW(MD5Exception, "Cannot update after a call to toString()");
00102 }
00103 MD5Update(&m_ctx, reinterpret_cast<const unsigned char*>(input.c_str()),
00104 input.length());
00105 }
00107 String
00108 MD5::toString()
00109 {
00110 return convertBinToHex(getDigest());
00111 }
00113 unsigned char*
00114 MD5::getDigest()
00115 {
00116 if (!m_finished)
00117 {
00118 MD5Final(m_digest, &m_ctx);
00119 m_finished = true;
00120 }
00121 return m_digest;
00122 }
00124 String
00125 MD5::convertBinToHex( const unsigned char* sBin)
00126 {
00127 unsigned short i;
00128 unsigned char j;
00129 char Hex[ MD5HASHHEXLEN + 1 ];
00130 for ( i = 0; i < MD5HASHLEN; i++ )
00131 {
00132 j = (sBin[i] >> 4) & 0xf;
00133 if ( j <= 9 )
00134 {
00135 Hex[i*2] = (j + '0');
00136 }
00137 else
00138 {
00139 Hex[i*2] = (j + 'a' - 10);
00140 }
00141 j = sBin[i] & 0xf;
00142 if ( j <= 9 )
00143 {
00144 Hex[i*2+1] = (j + '0');
00145 }
00146 else
00147 {
00148 Hex[i*2+1] = (j + 'a' - 10);
00149 }
00150 };
00151 Hex[MD5HASHHEXLEN] = '\0';
00152 return String(Hex);
00153 };
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 typedef unsigned char *POINTER;
00176
00177
00178 #define S11 7
00179 #define S12 12
00180 #define S13 17
00181 #define S14 22
00182 #define S21 5
00183 #define S22 9
00184 #define S23 14
00185 #define S24 20
00186 #define S31 4
00187 #define S32 11
00188 #define S33 16
00189 #define S34 23
00190 #define S41 6
00191 #define S42 10
00192 #define S43 15
00193 #define S44 21
00194 static void MD5Transform(UInt32*, const unsigned char*);
00195 static void Encode(unsigned char *, UInt32 *, UInt32);
00196 static void Decode(UInt32 *, const unsigned char *, UInt32);
00197
00198
00199 static unsigned char PADDING[64] = {
00200 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00203 };
00204
00205
00206 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00207 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00208 #define H(x, y, z) ((x) ^ (y) ^ (z))
00209 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00210
00211
00212 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00213
00214
00215
00216 #define FF(a, b, c, d, x, s, ac) { \
00217 (a) += F ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00218 (a) = ROTATE_LEFT ((a), (s)); \
00219 (a) += (b); \
00220 }
00221 #define GG(a, b, c, d, x, s, ac) { \
00222 (a) += G ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00223 (a) = ROTATE_LEFT ((a), (s)); \
00224 (a) += (b); \
00225 }
00226 #define HH(a, b, c, d, x, s, ac) { \
00227 (a) += H ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00228 (a) = ROTATE_LEFT ((a), (s)); \
00229 (a) += (b); \
00230 }
00231 #define II(a, b, c, d, x, s, ac) { \
00232 (a) += I ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00233 (a) = ROTATE_LEFT ((a), (s)); \
00234 (a) += (b); \
00235 }
00236
00237
00238 void
00239 MD5::MD5Init(MD5_CTX* context)
00240 {
00241 context->count[0] = context->count[1] = 0;
00242
00243
00244 context->state[0] = 0x67452301;
00245 context->state[1] = 0xefcdab89;
00246 context->state[2] = 0x98badcfe;
00247 context->state[3] = 0x10325476;
00248 }
00249
00250
00251
00252
00253 void
00254 MD5::MD5Update(MD5_CTX* context, const unsigned char* input,
00255 UInt32 inputLen)
00256 {
00257 UInt32 i, index, partLen;
00258
00259 index = ((context->count[0] >> 3) & 0x3F);
00260
00261 if ((context->count[0] += (inputLen << 3)) < (inputLen << 3))
00262 {
00263 context->count[1]++;
00264 }
00265 context->count[1] += (inputLen >> 29);
00266 partLen = 64 - index;
00267
00268
00269 if (inputLen >= partLen)
00270 {
00271 memcpy(static_cast<POINTER>(&context->buffer[index]),
00272 static_cast<const unsigned char*>(input), partLen);
00273 MD5Transform (context->state, context->buffer);
00274 for (i = partLen; i + 63 < inputLen; i += 64)
00275 MD5Transform (context->state, &input[i]);
00276 index = 0;
00277 }
00278 else
00279 i = 0;
00280
00281 memcpy
00282 (static_cast<POINTER>(&context->buffer[index]),
00283 static_cast<const unsigned char*>(&input[i]),
00284 inputLen-i);
00285 }
00286
00287
00288
00289 void
00290 MD5::MD5Final (unsigned char* digest, MD5_CTX* context)
00291 {
00292 unsigned char bits[8];
00293 UInt32 index, padLen;
00294
00295 Encode (bits, context->count, 8);
00296
00297
00298 index = ((context->count[0] >> 3) & 0x3f);
00299 padLen = (index < 56) ? (56 - index) : (120 - index);
00300 MD5Update (context, PADDING, padLen);
00301
00302 MD5Update (context, bits, 8);
00303
00304 Encode (digest, context->state, 16);
00305
00306
00307 memset (reinterpret_cast<POINTER>(context), 0, sizeof (*context));
00308 }
00309
00310
00311 static void MD5Transform (UInt32* state, const unsigned char* block)
00312 {
00313 UInt32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00314 Decode (x, block, 64);
00315
00316 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
00317 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
00318 FF (c, d, a, b, x[ 2], S13, 0x242070db);
00319 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
00320 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
00321 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
00322 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
00323 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
00324 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
00325 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
00326 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
00327 FF (b, c, d, a, x[11], S14, 0x895cd7be);
00328 FF (a, b, c, d, x[12], S11, 0x6b901122);
00329 FF (d, a, b, c, x[13], S12, 0xfd987193);
00330 FF (c, d, a, b, x[14], S13, 0xa679438e);
00331 FF (b, c, d, a, x[15], S14, 0x49b40821);
00332
00333 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
00334 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
00335 GG (c, d, a, b, x[11], S23, 0x265e5a51);
00336 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
00337 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
00338 GG (d, a, b, c, x[10], S22, 0x2441453);
00339 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
00340 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
00341 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
00342 GG (d, a, b, c, x[14], S22, 0xc33707d6);
00343 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
00344 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
00345 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
00346 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
00347 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
00348 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
00349
00350 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
00351 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
00352 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
00353 HH (b, c, d, a, x[14], S34, 0xfde5380c);
00354 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
00355 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
00356 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
00357 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
00358 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
00359 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
00360 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
00361 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
00362 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
00363 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
00364 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
00365 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
00366
00367 II (a, b, c, d, x[ 0], S41, 0xf4292244);
00368 II (d, a, b, c, x[ 7], S42, 0x432aff97);
00369 II (c, d, a, b, x[14], S43, 0xab9423a7);
00370 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
00371 II (a, b, c, d, x[12], S41, 0x655b59c3);
00372 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
00373 II (c, d, a, b, x[10], S43, 0xffeff47d);
00374 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
00375 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
00376 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
00377 II (c, d, a, b, x[ 6], S43, 0xa3014314);
00378 II (b, c, d, a, x[13], S44, 0x4e0811a1);
00379 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
00380 II (d, a, b, c, x[11], S42, 0xbd3af235);
00381 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
00382 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
00383 state[0] += a;
00384 state[1] += b;
00385 state[2] += c;
00386 state[3] += d;
00387
00388 memset (reinterpret_cast<POINTER>(x), 0, sizeof (x));
00389 }
00390
00391
00392
00393 static void Encode (unsigned char* output, UInt32* input, UInt32 len)
00394 {
00395 UInt32 i, j;
00396 for (i = 0, j = 0; j < len; i++, j += 4)
00397 {
00398 output[j] = (input[i] & 0xff);
00399 output[j+1] = ((input[i] >> 8) & 0xff);
00400 output[j+2] = ((input[i] >> 16) & 0xff);
00401 output[j+3] = ((input[i] >> 24) & 0xff);
00402 }
00403 }
00404
00405
00406
00407 static void Decode (UInt32* output, const unsigned char* input, UInt32 len)
00408 {
00409 UInt32 i, j;
00410 for (i = 0, j = 0; j < len; i++, j += 4)
00411 output[i] = (static_cast<UInt32>(input[j])) | ((static_cast<UInt32>(input[j+1])) << 8) |
00412 ((static_cast<UInt32>(input[j+2])) << 16) | ((static_cast<UInt32>(input[j+3])) << 24);
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 }
00431
00432
00433 #ifdef OW_WIN32
00434 #pragma warning (pop)
00435 #endif
00436