How can I solve python openssl load_cert_chain function error? - python

I'm setting up a new server using Pytoh, tornado.
I'm going to set HTTPS.
But when server loads server certificate files, load_cert_chain function generates an error.
I purchased those certificate files from GoDaddy and it was okay on Apache Server before.
So certificate file and key file match and ca file is also okay.
python version: 3.7.4
tornado version : 4.5.2
openssl version: OpenSSL 1.1.1c 28 May 2019
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain("../server.crt", "../server.key")
ssl_ctx.load_verify_locations("../ca.crt")
ssl_ctx.verify_mode = ssl.CERT_REQUIRED
https_server = tornado.httpserver.HTTPServer(app, ssl_options=ssl_ctx)
This is error message.
ssl_ctx.load_cert_chain("../server.crt", "../server.key")
ssl.SSLError: [SSL] PEM lib (_ssl.c:3854)

I solved this problem. I use NginX server to host python server with digital signed certificates.

Related

SSL failure on Ubuntu 11.10

Hey I got a couple of errors and I need help to fix them because I can't find a solution for that.
Why am I using an old af version of ubuntu?
Because I need to build android 4 and the easiest way to get the right versions of the needed packages is to use an older version of ubuntu which is confirmed to work
So please don't tell me to just upgrade to the latest ubuntu
Some commands that don't work because of a failure with ssl
when trying to access any website with firefox it returns ssl_error_no_cypher_overlap
BUT google searches are working fine
$ repo init --depth=1 -u http://github.com/CyanogenMod/android.git -b ics
Downloading Repo source from http://gerrit.googlesource.com/git-repo
fatal: Cannot get http://gerrit.googlesource.com/git-repo/clone.bundle
fatal: error unknown url type: https
fatal: cloning the git-repo repository failed, will remove '.repo/repo'
a small information how I got repo to work but didn't break apt (apt uses python2 and repo needs python3)
I aliased python as python3 so when I run python as user it refers to python3 but when I run python as root it refers to the python symlink (/usr/bin/python) which is python2
$ sudo apt-add-repository ppa:relan/exfat
Traceback (most recent call last):
File "/usr/bin/apt-add-repository", line 88, in <module>
ppa_info = get_ppa_info_from_lp(user, ppa_name)
File "/usr/lib/python2.7/dist-packages/softwareproperties/ppa.py", line 83, in get_ppa_info_from_lp
curl.perform()
pycurl.error: (60, 'server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none')
$ wget https://www.python.org/ftp/python/3.10.1/Python-3.10.1.tgz
--2021-12-25 21:43:11-- https://www.python.org/ftp/python/3.10.1/Python-3.10.1.tgz
Resolving www.python.org... 2a04:4e42:3::223, 151.101.12.223
Connecting to www.python.org|2a04:4e42:3::223|:443... connected.
OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Unable to establish SSL connection.
$ curl -v https://www.python.org/ftp/python/3.10.1/Python-3.10.1.tgz
* About to connect() to www.python.org port 443 (#0)
* Trying 2a04:4e42:3::223... connected
* Connected to www.python.org (2a04:4e42:3::223) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS alert, Server hello (2):
* error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
* Closing connection #0
curl: (35) error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Solutions I found online and tried but didn't work
checked if time is correct
update-ca-certificates -f
Tell me if you need further information/logs or anything else
Every help is appreciated!
The problem is not (yet) the certificates, it fails before validating these. Instead the versions of the SSL libraries used a simply too old. This means your software stack is way to old for today's requirements. There is no easy way to fix this.
In detail:
The openssl version in 11.10 is 0.9.8 which has no support for modern protocols like TLS 1.2 or even TLS 1.3. Similar the version of Firefox at the time of Ubuntu 11.10 did not support TLS 1.2 either (even though NSS and not openssl was used as SSL library).

SSL Handshake issue with Pymongo on Python3

Trying to connect to Azure CosmosDB mongo server results into an SSL handshake error.
I am using Python3 and Pymongo to connect to my Azure CosmosDB. The connection works fine if I run the code with Python27 but causes the below error when using Python3:
import pymongo
from pymongo import MongoClient
import json
import sys
def check_server_status(client, data):
'''check the server status of the connected endpoint'''
db = client.result_DB
server_status = db.command('serverStatus')
print('Database server status:')
print(json.dumps(server_status, sort_keys=False, indent=2, separators=(',', ': ')))
coll = db.file_result
print (coll)
coll.insert_one(data)
def main():
uri = "mongodb://KEY123#backend.documents.azure.com:10255/?ssl=true&replicaSet=globaldb"
client = pymongo.MongoClient(uri)
emp_rec1 = {
"name":"Mr.Geek",
"eid":24,
"location":"delhi"
}
check_server_status(client, emp_rec1)
if __name__ == "__main__":
main()
Running this on Python3 results into below error:
pymongo.errors.ServerSelectionTimeoutError: SSL handshake failed:
backendstore.documents.azure.com:10255: [SSL:
CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
Here is my successful output when I run the same code with Python27:
Database server status: { "_t": "OKMongoResponse", "ok": 1 }
Collection(Database(MongoClient(host=['backend.documents.azure.com:10255'],
document_class=dict, tz_aware=False, connect=True, ssl=True,
replicaset='globaldb'), u'result_DB'), u'file_result')
On Windows you can do like this
pip install certifi
Then use it in code:
import certifi
ca = certifi.where()
client = pymongo.MongoClient(
"mongodb+srv://username:password#cluster0.xxxxx.mongodb.net/xyzdb?retryWrites=true&w=majority", tlsCAFile=ca)
Solved the problem with this change:
client = pymongo.MongoClient(uri, ssl_cert_reqs=ssl.CERT_NONE)
The section Troubleshooting TLS Errors of the PyMongo offical document `TLS/SSL and PyMongo introduces the issue as below.
TLS errors often fall into two categories, certificate verification failure or protocol version mismatch. An error message similar to the following means that OpenSSL was not able to verify the server’s certificate:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
This often occurs because OpenSSL does not have access to the system’s root certificates or the certificates are out of date. Linux users should ensure that they have the latest root certificate updates installed from their Linux vendor. macOS users using Python 3.6.0 or newer downloaded from python.org may have to run a script included with python to install root certificates:
open "/Applications/Python <YOUR PYTHON VERSION>/Install Certificates.command"
Users of older PyPy and PyPy3 portable versions may have to set an environment variable to tell OpenSSL where to find root certificates. This is easily done using the certifi module from pypi:
$ pypy -m pip install certifi
$ export SSL_CERT_FILE=$(pypy -c "import certifi; print(certifi.where())")
You can try to follow the description above to fix your issue, which seems to be for Linux and Mac Users. On Windows, I can not reproduce your issue in Python 3.7 and 3.6. If you have any concern, please feel free to let me know.
Faced the same issue when trying to connect mongodb from Digital Ocean,
Solved by using this function with params in MongoClient:
def get_client(host,port,username,password,db):
return MongoClient('mongodb://{}:{}/'.format(host,port),
username=username,
password=password,
authSource=db,
ssl=True,ssl_cert_reqs=ssl.CERT_NONE)
client = get_client("host-ip","port","username","password","db-name")
On Mac Mojave 10.14.6 , I used (PyMongo 3.10 and python 3.7), to solve:
flask pymongo pymongo.errors.ServerSelectionTimeoutError [SSL: CERTIFICATE_VERIFY_FAILED]
Execute in terminal:
sudo /Applications/Python\ 3.7/Install\ Certificates.command
If you use other python version, only change versión number (In my case, i have Python 3.7)
cluster = MongoClient(
"url",
ssl=True,
ssl_cert_reqs=ssl.CERT_NONE,
)
By default pymongo relies on the operating system’s root certificates.
It could be that Atlas itself updated its certificates or it could be that something on your OS changed. “certificate verify failed” often occurs because OpenSSL does not have access to the system’s root certificates or the certificates are out of date. For how to troubleshoot see TLS/SSL and PyMongo — PyMongo 3.12.0 documentation 107.
pls Try :
client = pymongo.MongoClient(connection, tlsCAFile=certifi.where())
and dont forget to install certifi
On mac Monterey, I used pymongo 3.12.1 and virtual environment
To solve, use
ssl_cert_reqs=CERT_NONE
with mongodb url

MQTT (Mosquitto) over TLS - certificate error in some programs

I set up a Mosquitto server a few days ago using https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-debian-8.
Playing around with it, everything seemd to be working like I wanted. I am able to connect an android client and MQTTSpy to my own server.
Yesterday I had the great idea of looking for a Kodi plugin that would push status and info to MQTT: https://github.com/owagner/kodi2mqtt
It is able to find the server as I see changes in the Mosquitto log file, however I keep getting the same error:
1492549927: New connection from 81.240.134.64 on port 8883.
1492549927: OpenSSL Error: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol
1492549927: Socket error on client <unknown>, disconnecting.
1492549932: New connection from 81.240.134.64 on port 8883.
1492549933: OpenSSL Error: error:140780E5:SSL routines:SSL23_READ:ssl handshake failure
1492549933: Socket error on client <unknown>, disconnecting.
1492549934: New connection from 81.240.134.64 on port 8883.
1492549934: OpenSSL Error: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol
1492549934: Socket error on client <unknown>, disconnecting.
1492549939: New connection from 81.240.134.64 on port 8883.
1492549939: OpenSSL Error: error:140780E5:SSL routines:SSL23_READ:ssl handshake failure
1492549939: Socket error on client <unknown>, disconnecting.
From what I understand there are some issues with certificates but I am not 100% sure what is missing. In the other applications I do not need to provide my own certificates, so I don't see what is missing. I tried using the generated certificates in the Kodi addon, however they seem not to work and I get a different error:
1492541859: New connection from 81.240.134.64 on port 8883.
1492541860: OpenSSL Error: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
1492541860: OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure
1492541860: Socket error on client <unknown>, disconnecting.
1492541862: New connection from 81.240.134.64 on port 8883.
1492541862: OpenSSL Error: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
1492541862: OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure
1492541862: Socket error on client <unknown>, disconnecting.
I'm not sure in what direction I should check. Is something wrong with my server/certificates (seems unlikely since other clients are working) or is something wrong with the python code of the Kodi addon? If so, could anyone shed some light on what is missing (I know my way around coding, just not really around certificate things).
Thanks for the help!
Joren C.
Your python client will need access to the trusted certificate authority. Copy the signed public certificate The browser clients don't need that because they already come loaded with trusted certificate authorities.
If the kodi addon is using the paho mqtt client library , then the following should fix it..
client.tls_set('$your server's public cert$.crt')
Try ssl connection:
openssl s_client -connect 81.240.134.xxx:8883 -CAfile /etc/certs/file.crt -debug

Ignore SSL cert for private PyPi

I have a a private PyPi repository, however the test server does not have a valid ssl certificate for its domain. When uploading the test package, i.e.,
python setup.py sdist upload -r privatepypi
I get this error:
ssl.CertificateError: hostname 'pypi.xxx.com' doesn't match either of 'www.yyy.com', 'api.yyy.com', 'pypi.yyy.com'
is it possible to tell it to ignore the server ssl certificate?

Passing crt/pem with paho

At the moment I am trying to figure out how to do an MQTT publish using the .crt and .pem files for our application.
below is some pseudo code for what I am trying to do:
connect to an existing topic over tls
publish a message
import paho.mqtt.publish as mqtt
import paho.mqtt.client as mqttclient
topic = "Some/Topic/Goes/Here"
my_ca_cert = open("<path_to_cert>\ca.crt", 'rb').read()
my_pri_cert = open("<path_to_cert>\private.pem", 'rb').read()
my_key_cert = open("<path_to_cert>\certificate.pem", 'rb').read()
mqttc = mqttclient.Client("Python_Ex_Pub")
mqttc.tls_set(my_ca_cert, certfile=my_pri_cert, keyfile=my_key_cert)
mqttc.connect("<gateway_address>", 8883)
mqttc.publish(topic_name, "This is a test pub from Python.")
mqttc.loop(timeout=2.0, max_packets=1)
When I run the script the following error is thrown:
Traceback (most recent call last):
File "mqtt_pub_test.py", line 9, in <module>
mqttc.tls_set(my_ca_cert, certfile=my_pri_cert, keyfile=my_key_cert)
File "C:\Python27\lib\site-packages\paho\mqtt\client.py", line 557, in tls_set
raise IOError(ca_certs+": "+err.strerror)
IOError: -----BEGIN CERTIFICATE-----
<cert_info_here>
-----END CERTIFICATE-----: No such file or directory
I read through the TLS example on the paho doc page, but just do not understand how I should be passing the crt / pem files in my code.
At one point I was only pointing to the folder containing the files, and even went as far as to chmod 777 the folder but at that point I was getting access denied from python at run time.
Any help is appreshiated
Do you want to do TLS client authentication (that is, your Python script needs to authenticate to the server / MQTT broker)? Or do you want your Python script to behave like a web browser, and just validate the server certificate?
If you only want the latter, I have had success using the tls_set() method in the Paho Python client when I point it to a PEM file containing the server's certificate. And that's the only argument you need to pass on tls_set() to have the Paho client validate the server certificate, and connect to the broker using TLS. For example:
mqttc.tls_set("/home/bob/certificates/mqttbrokercertificate.pem")
How do you obtain the mqtt broker's certificate in PEM format? The easiest way is with openssl:
openssl s_client -host mqtt.broker.hostname.com -port 8883 -showcerts
Redirect the output to a file, and delete every line in the file except what is between the "BEGIN CERTIFICATE" and "END CERTIFICATE" lines (inclusive -- be sure to include these lines as well). This is a good article here on StackOverflow about how to save a server's SSL certificate using openssl:
How to save server SSL certificate to a file
Lastly, you need to be sure of what version of TLS your broker supports, and make sure your Python client also supports it. For example, the IBM Watson IoT Platform requires TLS 1.2. The ssl module in Python 2.7 (which is built on openssl) does not support TLS 1.2. Generally, you need Python 3.X, and openssl of at least 1.0.1. Here is how you can set the TLS version on the Paho client (don't forget to import ssl):
mqttc.tls_set("/home/bob/certificates/mqttbrokercertificate.pem", tls_version=ssl.PROTOCOL_TLSv1_2)
If you want TLS client authentication, that's probably better handled in an entirely separate article. But I hope this helps with TLS server authentication using the Paho Python client.
Looking at the error it would suggest that the tls_set function is expecting paths to the files not the contents of the file to be passed in.

Categories