<div dir="ltr">Thanks, Viktor.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Mar 30, 2019 at 8:59 PM Viktor Dukhovni <<a href="mailto:openssl-users@dukhovni.org">openssl-users@dukhovni.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sat, Mar 30, 2019 at 08:09:01PM +0100, Ivan Medoedov wrote:<br>
<br>
> You are right of course. I handle HTTP myself. A TLS connection example<br>
> will suffice.<br>
> <br>
> > > <a href="https://wiki.openssl.org/index.php/SSL/TLS_Client" rel="noreferrer" target="_blank">https://wiki.openssl.org/index.php/SSL/TLS_Client</a><br>
<br>
That example can be simplified, but OpenSSL does not presently<br>
provide a built-in high-level function to make a verified connection<br>
to a given host:port.<br>
<br>
With library initialization now implicit in 1.1.0 and later, and<br>
thread-safety no longer requiring application callbacks, this would<br>
now be easier to provide, but:<br>
<br>
    * SSL_CTX creation is moderately expensive, and one should<br>
      generally create and use the same SSL_CTX for multiple SSL<br>
      connecitons in any applications that uses more than one SSL<br>
      connection.  So typically, there would still be a one-time<br>
      initialization step to create the SSL_CTX (application context).<br>
<br>
    * Some applications will want to do post-handshake I/O via the<br>
      socket API, and prefer to hand OpenSSL an already connected<br>
      socket on which to perform the TLS handshake.  Others may<br>
      want OpenSSL to establish the connection and may prefer to<br>
      use BIO interface to interact with the peer.<br>
<br>
    * While many systems have a usable default "trust store",<br>
      some do not, or the default "trust store" is overly inclusive.<br>
      Applications should generally allow the user to specify the<br>
      set of trusted CAs.<br>
<br>
    ...<br>
<br>
Through in enough similar qualifiers, and you end up with the rather<br>
complex example.  It could perhaps be refactored as (hypothetical<br>
interface):<br>
<br>
        /*<br>
         * Context with default trust store, protocols, ciphers, ...<br>
         * and peer verification enabled.<br>
         */<br>
        SSL_CTX *app_ctx = SSL_default_ssl_ctx(TLS_method());<br>
<br>
        /*<br>
         * Prepare verified (with name checks) SSL handle for the<br>
         * requested host:port (with SNI).<br>
         */<br>
        SSL *con = SSL_default_ssl(app_ctx, host, port);<br>
<br>
Then depending on whether you want to give OpenSSL an already<br>
connected socket, or have OpenSSL make the connection for you:<br>
<br>
        int err = SSL_connect_socket(con, fd);<br>
<br>
or (something along the lines of):<br>
<br>
        BIO *bp = SSL_connect_hostport(con, host, port, &err);<br>
<br>
At this point a stock error handler may be required, but if all<br>
went well, you now need an I/O loop.  And so would need to either<br>
use the connected file descriptor with your own buffering, ...<br>
or use OpenSSL BIOs, or some other buffering I/O layer that<br>
supports custom read/write wrappers.<br>
<br>
On FreeBSD/NetBSD it might be nice to have stock "fittings" to<br>
wrap stdio around OpenSSL connections via:<br>
<br>
     #include <stdio.h><br>
<br>
     FILE *<br>
     funopen(const void *cookie,<br>
             int        (*readfn)  (void *, char *, int),<br>
             int        (*writefn) (void *, const char *, int),<br>
             fpos_t     (*seekfn)  (void *, fpos_t, int),<br>
             int        (*closefn) (void *));<br>
<br>
Providing higher level interfaces to the core TLS library would<br>
make a good project for someone good at API design, who is familiar<br>
with OpenSSL, but more interested in the API than the internals.<br>
<br>
-- <br>
        Viktor.<br>
</blockquote></div>