/src/nss/lib/ssl/ssl3ext.c
Line | Count | Source |
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 | 129k | { |
216 | 129k | unsigned int i; |
217 | 1.64M | for (i = 0; i < PR_ARRAY_SIZE(ssl_supported_extensions); ++i) { |
218 | 1.61M | if (type == ssl_supported_extensions[i].type) { |
219 | 106k | return ssl_supported_extensions[i].support; |
220 | 106k | } |
221 | 1.61M | } |
222 | 23.6k | return ssl_ext_none; |
223 | 129k | } |
224 | | |
225 | | SECStatus |
226 | | SSLExp_GetExtensionSupport(PRUint16 type, SSLExtensionSupport *support) |
227 | 129k | { |
228 | 129k | *support = ssl_GetExtensionSupport(type); |
229 | 129k | return SECSuccess; |
230 | 129k | } |
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 | 2.00M | { |
295 | 2.00M | PRCList *cursor; |
296 | | |
297 | 2.00M | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
298 | 2.00M | cursor != &ss->extensionHooks; |
299 | 2.00M | 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 | 2.00M | return NULL; |
307 | 2.00M | } |
308 | | |
309 | | static PRBool |
310 | | arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) |
311 | 1.66M | { |
312 | 1.66M | unsigned int i; |
313 | 4.60M | for (i = 0; i < len; i++) { |
314 | 3.17M | if (ex_type == array[i]) |
315 | 242k | return PR_TRUE; |
316 | 3.17M | } |
317 | 1.42M | return PR_FALSE; |
318 | 1.66M | } |
319 | | |
320 | | PRBool |
321 | | ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type) |
322 | 1.37M | { |
323 | 1.37M | const TLSExtensionData *xtnData = &ss->xtnData; |
324 | 1.37M | return arrayContainsExtension(xtnData->negotiated, |
325 | 1.37M | xtnData->numNegotiated, ex_type); |
326 | 1.37M | } |
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 | 216k | { |
334 | 216k | const TLSExtensionData *xtnData = &ss->xtnData; |
335 | 216k | return arrayContainsExtension(xtnData->advertised, |
336 | 216k | xtnData->numAdvertised, ex_type); |
337 | 216k | } |
338 | | |
339 | | void |
340 | | ssl3_RecordExtensionNegotiated(const sslSocket *ss, TLSExtensionData *xtnData, |
341 | | PRUint16 ex_type) |
342 | 71.9k | { |
343 | | /* Record that an extension was negotiated during a full TLS handshake. |
344 | | * This function must NOT be used to track extensions carried in |
345 | | * post-handshake messages (e.g. CertificateRequest during PHA); |
346 | | * their negotiation state should instead be stored in dedicated fields on |
347 | | * TLSExtensionData or sslSocket (e.g. xtnData->compressionAlg for |
348 | | * certificate compression). */ |
349 | 71.9k | PORT_Assert(!ss->firstHsDone || |
350 | 71.9k | ss->opt.enableRenegotiation != SSL_RENEGOTIATE_NEVER); |
351 | 71.9k | PORT_Assert(!arrayContainsExtension(xtnData->negotiated, |
352 | 71.9k | xtnData->numNegotiated, ex_type)); |
353 | 71.9k | PORT_Assert(xtnData->numNegotiated < SSL_MAX_EXTENSIONS); |
354 | 71.9k | if (xtnData->numNegotiated < SSL_MAX_EXTENSIONS) { |
355 | 71.9k | xtnData->negotiated[xtnData->numNegotiated++] = ex_type; |
356 | 71.9k | } |
357 | 71.9k | } |
358 | | |
359 | | PRBool |
360 | | ssl3_ExtensionAdvertisedClientHelloInner(const sslSocket *ss, PRUint16 ex_type) |
361 | 4.91k | { |
362 | 4.91k | const TLSExtensionData *xtnData = &ss->xtnData; |
363 | 4.91k | return arrayContainsExtension(xtnData->echAdvertised, |
364 | 4.91k | xtnData->echNumAdvertised, ex_type); |
365 | 4.91k | } |
366 | | |
367 | | /* Go through hello extensions in |b| and deserialize |
368 | | * them into the list in |ss->ssl3.hs.remoteExtensions|. |
369 | | * The only checking we do in this point is for duplicates. |
370 | | * |
371 | | * IMPORTANT: This list just contains pointers to the incoming |
372 | | * buffer so they can only be used during ClientHello processing. |
373 | | */ |
374 | | SECStatus |
375 | | ssl3_ParseExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length) |
376 | 44.6k | { |
377 | | /* Clean out the extensions list. */ |
378 | 44.6k | ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); |
379 | | |
380 | 219k | while (*length) { |
381 | 175k | SECStatus rv; |
382 | 175k | PRUint32 extension_type; |
383 | 175k | SECItem extension_data = { siBuffer, NULL, 0 }; |
384 | 175k | TLSExtension *extension; |
385 | 175k | PRCList *cursor; |
386 | | |
387 | | /* Get the extension's type field */ |
388 | 175k | rv = ssl3_ConsumeHandshakeNumber(ss, &extension_type, 2, b, length); |
389 | 175k | if (rv != SECSuccess) { |
390 | 22 | return SECFailure; /* alert already sent */ |
391 | 22 | } |
392 | | |
393 | | /* Check whether an extension has been sent multiple times. */ |
394 | 175k | for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); |
395 | 660k | cursor != &ss->ssl3.hs.remoteExtensions; |
396 | 485k | cursor = PR_NEXT_LINK(cursor)) { |
397 | 485k | if (((TLSExtension *)cursor)->type == extension_type) { |
398 | 34 | (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
399 | 34 | PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); |
400 | 34 | return SECFailure; |
401 | 34 | } |
402 | 485k | } |
403 | | |
404 | | /* Get the data for this extension, so we can pass it or skip it. */ |
405 | 175k | rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length); |
406 | 175k | if (rv != SECSuccess) { |
407 | 143 | return rv; /* alert already sent */ |
408 | 143 | } |
409 | | |
410 | 174k | SSL_TRC(10, ("%d: SSL3[%d]: parsed extension %d len=%u", |
411 | 174k | SSL_GETPID(), ss->fd, extension_type, extension_data.len)); |
412 | | |
413 | 174k | extension = PORT_ZNew(TLSExtension); |
414 | 174k | if (!extension) { |
415 | 0 | return SECFailure; |
416 | 0 | } |
417 | | |
418 | 174k | extension->type = (PRUint16)extension_type; |
419 | 174k | extension->data = extension_data; |
420 | 174k | PR_APPEND_LINK(&extension->link, &ss->ssl3.hs.remoteExtensions); |
421 | 174k | } |
422 | | |
423 | 44.4k | return SECSuccess; |
424 | 44.6k | } |
425 | | |
426 | | TLSExtension * |
427 | | ssl3_FindExtension(sslSocket *ss, SSLExtensionType extension_type) |
428 | 164k | { |
429 | 164k | PRCList *cursor; |
430 | | |
431 | 164k | for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); |
432 | 382k | cursor != &ss->ssl3.hs.remoteExtensions; |
433 | 230k | cursor = PR_NEXT_LINK(cursor)) { |
434 | 230k | TLSExtension *extension = (TLSExtension *)cursor; |
435 | | |
436 | 230k | if (extension->type == extension_type) { |
437 | 12.1k | return extension; |
438 | 12.1k | } |
439 | 230k | } |
440 | | |
441 | 152k | return NULL; |
442 | 164k | } |
443 | | |
444 | | static SECStatus |
445 | | ssl_CallExtensionHandler(sslSocket *ss, SSLHandshakeType handshakeMessage, |
446 | | TLSExtension *extension, |
447 | | const ssl3ExtensionHandler *handler) |
448 | 159k | { |
449 | 159k | SECStatus rv = SECSuccess; |
450 | 159k | SSLAlertDescription alert = handshake_failure; |
451 | 159k | sslCustomExtensionHooks *customHooks; |
452 | | |
453 | 159k | customHooks = ssl_FindCustomExtensionHooks(ss, extension->type); |
454 | 159k | if (customHooks) { |
455 | 0 | if (customHooks->handler) { |
456 | 0 | rv = customHooks->handler(ss->fd, handshakeMessage, |
457 | 0 | extension->data.data, |
458 | 0 | extension->data.len, |
459 | 0 | &alert, customHooks->handlerArg); |
460 | 0 | } |
461 | 159k | } else { |
462 | | /* Find extension_type in table of Hello Extension Handlers. */ |
463 | 1.68M | for (; handler->ex_handler != NULL; ++handler) { |
464 | 1.64M | if (handler->ex_type == extension->type) { |
465 | 112k | SECItem tmp = extension->data; |
466 | | |
467 | 112k | rv = (*handler->ex_handler)(ss, &ss->xtnData, &tmp); |
468 | 112k | break; |
469 | 112k | } |
470 | 1.64M | } |
471 | 159k | } |
472 | | |
473 | 159k | if (rv != SECSuccess) { |
474 | 1.95k | if (!ss->ssl3.fatalAlertSent) { |
475 | | /* Send an alert if the handler didn't already. */ |
476 | 379 | (void)SSL3_SendAlert(ss, alert_fatal, alert); |
477 | 379 | } |
478 | 1.95k | return SECFailure; |
479 | 1.95k | } |
480 | | |
481 | 157k | return SECSuccess; |
482 | 159k | } |
483 | | |
484 | | /* Go through the hello extensions in |ss->ssl3.hs.remoteExtensions|. |
485 | | * For each one, find the extension handler in the table, and |
486 | | * if present, invoke that handler. |
487 | | * Servers ignore any extensions with unknown extension types. |
488 | | * Clients reject any extensions with unadvertised extension types |
489 | | * |
490 | | * In TLS >= 1.3, the client checks that extensions appear in the |
491 | | * right phase. |
492 | | */ |
493 | | SECStatus |
494 | | ssl3_HandleParsedExtensions(sslSocket *ss, SSLHandshakeType message) |
495 | 159k | { |
496 | 159k | const ssl3ExtensionHandler *handlers; |
497 | | /* HelloRetryRequest doesn't set ss->version. It might be safe to |
498 | | * do so, but we weren't entirely sure. TODO(ekr@rtfm.com). */ |
499 | 159k | PRBool isTLS13 = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) || |
500 | 149k | (message == ssl_hs_hello_retry_request); |
501 | | /* The following messages can include extensions that were not included in |
502 | | * the original ClientHello. */ |
503 | 159k | PRBool allowNotOffered = (message == ssl_hs_client_hello) || |
504 | 68.1k | (message == ssl_hs_certificate_request) || |
505 | 68.1k | (message == ssl_hs_new_session_ticket); |
506 | 159k | PRCList *cursor; |
507 | | |
508 | 159k | switch (message) { |
509 | 91.8k | case ssl_hs_client_hello: |
510 | 91.8k | handlers = clientHelloHandlers; |
511 | 91.8k | break; |
512 | 0 | case ssl_hs_new_session_ticket: |
513 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
514 | 0 | handlers = newSessionTicketHandlers; |
515 | 0 | break; |
516 | 2.87k | case ssl_hs_hello_retry_request: |
517 | 2.87k | handlers = helloRetryRequestHandlers; |
518 | 2.87k | break; |
519 | 0 | case ssl_hs_encrypted_extensions: |
520 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
521 | | /* fall through */ |
522 | 65.2k | case ssl_hs_server_hello: |
523 | 65.2k | if (ss->version > SSL_LIBRARY_VERSION_3_0) { |
524 | 65.2k | handlers = serverHelloHandlersTLS; |
525 | 65.2k | } else { |
526 | 0 | handlers = serverHelloHandlersSSL3; |
527 | 0 | } |
528 | 65.2k | break; |
529 | 0 | case ssl_hs_certificate: |
530 | 0 | PORT_Assert(!ss->sec.isServer); |
531 | 0 | handlers = serverCertificateHandlers; |
532 | 0 | break; |
533 | 0 | case ssl_hs_certificate_request: |
534 | 0 | PORT_Assert(!ss->sec.isServer); |
535 | 0 | handlers = certificateRequestHandlers; |
536 | 0 | break; |
537 | 0 | default: |
538 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
539 | 0 | PORT_Assert(0); |
540 | 0 | return SECFailure; |
541 | 159k | } |
542 | | |
543 | 159k | for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); |
544 | 328k | cursor != &ss->ssl3.hs.remoteExtensions; |
545 | 171k | cursor = PR_NEXT_LINK(cursor)) { |
546 | 171k | TLSExtension *extension = (TLSExtension *)cursor; |
547 | 171k | SECStatus rv; |
548 | | |
549 | | /* Check whether the server sent an extension which was not advertised |
550 | | * in the ClientHello. |
551 | | * |
552 | | * Note that a TLS 1.3 server should check if CertificateRequest |
553 | | * extensions were sent. But the extensions used for CertificateRequest |
554 | | * do not have any response, so we rely on |
555 | | * ssl3_ExtensionAdvertised to return false on the server. That |
556 | | * results in the server only rejecting any extension. */ |
557 | 171k | if (!allowNotOffered && (extension->type != ssl_tls13_cookie_xtn)) { |
558 | 30.3k | if (!ssl3_ExtensionAdvertised(ss, extension->type)) { |
559 | 107 | SSL_TRC(10, ("Server sent xtn type=%d which is invalid for the CHO", extension->type)); |
560 | 107 | (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension); |
561 | 107 | PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); |
562 | 107 | return SECFailure; |
563 | 107 | } |
564 | | /* If we offered ECH, we also check whether the extension is compatible with |
565 | | * the Client Hello Inner. We don't yet know whether the server accepted ECH, |
566 | | * so we only store this for now. If we later accept, we check this boolean |
567 | | * and reject with an unsupported_extension alert if it is set. */ |
568 | 30.2k | if (ss->ssl3.hs.echHpkeCtx && !ssl3_ExtensionAdvertisedClientHelloInner(ss, extension->type)) { |
569 | 1.25k | SSL_TRC(10, ("Server sent xtn type=%d which is invalid for the CHI", extension->type)); |
570 | 1.25k | ss->ssl3.hs.echInvalidExtension = PR_TRUE; |
571 | 1.25k | } |
572 | 30.2k | } |
573 | | |
574 | | /* Check that this is a legal extension in TLS 1.3 */ |
575 | 170k | if (isTLS13 && |
576 | 50.8k | !ssl_FindCustomExtensionHooks(ss, extension->type)) { |
577 | 50.8k | switch (tls13_ExtensionStatus(extension->type, message)) { |
578 | 39.1k | case tls13_extension_allowed: |
579 | 39.1k | break; |
580 | 11.6k | case tls13_extension_unknown: |
581 | 11.6k | if (allowNotOffered) { |
582 | 11.6k | continue; /* Skip over unknown extensions. */ |
583 | 11.6k | } |
584 | | /* RFC8446 Section 4.2 - Implementations MUST NOT send extension responses if |
585 | | * the remote endpoint did not send the corresponding extension request ... |
586 | | * Upon receiving such an extension, an endpoint MUST abort the handshake with |
587 | | * an "unsupported_extension" alert. */ |
588 | 6 | SSL_TRC(3, ("%d: TLS13: unknown extension %d in message %d", |
589 | 6 | SSL_GETPID(), extension, message)); |
590 | 6 | tls13_FatalError(ss, SSL_ERROR_RX_UNEXPECTED_EXTENSION, |
591 | 6 | unsupported_extension); |
592 | 6 | return SECFailure; |
593 | 19 | case tls13_extension_disallowed: |
594 | | /* RFC8446 Section 4.2 - If an implementation receives an extension which it |
595 | | * recognizes and which is not specified for the message in which it appears, |
596 | | * it MUST abort the handshake with an "illegal_parameter" alert. */ |
597 | 19 | SSL_TRC(3, ("%d: TLS13: disallowed extension %d in message %d", |
598 | 19 | SSL_GETPID(), extension, message)); |
599 | 19 | tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, |
600 | 19 | illegal_parameter); |
601 | 19 | return SECFailure; |
602 | 50.8k | } |
603 | 50.8k | } |
604 | | |
605 | | /* Special check for this being the last extension if it's |
606 | | * PreSharedKey */ |
607 | 159k | if (ss->sec.isServer && isTLS13 && |
608 | 28.1k | (extension->type == ssl_tls13_pre_shared_key_xtn) && |
609 | 571 | (PR_NEXT_LINK(cursor) != &ss->ssl3.hs.remoteExtensions)) { |
610 | 4 | tls13_FatalError(ss, |
611 | 4 | SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, |
612 | 4 | illegal_parameter); |
613 | 4 | return SECFailure; |
614 | 4 | } |
615 | | |
616 | 159k | rv = ssl_CallExtensionHandler(ss, message, extension, handlers); |
617 | 159k | if (rv != SECSuccess) { |
618 | 1.95k | return SECFailure; |
619 | 1.95k | } |
620 | 159k | } |
621 | 157k | return SECSuccess; |
622 | 159k | } |
623 | | |
624 | | /* Syntactic sugar around ssl3_ParseExtensions and |
625 | | * ssl3_HandleParsedExtensions. */ |
626 | | SECStatus |
627 | | ssl3_HandleExtensions(sslSocket *ss, |
628 | | PRUint8 **b, PRUint32 *length, |
629 | | SSLHandshakeType handshakeMessage) |
630 | 7.39k | { |
631 | 7.39k | SECStatus rv; |
632 | | |
633 | 7.39k | rv = ssl3_ParseExtensions(ss, b, length); |
634 | 7.39k | if (rv != SECSuccess) |
635 | 0 | return rv; |
636 | | |
637 | 7.39k | rv = ssl3_HandleParsedExtensions(ss, handshakeMessage); |
638 | 7.39k | if (rv != SECSuccess) |
639 | 17 | return rv; |
640 | | |
641 | 7.37k | ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); |
642 | 7.37k | return SECSuccess; |
643 | 7.39k | } |
644 | | |
645 | | /* Add a callback function to the table of senders of server hello extensions. |
646 | | */ |
647 | | SECStatus |
648 | | ssl3_RegisterExtensionSender(const sslSocket *ss, |
649 | | TLSExtensionData *xtnData, |
650 | | PRUint16 ex_type, |
651 | | sslExtensionBuilderFunc cb) |
652 | 47.2k | { |
653 | 47.2k | int i; |
654 | 47.2k | sslExtensionBuilder *sender; |
655 | 47.2k | if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { |
656 | 33.8k | sender = &xtnData->serverHelloSenders[0]; |
657 | 33.8k | } else { |
658 | 13.3k | if (tls13_ExtensionStatus(ex_type, ssl_hs_server_hello) == |
659 | 13.3k | tls13_extension_allowed) { |
660 | 5.58k | PORT_Assert(tls13_ExtensionStatus(ex_type, |
661 | 5.58k | ssl_hs_encrypted_extensions) == |
662 | 5.58k | tls13_extension_disallowed); |
663 | 5.58k | sender = &xtnData->serverHelloSenders[0]; |
664 | 7.80k | } else if (tls13_ExtensionStatus(ex_type, |
665 | 7.80k | ssl_hs_encrypted_extensions) == |
666 | 7.80k | tls13_extension_allowed) { |
667 | 7.11k | sender = &xtnData->encryptedExtensionsSenders[0]; |
668 | 7.11k | } else if (tls13_ExtensionStatus(ex_type, ssl_hs_certificate) == |
669 | 688 | tls13_extension_allowed) { |
670 | 688 | sender = &xtnData->certificateSenders[0]; |
671 | 688 | } else { |
672 | 0 | PORT_Assert(0); |
673 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
674 | 0 | return SECFailure; |
675 | 0 | } |
676 | 13.3k | } |
677 | 78.7k | for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { |
678 | 78.7k | if (!sender->ex_sender) { |
679 | 47.2k | sender->ex_type = ex_type; |
680 | 47.2k | sender->ex_sender = cb; |
681 | 47.2k | return SECSuccess; |
682 | 47.2k | } |
683 | | /* detect duplicate senders */ |
684 | 31.4k | PORT_Assert(sender->ex_type != ex_type); |
685 | 31.4k | if (sender->ex_type == ex_type) { |
686 | | /* duplicate */ |
687 | 0 | break; |
688 | 0 | } |
689 | 31.4k | } |
690 | 0 | PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */ |
691 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
692 | 0 | return SECFailure; |
693 | 47.2k | } |
694 | | |
695 | | SECStatus |
696 | | ssl_CallCustomExtensionSenders(sslSocket *ss, sslBuffer *buf, |
697 | | SSLHandshakeType message) |
698 | 0 | { |
699 | 0 | sslBuffer tail = SSL_BUFFER_EMPTY; |
700 | 0 | SECStatus rv; |
701 | 0 | PRCList *cursor; |
702 | | |
703 | | /* Save any extensions that want to be last. */ |
704 | 0 | if (ss->xtnData.lastXtnOffset) { |
705 | 0 | rv = sslBuffer_Append(&tail, buf->buf + ss->xtnData.lastXtnOffset, |
706 | 0 | buf->len - ss->xtnData.lastXtnOffset); |
707 | 0 | if (rv != SECSuccess) { |
708 | 0 | return SECFailure; |
709 | 0 | } |
710 | 0 | buf->len = ss->xtnData.lastXtnOffset; |
711 | 0 | } |
712 | | |
713 | | /* Reserve the maximum amount of space possible. */ |
714 | 0 | rv = sslBuffer_Grow(buf, 65535); |
715 | 0 | if (rv != SECSuccess) { |
716 | 0 | return SECFailure; |
717 | 0 | } |
718 | | |
719 | 0 | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
720 | 0 | cursor != &ss->extensionHooks; |
721 | 0 | cursor = PR_NEXT_LINK(cursor)) { |
722 | 0 | sslCustomExtensionHooks *hook = |
723 | 0 | (sslCustomExtensionHooks *)cursor; |
724 | 0 | PRBool append = PR_FALSE; |
725 | 0 | unsigned int len = 0; |
726 | |
|
727 | 0 | if (hook->writer) { |
728 | | /* The writer writes directly into |buf|. Provide space that allows |
729 | | * for the existing extensions, any tail, plus type and length. */ |
730 | 0 | unsigned int used = buf->len + tail.len + 4; |
731 | 0 | if (used > buf->space) { |
732 | 0 | PORT_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR); |
733 | 0 | goto loser; |
734 | 0 | } |
735 | 0 | unsigned int space = buf->space - used; |
736 | 0 | append = (*hook->writer)(ss->fd, message, |
737 | 0 | buf->buf + buf->len + 4, &len, space, |
738 | 0 | hook->writerArg); |
739 | 0 | if (len > space) { |
740 | 0 | PORT_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR); |
741 | 0 | goto loser; |
742 | 0 | } |
743 | 0 | } |
744 | 0 | if (!append) { |
745 | 0 | continue; |
746 | 0 | } |
747 | | |
748 | 0 | rv = sslBuffer_AppendNumber(buf, hook->type, 2); |
749 | 0 | if (rv != SECSuccess) { |
750 | 0 | goto loser; /* Code already set. */ |
751 | 0 | } |
752 | 0 | rv = sslBuffer_AppendNumber(buf, len, 2); |
753 | 0 | if (rv != SECSuccess) { |
754 | 0 | goto loser; /* Code already set. */ |
755 | 0 | } |
756 | 0 | buf->len += len; |
757 | |
|
758 | 0 | if (message == ssl_hs_client_hello || |
759 | 0 | message == ssl_hs_ech_outer_client_hello || |
760 | 0 | message == ssl_hs_certificate_request) { |
761 | 0 | ss->xtnData.advertised[ss->xtnData.numAdvertised++] = hook->type; |
762 | 0 | } |
763 | 0 | } |
764 | | |
765 | | /* Restore saved extension and move the marker. */ |
766 | 0 | if (ss->xtnData.lastXtnOffset) { |
767 | 0 | ss->xtnData.lastXtnOffset = buf->len; |
768 | 0 | rv = sslBuffer_Append(buf, tail.buf, tail.len); |
769 | 0 | if (rv != SECSuccess) { |
770 | 0 | goto loser; /* Code already set. */ |
771 | 0 | } |
772 | 0 | } |
773 | | |
774 | 0 | sslBuffer_Clear(&tail); |
775 | 0 | return SECSuccess; |
776 | | |
777 | 0 | loser: |
778 | 0 | sslBuffer_Clear(&tail); |
779 | 0 | return SECFailure; |
780 | 0 | } |
781 | | |
782 | | /* Call extension handlers for the given message. */ |
783 | | SECStatus |
784 | | ssl_ConstructExtensions(sslSocket *ss, sslBuffer *buf, SSLHandshakeType message) |
785 | 163k | { |
786 | 163k | const sslExtensionBuilder *sender; |
787 | 163k | SECStatus rv; |
788 | | |
789 | 163k | PORT_Assert(buf->len == 0); |
790 | | |
791 | | /* Clear out any extensions previously advertised */ |
792 | 163k | ss->xtnData.numAdvertised = 0; |
793 | 163k | ss->xtnData.echNumAdvertised = 0; |
794 | | |
795 | 163k | switch (message) { |
796 | 75.6k | case ssl_hs_client_hello: |
797 | 75.6k | if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) { |
798 | | /* Use TLS ClientHello Extension Permutation? */ |
799 | 75.6k | if (ss->opt.enableChXtnPermutation) { |
800 | 37.5k | sender = ss->ssl3.hs.chExtensionPermutation; |
801 | 38.0k | } else { |
802 | 38.0k | sender = clientHelloSendersTLS; |
803 | 38.0k | } |
804 | 75.6k | } else { |
805 | 0 | sender = clientHelloSendersSSL3; |
806 | 0 | } |
807 | 75.6k | break; |
808 | | |
809 | 80.5k | case ssl_hs_server_hello: |
810 | 80.5k | sender = ss->xtnData.serverHelloSenders; |
811 | 80.5k | break; |
812 | | |
813 | 1.24k | case ssl_hs_certificate_request: |
814 | 1.24k | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
815 | 1.24k | sender = tls13_cert_req_senders; |
816 | 1.24k | break; |
817 | | |
818 | 2.71k | case ssl_hs_certificate: |
819 | 2.71k | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
820 | 2.71k | sender = ss->xtnData.certificateSenders; |
821 | 2.71k | break; |
822 | | |
823 | 2.71k | case ssl_hs_encrypted_extensions: |
824 | 2.71k | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
825 | 2.71k | sender = ss->xtnData.encryptedExtensionsSenders; |
826 | 2.71k | break; |
827 | | |
828 | 950 | case ssl_hs_hello_retry_request: |
829 | 950 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
830 | 950 | sender = tls13_hrr_senders; |
831 | 950 | break; |
832 | | |
833 | 0 | default: |
834 | 0 | PORT_Assert(0); |
835 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
836 | 0 | return SECFailure; |
837 | 163k | } |
838 | | |
839 | 1.95M | for (; sender->ex_sender != NULL; ++sender) { |
840 | 1.79M | PRUint16 ex_type = sender->ex_type; |
841 | 1.79M | PRBool append = PR_FALSE; |
842 | 1.79M | unsigned int start = buf->len; |
843 | 1.79M | unsigned int length; |
844 | | |
845 | 1.79M | if (ssl_FindCustomExtensionHooks(ss, sender->ex_type)) { |
846 | 0 | continue; |
847 | 0 | } |
848 | | |
849 | | /* Save space for the extension type and length. Note that we don't grow |
850 | | * the buffer now; rely on sslBuffer_Append* to do that. */ |
851 | 1.79M | buf->len += 4; |
852 | 1.79M | rv = (*sender->ex_sender)(ss, &ss->xtnData, buf, &append); |
853 | 1.79M | if (rv != SECSuccess) { |
854 | 0 | goto loser; |
855 | 0 | } |
856 | | |
857 | | /* Save the length and go back to the start. */ |
858 | 1.79M | length = buf->len - start - 4; |
859 | 1.79M | buf->len = start; |
860 | 1.79M | if (!append) { |
861 | 1.04M | continue; |
862 | 1.04M | } |
863 | | |
864 | | /* If TLS 1.3 GREASE is enabled, replace ssl_tls13_grease_xtn dummy |
865 | | * GREASE extension types with randomly generated GREASE value. */ |
866 | 747k | rv = tls13_MaybeGreaseExtensionType(ss, message, &ex_type); |
867 | 747k | if (rv != SECSuccess) { |
868 | 0 | goto loser; /* Code already set. */ |
869 | 0 | } |
870 | | |
871 | 747k | rv = sslBuffer_AppendNumber(buf, ex_type, 2); |
872 | 747k | if (rv != SECSuccess) { |
873 | 0 | goto loser; /* Code already set. */ |
874 | 0 | } |
875 | 747k | rv = sslBuffer_AppendNumber(buf, length, 2); |
876 | 747k | if (rv != SECSuccess) { |
877 | 0 | goto loser; /* Code already set. */ |
878 | 0 | } |
879 | | /* Skip over the extension body. */ |
880 | 747k | buf->len += length; |
881 | | |
882 | 747k | if (message == ssl_hs_client_hello || |
883 | 711k | message == ssl_hs_certificate_request) { |
884 | 711k | ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
885 | 711k | ex_type; |
886 | 711k | } |
887 | 747k | } |
888 | | |
889 | 163k | if (!PR_CLIST_IS_EMPTY(&ss->extensionHooks)) { |
890 | 0 | if (message == ssl_hs_client_hello && ss->opt.callExtensionWriterOnEchInner) { |
891 | 0 | message = ssl_hs_ech_outer_client_hello; |
892 | 0 | } |
893 | 0 | rv = ssl_CallCustomExtensionSenders(ss, buf, message); |
894 | 0 | if (rv != SECSuccess) { |
895 | 0 | goto loser; |
896 | 0 | } |
897 | 0 | } |
898 | | |
899 | 163k | if (buf->len > 0xffff) { |
900 | 0 | PORT_SetError(SSL_ERROR_TX_RECORD_TOO_LONG); |
901 | 0 | goto loser; |
902 | 0 | } |
903 | | |
904 | 163k | return SECSuccess; |
905 | | |
906 | 0 | loser: |
907 | 0 | sslBuffer_Clear(buf); |
908 | 0 | return SECFailure; |
909 | 163k | } |
910 | | |
911 | | /* This extension sender can be used anywhere that an always empty extension is |
912 | | * needed. Mostly that is for ServerHello where sender registration is dynamic; |
913 | | * ClientHello senders are usually conditional in some way. */ |
914 | | SECStatus |
915 | | ssl_SendEmptyExtension(const sslSocket *ss, TLSExtensionData *xtnData, |
916 | | sslBuffer *buf, PRBool *append) |
917 | 8.87k | { |
918 | 8.87k | *append = PR_TRUE; |
919 | 8.87k | return SECSuccess; |
920 | 8.87k | } |
921 | | |
922 | | /* Takes the size of the ClientHello, less the record header, and determines how |
923 | | * much padding is required. */ |
924 | | static unsigned int |
925 | | ssl_CalculatePaddingExtLen(const sslSocket *ss, unsigned int clientHelloLength) |
926 | 75.6k | { |
927 | 75.6k | unsigned int extensionLen; |
928 | | |
929 | | /* Don't pad for DTLS, for SSLv3, or for renegotiation. */ |
930 | 75.6k | if (IS_DTLS(ss) || |
931 | 58.5k | ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_0 || |
932 | 58.5k | ss->firstHsDone) { |
933 | 57.0k | return 0; |
934 | 57.0k | } |
935 | | |
936 | | /* A padding extension may be included to ensure that the record containing |
937 | | * the ClientHello doesn't have a length between 256 and 511 bytes |
938 | | * (inclusive). Initial ClientHello records with such lengths trigger bugs |
939 | | * in F5 devices. */ |
940 | 18.5k | if (clientHelloLength < 256 || clientHelloLength >= 512) { |
941 | 10.9k | return 0; |
942 | 10.9k | } |
943 | | |
944 | 7.61k | extensionLen = 512 - clientHelloLength; |
945 | | /* Extensions take at least four bytes to encode. Always include at least |
946 | | * one byte of data if we are padding. Some servers will time out or |
947 | | * terminate the connection if the last ClientHello extension is empty. */ |
948 | 7.61k | if (extensionLen < 5) { |
949 | 3 | extensionLen = 5; |
950 | 3 | } |
951 | | |
952 | 7.61k | return extensionLen - 4; |
953 | 18.5k | } |
954 | | |
955 | | /* Manually insert an extension, retaining the position of the PSK |
956 | | * extension, if present. */ |
957 | | SECStatus |
958 | | ssl3_EmplaceExtension(sslSocket *ss, sslBuffer *buf, PRUint16 exType, |
959 | | const PRUint8 *data, unsigned int len, PRBool advertise) |
960 | 13.3k | { |
961 | 13.3k | SECStatus rv; |
962 | 13.3k | unsigned int tailLen; |
963 | | |
964 | | /* Move the tail if there is one. This only happens if we are sending the |
965 | | * TLS 1.3 PSK extension, which needs to be at the end. */ |
966 | 13.3k | if (ss->xtnData.lastXtnOffset) { |
967 | 2.82k | PORT_Assert(buf->len > ss->xtnData.lastXtnOffset); |
968 | 2.82k | tailLen = buf->len - ss->xtnData.lastXtnOffset; |
969 | 2.82k | rv = sslBuffer_Grow(buf, buf->len + 4 + len); |
970 | 2.82k | if (rv != SECSuccess) { |
971 | 0 | return SECFailure; |
972 | 0 | } |
973 | 2.82k | PORT_Memmove(buf->buf + ss->xtnData.lastXtnOffset + 4 + len, |
974 | 2.82k | buf->buf + ss->xtnData.lastXtnOffset, |
975 | 2.82k | tailLen); |
976 | 2.82k | buf->len = ss->xtnData.lastXtnOffset; |
977 | 10.5k | } else { |
978 | 10.5k | tailLen = 0; |
979 | 10.5k | } |
980 | 13.3k | if (exType == ssl_tls13_encrypted_client_hello_xtn) { |
981 | 5.78k | ss->xtnData.echXtnOffset = buf->len; |
982 | 5.78k | } |
983 | 13.3k | rv = sslBuffer_AppendNumber(buf, exType, 2); |
984 | 13.3k | if (rv != SECSuccess) { |
985 | 0 | return SECFailure; /* Code already set. */ |
986 | 0 | } |
987 | 13.3k | rv = sslBuffer_AppendVariable(buf, data, len, 2); |
988 | 13.3k | if (rv != SECSuccess) { |
989 | 0 | return SECFailure; /* Code already set. */ |
990 | 0 | } |
991 | | |
992 | 13.3k | if (ss->xtnData.lastXtnOffset) { |
993 | 2.82k | ss->xtnData.lastXtnOffset += 4 + len; |
994 | 2.82k | } |
995 | | |
996 | 13.3k | buf->len += tailLen; |
997 | | |
998 | | /* False only to retain behavior with padding_xtn. Maybe |
999 | | * we can just mark that advertised as well? TODO */ |
1000 | 13.3k | if (advertise) { |
1001 | 5.78k | ss->xtnData.advertised[ss->xtnData.numAdvertised++] = exType; |
1002 | 5.78k | } |
1003 | | |
1004 | 13.3k | return SECSuccess; |
1005 | 13.3k | } |
1006 | | |
1007 | | /* ssl3_SendPaddingExtension possibly adds an extension which ensures that a |
1008 | | * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures |
1009 | | * that we don't trigger bugs in F5 products. |
1010 | | * |
1011 | | * This takes an existing extension buffer, |buf|, and the length of the |
1012 | | * remainder of the ClientHello, |prefixLen|. It modifies the extension buffer |
1013 | | * to insert padding at the right place. |
1014 | | */ |
1015 | | SECStatus |
1016 | | ssl_InsertPaddingExtension(sslSocket *ss, unsigned int prefixLen, |
1017 | | sslBuffer *buf) |
1018 | 75.6k | { |
1019 | 75.6k | static unsigned char padding[252] = { 0 }; |
1020 | 75.6k | unsigned int paddingLen; |
1021 | | /* Exit early if an application-provided extension hook |
1022 | | * already added padding. */ |
1023 | 75.6k | if (ssl3_ExtensionAdvertised(ss, ssl_padding_xtn)) { |
1024 | 0 | return SECSuccess; |
1025 | 0 | } |
1026 | | |
1027 | | /* Account for the size of the header, the length field of the extensions |
1028 | | * block and the size of the existing extensions. */ |
1029 | 75.6k | paddingLen = ssl_CalculatePaddingExtLen(ss, prefixLen + 2 + buf->len); |
1030 | 75.6k | if (!paddingLen) { |
1031 | 68.0k | return SECSuccess; |
1032 | 68.0k | } |
1033 | | |
1034 | 7.61k | return ssl3_EmplaceExtension(ss, buf, ssl_padding_xtn, padding, paddingLen, PR_FALSE); |
1035 | 75.6k | } |
1036 | | |
1037 | | void |
1038 | | ssl3_MoveRemoteExtensions(PRCList *dst, PRCList *src) |
1039 | 0 | { |
1040 | 0 | PRCList *cur_p; |
1041 | 0 | while (!PR_CLIST_IS_EMPTY(src)) { |
1042 | 0 | cur_p = PR_LIST_TAIL(src); |
1043 | 0 | PR_REMOVE_LINK(cur_p); |
1044 | 0 | PR_INSERT_LINK(cur_p, dst); |
1045 | 0 | } |
1046 | 0 | } |
1047 | | |
1048 | | void |
1049 | | ssl3_DestroyRemoteExtensions(PRCList *list) |
1050 | 455k | { |
1051 | 455k | PRCList *cur_p; |
1052 | | |
1053 | 630k | while (!PR_CLIST_IS_EMPTY(list)) { |
1054 | 174k | cur_p = PR_LIST_TAIL(list); |
1055 | 174k | PR_REMOVE_LINK(cur_p); |
1056 | 174k | PORT_Free(cur_p); |
1057 | 174k | } |
1058 | 455k | } |
1059 | | |
1060 | | /* Initialize the extension data block. */ |
1061 | | void |
1062 | | ssl3_InitExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) |
1063 | 349k | { |
1064 | 349k | unsigned int advertisedMax; |
1065 | 349k | PRCList *cursor; |
1066 | | |
1067 | | /* Set things up to the right starting state. */ |
1068 | 349k | PORT_Memset(xtnData, 0, sizeof(*xtnData)); |
1069 | 349k | xtnData->peerSupportsFfdheGroups = PR_FALSE; |
1070 | 349k | PR_INIT_CLIST(&xtnData->remoteKeyShares); |
1071 | | |
1072 | | /* Allocate enough to allow for native extensions, plus any custom ones. */ |
1073 | 349k | if (ss->sec.isServer) { |
1074 | 85.2k | advertisedMax = PR_MAX(PR_ARRAY_SIZE(certificateRequestHandlers), |
1075 | 85.2k | PR_ARRAY_SIZE(tls13_cert_req_senders)); |
1076 | 264k | } else { |
1077 | 264k | advertisedMax = PR_MAX(PR_ARRAY_SIZE(clientHelloHandlers), |
1078 | 264k | PR_ARRAY_SIZE(clientHelloSendersTLS)); |
1079 | 264k | ++advertisedMax; /* For the RI SCSV, which we also track. */ |
1080 | 264k | } |
1081 | 349k | for (cursor = PR_NEXT_LINK(&ss->extensionHooks); |
1082 | 349k | cursor != &ss->extensionHooks; |
1083 | 349k | cursor = PR_NEXT_LINK(cursor)) { |
1084 | 0 | ++advertisedMax; |
1085 | 0 | } |
1086 | 349k | xtnData->advertised = PORT_ZNewArray(PRUint16, advertisedMax); |
1087 | 349k | xtnData->echAdvertised = PORT_ZNewArray(PRUint16, advertisedMax); |
1088 | | |
1089 | 349k | xtnData->peerDelegCred = NULL; |
1090 | 349k | xtnData->peerRequestedDelegCred = PR_FALSE; |
1091 | 349k | xtnData->sendingDelegCredToPeer = PR_FALSE; |
1092 | 349k | xtnData->selectedPsk = NULL; |
1093 | 349k | } |
1094 | | |
1095 | | void |
1096 | | ssl3_DestroyExtensionData(TLSExtensionData *xtnData) |
1097 | 349k | { |
1098 | 349k | ssl3_FreeSniNameArray(xtnData); |
1099 | 349k | PORT_Free(xtnData->sigSchemes); |
1100 | 349k | PORT_Free(xtnData->delegCredSigSchemes); |
1101 | 349k | PORT_Free(xtnData->delegCredSigSchemesAdvertised); |
1102 | 349k | SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); |
1103 | 349k | tls13_DestroyKeyShares(&xtnData->remoteKeyShares); |
1104 | 349k | SECITEM_FreeItem(&xtnData->certReqContext, PR_FALSE); |
1105 | 349k | SECITEM_FreeItem(&xtnData->applicationToken, PR_FALSE); |
1106 | 349k | if (xtnData->certReqAuthorities.arena) { |
1107 | 0 | PORT_FreeArena(xtnData->certReqAuthorities.arena, PR_FALSE); |
1108 | 0 | xtnData->certReqAuthorities.arena = NULL; |
1109 | 0 | } |
1110 | 349k | PORT_Free(xtnData->advertised); |
1111 | 349k | PORT_Free(xtnData->echAdvertised); |
1112 | 349k | tls13_DestroyDelegatedCredential(xtnData->peerDelegCred); |
1113 | | |
1114 | 349k | tls13_DestroyEchXtnState(xtnData->ech); |
1115 | 349k | xtnData->ech = NULL; |
1116 | 349k | } |
1117 | | |
1118 | | /* Free everything that has been allocated and then reset back to |
1119 | | * the starting state. */ |
1120 | | void |
1121 | | ssl3_ResetExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) |
1122 | 286k | { |
1123 | 286k | ssl3_DestroyExtensionData(xtnData); |
1124 | 286k | ssl3_InitExtensionData(xtnData, ss); |
1125 | 286k | } |
1126 | | |
1127 | | /* Thunks to let extension handlers operate on const sslSocket* objects. */ |
1128 | | void |
1129 | | ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, |
1130 | | SSL3AlertDescription desc) |
1131 | 1.02k | { |
1132 | 1.02k | (void)SSL3_SendAlert((sslSocket *)ss, level, desc); |
1133 | 1.02k | } |
1134 | | |
1135 | | void |
1136 | | ssl3_ExtDecodeError(const sslSocket *ss) |
1137 | 245 | { |
1138 | 245 | (void)ssl3_DecodeError((sslSocket *)ss); |
1139 | 245 | } |
1140 | | |
1141 | | SECStatus |
1142 | | ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRUint32 bytes, |
1143 | | PRUint8 **b, PRUint32 *length) |
1144 | 215 | { |
1145 | 215 | return ssl3_ConsumeHandshake((sslSocket *)ss, v, bytes, b, length); |
1146 | 215 | } |
1147 | | |
1148 | | SECStatus |
1149 | | ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRUint32 *num, |
1150 | | PRUint32 bytes, PRUint8 **b, PRUint32 *length) |
1151 | 211k | { |
1152 | 211k | return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, num, bytes, b, length); |
1153 | 211k | } |
1154 | | |
1155 | | SECStatus |
1156 | | ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, |
1157 | | PRUint32 bytes, PRUint8 **b, |
1158 | | PRUint32 *length) |
1159 | 15.6k | { |
1160 | 15.6k | return ssl3_ConsumeHandshakeVariable((sslSocket *)ss, i, bytes, b, length); |
1161 | 15.6k | } |
1162 | | |
1163 | | SECStatus |
1164 | | tls_ClientHelloExtensionPermutationSetup(sslSocket *ss) |
1165 | 15.9k | { |
1166 | 15.9k | size_t buildersLen = PR_ARRAY_SIZE(clientHelloSendersTLS); |
1167 | 15.9k | const size_t buildersSize = (sizeof(sslExtensionBuilder) * buildersLen); |
1168 | | /* Psk Extension and then NULL entry MUST be last. */ |
1169 | 15.9k | const size_t permutationLen = buildersLen - 2; |
1170 | | |
1171 | | /* There shouldn't already be a stored permutation. */ |
1172 | 15.9k | PR_ASSERT(!ss->ssl3.hs.chExtensionPermutation); |
1173 | | |
1174 | | /* This shuffle handles up to 256 extensions. */ |
1175 | 15.9k | PR_ASSERT(buildersLen < 256); |
1176 | 15.9k | uint8_t permutation[256] = { 0 }; |
1177 | | |
1178 | 15.9k | sslExtensionBuilder *builders = PORT_ZAlloc(buildersSize); |
1179 | 15.9k | if (!builders) { |
1180 | 0 | return SECFailure; |
1181 | 0 | } |
1182 | | |
1183 | | /* Get a working copy of default builders. */ |
1184 | 15.9k | PORT_Memcpy(builders, clientHelloSendersTLS, buildersSize); |
1185 | | |
1186 | | /* Get permutation randoms. */ |
1187 | 15.9k | if (PK11_GenerateRandom(permutation, permutationLen) != SECSuccess) { |
1188 | 0 | PORT_Free(builders); |
1189 | 0 | return SECFailure; |
1190 | 0 | } |
1191 | | |
1192 | | /* Fisher-Yates Shuffle */ |
1193 | 351k | for (size_t i = permutationLen - 1; i > 0; i--) { |
1194 | 335k | size_t idx = permutation[i - 1] % (i + 1); |
1195 | 335k | sslExtensionBuilder tmp = builders[i]; |
1196 | 335k | builders[i] = builders[idx]; |
1197 | 335k | builders[idx] = tmp; |
1198 | 335k | } |
1199 | | |
1200 | | /* Make sure that Psk extension is penultimate (before NULL entry). */ |
1201 | 15.9k | PR_ASSERT(builders[buildersLen - 2].ex_type == ssl_tls13_pre_shared_key_xtn); |
1202 | 15.9k | PR_ASSERT(builders[buildersLen - 2].ex_sender == clientHelloSendersTLS[buildersLen - 2].ex_sender); |
1203 | | |
1204 | 15.9k | ss->ssl3.hs.chExtensionPermutation = builders; |
1205 | 15.9k | return SECSuccess; |
1206 | 15.9k | } |
1207 | | |
1208 | | void |
1209 | | tls_ClientHelloExtensionPermutationDestroy(sslSocket *ss) |
1210 | 125k | { |
1211 | 125k | if (ss->ssl3.hs.chExtensionPermutation) { |
1212 | 15.9k | PORT_Free(ss->ssl3.hs.chExtensionPermutation); |
1213 | | ss->ssl3.hs.chExtensionPermutation = NULL; |
1214 | 15.9k | } |
1215 | 125k | } |