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