/src/nss/lib/ssl/ssl3ext.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * SSL3 Protocol |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
8 | | |
9 | | /* TLS extension code moved here from ssl3ecc.c */ |
10 | | |
11 | | #include "nssrenam.h" |
12 | | #include "nss.h" |
13 | | #include "pk11pub.h" |
14 | | #include "ssl.h" |
15 | | #include "sslimpl.h" |
16 | | #include "sslproto.h" |
17 | | #include "ssl3exthandle.h" |
18 | | #include "tls13ech.h" |
19 | | #include "tls13err.h" |
20 | | #include "tls13exthandle.h" |
21 | | #include "tls13subcerts.h" |
22 | | |
23 | | /* Callback function that handles a received extension. */ |
24 | | typedef SECStatus (*ssl3ExtensionHandlerFunc)(const sslSocket *ss, |
25 | | TLSExtensionData *xtnData, |
26 | | SECItem *data); |
27 | | |
28 | | /* Row in a table of hello extension handlers. */ |
29 | | typedef struct { |
30 | | SSLExtensionType ex_type; |
31 | | ssl3ExtensionHandlerFunc ex_handler; |
32 | | } ssl3ExtensionHandler; |
33 | | |
34 | | /* Table of handlers for received TLS hello extensions, one per extension. |
35 | | * In the second generation, this table will be dynamic, and functions |
36 | | * will be registered here. |
37 | | */ |
38 | | /* This table is used by the server, to handle client hello extensions. */ |
39 | | static const ssl3ExtensionHandler clientHelloHandlers[] = { |
40 | | { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
41 | | { ssl_supported_groups_xtn, &ssl_HandleSupportedGroupsXtn }, |
42 | | { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, |
43 | | { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
44 | | { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
45 | | { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn }, |
46 | | { ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn }, |
47 | | { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, |
48 | | { ssl_tls13_certificate_authorities_xtn, &tls13_ServerHandleCertAuthoritiesXtn }, |
49 | | { ssl_signature_algorithms_xtn, &ssl3_HandleSigAlgsXtn }, |
50 | | { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, |
51 | | { ssl_signed_cert_timestamp_xtn, &ssl3_ServerHandleSignedCertTimestampXtn }, |
52 | | { ssl_delegated_credentials_xtn, &tls13_ServerHandleDelegatedCredentialsXtn }, |
53 | | { ssl_tls13_key_share_xtn, &tls13_ServerHandleKeyShareXtn }, |
54 | | { ssl_tls13_pre_shared_key_xtn, &tls13_ServerHandlePreSharedKeyXtn }, |
55 | | { ssl_tls13_early_data_xtn, &tls13_ServerHandleEarlyDataXtn }, |
56 | | { ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ServerHandlePskModesXtn }, |
57 | | { ssl_tls13_cookie_xtn, &tls13_ServerHandleCookieXtn }, |
58 | | { ssl_tls13_post_handshake_auth_xtn, &tls13_ServerHandlePostHandshakeAuthXtn }, |
59 | | { ssl_record_size_limit_xtn, &ssl_HandleRecordSizeLimitXtn }, |
60 | | { ssl_certificate_compression_xtn, &ssl3_HandleCertificateCompressionXtn }, |
61 | | { 0, NULL } |
62 | | }; |
63 | | |
64 | | /* These two tables are used by the client, to handle server hello |
65 | | * extensions. */ |
66 | | static const ssl3ExtensionHandler serverHelloHandlersTLS[] = { |
67 | | { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
68 | | /* TODO: add a handler for ssl_ec_point_formats_xtn */ |
69 | | { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
70 | | { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
71 | | { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn }, |
72 | | { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn }, |
73 | | { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, |
74 | | { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, |
75 | | { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn }, |
76 | | { ssl_tls13_key_share_xtn, &tls13_ClientHandleKeyShareXtn }, |
77 | | { ssl_tls13_pre_shared_key_xtn, &tls13_ClientHandlePreSharedKeyXtn }, |
78 | | { ssl_tls13_early_data_xtn, &tls13_ClientHandleEarlyDataXtn }, |
79 | | { ssl_tls13_encrypted_client_hello_xtn, &tls13_ClientHandleEchXtn }, |
80 | | { ssl_record_size_limit_xtn, &ssl_HandleRecordSizeLimitXtn }, |
81 | | { 0, NULL } |
82 | | }; |
83 | | |
84 | | static const ssl3ExtensionHandler helloRetryRequestHandlers[] = { |
85 | | { ssl_tls13_key_share_xtn, tls13_ClientHandleKeyShareXtnHrr }, |
86 | | { ssl_tls13_cookie_xtn, tls13_ClientHandleHrrCookie }, |
87 | | { ssl_tls13_encrypted_client_hello_xtn, tls13_ClientHandleHrrEchXtn }, |
88 | | { 0, NULL } |
89 | | }; |
90 | | |
91 | | static const ssl3ExtensionHandler serverHelloHandlersSSL3[] = { |
92 | | { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
93 | | { 0, NULL } |
94 | | }; |
95 | | |
96 | | static const ssl3ExtensionHandler newSessionTicketHandlers[] = { |
97 | | { ssl_tls13_early_data_xtn, |
98 | | &tls13_ClientHandleTicketEarlyDataXtn }, |
99 | | { 0, NULL } |
100 | | }; |
101 | | |
102 | | /* This table is used by the client to handle server certificates in TLS 1.3 */ |
103 | | static const ssl3ExtensionHandler serverCertificateHandlers[] = { |
104 | | { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn }, |
105 | | { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, |
106 | | { ssl_delegated_credentials_xtn, &tls13_ClientHandleDelegatedCredentialsXtn }, |
107 | | { 0, NULL } |
108 | | }; |
109 | | |
110 | | static const ssl3ExtensionHandler certificateRequestHandlers[] = { |
111 | | { ssl_signature_algorithms_xtn, &ssl3_HandleSigAlgsXtn }, |
112 | | { ssl_tls13_certificate_authorities_xtn, |
113 | | &tls13_ClientHandleCertAuthoritiesXtn }, |
114 | | { ssl_certificate_compression_xtn, &ssl3_HandleCertificateCompressionXtn }, |
115 | | { 0, NULL } |
116 | | }; |
117 | | |
118 | | /* Tables of functions to format TLS hello extensions, one function per |
119 | | * extension. |
120 | | * These static tables are for the formatting of client hello extensions. |
121 | | * The server's table of hello senders is dynamic, in the socket struct, |
122 | | * and sender functions are registered there. |
123 | | * NB: the order of these extensions can have an impact on compatibility. Some |
124 | | * servers (e.g. Tomcat) will terminate the connection if the last extension in |
125 | | * the client hello is empty (for example, the extended master secret |
126 | | * extension, if it were listed last). See bug 1243641. |
127 | | */ |
128 | | static const sslExtensionBuilder clientHelloSendersTLS[] = { |
129 | | /* TLS 1.3 GREASE extensions - empty. */ |
130 | | { ssl_tls13_grease_xtn, &tls13_SendEmptyGreaseXtn }, |
131 | | { ssl_server_name_xtn, &ssl3_ClientSendServerNameXtn }, |
132 | | { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn }, |
133 | | { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, |
134 | | { ssl_supported_groups_xtn, &ssl_SendSupportedGroupsXtn }, |
135 | | { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
136 | | { ssl_session_ticket_xtn, &ssl3_ClientSendSessionTicketXtn }, |
137 | | { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn }, |
138 | | { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn }, |
139 | | { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, |
140 | | { ssl_delegated_credentials_xtn, &tls13_ClientSendDelegatedCredentialsXtn }, |
141 | | { ssl_signed_cert_timestamp_xtn, &ssl3_ClientSendSignedCertTimestampXtn }, |
142 | | { ssl_tls13_key_share_xtn, &tls13_ClientSendKeyShareXtn }, |
143 | | { ssl_tls13_early_data_xtn, &tls13_ClientSendEarlyDataXtn }, |
144 | | /* Some servers (e.g. WebSphere Application Server 7.0 and Tomcat) will |
145 | | * time out or terminate the connection if the last extension in the |
146 | | * client hello is empty. They are not intolerant of TLS 1.2, so list |
147 | | * signature_algorithms at the end. See bug 1243641. */ |
148 | | { ssl_tls13_supported_versions_xtn, &tls13_ClientSendSupportedVersionsXtn }, |
149 | | { ssl_signature_algorithms_xtn, &ssl3_SendSigAlgsXtn }, |
150 | | { ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn }, |
151 | | { ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ClientSendPskModesXtn }, |
152 | | { ssl_tls13_post_handshake_auth_xtn, &tls13_ClientSendPostHandshakeAuthXtn }, |
153 | | { ssl_record_size_limit_xtn, &ssl_SendRecordSizeLimitXtn }, |
154 | | { ssl_certificate_compression_xtn, &ssl3_SendCertificateCompressionXtn }, |
155 | | /* TLS 1.3 GREASE extensions - 1 zero byte. */ |
156 | | { ssl_tls13_grease_xtn, &tls13_SendGreaseXtn }, |
157 | | /* The pre_shared_key extension MUST be last. */ |
158 | | { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn }, |
159 | | { 0, NULL } |
160 | | }; |
161 | | |
162 | | static const sslExtensionBuilder clientHelloSendersSSL3[] = { |
163 | | { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, |
164 | | { 0, NULL } |
165 | | }; |
166 | | |
167 | | static const sslExtensionBuilder tls13_cert_req_senders[] = { |
168 | | { ssl_signature_algorithms_xtn, &ssl3_SendSigAlgsXtn }, |
169 | | { ssl_tls13_certificate_authorities_xtn, &tls13_SendCertAuthoritiesXtn }, |
170 | | /* TLS 1.3 GREASE extension. */ |
171 | | { ssl_tls13_grease_xtn, &tls13_SendEmptyGreaseXtn }, |
172 | | { ssl_certificate_compression_xtn, &ssl3_SendCertificateCompressionXtn }, |
173 | | { 0, NULL } |
174 | | }; |
175 | | |
176 | | static const sslExtensionBuilder tls13_hrr_senders[] = { |
177 | | { ssl_tls13_key_share_xtn, &tls13_ServerSendHrrKeyShareXtn }, |
178 | | { ssl_tls13_cookie_xtn, &tls13_ServerSendHrrCookieXtn }, |
179 | | { ssl_tls13_supported_versions_xtn, &tls13_ServerSendSupportedVersionsXtn }, |
180 | | { ssl_tls13_encrypted_client_hello_xtn, &tls13_ServerSendHrrEchXtn }, |
181 | | { 0, NULL } |
182 | | }; |
183 | | |
184 | | static const struct { |
185 | | SSLExtensionType type; |
186 | | SSLExtensionSupport support; |
187 | | } ssl_supported_extensions[] = { |
188 | | { ssl_server_name_xtn, ssl_ext_native_only }, |
189 | | { ssl_cert_status_xtn, ssl_ext_native }, |
190 | | { ssl_delegated_credentials_xtn, ssl_ext_native }, |
191 | | { ssl_supported_groups_xtn, ssl_ext_native_only }, |
192 | | { ssl_ec_point_formats_xtn, ssl_ext_native }, |
193 | | { ssl_signature_algorithms_xtn, ssl_ext_native_only }, |
194 | | { ssl_use_srtp_xtn, ssl_ext_native }, |
195 | | { ssl_app_layer_protocol_xtn, ssl_ext_native_only }, |
196 | | { ssl_signed_cert_timestamp_xtn, ssl_ext_native }, |
197 | | { ssl_padding_xtn, ssl_ext_native }, |
198 | | { ssl_extended_master_secret_xtn, ssl_ext_native_only }, |
199 | | { ssl_session_ticket_xtn, ssl_ext_native_only }, |
200 | | { ssl_tls13_key_share_xtn, ssl_ext_native_only }, |
201 | | { ssl_tls13_pre_shared_key_xtn, ssl_ext_native_only }, |
202 | | { ssl_tls13_early_data_xtn, ssl_ext_native_only }, |
203 | | { ssl_tls13_supported_versions_xtn, ssl_ext_native_only }, |
204 | | { ssl_tls13_cookie_xtn, ssl_ext_native_only }, |
205 | | { ssl_tls13_psk_key_exchange_modes_xtn, ssl_ext_native_only }, |
206 | | { ssl_tls13_ticket_early_data_info_xtn, ssl_ext_native_only }, |
207 | | { ssl_tls13_certificate_authorities_xtn, ssl_ext_native }, |
208 | | { ssl_renegotiation_info_xtn, ssl_ext_native }, |
209 | | { ssl_tls13_encrypted_client_hello_xtn, ssl_ext_native_only }, |
210 | | { ssl_certificate_compression_xtn, ssl_ext_native }, |
211 | | }; |
212 | | |
213 | | static SSLExtensionSupport |
214 | | ssl_GetExtensionSupport(PRUint16 type) |
215 | 0 | { |
216 | 0 | unsigned int i; |
217 | 0 | for (i = 0; i < PR_ARRAY_SIZE(ssl_supported_extensions); ++i) { |
218 | 0 | if (type == ssl_supported_extensions[i].type) { |
219 | 0 | return ssl_supported_extensions[i].support; |
220 | 0 | } |
221 | 0 | } |
222 | 0 | return ssl_ext_none; |
223 | 0 | } |
224 | | |
225 | | SECStatus |
226 | | SSLExp_GetExtensionSupport(PRUint16 type, SSLExtensionSupport *support) |
227 | 0 | { |
228 | 0 | *support = ssl_GetExtensionSupport(type); |
229 | 0 | return SECSuccess; |
230 | 0 | } |
231 | | |
232 | | SECStatus |
233 | | SSLExp_InstallExtensionHooks(PRFileDesc *fd, PRUint16 extension, |
234 | | SSLExtensionWriter writer, void *writerArg, |
235 | | SSLExtensionHandler handler, void *handlerArg) |
236 | 0 | { |
237 | 0 | sslSocket *ss = ssl_FindSocket(fd); |
238 | 0 | PRCList *cursor; |
239 | 0 | sslCustomExtensionHooks *hook; |
240 | |
|
241 | 0 | if (!ss) { |
242 | 0 | return SECFailure; /* Code already set. */ |
243 | 0 | } |
244 | | |
245 | | /* Need to specify both or neither, but not just one. */ |
246 | 0 | if ((writer && !handler) || (!writer && handler)) { |
247 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
248 | 0 | return SECFailure; |
249 | 0 | } |
250 | | |
251 | 0 | if (ssl_GetExtensionSupport(extension) == ssl_ext_native_only) { |
252 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
253 | 0 | return SECFailure; |
254 | 0 | } |
255 | | |
256 | 0 | if (ss->firstHsDone || ((ss->ssl3.hs.ws != idle_handshake) && |
257 | 0 | (ss->ssl3.hs.ws != wait_client_hello))) { |
258 | 0 | PORT_SetError(PR_INVALID_STATE_ERROR); |
259 | 0 | return SECFailure; |
260 | 0 | } |
261 | | |
262 | | /* Remove any old handler. */ |
263 | 0 | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
264 | 0 | cursor != &ss->extensionHooks; |
265 | 0 | cursor = PR_NEXT_LINK(cursor)) { |
266 | 0 | hook = (sslCustomExtensionHooks *)cursor; |
267 | 0 | if (hook->type == extension) { |
268 | 0 | PR_REMOVE_LINK(&hook->link); |
269 | 0 | PORT_Free(hook); |
270 | 0 | break; |
271 | 0 | } |
272 | 0 | } |
273 | |
|
274 | 0 | if (!writer && !handler) { |
275 | 0 | return SECSuccess; |
276 | 0 | } |
277 | | |
278 | 0 | hook = PORT_ZNew(sslCustomExtensionHooks); |
279 | 0 | if (!hook) { |
280 | 0 | return SECFailure; /* This removed the old one, oh well. */ |
281 | 0 | } |
282 | | |
283 | 0 | hook->type = extension; |
284 | 0 | hook->writer = writer; |
285 | 0 | hook->writerArg = writerArg; |
286 | 0 | hook->handler = handler; |
287 | 0 | hook->handlerArg = handlerArg; |
288 | 0 | PR_APPEND_LINK(&hook->link, &ss->extensionHooks); |
289 | 0 | return SECSuccess; |
290 | 0 | } |
291 | | |
292 | | sslCustomExtensionHooks * |
293 | | ssl_FindCustomExtensionHooks(sslSocket *ss, PRUint16 extension) |
294 | 16.8k | { |
295 | 16.8k | PRCList *cursor; |
296 | | |
297 | 16.8k | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
298 | 16.8k | cursor != &ss->extensionHooks; |
299 | 16.8k | cursor = PR_NEXT_LINK(cursor)) { |
300 | 0 | sslCustomExtensionHooks *hook = (sslCustomExtensionHooks *)cursor; |
301 | 0 | if (hook->type == extension) { |
302 | 0 | return hook; |
303 | 0 | } |
304 | 0 | } |
305 | | |
306 | 16.8k | return NULL; |
307 | 16.8k | } |
308 | | |
309 | | static PRBool |
310 | | arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) |
311 | 53.7k | { |
312 | 53.7k | unsigned int i; |
313 | 115k | for (i = 0; i < len; i++) { |
314 | 67.3k | if (ex_type == array[i]) |
315 | 5.37k | return PR_TRUE; |
316 | 67.3k | } |
317 | 48.3k | return PR_FALSE; |
318 | 53.7k | } |
319 | | |
320 | | PRBool |
321 | | ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type) |
322 | 53.7k | { |
323 | 53.7k | const TLSExtensionData *xtnData = &ss->xtnData; |
324 | 53.7k | return arrayContainsExtension(xtnData->negotiated, |
325 | 53.7k | xtnData->numNegotiated, ex_type); |
326 | 53.7k | } |
327 | | |
328 | | /* This checks for whether an extension was advertised. On the client, this |
329 | | * covers extensions that are sent in ClientHello; on the server, extensions |
330 | | * sent in CertificateRequest (TLS 1.3 only). */ |
331 | | PRBool |
332 | | ssl3_ExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type) |
333 | 0 | { |
334 | 0 | const TLSExtensionData *xtnData = &ss->xtnData; |
335 | 0 | return arrayContainsExtension(xtnData->advertised, |
336 | 0 | xtnData->numAdvertised, ex_type); |
337 | 0 | } |
338 | | |
339 | | PRBool |
340 | | ssl3_ExtensionAdvertisedClientHelloInner(const sslSocket *ss, PRUint16 ex_type) |
341 | 0 | { |
342 | 0 | const TLSExtensionData *xtnData = &ss->xtnData; |
343 | 0 | return arrayContainsExtension(xtnData->echAdvertised, |
344 | 0 | xtnData->echNumAdvertised, ex_type); |
345 | 0 | } |
346 | | |
347 | | /* Go through hello extensions in |b| and deserialize |
348 | | * them into the list in |ss->ssl3.hs.remoteExtensions|. |
349 | | * The only checking we do in this point is for duplicates. |
350 | | * |
351 | | * IMPORTANT: This list just contains pointers to the incoming |
352 | | * buffer so they can only be used during ClientHello processing. |
353 | | */ |
354 | | SECStatus |
355 | | ssl3_ParseExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length) |
356 | 8.20k | { |
357 | | /* Clean out the extensions list. */ |
358 | 8.20k | ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); |
359 | | |
360 | 19.7k | while (*length) { |
361 | 11.5k | SECStatus rv; |
362 | 11.5k | PRUint32 extension_type; |
363 | 11.5k | SECItem extension_data = { siBuffer, NULL, 0 }; |
364 | 11.5k | TLSExtension *extension; |
365 | 11.5k | PRCList *cursor; |
366 | | |
367 | | /* Get the extension's type field */ |
368 | 11.5k | rv = ssl3_ConsumeHandshakeNumber(ss, &extension_type, 2, b, length); |
369 | 11.5k | if (rv != SECSuccess) { |
370 | 1 | return SECFailure; /* alert already sent */ |
371 | 1 | } |
372 | | |
373 | | /* Check whether an extension has been sent multiple times. */ |
374 | 11.5k | for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); |
375 | 16.3k | cursor != &ss->ssl3.hs.remoteExtensions; |
376 | 11.5k | cursor = PR_NEXT_LINK(cursor)) { |
377 | 4.85k | if (((TLSExtension *)cursor)->type == extension_type) { |
378 | 2 | (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
379 | 2 | PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); |
380 | 2 | return SECFailure; |
381 | 2 | } |
382 | 4.85k | } |
383 | | |
384 | | /* Get the data for this extension, so we can pass it or skip it. */ |
385 | 11.5k | rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length); |
386 | 11.5k | if (rv != SECSuccess) { |
387 | 4 | return rv; /* alert already sent */ |
388 | 4 | } |
389 | | |
390 | 11.5k | SSL_TRC(10, ("%d: SSL3[%d]: parsed extension %d len=%u", |
391 | 11.5k | SSL_GETPID(), ss->fd, extension_type, extension_data.len)); |
392 | | |
393 | 11.5k | extension = PORT_ZNew(TLSExtension); |
394 | 11.5k | if (!extension) { |
395 | 0 | return SECFailure; |
396 | 0 | } |
397 | | |
398 | 11.5k | extension->type = (PRUint16)extension_type; |
399 | 11.5k | extension->data = extension_data; |
400 | 11.5k | PR_APPEND_LINK(&extension->link, &ss->ssl3.hs.remoteExtensions); |
401 | 11.5k | } |
402 | | |
403 | 8.19k | return SECSuccess; |
404 | 8.20k | } |
405 | | |
406 | | TLSExtension * |
407 | | ssl3_FindExtension(sslSocket *ss, SSLExtensionType extension_type) |
408 | 6.44k | { |
409 | 6.44k | PRCList *cursor; |
410 | | |
411 | 6.44k | for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); |
412 | 12.6k | cursor != &ss->ssl3.hs.remoteExtensions; |
413 | 6.44k | cursor = PR_NEXT_LINK(cursor)) { |
414 | 6.22k | TLSExtension *extension = (TLSExtension *)cursor; |
415 | | |
416 | 6.22k | if (extension->type == extension_type) { |
417 | 21 | return extension; |
418 | 21 | } |
419 | 6.22k | } |
420 | | |
421 | 6.42k | return NULL; |
422 | 6.44k | } |
423 | | |
424 | | static SECStatus |
425 | | ssl_CallExtensionHandler(sslSocket *ss, SSLHandshakeType handshakeMessage, |
426 | | TLSExtension *extension, |
427 | | const ssl3ExtensionHandler *handler) |
428 | 11.3k | { |
429 | 11.3k | SECStatus rv = SECSuccess; |
430 | 11.3k | SSLAlertDescription alert = handshake_failure; |
431 | 11.3k | sslCustomExtensionHooks *customHooks; |
432 | | |
433 | 11.3k | customHooks = ssl_FindCustomExtensionHooks(ss, extension->type); |
434 | 11.3k | if (customHooks) { |
435 | 0 | if (customHooks->handler) { |
436 | 0 | rv = customHooks->handler(ss->fd, handshakeMessage, |
437 | 0 | extension->data.data, |
438 | 0 | extension->data.len, |
439 | 0 | &alert, customHooks->handlerArg); |
440 | 0 | } |
441 | 11.3k | } else { |
442 | | /* Find extension_type in table of Hello Extension Handlers. */ |
443 | 97.6k | for (; handler->ex_handler != NULL; ++handler) { |
444 | 94.9k | if (handler->ex_type == extension->type) { |
445 | 8.71k | SECItem tmp = extension->data; |
446 | | |
447 | 8.71k | rv = (*handler->ex_handler)(ss, &ss->xtnData, &tmp); |
448 | 8.71k | break; |
449 | 8.71k | } |
450 | 94.9k | } |
451 | 11.3k | } |
452 | | |
453 | 11.3k | if (rv != SECSuccess) { |
454 | 88 | if (!ss->ssl3.fatalAlertSent) { |
455 | | /* Send an alert if the handler didn't already. */ |
456 | 5 | (void)SSL3_SendAlert(ss, alert_fatal, alert); |
457 | 5 | } |
458 | 88 | return SECFailure; |
459 | 88 | } |
460 | | |
461 | 11.2k | return SECSuccess; |
462 | 11.3k | } |
463 | | |
464 | | /* Go through the hello extensions in |ss->ssl3.hs.remoteExtensions|. |
465 | | * For each one, find the extension handler in the table, and |
466 | | * if present, invoke that handler. |
467 | | * Servers ignore any extensions with unknown extension types. |
468 | | * Clients reject any extensions with unadvertised extension types |
469 | | * |
470 | | * In TLS >= 1.3, the client checks that extensions appear in the |
471 | | * right phase. |
472 | | */ |
473 | | SECStatus |
474 | | ssl3_HandleParsedExtensions(sslSocket *ss, SSLHandshakeType message) |
475 | 11.6k | { |
476 | 11.6k | const ssl3ExtensionHandler *handlers; |
477 | | /* HelloRetryRequest doesn't set ss->version. It might be safe to |
478 | | * do so, but we weren't entirely sure. TODO(ekr@rtfm.com). */ |
479 | 11.6k | PRBool isTLS13 = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) || |
480 | 11.6k | (message == ssl_hs_hello_retry_request); |
481 | | /* The following messages can include extensions that were not included in |
482 | | * the original ClientHello. */ |
483 | 11.6k | PRBool allowNotOffered = (message == ssl_hs_client_hello) || |
484 | 11.6k | (message == ssl_hs_certificate_request) || |
485 | 11.6k | (message == ssl_hs_new_session_ticket); |
486 | 11.6k | PRCList *cursor; |
487 | | |
488 | 11.6k | switch (message) { |
489 | 11.6k | case ssl_hs_client_hello: |
490 | 11.6k | handlers = clientHelloHandlers; |
491 | 11.6k | break; |
492 | 0 | case ssl_hs_new_session_ticket: |
493 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
494 | 0 | handlers = newSessionTicketHandlers; |
495 | 0 | break; |
496 | 0 | case ssl_hs_hello_retry_request: |
497 | 0 | handlers = helloRetryRequestHandlers; |
498 | 0 | break; |
499 | 0 | case ssl_hs_encrypted_extensions: |
500 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
501 | | /* fall through */ |
502 | 0 | case ssl_hs_server_hello: |
503 | 0 | if (ss->version > SSL_LIBRARY_VERSION_3_0) { |
504 | 0 | handlers = serverHelloHandlersTLS; |
505 | 0 | } else { |
506 | 0 | handlers = serverHelloHandlersSSL3; |
507 | 0 | } |
508 | 0 | break; |
509 | 0 | case ssl_hs_certificate: |
510 | 0 | PORT_Assert(!ss->sec.isServer); |
511 | 0 | handlers = serverCertificateHandlers; |
512 | 0 | break; |
513 | 0 | case ssl_hs_certificate_request: |
514 | 0 | PORT_Assert(!ss->sec.isServer); |
515 | 0 | handlers = certificateRequestHandlers; |
516 | 0 | break; |
517 | 0 | default: |
518 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
519 | 0 | PORT_Assert(0); |
520 | 0 | return SECFailure; |
521 | 11.6k | } |
522 | | |
523 | 11.6k | for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); |
524 | 22.9k | cursor != &ss->ssl3.hs.remoteExtensions; |
525 | 11.6k | cursor = PR_NEXT_LINK(cursor)) { |
526 | 11.3k | TLSExtension *extension = (TLSExtension *)cursor; |
527 | 11.3k | SECStatus rv; |
528 | | |
529 | | /* Check whether the server sent an extension which was not advertised |
530 | | * in the ClientHello. |
531 | | * |
532 | | * Note that a TLS 1.3 server should check if CertificateRequest |
533 | | * extensions were sent. But the extensions used for CertificateRequest |
534 | | * do not have any response, so we rely on |
535 | | * ssl3_ExtensionAdvertised to return false on the server. That |
536 | | * results in the server only rejecting any extension. */ |
537 | 11.3k | if (!allowNotOffered && (extension->type != ssl_tls13_cookie_xtn)) { |
538 | 0 | if (!ssl3_ExtensionAdvertised(ss, extension->type)) { |
539 | 0 | SSL_TRC(10, ("Server sent xtn type=%d which is invalid for the CHO", extension->type)); |
540 | 0 | (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension); |
541 | 0 | PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); |
542 | 0 | return SECFailure; |
543 | 0 | } |
544 | | /* If we offered ECH, we also check whether the extension is compatible with |
545 | | * the Client Hello Inner. We don't yet know whether the server accepted ECH, |
546 | | * so we only store this for now. If we later accept, we check this boolean |
547 | | * and reject with an unsupported_extension alert if it is set. */ |
548 | 0 | if (ss->ssl3.hs.echHpkeCtx && !ssl3_ExtensionAdvertisedClientHelloInner(ss, extension->type)) { |
549 | 0 | SSL_TRC(10, ("Server sent xtn type=%d which is invalid for the CHI", extension->type)); |
550 | 0 | ss->ssl3.hs.echInvalidExtension = PR_TRUE; |
551 | 0 | } |
552 | 0 | } |
553 | | |
554 | | /* Check that this is a legal extension in TLS 1.3 */ |
555 | 11.3k | if (isTLS13 && |
556 | 11.3k | !ssl_FindCustomExtensionHooks(ss, extension->type)) { |
557 | 0 | switch (tls13_ExtensionStatus(extension->type, message)) { |
558 | 0 | case tls13_extension_allowed: |
559 | 0 | break; |
560 | 0 | case tls13_extension_unknown: |
561 | 0 | if (allowNotOffered) { |
562 | 0 | continue; /* Skip over unknown extensions. */ |
563 | 0 | } |
564 | | /* RFC8446 Section 4.2 - Implementations MUST NOT send extension responses if |
565 | | * the remote endpoint did not send the corresponding extension request ... |
566 | | * Upon receiving such an extension, an endpoint MUST abort the handshake with |
567 | | * an "unsupported_extension" alert. */ |
568 | 0 | SSL_TRC(3, ("%d: TLS13: unknown extension %d in message %d", |
569 | 0 | SSL_GETPID(), extension, message)); |
570 | 0 | tls13_FatalError(ss, SSL_ERROR_RX_UNEXPECTED_EXTENSION, |
571 | 0 | unsupported_extension); |
572 | 0 | return SECFailure; |
573 | 0 | case tls13_extension_disallowed: |
574 | | /* RFC8446 Section 4.2 - If an implementation receives an extension which it |
575 | | * recognizes and which is not specified for the message in which it appears, |
576 | | * it MUST abort the handshake with an "illegal_parameter" alert. */ |
577 | 0 | SSL_TRC(3, ("%d: TLS13: disallowed extension %d in message %d", |
578 | 0 | SSL_GETPID(), extension, message)); |
579 | 0 | tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, |
580 | 0 | illegal_parameter); |
581 | 0 | return SECFailure; |
582 | 0 | } |
583 | 0 | } |
584 | | |
585 | | /* Special check for this being the last extension if it's |
586 | | * PreSharedKey */ |
587 | 11.3k | if (ss->sec.isServer && isTLS13 && |
588 | 11.3k | (extension->type == ssl_tls13_pre_shared_key_xtn) && |
589 | 11.3k | (PR_NEXT_LINK(cursor) != &ss->ssl3.hs.remoteExtensions)) { |
590 | 0 | tls13_FatalError(ss, |
591 | 0 | SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, |
592 | 0 | illegal_parameter); |
593 | 0 | return SECFailure; |
594 | 0 | } |
595 | | |
596 | 11.3k | rv = ssl_CallExtensionHandler(ss, message, extension, handlers); |
597 | 11.3k | if (rv != SECSuccess) { |
598 | 88 | return SECFailure; |
599 | 88 | } |
600 | 11.3k | } |
601 | 11.5k | return SECSuccess; |
602 | 11.6k | } |
603 | | |
604 | | /* Syntactic sugar around ssl3_ParseExtensions and |
605 | | * ssl3_HandleParsedExtensions. */ |
606 | | SECStatus |
607 | | ssl3_HandleExtensions(sslSocket *ss, |
608 | | PRUint8 **b, PRUint32 *length, |
609 | | SSLHandshakeType handshakeMessage) |
610 | 5.25k | { |
611 | 5.25k | SECStatus rv; |
612 | | |
613 | 5.25k | rv = ssl3_ParseExtensions(ss, b, length); |
614 | 5.25k | if (rv != SECSuccess) |
615 | 0 | return rv; |
616 | | |
617 | 5.25k | rv = ssl3_HandleParsedExtensions(ss, handshakeMessage); |
618 | 5.25k | if (rv != SECSuccess) |
619 | 0 | return rv; |
620 | | |
621 | 5.25k | ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); |
622 | 5.25k | return SECSuccess; |
623 | 5.25k | } |
624 | | |
625 | | /* Add a callback function to the table of senders of server hello extensions. |
626 | | */ |
627 | | SECStatus |
628 | | ssl3_RegisterExtensionSender(const sslSocket *ss, |
629 | | TLSExtensionData *xtnData, |
630 | | PRUint16 ex_type, |
631 | | sslExtensionBuilderFunc cb) |
632 | 5.56k | { |
633 | 5.56k | int i; |
634 | 5.56k | sslExtensionBuilder *sender; |
635 | 5.56k | if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { |
636 | 5.56k | sender = &xtnData->serverHelloSenders[0]; |
637 | 5.56k | } else { |
638 | 0 | if (tls13_ExtensionStatus(ex_type, ssl_hs_server_hello) == |
639 | 0 | tls13_extension_allowed) { |
640 | 0 | PORT_Assert(tls13_ExtensionStatus(ex_type, |
641 | 0 | ssl_hs_encrypted_extensions) == |
642 | 0 | tls13_extension_disallowed); |
643 | 0 | sender = &xtnData->serverHelloSenders[0]; |
644 | 0 | } else if (tls13_ExtensionStatus(ex_type, |
645 | 0 | ssl_hs_encrypted_extensions) == |
646 | 0 | tls13_extension_allowed) { |
647 | 0 | sender = &xtnData->encryptedExtensionsSenders[0]; |
648 | 0 | } else if (tls13_ExtensionStatus(ex_type, ssl_hs_certificate) == |
649 | 0 | tls13_extension_allowed) { |
650 | 0 | sender = &xtnData->certificateSenders[0]; |
651 | 0 | } else { |
652 | 0 | PORT_Assert(0); |
653 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
654 | 0 | return SECFailure; |
655 | 0 | } |
656 | 0 | } |
657 | 5.67k | for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { |
658 | 5.67k | if (!sender->ex_sender) { |
659 | 5.56k | sender->ex_type = ex_type; |
660 | 5.56k | sender->ex_sender = cb; |
661 | 5.56k | return SECSuccess; |
662 | 5.56k | } |
663 | | /* detect duplicate senders */ |
664 | 108 | PORT_Assert(sender->ex_type != ex_type); |
665 | 108 | if (sender->ex_type == ex_type) { |
666 | | /* duplicate */ |
667 | 0 | break; |
668 | 0 | } |
669 | 108 | } |
670 | 0 | PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */ |
671 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
672 | 0 | return SECFailure; |
673 | 5.56k | } |
674 | | |
675 | | SECStatus |
676 | | ssl_CallCustomExtensionSenders(sslSocket *ss, sslBuffer *buf, |
677 | | SSLHandshakeType message) |
678 | 0 | { |
679 | 0 | sslBuffer tail = SSL_BUFFER_EMPTY; |
680 | 0 | SECStatus rv; |
681 | 0 | PRCList *cursor; |
682 | | |
683 | | /* Save any extensions that want to be last. */ |
684 | 0 | if (ss->xtnData.lastXtnOffset) { |
685 | 0 | rv = sslBuffer_Append(&tail, buf->buf + ss->xtnData.lastXtnOffset, |
686 | 0 | buf->len - ss->xtnData.lastXtnOffset); |
687 | 0 | if (rv != SECSuccess) { |
688 | 0 | return SECFailure; |
689 | 0 | } |
690 | 0 | buf->len = ss->xtnData.lastXtnOffset; |
691 | 0 | } |
692 | | |
693 | | /* Reserve the maximum amount of space possible. */ |
694 | 0 | rv = sslBuffer_Grow(buf, 65535); |
695 | 0 | if (rv != SECSuccess) { |
696 | 0 | return SECFailure; |
697 | 0 | } |
698 | | |
699 | 0 | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
700 | 0 | cursor != &ss->extensionHooks; |
701 | 0 | cursor = PR_NEXT_LINK(cursor)) { |
702 | 0 | sslCustomExtensionHooks *hook = |
703 | 0 | (sslCustomExtensionHooks *)cursor; |
704 | 0 | PRBool append = PR_FALSE; |
705 | 0 | unsigned int len = 0; |
706 | |
|
707 | 0 | if (hook->writer) { |
708 | | /* The writer writes directly into |buf|. Provide space that allows |
709 | | * for the existing extensions, any tail, plus type and length. */ |
710 | 0 | unsigned int space = buf->space - (buf->len + tail.len + 4); |
711 | 0 | append = (*hook->writer)(ss->fd, message, |
712 | 0 | buf->buf + buf->len + 4, &len, space, |
713 | 0 | hook->writerArg); |
714 | 0 | if (len > space) { |
715 | 0 | PORT_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR); |
716 | 0 | goto loser; |
717 | 0 | } |
718 | 0 | } |
719 | 0 | if (!append) { |
720 | 0 | continue; |
721 | 0 | } |
722 | | |
723 | 0 | rv = sslBuffer_AppendNumber(buf, hook->type, 2); |
724 | 0 | if (rv != SECSuccess) { |
725 | 0 | goto loser; /* Code already set. */ |
726 | 0 | } |
727 | 0 | rv = sslBuffer_AppendNumber(buf, len, 2); |
728 | 0 | if (rv != SECSuccess) { |
729 | 0 | goto loser; /* Code already set. */ |
730 | 0 | } |
731 | 0 | buf->len += len; |
732 | |
|
733 | 0 | if (message == ssl_hs_client_hello || |
734 | 0 | message == ssl_hs_ech_outer_client_hello || |
735 | 0 | message == ssl_hs_certificate_request) { |
736 | 0 | ss->xtnData.advertised[ss->xtnData.numAdvertised++] = hook->type; |
737 | 0 | } |
738 | 0 | } |
739 | | |
740 | 0 | rv = sslBuffer_Append(buf, tail.buf, tail.len); |
741 | 0 | if (rv != SECSuccess) { |
742 | 0 | goto loser; /* Code already set. */ |
743 | 0 | } |
744 | | |
745 | 0 | sslBuffer_Clear(&tail); |
746 | 0 | return SECSuccess; |
747 | | |
748 | 0 | loser: |
749 | 0 | sslBuffer_Clear(&tail); |
750 | 0 | return SECFailure; |
751 | 0 | } |
752 | | |
753 | | /* Call extension handlers for the given message. */ |
754 | | SECStatus |
755 | | ssl_ConstructExtensions(sslSocket *ss, sslBuffer *buf, SSLHandshakeType message) |
756 | 5.55k | { |
757 | 5.55k | const sslExtensionBuilder *sender; |
758 | 5.55k | SECStatus rv; |
759 | | |
760 | 5.55k | PORT_Assert(buf->len == 0); |
761 | | |
762 | | /* Clear out any extensions previously advertised */ |
763 | 5.55k | ss->xtnData.numAdvertised = 0; |
764 | 5.55k | ss->xtnData.echNumAdvertised = 0; |
765 | | |
766 | 5.55k | switch (message) { |
767 | 0 | case ssl_hs_client_hello: |
768 | 0 | if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) { |
769 | | /* Use TLS ClientHello Extension Permutation? */ |
770 | 0 | if (ss->opt.enableChXtnPermutation) { |
771 | 0 | sender = ss->ssl3.hs.chExtensionPermutation; |
772 | 0 | } else { |
773 | 0 | sender = clientHelloSendersTLS; |
774 | 0 | } |
775 | 0 | } else { |
776 | 0 | sender = clientHelloSendersSSL3; |
777 | 0 | } |
778 | 0 | break; |
779 | | |
780 | 5.55k | case ssl_hs_server_hello: |
781 | 5.55k | sender = ss->xtnData.serverHelloSenders; |
782 | 5.55k | break; |
783 | | |
784 | 0 | case ssl_hs_certificate_request: |
785 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
786 | 0 | sender = tls13_cert_req_senders; |
787 | 0 | break; |
788 | | |
789 | 0 | case ssl_hs_certificate: |
790 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
791 | 0 | sender = ss->xtnData.certificateSenders; |
792 | 0 | break; |
793 | | |
794 | 0 | case ssl_hs_encrypted_extensions: |
795 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
796 | 0 | sender = ss->xtnData.encryptedExtensionsSenders; |
797 | 0 | break; |
798 | | |
799 | 0 | case ssl_hs_hello_retry_request: |
800 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
801 | 0 | sender = tls13_hrr_senders; |
802 | 0 | break; |
803 | | |
804 | 0 | default: |
805 | 0 | PORT_Assert(0); |
806 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
807 | 0 | return SECFailure; |
808 | 5.55k | } |
809 | | |
810 | 11.0k | for (; sender->ex_sender != NULL; ++sender) { |
811 | 5.45k | PRUint16 ex_type = sender->ex_type; |
812 | 5.45k | PRBool append = PR_FALSE; |
813 | 5.45k | unsigned int start = buf->len; |
814 | 5.45k | unsigned int length; |
815 | | |
816 | 5.45k | if (ssl_FindCustomExtensionHooks(ss, sender->ex_type)) { |
817 | 0 | continue; |
818 | 0 | } |
819 | | |
820 | | /* Save space for the extension type and length. Note that we don't grow |
821 | | * the buffer now; rely on sslBuffer_Append* to do that. */ |
822 | 5.45k | buf->len += 4; |
823 | 5.45k | rv = (*sender->ex_sender)(ss, &ss->xtnData, buf, &append); |
824 | 5.45k | if (rv != SECSuccess) { |
825 | 0 | goto loser; |
826 | 0 | } |
827 | | |
828 | | /* Save the length and go back to the start. */ |
829 | 5.45k | length = buf->len - start - 4; |
830 | 5.45k | buf->len = start; |
831 | 5.45k | if (!append) { |
832 | 6 | continue; |
833 | 6 | } |
834 | | |
835 | | /* If TLS 1.3 GREASE is enabled, replace ssl_tls13_grease_xtn dummy |
836 | | * GREASE extension types with randomly generated GREASE value. */ |
837 | 5.44k | rv = tls13_MaybeGreaseExtensionType(ss, message, &ex_type); |
838 | 5.44k | if (rv != SECSuccess) { |
839 | 0 | goto loser; /* Code already set. */ |
840 | 0 | } |
841 | | |
842 | 5.44k | rv = sslBuffer_AppendNumber(buf, ex_type, 2); |
843 | 5.44k | if (rv != SECSuccess) { |
844 | 0 | goto loser; /* Code already set. */ |
845 | 0 | } |
846 | 5.44k | rv = sslBuffer_AppendNumber(buf, length, 2); |
847 | 5.44k | if (rv != SECSuccess) { |
848 | 0 | goto loser; /* Code already set. */ |
849 | 0 | } |
850 | | /* Skip over the extension body. */ |
851 | 5.44k | buf->len += length; |
852 | | |
853 | 5.44k | if (message == ssl_hs_client_hello || |
854 | 5.44k | message == ssl_hs_certificate_request) { |
855 | 0 | ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
856 | 0 | ex_type; |
857 | 0 | } |
858 | 5.44k | } |
859 | | |
860 | 5.55k | if (!PR_CLIST_IS_EMPTY(&ss->extensionHooks)) { |
861 | 0 | if (message == ssl_hs_client_hello && ss->opt.callExtensionWriterOnEchInner) { |
862 | 0 | message = ssl_hs_ech_outer_client_hello; |
863 | 0 | } |
864 | 0 | rv = ssl_CallCustomExtensionSenders(ss, buf, message); |
865 | 0 | if (rv != SECSuccess) { |
866 | 0 | goto loser; |
867 | 0 | } |
868 | 0 | } |
869 | | |
870 | 5.55k | if (buf->len > 0xffff) { |
871 | 0 | PORT_SetError(SSL_ERROR_TX_RECORD_TOO_LONG); |
872 | 0 | goto loser; |
873 | 0 | } |
874 | | |
875 | 5.55k | return SECSuccess; |
876 | | |
877 | 0 | loser: |
878 | 0 | sslBuffer_Clear(buf); |
879 | 0 | return SECFailure; |
880 | 5.55k | } |
881 | | |
882 | | /* This extension sender can be used anywhere that an always empty extension is |
883 | | * needed. Mostly that is for ServerHello where sender registration is dynamic; |
884 | | * ClientHello senders are usually conditional in some way. */ |
885 | | SECStatus |
886 | | ssl_SendEmptyExtension(const sslSocket *ss, TLSExtensionData *xtnData, |
887 | | sslBuffer *buf, PRBool *append) |
888 | 26 | { |
889 | 26 | *append = PR_TRUE; |
890 | 26 | return SECSuccess; |
891 | 26 | } |
892 | | |
893 | | /* Takes the size of the ClientHello, less the record header, and determines how |
894 | | * much padding is required. */ |
895 | | static unsigned int |
896 | | ssl_CalculatePaddingExtLen(const sslSocket *ss, unsigned int clientHelloLength) |
897 | 0 | { |
898 | 0 | unsigned int extensionLen; |
899 | | |
900 | | /* Don't pad for DTLS, for SSLv3, or for renegotiation. */ |
901 | 0 | if (IS_DTLS(ss) || |
902 | 0 | ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_0 || |
903 | 0 | ss->firstHsDone) { |
904 | 0 | return 0; |
905 | 0 | } |
906 | | |
907 | | /* A padding extension may be included to ensure that the record containing |
908 | | * the ClientHello doesn't have a length between 256 and 511 bytes |
909 | | * (inclusive). Initial ClientHello records with such lengths trigger bugs |
910 | | * in F5 devices. */ |
911 | 0 | if (clientHelloLength < 256 || clientHelloLength >= 512) { |
912 | 0 | return 0; |
913 | 0 | } |
914 | | |
915 | 0 | extensionLen = 512 - clientHelloLength; |
916 | | /* Extensions take at least four bytes to encode. Always include at least |
917 | | * one byte of data if we are padding. Some servers will time out or |
918 | | * terminate the connection if the last ClientHello extension is empty. */ |
919 | 0 | if (extensionLen < 5) { |
920 | 0 | extensionLen = 5; |
921 | 0 | } |
922 | |
|
923 | 0 | return extensionLen - 4; |
924 | 0 | } |
925 | | |
926 | | /* Manually insert an extension, retaining the position of the PSK |
927 | | * extension, if present. */ |
928 | | SECStatus |
929 | | ssl3_EmplaceExtension(sslSocket *ss, sslBuffer *buf, PRUint16 exType, |
930 | | const PRUint8 *data, unsigned int len, PRBool advertise) |
931 | 0 | { |
932 | 0 | SECStatus rv; |
933 | 0 | unsigned int tailLen; |
934 | | |
935 | | /* Move the tail if there is one. This only happens if we are sending the |
936 | | * TLS 1.3 PSK extension, which needs to be at the end. */ |
937 | 0 | if (ss->xtnData.lastXtnOffset) { |
938 | 0 | PORT_Assert(buf->len > ss->xtnData.lastXtnOffset); |
939 | 0 | tailLen = buf->len - ss->xtnData.lastXtnOffset; |
940 | 0 | rv = sslBuffer_Grow(buf, buf->len + 4 + len); |
941 | 0 | if (rv != SECSuccess) { |
942 | 0 | return SECFailure; |
943 | 0 | } |
944 | 0 | PORT_Memmove(buf->buf + ss->xtnData.lastXtnOffset + 4 + len, |
945 | 0 | buf->buf + ss->xtnData.lastXtnOffset, |
946 | 0 | tailLen); |
947 | 0 | buf->len = ss->xtnData.lastXtnOffset; |
948 | 0 | } else { |
949 | 0 | tailLen = 0; |
950 | 0 | } |
951 | 0 | if (exType == ssl_tls13_encrypted_client_hello_xtn) { |
952 | 0 | ss->xtnData.echXtnOffset = buf->len; |
953 | 0 | } |
954 | 0 | rv = sslBuffer_AppendNumber(buf, exType, 2); |
955 | 0 | if (rv != SECSuccess) { |
956 | 0 | return SECFailure; /* Code already set. */ |
957 | 0 | } |
958 | 0 | rv = sslBuffer_AppendVariable(buf, data, len, 2); |
959 | 0 | if (rv != SECSuccess) { |
960 | 0 | return SECFailure; /* Code already set. */ |
961 | 0 | } |
962 | | |
963 | 0 | if (ss->xtnData.lastXtnOffset) { |
964 | 0 | ss->xtnData.lastXtnOffset += 4 + len; |
965 | 0 | } |
966 | |
|
967 | 0 | buf->len += tailLen; |
968 | | |
969 | | /* False only to retain behavior with padding_xtn. Maybe |
970 | | * we can just mark that advertised as well? TODO */ |
971 | 0 | if (advertise) { |
972 | 0 | ss->xtnData.advertised[ss->xtnData.numAdvertised++] = exType; |
973 | 0 | } |
974 | |
|
975 | 0 | return SECSuccess; |
976 | 0 | } |
977 | | |
978 | | /* ssl3_SendPaddingExtension possibly adds an extension which ensures that a |
979 | | * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures |
980 | | * that we don't trigger bugs in F5 products. |
981 | | * |
982 | | * This takes an existing extension buffer, |buf|, and the length of the |
983 | | * remainder of the ClientHello, |prefixLen|. It modifies the extension buffer |
984 | | * to insert padding at the right place. |
985 | | */ |
986 | | SECStatus |
987 | | ssl_InsertPaddingExtension(sslSocket *ss, unsigned int prefixLen, |
988 | | sslBuffer *buf) |
989 | 0 | { |
990 | 0 | static unsigned char padding[252] = { 0 }; |
991 | 0 | unsigned int paddingLen; |
992 | | /* Exit early if an application-provided extension hook |
993 | | * already added padding. */ |
994 | 0 | if (ssl3_ExtensionAdvertised(ss, ssl_padding_xtn)) { |
995 | 0 | return SECSuccess; |
996 | 0 | } |
997 | | |
998 | | /* Account for the size of the header, the length field of the extensions |
999 | | * block and the size of the existing extensions. */ |
1000 | 0 | paddingLen = ssl_CalculatePaddingExtLen(ss, prefixLen + 2 + buf->len); |
1001 | 0 | if (!paddingLen) { |
1002 | 0 | return SECSuccess; |
1003 | 0 | } |
1004 | | |
1005 | 0 | return ssl3_EmplaceExtension(ss, buf, ssl_padding_xtn, padding, paddingLen, PR_FALSE); |
1006 | 0 | } |
1007 | | |
1008 | | void |
1009 | | ssl3_MoveRemoteExtensions(PRCList *dst, PRCList *src) |
1010 | 0 | { |
1011 | 0 | PRCList *cur_p; |
1012 | 0 | while (!PR_CLIST_IS_EMPTY(src)) { |
1013 | 0 | cur_p = PR_LIST_TAIL(src); |
1014 | 0 | PR_REMOVE_LINK(cur_p); |
1015 | 0 | PR_INSERT_LINK(cur_p, dst); |
1016 | 0 | } |
1017 | 0 | } |
1018 | | |
1019 | | void |
1020 | | ssl3_DestroyRemoteExtensions(PRCList *list) |
1021 | 49.4k | { |
1022 | 49.4k | PRCList *cur_p; |
1023 | | |
1024 | 60.9k | while (!PR_CLIST_IS_EMPTY(list)) { |
1025 | 11.5k | cur_p = PR_LIST_TAIL(list); |
1026 | 11.5k | PR_REMOVE_LINK(cur_p); |
1027 | 11.5k | PORT_Free(cur_p); |
1028 | 11.5k | } |
1029 | 49.4k | } |
1030 | | |
1031 | | /* Initialize the extension data block. */ |
1032 | | void |
1033 | | ssl3_InitExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) |
1034 | 28.6k | { |
1035 | 28.6k | unsigned int advertisedMax; |
1036 | 28.6k | PRCList *cursor; |
1037 | | |
1038 | | /* Set things up to the right starting state. */ |
1039 | 28.6k | PORT_Memset(xtnData, 0, sizeof(*xtnData)); |
1040 | 28.6k | xtnData->peerSupportsFfdheGroups = PR_FALSE; |
1041 | 28.6k | PR_INIT_CLIST(&xtnData->remoteKeyShares); |
1042 | | |
1043 | | /* Allocate enough to allow for native extensions, plus any custom ones. */ |
1044 | 28.6k | if (ss->sec.isServer) { |
1045 | 6.54k | advertisedMax = PR_MAX(PR_ARRAY_SIZE(certificateRequestHandlers), |
1046 | 6.54k | PR_ARRAY_SIZE(tls13_cert_req_senders)); |
1047 | 22.1k | } else { |
1048 | 22.1k | advertisedMax = PR_MAX(PR_ARRAY_SIZE(clientHelloHandlers), |
1049 | 22.1k | PR_ARRAY_SIZE(clientHelloSendersTLS)); |
1050 | 22.1k | ++advertisedMax; /* For the RI SCSV, which we also track. */ |
1051 | 22.1k | } |
1052 | 28.6k | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
1053 | 28.6k | cursor != &ss->extensionHooks; |
1054 | 28.6k | cursor = PR_NEXT_LINK(cursor)) { |
1055 | 0 | ++advertisedMax; |
1056 | 0 | } |
1057 | 28.6k | xtnData->advertised = PORT_ZNewArray(PRUint16, advertisedMax); |
1058 | 28.6k | xtnData->echAdvertised = PORT_ZNewArray(PRUint16, advertisedMax); |
1059 | | |
1060 | 28.6k | xtnData->peerDelegCred = NULL; |
1061 | 28.6k | xtnData->peerRequestedDelegCred = PR_FALSE; |
1062 | 28.6k | xtnData->sendingDelegCredToPeer = PR_FALSE; |
1063 | 28.6k | xtnData->selectedPsk = NULL; |
1064 | 28.6k | } |
1065 | | |
1066 | | void |
1067 | | ssl3_DestroyExtensionData(TLSExtensionData *xtnData) |
1068 | 28.6k | { |
1069 | 28.6k | ssl3_FreeSniNameArray(xtnData); |
1070 | 28.6k | PORT_Free(xtnData->sigSchemes); |
1071 | 28.6k | PORT_Free(xtnData->delegCredSigSchemes); |
1072 | 28.6k | PORT_Free(xtnData->delegCredSigSchemesAdvertised); |
1073 | 28.6k | SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); |
1074 | 28.6k | tls13_DestroyKeyShares(&xtnData->remoteKeyShares); |
1075 | 28.6k | SECITEM_FreeItem(&xtnData->certReqContext, PR_FALSE); |
1076 | 28.6k | SECITEM_FreeItem(&xtnData->applicationToken, PR_FALSE); |
1077 | 28.6k | if (xtnData->certReqAuthorities.arena) { |
1078 | 0 | PORT_FreeArena(xtnData->certReqAuthorities.arena, PR_FALSE); |
1079 | 0 | xtnData->certReqAuthorities.arena = NULL; |
1080 | 0 | } |
1081 | 28.6k | PORT_Free(xtnData->advertised); |
1082 | 28.6k | PORT_Free(xtnData->echAdvertised); |
1083 | 28.6k | tls13_DestroyDelegatedCredential(xtnData->peerDelegCred); |
1084 | | |
1085 | 28.6k | tls13_DestroyEchXtnState(xtnData->ech); |
1086 | 28.6k | xtnData->ech = NULL; |
1087 | 28.6k | } |
1088 | | |
1089 | | /* Free everything that has been allocated and then reset back to |
1090 | | * the starting state. */ |
1091 | | void |
1092 | | ssl3_ResetExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) |
1093 | 21.3k | { |
1094 | 21.3k | ssl3_DestroyExtensionData(xtnData); |
1095 | 21.3k | ssl3_InitExtensionData(xtnData, ss); |
1096 | 21.3k | } |
1097 | | |
1098 | | /* Thunks to let extension handlers operate on const sslSocket* objects. */ |
1099 | | void |
1100 | | ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, |
1101 | | SSL3AlertDescription desc) |
1102 | 45 | { |
1103 | 45 | (void)SSL3_SendAlert((sslSocket *)ss, level, desc); |
1104 | 45 | } |
1105 | | |
1106 | | void |
1107 | | ssl3_ExtDecodeError(const sslSocket *ss) |
1108 | 33 | { |
1109 | 33 | (void)ssl3_DecodeError((sslSocket *)ss); |
1110 | 33 | } |
1111 | | |
1112 | | SECStatus |
1113 | | ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRUint32 bytes, |
1114 | | PRUint8 **b, PRUint32 *length) |
1115 | 0 | { |
1116 | 0 | return ssl3_ConsumeHandshake((sslSocket *)ss, v, bytes, b, length); |
1117 | 0 | } |
1118 | | |
1119 | | SECStatus |
1120 | | ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRUint32 *num, |
1121 | | PRUint32 bytes, PRUint8 **b, PRUint32 *length) |
1122 | 4.11k | { |
1123 | 4.11k | return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, num, bytes, b, length); |
1124 | 4.11k | } |
1125 | | |
1126 | | SECStatus |
1127 | | ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, |
1128 | | PRUint32 bytes, PRUint8 **b, |
1129 | | PRUint32 *length) |
1130 | 311 | { |
1131 | 311 | return ssl3_ConsumeHandshakeVariable((sslSocket *)ss, i, bytes, b, length); |
1132 | 311 | } |
1133 | | |
1134 | | SECStatus |
1135 | | tls_ClientHelloExtensionPermutationSetup(sslSocket *ss) |
1136 | 0 | { |
1137 | 0 | size_t buildersLen = PR_ARRAY_SIZE(clientHelloSendersTLS); |
1138 | 0 | const size_t buildersSize = (sizeof(sslExtensionBuilder) * buildersLen); |
1139 | | /* Psk Extension and then NULL entry MUST be last. */ |
1140 | 0 | const size_t permutationLen = buildersLen - 2; |
1141 | | |
1142 | | /* There shouldn't already be a stored permutation. */ |
1143 | 0 | PR_ASSERT(!ss->ssl3.hs.chExtensionPermutation); |
1144 | | |
1145 | | /* This shuffle handles up to 256 extensions. */ |
1146 | 0 | PR_ASSERT(buildersLen < 256); |
1147 | 0 | uint8_t permutation[256] = { 0 }; |
1148 | |
|
1149 | 0 | sslExtensionBuilder *builders = PORT_ZAlloc(buildersSize); |
1150 | 0 | if (!builders) { |
1151 | 0 | return SECFailure; |
1152 | 0 | } |
1153 | | |
1154 | | /* Get a working copy of default builders. */ |
1155 | 0 | PORT_Memcpy(builders, clientHelloSendersTLS, buildersSize); |
1156 | | |
1157 | | /* Get permutation randoms. */ |
1158 | 0 | if (PK11_GenerateRandom(permutation, permutationLen) != SECSuccess) { |
1159 | 0 | PORT_Free(builders); |
1160 | 0 | return SECFailure; |
1161 | 0 | } |
1162 | | |
1163 | | /* Fisher-Yates Shuffle */ |
1164 | 0 | for (size_t i = permutationLen - 1; i > 0; i--) { |
1165 | 0 | size_t idx = permutation[i - 1] % (i + 1); |
1166 | 0 | sslExtensionBuilder tmp = builders[i]; |
1167 | 0 | builders[i] = builders[idx]; |
1168 | 0 | builders[idx] = tmp; |
1169 | 0 | } |
1170 | | |
1171 | | /* Make sure that Psk extension is penultimate (before NULL entry). */ |
1172 | 0 | PR_ASSERT(builders[buildersLen - 2].ex_type == ssl_tls13_pre_shared_key_xtn); |
1173 | 0 | PR_ASSERT(builders[buildersLen - 2].ex_sender == clientHelloSendersTLS[buildersLen - 2].ex_sender); |
1174 | |
|
1175 | 0 | ss->ssl3.hs.chExtensionPermutation = builders; |
1176 | 0 | return SECSuccess; |
1177 | 0 | } |
1178 | | |
1179 | | void |
1180 | | tls_ClientHelloExtensionPermutationDestroy(sslSocket *ss) |
1181 | 14.7k | { |
1182 | 14.7k | if (ss->ssl3.hs.chExtensionPermutation) { |
1183 | 0 | PORT_Free(ss->ssl3.hs.chExtensionPermutation); |
1184 | 0 | ss->ssl3.hs.chExtensionPermutation = NULL; |
1185 | 0 | } |
1186 | 14.7k | } |