Skip to content

OpenSSL 1.1.1e: clients sends more alerts after TLS shutdown (close_notify) was send #11388

@noxxi

Description

@noxxi

The TLS RFC states that after the close_notify no more messages should be send. OpenSSL 1.1.1e seems to have introduced a bug where it still sends more messages even after the close_notify.

This problem can be triggered if the client sends a close_notify but the server does not, i.e. the server closes the connection directly. In this case the client will send another alert.

Take the following example code fragment (full code at https://pastebin.com/i28hWcCr):

 39     res = SSL_connect(ssl);
 40     assert(res == 1);
 41 
 42     strcpy(buf, "GET / HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n");
 43     res = SSL_write(ssl, buf, strlen(buf));
 44     fprintf(stderr,"SSL_write len=%ld res=%d\n", strlen(buf), res);
 45 
 46     SSL_shutdown(ssl);
 47     shutdown(sock,1);
 48 
 49     res = SSL_read(ssl, &buf, sizeof(buf));
 50     fprintf(stderr,"SSL_read res=%d err=%d\n", res, SSL_get_error(ssl, res));

After connecting (line 39) and writing some data (line 43) the SSL layer will be shutdown (line 46) and then the socket will be shutdown for writing (line 47) to make sure that it definitely will not write any more data. Then it will try to read the response from the server (line 49).

With a server properly shutting down the SSL connection all will be well. With a server closing the TCP connection without shutting down the SSL part first (as in https://pastebin.com/MtXFQKCK) the client will get the socket close and likely as a result of the improper shutdown write another alert to the socket, which results in a SIGPIPE due to the explicit TCP shutdown in line 47 (without the shutdown the alert will also be send but the effect can be better seen with SIGPIPE).

The relevant strace output of the program:

   157  write(3, "\27\3\3\0003rI\23\227\362\355\315T\350\334\205\342\335>SC\311\351\202\6\2762\326\375\316\274\7"..., 56) = 56
   158  write(2, "SSL_write len=35 res=35\n", 24SSL_write len=35 res=35
   159  ) = 24
   160  write(3, "\25\3\3\0\22d{\365\303\303\211<Z\250\341H\261\372^\\\342)\25", 23) = 23
   161  shutdown(3, SHUT_WR)                    = 0
   162  read(3, "", 5)                          = 0
   163  write(3, "\25\3\3\0\22X\224\315\0358d\363\204r\0\4*K{V\4\205\1", 23) = -1 EPIPE (Broken pipe)
   164  --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=14910, si_uid=1001} ---
   165  write(2, "SSL_read res=0 err=1\n", 21SSL_read res=0 err=1
   166  )  = 21

In line 160 the sending of the close_notify from the SSL shutdown can be seen followed by the shutdown of the TCP socket in line 161. The SSL_read in the code will then result in the read in line 162 which returns 0, i.e. server closed socket. Line 162 then shows the attempt to write another alert to the socket which results in a SIGPIPE due to the previous TCP shutdown. The err=1 from SSL_read in the output (line 165) is the result from SSL_get_error and is SSL_ERROR_SSL.

The problem is the same with TLS 1.3 only that due to the new record layer with opaque_type always being application_data alerts are not that clearly visible in the strace output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    branch: 1.1.1Applies to OpenSSL_1_1_1-stable branch (EOL)branch: masterApplies to master branchseverity: importantImportant bugs affecting a released versiontriaged: bugThe issue/pr is/fixes a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions