Supporting TLS client certificate in PHP?
Côme Chilliet
come at chilliet.eu
Sun Dec 20 21:15:34 GMT 2020
Le dimanche 13 décembre 2020, 18:28:38 CET Jansen Price a écrit :
> I ran into the same problem when trying to add client certificate support
> on my PHP server (https://tildegit.org/sumpygump/orbit)
>
> I think that `capture_peer_cert` is intended to only work
> with stream_socket_client and not with socket servers. I started looking at
> the source code of PHP to see if I could find the part that handles the TLS
> handshake to find out if there is any way to get access to the cert that
> came along with the connection, but I have not been successful in my search
> yet.
So, I found something, it does work if you set verify_peer to true in the ssl context options.
The problem is that if you do so, a request without a client certificate will fail, even before you can know what is the request.
I’m not sure if you can change the context once a connection is accepted, if yes maybe you can attempt stream_socket_enable_crypto once with verify_peer and if it fails run it again without it, but it feels non-optimized.
This is related to the openssl behavior of https://www.openssl.org/docs/man1.1.1/man3/SSL_get_peer_certificate.html
It says: "Due to the protocol definition, a TLS/SSL server will always send a certificate, if present. A client will only send a certificate when explicitly requested to do so by the server (see SSL_CTX_set_verify(3))."
According to https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_verify.html , a client certificate request is sent by the server only if SSL_VERIFY_PEER is set, which php will only set if verify_peer is true.
However, even if I was implementing this in C it is not clear to me how to request a client certificate without making it mandatory, is that what SSL_VERIFY_CLIENT_ONCE is for?
Are there Gemini servers in C with client certificate support of which I could read the code out there?
Côme
More information about the Gemini
mailing list