【问题标题】:How to use openSSL with memory BIOs and non blocking sockets如何将 openSSL 与内存 BIO 和非阻塞套接字一起使用
【发布时间】:2012-10-31 18:57:44
【问题描述】:

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

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

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

由于我正在使用 libuv(但这可以是任何其他异步/非阻塞库),我 有一个 read 回调,当在套接字上接收到数据时会调用该回调。什么时候 我有必须写入套接字的数据,我将此数据传递到 write 图书馆的功能(在这个uv_write()),但在这之间我需要放 对 SSL 的调用。

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

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

虽然我见过很多使用阻塞套接字和核心 SSL 的示例 建立连接的功能我还没有找到一个很好的干净/简约的例子 它显示了如何将内存 BIO 用作客户端。

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

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

谢谢 回复

【问题讨论】:

  • 有什么原因不能使用套接字 BIO 吗?

标签: sockets ssl openssl client nonblocking


【解决方案1】:

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

ssl_server_nonblock.c

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

加密和未加密字节流

此图显示了读取和写入内存 BIO(rbio 和 wbio)的方式 分别与套接字读取和写入相关联。在入站流量上 (数据进入程序)从套接字读取字节并复制到 rbio 通过 BIO_write。这表示将加密数据传输到 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  |

【讨论】:

  • 欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.
  • @保罗。这个问题没有其他答案,我提供的链接提供了一个有据可查的代码示例,可以准确回答这个问题。事实上,我开发示例代码是因为我有同样的问题,并且在堆栈溢出的任何地方都没有回答。虽然我不能保证链接将永远存在(它在 github 上),但它确实存在,但它提供了价值。而且我不认为在这里发布几组文件是可行的或最有帮助的。此外,由于其他贡献者,示例代码已经发展,因此最好放在 github 之类的地方。
  • 很好的例子……我特别不确定如何处理 BIO 错误……看来我们无能为力
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2012-01-14
  • 2010-10-31
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多