您必须为您的 TIdSSLIOHandlerSocketOpenSSL 组件的 OnVerifyPeer 事件实现事件处理程序。
来自 IdSSLOpenSSL.pas:
请注意,您确实应该始终实现 OnVerifyPeer,否则不会检查您正在连接的对等方的证书以确保其有效。
如果您只想考虑有效的图书馆认为也有效的相同证书,您只需以这种方式实现它:
function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509;
AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
Result := AOk;
end;
由于 Indy 首先检查证书的有效性,并在 Aok 参数中将其传递给您。最后一句话在您的代码中,因为您可能希望通过一些小的验证错误,例如过期,或者甚至询问用户证书是否被接受以防出现任何错误(轻微或不) .
要了解它为什么会这样工作,您可能还需要阅读 IdSSLOpenSSL.pas 文件顶部的所有注释:
{
有关 OnVerifyPeer 的重要信息:2005 年 2 月的 Rev 1.39 故意破坏了 OnVerifyPeer 接口,它(显然?)只影响将回调作为 SSL 协商的一部分实现的程序。请注意,您确实应该始终实现 OnVerifyPeer,否则不会检查您正在连接的对等方的证书以确保其有效。
在此之前,如果 SSL 库检测到证书有问题或深度不足(即 VerifyCallback 中的“Ok”参数为 0 / FALSE),那么无论您的 OnVerifyPeer 返回 True 还是 False,SSL 连接都会故意失败。
这产生了一个问题,即即使链中的一个证书只有一个非常小的问题(对证书链中的每个证书调用一次 OnVerifyPeer),用户可能很乐意接受,SSL 协商会失败。但是,当用户为 OnVerifyPeer 返回 True 时更改代码以允许 SSL 连接将意味着依赖于自动拒绝无效证书的现有代码将接受无效证书,这将是不可接受的安全更改。
因此,OnVerifyPeer 被更改为通过添加 AOk 参数来故意破坏现有代码。要保留以前的功能,您的 OnVerifyPeer 事件应该执行“Result := AOk;”。如果您希望考虑接受 SSL 库认为无效的证书,那么在您的 OnVerifyPeer 中,确保您确信证书确实有效,然后将 Result 设置为 True。实际上,除了检查 AOk 之外,您还应该始终实现代码以确保您只接受有效的证书(至少从您的角度来看)。
Ciaran Costelloe, ccostelloe[_a_t_]flogas.ie
}
{
RLebeau 1/12/2011:再次中断 OnVerifyPeer 事件,这次添加了一个额外的 AError 参数(补丁由“jvlad”提供,dmda@yandex.ru)。这有助于用户代码区分自签名证书和无效证书。
}