七、asio的SSL


Asio 包含用於基本 SSL 支持的類和類模板。 這些類允許在現有流(例如 TCP 套接字)之上進行加密通信。

在創建一個加密流之前,應用必須構造一個SSL上下文對象。這個對象用來設置SSL選項,例如認證方式,證書文件等等。舉個例子,客戶端的初始化看起來如下:

ssl::context ctx(ssl::context::sslv23);
ctx.set_verify_mode(ssl::verify_peer);
ctx.load_verify_file("ca.pem");

要在 TCP 套接字中使用 SSL,可以這樣寫:

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

要執行特定於套接字的操作,例如建立出站連接或接受傳入連接,必須首先使用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_context);
ssl::stream<ip::tcp::socket&> ssl_sock(sock, ctx);

SSL 握手必須在通過加密連接傳輸或接收數據之前執行。 這是使用 ssl::stream 模板的 handshake() async_handshake() 成員函數來完成的。

一旦連接,SSL 流對象將用作同步或異步讀寫流。 這意味着對象可以與任何 read()、async_read()、write()、async_write()、read_until() async_read_until() 自由函數一起使用。

證書認證

Asio 提供了多種方法來配置 SSL 證書的驗證方式:

  • ssl::context::set_default_verify_paths()
  • ssl::context::set_verify_mode()
  • ssl::context::load_verify_file()
  • ssl::stream::set_verify_mode()
  • ssl::stream::set_verify_callback()

為了簡化根據 RFC 6125(傳輸層安全上下文中的身份驗證)中的規則驗證證書的使用場景,Asio 提供了一個可重用的驗證回調作為函數對象:

  • ssl::host_name_verification

以下示例顯示了根據 HTTPS 使用的規則驗證遠程主機的證書:

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

// 使用CE證書的默認路徑創建上下文
ssl::context ctx(ssl::context::sslv23);
ctx.set_default_verify_paths();

// 打開一個套接字並連接到遠程主機
boost::asio::io_context io_context;
ssl_socket sock(io_context, ctx);
tcp::resolver resolver(io_context);
tcp::resolver::query query("host.name", "https");
boost::asio::connect(sock.lowest_layer(), resolver.resolve(query));
sock.lowest_layer().set_option(tcp::no_delay(true));

// 執行SSL握手並認證遠程主機的證書
sock.set_verify_mode(ssl::verify_peer);
sock.set_verify_callback(ssl::host_name_verification("host.name"));
sock.handshake(ssl_socket::client);

// ... read and write as normal ...

SSL和Threads

SSL 流對象不執行自己的鎖定。 因此,所有異步 SSL 操作都必須在隱式或顯式strand中執行。 請注意,這意味着在單線程程序中不需要同步(因此不會產生鎖定開銷)。

需要 OpenSSL 才能使用 Asio 的 SSL 支持。 當應用程序需要使用 Asio 未封裝的 OpenSSL 功能時,可以通過調用ssl::context::native_handle()ssl::stream::native_handle() 獲取底層 OpenSSL 類型。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM