[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    [PATCH] KSSL bug in 2.2.2
From:       George Staikos <staikos () kde ! org>
Date:       2001-11-23 20:23:12
[Download RAW message or body]

There is a bug in 2.2.2 that makes SSL certificates still not properly verify 
on sites with frames.  This is not a security hole, but quite the opposite.  
It warns of a security problem when there isn't one.  Here is a possible 
patch for this.  I haven't tested this specfic patch but I believe Dawit has, 
and I tested a similar one in HEAD which worked.


-- 

George Staikos

["ksslpeerinfo.patch" (text/x-diff)]

Index: ksslpeerinfo.h
===================================================================
RCS file: /home/kde/kdelibs/kssl/ksslpeerinfo.h,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.2
diff -u -r1.12.2.1 -r1.12.2.2
--- ksslpeerinfo.h	2001/11/07 05:47:37	1.12.2.1
+++ ksslpeerinfo.h	2001/11/23 18:42:36	1.12.2.2
@@ -24,7 +24,7 @@
 class KSSL;
 
 #include <qglobal.h>
-#include <qstring.h>
+#include <qstringlist.h>
 #include <ksslcertificate.h>
 
 class KSSLPeerInfoPrivate;
@@ -38,14 +38,15 @@
   KSSLCertificate& getPeerCertificate();
   bool certMatchesAddress();
   QString getPeerAddress();
-  
+
   void setProxying(bool active, QString realHost = QString::null);
- 
+
 protected:
   KSSLPeerInfo();
 
   KSSLCertificate m_cert;
   void setPeerAddress(KInetSocketAddress &x);
+  void extractDomains(const QString &fqdn, QStringList &domains);
 
 private:
   KSSLPeerInfoPrivate *d;
Index: ksslpeerinfo.cc
===================================================================
RCS file: /home/kde/kdelibs/kssl/ksslpeerinfo.cc,v
retrieving revision 1.12.2.10
retrieving revision 1.12.2.11
diff -u -r1.12.2.10 -r1.12.2.11
--- ksslpeerinfo.cc	2001/11/07 05:47:37	1.12.2.10
+++ ksslpeerinfo.cc	2001/11/23 18:42:36	1.12.2.11
@@ -23,7 +23,6 @@
 #endif
 
 #include "ksslpeerinfo.h"
-#include <qstring.h>
 #include <kdebug.h>
 
 #include <ksockaddr.h>
@@ -74,25 +73,54 @@
   QString cn = certinfo.getValue("CN");
 
   if (d->proxying) {
-	if (cn.startsWith("*")) {
-		QRegExp cnre(cn.lower(), false, true);
-		if (cnre.match(d->proxyHost.lower()) >= 0) return true;
-	} else {
-		if (cn.lower() == d->proxyHost.lower()) return true;
-	}
-	return false;
+    QStringList domains;
+
+    kdDebug(7029) << "Matching CN=" << cn << " to " << d->proxyHost << endl;
+
+    extractDomains(d->proxyHost, domains);
+    QStringList::Iterator it = domains.begin();
+    for (; it != domains.end(); it++)
+    {
+      int match = cn.findRev(*it, -1, false);
+      kdDebug(7029) << "Match= " << match << ", CN.length= " << cn.length()
+                    << ", host.length= " << (*it).length() << endl;
+
+      if (match > -1 && ((match + (*it).length()) == cn.length()))
+      {
+        kdDebug(7029) << "Found a match ==> " << (*it) << endl;
+        return true;
+      }
+    }
+    return false;
   }
 
 
   if (cn.startsWith("*")) {   // stupid wildcard cn
-     QRegExp cnre(cn.lower(), false, true);
      QString host, port;
+     QStringList domains;
 
-     if (KExtendedSocket::resolve(d->host, host, port, NI_NAMEREQD) != 0) 
+     if (KExtendedSocket::resolve(d->host, host, port, NI_NAMEREQD) != 0)
         host = d->host->nodeName();
 
      kdDebug(7029) << "Matching CN=" << cn << " to " << host << endl;
-     if (cnre.match(host.lower()) >= 0) return true;
+
+     extractDomains( host, domains );
+     QStringList::Iterator it = domains.begin();
+
+     for (; it != domains.end(); it++)
+     {
+        int match = cn.findRev(*it, -1, false);
+        kdDebug(7029) << "Match= " << match << ", CN.length= " << cn.length()
+                      << ", host.length= " << (*it).length() << endl;
+
+        if (match > -1 && ((match + (*it).length()) == cn.length()))
+        {
+          kdDebug(7029) << "Found a match ==> " << (*it) << endl;
+          return true;
+         }
+     }
+
+     return false;
   } else {
      int err = 0;
      QList<KAddressInfo> cns = KExtendedSocket::lookup(cn.latin1(), 0, 0, &err);
@@ -102,17 +130,55 @@
      }
      cns.setAutoDelete(true);
 
-//     kdDebug(7029) << "The original ones were: " << d->host->nodeName()
-//                   << " and: " << certinfo.getValue("CN").latin1()
-//                   << endl;
+     kdDebug(7029) << "The original ones were: " << d->host->nodeName()
+                   << " and: " << certinfo.getValue("CN").latin1()
+                   << endl;
 
      for (KAddressInfo *x = cns.first(); x; x = cns.next()) {
         if ((*x).address()->isCoreEqual(d->host)) {
            return true;
         }
      }
+     kdDebug(7029) << "Testing failed!" << endl;
   }
 
 #endif
   return false;
+}
+
+void KSSLPeerInfo::extractDomains(const QString &fqdn, QStringList &domains)
+{
+    domains.clear();
+
+    // If fqdn is an IP address, then only use
+    // the entire IP address to find a match! (DA)
+    if (fqdn[0] >= '0' && fqdn[0] <= '9') {
+       domains.append(fqdn);
+       return;
+    }
+
+    QStringList partList = QStringList::split('.', fqdn, false);
+
+    if (partList.count())
+        partList.remove(partList.begin()); // Remove hostname
+
+    while(partList.count()) {
+       if (partList.count() == 1)
+         break; // We only have a TLD left.
+
+       if (partList.count() == 2) {
+          // If this is a TLD, we should stop. (e.g. co.uk)
+          // We assume this is a TLD if it ends with .xx.yy or .x.yy
+          if (partList[0].length() <= 2 && partList[1].length() == 2)
+             break; // This is a TLD.
+       }
+
+       QString domain = partList.join(".");
+       domains.append(domain);
+       partList.remove(partList.begin());
+    }
+
+    // Add the entire FQDN at the end of the
+    // list for fqdn == CN checks
+    domains.append(fqdn);
 }

>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic