Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20200326112540.GH466633@wirbelwind.zhasha.com>
Date: Thu, 26 Mar 2020 12:25:40 +0100
From: Joakim Sindholt <opensource@...sha.com>
To: tlsify@...ts.openwall.com
Subject: Re: Interface design considerations

On Mon, Mar 23, 2020 at 12:54:52PM +0100, Joakim Sindholt wrote:
> Some things that also warrant further discussion:
> * Specifying a set of acceptable TLS versions, key exchange algorithms
>   and ciphers.

To add a little context here: it's not just to force a higher level of
security than the default but also to support old misbehaving and
non-conformant servers.
I have a provider (not naming any names here) with, from what I can
tell, their own TLS implementation that, back when I originally tested
this, would not accept connections if you offered too high a version of
TLS regardless of lower versions being offered as well. They might have
imposed the same restrictions regarding KEX and ciphersuites as well but
I can't remember.
Unfortunately these exist and I NEED to have them supported :(

> * Having tlsify do the connecting for you.
>     - I disagree with this. IMO it's unrelated to TLS and a
>       feature-creep springboard for even more TLS-unrelated
>       functionality.
> * Specifying a client certificate.
>     - Rich thinks "some degree of protocol is needed to make it
>       meaningful."
> * How to specify ALPN and how to communicate to the host process what
>   was chosen.

* Should tlsify perform IDNA transformations?
    - My position is a dubious yes, since I believe tlsify should work
      transparently just like libc should in this regard, accepting
      unicode common names.
    - Maybe it's necessary. Do CAs issue certificates for the unicode
      name and is it expected to be valid? I really, really hope not.
    - The agressively annoying thing is that IDNA punycoding requires
      large UNICODE tables for all manner of non-punycode-related
      transformations...

> What I propose so far:
> 
> tlsify [options] fd[,fd]
> 
> If only 1 fd is specified it's both the TLS input and output fd. If 2
> are specified they're the TLS input and output fds respectively.
> 
> -n cn
>     Specify a common name for use in validation and SNI.
> -C dane-type path-to-file-or-dir
>     Act as a DANE record of the specified type, with the data being
>     pulled from the file or all files in the folder. This also
>     deactivates the fetching of DANE records and the use of the default
>     system trust store excepting dane-type=PKIX-*.
> -x dane-type
>     Turn off CN validation for a given DANE record type.
> -x CN
>     Turn off CN validation altogether.
> -x SNI
>     Turn off SNI.

It didn't dawn on me until well after I sent this that DANE also
requires knowledge of the port and protocol. While this can technically
be obtained from a socket that is a sort of layering violation.
If tlsify is to support random pipes unrelated to the actual socket
being used (if one is being used at all) then the spawner NEEDS to tell
tlsify what port and protocol is being used.
A TLSA record as specified in RFC6698 section 3[1] looks like:
_$port._$protocol.$cn
with $port being the decimal port, $protocol being one of udp, tcp, and
sctp, though I don't know if we should limit that. Also $cn is defines
as the IDNA punycoded name.
With that in mind I propose a port option:

-p protocol/port
    Specify a protocol and port used for DANE.
    Example: -p tcp/443

This option is mandatory for clients unless DANE validation is turned
off completely with another new option:

-x DANE
    Turn off DANE validation.

And to simplyify matters:

-x CA
    Turn off CA validation.
    Only applies to validations where DANE is not in effect.
    For example: PKIX-* records will still use the system CA.

This option would make it so that you could specify DANE-like records
with -C without implicitly turning off any specific existing validation,
thus providing only additional information. Also, if you simply wish to
turn off validation for whatever reason: -x CA -x DANE.

Similarly, we probably want very fine controls on how validation is
done, so for the sake of that (and consistency!) I would change the
relevant, currently proposed options to:

-x dane-type
    Ignore DANE records of a specific type.
-x CN[ dane-type]
    Turn off CN validation altogether or for a specific DANE record type.
    Example: -x CN or -x "CN DANE-EE"


I also didn't realize that getopt isn't really geared for multiple
arguments to follow a single option. In the case of:

-C dane-type path-to-file-or-dir

it would be a lot less of a hassle for tlsify users to have it as two
arguments so you don't have to start combining strings. POSIX says:
>Guideline 8:
>   When multiple option-arguments are specified to follow a single
>   option, they should be presented as a single argument, using <comma>
>   characters within that argument or <blank> characters within that
>   argument to separate them.
however it sucks to have to take that path your tlsify-calling-function
takes and prepend "DANE-TA " to it. Because of that I think it's valid,
in this case, to have them as separate arguments so you can do:
argv[argc++] = "-C";
argv[argc++] = "DANE-TA";
argv[argc++] = path;
instead of allocating huge stack buffers or using asprintf and by
extension: malloc.
This does pose a problem if you, for whatever reason, want to wrap
tlsify in a shell script using POSIX getopts.


Finally: we might as well spare a thought on how to distinguish client
and server invocations now. A few options would be:
tlsify [options] client|server fd[,fd]
tlsify -is_a_server [options] fd[,fd]
Since there are probably more clients wanting to use this than servers I
would go with option 2: an option to signify that it's a server and no
option specified meaning it's a client.

This brings the total so far to:

-s
    The fd(s) refers to a TLS server. Default is client.
-n cn
    Specify a common name for use in validation and SNI.
    * Required unless -s or -x DANE -x CN
-p protocol/port
    Specify a protocol and port used for DANE.
    * Required unless -s or -x DANE
-C dane-type path-to-file-or-dir
    Act as a DANE record of the specified type, with the certificate(s)
    being pulled from the file or all files in the folder.
-x dane-type
    Ignore DANE records of a specific type.
-x DANE
    Turn off DANE validation.
-x CA
    Turn off system CA validation.
    Only applies to validations where DANE is not in effect.
    For example: PKIX-* records will still use the system CA.
-x CN[ dane-type]
    Turn off CN validation altogether or for a specific DANE record type.
-x SNI
    Turn off SNI.
    * If no -n cn is specified, SNI is turned off implicitly


[1] https://tools.ietf.org/html/rfc6698

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.