Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590) #415

Open
Maltavius opened this issue Oct 3, 2021 · 24 comments
Labels

Comments

@Maltavius
Copy link

Describe the bug
Since the start of October my Python script that talks to my Home Assistant server doesn't work.

To Reproduce
This is the code

import requests as req
headers = {'Authorization': 'Bearer <token>', 'content-type': 'application/json'}
url = 'http://<url>/api/services/mqtt/publish'
data = '{"payload": "ON", "topic":"pc/activity/state"}'
response = req.post(url, headers=headers, data=data)
print(response.text)

Error from EventGhost

         Traceback (most recent call last):
           Python script "3", line 5, in <module>
             response = req.post(url, headers=headers, data=data)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 111, in post
             return request('post', url, data=data, json=json, **kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 57, in request
             return session.request(method=method, url=url, **kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 475, in request
             resp = self.send(prep, **send_kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 606, in send
             history = [resp for resp in gen] if allow_redirects else []
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 179, in resolve_redirects
             **adapter_kwargs
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 585, in send
             r = adapter.send(request, **kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\adapters.py", line 477, in send
             raise SSLError(e, request=request)
         SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

Expected behavior
That the connection can be done.

Additional context
From what I can tell this has something to do with Let'sEncrypts Root Certificate Expiring
https://www.socialgrep.com/search?query=%2Fr%2Feventghost
https://scotthelme.co.uk/lets-encrypt-old-root-expiration/

Is the Python version signed against an old Certificate or what is the problem?

EventGhost version
Software
Program Version: 0.5.0-rc6
Build Time: Mon, 24 Dec 2018 09:01:48
Python Version: Stackless Python 2.7.12 final 0
wxPython Version: 3.0.2.0

System
Operating System: Microsoft Windows 10 (Unknown Edition 101), 64-bit (build 19043)
CPU: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
RAM: 31.9 GB

@Maltavius Maltavius added the bug label Oct 3, 2021
@Maltavius
Copy link
Author

The solution seems to be to get Python to trust the new Certificate ISRG Root X1
https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/

@Gam3sFan
Copy link

Gam3sFan commented Oct 5, 2021

Hi, did you fixed it? any advice how to do
thanks

@Maltavius
Copy link
Author

I didn't

@Gam3sFan
Copy link

Gam3sFan commented Oct 5, 2021

Oh :(

@kdschlosser
Copy link
Member

kdschlosser commented Oct 5, 2021

you will need to start EventGhost as an Administrator. (right click EventGhost icon and click on "Run as Administrator" in the menu.

Make a new Python Script action and copy and paste the code below into that action. Then run the action. This will update the certificate file that is included with EventGhost. Report if it works or if it did not please. If it didn't any errors you get can you please copy them from the log and paste them into a reply here.

import requests
import certifi

content = requests.get('http://curl.se/ca/cacert.pem').content

path = certifi.where()

with open(path, 'w') as f:
    f.write(content)

print('Certificate update complete!!')

@Maltavius
Copy link
Author

Maltavius commented Oct 5, 2021

you will need to start EventGhost as an Administrator. (right click EventGhost icon and click on "Run as Administrator" in the menu.

Make a new Python Script action and copy and paste the code below into that action. Then run the action. This will update the certificate file that is included with EventGhost. Report if it works or if it did not please. If it didn't any errors you get can you please copy them from the log and paste them into a reply here.

import requests
import certifi

content = requests.get('http://curl.se/ca/cacert.pem').content

path = certifi.where()

with open(path, 'w') as f:
    f.write(content)

print('Certificate update complete!!')

image

   Traceback (most recent call last):
     Python script "5", line 4, in <module>
       content = requests.get('http://curl.se/ca/cacert.pem').content
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 71, in get
       return request('get', url, params=params, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 57, in request
       return session.request(method=method, url=url, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 475, in request
       resp = self.send(prep, **send_kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 606, in send
       history = [resp for resp in gen] if allow_redirects else []
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 179, in resolve_redirects
       **adapter_kwargs
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 585, in send
       r = adapter.send(request, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\adapters.py", line 477, in send
       raise SSLError(e, request=request)
   SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

The site Curl.se has ha Certificate issued by the Certificate that EventGhost doesn't trust
image

@kdschlosser
Copy link
Member

kdschlosser commented Oct 6, 2021

not sure why certificates are being used for a non secure connection.

If you don't use EventGhost to connect to any webpages on the internet you can use this code in a Python Script action as well.
The action you make MUST be placed into the Autostart group. It MUST be placed as the very first item in the list.

After you get the python script action made then save your EG session and then restart EG. You do not have to have administrative privlages for this to work.

import sys
import requests


eg.globals.original_get = getattr(eg.globals, 'original_get', requests.get)

def get(url, params=None, **kwargs):
    if 'verify' not in kwargs:
        kwargs['verify'] = False

    return eg.globals.original_get(url, params=params, **kwargs)

sys.modules['requests'].get = get

@kdschlosser
Copy link
Member

EG doesn't use the windows certificate store. It uses something different. The issue is being caused by a change to one of the root certificates and that new certificate is being used by websites and the certificate that EG has is an old one so it cannot verify the certificate.

@kdschlosser
Copy link
Member

If you want to give it a go again to download a new version of the certificates instead of disabling verification of them (that is what is being done in the script above) you can use this code .

import requests
import certifi

content = requests.get('http://curl.se/ca/cacert.pem', verify=False).content

path = certifi.where()

with open(path, 'w') as f:
    f.write(content)

print('Certificate update complete!!')

@Maltavius
Copy link
Author

If you want to give it a go again to download a new version of the certificates instead of disabling verification of them (that is what is being done in the script above) you can use this code .

import requests
import certifi

content = requests.get('http://curl.se/ca/cacert.pem', verify=False).content

path = certifi.where()

with open(path, 'w') as f:
    f.write(content)

print('Certificate update complete!!')

Sadly no dice.


Import Cert
   C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\packages\urllib3\connectionpool.py:821: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
     InsecureRequestWarning)
   Traceback (most recent call last):
     Python script "6", line 8, in <module>
       with open(path, 'w') as f:
   IOError: [Errno 2] No such file or directory: 'C:\\Program Files (x86)\\EventGhost\\lib27\\python27.zip\\certifi\\cacert.pem'

@kdschlosser
Copy link
Member

That's fine if it is stored in the zip file containing the libraries.

Use the script below and add it to your Autostart group at the top. This way the certificate bundle will always get updated when you startup EG as an Administrator. If you do not startup EG as an administrator an error will get printed out (this may only happen on Windows 10).

import requests
import certifi
import os

try:
    content = requests.get('http://curl.se/ca/cacert.pem', verify=False).content

    path = os.path.join9os.path.split(os.path.split(certifi.where())[0])[0], 'cacert.pem')

    with open(path, 'w') as f:
        f.write(content)

    print('Certificate update complete!!')

    os.environ['CURL_CA_BUNDLE'] = path

except Exception:
    import traceback
    traceback.print_exc()

@Maltavius
Copy link
Author

Maltavius commented Oct 6, 2021

That's fine if it is stored in the zip file containing the libraries.

Use the script below and add it to your Autostart group at the top. This way the certificate bundle will always get updated when you startup EG as an Administrator. If you do not startup EG as an administrator an error will get printed out (this may only happen on Windows 10).

      Error compiling script.
      Traceback (most recent call last):
      SyntaxError: invalid syntax (4, line 8)

I figured there was a parenthesis error or something so I changed line 8 to be:

path = os.path.join(os.path.split(os.path.split(certifi.where())[0])[0], 'cacert.pem')
But then I get

   C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\packages\urllib3\connectionpool.py:821: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
     InsecureRequestWarning)
   Traceback (most recent call last):
     File "11", line 10, in <module>
   IOError: [Errno 2] No such file or directory: 'C:\\Program Files (x86)\\EventGhost\\lib27\\python27.zip\\cacert.pem'

@kdschlosser
Copy link
Member

kdschlosser commented Oct 7, 2021

OK lets do this the easy way and hard code the path.

import requests
import os

try:
    content = requests.get('http://curl.se/ca/cacert.pem', verify=False).content

    path = r'C:\Program Files (x86)\EventGhost\lib27\cacert.pem'
    with open(path, 'w') as f:
        f.write(content)

    print 'Certificate update complete!!'

    os.environ['CURL_CA_BUNDLE'] = path

except Exception:
    import traceback
    traceback.print_exc()

@Maltavius
Copy link
Author

Ok, that seems to work.
image

   Import Cert
      C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\packages\urllib3\connectionpool.py:821: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
        InsecureRequestWarning)

But (even after a restart). I still get
image

         Traceback (most recent call last):
           Python script "3", line 5, in <module>
             response = req.post(url, headers=headers, data=data)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 111, in post
             return request('post', url, data=data, json=json, **kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 57, in request
             return session.request(method=method, url=url, **kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 475, in request
             resp = self.send(prep, **send_kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 585, in send
             r = adapter.send(request, **kwargs)
           File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\adapters.py", line 477, in send
             raise SSLError(e, request=request)
         SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

@kdschlosser
Copy link
Member

You have that last scrip placed at the top of the Autostart group? It needs to stay there as it makes a change to an environment variable that requests uses to locate the cacert.pem file. It has to run each and every time before any plugins load,

@Maltavius
Copy link
Author

Yes, I also run as Administrator. Still doesn't work.

image

image

@kdschlosser
Copy link
Member

OK I see where the problem is..

DST Root CA X3 will expire on September 30, 2021

and the cacert.pem

generated at Thu Sep 30 03:12:05 2021 GMT

LOL. would figure.

I have a linux VM set up. Let me update Firefox on it and generate a cacert.pem file. You will have to change your script and drop the new pem file into your EventGhost directory. I will give you the new script once I make the file.

@kdschlosser
Copy link
Member

kdschlosser commented Oct 8, 2021

ok change the script at the top of the autostart group to the code below
Download the attached file and unzip it to C:\Program Files (x86)\EventGhost\lib27 overwrite if a file already exists.

restart EG

import os
os.environ['REQUESTS_CA_BUNDLE'] = 'C:\\Program Files (x86)\\EventGhost\\lib27\\cacert.pem'

cacert.zip

@kdschlosser
Copy link
Member

the cacert file I attached on the post above was generated by Mozilla 6 days ago. If it doesn't work then I would imagine there is something wrong in your home assistant installation.

You might have to bypass the verification of certificates which I posted a way to do. I will need to make some modifications to the script to disable the warnings you get in the log, but that is not a big deal. I can also set it up so that it will only disable the verification for your home assistant installation. The home assistant installation MUST have a static IP or a DNS name in order for me to do that.

@Maltavius
Copy link
Author

ok change the script at the top of the autostart group to the code below Download the attached file and unzip it to C:\Program Files (x86)\EventGhost\lib27 overwrite if a file already exists.

restart EG

import os
os.environ['REQUESTS_CA_BUNDLE'] = 'C:\\Program Files (x86)\\EventGhost\\lib27\\cacert.pem'

cacert.zip

Thanks!
This worked
I just put the os.environ in my "Import Cert" script at the top of Autostart.
Do I need to leave it there for every time or will this solve it permanently?

Maybe a new release of EventGhost with a proper cacert would be in order?

@kdschlosser
Copy link
Member

You need to leave the script there. If you don't want the script there you can set the environment variable in windows.

Even if there is a release of EG that would allow for a download of the certificate file as you already found out it wouldn't have worked anyway because the file that is gotten via an automatic package update is gotten from there.

I am going to let the makers of curl and also certifi know that they need to update the file.

@kdschlosser
Copy link
Member

Ok I let both of those projects know they need to update the file.

I can write a script that will check once a day to see if the script that Mozilla has is changed or not. That's about the best that I can do. I am pretty much at the mercy of curl and how quickly they update the file. You would think that they monitor what Mozilla has since they use the database in Firefox to build the file they use.

Maybe they didn't know that Mozilla generated the same file.. dunno.

https://github.com/curl/curl/issues/7836

Glad we got it sorted for the moment. I am going to put some thought into how I am going to go about writing an automatic download of the file.

@mpr0st
Copy link

mpr0st commented Oct 16, 2021

Hi.

Thank you very much for this fix, AutoRemote: Send Message action from EventGhost AutoRemote plugin was producing the same error:

8:52:48   AutoRemote: Sending crtask=:=confirmed {eg.event.payload.arpar[1]} {eg.event.payload.arpar[2]} from {eg.event.payload.sender.name} to device5
8:52:48   Calling url https://autoremotejoaomgcd.appspot.com/sendrequest
8:52:49   Couldn't make request via the internet: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>
8:52:49   Couldn't send Request

The solution in @kdschlosser's post above fixes it.

@bloodsyphon
Copy link

For the PushBullet addon, it has its own cacert.pem file stored in C:\ProgramData\EventGhost\plugins\PushBullet\lib\websocket__0440 that you need to update. May be true with other addons as well. Check in the plugin directory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants