Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QT 5.15 QSSLCertificate::importpkcs12 returns false, how do I debug the reason?

QT 5.15 QSSLCertificate::importpkcs12 returns false, how do I debug the reason?

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 4 Posters 448 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.
  • D Offline
    D Offline
    Dadde
    wrote on 4 Apr 2025, 08:23 last edited by Dadde 4 Jul 2025, 08:51
    #1

    Hello, I'm trying to create an oauth2 authentication with certification flow.

    I have the following code:

        // Load client certificate and key from PFX file
        QFile pfxFile(certPath);
        bool is_Open = pfxFile.open(QFile::ReadOnly);
        Q_ASSERT(is_Open);
    
        QSslKey key;
        QSslCertificate certificate;
        QList<QSslCertificate> caCertificates;
    
        QString version = QSslSocket::sslLibraryBuildVersionString();
        qInfo() << version; // Prints "OpenSSL 1.1.1g  21 Apr 2020"
        
        if (QSslCertificate::importPkcs12(&pfxFile, &key, &certificate, &caCertificates, certPassword)) {
            qDebug() << "Loaded PFX file";
        }
        else {
            qDebug() << "Failed to load PFX file";
            return;
        }
    

    certPath is just my file name, "mycert.pfx". In debug I check the content of pfxFile once opened and it seems correct to me, so the proper file is opened.

    certPassword seems correct as well.

    Yet the function returns false and I have no idea what I can do to know what exactly went wrong? I have a python program that runs the same process which works with these inputs, so something is somehow different...

    Is there a way to know what exactly went wrong in this process when running the importpkcs12 function?

    Help is appreciated!

    J 1 Reply Last reply 4 Apr 2025, 09:07
    0
    • D Dadde
      4 Apr 2025, 08:23

      Hello, I'm trying to create an oauth2 authentication with certification flow.

      I have the following code:

          // Load client certificate and key from PFX file
          QFile pfxFile(certPath);
          bool is_Open = pfxFile.open(QFile::ReadOnly);
          Q_ASSERT(is_Open);
      
          QSslKey key;
          QSslCertificate certificate;
          QList<QSslCertificate> caCertificates;
      
          QString version = QSslSocket::sslLibraryBuildVersionString();
          qInfo() << version; // Prints "OpenSSL 1.1.1g  21 Apr 2020"
          
          if (QSslCertificate::importPkcs12(&pfxFile, &key, &certificate, &caCertificates, certPassword)) {
              qDebug() << "Loaded PFX file";
          }
          else {
              qDebug() << "Failed to load PFX file";
              return;
          }
      

      certPath is just my file name, "mycert.pfx". In debug I check the content of pfxFile once opened and it seems correct to me, so the proper file is opened.

      certPassword seems correct as well.

      Yet the function returns false and I have no idea what I can do to know what exactly went wrong? I have a python program that runs the same process which works with these inputs, so something is somehow different...

      Is there a way to know what exactly went wrong in this process when running the importpkcs12 function?

      Help is appreciated!

      J Offline
      J Offline
      JonB
      wrote on 4 Apr 2025, 09:07 last edited by
      #2

      @Dadde
      Well the first thing to verify is is_Open, we do not know whether your path is correct. We don't know where relative path "mycert.pfx"resolves to in your application. At least put in, say, a Q_ASSERT(is_Open) so people know for sure.

      D 1 Reply Last reply 4 Apr 2025, 09:26
      1
      • J JonB
        4 Apr 2025, 09:07

        @Dadde
        Well the first thing to verify is is_Open, we do not know whether your path is correct. We don't know where relative path "mycert.pfx"resolves to in your application. At least put in, say, a Q_ASSERT(is_Open) so people know for sure.

        D Offline
        D Offline
        Dadde
        wrote on 4 Apr 2025, 09:26 last edited by
        #3

        @JonB I updated my post with the assert, it passes so the file is opened.

        D 1 Reply Last reply 4 Apr 2025, 14:25
        1
        • D Dadde
          4 Apr 2025, 09:26

          @JonB I updated my post with the assert, it passes so the file is opened.

          D Offline
          D Offline
          Dadde
          wrote on 4 Apr 2025, 14:25 last edited by
          #4

          @Dadde I still have the issue though that importPkcs12 function fails. Is there any way to know exactly what part of the function is failing? Is it because I pass pfxFile as a QFile when the input parameter is actually QIODevice, even though QFile is inheriting QIODevice and therefore seems to compile?

          Or is the password of the wrong type? Here's how I declare it in the related header:

          QByteArray certPassword = "mypassword";

          J 1 Reply Last reply 4 Apr 2025, 15:26
          0
          • D Dadde
            4 Apr 2025, 14:25

            @Dadde I still have the issue though that importPkcs12 function fails. Is there any way to know exactly what part of the function is failing? Is it because I pass pfxFile as a QFile when the input parameter is actually QIODevice, even though QFile is inheriting QIODevice and therefore seems to compile?

            Or is the password of the wrong type? Here's how I declare it in the related header:

            QByteArray certPassword = "mypassword";

            J Offline
            J Offline
            JonB
            wrote on 4 Apr 2025, 15:26 last edited by
            #5

            @Dadde said in QT 5.15 QSSLCertificate::importpkcs12 returns false, how do I debug the reason?:

            Is it because I pass pfxFile as a QFile when the input parameter is actually QIODevice, even though QFile is inheriting QIODevice and therefore seems to compile?

            No, that is fine.
            I do not have an answer to how you discover exactly what is wrong.

            1 Reply Last reply
            1
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 4 Apr 2025, 18:56 last edited by SGaist 4 Apr 2025, 18:57
              #6

              Hi,

              Which version of Qt are you using ?
              On which platform ?
              Would it be possible for you to share how one can generate such a certificate to test ?
              The Python code you are using as well so people can double check in conditions similar as yours.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              D 1 Reply Last reply 5 Apr 2025, 06:23
              1
              • C Offline
                C Offline
                ChrisW67
                wrote on 5 Apr 2025, 04:51 last edited by
                #7

                Have you installed the relevant OpenSSL libraries into the runtime path of your executable?
                Have you provided the correct password for the input file?

                D 1 Reply Last reply 5 Apr 2025, 06:31
                1
                • S SGaist
                  4 Apr 2025, 18:56

                  Hi,

                  Which version of Qt are you using ?
                  On which platform ?
                  Would it be possible for you to share how one can generate such a certificate to test ?
                  The Python code you are using as well so people can double check in conditions similar as yours.

                  D Offline
                  D Offline
                  Dadde
                  wrote on 5 Apr 2025, 06:23 last edited by Dadde 9 days ago
                  #8

                  @SGaist I'm using QT version 5.15.2, visual studio

                  I don't know myself how to create the certificate since I'm new to these topics but I will see what I can accomplish after the weekend.

                  I think I can provide the python code though:

                  import base64
                  import requests
                  import jwt
                  import hashlib
                  import uuid
                  from datetime import datetime, timedelta
                  from cryptography.hazmat.backends import default_backend
                  from cryptography.hazmat.primitives import hashes, serialization
                  from cryptography.hazmat.primitives.serialization import pkcs12
                   
                  token_endpoint = 'https://xxx.yyy/zzz/oauth2/token'
                   
                  # ADFS endpoint URL
                  authority = 'https://xxx.yyy/zzz'
                   
                  # PFX certificate file path and password
                  cert_file = 'C:/xxx/yyy/zzz.pfx'
                  cert_password = 'password'
                   
                  # Client ID and Secret for your registered application on ADFS
                  client_id = 'xxx-yyy-zzz-vvv-www'
                   
                  # Define the scope of the access token
                  scope = ['https://xxx.yyy.zzz.vvv']
                   
                  # Load the PFX certificate
                  with open(cert_file, 'rb') as f:
                      pfx_data = f.read()
                   
                  # Load the PFX data and extract the private key
                  private_key, cert, ca_certs = pkcs12.load_key_and_certificates(pfx_data, cert_password.encode(), default_backend())
                   
                  def hex_string_readable(bytes):
                          return ["{:02X}".format(x) for x in bytes]
                  fingerprint = hex_string_readable(cert.fingerprint(hashes.SHA1()))
                  print(",".join(str(element) for element in fingerprint))
                   
                  # Serialize the private key to PEM format
                  private_key_pem = private_key.private_bytes(
                      encoding=serialization.Encoding.PEM,
                      format=serialization.PrivateFormat.TraditionalOpenSSL,
                      encryption_algorithm=serialization.NoEncryption()
                  )
                  # Convert bytes to string
                  private_key_pem_str = private_key_pem.decode()
                   
                  print(private_key_pem_str)
                   
                  # Create a client assertion
                  now = datetime.utcnow()
                  expiry = now + timedelta(minutes=10)  # Set expiry time for 10 minutes from now
                   
                  kid = "".join(str(element) for element in fingerprint)
                   
                  cert_sha1 = hashlib.sha1()
                  cert_sha1.update(cert.public_bytes(serialization.Encoding.DER))
                   
                  # Convert the SHA-1 hash to base64
                  x5t = base64.urlsafe_b64encode(cert_sha1.digest()).rstrip(b'=').decode()
                   
                  claims = {
                      "aud": token_endpoint,
                      "iss": client_id,
                      "sub": client_id,
                      "jti": str(uuid.uuid4()),
                      "exp": expiry,
                  }
                   
                  header = {
                      "kid": kid,
                      "x5t": x5t
                  }
                  # Encode and sign the JWT using the private key
                  client_assertion_bytes = jwt.encode(claims, private_key_pem_str, algorithm='RS256', headers=header)
                   
                  # Prepare data for token request
                  token_request_data = {
                      'grant_type': 'client_credentials',
                      'client_id': client_id,
                      'scope': scope,
                      'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
                      'client_assertion': client_assertion_bytes,
                  }
                   
                  # Send token request to ADFS token endpoint
                  response = requests.post(token_endpoint, data=token_request_data)
                   
                  # Check if the token request was successful
                  if response.status_code == 200:
                      # Print the access token
                      access_token = response.json()['access_token']
                      print("Access token:", access_token)
                  else:
                      print("Failed to acquire token:", response.text)
                   
                  url = "https://xxx.yyy.zzz.vvv/v2/data.xml"
                   
                  payload = "Change to your request"
                  headers = {
                    'Content-Type': 'application/xml',
                    'Authorization': 'Bearer '+access_token
                  }
                   
                  response = requests.request("POST", url, headers=headers, data=payload)
                   
                  print(response.text)
                  
                  1 Reply Last reply
                  0
                  • C ChrisW67
                    5 Apr 2025, 04:51

                    Have you installed the relevant OpenSSL libraries into the runtime path of your executable?
                    Have you provided the correct password for the input file?

                    D Offline
                    D Offline
                    Dadde
                    wrote on 5 Apr 2025, 06:31 last edited by Dadde 9 days ago
                    #9

                    @ChrisW67 My hope was that the QT framework has the tools I need to accomplish oauth2 communication(with certification) and it seems that it does, at least for this step with creating the pkcs12 file? Will I still need OpenSsl?

                    D 1 Reply Last reply 5 Apr 2025, 08:48
                    0
                    • D Dadde
                      5 Apr 2025, 06:31

                      @ChrisW67 My hope was that the QT framework has the tools I need to accomplish oauth2 communication(with certification) and it seems that it does, at least for this step with creating the pkcs12 file? Will I still need OpenSsl?

                      D Offline
                      D Offline
                      Dadde
                      wrote on 5 Apr 2025, 08:48 last edited by
                      #10

                      @Dadde I did some reading and I think I already have openssl configured since I previously included QtNetwork which should contain these tools: https://doc.qt.io/qt-5/ssl.html

                      J 1 Reply Last reply 5 Apr 2025, 10:11
                      0
                      • D Dadde
                        5 Apr 2025, 08:48

                        @Dadde I did some reading and I think I already have openssl configured since I previously included QtNetwork which should contain these tools: https://doc.qt.io/qt-5/ssl.html

                        J Offline
                        J Offline
                        JonB
                        wrote on 5 Apr 2025, 10:11 last edited by JonB 9 days ago
                        #11

                        @Dadde
                        I do not use SSL nor build Qt from source, so I could easily be incorrect here. But I think you have to do something/check that you do have OpenSSL installed and found from Qt app.

                        I think they come with OS or Qt binary installer or you download or build them yourself. @ChrisW67 asked you above

                        Have you installed the relevant OpenSSL libraries into the runtime path of your executable?

                        What OpenSSL libraries do you have where on what platform, and how is your program run such that it will locate and load them?

                        D 1 Reply Last reply 7 Apr 2025, 08:45
                        1
                        • J JonB
                          5 Apr 2025, 10:11

                          @Dadde
                          I do not use SSL nor build Qt from source, so I could easily be incorrect here. But I think you have to do something/check that you do have OpenSSL installed and found from Qt app.

                          I think they come with OS or Qt binary installer or you download or build them yourself. @ChrisW67 asked you above

                          Have you installed the relevant OpenSSL libraries into the runtime path of your executable?

                          What OpenSSL libraries do you have where on what platform, and how is your program run such that it will locate and load them?

                          D Offline
                          D Offline
                          Dadde
                          wrote on 7 Apr 2025, 08:45 last edited by Dadde 4 Jul 2025, 10:15
                          #12

                          @JonB @ChrisW67 I haven't "explicitly" installed openssl, so I'm not 100% sure myself, but there is a QSslSocket::sllLibraryBuildVersionString() function that tells the openssl version found and used. I think it is fairly safe to say it is what is used for the QSslCertificate() function as well since it is part of the QTNetwork module which I have installed. I think it is the closest I can get to know if openssl is used?

                          Here's what the function says when I run it in my program: "OpenSSL 1.1.1g 21 Apr 2020".

                          I will update the code in the main post.

                          D 1 Reply Last reply 7 Apr 2025, 10:25
                          0
                          • D Dadde
                            7 Apr 2025, 08:45

                            @JonB @ChrisW67 I haven't "explicitly" installed openssl, so I'm not 100% sure myself, but there is a QSslSocket::sllLibraryBuildVersionString() function that tells the openssl version found and used. I think it is fairly safe to say it is what is used for the QSslCertificate() function as well since it is part of the QTNetwork module which I have installed. I think it is the closest I can get to know if openssl is used?

                            Here's what the function says when I run it in my program: "OpenSSL 1.1.1g 21 Apr 2020".

                            I will update the code in the main post.

                            D Offline
                            D Offline
                            Dadde
                            wrote on 7 Apr 2025, 10:25 last edited by
                            #13

                            @Dadde Update: I added "Q_ASSERT(QSslSocket::supportsSsl());" and it returns false, so I guess I haven't actually properly implemented openssl then, also previous function "QSslSocket::sllLibraryBuildVersionString()" only checks what version it finds during compile time, "QSslSocket::sslLibraryVersionNumber();" is for runtime and it returns "0". I will look into implementing openssl properly and update if it solved my issue.

                            1 Reply Last reply
                            0
                            • C Offline
                              C Offline
                              ChrisW67
                              wrote on 8 Apr 2025, 00:14 last edited by
                              #14

                              QSslSocket::sllLibraryBuildVersionString() "Returns the version string of the SSL library in use at compile time. " That is, the version of the OpenSSL libraries that the Qt binaries you are using were built to match. This does not mean those libraries are present in your runtime environment: they are detected and used if present.

                              So, your runtime environment needs to have OpenSSL 1.1.1 libraries. You may be able to access a compatible version through the Qt Online Installer. Ensuring it is in the run time environment (application binary directory or PATH on Windows, LD_LIBRARY_PATH on Linux etc.) is largely up to you.

                              1 Reply Last reply
                              1

                              8/14

                              5 Apr 2025, 06:23

                              • Login

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