使用OpenSSL BIO实现无阻塞I/O
Non-Blocking I/O With OpenSSL BIO
我在Linux上使用的是OpenSSL 1.0.0-fips。我遇到的问题是SSL_connect()
返回-1,而SSL_get_error()
返回SSL_ERROR_WANT_READ
。然后,我将文件描述符放入select()
中,timeval
结构设置为10秒,select()
刚好超时。
我启动了Wireshark,我看到"客户端你好"熄灭,我看到ServerHello
回到客户端,但它从未在select()
中"醒来"。它只是超时。
我的问题是:
-
是否必须使用
BIO_new_socket()
创建一个BIO对象,然后使用SSL_set_bio()
将该BIO对象分配给我的SSL对象?SSL_set_fd()
的手册页说它将自动创建一个BIO对象,这似乎意味着SSL_set_bio()
是一个无用的函数,你永远不必真正调用它。 -
假设我们使用
SSL_set_fd()
并分配一个正在阻塞的连接TCP文件描述符。假设我们稍后使用fcntl()
将该文件描述符更改为非阻塞。这是否会破坏SSL对象(或底层BIO对象)?
1)是否必须使用BIO_new_socket()创建一个BIO对象,然后使用SSL_set_BIO()将BIO对象分配给我的SSL对象?那个男人SSL_set_fd()的页面表示它将自动创建一个BIO对象所以这似乎意味着SSL_set_bio()有点无用函数,而您从未真正调用过该函数。
如果默认的BIO对象足以满足您的需要,那么您不必手动创建和安装自己的BIO。SSL_set_bio()调用就在那里,以防您想要创建/使用与SSL_set_fd()代表您创建的默认对象不同的bio对象。
2)假设我们使用SSL_set_fd()并分配一个连接的TCP文件正在阻塞的描述符。让我们说,我们以后会改变这一点使用fcntl()将文件描述符设置为非阻塞。这会破坏SSL吗对象(或底层BIO对象)?
是的,我相信它会坏掉的。非阻塞OpenSSL的调用模式与阻塞OpenSSL时使用的调用模式非常不同,我不相信您可以在运行中从一种模式来回切换到另一种模式。也就是说,我自己还没有尝试过,所以我可能错了,但我认为为了安全起见(并保持一致),你应该提前选择使用阻塞或非阻塞I/O,并在连接期间坚持使用它。
特别是,手册页中的这句话:
BIO和SSL引擎继承fd的行为。
。。。建议SSL设置调用将检查fd的状态,并根据fd的阻塞/非阻塞状态在BIO和SSL对象中设置私有变量。如果你"背着OpenSSL"改变fd的行为,OpenSSL的例程就不会预料到这一点,很可能会做错事,无法正常工作。
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 如何在openssl-ecc中获取十六进制格式的私钥
- LINK 尝试使用 OpenSSL evp aes 256 c++ 时出错
- 如何在OpenSSL中从configuration.h.in获取configuration.h
- OpenSSL TLS服务器-使用客户端证书白名单
- 通过 Openssl 命令行加密,通过 c++ 解密
- 使用已使用 java 编码的 openssl 解码数据
- OpenSSL没有共享密码
- OpenSSL 解密功能无法正常工作
- OpenSSL BIO and SSL_read
- OpenSSL:将不安全的BIO提升为安全
- "400 Bad request"使用 OpenSSL BIO 进行请求时
- base64 decode with openssl BIO block by block
- 如何正确处理OpenSSL错误(BIO)
- 使用OpenSSL BIO实现无阻塞I/O
- OpenSSL - 通过内存将 X509* x509 转换为 file-BIO*
- 如何让使用阻塞BIO的OpenSSL服务器干净地关闭
- 使用OpenSSL库在C++中将BIO*转换为PKCS7*
- C++将TCP套接字转换为BIO(OpenSSL)
- 指示OpenSSL在设置新BIO时不释放BIO对象