|
41 | 41 |
|
42 | 42 | #include "php_crypt_r.h"
|
43 | 43 | #include "crypt_freesec.h"
|
44 |
| - |
45 |
| -#if !PHP_WIN32 |
46 | 44 | #include "ext/standard/md5.h"
|
47 |
| -#endif |
48 | 45 |
|
49 | 46 | #ifdef ZTS
|
50 | 47 | MUTEX_T php_crypt_extended_init_lock;
|
51 | 48 | #endif
|
52 | 49 |
|
53 |
| -/* TODO: enable it when enabling vista/2k8 mode in tsrm */ |
54 |
| -#if 0 |
55 |
| -CONDITION_VARIABLE initialized; |
56 |
| -#endif |
57 |
| - |
58 | 50 | void php_init_crypt_r()
|
59 | 51 | {
|
60 | 52 | #ifdef ZTS
|
@@ -87,210 +79,22 @@ void _crypt_extended_init_r(void)
|
87 | 79 | #endif
|
88 | 80 | }
|
89 | 81 |
|
90 |
| -/* MD% crypt implementation using the windows CryptoApi */ |
| 82 | +/* MD5 crypt implementation using the windows CryptoApi */ |
91 | 83 | #define MD5_MAGIC "$1$"
|
92 | 84 | #define MD5_MAGIC_LEN 3
|
93 | 85 |
|
94 | 86 | static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
|
95 | 87 | "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
96 | 88 |
|
97 |
| -static void |
98 |
| -to64(char *s, int32_t v, int n) |
| 89 | +/* Convert a 16/32 bit integer to Base64 string representation */ |
| 90 | +static void to64(char *s, int32_t v, int n) |
99 | 91 | {
|
100 | 92 | while (--n >= 0) {
|
101 | 93 | *s++ = itoa64[v & 0x3f];
|
102 | 94 | v >>= 6;
|
103 | 95 | }
|
104 | 96 | }
|
105 | 97 |
|
106 |
| -#ifdef PHP_WIN32 |
107 |
| -char * php_md5_crypt_r(const char *pw, const char *salt, char *out) { |
108 |
| - HCRYPTPROV hCryptProv; |
109 |
| - HCRYPTHASH ctx, ctx1; |
110 |
| - DWORD i, pwl, sl; |
111 |
| - const BYTE magic_md5[4] = "$1$"; |
112 |
| - const DWORD magic_md5_len = 3; |
113 |
| - DWORD dwHashLen; |
114 |
| - int pl; |
115 |
| - __int32 l; |
116 |
| - const char *sp = salt; |
117 |
| - const char *ep = salt; |
118 |
| - char *p = NULL; |
119 |
| - char *passwd = out; |
120 |
| - unsigned char final[16]; |
121 |
| - |
122 |
| - /* Acquire a cryptographic provider context handle. */ |
123 |
| - if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { |
124 |
| - return NULL; |
125 |
| - } |
126 |
| - |
127 |
| - pwl = (DWORD) strlen(pw); |
128 |
| - |
129 |
| - /* Refine the salt first */ |
130 |
| - sp = salt; |
131 |
| - |
132 |
| - /* If it starts with the magic string, then skip that */ |
133 |
| - if (strncmp(sp, MD5_MAGIC, MD5_MAGIC_LEN) == 0) { |
134 |
| - sp += MD5_MAGIC_LEN; |
135 |
| - } |
136 |
| - |
137 |
| - /* It stops at the first '$', max 8 chars */ |
138 |
| - for (ep = sp; *ep != '\0' && *ep != '$' && ep < (sp + 8); ep++); |
139 |
| - |
140 |
| - /* get the length of the true salt */ |
141 |
| - sl = (DWORD)(ep - sp); |
142 |
| - |
143 |
| - /* Create an empty hash object. */ |
144 |
| - if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx)) { |
145 |
| - goto _destroyProv; |
146 |
| - } |
147 |
| - |
148 |
| - /* The password first, since that is what is most unknown */ |
149 |
| - if(!CryptHashData(ctx, (BYTE *)pw, pwl, 0)) { |
150 |
| - goto _destroyCtx0; |
151 |
| - } |
152 |
| - |
153 |
| - /* Then our magic string */ |
154 |
| - if(!CryptHashData(ctx, magic_md5, magic_md5_len, 0)) { |
155 |
| - goto _destroyCtx0; |
156 |
| - } |
157 |
| - |
158 |
| - /* Then the raw salt */ |
159 |
| - if(!CryptHashData( ctx, (BYTE *)sp, sl, 0)) { |
160 |
| - goto _destroyCtx0; |
161 |
| - } |
162 |
| - |
163 |
| - /* MD5(pw,salt,pw), valid. */ |
164 |
| - /* Then just as many characters of the MD5(pw,salt,pw) */ |
165 |
| - if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx1)) { |
166 |
| - goto _destroyCtx0; |
167 |
| - } |
168 |
| - if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) { |
169 |
| - goto _destroyCtx1; |
170 |
| - } |
171 |
| - if(!CryptHashData(ctx1, (BYTE *)sp, sl, 0)) { |
172 |
| - goto _destroyCtx1; |
173 |
| - } |
174 |
| - if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) { |
175 |
| - goto _destroyCtx1; |
176 |
| - } |
177 |
| - |
178 |
| - dwHashLen = 16; |
179 |
| - CryptGetHashParam(ctx1, HP_HASHVAL, final, &dwHashLen, 0); |
180 |
| - /* MD5(pw,salt,pw). Valid. */ |
181 |
| - |
182 |
| - for (pl = pwl; pl > 0; pl -= 16) { |
183 |
| - CryptHashData(ctx, final, (DWORD)(pl > 16 ? 16 : pl), 0); |
184 |
| - } |
185 |
| - |
186 |
| - /* Don't leave anything around in vm they could use. */ |
187 |
| - ZEND_SECURE_ZERO(final, sizeof(final)); |
188 |
| - |
189 |
| - /* Then something really weird... */ |
190 |
| - for (i = pwl; i != 0; i >>= 1) { |
191 |
| - if ((i & 1) != 0) { |
192 |
| - CryptHashData(ctx, (const BYTE *)final, 1, 0); |
193 |
| - } else { |
194 |
| - CryptHashData(ctx, (const BYTE *)pw, 1, 0); |
195 |
| - } |
196 |
| - } |
197 |
| - |
198 |
| - memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN); |
199 |
| - |
200 |
| - if (strncpy_s(passwd + MD5_MAGIC_LEN, MD5_HASH_MAX_LEN - MD5_MAGIC_LEN, sp, sl + 1) != 0) { |
201 |
| - goto _destroyCtx1; |
202 |
| - } |
203 |
| - passwd[MD5_MAGIC_LEN + sl] = '\0'; |
204 |
| - strcat_s(passwd, MD5_HASH_MAX_LEN, "$"); |
205 |
| - |
206 |
| - dwHashLen = 16; |
207 |
| - |
208 |
| - /* Fetch the ctx hash value */ |
209 |
| - CryptGetHashParam(ctx, HP_HASHVAL, final, &dwHashLen, 0); |
210 |
| - |
211 |
| - for (i = 0; i < 1000; i++) { |
212 |
| - if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx1)) { |
213 |
| - goto _destroyCtx1; |
214 |
| - } |
215 |
| - |
216 |
| - if ((i & 1) != 0) { |
217 |
| - if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) { |
218 |
| - goto _destroyCtx1; |
219 |
| - } |
220 |
| - } else { |
221 |
| - if(!CryptHashData(ctx1, (BYTE *)final, 16, 0)) { |
222 |
| - goto _destroyCtx1; |
223 |
| - } |
224 |
| - } |
225 |
| - |
226 |
| - if ((i % 3) != 0) { |
227 |
| - if(!CryptHashData(ctx1, (BYTE *)sp, sl, 0)) { |
228 |
| - goto _destroyCtx1; |
229 |
| - } |
230 |
| - } |
231 |
| - |
232 |
| - if ((i % 7) != 0) { |
233 |
| - if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) { |
234 |
| - goto _destroyCtx1; |
235 |
| - } |
236 |
| - } |
237 |
| - |
238 |
| - if ((i & 1) != 0) { |
239 |
| - if(!CryptHashData(ctx1, (BYTE *)final, 16, 0)) { |
240 |
| - goto _destroyCtx1; |
241 |
| - } |
242 |
| - } else { |
243 |
| - if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) { |
244 |
| - goto _destroyCtx1; |
245 |
| - } |
246 |
| - } |
247 |
| - |
248 |
| - /* Fetch the ctx hash value */ |
249 |
| - dwHashLen = 16; |
250 |
| - CryptGetHashParam(ctx1, HP_HASHVAL, final, &dwHashLen, 0); |
251 |
| - if(!(CryptDestroyHash(ctx1))) { |
252 |
| - goto _destroyCtx0; |
253 |
| - } |
254 |
| - } |
255 |
| - |
256 |
| - ctx1 = (HCRYPTHASH) NULL; |
257 |
| - |
258 |
| - p = passwd + sl + MD5_MAGIC_LEN + 1; |
259 |
| - |
260 |
| - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; |
261 |
| - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; |
262 |
| - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; |
263 |
| - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; |
264 |
| - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; |
265 |
| - l = final[11]; to64(p,l,2); p += 2; |
266 |
| - |
267 |
| - *p = '\0'; |
268 |
| - |
269 |
| - ZEND_SECURE_ZERO(final, sizeof(final)); |
270 |
| - |
271 |
| - |
272 |
| -_destroyCtx1: |
273 |
| - if (ctx1) { |
274 |
| - if (!CryptDestroyHash(ctx1)) { |
275 |
| - |
276 |
| - } |
277 |
| - } |
278 |
| - |
279 |
| -_destroyCtx0: |
280 |
| - CryptDestroyHash(ctx); |
281 |
| - |
282 |
| -_destroyProv: |
283 |
| - /* Release the provider handle.*/ |
284 |
| - if(hCryptProv) { |
285 |
| - if(!(CryptReleaseContext(hCryptProv, 0))) { |
286 |
| - return NULL; |
287 |
| - } |
288 |
| - } |
289 |
| - |
290 |
| - return out; |
291 |
| -} |
292 |
| -#else |
293 |
| - |
294 | 98 | /*
|
295 | 99 | * MD5 password encryption.
|
296 | 100 | */
|
@@ -398,7 +202,3 @@ char * php_md5_crypt_r(const char *pw, const char *salt, char *out)
|
398 | 202 | ZEND_SECURE_ZERO(final, sizeof(final));
|
399 | 203 | return (passwd);
|
400 | 204 | }
|
401 |
| - |
402 |
| -#undef MD5_MAGIC |
403 |
| -#undef MD5_MAGIC_LEN |
404 |
| -#endif |
0 commit comments