1 /*
2 * Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 /* Custom extension utility functions */
11
12 #include <openssl/ct.h>
13 #include "../ssl_local.h"
14 #include "internal/cryptlib.h"
15 #include "internal/ssl_unwrap.h"
16 #include "statem_local.h"
17
18 typedef struct {
19 void *add_arg;
20 custom_ext_add_cb add_cb;
21 custom_ext_free_cb free_cb;
22 } custom_ext_add_cb_wrap;
23
24 typedef struct {
25 void *parse_arg;
26 custom_ext_parse_cb parse_cb;
27 } custom_ext_parse_cb_wrap;
28
29 /*
30 * Provide thin wrapper callbacks which convert new style arguments to old style
31 */
custom_ext_add_old_cb_wrap(SSL * s,unsigned int ext_type,unsigned int context,const unsigned char ** out,size_t * outlen,X509 * x,size_t chainidx,int * al,void * add_arg)32 static int custom_ext_add_old_cb_wrap(SSL *s, unsigned int ext_type,
33 unsigned int context,
34 const unsigned char **out,
35 size_t *outlen, X509 *x, size_t chainidx,
36 int *al, void *add_arg)
37 {
38 custom_ext_add_cb_wrap *add_cb_wrap = (custom_ext_add_cb_wrap *)add_arg;
39
40 if (add_cb_wrap->add_cb == NULL)
41 return 1;
42
43 return add_cb_wrap->add_cb(s, ext_type, out, outlen, al,
44 add_cb_wrap->add_arg);
45 }
46
custom_ext_free_old_cb_wrap(SSL * s,unsigned int ext_type,unsigned int context,const unsigned char * out,void * add_arg)47 static void custom_ext_free_old_cb_wrap(SSL *s, unsigned int ext_type,
48 unsigned int context,
49 const unsigned char *out, void *add_arg)
50 {
51 custom_ext_add_cb_wrap *add_cb_wrap = (custom_ext_add_cb_wrap *)add_arg;
52
53 if (add_cb_wrap->free_cb == NULL)
54 return;
55
56 add_cb_wrap->free_cb(s, ext_type, out, add_cb_wrap->add_arg);
57 }
58
custom_ext_parse_old_cb_wrap(SSL * s,unsigned int ext_type,unsigned int context,const unsigned char * in,size_t inlen,X509 * x,size_t chainidx,int * al,void * parse_arg)59 static int custom_ext_parse_old_cb_wrap(SSL *s, unsigned int ext_type,
60 unsigned int context,
61 const unsigned char *in,
62 size_t inlen, X509 *x, size_t chainidx,
63 int *al, void *parse_arg)
64 {
65 custom_ext_parse_cb_wrap *parse_cb_wrap = (custom_ext_parse_cb_wrap *)parse_arg;
66
67 if (parse_cb_wrap->parse_cb == NULL)
68 return 1;
69
70 return parse_cb_wrap->parse_cb(s, ext_type, in, inlen, al,
71 parse_cb_wrap->parse_arg);
72 }
73
74 /*
75 * Find a custom extension from the list. The |role| param is there to
76 * support the legacy API where custom extensions for client and server could
77 * be set independently on the same SSL_CTX. It is set to ENDPOINT_SERVER if we
78 * are trying to find a method relevant to the server, ENDPOINT_CLIENT for the
79 * client, or ENDPOINT_BOTH for either
80 */
custom_ext_find(const custom_ext_methods * exts,ENDPOINT role,unsigned int ext_type,size_t * idx)81 custom_ext_method *custom_ext_find(const custom_ext_methods *exts,
82 ENDPOINT role, unsigned int ext_type,
83 size_t *idx)
84 {
85 size_t i;
86 custom_ext_method *meth = exts->meths;
87
88 for (i = 0; i < exts->meths_count; i++, meth++) {
89 if (ext_type == meth->ext_type
90 && (role == ENDPOINT_BOTH || role == meth->role
91 || meth->role == ENDPOINT_BOTH)) {
92 if (idx != NULL)
93 *idx = i;
94 return meth;
95 }
96 }
97 return NULL;
98 }
99
100 /*
101 * Initialise custom extensions flags to indicate neither sent nor received.
102 */
custom_ext_init(custom_ext_methods * exts)103 void custom_ext_init(custom_ext_methods *exts)
104 {
105 size_t i;
106 custom_ext_method *meth = exts->meths;
107
108 for (i = 0; i < exts->meths_count; i++, meth++)
109 meth->ext_flags &= ~(SSL_EXT_FLAG_SENT | SSL_EXT_FLAG_RECEIVED);
110 }
111
112 /* Pass received custom extension data to the application for parsing. */
custom_ext_parse(SSL_CONNECTION * s,unsigned int context,unsigned int ext_type,const unsigned char * ext_data,size_t ext_size,X509 * x,size_t chainidx)113 int custom_ext_parse(SSL_CONNECTION *s, unsigned int context,
114 unsigned int ext_type,
115 const unsigned char *ext_data, size_t ext_size, X509 *x,
116 size_t chainidx)
117 {
118 int al = 0;
119 custom_ext_methods *exts = &s->cert->custext;
120 custom_ext_method *meth;
121 ENDPOINT role = ENDPOINT_BOTH;
122
123 if ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0)
124 role = s->server ? ENDPOINT_SERVER : ENDPOINT_CLIENT;
125
126 meth = custom_ext_find(exts, role, ext_type, NULL);
127 /* If not found return success */
128 if (!meth)
129 return 1;
130
131 /* Check if extension is defined for our protocol. If not, skip */
132 if (!extension_is_relevant(s, meth->context, context))
133 return 1;
134
135 if ((context & (SSL_EXT_TLS1_2_SERVER_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS)) != 0) {
136 /*
137 * If it's ServerHello or EncryptedExtensions we can't have any
138 * extensions not sent in ClientHello.
139 */
140 if ((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0) {
141 SSLfatal(s, TLS1_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION);
142 return 0;
143 }
144 }
145
146 /*
147 * Extensions received in the ClientHello or CertificateRequest are marked
148 * with the SSL_EXT_FLAG_RECEIVED. This is so we know to add the equivalent
149 * extensions in the response messages
150 */
151 if ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST))
152 != 0)
153 meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;
154
155 /* If no parse function set return success */
156 if (meth->parse_cb == NULL)
157 return 1;
158
159 if (meth->parse_cb(SSL_CONNECTION_GET_USER_SSL(s), ext_type, context, ext_data,
160 ext_size, x, chainidx, &al, meth->parse_arg)
161 <= 0) {
162 SSLfatal(s, al, SSL_R_BAD_EXTENSION);
163 return 0;
164 }
165
166 return 1;
167 }
168
169 /*
170 * Request custom extension data from the application and add to the return
171 * buffer.
172 */
custom_ext_add(SSL_CONNECTION * s,int context,WPACKET * pkt,X509 * x,size_t chainidx,int maxversion)173 int custom_ext_add(SSL_CONNECTION *s, int context, WPACKET *pkt, X509 *x,
174 size_t chainidx, int maxversion)
175 {
176 custom_ext_methods *exts = &s->cert->custext;
177 custom_ext_method *meth;
178 size_t i;
179 int al;
180 int for_comp = (context & SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION) != 0;
181
182 for (i = 0; i < exts->meths_count; i++) {
183 const unsigned char *out = NULL;
184 size_t outlen = 0;
185
186 meth = exts->meths + i;
187
188 if (!should_add_extension(s, meth->context, context, maxversion))
189 continue;
190
191 if ((context & (SSL_EXT_TLS1_2_SERVER_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS | SSL_EXT_TLS1_3_CERTIFICATE | SSL_EXT_TLS1_3_RAW_PUBLIC_KEY | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST)) != 0) {
192 /* Only send extensions present in ClientHello/CertificateRequest */
193 if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED))
194 continue;
195 }
196 /*
197 * We skip it if the callback is absent - except for a ClientHello where
198 * we add an empty extension.
199 */
200 if ((context & SSL_EXT_CLIENT_HELLO) == 0 && meth->add_cb == NULL)
201 continue;
202
203 if (meth->add_cb != NULL) {
204 int cb_retval = meth->add_cb(SSL_CONNECTION_GET_USER_SSL(s),
205 meth->ext_type, context, &out,
206 &outlen, x, chainidx, &al,
207 meth->add_arg);
208
209 if (cb_retval < 0) {
210 if (!for_comp)
211 SSLfatal(s, al, SSL_R_CALLBACK_FAILED);
212 return 0; /* error */
213 }
214 if (cb_retval == 0)
215 continue; /* skip this extension */
216 }
217
218 if (!WPACKET_put_bytes_u16(pkt, meth->ext_type)
219 || !WPACKET_start_sub_packet_u16(pkt)
220 || (outlen > 0 && !WPACKET_memcpy(pkt, out, outlen))
221 || !WPACKET_close(pkt)) {
222 if (meth->free_cb != NULL)
223 meth->free_cb(SSL_CONNECTION_GET_USER_SSL(s), meth->ext_type,
224 context, out, meth->add_arg);
225 if (!for_comp)
226 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
227 return 0;
228 }
229 if ((context & SSL_EXT_CLIENT_HELLO) != 0) {
230 /*
231 * We can't send duplicates: code logic should prevent this.
232 */
233 if (!ossl_assert((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0)) {
234 if (meth->free_cb != NULL)
235 meth->free_cb(SSL_CONNECTION_GET_USER_SSL(s), meth->ext_type,
236 context, out, meth->add_arg);
237 if (!for_comp)
238 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
239 return 0;
240 }
241 /*
242 * Indicate extension has been sent: this is both a sanity check to
243 * ensure we don't send duplicate extensions and indicates that it
244 * is not an error if the extension is present in ServerHello.
245 */
246 meth->ext_flags |= SSL_EXT_FLAG_SENT;
247 }
248 if (meth->free_cb != NULL)
249 meth->free_cb(SSL_CONNECTION_GET_USER_SSL(s), meth->ext_type,
250 context, out, meth->add_arg);
251 }
252 return 1;
253 }
254
255 /* Copy the flags from src to dst for any extensions that exist in both */
custom_exts_copy_flags(custom_ext_methods * dst,const custom_ext_methods * src)256 int custom_exts_copy_flags(custom_ext_methods *dst,
257 const custom_ext_methods *src)
258 {
259 size_t i;
260 custom_ext_method *methsrc = src->meths;
261
262 for (i = 0; i < src->meths_count; i++, methsrc++) {
263 custom_ext_method *methdst = custom_ext_find(dst, methsrc->role,
264 methsrc->ext_type, NULL);
265
266 if (methdst == NULL)
267 continue;
268
269 methdst->ext_flags = methsrc->ext_flags;
270 }
271
272 return 1;
273 }
274
275 /* Copy old style API wrapper arguments */
custom_ext_copy_old_cb(custom_ext_method * methdst,const custom_ext_method * methsrc,int * err)276 static void custom_ext_copy_old_cb(custom_ext_method *methdst,
277 const custom_ext_method *methsrc,
278 int *err)
279 {
280 if (methsrc->add_cb != custom_ext_add_old_cb_wrap)
281 return;
282
283 if (*err) {
284 methdst->add_arg = NULL;
285 methdst->parse_arg = NULL;
286 return;
287 }
288
289 methdst->add_arg = OPENSSL_memdup(methsrc->add_arg,
290 sizeof(custom_ext_add_cb_wrap));
291 methdst->parse_arg = OPENSSL_memdup(methsrc->parse_arg,
292 sizeof(custom_ext_parse_cb_wrap));
293
294 if (methdst->add_arg == NULL || methdst->parse_arg == NULL)
295 *err = 1;
296
297 return;
298 }
299
300 /* Copy table of custom extensions */
custom_exts_copy(custom_ext_methods * dst,const custom_ext_methods * src)301 int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
302 {
303 size_t i;
304 int err = 0;
305
306 if (src->meths_count > 0) {
307 dst->meths = OPENSSL_memdup(src->meths,
308 sizeof(*src->meths) * src->meths_count);
309 if (dst->meths == NULL)
310 return 0;
311 dst->meths_count = src->meths_count;
312
313 for (i = 0; i < src->meths_count; i++)
314 custom_ext_copy_old_cb(&dst->meths[i], &src->meths[i], &err);
315 }
316
317 if (err) {
318 custom_exts_free(dst);
319 return 0;
320 }
321
322 return 1;
323 }
324
325 /* Copy custom extensions that were set on connection */
custom_exts_copy_conn(custom_ext_methods * dst,const custom_ext_methods * src)326 int custom_exts_copy_conn(custom_ext_methods *dst,
327 const custom_ext_methods *src)
328 {
329 size_t i;
330 int err = 0;
331
332 if (src->meths_count > 0) {
333 size_t meths_count = 0;
334
335 for (i = 0; i < src->meths_count; i++)
336 if ((src->meths[i].ext_flags & SSL_EXT_FLAG_CONN) != 0)
337 meths_count++;
338
339 if (meths_count > 0) {
340 custom_ext_method *methdst = OPENSSL_realloc(dst->meths,
341 (dst->meths_count + meths_count) * sizeof(custom_ext_method));
342
343 if (methdst == NULL)
344 return 0;
345
346 for (i = 0; i < dst->meths_count; i++)
347 custom_ext_copy_old_cb(&methdst[i], &dst->meths[i], &err);
348
349 dst->meths = methdst;
350 methdst += dst->meths_count;
351
352 for (i = 0; i < src->meths_count; i++) {
353 custom_ext_method *methsrc = &src->meths[i];
354
355 if ((methsrc->ext_flags & SSL_EXT_FLAG_CONN) == 0)
356 continue;
357
358 memcpy(methdst, methsrc, sizeof(custom_ext_method));
359 custom_ext_copy_old_cb(methdst, methsrc, &err);
360 methdst++;
361 }
362
363 dst->meths_count += meths_count;
364 }
365 }
366
367 if (err) {
368 custom_exts_free(dst);
369 return 0;
370 }
371
372 return 1;
373 }
374
custom_exts_free(custom_ext_methods * exts)375 void custom_exts_free(custom_ext_methods *exts)
376 {
377 size_t i;
378 custom_ext_method *meth;
379
380 for (i = 0, meth = exts->meths; i < exts->meths_count; i++, meth++) {
381 if (meth->add_cb != custom_ext_add_old_cb_wrap)
382 continue;
383
384 /* Old style API wrapper. Need to free the arguments too */
385 OPENSSL_free(meth->add_arg);
386 OPENSSL_free(meth->parse_arg);
387 }
388 OPENSSL_free(exts->meths);
389 exts->meths = NULL;
390 exts->meths_count = 0;
391 }
392
393 /* Return true if a client custom extension exists, false otherwise */
SSL_CTX_has_client_custom_ext(const SSL_CTX * ctx,unsigned int ext_type)394 int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type)
395 {
396 return custom_ext_find(&ctx->cert->custext, ENDPOINT_CLIENT, ext_type,
397 NULL)
398 != NULL;
399 }
400
ossl_tls_add_custom_ext_intern(SSL_CTX * ctx,custom_ext_methods * exts,ENDPOINT role,unsigned int ext_type,unsigned int context,SSL_custom_ext_add_cb_ex add_cb,SSL_custom_ext_free_cb_ex free_cb,void * add_arg,SSL_custom_ext_parse_cb_ex parse_cb,void * parse_arg)401 int ossl_tls_add_custom_ext_intern(SSL_CTX *ctx, custom_ext_methods *exts,
402 ENDPOINT role, unsigned int ext_type,
403 unsigned int context,
404 SSL_custom_ext_add_cb_ex add_cb,
405 SSL_custom_ext_free_cb_ex free_cb,
406 void *add_arg,
407 SSL_custom_ext_parse_cb_ex parse_cb,
408 void *parse_arg)
409 {
410 custom_ext_method *meth, *tmp;
411
412 /*
413 * Check application error: if add_cb is not set free_cb will never be
414 * called.
415 */
416 if (add_cb == NULL && free_cb != NULL)
417 return 0;
418
419 if (exts == NULL)
420 exts = &ctx->cert->custext;
421
422 #ifndef OPENSSL_NO_CT
423 /*
424 * We don't want applications registering callbacks for SCT extensions
425 * whilst simultaneously using the built-in SCT validation features, as
426 * these two things may not play well together.
427 */
428 if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp
429 && (context & SSL_EXT_CLIENT_HELLO) != 0
430 && ctx != NULL
431 && SSL_CTX_ct_is_enabled(ctx))
432 return 0;
433 #endif
434
435 /*
436 * Don't add if extension supported internally, but make exception
437 * for extension types that previously were not supported, but now are.
438 */
439 if (SSL_extension_supported(ext_type)
440 && ext_type != TLSEXT_TYPE_signed_certificate_timestamp)
441 return 0;
442
443 /* Extension type must fit in 16 bits */
444 if (ext_type > 0xffff)
445 return 0;
446 /* Search for duplicate */
447 if (custom_ext_find(exts, role, ext_type, NULL))
448 return 0;
449 tmp = OPENSSL_realloc(exts->meths,
450 (exts->meths_count + 1) * sizeof(custom_ext_method));
451 if (tmp == NULL)
452 return 0;
453
454 exts->meths = tmp;
455 meth = exts->meths + exts->meths_count;
456 memset(meth, 0, sizeof(*meth));
457 meth->role = role;
458 meth->context = context;
459 meth->parse_cb = parse_cb;
460 meth->add_cb = add_cb;
461 meth->free_cb = free_cb;
462 meth->ext_type = ext_type;
463 meth->ext_flags = (ctx == NULL) ? SSL_EXT_FLAG_CONN : 0;
464 meth->add_arg = add_arg;
465 meth->parse_arg = parse_arg;
466 exts->meths_count++;
467 return 1;
468 }
469
add_old_custom_ext(SSL_CTX * ctx,ENDPOINT role,unsigned int ext_type,unsigned int context,custom_ext_add_cb add_cb,custom_ext_free_cb free_cb,void * add_arg,custom_ext_parse_cb parse_cb,void * parse_arg)470 static int add_old_custom_ext(SSL_CTX *ctx, ENDPOINT role,
471 unsigned int ext_type,
472 unsigned int context,
473 custom_ext_add_cb add_cb,
474 custom_ext_free_cb free_cb,
475 void *add_arg,
476 custom_ext_parse_cb parse_cb, void *parse_arg)
477 {
478 custom_ext_add_cb_wrap *add_cb_wrap
479 = OPENSSL_malloc(sizeof(*add_cb_wrap));
480 custom_ext_parse_cb_wrap *parse_cb_wrap
481 = OPENSSL_malloc(sizeof(*parse_cb_wrap));
482 int ret;
483
484 if (add_cb_wrap == NULL || parse_cb_wrap == NULL) {
485 OPENSSL_free(add_cb_wrap);
486 OPENSSL_free(parse_cb_wrap);
487 return 0;
488 }
489
490 add_cb_wrap->add_arg = add_arg;
491 add_cb_wrap->add_cb = add_cb;
492 add_cb_wrap->free_cb = free_cb;
493 parse_cb_wrap->parse_arg = parse_arg;
494 parse_cb_wrap->parse_cb = parse_cb;
495
496 ret = ossl_tls_add_custom_ext_intern(ctx, NULL, role, ext_type,
497 context,
498 custom_ext_add_old_cb_wrap,
499 custom_ext_free_old_cb_wrap,
500 add_cb_wrap,
501 custom_ext_parse_old_cb_wrap,
502 parse_cb_wrap);
503
504 if (!ret) {
505 OPENSSL_free(add_cb_wrap);
506 OPENSSL_free(parse_cb_wrap);
507 }
508
509 return ret;
510 }
511
512 /* Application level functions to add the old custom extension callbacks */
SSL_CTX_add_client_custom_ext(SSL_CTX * ctx,unsigned int ext_type,custom_ext_add_cb add_cb,custom_ext_free_cb free_cb,void * add_arg,custom_ext_parse_cb parse_cb,void * parse_arg)513 int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
514 custom_ext_add_cb add_cb,
515 custom_ext_free_cb free_cb,
516 void *add_arg,
517 custom_ext_parse_cb parse_cb, void *parse_arg)
518 {
519 return add_old_custom_ext(ctx, ENDPOINT_CLIENT, ext_type,
520 SSL_EXT_TLS1_2_AND_BELOW_ONLY
521 | SSL_EXT_CLIENT_HELLO
522 | SSL_EXT_TLS1_2_SERVER_HELLO
523 | SSL_EXT_IGNORE_ON_RESUMPTION,
524 add_cb, free_cb, add_arg, parse_cb, parse_arg);
525 }
526
SSL_CTX_add_server_custom_ext(SSL_CTX * ctx,unsigned int ext_type,custom_ext_add_cb add_cb,custom_ext_free_cb free_cb,void * add_arg,custom_ext_parse_cb parse_cb,void * parse_arg)527 int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
528 custom_ext_add_cb add_cb,
529 custom_ext_free_cb free_cb,
530 void *add_arg,
531 custom_ext_parse_cb parse_cb, void *parse_arg)
532 {
533 return add_old_custom_ext(ctx, ENDPOINT_SERVER, ext_type,
534 SSL_EXT_TLS1_2_AND_BELOW_ONLY
535 | SSL_EXT_CLIENT_HELLO
536 | SSL_EXT_TLS1_2_SERVER_HELLO
537 | SSL_EXT_IGNORE_ON_RESUMPTION,
538 add_cb, free_cb, add_arg, parse_cb, parse_arg);
539 }
540
SSL_CTX_add_custom_ext(SSL_CTX * ctx,unsigned int ext_type,unsigned int context,SSL_custom_ext_add_cb_ex add_cb,SSL_custom_ext_free_cb_ex free_cb,void * add_arg,SSL_custom_ext_parse_cb_ex parse_cb,void * parse_arg)541 int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
542 unsigned int context,
543 SSL_custom_ext_add_cb_ex add_cb,
544 SSL_custom_ext_free_cb_ex free_cb,
545 void *add_arg,
546 SSL_custom_ext_parse_cb_ex parse_cb, void *parse_arg)
547 {
548 return ossl_tls_add_custom_ext_intern(ctx, NULL, ENDPOINT_BOTH, ext_type,
549 context, add_cb, free_cb, add_arg,
550 parse_cb, parse_arg);
551 }
552
SSL_extension_supported(unsigned int ext_type)553 int SSL_extension_supported(unsigned int ext_type)
554 {
555 switch (ext_type) {
556 /* Internally supported extensions. */
557 case TLSEXT_TYPE_application_layer_protocol_negotiation:
558 case TLSEXT_TYPE_ec_point_formats:
559 case TLSEXT_TYPE_supported_groups:
560 case TLSEXT_TYPE_key_share:
561 #ifndef OPENSSL_NO_NEXTPROTONEG
562 case TLSEXT_TYPE_next_proto_neg:
563 #endif
564 case TLSEXT_TYPE_padding:
565 case TLSEXT_TYPE_renegotiate:
566 case TLSEXT_TYPE_max_fragment_length:
567 case TLSEXT_TYPE_server_name:
568 case TLSEXT_TYPE_session_ticket:
569 case TLSEXT_TYPE_signature_algorithms:
570 #ifndef OPENSSL_NO_SRP
571 case TLSEXT_TYPE_srp:
572 #endif
573 #ifndef OPENSSL_NO_OCSP
574 case TLSEXT_TYPE_status_request:
575 #endif
576 #ifndef OPENSSL_NO_CT
577 case TLSEXT_TYPE_signed_certificate_timestamp:
578 #endif
579 #ifndef OPENSSL_NO_SRTP
580 case TLSEXT_TYPE_use_srtp:
581 #endif
582 case TLSEXT_TYPE_encrypt_then_mac:
583 case TLSEXT_TYPE_supported_versions:
584 case TLSEXT_TYPE_extended_master_secret:
585 case TLSEXT_TYPE_psk_kex_modes:
586 case TLSEXT_TYPE_cookie:
587 case TLSEXT_TYPE_early_data:
588 case TLSEXT_TYPE_certificate_authorities:
589 case TLSEXT_TYPE_psk:
590 case TLSEXT_TYPE_post_handshake_auth:
591 case TLSEXT_TYPE_compress_certificate:
592 case TLSEXT_TYPE_client_cert_type:
593 case TLSEXT_TYPE_server_cert_type:
594 return 1;
595 default:
596 return 0;
597 }
598 }
599