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.