OpenSSL SSL_CTX_NEW返回"null ssl method passed"



代码:TIdSSLIOHandlerSocketOpenSSL( ASMTP.IOHandler ).SSLOptions.SSLVersions := [sslvSSLv2,sslvSSLv23,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]

似乎问题出在方法TIdSSLOptions上。SetSSLVersions,如果您设置除了单个版本之外的任何内容,它将设置fMethod := sslvSSLv23。如果不可用,则使用TIdSSLContext。SetSSLMethod返回nil,你会得到这个错误。

Indy Dec-2015, TIdSSLContext。SetSSLMethod可以返回nil。解决方案恢复。

什么问题?没有,希望有人觉得有用。

这是一个问答网站。分享知识是可以的,但必须是Q& a格式。我能回答我自己的问题吗?

无论如何,这听起来更像是一个错误报告,应该报告给Indy的问题跟踪器,而不是公共论坛。

也就是说,你永远不应该启用SSLv2或SSLv3协议,因为它们不再安全,甚至在许多OpenSSL版本中都不再可用。并且SSLv23只是一个通配符,它意味着仅在Method属性中使用,而不是在SSLVersions属性中使用(事实上,如果您尝试使用任何其他版本指定它,它将被忽略)。您应该在SSLVersions中只使用TLSv1+协议,让Indy根据需要在内部处理SSLv23。

TIdSSLIOHandlerSocketOpenSSL( ASMTP.IOHandler ).SSLOptions.SSLVersions := [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]

似乎问题出在方法TIdSSLOptions上。SetSSLVersions,如果你设置的不是一个版本,它会设置fMethod:= sslvSSLv23。

应该是这样的,因为SSLv23方法是OpenSSL在SSL/TLS握手期间启用动态版本协商的方式,允许客户端和服务器协商它们都支持的最高TLS版本。否则,如果客户端只使用特定版本,而服务器不支持该版本,则TLS握手将失败。

如果不可用,则TIdSSLContext。SetSSLMethod返回nil,你会得到这个错误。

首先,SetSSLMethod()永远不会将nil返回给SSL_CTX_new()。如果所请求的方法不被OpenSSL支持,SetSSLMethod()会抛出EIdOSSLGetMethodError异常。

第二,这个条件意味着你不能进行版本协商,所以你必须使用一个特定的TLS版本。例外是故意的,让你知道你要求协商,但你的OpenSSL版本不支持它,所以尝试其他方法。

最简单的解决方法是在设置SSLVersions

之后设置Method

MethodSSLVersions属性是互斥的,设置一个属性会更新另一个属性。然而,Method是不赞成的,你真的应该只使用SSLVersions,即使是单个TLS版本。

也可能不存在,所以更好的解决方法可能是在indy:

当请求SSLv23时,您的解决方法完全禁用版本协商。对于Indy来说,这不是一个可行的选择。

真正的解决方法是让您自己的代码在SSLv23不可用时捕获EIdOSSLGetMethodError异常,然后您可以根据需要使用单个TLS版本重新尝试连接。不需要修改Indy的代码。

最新更新