classification
Title: ssl should raise an exception when trying to load an unusable key (ECC key not using a named curve)
Type: behavior Stage: resolved
Components: Extension Modules, SSL Versions: Python 3.5
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: christian.heimes Nosy List: abacabadabacaba, benjamin.peterson, christian.heimes
Priority: normal Keywords:

Created on 2016-02-01 01:50 by abacabadabacaba, last changed 2016-09-15 08:20 by christian.heimes. This issue is now closed.

Messages (4)
msg259305 - (view) Author: Evgeny Kapun (abacabadabacaba) Date: 2016-02-01 01:50
I tried to use ssl module to create a server with a certificate that uses an ECC key. However, this didn't work. Here is how to reproduce this:

First, generate a key and a certificate:

    $ openssl req -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -x509 -keyout key.pem -out cert.pem
    (type some passphrase, then just press Enter in response to the questions that it asks)

Then run this Python program:

    from socket import socket
    from ssl import wrap_socket
    s = socket()
    s.bind(('localhost', 12345))
    s.listen()
    wrap_socket(s.accept()[0], 'key.pem', 'cert.pem', True)

This program will wait for a connection, so try to connect:

    $ openssl s_client -connect localhost:12345

The program will ask for a passphrase, so type it. After that, you will get an exception:

    Traceback (most recent call last):
      File "test.py", line 6, in <module>
        wrap_socket(s.accept()[0], 'key.pem', 'cert.pem', True)
      File "/usr/lib/python3.5/ssl.py", line 1064, in wrap_socket
        ciphers=ciphers)
      File "/usr/lib/python3.5/ssl.py", line 747, in __init__
        self.do_handshake()
      File "/usr/lib/python3.5/ssl.py", line 983, in do_handshake
        self._sslobj.do_handshake()
      File "/usr/lib/python3.5/ssl.py", line 628, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:645)

If the certificate uses RSA key, it works. With ECC, I had no luck. I tried creating a context explicitly and using set_ciphers method to enable more ciphers. While it appears to support ECDSA ciphersuites, it can't use them for some reason.
msg259315 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2016-02-01 06:21
ECC certs using named curves have to have the OPENSSL_EC_NAMED_CURVE flag set. Pass -pkeyopt ec_param_enc:named_curve to the openssl req.
msg259348 - (view) Author: Evgeny Kapun (abacabadabacaba) Date: 2016-02-02 00:52
So, it looks like OpenSSL doesn't support keys using arbitrary curves at all. Then why don't I get an exception when trying to load such a key? Instead it just quietly disables all authenticated ciphersuites (anonymous ciphersuites still work) and then I get a confusing exception about lack of shared ciphers. I think that if it can't use a key, it should raise an exception right away.
msg276532 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2016-09-15 08:20
The SSL module uses SSL_CTX_check_private_key() to verify the private key. Further validations are up to OpenSSL or you.
History
Date User Action Args
2016-09-15 08:20:23christian.heimessetstatus: open -> closed

assignee: christian.heimes
components: + SSL

nosy: + christian.heimes
messages: + msg276532
resolution: rejected
stage: resolved
2016-02-02 00:52:41abacabadabacabasetstatus: closed -> open
resolution: not a bug -> (no value)
messages: + msg259348

title: ssl server doesn't work with ECC certificates -> ssl should raise an exception when trying to load an unusable key (ECC key not using a named curve)
2016-02-01 06:21:21benjamin.petersonsetstatus: open -> closed

nosy: + benjamin.peterson
messages: + msg259315

resolution: not a bug
2016-02-01 01:50:17abacabadabacabacreate