masqmail-0.2

annotate src/md5/hmac_md5.c @ 179:ec3fe72a3e99

Fixed an important bug with folded headers! g_strconcat() returns a *copy* of the string, but hdr->value still pointed to the old header (which probably was a memory leak, too). If the folded part had been quite small it was likely that the new string was at the same position as the old one, thus making everything go well. But if pretty long headers were folded several times it was likely that the new string was allocated somewhere else in memory, thus breaking things. In result mails to lots of recipients (folded header) were frequently only sent to the ones in the first line. Sorry for the inconvenience.
author meillo@marmaro.de
date Fri, 03 Jun 2011 09:52:17 +0200
parents 52c82d755215
children
rev   line source
meillo@0 1 /*
meillo@164 2 hmac_md5 -- implements RFC 2104
meillo@164 3
meillo@164 4 Copyright 2010, markus schnalke <meillo@marmaro.de>
meillo@164 5
meillo@164 6 Permission to use, copy, modify, and/or distribute this software for any
meillo@164 7 purpose with or without fee is hereby granted, provided that the above
meillo@164 8 copyright notice and this permission notice appear in all copies.
meillo@164 9
meillo@164 10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
meillo@164 11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
meillo@164 12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
meillo@164 13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
meillo@164 14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
meillo@164 15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
meillo@164 16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
meillo@164 17
meillo@164 18
meillo@164 19 My motivation to write this code was the lack of a nicely licensed
meillo@164 20 hmac_md5 function in C. I programmed it following the RFC's text.
meillo@164 21 Obviously this code is highly similar to the sample code of the RFC.
meillo@164 22 The code is tested against the test vectors of the RFC. Wikipedia's
meillo@164 23 HMAC page helped me to understand the algorithm better.
meillo@164 24
meillo@164 25 This hmac_md5 function requires an OpenSSL-compatible MD5
meillo@164 26 implementation. There are Public Domain MD5 implementations by Colin
meillo@164 27 Plumb and by Solar Designer. You probably want to use one of these.
meillo@0 28 */
meillo@0 29
meillo@0 30 #include <string.h>
meillo@0 31 #include "md5.h"
meillo@0 32
meillo@164 33
meillo@164 34 const int blocksize = 64;
meillo@164 35 const int hashsize = 16;
meillo@164 36
meillo@164 37
meillo@164 38 /*
meillo@164 39 The computed HMAC will be written to `digest'.
meillo@164 40 Ensure digest points to hashsize bytes of allocated memory.
meillo@164 41 */
meillo@10 42 void
meillo@164 43 hmac_md5(unsigned char* text, int textlen, unsigned char* key, int keylen, unsigned char* digest)
meillo@10 44 {
meillo@164 45 int i;
meillo@10 46 MD5_CTX context;
meillo@164 47 unsigned char ipad[blocksize];
meillo@164 48 unsigned char opad[blocksize];
meillo@0 49
meillo@164 50 /* too long keys are replaced by their hash value */
meillo@164 51 if (keylen > blocksize) {
meillo@164 52 MD5_Init(&context);
meillo@164 53 MD5_Update(&context, key, keylen);
meillo@164 54 MD5_Final(digest, &context);
meillo@164 55 key = digest;
meillo@164 56 keylen = hashsize;
meillo@10 57 }
meillo@0 58
meillo@164 59 /* copy the key into the pads */
meillo@164 60 memset(ipad, 0, sizeof(ipad));
meillo@164 61 memcpy(ipad, key, keylen);
meillo@0 62
meillo@164 63 memset(opad, 0, sizeof(opad));
meillo@164 64 memcpy(opad, key, keylen);
meillo@0 65
meillo@164 66 /* xor the pads with their ``basic'' value */
meillo@164 67 for (i=0; i<blocksize; i++) {
meillo@164 68 ipad[i] ^= 0x36;
meillo@164 69 opad[i] ^= 0x5c;
meillo@10 70 }
meillo@164 71
meillo@164 72 /* inner pass (ipad ++ message) */
meillo@164 73 MD5_Init(&context);
meillo@164 74 MD5_Update(&context, ipad, sizeof(ipad));
meillo@164 75 MD5_Update(&context, text, textlen);
meillo@164 76 MD5_Final(digest, &context);
meillo@164 77
meillo@164 78 /* outer pass (opad ++ result of inner pass) */
meillo@164 79 MD5_Init(&context);
meillo@164 80 MD5_Update(&context, opad, sizeof(opad));
meillo@164 81 MD5_Update(&context, digest, hashsize);
meillo@164 82 MD5_Final(digest, &context);
meillo@0 83 }