[qt/f13/master] multiple Browser Wildcard Cerficate Validation Weakness

Than Ngo than at fedoraproject.org
Mon Sep 6 13:30:17 UTC 2010


commit ba1464fdb569e7a367b39dab3e701870e13220f9
Author: Than Ngo <than at redhat.com>
Date:   Mon Sep 6 15:40:42 2010 +0200

    multiple Browser Wildcard Cerficate Validation Weakness

 qt-4.x-ssl-certificates-security.patch |   91 ++++++++++++++++++++++++++++++++
 qt.spec                                |    8 ++-
 2 files changed, 97 insertions(+), 2 deletions(-)
---
diff --git a/qt-4.x-ssl-certificates-security.patch b/qt-4.x-ssl-certificates-security.patch
new file mode 100644
index 0000000..4b0b855
--- /dev/null
+++ b/qt-4.x-ssl-certificates-security.patch
@@ -0,0 +1,91 @@
+From be3dc286effc4307c5ef9737c9e34e449831e02c Mon Sep 17 00:00:00 2001
+From: Richard J. Moore <rich at kde.org>
+Date: Sun, 6 Jun 2010 22:10:08 +0100
+Subject: [PATCH] Fix Qt's handling of wildcards in SSL certificates
+
+Task-number: QTBUG-4455
+---
+ src/network/ssl/qsslsocket_openssl.cpp |   42 ++++++++++++++++++++++++++++---
+ src/network/ssl/qsslsocket_openssl_p.h |    1 +
+ 2 files changed, 39 insertions(+), 4 deletions(-)
+
+diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
+index 050fb1b..467842c 100644
+--- a/src/network/ssl/qsslsocket_openssl.cpp
++++ b/src/network/ssl/qsslsocket_openssl.cpp
+@@ -819,17 +819,16 @@ bool QSslSocketBackendPrivate::startHandshake()
+             QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
+             QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName);
+ 
+-            QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard);
+-            if (!regexp.exactMatch(peerName)) {
++            if (!isMatchingHostname(commonName.lower(), peerName.lower())) {
+                 bool matched = false;
+                 foreach (const QString &altName, configuration.peerCertificate
+                          .alternateSubjectNames().values(QSsl::DnsEntry)) {
+-                    regexp.setPattern(altName);
+-                    if (regexp.exactMatch(peerName)) {
++                    if (isMatchingHostname(altName.lower(), peerName.lower())) {
+                         matched = true;
+                         break;
+                     }
+                 }
++
+                 if (!matched) {
+                     // No matches in common names or alternate names.
+                     QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
+@@ -959,4 +958,39 @@ QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates
+     return certificates;
+ }
+ 
++bool QSslSocketBackendPrivate::isMatchingHostname(const QString &cn, const QString &hostname)
++{
++    int wildcard = cn.indexOf(QChar('*', 0));
++
++    // Check this is a wildcard cert, if not then just compare the strings
++    if (wildcard < 0)
++        return cn == hostname;
++
++    int firstCnDot = cn.indexOf(QChar('.', 0));
++    int secondCnDot = cn.indexOf(QChar('.', 0), firstCnDot+1);
++
++    // Check at least 3 components
++    if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.length()))
++        return false;
++
++    // Check * is last character of 1st component (ie. there's a following .)
++    if (wildcard+1 != firstCnDot)
++        return false;
++
++    // Check only one star
++    if (cn.lastIndexOf(QChar('*', 0)) != wildcard)
++        return false;
++
++    // Check characters preceding * (if any) match
++    if (wildcard && (hostname.leftRef(wildcard) != cn.leftRef(wildcard)))
++        return false;
++
++    // Check characters following first . match
++    if (hostname.midRef(hostname.indexOf(QChar('.', 0))) != cn.midRef(firstCnDot))
++        return false;
++
++    // Ok, I guess this was a wildcard CN and the hostname matches.
++    return true;
++}
++
+ QT_END_NAMESPACE
+diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
+index 3c08757..7754e22 100644
+--- a/src/network/ssl/qsslsocket_openssl_p.h
++++ b/src/network/ssl/qsslsocket_openssl_p.h
+@@ -116,6 +116,7 @@ public:
+ 
+     static QSslCipher QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher);
+     static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
++    static bool isMatchingHostname(const QString &cn, const QString &hostname);
+ };
+ 
+ QT_END_NAMESPACE
+-- 
+1.6.1
+
diff --git a/qt.spec b/qt.spec
index bb0e7f0..7bfe8c9 100644
--- a/qt.spec
+++ b/qt.spec
@@ -13,7 +13,7 @@ Summary: Qt toolkit
 Name:    qt
 Epoch:   1
 Version: 4.6.3
-Release: 8%{?dist}
+Release: 9%{?dist}
 
 # See LGPL_EXCEPTIONS.txt, LICENSE.GPL3, respectively, for exception details
 License: LGPLv2 with exceptions or GPLv3 with exceptions
@@ -87,6 +87,7 @@ Patch117: qt-everywhere-opensource-src-4.6.3-CVE-2010-1773.patch
 Patch118: qt-everywhere-opensource-src-4.6.3-CVE-2010-1774.patch
 Patch119: qt-everywhere-opensource-src-4.6.3-CVE-2010-1119.patch
 Patch120: qt-everywhere-opensource-src-4.6.3-CVE-2010-1778.patch
+Patch121: qt-4.x-ssl-certificates-security.patch
 
 # kde-qt git patches
 Patch201: 0001-This-patch-uses-object-name-as-a-fallback-for-window.patch
@@ -467,7 +468,7 @@ Qt libraries used for drawing widgets and OpenGL items.
 %patch118 -p1 -b .CVE-2010-1774
 %patch119 -p1 -b .CVE-2010-1119
 %patch120 -p1 -b .CVE-2010-1778
-
+%patch121 -p1 -b .security-ssl-cerficate
 
 # kde-qt branch
 %patch201 -p1 -b .kde-qt-0001
@@ -1084,6 +1085,9 @@ fi
 
 
 %changelog
+* Mon Sep 06 2010 Than Ngo <than at redhat.com> - 4.6.3-9
+- multiple Browser Wildcard Cerficate Validation Weakness
+
 * Tue Jul 01 2010 Kevin Kofler <Kevin at tigcc.ticalc.org> - 4.6.3-8
 - use find_lang to package the qm files (#609749)
 - put the qm files into the correct subpackages


More information about the scm-commits mailing list