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