我正在尝试在另一个SSL连接(称为连接1)内创建SSL连接(称之为连接2)。连接2用于连接到我使用连接1连接的机器后面的机器。一旦建立连接2(即SSL握手完成),我关闭连接1.
我面临的问题是SSL_shutdown返回错误(返回代码< 0)。大部分时间它都有效,并且在连接1关闭后我能够成功地通过连接2进行通信。但突然之间,它突然出现错误。连接2上的后续SSL_read失败并显示错误。
SSL_get_error返回:2
ERR_error_string返回:错误:00000002:lib(0):func(0):system lib
注意连接1是java服务器,连接2是基于openssl的服务器。有人可以帮我确定这里可能出现的问题吗?
以下是一些代码供您参考,以帮助您了解我在做什么:
SSL *ssl; // connection 1
SSL *ssl2; //connection 2
// ssl is already established at this point
// i.e. connection 1 already exists.
BIO *rbio = BIO_new (BIO_s_mem());
BIO *wbio = BIO_new (BIO_s_mem());
SSL_set_bio (ssl, rbio, wbio);
SSL_set_connect_state (ssl);
while (!SSL_is_init_finished(ssl))
{
ret = SSL_do_handshake (ssl);
if (ret == 1) /* Handshake was successful */
{
break;
}
ssl_error = SSL_get_error (ssl, ret);
if (ssl_error != SSL_ERROR_WANT_READ
&& ssl_error != SSL_ERROR_WANT_WRITE)
{
// report failed
return;
}
size = BIO_ctrl_pending (wbio);
if (size > 0)
{
size = BIO_read (wbio, buff, size);
if (size <= 0)
{
// report failed this shouldn't happen
continue;
}
// Write using SSL_WRITE to connection 1
}
/* Read only if SSL_do_handshake expects */
if (ssl_error == SSL_ERROR_WANT_READ)
{
// read into buff from SSL_READ from connection 1
// continue if noting available
BIO_write (rbio, buff, size);
free (buff);
}
}
// Write to SSL connection 1 handshake is successful
// to let Javaserver know that it should close ssl part of connection 1
SSL_set_quiet_shutdown (ssl, 0);
ret = SSL_shutdown (ssl);
if (ret == 0)
ret = SSL_shutdown (ssl);
if (ret < 0)
{
/* FAILS HERE: This is where it fails sometimes
(may be once or twice out of 10)*/
}
// Some clean up
/* We are done with cleanup of old SSL connection,
* and establishing new SSL connection to the new
* one. Now let's start communicating using connection 2.
* But before that we need to do a few things. */
sock_bio = BIO_new_socket (INTERNAL (agentbi)->sock_fd, BIO_NOCLOSE);
SSL_set_bio (ssl2, sock_bio, sock_bio);
// From this point onwards we use connection 2 to communicate as
// connection 1 has been reduced to tcp only.
在java方面,我可以看到发送和接收的close_notify: 一旦客户端告知其连接2的SSL握手完成,我就在SSLSocket上调用close。这是java side ssl logging:
xxx-Thread-0, called close()
xxx-Thread-0, called closeInternal(true)
xxx-Thread-0, SEND TLSv1 ALERT: warning, description = close_notify
Padded plaintext before ENCRYPTION: len = 32
0000: 01 00 03 4B 21 22 DA ED 8D 0F 3B 9B 5D 1F 5D 23 ...K!"....;.].]#
0010: FE 72 EA B8 E8 9B 09 09 09 09 09 09 09 09 09 09 .r..............
xxx-Thread-0, WRITE: TLSv1 Alert, length = 32
[Raw write]: length = 37
0000: 15 03 01 00 20 46 A6 93 6C 3E FE 4A A7 01 A9 2C .... F..l>.J...,
0010: 3C D5 C9 FA C6 6C B8 D3 46 21 18 BB 77 CD C5 08 <....l..F!..w...
0020: C0 7F 06 80 01 .....
xxx-Thread-0, called closeSocket(true)
xxx-Thread-0, waiting for close_notify or alert: state 5
[Raw read]: length = 5
0000: 15 03 01 00 20 ....
[Raw read]: length = 32
0000: 87 DD CD 14 5B 4D 21 65 0A F4 38 15 22 BC 4C CD ....[M!e..8.".L.
0010: BF FE 36 57 8E 3F 5B EC C7 C1 9A 53 74 E8 71 FE ..6W.?[....St.q.
xxx-Thread-0, READ: TLSv1 Alert, length = 32
Padded plaintext after DECRYPTION: len = 32
0000: 01 00 F5 D6 26 D5 0F 40 76 45 42 7E 64 06 EB D2 ....&..@vEB.d...
0010: 26 37 3A 5D 65 F4 09 09 09 09 09 09 09 09 09 09 &7:]e...........
xxx-Thread-0, RECV TLSv1 ALERT: warning, close_notify
xxx-Thread-0, called closeInternal(false)
xxx-Thread-0, close invoked again; state = 5
shutCloseClientSocket ()
xxx-Thread-1, called close()
xxx-Thread-1, called closeInternal(true)
xxx-Thread-0, called close()
xxx-Thread-0, called closeInternal(true)