Self signed certificate, passed to via verify=/path/to/cert does still trigger certificate verify failed

```
-> request = session.get(url, verify=cert)
(Pdb) c
Traceback (most recent call last):
  File "inventory.py", line 195, in <module>
    inventory()
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "inventory.py", line 192, in inventory
    print get_host(host)
  File "inventory.py", line 174, in get_host
    for host in get_all_infrastructure_elements():
  File "inventory.py", line 98, in get_all_infrastructure_elements
    request = session.get(url, verify=cert)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/requests/sessions.py", line 488, in get
    return self.request('GET', url, **kwargs)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/requests/sessions.py", line 596, in send
    r = adapter.send(request, **kwargs)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/cachecontrol/adapter.py", line 47, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "/Users/do3cc/dev/ansible/lib/python2.7/site-packages/requests/adapters.py", line 497, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)
```

This happens under mac. openssl gets installed via brew.

I have installed requests with pip via requests[security]
Versions:
- python: 2.7.10
- SSL: python -c 'import ssl;print(ssl.OPENSSL_VERSION)'
  **OpenSSL 1.0.2j  26 Sep 2016**

I have downloaded the certificate via: 

```
/usr/local/Cellar/openssl/1.0.2j/bin/openssl s_client -showcerts -connect ourserver:443 </dev/null | openssl x509 -outform PEM > eam_cert.pem
```

I have verified that the cert itself is ok via:

```
curl --cacert eam_cert.pem https://ourserver
```

This used to work in the past, but the server got a new certificate.
Right now I am out of ideas what I could be doing wrong here.


Are you able to share with us the output of `openssl x509 -in eam_cert.pem -noout -text`?


Yes, here it is:

```
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            12:a6:13:9d:00:01:00:04:f3:bb
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: DC=net, DC=it, CN=Company Group Enterprise CA3
        Validity
            Not Before: Aug 11 13:28:38 2016 GMT
            Not After : Aug 10 13:28:38 2021 GMT
        Subject: C=DE, L=Somewhere, O=Company AG, CN=eam.company.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:c3:20:4e:2f:05:3a:6b:6b:85:82:7e:2e:a1:83:
                    85:98:a4:2f:cd:46:88:bc:3f:40:02:69:e7:97:8f:
                    e5:18:63:57:f9:63:48:c6:66:47:eb:b8:3b:34:ca:
                    86:c8:3e:df:a4:f3:5c:0b:62:a5:61:85:1e:9a:e0:
                    68:f1:92:ed:a6:22:47:cf:ae:b9:da:7b:67:f8:16:
                    36:44:1c:21:8b:82:1e:f6:e8:25:69:53:36:06:00:
                    79:fe:e8:a5:7e:20:8f:39:f7:12:ad:0d:1d:19:55:
                    33:3a:6a:93:5e:98:b6:35:f8:01:d4:45:5b:dd:c8:
                    f5:80:02:8a:30:53:23:77:2a:06:92:c1:95:8e:ce:
                    fc:69:9f:4d:4a:ee:b8:b7:28:d0:4f:ca:1a:c3:c7:
                    07:08:c4:aa:82:98:3f:e9:89:ac:92:1a:7a:3f:ca:
                    6a:7e:03:3f:e1:1a:36:64:e2:d3:cb:1a:11:38:de:
                    a0:b9:3a:6b:6f:40:da:9a:43:e6:d5:af:db:c2:a3:
                    15:67:69:8e:ff:a1:5d:80:22:c7:4a:09:e1:fe:06:
                    2c:eb:2e:d6:db:66:37:f4:29:c2:d4:9a:47:c5:8a:
                    76:be:2a:1e:72:11:d4:77:7c:68:28:0a:bb:07:08:
                    61:02:1c:1b:43:5d:cc:0e:4a:48:f6:1f:4c:45:6c:
                    03:5f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                A8:7A:25:98:F8:D8:1D:01:60:AC:72:0C:63:0B:FB:60:E7:47:50:18
            X509v3 Authority Key Identifier:
                keyid:04:F4:7E:8A:12:F6:92:4E:87:8D:A1:78:C9:2F:2A:D5:64:01:4A:6D

            X509v3 CRL Distribution Points:
                URI:ldap:///CN=Company%20Group%20Enterprise%20CA3(1),CN=hostname,CN=CDP,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=it,DC=net?certificateRevocationList?base?objectClass=cRLDistributionPoint
                URI:http://pki.xgrp.net/CA3/Company%20Group%20Enterprise%20CA3(1).crl

            Authority Information Access:
                CA Issuers - URI:ldap:///CN=Company%20Group%20Enterprise%20CA3,CN=AIA,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=it,DC=net?cACertificate?base?objectClass=certificationAuthority
                CA Issuers - URI:http://pki.xgrp.net/CA3/hostname.it.net_Company%20Group%20Enterprise%20CA3(1).crt

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            1.3.6.1.4.1.311.21.7:
                0-.%+.....7....t...
..."...-....a...u...4..d...
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            1.3.6.1.4.1.311.21.10:
                0.0
..+.......
    Signature Algorithm: sha256WithRSAEncryption
        66:f1:bf:eb:a8:d3:3f:d2:49:6f:93:d1:7b:b4:94:13:d1:91:
        9a:f9:c0:74:3b:f7:78:59:54:64:1e:3f:96:ae:ab:f8:7d:0b:
        68:63:00:f3:57:a2:20:76:49:dc:dd:95:10:b4:c4:d3:d8:e9:
        d1:ee:ed:a9:48:58:ff:82:3a:d6:7a:cd:f1:00:08:32:20:27:
        bc:f1:ce:9b:5c:9b:2c:67:69:2b:bf:d8:8e:03:5a:d6:da:c3:
        70:06:f1:a3:55:d2:8e:52:1d:65:05:5b:46:33:4f:f4:f2:70:
        d2:55:00:c7:f7:f3:11:e6:20:08:02:81:c8:67:4b:57:ce:9a:
        bf:8a:d0:e4:35:8e:67:29:38:60:32:cb:29:19:19:d6:90:57:
        cd:2b:29:ce:56:1c:e0:61:bc:dc:b6:3d:2f:64:50:38:50:0f:
        37:09:4c:47:18:3b:e4:21:a5:bf:d2:28:40:7a:a7:a1:27:3b:
        64:a0:e7:9d:d9:40:94:42:11:34:bd:a8:b3:09:66:7e:48:d8:
        8e:ec:d9:61:62:29:31:33:be:ff:e7:12:e0:8e:94:e3:37:80:
        db:39:18:1f:ca:fc:a4:b9:41:1d:ab:6c:ef:98:f5:2f:2d:d7:
        31:c2:13:ef:1b:77:4e:bc:26:9d:8a:d2:c3:a1:2c:22:a5:3b:
        ed:d8:b0:91
```


That certificate is not self-signed. As a result, it's not a root certificate and is not a valid issuer for that cert. I suspect you have the root cert for the connection in your macOS Keychain, which is what curl is actually using to validate the connection.


@Lukasa Thanks for your responses so far. Curl did not use my macos keychain, when I didn't pass the certificate as an argument, curl would not download anything either.
I followed the crt link in the output above, downloaded that certificate, checked the output too and so on to get something that might just be the root certificate. It still does not work but next I first try to find a human who might have the proper root certificate.


@do3cc Can you print `curl -V` for me please?


```
* Rebuilt URL to: https://eam.company.com/
*   Trying 192.168.239.102...
* Connected to eam.company.com (192.168.239.102) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: eam.company.com
* Server certificate: company Group Enterprise CA3
* Server certificate: company Group Internal Root CA
> GET / HTTP/1.1
> Host: eam.company.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Accept-Ranges: bytes
< ETag: W/"97-1434464263000"
< Last-Modified: Tue, 16 Jun 2015 14:17:43 GMT
< Content-Type: text/html
< Content-Length: 97
< Date: Tue, 27 Sep 2016 14:24:12 GMT
<
<html>

<head>
<meta http-equiv="refresh" content="0;URL=/rep/">
</head>

<body>
</body>

* Connection #0 to host eam.company.com left intact
</html>%
```


Sorry, I meant literally just the command `curl -V` (case-sensitive, that capital V is on purpose).


yeah, I just noticed myself:

```
curl 7.43.0 (x86_64-apple-darwin15.0) libcurl/7.43.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets
```


Yup, so it remains the case that curl is using `SecureTransport` here. Regardless of whether curl found a root in the keychain or not, curl is using a totally different library than Requests is to build its cert chain. That will always cause a deviance in behaviour. =(


Hi, I got an answer and the certificate files. 
It was still failing while adding all certs to my browser made my browser accept the website. Googling for how to validate the cert via ssl gave me this page http://stackoverflow.com/questions/25482199/verify-a-certificate-chain-using-openssl-verify and after that I realized that it is not enough to pass the root certificate to `verify` but also the intermediate certificates. 

Our org uses its own root certificate and intermediate certificates. To verify the https connection, requests needs the complete certificate chain. 
Creating a cert file where I pasted the root certificate and intermediate certificates did just that.

@Lukasa Thank you so much for your quick help!


@Lukasa @do3cc Hi, sorry for tagging you in an old issue but I have a similar question regarding how requests verify SSL certs. If I want to verify SSL cert of a Server which is using a chain like:
Cert1 (Root Certificate, self-signed) --> Cert2(Intermediate cert, for ABC, issued by root CA) --> Cert3(Server Cert issued by ABC )
What I have noticed is, if I put Cert2 in a directory and point to it by environment variable 'REQUESTS_CA_BUNDLE' (after running 'c_rehash' utility on it) or if I directly point to it in the requests method call, I am still receiving SSL verification error. From my understanding it seems root certificate(Cert1 in this scenario) is required to verify the SSL certs successfully.
Is there a way to verify SSL certificate for Server(Cert3) with just the intermediate cert(Cert2 in this case) without using root certificate?

No, Requests (more properly OpenSSL) always requires a root certificate to successfully build a chain. 

@Lukasa Thanks for the response.