我是使用OpenSSL库进行编程的新手,并且很难使用内存BIO来实现握手。 (以供以后使用重叠的I / O)

我不太了解没有显式处理握手的示例,因此我编写了一个仅进行握手的简单程序,但是我从服务器收到此错误,

9332:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:ssl\record\ssl3_record.c:210:

从客户那里
18792:error:141A10F4:SSL routines:ossl_statem_client_read_transition:unexpected message:ssl\statem\statem_clnt.c:269:

Wireshark表示服务器和客户端都使用TLSv1.2作为记录层,但是客户端使用TLS 1.0(0x0301)而服务器使用TLS 1.2(0x0303)

因此,我尝试使用SSL_set_min_proto_versionSSL_set_max_proto_versionTLS1_2_VERSION <= compatible <= TLS1_2_VERSION(以及这些功能的CTX版本)限制TLS版本。但是错误仍然发生。

这是片段
auto send = [&sock, &session]() -> void
{
    if (session.should_send()) // BIO_ctrl_pending(bio_write)
    {
        std::vector<char> buffer(session.read_from_write_bio());
        sock.send(buffer);
    }
};

auto receive = [&sock, &session]() -> void
{
    std::vector<char> buffer(sock.receive());
    auto status = session.write_to_read_bio(buffer);

    if (status != Status::DONE)
        while (session.should_write_bio_again())  // BIO_should_retry(bio_read)
            status = session.write_to_read_bio(buffer); // BIO_write(bio_read, ...)

    if (session.handshaking())  // SSL_is_init_finished(ssl);
        session.handshake();    // SSL_do_handshake(ssl);

    else // for later use
    {
        std::vector<char> buffer(GetMaxBufferSize(), '\0');
        session.read(buffer);
    }
};

从服务器,
receive();  // client hello
send();     // server hello
receive();  // client spec
send();     // server spec

来自客户
send();     // client hello
receive();  // server hello
send();     // client spec
receive();  // server spec

我正在使用OpenSSL 1.1.0h,可能会担心吗?

编辑:

我降级了库版本(1.0.2n),它给了我同样的错误,所以我猜库版本不会影响。但是我发现DTLS协议(protocol)(在创建SSL上下文时由DTLS_method指定)仅是适用于以上代码的协议(protocol)。

其他方法在握手期间会产生这些错误,
SSLv23_method
17484:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:.\ssl\s3_pkt.c:365:
2812:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:

TLSv1_2_method
20472:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:.\ssl\s3_pkt.c:365:
8580:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:

TLSv1_1_method
7868:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:.\ssl\s3_pkt.c:365:
3748:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:

TLSv1_method
19008:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:
9768:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:

SSLv3_method
13948:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:
14356:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:.\ssl\s3_both.c:408:

(SSL上下文无法使用SSLv2_method初始化)

希望可以有人帮帮我 ; )

最佳答案

经过几天的挖掘,我发现自己做错了。

从“写入BIO”读取数据时发生了问题。

int size_buffer = BIO_get_mem_data(bio_write, &p);
// copy contents from pointer 'p' to buffer

上面的代码导致“写入BIO”上的数据即使被读取后仍然保留,这导致OpenSSL认为IO尚未处理。

我通过将阅读方法更改为
int size_buffer = BIO_read(bio_write, buffer, buffer.size());
BIO_read在读取后清除“write BIO”上的数据,以便“write BIO”没有任何待处理数据。

关于c++ - 由于 'wrong version number'错误,无法完成握手,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49997802/

10-13 07:45