crypt_md5.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
10 * Shamelessly stolen from linux-pam, and adopted to work with
11 * OpenSSL md5 implementation and any magic string
12 *
13 * Origin2: md5_crypt.c,v 1.1.1.1 2000/01/03 17:34:46 gafton Exp
14 *
15 * ----------------------------------------------------------------------------
16 * "THE BEER-WARE LICENSE" (Revision 42):
17 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
18 * can do whatever you want with this stuff. If we meet some day, and you think
19 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
20 * ----------------------------------------------------------------------------
21 *
22 * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp
23 *
24 */
25
26#include "squid.h"
28#include "md5.h"
29
30#include <cstring>
31
32static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
33 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
34
35static void md5to64(char *s, unsigned long v, int n)
36{
37 while (--n >= 0) {
38 *s = itoa64[v & 0x3f];
39 ++s;
40 v >>= 6;
41 }
42}
43
44/*
45 * MD5 hash a password
46 *
47 * Use MD5 for what it is best at...
48 *
49 * If salt begins with $ then it is assumed to be on the form
50 * $magic$salt$...
51 * If not the normal UNIX magic $1$ is used.
52 */
53
54char *crypt_md5(const char *pw, const char *salt)
55{
56 const char *magic = "$1$";
57 int magiclen = 3;
58 static char passwd[120], *p;
59 static const char *sp, *ep;
60 unsigned char final[16];
61 int sl, pl, i, j;
62 SquidMD5_CTX ctx, ctx1;
63 unsigned long l;
64
65 if (*salt == '$') {
66 magic = salt;
67 ++salt;
68 while (*salt && *salt != '$')
69 ++salt;
70 if (*salt == '$') {
71 ++salt;
72 magiclen = salt - magic;
73 } else {
74 salt = magic;
75 magic = "$1$";
76 }
77 }
78
79 /* Refine the Salt first */
80 sp = salt;
81
82 /* It stops at the first '$', max 8 chars */
83 for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ++ep)
84 continue;
85
86 /* get the length of the true salt */
87 sl = ep - sp;
88
89 SquidMD5Init(&ctx);
90
91 /* The password first, since that is what is most unknown */
92 SquidMD5Update(&ctx, (unsigned const char *) pw, strlen(pw));
93
94 /* Then our magic string */
95 SquidMD5Update(&ctx, (unsigned const char *) magic, magiclen);
96
97 /* Then the raw salt */
98 SquidMD5Update(&ctx, (unsigned const char *) sp, sl);
99
100 /* Then just as many characters of the MD5(pw,salt,pw) */
101 SquidMD5Init(&ctx1);
102 SquidMD5Update(&ctx1, (unsigned const char *) pw, strlen(pw));
103 SquidMD5Update(&ctx1, (unsigned const char *) sp, sl);
104 SquidMD5Update(&ctx1, (unsigned const char *) pw, strlen(pw));
105 SquidMD5Final(final, &ctx1);
106 for (pl = strlen(pw); pl > 0; pl -= 16)
107 SquidMD5Update(&ctx, (unsigned const char *) final, pl > 16 ? 16 : pl);
108
109 /* Don't leave anything around in vm they could use. */
110 memset(final, 0, sizeof final);
111
112 /* Then something really weird... */
113 for (j = 0, i = strlen(pw); i; i >>= 1)
114 if (i & 1)
115 SquidMD5Update(&ctx, (unsigned const char *) final + j, 1);
116 else
117 SquidMD5Update(&ctx, (unsigned const char *) pw + j, 1);
118
119 /* Now make the output string */
120 memset(passwd, 0, sizeof(passwd));
121 strncat(passwd, magic, magiclen);
122 strncat(passwd, sp, sl);
123 strcat(passwd, "$");
124
125 SquidMD5Final(final, &ctx);
126
127 /*
128 * and now, just to make sure things don't run too fast
129 * On a 60 Mhz Pentium this takes 34 msec, so you would
130 * need 30 seconds to build a 1000 entry dictionary...
131 */
132 for (i = 0; i < 1000; ++i) {
133 SquidMD5Init(&ctx1);
134 if (i & 1)
135 SquidMD5Update(&ctx1, (unsigned const char *) pw, strlen(pw));
136 else
137 SquidMD5Update(&ctx1, (unsigned const char *) final, 16);
138
139 if (i % 3)
140 SquidMD5Update(&ctx1, (unsigned const char *) sp, sl);
141
142 if (i % 7)
143 SquidMD5Update(&ctx1, (unsigned const char *) pw, strlen(pw));
144
145 if (i & 1)
146 SquidMD5Update(&ctx1, (unsigned const char *) final, 16);
147 else
148 SquidMD5Update(&ctx1, (unsigned const char *) pw, strlen(pw));
149 SquidMD5Final(final, &ctx1);
150 }
151
152 p = passwd + strlen(passwd);
153
154 l = (final[0] << 16) | (final[6] << 8) | final[12];
155 md5to64(p, l, 4);
156 p += 4;
157 l = (final[1] << 16) | (final[7] << 8) | final[13];
158 md5to64(p, l, 4);
159 p += 4;
160 l = (final[2] << 16) | (final[8] << 8) | final[14];
161 md5to64(p, l, 4);
162 p += 4;
163 l = (final[3] << 16) | (final[9] << 8) | final[15];
164 md5to64(p, l, 4);
165 p += 4;
166 l = (final[4] << 16) | (final[10] << 8) | final[5];
167 md5to64(p, l, 4);
168 p += 4;
169 l = final[11];
170 md5to64(p, l, 2);
171 p += 2;
172 *p = '\0';
173
174 /* Don't leave anything around in vm they could use. */
175 memset(final, 0, sizeof final);
176
177 return passwd;
178}
179
180/* Created by Ramon de Carvalho <ramondecarvalho@yahoo.com.br>
181 Refined by Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
182*/
183char *md5sum(const char *s)
184{
185 static unsigned char digest[16];
186 SquidMD5_CTX ctx;
187 int idx;
188 static char sum[33];
189
190 memset(digest,0,16);
191
192 SquidMD5Init(&ctx);
193 SquidMD5Update(&ctx,(const unsigned char *)s,strlen(s));
194 SquidMD5Final(digest,&ctx);
195
196 for (idx=0; idx<16; ++idx)
197 snprintf(&sum[idx*2],(33-(idx*2)),"%02x",digest[idx]);
198
199 sum[32]='\0';
200
201 /* Don't leave anything around in vm they could use. */
202 memset(digest, 0, sizeof digest);
203
204 return sum;
205}
206
char * md5sum(const char *s)
Definition: crypt_md5.cc:183
char * crypt_md5(const char *pw, const char *salt)
Definition: crypt_md5.cc:54
static void md5to64(char *s, unsigned long v, int n)
Definition: crypt_md5.cc:35
static unsigned char itoa64[]
Definition: crypt_md5.cc:32
struct _sp sp
SQUIDCEXTERN void SquidMD5Init(struct SquidMD5Context *context)
Definition: md5.c:73
SQUIDCEXTERN void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len)
Definition: md5.c:89
SQUIDCEXTERN void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context)

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors