Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
--TEST--
TLS session resumption - num_tickets controls ticket generation (TLS 1.3)
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!function_exists("proc_open")) die("skip no proc_open");
?>
--FILE--
<?php
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_num_tickets.pem.tmp';

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

// Test with num_tickets = 3 (should issue 3 tickets)
$ctx = stream_context_create(['ssl' => [
'local_cert' => '%s',
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER,
'num_tickets' => 3, // Issue 3 tickets per connection
]]);

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

// Accept one connection
$client = @stream_socket_accept($server, 30);
if ($client) {
fwrite($client, "Ticket test\n");
// Keep connection open briefly to allow tickets to be sent
usleep(100000); // 100ms
fclose($client);
}

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

$clientCode = <<<'CODE'
$ticketCount = 0;

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

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

// Keep connection open briefly to receive all tickets
usleep(150000); // 150ms
fclose($client);
}

echo "Tickets received: $ticketCount\n";

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

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

include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
?>
--CLEAN--
<?php
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_num_tickets.pem.tmp');
?>
--EXPECTF--
Ticket test
Tickets received: 3
SERVER_DONE
Loading