Python ssl certificate connectivity issue from mac, ssl.c:2825

Hi,
I am trying to post the following from my mac device, also I installed the .pfx file in my keychain and trying to post the same.

``` py
r = requests.post("https://url", verify='/Users/my_user/Desktop/cert.pfx', data={}, auth=('user', 'password'))
```

it is throwing the following error 👍 

```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 88, in post
    return request('post', url, data=data, **kwargs)
  File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 456, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 559, in send
    r = adapter.send(request, **kwargs)
  File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 382, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: unknown error (_ssl.c:2825
```


What's the format of `cert.pfx`?


I am not sure but maybe a look at this may help (from source code)

 :param verify: (optional) whether the SSL cert will be verified. A CA_BUNDLE path can also be provided.      Defaults to `True`.
 :param stream: (optional) if `False`, the response content will be immediately downloaded.
 :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.

Did you try cert= instead of verify?
I think cert param is used for authentication purposes?


@Lukasa  cert.pfx is the SSL certificate which I need to mention in my POST/GET along with basic auth.
@baptistapedro I tried both the option and it is throwing me the following error.

I am attaching the error I encountered in both the option.

Option # 1

> > > import requests
> > > from requests.auth import HTTPBasicAuth
> > > auth = HTTPBasicAuth('auth_user', 'auth_pass')
> > > requests.post('https://my-site.com/rest_service', cert=('/Users/my_user/Desktop/auth_user.pfx', '/path/key'),  auth=auth)
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in <module>
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 88, in post
> > >     return request('post', url, data=data, *_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 44, in request
> > >     return session.request(method=method, url=url, *_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 456, in request
> > >     resp = self.send(prep, *_send_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 559, in send
> > >     r = adapter.send(request, *_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 382, in send
> > >     raise SSLError(e, request=request)
> > > requests.exceptions.SSLError: [SSL] PEM lib (_ssl.c:2580)

Option # 2

> > > r = requests.post("https://my-site.com/rest_service", verify='/Users/my_user/Desktop/auth_user.pfx', data={}, auth=('auth_user', 'auth_pass'))
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in <module>
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 88, in post
> > >     return request('post', url, data=data, *_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 44, in request
> > >     return session.request(method=method, url=url, *_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 456, in request
> > >     resp = self.send(prep, *_send_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 559, in send
> > >     r = adapter.send(request, *_kwargs)
> > >   File "/Users/my_user/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 382, in send
> > >     raise SSLError(e, request=request)
> > > requests.exceptions.SSLError: unknown error (_ssl.c:2825)


@nahonnyate My question was what is the _format_ of that certificate? How is it stored?

The reason I ask is that generally speaking a .pfx file is a Windows representation of a PKCS#12 format certificate. OpenSSL won't handle that format well, at least not as it's used here, so you'll need to convert it to PEM in order to use it. Find some instructions on [this page](https://www.sslshopper.com/article-most-common-openssl-commands.html).


@Lukasa thanks for the referred page, I just did info on that SSL .pfx file and here is the output: if it helps.

pkcs12 -info -in '/Users/my_user/Desktop/auth_user.pfx'
Enter Import Password:
MAC Iteration 2000
MAC verified OK
PKCS7 Data
Shrouded Keybag: pb***_SHA1**_-Key*****_-**_**, Iteration 2000
Bag Attributes
    localKeyID: 0\* *\* 00 00 
    friendlyName: le-*****_-**_-***_-**__-_********
    Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
Key Attributes
    X509v3 Key Usage: 80 


@Lukasa tried the following as you have suggested , not sure why it is complaining about the certificate now, I am using the same certificate (.pfx version) through SOAP UI in POST request and getting proper response back

## Converted .pfx file to .pem through this

openssl pkcs12 -in '/Users/auth_user/Desktop/cert.pfx' -out cert.pem -nodes

## use the same .pem in my POST

r = requests.post('https://my-site.com/rest_service', verify='/Users/auth_user/Desktop/cert.pem', data={}, auth=('auth_user', 'auth_pass'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/auth_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 88, in post
    return request('post', url, data=data, *_kwargs)
  File "/Users/auth_user/anaconda/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, *_kwargs)
  File "/Users/auth_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 456, in request
    resp = self.send(prep, *_send_kwargs)
  File "/Users/auth_user/anaconda/lib/python2.7/site-packages/requests/sessions.py", line 559, in send
    r = adapter.send(request, *_kwargs)
  File "/Users/auth_user/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 382, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)


Don't pass the cert to the `verify` parameter, pass it to `cert`.


thanks for your help on the same , it is going through right now but throwing me 401

r = requests.post('https://my-site.com/rest_service', verify=False, cert='/Users/auth_user/Desktop/cert.pem', data={}, auth=('auth_user', 'auth_pass'))
r.status_code = 401


401 suggests you're failing to authenticate. How does your site expect you to log in?


my site expects basic header authentication and I was thinking the argument auth=('auth_user', 'auth_pass') what I am paying in my POST will take care of that. Do I need to mention something else to do confirm its BasicAuth


Nope, that should do basic auth. Do you have logs from your site to indicate what it's 401-ing for?


@Lukasa I also tried with urllib2 with the following option and getting the same error as before:

---

import requests
import urllib2
import base64

chimpConfig = {
    "headers" : {
    "Authorization": "Basic " + base64.encodestring("auth_user:auth_pass").replace('\n', '')
    },
    "cert": "/Users/user/Desktop/ssl_suth_cert.pem",
    "url": 'https://url.com/'}

#perform authentication
datas = None
timeout = 2
cert = "/Users/user/Desktop/ssl_suth_cert.pem"
request = urllib2.Request(chimpConfig["url"], datas,  chimpConfig["headers"])
result = urllib2.urlopen(request)

print "Response:",result
print result.code

---

it is giving me the following error
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

now if I add "cert" parameter in my call I am getting the following error:
only change in the above code is: added cert param:
request = urllib2.Request(chimpConfig["url"], datas, **cert,** chimpConfig["headers"])

error:

Traceback (most recent call last):
  File "urlpost.py", line 16, in <module>
    request = urllib2.Request(chimpConfig["url"], datas, cert, chimpConfig["headers"])
  File "/Users/summukhe/anaconda/lib/python2.7/urllib2.py", line 238, in **init**
    for key, value in headers.items():
AttributeError: 'str' object has no attribute 'items'


I'm not really interested in what urllib2 is getting wrong (though the second traceback indicates a problem with your code, probably that the cert is being passed in the wrong place).

Regardless, I'm interested in seeing either logs from the server or some kind of reference for what the server is expecting.


@Lukasa  , thanks for your direction, after analyzing the log it seems the url was having some '\n' character which was causing the later issue.
simple rstrip() worked and Verify= False was the key as you have mentioned before. 

One more question, how do I post message through this ? if I am adding another param as "data", this request is throwing error "TypeError: post() got multiple values for keyword argument 'data'"

I really appreciate your help and the community to provide the support.

## POST started working

headers = {'content-type': 'application/json'}

> > > r = requests.post(url, headers, verify=False, cert='/Users/user/Desktop/auth_user.pem', auth=('user', 'pass'))
> > > r.content
> > > 'POST REQUEST PING'
> > > r.status_code
> > > 200
> > > ///


@Lukasa 

## I think we are all clean now, able to post with data-file as well.

Thanks everyone for the help, we can close the issue

payload='/Users/user/Desktop/a.xml'
r = requests.post(url,auth=('auth_user', 'pass'), data=payload, verify=False, cert='/Users/user/Desktop/sinri2683c.pem',headers=headers)


@nahonnyate I'm facing the same issue on my Mac. I use conda as my package manager. Please tell me how to resolve