Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TLS 1.3 with FTP over TLS transfers fails; lack of session resumption on data connection #3002

Closed
graxlop opened this issue Sep 16, 2018 · 8 comments

Comments

@graxlop
Copy link

graxlop commented Sep 16, 2018

I did this

# /opt/curl2/bin/curl -v 'ftp://207.15.12.19/test/test/test/test.bin' --user test:test --ftp-ssl-reqd -g -o /dev/null
*   Trying 207.15.12.19...
* TCP_NODELAY set
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 207.15.12.19 (207.15.12.19) port 21 (#0)
< 220 (vsFTPd 3.0.3)
> AUTH SSL
< 234 Proceed with negotiation.
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [6 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
{ [49 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2548 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [79 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [36 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
} [8 bytes data]
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [36 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* Server certificate:
*  subject: CN=207.15.12.19
*  start date: Sep  1 08:32:48 2018 GMT
*  expire date: Nov 30 08:32:48 2018 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> USER test
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [217 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [217 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 331 Please specify the password.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> PASS test
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 230 Login successful.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> PBSZ 0
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 200 PBSZ set to 0.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> PROT P
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 200 PROT now Private.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> PWD
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 257 "/" is the current directory
* Entry path is '/'
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> CWD test
* ftp_perform ends with SECONDARY: 0
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 250 Directory successfully changed.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> CWD test
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 250 Directory successfully changed.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> CWD test
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 250 Directory successfully changed.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> EPSV
* Connect data stream passively
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 229 Entering Extended Passive Mode (|||9305|)
*   Trying 207.15.12.19...
* TCP_NODELAY set
* Connecting to 207.15.12.19 (207.15.12.19) port 9305
* Connected to 207.15.12.19 (207.15.12.19) port 21 (#0)
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> TYPE I
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 200 Switching to Binary mode.
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> SIZE test.bin
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 213 9210696085
} [5 bytes data]
* TLSv1.3 (OUT), TLS app data, [no content] (0):
} [1 bytes data]
> RETR test.bin
{ [5 bytes data]
* TLSv1.3 (IN), TLS app data, [no content] (0):
{ [1 bytes data]
< 150 Opening BINARY mode data connection for test.bin (9210696085 bytes).
* Maxdownload = -1
* Getting file with size: 9210696085
* Doing the SSL/TLS handshake on the data stream
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL re-using session ID
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [6 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
{ [49 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2548 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [78 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [36 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
} [8 bytes data]
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [36 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* old SSL session ID is stale, removing
* Server certificate:
*  subject: CN=207.15.12.19
*  start date: Sep  1 08:32:48 2018 GMT
*  expire date: Nov 30 08:32:48 2018 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [217 bytes data]
* TLSv1.3 (IN), TLS handshake, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [217 bytes data]
* TLSv1.3 (IN), TLS alert, [no content] (0):
{ [1 bytes data]
* TLSv1.3 (IN), TLS alert, Client hello (1):
{ [2 bytes data]
* transfer closed with 9210696085 bytes remaining to read
} [5 bytes data]
* TLSv1.3 (OUT), TLS alert, [no content] (0):
} [1 bytes data]
* TLSv1.3 (OUT), TLS alert, Client hello (1):
} [2 bytes data]
  0 8784M    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
} [5 bytes data]
* TLSv1.3 (OUT), TLS alert, [no content] (0):
} [1 bytes data]
* TLSv1.3 (OUT), TLS alert, Client hello (1):
} [2 bytes data]
curl: (18) transfer closed with 9210696085 bytes remaining to read

I expected the following

Start the file transfer.

curl/libcurl version

curl 7.61.0 (x86_64-pc-linux-gnu) libcurl/7.61.0 OpenSSL/1.1.1 zlib/1.2.3
Release-Date: 2018-07-11
Protocols: ftp ftps http https
Features: AsynchDNS Largefile SSL libz HTTPS-proxy

operating system

CentOS 6.10

@bagder
Copy link
Member

bagder commented Sep 16, 2018

and this works if the (same) server offers TLS 1.2 or lower?

@graxlop
Copy link
Author

graxlop commented Sep 17, 2018

Yes, it works on 1.2 and lower.

@bagder
Copy link
Member

bagder commented Sep 18, 2018

To me, this looks like an openssl issue rather than a curl one. Post handshake, curl does nothing different on 1.3 than for previous TLS versions. Do you happen to know what server or TLS library is running the other end?

@graxlop
Copy link
Author

graxlop commented Sep 18, 2018

The FTP server is vsftpd 3.0.3 using OpenSSL 1.1.1. It also fails on other servers too, such as ProFTPD and Pure-FTPd, also using OpenSSL 1.1.1.

Edit: After looking into this more, it appears to be related to TLS session resumption. All modern FTP servers require TLS session resumption to be used for data connections and for some reason this doesn't appear to be working with cURL and TLS 1.3 (at least when using FTP), so the data connection fails. If I disable that requirement on the server-side, the transfer works.

I've tested several other FTP clients that are also using OpenSSL 1.1.1 and they seem to work fine, so far only cURL seems to have this problem.

I also noticed that when trying to use the flags --tlsv1.0, --tlsv1.1 or --tlsv1.2, there seems to be no effect. It will just attempt to use TLS 1.3 every time.

@bagder
Copy link
Member

bagder commented Oct 18, 2018

All modern FTP servers require TLS session resumption to be used for data connections

I've heard this before but for some reason it's never been added to KNOWN_BUGS... It'd be cool if someone wanted to work on it!

when trying to use the flags ...

They set the minimum version to use. --tls-max sets the maximum version allowed.

@bagder bagder changed the title TLS 1.3 with FTP over TLS transfers failing TLS 1.3 with FTP over TLS transfers fails; lack of session resumption on data connection Oct 18, 2018
@felixhaedicke
Copy link
Contributor

Had the same problem with curl 7.62, but it seems to be fixed in 7.63. Looks like commit 549310e made the difference.

@bagder
Copy link
Member

bagder commented Jan 18, 2019

Cool, thanks for this. @graxlop anything else or can we close this now?

@graxlop
Copy link
Author

graxlop commented Jan 27, 2019

Works in 7.63, thanks.

@graxlop graxlop closed this as completed Jan 27, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Apr 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

3 participants