IO完成端口和OpenSSL [英] IO Completion Ports and OpenSSL

查看:788
本文介绍了IO完成端口和OpenSSL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使用OpenSSL进行通信的旧代码。就像任何其他会话一样,它使用SSL功能进行握手,然后通过TCP进行加密通信。我们最近更改了我们的代码以使用IO完成端口。它的工作方式与OpenSSL的方式相反。基本上,我很难将我们的安全通信代码从完全OpenSSL使用迁移到IOCP套接字和OpenSSL加密。

I have some legacy code that uses OpenSSL for communication. Just like any other session it does a handshake using the SSL functions and then encrypted communication over TCP. We recently changed our code to use IO completion ports. The way it works is contrary to that of OpenSSL. Basically, I'm having a hard time migrating our secure communication code from full OpenSSL usage to IOCP sockets and OpenSSL encryption.

有人知道任何引用可能帮助我这样的任务?
TLS握手如何在IOCP上工作?

Does anyone have/anyone know of any references that might help me with such a task? How would TLS handshaking work over IOCP?

推荐答案

为了使用OpenSSL进行加密, IO,你基本上做的是创建一个内存BIO,你读取和写入套接字数据到可用,并附加到SSL上下文。

In order to use OpenSSL for encryption, but do your own socket IO, what you basically do is create a memory BIO, that you read and write socket data into as that becomes available, and attach that to the SSL context.

你做一个SSL_write调用,你跟着调用内存BIO来查看它的读缓冲区中是否有数据,读出并发送它。
相反,当数据通过io完成端口机制到达套接字时,您将它写入BIO并调用SSL_read读取数据。 SSL_read可能会返回一个错误代码,指示它在握手中,这通常意味着它生成更多的数据写入 - 您通过再次读取内存BIO来处理。

Each time you do a SSL_write call, you follow up with a call to the memory BIO to see if it has data in its read buffer, read that out and send it. Conversely, when data arrives on the socket via your io completion port mechanism, you write it to the BIO and call SSL_read to read the data out. SSL_read might return an error code indicating its in a handshake, which usually means its generated more data to write - which you handle by reading the memory BIO again.

要创建我的SSL会话,我这样做:

To create my SSL session, I do this:

// This creates a SSL session, and an in, and an out, memory bio and
// attaches them to the ssl session.
SSL* conn = SSL_new(ctx);
BIO* bioIn = BIO_new(BIO_s_mem());
BIO* bioOut = BIO_new(BIO_s_mem());
SSL_set_bio(conn,bioIn,bioOut);
// This tells the ssl session to start the negotiation.
SSL_set_connect_state(conn);

当我从网络层接收数据时:

As I receive data from the network layer:

// buf contains len bytes read from the socket.
BIO_write(bioIn,buf,len);
SendPendingHandshakeData();
TryResendBufferedData(); // see below
int cbPlainText;
while( cbPlainText = SSL_read(ssl,&plaintext,sizeof(plaintext)) >0)
{
  // Send the decoded data to the application
  ProcessPlaintext(plaintext,cbPlaintext);
}

当我从应用程序接收数据发送时 - 您需要准备SSL_write失败,因为握手正在进行,在这种情况下,您缓冲数据,并尝试并在收到一些数据后再次发送它。

As I receive data from the application to send - you need to be prepared for SSL_write to fail because a handshake is in progress, in which case you buffer the data, and try and send it again in the future after receiving some data.

if( SSL_write(conn,buf,len) < 0)
{
  StoreDataForSendingLater(buf,len);
}
SendPendingHandshakeData();

SendPendingHandshakeData发送SSL需要发送的任何数据(握手或密文)。

And SendPendingHandshakeData sends any data (handshake or ciphertext) that SSL needs to send.

while(cbPending = BIO_ctrl_pending(bioOut))
{
  int len = BIO_read(bioOut,buf,sizeof(buf));
  SendDataViaSocket(buf,len); // you fill this in here.
}

简而言之,代码示例不完整,因为我不得不从一个更大的库中提取它们,但我相信他们足以让一个开始使用SSL。在实际代码中,当SSL_read / write / BIO_read / write失败时,它可能更好地调用SSL_get_error并根据结果决定做什么:SSL_ERROR_WANT_READ是重要的一个,意味着您不能SSL_write任何更多的数据,因为它需要你以先读取和发送bioOut BIO中的未决数据。

Thats the process in a nutshell. The code samples arn't complete as I had to extract them from a much larger library, but I believe they are sufficient to get one started with this use of SSL. In real code, when SSL_read/write / BIO_read/write fail, its probably better to call SSL_get_error and decide what to do based on the result: SSL_ERROR_WANT_READ is the important one and means that you could not SSL_write any more data, as it needs you to read and send the pending data in the bioOut BIO first.

这篇关于IO完成端口和OpenSSL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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