Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions ext/openssl/tests/session_resumption_cache_disabled.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
--TEST--
TLS session resumption - server with cache disabled
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!function_exists("proc_open")) die("skip no proc_open");
?>
--FILE--
<?php
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_cache_disabled.pem.tmp';

$serverCode = <<<'CODE'
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
$ctx = stream_context_create(['ssl' => [
'local_cert' => '%s',
'session_cache' => false, /* Disable session caching */
]]);

$server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
phpt_notify_server_start($server);

/* Accept two connections */
for ($i = 0; $i < 2; $i++) {
$client = @stream_socket_accept($server, 30);
if ($client) {
fwrite($client, "No cache connection " . ($i + 1) . "\n");
fclose($client);
}
}

phpt_notify(message: "CACHE_DISABLED_TEST_DONE");
CODE;
$serverCode = sprintf($serverCode, $certFile);

$clientCode = <<<'CODE'
$sessionData = null;

$flags = STREAM_CLIENT_CONNECT;
$ctx = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_new_cb' => function($stream, $sessionId, $data) use (&$sessionData) {
$sessionData = $data;
}
]]);

/* First connection */
$client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);
if ($client1) {
echo trim(fgets($client1)) . "\n";
fclose($client1);
}

/* Second connection - server won't use cached session */
$ctx2 = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_data' => $sessionData,
]]);

$client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2);
if ($client2) {
echo trim(fgets($client2)) . "\n";
fclose($client2);
}

$result = phpt_wait();
echo trim($result) . "\n";
CODE;

include 'CertificateGenerator.inc';
$certificateGenerator = new CertificateGenerator();
$certificateGenerator->saveNewCertAsFileWithKey('session_disabled_test', $certFile);

include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
?>
--CLEAN--
<?php
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_cache_disabled.pem.tmp');
?>
--EXPECTF--
No cache connection 1
No cache connection 2
CACHE_DISABLED_TEST_DONE
91 changes: 91 additions & 0 deletions ext/openssl/tests/session_resumption_client_basic.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
--TEST--
TLS session resumption - client basic resumption
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!function_exists("proc_open")) die("skip no proc_open");
?>
--FILE--
<?php
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_resumption_client.pem.tmp';

$serverCode = <<<'CODE'
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
$ctx = stream_context_create(['ssl' => [
'local_cert' => '%s',
]]);

$server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
phpt_notify_server_start($server);

/* Accept two connections */
for ($i = 0; $i < 2; $i++) {
$client = @stream_socket_accept($server, 30);
if ($client) {
fwrite($client, "Hello from server\n");
fclose($client);
}
}
CODE;
$serverCode = sprintf($serverCode, $certFile);

$clientCode = <<<'CODE'
$sessionData = '';
$sessionReceived = false;

$flags = STREAM_CLIENT_CONNECT;
$ctx = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_new_cb' => function($stream, $sessionId, $sessionDataArg) use (&$sessionReceived, &$sessionData) {
$sessionData = $sessionDataArg;
$sessionReceived = true;
}
]]);

/* First connection - full handshake */
$client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);
if ($client1) {
$response = fgets($client1);
echo "First connection: " . trim($response) . "\n";
fclose($client1);
}

var_dump($sessionReceived);
var_dump(strlen($sessionData) > 0);

/* Second connection - resumed session */
$ctx2 = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_data' => $sessionData,
]]);

$client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2);
if ($client2) {
$response = fgets($client2);
echo "Second connection: " . trim($response) . "\n";
fclose($client2);
}

echo "Session resumption test completed\n";
CODE;

include 'CertificateGenerator.inc';
$certificateGenerator = new CertificateGenerator();
$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile);

include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
?>
--CLEAN--
<?php
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_resumption_client.pem.tmp');
?>
--EXPECTF--
First connection: Hello from server
bool(true)
bool(true)
Second connection: Hello from server
Session resumption test completed
75 changes: 75 additions & 0 deletions ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
--TEST--
TLS session resumption - warning when trying to enable tickets with session_get_cb
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!function_exists("proc_open")) die("skip no proc_open");
?>
--FILE--
<?php
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_no_ticket.pem.tmp';

$serverCode = <<<'CODE'
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;

