Closed u279897 closed 1 year ago
It is not fully clear to me from the description - are you trying to use the same tls object from multiple threads? If so, you would have to properly lock the access to the object as simultaneous calls on a single object from multiple threads will cause race conditions and memory corruption.
thanks for the clue, SSL object is created on thread t1, application data is sent on thread T2, and renegotiation is triggered on main thread, with potential data race between T2 and main thread.
@t8m I updated the issue description with more details regarding the settings and using of SSL object, Im not using it anymore from multiple threads but I still have the same issue, could you please give any hint what might be still wrong ? Is there an alternative solution to perform the renegotiation that might work ?
You should not call SSL_connect() after SSL_renegotiate(). SSL_renegotiate() should be called on an already connected SSL object.
Thank you @t8m, I think it works using only SSL_renegotiate(). As far as I understand it will schedule a renegotiation and it will be performed automatically so no need of explicit call of SSL_connect()/SSL_do_handshake when client wants to renegotiate over existing TLS connection -> please confirm
You can use SSL_renegotiate_pending() to check whether the renegotiation is still pending or it was done. AFAIK if the renegotiation fails, the SSL connection will end up in an error state so it will not be possible to do further reads/writes through it.
@t8m, I want to use a dummy SSL_write_ex to trigger renegotiation following SSL_renegotiate, then wait until SSL_renegotiate_pending returns 1, at the end of it a new dummy SSL_write_ex to see whether renegotiation was succesful or not, but the SSL_write_ex meant to trigger renegotiation returns < 1.
```
// triggger renegotiation
int res = SSL_write_ex(tls, (NULL), 0, 0);
if (res < 1)
{
std::cout<< " Renegotiate trigger SSL_write failed"; // fails here
}
// wait until SSL_renegotiate_pending is 1 max 10s
// c
res = SSL_write_ex(sslPtr, (NULL), 0, 0);
if (res < 1)
{
std::cout << " Caannot write in SSL object meaning renegotiation failed!";
return;
}
// renegotiation ended succesfull I can verify server certificate
Could you please tell me it this approach can be used and if so why the first SSL_write_ex returns < 1 ?
Thank you!
Do you use non-blocking sockets? If so, the SSL_write() might return until there is the handshake data from the peer on the socket.
yes, I use non-blocking sockets, is any other way to trigger the renegotiation right after it was scheduled instead of waiting for an SSL_write which is called for application data ?
SSL_do_handshake() can do it. However with non-blocking sockets you still need a loop to allow for the handshake data to arrive from the peer.
how could I do that, allowing the handshake data to arrive from the peer ? is any opensource project example for that ?
how could I do that, allowing the handshake data to arrive from the peer ? is any opensource project example for that ?
You have a SSL_connect() loop in you opening comment in this issue, this would be very much similar using SSL_do_handshake() instead of SSL_connect().
@t8m I did try also with SSL_do_handshake instead of SSL_connect but it doesn't work, Do I need to add more changes to it ? Thanks.
if ((ret = SSL_renegotiate(tls)) <= 0)
{
std::cout<< "failed with SSL_renegotiate";
return;
}
int ssl_get_error;
int waitMax = 10; // wait for max 10 seconds.
while ((ret = SSL_do_handshake(tls)) != 1)
{
ssl_get_error = SSL_get_error(tls, ret);
if (ssl_get_error != SSL_ERROR_WANT_READ)
{
std::cout << " Failure ssl_get_error: " << ssl_get_error;
break;
}
if ((time(nullptr) - startTime) >= waitMax)
{
std::cout<< " failed due to timeout"; // **1
return;
}
}
if (ret != 1)
{
std::cout<< " failed";
return;
}
What do you get returned from the SSL_get_error() call?
using select on SSL fd for read and write based on SSL_get_error() solved my issue
I create ssl_ctx , SSL structure and perform first handshake as follows:
From thread t1:
/ I have a session succesfully established over TLSv1.2 with following openssl version: OPENSSL_VERSION_TEXT: OpenSSL 3.0.8 7 Feb 2023 After a certain period I want to trigger renegotiation from client side as follows /
I send application data and trigger the renegotiation from Thread t2:
I trigger the renegotiation following 3-4 seconds SSL structure is created, in that time application succesfully sends data using tls. It sometimes works and renegotiation is performed even multiple times succesfully but sometimes it doesn't. I usually encounter timeout or the 10 seconds ends without SSL_connect succeding with following SSL_get_error outputs:
I basically just use SSL_renegotiate and SSL_connect which runs max 10 seconds until it keep receiving SSL_ERROR_WANT_READ. My SSL server is a pyton tls socket server
What might be wrong with my code, how could it be improved? How could I find out why it doesn't work sometimes ?