Summary

This tool can be used to determine if an application that uses TLS/SSL for its data transfers does this in a secure way.

qsslcaudit was inspired by sslcaudit and performs the same set of tests. However, this tool has been rewritten from scratch using C++ with Qt (that is why there is q in the name) instead of Python.

Basically, after performing tests using qsslcaudit one can answer the following questions about TLS/SSL client:

Does it properly verify server's certificate?

Does it verify that server name (CN) field in the certificate is the same as the target name?

Does it verify that certificate was issued by an authority that can be trusted?

Does it support weak protocols (SSLv2, SSLv3) or weak ciphers (EXPORT/LOW/MEDIUM grade)?

If the tested application has some weaknesses in TLS/SSL implementation, there is a risk of man-in-the-middle attack which could lead to sensitive information (such as user credentials) disclosure.

Assume that we have mobile application which at some point requests https://login.domain.tld/ Such request can be forwarded to rogue server (i.e. on public WiFi network) and, if mobile app does not verify server's certificate, users credentials will be intercepted.

To check how the application behaves in this scenario we should setup our own rogue TLS/SSL server and forward the app to it. Then we launch the application, try to login and observe the results. In case login failed -- all is fine.

However, there could be misconfigurations on client which are not easy to find. For instance, the application can check that server's certificate is valid, but does not check if it is issued to the target domain (does not check CN property).

In order to help with tasks like described above, qsslcaudit tool has been created.

Installation from Binary Packages

Prior note: openssl-unsafe package will not override system OpenSSL library. It has all its libraries renamed so one can not occasionally link against unsafe version.

Installation from Sources

Note on OpenSSL 1.1.0

OpenSSL 1.1.0 removed support for SSLv2 protocol and other insecure features, see here.

Thus, compiling qsslcaudit with this version results in some (i.e. SSLv2-related) tests not working.

Moreover, runtime linking with "unsafe" library version 1.0.yx with qsslcaudit compiled with OpenSSL 1.1.0x is not possible, as these versions are not binary compatible.

For these reasons we advise you to compile qsslcaudit using OpenSSL versions 1.0.yx.

Note on unsafe OpenSSL variant

As even 1.0.x versions are too safe for some of the tests included, we prepared so-called unsafe build of OpenSSL library. See repositories for Debian and Alt Linux.

Packages backed from these repos follow filesystem hierarchy standard but install renamed OpenSSL libraries, i.e. libunsafessl and libunsafecrypto. This makes it impossible to accidentally link your program against these libraries. Additionally, they provide openssl-unsafe binary which can be useful by itself with tools like testssl.

Build system of qsslcaudit determines which OpenSSL variant is installed and will use unsafe version if it is available.

OpenSSL library is determine during cmake run. If your system has unsafe version (see above), it will be used. Otherwise -- available system version (1.0.x or 1.1.x).

Building unsafe OpenSSL library

Manual building unsafe OpenSSL library is (now) not supported. For those who are curious, see spec files in the corresponding unsafeopenssl repository.

Usage

Use -h flag to get some usage help.

The most easy way to understand how to use the tool properly is to follow examples provided below.

Forwarding Connection

The first task before launching any test is to configure forwarding connections from client to qsslcaudit instance. This depends on the client itself and network configuration. Thus, there is no common solution. However, several recommendations still can be provided.

application settings

In some cases the client can be reconfigured to connect to another hostname. I.e.: login.domain.tld --> login.rogue.tld.

Implications:

If you own SSL certificate for login.rogue.tld and use it in qsslcaudit tests, the client will successfully connect to qsslcaudit instance. Corresponding test will fail, but technically all is correct. This can be used as MitM configuration for traffic interception.

hosts file

Modify hosts file on the system where client is. Change IP address of the target domain to the IP address of the host running qsslcaudit.

Implications:

superuser privileges required on client's system to edit hosts file;

superuser privileges required on server's system to listen privileged port (443, as we can not change port number via hosts file);

traffic forwarding

The actual setup highly depends on network configuration.

For instance: TLS/SSL client as mobile application running on Android/iOS device. Device is connected to the Internet via laptop's WiFi access point. WiFi network: 192.168.12.0/24. Use the following commands on laptop's OS:

Usage Example #2

Test if client accepts valid certificate for another domain. It is similar to the example above, but we explicitly set which certificate to present to client. Note that full chain of public keys should be included in certificate file.

We simulated test failure by using s_client tool with explicitly set weak configuration:

$ openssl s_client -connect 127.0.0.1:8443 -ssl3 -cipher MEDIUM

