@@ -324,6 +324,9 @@ typedef struct {
324324 PyObject * set_hostname ;
325325#endif
326326 int check_hostname ;
327+ #ifdef TLS1_3_VERSION
328+ int post_handshake_auth ;
329+ #endif
327330} PySSLContext ;
328331
329332typedef struct {
@@ -606,6 +609,28 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
606609#endif
607610 SSL_set_mode (self -> ssl , mode );
608611
612+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
613+ * server sockets and SSL_set_post_handshake_auth() for client. */
614+ // #ifdef TLS1_3_VERSION
615+ // if (sslctx->post_handshake_auth == 1) {
616+ // if (socket_type == PY_SSL_SERVER) {
617+ // /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE.
618+ // * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and
619+ // * only in combination with SSL_VERIFY_PEER flag. */
620+ // int mode = SSL_get_verify_mode(self->ssl);
621+ // if (mode & SSL_VERIFY_PEER) {
622+ // int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
623+ // verify_cb = SSL_get_verify_callback(self->ssl);
624+ // mode |= SSL_VERIFY_POST_HANDSHAKE;
625+ // SSL_set_verify(self->ssl, mode, verify_cb);
626+ // }
627+ // } else {
628+ // /* client socket */
629+ // SSL_set_post_handshake_auth(self->ssl, 1);
630+ // }
631+ // }
632+ // #endif
633+
609634#if HAVE_SNI
610635 if (server_hostname != NULL ) {
611636/* Don't send SNI for IP addresses. We cannot simply use inet_aton() and
@@ -2308,6 +2333,11 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23082333 }
23092334#endif
23102335
2336+ #ifdef TLS1_3_VERSION
2337+ self -> post_handshake_auth = 0 ;
2338+ SSL_CTX_set_post_handshake_auth (self -> ctx , self -> post_handshake_auth );
2339+ #endif
2340+
23112341 return (PyObject * )self ;
23122342}
23132343
@@ -2527,6 +2557,8 @@ static int
25272557set_verify_mode (PySSLContext * self , PyObject * arg , void * c )
25282558{
25292559 int n , mode ;
2560+ int (* verify_cb )(int , X509_STORE_CTX * ) = NULL ;
2561+
25302562 if (!PyArg_Parse (arg , "i" , & n ))
25312563 return -1 ;
25322564 if (n == PY_SSL_CERT_NONE )
@@ -2540,13 +2572,20 @@ set_verify_mode(PySSLContext *self, PyObject *arg, void *c)
25402572 "invalid value for verify_mode" );
25412573 return -1 ;
25422574 }
2575+
25432576 if (mode == SSL_VERIFY_NONE && self -> check_hostname ) {
25442577 PyErr_SetString (PyExc_ValueError ,
25452578 "Cannot set verify_mode to CERT_NONE when "
25462579 "check_hostname is enabled." );
25472580 return -1 ;
25482581 }
2549- SSL_CTX_set_verify (self -> ctx , mode , NULL );
2582+
2583+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
2584+ * server sockets and SSL_set_post_handshake_auth() for client. */
2585+
2586+ /* keep current verify cb */
2587+ verify_cb = SSL_CTX_get_verify_callback (self -> ctx );
2588+ SSL_CTX_set_verify (self -> ctx , mode , verify_cb );
25502589 return 0 ;
25512590}
25522591
@@ -2651,6 +2690,27 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c)
26512690 return 0 ;
26522691}
26532692
2693+ #if TLS1_3_VERSION
2694+ static int
2695+ set_post_handshake_auth (PySSLContext * self , PyObject * arg , void * c ) {
2696+ if (arg == NULL ) {
2697+ PyErr_SetString (PyExc_AttributeError , "cannot delete attribute" );
2698+ return -1 ;
2699+ }
2700+ int pha = PyObject_IsTrue (arg );
2701+
2702+ if (pha == -1 ) {
2703+ return -1 ;
2704+ }
2705+ self -> post_handshake_auth = pha ;
2706+
2707+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
2708+ * server sockets and SSL_set_post_handshake_auth() for client. */
2709+
2710+ return 0 ;
2711+ }
2712+ #endif
2713+
26542714
26552715typedef struct {
26562716 PyThreadState * thread_state ;
0 commit comments