POST to CA fails using TLS 

Hello i'm facing a issue using requests lib to post to a CA with self-signed certificate Everything goes well when I POST from curl:

```curl --cacert "./ca-cert.pem" https://ca.goledger.com:7054/api/v1/cainfo -X POST```

I get my response with CAChain

If I try using requests lib it fails

## Expected Result

A response containing CAChain from CA at ca.goledger.com

## Actual Result

The command fails throwing a strange SSLError (BAD_ECC_CERT)

```python
 Traceback (most recent call last):
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/connectionpool.py", line 601, in urlopen
        chunked=chunked)
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/connectionpool.py", line 346, in _make_request
        self._validate_conn(conn)
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/connectionpool.py", line 850, in _validate_conn
        conn.connect()
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/connection.py", line 326, in connect
        ssl_context=context)
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket
        return context.wrap_socket(sock, server_hostname=server_hostname)
    File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
        _context=self)
    File "/usr/lib/python3.5/ssl.py", line 752, in __init__
        self.do_handshake()
    File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
        self._sslobj.do_handshake()
    File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: BAD_ECC_CERT] bad ecc cert (_ssl.c:645)

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File "/usr/local/lib/python3.5/dist-packages/requests-2.18.4-py3.5.egg/requests/adapters.py", line 440, in send
        timeout=timeout
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/connectionpool.py", line 639, in urlopen
        _stacktrace=sys.exc_info()[2])
    File "/usr/local/lib/python3.5/dist-packages/urllib3-1.22-py3.5.egg/urllib3/util/retry.py", line 388, in increment
        raise MaxRetryError(_pool, url, error or ResponseError(cause))
    urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='ca.goledger.com', port=7054): Max retries exceeded with url: /api/v1/cainfo (Caused by SSLError(SSLError(1, '[SSL: BAD_ECC_CERT] bad ecc cert (_ssl.c:645)'),))

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python3.5/dist-packages/requests-2.18.4-py3.5.egg/requests/api.py", line 112, in post
        return request('post', url, data=data, json=json, **kwargs)
    File "/usr/local/lib/python3.5/dist-packages/requests-2.18.4-py3.5.egg/requests/api.py", line 58, in request
        return session.request(method=method, url=url, **kwargs)
    File "/usr/local/lib/python3.5/dist-packages/requests-2.18.4-py3.5.egg/requests/sessions.py", line 508, in request
        resp = self.send(prep, **send_kwargs)
    File "/usr/local/lib/python3.5/dist-packages/requests-2.18.4-py3.5.egg/requests/sessions.py", line 618, in send
        r = adapter.send(request, **kwargs)
    File "/usr/local/lib/python3.5/dist-packages/requests-2.18.4-py3.5.egg/requests/adapters.py", line 506, in send
        raise SSLError(e, request=request)
    requests.exceptions.SSLError: HTTPSConnectionPool(host='ca.goledger.com', port=7054): Max retries exceeded with url: /api/v1/cainfo (Caused by SSLError(SSLError(1, '[SSL: BAD_ECC_CERT] bad ecc cert (_ssl.c:645)'),))
```

## Reproduction Steps

```python
import requests
requests.post(url='https://ca.goledger.com:7054/api/v1/cainfo', verify='./ca-cert.pem')
```

## System Information

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.6"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.5.2"
  },
  "platform": {
    "release": "4.10.0-38-generic",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.18.4"
  },
  "system_ssl": {
    "version": "1000207f"
  },
  "urllib3": {
    "version": "1.22"
  },
  "using_pyopenssl": false
}
```

@tiran Do you know if python 3.5 can handle ECC certificates from servers? It seems to either be that we can't handle that or the ECC cert is somehow invalid that this server is providing.

I can't figure this out because `openssl s_client -connect ca.goledger.com:7054` can't find the service. I'm not sure there's much we can actually do to help you here once my question above is answered by @tiran, @vieiramanoel 

Python 3.5 can handle ECC certs just fine with modern OpenSSL.

```python
Python 3.5.4 (default, Dec  6 2017, 16:39:49) 
[GCC 7.2.1 20170915 (Red Hat 7.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl, socket
>>> s = socket.create_connection(('ecc384.badssl.com', 443))
>>> tls = ssl.create_default_context().wrap_socket(s, server_hostname='ecc384.badssl.com')
>>> tls.cipher()
('ECDHE-ECDSA-AES128-GCM-SHA256', 'TLSv1.2', 128)
```

@vieiramanoel what's your OpenSSL version? Which ECC curves and signing algorithm does your service use? In general only named ANSI curves are supported well, e.g. secp384r1 and prime256v1.

```python
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.1.0g-fips  2 Nov 2017'
````


@sigmavirus24 You're right ca.goledger.com isn't a valid domain until you map its aws's public ip to this custom domain inside /etc/hosts. Is a bypass needed on dev-env. 
`openssl s_client -connect ca.goledger.com:7054` returns:
```
CONNECTED(00000003)
depth=0 C = BR, ST = Distrito Federal, L = Brasilia, O = GoLedger, CN = ca.goledger.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = BR, ST = Distrito Federal, L = Brasilia, O = GoLedger, CN = ca.goledger.com
verify error:num=26:unsupported certificate purpose
verify return:1
depth=0 C = BR, ST = Distrito Federal, L = Brasilia, O = GoLedger, CN = ca.goledger.com
verify return:1
140257510512280:error:1411713E:SSL routines:ssl_check_srvr_ecc_cert_and_alg:ecc cert not for signing:ssl_lib.c:2514:
140257510512280:error:14082130:SSL routines:ssl3_check_cert_and_algorithm:bad ecc cert:s3_clnt.c:3535:
---
Certificate chain
 0 s:/C=BR/ST=Distrito Federal/L=Brasilia/O=GoLedger/CN=ca.goledger.com
   i:/C=BR/ST=Distrito Federal/L=Brasilia/O=GoLedger/CN=ca.goledger.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICFzCCAb2gAwIBAgIUc+LUnIbPxmx91QVSUT0glVZaoccwCgYIKoZIzj0EAwIw
aDELMAkGA1UEBhMCQlIxGTAXBgNVBAgTEERpc3RyaXRvIEZlZGVyYWwxETAPBgNV
BAcTCEJyYXNpbGlhMREwDwYDVQQKEwhHb0xlZGdlcjEYMBYGA1UEAxMPY2EuZ29s
ZWRnZXIuY29tMB4XDTE4MDExNTE3MDYwMFoXDTMzMDExMTE3MDYwMFowaDELMAkG
A1UEBhMCQlIxGTAXBgNVBAgTEERpc3RyaXRvIEZlZGVyYWwxETAPBgNVBAcTCEJy
YXNpbGlhMREwDwYDVQQKEwhHb0xlZGdlcjEYMBYGA1UEAxMPY2EuZ29sZWRnZXIu
Y29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEogWNHFmQ++bbgvdcBPcMt19p
vkCjustvgwIlZPFsaDybD43P4+blO+boIuCNUYM6PsRcFJ0GeXAu8rQZxR+xO6NF
MEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE
FPGLpi9U+Omi6tIXmfaHsEL34dFuMAoGCCqGSM49BAMCA0gAMEUCIQCOKJ/ybqLU
MUZMAWTg5rZtCRmPJTIIjxMf/AQ9P1uiIwIgHg0l+fCVCEu57EnJzCnGsUyAdPAW
rgpTqINA1jrOpbs=
-----END CERTIFICATE-----
subject=/C=BR/ST=Distrito Federal/L=Brasilia/O=GoLedger/CN=ca.goledger.com
issuer=/C=BR/ST=Distrito Federal/L=Brasilia/O=GoLedger/CN=ca.goledger.com
---
No client certificate CA names sent
Peer signing digest: SHA384
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 764 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1516213541
    Timeout   : 300 (sec)
    Verify return code: 26 (unsupported certificate purpose)
---

```


@tiran 'OpenSSL 1.0.2g  1 Mar 2016', a bit late I guess, do you recommend upgrading it?

I don't have 1.0.2g, but 1.0.2 and 1.0.2h support ECC just fine. Please try openssl s_client and show me the ``Subject Public Key Info`` block:

```
$ 1.0.2h/bin/openssl version
OpenSSL 1.0.2h  3 May 2016
$ 1.0.2h/bin/openssl s_client -connect ecc256.badssl.com:443 -servername ecc256.badssl.com -CAfile /etc/pki/tls/cert.pem | 1.0.2h/bin/openssl x509 -text
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert ECC Secure Server CA
verify return:1
depth=0 C = US, ST = California, L = Walnut Creek, O = Lucas Garron, CN = *.badssl.com
verify return:1
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0c:dc:1a:66:d0:f1:4a:1b:e4:48:4e:28:c5:18:a1:92
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=DigiCert Inc, CN=DigiCert ECC Secure Server CA
        Validity
            Not Before: Jan 28 00:00:00 2017 GMT
            Not After : Feb  5 12:00:00 2020 GMT
        Subject: C=US, ST=California, L=Walnut Creek, O=Lucas Garron, CN=*.badssl.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub: 
                    04:f1:a3:ff:46:e9:3a:cd:4d:9d:8c:10:4a:fe:2a:
                    f5:9c:b9:a0:ec:73:29:cf:2a:3a:58:c6:57:fc:24:
                    37:90:2e:08:5b:e0:0e:63:50:1d:20:21:13:e4:95:
                    df:a4:b1:23:be:19:97:eb:ce:80:a8:aa:d5:cd:cd:
                    4a:36:d9:85:3f
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
...
```

The last comment output is my entire output when I `openssl connect` and there isn't  the `Subject Public Key Info` block, in fact reading it better trying to find this block there's some returns that can clarify the problem, but I don't how to fix it.
```
verify return:1
140257510512280:error:1411713E:SSL routines:ssl_check_srvr_ecc_cert_and_alg:ecc cert not for signing:ssl_lib.c:2514:
140257510512280:error:14082130:SSL routines:ssl3_check_cert_and_algorithm:bad ecc cert:s3_clnt.c:3535:
---
```

You need to pipe the certificate to ``| openssl x509 -text`` to print the certificate as human readable text. Please also include the ``Signature Algorithm:``, ``X509v3 Key Usage`` and ``X509v3 Extended Key Usage`` blocks. Your cert may be missing ``Digital Signature`` key usage.

Oh, I'm so sorry I didn't see the horizontal scroll bar :confused: 
Here's the output you asked for!

```
depth=0 C = BR, ST = Distrito Federal, L = Brasilia, O = GoLedger, CN = ca.goledger.com
verify return:1
139867698919064:error:1411713E:SSL routines:ssl_check_srvr_ecc_cert_and_alg:ecc cert not for signing:ssl_lib.c:2514:
139867698919064:error:14082130:SSL routines:ssl3_check_cert_and_algorithm:bad ecc cert:s3_clnt.c:3535:
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            73:e2:d4:9c:86:cf:c6:6c:7d:d5:05:52:51:3d:20:95:56:5a:a1:c7
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=BR, ST=Distrito Federal, L=Brasilia, O=GoLedger, CN=ca.goledger.com
        Validity
            Not Before: Jan 15 17:06:00 2018 GMT
            Not After : Jan 11 17:06:00 2033 GMT
        Subject: C=BR, ST=Distrito Federal, L=Brasilia, O=GoLedger, CN=ca.goledger.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub: 
                    04:a2:05:8d:1c:59:90:fb:e6:db:82:f7:5c:04:f7:
                    0c:b7:5f:69:be:40:a3:ba:cb:6f:83:02:25:64:f1:
                    6c:68:3c:9b:0f:8d:cf:e3:e6:e5:3b:e6:e8:22:e0:
                    8d:51:83:3a:3e:c4:5c:14:9d:06:79:70:2e:f2:b4:
                    19:c5:1f:b1:3b
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:1
            X509v3 Subject Key Identifier: 
                F1:8B:A6:2F:54:F8:E9:A2:EA:D2:17:99:F6:87:B0:42:F7:E1:D1:6E
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:8e:28:9f:f2:6e:a2:d4:31:46:4c:01:64:e0:
         e6:b6:6d:09:19:8f:25:32:08:8f:13:1f:fc:04:3d:3f:5b:a2:
         23:02:20:1e:0d:25:f9:f0:95:08:4b:b9:ec:49:c9:cc:29:c6:
         b1:4c:80:74:f0:16:ae:0a:53:a8:83:40:d6:3a:ce:a5:bb
```

The certificate is a CA cert, not a server cert. Did the CA send you this cert together with a matching private key? Asking for a friend...

No, there's the pair inside server and I can get both this certs getting from inside the server itself. 
But our CA is a fabric-ca, part of hyperledger-fabric project, normally we do requests using ca cert as tls certificate and everything goes well, no ECC cert is used at others sdk's or via client command line

I checked in server, I do have a private key for server, but there's only a public cert which is the 'ca-cert.pem' that I'm using to make those requests to CA server

Yeah, so like I thought, this has nothing to do with requests. The problem is in the certificate chain you're using. The fact that we don't magic every possible input that cURL also handles isn't a bug. It's something Requests itself flat out just can't possibly handle every permutation of. I'm going to close this. I'd ask you two to continue this conversation elsewhere and update this with a conclusion in case someone else stumbles upon it.

Ok, @sigmavirus24 I'm grateful for your time and @tiran's. 
I opened issue as last resort in order to solve this problem, I've got a better idea about the problem itself now, thanks again!

Just got the same issue by using requests with the fabric-sdk-py from hyperledger fabric too.
Sorry, it is clearly not related to requests, but @vieiramanoel did you find the solution to the problem? Can you point me out to a referenced issue?
I'd really appreciate that. Thanks

EDIT : ended up on the hyperledger fabric-sdk-py gerrit and added a PR by using `pycurl`
https://jira.hyperledger.org/browse/FAB-7743?jql=text%20~%20%22Python-SDK%22

Anyone has some clue of the root cause?

If pycurl/curl can work, but requests lib cannot work, then means something wrong in the requests lib?

@yeasy, this is an issue with openssl and the certificate chain being used. The reason pycurl works is because it has an additional dependency on libcurl-openssl-dev which is allowing cert resolution. We don't have an good way to support this behavior in Requests and as @sigmavirus24 stated can't support everything that curl does.

This issue specifically related to hyperledger has been determined.
The `X509v3 extensions` are not correctly generated when creating the certificate.

You can read the whole thread here: https://jira.hyperledger.org/browse/FABP-68