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. Certificate issue

Certificate issue

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 3.3k 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.
  • L Offline
    L Offline
    LuGRU
    wrote on last edited by
    #1

    Hello,
    I do have a strange issue. I do connect to server that require client certificate to verify client. And what's strange is that it do work fine on Windows but on OsX I do get error:

     Error occured QNetworkReply::NetworkError(UnknownNetworkError) "SSLRead failed: -9842"
    

    I thought that this may be issue with OpenSSL version on OsX so I did updated from 0.9.8zh to 1.0.2g but exactly same error occur.
    On Windows I do use: 1.0.2d.

    Client certificates are given to me, so I don't know if they are actually valid. Testes access url on web browsers (Safari / Firefox) both on Windows and OsX resulted in handshake failure and on Safari, after importing client cert to keychain, they did not showed up on list). Honestly I do suspect that they are not valid with is even more puzzling that OpenSSL on win will allow connection.

    1 Reply Last reply
    0
    • Paul ColbyP Offline
      Paul ColbyP Offline
      Paul Colby
      wrote on last edited by
      #2

      Hi @LuGRU

      SSL libraries can be a real pain to debug - often because the won't report any meaning error codes (most codes translate to little more then "read failed").

      Anyway, if I understand you correctly, then a third-party has supplied you with an SSL client certificate, and now you're trying to use that client certificate to connect to that third-party's server using Qt? And this is working fine on one Windows machine, but not on an OSX machine?

      I suspect you'll find that its the server's certificate that OSX has an issue with, rather than the client certificate. Put another way, the clients (both Window and OSX) will use the client certificate (and key) quite happily without any concept of trust, however, whether or not the clients trust the server's certificate will depend on many host-specific things, such as the client's list of trusted root CAs, and the completeness of the server's certificate chain.

      Anyway, if I were you, I'd start with OpenSSL's s_client command to test if this is something host-specific, or application specific.

      Something like:

      openssl -connect example.com:443 -cert clientcert.pem
      

      If that fails, you should at least be able to see why (you can add a -debug too if that helps). Once you get that working, then, then we can figure out if there's something else prevent your app from handshaking.

      Good luck :)

      1 Reply Last reply
      0
      • L Offline
        L Offline
        LuGRU
        wrote on last edited by
        #3

        Thank You @Paul

        Issue seams to be related to DNS.

        openssl s_client -connect example.host.com/end/point -cert $cert -key $key -state -nbio 
        

        results in

        gethostbyname failure
        connect:errno=0
        

        so switching to IP, i.e.

        openssl s_client -connect 123.456.789.099/end/point -cert $cert -key $key -state -nbio 
        

        correctly connect to peer and I do get 400 as end point accepts only POST request - response is in HTML with is readable so all fine.

        End point problem, full URI is like example.host.com/snd/point. When connecting to example.host.com via connectToHostEncrypted() in both QNetworkAccessmanager and QSslSocket connection is made and with setPeerVerifyMode( QSslSocket::VerifyNone) I can connect (MiTM enabled, I know, but those certificates are self signed). But when connecting to example.host.com/end/point same error occur

        "SSLRead failed: -9842"
        

        Any idea why this happens?

        Paul ColbyP 1 Reply Last reply
        0
        • L LuGRU

          Thank You @Paul

          Issue seams to be related to DNS.

          openssl s_client -connect example.host.com/end/point -cert $cert -key $key -state -nbio 
          

          results in

          gethostbyname failure
          connect:errno=0
          

          so switching to IP, i.e.

          openssl s_client -connect 123.456.789.099/end/point -cert $cert -key $key -state -nbio 
          

          correctly connect to peer and I do get 400 as end point accepts only POST request - response is in HTML with is readable so all fine.

          End point problem, full URI is like example.host.com/snd/point. When connecting to example.host.com via connectToHostEncrypted() in both QNetworkAccessmanager and QSslSocket connection is made and with setPeerVerifyMode( QSslSocket::VerifyNone) I can connect (MiTM enabled, I know, but those certificates are self signed). But when connecting to example.host.com/end/point same error occur

          "SSLRead failed: -9842"
          

          Any idea why this happens?

          Paul ColbyP Offline
          Paul ColbyP Offline
          Paul Colby
          wrote on last edited by
          #4

          openssl s_client -connect example.host.com/end/point -cert $cert -key $key -state -nbio
          results in gethostbyname failure

          That's because the -connect argument takes a hostname and port. You've provided a hostname with trailing URL path (ie the '/end/point'). So, openssl is trying to resolve the "example.host.com/end/point" hostname. You need to drop the "/end/point", and add a port.

          For example:

          openssl s_client -connect www.google.com/index # Not okay.
          openssl s_client -connect www.google.com/index:443 # Not okay.
          openssl s_client -connect www.google.com:443 # Okay :)
          

          so switching to IP, i.e.
          openssl s_client -connect 123.456.789.099/end/point -cert $cert -key $key -state -nbio

          That still shouldn't work because of the invalid -connect format (what version of openssl are you using?).

          But regardless, the issue with IP addresses here, is that s_client won't attempt to verify the host's "subject" (ie the hostname).

          For example, for one of www.google.com's IP addresses:

          openssl s_client -connect 198.142.186.222:443 # Works, certificate is not fully verified though.
          openssl s_client -connect 198.142.186.222:443 -verify_hostname example.com # Fails as expected.
          

          So what output do you get when run:

          openssl s_client -connect example.host.com:443 -cert $cert -key $key -state -nbio
          

          If you can't show the whole output (understandable), what about just:

          openssl s_client -connect example.host.com:443 -cert $cert -key $key -state -nbio | grep Verify
          

          Finally, I'm curious about how you got a 400 error via openssl? Did you manually type (or cat) something like "GET / HTTP/1.0\n\n"? Or was you're openssl doing a whole lot more than mine does? (Just trying to make sure we're talking about the same things).

          Cheers.

          1 Reply Last reply
          1
          • L Offline
            L Offline
            LuGRU
            wrote on last edited by
            #5

            Thank You for info.
            I tried more test today, and indeed I forgot about port in post (with I used in script) in connect statement.
            Also I thought example.host.com/end/point:port is valid syntax.

            Anyways, here is output for:
            openssl s_client -connect example.host.com:443 -cert $cert -key $key -state -nbio

            CONNECTED(00000003)
            turning on non blocking io
            write R BLOCK
            read R BLOCK
            read R BLOCK
            read R BLOCK
            read R BLOCK
            ---
            Certificate chain
             0 s:/1.3.6.1.4.1.311.60.2.1.3=xx/businessCategory=Private Organization/O=xxxxx xx/serialNumber=xxxxxxxxx/C=xx/ST=xxxxx/L=xxxx/OU=IT/CN=aaaaaa
               i:/C=US/O=thawte, Inc./CN=thawte EV SSL CA - G3
             1 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
               i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
             2 s:/C=US/O=thawte, Inc./CN=thawte EV SSL CA - G3
               i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
            ---
            Server certificate
            -----BEGIN CERTIFICATE-----
            xxxxxxxxxxxxxxxxxxxxxxxxxxxx
            -----END CERTIFICATE-----
            subject=/xxxxxxxxxxxxxxxxxx=xxxx/businessCategory=Private Organization/O=xxxxxxxxxxxxx /serialNumber=xxxxxxx/C=xxxx/ST=xxxx/L=xxxxx/OU=IT/CN=aaaaaa
            issuer=/C=US/O=thawte, Inc./CN=thawte EV SSL CA - G3
            ---
            No client certificate CA names sent
            ---
            SSL handshake has read 4643 bytes and written 328 bytes
            ---
            New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
            Server public key is 2048 bit
            Secure Renegotiation IS supported
            Compression: NONE
            Expansion: NONE
            SSL-Session:
                Protocol  : TLSv1
                Cipher    : DHE-RSA-AES256-SHA
                Session-ID: 530..............
                Session-ID-ctx: 
                Master-Key: F12..........
                Key-Arg   : None
                Start Time: 1..............
                Timeout   : 300 (sec)
                Verify return code: 0 (ok)
            ---
            <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
            <html><head>
            <title>400 Bad Request</title>
            </head><body>
            <h1>Bad Request</h1>
            <p>Your browser sent a request that this server could not understand.<br />
            045</p>
            </body></html>
            closed
            

            On OsX OpenSSL 0.9.8zh (14 Jan 2016).
            When running openssl I do see "Turning on non blocking io" and after server OK I can write so I just type some random keys + hit enter and I do get 400 from web server.

            Now strange part is that I'm able to connect from Qt to example.host.com, i.e. (example code - based on actual impl. simplified, showing methods invoked):

                QSslConfiguration sslConfiguration;
                sslConfiguration.setDefaultConfiguration(QSslConfiguration::defaultConfiguration());
                sslConfiguration.setLocalCertificate( QSslCertificate());
                sslConfiguration.setPrivateKey( QSslKey());
                // dont verify peer
                sslConfiguration.setPeerVerifyMode( QSslSocket::VerifyNone);
            
                QNetworkRequest req;
                req.setUrl( QUrl()); 
                req->setSslConfiguration(sslConfiguration);
                //...
                QNetworkAccessManager->post( req, postData);
            

            And if QSslSocket::VerifyNone is set socket enters encrypted state (with QSslSocket::VerifyPeer fails as expected, both certificates are self signed so SNI will not work correctly?). Now this is not end point that POST data should go, so connecting to example.host.com/end/point is required and with that set to QUrl() in QRequest error is returned:

            "SSLRead failed: -9842"
            
            1 Reply Last reply
            0
            • T Offline
              T Offline
              Timur Pocheptsov
              wrote on last edited by
              #6

              Well, it's a bit late to reply but anyway ... The TLS back-end in question is SecureTransport, not OpenSSL. Previously we did not have the logic needed to handle a renegotiation. So SSLRead was not expected to return errSSLClientCertRequested (-9842). This sneaky (but reasonable after all) behavior is not documented and the fact that SSLRead is doing handshake also is anything, but obvious. This was fixed recently in Qt - now we can detect that SSLRead finds HelloRequest and can handle the following renegotiation properly.

              1 Reply Last reply
              2

              • Login

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