VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.0g/ssl/t1_ext.c@ 69881

Last change on this file since 69881 was 69881, checked in by vboxsync, 7 years ago

Update OpenSSL to 1.1.0g.
bugref:8070: src/libs maintenance

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette