Skip to content

Commit 957613b

Browse files
committed
Add new files.
1 parent 38bb1ab commit 957613b

File tree

2 files changed

+324
-0
lines changed

2 files changed

+324
-0
lines changed

src/backend/libpq/md5.c

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
/*
2+
* md5.c
3+
*
4+
* Implements the MD5 Message-Digest Algorithm as specified in
5+
* RFC 1321. This implementation is a simple one, in that it
6+
* needs every input byte to be buffered before doing any
7+
* calculations. I do not expect this file to be used for
8+
* general purpose MD5'ing of large amounts of data, only for
9+
* generating hashed passwords from limited input.
10+
*
11+
* Sverre H. Huseby <sverrehu@online.no>
12+
*/
13+
14+
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <string.h>
18+
#include <errno.h>
19+
20+
#include "postgres.h"
21+
#include "libpq/md5.h"
22+
23+
/*
24+
* PRIVATE FUNCTIONS
25+
*/
26+
27+
typedef unsigned char unsigned8;
28+
typedef unsigned int unsigned32;
29+
typedef unsigned long unsigned64;
30+
31+
/*
32+
* The returned array is allocated using malloc. the caller should free it
33+
* when it is no longer needed.
34+
*/
35+
static unsigned8 *
36+
createPaddedCopyWithLength(unsigned8 *b, unsigned32 *l)
37+
{
38+
unsigned8 *ret;
39+
unsigned32 q;
40+
unsigned32 len, newLen448;
41+
unsigned64 len64;
42+
43+
len = ((b == NULL) ? 0 : *l);
44+
newLen448 = len + 64 - (len % 64) - 8;
45+
if (newLen448 <= len)
46+
newLen448 += 64;
47+
48+
*l = newLen448 + 8;
49+
if ((ret = (unsigned8 *) malloc(sizeof(unsigned8) * *l)) == NULL)
50+
return NULL;
51+
52+
if (b != NULL)
53+
memcpy(ret, b, sizeof(unsigned8) * len);
54+
55+
/* pad */
56+
ret[len] = 0x80;
57+
for (q = len + 1; q < newLen448; q++)
58+
ret[q] = 0x00;
59+
60+
/* append length as a 64 bit bitcount */
61+
len64 = len;
62+
len64 <<= 3;
63+
q = newLen448;
64+
ret[q++] = (len64 & 0xFF);
65+
len64 >>= 8;
66+
ret[q++] = (len64 & 0xFF);
67+
len64 >>= 8;
68+
ret[q++] = (len64 & 0xFF);
69+
len64 >>= 8;
70+
ret[q++] = (len64 & 0xFF);
71+
len64 >>= 8;
72+
ret[q++] = (len64 & 0xFF);
73+
len64 >>= 8;
74+
ret[q++] = (len64 & 0xFF);
75+
len64 >>= 8;
76+
ret[q++] = (len64 & 0xFF);
77+
len64 >>= 8;
78+
ret[q] = (len64 & 0xFF);
79+
80+
return ret;
81+
}
82+
83+
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
84+
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
85+
#define H(x, y, z) ((x) ^ (y) ^ (z))
86+
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
87+
#define ROT_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
88+
89+
static void
90+
doTheRounds(unsigned32 X[16], unsigned32 state[4])
91+
{
92+
unsigned32 a, b, c, d;
93+
94+
a = state[0];
95+
b = state[1];
96+
c = state[2];
97+
d = state[3];
98+
99+
/* round 1 */
100+
a = b + ROT_LEFT((a + F(b, c, d) + X[ 0] + 0xd76aa478), 7); /* 1 */
101+
d = a + ROT_LEFT((d + F(a, b, c) + X[ 1] + 0xe8c7b756), 12); /* 2 */
102+
c = d + ROT_LEFT((c + F(d, a, b) + X[ 2] + 0x242070db), 17); /* 3 */
103+
b = c + ROT_LEFT((b + F(c, d, a) + X[ 3] + 0xc1bdceee), 22); /* 4 */
104+
a = b + ROT_LEFT((a + F(b, c, d) + X[ 4] + 0xf57c0faf), 7); /* 5 */
105+
d = a + ROT_LEFT((d + F(a, b, c) + X[ 5] + 0x4787c62a), 12); /* 6 */
106+
c = d + ROT_LEFT((c + F(d, a, b) + X[ 6] + 0xa8304613), 17); /* 7 */
107+
b = c + ROT_LEFT((b + F(c, d, a) + X[ 7] + 0xfd469501), 22); /* 8 */
108+
a = b + ROT_LEFT((a + F(b, c, d) + X[ 8] + 0x698098d8), 7); /* 9 */
109+
d = a + ROT_LEFT((d + F(a, b, c) + X[ 9] + 0x8b44f7af), 12); /* 10 */
110+
c = d + ROT_LEFT((c + F(d, a, b) + X[10] + 0xffff5bb1), 17); /* 11 */
111+
b = c + ROT_LEFT((b + F(c, d, a) + X[11] + 0x895cd7be), 22); /* 12 */
112+
a = b + ROT_LEFT((a + F(b, c, d) + X[12] + 0x6b901122), 7); /* 13 */
113+
d = a + ROT_LEFT((d + F(a, b, c) + X[13] + 0xfd987193), 12); /* 14 */
114+
c = d + ROT_LEFT((c + F(d, a, b) + X[14] + 0xa679438e), 17); /* 15 */
115+
b = c + ROT_LEFT((b + F(c, d, a) + X[15] + 0x49b40821), 22); /* 16 */
116+
117+
/* round 2 */
118+
a = b + ROT_LEFT((a + G(b, c, d) + X[ 1] + 0xf61e2562), 5); /* 17 */
119+
d = a + ROT_LEFT((d + G(a, b, c) + X[ 6] + 0xc040b340), 9); /* 18 */
120+
c = d + ROT_LEFT((c + G(d, a, b) + X[11] + 0x265e5a51), 14); /* 19 */
121+
b = c + ROT_LEFT((b + G(c, d, a) + X[ 0] + 0xe9b6c7aa), 20); /* 20 */
122+
a = b + ROT_LEFT((a + G(b, c, d) + X[ 5] + 0xd62f105d), 5); /* 21 */
123+
d = a + ROT_LEFT((d + G(a, b, c) + X[10] + 0x02441453), 9); /* 22 */
124+
c = d + ROT_LEFT((c + G(d, a, b) + X[15] + 0xd8a1e681), 14); /* 23 */
125+
b = c + ROT_LEFT((b + G(c, d, a) + X[ 4] + 0xe7d3fbc8), 20); /* 24 */
126+
a = b + ROT_LEFT((a + G(b, c, d) + X[ 9] + 0x21e1cde6), 5); /* 25 */
127+
d = a + ROT_LEFT((d + G(a, b, c) + X[14] + 0xc33707d6), 9); /* 26 */
128+
c = d + ROT_LEFT((c + G(d, a, b) + X[ 3] + 0xf4d50d87), 14); /* 27 */
129+
b = c + ROT_LEFT((b + G(c, d, a) + X[ 8] + 0x455a14ed), 20); /* 28 */
130+
a = b + ROT_LEFT((a + G(b, c, d) + X[13] + 0xa9e3e905), 5); /* 29 */
131+
d = a + ROT_LEFT((d + G(a, b, c) + X[ 2] + 0xfcefa3f8), 9); /* 30 */
132+
c = d + ROT_LEFT((c + G(d, a, b) + X[ 7] + 0x676f02d9), 14); /* 31 */
133+
b = c + ROT_LEFT((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20); /* 32 */
134+
135+
/* round 3 */
136+
a = b + ROT_LEFT((a + H(b, c, d) + X[ 5] + 0xfffa3942), 4); /* 33 */
137+
d = a + ROT_LEFT((d + H(a, b, c) + X[ 8] + 0x8771f681), 11); /* 34 */
138+
c = d + ROT_LEFT((c + H(d, a, b) + X[11] + 0x6d9d6122), 16); /* 35 */
139+
b = c + ROT_LEFT((b + H(c, d, a) + X[14] + 0xfde5380c), 23); /* 36 */
140+
a = b + ROT_LEFT((a + H(b, c, d) + X[ 1] + 0xa4beea44), 4); /* 37 */
141+
d = a + ROT_LEFT((d + H(a, b, c) + X[ 4] + 0x4bdecfa9), 11); /* 38 */
142+
c = d + ROT_LEFT((c + H(d, a, b) + X[ 7] + 0xf6bb4b60), 16); /* 39 */
143+
b = c + ROT_LEFT((b + H(c, d, a) + X[10] + 0xbebfbc70), 23); /* 40 */
144+
a = b + ROT_LEFT((a + H(b, c, d) + X[13] + 0x289b7ec6), 4); /* 41 */
145+
d = a + ROT_LEFT((d + H(a, b, c) + X[ 0] + 0xeaa127fa), 11); /* 42 */
146+
c = d + ROT_LEFT((c + H(d, a, b) + X[ 3] + 0xd4ef3085), 16); /* 43 */
147+
b = c + ROT_LEFT((b + H(c, d, a) + X[ 6] + 0x04881d05), 23); /* 44 */
148+
a = b + ROT_LEFT((a + H(b, c, d) + X[ 9] + 0xd9d4d039), 4); /* 45 */
149+
d = a + ROT_LEFT((d + H(a, b, c) + X[12] + 0xe6db99e5), 11); /* 46 */
150+
c = d + ROT_LEFT((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16); /* 47 */
151+
b = c + ROT_LEFT((b + H(c, d, a) + X[ 2] + 0xc4ac5665), 23); /* 48 */
152+
153+
/* round 4 */
154+
a = b + ROT_LEFT((a + I(b, c, d) + X[ 0] + 0xf4292244), 6); /* 49 */
155+
d = a + ROT_LEFT((d + I(a, b, c) + X[ 7] + 0x432aff97), 10); /* 50 */
156+
c = d + ROT_LEFT((c + I(d, a, b) + X[14] + 0xab9423a7), 15); /* 51 */
157+
b = c + ROT_LEFT((b + I(c, d, a) + X[ 5] + 0xfc93a039), 21); /* 52 */
158+
a = b + ROT_LEFT((a + I(b, c, d) + X[12] + 0x655b59c3), 6); /* 53 */
159+
d = a + ROT_LEFT((d + I(a, b, c) + X[ 3] + 0x8f0ccc92), 10); /* 54 */
160+
c = d + ROT_LEFT((c + I(d, a, b) + X[10] + 0xffeff47d), 15); /* 55 */
161+
b = c + ROT_LEFT((b + I(c, d, a) + X[ 1] + 0x85845dd1), 21); /* 56 */
162+
a = b + ROT_LEFT((a + I(b, c, d) + X[ 8] + 0x6fa87e4f), 6); /* 57 */
163+
d = a + ROT_LEFT((d + I(a, b, c) + X[15] + 0xfe2ce6e0), 10); /* 58 */
164+
c = d + ROT_LEFT((c + I(d, a, b) + X[ 6] + 0xa3014314), 15); /* 59 */
165+
b = c + ROT_LEFT((b + I(c, d, a) + X[13] + 0x4e0811a1), 21); /* 60 */
166+
a = b + ROT_LEFT((a + I(b, c, d) + X[ 4] + 0xf7537e82), 6); /* 61 */
167+
d = a + ROT_LEFT((d + I(a, b, c) + X[11] + 0xbd3af235), 10); /* 62 */
168+
c = d + ROT_LEFT((c + I(d, a, b) + X[ 2] + 0x2ad7d2bb), 15); /* 63 */
169+
b = c + ROT_LEFT((b + I(c, d, a) + X[ 9] + 0xeb86d391), 21); /* 64 */
170+
171+
state[0] += a;
172+
state[1] += b;
173+
state[2] += c;
174+
state[3] += d;
175+
}
176+
177+
static int
178+
calculateDigestFromBuffer(unsigned8 *b, unsigned32 len, unsigned8 sum[16])
179+
{
180+
register unsigned32 i, j, k, newI;
181+
unsigned32 l;
182+
unsigned8 *input;
183+
register unsigned32 *wbp;
184+
unsigned32 workBuff[16], state[4];
185+
186+
l = len;
187+
188+
state[0] = 0x67452301;
189+
state[1] = 0xEFCDAB89;
190+
state[2] = 0x98BADCFE;
191+
state[3] = 0x10325476;
192+
193+
if ((input = createPaddedCopyWithLength(b, &l)) == NULL)
194+
return 0;
195+
196+
for (i = 0;;) {
197+
if ((newI = i + 16 * 4) > l)
198+
break;
199+
k = i + 3;
200+
for (j = 0; j < 16; j++) {
201+
wbp = (workBuff + j);
202+
*wbp = input[k--];
203+
*wbp <<= 8;
204+
*wbp |= input[k--];
205+
*wbp <<= 8;
206+
*wbp |= input[k--];
207+
*wbp <<= 8;
208+
*wbp |= input[k];
209+
k += 7;
210+
}
211+
doTheRounds(workBuff, state);
212+
i = newI;
213+
}
214+
free(input);
215+
216+
j = 0;
217+
for (i = 0; i < 4; i++) {
218+
k = state[i];
219+
sum[j++] = (k & 0xFF);
220+
k >>= 8;
221+
sum[j++] = (k & 0xFF);
222+
k >>= 8;
223+
sum[j++] = (k & 0xFF);
224+
k >>= 8;
225+
sum[j++] = (k & 0xFF);
226+
}
227+
return 1;
228+
}
229+
230+
static void
231+
bytesToHex(unsigned8 b[16], char *s)
232+
{
233+
static char *hex = "0123456789abcdef";
234+
int q, w;
235+
236+
for (q = 0, w = 0; q < 16; q++) {
237+
s[w++] = hex[(b[q] >> 4) & 0x0F];
238+
s[w++] = hex[b[q] & 0x0F];
239+
}
240+
s[w] = '\0';
241+
}
242+
243+
/*
244+
* PUBLIC FUNCTIONS
245+
*/
246+
247+
/*
248+
* md5_hash
249+
*
250+
* Calculates the MD5 sum of the bytes in a buffer.
251+
*
252+
* SYNOPSIS #include "md5.h"
253+
* int md5_hash(const void *buff, size_t len, char *hexsum)
254+
*
255+
* INPUT buff the buffer containing the bytes that you want
256+
* the MD5 sum of.
257+
* len number of bytes in the buffer.
258+
*
259+
* OUTPUT hexsum the MD5 sum as a '\0'-terminated string of
260+
* hexadecimal digits. an MD5 sum is 16 bytes long.
261+
* each byte is represented by two heaxadecimal
262+
* characters. you thus need to provide an array
263+
* of 33 characters, including the trailing '\0'.
264+
*
265+
* RETURNS 0 on failure (out of memory for internal buffers) or
266+
* non-zero on success.
267+
*
268+
* STANDARDS MD5 is described in RFC 1321.
269+
*
270+
* AUTHOR Sverre H. Huseby <sverrehu@online.no>
271+
*
272+
*/
273+
bool
274+
md5_hash(const void *buff, size_t len, char *hexsum)
275+
{
276+
unsigned8 sum[16];
277+
278+
if (!calculateDigestFromBuffer((unsigned8 *) buff, len, sum))
279+
return false;
280+
281+
bytesToHex(sum, hexsum);
282+
return true;
283+
}
284+
285+
286+
287+
/*
288+
* puts md5(username+passwd) in buf provided buflen is at least 36 bytes
289+
* returns 1 on success, 0 on any kind of failure and sets errno accordingly
290+
*/
291+
bool EncryptMD5(const char *passwd, const char *salt, char *buf)
292+
{
293+
char crypt_buf[128];
294+
295+
if (strlen(salt) + strlen(passwd) > 127)
296+
return false;
297+
298+
strcpy(buf, "md5");
299+
memset(crypt_buf, 0, 128);
300+
sprintf(crypt_buf,"%s%s", salt, passwd);
301+
302+
return md5_hash(crypt_buf, strlen(crypt_buf), buf + 3);
303+
}

src/include/libpq/md5.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* md5.h
4+
* Interface to hba.c
5+
*
6+
*
7+
*-------------------------------------------------------------------------
8+
*/
9+
#ifndef PG_MD5_H
10+
#define PG_MD5_H
11+
12+
extern bool md5_hash(const void *buff, size_t len, char *hexsum);
13+
extern bool CheckMD5Pwd(char *passwd, char *storedpwd, char *seed);
14+
extern bool EncryptMD5(const char *passwd, const char *salt, char *buf);
15+
16+
#define MD5_PASSWD_LEN 35
17+
18+
#define isMD5(passwd) (strncmp((passwd),"md5",3) == 0 && \
19+
strlen(passwd) == MD5_PASSWD_LEN)
20+
21+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy