Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. SSL: Handshake failed for requests made from QML.

SSL: Handshake failed for requests made from QML.

Scheduled Pinned Locked Moved QML and Qt Quick
ssltlsqml
2 Posts 2 Posters 4.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    PelleKrogstad
    wrote on 17 Mar 2015, 07:32 last edited by PelleKrogstad
    #1

    Hey, I make some https requests directly from my qml views, for instance for image sources. As I have a self signed certificate server side, I need to tell qt to ignore some ssl errors. (I control both the server and the client applications, so this shouldn't be a problem really.)

    I've made a QQmlNetworkAccessManagerFactory to create NAMs, where I connect to the sslErrors signal.

    UltraQmlAccessManagerFactory.h

    #ifndef FACKFACKTORy_H
    #define FACKFACKTORy_H
    
    
    #include <QQmlNetworkAccessManagerFactory>
    #include <QObject>
    #include <QNetworkReply>
    #include <QList>
    #include <QSslError>
    #include <QNetworkAccessManager>
    #include <QDebug>
    #include <QSslCertificate>
    
    class UltraQmlNetworkAccessManagerFactory : public QObject,
                                                public QQmlNetworkAccessManagerFactory {
      Q_OBJECT
    private:
      QNetworkAccessManager* nam;
      QList<QSslError> expectedSslErrors;
    public:
      explicit UltraQmlNetworkAccessManagerFactory();
      ~UltraQmlNetworkAccessManagerFactory();
      virtual QNetworkAccessManager* create(QObject* parent);
    
    public slots:
      void onIgnoreSslErrors(QNetworkReply* reply, QList<QSslError> errors);
    };
    
    #endif
    

    UltraQmlNetworkAccessManagerFactory.cpp

    #include "UltraQmlNetworkAccessManagerFactory.h"
    
    UltraQmlNetworkAccessManagerFactory::UltraQmlNetworkAccessManagerFactory() {
    
      // disregard this for now...
      QList<QSslCertificate> cert = QSslCertificate::fromPath(":/public.crt");
      QSslError self_signed_error(QSslError::SelfSignedCertificate, cert.at(0));
      QSslError host_name_error(QSslError::HostNameMismatch, cert.at(0));
      //  QSslError untrusted_error(QSslError::CertificateUntrusted, cert.at(0));
      expectedSslErrors.append(self_signed_error);
      //  expectedSslErrors.append(host_name_error);
      //  expectedSslErrors.append(untrusted_error);
    
    
    }
    
    UltraQmlNetworkAccessManagerFactory::~UltraQmlNetworkAccessManagerFactory() {
      delete nam;
    }
    
    QNetworkAccessManager* UltraQmlNetworkAccessManagerFactory::create(QObject* parent) {
      QNetworkAccessManager* nam = new QNetworkAccessManager(parent);
      QObject::connect(nam, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)),
                       this, SLOT(onIgnoreSslErrors(QNetworkReply*,QList<QSslError>))
                       );
      return nam;
    
    }
    
    
    void UltraQmlNetworkAccessManagerFactory::onIgnoreSslErrors(QNetworkReply *reply, QList<QSslError> errors) {
    
      QNetworkRequest req = reply->request();
      
      qDebug() << "Hello!" << endl;
    
      for (int i = 0; i < errors.size(); i++) {
        qDebug() << "e: " << errors.at(i) << endl;
    
      }
    
      reply->ignoreSslErrors(errors);
    }
    

    There is also some glue in main.cpp that sets this factory to be used, I doubt that part is a source of errors as the qDebug prints are visible in the output.

    As you can see in the .cpp file in the function/slot onIgnoreSslErrors, I try to ignore every error (as a test) that I receive, but as you can see in the output I do not get the expected results.

    Output

    Hello! 
    
    e:  "The certificate is self-signed, and untrusted" 
    
    qrc:/qml/file/ImageView.qml:16:5: QML Image: SSL handshake failed
    

    I have successfully made QNetworkRequests from c++ directly with a QSslConfiguration, specifying TLSV1_0 and a certificate. As I have a suspicion that the handshake fails because one side expects SSL and the other TLS I have also tried to set the QSslConfiguration on the QNetworkRequest object throgh reply->request(); This however, changes nothing.

    Thanks for taking time to read my post.

    Pelle K

    P 1 Reply Last reply 19 Mar 2015, 11:33
    0
    • P PelleKrogstad
      17 Mar 2015, 07:32

      Hey, I make some https requests directly from my qml views, for instance for image sources. As I have a self signed certificate server side, I need to tell qt to ignore some ssl errors. (I control both the server and the client applications, so this shouldn't be a problem really.)

      I've made a QQmlNetworkAccessManagerFactory to create NAMs, where I connect to the sslErrors signal.

      UltraQmlAccessManagerFactory.h

      #ifndef FACKFACKTORy_H
      #define FACKFACKTORy_H
      
      
      #include <QQmlNetworkAccessManagerFactory>
      #include <QObject>
      #include <QNetworkReply>
      #include <QList>
      #include <QSslError>
      #include <QNetworkAccessManager>
      #include <QDebug>
      #include <QSslCertificate>
      
      class UltraQmlNetworkAccessManagerFactory : public QObject,
                                                  public QQmlNetworkAccessManagerFactory {
        Q_OBJECT
      private:
        QNetworkAccessManager* nam;
        QList<QSslError> expectedSslErrors;
      public:
        explicit UltraQmlNetworkAccessManagerFactory();
        ~UltraQmlNetworkAccessManagerFactory();
        virtual QNetworkAccessManager* create(QObject* parent);
      
      public slots:
        void onIgnoreSslErrors(QNetworkReply* reply, QList<QSslError> errors);
      };
      
      #endif
      

      UltraQmlNetworkAccessManagerFactory.cpp

      #include "UltraQmlNetworkAccessManagerFactory.h"
      
      UltraQmlNetworkAccessManagerFactory::UltraQmlNetworkAccessManagerFactory() {
      
        // disregard this for now...
        QList<QSslCertificate> cert = QSslCertificate::fromPath(":/public.crt");
        QSslError self_signed_error(QSslError::SelfSignedCertificate, cert.at(0));
        QSslError host_name_error(QSslError::HostNameMismatch, cert.at(0));
        //  QSslError untrusted_error(QSslError::CertificateUntrusted, cert.at(0));
        expectedSslErrors.append(self_signed_error);
        //  expectedSslErrors.append(host_name_error);
        //  expectedSslErrors.append(untrusted_error);
      
      
      }
      
      UltraQmlNetworkAccessManagerFactory::~UltraQmlNetworkAccessManagerFactory() {
        delete nam;
      }
      
      QNetworkAccessManager* UltraQmlNetworkAccessManagerFactory::create(QObject* parent) {
        QNetworkAccessManager* nam = new QNetworkAccessManager(parent);
        QObject::connect(nam, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)),
                         this, SLOT(onIgnoreSslErrors(QNetworkReply*,QList<QSslError>))
                         );
        return nam;
      
      }
      
      
      void UltraQmlNetworkAccessManagerFactory::onIgnoreSslErrors(QNetworkReply *reply, QList<QSslError> errors) {
      
        QNetworkRequest req = reply->request();
        
        qDebug() << "Hello!" << endl;
      
        for (int i = 0; i < errors.size(); i++) {
          qDebug() << "e: " << errors.at(i) << endl;
      
        }
      
        reply->ignoreSslErrors(errors);
      }
      

      There is also some glue in main.cpp that sets this factory to be used, I doubt that part is a source of errors as the qDebug prints are visible in the output.

      As you can see in the .cpp file in the function/slot onIgnoreSslErrors, I try to ignore every error (as a test) that I receive, but as you can see in the output I do not get the expected results.

      Output

      Hello! 
      
      e:  "The certificate is self-signed, and untrusted" 
      
      qrc:/qml/file/ImageView.qml:16:5: QML Image: SSL handshake failed
      

      I have successfully made QNetworkRequests from c++ directly with a QSslConfiguration, specifying TLSV1_0 and a certificate. As I have a suspicion that the handshake fails because one side expects SSL and the other TLS I have also tried to set the QSslConfiguration on the QNetworkRequest object throgh reply->request(); This however, changes nothing.

      Thanks for taking time to read my post.

      Pelle K

      P Offline
      P Offline
      p3c0
      Moderators
      wrote on 19 Mar 2015, 11:33 last edited by p3c0
      #2

      @PelleKrogstad
      I too had the same requirement. Looking further into I found out that the slot for onIgnoreSslErrors was never called as it is required for Self Signed Certificates and which cause these SSL errors.
      So actually the request needs to modified a bit which could be done by re-implementing createRequest
      Thus in QNAM subclassed class:

      QNetworkReply *MyNam::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
      {
          QNetworkRequest req = request;
          QSslConfiguration conf = req.sslConfiguration();
          conf.setProtocol(QSsl::AnyProtocol);
          req.setSslConfiguration(conf);
      
          QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
          qDebug() << req.url();
          return reply;
      }
      

      And thus the ignoreSSLErrors slot was called where the errors were ignored. This worked for me. Let me know if it works for you.

      157

      1 Reply Last reply
      0

      2/2

      19 Mar 2015, 11:33

      • Login

      • Login or register to search.
      2 out of 2
      • First post
        2/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved