SSL

Asio提供基础的类模板来支持SSL。这些类允许用户在已经存在的流顶层添加加密通信,比如在TCP socket上加密。

在创建加密流之前,应用必须要构造SSL上下文对象。这个对象被用来设置SSL选项,比如核实模块,文件证书等。客户端的初始化可能像这样实现:

ssl::context ctx(ssl::context::sslv23);
ctx.set_verify_mode(ssl::verify_peer);
ctx.set_verify_file("ca.pam");

在TCP上使用SSL,可以这样写:

ssl::stream<ip::tcp::socket> ssl_sock(my_io_service, ctx);

为了实现socket特有的操作,例如建立出站的连接或者接收外来的连接,底层的socket首先要使用ssl::stream的lowest_layer()函数:

ip::tcp::socket::lowest_layer_type& sock = ssl_sock.lowest_layer();
sock.connect(my_endpoint);

有的时候底层的流对象需要比SSL流更长的生存期,在这种情况下,模板的参数需要使用引用:

ip::tcp::socket sock(my_io_service);
ssl::stream<ip::tcp::socket&> ssl_sock(sock, ctx);

SSL握手必须要优先通过加密连接获取数据。这通过ssl::stream模板的handshake()和async_handshake()函数实现。

一旦连接成功,SSL流对象就变成了同步和异步的输入输出流。这意味着我们又可以用那些自由函数来读写了。

证书验证

Asio提供了多种方法来做SSL证书验证:

  • ssl::context::set_default_verify_paths()

  • ssl::context::set_verify_mode()

  • ssl::context::set_verify_callback()

  • ssl::context::load_verify_file()

  • ssl::stream::set_verify_mode()

  • ssl::stream::set_verify_callback()

为了简化RFC 2818规则(HTTPS的证书验证)的证书验证,Asio提供了一个可复用的验证回调,该回调是一个函数对象:

  • ssl::rfc2818_verification

下面的用例展示了远程主机如何做HTTPS验证:

using asio::ip::tcp;
namespace ssl = asio::ssl;
typedef ssl::stream<tcp::socket>

// Create a context that use the defualt paths for
// finding CA certification
ssl::context ctx(ssl::context::sslv23);
ctx.set_default_verify_paths();

// Open a socket and connect it to the remote host.
asio::io_service my_io_service;
ssl_socket sock(my_io_service, ctx);
tcp::resolver reslvr(my_io_service);
tcp::resolver::query qery("host.name", "https");
asio::connect(sock.lowest_layer(), reslvr.resolve(qery));
sock.lowest_layer().set_option(tcp::no_delay(true));

// Perform SSL handshake and verify the remote host's
// certification
sock.set_verify_mode(ssl::verify_peer);
sock.set_verify_callback(ssl::rfc2818_verification("host.name"));
sock.handshake(ssl_socket::client);

// ... read and write normal

SSL和线程

SSL流对象是无阻塞设计的,因此,所有的异步SSL操作都要放在一个显式或者隐式的strand里面。当心,这意味着我们不需要在单线程中使用同步事件。(译者注:同步事件会引起阻塞)。

参见

ssl::context, ssl::rfc2818_verification, ssl::stream, SSL example

注意

Asio的SSL需要OpenSSL库的支持,如果应用程序想要使用未被包装过的OpenSSL功能,可以调用ssl::context::native_handle()或者ssl::stream::native_handle()来设置上下文。

results matching ""

    No results matching ""