Hello to all. I'm programming client-server where both need to identify to the other with certificate (they both also check if the certificate is really from who it says to be - with CA).

So here's the code of server and client program. The problem is it never starts a SSL handshake, it keeps saying: the socket is not encrypted:

Server.cpp
Qt Code:
  1. Server::Server(QObject *parent) : QTcpServer(parent) {
  2. /* listen for incoming connections on localhost:PORT */
  3. if(!this->listen(QHostAddress::LocalHost, PORT)) {
  4. qFatal("Unable to start the server on localhost:%d",PORT);
  5. }
  6.  
  7. //connect(tcpServer, SIGNAL(incomingConnection(int)), this, SLOT(check_ssl_connection()));
  8. /* newConnection() signal is emitted every time a client connects to server */
  9. //connect(tcpServer, SIGNAL(newConnection(int &)), this, SLOT(incomingConnection2(int &)));
  10. }
  11.  
  12. /**
  13. * This function is called by QTcpServer whenever a new connection is available
  14. **/
  15. void Server::incomingConnection(int socket_descriptor) {
  16. (void)new SSLServer(socket_descriptor, this);
  17. }
To copy to clipboard, switch view to plain text mode 


SSLServer.cpp
Qt Code:
  1. SSLServer::SSLServer(int socket_descriptor, QObject *parent) : QObject(parent) {
  2. /* create server socket */
  3. server = new QSslSocket(this);
  4.  
  5. /* set socket descriptor */
  6. if(!server->setSocketDescriptor(socket_descriptor)) {
  7. qWarning("Failed to set socket descriptor in SSLServer");
  8. close(socket_descriptor);
  9. delete this;
  10. return;
  11. }
  12.  
  13. //TODO: dynamic filename
  14. /* add CA certificate: it is used by the handshake process to validate the peer's certificate*/
  15. QSslCertificate ca_cert = handle_certificate("/cert/ca.crt");
  16. server->addCaCertificate(ca_cert);
  17.  
  18. /* set the server's (LOCAL) digital certificate */
  19. QSslCertificate server_cert = handle_certificate("/cert/server.crt");
  20. server->setLocalCertificate(server_cert);
  21.  
  22. /* set the server's (LOCAL) private key -> [key+certificate == prove identity to SSL peer] */
  23. server->setPrivateKey("/cert/server.key", QSsl::Rsa, QSsl::Pem, "");
  24.  
  25. /* set cipher protocol */
  26. server->setProtocol(QSsl::SslV3);
  27.  
  28. /* wait for socket to complete SSL handshake -> when encrypted it emits encrypted signal */
  29. if(server->waitForEncrypted(5000))
  30. qDebug() << "Socket is encrypted." << endl;
  31.  
  32. QFile file("/home/eleanor/client.p12");
  33. file.open(QIODevice::ReadOnly);
  34. QByteArray data = file.readAll();
  35. server->write(data);
  36.  
  37. print_socket_info();
  38.  
  39. /* handshake is successful and encrypted socket is ready to use */
  40. connect(server, SIGNAL(encrypted()), this, SLOT(connection_established()));
  41. /* if error occurs the sslErrors() signal is emitted */
  42. connect(server, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(error_occured(const QList<QSslError> &)));
  43. /* socket has changed the mode from unencrypted to client/server mode */
  44. connect(server, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(mode_has_changed(QSslSocket::SslMode)));
  45. }
  46.  
  47. void SSLServer::mode_has_changed(QSslSocket::SslMode mode) {
  48. qDebug() << "SSL Handshake Mode is: " << mode << endl;
  49.  
  50. }
  51.  
  52. /**
  53. * This function prints useful information about a SSL socket
  54. **/
  55. void SSLServer::print_socket_info() {
  56. /* if the socket is encrypted */
  57. if(server->isEncrypted()) {
  58. qDebug() << "Server socket is encrypted" << endl;
  59. }
  60. else {
  61. qDebug() << "Server socket is not encryted" << endl;
  62. }
  63.  
  64. }
  65.  
  66.  
  67. /**
  68. * This function reads the certificate from:
  69. * - disk - if available
  70. * - network - if not avalable it downloads the certificate from the server and store it on disk
  71. * Then return the certificate
  72. **/
  73. QSslCertificate SSLServer::handle_certificate(QString filename) {
  74. /* read the CA certificate */
  75. QFile file(filename);
  76.  
  77. /* if file exists */
  78. if(!file.exists()) {
  79. qWarning("Filename %s doesn't exists.", qPrintable(filename));
  80. //TODO: download the file from server and store it on disk (predefined location)
  81. }
  82.  
  83. /* open file */
  84. if(!file.open(QIODevice::ReadOnly)) {
  85. qWarning("Cannot open filename %s.", qPrintable(filename));
  86. }
  87.  
  88. /* read the whole file into array */
  89. QByteArray data = file.readAll();
  90.  
  91. /* construct new certificate */
  92. QSslCertificate cert(data, QSsl::Pem);
  93.  
  94. /* check if the certificate is null */
  95. if(cert.isNull()) {
  96. qWarning("The CA certificate has no content.");
  97. }
  98.  
  99. /* check if the certificate is valid */
  100. if(!cert.isValid()) {
  101. qWarning("The CA certificate expired.");
  102. }
  103.  
  104. return cert;
  105. }
  106.  
  107.  
  108. void SSLServer::connection_established() {
  109. qDebug() << "SSL Handshake succedded. The socket is now encrypted." << endl;
  110. /* get client's (PEER) digital certificate - for diagnostic purposes */
  111. QSslCertificate client_cert = server->peerCertificate();
  112.  
  113. }
  114.  
  115.  
  116. void SSLServer::error_occured(const QList<QSslError> &error) {
  117. /* ignore the errors */
  118. //server->ignoreSslErrors();
  119. qDebug() << "The following errors occured duing SSH Handshake: " << endl;
  120. for(quint16 i=0;i<error.count(); i++) {
  121. qDebug() << error[i] << endl;
  122. }
  123.  
  124. }
