php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77787 OPENSSL PRIVATE KEY is missing
Submitted: 2019-03-24 02:14 UTC Modified: 2019-12-03 05:57 UTC
From: xxalfa at gmail dot com Assigned: bukka (profile)
Status: Not a bug Package: OpenSSL related
PHP Version: 7.3.11 OS:
Private report: No CVE-ID: None
 [2019-03-24 02:14 UTC] xxalfa at gmail dot com
Description:
------------
When creating private and public keys, there are some problems. With the option "config" I have the configuration file "C:\php\extras\ssl\openssl.cnf" deposited, but I get only the public key. PHP insists on taking the configuration file located in "C:\usr\local\ssl\openssl.cnf".

Test script:
---------------
<?php

    // C:\Users\User\Desktop\php-openssl-certificate-example.cmd

    // @echo off

    // title PHP Development Server

    // cd "%cd%"

    // "C:\php\php.exe" "php-openssl-certificate-example.php"

    // pause

    // C:\Users\User\Desktop\php-openssl-certificate-example.php [PID:9676][PHP:7.3.3]

    //-------------------------------------------------
    // HEAD
    //-------------------------------------------------

    declare( strict_types = 1 );

    header( 'Content-Type:text/plain' );

    error_reporting( E_ALL );

    ini_set( 'display_errors', '1' );

    ini_set( 'html_errors', '0' );

    define( 'CORE_DIR', dirname( __FILE__ ) . DIRECTORY_SEPARATOR );

    isset( $argv ) or trigger_error( 'This is a command terminal application.', E_USER_ERROR );

    echo __FILE__ . ' [PID:' . getmypid() . '][PHP:' . phpversion() . ']' . PHP_EOL . PHP_EOL;

    extension_loaded( 'openssl' ) or dl( 'openssl' ) or trigger_error( 'The openssl extension is required.', E_USER_ERROR );

    //-------------------------------------------------
    // CERTIFICATE LOCATIONS
    //-------------------------------------------------

    $array_of_certificate_locations = openssl_get_cert_locations();

    echo var_export( $array_of_certificate_locations, true ) . PHP_EOL;

    // The ".rnd" file is created at the point of execution. In my case on the desktop. And not as planned in the specified directory.

    // $file_path = $array_of_certificate_locations[ 'default_default_cert_area' ] . DIRECTORY_SEPARATOR . '.rnd';

    // file_exists( $file_path ) or touch( $file_path );

    // is_writeable( $file_path ) or trigger_error( 'The file (' . $file_path . ') does not exist or is not writable.', E_USER_ERROR );

    //-------------------------------------------------
    // CREATE PRIVATE AND PUBLIC KEY
    //-------------------------------------------------

    $options = array();

    $options[ 'config' ] = realpath( 'C:\php' . DIRECTORY_SEPARATOR . 'extras/ssl\\openssl.cnf' ); // Returns: only public key

    // $options[ 'config' ] = realpath( 'C:\usr\local\ssl\renamed_openssl.cnf' ); // Returns: only public key

    // $options[ 'config' ] = realpath( 'C:\usr\local\ssl\openssl.cnf' ); // Returns: private and public key

    // $options[ 'encrypt_key' ] = true; // If I set this value true, where do I deposit the password?

    $options[ 'digest_alg' ] = 'sha512';

    $options[ 'private_key_bits' ] = 1024;

    $options[ 'private_key_type' ] = OPENSSL_KEYTYPE_RSA;

    $openssl_resource = openssl_pkey_new( $options ) or trigger_error( 'An error occurred while processing the configuration.', E_USER_ERROR );

    // openssl_pkey_export( $openssl_resource, $private_key, $passphrase = 'password' ); // Is $passphrase set only if encrypt_key is true?

    openssl_pkey_export( $openssl_resource, $private_key );

    echo $private_key . PHP_EOL . PHP_EOL;

    $public_key = openssl_pkey_get_details( $openssl_resource );

    $public_key = $public_key[ 'key' ];

    echo $public_key . PHP_EOL . PHP_EOL;

    //-------------------------------------------------
    // PLAINTEXT
    //-------------------------------------------------

    // $plaintext = 'plaintext data goes here';

    // echo $plaintext . PHP_EOL . PHP_EOL;

    //-------------------------------------------------
    // OPENSSL PRIVATE ENCRYPT
    //-------------------------------------------------

    // Encrypt data with the private key.

    // openssl_private_encrypt( $plaintext, $private_encrypted, $private_key );

    // echo 'openssl_private_encrypt' . PHP_EOL . PHP_EOL . bin2hex( $private_encrypted ) . PHP_EOL . PHP_EOL;

    //-------------------------------------------------
    // OPENSSL PUBLIC DECRYPT
    //-------------------------------------------------

    // Data encrypted with the private key, now decrypted with the public key.

    // openssl_public_decrypt( $private_encrypted, $public_decrypted, $public_key );

    // echo 'openssl_public_decrypt' . PHP_EOL . PHP_EOL . $public_decrypted . PHP_EOL . PHP_EOL;

    //-------------------------------------------------
    // OPENSSL PUBLIC ENCRYPT
    //-------------------------------------------------

    // Encrypt data with the public key.

    // openssl_public_encrypt( $plaintext, $public_encrypted, $public_key );

    // echo 'openssl_public_encrypt' . PHP_EOL . PHP_EOL . bin2hex( $public_encrypted ) . PHP_EOL . PHP_EOL;

    //-------------------------------------------------
    // OPENSSL PRIVATE DECRYPT
    //-------------------------------------------------

    // Data encrypted with the public key, now decrypted with the private key.

    // openssl_private_decrypt( $public_encrypted, $private_decrypted, $private_key );

    // echo 'openssl_private_decrypt' . PHP_EOL . PHP_EOL . $private_decrypted . PHP_EOL . PHP_EOL;

    //-------------------------------------------------
    // ERROR HANDLING
    //-------------------------------------------------

    // echo openssl_error_string() . PHP_EOL . PHP_EOL;

?>

Expected result:
----------------
array (
  'default_cert_file' => 'C:\\usr\\local\\ssl/cert.pem',
  'default_cert_file_env' => 'SSL_CERT_FILE',
  'default_cert_dir' => 'C:\\usr\\local\\ssl/certs',
  'default_cert_dir_env' => 'SSL_CERT_DIR',
  'default_private_dir' => 'C:\\usr\\local\\ssl/private',
  'default_default_cert_area' => 'C:\\usr\\local\\ssl',
  'ini_cafile' => '',
  'ini_capath' => '',
)
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL7Z4Z1x93+4nlO9
MLDBkzOswqPC6E3ztL8oPuhn8hfBqZ0xb5Vp+yMp9N+yu+UDnPn6bUzM+JX1qZfS
UJY/gJxFIB3Ry2TAsKdHb645QKEwuIWEMGO7IuLx23eD5BjyDrJ6hSVqQrWefQGn
eX2lpWfd7LPBBsEdMCvhGSLh1yUbAgMBAAECgYBWhxAsQux0Yq6dxqvZp5nmltAU
URzjordy53tGAUKYlLwiwbQWaNtswOv9s9pOZYn5KBn/9PpLevquE7Nnu1jCOHQP
6snRVU2emDtLD4wydewgjGD5aq/UogeNCTBL5S3323/Ys+m3hKnWM5Ud2ekojDMi
tCLD926s/gqPtPBPCQJBAOJh7kdHN/sNLldqWEB62WCMTZw2J90GvgIaXLVas1aH
BUod+mygtGNZdbaO/rLDHaJ/+o0twwEuXDaynvRv5ecCQQDX0evUxOmjEpLP3ihP
Q5IMwPCFL0hoDgDJORq7QqkrD6ICqhxR+AeI0vbx9uGxl/mg7f6/IDxFOCWpdOFG
V/itAkEAmz+tuRQOQAz6CtjTTOTyzlNppgc9r0ZAaBDMI1LgSiauafXFF1neW4Ou
RlQqN023tQkvOkJ3yQeSFbDJcbiLYQJBANDoZI2qpjWx7ubDtuUzFRa/VJK3ODFx
DJW7bwLA/huuoDZQD+XQXwq0m1GQlttfrsV2WtcLDww500r61m1PDmkCQHFoOJ0a
funMLzvdfijgwQmIJTgAg+ZZqrGqQapRrsimwTFNJ6+dOsBcDKaKfl66TQAAoeNW
RuvAIB6JPTnvcZA=
-----END PRIVATE KEY-----


-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+2eGdcfd/uJ5TvTCwwZMzrMKj
wuhN87S/KD7oZ/IXwamdMW+VafsjKfTfsrvlA5z5+m1MzPiV9amX0lCWP4CcRSAd
0ctkwLCnR2+uOUChMLiFhDBjuyLi8dt3g+QY8g6yeoUlakK1nn0Bp3l9paVn3eyz
wQbBHTAr4Rki4dclGwIDAQAB
-----END PUBLIC KEY-----

Actual result:
--------------
array (
  'default_cert_file' => 'C:\\usr\\local\\ssl/cert.pem',
  'default_cert_file_env' => 'SSL_CERT_FILE',
  'default_cert_dir' => 'C:\\usr\\local\\ssl/certs',
  'default_cert_dir_env' => 'SSL_CERT_DIR',
  'default_private_dir' => 'C:\\usr\\local\\ssl/private',
  'default_default_cert_area' => 'C:\\usr\\local\\ssl',
  'ini_cafile' => '',
  'ini_capath' => '',
)


-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEvBAJCSq/sJalTyvKOJvr/Avd
6vaSB3hIPnnsxC3nknyudbv5DYOyOUAf0gGaPjGyUyy/5UCWNaA7h5gPyAMigzMg
EEikpfJxqoDqM3heMB5dU08hP/2QLVRW+ZJNUawrJhfz9fexuKgbzUM+OZrz6uWl
zuNKJlpl1rumqYJK3QIDAQAB
-----END PUBLIC KEY-----

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-06-01 08:54 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2019-06-01 08:54 UTC] cmb@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions.  Due to the volume
of reports we can not explain in detail here why your report is not
a bug.  The support channels will be able to provide an explanation
for you.

Thank you for your interest in PHP.

See <https://www.php.net/manual/en/openssl.installation.php>.
 [2019-06-01 13:09 UTC] xxalfa at gmail dot com
I appreciate her apology, but I can not accept it.  Because I simply expect more from PHP.  The specified help page is not helpful for me.  In the deposited channels, I was not so far appropriate find.  Let's look at my message: of course it is not a bug, in my view it is just a misconduct, the configuration of openssl should be more flexible, only please whom and where can I explain this appropriately?
 [2019-06-01 15:38 UTC] cmb@php.net
-Status: Not a bug +Status: Re-Opened -Assigned To: cmb +Assigned To:
 [2019-10-27 19:40 UTC] bukka@php.net
-Status: Re-Opened +Status: Feedback -Assigned To: +Assigned To: bukka
 [2019-10-27 19:40 UTC] bukka@php.net
Looks like openssl_pkey_export failed so it's empty because the value is false. You should see the errors using openssl_error_string. You need to provide more info as the current output doesn't suggest any bug in PHP.
 [2019-10-27 20:52 UTC] xxalfa at gmail dot com
-Status: Feedback +Status: Assigned
 [2019-10-27 20:52 UTC] xxalfa at gmail dot com
After all this time, are not we a millimeter further? Although parameter $options[ 'config' ] is set, openssl insists that file C:\usr\local\ssl\openssl.cnf must exist there.

I have already stated that it is not a bug, it is simply a misconduct.
 [2019-11-10 19:10 UTC] bukka@php.net
-Status: Assigned +Status: Wont fix
 [2019-11-10 19:10 UTC] bukka@php.net
Ah yeah this is expected and lots of code depends on it so we can't change this. Most of the time it's what users want as it allows using system config.

The only thing that you can do is to change the location using environment variable OPENSSL_CONF (or SSLEAY_CONF is also checked for legacy reasons). Have to close it as there is nothing we can do about this.
 [2019-11-10 22:32 UTC] xxalfa at gmail dot com
-Type: Bug +Type: Documentation Problem
 [2019-11-10 22:32 UTC] xxalfa at gmail dot com
An alternative file can be specified on page "https://www.php.net/manual/de/function.openssl-csr-new.php" under config, but what do I have to do to use this file?
 [2019-11-17 18:23 UTC] bukka@php.net
Could you actually share the content of C:\usr\local\ssl\openssl.cnf and C:\php\extras\ssl\openssl.cnf . I think there might be issue in the actual config as it's strange that it doesn't work for you.
 [2019-11-17 18:23 UTC] bukka@php.net
-Status: Wont fix +Status: Re-Opened
 [2019-11-18 00:05 UTC] xxalfa at gmail dot com
-PHP Version: 7.3.3 +PHP Version: 7.3.11
 [2019-11-18 00:05 UTC] xxalfa at gmail dot com
I have update all files to version 7.3.11. Not the content is the problem, but if C:\usr\local\ssl\openssl.cnf does not exist, the key is not generated. It bothers me that I had to create the path C:\usr\local\ssl\ myself.
 [2019-12-01 19:23 UTC] bukka@php.net
-Status: Re-Opened +Status: Not a bug -Type: Documentation Problem +Type: Bug
 [2019-12-01 19:23 UTC] bukka@php.net
Ok I finally see the issue in your code. You don't pass options to each function so config is not set. In this case it's missing in openssl_pkey_export. It works if you replace it with

openssl_pkey_export( $openssl_resource, $private_key, null, $options );
 [2019-12-01 19:26 UTC] bukka@php.net
Basically if you remove the main config, you have to always specify it for all functions that use config, otherwise it fails because there is no default or specified config.

Is it difficult to set ENV var as suggested before on Windows? Or would it be maybe better if we introduced INI options for default config?
 [2019-12-03 05:57 UTC] xxalfa at gmail dot com
The ENV can be changed very easily, but I think it makes more sense to set the OPENSSL_CONF/SSLEAY_CONF in the INI. I did not expect $options to be quoted twice. The problem is finally solved.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 13:01:30 2024 UTC