1 /*
2 * md5-apps.c
3 *
4 * This file is part of msmtp, an SMTP client.
5 *
6 * This code was adapted from GNU Anubis, version 3.6.2
7 * Copyright (C) 2001, 2002 The Anubis Team.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <string.h>
29
30 #include "md5.h"
31 #include "md5-apps.h"
32
33
md5_hmac(const char * secret,size_t secret_len,char * challenge,size_t challenge_len,unsigned char * digest)34 void md5_hmac(const char *secret, size_t secret_len,
35 char *challenge, size_t challenge_len,
36 unsigned char *digest)
37 {
38 MD5_CTX context;
39 unsigned char ipad[64];
40 unsigned char opad[64];
41 int i;
42
43 memset(digest, 0, (size_t)16);
44 memset(ipad, 0, sizeof(ipad));
45 memset(opad, 0, sizeof(opad));
46
47 if (secret_len > 64)
48 {
49 MD5_Init(&context);
50 MD5_Update(&context, (unsigned char *)secret, secret_len);
51 MD5_Final(ipad, &context);
52 MD5_Final(opad, &context);
53 }
54 else
55 {
56 memcpy(ipad, secret, secret_len);
57 memcpy(opad, secret, secret_len);
58 }
59
60 for (i = 0; i < 64; i++)
61 {
62 ipad[i] ^= 0x36;
63 opad[i] ^= 0x5c;
64 }
65
66 MD5_Init(&context);
67 MD5_Update(&context, ipad, (size_t)64);
68 MD5_Update(&context, (unsigned char *)challenge, challenge_len);
69 MD5_Final(digest, &context);
70
71 MD5_Init(&context);
72 MD5_Update(&context, opad, (size_t)64);
73 MD5_Update(&context, digest, (size_t)16);
74 MD5_Final(digest, &context);
75 }
76
md5_digest(unsigned char * src,size_t srclen,char * dst)77 void md5_digest(unsigned char *src, size_t srclen, char *dst)
78 {
79 MD5_CTX context;
80 unsigned char digest[16];
81 char hex[] = "0123456789abcdef";
82 int i;
83
84 MD5_Init(&context);
85 MD5_Update(&context, src, srclen);
86 MD5_Final(digest, &context);
87
88 for (i = 0; i < 16; i++)
89 {
90 dst[2 * i] = hex[(digest[i] & 0xf0) >> 4];
91 dst[2 * i + 1] = hex[digest[i] & 0x0f];
92 }
93 dst[32] = '\0';
94 }
95