(Some) Command Line Options

Please note that some options are ignored in certain tests or are essential to others. The application tries to perform all (selected) tests and if the test can not be performed with provided options, it is skipped.

--selected-tests selects tests to execute. By default, all tests are performed.

--forward in case TLS/SSL connection successfully established (usually this means that MitM attack is possible), forward connection (non-SSL) to the specified host:port. This can be used to intercept client-provided data (i.e. credentials in POST requests).

--loop-tests this is helpful when it is desired to test TLS/SSL client multiple times or launch SSL server assessment tools against qsslcaudit.

Tests

Current list of TLS/SSL client tests.

certificate trust test with user-supplied certificate

The client is presented with user-supplied certificate. This is only useful when user-supplied certificate is valid. In case CN differs from the one the client connects to, the connection should not be established. This test verifies that client properly checks for common-name value.

certificate trust test with self-signed certificate for user-supplied common name

The client is presented with self-signed certificate with common-name taken from user --user-cn or --server options. This test verifies that client properly checks certificate signer.

The client is presented with self-signed certificate with common-name set to www.example.com. If client connects to such server, then it does not validate neither certificate, nor server name.

certificate trust test with user-supplied common name signed by user-supplied certificate

The client is presented with certificate signed by user-supplied one with common-name taken from user --user-cn or --server options. This is only useful when user-supplied certificate is valid (but issued to another domain). This test verifies that client properly checks certificate signer.

certificate trust test with www.example.com common name signed by user-supplied certificate

The client is presented with certificate signed by user-supplied one but with common-name set to www.example.com. This is only useful when user-supplied certificate is valid. If client connects to such server, then it does not validate neither certificate, nor server name.

certificate trust test with user-supplied common name signed by user-supplied CA certificate

certificate trust test with www.example.com common name signed by user-supplied CA certificate

SSLv2 protocol support test

The client is presented with self-signed certificate with CN set via --user-cn or --server options or www.example.com. Protocol forced to SSLv2. Client should refuse to connect to such server.

SSLv3 protocol support test

The client is presented with self-signed certificate with CN set via --user-cn or --server options or www.example.com. Protocol forced to SSLv3. Client should refuse to connect to such server.

SSLv3 protocol and EXPORT grade ciphers support test

The client is presented with self-signed certificate with CN set via --user-cn or --server options or www.example.com. Protocol forced to SSLv3 and EXPORT-grade ciphers. Client should refuse to connect to such server.

SSLv3 protocol and LOW grade ciphers support test

The client is presented with self-signed certificate with CN set via --user-cn or --server options or www.example.com. Protocol forced to SSLv3 and LOW-grade ciphers. Client should refuse to connect to such server.

SSLv3 protocol and MEDIUM grade ciphers support test

The client is presented with self-signed certificate with CN set via --user-cn or --server options or www.example.com. Protocol forced to SSLv3 and MEDIUM-grade ciphers. Client should refuse to connect to such server.

Adding New Tests

At the time of writing adding new tests requires some knowledge of C++ and QtSsl module API (see http://doc.qt.io/qt-5/ssl.html). However, it should be quite easy to add a new test once the content of src/ssltest.{h,cpp} and src/ssltests.{h,cpp} is clear.

Technical Details

qsslcaudit is written in C++ and uses Qt library for most of the high-level functions.

The repository includes copy modified sources of Qt Certificate Addon project. Qt Certificate Addon implements abstraction layer over GNU TLS library and provides Qt-friendly methods to generate certificates. As its sources were modified (mostly, adaptations to modified Qt SSL stack), it was decided to this project into the repository. However, in future, this decision could be reconsidered.

The most time-consuming part of qsslcaudit project development was supporting insecure/unsafe TLS/SSL configurations. Indeed, in present (year 2018) times most operating systems (Linux distributions) include OpenSSL library compiled with security-safe settings (disabling SSLv2 and weak ciphers). Some TLS/SSL libraries (like GNU TLS) do not support weak protocols at all. Additionally, abstraction layers (QtSsl, Python M2Crypto and others) implement some security checks disabling unsafe configurations. To overcome these problems and be able to test unsafe TLS/SSL cases it was decided to take QtSsl module implementation and make it unsafe.

For this reason one can find src/unsafessl directory here with QtSsl modules sources taken from https://github.com/qt/qtbase.git, Git tag v5.10.0. Obviously, these sources were heavily modified to make them work outside of the Qt main source tree. However, having such complete implementation in our hands is very helpful if we want to test some non-standard cases.