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