[Solved] Https page works in Windows but not in Linux
-
Hi everybody,
I wrote a small program under Linux which uses QWebView to display Web pages. When I tested this with HTTPS sites I stumbled upon a site (https://www.vertriebspartner.de.o2.com) which results in a blank page. I tried the exact same code under Windows and there everything works. The only difference I saw was that under Windows the onSslError() displays 'The certificate has expired' message which I didn't see under Linux. Under Linux it doesn't display any error message! The only other difference I noticed was that under Windows the OpenSSL ssleay32.dll version 0.9.8.14 is used but under Linux it's libssl.so.1.0.0
I also tested another QtWebKit based browser (Arora 0.11.0) (but only under Linux) and it shows the same blank page and it gets stuck at 10%. But when I used the KDE rekonq browser or Googles Chrome, then the page gets loaded. So It seems to me it is not a WebKit problem, but they are obviously doing something differently then the plain QtWebKit based browsers. But I'm not an SSL expert, so I don't know whether I'm supposed to do something different under Linux and I was not able to find out what rekonq is doing differently.
Out of sheer desperation I even build Qt5 and tested my program with it, just to see whether it might be a (fixed) bug in Qt, but it shows the same blank page.
I'm running out of ideas, so if somebody could give me a hint what I have to do, it would be greatly appreciated.
My environment is:
- Kubuntu 12.04 (64-Bit) / Windows XP (32-Bit)
- QtSdk 1.2.1 (Qt 4.8.1) (Windows and Linux)
Regards Peter
PS: I tried the solution from this thread http://qt-project.org/forums/viewthread/15949/ but this didnt' help
mainwindow.h:
@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QtGui/QMainWindow>
#include <QtNetwork/QNetworkReply>class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);private slots:
void onSslErrors(QNetworkReply* reply, const QList<QSslError> &errors);
};#endif // MAINWINDOW_H
@mainwindow.cpp:
@
#include "mainwindow.h"
#include <QDebug>
#include <QtGui/QApplication>
#include <QtWebKit/QWebView>
#include <QtNetwork/QSslError>
#include <QtNetwork/QSslConfiguration>MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWebView *view = new QWebView( this );connect(view->page()->networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> & )), this, SLOT(onSslErrors(QNetworkReply*, const QList<QSslError> & ))); view->load( QUrl( "https://www.vertriebspartner.de.o2.com")); view->show(); setCentralWidget( view );
}
void MainWindow::onSslErrors(QNetworkReply* reply, const QList<QSslError> &errors)
{
qDebug() << "onSslErrors: ";
foreach (QSslError e, errors)
qDebug() << "ssl error: " << e;reply->ignoreSslErrors();
}
int main(int argc, char *argv[])
{
QApplication application(argc, argv);Q_ASSERT( QSslSocket::supportsSsl() ); MainWindow w; w.show(); return application.exec();
}
@@
#-------------------------------------------------Project created by QtCreator 2012-08-18T12:25:22
#-------------------------------------------------
QT += core gui webkit network
CONFIG += debug
TARGET = WebViewBrowser
TEMPLATE = appSOURCES += mainwindow.cpp
HEADERS += mainwindow.h
@ -
Have tested it right now with QT 4.7.4 & 4.8.3(own compilation) on my LFS 64-bit and Ubuntu 12.04 32-bit, works just fine...
Seems to be openssl problem on your linux distribution... -
Hi,
thank you for the test! Could you tell me what version of openssl is installed on your machines? This might help me in narrowing down the problem.
But what I don't understand then is, if Chrome and rekonq are QtWebKit based and hence use openssl, why do they work?
Regards Peter
-
On LFS 64-bit it is:
@OpenSSL 1.0.0c 2 Dec 2010@On ubuntu 12.04 32-bit:
@OpenSSL 1.0.1c 10 May 2012@But like I said - I have compiled Qt by myself... That can be the reason too...
-
I've compiled Qt5 myself and it didn't work, so I don't think that is the problem. I'm not (yet) an SSL expert and I hoped I can avoid becoming one ;-) , but my current guess is that is has something to do with the certificates installed on my machine.
The biggest problem is that I'm not getting any error message what so ever, which would give me a hint to what is wrong.
Regards Peter
-
So, your onSslErrors function didn't even get fired?
Can you try to download website certificate and test it with "QSslCertificate":http://qt-project.org/doc/qt-4.8/qsslcertificate.html ?
And maybe playing with "QSslConfiguration":http://qt-project.org/doc/qt-4.8/qsslconfiguration.html can help you... -
[quote]So, your onSslErrors function didn't even get fired?[/quote]
No, not in Linux. But on windows (as i wrote ;-) ) I did get ‘The certificate has expired’.
[quote]Can you try to download website certificate and test it with "QSslCertificate":http://qt-project.org/doc/qt-4.8/qsslcertificate.html ? [/quote]
Well, that's why I said I'm not an SSL expert ;-) Could you give me some pointers on how to do this and what I have to look for?
Thank you for your help.
Regards Peter
-
Ok, i have started fresh Ubuntu 12.04 under VirutalBox and can see the same problem.
The problem is in the openssl. You can test it by yourself.(in console)
@
openssl s_client -showcerts -connect www.vertriebspartner.de.o2.com:443
@It will stack right after connection is established. SSL certificate from website uses TLSv1 , no idea why original openssl from Ubuntu can't just switch right to TLSv1 protocol....
Using following option works just fine:
@openssl s_client -showcerts -tls1 -connect www.vertriebspartner.de.o2.com:443@So, try to set following ssl configuration for QNetworkAccessManager of your WebPage:
@QSslConfiguration config = sslSocket.sslConfiguration();
config.setProtocol(QSsl::TlsV1);@ -
OK, so I modified main() like this:
@
int main(int argc, char *argv[])
{
QApplication application(argc, argv);Q_ASSERT( QSslSocket::supportsSsl() );
QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
sslConfig.setProtocol( QSsl::TlsV1 );
QSslConfiguration::setDefaultConfiguration( sslConfig );
Q_ASSERT(QSslConfiguration::defaultConfiguration().protocol() == QSsl::TlsV1);MainWindow w;
w.show();return application.exec();
}
@which I hope is correct because I couldn't figure out how I get the 'sslSocket' from the QNetworkAccessManager. But it didn't change anything :-(
One think I noted though was when I ran one of the openssl commands you gave me, I get:
'Verify return code: 20 (unable to get local issuer certificate)'
and then it just hangs. -
It is known BUG in Ubuntu, where is a lot BUGs around this problem with openssl. For example: "Bug #965371":https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371
I have tested it too with QSslConfiguration::setDefaultConfiguration and with QNetworkAccessManager(subclassing QNAM and overriding createRequest function), it just doesn't work...
Looks like Qt BUG, because sslConfig.setProtocol( QSsl::TlsV1 ); should work, and work in openssl client and in Python using openssl too.
Maybe you can try to rebuild openssl for your Ubuntu...
-
So I build the OpenSSL version 1.0.1c and made sure the newly build shared libraries are picked up from my test application:
@
lsof -p 9052 | grep ssl
WebViewBr 9052 peter mem REG 8,1 470813 9569610 /usr/local/ssl/lib/libssl.so.1.0.0
WebViewBr 9052 peter mem REG 8,1 2194319 9569606 /usr/local/ssl/lib/libcrypto.so.1.0.0
@
but nothing changed. To be honest, I didn't think it could be an openssl bug because if it were then the questions remains why are Chrome and rekonq working?So the only option which remains is to wade through the rekonq and KDE Network source and try to find out what it does different :-(
If anybody has another idea or hint, please let me know.
Regards Peter
-
Finally I got it to work! :-) I don't quite understand it completely yet, but I do understand that openssl on 12.04 seems to be really messy after all the bug reports I've read. But anyway, I simply had to replace:
@
sslConfig.setProtocol( QSsl::TlsV1 );
@with
@
sslConfig.setProtocol( QSsl::SslV3 );
@then at least for this specific site it works and for now this is good enough for me.
Thanks again AcerExtensa!
Regards Peter