27

I am trying to write a pycurl script to access a secured site (HTTPS).

c = pycurl.Curl()
c.setopt(pycurl.USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0')
c.setopt(pycurl.URL, 'https://for-example-securedsite')
c.setopt(pycurl.COOKIEFILE, 'cookie.txt')
c.setopt(pycurl.COOKIEJAR, 'cookies.txt')
c.setopt(pycurl.WRITEDATA, file("page.html","wb"))   

I am getting the below error..

pycurl.error: (60, 'SSL certificate problem, verify that the CA cert is OK. Details:\nerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed')

The code failed, as it failed to get the SSL cert.

The error went away if I add the below lines to my code.

c.setopt(pycurl.SSL_VERIFYPEER, 0)   
c.setopt(pycurl.SSL_VERIFYHOST, 0)

The above code will skip the certificate verification. But its subjected to 'man in middle' attack.

I know I have the SSL certificate in my local certificate store. Do anyone know how to export my certificate and use it my code.. Some sample codes will be awesome..

Thanks for your time!

K2M
  • 379
  • 1
  • 5
  • 12

4 Answers4

25

You are right, the way you are doing it subjects you to a man-in-the-middle attack, especially in light of the most recent SSL vulnerabilities. You can resolve it as follows:

import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, "https://your-secure-website.com/")
curl.setopt(pycurl.SSL_VERIFYPEER, 1)
curl.setopt(pycurl.SSL_VERIFYHOST, 2)
curl.setopt(pycurl.CAINFO, "/path/to/updated-certificate-chain.crt")
curl.perform()

curl by default comes with an outdated certificate list. Whether you want to update it or just use your own certs for testing, make sure to place the updated-certificate-chain.crt file in an accessible location and use the pycurl.CAINFO option to point to it.

Also make sure pycurl.SSL_VERIFYHOST is set to 2, the highest security check setting.

Suman
  • 9,221
  • 5
  • 49
  • 62
2

It happened to me using python 3 in windows, getting this error :

(60, 'SSL certificate problem: unable to get local issuer certificate')

The final two solutions :

1 - adding a certificate, curl.setopt(pycurl.CAINFO, "c:\certs\ssl.cert")

OR

2 - ignoring the ssl verification using :
curl.setopt(pycurl.SSL_VERIFYPEER, 0)
curl.setopt(pycurl.SSL_VERIFYHOST, 0)

@ for all python users in windows.

1

Have you read the cURL documentation about SSL certificates? This seems to directly address your question...in particular, item 2:

 2. Get a CA certificate that can verify the remote server and use the proper
    option to point out this CA cert for verification when connecting. For
    libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath);

It looks like the pycurl module contains the CAPATH option, so this should be simple to implement in your code.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thanks for your reply.. I read the article.. Then I tried to get the cert by using curl.exe with the following options.. curl.exe --cacert test.crt https://secure-site/ .. I got the following error.. "curl: (1) Protocol https not supported or disabled in libcurl" .. Any ideas how do I fix it? – K2M Nov 30 '11 at 21:03
  • I downloaded the curl source and build on my own.. Just got a url where I can download the readily built Curl.exe "http://curl.haxx.se/latest.cgi?curl=win32-ssl-devel-msvc".. I will explore that! – K2M Nov 30 '11 at 22:53
0

The Solution to this problem lies in providing the curl object access to the 'https' based protocol url's via insecure argument In a cmd terminal we exclusively input the arg '-k'

In Pycurl we have to set the same option to the curl object by the methods as below, with minimal level of security i.e '0'.

c.setopt(pycurl.SSL_VERIFYPEER, 0)   
c.setopt(pycurl.SSL_VERIFYHOST, 0)

allow the insecure connection After which, access to the SSL is made without any obstruction

joanis
  • 10,635
  • 14
  • 30
  • 40