summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL30
-rw-r--r--doc/index.html16
-rw-r--r--doc/libsbearssl/index.html548
-rw-r--r--doc/libstls/index.html127
-rw-r--r--doc/s6-tlsc.html268
-rw-r--r--doc/s6-tlsclient.html168
-rw-r--r--doc/s6-tlsd.html280
-rw-r--r--doc/s6-tlsserver.html216
-rw-r--r--doc/upgrade.html2
-rw-r--r--src/conn-tools/s6-tlsserver.c12
-rw-r--r--src/sbearssl/sbearssl_run.c7
-rw-r--r--src/stls/stls_run.c5
-rw-r--r--src/stls/stls_s6tlsc.c2
13 files changed, 1658 insertions, 23 deletions
diff --git a/INSTALL b/INSTALL
index 87e065a..d12dfc0 100644
--- a/INSTALL
+++ b/INSTALL
@@ -177,16 +177,40 @@ source tree if parallel builds are needed.
* SSL support
-----------
- s6-networking implements UCSPI tools for TLS1.2 connections: s6-tlsclient,
+ s6-networking implements UCSPI tools for SSL/TLS connections: s6-tlsclient,
s6-tlsserver, s6-tlsc and s6-tlsd. Those are built if you give the
--enable-ssl=<implementation> flag to configure. There are two supported
values for <implementation>: libressl (in which case the tools will be
built against libtls) and bearssl (in which case the tools will be built
against libbearssl). You should install the relevant header and library
-files for your chosen implementation before building a SSL-enabled
-s6-networking.
+files for your chosen implementation, be it LibreSSL or BearSSL, before
+building a SSL-enabled s6-networking.
+
If your SSL headers and library files are not installed in /usr/include
and /usr/lib, you can use the --with-ssl-path=DIR configure option:
headers will be searched in DIR/include and libraries will be searched in
DIR/lib. For more complex setups, use the generic --with-include and
--with-dir configure options.
+
+ If you choose --enable-ssl=bearssl, then s6-networking will build a
+"libsbearssl" support library, which s6-tlsc and s6-tlsd will be linked
+against. This support library depends on libbearssl interfaces.
+
+ If you choose --enable-ssl=libressl, then s6-networking will build
+a "libstls" support library, which s6-tlsc and s6-tlsd will be linked
+against. This support library depends on libtls interfaces, but not
+on libssl or libcrypto interfaces - so it is possible to use alternative
+implementations of the libtls API.
+
+ If your SSL implementation library needs nonstandard -l options to link
+against it, you can override the CRYPTO_LIB make variable.
+By default, CRYPTO_LIB is "-lbearssl" when building against BearSSL,
+and "-ltls -lssl -lcrypto" when building against LibreSSL.
+
+ As of 2016-12-02, please note that BearSSL is experimental and not
+considered production-ready by its author yet. Nevertheless, it's an
+incredibly promising library with high-quality interfaces and likely
+high-quality implementation. When statically linked against BearSSL,
+the s6-tlsc and s6-tlsd binaries are 1/10th the size of what they are
+when statically linked against LibreSSL, with a smaller RAM footprint
+too.
diff --git a/doc/index.html b/doc/index.html
index 8ad4264..9ba1daf 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -24,6 +24,8 @@
It includes command-line client and server management, TCP access
control, privilege escalation across UNIX domain sockets, IDENT
protocol management and clock synchronization.
+Optionally, it also includes command-line TLS/SSL tools for
+secure communications.
</p>
<p>
@@ -53,9 +55,9 @@ library. </li>
2.1.0.0 or later. It's a build-time requirement. It's also a run-time
requirement if you link against the shared version of the s6-dns
libraries. </li>
- <li> If you want to build the TLS tools:
+ <li> If you want to build the TLS/SSL tools:
<ul>
- <li> Either <a href="http://libressl.org/">LibreSSL</a> version 2.5.0
+ <li> Either <a href="http://libressl.org/">LibreSSL</a> version 2.4.4
or later </li>
<li> Or <a href="http://bearssl.org/">BearSSL</a> version 0.1
or later. <strong>THIS IS EXPERIMENTAL.</strong> </li>
@@ -134,7 +136,7 @@ relevant page.
<li><a href="s6-tcpserver6d.html">The <tt>s6-tcpserver6d</tt> program</a></li>
</ul>
-<h4> UCSPI tools for TLS 1.2 over TCP </h4>
+<h4> UCSPI tools for SSL/TLS over TCP </h4>
<ul>
<li><a href="s6-tlsclient.html">The <tt>s6-tlsclient</tt> program</a></li>
@@ -165,8 +167,12 @@ relevant page.
<h3> Libraries </h3>
<ul>
-<li> The <a href="libs6net/">s6net</a> library, containing: </li>
-<li> <a href="libs6net/ident.html">The <tt>ident</tt> library interface</a> </li>
+<li> The <a href="libstls/">stls</a> library </li>
+<li> The <a href="libsbearssl/">sbearssl</a> library </li>
+<li> The <a href="libs6net/">s6net</a> library, containing:
+ <ul>
+ <li> <a href="libs6net/ident.html">The <tt>ident</tt> library interface</a> </li>
+ </ul> </li>
</ul>
<hr />
diff --git a/doc/libsbearssl/index.html b/doc/libsbearssl/index.html
new file mode 100644
index 0000000..1c797c7
--- /dev/null
+++ b/doc/libsbearssl/index.html
@@ -0,0 +1,548 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-networking: the sbearssl library interface</title>
+ <meta name="Description" content="s6-networking: the sbearssl interface" />
+ <meta name="Keywords" content="s6-networking net sbearssl library TLS SSL BearSSL libbearssl" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="../">s6-networking</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>sbearssl</tt> library interface </h1>
+
+<h2> General information </h2>
+
+<p>
+ <tt>libsbearssl</tt> is a support library for the
+<a href="../s6-tlsc.html">s6-tlsc</a> and
+<a href="../s6-tlsd.html">s6-tlsd</a> executables when they're built
+against the <a href="https://bearssl.org/">BearSSL</a>
+backend. Among other things, it offers interfaces to read private
+keys and certificates from a Unix filesystem, which BearSSL does
+not provide on its own.
+</p>
+
+<h2> Compiling </h2>
+
+<ul>
+ <li> Make sure the s6-networking headers, as well as the skalibs headers,
+and the <tt>bearssl.h</tt> header, are visible in your header search path. </li>
+ <li> Use <tt>#include &lt;s6-networking/sbearssl.h&gt;</tt> </li>
+</ul>
+
+<h2> Linking </h2>
+
+<ul>
+ <li> Make sure the s6-networking libraries, as well as the skalibs
+libraries, and the BearSSL libraries, are visible in your library search path. </li>
+ <li> Link against <tt>-lsbearssl</tt>, <tt>-lskarnet</tt>, <tt>-lbearssl</tt>,
+<tt>`cat $sysdeps/socket.lib`</tt>, <tt>`cat $sysdeps/spawn.lib`</tt>, and
+<tt>`cat $sysdeps/tainnow.lib`</tt>, where <tt>$sysdeps</tt> is your skalibs
+sysdeps directory. </li>
+</ul>
+
+<h2> Programming </h2>
+
+<h3> General concepts </h3>
+
+<p>
+ <a href="https://bearssl.org/">BearSSL</a> provides engines
+to decode PEM objects and X.509 certificates, and to run a
+TLS/SSL connection. However, it does not store such objects:
+it never allocates memory, and does not interact with the
+filesystem. <tt>sbearssl</tt> provides functions to
+address this.
+</p>
+
+<p>
+ When reading an object into memory, <tt>sbearssl</tt> stores all
+the bytes of the object in a
+<a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a>,
+and the <tt>sbearssl_*</tt> structures contain indices of bytes in that
+stralloc. That allows the structures to remain valid even when the stralloc
+contents get reallocated and move to some other place in the heap. After
+you have finished adding data to the stralloc and are sure its contents
+will not move again, you can use the
+<tt>sbearssl_*_to</tt> functions to convert <tt>sbearssl_*</tt> structures
+to the corresponding <tt>br_*</tt> structures (native BearSSL), which
+contain pointers to memory.
+</p>
+
+<h3> Private keys (typically for servers) </h3>
+
+<p>
+ BearSSL handles two types of private keys: RSA keys and
+EC keys (i.e. points on an elliptic curve). <tt>sbearssl</tt>
+adds some generic functions to handle keys no matter their
+type.
+</p>
+
+<h4> <code> int sbearssl_rsa_skey_from (sbearssl_rsa_skey *l, br_rsa_private_key const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts the RSA private key from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_rsa_skey_to (sbearssl_rsa_skey const *l, br_rsa_private_key *k, char *s) </code> </h4>
+
+<p>
+ Converts the RSA private key from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_ec_skey_from (sbearssl_ec_skey *l, br_ec_private_key const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts the EC private key from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_ec_skey_to (sbearssl_ec_skey const *l, br_ec_private_key *k, char *s) </code> </h4>
+
+<p>
+ Converts the EC private key from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_skey_from (sbearssl_skey *l, br_skey const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts the private key from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_skey_to (sbearssl_skey const *l, br_skey *k, char *s) </code> </h4>
+
+<p>
+ Converts the private key from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_skey_readfile (char const *fn, sbearssl_skey *key, stralloc *sa) </code> </h4>
+
+<p>
+ Reads a private key from the file named <em>fn</em> and stores it
+in <tt>sbearssl</tt> format into the structure in *<em>key</em>,
+the bytes of the key being added to the stralloc in *<em>sa</em>.
+</p>
+
+<p>
+The private key in <em>fn</em> can be either DER-encoded (binary format)
+or PEM-encoded (text format).
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h3> Public keys </h3>
+
+<p>
+ BearSSL handles two types of public keys: RSA keys and
+EC keys (i.e. points on an elliptic curve). <tt>sbearssl</tt>
+adds some generic functions to handle keys no matter their
+type.
+</p>
+
+<p>
+ You normally should not handle public keys directly;
+you should handle x509 certificate chains instead.
+</p>
+
+<h4> <code> int sbearssl_rsa_pkey_from (sbearssl_rsa_pkey *l, br_rsa_public_key const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts the RSA public key from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_rsa_pkey_to (sbearssl_rsa_pkey const *l, br_rsa_public_key *k, char *s) </code> </h4>
+
+<p>
+ Converts the RSA public key from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_ec_pkey_from (sbearssl_ec_skey *l, br_ec_public_key const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts the EC public key from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_ec_pkey_to (sbearssl_ec_pkey const *l, br_ec_public_key *k, char *s) </code> </h4>
+
+<p>
+ Converts the EC public key from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_pkey_from (sbearssl_pkey *l, br_x509_pkey const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts the public key from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_pkey_to (sbearssl_pkey const *l, br_x509_pkey *k, char *s) </code> </h4>
+
+<p>
+ Converts the public key from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h3> Generic PEM objects </h3>
+
+<p>
+ You normally should not have to call these functions
+directly. Instead, you should use the higher-level functions for
+private keys, X509 certificate chains and trust anchors, which
+will perform the PEM decoding for you.
+</p>
+
+<h4> <code> int sbearssl_pem_decode_from_buffer (buffer *b, genalloc *list, stralloc *sa) </code> </h4>
+
+<p>
+ Decodes a PEM object, reading from the
+<a href="http://skarnet.org/software/skalibs/libstddjb/buffer.html">buffer</a>
+in *<em>b</em>. The decoded bytes are appended to *<em>sa</em>.
+<em>list</em> points to a
+<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a>
+containing objects of type <tt>sbearssl_pemobject</tt>.
+One <tt>sbearssl_pemobject</tt> is appended to the genalloc per PEM entity
+decoded from the byte stream read from the buffer.
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h4> <code> int sbearssl_pem_decode_from_string (char const *s, size_t len, genalloc *list, stralloc *sa) </code> </h4>
+
+<p>
+ Decodes a PEM object from the <em>len</em> bytes pointed to by <em>s</em>.
+The decoded bytes are appended to *<em>sa</em>.
+<em>list</em> points to a
+<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a>
+containing objects of type <tt>sbearssl_pemobject</tt>.
+One <tt>sbearssl_pemobject</tt> is appended to the genalloc per PEM entity
+found in the bytes in <em>s</em>.
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h3> X.509 certificates (typically for servers) </h3>
+
+<h4> <code> int sbearssl_cert_from (sbearssl_cert *l, br_x509_certificate const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts a certificate from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_cert_to (sbearssl_cert const *l, br_x509_certificate *k, char *s) </code> </h4>
+
+<p>
+ Converts a certificate from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_cert_readfile (char const *fn, genalloc *list, stralloc *sa) </code> </h4>
+
+<p>
+ Reads one or more certificates from the file named <em>fn</em> and appends
+them to the <a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a>
+in *<em>list</em>, which is a dynamically growing list of
+<tt>sbearssl_cert</tt> structures. The bytes of the
+(maybe PEM-decoded, but still DER-encoded) certificate are
+appended to the stralloc in *<em>sa</em>.
+</p>
+
+<p>
+ The <em>fn</em> file can be either DER-encoded (binary format)
+or PEM-encoded (text format). If it is DER-encoded, it must
+contain exactly one X.509 certificate. If it is PEM-encoded,
+it may contain a chain of certificates as long as the PEM
+file fits within the size limits.
+</p>
+
+<p>
+ <em>fn</em> must not be bigger than SBEARSSL_MAXCERTFILESIZE,
+which is 8 kB. This function is meant to read individual
+certificates, not files containing large certificate chains or
+sets of trust anchors. To do that, use
+<tt>sbearssl_cert_readbigpem()</tt> instead.
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h4> <code> int sbearssl_cert_readbigpem (char const *fn, genalloc *, stralloc *sa) </code> </h4>
+
+<p>
+ Reads one or more PEM-encoded certificates from the file named
+<em>fn</em> and appends them to the
+<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a>
+in *<em>list</em>, which is a dynamically growing list of
+<tt>sbearssl_cert</tt> structures. The bytes of the PEM-decoded (but
+still DER-encoded) certificates are appended to the stralloc
+in *<em>sa</em>.
+</p>
+
+<p>
+ The function will refuse to read a file that is not valid PEM.
+Inside the file, It will ignore PEM objects that are
+not X.509 certificates.
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h3> Trust anchors (typically for clients) </h3>
+
+<p>
+ BearSSL clients do not use X.509-encoded certificates,
+they use sets of <em>trust anchors</em>, i.e. structures
+decoded from certificates representing (intermediate or)
+root CAs.
+</p>
+
+<h4> <code> int sbearssl_ta_from (sbearssl_ta *l, br_x509_trust_anchor const *k, stralloc *sa) </code> </h4>
+
+<p>
+ Converts a trust anchor from BearSSL format (reading from a structure pointed to by <em>k</em>)
+to <tt>sbearssl</tt> format (writing to a structure pointed to by <em>l</em>).
+The data from *<em>k</em>'s contents are copied into the stralloc in *<em>sa</em>.
+The function returns 1 on success and 0 (and sets errno) on failure.
+</p>
+
+<h4> <code> void sbearssl_ta_to (sbearssl_ta const *l, br_x509_trust_anchor *k, char *s) </code> </h4>
+
+<p>
+ Converts a trust anchor from <tt>sbearssl</tt> format (reading from a structure pointed to by <em>l</em>)
+to BearSSL format (writing to a structure pointed to by <em>k</em>).
+The indices in <em>l</em> must refer to data stored in the string <em>s</em>.
+</p>
+
+<h4> <code> int sbearssl_ta_readfile (char const *fn, genalloc *list, stralloc *sa) </code> </h4>
+
+<p>
+ Reads a set of trust anchors from a PEM file named <em>fn</em>
+which must contain a list of (intermediate or) root CA certificates.
+The trust anchors are appended to the
+<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a>
+in *<em>list</em>, which is a dynamically growing list of
+<tt>sbearssl_ta</tt> structures. The contents of the trust anchors
+are appended to *<em>sa</em>, which is a
+<a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a>
+used for storage.
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h4> <code> int sbearssl_ta_readdir (char const *dir, genalloc *list, stralloc *sa) </code> </h4>
+
+<p>
+ Reads a set of trust anchors from a directory named <em>dir</em>,
+which must contain a list of (intermediate or) root CA certificates
+stored as individual DER- or PEM-encoded files.
+The trust anchors are appended to the
+<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a>
+in *<em>list</em>, which is a dynamically growing list of
+<tt>sbearssl_ta</tt> structures. The contents of the trust anchors
+are appended to *<em>sa</em>, which is a
+<a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a>
+used for storage.
+</p>
+
+<p>
+ The function ignores files that do not contain valid DER
+or PEM objects containing X.509 certificates representing
+certification authorities.
+</p>
+
+<p>
+ The function returns 0 on success. It returns a negative value in
+case of a system error, in which case <tt>errno</tt> identifies the
+error. It returns a positive value in case of an error returned by
+a BearSSL decoder, in which case an appropriate message can be
+obtained with the <tt>sbearssl_error_str()</tt> function.
+</p>
+
+<h3> Miscellaneous utilities </h3>
+
+<p>
+ You probably shouldn't need to call any of these functions
+directly, except for the first one.
+</p>
+
+<h4> <code> char const *sbearssl_error_str (int err) </code> </h4>
+
+<p>
+ Returns a fixed string containing an error message corresponding
+to the <em>err</em> code, which must be non-negative. The return
+value from a few <tt>sbearssl</tt> functions, if positive, can be
+interpreted via this function.
+</p>
+
+<h4> <code> int sbearssl_isder (unsigned char const *s, size_t len) </code> </h4>
+
+<p>
+ Tests whether the array of <em>len</em> bytes pointed to by <em>s</em>
+looks like a DER-encoded object. Returns 1 if it does and 0 otherwise.
+</p>
+
+<h4> <code> int sbearssl_x509_minimal_set_tai (br_x509_minimal_context *ctx, tai_t t) </code> </h4>
+
+<p>
+ Sets the validation time for the X.509 context in *<em>ctx</em> to
+the absolute time contained in *<em>t</em>, which is a
+<a href="http://skarnet.org/software/skalibs/libstddjb/tai.html">tai_t</a>.
+Returns 1 if it succeeds, or 0 if it fails - probably
+because *<em>t</em> does not represent a valid time.
+</p>
+
+<h4> <code> int sbearssl_x509_minimal_set_tain (br_x509_minimal_context *ctx, tain_t a) </code> </h4>
+
+<p>
+ Same as the above function, except the time is given as a
+<a href="http://skarnet.org/software/skalibs/libstddjb/tai.html">tain_t</a>,
+i.e. a <tt>tai_t</tt> plus nanoseconds (which are simply ignored).
+</p>
+
+
+<h3> Running the TLS/SSL engine (both clients and servers) </h3>
+
+<h4> <code> int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity, uint32_t options, tain_t const *tto) </code> </h4>
+
+<p>
+ This function runs a full-duplex TLS/SSL engine, reading/writing
+clear text from/to two file descriptors, and writing/reading
+ciphertext to/from two other file descriptors, until the
+connection is closed both ways (either with a SSL close, or
+with EOF).
+</p>
+
+<ul>
+ <li> <em>ctx</em> is a pointer to a fully initialized context,
+connected to <em>fds</em>[2] and <em>fds</em>[3]. The
+TLS/SSL handshake does not have to be completed. </li>
+ <li> <em>fds</em> is an array of 4 file descriptors, in this
+order: fd reading clear text, fd writing clear text, fd reading
+ciphertext, fd writing ciphertext. </li>
+ <li> <em>verbosity</em> defines the engine's verbosity: the
+higher the more verbose. This parameter is currently ignored. </li>
+ <li> <em>options</em> is a bitfield.
+ <ul>
+ <li> bit 0 tells the engine how to behave when
+the local application closes the connection (i.e. when the engine
+reads EOF on <em>fds</em>[0]). If the bit is clear, then the
+engine will perform as SSL close: it will send a SSL close_notify,
+and stop processing incoming records, waiting for a peer
+acknowledgement of the close_notify. If the bit is set, then the
+engine will not send a close_notify but simply transmit EOF to
+the peer, while continuing to process incoming records until it
+gets EOF back. close_notify is secure when handling protocols that
+are not auto-terminated (such as HTTP 0.9), but it does not permit
+separate closing of both ways. EOF allows full-duplex until the
+very end, but is insecure if the application protocol does not
+know in advance how many bytes it should get. Modern application
+protocols should all work with EOF. </li>
+ </ul> </li>
+ <li> <em>tto</em> is a pointer to a
+ <a href="http://skarnet.org/software/skalibs/libstddjb/tai.html">tain_t</a>
+containing a relative time (i.e. a timeout) If *<em>tto</em> time elapses
+with no application data being exchanged, the engine will forcibly close the
+connection (with the method defined by <tt><em>options</em> &amp; 1</tt>).
+ You can use <tt>&amp;tain_infinite_relative</tt> as a value for <em>tto</em>
+if you don't want the engine to ever timeout. </li>
+</ul>
+
+<p>
+ <tt>sbearssl_run</tt> will make the process die with an appropriate error
+message if it encounters an unrecoverable error. If there were no problems
+and the SSL/TLS connection closed cleanly, it returns 0. If a SSL/TLS-level
+error occurred, it returns nonzero; a corresponding error message for the
+return value can be obtained via <tt>sbearssl_error_str()</tt>.
+All four descriptors in <em>fds</em> are closed when
+<tt>sbearssl_run</tt> returns.
+</p>
+
+<h4> <code> int sbearssl_s6tlsc (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity, char const *servername, int *sfd) </code> </h4>
+
+<p>
+ This function implements <a href="../s6-tlsc.html">s6-tlsc</a> on top of BearSSL.
+It has no other practical purpose; you're better off directly invoking
+<a href="../s6-tlsc.html">s6-tlsc</a>.
+</p>
+
+<h4> <code> int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity) </code> </h4>
+
+<p>
+ This function implements <a href="../s6-tlsd.html">s6-tlsd</a> on top of BearSSL.
+It has no other practical purpose; you're better off directly invoking
+<a href="../s6-tlsd.html">s6-tlsd</a>.
+</p>
+
+</body>
+</html>
diff --git a/doc/libstls/index.html b/doc/libstls/index.html
new file mode 100644
index 0000000..4c6819b
--- /dev/null
+++ b/doc/libstls/index.html
@@ -0,0 +1,127 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-networking: the stls library interface</title>
+ <meta name="Description" content="s6-networking: the stls library interface" />
+ <meta name="Keywords" content="s6-networking net stls library TLS SSL LibreSSL OpenSSL libtls" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="../">s6-networking</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>stls</tt> library interface </h1>
+
+<h2> General information </h2>
+
+<p>
+ <tt>libstls</tt> is a small support library for the
+<a href="../s6-tlsc.html">s6-tlsc</a> and
+<a href="../s6-tlsd.html">s6-tlsd</a> executables when they're built
+against the <a href="https://www.libressl.org/">LibreSSL</a>
+backend. You can use it in your own programs, but since
+<a href="http://man.openbsd.org/OpenBSD-current/man3/tls_init.3">libtls</a>
+is already relatively high-level, it's probably not very useful.
+</p>
+
+<h2> Compiling </h2>
+
+<ul>
+ <li> Make sure the s6-networking headers, as well as the skalibs headers,
+and the <tt>tls.h</tt> header, are visible in your header search path. </li>
+ <li> Use <tt>#include &lt;s6-networking/stls.h&gt;</tt> </li>
+</ul>
+
+<h2> Linking </h2>
+
+<ul>
+ <li> Make sure the s6-networking libraries, as well as the skalibs
+libraries, and the LibreSSL libraries, are visible in your library search path. </li>
+ <li> Link against <tt>-lstls</tt>, <tt>-lskarnet</tt>, <tt>-ltls</tt>,
+<tt>-lssl</tt>, <tt>-lcrypto</tt>,
+<tt>`cat $sysdeps/socket.lib`</tt>, <tt>`cat $sysdeps/spawn.lib`</tt>, and
+<tt>`cat $sysdeps/tainnow.lib`</tt>, where <tt>$sysdeps</tt> is your skalibs
+sysdeps directory. </li>
+</ul>
+
+<h2> Programming </h2>
+
+<h3> Running the TLS/SSL engine </h3>
+
+<h4> <code> int stls_run (struct tls *ctx, int *fds, unsigned int verbosity, uint32_t options, tain_t const *tto) </code> </h4>
+
+<p>
+ This function runs a full-duplex TLS/SSL engine, reading/writing
+clear text from/to two file descriptors, and writing/reading
+ciphertext to/from two other file descriptors, until the
+connection is closed both ways (either with a SSL close, or
+with EOF).
+</p>
+
+<ul>
+ <li> <em>ctx</em> is a pointer to a fully initialized context,
+connected to <em>fds</em>[2] and <em>fds</em>[3]. The TLS
+handshake must already be completed. </li>
+ <li> <em>fds</em> is an array of 4 file descriptors, in this
+order: fd reading clear text, fd writing clear text, fd reading
+ciphertext, fd writing ciphertext. </li>
+ <li> <em>verbosity</em> defines the engine's verbosity: the
+higher the more verbose. This parameter is currently ignored. </li>
+ <li> <em>options</em> is a bitfield.
+ <ul>
+ <li> bit 0 tells the engine how to behave when
+the local application closes the connection (i.e. when the engine
+reads EOF on <em>fds</em>[0]). If the bit is clear, then the
+engine will perform as SSL close: it will send a SSL close_notify,
+and stop processing incoming records, waiting for a peer
+acknowledgement of the close_notify. If the bit is set, then the
+engine will not send a close_notify but simply transmit EOF to
+the peer, while continuing to process incoming records until it
+gets EOF back. close_notify is secure when handling protocols that
+are not auto-terminated (such as HTTP 0.9), but it does not permit
+separate closing of both ways. EOF allows full-duplex until the
+very end, but is insecure if the application protocol does not
+know in advance how many bytes it should get. Modern application
+protocols should all work with EOF. </li>
+ </ul> </li>
+ <li> <em>tto</em> is a pointer to a
+ <a href="http://skarnet.org/software/skalibs/libstddjb/tai.html">tain_t</a>
+containing a relative time (i.e. a timeout). If *<em>tto</em> time elapses
+with no application data being exchanged, the engine will forcibly close the
+connection (with the method defined by <tt><em>options</em> &amp; 1</tt>).
+ You can use <tt>&amp;tain_infinite_relative</tt> as a value for <em>tto</em>
+if you don't want the engine to ever timeout. </li>
+</ul>
+
+<p>
+ <tt>stls_run</tt> will make the process die with an appropriate error
+message if it encounters an error. If there were no problems and the
+SSL/TLS connection closed cleanly, it returns 0. All four descriptors
+in <em>fds</em> are closed when <tt>stls_run</tt> returns, but the
+caller should still free <em>ctx</em> itself.
+</p>
+
+<h4> <code> int stls_s6tlsc (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity, char const *servername, int *sfd) </code> </h4>
+
+<p>
+ This function implements <a href="../s6-tlsc.html">s6-tlsc</a> on top of LibreSSL.
+It has no other practical purpose; you're better off directly invoking
+<a href="../s6-tlsc.html">s6-tlsc</a>.
+</p>
+
+<h4> <code> int stls_s6tlsd (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity) </code> </h4>
+
+<p>
+ This function implements <a href="../s6-tlsd.html">s6-tlsd</a> on top of LibreSSL.
+It has no other practical purpose; you're better off directly invoking
+<a href="../s6-tlsd.html">s6-tlsd</a>.
+</p>
+
+</body>
+</html>
diff --git a/doc/s6-tlsc.html b/doc/s6-tlsc.html
new file mode 100644
index 0000000..b44caf5
--- /dev/null
+++ b/doc/s6-tlsc.html
@@ -0,0 +1,268 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-networking: the s6-tlsc program</title>
+ <meta name="Description" content="s6-networking: the s6-tlsc program" />
+ <meta name="Keywords" content="s6-networking s6-tlsc tlsc tls ssl ucspi tcp inet network tcp/ip client" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-networking</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-tlsc</tt> program </h1>
+
+<p>
+<tt>s6-tlsc</tt> is a program that establishes a TLS or SSL
+client connection over an existing TCP connection, then spawns
+an application. It is meant to make network communications
+secure even for applications that do not natively support
+TLS/SSL.
+</p>
+
+<p>
+ <a href="index.html">s6-networking</a> does not include
+cryptographic software. All the crypto used in <tt>s6-tlsc</tt>
+is provided by the chosen SSL backend:
+<a href="https://bearssl.org/">BearSSL</a> or
+<a href="https://www.libressl.org/">LibreSSL</a>, depending on
+the options given when configuring <tt>s6-networking</tt>.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-tlsc [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v <em>verbosity</em> ] [ -K kimeout ] [ -k <em>servername</em> ] [ -6 <em>rfd</em> ] [ -7 <em>wfd</em> ] [ -- ] <em>prog...</em>
+</pre>
+
+<ul>
+ <li> s6-tlsc expects to have an open TCP connection it
+can talk to on its (by default) descriptors 6 (for reading)
+and 7 (for writing). </li>
+ <li> It spawns <em>prog...</em> as a child process,
+interposing itself between it and the network. </li>
+ <li> It initiates a TLS/SSL handshake over the
+network connection, expecting a TLS/SSL server on the other
+side. </li>
+ <li> It manages the encryption/decryption of all the
+messages between <em>prog</em> and the server.
+<em>prog</em> speaks plaintext, but only ciphertext is sent
+on the network. </li>
+ <li> When <em>prog</em> exits, <tt>s6-tlsc</tt> exits.
+</ul>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 96: error while configuring the TLS/SSL context - for instance, invalid trust anchor set. </li>
+ <li> 97: error while setting up the TLS/SSL client engine. </li>
+ <li> 98: TLS/SSL error while running the engine. </li>
+ <li> 100: wrong usage. </li>
+ <li> 111: system call failed. </li>
+</ul>
+
+<p>
+ If the TLS/SSL connection closes cleanly, <tt>s6-tlsc</tt>
+waits for <em>prog</em> to exit, then exits with an
+<a href="http://skarnet.org/software/execline/exitcodes.html">approximation</a>
+of <em>prog</em>'s exit code.
+</p>
+
+<h2> Protocol version and parameters </h2>
+
+<p>
+ During the TLS/SSL handshake, <tt>s6-tlsc</tt> tries
+every version of the protocol that is supported by the
+backend, with all supported algorithms and cipher suites;
+the backend normally ensures that the most secure combination
+is tried first, with slow degradation until the client and
+the server agree.
+</p>
+
+<ul>
+ <li> For BearSSL, this means use of the
+<a href="https://bearssl.org/apidoc/bearssl__ssl_8h.html#aa386dd0b03a0123760bf63df5a41c1e0">br_ssl_client_init_full()</a>
+function. The supported protocol versions are described
+<a href="https://bearssl.org/support.html#supported-versions">here</a>. </li>
+ <li> For LibreSSL, this means use of the
+<a href="http://man.openbsd.org/OpenBSD-current/man3/tls_config_set_protocols.3">tls_config_set_protocols(TLS_PROTOCOLS_ALL)</a>
+call. </li>
+</ul>
+
+<p>
+ As a client, it is better for <tt>s6-tlsc</tt> to adapt to as many servers
+as possible, that's why it adopts a liberal approach to protocol
+versions.
+</p>
+
+<h2> Environment variables </h2>
+
+<h3> Read </h3>
+
+<p>
+ <tt>s6-tlsc</tt> expects to have one of the
+<tt>CADIR</tt> or <tt>CAFILE</tt> environment variables set.
+It will refuse to run if both are unset. If both are set,
+<tt>CADIR</tt> has priority. The value of that variable is:
+</p>
+
+<ul>
+ <li> for <tt>CADIR</tt>: a directory where trust anchors
+(i.e. root or intermediate CA certificates) can be found,
+one per file, DER- or PEM-encoded. </li>
+ <li> for <tt>CAFILE</tt>: a file containing the whole set
+of trust anchors, PEM-encoded. </li>
+</ul>
+
+<p>
+ If you are using client certificates, s6-tlsc also reads
+two more environment variables: <tt>KEYFILE</tt> contains
+the path to a file containing the private key, DER- or
+PEM-encoded; and <tt>CERTFILE</tt> contains the path to
+a file containing the client certificate, DER- or
+PEM-encoded. Please note that for now, support for client
+certificates is experimental, and only works
+with the <a href="https://www.libressl.org/">LibreSSL</a>
+backend (BearSSL does not support client certificates yet).
+</p>
+
+<p>
+ If <tt>s6-tlsc</tt> is run as root, it can also read two
+other environment variables, <tt>TLS_UID</tt> and <tt>TLS_GID</tt>,
+which contain a numeric uid and a numeric gid; <tt>s6-tlsc</tt>
+then drops its root privileges to this uid/gid after spawning
+<em>prog...</em>. This ensures that the TLS/engine and the
+application run with different privileges. Note that <em>prog...</em>
+should drop its own root privileges by its own means: the
+<a href="http://skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>
+program is a way of doing it.
+</p>
+
+<h3> Written </h3>
+
+<p>
+ Unless the <tt>-Z</tt> option has been given to
+<tt>s6-tlsc</tt>, <em>prog...</em> is run with all the
+TLS/SSL variables <em>unset</em>: CADIR, CAFILE,
+KEYFILE, CERTFILE, TLS_UID and TLS_GID. The goal is
+for <tt>s6-tlsc</tt> to be, by default, as invisible
+as possible.
+</p>
+
+<h2> Server name determination for SNI </h2>
+
+<p>
+ The <tt>-k <em>servername</em></tt> option is important to
+<tt>s6-tlsc</tt>: it tells it to send <em>servername</em>
+as the name to require a certificate for.
+Not setting this option allows <tt>s6-tlsc</tt> to
+proceed without SNI,
+<strong>which may be a security risk.</strong>
+</p>
+
+<p>
+ The <a href="s6-tlsclient.html">s6-tlsclient</a> program can
+automatically craft a <tt>-k</tt> option for <tt>s6-tlsc</tt>
+if the <em>host</em> argument that is given to it is a
+host name. But if you're invoking <tt>s6-tlsc</tt> directly,
+do not forget to give it this option.
+</p>
+
+<h2> SSL close handling </h2>
+
+<p>
+ If <em>prog</em> initiates the end of the session by sending
+EOF, there are two ways for the TLS/SSL layer to handle it.
+</p>
+
+<ul>
+ <li> It can send a <tt>close_notify</tt> alert, and wait for
+an acknowledgement from the peer, at which point the connection
+is closed. The advantage of this setup is that it is secure
+even when the application protocol is not auto-terminated, i.e.
+when it does not know when its data stops. Old protocols such
+as HTTP-0.9 are in this case. The drawback of this setup is
+that it breaks full-duplex: once a peer has sent the
+<tt>close_notify</tt>, it must discard all the incoming
+records that are not a <tt>close_notify</tt> from the
+other peer. So if a client sends EOF while it is still
+receiving data from the server, the connection closes
+immediately and the data can be truncated. </li>
+ <li> It can simply transmit the EOF, shutting down
+half the TCP connection, and wait for the EOF back.
+The advantage of this setup is that it maintains
+full-duplex: a client can send EOF after its initial
+request, and still receive a complete answer from the
+server. The drawback is that it is insecure when the application
+protocol is not auto-terminated. </li>
+</ul>
+
+<p>
+ Nowadays (2016), most protocols are auto-terminated, so
+it is not dangerous anymore to use EOF tranmission, and that
+is the default fo <tt>s6-tlsc</tt>. Nevertheless, by
+using the <tt>-S</tt> option, you can
+force it to use the <tt>close_notify</tt> method if your
+application requires it to be secure.
+</p>
+
+<h2> <tt>s6-tlsc</tt> options </h2>
+
+<ul>
+ <li> <tt>-v&nbsp;<em>verbosity</em></tt>&nbsp: Be more or less
+verbose. Default for <em>verbosity</em> is 1. 0 is quiet, 2 is
+verbose, more than 2 is debug output. This option currently has
+no effect. </li>
+ <li> <tt>-Z</tt>&nbsp;: do not clean the environment of
+<tt>s6-tlsc</tt>-related variables before spawning <em>prog...</em>. </li>
+ <li> <tt>-z</tt>&nbsp;: clean the environment of
+<tt>s6-tlsc</tt>-related variables before spawning <em>prog...</em>.
+This is the default. </li>
+ <li> <tt>-S</tt>&nbsp;: send a <tt>close_notify</tt> alert
+and break the connection when <em>prog</em> sends EOF. </li>
+ <li> <tt>-s</tt>&nbsp;: transmit EOF by half-closing the TCP
+connection without using <tt>close_notify</tt>. This is the default. </li>
+ <li> <tt>-Y</tt>&nbsp;: Do not send a client certificate. This is the default. </li>
+ <li> <tt>-y</tt>&nbsp;: Send a client certificate. This is experimental and
+for now unsupported by BearSSL. </li>
+ <li> <tt>-k&nbsp;<em>servername</em></tt>&nbsp: use Server Name
+Indication, and send <em>servername</em>. The default is not to
+use SNI, which may be a security risk. </li>
+ <li> <tt>-K&nbsp;<em>kimeout</em></tt>&nbsp;: close the connection
+if <em>kimeout</em> milliseconds elapse without any data being
+received from either side. The default is 0, which means
+infinite timeout (never kill the connection). </li>
+ <li> <tt>-6&nbsp;<em>rfd</em></tt>&nbsp;: expect an open file
+descriptor numbered <em>rfd</em> to read network (ciphertext)
+data from. Make sure <em>prog</em> also reads its data
+from its own fd <em>rfd</em>. Default is 6. </li>
+ <li> <tt>-7&nbsp;<em>wfd</em></tt>&nbsp;: expect an open file
+descriptor numbered <em>wfd</em> to write network (ciphertext)
+data to. Make sure <em>prog</em> also writes its data to
+its own fd <em>wfd</em>. Default is 7. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> The goal of the <tt>s6-tlsc</tt> interface (and its
+server-side companion <a href="s6-tlsd.html">s6-tlsd</a> is to
+make it so that if you have a client, run by the command line
+<tt>client...</tt> that speaks a cleartext protocol to a server
+run by the command line <tt>server...</tt>, then if the server
+has the proper private key and certificate, and the client has
+the proper list of trust anchors, you can just change the
+client command line to <tt>s6-tlsc client...</tt> and the
+server command line to <tt>s6-tlsd server...</tt>
+without changing the client or the server themselves, and the
+communication between them will be secure. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-tlsclient.html b/doc/s6-tlsclient.html
new file mode 100644
index 0000000..aea1c33
--- /dev/null
+++ b/doc/s6-tlsclient.html
@@ -0,0 +1,168 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-networking: the s6-tlsclient program</title>
+ <meta name="Description" content="s6-networking: the s6-tlsclient program" />
+ <meta name="Keywords" content="s6-networking s6-tlsclient tlsclient tls ssl ucspi tcp inet network tcp/ip client" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-networking</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-tlsclient</tt> program </h1>
+
+<p>
+<tt>s6-tlsclient</tt> is an
+<a href="http://cr.yp.to/proto/ucspi.txt">UCSPI client tool</a> for
+TLS/SSL connections over INET domain sockets. It establishes a TCP
+connection to a server and a TLS transport over it,
+then executes into a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-tlsclient [ <em>options</em> ] [ -- ] <em>host</em> <em>port</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> s6-tlsclient rewrites itself into a command line
+involving:
+ <ul>
+ <li> <a href="s6-tcpclient.html">s6-tcpclient</a>, which
+establishes a TCP connection to host <em>host</em> port <em>port</em>. </li>
+ <li> <a href="s6-tlsc.html">s6-tlsc</a>, which establishes
+a TLS transport (client-side) over that connection. </li>
+ <li> <em>prog...</em>, your client program, which is run as a
+child of <a href="s6-tlsc.html">s6-tlsc</a>. </li>
+ </ul> </li>
+ <li> It runs until the connection closes. </li>
+ <li> It exits either with a <a href="s6-tlsc.html">s6-tlsc</a>
+error code (and error message), or with an
+<a href="https://skarnet.org/software/execline/exitcodes.html">approximation</a>
+of <em>prog</em>'s exit code. </li>
+</ul>
+
+<p>
+ <em>prog</em> is expected to read from its peer on
+descriptor 6 and write to its peer on descriptor 7.
+Since there will be a <a href="s6-tlsc.html">s6-tlsc</a>
+program between <em>prog</em> and the network to perform
+the SSL encryption/decryption, those descriptors will not
+be a network socket - they will be pipes.
+</p>
+
+<h2> Server name determination for SNI </h2>
+
+<p>
+
+ If the <tt>-H</tt> option is not given to <tt>s6-tlsclient</tt>,
+then <em>host</em> will be used as the server name to verify.
+You can use the <tt>-k</tt> option to override this default.
+Please note that if you use the <tt>-H</tt> option and do not
+provide a server name via <tt>-k</tt>, <strong>SNI will not be
+used, which may be a security risk.</strong>
+</p>
+
+
+<h2> Environment variables </h2>
+
+<h3> Read </h3>
+
+<p>
+ The following variables should be set before invoking
+<tt>s6-tlsclient</tt>, because they will be used by
+<a href="s6-tlsc.html">s6-tlsc</a>:
+</p>
+
+<ul>
+ <li> CADIR </li>
+ <li> CAFILE (alternative to CADIR) </li>
+ <li> KEYFILE (if you're using a client certificate) </li>
+ <li> CERTFILE (if you're using a client certificate) </li>
+ <li> TLS_UID and TLS_GID (if you run <tt>s6-tlsclient</tt> as root) </li>
+</ul>
+
+<p>
+ Setting either CADIR or CAFILE is mandatory.
+</p>
+
+<h3> Written </h3>
+
+<p>
+ <em>prog...</em> is run with the following variables added to,
+or removed from, its environment by <a href="s6-tcpclient.html">s6-tcpclient</a>:
+</p>
+
+<ul>
+ <li> PROTO </li>
+ <li> TCPREMOTEIP </li>
+ <li> TCPREMOTEPORT </li>
+ <li> TCPREMOTEHOST </li>
+ <li> TCPLOCALHOST </li>
+ <li> TCPREMOTEINFO </li>
+</ul>
+
+<p>
+ Unless the <tt>-Z</tt> option is given to <tt>s6-tlsclient</tt>,
+the CADIR, CAFILE, KEYFILE, CERTFILE, TLS_UID and TLS_GID
+variables will not appear in <em>prog</em>'s environment.
+</p>
+
+
+<h2> Options </h2>
+
+<p>
+ <tt>s6-tlsclient</tt> accepts a myriad of options, most of which are
+passed as is to the correct executable. Not giving any options will
+generally work: the defaults are sensible.
+</p>
+
+<h3> Options passed as is to s6-tcpclient </h3>
+
+<ul>
+ <li> <tt>-q</tt>, <tt>-Q</tt>, <tt>-v</tt> </li>
+ <li> <tt>-4</tt>, <tt>-6</tt> </li>
+ <li> <tt>-d</tt>, <tt>-D</tt> </li>
+ <li> <tt>-r</tt>, <tt>-R</tt> </li>
+ <li> <tt>-h</tt>, <tt>-H</tt>, <tt>-l <em>localname</em></tt> </li>
+ <li> <tt>-n</tt>, <tt>-N</tt> </li>
+ <li> <tt>-t <em>timeout</em></tt> </li>
+ <li> <tt>-i <em>localip</em></tt>, <tt>-p <em>localport</em></tt> </li>
+ <li> <tt>-T <em>timeoutconn</em></tt> </li>
+</ul>
+
+<h3> Options passed as is to s6-tlsc </h3>
+
+<ul>
+ <li> <tt>-Z</tt>, <tt>-z</tt> </li>
+ <li> <tt>-S</tt>, <tt>-s</tt> </li>
+ <li> <tt>-Y</tt>, <tt>-y</tt> </li>
+ <li> <tt>-k <em>servername</em></tt> </li>
+ <li> <tt>-K <em>kimeout</em></tt> </li>
+</ul>
+
+<h2> Example </h2>
+
+<p>
+ <code> CADIR=/etc/ssl/certs s6-tlsclient skarnet.org 443 s6-ioconnect </code>
+</p>
+
+<p>
+ This will open a connection to
+<a href="https://skarnet.org/">the skarnet.org web server
+over TLS</a> and verify its certificate via the trust anchors
+listed in the <tt>/etc/ssl/certs</tt> directory. It will then
+branch your terminal to it: try typing
+<tt>GET / HTTP/1.0</tt> then hitting return twice.
+</p>
+
+</body>
+</html>
diff --git a/doc/s6-tlsd.html b/doc/s6-tlsd.html
new file mode 100644
index 0000000..ab3243a
--- /dev/null
+++ b/doc/s6-tlsd.html
@@ -0,0 +1,280 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-networking: the s6-tlsd program</title>
+ <meta name="Description" content="s6-networking: the s6-tlsd program" />
+ <meta name="Keywords" content="s6-networking s6-tlsd tlsd tls ssl ucspi tcp inet network tcp/ip server" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-networking</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-tlsd</tt> program </h1>
+
+<p>
+<tt>s6-tlsd</tt> is a program that performs the server side of
+a TLS or SSL connection over an existing TCP connection, then spawns
+an application. It is meant to make network communications
+secure even for applications that do not natively support
+TLS/SSL.
+</p>
+
+<p>
+ <a href="index.html">s6-networking</a> does not include
+cryptographic software. All the crypto used in <tt>s6-tlsc</tt>
+is provided by the chosen SSL backend:
+<a href="https://bearssl.org/">BearSSL</a> or
+<a href="https://www.libressl.org/">LibreSSL</a>, depending on
+the options given when configuring <tt>s6-networking</tt>.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-tlsd [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v <em>verbosity</em> ] [ -K kimeout ] [ -- ] <em>prog...</em>
+</pre>
+
+<ul>
+ <li> s6-tlsd expects to have an open TCP connection it
+can talk to on its stdin (for reading) and stdout
+(for writing). </li>
+ <li> It spawns <em>prog...</em> as a child process,
+interposing itself between it and the network.
+In other words: <em>prog</em> still reads cleartext
+on its stdin and writes cleartext on its stdout, but
+those will actually be pipes to <tt>s6-tlsd</tt>, which
+will read ciphertext from its own stdin (the network)
+and write ciphertext to its own stdout (the network). </li>
+ <li> It initiates the server side of a TLS/SSL handshake
+over the network connection, expecting a TLS/SSL client on
+the other side. </li>
+ <li> It manages the encryption/decryption of all the
+messages between <em>prog</em> and the client.
+<em>prog</em> speaks plaintext, but only ciphertext is sent
+on the network. </li>
+ <li> When <em>prog</em> exits, <tt>s6-tlsd</tt> exits.
+</ul>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 96: error while configuring the TLS/SSL context - for instance, invalid
+private key or server certificate files. </li>
+ <li> 97: error while setting up the TLS/SSL client engine. </li>
+ <li> 98: TLS/SSL error while running the engine. </li>
+ <li> 100: wrong usage. </li>
+ <li> 111: system call failed. </li>
+</ul>
+
+<p>
+ If the TLS/SSL connection closes cleanly, <tt>s6-tlsd</tt>
+waits for <em>prog</em> to exit, then exits with an
+<a href="http://skarnet.org/software/execline/exitcodes.html">approximation</a>
+of <em>prog</em>'s exit code.
+</p>
+
+<h2> Protocol version and parameters </h2>
+
+<p>
+ During the TLS/SSL handshake, <tt>s6-tlsd</tt> tries the
+versions of the protocol that is supported by default by the
+backend, with the default algorithms and cipher suites;
+the backend normally ensures that the most secure combination
+is tried first, with slow degradation until the client and
+the server agree.
+</p>
+
+<ul>
+ <li> For BearSSL, this means use of the
+<a href="https://bearssl.org/apidoc/bearssl__ssl_8h.html#a76293c81c4624c58254a62be7b2d5e79">br_ssl_server_init_full_rsa()</a> or
+<a href="https://bearssl.org/apidoc/bearssl__ssl_8h.html#a592b2af27b2f6b9389aac854fb0b783a">br_ssl_server_init_full_ec()</a>
+function. The supported protocol versions are described
+<a href="https://bearssl.org/support.html#supported-versions">here</a>. </li>
+ <li> For LibreSSL, this means use of the
+<a href="http://man.openbsd.org/OpenBSD-current/man3/tls_config_set_protocols.3">tls_config_set_protocols(TLS_PROTOCOLS_DEFAULT)</a>
+call. </li>
+</ul>
+
+<p>
+ As a server, <tt>s6-tlsd</tt> can be conservative in its
+choice of protocols. It is currently not very conservative
+when using the BearSSL backend; it could become more so in
+the future, by defining a custom server profile that supports
+only TLS-1.2 but with several algorithms and cipher suites.
+</p>
+
+<h2> Environment variables </h2>
+
+<h3> Read </h3>
+
+<p>
+ <tt>s6-tlsd</tt> expects to have the following
+environment variables set:
+</p>
+
+<ul>
+ <li> <tt>KEYFILE</tt>: a path to the file
+containing the server's private key, DER- or PEM-encoded. </li>
+ <li> <tt>CERTFILE</tt>: a path to the file
+containing the server's certificate, DER- or PEM-encoded.
+If PEM-encoded, the file can actually contain a chain
+of certificates. </li>
+</ul>
+
+<p>
+ If one of those variables is unset, <tt>s6-tlsd</tt>
+will refuse to run.
+</p>
+
+<p>
+ If you are using client certificats, <tt>s6-tlsd</tt>
+also requires either one of the following variables to be set:
+</p>
+
+<ul>
+ <li> <tt>CADIR</tt>: a directory where trust anchors
+(i.e. root or intermediate CA certificates) can be found,
+one per file, DER- or PEM-encoded. </li>
+ <li> <tt>CAFILE</tt>: a file containing the whole set
+of trust anchors, PEM-encoded. </li>
+</ul>
+
+<p>
+Please note that for now, support for client
+certificates is experimental, and only works
+with the <a href="https://www.libressl.org/">LibreSSL</a>
+backend (BearSSL does not support client certificates yet).
+</p>
+
+<p>
+ If <tt>s6-tlsd</tt> is run as root, it can also read two
+more environment variables, <tt>TLS_UID</tt> and <tt>TLS_GID</tt>,
+which contain a numeric uid and a numeric gid; <tt>s6-tlsd</tt>
+then drops its root privileges to this uid/gid after spawning
+<em>prog...</em>. This ensures that the TLS/engine and the
+application run with different privileges.
+</p>
+
+<p>
+ Note that <em>prog...</em>
+should drop its own root privileges by its own means: the
+<a href="http://skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>
+program is a way of doing it. If the <tt>s6-tlsd</tt>
+invocation actually comes from a
+<a href="s6-tlsserver.html">s6-tlsserver</a> command line,
+and privilege-dropping options (<tt>-G</tt>, <tt>-g</tt>,
+<tt>-u</tt> or <tt>-U</tt>) have been given to
+<a href="s6-tlsserver.html">s6-tlsserver</a>, then
+<a href="http://skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>
+directly follows <tt>s6-tlsd</tt> on the command line, in order
+to also drop the child's privileges before executing the application.
+The point of that setup is:
+</p>
+
+<ul>
+ <li> To read the private key file as root </li>
+ <li> To run the application as a non-root user </li>
+ <li> To run <tt>s6-tlsd</tt> as a <em>different</em> non-root user </li>
+ <li> That way, even if <tt>s6-tlsd</tt>, the application, or both,
+get compromised, the private key is still secure. </li>
+</ul>
+
+<h3> Written </h3>
+
+<p>
+ Unless the <tt>-Z</tt> option has been given to
+<tt>s6-tlsd</tt>, <em>prog...</em> is run with all the
+TLS/SSL variables <em>unset</em>: CADIR, CAFILE,
+KEYFILE, CERTFILE, TLS_UID and TLS_GID. The goal is
+for <tt>s6-tlsd</tt> to be, by default, as invisible
+as possible.
+</p>
+
+<h2> SSL close handling </h2>
+
+<p>
+ If <em>prog</em> initiates the end of the session by sending
+EOF, there are two ways for the TLS/SSL layer to handle it.
+</p>
+
+<ul>
+ <li> It can send a <tt>close_notify</tt> alert, and wait for
+an acknowledgement from the peer, at which point the connection
+is closed. The advantage of this setup is that it is secure
+even when the application protocol is not auto-terminated, i.e.
+when it does not know when its data stops. Old protocols such
+as HTTP-0.9 are in this case. The drawback of this setup is
+that it breaks full-duplex: once a peer has sent the
+<tt>close_notify</tt>, it must discard all the incoming
+records that are not a <tt>close_notify</tt> from the
+other peer. So if a client sends EOF while it is still
+receiving data from the server, the connection closes
+immediately and the data can be truncated. </li>
+ <li> It can simply transmit the EOF, shutting down
+half the TCP connection, and wait for the EOF back.
+The advantage of this setup is that it maintains
+full-duplex: a client can send EOF after its initial
+request, and still receive a complete answer from the
+server. The drawback is that it is insecure when the application
+protocol is not auto-terminated. </li>
+</ul>
+
+<p>
+ Nowadays (2016), most protocols are auto-terminated, so
+it is not dangerous anymore to use EOF tranmission, and that
+is the default fo <tt>s6-tlsd</tt>. Nevertheless, by
+using the <tt>-S</tt> option, you can
+force it to use the <tt>close_notify</tt> method if your
+application requires it to be secure.
+</p>
+
+<h2> <tt>s6-tlsd</tt> options </h2>
+
+<ul>
+ <li> <tt>-v&nbsp;<em>verbosity</em></tt>&nbsp: Be more or less
+verbose. Default for <em>verbosity</em> is 1. 0 is quiet, 2 is
+verbose, more than 2 is debug output. This option currently has
+no effect. </li>
+ <li> <tt>-Z</tt>&nbsp;: do not clean the environment of
+<tt>s6-tlsd</tt>-related variables before spawning <em>prog...</em>. </li>
+ <li> <tt>-z</tt>&nbsp;: clean the environment of
+<tt>s6-tlsd</tt>-related variables before spawning <em>prog...</em>.
+This is the default. </li>
+ <li> <tt>-S</tt>&nbsp;: send a <tt>close_notify</tt> alert
+and break the connection when <em>prog</em> sends EOF. </li>
+ <li> <tt>-s</tt>&nbsp;: transmit EOF by half-closing the TCP
+connection without using <tt>close_notify</tt>. This is the default. </li>
+ <li> <tt>-Y</tt>&nbsp;: Do not require a client certificate. This is the default. </li>
+ <li> <tt>-y</tt>&nbsp;: Require a client certificate. This is experimental and
+for now unsupported by BearSSL. </li>
+ <li> <tt>-K&nbsp;<em>kimeout</em></tt>&nbsp;: close the connection
+if <em>kimeout</em> milliseconds elapse without any data being
+received from either side. The default is 0, which means
+infinite timeout (never kill the connection). </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> The goal of the <tt>s6-tlsd</tt> interface (and its
+client-side companion <a href="s6-tlsc.html">s6-tlsc</a> is to
+make it so that if you have a client, run by the command line
+<tt>client...</tt> that speaks a cleartext protocol to a server
+run by the command line <tt>server...</tt>, then if the server
+has the proper private key and certificate, and the client has
+the proper list of trust anchors, you can just change the
+client command line to <tt>s6-tlsc client...</tt> and the
+server command line to <tt>s6-tlsd server...</tt>
+without changing the client or the server themselves, and the
+communication between them will be secure. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-tlsserver.html b/doc/s6-tlsserver.html
new file mode 100644
index 0000000..e50f817
--- /dev/null
+++ b/doc/s6-tlsserver.html
@@ -0,0 +1,216 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-networking: the s6-tlsserver program</title>
+ <meta name="Description" content="s6-networking: the s6-tlsserver program" />
+ <meta name="Keywords" content="s6-networking s6-tlsclient tlsserver tls ssl ucspi tcp inet network tcp/ip server superserver" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-networking</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-tlsserver</tt> program </h1>
+
+<p>
+<tt>s6-tlsserver</tt> is an
+<a href="http://cr.yp.to/proto/ucspi.txt">UCSPI server tool</a> for
+TLS/SSL connections over INET domain sockets. It acts as a TCP superserver
+that listens to connections, accepts them, and for each connection,
+establishes a TLS transport over it, then executes into a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-tlsserver [ <em>options</em> ] [ -- ] <em>ip</em> <em>port</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> s6-tlsserver rewrites itself into a command line
+involving:
+ <ul>
+ <li> <a href="s6-tcpserver.html">s6-tcpserver</a>, which
+listens to TCP connections on IP address <em>ip</em> port <em>port</em>
+and forks a command line for every connection. Note that
+<a href="s6-tcpserver.html">s6-tcpserver</a> also rewrites
+itself into a more complex commnd line (the final long-lived
+process being <a href="s6-tcpserver4d.html">s6-tcpserver4d</a>
+or <a href="s6-tcpserver4d.html">s6-tcpserver6d</a>),
+so your end command line may look a lot longer in <tt>ps</tt>
+than what you originally wrote. This is normal and healthy. </li>
+ <li> (if applicable) <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>,
+which performs TCP access control and various operations on the
+TCP connection. </li>
+ <li> <a href="s6-tlsd.html">s6-tlsd</a>, which establishes
+a TLS transport (server-side) over a connection. </li>
+ <li> (if applicable)
+<a href="http://skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>,
+which drops root privileges. </li>
+ <li> <em>prog...</em>, your client program, which is run as a
+child of <a href="s6-tlsd.html">s6-tlsd</a>. </li>
+ </ul> </li>
+ <li> It runs until it is killed by a signal. </li>
+</ul>
+
+<p>
+ <em>prog</em> is expected to read from its peer on its
+standard input and write to its peer on its standard output.
+Since there will be a <a href="s6-tlsd.html">s6-tlsd</a>
+program between <em>prog</em> and the network to perform
+the SSL encryption/decryption, those descriptors will not
+be a network socket - they will be pipes.
+</p>
+
+<h2> Signals </h2>
+
+<p>
+ <tt>s6-tlsserver</tt> reacts to the same signals as
+<a href="s6-tcpserver4d.html">s6-tcpserver4d</a> or
+<a href="s6-tcpserver6d.html">s6-tcpserver6d</a>,
+one of which is the long-lived process hanging around.
+</p>
+
+<h2> Environment variables </h2>
+
+<h3> Read </h3>
+
+<p>
+ The following variables should be set before invoking
+<tt>s6-tlsserver</tt>, because they will be used by
+every <a href="s6-tlsd.html">s6-tlsd</a> invocation:
+</p>
+
+<ul>
+ <li> KEYFILE </li>
+ <li> CERTFILE </li>
+ <li> TLS_UID and TLS_GID (if you run <tt>s6-tlsserver</tt> as root) </li>
+ <li> CADIR (if you want client certificates) </li>
+ <li> CAFILE (if you want client certificates, alternative to CADIR) </li>
+</ul>
+
+<p>
+ Setting both KEYFILE and CERTFILE is mandatory.
+</p>
+
+<h3> Written </h3>
+
+<p>
+ <em>prog...</em> is run with the following variables added to,
+or removed from, its environment by <a href="s6-tcpserver4d.html">s6-tcpserver4d</a>
+or <a href="s6-tcpserver6d.html">s6-tcpserver6d</a>, and possibly
+by <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>:
+</p>
+
+<ul>
+ <li> PROTO </li>
+ <li> TCPREMOTEIP </li>
+ <li> TCPREMOTEPORT </li>
+ <li> TCPCONNNUM </li>
+ <li> TCPLOCALIP </li>
+ <li> TCPLOCALPORT </li>
+ <li> TCPREMOTEHOST </li>
+ <li> TCPLOCALHOST </li>
+ <li> TCPREMOTEINFO </li>
+</ul>
+
+<p>
+ Depending on TCP access rules (if the <tt>-i</tt> or <tt>-x</tt>
+option has been given), it is possible that <em>prog</em>'s
+environment undergoes more modifications. Also, since
+<a href="s6-tlsd.html">s6-tlsd</a> is always run
+after <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>,
+it is possible to set different TLS/SSL parameters (typically
+a different KEYFILE and CERTFILE) depending on the client
+connection, by writing the correct set of TCP access rules.
+</p>
+
+<p>
+ Unless the <tt>-Z</tt> option is given to <tt>s6-tlsserver</tt>,
+the CADIR, CAFILE, KEYFILE, CERTFILE, TLS_UID and TLS_GID
+variables will not appear in <em>prog</em>'s environment.
+</p>
+
+
+<h2> Options </h2>
+
+<p>
+ <tt>s6-tlsserver</tt> accepts a myriad of options, most of which are
+passed as is to the correct executable. Not giving any options will
+generally work, but unless you're running a very public server
+(such as a Web server) or base your access control on client
+certificates, you probably still want TCP access rules.
+</p>
+
+<h3> Options passed as is to s6-tcpserver </h3>
+
+<ul>
+ <li> <tt>-q</tt>, <tt>-Q</tt>, <tt>-v</tt> </li>
+ <li> <tt>-4</tt>, <tt>-6</tt> </li>
+ <li> <tt>-1</tt> </li>
+ <li> <tt>-c <em>maxconn</em></tt> </li>
+ <li> <tt>-C <em>localmaxconn</em></tt> </li>
+ <li> <tt>-b <em>backlog</em></tt> </li>
+</ul>
+
+<h3> Options passed as is to s6-tcpserver-access </h3>
+
+<ul>
+ <li> The verbosity level, if not default, as <tt>-v0</tt> or <tt>-v2</tt> </li>
+ <li> <tt>-w</tt>, <tt>-W</tt> </li>
+ <li> <tt>-d</tt>, <tt>-D</tt> </li>
+ <li> <tt>-r</tt>, <tt>-R</tt> </li>
+ <li> <tt>-p</tt>, <tt>-P</tt> </li>
+ <li> <tt>-h</tt>, <tt>-H</tt>, <tt>-l <em>localname</em></tt> </li>
+ <li> <tt>-B <em>banner</em></tt> </li>
+ <li> <tt>-t <em>timeout</em></tt> </li>
+ <li> <tt>-i <em>rulesdir</em></tt>, <tt>-x <em>rulesfile</em></tt> </li>
+</ul>
+
+<h3> Options passed as is to s6-tlsd </h3>
+
+<ul>
+ <li> <tt>-Z</tt>, <tt>-z</tt> </li>
+ <li> <tt>-S</tt>, <tt>-s</tt> </li>
+ <li> <tt>-Y</tt>, <tt>-y</tt> </li>
+ <li> <tt>-k <em>servername</em></tt> </li>
+ <li> <tt>-K <em>kimeout</em></tt> </li>
+</ul>
+
+<h3> Options passed to s6-applyuidgid </h3>
+
+<ul>
+ <li> <tt>-u <em>uid</em></tt>, <tt>-g <em>gid</em></tt>, <tt>-G <em>gidlist</em></tt> </li>
+ <li> <tt>-U</tt> (passed as <tt>-Uz</tt>) </li>
+</ul>
+
+<h2> Example </h2>
+
+
+<p>
+ As root:
+ <code> KEYFILE=/etc/ssl/private/mykey.der CERTFILE=/etc/ssl/public/mycert.pem \
+ TLS_UID=65534 TLS_UID=65536 \
+ s6-envuidgid www
+ s6-tlsserver -U -- 1.2.3.4 443 httpd </code>
+</p>
+
+<p>
+This will start a server listening to 1.2.3.4 on TCP port 443,
+ and for every connection, spawn the <tt>httpd</tt> program
+reading queries on stdin and replying on stdout, as user <tt>www</tt>,
+with a TLS layer protecting the connection, the TLS engine running
+as user <tt>nobody</tt> (<tt>65534:65534</tt>). The server is
+authentified by the certificate in <tt>/etc/ssl/public/mycert.pem</tt>
+that it sends to the client, and the private key in
+<tt>/etc/ssl/private/mykey.der</tt> that it keeps to itself.
+</p>
+
+</body>
+</html>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 4b20888..b2cfe21 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -22,7 +22,7 @@
<ul>
<li> skalibs dependency bumped to 2.4.0.1. </li>
- <li> TLS 1.2 support added:
+ <li> SSL/TLS support added:
<ul>
<li> <a href="s6-tlsclient.html">s6-tlsclient</a> </li>
<li> <a href="s6-tlsserver.html">s6-tlsserver</a> </li>
diff --git a/src/conn-tools/s6-tlsserver.c b/src/conn-tools/s6-tlsserver.c
index bb7b060..e0c3387 100644
--- a/src/conn-tools/s6-tlsserver.c
+++ b/src/conn-tools/s6-tlsserver.c
@@ -138,7 +138,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
unsigned int m = 0 ;
unsigned int pos = 0 ;
char fmt[UINT_FMT * 5 + GID_FMT * (NGROUPS_MAX + 1) + UINT64_FMT] ;
- char const *newargv[47 + argc] ;
+ char const *newargv[45 + argc] ;
newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver" ;
if (o.verbosity != 1) newargv[m++] = o.verbosity ? "-v" : "-q" ;
if (o.flag46) newargv[m++] = o.flag46 == 1 ? "-4" : "-6" ;
@@ -171,10 +171,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
{
newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver-access" ;
if (o.verbosity != 1)
- {
- newargv[m++] = "-v" ;
- newargv[m++] = o.verbosity ? "2" : "0" ;
- }
+ newargv[m++] = o.verbosity ? "-v2" : "-v0" ;
if (o.flagw) newargv[m++] = "-w" ;
if (o.flagD) newargv[m++] = "-D" ;
if (o.flagH) newargv[m++] = "-H" ;
@@ -206,10 +203,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
}
newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tlsd" ;
if (o.verbosity != 1)
- {
- newargv[m++] = "-v" ;
- newargv[m++] = o.verbosity ? "2" : "0" ;
- }
+ newargv[m++] = o.verbosity ? "-v2" : "-v0" ;
if (o.flagS) newargv[m++] = "-S" ;
if (o.flagy) newargv[m++] = "-y" ;
if (o.kimeout)
diff --git a/src/sbearssl/sbearssl_run.c b/src/sbearssl/sbearssl_run.c
index e4d49fa..ca4a79e 100644
--- a/src/sbearssl/sbearssl_run.c
+++ b/src/sbearssl/sbearssl_run.c
@@ -71,7 +71,12 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
else if (!r)
{
fd_close(fds[0]) ; fds[0] = -1 ;
- br_ssl_engine_close(ctx) ;
+ if (options & 1)
+ {
+ shutdown(fds[3], SHUT_WR) ;
+ fd_close(fds[3]) ; fds[3] = -1 ;
+ }
+ else br_ssl_engine_close(ctx) ;
continue ;
}
diff --git a/src/stls/stls_run.c b/src/stls/stls_run.c
index 848295c..86e0faa 100644
--- a/src/stls/stls_run.c
+++ b/src/stls/stls_run.c
@@ -6,7 +6,6 @@
#include <errno.h>
#include <signal.h>
#include <tls.h>
-#include <skalibs/uint32.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/error.h>
#include <skalibs/buffer.h>
@@ -116,7 +115,7 @@ static void closeit (struct tls *ctx, int *fds, int brutal)
fd_close(fds[3]) ; fds[3] = -1 ;
}
-int stls_run (struct tls *ctx, int *fds, unsigned int verbosity, uint32 options, tain_t const *tto)
+int stls_run (struct tls *ctx, int *fds, unsigned int verbosity, uint32_t options, tain_t const *tto)
{
tlsbuf_t b[2] = { { .blockedonother = 0 }, { .blockedonother = 0 } } ;
iopause_fd x[4] ;
@@ -138,7 +137,7 @@ int stls_run (struct tls *ctx, int *fds, unsigned int verbosity, uint32 options,
unsigned int xlen = 0 ;
register int r ;
- tain_add_g(&deadline, fds[0] >= 0 && fds[1] >= 0 && buffer_isempty(&b[0].b) && buffer_isempty(&b[1].b) ? tto : &tain_infinite_relative) ;
+ tain_add_g(&deadline, fds[0] >= 0 && fds[2] >= 0 && buffer_isempty(&b[0].b) && buffer_isempty(&b[1].b) ? tto : &tain_infinite_relative) ;
/* poll() preparation */
diff --git a/src/stls/stls_s6tlsc.c b/src/stls/stls_s6tlsc.c
index 70e8f20..bafc2b8 100644
--- a/src/stls/stls_s6tlsc.c
+++ b/src/stls/stls_s6tlsc.c
@@ -75,7 +75,7 @@ int stls_s6tlsc (char const *const *argv, char const *const *envp, tain_t const
diecfg(cfg, "tls_config_set_ecdhecurve") ;
tls_config_verify(cfg) ;
- tls_config_set_protocols(cfg, TLS_PROTOCOLS_DEFAULT) ;
+ tls_config_set_protocols(cfg, TLS_PROTOCOLS_ALL) ;
tls_config_prefer_ciphers_server(cfg) ;
if (!servername) tls_config_insecure_noverifyname(cfg) ;