Skip to content

Commit c7fe71c

Browse files
committed
Add SubjectAltName support to certificate generator
And switch tests using SAN certificates to the generator. This is ugly, but there doesn't seem to be a more direct way to privide SAN in PHP.
1 parent acdd6e5 commit c7fe71c

File tree

7 files changed

+71
-77
lines changed

7 files changed

+71
-77
lines changed

ext/openssl/tests/CertificateGenerator.inc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
class CertificateGenerator
44
{
55
const CONFIG = __DIR__. DIRECTORY_SEPARATOR . 'openssl.cnf';
6+
const SAN_CONFIG = __DIR__ . DIRECTORY_SEPARATOR . 'san.cnf';
67

78
/** @var resource */
89
private $ca;
@@ -82,23 +83,36 @@ class CertificateGenerator
8283
openssl_x509_export_to_file($this->ca, $file);
8384
}
8485

85-
public function saveNewCertAsFileWithKey($commonNameForCert, $file, $keyLength = null)
86-
{
86+
public function saveNewCertAsFileWithKey(
87+
$commonNameForCert, $file, $keyLength = null, $subjectAltName = null
88+
) {
8789
$dn = [
8890
'countryName' => 'BY',
8991
'stateOrProvinceName' => 'Minsk',
9092
'localityName' => 'Minsk',
9193
'organizationName' => 'Example Org',
92-
'commonName' => $commonNameForCert,
9394
];
95+
if ($commonNameForCert !== null) {
96+
$dn['commonName'] = $commonNameForCert;
97+
}
98+
99+
$config = [
100+
'digest_alg' => 'sha256',
101+
'req_extensions' => 'v3_req',
102+
'x509_extensions' => 'usr_cert',
103+
];
104+
if ($subjectAltName !== null) {
105+
putenv("PHP_SUBJECTALTNAME=$subjectAltName");
106+
$config['config'] = self::SAN_CONFIG;
107+
}
94108

95109
$this->lastKey = self::generateKey($keyLength);
96110
$this->lastCert = openssl_csr_sign(
97-
openssl_csr_new($dn, $this->lastKey, ['req_extensions' => 'v3_req']),
111+
openssl_csr_new($dn, $this->lastKey, $config),
98112
$this->ca,
99113
$this->caKey,
100114
/* days */ 2,
101-
['digest_alg' => 'sha256'],
115+
$config,
102116
);
103117

104118
$certText = '';

ext/openssl/tests/bug68265.pem

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

ext/openssl/tests/bug68265.phpt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,22 @@ if (!function_exists("proc_open")) die("skip no proc_open");
77
?>
88
--FILE--
99
<?php
10+
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug68265.pem.tmp';
11+
$san = 'DNS:debs.ak-online.be., DNS:debs.ak-online.net.';
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__ . '/bug68265.pem',
15-
'passphrase' => 'elephpant',
17+
'local_cert' => '%s',
1618
]]);
1719
1820
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
1921
phpt_notify();
2022
2123
stream_socket_accept($server, 30);
2224
CODE;
25+
$serverCode = sprintf($serverCode, $certFile);
2326

2427
$clientCode = <<<'CODE'
2528
$serverUri = "ssl://127.0.0.1:64321";
@@ -35,8 +38,16 @@ $clientCode = <<<'CODE'
3538
var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx));
3639
CODE;
3740

41+
include 'CertificateGenerator.inc';
42+
$certificateGenerator = new CertificateGenerator();
43+
$certificateGenerator->saveNewCertAsFileWithKey('test.com', $certFile, null, $san);
44+
3845
include 'ServerClientTestCase.inc';
3946
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
4047
?>
48+
--CLEAN--
49+
<?php
50+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug68265.pem.tmp');
51+
?>
4152
--EXPECTF--
4253
resource(%d) of type (stream)

ext/openssl/tests/bug68879.pem

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

ext/openssl/tests/bug68879.phpt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,22 @@ if (!function_exists("proc_open")) die("skip no proc_open");
77
?>
88
--FILE--
99
<?php
10+
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug68879.pem.tmp';
11+
$san = 'DNS:test.com, DNS:www.test.com, DNS:subdomain.test.com, IP:0:0:0:0:0:FFFF:A02:1, IP:10.2.0.1';
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__ . '/bug68879.pem',
15-
'passphrase' => 'elephpant',
17+
'local_cert' => '%s',
1618
]]);
1719
1820
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
1921
phpt_notify();
2022
2123
stream_socket_accept($server, 30);
2224
CODE;
25+
$serverCode = sprintf($serverCode, $certFile);
2326

2427
$clientCode = <<<'CODE'
2528
$serverUri = "ssl://127.0.0.1:64321";
@@ -35,8 +38,16 @@ $clientCode = <<<'CODE'
3538
var_dump(stream_socket_client($serverUri, $errno, $errstr, 30, $clientFlags, $clientCtx));
3639
CODE;
3740

41+
include 'CertificateGenerator.inc';
42+
$certificateGenerator = new CertificateGenerator();
43+
$certificateGenerator->saveNewCertAsFileWithKey('test.com', $certFile, null, $san);
44+
3845
include 'ServerClientTestCase.inc';
3946
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
4047
?>
48+
--CLEAN--
49+
<?php
50+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug68879.pem.tmp');
51+
?>
4152
--EXPECTF--
4253
resource(%d) of type (stream)

ext/openssl/tests/san.cnf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[ req ]
2+
distinguished_name = req_distinguished_name
3+
4+
[ req_distinguished_name ]
5+
6+
[ v3_req ]
7+
basicConstraints = CA:FALSE
8+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
9+
subjectAltName = ${ENV::PHP_SUBJECTALTNAME}
10+
11+
[ usr_cert ]
12+
basicConstraints = CA:FALSE
13+
subjectAltName = ${ENV::PHP_SUBJECTALTNAME}

ext/openssl/tests/san_peer_matching.phpt

Lines changed: 13 additions & 2 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 . 'san_peer_matching.pem.tmp';
11+
$san = 'DNS:example.org, DNS:www.example.org, DNS:test.example.org';
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__ . '/san-cert.pem',
17+
'local_cert' => '%s',
1518
]]);
1619
1720
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
@@ -20,13 +23,13 @@ $serverCode = <<<'CODE'
2023
@stream_socket_accept($server, 1);
2124
@stream_socket_accept($server, 1);
2225
CODE;
26+
$serverCode = sprintf($serverCode, $certFile);
2327

2428
$clientCode = <<<'CODE'
2529
$serverUri = "ssl://127.0.0.1:64321";
2630
$clientFlags = STREAM_CLIENT_CONNECT;
2731
$clientCtx = stream_context_create(['ssl' => [
2832
'verify_peer' => false,
29-
'cafile' => __DIR__ . '/san-ca.pem',
3033
]]);
3134
3235
phpt_wait();
@@ -38,9 +41,17 @@ $clientCode = <<<'CODE'
3841
var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx));
3942
CODE;
4043

44+
include 'CertificateGenerator.inc';
45+
$certificateGenerator = new CertificateGenerator();
46+
$certificateGenerator->saveNewCertAsFileWithKey(null, $certFile, null, $san);
47+
4148
include 'ServerClientTestCase.inc';
4249
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
4350
?>
51+
--CLEAN--
52+
<?php
53+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'san_peer_matching.pem.tmp');
54+
?>
4455
--EXPECTF--
4556
resource(%d) of type (stream)
4657

0 commit comments

Comments
 (0)