gpt4 book ai didi

c++ - 使用 openssl 及其未阻塞的 bio,ssl_read 返回 SSL_ERROR_SYSCALL 和 SSL_ERROR_WANT_READ

转载 作者:行者123 更新时间:2023-11-30 05:45:50 24 4
gpt4 key购买 nike

我使用 zeromq 和 openssl 来编写我的服务器和客户端。

握手成功后,客户端再次向服务器发送消息时,服务器中的ssl_read()返回-1,ssl_get_erro()返回SSL_ERROR_SYSCALL,

当服务器再次收到消息时,这种情况会重复出现。我找不到原因。我需要 BIO_flush() 吗?我真的很感激你,即使只是给我一些灵感来解决这个问题。


好吧,我的程序太复杂了,无法显示。我被要求在 rpcz 中添加 ssl 以提高其安全性(我不知道 rpcz 是否流行到大多数人都知道。用我的话说,它结合了 zeromq、protobuf 和 rpc 来实现远程过程调用)。所以有很多代码片段,我认为将它们全部显示在这里不会有帮助。

我正在努力提供更多细节。

握手成功后,当服务器尝试解密它收到的数据时,使用这样的方法

`{
//.......
bio_write();
//.......
ssl_read();
}`

事实证明,bio_write() 已通过返回数据数成功将数据写入 bio,但 ssl_read() 始终返回 -1。所以我使用 ssl_get_error() 检查错误号,它返回 SSL_ERROR_SYSCALL,对于接收到的下一个数据,它返回 SSL_ERROR_WANT_READ。

希望有人能帮忙解释一下为什么ssl_read会返回这些代码?我认为如果 ssl 连接没有成功握手,ssl_write() 不会返回正数。所以问题可能不是 ssl 连接。


再次添加一些细节

void TLSZmq::ssl_decrypt()
{
//........
ERR_clear_error();
int rc = BIO_write(rbio,zmq_to_ssl->data(),zmq_to_ssl->size());
ERR_get_error();
check_ssl_err(rc); //written by myself
//.........
ERR_clear_error();
aread = SSL_read(ssl_,buffer,BUFFERSIZE);
ERR_get_error();
check_ssl_err(rc); //written by myself
//..........
}

void TLSZmq::check_ssl_err(int rc)
{
//...................
int err = SSL_get_error(ssl_, rc);
if (err == SSL_ERROR_NONE)
{
std::cout<<"SSL_ERROR_NONE:"<<SSL_ERROR_NONE<<std::endl;
}
else if (err == SSL_ERROR_WANT_READ )
{
std::cout<<"SSL_ERROR_WANT_READ:"<<SSL_ERROR_WANT_READ<<std::endl;
}
else if (SSL_ERROR_SYSCALL)
{
std::cout<<"SSL_ERROR_SYSCALL:"<<SSL_ERROR_SYSCALL<<std::endl;

}

//.....................
}

我不确定这是检查错误堆栈或其他东西的正确方法。当出现SSL_ERROR_SYSCALL时,ERR_get_error()返回一个奇怪的数字,如336130315,当出现SSL_ERROR_WANT_READ时,ERR_get_error()返回0。

我还测试了握手后解密过程使用的ssl连接(SSL * ssl)与握手期间使用的相同。

呃……我们说的是 openssl 吧? rc获取openssl的BIO_write()函数的返回值。附言我使用 zeromq 套接字发送消息,我已经指出了这一点。我很困惑。通过或调用 perror() 获取 errno 是否有意义?


非常感谢您花时间阅读本文。

最佳答案

SSL连接不是可以独立使用的解密函数和加密函数。如果您想要 block 密码或流密码,您可以使用 OpenSSL 代码获得其中的一部分。但是您不能那样使用 SSL 本身

可以使用 BIO 对允许 SSL 在 TCP 以外的传输层上运行。但是您必须复制 TCP 的语义——它很复杂,而且代码看起来与您上面的代码完全不同。 (例如,TCP 允许在任何时候向任一方向传输。您不能复制它。SSL 设计为在 TCP 之上分层,需要您复制它才能在其他传输上工作。)

如果你想要一个流密码,就用一个。

关于c++ - 使用 openssl 及其未阻塞的 bio,ssl_read 返回 SSL_ERROR_SYSCALL 和 SSL_ERROR_WANT_READ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29211061/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com