Python error: “certificate verify failed”
XBee Gateway firmware with version 3.2.32 or later includes an updated version of Python 2.7 (version 2.7.18), which has changed the default behavior of the ssl module to be more strict in verifying the authenticity of server certificates in SSL/TLS connections. This change improves security for applications. An explanation of this change can be found in PEP 476.
Due to filesystem space limitations, XBee Gateway does not ship with a built-in set of known CA certificates (otherwise known as a “trust store”). As a result, when a Python application running on firmware version 3.2.32 or newer attempts to establish an SSL/TLS connection, a “certificate verify failed” error may be generated.
Solutions
There are two ways to avoid this error:
Option 1: Load and use a Certificate Authority for the host you are connecting to
This method updates your Python application code to validate the identity of the remote server.
-
Identify and download the public CA signing certificate associated with the SSL/TLS server that your application connects to.
-
For public IoT “cloud” services, information about this certificate is typically provided by the service vendor.
-
For non-public hosts, such as services running only locally on your network, contact your network administrator for assistance.
-
-
Load the CA signing certificate file onto the XBee Gateway’s filesystem, at a location such as /WEB/python/ca.crt.
-
Update your Python application code to use that CA certificate to verify the authenticity of the server certificate.
-
Example code for doing this with a bare SSL/TLS connection can be found in the Python ssl module documentation.
-
For other libraries, check the library documentation for information on specifying a server certificate.
-
-
Deploy the updated Python application code to the XBee Gateway.
Option 2: Use the older, more permissive behavior
This option is NOT RECOMMENDED for security reasons.
Do not follow these instructions unless you fully understand the security implications.
This method reverts the Python application process to the older, more permissive behavior of Python 2.7.8 and earlier, where server certificates are not verified by default. Using this option means you are choosing to make your application less secure, and vulnerable to connecting to malicious hosts.
To revert to the more permissive SSL/TLS behavior, add the following lines of code to your application’s primary file:
ssl._https_verify_certificates(False)
Or, if your application has only one SSL/TLS connection, an SSLContext which does not perform server verification can be created using:
ssl._create_unverified_context()
How to make use of this context is dependent on the application code or libraries being used.