Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions ext/standard/basic_functions.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,49 @@
const CRYPT_SHA256 = 1;
/** @var int */
const CRYPT_SHA512 = 1;
/** @var string */
const CRYPT_PREFIX_STD_DES = '';
/** @var string */
const CRYPT_PREFIX_EXT_DES = '_';
/** @var string */
const CRYPT_PREFIX_MD5 = '$1$';
/** @var string */
const CRYPT_PREFIX_BLOWFISH = '$2y$';
/** @var string */
const CRYPT_PREFIX_SHA256 = '$5$';
/** @var string */
const CRYPT_PREFIX_SHA512 = '$6$';
/** @var string */
const CRYPT_PREFIX_SCRYPT = '$7$';
/** @var string */
const CRYPT_PREFIX_GOST_YESCRYPT = '$gy$';
/** @var string */
const CRYPT_PREFIX_YESCRYPT = '$y$';
/**
* @var int
* @cvalue CRYPT_SALT_OK
*/
const CRYPT_SALT_OK = UNKNOWN;
/**
* @var int
* @cvalue CRYPT_SALT_INVALID
*/
const CRYPT_SALT_INVALID = UNKNOWN;
/**
* @var int
* @cvalue CRYPT_SALT_METHOD_DISABLED
*/
const CRYPT_SALT_METHOD_DISABLED = UNKNOWN;
/**
* @var int
* @cvalue CRYPT_SALT_METHOD_LEGACY
*/
const CRYPT_SALT_METHOD_LEGACY = UNKNOWN;
/**
* @var int
* @cvalue CRYPT_SALT_TOO_CHEAP
*/
const CRYPT_SALT_TOO_CHEAP = UNKNOWN;

/* dns.c */

Expand Down Expand Up @@ -2111,6 +2154,12 @@ function crc32(string $string): int {}
/** @refcount 1 */
function crypt(#[\SensitiveParameter] string $string, string $salt): string {}

function crypt_gensalt(?string $salt = null, int $count = 0): ?string {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first parameter should likely be called $prefix instead of $salt.


function crypt_preferred_method(): ?string {}

function crypt_checksalt(string $salt): int {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here the parameter should probably be called $settings. Also affects the C code, which uses prefix.


/* datetime.c */

#ifdef HAVE_STRPTIME
Expand Down
34 changes: 33 additions & 1 deletion ext/standard/basic_functions_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions ext/standard/crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,53 @@ PHP_FUNCTION(crypt)
RETURN_STR(result);
}
/* }}} */

/* {{{ Generates a salt for algo */
PHP_FUNCTION(crypt_gensalt)
{
char salt[CRYPT_GENSALT_OUTPUT_SIZE + 1];
char *prefix = NULL;
size_t prefix_len = 0;
zend_long count = 0;

ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_STRING(prefix, prefix_len)
Z_PARAM_LONG(count)
ZEND_PARSE_PARAMETERS_END();

if (crypt_gensalt_rn(prefix, (unsigned long)count, NULL, 0, salt, CRYPT_GENSALT_OUTPUT_SIZE)) {
RETURN_STRING(salt);
}
RETURN_NULL();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably throw an Exception, similarly to how password_hash() will either succeed or throw.

}
/* }}} */

/* {{{ Get preferred hasing method prefix */
PHP_FUNCTION(crypt_preferred_method)
{
const char *prefix;

ZEND_PARSE_PARAMETERS_NONE();

prefix = crypt_preferred_method();
if (prefix) {
RETURN_STRING(prefix);
}
RETURN_NULL();
}
/* }}} */

/* {{{ Determine whether the user's passphrase should be re-hashed using the currently preferred hashing method */
PHP_FUNCTION(crypt_checksalt)
{
char *prefix;
size_t prefix_len;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(prefix, prefix_len)
ZEND_PARSE_PARAMETERS_END();

RETURN_LONG(crypt_checksalt(prefix));
}
/* }}} */
12 changes: 12 additions & 0 deletions ext/standard/php_crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,24 @@
#ifndef PHP_CRYPT_H
#define PHP_CRYPT_H

#ifdef HAVE_CRYPT_H
# if defined(CRYPT_R_GNU_SOURCE) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE
# endif
# include <crypt.h>
#endif

PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, bool quiet);
PHP_MINIT_FUNCTION(crypt);
PHP_MSHUTDOWN_FUNCTION(crypt);
PHP_RINIT_FUNCTION(crypt);

#ifdef CRYPT_GENSALT_OUTPUT_SIZE
/* use salt length from library (192) */
#define PHP_MAX_SALT_LEN CRYPT_GENSALT_OUTPUT_SIZE
#else
/* sha512 crypt has the maximal salt length of 123 characters */
#define PHP_MAX_SALT_LEN 123
#endif

#endif
22 changes: 22 additions & 0 deletions ext/standard/tests/crypt/password_compat.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Test crypt compatibility with password_hash
--FILE--
<?php
$secret = 'mysecret';

/* generate with password_hash, check with both */
$h = password_hash($secret, PASSWORD_BCRYPT);
var_dump($h, password_verify($secret, $h), $h===crypt($secret, $h));

/* generate with crypt, check with both */
$h = crypt($secret, crypt_gensalt(CRYPT_PREFIX_BLOWFISH));
var_dump($h, password_verify($secret, $h), $h===crypt($secret, $h));
?>
--EXPECTF--
string(60) "$2y$%s$%s"
bool(true)
bool(true)
string(60) "$2y$%s$%s"
bool(true)
bool(true)

Loading