**Keeping up with C++**
This (part of the) blog is mostly meant as a dump for me to put solutions to problems I had a hard time finding solutions to, in the hope that it then helps other people (and future-me) find the solutions faster.
# Using letsencrypt with QSslSocket
Aug 31, 2018
Recently, I had to implement safe online communication in C++ and Qt with an online server. Obviously, QSslSocket on the client side and a modified QTcpServer (like the one by Rich Moore (maintainer of Qt Network) over at [his github](https://github.com/richmoore/qt-examples/tree/master/httpserver)) is the way to go here. The basic setup was quickly implemented but securing it correctly was a bit more of a challenge than expected and took quite a bit of googling as I’m not an expert on SSL and/or network security (so also take the advice here with a grain of salt ;)).
In the end I think I have a pretty good and actually easy setup, so I wanted to share it here. First of all, I wanted to use a real certificate from a CA and not a self-signed one. As I’m currently on a budget [Let’s Encrypt](https://letsencrypt.org/) is a perfect choice there. It took me about 5 minutes to read the instructions, install it on my server, and generate the first certificates. To use those certificates I added the following code to an `init()` method in my SslServer:
if( !certFile.open( QIODevice::ReadOnly ) )
qCritical() << "Unable to open the certificate!!!";
m_cert = QSslCertificate( &certFile );
if( m_cert.isNull() )
qCritical() << "Certificate was not valid!";
if( !keyFile.open( QIODevice::ReadOnly ) )
qCritical() << "Unable to open the key!!!";
m_key = QSslKey( &keyFile, QSsl::Rsa );
if( m_key.isNull() )
qCritical() << "Key was not valid!";
`m_cert` and `m_key` are member variables for the certificate and private key. Unfortunately that means, that you have to either start your server as root or make the key and certificate readable for your program. The “cleanest” way I found was to create a new group like `sslUsers` and add every user that needs access to it and use `chown` to make the files accessible by that group.
After that, I added the following code to the `incommingConnection()` method of the server just before the `addPendingConnection()` and `socket->startServerEncryption()`:
socket->setLocalCertificate( m_cert );
socket->setPrivateKey( m_key );
The last thing you have to do after all this is to package your client with the `chain.pem` also found in `/etc/letsencrypt/live//` and load it into the `QSslSocket` before establishing the connection like this:
if( chain.open( QIODevice::ReadOnly ) )
QSslCertificate chainCert( &chain );
if( !chainCert.isNull() )
socket->addCaCertificate( chainCert );
qWarning() << "Chain certificate is invalid.";
qWarning() << "Unable to read chain certificate.";
Now you can establish a secure connection without ever using `QSslSocket::ignoreSslErrors()`.
I hope this little entry helped you in some way. If it didn’t or you have some comments, please let me know! If it did help you, let me know too! :)