From 85f454faabef5453c08eb5493d0afc63e23f650b Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Sat, 23 Jul 2011 18:29:15 +0200 Subject: SSL fixes I hope I addressed here a number of fixes in my first implementation: - working hasSSLValid() function (checking cert validity and chain errors) - escaping certificate strings - typos (Sha256/Md5, supportedCipherBits/usedCipherBits) - encryption check (at least I hope so) CCMAIL: rich@kde.org --- src/sslinfo.ui | 6 ++- src/sslinfodialog.cpp | 56 ++++++++-------------- src/urlbar/bookmarkwidget.cpp | 5 +- src/urlbar/rsswidget.cpp | 5 +- src/urlbar/sslwidget.cpp | 105 ++++++++++++++++++++---------------------- src/webpage.cpp | 22 ++++----- 6 files changed, 90 insertions(+), 109 deletions(-) diff --git a/src/sslinfo.ui b/src/sslinfo.ui index bd0bdeda..41393bb4 100644 --- a/src/sslinfo.ui +++ b/src/sslinfo.ui @@ -298,7 +298,11 @@ - <h4>FingerPrints:</h4> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:medium; font-weight:600;">Digests:</span></p></body></html> diff --git a/src/sslinfodialog.cpp b/src/sslinfodialog.cpp index 97aafd81..2bdf1425 100644 --- a/src/sslinfodialog.cpp +++ b/src/sslinfodialog.cpp @@ -31,15 +31,13 @@ #include -#include #include #include + #include -#include -#include -#include +#include -#include +#include #include #include @@ -58,7 +56,7 @@ SslInfoDialog::SslInfoDialog(const QString &host, const WebSslInfo &info, QWidge setButtons(KDialog::User1 | KDialog::Close); - setButtonGuiItem(User1, KGuiItem(i18n("Export"), "view-certificate-export")); + setButtonGuiItem(User1, KGuiItem(i18n("Export"), QL1S("view-certificate-export"))); connect(this, SIGNAL(user1Clicked()), this, SLOT(exportCert())); ui.setupUi(mainWidget()); @@ -88,39 +86,20 @@ void SslInfoDialog::showCertificateInfo(QSslCertificate subjectCert, const QStri c += QL1S(""); ui.certInfoLabel->setText(c); - // WARNING (Security Issue): set these labels to use PlainText! - ui.subjectCN->setText(subjectCert.subjectInfo(QSslCertificate::CommonName)); - ui.subjectCN->setTextFormat(Qt::PlainText); - - ui.subjectO->setText(subjectCert.subjectInfo(QSslCertificate::Organization)); - ui.subjectO->setTextFormat(Qt::PlainText); - - ui.subjectOU->setText(subjectCert.subjectInfo(QSslCertificate::OrganizationalUnitName)); - ui.subjectOU->setTextFormat(Qt::PlainText); - - ui.subjectSN->setText(subjectCert.serialNumber()); - ui.subjectSN->setTextFormat(Qt::PlainText); - - ui.issuerCN->setText(subjectCert.issuerInfo(QSslCertificate::CommonName)); - ui.issuerCN->setTextFormat(Qt::PlainText); + ui.subjectCN->setText( Qt::escape(subjectCert.subjectInfo(QSslCertificate::CommonName)) ); + ui.subjectO->setText( Qt::escape(subjectCert.subjectInfo(QSslCertificate::Organization)) ); + ui.subjectOU->setText( Qt::escape(subjectCert.subjectInfo(QSslCertificate::OrganizationalUnitName)) ); + ui.subjectSN->setText( Qt::escape(subjectCert.serialNumber()) ); - ui.issuerO->setText(subjectCert.issuerInfo(QSslCertificate::Organization)); - ui.issuerO->setTextFormat(Qt::PlainText); + ui.issuerCN->setText( Qt::escape(subjectCert.issuerInfo(QSslCertificate::CommonName)) ); + ui.issuerO->setText( Qt::escape(subjectCert.issuerInfo(QSslCertificate::Organization)) ); + ui.issuerOU->setText( Qt::escape(subjectCert.issuerInfo(QSslCertificate::OrganizationalUnitName)) ); - ui.issuerOU->setText(subjectCert.issuerInfo(QSslCertificate::OrganizationalUnitName)); - ui.issuerOU->setTextFormat(Qt::PlainText); + ui.issuedOn->setText( Qt::escape(subjectCert.effectiveDate().date().toString(Qt::SystemLocaleShortDate)) ); + ui.expiresOn->setText( Qt::escape(subjectCert.expiryDate().date().toString(Qt::SystemLocaleShortDate)) ); - ui.issuedOn->setText(subjectCert.effectiveDate().date().toString(Qt::SystemLocaleShortDate)); - ui.issuedOn->setTextFormat(Qt::PlainText); - - ui.expiresOn->setText(subjectCert.expiryDate().date().toString(Qt::SystemLocaleShortDate)); - ui.expiresOn->setTextFormat(Qt::PlainText); - - ui.md5->setText(subjectCert.digest(QCryptographicHash::Md5).toHex()); - ui.md5->setTextFormat(Qt::PlainText); - - ui.sha1->setText(subjectCert.digest(QCryptographicHash::Sha1).toHex()); - ui.sha1->setTextFormat(Qt::PlainText); + ui.md5->setText( Qt::escape(subjectCert.digest(QCryptographicHash::Md5).toHex()) ); + ui.sha1->setText( Qt::escape(subjectCert.digest(QCryptographicHash::Sha1).toHex()) ); } @@ -149,7 +128,10 @@ void SslInfoDialog::exportCert() { QSslCertificate cert = m_info.certificateChain().at(ui.comboBox->currentIndex()); - QString name = cert.subjectInfo(QSslCertificate::CommonName) + QL1S(".pem"); + if (cert.isNull()) + return; + + QString name = m_host + QL1S(".pem"); QString certPath = KFileDialog::getSaveFileName(name, QString(), this); diff --git a/src/urlbar/bookmarkwidget.cpp b/src/urlbar/bookmarkwidget.cpp index 0cacd41d..eb2ac08e 100644 --- a/src/urlbar/bookmarkwidget.cpp +++ b/src/urlbar/bookmarkwidget.cpp @@ -61,7 +61,10 @@ BookmarkWidget::BookmarkWidget(const KBookmark &bookmark, QWidget *parent) // Title QVBoxLayout *vLayout = new QVBoxLayout(this); QLabel *bookmarkInfo = new QLabel(this); - bookmarkInfo->setText(i18n("

Edit this Bookmark

")); + bookmarkInfo->setText(i18n("Edit this Bookmark")); + QFont f = bookmarkInfo->font(); + f.setBold(true); + bookmarkInfo->setFont(f); bookmarkInfo->setAlignment(Qt::AlignCenter); vLayout->addWidget(bookmarkInfo); diff --git a/src/urlbar/rsswidget.cpp b/src/urlbar/rsswidget.cpp index fc926e38..c0d78225 100644 --- a/src/urlbar/rsswidget.cpp +++ b/src/urlbar/rsswidget.cpp @@ -62,7 +62,10 @@ RSSWidget::RSSWidget(const QMap< KUrl, QString > &map, QWidget *parent) // Title QLabel *title = new QLabel(this); - title->setText(i18n("

Subscribe to RSS Feeds

")); + title->setText(i18n("Subscribe to RSS Feeds")); + QFont f = title->font(); + f.setBold(true); + title->setFont(f); title->setAlignment(Qt::AlignCenter); layout->addRow(title); diff --git a/src/urlbar/sslwidget.cpp b/src/urlbar/sslwidget.cpp index dec7033c..a86151a9 100644 --- a/src/urlbar/sslwidget.cpp +++ b/src/urlbar/sslwidget.cpp @@ -38,6 +38,7 @@ #include #include #include +#include SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) @@ -49,7 +50,7 @@ SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) setMinimumWidth(400); QSslCertificate cert = m_info.certificateChain().first(); - QStringList errorList = SslInfoDialog::errorsFromString(m_info.certificateErrors()).first(); + QStringList firstCertErrorList = SslInfoDialog::errorsFromString(m_info.certificateErrors()).first(); QGridLayout *layout = new QGridLayout(this); @@ -63,55 +64,41 @@ SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) label = new QLabel(this); label->setWordWrap(true); - label->setText(i18n("

