Skip to content

Commit 1fab01b

Browse files
kamazeebukka
authored andcommitted
Generate certs for openssl tests on the fly
The idea is to create an easy way to provide a certificate that never expires. In order to make it cross-platform, PHP is used rather than openssl CLI app. Using openssl to generate certificates for tests that test openssl might be not the best idea but pros seem to outweight cons that this "recursice dependency" adds
1 parent 6b4cdba commit 1fab01b

25 files changed

+505
-219
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
class CertificateGenerator
4+
{
5+
const CONFIG = __DIR__. DIRECTORY_SEPARATOR . 'openssl.cnf';
6+
7+
/** @var resource */
8+
private $ca;
9+
10+
/** @var resource */
11+
private $caKey;
12+
13+
/** @var resource|null */
14+
private $lastCert;
15+
16+
/** @var resource|null */
17+
private $lastKey;
18+
19+
public function __construct()
20+
{
21+
if (!extension_loaded('openssl')) {
22+
throw new RuntimeException(
23+
'openssl extension must be loaded to generate certificates'
24+
);
25+
}
26+
$this->generateCa();
27+
}
28+
29+
/**
30+
* @param int|null $keyLength
31+
* @return resource
32+
*/
33+
private static function generateKey($keyLength = null)
34+
{
35+
if (null === $keyLength) {
36+
$keyLength = 2048;
37+
}
38+
39+
return openssl_pkey_new([
40+
'private_key_bits' => $keyLength,
41+
'private_key_type' => OPENSSL_KEYTYPE_RSA,
42+
'encrypt_key' => false,
43+
]);
44+
}
45+
46+
private function generateCa()
47+
{
48+
$this->caKey = self::generateKey();
49+
$dn = [
50+
'countryName' => 'GB',
51+
'stateOrProvinceName' => 'Berkshire',
52+
'localityName' => 'Newbury',
53+
'organizationName' => 'Example Certificate Authority',
54+
'commonName' => 'CA for PHP Tests'
55+
];
56+
57+
$this->ca = openssl_csr_sign(
58+
openssl_csr_new(
59+
$dn,
60+
$this->caKey,
61+
[
62+
'x509_extensions' => 'v3_ca',
63+
'config' => self::CONFIG,
64+
]
65+
),
66+
null,
67+
$this->caKey,
68+
2
69+
);
70+
}
71+
72+
public function getCaCert()
73+
{
74+
$output = '';
75+
openssl_x509_export($this->ca, $output);
76+
77+
return $output;
78+
}
79+
80+
public function saveCaCert($file)
81+
{
82+
openssl_x509_export_to_file($this->ca, $file);
83+
}
84+
85+
public function saveNewCertAsFileWithKey($commonNameForCert, $file, $keyLength = null)
86+
{
87+
$dn = [
88+
'countryName' => 'BY',
89+
'stateOrProvinceName' => 'Minsk',
90+
'localityName' => 'Minsk',
91+
'organizationName' => 'Example Org',
92+
'commonName' => $commonNameForCert,
93+
];
94+
95+
$this->lastKey = self::generateKey($keyLength);
96+
$this->lastCert = openssl_csr_sign(
97+
openssl_csr_new($dn, $this->lastKey, ['req_extensions' => 'v3_req']),
98+
$this->ca,
99+
$this->caKey,
100+
2
101+
);
102+
103+
$certText = '';
104+
openssl_x509_export($this->lastCert, $certText);
105+
106+
$keyText = '';
107+
openssl_pkey_export($this->lastKey, $keyText);
108+
109+
file_put_contents($file, $certText . PHP_EOL . $keyText);
110+
}
111+
112+
public function getCertDigest($algo)
113+
{
114+
return openssl_x509_fingerprint($this->lastCert, $algo);
115+
}
116+
}

ext/openssl/tests/bug46127.pem

Lines changed: 0 additions & 33 deletions
This file was deleted.

ext/openssl/tests/bug46127.phpt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
--TEST--
2-
#46127, openssl_sign/verify: accept different algos
2+
#46127 php_openssl_tcp_sockop_accept forgets to set context on accepted stream
33
--SKIPIF--
44
<?php
55
if (!extension_loaded("openssl")) die("skip openssl not loaded");
66
if (!function_exists("proc_open")) die("skip no proc_open");
77
?>
88
--FILE--
99
<?php
10+
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug46127.pem.tmp';
11+
1012
$serverCode = <<<'CODE'
1113
$serverUri = "ssl://127.0.0.1:64321";
1214
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
1315
$serverCtx = stream_context_create(['ssl' => [
14-
'local_cert' => __DIR__ . '/bug46127.pem',
16+
'local_cert' => '%s',
1517
]]);
1618
1719
$sock = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
@@ -20,6 +22,7 @@ $serverCode = <<<'CODE'
2022
$link = stream_socket_accept($sock);
2123
fwrite($link, "Sending bug 46127\n");
2224
CODE;
25+
$serverCode = sprintf($serverCode, $certFile);
2326

2427
$clientCode = <<<'CODE'
2528
$serverUri = "ssl://127.0.0.1:64321";
@@ -36,8 +39,16 @@ $clientCode = <<<'CODE'
3639
echo fgets($sock);
3740
CODE;
3841

42+
include 'CertificateGenerator.inc';
43+
$certificateGenerator = new CertificateGenerator();
44+
$certificateGenerator->saveNewCertAsFileWithKey('bug46127', $certFile);
45+
3946
include 'ServerClientTestCase.inc';
4047
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
4148
?>
49+
--CLEAN--
50+
<?php
51+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug46127.pem.tmp');
52+
?>
4253
--EXPECT--
4354
Sending bug 46127

ext/openssl/tests/bug48182.phpt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ if (!function_exists("proc_open")) die("skip no proc_open");
77
?>
88
--FILE--
99
<?php
10+
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug48182.pem.tmp';
11+
$cacertFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug48182-ca.pem.tmp';
12+
1013
$serverCode = <<<'CODE'
1114
$serverUri = "ssl://127.0.0.1:64321";
1215
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
1316
$serverCtx = stream_context_create(['ssl' => [
14-
'local_cert' => __DIR__ . '/bug54992.pem'
17+
'local_cert' => '%s'
1518
]]);
1619
1720
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
@@ -22,13 +25,15 @@ $serverCode = <<<'CODE'
2225
$data = "Sending bug48182\n" . fread($client, 8192);
2326
fwrite($client, $data);
2427
CODE;
28+
$serverCode = sprintf($serverCode, $certFile);
2529

30+
$peerName = 'bug48182';
2631
$clientCode = <<<'CODE'
2732
$serverUri = "ssl://127.0.0.1:64321";
2833
$clientFlags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT;
2934
$clientCtx = stream_context_create(['ssl' => [
30-
'cafile' => __DIR__ . '/bug54992-ca.pem',
31-
'peer_name' => 'bug54992.local'
35+
'cafile' => '%s',
36+
'peer_name' => '%s'
3237
]]);
3338
3439
phpt_wait();
@@ -39,13 +44,24 @@ $clientCode = <<<'CODE'
3944
fwrite($client, $data);
4045
echo fread($client, 1024);
4146
CODE;
47+
$clientCode = sprintf($clientCode, $cacertFile, $peerName);
4248

4349
echo "Running bug48182\n";
4450

51+
include 'CertificateGenerator.inc';
52+
$certificateGenerator = new CertificateGenerator();
53+
$certificateGenerator->saveCaCert($cacertFile);
54+
$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile);
55+
4556
include 'ServerClientTestCase.inc';
4657
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
4758
?>
48-
--EXPECTF--
59+
--CLEAN--
60+
<?php
61+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug48182.pem.tmp');
62+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug48182-ca.pem.tmp');
63+
?>
64+
--EXPECT--
4965
Running bug48182
5066
Sending bug48182
5167
Sending data over to SSL server in async mode with contents like Hello World

ext/openssl/tests/bug54992-ca.pem

Lines changed: 0 additions & 35 deletions
This file was deleted.

ext/openssl/tests/bug54992.pem

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)