Index: doc/tls.html
==================================================================
--- doc/tls.html
+++ doc/tls.html
@@ -171,10 +171,12 @@
Callback to invoke when OpenSSL needs to obtain a password,
typically to unlock the private key of a certificate. The
callback should return a string which represents the password
to be used. See CALLBACK OPTIONS
for further discussion.
+ -post_handshake bool
+ Allow post-handshake ticket updates.
-request bool
Request a certificate from peer during SSL handshake.
(default is true)
-require bool
Require a valid certificate from peer during SSL handshake.
Index: generic/tls.c
==================================================================
--- generic/tls.c
+++ generic/tls.c
@@ -1071,11 +1071,11 @@
const unsigned char *session_id = NULL;
Tcl_Obj *alpn = NULL;
int ssl2 = 0, ssl3 = 0;
int tls1 = 1, tls1_1 = 1, tls1_2 = 1, tls1_3 = 1;
int proto = 0, level = -1;
- int verify = 0, require = 0, request = 1;
+ int verify = 0, require = 0, request = 1, post_handshake = 0;
dprintf("Called");
#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) && defined(NO_SSL3) && defined(NO_TLS1) && defined(NO_TLS1_1) && defined(NO_TLS1_2) && defined(NO_TLS1_3)
ssl2 = 1;
@@ -1124,10 +1124,11 @@
OPTOBJ("-command", script);
OPTSTR("-dhparams", DHparams);
OPTSTR("-keyfile", keyfile);
OPTSTR("-model", model);
OPTOBJ("-password", password);
+ OPTBOOL("-post_handshake", post_handshake);
OPTBOOL("-require", require);
OPTBOOL("-request", request);
OPTINT("-securitylevel", level);
OPTBOOL("-server", server);
OPTSTR("-servername", servername);
@@ -1146,10 +1147,11 @@
return TCL_ERROR;
}
if (request) verify |= SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_PEER;
if (request && require) verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ if (request && post_handshake) verify |= SSL_VERIFY_POST_HANDSHAKE;
if (verify == 0) verify = SSL_VERIFY_NONE;
proto |= (ssl2 ? TLS_PROTO_SSL2 : 0);
proto |= (ssl3 ? TLS_PROTO_SSL3 : 0);
proto |= (tls1 ? TLS_PROTO_TLS1 : 0);
@@ -1361,17 +1363,27 @@
/* Server callbacks */
SSL_CTX_set_alpn_select_cb(statePtr->ctx, ALPNCallback, (void *)statePtr);
SSL_CTX_set_tlsext_servername_arg(statePtr->ctx, (void *)statePtr);
SSL_CTX_set_tlsext_servername_callback(statePtr->ctx, SNICallback);
SSL_CTX_set_client_hello_cb(statePtr->ctx, HelloCallback, (void *)statePtr);
+
+ /* Enable server to send cert request after handshake (TLS 1.3 only) */
+ if (request && post_handshake) {
+ SSL_verify_client_post_handshake(statePtr->ssl);
+ }
statePtr->flags |= TLS_TCL_SERVER;
SSL_set_accept_state(statePtr->ssl);
} else {
/* Session caching */
SSL_CTX_set_session_cache_mode(statePtr->ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
SSL_CTX_sess_set_new_cb(statePtr->ctx, SessionCallback);
+
+ /* Enable post handshake Authentication extension. TLS 1.3 only, not http/2. */
+ if (request && post_handshake) {
+ SSL_set_post_handshake_auth(statePtr->ssl, 1);
+ }
SSL_set_connect_state(statePtr->ssl);
}
SSL_set_bio(statePtr->ssl, statePtr->p_bio, statePtr->p_bio);
BIO_set_ssl(statePtr->bio, statePtr->ssl, BIO_NOCLOSE);