php 获取gemini服务器的stream_socket_server中的客户端证书,但未将verify_peer设置为true

aemubtdh  于 9个月前  发布在  PHP
关注(0)|答案(1)|浏览(91)

我想用PHP写一个gemini服务器。
为了让它在任何情况下都能正常工作,我需要获得客户端证书,如果客户端发送的话。
如果我像这样创建上下文和套接字

$context = stream_context_create(options: [
  'ssl' => [
    'local_cert' => "path/to/file",
    'local_pk' => "path/to/key",

    'allow_self_signed' => true,
    'verify_peer' => false,
    'capture_peer_cert' => true,
  ],
]);

$socket = stream_socket_server(
  address: "tls://localhost:1965",
  context: $context
);

字符串
我可以接受这样的关系

$connection = stream_socket_accept(
  socket: $socket,
  timeout: -1,
  peer_name: $peer
);


连接可以建立而不会出错。但是当客户端发送证书时,我无法获得它,因为上下文参数中的peer_certificate没有设置。

$streamParams = stream_context_get_params($resource);
$clientCertificate = $streamParams['options']['ssl']['peer_certificate'] ?? null; # always null


当我将verify_peer设置为true时,则peer_certificate被设置为OpenSSLCertificate对象。但是来自客户端的请求没有证书,导致false$connection和以下错误:

Warning: stream_socket_accept(): Could not get peer certificate in [...]
Warning: stream_socket_accept(): Failed to enable crypto in [...]
Warning: stream_socket_accept(): Accept failed: Success in [...]


我检查了gemini服务器的python实现,在python中有一个verify_mode可以设置为CERT_OPTIONAL
https://docs.python.org/3/library/ssl.html#ssl.CERT_OPTIONAL
我在PHP中找不到这样的东西。有没有一种方法可以选择性地获取客户端证书?

nhaq1z21

nhaq1z211#

如果verify_peer为false,则服务器将不会向客户端请求证书,客户端将不会发送证书,因此无法捕获证书。
似乎没有一种方法可以只请求客户端证书并在没有验证的情况下捕获它。还有一个关于此的公开错误-https://bugs.php.net/bug.php?id=80770-近3年未修复。
.在python中有一个verify_mode,您可以将其设置为CERT_OPTIONAL
这并不能解决证书验证的问题。它只是意味着即使客户端请求也不发送证书。但如果客户端发送证书,它必须仍然有效。

相关问题