ietf-smtp
[Top] [All Lists]

Re: [ietf-smtp] TLS1.3

2020-05-05 19:04:15
Viktor Dukhovni writes:

On Wed, Apr 29, 2020 at 06:02:13PM -0400, Sam Varshavchik wrote:

> > It emits a fatal "unexpected message" alert.  Turn off the
> > client-cert request, and it works fine.
> >
> > Name withheld to protect the guilty.
>
> I wouldn't necessarily blame the operator. It's almost a sure bet that
> they're using OpenSSL, and this developer's opinion is that OpenSSL is one
> of the worst, most confusing, and the most poorly documented API libraries
> in existence.

I are of course free to vent, but on this particular issue the
frustration is misdirected.  The OpenSSL TLS client silently ignores
solications for client certificates when none are configured at the
client.  It is up to the server to then accept or deny the handshake.
[ Rare applications that want to select certificates dynamically can
register for a callback, but then the decisions are theirs to make. ]

So after reading the following:

# When a certificate was set using the SSL_CTX_use_certificate(3) family of # functions, it will be sent to the server. The TLS standard requires that # only a certificate is sent, if it matches the list of acceptable CAs sent by # the server. This constraint is violated by the default behavior of the # OpenSSL library.

This appeared to me like a client that was configured with a certificate for some other host, but sending it in error, here, and the server rejecting the connection for that reason.

Problematic TLS implementation have been quite common, historically. For a long time I was seeing frequently TLS-related misconfigurations with SMTP servers. I lost count how many servers I saw advertising STARTTLS but choking when taken up on their offer:

220 poorly-configured-server.example.com ESMTP
EHLO hythere
250-poorly-configured-server.example.com Ok.
250-STARTTLS
250-PIPELINING
250-8BITMIME
250-SIZE
250 DSN
STARTTLS
450 Not now, maybe someday.

At one point I had to carefully implement an adaptive, transient TLS blacklist: ignore the server's STARTTLS if you have a prior record of the server failing to negotiate a TLS connection.

> Things
> have reached the stage where it's been determined that the OpenSSL library
> is reporting an error code that its own documentation describes thusly:
>
>       SSL_ERROR_SYSCALL
>           Some non-recoverable, fatal I/O error occurred. The OpenSSL error
> queue may contain more information on the error. For socket I/O on
>           Unix systems, consult errno for details.
>
> And, immediately after that, the code in question does "consult errno", and
> finds that it's zero. No error has occured, according to the operating
> system.

This is likely TLS session termination without a TLS close notify, i.e.
potentially vulnerable to truncation attacks.  An empty read on EOF does
not set errno.  In OpenSSL 1.1.1e there was a fix for that, to make it
an SSL_ERROR_SSL, but that turned to have too many backwards compatibility
issues, so it got rolled back in 1.1.1f.

I did not find this called out in the documentation, just a blanket statement: check errno, here's your error. This behavior was observed not with an active connection, but in a middle of a handshake, inside SSL_accept. The connection failed with no other indication of what the issue was. I'm too lazy to dig into openssl's source, but it seems that SSL_accept uses BIO_read, where "no data was successfully read or written if the result is 0 or -1". Then the default BIO_should_retry returns an indication calculated as follows: the read or write failed with -1 and errno was EAGAIN or EWOULDBLOCK. A closed socket connection (obviously) does not meet that criteria.

So, I surmised that SSL_accept was likely calling BIO_read, and if it returns 0 or -1 BIO_should_retry gets called; and SSL_ERROR_WANT_READ if so, otherwise it must be SSL_ERROR_SYSCALL. And in this sequence, I was getting an SSL_ERROR_SYSCALL but errno remained unset. I could not see how this was documented behavior, from any public documentation.

Attachment: pgpv8YaMRmUNW.pgp
Description: PGP signature

_______________________________________________
ietf-smtp mailing list
ietf-smtp(_at_)ietf(_dot_)org
https://www.ietf.org/mailman/listinfo/ietf-smtp
<Prev in Thread] Current Thread [Next in Thread>