我正在使用OpenSSL 1.0.2g。在我的客户端中,我想完全禁用SSL会话恢复(用于测试目的)。
在创建SSL_CTX后,我在连接之前执行:
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
但是我在流量捕获中看到的是,我的客户端总是通过发送非空会话ID来进行会话重用。服务器确实接受了它。
如何完全禁用SSL会话恢复?
更多扩展代码段:
SSL_CTX *ctx = NULL;
ctx = SSL_CTX_new(SSLv23_client_method()))
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_verify_depth(ctx, 0);
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
我做错了吗?缺少任何必要的步骤?
答案 0 :(得分:1)
您正在设置自动重试:
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
<强> SSL_MODE_AUTO_RETRY 强>
如果传输是,请不要在重试时打扰应用程序 阻塞。如果在正常操作期间进行重新协商,a SSL_read或SSL_write将返回-1并指示需要 使用SSL_ERROR_WANT_READ重试。在非阻塞环境中 应用程序必须准备好处理不完整的读/写 操作。在阻塞环境中,应用程序并非总是如此 准备处理读/写操作返回没有成功 报告。 标志SSL_MODE_AUTO_RETRY将导致读/写操作 仅在握手和成功完成后返回。
这意味着自动重新协商将以静默方式发生,而不会使用OpenSSL库知道的应用程序。见the documentation for SSL_write()
:
如果底层BIO阻塞,SSL_write()将只返回一次 写操作已完成或发生错误,除外 重新协商发生时,在这种情况下是SSL_ERROR_WANT_READ 可能导致。可以使用。来控制此行为 SSL_CTX_set_mode调用的SSL_MODE_AUTO_RETRY标志。
这样&#34;沉默&#34;重新谈判可以解释您观察到的行为,如果是,则不使用SSL_MODE_AUTO_RETRY
可以解决您的问题。
OpenSSL是一个非常复杂的工具,在我看来,很多选项的记录很差。对于一个非常相关的示例,做什么,&#34;可以使用SSL_CTX_set_mode调用的SSL_MODE_AUTO_RETRY标志来控制此行为。&#34;受控如何? 暗示使用SSL_MODE_AUTO_RETRY
允许进行静默重新协商以及会话重用,但它从未明确说明。
同样,the many options for SSL_CTX_set_session_cache_mode()
中的一个可能是相关的:
为了重用会话,客户端必须发送会话的ID 服务器。它只能发送一个id。然后服务器 同意重用会话或者它开始一个完整的握手(创建一个 新会议。)
服务器将在其内部会话存储中查找会话。 如果在内部存储中找不到会话或查找该会话 内部存储已停用 (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP),服务器将尝试外部 储存(如果有的话)。
那么,
<强> SSL_SESS_CACHE_OFF 强>
不会发生客户端或服务器的会话缓存。
禁用内部缓存?对我而言,其含义是不。
答案 1 :(得分:0)
我做错了吗?
我认为您在查看流量时必须做错事,或者您没有显示代码的重要部分。默认情况下,客户端根本不会恢复任何会话,因为它不知道应该恢复哪个会话。来自SSL_CTX_set_session_cache_mode的文档:
SSL_SESS_CACHE_CLIENT
...由于OpenSSL库没有可靠的方法来了解是否应该重用会话或选择哪个会话(由于抽象BIO层,SSL引擎没有关于连接的详细信息),应用程序必须使用SSL_set_session函数选择要重用的会话 ...