1.. Licensed to the Apache Software Foundation (ASF) under one 2 or more contributor license agreements. See the NOTICE file 3 distributed with this work for additional information 4 regarding copyright ownership. The ASF licenses this file 5 to you under the Apache License, Version 2.0 (the 6 "License"); you may not use this file except in compliance 7 with the License. You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11 Unless required by applicable law or agreed to in writing, 12 software distributed under the License is distributed on an 13 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 KIND, either express or implied. See the License for the 15 specific language governing permissions and limitations 16 under the License. 17 18.. include:: ../../../common.defs 19 20.. _developer-plugins-ssl-hooks: 21 22TLS User Agent Hooks 23******************** 24 25In addition to the HTTP oriented hooks, a plugin can add hooks (by calling :c:func:`TSHttpHookAdd`) 26to trigger code during the TLS handshake with the user agent. This TLS handshake occurs well 27before the HTTP transaction is available, so a separate state machine is required to track the 28TLS hooks. 29 30TLS Hooks 31--------- 32 33In all cases, the hook callback has the following signature. 34 35.. function:: int SSL_callback(TSCont contp, TSEvent event, void * edata) 36 37The edata parameter is a TSVConn object. 38 39The following actions are valid from these callbacks. 40 41 * Fetch the SSL object associated with the connection - :c:func:`TSVConnSslConnectionGet` 42 * Set a connection to blind tunnel - :c:func:`TSVConnTunnel` 43 * Re-enable the ssl connection - :c:func:`TSVConnReenable` 44 * Find SSL context by name - :c:func:`TSSslContextFindByName` 45 * Find SSL context by address - :c:func:`TSSslContextFindByAddr` 46 * Determine whether the TSVConn is really representing a SSL connection - :c:func:`TSVConnIsSsl` 47 48TS_VCONN_START_HOOK 49------------------------ 50 51This hook is invoked after the client has connected to ATS and before the SSL handshake is started, 52i.e., before any bytes have been read from the client. The data for the callback is a TSVConn 53instance which represents the client connection. There is no HTTP transaction as no headers have 54been read. 55 56In theory this hook could apply and be useful for non-SSL connections as well, but at this point 57this hook is only called in the SSL sequence. 58 59The TLS handshake processing will not proceed until :c:func:`TSVConnReenable()` is called either 60from within the hook callback or from another piece of code. 61 62TS_VCONN_CLOSE_HOOK 63------------------------ 64 65This hook is invoked after the SSL handshake is done and when the IO is closing. The TSVConnArgs 66should be cleaned up here. A callback at this point must re-enable. 67 68TS_SSL_CLIENT_HELLO_HOOK 69------------------------ 70 71This hook is called when the client hello arrived for the TLS handshake. If called it will always be 72called after TS_VCONN_START_HOOK. The plugin callback can execute code to examine client hello 73information. 74 75TLS handshake processing will pause until the hook callback executes :c:func:`TSVConnReenable()`. 76 77TS_SSL_SERVERNAME_HOOK 78---------------------- 79 80This hook is called if the client provides SNI information in the SSL handshake. If called it will 81always be called after TS_VCONN_START_HOOK. 82 83The Traffic Server core first evaluates the settings in the ssl_multicert.config file based on the 84server name. Then the core SNI callback executes the plugin registered SNI callback code. The plugin 85callback can access the servername by calling the openssl function SSL_get_servername(). 86 87Processing will continue regardless of whether the hook callback executes 88:c:func:`TSVConnReenable()` since the openssl implementation does not allow for pausing processing 89during the openssl servername callback. 90 91TS_SSL_CERT_HOOK 92---------------- 93 94This hook is called as the server certificate is selected for the TLS handshake. The plugin callback 95can execute code to create or select the certificate that should be used for the TLS handshake. 96This will override the default Traffic Server certificate selection. 97 98If you are running with openssl 1.0.2 or later, you can control whether the TLS handshake processing 99will continue after the certificate hook callback execute by calling :c:func:`TSVConnReenable()` or 100not. The TLS handshake processing will not proceed until :c:func:`TSVConnReenable()` is called. 101 102It may be useful to delay the TLS handshake processing if other resources must be consulted to 103select or create a certificate. 104 105TS_SSL_VERIFY_CLIENT_HOOK 106------------------------- 107 108This hook is called when a client connects to |TS| and presents a client certificate in the case of 109a mutual TLS handshake. The callback can use the TSVConn argument and fetch the TSSslVerifyCTX 110object using the :c:func:`TSVConnSslVerifyCTXGet()` method and fetch the peer's certificates to make 111any additional checks. 112 113Processing will continue regardless of whether the hook callback executes 114:c:func:`TSVConnReenable()` since the openssl implementation does not allow for pausing processing 115during the certificate verify callback. The plugin can use the :c:func:`TSVConnReenableEx()` 116function to pass in the TS_EVENT_ERROR and stop the TLS handshake. 117 118TS_SSL_VERIFY_SERVER_HOOK 119------------------------- 120 121This hook is called when a Traffic Server connects to an origin and the origin presents a 122certificate. The callback can use the TSVConn argument and fetch the TSSslVerifyCTX object using 123the :c:func:`TSVConnSslVerifyCTXGet()` method and fetch the peer's certificates to make any 124additional checks. 125 126Processing will continue regardless of whether the hook callback executes 127:c:func:`TSVConnReenable()` since the openssl implementation does not allow for pausing processing 128during the certificate verify callback. The plugin can use the :c:func:`TSVConnReenableEx()` 129function to pass in the TS_EVENT_ERROR and 130 131TS_VCONN_OUTBOUND_START_HOOK 132---------------------------- 133 134This hook is invoked after ATS has connected to the upstream server and before the SSL handshake has 135started. This gives the plugin the option of overriding the default SSL connection options on the 136SSL object. 137 138In theory this hook could apply and be useful for non-SSL connections as well, but at this point 139this hook is only called in the SSL sequence. 140 141The TLS handshake processing will not proceed until :c:func:`TSVConnReenable()` is called either 142from within the hook callback or from another piece of code. 143 144TS_VCONN_OUTBOUND_CLOSE_HOOK 145----------------------------- 146 147This hook is invoked after the SSL handshake is done and right before the outbound connection 148closes. A callback at this point must re-enable. 149 150TLS Inbound Hook State Diagram 151------------------------------ 152 153.. graphviz:: 154 :alt: TLS Inbound Hook State Diagram 155 156 digraph tls_hook_state_diagram{ 157 HANDSHAKE_HOOKS_PRE -> TS_VCONN_START_HOOK; 158 HANDSHAKE_HOOKS_PRE -> TS_SSL_CERT_HOOK; 159 HANDSHAKE_HOOKS_PRE -> TS_SSL_SERVERNAME_HOOK; 160 HANDSHAKE_HOOKS_PRE -> HANDSHAKE_HOOKS_DONE; 161 TS_VCONN_START_HOOK -> HANDSHAKE_HOOKS_PRE_INVOKE; 162 HANDSHAKE_HOOKS_PRE_INVOKE -> TSVConnReenable; 163 TSVConnReenable -> HANDSHAKE_HOOKS_PRE; 164 TS_SSL_CLIENT_HELLO_HOOK -> HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE; 165 HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE -> TSVConnReenable2; 166 TSVConnReenable2 -> HANDSHAKE_HOOKS_CLIENT_HELLO; 167 HANDSHAKE_HOOKS_CLIENT_HELLO -> TS_SSL_CLIENT_HELLO_HOOK; 168 HANDSHAKE_HOOKS_CLIENT_HELLO -> TS_SSL_SERVERNAME_HOOK; 169 TS_SSL_SERVERNAME_HOOK -> HANDSHAKE_HOOKS_SNI; 170 HANDSHAKE_HOOKS_SNI -> TS_SSL_SERVERNAME_HOOK; 171 HANDSHAKE_HOOKS_SNI -> TS_SSL_CERT_HOOK; 172 HANDSHAKE_HOOKS_SNI -> HANDSHAKE_HOOKS_DONE; 173 HANDSHAKE_HOOKS_CERT -> TS_SSL_CERT_HOOK; 174 TS_SSL_CERT_HOOK -> HANDSHAKE_HOOKS_CERT_INVOKE; 175 HANDSHAKE_HOOKS_CERT_INVOKE -> TSVConnReenable3; 176 TSVConnReenable3 -> HANDSHAKE_HOOKS_CERT; 177 178 HANDSHAKE_HOOKS_CERT -> TS_SSL_VERIFY_CLIENT_HOOK; 179 HANDSHAKE_HOOKS_SNI -> TS_SSL_VERIFY_CLIENT_HOOK; 180 HANDSHAKE_HOOKS_PRE -> TS_SSL_VERIFY_CLIENT_HOOK; 181 TS_SSL_VERIFY_CLIENT_HOOK -> HANDSHAKE_HOOKS_VERIFY; 182 HANDSHAKE_HOOKS_VERIFY -> TS_SSL_VERIFY_CLIENT_HOOK; 183 HANDSHAKE_HOOKS_VERIFY -> HANDSHAKE_HOOKS_DONE; 184 185 HANDSHAKE_HOOKS_CERT -> HANDSHAKE_HOOKS_DONE; 186 HANDSHAKE_HOOKS_DONE -> TS_VCONN_CLOSE_HOOK; 187 TS_VCONN_CLOSE_HOOK -> HANDSHAKE_HOOKS_DONE; 188 189 HANDSHAKE_HOOKS_PRE [shape=box]; 190 HANDSHAKE_HOOKS_PRE_INVOKE [shape=box]; 191 HANDSHAKE_HOOKS_CLIENT_HELLO [shape=box]; 192 HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE [shape=box]; 193 HANDSHAKE_HOOKS_SNI [shape=box]; 194 HANDSHAKE_HOOKS_VERIFY [shape=box]; 195 HANDSHAKE_HOOKS_CERT [shape=box]; 196 HANDSHAKE_HOOKS_CERT_INVOKE [shape=box]; 197 HANDSHAKE_HOOKS_DONE [shape=box]; 198 } 199 200TLS Outbound Hook State Diagram 201------------------------------- 202 203.. graphviz:: 204 :alt: TLS Outbound Hook State Diagram 205 206 digraph tls_hook_state_diagram{ 207 HANDSHAKE_HOOKS_OUTBOUND_PRE -> TS_VCONN_OUTBOUND_START_HOOK; 208 TS_VCONN_OUTBOUND_START_HOOK -> HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE; 209 HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE-> TSVConnReenable; 210 TSVConnReenable -> HANDSHAKE_HOOKS_OUTBOUND_PRE; 211 HANDSHAKE_HOOKS_OUTBOUND_PRE -> TS_SSL_VERIFY_SERVER_HOOK; 212 TS_SSL_VERIFY_SERVER_HOOK -> HANDSHAKE_HOOKS_OUTBOUND_PRE; 213 HANDSHAKE_HOOKS_OUTBOUND_PRE -> TS_VCONN_OUTBOUND_CLOSE; 214 TS_VCONN_OUTBOUND_CLOSE -> HANDSHAKE_HOOKS_OUTBOUND_PRE; 215 TS_VCONN_OUTBOUND_CLOSE -> HANDSHAKE_HOOKS_DONE; 216 217 HANDSHAKE_HOOKS_OUTBOUND_PRE [shape=box]; 218 HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE [shape=box]; 219 HANDSHAKE_HOOKS_DONE [shape=box]; 220 } 221 222