Hello,
It seems that is does not work to pass option capture_peer_cert to
stream_socket_server context in order to get the client certificate used in the
TLS handshake.
Is that how it is supposed to work, and is it broken?
I tried the following:
$context = stream_context_create(
[
'ssl' => [
'allow_self_signed' => true,
'SNI_enabled' => true,
'SNI_server_certs' => ['example.com' => '/path/to/cert.pem'],
'capture_peer_cert' => true,
]
]
);
$socket = stream_socket_server(
'tcp://[::]:' . $port,
$errno,
$errstr,
STREAM_SERVER_BIND
| STREAM_SERVER_LISTEN,
$context,
);
if ($socket === false) {
throw new \Exception($errstr, $errno);
} else {
while ($conn = stream_socket_accept($socket, -1, $peername)) {
$tlsSuccess = stream_socket_enable_crypto(
$conn,
true,
STREAM_CRYPTO_METHOD_TLS_SERVER
);
if ($tlsSuccess !== true) {
fclose($conn);
continue;
}
var_dump(stream_context_get_options($conn));
}
}
No peer_certificate option is created when a client connects with a certificate.
Despite what https://www.php.net/manual/en/context.ssl.php says.
This is a problem for implementing client certificate support into Gemini
servers written in PHP, such as https://tildegit.org/sumpygump/orbit and
https://framagit.org/MCMic/gemini-server
Côme