调用SSL_set_accept_state()后还需在SSL_read()前执行SSL_accept()吗?
问题解答
你提到的两处文档说明是对的:
如果尚未通过SSL_connect(3)或SSL_accept(3)显式完成TLS/SSL会话协商,必要时写函数会自动完成协商;若对端请求重新协商,也会在写函数执行过程中透明处理,写函数的行为依赖底层BIO。
要让透明协商正常生效,SSL对象必须预先初始化为客户端或服务端模式,该操作可在首次调用写函数前调用SSL_set_connect_state(3)或SSL_set_accept_state()完成。
但你不能直接省略SSL_accept()调用就执行SSL_read(),核心原因如下:
- 文档里明确标注了自动协商逻辑仅对写函数生效,
SSL_read()没有自带触发首次TLS握手的能力。直接调用SSL_read()时,SSL对象还处于等待握手启动的初始状态,接口会直接返回错误,不会主动推进协商流程。 SSL_set_accept_state()只是完成了SSL对象的服务端模式初始化,相当于告知OpenSSL该对象要作为服务端处理握手,并没有启动任何握手相关的流程。
如果确实想要减少显式调用SSL_accept()的代码,只有一种场景可行:你的业务逻辑里服务端需要先向客户端发送数据,此时你可以先调用SSL_write()触发自动协商,等握手完成后再调用SSL_read()读数据。但如果你的业务是客户端先发请求,那你还是必须显式调用SSL_accept()完成握手,才能正常读取客户端发送的内容。
另外要额外注意:不管是显式调用SSL_accept()还是用SSL_write()触发自动协商,都必须处理接口返回的SSL_ERROR_WANT_READ、SSL_ERROR_WANT_WRITE类IO等待错误,按规则重试,否则协商流程会直接失败。
内容的提问来源于stack exchange,提问作者suxb201
相关产品推荐
相关产品推荐

