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

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate #65

Closed
Fretless14 opened this issue Sep 22, 2023 · 6 comments

Comments

@Fretless14
Copy link

Hi,
Does this package support Apple's M1/M2 chips?

I have everything working on my Apple Intel and Windows laptops, but I sent my program to a friend that has an M2 Apple laptop and he is getting this error stemming from a package used in cryptolens:

An error occurred: Could not contact the server. Error message: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>

I know this is part of the urllib package, but can someone verify this is an Apple Silicon compatibility issue?

@artemlos
Copy link
Contributor

Hi @Fretless14!

I just tried on Apple Silicon M1 and it worked as expected.

I think the problem is with either outed CA bundle or that it was not installed.

Could you please check if the following solution helps?
https://stackoverflow.com/questions/44649449/brew-installation-of-python-3-6-1-ssl-certificate-verify-failed-certificate/44649450#44649450

@Fretless14
Copy link
Author

I will test it out tonight, thank you! I think on Mac the cert path defaults to a location that is made when you install Python on your computer, which I have on my Mac obviously, so any computer that doesn't have Python installed (running on a .app build), will run into this error, and that script will fix it; I THINK that's what's happening. Will update when I can run my program on another Mac

Though I didn't run into that issue on my Windows laptop after I uninstalled Python... so must be a Mac thing with some default Python package/cert.

@Fretless14
Copy link
Author

I have it implemented, after changing the script slightly to take care of the missing path of the default ssl path for python (only made during python install, won't be there on customer systems) [ignore my logger import]:

import os
import os.path
import ssl
import stat
import subprocess
import sys
from Logger import Logger

logger = Logger()

STAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
			 | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
			 | stat.S_IROTH |                stat.S_IXOTH )


def install_certifi():
	openssl_dir, openssl_cafile = os.path.split(ssl.get_default_verify_paths().openssl_cafile)

	logger.logger.debug(" -- pip install --upgrade certifi")

	subprocess.check_call([sys.executable, "-s", "-m", "pip", "install", "--upgrade", "certifi"])

	import certifi

	logger.logger.debug(" -- removing any existing file or link")
	try:
		# change working directory to the default SSL directory
		os.chdir(openssl_dir)
		os.remove(openssl_cafile)
	except FileNotFoundError:
		pass

	relpath_to_certifi_cafile = os.path.relpath(certifi.where())
	logger.logger.debug(" -- creating symlink to certifi certificate bundle")
	os.symlink(relpath_to_certifi_cafile, openssl_cafile)

	logger.logger.debug(" -- setting permissions")
	os.chmod(openssl_cafile, STAT_0o775)

	logger.logger.debug(" -- update complete")


if __name__ == '__main__':
	install_certifi()

However, on another Mac, the original error remains. I'm thinking I need to create an SSL context object for the request function pointing to the cert file? Though I also thought that the above script changes the default path of the CA cert, so default_context should point to the new cert already... idk, I have to spend some time to look into this

@Fretless14
Copy link
Author

Wow okay, way easier fix. I thought of looking in connection to Pyinstaller, and it was mentioned and resolved here: pyinstaller/pyinstaller#7229 (comment)

Simply add this to your project:

import certifi
os.environ['SSL_CERT_FILE'] = certifi.where()

This makes it work for me, though I will have to go back and test on my other systems (Windows with and without Python installed)

@Fretless14 Fretless14 changed the title Possibly doesn't work on Apple Silicon? urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate Sep 23, 2023
@artemlos
Copy link
Contributor

@Fretless14 thanks for sharing the solution! I think we might be able to incorporate this into the next release. Just need to test it on Mac and Windows, as well as perform other tests.

@artemlos
Copy link
Contributor

artemlos commented Sep 28, 2023

@Fretless14

We noticed that certifi is an external dependency that needs to be installed, and we decided not to add this directly into the library and instead provide a solution on the wiki page (https://github.com/Cryptolens/cryptolens-python#could-not-contact-the-server-error-message-urlopen-error-ssl-certificate_verify-_failed-certificate-verify-failed-unable-to-get-local-issuer-certificate-sslc1125). For compatibility reasons, we need to keep the library free from external dependencies, since some of our customers are using it in an environment where external dependencies would cause issues.

Based on our discussion, it appears that this issue is specific to some Mac users, likely due to an error during the installation of the Python 3 bundle. It does not seem to affect all Mac users (since it worked on both your machine and mine).

Thank you once again for your feedback!

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

No branches or pull requests

2 participants