我使用zeromq和openssl编写我的服务器和客户端。
成功握手后,当客户端再次向服务器发送消息时,服务器中的ssl_read()返回-1,ssl_get_erro()返回SSL_ERROR_SYSCALL,
当服务器再次收到消息时,这种情况会重复出现。我找不到原因。我需要BIO_flush()吗?我真的很感激你,甚至只是给我一些灵感来解决这个问题。
我想提供更多细节。
成功握手后,服务器尝试使用类似
的方法解密收到的数据`{
//.......
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.
非常感谢您抽出时间阅读本文。
答案 0 :(得分:1)
SSL连接不是可以单独使用的解密功能和加密功能。如果你想要一个块或流密码,你可以使用OpenSSL代码获得一些密码。但是你不能以这种方式使用SSL 本身。
可以使用BIO对来允许SSL在TCP以外的传输层上运行。但是你必须复制TCP的语义 - 它很复杂,代码看起来与你上面的代码完全不同。 (例如,TCP允许在任何时间向任一方向传输。您不会复制它。设计为在TCP之上分层的SSL,要求您复制它以便在其他传输上工作。)
如果你想要一个流密码,只需使用一个密码。