7

我是 openSSL 的新手,我试图找出在使用非阻塞套接字以及 libevent、libev 或 libuv 等库与内存 BIO 结合时创建 https 连接的最佳/好的解决方案。

我试图弄清楚如何管理 openSSL 调用/数据和应用程序数据。简而言之,我对 ssl 客户端应用程序应该如何工作的理解是这样的:

  • 创建 SSL_CTX
  • 创建一个新的套接字连接(例如我正在使用 libuv)
  • 创建两个内存 BIO:
    • 一个充满了我从服务器收到的数据(readBio)
    • 另一个用于在应用程序代码中读取。(写生物)
  • 创建 SSL* 并将状态设置为 SSL_connect_state
  • 使用 SSL_do_handshake 启动握手过程
  • [循环] 接收/发送数据

由于我正在使用 libuv(但这可能是任何其他异步/非阻塞库),我有一个读取回调,当在套接字上接收到数据时会调用它。当我有必须写入套接字的数据时,我将此数据传递给库的写入 函数(在 this 中uv_write()),但在这之间我需要调用 SSL。

所以在调用 SSL_do_handshake(...) 之后,SSL 将一些数据存储到 writeBIO 中,我必须读取这些数据并将其传递到套接字中。我在想一个问题,我怎么知道 SSL 将数据存储到这个 BIO 中,其次我怎么知道我应该什么时候通过套接字发送这个。

在查看了一些代码之后,我发现在调用 SSL_do_handshake() 之后我必须从 writeBIO 中消费。但是我不清楚接下来的步骤。在 s 结束握手的第一个字节之后,libuv 的“事件”循环使一切都在运动;当新数据到达套接字时,我的 'onread()回调被调用。但是我该如何处理这些传入的数据呢?(例如,我自己是否保持 SSL 状态(<-- 有些人建议我要这样做))。

尽管我已经看到很多使用阻塞套接字和核心 SSL 功能建立连接的示例,但我还没有找到一个很好的干净/简约的示例来展示如何将内存 BIO 用作客户端。

我在这里粘贴了一些用于测试 openSSL 的代码:https ://gist.github.com/3989091

有人可以描述使用带有 SSL 的异步/非阻塞套接字和内存 BIO 的过程吗?

谢谢R

4

1 回答 1

3

我还整理了一个将内存 BIO 与非阻塞套接字和基于轮询的事件循环一起使用的基本示例。

ssl_server_nonblock.c

我认为在这里发布该示例的所有源代码是有意义的。但这里是示例代码所做的概要。

加密和未加密字节流

此图显示了读写内存 BIO(rbio 和 wbio)如何分别与套接字读取和写入相关联。在入站流(数据进入程序)中,从套接字读取字节并通过 BIO_write 复制到 rbio。这表示将加密数据传输到 SSL 对象中。然后通过调用 SSL_read 获取未加密的数据。反向发生在出站流上,将未加密的用户数据传输到加密数据的套接字写入中。

  +------+                                    +-----+
  |......|--> read(fd) --> BIO_write(rbio) -->|.....|--> SSL_read(ssl)  --> IN
  |......|                                    |.....|
  |.sock.|                                    |.SSL.|
  |......|                                    |.....|
  |......|<-- write(fd) <-- BIO_read(wbio) <--|.....|<-- SSL_write(ssl) <-- OUT
  +------+                                    +-----+

          |                                  |       |                     |
          |<-------------------------------->|       |<------------------->|
          |         encrypted bytes          |       |  unencrypted bytes  |
于 2017-03-21T19:22:47.643 回答