I am trying to load a certificate in order to bypass our corporate firewall when downloading certain files. I download these files with urllib2 and I try to add a certificate as context. That used to work for some time but now it doesn't anymore. I get the following error:
TypeError: descriptor 'load_cert_chain' requires a '_ssl._SSLContext' object but received a 'str'
The documentation on the Python website says the following:
SSLContext.load_cert_chain(certfile, keyfile=None, password=None)
Load a private key and the corresponding certificate. The certfile string must be the path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the certificate’s authenticity. The keyfile string, if present, must point to a file containing the private key in. Otherwise the private key will be taken from certfile as well. See the discussion of Certificates for more information on how the certificate is stored in the certfile.
My code is as following:
cert = SSLContext.load_cert_chain('<abs_path_to_PEM_file>')
scheme, netloc, path, params, query, frag = urlparse(url)
auth, host = urllib2.splituser(netloc)
if auth:
url = urlunparse((scheme, host, path, params, query, frag))
req = urllib2.Request(url)
base64string = base64.encodestring(auth)[:-1]
basic = "Basic " + base64string
req.add_header("Authorization", basic)
else:
req = urllib2.Request(url)
url_obj = urllib2.urlopen(req, context=cert)
with open(tmp_path, 'wb') as fp:
fp.write(url_obj.read())
return tmp_path, url_obj.info()
It says right there that the certfile parameter should be a string of the path where the PEM file is located. That's exactly what I am doing yet I get this error. I'm confused. What am I doing wrong here?
Thanks in advance!
.load_cert_chain
is not a static method. You need to instantiate an SSLContext
object. In the easiest case, this can be accomplished with the method
ctx = ssl.create_default_context()
and with that
ctx.load_default_certs()
You can then use that as following:
url_obj = urllib2.urlopen(req, context=ctx)