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