Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

POST request over HTTPS



  • Hi,

    I want to send a post request to an HTTPS server wich expects a client certificate.
    I have the client and the CA certificates but I dont know how to properly use them.
    I use QNetworkAcessManager and QSslConfiguration to do it.

    my code looks like :

    @
    QFile sslCertificateFile("ssl/cert.pem");
    QFile sslKeyFile("ssl/pkey.key");
    QSslCertificate sslCertificate;
    QSslConfiguration sslConfiguration;

    if ((sslCertificateFile.open(QIODevice::ReadOnly)) && (sslKeyFile.open(QIODevice::ReadOnly))) {

        //Read certificates from file
        QList<QSslCertificate> sslCertificateList = QSslCertificate::fromData(sslCertificateFile.readAll(), QSsl::Pem);
    
        sslCertificate = sslCertificateList.takeAt(0);
    
        //Read key from file
        QSslKey privateKey(&sslKeyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey , "mdp");
    
        sslConfiguration.QSslConfiguration::defaultConfiguration();
        sslConfiguration.setProtocol(QSsl::TlsV1_0);
        sslConfiguration.setLocalCertificate(sslCertificate);
        sslConfiguration.setPrivateKey(privateKey);
    
    
    } else {
        QMessageBox::information(this, tr("HTTPS"), tr("Cannot open ssl files !"));
    }
    
    //network
    QUrl url("https://url_example/prog");
    QNetworkRequest request(url);
    request.setRawHeader("Content-Type", "application/octet-stream");
    request.setSslConfiguration(sslConfiguration);
    
    QNetworkAccessManager *networkManager = new QNetworkAccessManager();
    QNetworkReply *reply = networkManager->post(request,post_data);
    
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
    connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreSslErrors(QList<QSslError>)));
    
    sslCertificateFile.close();
    sslKeyFile.close();
    

    @

    I like to do something equivalent to :

    @
    curl https://url_example/prog --cert ssl/cert.pem --key ssl/pkey.key --cacert ssl/CA.pem --data-binary @post_data.bin -H "Content-type: application/octet-stream"
    @

    Thank you.


  • Moderators

    maybe you can be more specific before we start guessing what isn't working...



  • In the code above, I dont use the CA certificate because I dont know how to use it properly. So my first question is how to properly use certificates, client and CA.

    I have a "SSL handshake failed" message.


  • Moderators

    [quote author="zentaf" date="1388674092"]In the code above, I dont use the CA certificate because I dont know how to use it properly. So my first question is how to properly use certificates, client and CA.
    [/quote]

    you set the certificate to the ssl configuration and the configuration to the request... so far so good

    [quote author="zentaf" date="1388674092"]
    I have a "SSL handshake failed" message.
    [/quote]

    Maybe it already solves your problem when you set the protocol of your ssl config:
    @
    sslConfiguration.setProtocol(QSsl::TlsV1_0);
    @

    Which Qt version are you using?



  • [quote] you set the certificate to the ssl configuration and the configuration to the request... so far so good[/quote]

    But what I am using here is the client certificate. Do I use the CA certificate in the same way? using QSslConfiguration::setLocalCertificate()?

    [quote]Which Qt version are you using?[/quote]
    I am using Qt 5.1.1.



  • I modify my code by adding :

    QFile caCertificateFile("ssl/CA.pem");
    QList<QSslCertificate> caCertificateList = QSslCertificate::fromData(caCertificateFile.readAll(), QSsl::Pem);
    
    sslConfiguration.setCaCertificates(caCertificateList);
    

    I still have the error message : SSL handshake failed in requestFinished SLOT, and the error message : The host name did not match any of the valid hosts for this certificate in the ignoreSslErrors SLOT, (because the certificate CN is not the same as the server URL).

    After this, I add :

    QSslError error(QSslError::HostNameMismatch);
    QList<QSslError> expectedSslErrors;
    expectedSslErrors.append(error);
    reply->ignoreSslErrors(expectedSslErrors);
    

    But I still have the two error messages above.



  • Why I have not any response to fix my problem !!!



  • The reason can be found in this thread. Basically, You need to check your certificate's details (can be accessed through browser) and see whether they fit your system. The Common Name (CN) is the variable you want to check.

    Secondly, you can ignore the error, if you don't care the certificate's problem.

     _netManager =  new QNetworkAccessManager;
    connect(_netManager,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),this,SLOT(onSslError(QNetworkReply*,QList<QSslError>)));
    connect(_netManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onNetworkReply(QNetworkReply*)));
    

    In onSslError(QNetworkReply*,QList<QSslError>)) make sure to reply->ignoreSslErrors(expectedSslErrors); and the content of the network reply will appear in the onNetworkReply(QNetworkReply*)

    Cheers


Log in to reply