mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
Merge branch 'PHP-7.0'
This commit is contained in:
commit
e933da9028
3 changed files with 166 additions and 99 deletions
|
@ -1006,6 +1006,22 @@ static void php_openssl_dispose_config(struct php_x509_request * req) /* {{{ */
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_OPENSSL_RAND_ADD_TIME() ((void) 0)
|
||||
#else
|
||||
#define PHP_OPENSSL_RAND_ADD_TIME() php_openssl_rand_add_timeval()
|
||||
|
||||
static inline void php_openssl_rand_add_timeval() /* {{{ */
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
RAND_add(&tv, sizeof(tv), 0.0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#endif
|
||||
|
||||
static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded) /* {{{ */
|
||||
{
|
||||
char buffer[MAXPATHLEN];
|
||||
|
@ -1048,6 +1064,7 @@ static int php_openssl_write_rand_file(const char * file, int egdsocket, int see
|
|||
if (file == NULL) {
|
||||
file = RAND_file_name(buffer, sizeof(buffer));
|
||||
}
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
if (file == NULL || !RAND_write_file(file)) {
|
||||
php_error_docref(NULL, E_WARNING, "unable to write random state");
|
||||
return FAILURE;
|
||||
|
@ -3414,6 +3431,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
|||
RSA* rsaparam;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
||||
/* OpenSSL 1.0.2 deprecates RSA_generate_key */
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
rsaparam = (RSA*)RSA_generate_key(req->priv_key_bits, RSA_F4, NULL, NULL);
|
||||
#else
|
||||
{
|
||||
|
@ -3424,6 +3442,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
|||
return NULL;
|
||||
}
|
||||
rsaparam = RSA_new();
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
RSA_generate_key_ex(rsaparam, req->priv_key_bits, bne, NULL);
|
||||
BN_free(bne);
|
||||
}
|
||||
|
@ -3435,6 +3454,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
|||
break;
|
||||
#if !defined(NO_DSA)
|
||||
case OPENSSL_KEYTYPE_DSA:
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
{
|
||||
DSA *dsaparam = NULL;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
||||
|
@ -3457,6 +3477,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
|||
#endif
|
||||
#if !defined(NO_DH)
|
||||
case OPENSSL_KEYTYPE_DH:
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
{
|
||||
int codes = 0;
|
||||
DH *dhparam = NULL;
|
||||
|
@ -3570,6 +3591,46 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey)
|
|||
} \
|
||||
} while (0);
|
||||
|
||||
/* {{{ php_openssl_pkey_init_dsa */
|
||||
zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
|
||||
{
|
||||
if (!dsa->p || !dsa->q || !dsa->g) {
|
||||
return 0;
|
||||
}
|
||||
if (dsa->priv_key || dsa->pub_key) {
|
||||
return 1;
|
||||
}
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
if (!DSA_generate_key(dsa)) {
|
||||
return 0;
|
||||
}
|
||||
/* if BN_mod_exp return -1, then DSA_generate_key succeed for failed key
|
||||
* so we need to double check that public key is created */
|
||||
if (!dsa->pub_key || BN_is_zero(dsa->pub_key)) {
|
||||
return 0;
|
||||
}
|
||||
/* all good */
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_openssl_pkey_init_dh */
|
||||
zend_bool php_openssl_pkey_init_dh(DH *dh)
|
||||
{
|
||||
if (!dh->p || !dh->g) {
|
||||
return 0;
|
||||
}
|
||||
if (dh->pub_key) {
|
||||
return 1;
|
||||
}
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
if (!DH_generate_key(dh)) {
|
||||
return 0;
|
||||
}
|
||||
/* all good */
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource openssl_pkey_new([array configargs])
|
||||
Generates a new private key */
|
||||
|
@ -3622,10 +3683,7 @@ PHP_FUNCTION(openssl_pkey_new)
|
|||
OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, g);
|
||||
OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, priv_key);
|
||||
OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, pub_key);
|
||||
if (dsa->p && dsa->q && dsa->g) {
|
||||
if (!dsa->priv_key && !dsa->pub_key) {
|
||||
DSA_generate_key(dsa);
|
||||
}
|
||||
if (php_openssl_pkey_init_dsa(dsa)) {
|
||||
if (EVP_PKEY_assign_DSA(pkey, dsa)) {
|
||||
RETURN_RES(zend_register_resource(pkey, le_key));
|
||||
}
|
||||
|
@ -3645,11 +3703,11 @@ PHP_FUNCTION(openssl_pkey_new)
|
|||
OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, g);
|
||||
OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, priv_key);
|
||||
OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, pub_key);
|
||||
if (dh->p && dh->g &&
|
||||
(dh->pub_key || DH_generate_key(dh)) &&
|
||||
EVP_PKEY_assign_DH(pkey, dh)) {
|
||||
ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key));
|
||||
return;
|
||||
if (php_openssl_pkey_init_dh(dh)) {
|
||||
if (EVP_PKEY_assign_DH(pkey, dh)) {
|
||||
ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key));
|
||||
return;
|
||||
}
|
||||
}
|
||||
DH_free(dh);
|
||||
}
|
||||
|
@ -5511,7 +5569,7 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
|
|||
#else
|
||||
|
||||
PHP_OPENSSL_CHECK_LONG_TO_INT(buffer_length, length);
|
||||
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
if (RAND_bytes((unsigned char*)ZSTR_VAL(buffer), (int)buffer_length) <= 0) {
|
||||
zend_string_release(buffer);
|
||||
if (zstrong_result_returned) {
|
||||
|
|
24
ext/openssl/tests/bug72336.phpt
Normal file
24
ext/openssl/tests/bug72336.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Bug #72336 (openssl_pkey_new does not fail for invalid DSA params)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$p = '00f8000ae45b2dacb47dd977d58b719d097bdf07cb2c17660ad898518c08' .
|
||||
'1a61659a16daadfaa406a0a994c743df5eda07e36bd0adcad921b77432ff' .
|
||||
'24ccc31e782d647e66768122b578857e9293df78387dc8b44af2a4a3f305' .
|
||||
'1f236b1000a3e31da489c6681b0031f7ec37c2e1091bdb698e7660f135b6' .
|
||||
'996def90090303b7ad';
|
||||
|
||||
$q = '009b3734fc9f7a4a9d6437ec314e0a78c2889af64b';
|
||||
|
||||
$g = '00b320300a0bc55b8f0ec6edc218e2185250f38fbb8291db8a89227f6e41' .
|
||||
'00d47d6ccb9c7d42fc43280ecc2ed386e81ff65bc5d6a2ae78db7372f5dc' .
|
||||
'f780f4558e7ed3dd0c96a1b40727ac56c5165aed700a3b63997893a1fb21' .
|
||||
'4e882221f0dd9604820dc34e2725dd6901c93e0ca56f6d76d495c332edc5' .
|
||||
'b81747c4c447a941f3';
|
||||
|
||||
var_dump(openssl_pkey_new(array('dsa' => array('p' => $p, 'q' => $q, 'g' => $g))));
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
|
@ -1,16 +1,37 @@
|
|||
--TEST--
|
||||
openssl_error_string() tests
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) print "skip";
|
||||
//if (OPENSSL_VERSION_NUMBER < 0x10001001) die("skip OpenSSLv1.0.1 required");
|
||||
?>
|
||||
--XFAIL--
|
||||
ot ready baked yet, fails different ways on different envs
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
// helper function to dump openssl errors
|
||||
function dump_openssl_errors() {
|
||||
// helper function to check openssl errors
|
||||
function expect_openssl_errors($name, $expected_error_codes) {
|
||||
$expected_errors = array_fill_keys($expected_error_codes, false);
|
||||
while (($error_string = openssl_error_string()) !== false) {
|
||||
if (strlen($error_string) > 14) {
|
||||
$error_code = substr($error_string, 6, 8);
|
||||
if (isset($expected_errors[$error_code])) {
|
||||
$expected_errors[$error_code] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fail = false;
|
||||
foreach ($expected_errors as $error_code => $error_code_found) {
|
||||
if (!$error_code_found) {
|
||||
$fail = true;
|
||||
echo "$name: no error code $error_code\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fail) {
|
||||
echo "$name: ok\n";
|
||||
}
|
||||
}
|
||||
|
||||
// helper for debugging errors
|
||||
function dump_openssl_errors($name) {
|
||||
echo "\n$name\n";
|
||||
while (($error_string = openssl_error_string()) !== false) {
|
||||
var_dump($error_string);
|
||||
}
|
||||
|
@ -56,61 +77,59 @@ while (($enc_error_new = openssl_error_string()) !== false) {
|
|||
++$error_queue_size;
|
||||
}
|
||||
var_dump($error_queue_size);
|
||||
echo "\n";
|
||||
|
||||
// PKEY
|
||||
echo "PKEY errors\n";
|
||||
// file for pkey (file:///) fails when opennig (BIO_new_file)
|
||||
openssl_pkey_export_to_file("file://" . $invalid_file_for_read, $output_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_pkey_export_to_file("file://" . $invalid_file_for_read, $output_file);
|
||||
expect_openssl_errors('openssl_pkey_export_to_file opening', ['02001002', '2006D080']);
|
||||
// file or private pkey is not correct PEM - failing PEM_read_bio_PrivateKey
|
||||
openssl_pkey_export_to_file($csr_file, $output_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_pkey_export_to_file($csr_file, $output_file);
|
||||
expect_openssl_errors('openssl_pkey_export_to_file pem', ['0906D06C']);
|
||||
// file to export cannot be written
|
||||
openssl_pkey_export_to_file($private_key_file, $invalid_file_for_write);
|
||||
dump_openssl_errors();
|
||||
@openssl_pkey_export_to_file($private_key_file, $invalid_file_for_write);
|
||||
expect_openssl_errors('openssl_pkey_export_to_file write', ['2006D002', '09072007']);
|
||||
// succesful export
|
||||
openssl_pkey_export($private_key_file_with_pass, $out, 'wrong pwd');
|
||||
dump_openssl_errors();
|
||||
@openssl_pkey_export($private_key_file_with_pass, $out, 'wrong pwd');
|
||||
expect_openssl_errors('openssl_pkey_export', ['06065064', '0906A065']);
|
||||
// invalid x509 for getting public key
|
||||
openssl_pkey_get_public($private_key_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_pkey_get_public($private_key_file);
|
||||
expect_openssl_errors('openssl_pkey_get_public', ['0906D06C']);
|
||||
// private encrypt with unknown padding
|
||||
openssl_private_encrypt("data", $crypted, $private_key_file, 1000);
|
||||
dump_openssl_errors();
|
||||
@openssl_private_encrypt("data", $crypted, $private_key_file, 1000);
|
||||
expect_openssl_errors('openssl_private_encrypt', ['04066076']);
|
||||
// private decrypt with failed padding check
|
||||
openssl_private_decrypt("data", $crypted, $private_key_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_private_decrypt("data", $crypted, $private_key_file);
|
||||
expect_openssl_errors('openssl_private_decrypt', ['04065072']);
|
||||
// public encrypt and decrypt with failed padding check and padding
|
||||
openssl_public_encrypt("data", $crypted, $public_key_file, 1000);
|
||||
openssl_public_decrypt("data", $crypted, $public_key_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_public_encrypt("data", $crypted, $public_key_file, 1000);
|
||||
@openssl_public_decrypt("data", $crypted, $public_key_file);
|
||||
expect_openssl_errors('openssl_private_(en|de)crypt padding', ['0906D06C', '04068076', '0407006A', '04067072']);
|
||||
|
||||
// X509
|
||||
echo "X509 errors\n";
|
||||
// file for x509 (file:///) fails when opennig (BIO_new_file)
|
||||
openssl_x509_export_to_file("file://" . $invalid_file_for_read, $output_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_x509_export_to_file("file://" . $invalid_file_for_read, $output_file);
|
||||
expect_openssl_errors('openssl_x509_export_to_file open', ['02001002']);
|
||||
// file or str cert is not correct PEM - failing PEM_read_bio_X509 or PEM_ASN1_read_bio
|
||||
openssl_x509_export_to_file($csr_file, $output_file);
|
||||
dump_openssl_errors();
|
||||
@openssl_x509_export_to_file($csr_file, $output_file);
|
||||
expect_openssl_errors('openssl_x509_export_to_file pem', ['0906D06C']);
|
||||
// file to export cannot be written
|
||||
openssl_x509_export_to_file($crt_file, $invalid_file_for_write);
|
||||
dump_openssl_errors();
|
||||
@openssl_x509_export_to_file($crt_file, $invalid_file_for_write);
|
||||
expect_openssl_errors('openssl_x509_export_to_file write', ['2006D002']);
|
||||
// checking purpose fails because there is no such purpose 1000
|
||||
openssl_x509_checkpurpose($crt_file, 1000);
|
||||
dump_openssl_errors();
|
||||
// make sure that X509_STORE_add_lookup will not emmit any error (just PHP warning)
|
||||
openssl_x509_checkpurpose($crt_file, X509_PURPOSE_SSL_CLIENT, array( __DIR__ . "/cert.csr"));
|
||||
dump_openssl_errors();
|
||||
@openssl_x509_checkpurpose($crt_file, 1000);
|
||||
expect_openssl_errors('openssl_x509_checkpurpose purpose', ['0B086079']);
|
||||
|
||||
// CSR
|
||||
echo "CSR errors\n";
|
||||
// file for csr (file:///) fails when opennig (BIO_new_file)
|
||||
openssl_csr_get_subject("file://" . $invalid_file_for_read);
|
||||
dump_openssl_errors();
|
||||
@openssl_csr_get_subject("file://" . $invalid_file_for_read);
|
||||
expect_openssl_errors('openssl_csr_get_subject open', ['02001002', '2006D080', '20068079', '0906D06C']);
|
||||
// file or str csr is not correct PEM - failing PEM_read_bio_X509_REQ
|
||||
openssl_csr_get_subject($crt_file);
|
||||
dump_openssl_errors();
|
||||
@expect_openssl_errors('openssl_csr_get_subjec pem', ['0906D06C']);
|
||||
|
||||
// other possible cuases that are difficult to catch:
|
||||
// - ASN1_STRING_to_UTF8 fails in add_assoc_name_entry
|
||||
|
@ -124,59 +143,25 @@ if (is_file($output_file)) {
|
|||
unlink($output_file);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
--EXPECT--
|
||||
string(89) "error:0607A082:digital envelope routines:EVP_CIPHER_CTX_set_key_length:invalid key length"
|
||||
bool(false)
|
||||
int(15)
|
||||
|
||||
PKEY errors
|
||||
|
||||
Warning: openssl_pkey_export_to_file(): cannot get key from parameter 1 in %s on line %d
|
||||
string(61) "error:02001002:system library:fopen:No such file or directory"
|
||||
string(53) "error:2006D080:BIO routines:BIO_new_file:no such file"
|
||||
|
||||
Warning: openssl_pkey_export_to_file(): cannot get key from parameter 1 in %s on line %d
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
string(68) "error:0E06D06C:configuration file routines:NCONF_get_string:no value"
|
||||
string(68) "error:0E06D06C:configuration file routines:NCONF_get_string:no value"
|
||||
string(68) "error:0E06D06C:configuration file routines:NCONF_get_string:no value"
|
||||
string(68) "error:0E06D06C:configuration file routines:NCONF_get_string:no value"
|
||||
string(68) "error:0E06D06C:configuration file routines:NCONF_get_string:no value"
|
||||
string(68) "error:0E06D06C:configuration file routines:NCONF_get_string:no value"
|
||||
string(50) "error:02001015:system library:fopen:Is a directory"
|
||||
string(51) "error:2006D002:BIO routines:BIO_new_file:system lib"
|
||||
string(49) "error:09072007:PEM routines:PEM_write_bio:BUF lib"
|
||||
|
||||
Warning: openssl_pkey_export(): cannot get key from parameter 1 in %s on line %d
|
||||
string(72) "error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt"
|
||||
string(53) "error:0906A065:PEM routines:PEM_do_header:bad decrypt"
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
string(72) "error:04066076:rsa routines:RSA_EAY_PRIVATE_ENCRYPT:unknown padding type"
|
||||
string(78) "error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error"
|
||||
string(72) "error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed"
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
string(71) "error:04068076:rsa routines:RSA_EAY_PUBLIC_ENCRYPT:unknown padding type"
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
string(79) "error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01"
|
||||
string(71) "error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed"
|
||||
openssl_pkey_export_to_file opening: ok
|
||||
openssl_pkey_export_to_file pem: ok
|
||||
openssl_pkey_export_to_file write: ok
|
||||
openssl_pkey_export: ok
|
||||
openssl_pkey_get_public: ok
|
||||
openssl_private_encrypt: ok
|
||||
openssl_private_decrypt: ok
|
||||
openssl_private_(en|de)crypt padding: ok
|
||||
X509 errors
|
||||
|
||||
Warning: openssl_x509_export_to_file(): cannot get cert from parameter 1 in %s on line %d
|
||||
string(61) "error:02001002:system library:fopen:No such file or directory"
|
||||
string(53) "error:2006D080:BIO routines:BIO_new_file:no such file"
|
||||
|
||||
Warning: openssl_x509_export_to_file(): cannot get cert from parameter 1 in %s on line %d
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
|
||||
Warning: openssl_x509_export_to_file(): error opening file %s in %s on line %d
|
||||
string(50) "error:02001015:system library:fopen:Is a directory"
|
||||
string(51) "error:2006D002:BIO routines:BIO_new_file:system lib"
|
||||
string(90) "error:0B086079:x509 certificate routines:X509_STORE_CTX_purpose_inherit:unknown purpose id"
|
||||
|
||||
Warning: openssl_x509_checkpurpose(): error loading file %s in %s on line %d
|
||||
openssl_x509_export_to_file open: ok
|
||||
openssl_x509_export_to_file pem: ok
|
||||
openssl_x509_export_to_file write: ok
|
||||
openssl_x509_checkpurpose purpose: ok
|
||||
CSR errors
|
||||
string(61) "error:02001002:system library:fopen:No such file or directory"
|
||||
string(53) "error:2006D080:BIO routines:BIO_new_file:no such file"
|
||||
string(55) "error:20068079:BIO routines:BIO_gets:unsupported method"
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
string(54) "error:0906D06C:PEM routines:PEM_read_bio:no start line"
|
||||
openssl_csr_get_subject open: ok
|
||||
openssl_csr_get_subjec pem: ok
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue