Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does OpenSSL really need a path to openssl.conf?

I want to create a self-signed-certificate in PHP 5.x. with my own (alternative) openssl configuration which should be defined by my PHP code. The PHP script will run on different environments (shared hosting webservers).

The official PHP Manual says:

By default, the information in your system openssl.conf is used to initialize the request; you can specify a configuration file section by setting the config_section_section key of configargs. You can also specify an alternative openssl configuration file by setting the value of the config key to the path of the file you want to use. The following keys, if present in configargs behave as their equivalents in the openssl.conf, as listed in the table below.....

My question: Is there a reason why I have to specify the path to openssl.conf explicitly, because it seems to work fine without it:

$Configs = array(       
    'digest_alg' => 'sha1',
    'x509_extensions' => 'v3_ca',
    'req_extensions' => 'v3_req',
    'private_key_bits' => 1024,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
    'encrypt_key' => true,
    'encrypt_key_cipher' => OPENSSL_CIPHER_3DES
);

$privkey = openssl_pkey_new();
$csr = openssl_csr_new($dn, $privkey, $Configs);
$sscert = openssl_csr_sign($csr, null, $privkey, 365, $Configs);

Edit:

In the user contributed notes on the PHP Manual, why do they always specify a path to openssl.cnf? For example:

$configargs = array(
    'config' => '/etc/ssl/openssl.cnf',
    'digest_alg' => 'md5',
    'x509_extensions' => 'v3_ca',
    'req_extensions'   => 'v3_req',
    'private_key_bits' => 666,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
    'encrypt_key' => false,
);
like image 413
Roland Avatar asked Mar 05 '12 16:03

Roland


3 Answers

There are many configuration settings in OpenSSL that can't be defined in PHP by $configargs (the PHP parameters you pass to the OpenSSL functions).

If you don't specify an alternative openssl configuration file, it will automatically take the default openssl.cnf.

Recommendation: Since your script will run on different servers, you should always use your own openssl.cnf.

Just create a simple text file and put the following 4 lines in it. Then pass the path to it to the OpenSSL function you are using (look at your second example above).

distinguished_name  = req_distinguished_name
[req_distinguished_name]
[v3_req]
[v3_ca]

It seems that these 4 lines are the minimum openssl.cnf must contain.

like image 119
HomeCoder Avatar answered Oct 21 '22 11:10

HomeCoder


The answer to this relates to the role of SSL. It is a "shell" around the html/http conversation between client and server. Apache runs it. It's not really "in" PHP land. When you elect to recreate the key pair all you are really doing is kicking Apache in the shins to force the client /server to re-initiate their conversation with a new pair of SSL key pairs.

In some senses this might be seen as a bit like remaking a session_id

My question: Is there a reason why I have to specify the path to openssl.conf explicitly, because it seems to work fine without it:

The creation of a self signed certificate is not being done here, a re-creation of it is. therefore when you don't supply a path, it's fine with it because it's already had a path from Apache.

like image 36
conners Avatar answered Oct 21 '22 13:10

conners


Creating a self-signed cert in PHP without OpenSSL (requires phpseclib, a pure PHP X.509 implementation)...

<?php
include('File/X509.php');
include('Crypt/RSA.php');

// create private key / x.509 cert for stunnel / website
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);

$pubKey = new Crypt_RSA();
$pubKey->loadKey($publickey);
$pubKey->setPublicKey();

$subject = new File_X509();
$subject->setPublicKey($pubKey);
$subject->setDNProp('id-at-organizationName', 'phpseclib demo cert');
$subject->setDomain('www.whatever.com');

$issuer = new File_X509();
$issuer->setPrivateKey($privKey);
$issuer->setDN($subject->getDN());

$x509 = new File_X509();
$x509->setStartDate('-1 month');
$x509->setEndDate('+1 year');
$x509->setSerialNumber(chr(30));

$result = $x509->sign($issuer, $subject);
echo "the stunnel.pem contents are as follows:\r\n\r\n";
echo $privKey->getPrivateKey();
echo "\r\n";
echo $x509->saveX509($result);
echo "\r\n";
like image 2
neubert Avatar answered Oct 21 '22 12:10

neubert