我需要创建一个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连接,但从未使用内存BIOs进行过此操作,因此非常感谢对此提供任何帮助。谢谢!
发布于 2014-04-18 15:37:49
我终于开始工作了,我走对了路:
需要函数SSL_set_connect_state(ssl)来告知要为握手init准备的连接。然后,我们调用SSL_do_handshake(ssl)开始握手。此函数将返回-1,因为握手尚未完成,但我们实际上可以从客户端ssl连接BIO编写器读取数据,并使用我们想要的协议发送数据(在我的例子中,EAP数据包通过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_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_read和SSL_write函数在客户机/服务器之间发送安全数据。希望这个简短的解释对某人有用!
发布于 2014-04-06 00:46:03
试着做这个
// Connect the TCP socket (this is client side)
int sock = tcp_connect(host, port);
// Create BIO around the connected TCP socket
BIO *sbio = BIO_new_socket(sock, BIO_NOCLOSE);
SSL_set_bio(ssl,sbio,sbio);
int ret = SSL_connect(ssl);把BIO看作是套筒的包装。对于客户端,您必须使用connect(.)给它一个连接到所需主机和端口的套接字。打电话。对于服务器端,只需使用accept(.)返回的套接字即可。打电话。
https://stackoverflow.com/questions/22753221
复制相似问题