我正在为第三方客户端应用程序编写一个https服务器。我正在使用 pion c++网络库来实现服务器,

棘手的事情是:客户端使用 sslv2 ,但是pion使用 sslv23 作为上下文方法。这是构造函数:

server::server(...)
    : .....
    m_ssl_context(m_active_scheduler.get_io_service(),
                        boost::asio::ssl::context::sslv23), // <--- not configurable
    ....
{}

我了解sslv2存在安全问题,因此pion使用sslv23作为默认设置,但客户端仅使用 sslv2 。使用 sslv23 ,服务器在握手期间会抱怨“未知协议(protocol)”。

我不想修改pion源使其仅支持 sslv2 。我可以获得底层的 ssl::context 对象,如何对其进行修改以支持 sslv2

我查看了 boost / asio / ssl / impl / context.ipp ,ssl::context是不可复制,并且不能使用任何辅助功能。

任何的想法?

谢谢。

UPDATE_1 :

这是一些测试

测试1 :

我修改了pion源码并重新编译,只需注释掉 no_sslv2
    m_ssl_context.set_options(
        boost::asio::ssl::context::default_workarounds
        //| boost::asio::ssl::context::no_sslv2 <------ remove this
        | boost::asio::ssl::context::single_dh_use);

并使用sslv23(构造函数中有四个sslv23)
server::server(...)
    : .....
    m_ssl_context(m_active_scheduler.get_io_service(),
                        boost::asio::ssl::context::sslv23), // left it as sslv23
    ....
{}

它不起作用,提高error_code.message():
peer error no cipher

测试2 :

如果我不碰no_sslv2
    m_ssl_context.set_options(
        boost::asio::ssl::context::default_workarounds
        | boost::asio::ssl::context::no_sslv2 <------
        | boost::asio::ssl::context::single_dh_use);

并将四个sslv23更改为sslv2
server::server(...)
    : .....
    m_ssl_context(m_active_scheduler.get_io_service(),
                        boost::asio::ssl::context::sslv2), // change from sslv23 to sslv2
    ....
{}

然后就可以了我想这实际上是构造函数中的sslv23方法。在上下文的构造函数中:
context::context(context::method m)
  : handle_(0)
{
  switch (m)
  {
  ...
  case context::sslv2:
    handle_ = ::SSL_CTX_new(::SSLv2_method());
    break;
  ...
  case context::sslv23:
    handle_ = ::SSL_CTX_new(::SSLv23_method());
    break;
  }
  ....
}

SSLv23_method与SSLv2_method不兼容吗?

而且我认为客户端使用sslv2是因为我使用openssl对其进行了测试:

测试3 :
openssl s_server -accept 443 -key server.pem -cert server.pem -ssl2

这使openssl充当服务器,然后将客户端连接到它,效果很好。根据openssl的文档,结尾的 -ssl2 强制其使用sslv2。而且 -ssl3 -tls1 都不起作用,openssl说:“版本号错误”

UPDATE_2

我试过了,似乎也可以,不知道是否会引起内存泄漏。
    SSL_CTX_set_ssl_version( // use the native handle
        m_server_443->get_ssl_context_type().native_handle(), ::SSLv2_method()
    );

最佳答案

您的问题不在于显示的m_ssl_context的构造。 ssl::context::sslv23的规范意味着您的服务器接受SSLv2或更高版本以开始协商安全连接。禁止SSLv2的限制在同一文件中,但之后:

m_ssl_context.set_options(boost::asio::ssl::context::default_workarounds
                          | boost::asio::ssl::context::no_sslv2
                          | boost::asio::ssl::context::single_dh_use);

拒绝SSLv2连接的是ssl::context::no_sslv2选项。

您可以像这样重置这些选项:
SSL_CTX_clear_options(m_server->get_ssl_context_type().native_handle(), SSL_OP_NO_SSLv2)
SSL_CTX_set_cipher_list(m_server->get_ssl_context_type().native_handle(), "TLSv1:SSLv3:SSLv2");

这两行使用基础OpenSSL API来(1)清除no_sslv2成员函数中设置的set_ssl_key_file()选项,以及(2)确保启用了SSLv2密码。使用set_options()成员函数不起作用,因为它无法清除先前设置的选项,因此必须使用OpenSSL API函数SSL_CTX_clear_options()

奇怪的是,您有一个仅使用SSLv2的客户端,因为很长一段时间(将近20年!),该协议(protocol)都已被弃用为不安全的协议(protocol)。

10-08 06:41