Gniazdo SSL (QSslSocket) - dopuszczenie wyłącznie klientów posiadających poprawny klucz publiczny
-
Witam,
od wczoraj próbuję zaimplementować gniazdo SSL (QSslSocket), dzieki któremu serwer dopuszczał by wyłącznie klientów posiadających klucz publiczny (certyfikat).
Kod serwera:void NewClient() { const QString rootCAPath(":/ssl.crt"); auto rootCACert = QSslCertificate::fromPath(rootCAPath); Q_ASSERT(!rootCACert.isEmpty()); socket->setCaCertificates(rootCACert); socket->setProtocol(QSsl::SslProtocol::SslV3); socket->setPeerVerifyMode(QSslSocket::PeerVerifyMode::QueryPeer); connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslError(QList<QSslError>))); socket->connectToHostEncrypted(ip.toString(), port); if (!socket->waitForEncrypted(1000)) { qDebug() << "Error: " + socket->errorString(); return false; } if (!socket->waitForConnected(5000)) { qDebug() << "Error: " + socket->errorString(); return false; } else { return true; } } void Client::sslError(const QList<QSslError> & error) { qDebug() << "sslErrorOccured: " << error; //socket->ignoreSslErrors(error); }
Serwer:
void Server::sslError(const QList<QSslError>& error) { qDebug() << "sslErrorOccured: " << error << error[0]; } void Server::newRequest() { if (!socketDescriptor) { return; } socket.reset(new QSslSocket()); socket->setSocketDescriptor(socketDescriptor); socket->setPrivateKey(":/ssl.key", QSsl::Rsa); socket->setLocalCertificate(":/ssl.crt"); socket->setProtocol(QSsl::SslProtocol::SslV3); socket->setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyPeer); connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslError(QList<QSslError>))); socket->startServerEncryption(); if (!socket->waitForEncrypted(1000)) { qDebug() << "Timeout!"; socket->close(); return; } if (!socket->waitForReadyRead(5000)) { qDebug() << "Timeout!"; socket->close(); return; } // (...) request processing socket->close(); }
Po obu stronach plik ssl.crt jest ten sam.
W wyniku serwer nie otrzymuje certyfikatu od klienta (status: invalid), dostaje błąd ssl, że nie otrzymano go od drugiej strony i go odrzuca.
Klient zaś dostaje 2 błędy dla innego certyfikatu: QSslError::SelfSignedCertificate (co wiem, że powinienem zignorować) oraz CertificateUntrusted), w przypadku prawidłowego certyfikatu pojawia się wyłącznie błąd pierwszy.Sprawdzałem pakiety za pomoca wireshark'a - są zaszyfrowane ale faktycznie informacje o certyfikacie (lub kluczu prywatnym) wysyła wyłącznie serwer (klient milczy).
Certyfikat i klucz na pewno są dobrze czytane z pliku (sprawdzałem za pomocą QFile).
Jak to poprawić?