QsslSocket Encryption issues



  • Ok i have a few questions that i am hoping someone can help me with. First off when i attempt to establish an encrypted connection to the server i get this error:

    @QSslSocket::startServerEncryption: cannot start handshake on non-plain connection@

    or vice vera if i try to delay encryption on the client side. Second( and i know this is probably a bad thing) But i noticed that you can type cast the TcpSocket in nextpendingconnection to a SslSocket like so:

    @ QSslSocket client = (QSslSocket)(const_cast<QTcpSocket*>(server->nextPendingConnection()));@

    to enable a ssl client connection on the server side. now i would imagine that this is a bad way to do it, but i can not find much documentation on it and everything seems to work fine ( unless i try to connect encrypted like i said before). So I guess my questions are; What exactly causes the aforementioned error, and what, if any drawbacks exist from casting the socket as an ssl socket like ive shown above. I have also noticed that when i connect encrypted on the client side, the server get a bunch of garbage written to it, basically i write upload and the server receives "_" and a heart symbol and 90 empty bytes. I am not very knowledgeable(yet) about writing network applications so if i missed something obvious i apologize. Thanks for any insight.



  • It's a bit unclear what you are actually doing. How comes that your cast works? (BTW: your const_cast is not necessary!) Did you reimplement QTcpSocket as suggested in the docs?

    Regarding your error: QSslSocket has two client side modes:

    bq. With an immediate SSL handshake, or with a delayed SSL handshake occurring after the connection has been established in unencrypted mode. (from Qt docs)

    Maybe you should change the one with the other.



  • Honestly I was simply curious as to whether or not i could cast a tcpsocket as an sslsocket so i tried it, and it works just fine. I was a bit surprised. As far as switching them around, that did not seem to change anything. When i connect it does not read anything in. If I simply connect unencrypted it reads everything in. But when i call sessionCipher it returns NULL. So does that mean openSSL is no configured properly?



  • some client side:

    @ QSslSocket *sock = new QSslSocket;
    cout << "[CLIENT]: Attempting Connection..." << endl;
    sock->connectToHost("192.168.1.54", 9003,QAbstractSocket::ReadWrite);
    if(sock->waitForConnected(1000))
    {
    qDebug("Connected");

    }
    
    sock->startClientEncryption();
    qDebug()<<sock->sessionCipher();
    sock->write("UPLOAD");
    sock->flush();
    sock->waitForBytesWritten(1000);
    

    QFile file("C:/Users/admin/Desktop/SocketConnection/Files/1500k.e")

    if(!(file.open(QIODevice::ReadOnly)))
    {
    cout<< "Files Could not be opened";
    }
    else
    cout<< " file opend successfully" <<endl;
    qDebug()<<sock->sessionCipher();
    QByteArray blah;
    QTextStream out(&blah,QIODevice::WriteOnly);
    out << (quint16)0;
    out << blah;
    sock->flush();
    blah = file.readAll();
    file.flush();

      if(file.atEnd())
      {
        sock->waitForReadyRead(1000);
        sock->write(blah);
        qDebug() << sock->bytesToWrite();
       qDebug() << sock->bytesAvailable();
       sock->waitForBytesWritten();
       if(sock->atEnd() == true)
       {
        qDebug()<< "still data to write";
        sock->flush();
       }
    sock->disconnectFromHost();
    

    }@

    Server Side:

    @ QSslSocket client = (QSslSocket)(const_cast<QTcpSocket*>(server->nextPendingConnection()));

    client->startServerEncryption();
    qDebug() << client->defaultCiphers();
    QString  encryptionKey = randomKey::GetInstance()->generateKey();
    QByteArray encryption;
    encryption.append(encryptionKey);
    qDebug() << encryption;
    QByteArray clientIn;
    cout<< "blahblahblah";
    client->waitForReadyRead(100);
    clientIn = client->readAll();
    qDebug() << clientIn;
    QString input(clientIn);
    qDebug() << clientIn.size();
    qDebug() << clientIn;
    if(input == "UPLOAD")
    {
    
       cout<< "Made it to here";
       client->write(encryption);
       client->waitForBytesWritten();
       QByteArray clientData;
       QByteArray clientDataStorage;
       while(client->waitForReadyRead(-1))
        {
            clientData = client->readAll();
                if(client->error()== true)
                  {
                     qDebug() <<  client->errorString();
                       }
            clientDataStorage += clientData;
    

    }@



  • Can you please reformat you code.

    It is quite unreadable with the unaligned indention and all the unnecessary empty lines.

    If we care about your code then please do us a favor and make it easily readable - thanks.

    Please use the edit link on the right side of your comment, just below your username and avatar and edit the answer; please do not add a new comment.


  • Moderators

    You are doing a c-style cast which is rather... let's call it powerful. If all else fails it will do an equivalent to a reinterpret_cast which just tells the compiler "the developer is sure this will work, so just do it". You should be able to c-style cast an int to a QSslSocket if you insist.



  • Sorry about the bad formatting Volker. It still seems like for some reason OpenSsl is not properly implemented. As when i call sessionCipher it returns NULL, but at the same time it does return a list of default ciphers that I can use when i call defaultCipher. Does the garbage I am reading in on the server side have to do with the handshake phase? I do not fully understand what goes on during the handshake yet.



  • A couple of suggestions here. First, don't try implementing your own server and client at the same time - if you do that you can't figure out which end has the bug. You can connect to an ssl server using:
    @
    openssl s_client -connect hostname:port
    @

    This will let you test if your server is working ok. You can also use my sslinfo tool (described at "http://www.kdedevelopers.org/node/4371":http://www.kdedevelopers.org/node/4371) if you want to see what cipher etc. you end up with. This class is also a simple example of how to implement an ssl client for protocols that use ssl from the start.

    One thing I'd note is that you seem to be trying to implement things synchronously in your code, this is generally a bad idea and you'd be better off designing things so that you can do your networking asynchronously.

    [EDIT: link fixed, Volker]



  • Ok So I have tried to run the client side on a php server ive written. The issues is when i try to connect encrypted, it immediately disconnects from the host. So that tells me that is what is happening when i try to connect to my server more than likely. I have seen this problem before searching around, but have not found anyone who has solved it. I also read that this was a bug in qt in earlier releases. Does this mean this bug still exists? Or am i simply missing something. thanks



  • Did you try running the sslinfo tool? Do you have a valid certificate for the server? (You don't seem to be doing anything to allow self-signed certificates for example, which would cause your ssl connection to be terminated). Without a lot clearer information, there's not much anyone can do to help.



  • thats what it was I did not have a valid certificate on the server


Log in to reply
 

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