8

我们有一个使用套接字 10 年的多线程网络应用程序,现在我们正尝试使用 OpenSSL 0.9.8L 保护该应用程序。多年来,应用程序的网络协议被设计为利用单套接字连接的双工特性;应用程序同时在同一个套接字上读取和写入。应用程序自己管理底层套接字,并通过 SSL_set_fd 将套接字描述符传递给 OpenSSL。

我们为多线程支持配置了 OpenSSL,同时设置了静态和动态锁定回调,例如 CRYPTO_set_id_callback()、CRYPTO_set_locking_callback() 等。在大多数情况下,应用程序运行良好,但我们看到了一些异常情况。为了帮助我们确定原因,对几个问题的明确回答会有所帮助。

OpenSSL 常见问题页面声明 OpenSSL 是线程安全的,但坚持单个“SSL 连接可能不会被多个线程同时使用”。

http://www.openssl.org/support/faq.html#PROG1

  1. 对或错。OpenSSL 连接 API 调用(SSL_Read、SSL_Write 等)可能在同一个 SSL 实例上同时执行(SSL_new 调用返回的指向 SSL 的指针)?
  2. 对或错。对于启用 SSL_MODE_AUTO_RETRY 的阻塞套接字,线程 A 可以在 SSL 实例 X 上调用 SSL_Read() 而线程 B 在 SSL 实例 X 上同时调用 SSL_Write()?
  3. 对或错。当应用程序使用非阻塞套接字并防止在同一 SSL 实例上同时执行 SSL_Read 和 SSL_Write(以及其他连接 API 调用)时,OpenSSL 可以正常工作吗?
  4. 对或错。SSL_new 返回的 OpenSSL SSL 实例绑定到名为 SSL_new 的单个线程;绑定意味着 SSL 实例不能与任何其他线程共享,SSL 实例仅对调用 SSL_new 的线程有效?
  5. 对或错。如果线程A i) 调用SSL_new,获得一个SSL 实例X 并且ii) 使用SSL 实例X 调用SSL_Read。如果线程B 非并发地使用同一个SSL 实例X 调用SSL_Read/SSL_Write,最终会失败?
4

2 回答 2

16

1.对或错。OpenSSL 连接 API 调用(SSL_Read、SSL_Write 等)可能在同一个 SSL 实例上同时执行(SSL_new 调用返回的指向 SSL 的指针)?

*错误。不,您不能在同一个 SSL 实例上同时使用 SSL_read / SSL_write。*

2.对或错。对于启用 SSL_MODE_AUTO_RETRY 的阻塞套接字,线程 A 可以在 SSL 实例 X 上调用 SSL_Read() 而线程 B 在 SSL 实例 X 上同时调用 SSL_Write()?

*与上述相同的答案。使用或不使用 SSL_MODE_AUTO_RETRY,您不能同时使用同一个 SSL 实例 X 来并行执行 SSL_read 和 SSL_write*

3.对或错。当应用程序使用非阻塞套接字并防止在同一 SSL 实例上同时执行 SSL_Read 和 SSL_Write(以及其他连接 API 调用)时,OpenSSL 可以正常工作吗?

真的。如果没有并发执行,那么 OpenSSL 可以很好地用于阻塞和非阻塞套接字。

4.对或错。SSL_new 返回的 OpenSSL SSL 实例绑定到名为 SSL_new 的单个线程;绑定意味着 SSL 实例不能与任何其他线程共享,SSL 实例仅对调用 SSL_new 的线程有效?

错误的。SSL 实例未通过 OpenSSL 本身绑定到任何线程。只要在任何一个时间点只有一个线程使用单个 SSL 实例,您就可以在另一个线程中使用在一个线程中创建的 SSL 实例。

5.对或错。如果线程A i) 调用SSL_new,获得一个SSL 实例X 并且ii) 使用SSL 实例X 调用SSL_Read。如果线程B 非并发地使用同一个SSL 实例X 调用SSL_Read/SSL_Write,最终会失败?

错误的。线程 A 和线程 B 都可以使用同一个 SSL 实例 X,只要两者都不对 SSL 实例 X 进行并发操作。

于 2013-01-23T05:47:05.520 回答
0

实验证明,如果 SSL 连接已经通过了协商阶段,并且之后没有重新协商,那么 SSL_read 和 SSL_write 同时使用证明是没有害处的。这是根据我的测试,我将 OpenSSL 与 Push Framework(一个多线程网络库)集成在一起。然而,在我们阅读的任何地方,OpenSSL 专业人士都坚持认为同一上下文不能被多个线程同时使用。

于 2013-09-25T09:31:32.660 回答