~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to win32/md5crypt.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   +----------------------------------------------------------------------+
 
3
   | PHP Version 5                                                        |
 
4
   +----------------------------------------------------------------------+
 
5
   | Copyright (c) 1997-2004 The PHP Group                                |
 
6
   +----------------------------------------------------------------------+
 
7
   | This source file is subject to version 3.0 of the PHP license,       |
 
8
   | that is bundled with this package in the file LICENSE, and is        |
 
9
   | available through the world-wide-web at the following url:           |
 
10
   | http://www.php.net/license/3_0.txt.                                  |
 
11
   | If you did not receive a copy of the PHP license and are unable to   |
 
12
   | obtain it through the world-wide-web, please send a note to          |
 
13
   | license@php.net so we can mail you a copy immediately.               |
 
14
   +----------------------------------------------------------------------+
 
15
   | Author: Edin Kadribasic                                              |
 
16
   +----------------------------------------------------------------------+
 
17
 */
 
18
 
 
19
/* $Id: md5crypt.c,v 1.5 2004/01/08 08:18:21 andi Exp $ */
 
20
 
 
21
/*
 
22
 * ----------------------------------------------------------------------------
 
23
 * "THE BEER-WARE LICENSE" (Revision 42):
 
24
 * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
 
25
 * can do whatever you want with this stuff. If we meet some day, and you think
 
26
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 
27
 * ----------------------------------------------------------------------------
 
28
 *
 
29
 * from FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp
 
30
 * via OpenBSD: md5crypt.c,v 1.9 1997/07/23 20:58:27 kstailey Exp
 
31
 * via NetBSD: md5crypt.c,v 1.4.2.1 2002/01/22 19:31:59 he Exp
 
32
 *
 
33
 */
 
34
 
 
35
#include "php.h"
 
36
#include "ext/standard/md5.h"
 
37
#include "md5crypt.h"
 
38
 
 
39
static unsigned char itoa64[] =         /* 0 ... 63 => ascii - 64 */
 
40
        "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
41
 
 
42
static void to64(char *, php_uint32, int);
 
43
 
 
44
static void
 
45
to64(char *s, php_uint32 v, int n)
 
46
{
 
47
 
 
48
        while (--n >= 0) {
 
49
                *s++ = itoa64[v & 0x3f];
 
50
                v >>= 6;
 
51
        }
 
52
}
 
53
 
 
54
/*
 
55
 * MD5 password encryption.
 
56
 */
 
57
char *
 
58
md5_crypt(const char *pw, const char *salt)
 
59
{
 
60
        static char passwd[120], *p;
 
61
        const char *sp, *ep;
 
62
        unsigned char final[16];
 
63
        unsigned int i, sl, pwl;
 
64
        PHP_MD5_CTX     ctx, ctx1;
 
65
        php_uint32 l;
 
66
        int pl;
 
67
        
 
68
        pwl = strlen(pw);
 
69
        
 
70
        /* Refine the salt first */
 
71
        sp = salt;
 
72
 
 
73
        /* If it starts with the magic string, then skip that */
 
74
        if (strncmp(sp, MD5_MAGIC, MD5_MAGIC_LEN) == 0)
 
75
                sp += MD5_MAGIC_LEN;
 
76
 
 
77
        /* It stops at the first '$', max 8 chars */
 
78
        for (ep = sp; *ep != '\0' && *ep != '$' && ep < (sp + 8); ep++)
 
79
                continue;
 
80
 
 
81
        /* get the length of the true salt */
 
82
        sl = ep - sp;
 
83
 
 
84
        PHP_MD5Init(&ctx);
 
85
 
 
86
        /* The password first, since that is what is most unknown */
 
87
        PHP_MD5Update(&ctx, (const unsigned char *)pw, pwl);
 
88
 
 
89
        /* Then our magic string */
 
90
        PHP_MD5Update(&ctx, (const unsigned char *)MD5_MAGIC, MD5_MAGIC_LEN);
 
91
 
 
92
        /* Then the raw salt */
 
93
        PHP_MD5Update(&ctx, (const unsigned char *)sp, sl);
 
94
 
 
95
        /* Then just as many characters of the MD5(pw,salt,pw) */
 
96
        PHP_MD5Init(&ctx1);
 
97
        PHP_MD5Update(&ctx1, (const unsigned char *)pw, pwl);
 
98
        PHP_MD5Update(&ctx1, (const unsigned char *)sp, sl);
 
99
        PHP_MD5Update(&ctx1, (const unsigned char *)pw, pwl);
 
100
        PHP_MD5Final(final, &ctx1);
 
101
 
 
102
        for (pl = pwl; pl > 0; pl -= 16)
 
103
                PHP_MD5Update(&ctx, final, (unsigned int)(pl > 16 ? 16 : pl));
 
104
 
 
105
        /* Don't leave anything around in vm they could use. */
 
106
        memset(final, 0, sizeof(final));
 
107
 
 
108
        /* Then something really weird... */
 
109
        for (i = pwl; i != 0; i >>= 1)
 
110
                if ((i & 1) != 0)
 
111
                    PHP_MD5Update(&ctx, final, 1);
 
112
                else
 
113
                    PHP_MD5Update(&ctx, (const unsigned char *)pw, 1);
 
114
 
 
115
        /* Now make the output string */
 
116
        memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN);
 
117
        strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1);
 
118
        strcat(passwd, "$");
 
119
 
 
120
        PHP_MD5Final(final, &ctx);
 
121
 
 
122
        /*
 
123
         * And now, just to make sure things don't run too fast. On a 60 MHz
 
124
         * Pentium this takes 34 msec, so you would need 30 seconds to build
 
125
         * a 1000 entry dictionary...
 
126
         */
 
127
        for (i = 0; i < 1000; i++) {
 
128
                PHP_MD5Init(&ctx1);
 
129
 
 
130
                if ((i & 1) != 0)
 
131
                        PHP_MD5Update(&ctx1, (const unsigned char *)pw, pwl);
 
132
                else
 
133
                        PHP_MD5Update(&ctx1, final, 16);
 
134
 
 
135
                if ((i % 3) != 0)
 
136
                        PHP_MD5Update(&ctx1, (const unsigned char *)sp, sl);
 
137
 
 
138
                if ((i % 7) != 0)
 
139
                        PHP_MD5Update(&ctx1, (const unsigned char *)pw, pwl);
 
140
 
 
141
                if ((i & 1) != 0)
 
142
                        PHP_MD5Update(&ctx1, final, 16);
 
143
                else
 
144
                        PHP_MD5Update(&ctx1, (const unsigned char *)pw, pwl);
 
145
 
 
146
                PHP_MD5Final(final, &ctx1);
 
147
        }
 
148
 
 
149
        p = passwd + sl + MD5_MAGIC_LEN + 1;
 
150
 
 
151
        l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
 
152
        l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
 
153
        l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
 
154
        l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
 
155
        l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
 
156
        l =                    final[11]                ; to64(p,l,2); p += 2;
 
157
        *p = '\0';
 
158
 
 
159
        /* Don't leave anything around in vm they could use. */
 
160
        memset(final, 0, sizeof(final));
 
161
        return (passwd);
 
162
}
 
163