src/network/ssl/qsslsocket_openssl.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
child 30 5dc02b23752f
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
     8 **
     8 **
   551 #ifdef QSSLSOCKET_DEBUG
   551 #ifdef QSSLSOCKET_DEBUG
   552                 qDebug() << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes";
   552                 qDebug() << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes";
   553 #endif
   553 #endif
   554                 writeBuffer.free(writtenBytes);
   554                 writeBuffer.free(writtenBytes);
   555                 totalBytesWritten += writtenBytes;
   555                 totalBytesWritten += writtenBytes;
       
   556 
       
   557                 if (writtenBytes < nextDataBlockSize) {
       
   558                     // break out of the writing loop and try again after we had read
       
   559                     transmitting = true;
       
   560                     break;
       
   561                 }
   556             }
   562             }
   557 
   563 
   558             if (totalBytesWritten > 0) {
   564             if (totalBytesWritten > 0) {
   559                 // Don't emit bytesWritten() recursively.
   565                 // Don't emit bytesWritten() recursively.
   560                 if (!emittedBytesWritten) {
   566                 if (!emittedBytesWritten) {
   584         // Check if we've got any data to be read from the socket.
   590         // Check if we've got any data to be read from the socket.
   585         if (!connectionEncrypted || !readBufferMaxSize || readBuffer.size() < readBufferMaxSize)
   591         if (!connectionEncrypted || !readBufferMaxSize || readBuffer.size() < readBufferMaxSize)
   586             while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
   592             while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
   587                 // Read encrypted data from the socket into a buffer.
   593                 // Read encrypted data from the socket into a buffer.
   588                 data.resize(pendingBytes);
   594                 data.resize(pendingBytes);
   589                 int decryptedBytesRead = plainSocket->read(data.data(), pendingBytes);
   595                 // just peek() here because q_BIO_write could write less data than expected
       
   596                 int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes);
   590 #ifdef QSSLSOCKET_DEBUG
   597 #ifdef QSSLSOCKET_DEBUG
   591                 qDebug() << "QSslSocketBackendPrivate::transmit: read" << decryptedBytesRead << "encrypted bytes from the socket";
   598                 qDebug() << "QSslSocketBackendPrivate::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket";
   592 #endif
   599 #endif
   593                 // Write encrypted data from the buffer into the read BIO.
   600                 // Write encrypted data from the buffer into the read BIO.
   594                 q_BIO_write(readBio, data.constData(), decryptedBytesRead);
   601                 int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead);
       
   602 
       
   603                 // do the actual read() here and throw away the results.
       
   604                 if (writtenToBio > 0) {
       
   605                     // ### TODO: make this cheaper by not making it memcpy. E.g. make it work with data=0x0 or make it work with seek
       
   606                     plainSocket->read(data.data(), writtenToBio);
       
   607                 } else {
       
   608                     // ### Better error handling.
       
   609                     q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg(SSL_ERRORSTR()));
       
   610                     q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   611                     emit q->error(QAbstractSocket::UnknownSocketError);
       
   612                     return;
       
   613                 }
       
   614 
   595                 transmitting = true;
   615                 transmitting = true;
   596             }
   616             }
   597 
   617 
   598         // If the connection isn't secured yet, this is the time to retry the
   618         // If the connection isn't secured yet, this is the time to retry the
   599         // connect / accept.
   619         // connect / accept.
   796             QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName);
   816             QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName);
   797 
   817 
   798             QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard);
   818             QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard);
   799             if (!regexp.exactMatch(peerName)) {
   819             if (!regexp.exactMatch(peerName)) {
   800                 bool matched = false;
   820                 bool matched = false;
   801                 foreach (QString altName, configuration.peerCertificate
   821                 foreach (const QString &altName, configuration.peerCertificate
   802                          .alternateSubjectNames().values(QSsl::DnsEntry)) {
   822                          .alternateSubjectNames().values(QSsl::DnsEntry)) {
   803                     regexp.setPattern(altName);
   823                     regexp.setPattern(altName);
   804                     if (regexp.exactMatch(peerName)) {
   824                     if (regexp.exactMatch(peerName)) {
   805                         matched = true;
   825                         matched = true;
   806                         break;
   826                         break;