Skip to content

Commit 81d1529

Browse files
committed
Merge branch 'PHP-8.4'
2 parents 25c0874 + 0d19984 commit 81d1529

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

ext/openssl/tests/bug80770.phpt

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
--TEST--
2+
Bug #80770: SNI_server_certs does not inherit peer verification options
3+
--EXTENSIONS--
4+
openssl
5+
--SKIPIF--
6+
<?php
7+
if (!function_exists("proc_open")) die("skip no proc_open");
8+
if (OPENSSL_VERSION_NUMBER < 0x10101000) die("skip OpenSSL v1.1.1 required");
9+
?>
10+
--FILE--
11+
<?php
12+
$clientCertFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug80770_client.pem.tmp';
13+
$caCertFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug80770_ca.pem.tmp';
14+
15+
$serverCode = <<<'CODE'
16+
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
17+
$ctx = stream_context_create(['ssl' => [
18+
'SNI_server_certs' => [
19+
"cs.php.net" => __DIR__ . "/sni_server_cs.pem",
20+
"uk.php.net" => __DIR__ . "/sni_server_uk.pem",
21+
"us.php.net" => __DIR__ . "/sni_server_us.pem"
22+
],
23+
'verify_peer' => true,
24+
'cafile' => '%s',
25+
'capture_peer_cert' => true,
26+
'verify_peer_name' => false,
27+
'security_level' => 0,
28+
]]);
29+
$server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
30+
phpt_notify_server_start($server);
31+
32+
$client = stream_socket_accept($server, 30);
33+
if ($client) {
34+
$success = stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_SERVER);
35+
if ($success) {
36+
$options = stream_context_get_options($client);
37+
$hasCert = isset($options['ssl']['peer_certificate']);
38+
phpt_notify(message: $hasCert ? "CLIENT_CERT_CAPTURED" : "NO_CLIENT_CERT");
39+
} else {
40+
phpt_notify(message: "TLS_HANDSHAKE_FAILED");
41+
}
42+
} else {
43+
phpt_notify(message: "ACCEPT_FAILED");
44+
}
45+
CODE;
46+
$serverCode = sprintf($serverCode, $caCertFile);
47+
48+
$clientCode = <<<'CODE'
49+
$flags = STREAM_CLIENT_CONNECT;
50+
$ctx = stream_context_create(['ssl' => [
51+
'verify_peer' => false,
52+
'verify_peer_name' => false,
53+
'local_cert' => '%s',
54+
'peer_name' => 'cs.php.net',
55+
'security_level' => 0,
56+
]]);
57+
$client = stream_socket_client("tcp://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);
58+
if ($client) {
59+
stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
60+
}
61+
62+
$result = phpt_wait();
63+
echo trim($result);
64+
CODE;
65+
$clientCode = sprintf($clientCode, $clientCertFile);
66+
67+
include 'CertificateGenerator.inc';
68+
69+
// Generate CA and client certificate signed by that CA
70+
$certificateGenerator = new CertificateGenerator();
71+
$certificateGenerator->saveCaCert($caCertFile);
72+
$certificateGenerator->saveNewCertAsFileWithKey('Bug80770 Test Client', $clientCertFile);
73+
74+
include 'ServerClientTestCase.inc';
75+
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
76+
?>
77+
--CLEAN--
78+
<?php
79+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug80770_client.pem.tmp');
80+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug80770_ca.pem.tmp');
81+
?>
82+
--EXPECTF--
83+
CLIENT_CERT_CAPTURED

ext/openssl/xp_ssl.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,8 @@ static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_pat
13241324
}
13251325
/* }}} */
13261326

1327-
static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
1327+
static zend_result php_openssl_enable_server_sni(
1328+
php_stream *stream, php_openssl_netstream_data_t *sslsock, bool verify_peer)
13281329
{
13291330
zval *val;
13301331
zval *current;
@@ -1445,6 +1446,12 @@ static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl
14451446
return FAILURE;
14461447
}
14471448

1449+
if (!verify_peer) {
1450+
php_openssl_disable_peer_verification(ctx, stream);
1451+
} else if (FAILURE == php_openssl_enable_peer_verification(ctx, stream)) {
1452+
return FAILURE;
1453+
}
1454+
14481455
sslsock->sni_certs[i].name = pestrdup(ZSTR_VAL(key), php_stream_is_persistent(stream));
14491456
sslsock->sni_certs[i].ctx = ctx;
14501457
++i;
@@ -1455,7 +1462,6 @@ static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl
14551462

14561463
return SUCCESS;
14571464
}
1458-
/* }}} */
14591465

14601466
static void php_openssl_enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
14611467
{
@@ -1547,6 +1553,7 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
15471553
char *cipherlist = NULL;
15481554
char *alpn_protocols = NULL;
15491555
zval *val;
1556+
bool verify_peer = false;
15501557

15511558
if (sslsock->ssl_handle) {
15521559
if (sslsock->s.is_blocked) {
@@ -1594,8 +1601,11 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
15941601

15951602
if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) {
15961603
php_openssl_disable_peer_verification(sslsock->ctx, stream);
1597-
} else if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) {
1598-
return FAILURE;
1604+
} else {
1605+
verify_peer = true;
1606+
if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) {
1607+
return FAILURE;
1608+
}
15991609
}
16001610

16011611
/* callback for the passphrase (for localcert) */
@@ -1694,7 +1704,7 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
16941704

16951705
#ifdef HAVE_TLS_SNI
16961706
/* Enable server-side SNI */
1697-
if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock) == FAILURE) {
1707+
if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock, verify_peer) == FAILURE) {
16981708
return FAILURE;
16991709
}
17001710
#endif

0 commit comments

Comments
 (0)