使用Memory BIO直接读取/写入握手数据 [英] Directly Read/Write Handshake data with Memory BIO

查看:209
本文介绍了使用Memory BIO直接读取/写入握手数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个OpenSSL连接,在这里我可以直接读取/写入握手数据.原因是握手数据将在UDP连接中传输(DTLS是不可选项,因为数据不是直接在数据报中,而是在另一个协议包内部,

I need to create an OpenSSL connection where I can directly read/write handshake data. The reason is the handshake data will be transported in a UDP connection (DTLS is not an option, because the data is not directly in the datagram, but inside another protocol packets, EAP if you're curious). So far, I've created an OpenSSL connection but I've not even been able to read the client's handshake to send to the server.

在我的研究中,我发现我需要一个Memory BIO来读写连接,但是无法弄清楚如何提取握手数据.这是我初始化 client 连接的方法:

In my research I've found I need a Memory BIO to read/write to the connection, but cannot figure out how to extract the handshake data. Here's how I initialize the client connection:

SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();

ctx = SSL_CTX_new(SSLv3_client_method());
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);

ssl = SSL_new(ctx);
rbio = BIO_new(BIO_s_mem());
wbio = BIO_new(BIO_s_mem());

SSL_set_bio(ssl, rbio, wbio);
SSL_set_connect_state(ssl);

我已经尝试过doint SSL_connect来发起握手:

I've tried doint SSL_connect, to initiate the handshake:

int ret = SSL_connect(ssl);

但是返回-1,并执行SSL_get_error(ssl, res)时,我得到一个错误代码2,然后用该代码执行ERR_error_string并得到:

But returns -1, and doing SSL_get_error(ssl, res) I get an error code 2, then I execute ERR_error_string with that code and get:

error:00000002:lib(0):func(0):system lib

此外,如果我使用SSL_do_handshake而不是SSL_connect,则会收到完全相同的错误.

Also, if I use SSL_do_handshake instead of SSL_connect I get exactly the same error.

我已经能够通过TCP设置OpenSSL连接,但是从来没有使用Memory BIO做到这一点,因此对此提供的任何帮助将不胜感激.谢谢!

I've been able to set a OpenSSL connection over TCP, but have never done this with Memory BIOs, so any help with this would be very appreciated. Thanks!

推荐答案

最后,我开始使用它了,我的方法是正确的:

Finally I get it to work, I was in the right way:

需要功能SSL_set_connect_state(ssl)来告知要为握手初始化准备的连接.然后,我们调用SSL_do_handshake(ssl)开始握手.该函数将返回-1,因为握手尚未完成,但实际上我们可以从客户端ssl连接BIO编写器读取数据,并使用所需的协议(在我的情况下为UDP上的EAP RADIUS数据包)发送数据.

The function SSL_set_connect_state(ssl) is needed to tell the connection to be prepared for the handshake init. Then, we call SSL_do_handshake(ssl) to start the handshake. This function will return -1 because the handshake was not finished, but we can actually read from the client ssl connection BIO writer and send the data using the protocol we want (in my case, EAP RADIUS packets over UDP).

客户

ctx = SSL_CTX_new(SSLv3_client_method());
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);

ssl = SSL_new(ctx);
rbio = BIO_new(BIO_s_mem());
wbio = BIO_new(BIO_s_mem());

SSL_set_bio(ssl, rbio, wbio);
SSL_set_connect_state(ssl); 

SSL_do_handshake(ssl); // This will return -1 (error) as the handshake is not finished, we can ignore it.

char buf[4096];
BIO_read(wbio, buf, 4096); // Read from BIO, put data in buffer

// Then use data in buffer to send to the server

另一方面,应该使用凭据和私钥来配置服务器.另外,我们应该使用SSL_set_accept_state()而不是SSL_set_connect_state(),因为服务器将等待客户端的握手问候.然后,我们只需将客户端握手问候数据写入服务器BIO阅读器:

The server, in the other hand, should be configured using the credential and private key. Also, instead of SSL_set_connect_state() we should use SSL_set_accept_state() as the server will wait for the client's handshake hello. Then, we simply write the client handshake hello data to the server BIO reader:

服务器

ctx = SSL_CTX_new(SSLv3_server_method()); // This is the server!
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);

ssl = SSL_new(ctx);
rbio = BIO_new(BIO_s_mem());
wbio = BIO_new(BIO_s_mem());

SSL_set_bio(ssl, rbio, wbio);
SSL_set_accept_state(ssl); // The server uses SSL_set_accept_state

// Here we get the data from the client suppose it's in the variable buf
// and write it to the connection reader BIO.
BIO_write(rbio, buf, strlen(buf));

if (!SSL_is_init_finished(ssl)) {
    SSL_do_handshake(ssl);
}

我们可以使用SSL_is_init_finished(ssl)函数来检查握手是否完成,而如果握手未完成,则调用SSL_do_handshake(ssl),然后再次从BIO_writer中读取数据以将数据发送给客户端.

We can use the the SSL_is_init_finished(ssl) function to check if the handshake was done, and while it is not done we call SSL_do_handshake(ssl), and then read again from the BIO_writer to send data to the client.

客户端和服务器之间的此过程应完成,直到连接完成(即SSL_is_init_finished(ssl)返回true).

This process between client and server should be done until the connection is done (i.e. SSL_is_init_finished(ssl) returns true).

然后,握手完成后,您可以使用SSL_readSSL_write函数在客户端/服务器之间发送安全数据.希望这个简短的解释对某人有用!

Then, after the handshake is done, you can send secure data between client/server, by using the SSL_read and SSL_write functions. Hope this short explanation is useful for someone!

这篇关于使用Memory BIO直接读取/写入握手数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