/* Trying to enable tickets with external cache - should warn */
$ctx = stream_context_create(['ssl' => [
'local_cert' => '%s',
'session_context_id' => 'test-app',
'no_ticket' => false, // Explicitly trying to enable tickets
'session_new_cb' => function($stream, $sessionId, $sessionData) {
// Store session
},
'session_get_cb' => function($stream, $sessionId) {
return null;
}
]]);

$server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
phpt_notify_server_start($server);

$client = @stream_socket_accept($server, 30);
if ($client === false) {
phpt_notify(message: "SERVER_FAILED_AS_EXPECTED");
} else {
phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY");
fclose($server);
}
CODE;
$serverCode = sprintf($serverCode, $certFile);

$clientCode = <<<'CODE'
$flags = STREAM_CLIENT_CONNECT;

/* Try to use corrupted session data */
$ctx = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_data' => 'this_is_invalid_session_data',
]]);

$client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);

if ($client === false) {
echo "Connection failed as expected\n";
}

$result = phpt_wait();
echo trim($result) . "\n";
CODE;

include 'CertificateGenerator.inc';
$certificateGenerator = new CertificateGenerator();
$certificateGenerator->saveNewCertAsFileWithKey('session_no_ticket_test', $certFile);

include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
?>
--CLEAN--
<?php
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_no_ticket.pem.tmp');
?>
--EXPECT--
Connection failed as expected
SERVER_FAILED_AS_EXPECTED
60 changes: 60 additions & 0 deletions ext/openssl/tests/session_resumption_invalid_callback.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
--TEST--
TLS session resumption - invalid callback throws TypeError
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!function_exists("proc_open")) die("skip no proc_open");
?>
--FILE--
<?php
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_invalid_cb.pem.tmp';

$serverCode = <<<'CODE'
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
$ctx = stream_context_create(['ssl' => [
'local_cert' => '%s',
]]);

$server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
phpt_notify_server_start($server);

$client = @stream_socket_accept($server, 30);
if ($client) {
fclose($client);
}
CODE;
$serverCode = sprintf($serverCode, $certFile);

$clientCode = <<<'CODE'
$flags = STREAM_CLIENT_CONNECT;

/* Try to use invalid callback */
$ctx = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_new_cb' => 'not_a_valid_function',
]]);

try {
$client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);
echo "Should not reach here\n";
} catch (TypeError $e) {
echo "TypeError caught: " . (strpos($e->getMessage(), 'session_new_cb must be a valid callback') !== false ? "YES" : "NO");
echo "\n";
}
CODE;

include 'CertificateGenerator.inc';
$certificateGenerator = new CertificateGenerator();
$certificateGenerator->saveNewCertAsFileWithKey('session_invalid_cb_test', $certFile);

include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
?>
--CLEAN--
<?php
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_invalid_cb.pem.tmp');
?>
--EXPECTF--
TypeError caught: YES
64 changes: 64 additions & 0 deletions ext/openssl/tests/session_resumption_invalid_data.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
--TEST--
TLS session resumption - invalid session data is fatal
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!function_exists("proc_open")) die("skip no proc_open");
?>
--FILE--
<?php
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_invalid.pem.tmp';

$serverCode = <<<'CODE'
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
$ctx = stream_context_create(['ssl' => [
'local_cert' => '%s',
]]);
$server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
phpt_notify_server_start($server);
$client = @stream_socket_accept($server, 30);
if ($client) {
fclose($client);
}
CODE;
$serverCode = sprintf($serverCode, $certFile);

$clientCode = <<<'CODE'
$flags = STREAM_CLIENT_CONNECT;
/* Try to use corrupted session data */
$ctx = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'session_data' => 'this_is_invalid_session_data',
]]);
$client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);
if ($client === false) {
echo "Connection failed as expected\n";
}
CODE;

include 'CertificateGenerator.inc';
$certificateGenerator = new CertificateGenerator();
$certificateGenerator->saveNewCertAsFileWithKey('session_invalid_test', $certFile);

include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
?>
--CLEAN--
<?php
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_invalid.pem.tmp');
?>
--EXPECTF--

Warning: stream_socket_client(): Invalid or corrupted session_data, falling back to full handshake in %s on line %d

Warning: stream_socket_client(): Failed to enable crypto in %s on line %d

Warning: stream_socket_client(): Unable to connect to %s in %s on line %d
Connection failed as expected
Loading
Loading