diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 050fb1b..a047719 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('*'));
+
+    // Check this is a wildcard cert, if not then just compare the strings
+    if (wildcard < 0)
+        return cn == hostname;
+
+    int firstCnDot = cn.indexOf(QChar('.'));
+    int secondCnDot = cn.indexOf(QChar('.'), 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('*')) != 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('.'))) != 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

