2021-11-04 11:22 am

Revisiting SSL Libraries

I've been looking into three different choices for a SSL/TLS library: LibreSSL, MbedTLS and BearSSL. I'd investigated SSL libraries and switched to LibreSSL in 2017: https://lmemsm.dreamwidth.org/7048.html With some Linux distributions dropping LibreSSL as their library of choice and reports of compatability issues with various applications, I felt it was a good time to reevaluate that decision.

Parts of LibreSSL are under multiple licenses including BSD style licenses.  However, there are some clauses in at least one license that are controversial when combined with GNU public licenses.  MbedTLS is available under a dual license of either Apache 2.0 or GPL 2.0.  The GNU GPL 2.0 option makes it more compatible with some GNU public licenses.  BearSSL is released under a MIT license which is typically the least problematic license of the three when it comes to using it in projects with other licenses.  Plus, BearSSL is very secure.  Many of the security issues reported for various SSL/TLS libraries typically just aren't a problem with BearSSL. The major drawback is that many applications and utilities expect an OpenSSL compatible library.  LibreSSL has typically been able to fill that role very easily.  However, as the designs between OpenSSL and LibreSSL diverge, it's going to be harder to find applications that support both without requiring more and more patching.

The curl project is notable because it offers several choices for backends. There are at least 14 to date:
https://daniel.haxx.se/blog/2019/12/11/BearSSL-is-curls-14th-tls-backend/
Plus, many other programs use libcurl.  There's also an easy interface for adding libcurl functionality to a program should a C/C++ programmer want libcurl functionality:
https://github.com/curl/fcurl  
So, some of the issues with finding a SSL library that is supported can be overcome by using programs that instead support curl as a backend.  As an example, Netrider's wkccc web library works with libcurl. So does vorbistools.

Many SSL libraries also provide a cryptographic library.  However, some projects only supply cryptographic support.  Of the various cryptographic libraries, I've been using LibTomCrypt https://github.com/libtom/LibTomCrypt which is public domain.  Interestingly enough, NaCl is also in the public domain.  Might be worth investigating if there is any functionality in it that is not yet available in LibTomCrypt. I've written my own checksum utilities including md5sum, sha256sum, sha512sum and a base64 program.  I used LibTomCrypt as the backend for these utilities to provide the hash functionality. There are several implementations of hash functions available in the public domain or with a variety of licenses. There was no reason to reinvent the wheel yet again and create a new hash implementation. Plus, LibTomCrypt has a nice API that will let you easily switch between hash functions if you want to write your own all-in-one checksum utilities similar to a BusyBox or ToyBox implementation. Even libraries like musl borrowed from some of the public domain code from libraries such as LibTomCrypt instead of creating something completely from scratch.

I'd like to minimize the number of SSL and cryptographic libraries on my system without losing too much functionality.  I'd rather not have to pick and choose building some programs with one SSL library and some with another just because of licensing issues.  So, the trick will be finding enough useful programs that will work with whichever SSL library I end up with.

There's a library for working with Keepass compatible files called libkpass which is used by the program ckpass.  It has GNU GPLv3 licensing and currently uses nettle.  I'm trying to see if LibTomCrypt or one of the other SSL crypto libraries will work as alternative to nettle. Using nettle and GnuTLS is another option for SSL/TLS support. However, I'd prefer to avoid that option if possible or it will bring GPL license considerations into every application, not just those that already use the GPL license.

My main issue is making sure curl will build because it is such a useful program and library. The dependencies I currently have for building curl currently include c-ares, libssh2 and nghttp2. Curl uses a SSL/TLS library of some kind, but, as mentioned, there are several choices available.

libssh2 requires a cryptographic library.  It has support for the cryptographic libraries that are part of the LibreSSL and MbedTLS projects.  However, there's no direct support for BearSSL.  I'm looking into how difficult it would be to add LibTomCrypt as a backend since I'm already using it with other utilities.

nghttp2 may need a SSL library as well.  It has options to use OpenSSL (or LibreSSL) and it needs c-ares (another curl dependency).

I didn't notice any SSL or cryptographic requirements with c-ares, but I've been having other issues with it. One platform I build programs on is Windows and I prefer to keep the programs backward compatible with older versions of Windows so they can be built with a compiler from the original MinGW project and so that they will run on systems like ReactOS. Every time I build a new version of c-ares, I'm finding it less and less compatible with older versions of Windows. The latest version of c-ares requires at least a Windows Vista system and I'm still attempting to be backward compatible with Windows XP systems. A couple of alternatives, patch around the functionality that's not available on older systems or switch to using a POSIX compatible layer underneath like Cygwin does. That latter approach would avoid the constantly changing Win32 API completely. I have been checking into creating a POSIX compatible socket library and did a lot of work on it at one point. However, some libraries and programs would still require a lot of patching to switch Windows builds to using it over the Win32 API because they assume if it's a Windows platform it must use the Win32 API.

I rebuilt curl last year without too many issues. However, trying to update to the most recent libraries and programs needed to build curl has become a mess of dependencies and backward compatibility issues without a clear resolution in sight. So, it's basically a work in progress.

Building curl successfully is one piece of the decision making process when choosing a SSL library but there are other factors. Not all programs use libcurl for SSL support. Some use a SSL library directly and will need to lose SSL capabilities or be modified to use another library or libcurl if their dependency needs can't be met. Tools from SSL libraries are often needed to set up certificates on a system. Cryptographic libraries may be needed for signing shared messages or files and for checking security of signed information.

Michael Forney has done a lot of work adding compatibility with BearSSL to software used in Oasis Linux.  His list of BearSSL compatible programs is here:
https://github.com/oasislinux/oasis/issues/14
He's also written libtls on top of BearSSL to help with some of the compatibility issues. I have not attempted porting libtls to non-POSIX platforms, but it doesn't look like a quick option.

Michael Forney has written a tool to help generate X509 certificates and certificate requests:
https://github.com/michaelforney/x509cert
This functionality is something that OpenSSL and LibreSSL already provide.  There may be code available to provide this type of functionality for MbedTLS, but I haven't found it yet.  The x509cert program does port to non-Posix platforms like Windows with a little patching.  LibTomCrypt added some X509 support, so it might be interesting to see if a tool could be created that worked with that library.

SSL libraries are used most often with browser programs. As mentioned, netrider uses curl, so that won't be as big of an issue. The other browsers I like to build from source are lynx, D+ (a more portable fork of Dillo) and possibly links. The lynx browser is a text based browser. I find it very useful when checking the accessibility of web sites. If it looks okay in lynx, odds are, it will be okay in most browsers and accessible to some screen readers. It is useful to have some basic graphical support in browsers without requiring the latest browser engine implementation with all the newest HTML, CSS and scripting features. Links is very similar to lynx but adds some basic graphics capabilities. There's a fork that uses SDL as a backend, so graphics could be viewable in framebuffer mode outside of X and Wayland on Linux systems. D+ and Dillo are lightweight GUI based browsers that use FLTK. FLTK is one of the lighter GUI frameworks still available and actively developed. I like to use diffh in conjunction with the diff utility. The output of diffh is HTML. Unfortunately, I've yet to find a text browser that renders the output well (even when the content is all text). D+ offers a lightweight solution without requiring a high-powered browser on the system. Dillo is more updated and better supported, but the project has never been open to cross-platform portability. So, D+ which works in a variety of environments including FreeDOS seems like a better choice for my purposes.

There are issues when using certain types of licenses together in a project. The LibreSSL and original OpenSSL licenses are not compatible with GNU Public Licenses due to conflicting restrictions in one of the license clauses. There are BSD style licenses with clauses ranging from 0 to 4 or more. BSD style licenses with 4 or more clauses typically become an issue with compatibility if you want to work with projects that use the GPL. There are issues with some versions of Apache licenses combined with some versions of GNU licenses. The Apache 2 license now used by OpenSSL fixed a lot of that but there are still conflicts between the GNU GPLv2 license and the Apache 2 license. I tend to prefer less strict licenses so I often opt for GNU GPLv2 applications over GPLv3 applications. The Linux kernel remains GNU GPLv2 as well. So, any decision on SSL libraries not only needs to take into account which libraries are easiest to build projects with but also which libraries are legally compatible when used.

The lynx license is GPLv2.  It will probably never be updated to GPLv3 or later because many of the original contributors can't be contacted to get approval for the license change. I don't see any linking exceptions for lynx in the current documentation.  The Apache 2 license that OpenSSL uses may be an issue with GNU GPLv2 programs like lynx.  However, lynx shows that support has been added for OpenSSL, LibreSSL and gnutls in some of the comments. I assume, since the code includes mention of these libraries, the developer(s) are okay with use of OpenSSL or LibreSSL being linked to the lynx code. Links, on the other hand, uses GPLv2 or later, so doesn't run into some of the issues of programs that only support GPLv2.

Dillo, which is currently licensed GPLv3, had a linking exception for OpenSSL at one point.  I thought it had added LibreSSL as an exception as well, but current versions no longer have any license exception clause and no longer mention OpenSSL as an exception.  This is probably due to the fact that they assume use of a later version of OpenSSL with the newer Apache 2 license. That license is compatible with GPLv3. D+ had support for OpenSSL and experimental support for cyassl (now available as WolfSSL).  There was an exception for OpenSSL but not for LibreSSL.  Unfortunately, there's no way to contact the author and find out if an exception can be added for LibreSSL. The program could be built without SSL support. It's really not necessary just to view the output of diffh. It would be interesting to see what it would take to add BearSSL support though since there is no issue between licenses.

That covers some of the browsers options. There are other programs and libraries I typically use or need as dependencies when building applications that require SSL/TLS and/or cryptographic support. With many of the cases, it might not be intuitive to consider they'd even need it. Yet, many do require it. In some situations, you can avoid the issue and just leave the needed functionality out. In others, the libraries or programs are designed not to build without the dependency.

LibArchive has an optional dependency of a cryptographic library and offers support for OpenSSL/LibreSSL and Nettle. LibArchive and LibreSSL are both BSD projects created to replace other popular projects. So, it would be natural to assume that LibArchive would function well with LibreSSL. Support for using LibreSSL is probably going to be better than OpenSSL in this one particular case.

PostgreSQL requires OpenSSL. I've built it with LibreSSL and, so far, compatibility with that seems fine. I did not see options for other SSL/TLS libraries. Some other Linux distributions may provide patches that offer other options.

Vorbistools uses the curl library.  Opusfile requires OpenSSL (or LibreSSL).  It won't build without the dependency. There are two libraries that opusfile creates, libopusfile and libopusurl.  The libopusurl library needs the OpenSSL dependency.  Luckily, many programs only link with libopusfile which doesn't list OpenSSL as a dependency.

Fossil is one of the simpler version control systems to build from source code. It optionally uses OpenSSL (or LibreSSL) if SSL support is desired.

The picaxo program is a lightweight SDL based graphics viewer. It can also display graphics at a URL location. It uses sockets directly and doesn't appear to support SSL/TLS options.  The sdl_net library also appears to use sockets directly.

I haven't looked into email clients recently, but this is another area where a SSL/TLS library will be an important factor. My preference is to use Sylpheed for email, but the builds are older and I've been having trouble with certificates of late. I'd prefer to use a different GUI library if I'm going to build my email client from scratch. Building with a fork of GTK+ that offers a ncurses backend might also be an interesting option.

There are several email options using the lighter FLTK GUI framework. flmail and hermail are both FLTK based options. I believe hermail is no longer available from Sourceforge. I still have the source somewhere. flmail is part of the NanoLinux distribution at Sourceforge. PostOffice is an old FLTK email client. I was able to get it to build from source with later versions of FLTK after some patching. The user interface works to some extent, but the mail code probably needs extensive updating. It does have a nice interface with 3 panes comparable to email clients such as Sylpheed. It would be nice to use a project like this as a front end to a more modern command line only email client.

One text based email option I like is alpine. There are several forks of it including realpine, so I'd need to look into which is the most useful to start with. Originally, alpine licensing was an issue. That was one reason the GNU based nano project was created to replace pico. The latest alpine version at https://repo.or.cz/alpine.git has an Apache 2 license. It also lists openssl and libressl in its directory tree so OpenSSL and LibreSSL appear to be the valid options for SSL/TLS support.

If there are other lightweight, cross-platform portable email client suggestions, I'd be very interesting in hearing about them.

Cryptographic libraries are also used with many signing programs to make sure messages and files are authentic. Some of the smaller Linux distributions I've looked at are adding features to sign their archives and ensure they're legitimate. I recently checked into lightweight software options that can be used for this purpose in place of programs like GnuPG. I ran across several solutions. Most used Ed25519. Many BSD systems use signify. There are various ports of signify to Linux. They typically need some kind of BSD compatibility library. I ran across asignify which uses TweetNaCl and was inspired by signify. I also found minisign which uses libsodium and is maintained by the libsodium developer. The lightest option I've found to date is usign. It includes the cryptographic code. It's lightweight enough that I was able to port it to non-POSIX platforms without much issue. Since LibTomCrypt or some of the SSL libraries offer cryptographic support for Ed25519, another good option might be to write something specifically using one of them as a backend. That would cut down the number of cryptographic algorithm implementations on the system that would need to be supported and maintained. If anyone else is investigating this sort of thing, I'd appreciate hearing how you plan to approach the issue of signing information and/or packages.

The other place tools from a cryptographic library are needed is with certificates. I've covered certificate requests, but certificates need to be installed for programs like curl, a web browser or email client in order to work properly. I'm not familiar with how most Linux Distributions create their certificates packages, but Linux From Scratch gives an interesting glimpse on one way to do so with their make-ca program:
https://www.linuxfromscratch.org/blfs/view/svn/postlfs/make-ca.html
I did contact one distribution that was using BearSSL and asked how certificates were handled. In that case, the bundle from the curl web site was used. I do like the LFS method of creating a certificate package including a certificate bundle. One nice thing is that I can easily add some custom certificates if I need them behind a firewall. I currently use a simplified version of the make-ca process to create my own certificate package for the systems I build programs on. The make-ca script calls the openssl program. Some of the utility calls in the make-ca script are just doing base64 encoding. So, any base64 program with equivalent functionality could be used in place of calling openssl. However, there are other cases where specific openssl functionality is called. I've yet to find replacements for that or other ways to simplify the make-ca process to avoid it. So, for now, the process requires OpenSSL or LibreSSL in order to work. I would be very interested to hear how other distributions (besides LFS) create their certificate packages and what tools they use to do so.

I had hoped the process to switch completely to BearSSL would be a simple one especially since curl added support for it. However, reviewing the programs I like to work with, there are several that would require patching, losing SSL/TLS support or just wouldn't work with the switch. It does appear to be the most secure option at this point. LibreSSL works with all the libraries and programs I currently build, but there may be licensing issues in some cases. Also, support for LibreSSL may or may not be available in future updates of the software. Continuing to use LibreSSL requires less work at present, but may not be the best decision moving forward. MbedTLS is an interesting option. The dual license covers the situation of using it with GPL and non-GPL programs. It's used by ReactOS, so it currently has decent support for older versions of Windows. Other than curl and some of its dependencies, there aren't a lot of programs out there designed to use it though. There aren't a lot of tools to use with it either such as for dealing with certificates. I'm still investigating the various alternatives and their pros and cons. I'd really prefer to not have to work with multiple SSL/TLS libraries on my system. The choice may just come down to what will allow the most applications to build successfully.

It has recently come to my attention that MbedTLS 2.17 and greater will no longer be available under a GNU GPL license. This causes license conflicts with GNU GPLv2 licensed software. This change pretty much rules out using MbedTLS as a useful option for me at this point.

I'd be very interested to hear from others who build their programs from source or who work with small operating system distributions or packaging of libraries and programs as to what their choices are in this area. Possibly if enough small projects banded together, good support for a less popular library could be created. If anyone's interested in that or knows of projects that are interested, please pass that information on to me. I believe in the principle of security through obscurity. So, going off the beaten path and using a less well-known SSL library may have a very good overall benefit.
2017-07-05 03:27 pm

ssl libraries

I only recently checked the OpenSSL site and found out that they've changed their license from 4 clause BSD to an Apache style license. Many sites mention a license conflict between BSD 4 clause licenses and GNU GPL licenses. Several programs I use try to avoid the issue by adding a waiver to their license to allow linking with OpenSSL. Some examples are Dillo and D+. The issue can also be avoided in many cases by using software with a license other than the GNU GPL. So, the new switch to an Apache style license solves the license conflict issue in many cases (although it may cause new license conflict issues).

There's a useful reference on license information at the curl site:
https://curl.haxx.se/legal/licmix.html

There was an interesting thread about the GPL/BSD 4 clause license conflict on the lynx development list. Various SSL library options such as OpenSSL, gnutls and nss were discussed. It was mentioned that parts of the gnutls library (the compatibility layer) was licensed under GPLv3 which is incompatible with GPLv2 only ( https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility ). The thread concluded with a recommendation to use the nss library to avoid license conflicts. It also mentioned that contacting everyone who worked on the project to re-license lynx would be too difficult. I guess there was some accommodation made after the thread because the latest version of lynx includes a COPYHEADER file that includes permission to use libraries such as OpenSSL and gnutls.

With the license change to OpenSSL, I hoped that the various license issues one might run across when building and distributing software that need SSL support had been solved. I've been using OpenSSL for a long time and it's always been highly portable and worked on a variety of platforms. However, when I downloaded the latest version of OpenSSL, I found that was no longer the case. With the various OpenSSL security issues in the news, work has been done to update the library and make it more secure. It appears, in this particular case, the security enhancements have come at the cost of portability. I used to be able to build OpenSSL using the ActiveState version of Perl. Now, OpenSSL is designed to only allow use of ActiveState or Windows native Perl builds using the Visual C++ compiler. If I continue to use the mingw compiler, I need a msys or cygwin based version of Perl. I'd previously built OpenSSL for DOS with no issues. Looking through some of the code, I'm afraid to even give it a try with the latest version of OpenSSL. OpenSSL is also much more dependent on Perl than it used to be. If I'm building a C library, it would be nice if it was only dependent on C code to build instead of requiring an interpreted language that's rather complicated to build.

I found it was time to either redesign my build of Perl (since a native Perl could no longer be used with MinGW to build OpenSSL) or to look for a new SSL library alternative. I'll share some of the results in my search for SSL library alternatives.

The major SSL options are OpenSSL, gnutls (with GNU GPL license) and nss (from Mozilla with Mozilla Public License). There are OpenSSL compatibility layers for gnutls (GPLv3 license) and nss ( Nss_compat_ossl originally from Fedora and no longer supported ). From some of the articles I read online, OpenSSL and nss were mentioned as more secure than gnutls. I also read that gnutls was a popular option on certain Linux systems such as Debian.

However, these aren't the only SSL libraries. There are several other options for embedded systems and other specialty uses. It's actually hard to track the options since the names of some of them keep changing. Typically, a program needs to offer support specifically for one or more of these library options because there usually isn't a compatibility layer to use that SSL library in place of a more common SSL library. Curl is a great example of a program that supports multiple SSL library options. D+ included support for cyassl. However, cyassl is now known as wolfssl. axtls looked like an interesting possibility because of its BSD license. It supposedly builds on Windows, but I didn't have any luck with it. Of all the various lightweight and/or embedded options, the only one I was able to get to build out of the box on Windows was mbedtls (formerly polarssl). mbedtls is available under a GPL license. Rather than try to track all the options and library name changes, I'll refer to the Wikipedia list:
https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations

After the recent security issues with OpenSSL, there were also forks of OpenSSL. These include LibreSSL (a fork by the OpenBSD developers) and BoringSSL (by Google). I tried building BoringSSL, but it required an interpreter (similar to OpenSSL), so why not stick with OpenSSL instead of switching to BoringSSL. I also tried building some of the various SSL options with cmake and had no luck at all.

I'd tried building LibreSSL in the past with no luck either. The fork was originally just designed for BSD systems and support for other platforms was added later. There are even some posts on the Internet about how early versions of LibreSSL include issues that made it insecure on Linux and other non-BSD systems. Once support was added for other platforms, I ran into an issue with what platforms were supported. The developers only supported the MinGW64 project on Windows. I use a version of MinGW based on an earlier version of the original MinGW which has a more lenient license. I've been adapting the mingwrt and w32api libraries, but they're based on the original public domain licensed versions of the libraries. So, when I previously tried to build LibreSSL, it wasn't compatible with my MinGW compiler. However, after the various changes to OpenSSL, I decided to give LibreSSL another try. Was pleasantly surprised this time when it only required minor patching with my particular version of MinGW in order to get it to build. It also uses the standard GNU autotools style configure/make/make install rather than requiring Perl just to configure and build it. If anyone's interested in the patches, feel free to contact me about getting a copy.

At this point, I'm considering switching to the LibreSSL fork. Several Linux distributions that use musl as their main C library are using LibreSSL as their SSL library of choice. They included patches to get various libraries and programs to build with LibreSSL instead of OpenSSL. There are also some patches at the LibreSSL site.

However, there are still some issues with switching. Many of the programs that included a waiver for OpenSSL, do not provide a similar waiver for LibreSSL. I certainly be interested in hearing how others are handling this particular issue. It would be nice if LibreSSL users could contact some of these projects and ask about a waiver for LibreSSL as well as OpenSSL. Some of the projects that come to mind are D+, Dillo, lynx, opusfile. Curl, libarchive and libssh2 can also use LibreSSL instead of OpenSSL, but there aren't any issues with license conflicts unless one adds a GNU GPL licensed library or a similar incompatible license to the mix.

I'd be interested to hear what others use as their SSL library of choice when building cross-platform applications and why they chose that particular library. You can find further discussion of this topic on the CPPDesign mailing list ( http://www.distasis.com/connect.htm ).