Russian Qt Forum
Сентябрь 25, 2024, 23:23 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSslSocket Клиент-сервер  (Прочитано 11576 раз)
Magvaj
Гость
« : Июль 30, 2009, 21:20 »

Нелепая проблема, но никак не могу найти решение.

Делаю по докам: переопределил QTcpServer::incomingConnection():

Код:
void SslServer::incomingConnection(int socketDescriptor)
{
    QSslSocket *serverSocket=new QSslSocket(this);
    if(serverSocket->setSocketDescriptor(socketDescriptor))
    {
        QObject::connect(serverSocket, SIGNAL(encrypted()), this, SLOT(socketReady()));
        QObject::connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &)));
        QObject::connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
        serverSocket->startServerEncryption();
    }
    else
    {
        delete serverSocket;
    }
}

На стороне клиента создаю сокет и подсоединяюсь(всё по докам):

Код:
    socket=new QSslSocket(this);
    QObject::connect(socket, SIGNAL(encrypted()), this, SLOT(socketReady()));
    QObject::connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &)));
    QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
    socket->connectToHostEncrypted(this->serverHost, this->serverPort);

Что только не делал выдаёт ошибку:
Error during SSL handshake: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher

Что это и как это исправить?
Записан
VAP
Гость
« Ответ #1 : Июль 30, 2009, 23:17 »

 Возможно ошибка криптографии. Полезный материал по теме здесь: http://lists.trolltech.com/qt4-preview-feedback/2007-05/thread00001-0.html
Записан
Magvaj
Гость
« Ответ #2 : Июль 31, 2009, 09:07 »

почитал.. там идёт явная установка ключа и сертификата... я же ничего не устанавливаю... без этого же можно обойтись?
Записан
Magvaj
Гость
« Ответ #3 : Июль 31, 2009, 11:43 »

попробовал с сертификатами- та же лажа:


вот код сервера:
Код:
#include "sslserver.h"
#include <QSslConfiguration>
#include <QFile>

SslServer::SslServer(QObject *parent): QTcpServer(parent)
{

}

void SslServer::socketReady()
{
    qDebug("Connected!");
}

void SslServer::socketSslErrors(const QList<QSslError> &errors)
{
    emit logString(qobject_cast<QSslSocket*>(sender())->errorString(), SSLSERVER_LOG_ERROR);
}

void SslServer::socketError(QAbstractSocket::SocketError socketError)
{
    emit logString(qobject_cast<QSslSocket*>(sender())->errorString(), SSLSERVER_LOG_ERROR);
}

void SslServer::incomingConnection(int socketDescriptor)
{
    QSslSocket *serverSocket=new QSslSocket(this);
    if(serverSocket->setSocketDescriptor(socketDescriptor))
    {

        QSslConfiguration a;
        QFile *f=new QFile("./RSA/server.crt");
        QFile *f1=new QFile("./RSA/server.key");
        f->open(QIODevice::ReadWrite);
        f1->open(QIODevice::ReadWrite);
        a.setCaCertificates(QSslCertificate::fromDevice(f));
        a.setPrivateKey(QSslKey(f1, QSsl::Rsa));
        f->close();
        f1->close();
        serverSocket->setSslConfiguration(a);
        serverSocket->setCiphers("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5");

        QObject::connect(serverSocket, SIGNAL(encrypted()), this, SLOT(socketReady()));
        QObject::connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &)));
        QObject::connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
        serverSocket->startServerEncryption();
    }
    else
    {
     delete serverSocket;
    }
}

и клиента:
Код:
MegaConnector::MegaConnector()
{
    socket=new QSslSocket(this);
    QObject::connect(socket, SIGNAL(encrypted()), this, SLOT(socketReady()));
    QObject::connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &)));
    QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
}

MegaConnector::~MegaConnector()
{
    delete socket;
}

void MegaConnector::connect()
{
    socket->connectToHostEncrypted(this->serverHost, this->serverPort);
}

void MegaConnector::socketReady()
{
    qDebug("Ready!");
}

void MegaConnector::socketSslErrors(const QList<QSslError> &errors)
{
    qDebug("SSL error");
}

void MegaConnector::socketError(QAbstractSocket::SocketError socketError)
{
    qDebug("Error");
    qDebug(QVariant(socketError).toString().toAscii());
    qDebug(socket->errorString().toAscii());
}

может кто посмотрит? может я вообще чтото нелепое упустил...
Записан
denka
Гость
« Ответ #4 : Июль 31, 2009, 11:59 »

Попробуй в MegaConnector::socketSslErrors вызвать QSslSocket::ignoreSslErrors
Записан
Magvaj
Гость
« Ответ #5 : Август 03, 2009, 10:06 »

Попробуй в MegaConnector::socketSslErrors вызвать QSslSocket::ignoreSslErrors


он туда даже не попадает... на клиенте ошибка сокета QAbstractSocket::RemoteHostClosedError, а на сервере QAbstractSocket::SslHandshakeFailedError
Записан
Magvaj
Гость
« Ответ #6 : Август 05, 2009, 08:31 »

решение было выпрошено у поддержки Qt. Питер Хартманн любезно объяснил причину возникновения сей ситуации, за что ему поклон.

Для того чтобы соединение проходило нормально, надо на сервере установить локальный сертификат и приватный ключ:

serverSocket->setPrivateKey("../rsa/server.key");
serverSocket->setLocalCertificate("../rsa/server.pem");

для каждого вновь созданного сокета...

Также было обещано включить сие в документацию, чтобы подобные вопросы больше не мучали умы людей ;-)

Вот оригинал конечного сообщения из переписки:


Цитировать
...In order to make SSL encryption work on the server side,
you need to set the local certificate and the private key. So you want
to do something like the following in your code:
----------------
    serverSocket->setPrivateKey("../rsa/server.key");
    serverSocket->setLocalCertificate("../rsa/server.pem");
----------------
Then it should work. In case you also get an error about wrong version
numbers, you can also set
----------------
    serverSocket->setProtocol(QSsl::AnyProtocol);
----------------
However, that might be a security risk and you probably only want to use
SSLv3 and TLS.
But I agree that this is not well documented, so I am planning to either
extend the documentation or just write a small SSL server example and
put that on the documentation pages, because you are not the first one
to ask about this...
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.126 секунд. Запросов: 21.