OSDN Git Service

QSslSocketPrivate, QSslKeyPrivate and QSslCipher cleanup
authorIvailo Monev <xakepa10@laimg.moc>
Wed, 19 Jun 2019 12:08:33 +0000 (12:08 +0000)
committerIvailo Monev <xakepa10@laimg.moc>
Wed, 19 Jun 2019 12:08:33 +0000 (12:08 +0000)
Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
src/network/ssl/qsslcipher.cpp
src/network/ssl/qsslkey.cpp
src/network/ssl/qsslkey_p.h
src/network/ssl/qsslsocket.cpp
src/network/ssl/qsslsocket_openssl.cpp
src/network/ssl/qsslsocket_p.h

index bd53eda..2d97f7f 100644 (file)
@@ -92,7 +92,7 @@ QSslCipher::QSslCipher(const QString &name, QSsl::SslProtocol protocol)
     foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) {
         if (cipher.name() == name && cipher.protocol() == protocol) {
             *this = cipher;
-            return;
+            break;
         }
     }
 }
index a0ebee3..cf49661 100644 (file)
@@ -74,19 +74,17 @@ QT_BEGIN_NAMESPACE
 /*!
     \internal
  */
-void QSslKeyPrivate::clear(bool deep)
+void QSslKeyPrivate::clear()
 {
     isNull = true;
     if (!QSslSocket::supportsSsl())
         return;
     if (rsa) {
-        if (deep)
-            RSA_free(rsa);
+        RSA_free(rsa);
         rsa = 0;
     }
     if (dsa) {
-        if (deep)
-            DSA_free(dsa);
+        DSA_free(dsa);
         dsa = 0;
     }
 }
@@ -97,20 +95,15 @@ void QSslKeyPrivate::clear(bool deep)
     Allocates a new rsa or dsa struct and decodes \a pem into it
     according to the current algorithm and type.
 
-    If \a deepClear is true, the rsa/dsa struct is freed if it is was
-    already allocated, otherwise we "leak" memory (which is exactly
-    what we want for copy construction).
-
     If \a passPhrase is non-empty, it will be used for decrypting
     \a pem.
 */
