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; |