Identity

")); + label->setText(i18n("Identity")); + QFont f1 = label->font(); + f1.setBold(true); + label->setFont(f1); layout->addWidget(label, rows++, 1); + label = new QLabel(this); + label->setWordWrap(true); if(cert.isNull()) { - label = new QLabel(this); - label->setWordWrap(true); - label->setText(i18n("Warning: this site is carrying a NULL certificate!")); + label->setText(i18n("Warning: this site is NOT carrying a certificate!")); imageLabel->setPixmap(KIcon("security-low").pixmap(32)); } else { - if(cert.isValid() && errorList.isEmpty()) + if(cert.isValid() && firstCertErrorList.isEmpty()) { - label = new QLabel(this); - label->setWordWrap(true); - label->setTextFormat(Qt::PlainText); label->setText(i18n("This certificate for this site is valid and has been verified by:\n%1.", - cert.issuerInfo(QSslCertificate::CommonName))); - + Qt::escape(cert.issuerInfo(QSslCertificate::CommonName)) )); imageLabel->setPixmap(KIcon("security-high").pixmap(32)); } else { - label = new QLabel(this); - label->setWordWrap(true); - - QList errorList = SslInfoDialog::errorsFromString(m_info.certificateErrors()); - if(errorList.at(0).isEmpty()) - { - label->setText(i18n("The certificate for this site is valid, but some on the certificate chain are not!")); - imageLabel->setPixmap(KIcon("security-medium").pixmap(32)); - } - else + QString c = QL1S("
    "); + Q_FOREACH(const QString & s, firstCertErrorList) { - QStringList sl = errorList.at(0); - QString c = QL1S("
      "); - Q_FOREACH(const QString & s, sl) - { - c += QL1S("
    • ") + s + QL1S("
    • "); - } - c += QL1S("
    "); - - label->setText(i18n("The certificate for this site is NOT valid, for the following reasons:\n%1", c)); - label->setTextFormat(Qt::RichText); - imageLabel->setPixmap(KIcon("security-low").pixmap(32)); + c += QL1S("
  • ") + s + QL1S("
  • "); } + c += QL1S("
"); + + label->setText(i18n("The certificate for this site is NOT valid, for the following reasons:\n%1", c)); + label->setTextFormat(Qt::RichText); + imageLabel->setPixmap(KIcon("security-low").pixmap(32)); } } @@ -126,13 +113,17 @@ SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) // ------------------------------------------------------------------------------------------------------------------ label = new QLabel(this); label->setWordWrap(true); - label->setText(QL1S("

Encryption

")); // ----------------------------------------------- // + label->setText(i18n("Encryption")); + QFont f2 = label->font(); + f2.setBold(true); + label->setFont(f2); layout->addWidget(label, rows, 1); imageLabel = new QLabel(this); layout->addWidget(imageLabel, rows++ , 0, Qt::AlignCenter); - if(cert.isNull()) + QString ciph = m_info.ciphers(); + if (ciph.isEmpty()) // NOTE: Can I verify encryption in another (better?) way? { label = new QLabel(this); label->setWordWrap(true); @@ -145,47 +136,48 @@ SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) { label = new QLabel(this); label->setWordWrap(true); - label->setTextFormat(Qt::PlainText); - label->setText(i18n("Your connection to %1 is encrypted with %2-bit encryption.\n", m_url.host(), m_info.supportedChiperBits())); + label->setText( i18n("Your connection to \"%1\" is encrypted!\n", m_url.host()) ); layout->addWidget(label, rows++, 1); - int vers = cert.version().toInt(); + QString vers = m_info.protocol(); QString sslVersion; - switch(vers) + if (vers == QL1S("SSLv3")) { - case 0: sslVersion = QL1S("SSL 3.0"); imageLabel->setPixmap(KIcon("security-high").pixmap(32)); - break; - case 1: + } + else if (vers == QL1S("SSLv2")) + { sslVersion = QL1S("SSL 2.0"); - imageLabel->setPixmap(KIcon("security-medium").pixmap(32)); - break; - case 2: - case 3: + imageLabel->setPixmap(KIcon("security-low").pixmap(32)); + } + else if (vers == QL1S("TLSv1")) + { sslVersion = QL1S("TLS 1.0"); imageLabel->setPixmap(KIcon("security-high").pixmap(32)); - break; - default: - sslVersion = QL1S("Unknown"); - imageLabel->setPixmap(KIcon("security-medium").pixmap(32)); + } + else + { + sslVersion = i18n("Unknown"); + imageLabel->setPixmap(KIcon("security-low").pixmap(32)); } label = new QLabel(this); label->setWordWrap(true); - label->setText(i18n("The connection uses %1.\n", sslVersion)); + label->setText( i18n("It uses protocol: %1.\n", sslVersion) ); layout->addWidget(label, rows++, 1); const QStringList cipherInfo = m_info.ciphers().split('\n', QString::SkipEmptyParts); label = new QLabel(this); label->setWordWrap(true); - label->setTextFormat(Qt::PlainText); label->setText( - i18n("The connection is encrypted using %1 at %2 bits with %3 for message authentication and %4 as the key exchange mechanism.\n\n", + i18n("It is encrypted using %1 at %2 bits\nMessage authentication: %3\nKey exchange mechanism: %4, with Auth %5.\n\n", cipherInfo[0], m_info.usedChiperBits(), cipherInfo[3], - cipherInfo[1])); + cipherInfo[2], + cipherInfo[1]) + ); layout->addWidget(label, rows++, 1); } @@ -196,7 +188,10 @@ SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) label = new QLabel(this); label->setWordWrap(true); - label->setText(i18n("

Site Information

")); + label->setText(i18n("Site Information")); + QFont f3 = label->font(); + f3.setBold(true); + label->setFont(f3); layout->addWidget(label, rows++, 1); label = new QLabel(this); @@ -206,7 +201,7 @@ SSLWidget::SSLWidget(const QUrl &url, const WebSslInfo &info, QWidget *parent) if(firstVisit.visitCount == 1) { - label->setText(i18n("It's your first time visiting this site!")); + label->setText(i18n("It is your first time visiting this site!")); imageLabel->setPixmap(KIcon("security-medium").pixmap(32)); } else diff --git a/src/webpage.cpp b/src/webpage.cpp index 0c9b436d..3f4b4e1f 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -545,10 +545,11 @@ void WebPage::manageNetworkErrors(QNetworkReply *reply) QWebFrame* frame = qobject_cast(reply->request().originatingObject()); const bool isMainFrameRequest = (frame == mainFrame()); - //const bool isUrlFrameLoading = (_loadingUrl == frame->url()); + const bool isLoadingUrlReply = (_loadingUrl == reply->url()); if(isMainFrameRequest && _sslInfo.isValid() + && isLoadingUrlReply && !domainSchemeMatch(reply->url(), _sslInfo.url()) ) { @@ -562,7 +563,7 @@ void WebPage::manageNetworkErrors(QNetworkReply *reply) { case QNetworkReply::NoError: // no error. Simple :) - if(isMainFrameRequest && !_sslInfo.isValid()) + if(isMainFrameRequest && isLoadingUrlReply && !_sslInfo.isValid()) { // Obtain and set the SSL information if any... _sslInfo.restoreFrom(reply->attribute(static_cast(KIO::AccessManager::MetaData)), reply->url()); @@ -754,22 +755,15 @@ void WebPage::copyToTempFileResult(KJob* job) bool WebPage::hasSslValid() { - bool v = true; QList certList = _sslInfo.certificateChain(); if (certList.isEmpty()) return false; - Q_FOREACH(const QSslCertificate & cert, certList) - { - v &= cert.isValid(); - } + QSslCertificate firstCert = certList.at(0); + if (!firstCert.isValid()) + return false; - QList errorsList = SslInfoDialog::errorsFromString(_sslInfo.certificateErrors()); - Q_FOREACH(const QStringList & err, errorsList) - { - v &= err.isEmpty(); - } - - return v; + QStringList firstCertErrorsList = SslInfoDialog::errorsFromString(_sslInfo.certificateErrors()).at(0); + return firstCertErrorsList.isEmpty(); } -- cgit v1.2.1