View Ticket
Ticket Hash: c5811f0d433d34ca16ccecdec10fb61e2f3ba657
Title: Unexpected EOF's treated as errors by openssl 3.0
Status: Closed Type: Code Defect
Severity: Important Priority: Immediate
Subsystem: Resolution: Duplicate
Last Modified: 2023-11-10 21:00:59
Version Found In: 1.7.22
User Comments:
azazel added on 2023-11-10 18:31:52:

OpenSSL 3.0 introduced a new ssl option SSL_OP_IGNORE_UNEXPECTED_EOF. If this is not set, and OpenSSL receives an unexpected EOF, it is treated as a fatal error. TclTLS does not set this, which can lead do unexpected errors. For example:

$ cat /space/azazel/tmp/test/tlstest.tcl
#!/bin/sh
#\
exec tclsh8.6 "$0" ${1+"$@"}

package require tls

proc main host {

    global done

    set req [subst {
GET / HTTP/1.1
Host: $host
Connection: close    

}]

    set s [socket $host 443]

    tls::import $s -require 0 -ssl2 0 -ssl3 0 -tls1 1 -servername $host

    tls::handshake $s

    fconfigure $s -translation crlf -blocking 0 -buffering none

    puts -nonewline $s $req

    set done 0

    fileevent $s readable [list read_response $s]

    vwait done

    close $s

}

proc read_response s {

    global done

    while 1 {

        if { [eof $s] } {
            puts stderr "read_response: got EOF"
            set done 1
            break
        }

        if { [catch { set resp [read $s] } error] } {
            puts stderr "read_response: error = $error"
            set done 1
            break
        }

        puts stderr "read_response: $resp"

        if { [fblocked $s] } {
            break
        }

    }

    if { $done } {
        fileevent $s readable [list]
    }

}

main [lindex $argv 0]
$ /space/azazel/tmp/test/tlstest.tcl google.com
read_response: HTTP/1.1 301 Moved Permanently
Location: https://www.google.com/
Content-Type: text/html; charset=UTF-8
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-RriZ0vurw26vE_UywsmQQg' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
Date: Fri, 10 Nov 2023 18:16:14 GMT
Expires: Fri, 10 Nov 2023 18:16:14 GMT
Cache-Control: private, max-age=2592000
Server: gws
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: CONSENT=PENDING+895; expires=Sun, 09-Nov-2025 18:16:14 GMT; path=/; domain=.google.com; Secure
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>

read_response: error = error reading "sock560f01ccd5c0": software caused connection abort

Setting the option:

$ fossil diff
Index: tls.c
==================================================================
--- tls.c
+++ tls.c
@@ -1212,10 +1212,13 @@
 #endif

     SSL_CTX_set_app_data( ctx, (VOID*)interp); /* remember the interpreter */
     SSL_CTX_set_options( ctx, SSL_OP_ALL);     /* all SSL bug workarounds */
     SSL_CTX_set_options( ctx, off);    /* all SSL bug workarounds */
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
+    SSL_CTX_set_options( ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
+#endif
     SSL_CTX_sess_set_cache_size( ctx, 128);

     if (ciphers != NULL)
        SSL_CTX_set_cipher_list(ctx, ciphers);

causes the EOF to be handled as expected:

$ /space/azazel/tmp/test/tlstest.tcl google.com
read_response: HTTP/1.1 301 Moved Permanently
Location: https://www.google.com/
Content-Type: text/html; charset=UTF-8
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-GtEz85sCnLQF8adC4dzohw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
Date: Fri, 10 Nov 2023 18:24:57 GMT
Expires: Fri, 10 Nov 2023 18:24:57 GMT
Cache-Control: private, max-age=2592000
Server: gws
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: CONSENT=PENDING+011; expires=Sun, 09-Nov-2025 18:24:57 GMT; path=/; domain=.google.com; Secure
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>

read_response: 
read_response: got EOF

azazel added on 2023-11-10 21:00:59:

This is a dup of https://core.tcl-lang.org/tcltls/tktview/88c0c84969