使用OpenSSL的,其畅通生物,ssl_read返回SSL_ERROR_SYSCALL和SSL_E

2019-10-22 08:29发布

我用zeromq和OpenSSL写我的服务器和客户端。

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

当服务器再次接收消息这种情况重复。 我找不到原因。 我是否需要BIO_flush()? 我真的很感激你甚至只要给我一些灵感来工作了这一点。


好了,我的程序太复杂显现。 我被要求添加SSL来rpcz,以提高其安全性(我不知道如果rpcz人气很足,对大多数人知道的。在我的话,它结合zeromq,protobuf的和RPC实现远程过程调用)。 因此,有大量的代码块,我认为它不会显示他们都在这里帮助。

我想提供更多的细节。

一个成功的握手之后,当服务器尝试解密接收到的数据,利用这样的方法

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

而事实证明,BIO_WRITE()通过返回的数据的数量已经成功写入数据到生物,但ssl_read()总是retun -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()函数的返回值。 PS我用zeromq插座发送消息时,我已经指出了。 我很困惑。 是否有意义获得通过或致电PERROR errno设置()?


真的感谢您的时间阅读本。

Answer 1:

SSL连接不是解密功能和可独立使用的加密功能。 如果你想有一个块或流密码,您可以使用OpenSSL的代码,某些块得到一个。 但你不能使用SSL 本身的方式。

它可以使用BIO对以允许SSL比TCP以外的传输层上操作。 但是你要复制TCP的语义 - 这是复杂的,并且代码看起来一点也不像你有上面的代码。 (例如,TCP在任何时候允许在两个方向上传输。你不复制这一点。SSL,设计在TCP之上进行分层,需要你复制,对于它的一些其他的运输工作。)

如果你想有一个流密码,只需使用一个。



文章来源: using openssl with its unblocked bio, ssl_read return SSL_ERROR_SYSCALL and SSL_ERROR_WANT_READ