SSL/TLS client command line API?

Rob Landley rob at landley.net
Fri Jan 27 18:23:10 UTC 2017


On 01/19/2017 08:17 AM, Denys Vlasenko wrote:
> Hi folks,
>
> Now that I have some code reaching a state where
> it does talk TLS 1.2, the question is how to integrate it.

This is one of my longstanding todo items for toybox too.

> TLS i/o entails some buffering.

Possibly protocol-required? You want to eliminate keystroke timings as
an attack vector. I was thinking some variant of nagle with 1/4 second
timeouts would probably be enough collating to defeat that without
annoying humans too much. (I added some code like this to busybox's vi a
few years back to collate escape sequences, possibly genericizable? On
my end I first wanted to test if the command line utility was already
_doing_ that...)

> I feel it would be better
> if we don't complicate other applets code with changes to
> accomodate that. Even if at first it looks "easy",
> just replace
> 
>     write(fd, buf, len)
> with
>     tls_write(tls, buf, len)
> 
> it quickly becomes much more difficult when you need a proper
> bidirectional piping, not a simple synchronous blocking reads
> and writes.

You either pipe through an external program or add busybox's first build
dependency. The first seems more in keeping with the project so far. :)

> wget already has a solution. It forks a child which does TLS magic,
> and talks to it over an ordinary socketpair.
> Right now it launched either "openssl s_client" or our own separate
> helper utility linked against a SSL library.
> 
> Our helper works like this:
> 
> ssl_helper -d N
> 
> it talks TLS over fd N, passing plaintext from/to stdin/out.
> 
> In order to add a real applet, I looked for an SSL/TLS client tool
> in widespread use to emulate, and did not find one with a suitable API.
> 
> "openssl s_client" is not a production tool, it's a debug thing.

I lean towards 'use existing tool' vs 'invent a new thing'. It seems to
be installed by default on the systems I've looked at.

There's also one in https://bearssl.org/ but I haven't played with it
much yet:

$ build/brssl client --help
ERROR: unknown option: '--help'
usage: brssl client server[:port] [ options ]
options:
   -q              suppress verbose messages
   -trace          activate extra debug messages (dump of all packets)
   -sni name       use this specific name for SNI
   -nosni          do not send any SNI
   -mono           use monodirectional buffering
   -buf length     set the I/O buffer length (in bytes)
   -CA file        add certificates in 'file' to trust anchors
   -cert file      set client certificate chain
   -key file       set client private key (for certificate authentication)
   -nostaticecdh   prohibit full-static ECDH (client certificate)
   -list           list supported names (protocols, algorithms...)
   -vmin name      set minimum supported version (default: TLS-1.0)
   -vmax name      set maximum supported version (default: TLS-1.2)
   -cs names       set list of supported cipher suites (comma-separated)
   -hf names       add support for some hash functions (comma-separated)
   -minhello len   set minimum ClientHello length (in bytes)
   -fallback       send the TLS_FALLBACK_SCSV (i.e. claim a downgrade)
   -noreneg        prohibit renegotiations
   -alpn name      add protocol name to list of protocols (ALPN extension)
   -strictalpn     fail on ALPN mismatch

That one doesn't say it's a debug tool, it seems a normal part of the
package.

> Bigger problem is, it can't be handed a fd to perform TLS on,
> it takes hostname.

Also required by the protocol: you have to verify the hostname attached
to the certificate is the one you expected. (The main reason this is
still on my todo list is I haven't tackled the certificate management
can of worms for mkroot yet.)

> Meaning, wget can't launch it saying "here's
> a socket I already opened, please wrap it in TLS".

And you want wget to do this because...?

(In theory you can upgrade an existing connection to ssl, but dialing
out again when you get a redirect is pretty normal...)

> This second problem is shared by stunnel, various flavors of
> "enhanced netcats" with --ssl options etc: none of them will wrap
> a given fd.

Because the protocol requires them to know the hostname they're
connecting to.

> Do you know a tool whose command line is suitable for us?

I was pretty happy with the bearssl one, but haven't tried to do that
much with it yet.

I have a todo item to poke the bearssl guy to let his command line
server mode run an inetd-style command line with each connection (like
netcat server mode does). I'd also like to convince him that cutting
releases is a good idea...

I have no idea what openssl's server mode thinks it's doing...

Rob


More information about the busybox mailing list