Boost ASIO:SSL握手()从未完成 [英] Boost ASIO: SSL handshake() never finishes

查看:905
本文介绍了Boost ASIO:SSL握手()从未完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C + +客户端应用程序,使用Boost ASIO来建立到各种服务器的SSL连接。但是对于2个特定的服务器,无法建立SSL连接。它挂在调用 boost :: asio :: ssl :: stream :: handshake()

I have a C++ client app that uses Boost ASIO to make SSL connections to various servers. But against 2 specific servers, the SSL connection cannot be established. It hangs in the call to boost::asio::ssl::stream::handshake().

我使用Wireshark观察客户端和服务器之间的对话。一个有效的SSL连接似乎这样做:

I've used Wireshark to observe the conversation between client and server. A working SSL connection seems to do this:

sslsocket.lowest_layer().connect( endpoint, ec );
C ->    SYN    -> S
C <-  SYN ACK  <- S
C ->    ACK    -> S
sslsocket.handshake( SSLSocket::client, ec );
C -> 209 bytes -> S
C <- 690 bytes <- S
C -> 198 bytes -> S
C <- 415 bytes <- S

...指向ASIO handshake()调用返回指示一切正常,并且SSL套接字连接正常。

...and at this point the ASIO handshake() call returns indicating all is well, and the SSL socket connection works fine.

但是对于两个不同的服务器[*],握手看起来像这样:

But against 2 different servers [*], the handshake looks like this:

sslsocket.lowest_layer().connect( endpoint, ec );
C ->    SYN    -> S
C <-  SYN ACK  <- S
C ->    ACK    -> S
sslsocket.handshake( SSLSocket::client, ec );
C -> 209 bytes -> S
...2 minute pause...
C <-    RST    <- S


b $ b

查看这些服务器上的日志文件,似乎在握手中发送了最初的209个字节后,服务器认为SSL连接已完全建立。但是客户端仍然坐在Boost ASIO handshake()调用中,并且在连接重置时最终返回ec = 104。

Looking at log files on these servers, it seems as if after the initial 209 bytes are sent in the handshake, the server considered the SSL connection fully established. But the client is still sitting in the Boost ASIO handshake() call, and eventually returns ec=104 when the connection is reset.

所以我想可能有不同类型的SSL握手,也许有一个我应该使用的更简单的一个?

So I'm thinking maybe there are different types of SSL handshakes, and maybe there is a "simpler" one I should be using?

[*]我知道有人想知道:导致客户端应用程序的这个问题是FileZilla Server for Windows设置使用SSL / TLS [FTPS],另一个是在Linux上运行的专有服务。)

[*] I know someone will want to know: one of the servers causing this problem with the client app is FileZilla Server for Windows setup to use SSL/TLS [FTPS], and the other is a proprietary service running on Linux.)

更新:Sam Miller要求我发布我的代码描述如何设置ssl上下文:

UPDATE: Sam Miller asked that I post my code describing how the ssl context is setup:

类(.hpp文件)这:

Class (.hpp file) contains this:

typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLSocket;
boost::asio::io_service    ioservice;
boost::asio::ssl::context  sslcontext;
SSLSocket                  sslDataSocket;
boost::system::error_code  ec;

构造函数具有以下初始值:

Constructor has these initializers:

ioservice      ( 2 ),
sslcontext     ( ioservice, boost::asio::ssl::context::sslv23 ),
sslDataSocket  ( ioservice, sslcontext ),

...和此代码:

sslcontext.set_options( boost::asio::ssl::context::default_workarounds |
                        boost::asio::ssl::context::verify_none         );

这是SSL套接字建立并握手挂起的代码:

And this is the code where the SSL socket is established and the handshake hangs:

std::cout << "connecting SSL socket to endpoint " << buffer << std::endl;
sslDataSocket.lowest_layer().connect( tcpEndpoint, ec );
std::cout << "connect() done, ec=" << ec.value() << std::endl;
if ( ec ) throw "test 1";

std::cout << "starting ssl handshake" << std::endl;
sslDataSocket.handshake( SSLSocket::client, ec );
std::cout << "handshake done, ec=" << ec.value() << std::endl;
if ( ec ) throw "test 2";


推荐答案

此SSL教程( http://h71000.www7.hp.com/doc/83final/ba554_90007/ ch04s03.html )包含了最终为我工作的关键。

I figured it out. This SSL tutorial (http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html) contained the key that finally got this working for me. Quote:


您可以重复使用已建立的SSL会话
中的信息来创建新的SSL连接。因为新的SSL连接是
重用相同的主密钥,所以SSL握手可以更快地执行
。因此,SSL会话恢复可以减少正在接受许多SSL连接的服务器的负载

You can reuse the information from an already established SSL session to create a new SSL connection. Because the new SSL connection is reusing the same master secret, the SSL handshake can be performed more quickly. As a result, SSL session resumption can reduce the load of a server that is accepting many SSL connections.

是我如何使用Boost ASIO:

So here is how I got this working with Boost ASIO:


  • 设置普通的SSL控制插座(很多例子,包括这个问题)


    sslSocket2.lowest_layer().connect( tcpEndpoint, ec );
    SSLSocket::impl_type impl1 = sslSocket1.impl();
    SSLSocket::impl_type impl2 = sslSocket2.impl();
    SSL_SESSION *savedSession = SSL_get1_session( impl1->ssl );
    SSL_set_session( impl2->ssl, savedSession );
    SSL_connect( impl2->ssl );

就是这样。此时,无需调用sslSocket2.handshake()。只要读取和写入套接字知道连接已经建立。

That's it. At this point, no need to call sslSocket2.handshake(). Just read and write to the socket knowing the connection has been established.

这篇关于Boost ASIO:SSL握手()从未完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