This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ssl.get_server_certificate should allow specifying certificate / key type
Type: enhancement Stage: needs patch
Components: SSL Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: alex, christian.heimes, dstufft, hanno, janssen
Priority: normal Keywords:

Created on 2017-10-29 09:59 by hanno, last changed 2022-04-11 14:58 by admin.

Messages (5)
msg305182 - (view) Author: Hanno Boeck (hanno) * Date: 2017-10-29 09:59
The function ssl.get_server_certificate() from the ssl module is supposed to allow fetching the certificate of a TLS server.

However in its current form it provides no way to specify a key type. Many popular hosts (e.g. facebook, google) support both ECDSA and RSA these days, depending on the cipher suites one uses to try to connect to them.

If one wants to fetch the RSA certificate of e.g. facbeook this is not possible with the current python ssl module, as it will always output the ECDSA certificate. One can create a connection with an SSLContext that has only RSA ciphers set, but it's not possible to get the certificate out of an SSLContext. And the get_server_certificate function provides neither a way to bind it to a context nor a way to specify ciphers or key types.

I think there should be an optional parameter to get_server_certificate that allows asking for a specific key type.
msg305380 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-11-01 13:19
Thanks for your feature request, Hanno.

It's fairly easy to implement with current API for TLS protocols up to TLS 1.2, e.g. cipher suite "DEFAULT:!aRSA:!aDSS" or "aECDSA:!NULL" for ECDSA certs.

However TLS 1.3 cipher suites no longer specify authentication and KE/KX algorithms, e.g. TLS13-AES-256-GCM-SHA384. I have to find a way to force OpenSSL's state machine to establish a connection with a specific authentication algorithm.

Memo to me: TLS 1.3 also has EdDSA.
msg305414 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-11-02 10:51
Example implementation of get_server_certificate() with cert type: https://gist.github.com/tiran/6e7a5b00483376e164c951730db7d4e5

TLS 1.3 has a signature_algorithms extension that allows a client to have even more control over the selected certificate and signature algorithms. It defines authentication algorithm (RSA, ECDSA, EdDSA), signature scheme (PKCS#1 v1.5 or PKCS#1 v2.1 aka RSA-PSS for RSA, curve for ECDSA), and hashing algorithm (SHA-1, SHA-2 256/384/512). https://tools.ietf.org/html/draft-ietf-tls-tls13-21#section-4.2.3

I've contacted openssl maintainers and asked them for advice: https://mta.openssl.org/pipermail/openssl-users/2017-November/006834.html
msg305420 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-11-02 12:21
Matt suggested to use https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_sigalgs.html The SSL_CTX_set1_sigalgs_list() function takes a string of colon-separated algorithms, e.g. "ECDSA+SHA256:RSA+SHA256" for ECDSA and PKCS#1 v1.5 RSA with both SHA256 as hashing algorithm.
msg415242 - (view) Author: Hanno Boeck (hanno) * Date: 2022-03-15 13:21
Any update? :-)
History
Date User Action Args
2022-04-11 14:58:53adminsetgithub: 76073
2022-03-15 13:21:55hannosetmessages: + msg415242
2018-02-26 08:29:59christian.heimessetassignee: christian.heimes ->
stage: needs patch
versions: + Python 3.8, - Python 2.7, Python 3.6, Python 3.7
2017-11-02 12:21:30christian.heimessetmessages: + msg305420
2017-11-02 10:51:04christian.heimessetmessages: + msg305414
2017-11-01 13:19:31christian.heimessetnosy: + janssen, alex, dstufft

messages: + msg305380
versions: + Python 2.7, Python 3.6, Python 3.7
2017-10-29 09:59:06hannocreate