当前位置:  开发笔记 > 编程语言 > 正文

使用Memory BIO直接读/写握手数据

如何解决《使用MemoryBIO直接读/写握手数据》经验,为你挑选了1个好方法。

我需要创建一个OpenSSL连接,我可以直接读/写握手数据.原因是握手数据将以UDP连接方式传输(DTLS不是一个选项,因为数据不是直接在数据报中,而是在另一个协议包内,如果你好奇则是EAP).到目前为止,我已经创建了一个OpenSSL连接,但我甚至无法读取客户端的握手以发送到服务器.

在我的研究,我发现我需要一个内存BIO读/写的连接,但无法弄清楚如何提取握手数据.以下是我初始化客户端连接的方法:

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,发起握手:

int ret = SSL_connect(ssl);

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

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

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

我已经能够通过TCP设置OpenSSL连接,但从未使用Memory BIO这样做,所以对此的任何帮助都将非常感激.谢谢!



1> Sergio A...:

最后我让它工作,我是以正确的方式:

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

客户

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_connect_state()我们不应该使用SSL_set_accept_state()服务器等待客户端的握手问候.然后,我们简单地将客户端握手hello数据写入服务器BIO读取器:

服务器

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读取以将数据发送到客户端.

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

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


没关系,我发现了这个例子:http://www.roxlu.com/2014/042/using-openssl-with-memory-bios它有效,它非常有用:)
推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有