omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    SSL: CERTIFICATE_VERIFY_FAILED during handshake

    Pythonista
    5
    8
    4326
    Loading More Posts
    • 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.
    • samaklis
      samaklis last edited by

      I have a very simple snippet of code which makes a connection to my server running MQTT and subscribes to a topic. This is a simplified example of a bigger application. The code was working fine until today on both my iPhone and iPad.

      All of the sudden I am getting an error in the Framework/pylib/ssl.py in do_handshake saying: SSL: CERTIFICATE_VERIFY_FAILED

      If i take the same piece of code and run it from Windows, or Mac it works fine so to me that eliminates anything being wrong with the server.

      Pythonista has not had any updates so I am at a loss as to why I am having this issue all of the sudden and especially on the Pythonista side only.

      Any help would be appreciated

      import paho.mqtt.client as mqtt
      
      # The callback for when the client receives a CONNACK response from the server.
      def on_connect(client, userdata, flags, rc):
          print("Connected with result code "+str(rc))
      
          # Subscribing in on_connect() means that if we lose the connection and
          # reconnect then subscriptions will be renewed.
          client.subscribe("weather/#")
      
      # The callback for when a PUBLISH message is received from the server.
      def on_message(client, userdata, msg):
          print(msg.topic+" "+str(msg.payload))
      
      client = mqtt.Client(transport="websockets")
      client.tls_set()
      client.on_connect = on_connect
      client.on_message = on_message
      
      client.connect("myHostName", 9001, 60)
      
      client.loop_forever()
      
      1 Reply Last reply Reply Quote 0
      • mcriley821
        mcriley821 last edited by

        If it worked fine before, it’s probably that your server has put your phone/script/whatever on a Do Not Trust list after repetitive problems.

        This has some good info on identifying problems with specifically Python-based client-server setups:
        https://access.redhat.com/articles/2039753

        1 Reply Last reply Reply Quote 0
        • samaklis
          samaklis last edited by

          Turns out that the service publishing to MQTT had some errors, and also Pythonista somehow was caching the handshake. After restarting both the error cleared out.

          Thanks for the reply.

          1 Reply Last reply Reply Quote 1
          • samaklis
            samaklis last edited by samaklis

            Unfortunately, this issue is back again. I came to realize that there must be something related to iOS 13.5 vs 13.4.* that breaks the SSL for Pythonista. It has nothing to do with a do not trust list or configuration on the server side. Every other client can connect fine.

            I noticed that the ssl.py in Pythonista is from 2016. At this point I cannot open a secure websocket connection on my iOS devices where every other client, Windows, Mac, run the below code fine. In addition browsers have no issues connecting to the server as well.

            This leaves me to believe that there must be some connection to the iOS update and the SSL version in Pythonista that breaks the ability to talk via secure websocets on iOS.

            I am on Pythonista version 3.3 (330025) default interpreter 3.6.1
            iOS 13.5.1

            I have also submitted a bug: https://github.com/omz/Pythonista-Issues/issues/652

            import ssl
            import socket
            
            
            host = 'my_host'
            
            context = ssl.create_default_context()
            
            with socket.create_connection((host, 9001)) as sock:
                with context.wrap_socket(sock, server_hostname=host) as ssock:
                    print(ssock.version())
            

            I have tested the issue by installing a local version of openssl: OpenSSL 1.0.2f 28 Jan 2016 which is the same that Pythonista comes with and when I issue the command openssl s_client connect host:port I get the below (look at error in return code)

            No client certificate CA names sent
            Peer signing digest: SHA512
            Server Temp Key: ECDH, P-256, 256 bits
            ---
            SSL handshake has read 5357 bytes and written 443 bytes
            ---
            New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
            Server public key is 2048 bit
            Secure Renegotiation IS supported
            Compression: NONE
            Expansion: NONE
            No ALPN negotiated
            SSL-Session:
                Protocol  : TLSv1.2
                Cipher    : ECDHE-RSA-AES256-GCM-SHA384
                Session-ID: 3B19973E06CB84FCBB96178FA11FE78A13AC697854FBBD51A895B39B65829C4E
                Session-ID-ctx:
                Master-Key: DDBE9EAFC7FC20E6956EB694FCF1621B495E24EAB134D5EB44BB4A22134138B638047F571DB113CCA3D86DC1C9196D8B
                Key-Arg   : None
                PSK identity: None
                PSK identity hint: None
                SRP username: None
                TLS session ticket lifetime hint: 7200 (seconds)
                TLS session ticket:
                0000 - 04 f6 10 db 51 72 36 ff-01 ef 3a a0 16 c8 62 02   ....Qr6...:...b.
                0010 - b1 98 95 76 50 76 e4 12-af 28 d8 4c d1 26 75 2f   ...vPv...(.L.&u/
                0020 - 7a de ed e0 0b d7 0a 9f-b1 c9 6c af f3 4a 4c 1d   z.........l..JL.
                0030 - 41 7a 23 37 73 8b 21 90-2c a6 23 f7 11 30 28 8b   Az#7s.!.,.#..0(.
                0040 - 9f fc 1f d2 f9 07 f8 e5-5d a6 00 02 9d 9f ad f1   ........].......
                0050 - e1 a6 c9 48 3a 17 25 95-98 ae 16 f5 38 e0 a0 f8   ...H:.%.....8...
                0060 - ce f1 51 59 31 57 fa 30-49 39 f1 55 b9 e7 48 b7   ..QY1W.0I9.U..H.
                0070 - ae 12 a3 fb 6c 76 52 23-d5 53 08 0b 59 01 77 b2   ....lvR#.S..Y.w.
                0080 - 31 0e 3a b5 10 b7 6b a4-b6 1f 2b b5 73 af b9 c7   1.:...k...+.s...
                0090 - 7f 56 85 15 07 33 c4 4c-d9 11 00 7b 2d b1 b3 26   .V...3.L...{-..&
            
                Start Time: 1591927357
                Timeout   : 300 (sec)
                Verify return code: 20 (unable to get local issuer certificate)
            

            When I run the same command with version: OpenSSL 1.1.1f 31 Mar 2020 I get no errors (look at return code=0):

            No client certificate CA names sent
            Peer signing digest: SHA512
            Peer signature type: RSA
            Server Temp Key: ECDH, P-256, 256 bits
            ---
            SSL handshake has read 5381 bytes and written 434 bytes
            Verification: OK
            ---
            New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
            Server public key is 2048 bit
            Secure Renegotiation IS supported
            Compression: NONE
            Expansion: NONE
            No ALPN negotiated
            SSL-Session:
                Protocol  : TLSv1.2
                Cipher    : ECDHE-RSA-AES256-GCM-SHA384
                Session-ID: 2D876927EB37E715EACF58C6AEA2EDA5EC8EE3D4067D089C2CAE256345B83A8C
                Session-ID-ctx:
                Master-Key: 2AF552551C08BF01A0B8F166510E83BFDF03439A67698DA68502BC9B84891DD099C04545B73CD2D9EC729CF47D533AF5
                PSK identity: None
                PSK identity hint: None
                SRP username: None
                TLS session ticket lifetime hint: 7200 (seconds)
                TLS session ticket:
                0000 - 04 f6 10 db 51 72 36 ff-01 ef 3a a0 16 c8 62 02   ....Qr6...:...b.
                0010 - 15 49 44 26 0e 71 18 58-54 27 28 0c 8b bb ce 38   .ID&.q.XT'(....8
                0020 - 5c b2 f8 33 13 f8 3a 14-ee 23 c8 c5 40 fe 80 c0   \..3..:..#..@...
                0030 - 05 ea f5 5e 94 4b bb 33-54 ab 46 f1 0c e8 b0 b7   ...^.K.3T.F.....
                0040 - 52 e3 51 e1 20 d6 9f 58-c6 40 5f 11 58 e1 dd de   R.Q. ..X.@_.X...
                0050 - db 05 3c 69 74 38 3b 6e-3f 93 21 bb 1d 4e 48 4a   ..<it8;n?.!..NHJ
                0060 - cf 19 f1 fd ec ac 0b e3-93 b4 4e 12 d1 03 61 9a   ..........N...a.
                0070 - 24 d6 c8 13 19 ba cd 9c-5a 1d 0c da ab e3 c5 b2   $.......Z.......
                0080 - 2d 79 f2 91 31 29 08 32-c7 1b c5 ef 89 bf fb db   -y..1).2........
                0090 - e4 66 2b a8 bb e3 23 76-ac a1 83 bb 4a 5f 4b 6c   .f+...#v....J_Kl
                00a0 - 6d 36 e2 71 ac 68 23 4b-de 6f 5c d7 b1 8c d1 5c   m6.q.h#K.o\....\
            
                Start Time: 1591927401
                Timeout   : 7200 (sec)
                Verify return code: 0 (ok)
                Extended master secret: yes
            

            I think this proves that the included openssl that comes with Pythonista (which ssl.py sources) needs to be upgraded to a later version

            1 Reply Last reply Reply Quote 0
            • JonB
              JonB last edited by

              I wonder if the cert authority that certified your server is trusted by your iOS version.

              See
              https://support.apple.com/en-us/HT210770

              You may be able to install the server cert directly onto your device to trust it implicitly.

              Have you looked at the change logs between those two openssl versions? Might give a hint as to what is wrong.

              1 Reply Last reply Reply Quote 0
              • samaklis
                samaklis last edited by samaklis

                Thanks for the feedback.

                Not sure how exactly to interpret the below but below is what I get back as the "Issuer" information from my certificate. COMODO Certification Authority seems to be trusted based on the list in the link you provided.

                CN = COMODO RSA Domain Validation Secure Server CA
                O = COMODO CA Limited
                L = Salford
                S = Greater Manchester
                C = GB

                In regards to the openssl changes, they are quite extensive (4 years) worth, and I am not sure I can quite pick out what change may have had an adverse effect, although I did go through their CHANGES file.

                Wouldn't the fact that I can replicate the issue outside of Pythonista "prove" that this is not specific to iOS but specific to the openssl version used by it?

                1 Reply Last reply Reply Quote 0
                • P
                  PrivateTech last edited by

                  Does anybody know what's going on with SSL certificate errors in Pythonista on iPhone?

                  EDIT: This very forum page on omz-software.com shows a certificate error in Google Chrome on a desktop.

                  I tried the simplest code to retrieve a small plain text web page. I tried the same code on iPhone in Pythonista and in Pyto. Tried many other pages too.

                  Pyto works fine every time.

                  Pyntonosta fails with error message on some web sites but not others.

                  I think I’ve identified a pattern. Pythonista breaks on web sites with Let’s Encrypt SSL Certificate.

                  Even stranger behavior is that some pages fail on some days but the very same pages seem to return no errors on another day when I tested again. And back to errors again a day later.

                  I contacted omz-software (omz:software) support via email a few days ago but haven’t heard from them yet.

                  The script is extremely simple:

                  with urllib.request.urlopen(URL) as response:
                       html = response.read()
                  

                  The error I get:

                  urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)

                  /var/containers/Bundle/Application/08EAF123-C40E-4CCA-98BE-395691A7AC9D/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/urllib/request.py", line 1321, in do_open

                  var/containers/Bundle/Application/08EAF123-C40E-4CCA-98BE-395691A7AC9D/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/urllib/request.py", line 1362, in https_open
                  context=self._context, check_hostname=self._check_hostname)

                  Any Ideas?

                  It is also posed here in case if someone responds there as well

                  omz 1 Reply Last reply Reply Quote 0
                  • omz
                    omz @PrivateTech last edited by

                    @PrivateTech I'll look into it. The workaround in this StackOverflow answer should also work in Pythonista.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post
                    Powered by NodeBB Forums | Contributors