-void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase,
-                               bool deepClear)
+void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase)
 {
     if (pem.isEmpty())
         return;
 
-    clear(deepClear);
+    clear();
 
     if (!QSslSocket::supportsSsl())
         return;
@@ -153,12 +146,11 @@ QSslKey::QSslKey()
 */
 QByteArray QSslKeyPrivate::pemHeader() const
 {
-    // ### use QByteArray::fromRawData() instead
     if (type == QSsl::PublicKey)
-        return QByteArray("-----BEGIN PUBLIC KEY-----\n");
+        return QByteArray::fromRawData("-----BEGIN PUBLIC KEY-----\n", 27);
     else if (algorithm == QSsl::Rsa)
-        return QByteArray("-----BEGIN RSA PRIVATE KEY-----\n");
-    return QByteArray("-----BEGIN DSA PRIVATE KEY-----\n");
+        return QByteArray::fromRawData("-----BEGIN RSA PRIVATE KEY-----\n", 32);
+    return QByteArray::fromRawData("-----BEGIN DSA PRIVATE KEY-----\n", 32);
 }
 
 /*!
@@ -166,12 +158,11 @@ QByteArray QSslKeyPrivate::pemHeader() const
 */
 QByteArray QSslKeyPrivate::pemFooter() const
 {
-    // ### use QByteArray::fromRawData() instead
     if (type == QSsl::PublicKey)
-        return QByteArray("-----END PUBLIC KEY-----\n");
+        return QByteArray::fromRawData("-----END PUBLIC KEY-----\n", 25);
     else if (algorithm == QSsl::Rsa)
-        return QByteArray("-----END RSA PRIVATE KEY-----\n");
-    return QByteArray("-----END DSA PRIVATE KEY-----\n");
+        return QByteArray::fromRawData("-----END RSA PRIVATE KEY-----\n", 30);
+    return QByteArray::fromRawData("-----END DSA PRIVATE KEY-----\n", 30);
 }
 
 /*!
index 6d8e4ea..c264a7d 100644 (file)
@@ -66,10 +66,9 @@ public:
     inline ~QSslKeyPrivate()
     { clear(); }
 
-    void clear(bool deep = true);
+    void clear();
 
-    void decodePem(const QByteArray &pem, const QByteArray &passPhrase,
-                   bool deepClear = true);
+    void decodePem(const QByteArray &pem, const QByteArray &passPhrase);
     QByteArray pemHeader() const;
     QByteArray pemFooter() const;
     QByteArray pemFromDer(const QByteArray &der) const;
index b6d0d9a..7371c40 100644 (file)
@@ -2300,15 +2300,35 @@ bool QSslSocketPrivate::rootCertOnDemandLoadingSupported()
 /*!
     \internal
 */
-QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
-{
-    return QList<QByteArray>() <<  "/etc/ssl/certs/" // (K)ubuntu, OpenSUSE, Mandriva ...
-                               << "/usr/lib/ssl/certs/" // Gentoo, Mandrake
-                               << "/usr/share/ssl/" // Centos, Redhat, SuSE
-                               << "/usr/local/ssl/" // Normal OpenSSL Tarball
-                               << "/var/ssl/certs/" // AIX
-                               << "/usr/local/ssl/certs/" // Solaris
-                               << "/opt/openssl/certs/"; // HP-UX
+QByteArray QSslSocketPrivate::unixRootCertDirectory()
+{
+    static QByteArray certdir;
+    if (certdir.isEmpty()) {
+        QByteArray fromenv = qgetenv(X509_get_default_cert_dir_env());
+        if (!fromenv.isEmpty()) {
+            certdir = fromenv;
+        } else {
+            certdir = QByteArray(X509_get_default_cert_dir());
+        }
+    }
+    return certdir;
+}
+
+/*!
+    \internal
+*/
+QByteArray QSslSocketPrivate::unixRootCertFile()
+{
+    static QByteArray certfile;
+    if (certfile.isEmpty()) {
+        QByteArray fromenv = qgetenv(X509_get_default_cert_file_env());
+        if (!fromenv.isEmpty()) {
+            certfile = fromenv;
+        } else {
+            certfile = QByteArray(X509_get_default_cert_file());
+        }
+    }
+    return certfile;
 }
 
 QT_END_NAMESPACE
index c16edea..e7cd605 100644 (file)
@@ -350,10 +350,8 @@ init_context:
     }
 
     if (s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
-        // tell OpenSSL the directories where to look up the root certs on demand
-        QList<QByteArray> unixDirs = unixRootCertDirectories();
-        for (int a = 0; a < unixDirs.count(); ++a)
-            SSL_CTX_load_verify_locations(ctx, 0, unixDirs.at(a).constData());
+        // tell OpenSSL the directory where to look up the root certs on demand
+        SSL_CTX_load_verify_locations(ctx, 0, unixRootCertDirectory().constData());
     }
 
     if (!configuration.localCertificate.isNull()) {
@@ -558,14 +556,10 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
     resetDefaultCiphers();
 
     // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
-    const QList<QByteArray> dirs = unixRootCertDirectories();
     const QStringList symLinkFilter = QStringList() << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
-    for (int a = 0; a < dirs.count(); ++a) {
-        QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
-        if (iterator.hasNext()) {
-            s_loadRootCertsOnDemand = true;
-            break;
-        }
+    QDirIterator iterator(unixRootCertDirectory(), symLinkFilter, QDir::Files);
+    if (iterator.hasNext()) {
+        s_loadRootCertsOnDemand = true;
     }
     // if on-demand loading was not enabled, load the certs now
     if (!s_loadRootCertsOnDemand)
@@ -636,27 +630,16 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
 #endif
     QList<QSslCertificate> systemCerts;
 
-    QSet<QString> certFiles;
-    QList<QByteArray> directories = unixRootCertDirectories();
-    QDir currentDir;
-    QStringList nameFilters;
-    nameFilters << QLatin1String("*.pem") << QLatin1String("*.crt");
+    QDir currentDir(unixRootCertDirectory());
+    QStringList nameFilters = QStringList() << QLatin1String("*.pem") << QLatin1String("*.crt");
     currentDir.setNameFilters(nameFilters);
-    for (int a = 0; a < directories.count(); a++) {
-        currentDir.setPath(QLatin1String(directories.at(a)));
-        QDirIterator it(currentDir);
-        while(it.hasNext()) {
-            it.next();
-            // use canonical path here to not load the same certificate twice if symlinked
-            certFiles.insert(it.fileInfo().canonicalFilePath());
-        }
-    }
-    QSetIterator<QString> it(certFiles);
+    QDirIterator it(currentDir);
     while(it.hasNext()) {
-        systemCerts.append(QSslCertificate::fromPath(it.next()));
+        it.next();
+        // use canonical path here to not load the same certificate twice if symlinked
+        systemCerts.append(QSslCertificate::fromPath(it.fileInfo().canonicalFilePath()));
     }
-    systemCerts.append(QSslCertificate::fromPath(QLatin1String("/etc/pki/tls/certs/ca-bundle.crt"), QSsl::Pem)); // Fedora, Mandriva
-    systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/share/certs/ca-root-nss.crt"), QSsl::Pem)); // FreeBSD's ca_root_nss
+    systemCerts.append(QSslCertificate::fromPath(unixRootCertFile(), QSsl::Pem));
 
 #ifdef QSSLSOCKET_DEBUG
     qDebug() << "systemCaCertificates retrieval time " << timer.elapsed() << "ms";
index a755569..64218c5 100644 (file)
@@ -136,7 +136,8 @@ private:
     static bool s_loadedCiphersAndCerts;
 protected:
     static bool s_loadRootCertsOnDemand;
-    static QList<QByteArray> unixRootCertDirectories();
+    static QByteArray unixRootCertDirectory();
+    static QByteArray unixRootCertFile();
 };
 
 QT_END_NAMESPACE