我的情况不同。我使用 boost::asio::ssl
编写了一个 SSL 客户端但目前没有服务器可以测试,因为它是由其他组开发的。所以目前的服务器只接受纯 TCP(不安全)连接。当我对服务器使用我的 ssl 客户端时,阻塞 handshake()
挂起/永不返回。我在网上搜索了一下,发现 Mozilla 也有类似的问题——它在启动与不支持 SSL 的服务器的 SSL 连接时挂起,但他们的错误已修复。我只会对我的部分代码进行解释,以确保没有编码错误:
在ctor
:
SecuredConnectionPolicy<ThreadPolicy>::SecuredConnectionPolicy() :
m_sslContext(boost::asio::ssl::context::sslv23),
m_socket(m_ioService, m_sslContext) //ssl::stream<tcp::socket>
{
}
然后当我的“connect
(...)”被调用时:
m_sslContext.set_options(boost::asio::ssl::context::default_workarounds);
m_sslContext.set_verify_mode(
boost::asio::ssl::context::verify_none,
errorCode
);
if(!errorCode)
{
/*m_sslContext.set_verify_callback(
[this](bool bIsPreverificationSuccessful, boost::asio::ssl::verify_context &context){return this->verificationHandler(bIsPreverificationSuccessful, context);},
errorCode
);*/
if(!errorCode)
{
m_sslContext.load_verify_file("newcert.pem", errorCode);
if(!errorCode)
{
m_socket.lowest_layer().connect(remoteEndpoint, errorCode);
if(!errorCode)
{ // ########### Following NEVER RETURNS #############
m_socket.handshake(boost::asio::ssl::stream_base::client, errorCode);
if(errorCode)
{
std::cerr << "Secured Connection Handshake Failed! " << errorCode.message() << std::endl;
}
}
else
{
std::cerr << "Secured Connection Failed! " << errorCode.message() << std::endl;
}
}
else
{
std::cerr << "Secured Connection loading certificate files from default paths Failed! " << errorCode.message() << std::endl;
}
}
else
{
std::cerr << "Registering Verification callback failed! " << errorCode.message() << std::endl;
}
}
else
{
std::cerr << "Secured Connection verify mode Failed! " << errorCode.message() << std::endl;
}
可能是什么原因?我做错了什么吗?
我没有提供任何 verify_callback 处理程序,因为我假设由 OpenSSL 完成的预验证(因为在 boost 中到处都说它正在调用 OpenSSL 等效函数)应该足够了。它有什么缺点或者这会影响 <1> 吗?
这是一个微不足道的问题,但只是为了确保它不会引起问题:一般情况下,boost 中的示例表明 ssl 上下文对象在给
ssl::stream<tcp::socket>
的构造函数之前已经设置好了。 .然而,我之前(在上面的 ctor 中)给出了它,后来在connect()
中更改了属性。 .这些是否会反射(reflect)在构造的 ssl::stream 的行为中(因为它通过引用获取,我希望它不会制作任何拷贝)?
附带说明(如果它有用的话),我创建了一个 CA rootKey、CA 自签名 PEM 证书、由 CA 证书签名的服务器证书。 CA 证书是我给 load_verify_file(...)
的证书.
最佳答案
您选择调用一个阻塞直到完成或失败的操作,它既不执行也不执行,因此它永远阻塞。如果您不想在操作确定成功或失败时一直阻塞,请不要调用专门记录的操作来执行此操作。
如果您在另一端从不写入的连接上执行阻塞读取,您期望发生什么?它会永远阻塞。在这里,您在另一端永远不会与您握手的连接上进行了阻塞握手。您的代码会一直等到它完成,就像您要求的那样。
关于c++ - Boost Asio SSL 握手永远不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15354737/