Bonjour,
Après plusieurs a jours a chercher l'origine de problème je vient finalement vous demander;
J'essai actuellement de créer un serveur qui va se connecter avec un client (logique) au travers d'un socket tcp sécurisé en SSL.
Je commence donc a créer un serveur TCP
Puis quand un client se connecte :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 Server::Server(const QHostAddress host, quint16 port) : QObject() { server = new QTcpServer(this); server->listen(host, port); connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); qDebug() << QString("Accepting connection on %1:%2").arg(shost.toString()).arg(QString::number(port))); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void Server::newConnection(){ if(QSslSocket::supportsSsl()){ QTcpSocket* sock = server->nextPendingConnection(); connect(sock, SIGNAL(readyRead()), this, SLOT(read())); connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); Socket* socket = new Socket(sock->socketDescriptor(), this); } }Comme vous pouvez le voir, je connecte beaucoup de slots dans le but d'intercepter la moindre information qui puisse être émise par Qt.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 Socket::Socket(int descriptor, QObject *parent) : QSslSocket(parent) { qDebug() << "New Client"; if(this->setSocketDescriptor(descriptor)){ connect(this, SIGNAL(bytesWritten(qint64)), this, SLOT(byte(qint64))); connect(this, SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(byte(qint64))); connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater())); connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); connect(this, SIGNAL(peerVerifyError(QSslError)), this, SLOT(peerError(QSslError))); connect(this, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(modeChange(QSslSocket::SslMode))); connect(this, SIGNAL(encrypted()), this, SLOT(ready())); connect(this, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslError(QList<QSslError>))); connect(this, SIGNAL(readyRead()), this, SLOT(read())); this->setPrivateKey("./server-key.pem", QSsl::Rsa, QSsl::Pem); if(!this->addCaCertificates("./ca.pem")) qDebug() << QString("Cannot load %1").arg("./ca.pem"); this->setLocalCertificate("./server-crt.pem"); this->setPeerVerifyMode(QSslSocket::VerifyNone); this->startServerEncryption(); qDebug() << QString("Starting SSL with %1").arg(this->peerAddress().toString()); } else { qDebug() << "error"; this->abort(); this->deleteLater(); } }
Je vous épargne tout les SLOTS car c'est pour la pluspart de simple qDebug() qui on juste pour but d'indiquer l'erreur (ou le message reçu ou autre).
Coté client j'instancie QSslSocket, déclare de la même façon la cléf privé, le certificat local et le CA. (CA identiques). Puis un simple connectToHostEncrypted.
Et voile ce que j'obtient pour la partie cliente :
Le "Written : 289" correspond au signal byteWritten émis pas QSslSocket.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method Connexion Setting Private Key to .client-key.pem Setting Local Certificate to ./client-crt.pem Setting CA Cert to ./ca.pem Connecting to host 127.0.0.1:12346 Written : 289
Coté serveur :
mode 2 correspond a QSslSocket::SslServerMode emis par le signal modeChanged de QSslSocket.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method Accepting connection on 0.0.0.0:12346 New Client mode 2 Starting SSL with 127.0.0.1 TCP : QSocketNotifier: Invalid socket 9 and type 'Read', disabling...
Quand a TCP : , il s'agit d'une trame reçus par QTcpSocket que je connecte dans Server:newConnection. De plus des données sont bien reçu mais ne peuvent pas être affichée (wireshark permet de voir ces données, 289bytes).
Il semblerai donc que le client initialise bien la connection mais que le serveur ne réponde pas. J'ai essayé avec le client SSL fournis dans les exemples de Qt et j'ai exactement le même soucis.
Absolument aucune erreur n'est renvoyée ni par QSslSocket ni par QTcpSocket.
On dirai simplement que le serveur reçoit le message du client mais ne répond pas, comme si le handshake ne démarrai pas. Ils attendent tout les deux un message de la part de l'autre. On le voi d'ailleur avec "QSocketNotifier: Invalid socket 9 and type 'Read', disabling..." lorsque le client se coupe.
J'ai tester les certificat et les clef privés. Ils semblent tous correctement chargés puisque j'accède aux informations qui leurs sont liés (subject info). J'ai également essayé de les régénéré et cela n'a absolument rien changé.
J'ai également essayé un ignoreSslErrors mais cela n'a rien donné. Comme si le QSslSocket ne recevait pas les données. Cela fait plusieurs jours que je cherche et je n'arrive vraiment pas a trouver la solution.
Merci d'avance.
Partager