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ć?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.