Repository navigation
Add set_post_handshake_auth for TLS 1.3 #78851
Description
Activity
TLS 1.3 removed renegotiation in favor of rekeying and post handshake authentication (PHA). With PHA, a server can request a client certificate from a client at some point after the handshake. The feature is commonly used by HTTP server for conditional and path specific TLS client auth. For example a server can decide to require a cert based on HTTP method and/or path. A client must announce support for PHA during the handshake
Apache mod_ssl uses PHA, https://github.com/apache/httpd/blob/trunk/modules/ssl/ssl_engine_kernel.c#L1207
As of OpenSSL ticket openssl/openssl#6933, TLS 1.3 clients no longer send the PHA TLS extension by default. Nikos and I requested the change, because PHA breaks some assumptions of TLS 1.2 clients. For on-demand auth, PHA extension must be enabled with SSL_CTX_set_post_handshake_auth(), https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_post_handshake_auth.html .
I propose to add a property on SSLContext to enable PHA and backport the change to Python 2.7, 3.6 and 3.7.
In order to test the feature, I'd also have to add some flags and a function for the server side: (SSL_VERIFY_CLIENT_ONCE, SSL_VERIFY_POST_HANDSHAKE, SSL_verify_client_post_handshake()).
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Sep 14, 2018 Please note that SSL_verify_client_post_handshake() doesn't perform any IO by itself.
A typical scenario for HTTP looks like this (actual flow may vary):
- client
- send
HTTP GET /path
- send
- server
- recv
- verify_client_post_handshake
- send HTTP Connection Upgrade (emits CertRequest message)
- client
- recv
- send upgrade confirmation (emits Certificate, CertificateVerify, Finish message)
- server
- recv
- verify certificate
- send payload or error (may emit TLS alert for unknown, invalid, or missing cert)
- client
- recv (receive TLS alert or server response)
- client
Will this be backported to the 2.7 branch as well? Pretty please =)
FYI Christian, your "typical scenario for HTTP" doesn't make sense to me... you can't send HTTP Connection Upgrade in the middle of a regular request/response cycle. I feel like the typical scenario ought to be more like:
- client
- send
HTTP GET /path
- send
- server
- recv
- verify_client_post_handshake (maybe... via calling SSL_do_handshake again?)
- client
- recv
- send upgrade confirmation (emits Certificate, CertificateVerify, Finish message)
- server
- recv
- verify certificate
- send either the requested response, or a 401 Unauthorized depending
But I don't really understand the underlying design here, either at the TLS 1.3 level or the openssl level, and haven't found very useful docs yet, so I could be wrong.
- client
I don't think is anything left to do here. PHA has been supported for a while and I haven't seen any problems.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields: