Split out DHE CKE construction into a separate function
[openssl.git] / ssl / t1_ext.c
1 /*
2  * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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_locl.h"
14
15
16 /* Find a custom extension from the list. */
17 static custom_ext_method *custom_ext_find(const custom_ext_methods *exts,
18                                           unsigned int ext_type)
19 {
20     size_t i;
21     custom_ext_method *meth = exts->meths;
22     for (i = 0; i < exts->meths_count; i++, meth++) {
23         if (ext_type == meth->ext_type)
24             return meth;
25     }
26     return NULL;
27 }
28
29 /*
30  * Initialise custom extensions flags to indicate neither sent nor received.
31  */
32 void custom_ext_init(custom_ext_methods *exts)
33 {
34     size_t i;
35     custom_ext_method *meth = exts->meths;
36     for (i = 0; i < exts->meths_count; i++, meth++)
37         meth->ext_flags = 0;
38 }
39
40 /* Pass received custom extension data to the application for parsing. */
41 int custom_ext_parse(SSL *s, int server,
42                      unsigned int ext_type,
43                      const unsigned char *ext_data, size_t ext_size, int *al)
44 {
45     custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext;
46     custom_ext_method *meth;
47     meth = custom_ext_find(exts, ext_type);
48     /* If not found return success */
49     if (!meth)
50         return 1;
51     if (!server) {
52         /*
53          * If it's ServerHello we can't have any extensions not sent in
54          * ClientHello.
55          */
56         if (!(meth->ext_flags & SSL_EXT_FLAG_SENT)) {
57             *al = TLS1_AD_UNSUPPORTED_EXTENSION;
58             return 0;
59         }
60     }
61     /* If already present it's a duplicate */
62     if (meth->ext_flags & SSL_EXT_FLAG_RECEIVED) {
63         *al = TLS1_AD_DECODE_ERROR;
64         return 0;
65     }
66     meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;
67     /* If no parse function set return success */
68     if (!meth->parse_cb)
69         return 1;
70
71     return meth->parse_cb(s, ext_type, ext_data, ext_size, al,
72                           meth->parse_arg);
73 }
74
75 /*
76  * Request custom extension data from the application and add to the return
77  * buffer.
78  */
79 int custom_ext_add(SSL *s, int server,
80                    unsigned char **pret, unsigned char *limit, int *al)
81 {
82     custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext;
83     custom_ext_method *meth;
84     unsigned char *ret = *pret;
85     size_t i;
86
87     for (i = 0; i < exts->meths_count; i++) {
88         const unsigned char *out = NULL;
89         size_t outlen = 0;
90         meth = exts->meths + i;
91
92         if (server) {
93             /*
94              * For ServerHello only send extensions present in ClientHello.
95              */
96             if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED))
97                 continue;
98             /* If callback absent for server skip it */
99             if (!meth->add_cb)
100                 continue;
101         }
102         if (meth->add_cb) {
103             int cb_retval = 0;
104             cb_retval = meth->add_cb(s, meth->ext_type,
105                                      &out, &outlen, al, meth->add_arg);
106             if (cb_retval < 0)
107                 return 0;       /* error */
108             if (cb_retval == 0)
109                 continue;       /* skip this extension */
110         }
111         if (4 > limit - ret || outlen > (size_t)(limit - ret - 4))
112             return 0;
113         s2n(meth->ext_type, ret);
114         s2n(outlen, ret);
115         if (outlen) {
116             memcpy(ret, out, outlen);
117             ret += outlen;
118         }
119         /*
120          * We can't send duplicates: code logic should prevent this.
121          */
122         OPENSSL_assert(!(meth->ext_flags & SSL_EXT_FLAG_SENT));
123         /*
124          * Indicate extension has been sent: this is both a sanity check to
125          * ensure we don't send duplicate extensions and indicates that it is
126          * not an error if the extension is present in ServerHello.
127          */
128         meth->ext_flags |= SSL_EXT_FLAG_SENT;
129         if (meth->free_cb)
130             meth->free_cb(s, meth->ext_type, out, meth->add_arg);
131     }
132     *pret = ret;
133     return 1;
134 }
135
136 /* Copy table of custom extensions */
137 int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
138 {
139     if (src->meths_count) {
140         dst->meths =
141             OPENSSL_memdup(src->meths,
142                        sizeof(custom_ext_method) * src->meths_count);
143         if (dst->meths == NULL)
144             return 0;
145         dst->meths_count = src->meths_count;
146     }
147     return 1;
148 }
149
150 void custom_exts_free(custom_ext_methods *exts)
151 {
152     OPENSSL_free(exts->meths);
153 }
154
155 /* Set callbacks for a custom extension. */
156 static int custom_ext_meth_add(custom_ext_methods *exts,
157                                unsigned int ext_type,
158                                custom_ext_add_cb add_cb,
159                                custom_ext_free_cb free_cb,
160                                void *add_arg,
161                                custom_ext_parse_cb parse_cb, void *parse_arg)
162 {
163     custom_ext_method *meth, *tmp;
164     /*
165      * Check application error: if add_cb is not set free_cb will never be
166      * called.
167      */
168     if (!add_cb && free_cb)
169         return 0;
170     /*
171      * Don't add if extension supported internally, but make exception
172      * for extension types that previously were not supported, but now are.
173      */
174     if (SSL_extension_supported(ext_type) &&
175         ext_type != TLSEXT_TYPE_signed_certificate_timestamp)
176         return 0;
177     /* Extension type must fit in 16 bits */
178     if (ext_type > 0xffff)
179         return 0;
180     /* Search for duplicate */
181     if (custom_ext_find(exts, ext_type))
182         return 0;
183     tmp = OPENSSL_realloc(exts->meths,
184                           (exts->meths_count + 1) * sizeof(custom_ext_method));
185
186     if (tmp == NULL) {
187         OPENSSL_free(exts->meths);
188         exts->meths = NULL;
189         exts->meths_count = 0;
190         return 0;
191     }
192
193     exts->meths = tmp;
194     meth = exts->meths + exts->meths_count;
195     memset(meth, 0, sizeof(*meth));
196     meth->parse_cb = parse_cb;
197     meth->add_cb = add_cb;
198     meth->free_cb = free_cb;
199     meth->ext_type = ext_type;
200     meth->add_arg = add_arg;
201     meth->parse_arg = parse_arg;
202     exts->meths_count++;
203     return 1;
204 }
205
206 /* Return true if a client custom extension exists, false otherwise */
207 int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type)
208 {
209     return custom_ext_find(&ctx->cert->cli_ext, ext_type) != NULL;
210 }
211
212 /* Application level functions to add custom extension callbacks */
213 int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
214                                   custom_ext_add_cb add_cb,
215                                   custom_ext_free_cb free_cb,
216                                   void *add_arg,
217                                   custom_ext_parse_cb parse_cb,
218                                   void *parse_arg)
219 {
220 #ifndef OPENSSL_NO_CT
221     /*
222      * We don't want applications registering callbacks for SCT extensions
223      * whilst simultaneously using the built-in SCT validation features, as
224      * these two things may not play well together.
225      */
226     if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp &&
227         SSL_CTX_ct_is_enabled(ctx))
228         return 0;
229 #endif
230     return custom_ext_meth_add(&ctx->cert->cli_ext, ext_type, add_cb,
231                                free_cb, add_arg, parse_cb, parse_arg);
232 }
233
234 int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
235                                   custom_ext_add_cb add_cb,
236                                   custom_ext_free_cb free_cb,
237                                   void *add_arg,
238                                   custom_ext_parse_cb parse_cb,
239                                   void *parse_arg)
240 {
241     return custom_ext_meth_add(&ctx->cert->srv_ext, ext_type,
242                                add_cb, free_cb, add_arg, parse_cb, parse_arg);
243 }
244
245 int SSL_extension_supported(unsigned int ext_type)
246 {
247     switch (ext_type) {
248         /* Internally supported extensions. */
249     case TLSEXT_TYPE_application_layer_protocol_negotiation:
250     case TLSEXT_TYPE_ec_point_formats:
251     case TLSEXT_TYPE_elliptic_curves:
252     case TLSEXT_TYPE_heartbeat:
253 #ifndef OPENSSL_NO_NEXTPROTONEG
254     case TLSEXT_TYPE_next_proto_neg:
255 #endif
256     case TLSEXT_TYPE_padding:
257     case TLSEXT_TYPE_renegotiate:
258     case TLSEXT_TYPE_server_name:
259     case TLSEXT_TYPE_session_ticket:
260     case TLSEXT_TYPE_signature_algorithms:
261     case TLSEXT_TYPE_srp:
262     case TLSEXT_TYPE_status_request:
263     case TLSEXT_TYPE_signed_certificate_timestamp:
264     case TLSEXT_TYPE_use_srtp:
265 #ifdef TLSEXT_TYPE_encrypt_then_mac
266     case TLSEXT_TYPE_encrypt_then_mac:
267 #endif
268         return 1;
269     default:
270         return 0;
271     }
272 }