Skip to content

Commit 0f4afbb

Browse files
committed
extend libxcrypt bindings
1 parent cd232ed commit 0f4afbb

File tree

5 files changed

+166
-19
lines changed

5 files changed

+166
-19
lines changed

ext/standard/basic_functions.stub.php

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -383,18 +383,49 @@
383383
* @cvalue PHP_MAX_SALT_LEN
384384
*/
385385
const CRYPT_SALT_LENGTH = UNKNOWN;
386-
/** @var int */
387-
const CRYPT_STD_DES = 1;
388-
/** @var int */
389-
const CRYPT_EXT_DES = 1;
390-
/** @var int */
391-
const CRYPT_MD5 = 1;
392-
/** @var int */
393-
const CRYPT_BLOWFISH = 1;
394-
/** @var int */
395-
const CRYPT_SHA256 = 1;
396-
/** @var int */
397-
const CRYPT_SHA512 = 1;
386+
/** @var string */
387+
const CRYPT_STD_DES = '';
388+
/** @var string */
389+
const CRYPT_EXT_DES = '_';
390+
/** @var string */
391+
const CRYPT_MD5 = '$1$';
392+
/** @var string */
393+
const CRYPT_BLOWFISH = '$2y$';
394+
/** @var string */
395+
const CRYPT_SHA256 = '$5$';
396+
/** @var string */
397+
const CRYPT_SHA512 = '$6$';
398+
/** @var string */
399+
const CRYPT_SCRYPT = '$7$';
400+
/** @var string */
401+
const CRYPT_GOST_YESCRYPT = '$gy$';
402+
/** @var string */
403+
const CRYPT_YESCRYPT = '$y$';
404+
/**
405+
* @var int
406+
* @cvalue CRYPT_SALT_OK
407+
*/
408+
const CRYPT_SALT_OK = UNKNOWN;
409+
/**
410+
* @var int
411+
* @cvalue CRYPT_SALT_INVALID
412+
*/
413+
const CRYPT_SALT_INVALID = UNKNOWN;
414+
/**
415+
* @var int
416+
* @cvalue CRYPT_SALT_METHOD_DISABLED
417+
*/
418+
const CRYPT_SALT_METHOD_DISABLED = UNKNOWN;
419+
/**
420+
* @var int
421+
* @cvalue CRYPT_SALT_METHOD_LEGACY
422+
*/
423+
const CRYPT_SALT_METHOD_LEGACY = UNKNOWN;
424+
/**
425+
* @var int
426+
* @cvalue CRYPT_SALT_TOO_CHEAP
427+
*/
428+
const CRYPT_SALT_TOO_CHEAP = UNKNOWN;
398429

399430
/* dns.c */
400431

@@ -2111,6 +2142,12 @@ function crc32(string $string): int {}
21112142
/** @refcount 1 */
21122143
function crypt(#[\SensitiveParameter] string $string, string $salt): string {}
21132144

2145+
function crypt_gensalt(?string $salt = null, int $count = 0): ?string {}
2146+
2147+
function crypt_preferred_method(): ?string {}
2148+
2149+
function crypt_checksalt(string $salt): int {}
2150+
21142151
/* datetime.c */
21152152

21162153
#ifdef HAVE_STRPTIME

ext/standard/basic_functions_arginfo.h

Lines changed: 33 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/standard/crypt.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,53 @@ PHP_FUNCTION(crypt)
218218
RETURN_STR(result);
219219
}
220220
/* }}} */
221+
222+
/* {{{ Generates a salt for algo */
223+
PHP_FUNCTION(crypt_gensalt)
224+
{
225+
char salt[CRYPT_GENSALT_OUTPUT_SIZE + 1];
226+
char *prefix = NULL;
227+
size_t prefix_len = 0;
228+
zend_long count = 0;
229+
230+
ZEND_PARSE_PARAMETERS_START(0, 2)
231+
Z_PARAM_OPTIONAL
232+
Z_PARAM_STRING(prefix, prefix_len)
233+
Z_PARAM_LONG(count)
234+
ZEND_PARSE_PARAMETERS_END();
235+
236+
if (crypt_gensalt_rn(prefix, (unsigned long)count, NULL, 0, salt, CRYPT_GENSALT_OUTPUT_SIZE)) {
237+
RETURN_STRING(salt);
238+
}
239+
RETURN_NULL();
240+
}
241+
/* }}} */
242+
243+
/* {{{ Get preferred hasing method prefix */
244+
PHP_FUNCTION(crypt_preferred_method)
245+
{
246+
const char *prefix;
247+
248+
ZEND_PARSE_PARAMETERS_NONE();
249+
250+
prefix = crypt_preferred_method();
251+
if (prefix) {
252+
RETURN_STRING(prefix);
253+
}
254+
RETURN_NULL();
255+
}
256+
/* }}} */
257+
258+
/* {{{ Determine whether the user's passphrase should be re-hashed using the currently preferred hashing method */
259+
PHP_FUNCTION(crypt_checksalt)
260+
{
261+
char *prefix;
262+
size_t prefix_len;
263+
264+
ZEND_PARSE_PARAMETERS_START(1, 1)
265+
Z_PARAM_STRING(prefix, prefix_len)
266+
ZEND_PARSE_PARAMETERS_END();
267+
268+
RETURN_LONG(crypt_checksalt(prefix));
269+
}
270+
/* }}} */

ext/standard/php_crypt.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,24 @@
1919
#ifndef PHP_CRYPT_H
2020
#define PHP_CRYPT_H
2121

22+
#ifdef HAVE_CRYPT_H
23+
# if defined(CRYPT_R_GNU_SOURCE) && !defined(_GNU_SOURCE)
24+
# define _GNU_SOURCE
25+
# endif
26+
# include <crypt.h>
27+
#endif
28+
2229
PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, bool quiet);
2330
PHP_MINIT_FUNCTION(crypt);
2431
PHP_MSHUTDOWN_FUNCTION(crypt);
2532
PHP_RINIT_FUNCTION(crypt);
2633

34+
#ifdef CRYPT_GENSALT_OUTPUT_SIZE
35+
/* use salt length from library (192) */
36+
#define PHP_MAX_SALT_LEN CRYPT_GENSALT_OUTPUT_SIZE
37+
#else
2738
/* sha512 crypt has the maximal salt length of 123 characters */
2839
#define PHP_MAX_SALT_LEN 123
40+
#endif
2941

3042
#endif
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Test crypt compatibility with password_hash
3+
--FILE--
4+
<?php
5+
$secret = 'mysecret';
6+
7+
/* generate with password_hash, check with both */
8+
$h = password_hash($secret, PASSWORD_BCRYPT);
9+
var_dump($h, password_verify($secret, $h), $h===crypt($secret, $h));
10+
11+
/* generate with crypt, check with both */
12+
$h = crypt($secret, crypt_gensalt(CRYPT_BLOWFISH));
13+
var_dump($h, password_verify($secret, $h), $h===crypt($secret, $h));
14+
?>
15+
--EXPECTF--
16+
string(60) "$2y$%s$%s"
17+
bool(true)
18+
bool(true)
19+
string(60) "$2y$%s$%s"
20+
bool(true)
21+
bool(true)
22+

0 commit comments

Comments
 (0)