diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/index.html | 7 | ||||
-rw-r--r-- | doc/libsbearssl/index.html | 131 | ||||
-rw-r--r-- | doc/libstls/index.html | 112 | ||||
-rw-r--r-- | doc/s6-tlsc-io.html | 217 | ||||
-rw-r--r-- | doc/s6-tlsc.html | 197 | ||||
-rw-r--r-- | doc/s6-tlsclient.html | 18 | ||||
-rw-r--r-- | doc/s6-tlsd-io.html | 212 | ||||
-rw-r--r-- | doc/s6-tlsd.html | 193 | ||||
-rw-r--r-- | doc/s6-tlsserver.html | 11 | ||||
-rw-r--r-- | doc/s6-ucspitlsc.html | 178 | ||||
-rw-r--r-- | doc/s6-ucspitlsd.html | 168 | ||||
-rw-r--r-- | doc/tls-overview.html | 142 |
12 files changed, 1195 insertions, 391 deletions
diff --git a/doc/index.html b/doc/index.html index 049ed70..f402ab3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -139,10 +139,15 @@ relevant page. <h4> UCSPI tools for secure communication (TLS protocol) over TCP </h4> <ul> +<li> An <a href="tls-overview.html">overview</a> of the TLS-related programs </li> <li><a href="s6-tlsclient.html">The <tt>s6-tlsclient</tt> program</a></li> -<li><a href="s6-tlsserver.html">The <tt>s6-tlsserver</tt> program</a></li> <li><a href="s6-tlsc.html">The <tt>s6-tlsc</tt> program</a></li> +<li><a href="s6-tlsc-io.html">The <tt>s6-tlsc-io</tt> program</a></li> +<li><a href="s6-ucspitlsc.html">The <tt>s6-ucspitlsc</tt> program</a></li> +<li><a href="s6-tlsserver.html">The <tt>s6-tlsserver</tt> program</a></li> <li><a href="s6-tlsd.html">The <tt>s6-tlsd</tt> program</a></li> +<li><a href="s6-tlsd-io.html">The <tt>s6-tlsd-io</tt> program</a></li> +<li><a href="s6-ucspitlsd.html">The <tt>s6-ucspitlsd</tt> program</a></li> </ul> <h4> TCP access control </h4> diff --git a/doc/libsbearssl/index.html b/doc/libsbearssl/index.html index 1579b2d..656c724 100644 --- a/doc/libsbearssl/index.html +++ b/doc/libsbearssl/index.html @@ -470,33 +470,44 @@ because *<em>t</em> does not represent a valid time. i.e. a <tt>tai_t</tt> plus nanoseconds (which are simply ignored). </p> +<h4> <code> void sbearssl_drop () </code> </h4> -<h3> Running the TLS/SSL engine (both clients and servers) </h3> +<p> + If the process is running as root, then this function drops its privileges +(else it does nothing). +The gid to drop to is read from the TLS_GID environment variable; the uid to +drop to is read from the TLS_UID environment variable. If those variables +are not given, then the uid, or gid, or both, are not changed. If they +contain something else than numerical uid/gids, the process exits 111 with +an error message. +</p> + +<h3> Running the TLS/SSL engine (internal function for both clients and servers) </h3> -<h4> <code> int sbearssl_run (br_ssl_engine_context *ctx, int *fds, pid_t pid, unsigned int verbosity, uint32_t options, tain_t const *tto) </code> </h4> +<h4> <code> void sbearssl_run (br_ssl_engine_context *ctx, int *fds, tain_t const *tto, uint32_t options, unsigned int verbosity, sbearssl_handshake_cb_t_ref cb, sbearssl_handshake_cb_context_t *cbarg) </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) or a given subprocess dies. +with EOF). It does not return. </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 5 file descriptors, in this + <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, selfpipe. </li> - <li> <em>pid</em> is the pid of the application subprocess. -When a SIGCHLD is detected on the selfpipe, the newly deceased -process is reaped, and if it was <em>pid</em>, then the function -returns as soon as it doesn't have anything left to write to -the network peer. </li> - <li> <em>verbosity</em> defines the engine's verbosity: the -higher the more verbose. This parameter is currently ignored. </li> +ciphertext, fd writing ciphertext. </li> + <li> <em>tto</em> is a pointer to a + <a href="//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> & 1</tt>). + You can use <tt>&tain_infinite_relative</tt> as a value for <em>tto</em> +if you don't want the engine to ever timeout. </li> <li> <em>options</em> is a bitfield. <ul> <li> bit 0 tells the engine how to behave when @@ -514,40 +525,94 @@ 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="//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> & 1</tt>). - You can use <tt>&tain_infinite_relative</tt> as a value for <em>tto</em> -if you don't want the engine to ever timeout. </li> + <li> <em>verbosity</em> defines the engine's verbosity: the +higher the more verbose. This parameter is currently ignored. </li> + <li> <em>cb</em> is a pointer to a callback function that will be called +once after the TLS handshake is performed. This function is called with +two arguments: <em>ctx</em> (a pointer to the current bearssl context), +and <em>cbarg</em> (a pointer to a caller-provided structure). </li> + <li> <em>cbarg</em> is a pointer to a structure provided by the caller. +It will be passed as a second argument to <em>cb</em> when the TLS +handshake has successfully completed. </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 -1. If the application -subprocess dies early, <tt>sbearssl_run</tt> returns the <em>wstat</em> -for that subprocess, i.e. the integer containing the information about -its exit code or crash signal. No matter how <tt>sbearssl_run</tt> returns, -the first four descriptors in <em>fds</em> are closed, but the -selfpipe is untouched and the caller should free <em>ctx</em> itself. +SSL/TLS connection closed cleanly, the process exits 0. </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> +<h3> Initializing and running the engine </h3> + +<h4> <code> void sbearssl_client_init_and_run (int *fds, tain_t const *tto, uint32_t preoptions, uint32_t options, unsigned int verbosity, char const *servername, sbearssl_handshake_cb_t_ref cb, unsigned int notif) </code> </h4> + +<p> + This function initializes a TLS context for a client-side connection, +then runs the TLS engine via a call to <tt>sbearssl_run()</tt>. The +function does not return. +If the context cannot be initialized, the process exits 96 with an +appropriate error message. +</p> + +<p> + If the <tt>CADIR</tt> environment variable is set, then it must contain +the path of a directory containing the hashed names of the public +certificates identifying the trust anchors. Else, if the <tt>CAFILE</tt> +environment variable is set, then it must contain the path to a PEM file +containing all the certificates for the trust anchors. Else, the process +exits 100 with an error message. +</p> <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>. + The arguments are as follows: </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> +<ul> + <li> <tt>fds</tt> : an array of 4 file descriptors, that are in this +order: the fd reading from the application (cleartext), the fd writing to the +application (cleartext), the fd reading from the network, the fd writing to +the network. </li> + <li> <tt>preoptions : a bitfield. + <ul> + <li> Bit 0: if clear, no client authentication is performed. If set, +the <tt>CERTFILE</tt> and <tt>KEYFILE</tt> environment variables are read, +they must contain the path to a valid client certificate and private key +(else the process exits 96); this certificate is then provided to the +server for client authentication. <strong>This feature is currently +unsupported and will not work; leave that bit clear for now.</strong> </li> + </ul> </li> + <li> <tt>options : a bitfield, which will be passed to +<tt>sbearssl_run()</tt>. + <ul> + <li> Bit 0: if clear, no close_notify is performed and the engine +will transmit EOF as received. If set, close_notify will be performed to +end the TLS connection. </li> + </ul> </li> + <li> <em>verbosity</em> defines the engine's verbosity: the +higher the more verbose. This parameter is currently ignored. </li> + <li> <tt>servername</tt> : the server name used for SNI. If NULL, then +no SNI is performed, which may be a security risk. </li> + <li> <tt>cb</tt> : a pointer to a callback function, that will be +passed as is to <tt>sbearssl_run()</tt>. </li> + <li> <tt>notif</tt> : an unsigned integer that will be embedded into +the <em>cbarg</em> structure that will be passed to <tt>sbearssl_run()</tt>. +It is used by <a href="../s6-tlsc-io.html">s6-tlsc-io</a> to identify a +valid fd on which to write SSL data information once the handshake has +completed. </li> +</ul> + +<h4> <code> void sbearssl_server_init_and_run (int *fds, tain_t const *tto, uint32_t preoptions, uint32_t options, unsigned int verbosity, sbearssl_handshake_cb_t_ref cb, unsigned int notif) </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>. + Same as the previous function, but on the server side. No <em>servername</em> +argument is required. The <tt>CERTFILE</tt> and <tt>KEYFILE</tt> environment +variables are mandatory, they point to the server's certificate and private +key. It is only necessary to set <tt>CADIR</tt> or <tt>CAFILE</tt> when bit +0 of <em>preoptions</em> is set <strong>(this functionality <em>is</em> supported server-side)</strong>, +in which case client authentication will be +requested, and a list of trust anchors (read from either the directory +in <tt>CADIR</tt> or the PEM file in <tt>CAFILE</tt>) will be used to verify +the client certificate. </p> </body> diff --git a/doc/libstls/index.html b/doc/libstls/index.html index fcd839a..f81396c 100644 --- a/doc/libstls/index.html +++ b/doc/libstls/index.html @@ -52,30 +52,97 @@ sysdeps directory. </li> <h2> Programming </h2> -<h3> Running the TLS/SSL engine </h3> +<h3> Utilities </h3> -<h4> <code> int stls_run (struct tls *ctx, int *fds, pid_t pid, unsigned int verbosity, uint32_t options, tain_t const *tto) </code> </h4> +<h4> <code> void stls_drop () </code> </h4> + +<p> + If the process is running as root, then this function drops its privileges +(else it does nothing). +The gid to drop to is read from the TLS_GID environment variable; the uid to +drop to is read from the TLS_UID environment variable. If those variables +are not given, then the uid, or gid, or both, are not changed. If they +contain something else than numerical uid/gids, the process exits 111 with +an error message. +</p> + +<h3> Initializing the TLS engine </h3> + +<h4> <code> struct tls *stls_client_init_and_handshake (int const *fds, uint32_t preoptions, char const *servername) </code> </h4> + +<p> + This function initializes a TLS context for a client-side connection, +then performs a TLS handshake. +It then returns a non-null pointer to a <tt>struct tls</tt> context for the +application to pass to the <tt>stls_run</tt> function when it wants to +run the engine. +If the context cannot be initialized or the handshake cannot be performed, +the process exits (96 for configuration issues, 97 for context and handshake +issues) with an appropriate error message. +</p> + +<p> + If the <tt>CADIR</tt> environment variable is set, then it must contain +the path of a directory containing the hashed names of the public +certificates identifying the trust anchors. Else, if the <tt>CAFILE</tt> +environment variable is set, then it must contain the path to a PEM file +containing all the certificates for the trust anchors. Else, the process +exits 100 with an error message. +</p> + +<p> + The arguments are as follows: +</p> + +<ul> + <li> <tt>fds</tt> : an array of 4 file descriptors, that are in this +order: the fd reading from the application (cleartext), the fd writing to the +application (cleartext), the fd reading from the network, the fd writing to +the network. </li> + <li> <tt>preoptions : a bitfield. + <ul> + <li> Bit 0: if clear, no client authentication is performed. If set, +the <tt>CERTFILE</tt> and <tt>KEYFILE</tt> environment variables are read, +they must contain the path to a valid client certificate and private key +(else the process exits 96); this certificate is then provided to the +server for client authentication. </li> + </ul> </li> + <li> <tt>servername</tt> : the server name used for SNI. If NULL, then +no SNI is performed, which may be a security risk. </li> +</ul> + +<h4> <code> struct tls *stls_server_init_and_handshake (int const *fds, uint32_t preoptions) </code> </h4> + +<p> + Same as the previous function, but on the server side. No <em>servername</em> +argument is required. The <tt>CERTFILE</tt> and <tt>KEYFILE</tt> environment +variables are mandatory, they point to the server's certificate and private +key. It is only necessary to set <tt>CADIR</tt> or <tt>CAFILE</tt> when bit +0 of <em>preoptions</em> is set, in which case client authentication will be +requested, and a list of trust anchors (read from either the directory +in <tt>CADIR</tt> or the PEM file in <tt>CAFILE</tt>) will be used to verify +the client certificate. +</p> + +<h3> Running the TLS engine </h3> + +<h4> <code> void 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) or a given subprocess dies. +with EOF). It does not return. </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 5 file descriptors, in this + <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, selfpipe. </li> - <li> <em>pid</em> is the pid of the application subprocess. -When a SIGCHLD is detected on the selfpipe, the newly deceased -process is reaped, and if it was <em>pid</em>, then the function -returns as soon as it doesn't have anything left to write to -the network peer. </li> +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. @@ -106,29 +173,8 @@ if you don't want the engine to ever timeout. </li> <p> <tt>stls_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 -1. If the application -subprocess dies early, <tt>stls_run</tt> returns the <em>wstat</em> -for that subprocess, i.e. the integer containing the information about -its exit code or crash signal. No matter how <tt>stls_run</tt> returns, -the first four descriptors in <em>fds</em> are closed, but the -selfpipe is untouched and the caller should 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>. +message and exit code if it encounters an unrecoverable error. If there were +no problems and the SSL/TLS connection closed cleanly, the process exits 0. </p> </body> diff --git a/doc/s6-tlsc-io.html b/doc/s6-tlsc-io.html new file mode 100644 index 0000000..2f02841 --- /dev/null +++ b/doc/s6-tlsc-io.html @@ -0,0 +1,217 @@ +<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-io program</title> + <meta name="Description" content="s6-networking: the s6-tlsc-io program" /> + <meta name="Keywords" content="s6-networking s6-tlsc-io tlsc tls ssl ucspi tcp inet network tcp/ip client" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-networking</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6-tlsc-io</tt> program </h1> + +<p> +<tt>s6-tlsc-io</tt> is a program that establishes a TLS or SSL +client connection over an existing TCP connection, then +communicates with an existing local program over already +established pipes. It is the only client-side program in +s6-networking that performs cryptography. +</p> + +<p> + <a href="index.html">s6-networking</a> does not include +cryptographic software. All the crypto used in <tt>s6-tlsc-io</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 s6-networking. +</p> + +<h2> Interface </h2> + +<pre> + s6-tlsc-io [ -S | -s ] [ -Y | -y ] [ -v <em>verbosity</em> ] [ -K kimeout ] [ -k <em>servername</em> ] [ -d notif ] [ -- ] <em>fdr</em> <em>fdw</em> +</pre> + +<ul> + <li> s6-tlsc-io expects to have an open connection it +can talk to on its standard input and output. It also expects to read +cleartext data from file descriptor <em>fdr</em> and write cleartext +data to file descriptor <em>fdw</em>. </li> + <li> It initiates a TLS handshake over the network connection, +expecting a TLS server on the other side. </li> + <li> Then it acts as a full duplex tunnel, decrypting and transmitting +data from stdin to <em>fdw</em>, and encrypting and transmitting data +from <em>fdr</em> to stdout. </li> + <li> When it cannot transmit any more data from/to the local application +because connections have closed, <tt>s6-tlsc-io</tt> exits. </li> +</ul> + +<h2> Exit codes </h2> + +<ul> + <li> 0: the connection terminated normally. + <li> 96: error while configuring the TLS context - for instance, invalid trust anchor set. </li> + <li> 97: error while setting up the TLS client engine. </li> + <li> 98: TLS error while running the engine. </li> + <li> 100: wrong usage. </li> + <li> 111: system call failed. </li> +</ul> + +<h2> Protocol version and parameters </h2> + +<p> + During the TLS handshake, <tt>s6-tlsc-io</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="https://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-io</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> + +<p> + <tt>s6-tlsc-io</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-io 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. +</p> + +<p> + If <tt>s6-tlsc-io</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-io</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="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a> +program is a chainloading way of doing it. +</p> + +<h2> Server name determination for SNI </h2> + +<p> + The <tt>-k <em>servername</em></tt> option is important to +<tt>s6-tlsc-io</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-io</tt> to +proceed without SNI, <strong>which may be a security risk.</strong> +</p> + +<h2> SSL close handling </h2> + +<p> + If the local application initiates the end of the session by sending +EOF to <em>fdr</em>, there are two ways for the TLS 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 (2020), most protocols are auto-terminated, so +it is not dangerous anymore to use EOF tranmission, and that +is the default for <tt>s6-tlsc-io</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-io</tt> options </h2> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : 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>-S</tt> : send a <tt>close_notify</tt> alert +and break the connection when receiving a local EOF. </li> + <li> <tt>-s</tt> : transmit EOF by half-closing the TCP +connection without using <tt>close_notify</tt>. This is the default. </li> + <li> <tt>-Y</tt> : Do not send a client certificate. This is the default. </li> + <li> <tt>-y</tt> : Send a client certificate. </li> + <li> <tt>-k <em>servername</em></tt> : 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 <em>kimeout</em></tt> : 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>-d <em>notif</em></tt> : handshake notification. +<em>notif</em> must be a file descriptor open for writing. When the +TLS handshake has completed, some data (terminated by two null +characters) will be sent to file descriptor <em>notif</em>. The +data contains information about the TLS parameters of the connection; +its exact contents are left unspecified, but there's at least +a <tt>SSL_PROTOCOL=<em>protocol</em></tt> string +and a <tt>SSL_CIPHER=<em>cipher</em></tt> string, both null-terminated. +Sending this data serves a dual purpose: telling the <em>notif</em> +reader that the handshake has completed, and providing it with some +basic information about the connection. If this option is not given, +no such notification is performed. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-tlsc.html b/doc/s6-tlsc.html index 1237460..c2e7521 100644 --- a/doc/s6-tlsc.html +++ b/doc/s6-tlsc.html @@ -20,21 +20,12 @@ <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 +client connection over an existing TCP connection, then execs +into 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> @@ -45,60 +36,25 @@ the options given when configuring <tt>s6-networking</tt>. <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. + <li> It spawns a <a href="s6-tlsc-io.html">s6-tlsc-io</a> +child process that will initiate the TLS connection, perform the +handshake (expecting a TLS server on the other side of the +network) and maintain the TLS tunnel. </li> + <li> When notified by <a href="s6-tlsc-io.html">s6-tlsc-io</a> +that the handshake has completed, s6-tlsc execs into +<em>prog...</em>. </li> </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="//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="https://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. + If everything goes smoothly, s6-tlsc does not exit, but execs +into <em>prog...</em> instead. </p> <h2> Environment variables </h2> @@ -106,110 +62,44 @@ versions. <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: + s6-tlsc does not expect to have any particular +environment variables, but it spawns a +<a href="s6-tlsc-io.html">s6-tlsc-io</a> program that does. +So it should pay attention to the following variables: </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> + <li> <tt>CADIR</tt> or <tt>CAFILE</tt> </li> + <li> (if the -y option has been given) <tt>CERTFILE</tt> and <tt>KEYFILE</tt> </li> + <li> <tt>TLS_UID</tt> and <tt>TLS_GID</tt> </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. -</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="//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> + By default, <em>prog...</em> is run with all these +variables <em>unset</em>: CADIR, CAFILE, +KEYFILE, CERTFILE, TLS_UID and TLS_GID. They're passed to +the <a href="s6-tlsc-io.html">s6-tlsc-io</a> child but +not to <em>prog...</em>. +The <tt>-Z</tt> option prevents that behaviour. </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. + However, <em>prog...</em> is run with the following additional +environment variables: </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> + <li> <tt>SSL_PROTOCOL</tt> contains the protocol version: +TLSv1, TLSv1.1, TLSv1.2... </li> + <li> <tt>SSL_CIPHER</tt> contains the name of the cipher +used. </li> + <li> More similar environment variables containing information +about the connection may be added in the future. </li> </ul> -<p> - Nowadays (2017), most protocols are auto-terminated, so -it is not dangerous anymore to use EOF tranmission, and that -is the default for <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> +<h2> Options </h2> <ul> <li> <tt>-v <em>verbosity</em></tt> : Be more or less @@ -217,10 +107,11 @@ 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> : do not clean the environment of -<tt>s6-tlsc</tt>-related variables before spawning <em>prog...</em>. </li> +the variables used by <a href="s6-tlsc-io.html">s6-tlsc-io</a> +before execing <em>prog...</em>. </li> <li> <tt>-z</tt> : clean the environment of -<tt>s6-tlsc</tt>-related variables before spawning <em>prog...</em>. -This is the default. </li> +the variables used by <a href="s6-tlsc-io.html">s6-tlsc-io</a> +before execing <em>prog...</em>. This is the default. </li> <li> <tt>-S</tt> : send a <tt>close_notify</tt> alert and break the connection when <em>prog</em> sends EOF. </li> <li> <tt>-s</tt> : transmit EOF by half-closing the TCP @@ -234,20 +125,20 @@ use SNI, which may be a security risk. </li> 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 <em>rfd</em></tt> : expect an open file -descriptor numbered <em>rfd</em> to read network (ciphertext) + <li> <tt>-6 <em>fdr</em></tt> : expect an open file +descriptor numbered <em>fdr</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 <em>wfd</em></tt> : expect an open file -descriptor numbered <em>wfd</em> to write network (ciphertext) +from its own fd <em>fdr</em>. Default is 6. </li> + <li> <tt>-7 <em>fdw</em></tt> : expect an open file +descriptor numbered <em>fdw</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> +its own fd <em>fdw</em>. Default is 7. </li> </ul> <h2> Notes </h2> <ul> - <li> The goal of the <tt>s6-tlsc</tt> interface (and its + <li> The goal of the s6-tlsc 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 diff --git a/doc/s6-tlsclient.html b/doc/s6-tlsclient.html index 2553637..fc357a7 100644 --- a/doc/s6-tlsclient.html +++ b/doc/s6-tlsclient.html @@ -40,22 +40,20 @@ involving: 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> + <li> <em>prog...</em>, your client program, which is executed into by +<a href="s6-tlsc.html">s6-tlsc</a> once the +<a href="s6-tlsc-io.html">s6-tlsc-io</a> child it has spawned has +set up the TLS connection and performed the handshake. </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> + <li> <em>prog...</em> is run with the same pid as s6-tlsclient. </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> +Since there will be a <a href="s6-tlsc-io.html">s6-tlsc-io</a> program between <em>prog</em> and the network to perform -the SSL encryption/decryption, those descriptors will not +the TLS encryption/decryption, those descriptors will not be a network socket - they will be pipes. </p> @@ -79,7 +77,7 @@ used, which may be a security risk.</strong> <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>: +<a href="s6-tlsc-io.html">s6-tlsc-io</a>: </p> <ul> diff --git a/doc/s6-tlsd-io.html b/doc/s6-tlsd-io.html new file mode 100644 index 0000000..6aad7dc --- /dev/null +++ b/doc/s6-tlsd-io.html @@ -0,0 +1,212 @@ +<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-io program</title> + <meta name="Description" content="s6-networking: the s6-tlsc-io program" /> + <meta name="Keywords" content="s6-networking s6-tlsc-io tlsc tls ssl ucspi tcp inet network tcp/ip client" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-networking</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6-tlsc-io</tt> program </h1> + +<p> +<tt>s6-tlsd-io</tt> is a program that establishes a TLS or SSL +server connection over an existing TCP connection, then +communicates with an existing local program over already +established pipes. It is the only server-side program in +s6-networking that performs cryptography. +</p> + +<p> + <a href="index.html">s6-networking</a> does not include +cryptographic software. All the crypto used in <tt>s6-tlsd-io</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 s6-networking. +</p> + +<h2> Interface </h2> + +<pre> + s6-tlsd-io [ -S | -s ] [ -Y | -y ] [ -v <em>verbosity</em> ] [ -K kimeout ] [ -d notif ] [ -- ] <em>fdr</em> <em>fdw</em> +</pre> + +<ul> + <li> s6-tlsd-io expects to have an open connection it +can talk to on its standard input and output. It also expects to read +cleartext data from file descriptor <em>fdr</em> and write cleartext +data to file descriptor <em>fdw</em>. </li> + <li> It expects a TLS client on the other side of the network connection +to initiate a TLS handshake, and it answers it. </li> + <li> Then it acts as a full duplex tunnel, decrypting and transmitting +data from stdin to <em>fdw</em>, and encrypting and transmitting data +from <em>fdr</em> to stdout. </li> + <li> When it cannot transmit any more data from/to the local application +because connections have closed, <tt>s6-tlsd-io</tt> exits. </li> +</ul> + +<h2> Exit codes </h2> + +<ul> + <li> 0: the connection terminated normally. + <li> 96: error while configuring the TLS context - for instance, invalid private key or server certificate files. </li> + <li> 97: error while setting up the TLS server engine. </li> + <li> 98: TLS error while running the engine. </li> + <li> 100: wrong usage. </li> + <li> 111: system call failed. </li> +</ul> + +<h2> Protocol version and parameters </h2> + +<p> + During the TLS/SSL handshake, <tt>s6-tlsd-io</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="https://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-io</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> + +<p> + <tt>s6-tlsd-io</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-io</tt> +will refuse to run. +</p> + +<p> + If you are using client certificats, <tt>s6-tlsd-io</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> + If <tt>s6-tlsd-io</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-io</tt> +then drops its root privileges to this uid/gid after reading its +private key file. This ensures that the engine, including the +handshake, is run with as little privilege as possible. +</p> + +<h2> SSL close handling </h2> + +<p> + If the local application initiates the end of the session by sending +EOF to <em>fdr</em>, there are two ways for the TLS 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 (2020), most protocols are auto-terminated, so +it is not dangerous anymore to use EOF tranmission, and that +is the default for <tt>s6-tlsd-io</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-io</tt> options </h2> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : 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>-S</tt> : send a <tt>close_notify</tt> alert +and break the connection when receiving a local EOF. </li> + <li> <tt>-s</tt> : transmit EOF by half-closing the TCP +connection without using <tt>close_notify</tt>. This is the default. </li> + <li> <tt>-Y</tt> : Do not send a client certificate. This is the default. </li> + <li> <tt>-y</tt> : Send a client certificate. </li> + <li> <tt>-K <em>kimeout</em></tt> : 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>-d <em>notif</em></tt> : handshake notification. +<em>notif</em> must be a file descriptor open for writing. When the +TLS handshake has completed, some data (terminated by two null +characters) will be sent to file descriptor <em>notif</em>. The +data contains information about the TLS parameters of the connection; +its exact contents are left unspecified, but there's at least +a <tt>SSL_PROTOCOL=<em>protocol</em></tt> string +and a <tt>SSL_CIPHER=<em>cipher</em></tt> string, both null-terminated. +Sending this data serves a dual purpose: telling the <em>notif</em> +reader that the handshake has completed, and providing it with some +basic information about the connection. If this option is not given, +no such notification is performed. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-tlsd.html b/doc/s6-tlsd.html index 36125d2..beeedda 100644 --- a/doc/s6-tlsd.html +++ b/doc/s6-tlsd.html @@ -20,8 +20,8 @@ <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 +a TLS or SSL connection over an existing TCP connection, then execs +into an application. It is meant to make network communications secure even for applications that do not natively support TLS/SSL. </p> @@ -45,69 +45,25 @@ the options given when configuring <tt>s6-networking</tt>. <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. + <li> It spawns a <a href="s6-tlsd-io.html">s6-tlsd-io</a> +child process that will be the server-side of a TLS connection, +perform the handshake (expecting a TLS client on the other side +of the network) and maintain the TLS tunnel. </li> + <li> When notified by <a href="s6-tlsd-io.html">s6-tlsd-io</a> +that the handshake has completed, s6-tlsd execs into +<em>prog...</em>. </li> </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="//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="https://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. + If everything goes smoothly, s6-tlsd does not exit, but execs +into <em>prog...</em> instead. </p> <h2> Environment variables </h2> @@ -115,120 +71,44 @@ only TLS-1.2 but with several algorithms and cipher suites. <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> - 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="//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="//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: + s6-tlsd does not expect to have any particular +environment variables, but it spawns a +<a href="s6-tlsd-io.html">s6-tlsd-io</a> program that does. +So it should pay attention to the following variables: </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> + <li> <tt>KEYFILE</tt> and <tt>CERTFILE</tt> </li> + <li> (if the -y or -Y option has been given) <tt>CADIR</tt> or <tt>CAFILE</tt> </li> + <li> <tt>TLS_UID</tt> and <tt>TLS_GID</tt> </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. + By default, <em>prog...</em> is run with all these +variables <em>unset</em>: CADIR, CAFILE, +KEYFILE, CERTFILE, TLS_UID and TLS_GID. They're passed to +the <a href="s6-tlsd-io.html">s6-tlsd-io</a> child but +not to <em>prog...</em>. +The <tt>-Z</tt> option prevents that behaviour. </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. + However, <em>prog...</em> is run with the following additional +environment variables: </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> + <li> <tt>SSL_PROTOCOL</tt> contains the protocol version: +TLSv1, TLSv1.1, TLSv1.2... </li> + <li> <tt>SSL_CIPHER</tt> contains the name of the cipher +used. </li> + <li> More similar environment variables containing information +about the connection may be added in the future. </li> </ul> -<p> - Nowadays (2017), most protocols are auto-terminated, so -it is not dangerous anymore to use EOF tranmission, and that -is the default for <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> +<h2> Options </h2> <ul> <li> <tt>-v <em>verbosity</em></tt> : Be more or less @@ -236,10 +116,11 @@ 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> : do not clean the environment of -<tt>s6-tlsd</tt>-related variables before spawning <em>prog...</em>. </li> +the variables used by <a href="s6-tlsd-io.html">s6-tlsd-io</a> +before execing <em>prog...</em>. </li> <li> <tt>-z</tt> : clean the environment of -<tt>s6-tlsd</tt>-related variables before spawning <em>prog...</em>. -This is the default. </li> +the variables used by <a href="s6-tlsd-io.html">s6-tlsd-io</a> +before execing <em>prog...</em>. This is the default. </li> <li> <tt>-S</tt> : send a <tt>close_notify</tt> alert and break the connection when <em>prog</em> sends EOF. </li> <li> <tt>-s</tt> : transmit EOF by half-closing the TCP diff --git a/doc/s6-tlsserver.html b/doc/s6-tlsserver.html index a87fbb7..04d9951 100644 --- a/doc/s6-tlsserver.html +++ b/doc/s6-tlsserver.html @@ -21,7 +21,7 @@ <p> <tt>s6-tlsserver</tt> is an <a href="https://cr.yp.to/proto/ucspi.txt">UCSPI server tool</a> for -TLS/SSL connections over INET domain sockets. It acts as a TCP superserver +TLS/SSL connections over INET domain sockets. It acts as a TCP super-server that listens to connections, accepts them, and for each connection, establishes a TLS transport over it, then executes into a program. </p> @@ -49,12 +49,13 @@ than what you originally wrote. This is normal and healthy. </li> 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> +a TLS transport (server-side) over a connection, via a +<a href="s6-tlsd-io.html">s6-tlsd-io</a> child process. </li> <li> (if applicable) <a href="//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> + <li> <em>prog...</em>, your client program, which is run with the +same pid as <a href="s6-tlsd.html">s6-tlsd</a>. </li> </ul> </li> <li> It runs until it is killed by a signal. </li> </ul> @@ -62,7 +63,7 @@ child of <a href="s6-tlsd.html">s6-tlsd</a>. </li> <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> +Since there will be a <a href="s6-tlsd-io.html">s6-tlsd-io</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. diff --git a/doc/s6-ucspitlsc.html b/doc/s6-ucspitlsc.html new file mode 100644 index 0000000..4c1d2be --- /dev/null +++ b/doc/s6-ucspitlsc.html @@ -0,0 +1,178 @@ +<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-ucspitlsc program</title> + <meta name="Description" content="s6-networking: the s6-ucspitlsc program" /> + <meta name="Keywords" content="s6-networking s6-ucspitlsc tlsc tls ssl ucspi ucspi-tls delayed encryption opportunistic tls tcp inet network tcp/ip client" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-networking</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6-ucspitlsc</tt> program </h1> + +<p> +<tt>s6-ucspitlsc</tt> is a client-side program that establishes +communication channels according to the UCSPI-TLS protocol, +then execs into an application. Later, if the application sends +a command, a TLS tunnel will be started and the application will +be able to use it instead of communicating with the network via +cleartext. +</p> + +<p> + The point of this protocol, and this program, is to make it easy +to implement commands like SMTP's STARTTLS without embedding a +TLS stack in the client itself. +</p> + +<h2> Interface </h2> + +<pre> + s6-ucspitlsc [ -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-ucspitlsc 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 forks and establishes communication channels between +the parent and the child. The parent executes into +<em>prog...</em>; the child remains and waits for a +command. </li> + <li> At any time, <em>prog...</em> can send a command to its +control socket provided by s6-ucspitlsc, following the +<a href="https://web.archive.org/web/20150311223933/http://www.suspectclass.com/sgifford/ucspi-tls/ucspi-tls.txt">UCSPI-TLS</a> +protocol. Then the s6-ucspitlsc child will exec into a +<a href="s6-tlsc-io.html">s6-tlsc-io</a> +process that will initiate the TLS connection, perform the +handshake (expecting a TLS server on the other side of the +network) and maintain a TLS tunnel. <em>prog</em> can +use that TLS tunnel instead of talking directly to the +network. </li> +</ul> + +<h2> Exit codes </h2> + +<ul> + <li> 100: wrong usage. </li> + <li> 111: system call failed. </li> +</ul> + +<p> + Normally the parent s6-ucspitlsc process execs into <em>prog...</em> +and the child process execs into <a href="s6-tlsc-io.html">s6-tlsc-io</a>. +If the parent dies or closes its control socket before sending a +command to start TLS, the child exits 0. +</p> + +<h2> Environment variables </h2> + +<h3> Read </h3> + +<p> + s6-ucspitlsc does not expect to have any particular +environment variables, but it spawns a +<a href="s6-tlsc-io.html">s6-tlsc-io</a> program that does. +So it should pay attention to the following variables: +</p> + +<ul> + <li> <tt>CADIR</tt> or <tt>CAFILE</tt> </li> + <li> (if the -y option has been given) <tt>CERTFILE</tt> and <tt>KEYFILE</tt> </li> + <li> <tt>TLS_UID</tt> and <tt>TLS_GID</tt> +</ul> + +<h3> Written </h3> + +<p> + By default, <em>prog...</em> is run with all these +variables <em>unset</em>: CADIR, CAFILE, +KEYFILE, CERTFILE, TLS_UID and TLS_GID. They're passed to +the <a href="s6-tlsc-io.html">s6-tlsc-io</a> child but +not to <em>prog...</em>. +The <tt>-Z</tt> option prevents that behaviour. +</p> + +<p> + However, <em>prog...</em> is run with the following additional +environment variables, following the UCSPI-TLS protocol: +</p> + +<ul> + <li> <tt>SSLCTLFD</tt> contains the file descriptor number of +the control socket. </li> + <li> <tt>SSLREADFD</tt> contains the file descriptor number of +the pipe used to read data from the TLS tunnel after it +has been activated. </li> + <li> <tt>SSLWRITEFD</tt> contains the file descriptor number of +the pipe used to write data to the TLS tunnel after it +has been activated. </li> +</ul> + +<p> + Since <em>prog</em> is exec'ed before the TLS handshake takes +place, it cannot get information about the TLS connection via +environment variables. However, if it starts the TLS connection +via a <tt>Y</tt> command (as opposed to a <tt>y</tt> command), +it will receive this information as a string sent over the +control socket. +</p> + +<h2> Options </h2> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : 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> : do not clean the environment of +the variables used by <a href="s6-tlsc-io.html">s6-tlsc-io</a> +before execing <em>prog...</em>. </li> + <li> <tt>-z</tt> : clean the environment of +the variables used by <a href="s6-tlsc-io.html">s6-tlsc-io</a> +before execing <em>prog...</em>. This is the default. </li> + <li> <tt>-S</tt> : send a <tt>close_notify</tt> alert +and break the connection when <em>prog</em> sends EOF. </li> + <li> <tt>-s</tt> : transmit EOF by half-closing the TCP +connection without using <tt>close_notify</tt>. This is the default. </li> + <li> <tt>-Y</tt> : Do not send a client certificate. This is the default. </li> + <li> <tt>-y</tt> : Send a client certificate. </li> + <li> <tt>-k <em>servername</em></tt> : 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 <em>kimeout</em></tt> : 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 <em>fdr</em></tt> : expect an open file +descriptor numbered <em>fdr</em> to read network (ciphertext) +data from. Make sure <em>prog</em> also reads its data +from its own fd <em>fdr</em>. Default is 6. </li> + <li> <tt>-7 <em>fdw</em></tt> : expect an open file +descriptor numbered <em>fdw</em> to write network (ciphertext) +data to. Make sure <em>prog</em> also writes its data to +its own fd <em>fdw</em>. Default is 7. </li> +</ul> + +<h2> Notes </h2> + +<ul> + <li> It only makes sense to run s6-ucspitlsc if its application +program <em>prog</em> knows and understands the +<a href="https://web.archive.org/web/20150311223933/http://www.suspectclass.com/sgifford/ucspi-tls/ucspi-tls.txt">UCSPI-TLS</a> +protocol for opportunistic TLS. If it does not, you will not +be able to secure your connection, and what you need is a regular +immediate TLS program instead, which means +<a href="s6-tlsc.html">s6-tlsc</a>. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-ucspitlsd.html b/doc/s6-ucspitlsd.html new file mode 100644 index 0000000..51372e2 --- /dev/null +++ b/doc/s6-ucspitlsd.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-ucspitlsd program</title> + <meta name="Description" content="s6-networking: the s6-ucspitlsd program" /> + <meta name="Keywords" content="s6-networking s6-ucspitlsd tlsd tls ssl ucspi ucspi-tls delayed encryption opportunistic tls tcp inet network tcp/ip client" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-networking</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6-ucspitlsd</tt> program </h1> + +<p> +<tt>s6-ucspitlsd</tt> is a server-side program that establishes +communication channels according to the UCSPI-TLS protocol, +then execs into an application. Later, if the application sends +a command, a TLS tunnel will be started and the application will +be able to use it instead of communicating with the network via +cleartext. +</p> + +<p> + The point of this protocol, and this program, is to make it easy +to implement commands like SMTP's STARTTLS without embedding a +TLS stack in the server itself. +</p> + +<h2> Interface </h2> + +<pre> + s6-ucspitlsd [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v <em>verbosity</em> ] [ -K kimeout ] [ -- ] <em>prog...</em> +</pre> + +<ul> + <li> s6-ucspitlsd expects to have an open TCP connection it +can talk to on its stdin and stdout. </li> + <li> It forks and establishes communication channels between +the parent and the child. The parent executes into +<em>prog...</em>; the child remains and waits for a +command. </li> + <li> At any time, <em>prog...</em> can send a command to its +control socket provided by s6-ucspitlsd, following the +<a href="https://web.archive.org/web/20150311223933/http://www.suspectclass.com/sgifford/ucspi-tls/ucspi-tls.txt">UCSPI-TLS</a> +protocol. Then the s6-ucspitlsd child will exec into a +<a href="s6-tlsd-io.html">s6-tlsd-io</a> +process that will initialize the TLS connection, perform the +handshake (expecting a TLS client on the other side of the +network) and maintain a TLS tunnel. <em>prog</em> can +use that TLS tunnel instead of talking directly to the +network. </li> +</ul> + +<h2> Exit codes </h2> + +<ul> + <li> 100: wrong usage. </li> + <li> 111: system call failed. </li> +</ul> + +<p> + Normally the parent s6-ucspitlsd process execs into <em>prog...</em> +and the child process execs into <a href="s6-tlsd-io.html">s6-tlsd-io</a>. +If the parent dies or closes its control socket before sending a +command to start TLS, the child exits 0. +</p> + +<h2> Environment variables </h2> + +<h3> Read </h3> + +<p> + s6-ucspitlsd does not expect to have any particular +environment variables, but it spawns a +<a href="s6-tlsd-io.html">s6-tlsd-io</a> program that does. +So it should pay attention to the following variables: +</p> + +<ul> + <li> <tt>CERTFILE</tt> and <tt>KEYFILE</tt> </li> + <li> (if the <tt>-Y</tt> or <tt>-y</tt> option has been given) <tt>CADIR</tt> or <tt>CAFILE</tt> </li> + <li> <tt>TLS_UID</tt> and <tt>TLS_GID</tt> +</ul> + +<h3> Written </h3> + +<p> + By default, <em>prog...</em> is run with all these +variables <em>unset</em>: CADIR, CAFILE, +KEYFILE, CERTFILE, TLS_UID and TLS_GID. They're passed to +the <a href="s6-tlsd-io.html">s6-tlsd-io</a> child but +not to <em>prog...</em>. +The <tt>-Z</tt> option prevents that behaviour. +</p> + +<p> + However, <em>prog...</em> is run with the following additional +environment variables, following the UCSPI-TLS protocol: +</p> + +<ul> + <li> <tt>SSLCTLFD</tt> contains the file descriptor number of +the control socket. </li> + <li> <tt>SSLREADFD</tt> contains the file descriptor number of +the pipe used to read data from the TLS tunnel after it +has been activated. </li> + <li> <tt>SSLWRITEFD</tt> contains the file descriptor number of +the pipe used to write data to the TLS tunnel after it +has been activated. </li> +</ul> + +<p> + Since <em>prog</em> is exec'ed before the TLS handshake takes +place, it cannot get information about the TLS connection via +environment variables. However, if it starts the TLS connection +via a <tt>Y</tt> command (as opposed to a <tt>y</tt> command), +it will receive this information as a string sent over the +control socket. +</p> + +<h2> Options </h2> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : 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> : do not clean the environment of +the variables used by <a href="s6-tlsc-io.html">s6-tlsc-io</a> +before execing <em>prog...</em>. </li> + <li> <tt>-z</tt> : clean the environment of +the variables used by <a href="s6-tlsd-io.html">s6-tlsd-io</a> +before execing <em>prog...</em>. This is the default. </li> + <li> <tt>-S</tt> : send a <tt>close_notify</tt> alert +and break the connection when <em>prog</em> sends EOF. </li> + <li> <tt>-s</tt> : transmit EOF by half-closing the TCP +connection without using <tt>close_notify</tt>. This is the default. </li> + <li> <tt>-Y</tt> : Require an optional client certificate. </li> + <li> <tt>-y</tt> : Require a mandatory client certificate. +The default, with neither the <tt>-Y</tt> nor the <tt>-y</tt> option, +is not to require a client certificate at all. </li> + <li> <tt>-K <em>kimeout</em></tt> : 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> It only makes sense to run s6-ucspitlsd if its application +program <em>prog</em> knows and understands the +<a href="https://web.archive.org/web/20150311223933/http://www.suspectclass.com/sgifford/ucspi-tls/ucspi-tls.txt">UCSPI-TLS</a> +protocol for opportunistic TLS. If it does not, you will not +be able to secure your connection, and what you need is a regular +immediate TLS program instead, which means +<a href="s6-tlsd.html">s6-tlsd</a>. </li> +</ul> + +</body> +</html> diff --git a/doc/tls-overview.html b/doc/tls-overview.html new file mode 100644 index 0000000..4ba3f69 --- /dev/null +++ b/doc/tls-overview.html @@ -0,0 +1,142 @@ +<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: an overview of the tls-related programs</title> + <meta name="Description" content="s6-networking: an overview of the tls-related programs" /> + <meta name="Keywords" content="s6-networking s6-tlsc s6-tlsd tlsc tlsd tlsc-io ucspi-tls ucspi-ssl tlsd-io ssl ucspi tcp inet network tcp/ip client" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-networking</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> An overview of the tls-related programs </h1> + +<p> + The <tt>s6-*tls*</tt> programs are organized in a way that minimizes +the amount of code, and in particular that keeps the crypto code as +encapsulated as possible. +</p> + +<p> + They are divided in two sets: client programs, which have <tt>client</tt> +or <tt>c</tt> in their name, and server programs, which have <tt>server</tt> +or <tt>d</tt> in their name. The sets are symmetrical: the same +functionality is available whether you're interested in using a +client or a server. +</p> + +<p> + Of course, they do not have to be used together. You can run a +TLS-enabled super-server via <a href="s6-tlsserver.html">s6-tlsserver</a> +and it will work with any client speaking the correct TLS-enabled +protocol, not only <a href="s6-tlsclient.html">s6-tlsclient</a>. +</p> + +<h2> The core TLS engine: s6-tlsc-io and s6-tlsd-io </h2> + +<ul> + <li> <a href="s6-tlsc-io.html">s6-tlsc-io</a> and +<a href="s6-tlsd-io.html">s6-tlsd-io</a> are the only programs +that actually perform TLS operations; the only ones that are linked +against the BearSSL or LibreSSL libraries. </li> + <li> They read TLS-related +information (where to find my trust anchor list? where to find my +server certificate and private key?) from their environment. </li> + <li> They assume that their stdin/stdout is talking to the network; they +also take two other fds on the command line that they assume are +open and talking to the local application - one for reading, one for +writing. </li> + <li> They establish a TLS tunnel over the network. </li> + <li> They maintain full-duplex communication: what they read +from the local application is sent to stdout as ciphertext; what +they read from stdin is sent to the local application as cleartext. </li> + <li> They exit when they cannot transmit any more data. </li> +</ul> + +<p> + Other programs in the s6-tls set perform various operations such as +Unix file descriptor plumbing in order to provide a specific interface, +but they always end up spawning a +<a href="s6-tlsc-io.html">s6-tlsc-io</a> or +<a href="s6-tlsd-io.html">s6-tlsd-io</a> child that will handle the +actual TLS management for them. +</p> + +<h2> Regular TLSification of a service: s6-tlsc and s6-tlsd </h2> + +<ul> + <li> The <a href="s6-tlsc.html">s6-tlsc</a> and +<a href="s6-tlsd.html">s6-tlsd</a> programs are "immediate encryption"-type +programs. They assume that the rest of their command line is a +UCSPI client or server application, i.e. reads from the network on +fd (6 for clients, 0 for servers) and writes to the network on fd +(7 for clients, 1 for servers); their goal is to provide this +application with transparent encryption. </li> + <li> They first spawn a <a href="s6-tlsc-io.html">s6-tlsc-io</a> or +<a href="s6-tlsd-io.html">s6-tlsd-io</a> child to initialize the TLS +connection. </li> + <li> When the TLS handshake has completed, they exec into the +rest of their command line, interposing the s6-tls[cd]-io program +in between this application and the network. </li> + <li> The application still communicates via cleartext, but the +data is transparently encrypted before it goes to the network. </li> + <li> The application is <em>only</em> started after the handshake +succeeds; the TLS tunnel stays up for the whole lifetime of the +application, or until the application closes the fds it uses to +communicate with (what it thinks is) the network. </li> +</ul> + +<h2> Opportunistic TLS: s6-ucspitlsc and s6-ucspitlsd </h2> + +<ul> + <li> The <a href="s6-ucspitlsc.html">s6-ucspitlsc</a> and +<a href="s6-ucspitlsd.html">s6-ucspitlsd</a> programs are +"delayed encryption"-type programs. They assume that the rest +of their command line is an application that follows the +<a href="https://web.archive.org/web/20150311223933/http://www.suspectclass.com/sgifford/ucspi-tls/ucspi-tls.txt">UCSPI-TLS</a> +protocol. This is a bit of a misnomer: the aim of this protocol is +just to provide an application with a means to ask for TLS +encryption at any time. </li> + <li> They prepare the necessary communication channels, then +fork. The parent execs into the rest of its command line, with +the appropriate ucspi-tls environment variables set. The child +stays and waits for a command. </li> + <li> When the application sends a command to start TLS, the +child execs into <a href="s6-tlsc-io.html">s6-tlsc-io</a> or +<a href="s6-tlsd-io.html">s6-tlsd-io</a>, which initializes +a TLS connection and performs a handshake. </li> + <li> The application then communicates via the fds that have +been provided to it via the ucspi-tls protocol. Those fds go +through the TLS engine. </li> +</ul> + +<h2> High-level client connections and super-servers: s6-tlsclient and s6-tlsserver </h2> + +<ul> + <li> The <a href="s6-tlsclient.html">s6-tlsclient</a> and +<a href="s6-tlsserver.html">s6-tlsserver</a> programs are high-level +wrappers around TCP client and server functionality, followed by the +establishment of a TLS tunnel, followed by the execution of an +application. They're meant to provide simpler interfaces over +long, complex command lines. </li> + <li> <a href="s6-tlsclient.html">s6-tlsclient</a> rewrites itself +into a command line involving +<a href="s6-tcpclient.html">s6-tcpclient</a> and +<a href="s6-tlsc.html">s6-tlsc</a>. </li> + <li> <a href="s6-tlsserver.html">s6-tlsserver</a> rewrites itself +into a command line involving (depending on the given options) +<a href="s6-tcpserver.html">s6-tcpserver</a>, +<a href="s6-tcpserver.html">s6-tcpserver-access</a>, +<a href="s6-tlsd.html">s6-tlsd</a>, and +<a href="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>. </li> +</ul> + +</body> +</html> |