SSL_shutdown() returns -1 and errno is 0

Arne Fischer

In my C++ application I use OpenSSL to connect to a server using nonblocking BIO. I am developing for mac OS X and iOS.

The first call to SSL_shutdown() returns 0. Which means I have to call SSL_shutdown() again:

The following return values can occur:

0 The shutdown is not yet finished. Call SSL_shutdown() for a second time, if a bidirectional shutdown shall be performed. The output of SSL_get_error may be misleading, as an erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred.

<0 The shutdown was not successful because a fatal error occurred either at the protocol level or a connection failure occurred. It can also occur if action is need to continue the operation for non-blocking BIOs. Call SSL_get_error with the return value ret to find out the reason.

https://www.openssl.org/docs/ssl/SSL_shutdown.html

So far so god. The problem occurs on the second call to SSL_shutdown(). This returns -1 which means an error has occurred (see above). Now if I check with SSL_get_error() I get error SSL_ERROR_SYSCALL which in turn is supposed to mean a system error has occurred. But now the catch. If I check the errno it returns 0 -> unknown error. What I have read so far about the issue is, that it could mean that the server did just "hang up", but to be honest this does not satisfy me.

Here is my implementation of the shutdown:

int result = 0;
int shutdownResult;
while ((shutdownResult = SSL_shutdown(sslHandle)) != 1) { //close connection 1 means everything is shut down ok
  if (shutdownResult == 0) { //we are supposed to call shutdown again
    continue;
  } else if (SSL_get_error(sslHandle, shutdownResult) == SSL_ERROR_WANT_READ) {
                [...] //omitted want read code, in this case the application never reaches this point
  } else if (SSL_get_error(sslHandle, shutdownResult) == SSL_ERROR_WANT_WRITE) {
                [...] //omitted want write code, in this case the application never reaches this point
  } else {
    logError("Error in ssl shutdown, ssl error: " + std::to_string(SSL_get_error(sslHandle, shutdownResult)) + ", system error: " + std::string(strerror(errno))); //something went wrong
    break;
  }
} 

When run the application logs:

ERROR:: Error in ssl shutdown, ssl error: 5, system error: Undefined error: 0

So is here just the server shutting down the connection or is there a more critical issue? Am I just missing something really obvious?

Steffen Ullrich

A full SSL shutdown consists of two parts:

  • sending the 'close notify' alert to the peer
  • receiving the 'close notify' alert from the peer

The first SSL_shutdown returned 0 which means that it did send the 'close notify' to the peer but did not receive anything back yet. The second call of SSL_shutdown fails because the peer did not do a proper SSL shutdown and send a 'close notify' back, but instead just closed the underlying TCP connection.

This behavior is actually very common and you can usually just ignore the error. It does not matter much if the underlying TCP connection should be closed anyway. But a proper SSL shutdown is usually needed when you want to continue in plain text on the same TCP connection, like needed for the CCC command in FTPS connections (but even there various implementation fail to handle this case properly).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

SSL_shutdown() returns -1 and errno is 0

From Dev

$mysqli->affected_rows returns -1, but $mysqli->errno returns 0

From Dev

Handling SSL_shutdown correctly

From Dev

getaddrinfo() returns 0 (success) but sets errno to EINVAL (22)

From Dev

WEXITSTATUS(childStatus) returns 0 but waitpid returns -1

From Dev

WEXITSTATUS(childStatus) returns 0 but waitpid returns -1

From Dev

SSL_connect returns SSL_ERROR_SYSCALL , errno == ESRCH

From Dev

scandir returns [0] =>. and [1]=>.. in array

From Dev

Why this code returns 0 & 1?

From Dev

pow(1,0) returns 0?

From Dev

pow(1,0) returns 0?

From Dev

Getting "SSL_connect returned=1 errno=0 state=error: certificate verify failed" when connecting to S3

From Dev

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed MAC

From Dev

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate, certificate verify failed

From Dev

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed MAC

From Dev

Google Oauth SSL error - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

From Dev

Heroku Rails Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

From Dev

Popen command chaining returns 0 instead of 1

From Dev

JavaScript regex returns -1 when > 0 is expected

From Dev

Count(*) in Group By - Returns 1, instead of '0'

From Dev

Codeigniter num_rows() returns 0, same query returns 1

From Dev

CountA returns 0, WorksheetFunction.CountA returns 1

From Dev

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed ONLY WHEN PROXYING

From Dev

Receiving "SSL_connect returned=1 errno=0 state=SSLv3 read server hello A: sslv3 alert handshake failure" with openshift nodejs app

From Dev

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed ONLY WHEN PROXYING

From Dev

socket connect() returns errno EINVAL

From Dev

Ruby: SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)

From Dev

What is "curl: (56) SSL read: error:00000000:lib(0):func(0):reason(0), errno 73" telling me?

From Dev

Hive - Select query returns 1 or 0 based on lookup table values

Related Related

  1. 1

    SSL_shutdown() returns -1 and errno is 0

  2. 2

    $mysqli->affected_rows returns -1, but $mysqli->errno returns 0

  3. 3

    Handling SSL_shutdown correctly

  4. 4

    getaddrinfo() returns 0 (success) but sets errno to EINVAL (22)

  5. 5

    WEXITSTATUS(childStatus) returns 0 but waitpid returns -1

  6. 6

    WEXITSTATUS(childStatus) returns 0 but waitpid returns -1

  7. 7

    SSL_connect returns SSL_ERROR_SYSCALL , errno == ESRCH

  8. 8

    scandir returns [0] =>. and [1]=>.. in array

  9. 9

    Why this code returns 0 & 1?

  10. 10

    pow(1,0) returns 0?

  11. 11

    pow(1,0) returns 0?

  12. 12

    Getting "SSL_connect returned=1 errno=0 state=error: certificate verify failed" when connecting to S3

  13. 13

    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed MAC

  14. 14

    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate, certificate verify failed

  15. 15

    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed MAC

  16. 16

    Google Oauth SSL error - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

  17. 17

    Heroku Rails Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

  18. 18

    Popen command chaining returns 0 instead of 1

  19. 19

    JavaScript regex returns -1 when > 0 is expected

  20. 20

    Count(*) in Group By - Returns 1, instead of '0'

  21. 21

    Codeigniter num_rows() returns 0, same query returns 1

  22. 22

    CountA returns 0, WorksheetFunction.CountA returns 1

  23. 23

    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed ONLY WHEN PROXYING

  24. 24

    Receiving "SSL_connect returned=1 errno=0 state=SSLv3 read server hello A: sslv3 alert handshake failure" with openshift nodejs app

  25. 25

    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed ONLY WHEN PROXYING

  26. 26

    socket connect() returns errno EINVAL

  27. 27

    Ruby: SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)

  28. 28

    What is "curl: (56) SSL read: error:00000000:lib(0):func(0):reason(0), errno 73" telling me?

  29. 29

    Hive - Select query returns 1 or 0 based on lookup table values

HotTag

Archive