
1. Introduction
===============

This is an example code showing how to create a client and a server in Qt using secure (SSL) sockets. We create our own CA (Certification Authority) and trust only it, and both the client and the server have their own certificates signed by our CA. This is used so that both the client and the server are authenticated against their respectives peers.

The idea is using this code as the base for the communication between Opengnsys user terminals and the opengsys central server(s). The clients would have a daemon running with a QTcpServer listening for new incoming connections from the server. These connections would always come from the server, so most probably there will be only at most one incoming connection to the client daemon.

2. Installation
===============

To get the example working you only need to compile and install it. The build system is cmake. The following instructions are for Linux systems, but the project should work on any platform Qt supports. Execute the following commands to build and install the project (change the install prefix to some directory in your PATH variable. ):

 $ cd opengnsys/sslsockets_example
 $ mkdir build
 $ cd build
 $ cmake .. -DCMAKE_INSTALL_PREFIX=~/local/install && make && make install

This will install two executables: sslsockets_example_server and sslsockets_example_client. Both executables need to be run in a directory containing:
 * the CA certificate, in a file called ca-cert.pem
 * its own signed certificate, in a file called localhost.pem
 * its own private key for the certificate, in a file called localhost.key

3. Execute it!
==============

Next section will explain how to create those files, but we provide examples of them for convenience too in the directory opengnsys/sslsockets_example/certs/server_cert. You can execute both the client and the server within that directory, and both will use the same certificate to authenticate against each other. The SSL connection will be secure as the certificate is signed by the trusted root CA we created.

To test everything is working, execute the following commands for launching the server:

 $ cd opengnsys/sslsockets_example/certs/server_cert
 $ sslsockets_example_server
Listening on port  1025

As you can see, the server is now listening on port 1025. No errors happened. Now in the same computer (the certificate we provide by default is only valid for localhost hostname) but in a different terminal, execute the client:

 $ cd opengnsys/sslsockets_example/certs/server_cert
 $ sslsockets_example_client
caCertificates.first().subjectInfo(QSslCertificate::LocalityName) "Sevilla"
SecureClient::start(); called to m_socket->connectToHostEncrypted
SecureClient::hostFound()
SecureClient::connected()
SecureClient::connectionEstablished()
Peer certificate: is valid?  true
Peer certificate: CommonName:  "Kurusoft"
Peer certificate: Organization:  "localhost"

As you can see the client connected successfully to the server, the conection is encrypted and it shows some details about the peer (the server) certificate. If you take a look at the server terminal, you will see the following new output:

SslServerConnection::SslServerConnection 8
privateKey.isNull():  false
certificate.isNull():  false
SslServerConnection::stateChanged()
mode:  0
state:  QAbstractSocket::ConnectedState
Calling startServerEncryption()
SslServerConnection::sslModeChanged() 2
SslServerConnection::encrypted()
Peer certificate: is valid?  true
Peer certificate: CommonName:  "Kurusoft"
Peer certificate: Organization:  "localhost"
SslServerConnection::readyRead()
Read from socket: "hello"

This means the server received a new connection (from our client), shows the peer (in this, case, the client) certificate information, and also shows what the client wrote to us the "hello" string. And that is basically all this example does for now.

4. Creating your own certificates
=================================

Until now you've been using the certificates that we provide by default. In this section I'll explain how to create your own certificates for the client and the server, how to create your own Certification Authority and sign your certificates.

This small HOWTO is based on [1] and [2]. Refer to those manuals for a more detailed explanation.

4.1 Creating your own certificate
=================================

To create a certificate, you first create your own private key:

 $ openssl genrsa -out host.key 1024
 $ chmod 400 host.key

This is PRIVATE and you should never give it to anyone. You could encrypt it with a symetric cypher adding the -des3  option. Okey, now you need to create a Certificate Signing Request (CSR). This is the file that you will give to the CA (Certification Authority, which will be yourself in this case). The CA will sign your certificate, and then those who trust on that CA will trust your certificate.

Execute the following command to generate the CSR:

 $ openssl req -new -nodes -key host.key -out host.csr

You will be asked some questions. When prompted for the "Common Name", enter the fully qualified hostname the certificate will be used on, for example "localhost" or "www.yoursite.es".

The host.csr file will be the one we need to deliver to the CA.

4.2 Creating your own CA and signing the certificate
====================================================

So before signing the certificate you generated, you first need to create a CA which can sign it. We provide a Makefile and a openssl.cnf file that will make the CA tasks easier. First you need to create your pair of private and public keys, and some other files:

 $ cd opengnsys/sslsockets_example/certs/ca
 $ make init

Among various files, the file ca-cert.pem will be created and contains the public key of your CA. Note that as we are not going to sign this certificate, the CA will act as a root CA.

Now you need to copy the CSR file you previously created to opengnsys/sslsockets_example/certs/ca, and sign it:

 $ cp path/to/yourdomain.crt .
 $ make sign

This will create a file in opengnsys/sslsockets_example/certs/ca/newcerts called "01.pem", which is the signed certificate. You can copy it wherever you need and rename it. The next certificate that you sign with make sign will appear in newcerts/ dir as 02.pem and so on. This is the file we called in our default example "localhost.pem".

--
[1] http://sial.org/howto/openssl/ca/
[2] http://sial.org/howto/openssl/csr/
