Results 1 to 8 of 8

Thread: QSslSocket and decryption buffer

  1. #1
    Join Date
    Nov 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QSslSocket and decryption buffer

    Hello all.

    Just now found strange situation in Qt4.5.
    on server side
    Qt Code:
    1. QSslSocketBackendPrivate::transmit: encrypted 15798 bytes
    2. QSslSocketBackendPrivate::transmit: wrote 15845 encrypted bytes to the socket
    To copy to clipboard, switch view to plain text mode 
    on client
    Qt Code:
    1. QSslSocketBackendPrivate::transmit: read 15845 encrypted bytes from the socket
    2. QSslSocketBackendPrivate::transmit: decrypted 4096 bytes
    To copy to clipboard, switch view to plain text mode 
    debug information.

    So bytes available returns wrong value and protocol become broken.

    Does it normal?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QSslSocket and decryption buffer

    You mean you can't decrypt the data properly?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Nov 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket and decryption buffer

    I mean that QSslSocket on one side read, encrypt and send all data, but on another side QSslSocket read all data from socket correct but decrypt and return only 4096 bytes (As you can see).
    If I try to send <4096 of data it's ok.
    Is this a feature of QSslSocket or just a trick and I must send data throw socket by small fragments?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QSslSocket and decryption buffer

    Neither. I'd say you have to start reading the data at all. The difference probably comes from a fact that the rest apart the 4 kilobytes is a SSL handshake or you simply filled the input buffer on the receiving side. If you read the data, more should come.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Nov 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket and decryption buffer

    Client code is

    Qt Code:
    1. QByteArray KSocket::receiveData(qint64 size)
    2. {
    3. __PRFUNC__<<"waiting for"<<size<<bytesAvailable();
    4. qint64 offset=0;
    5. QByteArray returnBytes;
    6. QByteArray tempBytes;
    7.  
    8.  
    9. if (bytesAvailable()>=size)
    10. {
    11. tempBytes=read(size);
    12. offset+=tempBytes.size();
    13. returnBytes+=tempBytes;
    14. }
    15. else
    16. {
    17. while (bytesAvailable() < size-offset)
    18. {
    19. __PRFUNC__<<"Bytes Available"<<bytesAvailable()<<"Need"<<size-offset;
    20. __PRFUNC__<<"Has Encrypted bytes"<<encryptedBytesAvailable();
    21. if (state()==QAbstractSocket::UnconnectedState)
    22. return 0;
    23. if(bytesAvailable())
    24. {
    25. tempBytes=read(size-offset);
    26. offset+=tempBytes.size();
    27. returnBytes+=tempBytes;
    28. }
    29. else
    30. if (!waitForReadyRead(5000))
    31. if (state()==QAbstractSocket::UnconnectedState)
    32. return returnBytes;
    33. }
    34. }
    35. return returnBytes;
    36. }
    To copy to clipboard, switch view to plain text mode 

    Debug Trace is
    Qt Code:
    1. QSslSocket::_q_readyReadSlot() - 15845 bytes available
    2. QSslSocketBackendPrivate::transmit: read 15845 encrypted bytes from the socket
    3. QSslSocketBackendPrivate::transmit: decrypted 4096 bytes
    4. "Kalpa::CoreModule::readPacket"
    5. "Kalpa::CoreModule::readPacket" 4096 QAbstractSocket::ConnectedState
    6. "Kalpa::CoreModule::readPacket"
    7. "Kalpa::KSocket::receiveData" waiting for 8 packet
    8. "Kalpa::KSocket::receiveData" 4096
    9. QSslSocket::readData( 0x66e3e8 , 16384 ) == 4096
    10. "Kalpa::KSocket::receiveData" Normal return 8
    11. "Kalpa::KSocket::receiveData" waiting for 15790 4088
    12. "Kalpa::KSocket::receiveData" 4088 Need 15790
    13. "Kalpa::KSocket::receiveData" Has Encrypted bytes 0
    14. QSslSocket::readData( 0x7fffa5d9a658 , 8 ) == 0
    15. "Kalpa::KSocket::receiveData" 0 Need 11702
    16. "Kalpa::KSocket::receiveData" Has Encrypted bytes 0
    17. QSslSocket::_q_errorSlot( QAbstractSocket::SocketTimeoutError )
    18. state = QAbstractSocket::ConnectedState
    19. errorString = "Unknown error"
    20. "Kalpa::KSocket::receiveData" 0 Need 11702
    21. "Kalpa::KSocket::receiveData" Has Encrypted bytes 0
    22. QSslSocket::_q_errorSlot( QAbstractSocket::SocketTimeoutError )
    23. state = QAbstractSocket::ConnectedState
    24. errorString = "Network operation timed out"
    25. "Kalpa::KSocket::receiveData" 0 Need 11702
    26. "Kalpa::KSocket::receiveData" Has Encrypted bytes 0
    27. QSslSocket::_q_errorSlot( QAbstractSocket::SocketTimeoutError )
    28. state = QAbstractSocket::ConnectedState
    29. errorString = "Network operation timed out"
    30. "Kalpa::KSocket::receiveData" 0 Need 11702
    31. "Kalpa::KSocket::receiveData" Has Encrypted bytes 0
    To copy to clipboard, switch view to plain text mode 

    I try to read more than 4K data, but QSslSocket decrypts only 4K

    Trying to investigate situation in isolation form.

  6. #6
    Join Date
    Nov 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket and decryption buffer

    The situation I described before is reproducible with QSslSocket and ReadyRead signal.

    just pooling in loop working normal
    Qt Code:
    1. for (;;)
    2. {
    3. mSocket.waitForReadyRead(3000);
    4.  
    5. qint64 size=0;
    6. qint64 offset=0;
    7. QByteArray data;
    8. QByteArray tempData;
    9.  
    10. mSocket.read((char*)&size, sizeof(size));
    11.  
    12.  
    13. if (mSocket.bytesAvailable()>=size)
    14. data=mSocket.read(size);
    15. else
    16. {
    17. while (offset<size)
    18. {
    19. QCoreApplication::instance()->processEvents();
    20. mSocket.waitForReadyRead(300);
    21. QCoreApplication::instance()->processEvents();
    22. if (mSocket.state()==QAbstractSocket::UnconnectedState)
    23. {
    24. qDebug()<<"Connection close";
    25. ::exit(0);
    26. }
    27. tempData=mSocket.read(size-offset);
    28. offset+=tempData.size();
    29. data+=tempData;
    30. qDebug()<<"Read"<<offset<<"of"<<size<<"Bytes available"<<mSocket.bytesAvailable();
    31. }
    32. }
    33. qDebug()<<"Read"<<data.size()<<"bytes";
    34. }
    To copy to clipboard, switch view to plain text mode 

    But if you'll attach this procedure as signal for ReadyRead slot
    Qt Code:
    1. void KClientSession::readData()
    2. {
    3. qDebug()<<"void KClientSession::readData()";
    4.  
    5. /* for (;;)
    6.   {
    7.   mSocket.waitForReadyRead(3000);
    8.   */
    9. qint64 size=0;
    10. qint64 offset=0;
    11. QByteArray data;
    12. QByteArray tempData;
    13.  
    14. mSocket.read((char*)&size, sizeof(size));
    15.  
    16.  
    17. if (mSocket.bytesAvailable()>=size)
    18. data=mSocket.read(size);
    19. else
    20. {
    21. while (offset<size)
    22. {
    23. QCoreApplication::instance()->processEvents();
    24. mSocket.waitForReadyRead(300);
    25. QCoreApplication::instance()->processEvents();
    26. if (mSocket.state()==QAbstractSocket::UnconnectedState)
    27. {
    28. qDebug()<<"Connection close";
    29. ::exit(0);
    30. }
    31. tempData=mSocket.read(size-offset);
    32. offset+=tempData.size();
    33. data+=tempData;
    34. qDebug()<<"Read"<<offset<<"of"<<size<<"Bytes available"<<mSocket.bytesAvailable();
    35. }
    36. }
    37. qDebug()<<"Read"<<data.size()<<"bytes";
    38. // }
    39. }
    To copy to clipboard, switch view to plain text mode 
    You have got a problem. QSslSocket now not works properly. As you can see QSslSocket don't decrypt all data but only 4096 bytes.

    Qt Code:
    1. QSslSocket::_q_readyReadSlot() - 21759 bytes available
    2. QSslSocketBackendPrivate::transmit: read 21759 encrypted bytes from the socket
    3. QSslSocketBackendPrivate::transmit: decrypted 4096 bytes
    4. void KClientSession::readData()
    5. QSslSocket::readData( 0x685f58 , 16384 ) == 4096
    6. QSslSocket::_q_errorSlot( QAbstractSocket::SocketTimeoutError )
    To copy to clipboard, switch view to plain text mode 

    I believe that's it's a trick I don't know about because it's so stupid to polling socket in loop via waitForReadyRead in Client-side GUI application.

    The situation is reproducible on packets more than 4K.

    Anybody can help me?

    Thanks a lot.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QSslSocket and decryption buffer

    What is the point of calling processEvents() before and after waitForReadyRead()?

    Can you provide a minimal compilable example reproducing the problem?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Nov 2006
    Posts
    14
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket and decryption buffer

    Of course. Full example in attachment.

    Clilent code (with signal-slot processing in decryption problem)

    Qt Code:
    1. void TestClient::connectTo(const QString &host, int port)
    2. {
    3. mSocket.connectToHostEncrypted(host, port);
    4. mSocket.ignoreSslErrors();
    5.  
    6. if (!mSocket.waitForEncrypted(50000))
    7. return ;
    8.  
    9. qDebug()<<"********** encrypted ************"<<mSocket.isEncrypted();
    10.  
    11. connect(&mSocket, SIGNAL(readyRead()), this, SLOT(readData()));
    12. // readData();
    13. }
    14.  
    15. void TestClient::readData()
    16. {
    17. qDebug()<<"*******************************************"<<mSocket.bytesAvailable();
    18.  
    19.  
    20. while (mSocket.bytesAvailable()>0)
    21. {
    22. qint64 size=0;
    23. qint64 offset=0;
    24. QByteArray data;
    25. QByteArray tempData;
    26. int i;
    27.  
    28. mSocket.read((char*)&size, sizeof(size));
    29. mSocket.read((char*)&i, sizeof(i));
    30.  
    31. if (mSocket.bytesAvailable()>=size)
    32. {
    33. qDebug()<<"*** Read all";
    34. data=mSocket.read(size);
    35. }
    36. else
    37. {
    38. while (offset<size)
    39. {
    40. qDebug()<<"*** Read parts";
    41. mSocket.waitForReadyRead(3000);
    42. if (mSocket.state()==QAbstractSocket::UnconnectedState)
    43. {
    44. qDebug()<<"Connection close";
    45. ::exit(0);
    46. }
    47. tempData=mSocket.read(size-offset);
    48. offset+=tempData.size();
    49. data+=tempData;
    50. }
    51. }
    52.  
    53. qDebug()<<"packet"<<i<<"Read"<<offset<<"of"<<size<<"Bytes available"<<mSocket.bytesAvailable();
    54. if (mSocket.bytesAvailable()>0)
    55. {
    56. qDebug()<<"We have some bytes"<<mSocket.bytesAvailable();
    57. continue;
    58. }
    59.  
    60. mSocket.waitForReadyRead(7000);
    61.  
    62. }
    63.  
    64. qDebug()<<"I hope no data. Exit from ReadData";
    65. }
    To copy to clipboard, switch view to plain text mode 

    Server code
    Qt Code:
    1. TestServer::TestServer()
    2. : QObject()
    3. {
    4. }
    5.  
    6. void TestServer::init(int port)
    7. {
    8. mServerSocket=new TServer;
    9. connect(mServerSocket, SIGNAL(newConnection(int)), this, SLOT(incomingConnection(int)));
    10.  
    11. mServerSocket->setMaxPendingConnections(10);
    12. if (!mServerSocket->listen(QHostAddress::Any, port))
    13. {
    14. qDebug()<<tr("Port is busy");
    15. ::exit(0);
    16. }
    17. }
    18.  
    19. void TestServer::incomingConnection(int handle)
    20. {
    21. mSocket=new QSslSocket(this);
    22. mSocket->setLocalCertificate("./server.crt");
    23. mSocket->setPrivateKey("./server.pem");
    24. mSocket->ignoreSslErrors();
    25.  
    26. connect(this, SIGNAL(connectionOK()), this, SLOT(mproc()), Qt::QueuedConnection);
    27.  
    28. if ( mSocket->setSocketDescriptor( handle ) )
    29. {
    30. mSocket->startServerEncryption();
    31. if (!mSocket->waitForEncrypted())
    32. {
    33. qDebug()<<"Error ssl";
    34. ::exit(0);
    35. }
    36. }
    37. else
    38. ::exit(0);
    39.  
    40.  
    41. qDebug()<<"Is Server side encrypted"<<mSocket->isEncrypted();
    42.  
    43. emit connectionOK();
    44. qDebug()<<"#################################";
    45. }
    46.  
    47. void TestServer::mproc()
    48. {
    49. qDebug()<<"void TestServer::mproc()";
    50.  
    51.  
    52. for (int i=0; i<5; i++)
    53. {
    54. // Simple test packet
    55. QString TestData;
    56. qint64 size=0;
    57. qint64 wrote=0;
    58.  
    59. // packet preparing
    60. for (int a=0; a<900000; a++)
    61. TestData+=QUuid::createUuid().toString();
    62.  
    63. size=TestData.toAscii().size();
    64.  
    65. mSocket->write((const char*)&size, sizeof(size));
    66. mSocket->write((const char*)&i, sizeof(i));
    67. wrote=mSocket->write(TestData.toAscii());
    68.  
    69. qDebug()<<"packet"<<i<<"wrote"<<wrote<<"bytes";
    70. mSocket->flush();
    71.  
    72.  
    73. // sleep(2);
    74. }
    75. }
    To copy to clipboard, switch view to plain text mode 


    Where I am wrong? Please correct me. Where is the trick?
    Now I have no ideas how to use QSslSocket in Signal-Slot Gui application.
    Attached Files Attached Files

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.