由于错误的版本号错误导致无法完成握手'错误

时间:2018-04-24 09:16:13

标签: c++ openssl

我很擅长使用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_version SSL_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

来自客户,

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:

我使用的是OpenSSL 1.1.0h,可能会受到关注吗?

编辑:

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

其他方法在握手期间因产生这些错误而失败,

{{1}}

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

希望有人可以帮助我; )

1 个答案:

答案 0 :(得分:0)

经过几天的挖掘,我发现了我做错了什么。

从BIO&#39;中读取数据时发生了问题。

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

以上代码导致数据写入BIO&#39;读取后仍然保留,这导致OpenSSL认为IO尚未处理。

我通过改变阅读方法来解决它,

int size_buffer = BIO_read(bio_write, buffer, buffer.size());

BIO_read清除关于写BIO&#39;的数据读完之后,这样就可以写BIO&#39;没有任何待处理的数据。