Boost ASIO: SSL handshake() никогда не завершается

У меня есть клиентское приложение C++, которое использует Boost ASIO для создания SSL-подключений к различным серверам. Но против 2-х конкретных серверов SSL-соединение не может быть установлено. Он зависает при вызове boost::asio::ssl::stream::handshake().

Я использовал Wireshark для наблюдения за диалогом между клиентом и сервером. Работающее SSL-соединение, кажется, делает это:

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 работает нормально.

Но для 2 разных серверов [*] рукопожатие выглядит так:

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

Глядя на лог-файлы на этих серверах, создается впечатление, что после того, как в рукопожатии были отправлены начальные 209 байт, сервер считал SSL-соединение полностью установлен. Но клиент все еще находится в вызове Boost ASIO handshake() и в конечном итоге возвращает ec=104 при сбросе соединения.

Итак, я думаю, может быть, есть разные типы рукопожатий SSL, и, может быть, есть «более простой» вариант, который мне следует использовать?

[*] Я знаю, что кому-то будет интересно узнать: один из серверов, вызывающих эту проблему с клиентским приложением, — это FileZilla Server для Windows, настроенный на использование SSL/TLS [FTPS], а другой — проприетарная служба, работающая в Linux. .)


ОБНОВЛЕНИЕ: Сэм Миллер попросил меня опубликовать мой код, описывающий настройку контекста ssl:

Класс (.hpp) содержит это:

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;

Конструктор имеет эти инициализаторы:

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 и зависает рукопожатие:

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";
14
задан Stéphane 4 March 2012 в 18:10
поделиться