To copy to clipboard, switch view to plain text mode 


Client.cpp
Qt Code:
  1. SSLClient::SSLClient(QObject *parent) : QObject(parent) {
  2. /* create client socket */
  3. client = new QSslSocket();
  4.  
  5. //TODO: dynamic filename
  6. /* CA certificate: it is used by the handshake process to validate the peer's certificate */
  7. QSslCertificate ca_cert = handle_certificate("/cert/ca.crt");
  8. client->addCaCertificate(ca_cert);
  9.  
  10. /* set the client's (LOCAL) digital certificate */
  11. QSslCertificate client_cert = handle_certificate("/cert/client.crt");
  12. client->setLocalCertificate(client_cert);
  13.  
  14. /* set the client's (LOCAL) private key -> [key+certificate == prove identity to SSL peer] */
  15. client->setPrivateKey("/cert/client.key", QSsl::Rsa, QSsl::Pem, "");
  16.  
  17. /* set cipher protocol */
  18. client->setProtocol(QSsl::SslV3);
  19.  
  20. /* get server's (PEER) digital certificate */
  21. //QSslCertificate server_cert = client->peerCertificate();
  22.  
  23. client->connectToHostEncrypted("127.0.0.1", 8088);
  24.  
  25. //client->startClientEncryption();
  26.  
  27. /* handshake is successful and encrypted socket is ready to use */
  28. connect(client, SIGNAL(encrypted()), this, SLOT(connection_established()));
  29. /* if error occurs the sslErrors() signal is emitted */
  30. connect(client, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(error_occured(const QList<QSslError> &)));
  31.  
  32. }
  33.  
  34.  
  35. /**
  36. * This function reads the certificate from:
  37. * - disk - if available
  38. * - network - if not avalable it downloads the certificate from the server and store it on disk
  39. * Then return the certificate
  40. **/
  41. QSslCertificate SSLClient::handle_certificate(QString filename) {
  42. /* read the CA certificate */
  43. QFile file(filename);
  44.  
  45. /* if file exists */
  46. if(!file.exists()) {
  47. qWarning("Filename %s doesn't exists.", qPrintable(filename));
  48. //TODO: download the file from server and store it on disk (predefined location)
  49. }
  50.  
  51. /* open file */
  52. if(!file.open(QIODevice::ReadOnly)) {
  53. qWarning("Cannot open filename %s.", qPrintable(filename));
  54. }
  55.  
  56. /* read the whole file into array */
  57. QByteArray data = file.readAll();
  58.  
  59. /* construct new certificate */
  60. QSslCertificate cert(data, QSsl::Pem);
  61.  
  62. /* check if the certificate is null */
  63. if(cert.isNull()) {
  64. qWarning("The CA certificate has no content.");
  65. }
  66.  
  67. /* check if the certificate is valid */
  68. if(!cert.isValid()) {
  69. qWarning("The CA certificate expired.");
  70. }
  71.  
  72. /* add CA certificate - to validate the peer's certificate during handshake */
  73. //client->addCaCertificate(cert);
  74. return cert;
  75. }
  76.  
  77.  
  78. void SSLClient::connection_established() {
  79. /* get the server's certificate */
  80. QSslCertificate server_cert = client->peerCertificate();
  81.  
  82. /* write on the ssl connection */
  83. client->write("Hello, world",13);
  84.  
  85.  
  86. }
  87.  
  88.  
  89. void SSLClient::error_occured(const QList<QSslError> &error) {
  90. /* ignore the errors */
  91. //client->ignoreSslErrors();
  92.  
  93. }
To copy to clipboard, switch view to plain text mode 

Thank you for all your help...