如何使Indy OpenSSL与大多数服务器兼容

时间:2014-02-28 17:24:16

标签: openssl indy indy10

我使用以下代码为POP3 / SMTP发送/接收应用设置SSLHandler:

IdSSLHandler->SSLOptions->Mode        = sslmClient;
IdSSLHandler->SSLOptions->Method      = slvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;

因此,上述代码应该自动支持SSL 3,TLS 1,TLS 1.1和TLS 1.2。这不能很好地报告“错误的版本”错误。删除SSLVersions行后,它会正常工作,但默认情况下它包含我不想支持的sslvSSLv2。它是一样的:

IdSSLHandler->SSLOptions->Mode        = sslmClient;
IdSSLHandler->SSLOptions->Method      = slvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv2 << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;

由于某种原因,这可行,而上述不在同一台服务器上。我知道slvSSLv23是一种“使用任何可用版本”的值。那么为什么它不适用于版本2不存在的上述代码?

此外,我可以使用似乎广泛部署的TSL1,但如果服务器支持1.1或1.2,那么我的代码将不会使用更新版本,但会强制使用1.0版本,除非使用上述内容。

我想按照以下目标进行初始化:

  • 与所有服务器兼容,无论他们使用的是v3,tls1,tls1.1还是tls1.2
  • 自动使用最新版本并使用较低版本,如果服务器上没有更新版本但不低于版本3 - 如果版本低于3则失败/异常

我认为代码的第一个版本会提供,但它会报告版本错误。上述目标是否可行,或者必须提供用户设置才能选择要使用的SSL版本?

1 个答案:

答案 0 :(得分:7)

SSLVersions设置为单个值会自动将Method设置为相应的单个版本。将SSLVersions设置为多个值会自动将Method设置为slvSSLv23

Method设置为单个版本会自动将SSLVersions设置为相应的单个值。将Method设置为slvSSLv23会自动将SSLVersions设置为所有支持的值。

Indy根据SSL_OP_NO_SSL_v#SSL_OP_NO_TLS_v#的值激活/停用OpenSSL中相应的MethodSSLVersions标记。

我建议采用以下方法,随着新TLS版本的添加,这是一个稍微更具未来的证据:

IdSSLHandler->SSLOptions->Method      = sslvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = IdSSLHandler->SSLOptions->SSLVersions >> sslvSSLv2;

无论哪种方式,Indy都会使用SSLv23而只激活SSL_OP_NO_SSL_v2标志。

在该配置中,“错误版本”错误通常意味着服务器使用的是不支持版本协商的特定版本(使用与SSLv2兼容的客户端问候语)。换句话说,连接到TLSv1服务器的SSLv23客户端将失败。服务器必须使用SSLv23才能支持版本协商。在服务器上使用SSLv23允许它接受任何版本客户端,因为客户端启动握手,因此服务器可以查看正在使用的版本标头。但是在客户端上使用SSLv23并不允许它连接到除SSLv23服务器之外的任何服务器。 SSLv2服务器只能接受SSLv2客户端,SSLv3服务器只能接受SSLv3客户端,TLSv1服务器只能接受TLSv1客户端,等等。

要真正连接到“任何”服务器,您必须检测“错误版本”错误,然后使用其他特定Method / SSLVersions配置重试。不幸的是,“错误版本”回复不包括服务器的实际版本,因此您必须使用反复试验。如果SSLv23失败,请尝试TLSv1_2。如果失败,请尝试TLSv1_1。如果失败,请尝试TLSv1。如果失败,请尝试SSLv3。

相关问题