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