
Libtls – New TLS API from LibreSSL - calineczka
http://www.openbsd.org/cgi-bin/man.cgi?query=tls_init&sektion=3
======
alexchamberlain
Not sure the trade off line has been drawn in the correct place here. TLS
should be implemented as a filter; the world isn't limited to files and
(blocking) sockets. What about integration with event loops, for example? How
does one test this API?

~~~
amelius
Indeed. Functions like tls_connect and tls_connect_fds don't belong at this
level. A TLS library should do only TLS, and behave like a black box, from
which you pull data and into which you can push data (in a non-blocking way).

Mixing in OS-related stuff only complicates the API.

~~~
wereHamster
1) Optimizing for the most common use case. 2) You can create file descriptors
not backed by any actual network connection or file on the harddrive (man 2
pipe and man 2 socketpair), you can still build an API on top of that which
operates purely on buffers.

~~~
amelius
> 1) Optimizing for the most common use case

My compiler is most commonly used together with an editor. Still I'm glad it
didn't come with an editor built-in :)

> 2) You can create file descriptors not backed by any actual network
> connection or file on the harddrive

Indeed. It doesn't mean it is the preferred way to do it, from a code-quality
or even performance point of view.

------
parley
Please correct me if I'm wrong, but I believe that the OpenSSL API allows one
to implement the actual transport of the TLS protected data however one
chooses, although it provides convenient socket/fd transports. Is this a
possibility with this new API? Regardless of whether OpenSSL can do it today,
I consider this a very valuable feature and allows for more flexible
composition of the TLS implementation and the rest of the system.

Edit: Grammar.

~~~
adekok
> I believe that the OpenSSL API allows one to implement the actual transport
> of the TLS protected data however one choose.

Yes. Through the terrible BIO_* API.

It's imperfect, but it lets you treat TLS as a "black box" that you shove
encrypted/cleartext data into, and get cleartext/encrypted data out.

This API is good for socket communication. Nothing more.

This API _could_ be extended by adding "underlying" read and write functions.
Off of the top of my head:

typedef int ( _tls_underlying_io)(struct tls_ ctx, void _u_ctx, const void_
in, size_t inlen, void _out, size_t_ outlen);

int tls_set_io(struct tls _ctx, void_ u_ctx, tls_underlying_io _u_read,
tls_underlying_io_ u_write)

Where "u_read" is used by libtls() instead of calling read(fd,...), and
u_write() is called by libtls instead of write(fd, ..)

~~~
robert-wallis
The hostname also needs to be verified somewhere in there.

------
cremno
This isn't a standalone implementation (yet [1]). It's a sane wrapper around
OpenSSL's less sane libssl API.

[1] [https://marc.info/?l=openbsd-
tech&m=141524972826918&w=2](https://marc.info/?l=openbsd-
tech&m=141524972826918&w=2)

~~~
jfindley
Nonetheless - for actually writing code using TLS, it's massively better than
navigating the wilds of libssl.

Having a full standalone implementation would be even better, but this is
still great as-is.

------
vog
To better understand the basic reasoning behind this API, I recommend to read
the last section ("ressl") of:

"LibreSSL: More Than 30 Days Later"

[http://www.openbsd.org/papers/eurobsdcon2014-libressl.html](http://www.openbsd.org/papers/eurobsdcon2014-libressl.html)

~~~
xiphias
Here's the important part:

The ressl API does provide one noteworthy feature. Hostname verification. In
order to make a secure TLS connection, you must do two things. Validate the
certificate and its trust chain. Then verify that the hostname in the cert
matches the hostname you've connected to. Lots of people don't do the latter
because OpenSSL doesn't do that latter. You have to do it yourself, which
requires knowing about things like CommonNames and SubjectAltNames. The good
news is that popular bindings for languages like python and ruby include a
function to verify the hostname. The bad news is if you pick a python or ruby
project at random, they probably forget to do it. Another funny fact is that
since everybody has to write this code themselves, everybody does it a little
bit differently. Especially regarding handling of wildcard certificates and
everybody's favorite, embedded nul bytes. Hostname verification is on by
default in ressl, and the API is designed so that you always provide a
hostname; there's no way to accidentally call the function that doesn't do
verification.

------
tedunangst
It's probably still early to be using this, unless it's of particular interest
(interest is encouraged, of course!). There's a reason the server API isn't
documented, for example.

~~~
mrweasel
So wait until the API is used by relayd, opensmtpd and httpd and see how that
works out? I assume that in the end the goal would be to use the libtls for
all of the home grown OpenBSD tools?

~~~
tedunangst
Basically yes. The API evolves as we adapt programs to use it.

------
rlpb
How does one poll for socket activity using this API, given that a read on a
socket doesn't necessarily mean that decrypted data is available, and yet that
socket writes may be required?

------
teddyh
Other TLS libraries tend to have an OpenSSL compatibility layer. Now here’s
yet _another_ API for them to write compatibility layers for. This is a bad
trend.

I’m thinking that there ought to be an API defined by an IETF working group
and specified in an RFC (like the IPv6 API C interface is), with obvious room
for expansion for library-specific features. Then all TLS libraries could
implement _that_ API and end the madness.

INB4 xkcd 927: [https://xkcd.com/927/](https://xkcd.com/927/)

------
nly
Do the defaults strike the best balance between security, PFS and
compatibility? Because I think that's really the problem with the TLS
libraries I've used, and introducing a new API is a good opportunity to fix
that. What happens, for example, if I don't call tls_config_set_ciphers()?

------
evilpie
Host and cert verification by default is good. You can use
tls_config_set_ciphers to set a cipher string, but I don't see if they disable
unsafe ciphers by default.

------
edwintorok
Does this API perform OCSP checks?

~~~
zdw
Unsure of this, but I doubt it.

OCSP is generally not a well thought out feature given current attack
scenarios:
[https://www.imperialviolet.org/2014/04/19/revchecking.html](https://www.imperialviolet.org/2014/04/19/revchecking.html)

------
dicroce
That looks very nice.

