为什么 openssl 提供两套 similar/duplicated 的 API:SSL_* 和 SSL_CTX_*

Why does openssl provide two similar/duplicated sets of APIs: SSL_* and SSL_CTX_*

我搜索了 google 和 bing、openssl 常见问题解答、一些 API 手册页,没有找到任何提示。

这是历史问题,还是刻意设计?

将 SSL_CTX 视为制作 SSL 对象的工厂。 SSL 连接仅由 SSL 对象处理。但是它们可以有很多设置。与其每次需要一个新的 SSL 对象时都重复这个,不如创建一个 SSL_CTX 并预先设置好所有设置,然后您可以使用已经存在的设置创建任意数量的 SSL 对象。当然,如果您愿意,您仍然可以选择在单个 SSL 对象级别进行设置。

补充一下 Matt Caswell 的回答,'factory' 设计模型背后的原因还在于服务器 POSIX 套接字的实现方式。对于服务器实现,您首先创建一个套接字并将其 'bind' 连接到您机器上的特定端口(例如端口 443,这是 TLS 连接的标准端口)。从那里,它可以 'listen' 用于客户端的传入连接。该程序然后重复调用 accept(),它会阻塞,直到有新的连接进入,并且 returns 一个新的文件描述符表示与该单个客户端的连接。该程序可能将该文件描述符传递给另一个线程或执行其他操作以允许同时处理多个连接。

现在,如果 OpenSSL 库只有 SSL 对象而不是 SSL_CTX,那么程序每次都必须重新配置要用于该 SSL 对象的所有设置 服务器接受新的客户端连接。想一想每个连接都会产生的开销——必须从文件中加载服务器证书和私钥,以及配置所有可能的设置(OpenSSL 中有很多设置)会花费相当多的时间.为了解决这个问题,SSL_CTX 可以加载所有这些设置,并准备好在接受新连接时传输到 SSL 对象。从本质上讲,它简化了代码并大大减少了每个连接的开销。

有关详细信息,请参阅 OpenSSL Wiki 的服务器实现 - https://wiki.openssl.org/index.php/Simple_TLS_Server

该代码未与最新版本的 OpenSSL 保持同步,但它很好地传达了 SSL_CTX 的实用性。