blob: 7ac82127b7788ddb37b2d53c4816f5673d7e39f8 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
Adam Langleye745b252018-02-26 14:02:17 -08007 *
Adam Langley95c29f32014-06-20 12:00:00 -07008 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
Adam Langleye745b252018-02-26 14:02:17 -080014 *
Adam Langley95c29f32014-06-20 12:00:00 -070015 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
Adam Langleye745b252018-02-26 14:02:17 -080021 *
Adam Langley95c29f32014-06-20 12:00:00 -070022 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
Adam Langleye745b252018-02-26 14:02:17 -080036 * 4. If you include any Windows specific code (or a derivative thereof) from
Adam Langley95c29f32014-06-20 12:00:00 -070037 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
Adam Langleye745b252018-02-26 14:02:17 -080039 *
Adam Langley95c29f32014-06-20 12:00:00 -070040 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
Adam Langleye745b252018-02-26 14:02:17 -080051 *
Adam Langley95c29f32014-06-20 12:00:00 -070052 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
Adam Langleye745b252018-02-26 14:02:17 -080065 * notice, this list of conditions and the following disclaimer.
Adam Langley95c29f32014-06-20 12:00:00 -070066 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com). */
108
David Benjamin9e4e01e2015-09-15 01:48:04 -0400109#include <openssl/ssl.h>
110
David Benjaminf0ae1702015-04-07 23:05:04 -0400111#include <assert.h>
David Benjamine3aa1d92015-06-16 15:34:50 -0400112#include <limits.h>
David Benjamin35a7a442014-07-05 00:23:20 -0400113#include <stdlib.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400114#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700115
Dan McArdle1920c6f2020-03-11 17:29:40 -0400116#include <algorithm>
David Benjamin499742c2017-07-22 12:45:38 -0400117#include <utility>
118
Dan McArdle1920c6f2020-03-11 17:29:40 -0400119#include <openssl/aead.h>
David Benjamin03973092014-06-24 23:27:17 -0400120#include <openssl/bytestring.h>
Adam Langley512a2892017-12-30 08:04:39 -0800121#include <openssl/chacha.h>
Dan McArdle1920c6f2020-03-11 17:29:40 -0400122#include <openssl/curve25519.h>
David Benjamind6a4ae92015-08-06 11:10:51 -0400123#include <openssl/digest.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400124#include <openssl/err.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700125#include <openssl/evp.h>
126#include <openssl/hmac.h>
David Benjamin070a6c32021-05-05 15:39:27 -0400127#include <openssl/hpke.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700128#include <openssl/mem.h>
David Benjamin98193672016-03-25 18:07:11 -0400129#include <openssl/nid.h>
David Benjamine9c5d722021-06-09 17:43:16 -0400130#include <openssl/rand.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700131
Steven Valdezcb966542016-08-17 16:56:14 -0400132#include "../crypto/internal.h"
Steven Valdez51607f12020-08-05 10:46:05 -0400133#include "internal.h"
Adam Langleyfcf25832014-12-18 17:42:32 -0800134
135
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -0700136BSSL_NAMESPACE_BEGIN
David Benjamin86e95b82017-07-18 16:34:25 -0400137
David Benjamin861abcc2018-07-14 17:40:26 -0400138static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs);
Steven Valdez51607f12020-08-05 10:46:05 -0400139static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs);
Adam Langley95c29f32014-06-20 12:00:00 -0700140
Adam Langleyfcf25832014-12-18 17:42:32 -0800141static int compare_uint16_t(const void *p1, const void *p2) {
142 uint16_t u1 = *((const uint16_t *)p1);
143 uint16_t u2 = *((const uint16_t *)p2);
144 if (u1 < u2) {
145 return -1;
146 } else if (u1 > u2) {
147 return 1;
148 } else {
149 return 0;
150 }
151}
David Benjamin35a7a442014-07-05 00:23:20 -0400152
David Benjaminc11ea9422017-08-29 16:33:21 -0400153// Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be
154// more than one extension of the same type in a ClientHello or ServerHello.
155// This function does an initial scan over the extensions block to filter those
156// out.
David Benjamin861abcc2018-07-14 17:40:26 -0400157static bool tls1_check_duplicate_extensions(const CBS *cbs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400158 // First pass: count the extensions.
David Benjamin08f5c762017-09-21 02:43:05 -0400159 size_t num_extensions = 0;
160 CBS extensions = *cbs;
Adam Langleyfcf25832014-12-18 17:42:32 -0800161 while (CBS_len(&extensions) > 0) {
162 uint16_t type;
163 CBS extension;
David Benjamin35a7a442014-07-05 00:23:20 -0400164
Adam Langleyfcf25832014-12-18 17:42:32 -0800165 if (!CBS_get_u16(&extensions, &type) ||
166 !CBS_get_u16_length_prefixed(&extensions, &extension)) {
David Benjamin861abcc2018-07-14 17:40:26 -0400167 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800168 }
David Benjamin35a7a442014-07-05 00:23:20 -0400169
Adam Langleyfcf25832014-12-18 17:42:32 -0800170 num_extensions++;
171 }
David Benjamin35a7a442014-07-05 00:23:20 -0400172
Adam Langleyfcf25832014-12-18 17:42:32 -0800173 if (num_extensions == 0) {
David Benjamin861abcc2018-07-14 17:40:26 -0400174 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800175 }
David Benjamin9a373592014-07-25 04:27:53 -0400176
David Benjamin08f5c762017-09-21 02:43:05 -0400177 Array<uint16_t> extension_types;
178 if (!extension_types.Init(num_extensions)) {
David Benjamin861abcc2018-07-14 17:40:26 -0400179 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800180 }
David Benjamin35a7a442014-07-05 00:23:20 -0400181
David Benjaminc11ea9422017-08-29 16:33:21 -0400182 // Second pass: gather the extension types.
Adam Langleyfcf25832014-12-18 17:42:32 -0800183 extensions = *cbs;
David Benjamin08f5c762017-09-21 02:43:05 -0400184 for (size_t i = 0; i < extension_types.size(); i++) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800185 CBS extension;
David Benjamin35a7a442014-07-05 00:23:20 -0400186
Adam Langleyfcf25832014-12-18 17:42:32 -0800187 if (!CBS_get_u16(&extensions, &extension_types[i]) ||
188 !CBS_get_u16_length_prefixed(&extensions, &extension)) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400189 // This should not happen.
David Benjamin861abcc2018-07-14 17:40:26 -0400190 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800191 }
192 }
193 assert(CBS_len(&extensions) == 0);
David Benjamin35a7a442014-07-05 00:23:20 -0400194
David Benjaminc11ea9422017-08-29 16:33:21 -0400195 // Sort the extensions and make sure there are no duplicates.
David Benjamin08f5c762017-09-21 02:43:05 -0400196 qsort(extension_types.data(), extension_types.size(), sizeof(uint16_t),
197 compare_uint16_t);
198 for (size_t i = 1; i < num_extensions; i++) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800199 if (extension_types[i - 1] == extension_types[i]) {
David Benjamin861abcc2018-07-14 17:40:26 -0400200 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800201 }
202 }
David Benjamin35a7a442014-07-05 00:23:20 -0400203
David Benjamin861abcc2018-07-14 17:40:26 -0400204 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800205}
David Benjamin35a7a442014-07-05 00:23:20 -0400206
Kris Kwiatkowski78c88c92019-03-11 14:40:59 +0000207static bool is_post_quantum_group(uint16_t id) {
Adam Langleyfc077382023-01-08 16:22:31 -0800208 switch (id) {
209 case SSL_CURVE_CECPQ2:
210 case SSL_CURVE_X25519KYBER768:
211 case SSL_CURVE_P256KYBER768:
212 return true;
213 default:
214 return false;
215 }
Kris Kwiatkowski78c88c92019-03-11 14:40:59 +0000216}
217
Adam Langleyc9827e02019-04-12 14:46:50 -0700218bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out,
Daniel McArdle00e434d2021-02-18 11:47:18 -0500219 Span<const uint8_t> body) {
David Benjamin18b68362021-06-18 23:13:46 -0400220 CBS cbs = body;
221 if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs, out) ||
222 CBS_len(&cbs) != 0) {
223 return false;
224 }
225 return true;
226}
227
228bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs,
229 SSL_CLIENT_HELLO *out) {
David Benjamin17cf2cb2016-12-13 01:07:13 -0500230 OPENSSL_memset(out, 0, sizeof(*out));
Adam Langleyc9827e02019-04-12 14:46:50 -0700231 out->ssl = const_cast<SSL *>(ssl);
David Benjamin8f2c20e2014-07-09 09:30:38 -0400232
David Benjamin18b68362021-06-18 23:13:46 -0400233 CBS copy = *cbs;
234 CBS random, session_id;
235 if (!CBS_get_u16(cbs, &out->version) ||
236 !CBS_get_bytes(cbs, &random, SSL3_RANDOM_SIZE) ||
237 !CBS_get_u8_length_prefixed(cbs, &session_id) ||
David Benjamine14ff062016-08-09 16:21:24 -0400238 CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
David Benjamin861abcc2018-07-14 17:40:26 -0400239 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800240 }
Adam Langleydc9b1412014-06-20 12:00:00 -0700241
David Benjamin731058e2016-12-03 23:15:13 -0500242 out->random = CBS_data(&random);
243 out->random_len = CBS_len(&random);
244 out->session_id = CBS_data(&session_id);
245 out->session_id_len = CBS_len(&session_id);
Adam Langleydc9b1412014-06-20 12:00:00 -0700246
David Benjaminc11ea9422017-08-29 16:33:21 -0400247 // Skip past DTLS cookie
David Benjamin731058e2016-12-03 23:15:13 -0500248 if (SSL_is_dtls(out->ssl)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800249 CBS cookie;
David Benjamin361e3e02022-09-11 13:58:38 -0400250 if (!CBS_get_u8_length_prefixed(cbs, &cookie)) {
David Benjamin861abcc2018-07-14 17:40:26 -0400251 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800252 }
253 }
Adam Langleydc9b1412014-06-20 12:00:00 -0700254
David Benjamine14ff062016-08-09 16:21:24 -0400255 CBS cipher_suites, compression_methods;
David Benjamin18b68362021-06-18 23:13:46 -0400256 if (!CBS_get_u16_length_prefixed(cbs, &cipher_suites) ||
David Benjamine14ff062016-08-09 16:21:24 -0400257 CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0 ||
David Benjamin18b68362021-06-18 23:13:46 -0400258 !CBS_get_u8_length_prefixed(cbs, &compression_methods) ||
Adam Langleyfcf25832014-12-18 17:42:32 -0800259 CBS_len(&compression_methods) < 1) {
David Benjamin861abcc2018-07-14 17:40:26 -0400260 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800261 }
David Benjamine14ff062016-08-09 16:21:24 -0400262
David Benjamin731058e2016-12-03 23:15:13 -0500263 out->cipher_suites = CBS_data(&cipher_suites);
264 out->cipher_suites_len = CBS_len(&cipher_suites);
265 out->compression_methods = CBS_data(&compression_methods);
266 out->compression_methods_len = CBS_len(&compression_methods);
Adam Langleydc9b1412014-06-20 12:00:00 -0700267
David Benjaminc11ea9422017-08-29 16:33:21 -0400268 // If the ClientHello ends here then it's valid, but doesn't have any
David Benjamin9bb15f52018-06-26 00:07:40 -0400269 // extensions.
David Benjamin18b68362021-06-18 23:13:46 -0400270 if (CBS_len(cbs) == 0) {
271 out->extensions = nullptr;
David Benjamin731058e2016-12-03 23:15:13 -0500272 out->extensions_len = 0;
David Benjamin18b68362021-06-18 23:13:46 -0400273 } else {
274 // Extract extensions and check it is valid.
275 CBS extensions;
276 if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
277 !tls1_check_duplicate_extensions(&extensions)) {
278 return false;
279 }
280 out->extensions = CBS_data(&extensions);
281 out->extensions_len = CBS_len(&extensions);
Adam Langleyfcf25832014-12-18 17:42:32 -0800282 }
Adam Langleydc9b1412014-06-20 12:00:00 -0700283
David Benjamin18b68362021-06-18 23:13:46 -0400284 out->client_hello = CBS_data(&copy);
285 out->client_hello_len = CBS_len(&copy) - CBS_len(cbs);
David Benjamin861abcc2018-07-14 17:40:26 -0400286 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800287}
Adam Langleydc9b1412014-06-20 12:00:00 -0700288
David Benjamin861abcc2018-07-14 17:40:26 -0400289bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
290 CBS *out, uint16_t extension_type) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800291 CBS extensions;
David Benjamin731058e2016-12-03 23:15:13 -0500292 CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800293 while (CBS_len(&extensions) != 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400294 // Decode the next extension.
Adam Langleyfcf25832014-12-18 17:42:32 -0800295 uint16_t type;
296 CBS extension;
Adam Langleyfcf25832014-12-18 17:42:32 -0800297 if (!CBS_get_u16(&extensions, &type) ||
298 !CBS_get_u16_length_prefixed(&extensions, &extension)) {
David Benjamin861abcc2018-07-14 17:40:26 -0400299 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800300 }
Adam Langleydc9b1412014-06-20 12:00:00 -0700301
Adam Langleyfcf25832014-12-18 17:42:32 -0800302 if (type == extension_type) {
David Benjamincec73442016-08-02 17:41:33 -0400303 *out = extension;
David Benjamin861abcc2018-07-14 17:40:26 -0400304 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800305 }
306 }
Adam Langleydc9b1412014-06-20 12:00:00 -0700307
David Benjamin861abcc2018-07-14 17:40:26 -0400308 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800309}
Adam Langley95c29f32014-06-20 12:00:00 -0700310
Steven Valdezce902a92016-05-17 11:47:53 -0400311static const uint16_t kDefaultGroups[] = {
David Benjamin9e68f192016-06-30 14:55:33 -0400312 SSL_CURVE_X25519,
313 SSL_CURVE_SECP256R1,
314 SSL_CURVE_SECP384R1,
Adam Langleyfcf25832014-12-18 17:42:32 -0800315};
Adam Langley95c29f32014-06-20 12:00:00 -0700316
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -0700317Span<const uint16_t> tls1_get_grouplist(const SSL_HANDSHAKE *hs) {
David Benjamin0ce090a2018-07-02 20:24:40 -0400318 if (!hs->config->supported_group_list.empty()) {
319 return hs->config->supported_group_list;
Adam Langleyfcf25832014-12-18 17:42:32 -0800320 }
David Benjamincf0ce672017-09-21 02:25:59 -0400321 return Span<const uint16_t>(kDefaultGroups);
Adam Langleyfcf25832014-12-18 17:42:32 -0800322}
David Benjamined439582014-07-14 19:13:02 -0400323
David Benjamin861abcc2018-07-14 17:40:26 -0400324bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900325 SSL *const ssl = hs->ssl;
David Benjaminf04976b2016-10-07 00:37:55 -0400326 assert(ssl->server);
David Benjamin072334d2014-07-13 16:24:27 -0400327
David Benjaminc11ea9422017-08-29 16:33:21 -0400328 // Clients are not required to send a supported_groups extension. In this
329 // case, the server is free to pick any group it likes. See RFC 4492,
330 // section 4, paragraph 3.
331 //
332 // However, in the interests of compatibility, we will skip ECDH if the
333 // client didn't send an extension because we can't be sure that they'll
334 // support our favoured group. Thus we do not special-case an emtpy
335 // |peer_supported_group_list|.
David Benjamin55a43642015-04-20 14:45:55 -0400336
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -0700337 Span<const uint16_t> groups = tls1_get_grouplist(hs);
David Benjamincf0ce672017-09-21 02:25:59 -0400338 Span<const uint16_t> pref, supp;
David Benjamin4298d772015-12-19 00:18:25 -0500339 if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
Steven Valdezce902a92016-05-17 11:47:53 -0400340 pref = groups;
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900341 supp = hs->peer_supported_group_list;
David Benjamin55a43642015-04-20 14:45:55 -0400342 } else {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900343 pref = hs->peer_supported_group_list;
Steven Valdezce902a92016-05-17 11:47:53 -0400344 supp = groups;
David Benjamin55a43642015-04-20 14:45:55 -0400345 }
346
David Benjamincf0ce672017-09-21 02:25:59 -0400347 for (uint16_t pref_group : pref) {
348 for (uint16_t supp_group : supp) {
Adam Langley7b935932018-11-12 13:53:42 -0800349 if (pref_group == supp_group &&
Adam Langleyfc077382023-01-08 16:22:31 -0800350 // Post-quantum key agreements don't fit in the u8-length-prefixed
351 // ECPoint field in TLS 1.2 and below.
Adam Langley7b935932018-11-12 13:53:42 -0800352 (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
Kris Kwiatkowski78c88c92019-03-11 14:40:59 +0000353 !is_post_quantum_group(pref_group))) {
David Benjamincf0ce672017-09-21 02:25:59 -0400354 *out_group_id = pref_group;
David Benjamin861abcc2018-07-14 17:40:26 -0400355 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800356 }
357 }
358 }
359
David Benjamin861abcc2018-07-14 17:40:26 -0400360 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800361}
Adam Langley95c29f32014-06-20 12:00:00 -0700362
David Benjamin0ce090a2018-07-02 20:24:40 -0400363bool tls1_set_curves(Array<uint16_t> *out_group_ids, Span<const int> curves) {
364 Array<uint16_t> group_ids;
365 if (!group_ids.Init(curves.size())) {
366 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800367 }
368
David Benjamin0ce090a2018-07-02 20:24:40 -0400369 for (size_t i = 0; i < curves.size(); i++) {
Steven Valdezce902a92016-05-17 11:47:53 -0400370 if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) {
David Benjamin0ce090a2018-07-02 20:24:40 -0400371 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800372 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800373 }
374
David Benjamin0ce090a2018-07-02 20:24:40 -0400375 *out_group_ids = std::move(group_ids);
376 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800377}
Adam Langley95c29f32014-06-20 12:00:00 -0700378
David Benjamin0ce090a2018-07-02 20:24:40 -0400379bool tls1_set_curves_list(Array<uint16_t> *out_group_ids, const char *curves) {
380 // Count the number of curves in the list.
381 size_t count = 0;
382 const char *ptr = curves, *col;
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100383 do {
384 col = strchr(ptr, ':');
David Benjamin0ce090a2018-07-02 20:24:40 -0400385 count++;
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100386 if (col) {
387 ptr = col + 1;
388 }
389 } while (col);
390
David Benjamin0ce090a2018-07-02 20:24:40 -0400391 Array<uint16_t> group_ids;
392 if (!group_ids.Init(count)) {
393 return false;
394 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100395
David Benjamin0ce090a2018-07-02 20:24:40 -0400396 size_t i = 0;
397 ptr = curves;
398 do {
399 col = strchr(ptr, ':');
400 if (!ssl_name_to_group_id(&group_ids[i++], ptr,
401 col ? (size_t)(col - ptr) : strlen(ptr))) {
402 return false;
403 }
404 if (col) {
405 ptr = col + 1;
406 }
407 } while (col);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100408
David Benjamin0ce090a2018-07-02 20:24:40 -0400409 assert(i == count);
410 *out_group_ids = std::move(group_ids);
411 return true;
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100412}
413
David Benjamin861abcc2018-07-14 17:40:26 -0400414bool tls1_check_group_id(const SSL_HANDSHAKE *hs, uint16_t group_id) {
Kris Kwiatkowski78c88c92019-03-11 14:40:59 +0000415 if (is_post_quantum_group(group_id) &&
Adam Langley7b935932018-11-12 13:53:42 -0800416 ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
Kris Kwiatkowski78c88c92019-03-11 14:40:59 +0000417 // CECPQ2(b) requires TLS 1.3.
Adam Langley7b935932018-11-12 13:53:42 -0800418 return false;
419 }
420
David Benjamin97ede402021-05-18 14:17:52 -0400421 // We internally assume zero is never allocated as a group ID.
422 if (group_id == 0) {
423 return false;
424 }
425
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -0700426 for (uint16_t supported : tls1_get_grouplist(hs)) {
David Benjamincf0ce672017-09-21 02:25:59 -0400427 if (supported == group_id) {
David Benjamin861abcc2018-07-14 17:40:26 -0400428 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800429 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800430 }
David Benjamin033e5f42014-11-13 18:47:41 -0500431
David Benjamin861abcc2018-07-14 17:40:26 -0400432 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800433}
David Benjamin033e5f42014-11-13 18:47:41 -0500434
David Benjaminc11ea9422017-08-29 16:33:21 -0400435// kVerifySignatureAlgorithms is the default list of accepted signature
436// algorithms for verifying.
David Benjamin3ef76972016-10-17 17:59:54 -0400437static const uint16_t kVerifySignatureAlgorithms[] = {
David Benjaminc11ea9422017-08-29 16:33:21 -0400438 // List our preferred algorithms first.
David Benjamin3a322f52016-10-26 12:45:35 -0400439 SSL_SIGN_ECDSA_SECP256R1_SHA256,
David Benjamin6879e192018-04-13 16:01:02 -0400440 SSL_SIGN_RSA_PSS_RSAE_SHA256,
David Benjamin3a322f52016-10-26 12:45:35 -0400441 SSL_SIGN_RSA_PKCS1_SHA256,
442
David Benjaminc11ea9422017-08-29 16:33:21 -0400443 // Larger hashes are acceptable.
David Benjamin3a322f52016-10-26 12:45:35 -0400444 SSL_SIGN_ECDSA_SECP384R1_SHA384,
David Benjamin6879e192018-04-13 16:01:02 -0400445 SSL_SIGN_RSA_PSS_RSAE_SHA384,
David Benjamin3a322f52016-10-26 12:45:35 -0400446 SSL_SIGN_RSA_PKCS1_SHA384,
447
David Benjamin6879e192018-04-13 16:01:02 -0400448 SSL_SIGN_RSA_PSS_RSAE_SHA512,
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400449 SSL_SIGN_RSA_PKCS1_SHA512,
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400450
David Benjaminc11ea9422017-08-29 16:33:21 -0400451 // For now, SHA-1 is still accepted but least preferable.
David Benjamin3a322f52016-10-26 12:45:35 -0400452 SSL_SIGN_RSA_PKCS1_SHA1,
David Benjamin3a322f52016-10-26 12:45:35 -0400453};
454
David Benjaminc11ea9422017-08-29 16:33:21 -0400455// kSignSignatureAlgorithms is the default list of supported signature
456// algorithms for signing.
David Benjamin3a322f52016-10-26 12:45:35 -0400457static const uint16_t kSignSignatureAlgorithms[] = {
David Benjaminc11ea9422017-08-29 16:33:21 -0400458 // List our preferred algorithms first.
David Benjamin69522112017-03-28 15:38:29 -0500459 SSL_SIGN_ED25519,
David Benjamin3a322f52016-10-26 12:45:35 -0400460 SSL_SIGN_ECDSA_SECP256R1_SHA256,
David Benjamin6879e192018-04-13 16:01:02 -0400461 SSL_SIGN_RSA_PSS_RSAE_SHA256,
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400462 SSL_SIGN_RSA_PKCS1_SHA256,
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400463
David Benjaminc11ea9422017-08-29 16:33:21 -0400464 // If needed, sign larger hashes.
465 //
466 // TODO(davidben): Determine which of these may be pruned.
David Benjamin3a322f52016-10-26 12:45:35 -0400467 SSL_SIGN_ECDSA_SECP384R1_SHA384,
David Benjamin6879e192018-04-13 16:01:02 -0400468 SSL_SIGN_RSA_PSS_RSAE_SHA384,
David Benjamin3a322f52016-10-26 12:45:35 -0400469 SSL_SIGN_RSA_PKCS1_SHA384,
470
471 SSL_SIGN_ECDSA_SECP521R1_SHA512,
David Benjamin6879e192018-04-13 16:01:02 -0400472 SSL_SIGN_RSA_PSS_RSAE_SHA512,
David Benjamin3a322f52016-10-26 12:45:35 -0400473 SSL_SIGN_RSA_PKCS1_SHA512,
474
David Benjaminc11ea9422017-08-29 16:33:21 -0400475 // If the peer supports nothing else, sign with SHA-1.
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400476 SSL_SIGN_ECDSA_SHA1,
David Benjamin3a322f52016-10-26 12:45:35 -0400477 SSL_SIGN_RSA_PKCS1_SHA1,
Steven Valdezeff1e8d2016-07-06 14:24:47 -0400478};
479
David Benjamin17669352020-02-05 17:33:36 -0500480static Span<const uint16_t> tls12_get_verify_sigalgs(const SSL_HANDSHAKE *hs) {
481 if (hs->config->verify_sigalgs.empty()) {
482 return Span<const uint16_t>(kVerifySignatureAlgorithms);
David Benjamin71c21b42017-04-14 17:05:40 -0400483 }
David Benjamin17669352020-02-05 17:33:36 -0500484 return hs->config->verify_sigalgs;
David Benjamine28552d2018-04-08 13:59:25 -0400485}
486
David Benjaminebad5082020-02-03 19:32:19 -0500487bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin17669352020-02-05 17:33:36 -0500488 for (uint16_t sigalg : tls12_get_verify_sigalgs(hs)) {
David Benjamin610cdbb2018-01-22 19:08:38 -0500489 if (!CBB_add_u16(out, sigalg)) {
490 return false;
David Benjamin69522112017-03-28 15:38:29 -0500491 }
492 }
David Benjamin610cdbb2018-01-22 19:08:38 -0500493 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800494}
Adam Langley95c29f32014-06-20 12:00:00 -0700495
David Benjaminebad5082020-02-03 19:32:19 -0500496bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
David Benjamin610cdbb2018-01-22 19:08:38 -0500497 uint16_t sigalg) {
David Benjamin17669352020-02-05 17:33:36 -0500498 for (uint16_t verify_sigalg : tls12_get_verify_sigalgs(hs)) {
David Benjamine28552d2018-04-08 13:59:25 -0400499 if (verify_sigalg == sigalg) {
David Benjamin610cdbb2018-01-22 19:08:38 -0500500 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800501 }
502 }
503
David Benjamin3ef76972016-10-17 17:59:54 -0400504 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
505 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin610cdbb2018-01-22 19:08:38 -0500506 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800507}
508
David Benjamin52b36382021-05-19 13:26:19 -0400509// tls_extension represents a TLS extension that is handled internally.
David Benjaminc11ea9422017-08-29 16:33:21 -0400510//
511// The parse callbacks receive a |CBS| that contains the contents of the
512// extension (i.e. not including the type and length bytes). If an extension is
513// not received then the parse callbacks will be called with a NULL CBS so that
514// they can do any processing needed to handle the absence of an extension.
515//
516// The add callbacks receive a |CBB| to which the extension can be appended but
517// the function is responsible for appending the type and length bytes too.
David Benjamin83a49932021-05-20 15:57:09 -0400518//
519// |add_clienthello| may be called multiple times and must not mutate |hs|. It
520// is additionally passed two output |CBB|s. If the extension is the same
521// independent of the value of |type|, the callback may write to
522// |out_compressible| instead of |out|. When serializing the ClientHelloInner,
523// all compressible extensions will be made continguous and replaced with
524// ech_outer_extensions when encrypted. When serializing the ClientHelloOuter
525// or not offering ECH, |out| will be equal to |out_compressible|, so writing to
526// |out_compressible| still works.
David Benjaminc11ea9422017-08-29 16:33:21 -0400527//
David Benjamin90522862021-05-27 14:50:31 -0400528// Note the |parse_serverhello| and |add_serverhello| callbacks refer to the
529// TLS 1.2 ServerHello. In TLS 1.3, these callbacks act on EncryptedExtensions,
530// with ServerHello extensions handled elsewhere in the handshake.
531//
David Benjamin31640932017-10-11 13:22:39 -0400532// All callbacks return true for success and false for error. If a parse
533// function returns zero then a fatal alert with value |*out_alert| will be
534// sent. If |*out_alert| isn't set, then a |decode_error| alert will be sent.
Adam Langley614c66a2015-06-12 15:26:58 -0700535struct tls_extension {
536 uint16_t value;
Adam Langley614c66a2015-06-12 15:26:58 -0700537
David Benjamin83a49932021-05-20 15:57:09 -0400538 bool (*add_clienthello)(const SSL_HANDSHAKE *hs, CBB *out,
539 CBB *out_compressible, ssl_client_hello_type_t type);
David Benjamin31640932017-10-11 13:22:39 -0400540 bool (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
541 CBS *contents);
Adam Langley614c66a2015-06-12 15:26:58 -0700542
David Benjamin31640932017-10-11 13:22:39 -0400543 bool (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
544 CBS *contents);
545 bool (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out);
Adam Langley614c66a2015-06-12 15:26:58 -0700546};
547
David Benjamin31640932017-10-11 13:22:39 -0400548static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
Steven Valdez51607f12020-08-05 10:46:05 -0400549 CBS *contents) {
Steven Valdez6b8509a2016-07-12 13:38:32 -0400550 if (contents != NULL) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400551 // Servers MUST NOT send this extension.
Steven Valdez6b8509a2016-07-12 13:38:32 -0400552 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
553 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
David Benjamin31640932017-10-11 13:22:39 -0400554 return false;
Steven Valdez6b8509a2016-07-12 13:38:32 -0400555 }
556
David Benjamin31640932017-10-11 13:22:39 -0400557 return true;
Steven Valdez6b8509a2016-07-12 13:38:32 -0400558}
559
David Benjamin31640932017-10-11 13:22:39 -0400560static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
Steven Valdez51607f12020-08-05 10:46:05 -0400561 CBS *contents) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400562 // This extension from the client is handled elsewhere.
David Benjamin31640932017-10-11 13:22:39 -0400563 return true;
Steven Valdez6b8509a2016-07-12 13:38:32 -0400564}
565
David Benjamin31640932017-10-11 13:22:39 -0400566static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
567 return true;
Steven Valdez6b8509a2016-07-12 13:38:32 -0400568}
Adam Langley614c66a2015-06-12 15:26:58 -0700569
David Benjaminc11ea9422017-08-29 16:33:21 -0400570// Server name indication (SNI).
571//
572// https://tools.ietf.org/html/rfc6066#section-3.
Adam Langley614c66a2015-06-12 15:26:58 -0700573
David Benjamin83a49932021-05-20 15:57:09 -0400574static bool ext_sni_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
575 CBB *out_compressible,
576 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -0400577 const SSL *const ssl = hs->ssl;
David Benjamin83a49932021-05-20 15:57:09 -0400578 // If offering ECH, send the public name instead of the configured name.
579 Span<const uint8_t> hostname;
580 if (type == ssl_client_hello_outer) {
581 hostname = hs->selected_ech_config->public_name;
582 } else {
583 if (ssl->hostname == nullptr) {
584 return true;
585 }
586 hostname =
587 MakeConstSpan(reinterpret_cast<const uint8_t *>(ssl->hostname.get()),
588 strlen(ssl->hostname.get()));
Adam Langley614c66a2015-06-12 15:26:58 -0700589 }
590
591 CBB contents, server_name_list, name;
592 if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
593 !CBB_add_u16_length_prefixed(out, &contents) ||
594 !CBB_add_u16_length_prefixed(&contents, &server_name_list) ||
595 !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) ||
596 !CBB_add_u16_length_prefixed(&server_name_list, &name) ||
David Benjamin83a49932021-05-20 15:57:09 -0400597 !CBB_add_bytes(&name, hostname.data(), hostname.size()) ||
Adam Langley614c66a2015-06-12 15:26:58 -0700598 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -0400599 return false;
Adam Langley614c66a2015-06-12 15:26:58 -0700600 }
601
David Benjamin31640932017-10-11 13:22:39 -0400602 return true;
Adam Langley614c66a2015-06-12 15:26:58 -0700603}
604
David Benjamin31640932017-10-11 13:22:39 -0400605static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
606 CBS *contents) {
David Benjamina8614602017-09-06 15:40:19 -0400607 // The server may acknowledge SNI with an empty extension. We check the syntax
608 // but otherwise ignore this signal.
609 return contents == NULL || CBS_len(contents) == 0;
Adam Langley614c66a2015-06-12 15:26:58 -0700610}
611
David Benjamin31640932017-10-11 13:22:39 -0400612static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
613 CBS *contents) {
David Benjaminef0183c2019-07-20 09:11:05 -0400614 // SNI has already been parsed earlier in the handshake. See |extract_sni|.
David Benjamin31640932017-10-11 13:22:39 -0400615 return true;
Adam Langley614c66a2015-06-12 15:26:58 -0700616}
617
David Benjamin31640932017-10-11 13:22:39 -0400618static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -0500619 if (hs->ssl->s3->session_reused ||
620 !hs->should_ack_sni) {
David Benjamin31640932017-10-11 13:22:39 -0400621 return true;
Adam Langley614c66a2015-06-12 15:26:58 -0700622 }
623
624 if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
625 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -0400626 return false;
Adam Langley614c66a2015-06-12 15:26:58 -0700627 }
628
David Benjamin31640932017-10-11 13:22:39 -0400629 return true;
Adam Langley614c66a2015-06-12 15:26:58 -0700630}
631
632
Daniel McArdle00e434d2021-02-18 11:47:18 -0500633// Encrypted ClientHello (ECH)
Dan McArdle1920c6f2020-03-11 17:29:40 -0400634//
David Benjamin18b68362021-06-18 23:13:46 -0400635// https://tools.ietf.org/html/draft-ietf-tls-esni-13
Dan McArdle1920c6f2020-03-11 17:29:40 -0400636
David Benjamin83a49932021-05-20 15:57:09 -0400637static bool ext_ech_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
638 CBB *out_compressible,
639 ssl_client_hello_type_t type) {
David Benjamin18b68362021-06-18 23:13:46 -0400640 if (type == ssl_client_hello_inner) {
641 if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) ||
642 !CBB_add_u16(out, /* length */ 1) ||
643 !CBB_add_u8(out, ECH_CLIENT_INNER)) {
644 return false;
645 }
646 return true;
647 }
648
649 if (hs->ech_client_outer.empty()) {
Dan McArdle1920c6f2020-03-11 17:29:40 -0400650 return true;
651 }
652
David Benjamin83a49932021-05-20 15:57:09 -0400653 CBB ech_body;
654 if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) ||
655 !CBB_add_u16_length_prefixed(out, &ech_body) ||
David Benjamin18b68362021-06-18 23:13:46 -0400656 !CBB_add_u8(&ech_body, ECH_CLIENT_OUTER) ||
657 !CBB_add_bytes(&ech_body, hs->ech_client_outer.data(),
658 hs->ech_client_outer.size()) ||
David Benjamin83a49932021-05-20 15:57:09 -0400659 !CBB_flush(out)) {
Dan McArdle1920c6f2020-03-11 17:29:40 -0400660 return false;
661 }
David Benjamin246c5562021-05-20 13:42:25 -0400662 return true;
Dan McArdle1920c6f2020-03-11 17:29:40 -0400663}
664
Dan McArdle1920c6f2020-03-11 17:29:40 -0400665static bool ext_ech_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
666 CBS *contents) {
David Benjamin5b7ec832021-06-02 11:12:13 -0400667 SSL *const ssl = hs->ssl;
Dan McArdle1920c6f2020-03-11 17:29:40 -0400668 if (contents == NULL) {
669 return true;
670 }
671
David Benjamin5b7ec832021-06-02 11:12:13 -0400672 // The ECH extension may not be sent in TLS 1.2 ServerHello, only TLS 1.3
David Benjamin18b68362021-06-18 23:13:46 -0400673 // EncryptedExtensions. It also may not be sent in response to an inner ECH
674 // extension.
675 if (ssl_protocol_version(ssl) < TLS1_3_VERSION ||
676 ssl->s3->ech_status == ssl_ech_accepted) {
David Benjamin5b7ec832021-06-02 11:12:13 -0400677 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
678 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
679 return false;
680 }
681
David Benjaminba423c92021-06-15 16:26:58 -0400682 if (!ssl_is_valid_ech_config_list(*contents)) {
683 *out_alert = SSL_AD_DECODE_ERROR;
684 return false;
685 }
686
David Benjamin18b68362021-06-18 23:13:46 -0400687 if (ssl->s3->ech_status == ssl_ech_rejected &&
David Benjaminba423c92021-06-15 16:26:58 -0400688 !hs->ech_retry_configs.CopyFrom(*contents)) {
689 *out_alert = SSL_AD_INTERNAL_ERROR;
Dan McArdle1920c6f2020-03-11 17:29:40 -0400690 return false;
691 }
David Benjaminba423c92021-06-15 16:26:58 -0400692
Dan McArdle1920c6f2020-03-11 17:29:40 -0400693 return true;
694}
695
Dan McArdlec2959352020-10-29 14:31:31 -0400696static bool ext_ech_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
697 CBS *contents) {
David Benjamin18b68362021-06-18 23:13:46 -0400698 if (contents == nullptr) {
Dan McArdlec2959352020-10-29 14:31:31 -0400699 return true;
700 }
David Benjamin18b68362021-06-18 23:13:46 -0400701
702 uint8_t type;
703 if (!CBS_get_u8(contents, &type)) {
704 return false;
705 }
706 if (type == ECH_CLIENT_OUTER) {
707 // Outer ECH extensions are handled outside the callback.
708 return true;
709 }
710 if (type != ECH_CLIENT_INNER || CBS_len(contents) != 0) {
711 return false;
712 }
713
714 hs->ech_is_inner = true;
Dan McArdlec2959352020-10-29 14:31:31 -0400715 return true;
716}
717
Daniel McArdle00e434d2021-02-18 11:47:18 -0500718static bool ext_ech_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
719 SSL *const ssl = hs->ssl;
David Benjaminba423c92021-06-15 16:26:58 -0400720 if (ssl_protocol_version(ssl) < TLS1_3_VERSION ||
721 ssl->s3->ech_status == ssl_ech_accepted || //
David Benjaminc3b373b2021-06-06 13:04:26 -0400722 hs->ech_keys == nullptr) {
Daniel McArdle00e434d2021-02-18 11:47:18 -0500723 return true;
724 }
725
David Benjaminc3b373b2021-06-06 13:04:26 -0400726 // Write the list of retry configs to |out|. Note |SSL_CTX_set1_ech_keys|
727 // ensures |ech_keys| contains at least one retry config.
Daniel McArdle00e434d2021-02-18 11:47:18 -0500728 CBB body, retry_configs;
729 if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) ||
730 !CBB_add_u16_length_prefixed(out, &body) ||
731 !CBB_add_u16_length_prefixed(&body, &retry_configs)) {
732 return false;
733 }
David Benjaminc3b373b2021-06-06 13:04:26 -0400734 for (const auto &config : hs->ech_keys->configs) {
David Benjamin1d58cd12021-05-04 15:24:24 -0400735 if (!config->is_retry_config()) {
Daniel McArdle00e434d2021-02-18 11:47:18 -0500736 continue;
737 }
David Benjamin83a49932021-05-20 15:57:09 -0400738 if (!CBB_add_bytes(&retry_configs, config->ech_config().raw.data(),
739 config->ech_config().raw.size())) {
Daniel McArdle00e434d2021-02-18 11:47:18 -0500740 return false;
741 }
742 }
743 return CBB_flush(out);
744}
745
Dan McArdle1920c6f2020-03-11 17:29:40 -0400746
David Benjaminc11ea9422017-08-29 16:33:21 -0400747// Renegotiation indication.
748//
749// https://tools.ietf.org/html/rfc5746
Adam Langley5021b222015-06-12 18:27:58 -0700750
David Benjamin83a49932021-05-20 15:57:09 -0400751static bool ext_ri_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
752 CBB *out_compressible,
753 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -0400754 const SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -0400755 // Renegotiation indication is not necessary in TLS 1.3.
David Benjamin83a49932021-05-20 15:57:09 -0400756 if (hs->min_version >= TLS1_3_VERSION ||
757 type == ssl_client_hello_inner) {
David Benjamin31640932017-10-11 13:22:39 -0400758 return true;
David Benjamin7c7d8312016-08-20 13:39:03 -0400759 }
760
David Benjamin52bf6902016-10-08 12:05:03 -0400761 assert(ssl->s3->initial_handshake_complete ==
762 (ssl->s3->previous_client_finished_len != 0));
763
Adam Langley5021b222015-06-12 18:27:58 -0700764 CBB contents, prev_finished;
765 if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
766 !CBB_add_u16_length_prefixed(out, &contents) ||
767 !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
768 !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
769 ssl->s3->previous_client_finished_len) ||
770 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -0400771 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700772 }
773
David Benjamin31640932017-10-11 13:22:39 -0400774 return true;
Adam Langley5021b222015-06-12 18:27:58 -0700775}
776
David Benjamin31640932017-10-11 13:22:39 -0400777static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
778 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -0500779 SSL *const ssl = hs->ssl;
David Benjamind1e3ce12017-10-06 18:31:15 -0400780 if (contents != NULL && ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
Steven Valdez246eeee2017-03-26 12:49:17 -0500781 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -0400782 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -0400783 }
784
David Benjaminc11ea9422017-08-29 16:33:21 -0400785 // Servers may not switch between omitting the extension and supporting it.
786 // See RFC 5746, sections 3.5 and 4.2.
David Benjamin3e052de2015-11-25 20:10:31 -0500787 if (ssl->s3->initial_handshake_complete &&
788 (contents != NULL) != ssl->s3->send_connection_binding) {
789 *out_alert = SSL_AD_HANDSHAKE_FAILURE;
790 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
David Benjamin31640932017-10-11 13:22:39 -0400791 return false;
David Benjamin3e052de2015-11-25 20:10:31 -0500792 }
793
Adam Langley5021b222015-06-12 18:27:58 -0700794 if (contents == NULL) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400795 // Strictly speaking, if we want to avoid an attack we should *always* see
796 // RI even on initial ServerHello because the client doesn't see any
797 // renegotiation during an attack. However this would mean we could not
798 // connect to any server which doesn't support RI.
799 //
800 // OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in
801 // practical terms every client sets it so it's just assumed here.
David Benjamin31640932017-10-11 13:22:39 -0400802 return true;
Adam Langley5021b222015-06-12 18:27:58 -0700803 }
804
805 const size_t expected_len = ssl->s3->previous_client_finished_len +
806 ssl->s3->previous_server_finished_len;
807
David Benjaminc11ea9422017-08-29 16:33:21 -0400808 // Check for logic errors
Adam Langley5021b222015-06-12 18:27:58 -0700809 assert(!expected_len || ssl->s3->previous_client_finished_len);
810 assert(!expected_len || ssl->s3->previous_server_finished_len);
David Benjamin52bf6902016-10-08 12:05:03 -0400811 assert(ssl->s3->initial_handshake_complete ==
812 (ssl->s3->previous_client_finished_len != 0));
813 assert(ssl->s3->initial_handshake_complete ==
814 (ssl->s3->previous_server_finished_len != 0));
Adam Langley5021b222015-06-12 18:27:58 -0700815
David Benjaminc11ea9422017-08-29 16:33:21 -0400816 // Parse out the extension contents.
Adam Langley5021b222015-06-12 18:27:58 -0700817 CBS renegotiated_connection;
818 if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
819 CBS_len(contents) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400820 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
Adam Langley5021b222015-06-12 18:27:58 -0700821 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -0400822 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700823 }
824
David Benjaminc11ea9422017-08-29 16:33:21 -0400825 // Check that the extension matches.
Adam Langley5021b222015-06-12 18:27:58 -0700826 if (CBS_len(&renegotiated_connection) != expected_len) {
David Benjamin3570d732015-06-29 00:28:17 -0400827 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
Adam Langley5021b222015-06-12 18:27:58 -0700828 *out_alert = SSL_AD_HANDSHAKE_FAILURE;
David Benjamin31640932017-10-11 13:22:39 -0400829 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700830 }
831
832 const uint8_t *d = CBS_data(&renegotiated_connection);
David Benjamin31640932017-10-11 13:22:39 -0400833 bool ok = CRYPTO_memcmp(d, ssl->s3->previous_client_finished,
834 ssl->s3->previous_client_finished_len) == 0;
David Benjamin9343b0b2017-07-01 00:31:27 -0400835#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
David Benjamin31640932017-10-11 13:22:39 -0400836 ok = true;
David Benjamin9343b0b2017-07-01 00:31:27 -0400837#endif
838 if (!ok) {
David Benjamin3570d732015-06-29 00:28:17 -0400839 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
Adam Langley5021b222015-06-12 18:27:58 -0700840 *out_alert = SSL_AD_HANDSHAKE_FAILURE;
David Benjamin31640932017-10-11 13:22:39 -0400841 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700842 }
843 d += ssl->s3->previous_client_finished_len;
844
David Benjamin9343b0b2017-07-01 00:31:27 -0400845 ok = CRYPTO_memcmp(d, ssl->s3->previous_server_finished,
846 ssl->s3->previous_server_finished_len) == 0;
847#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
David Benjamin31640932017-10-11 13:22:39 -0400848 ok = true;
David Benjamin9343b0b2017-07-01 00:31:27 -0400849#endif
850 if (!ok) {
David Benjamin3570d732015-06-29 00:28:17 -0400851 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
Adam Langley10e10602017-07-25 13:33:21 -0700852 *out_alert = SSL_AD_HANDSHAKE_FAILURE;
David Benjamin31640932017-10-11 13:22:39 -0400853 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700854 }
David Benjamin046bc1f2017-08-31 15:06:42 -0400855 ssl->s3->send_connection_binding = true;
Adam Langley5021b222015-06-12 18:27:58 -0700856
David Benjamin31640932017-10-11 13:22:39 -0400857 return true;
Adam Langley5021b222015-06-12 18:27:58 -0700858}
859
David Benjamin31640932017-10-11 13:22:39 -0400860static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
861 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -0500862 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -0400863 // Renegotiation isn't supported as a server so this function should never be
864 // called after the initial handshake.
Adam Langley5021b222015-06-12 18:27:58 -0700865 assert(!ssl->s3->initial_handshake_complete);
866
David Benjamind1e3ce12017-10-06 18:31:15 -0400867 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -0400868 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -0400869 }
870
Adam Langley5021b222015-06-12 18:27:58 -0700871 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -0400872 return true;
Adam Langley5021b222015-06-12 18:27:58 -0700873 }
874
875 CBS renegotiated_connection;
Adam Langley5021b222015-06-12 18:27:58 -0700876 if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
877 CBS_len(contents) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400878 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
David Benjamin31640932017-10-11 13:22:39 -0400879 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700880 }
881
David Benjaminc11ea9422017-08-29 16:33:21 -0400882 // Check that the extension matches. We do not support renegotiation as a
883 // server, so this must be empty.
David Benjamin52bf6902016-10-08 12:05:03 -0400884 if (CBS_len(&renegotiated_connection) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400885 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
Adam Langley5021b222015-06-12 18:27:58 -0700886 *out_alert = SSL_AD_HANDSHAKE_FAILURE;
David Benjamin31640932017-10-11 13:22:39 -0400887 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700888 }
889
David Benjamin046bc1f2017-08-31 15:06:42 -0400890 ssl->s3->send_connection_binding = true;
Adam Langley5021b222015-06-12 18:27:58 -0700891
David Benjamin31640932017-10-11 13:22:39 -0400892 return true;
Adam Langley5021b222015-06-12 18:27:58 -0700893}
894
David Benjamin31640932017-10-11 13:22:39 -0400895static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -0500896 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -0400897 // Renegotiation isn't supported as a server so this function should never be
898 // called after the initial handshake.
David Benjamin52bf6902016-10-08 12:05:03 -0400899 assert(!ssl->s3->initial_handshake_complete);
900
David Benjamind1e3ce12017-10-06 18:31:15 -0400901 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -0400902 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -0400903 }
904
Adam Langley5021b222015-06-12 18:27:58 -0700905 if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
David Benjamin52bf6902016-10-08 12:05:03 -0400906 !CBB_add_u16(out, 1 /* length */) ||
907 !CBB_add_u8(out, 0 /* empty renegotiation info */)) {
David Benjamin31640932017-10-11 13:22:39 -0400908 return false;
Adam Langley5021b222015-06-12 18:27:58 -0700909 }
910
David Benjamin31640932017-10-11 13:22:39 -0400911 return true;
Adam Langley5021b222015-06-12 18:27:58 -0700912}
913
Adam Langley0a056712015-07-01 15:03:33 -0700914
David Benjaminc11ea9422017-08-29 16:33:21 -0400915// Extended Master Secret.
916//
917// https://tools.ietf.org/html/rfc7627
Adam Langley0a056712015-07-01 15:03:33 -0700918
David Benjamin83a49932021-05-20 15:57:09 -0400919static bool ext_ems_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
920 CBB *out_compressible,
921 ssl_client_hello_type_t type) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400922 // Extended master secret is not necessary in TLS 1.3.
David Benjamin83a49932021-05-20 15:57:09 -0400923 if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner) {
David Benjamin31640932017-10-11 13:22:39 -0400924 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700925 }
926
927 if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
928 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -0400929 return false;
Adam Langley0a056712015-07-01 15:03:33 -0700930 }
931
David Benjamin31640932017-10-11 13:22:39 -0400932 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700933}
934
David Benjamin31640932017-10-11 13:22:39 -0400935static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
936 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -0500937 SSL *const ssl = hs->ssl;
David Benjaminfc02b592017-02-17 16:26:01 -0500938
939 if (contents != NULL) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400940 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
David Benjaminfc02b592017-02-17 16:26:01 -0500941 CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -0400942 return false;
David Benjamin163c9562016-08-29 23:14:17 -0400943 }
944
David Benjaminfd45ee72017-08-31 14:49:09 -0400945 hs->extended_master_secret = true;
David Benjamin163c9562016-08-29 23:14:17 -0400946 }
947
David Benjaminc11ea9422017-08-29 16:33:21 -0400948 // Whether EMS is negotiated may not change on renegotiation.
David Benjamin8e7bbba2017-10-13 17:18:35 -0400949 if (ssl->s3->established_session != nullptr &&
David Benjaminfc02b592017-02-17 16:26:01 -0500950 hs->extended_master_secret !=
David Benjaminfd45ee72017-08-31 14:49:09 -0400951 !!ssl->s3->established_session->extended_master_secret) {
David Benjaminfc02b592017-02-17 16:26:01 -0500952 OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH);
953 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -0400954 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -0400955 }
956
David Benjamin31640932017-10-11 13:22:39 -0400957 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700958}
959
David Benjamin31640932017-10-11 13:22:39 -0400960static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
961 CBS *contents) {
David Benjamin9bb15f52018-06-26 00:07:40 -0400962 if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -0400963 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -0400964 }
965
966 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -0400967 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700968 }
969
970 if (CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -0400971 return false;
Adam Langley0a056712015-07-01 15:03:33 -0700972 }
973
David Benjaminfd45ee72017-08-31 14:49:09 -0400974 hs->extended_master_secret = true;
David Benjamin31640932017-10-11 13:22:39 -0400975 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700976}
977
David Benjamin31640932017-10-11 13:22:39 -0400978static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjaminfc02b592017-02-17 16:26:01 -0500979 if (!hs->extended_master_secret) {
David Benjamin31640932017-10-11 13:22:39 -0400980 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700981 }
982
983 if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
984 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -0400985 return false;
Adam Langley0a056712015-07-01 15:03:33 -0700986 }
987
David Benjamin31640932017-10-11 13:22:39 -0400988 return true;
Adam Langley0a056712015-07-01 15:03:33 -0700989}
990
Adam Langley9b05bc52015-07-01 15:25:33 -0700991
David Benjaminc11ea9422017-08-29 16:33:21 -0400992// Session tickets.
993//
994// https://tools.ietf.org/html/rfc5077
Adam Langley9b05bc52015-07-01 15:25:33 -0700995
David Benjamin83a49932021-05-20 15:57:09 -0400996static bool ext_ticket_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
997 CBB *out_compressible,
998 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -0400999 const SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -04001000 // TLS 1.3 uses a different ticket extension.
David Benjamin83a49932021-05-20 15:57:09 -04001001 if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner ||
David Benjamin7c7d8312016-08-20 13:39:03 -04001002 SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
David Benjamin31640932017-10-11 13:22:39 -04001003 return true;
Adam Langley9b05bc52015-07-01 15:25:33 -07001004 }
1005
David Benjaminbfdd1a92018-06-29 16:26:38 -04001006 Span<const uint8_t> ticket;
Adam Langley9b05bc52015-07-01 15:25:33 -07001007
David Benjaminc11ea9422017-08-29 16:33:21 -04001008 // Renegotiation does not participate in session resumption. However, still
1009 // advertise the extension to avoid potentially breaking servers which carry
1010 // over the state from the previous handshake, such as OpenSSL servers
1011 // without upstream's 3c3f0259238594d77264a78944d409f2127642c4.
Adam Langley9b05bc52015-07-01 15:25:33 -07001012 if (!ssl->s3->initial_handshake_complete &&
David Benjamin50596f82018-07-02 19:47:27 -04001013 ssl->session != nullptr &&
David Benjaminbfdd1a92018-06-29 16:26:38 -04001014 !ssl->session->ticket.empty() &&
David Benjaminc11ea9422017-08-29 16:33:21 -04001015 // Don't send TLS 1.3 session tickets in the ticket extension.
David Benjamin50596f82018-07-02 19:47:27 -04001016 ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION) {
David Benjaminbfdd1a92018-06-29 16:26:38 -04001017 ticket = ssl->session->ticket;
Adam Langley9b05bc52015-07-01 15:25:33 -07001018 }
1019
David Benjaminbfdd1a92018-06-29 16:26:38 -04001020 CBB ticket_cbb;
Adam Langley9b05bc52015-07-01 15:25:33 -07001021 if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
David Benjaminbfdd1a92018-06-29 16:26:38 -04001022 !CBB_add_u16_length_prefixed(out, &ticket_cbb) ||
1023 !CBB_add_bytes(&ticket_cbb, ticket.data(), ticket.size()) ||
Adam Langley9b05bc52015-07-01 15:25:33 -07001024 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04001025 return false;
Adam Langley9b05bc52015-07-01 15:25:33 -07001026 }
1027
David Benjamin31640932017-10-11 13:22:39 -04001028 return true;
Adam Langley9b05bc52015-07-01 15:25:33 -07001029}
1030
David Benjamin31640932017-10-11 13:22:39 -04001031static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1032 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001033 SSL *const ssl = hs->ssl;
Adam Langley9b05bc52015-07-01 15:25:33 -07001034 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001035 return true;
Adam Langley9b05bc52015-07-01 15:25:33 -07001036 }
1037
David Benjamind1e3ce12017-10-06 18:31:15 -04001038 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001039 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04001040 }
1041
David Benjaminc11ea9422017-08-29 16:33:21 -04001042 // If |SSL_OP_NO_TICKET| is set then no extension will have been sent and
1043 // this function should never be called, even if the server tries to send the
1044 // extension.
Adam Langley9b05bc52015-07-01 15:25:33 -07001045 assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
1046
1047 if (CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001048 return false;
Adam Langley9b05bc52015-07-01 15:25:33 -07001049 }
1050
David Benjaminfd45ee72017-08-31 14:49:09 -04001051 hs->ticket_expected = true;
David Benjamin31640932017-10-11 13:22:39 -04001052 return true;
Adam Langley9b05bc52015-07-01 15:25:33 -07001053}
1054
David Benjamin31640932017-10-11 13:22:39 -04001055static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001056 if (!hs->ticket_expected) {
David Benjamin31640932017-10-11 13:22:39 -04001057 return true;
Adam Langley9b05bc52015-07-01 15:25:33 -07001058 }
1059
David Benjaminc11ea9422017-08-29 16:33:21 -04001060 // If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true.
David Benjamin8c880a22016-12-03 02:20:34 -05001061 assert((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) == 0);
Adam Langley9b05bc52015-07-01 15:25:33 -07001062
1063 if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
1064 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -04001065 return false;
Adam Langley9b05bc52015-07-01 15:25:33 -07001066 }
1067
David Benjamin31640932017-10-11 13:22:39 -04001068 return true;
Adam Langley9b05bc52015-07-01 15:25:33 -07001069}
1070
1071
David Benjaminc11ea9422017-08-29 16:33:21 -04001072// Signature Algorithms.
1073//
1074// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Adam Langley2e857bd2015-07-01 16:09:19 -07001075
David Benjamin83a49932021-05-20 15:57:09 -04001076static bool ext_sigalgs_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1077 CBB *out_compressible,
1078 ssl_client_hello_type_t type) {
David Benjamin68161cb2017-06-20 14:49:43 -04001079 if (hs->max_version < TLS1_2_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001080 return true;
Adam Langley2e857bd2015-07-01 16:09:19 -07001081 }
1082
David Benjamin0fc37ef2016-08-17 15:29:46 -04001083 CBB contents, sigalgs_cbb;
David Benjamin83a49932021-05-20 15:57:09 -04001084 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_signature_algorithms) ||
1085 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
David Benjamin69522112017-03-28 15:38:29 -05001086 !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb) ||
David Benjaminebad5082020-02-03 19:32:19 -05001087 !tls12_add_verify_sigalgs(hs, &sigalgs_cbb) ||
David Benjamin83a49932021-05-20 15:57:09 -04001088 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04001089 return false;
Adam Langley2e857bd2015-07-01 16:09:19 -07001090 }
1091
David Benjamin31640932017-10-11 13:22:39 -04001092 return true;
Adam Langley2e857bd2015-07-01 16:09:19 -07001093}
1094
David Benjamin31640932017-10-11 13:22:39 -04001095static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1096 CBS *contents) {
David Benjaminb1cf48e2017-09-21 11:37:46 -04001097 hs->peer_sigalgs.Reset();
Adam Langley2e857bd2015-07-01 16:09:19 -07001098 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001099 return true;
Adam Langley2e857bd2015-07-01 16:09:19 -07001100 }
1101
1102 CBS supported_signature_algorithms;
1103 if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) ||
Steven Valdez0d62f262015-09-04 12:41:04 -04001104 CBS_len(contents) != 0 ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +09001105 !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) {
David Benjamin31640932017-10-11 13:22:39 -04001106 return false;
Adam Langley2e857bd2015-07-01 16:09:19 -07001107 }
1108
David Benjamin31640932017-10-11 13:22:39 -04001109 return true;
Adam Langley2e857bd2015-07-01 16:09:19 -07001110}
1111
Adam Langley2e857bd2015-07-01 16:09:19 -07001112
David Benjaminc11ea9422017-08-29 16:33:21 -04001113// OCSP Stapling.
1114//
1115// https://tools.ietf.org/html/rfc6066#section-8
Adam Langleybb0bd042015-07-01 16:21:03 -07001116
David Benjamin83a49932021-05-20 15:57:09 -04001117static bool ext_ocsp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1118 CBB *out_compressible,
1119 ssl_client_hello_type_t type) {
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001120 if (!hs->config->ocsp_stapling_enabled) {
David Benjamin31640932017-10-11 13:22:39 -04001121 return true;
Adam Langleybb0bd042015-07-01 16:21:03 -07001122 }
1123
1124 CBB contents;
David Benjamin83a49932021-05-20 15:57:09 -04001125 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_status_request) ||
1126 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
Adam Langleybb0bd042015-07-01 16:21:03 -07001127 !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
1128 !CBB_add_u16(&contents, 0 /* empty responder ID list */) ||
1129 !CBB_add_u16(&contents, 0 /* empty request extensions */) ||
David Benjamin83a49932021-05-20 15:57:09 -04001130 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04001131 return false;
Adam Langleybb0bd042015-07-01 16:21:03 -07001132 }
1133
David Benjamin31640932017-10-11 13:22:39 -04001134 return true;
Adam Langleybb0bd042015-07-01 16:21:03 -07001135}
1136
David Benjamin31640932017-10-11 13:22:39 -04001137static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1138 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001139 SSL *const ssl = hs->ssl;
Adam Langleybb0bd042015-07-01 16:21:03 -07001140 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001141 return true;
Adam Langleybb0bd042015-07-01 16:21:03 -07001142 }
1143
David Benjaminc11ea9422017-08-29 16:33:21 -04001144 // TLS 1.3 OCSP responses are included in the Certificate extensions.
David Benjamind1e3ce12017-10-06 18:31:15 -04001145 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001146 return false;
Steven Valdez803c77a2016-09-06 14:13:43 -04001147 }
1148
David Benjaminc11ea9422017-08-29 16:33:21 -04001149 // OCSP stapling is forbidden on non-certificate ciphers.
Steven Valdeza833c352016-11-01 13:39:36 -04001150 if (CBS_len(contents) != 0 ||
David Benjamin45738dd2017-02-09 20:01:26 -05001151 !ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
David Benjamin31640932017-10-11 13:22:39 -04001152 return false;
David Benjamin942f4ed2016-07-16 19:03:49 +03001153 }
1154
David Benjaminc11ea9422017-08-29 16:33:21 -04001155 // Note this does not check for resumption in TLS 1.2. Sending
1156 // status_request here does not make sense, but OpenSSL does so and the
1157 // specification does not say anything. Tolerate it but ignore it.
David Benjamin942f4ed2016-07-16 19:03:49 +03001158
David Benjaminfd45ee72017-08-31 14:49:09 -04001159 hs->certificate_status_expected = true;
David Benjamin31640932017-10-11 13:22:39 -04001160 return true;
Adam Langleybb0bd042015-07-01 16:21:03 -07001161}
1162
David Benjamin31640932017-10-11 13:22:39 -04001163static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1164 CBS *contents) {
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001165 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001166 return true;
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001167 }
1168
1169 uint8_t status_type;
1170 if (!CBS_get_u8(contents, &status_type)) {
David Benjamin31640932017-10-11 13:22:39 -04001171 return false;
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001172 }
1173
David Benjaminc11ea9422017-08-29 16:33:21 -04001174 // We cannot decide whether OCSP stapling will occur yet because the correct
1175 // SSL_CTX might not have been selected.
David Benjamin8c880a22016-12-03 02:20:34 -05001176 hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001177
David Benjamin31640932017-10-11 13:22:39 -04001178 return true;
Adam Langleybb0bd042015-07-01 16:21:03 -07001179}
1180
David Benjamin31640932017-10-11 13:22:39 -04001181static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001182 SSL *const ssl = hs->ssl;
David Benjamind1e3ce12017-10-06 18:31:15 -04001183 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001184 !hs->ocsp_stapling_requested || hs->config->cert->ocsp_response == NULL ||
Steven Valdez803c77a2016-09-06 14:13:43 -04001185 ssl->s3->session_reused ||
David Benjamin45738dd2017-02-09 20:01:26 -05001186 !ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
David Benjamin31640932017-10-11 13:22:39 -04001187 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04001188 }
1189
David Benjaminfd45ee72017-08-31 14:49:09 -04001190 hs->certificate_status_expected = true;
David Benjamin942f4ed2016-07-16 19:03:49 +03001191
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001192 return CBB_add_u16(out, TLSEXT_TYPE_status_request) &&
Steven Valdeza833c352016-11-01 13:39:36 -04001193 CBB_add_u16(out, 0 /* length */);
Adam Langleybb0bd042015-07-01 16:21:03 -07001194}
1195
1196
David Benjaminc11ea9422017-08-29 16:33:21 -04001197// Next protocol negotiation.
1198//
1199// https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html
Adam Langley97dfcbf2015-07-01 18:35:20 -07001200
David Benjamin83a49932021-05-20 15:57:09 -04001201static bool ext_npn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1202 CBB *out_compressible,
1203 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04001204 const SSL *const ssl = hs->ssl;
David Benjamin83a49932021-05-20 15:57:09 -04001205 if (ssl->ctx->next_proto_select_cb == NULL ||
1206 // Do not allow NPN to change on renegotiation.
1207 ssl->s3->initial_handshake_complete ||
1208 // NPN is not defined in DTLS or TLS 1.3.
1209 SSL_is_dtls(ssl) || hs->min_version >= TLS1_3_VERSION ||
1210 type == ssl_client_hello_inner) {
David Benjamin31640932017-10-11 13:22:39 -04001211 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001212 }
1213
1214 if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
1215 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -04001216 return false;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001217 }
1218
David Benjamin31640932017-10-11 13:22:39 -04001219 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001220}
1221
David Benjamin31640932017-10-11 13:22:39 -04001222static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1223 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001224 SSL *const ssl = hs->ssl;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001225 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001226 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001227 }
1228
David Benjamind1e3ce12017-10-06 18:31:15 -04001229 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001230 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04001231 }
1232
David Benjaminc11ea9422017-08-29 16:33:21 -04001233 // If any of these are false then we should never have sent the NPN
1234 // extension in the ClientHello and thus this function should never have been
1235 // called.
Adam Langley97dfcbf2015-07-01 18:35:20 -07001236 assert(!ssl->s3->initial_handshake_complete);
David Benjamince079fd2016-08-02 16:22:34 -04001237 assert(!SSL_is_dtls(ssl));
Adam Langley97dfcbf2015-07-01 18:35:20 -07001238 assert(ssl->ctx->next_proto_select_cb != NULL);
1239
David Benjamin8e7bbba2017-10-13 17:18:35 -04001240 if (!ssl->s3->alpn_selected.empty()) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001241 // NPN and ALPN may not be negotiated in the same connection.
David Benjamin76c2efc2015-08-31 14:24:29 -04001242 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
1243 OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
David Benjamin31640932017-10-11 13:22:39 -04001244 return false;
David Benjamin76c2efc2015-08-31 14:24:29 -04001245 }
1246
Adam Langley97dfcbf2015-07-01 18:35:20 -07001247 const uint8_t *const orig_contents = CBS_data(contents);
1248 const size_t orig_len = CBS_len(contents);
1249
1250 while (CBS_len(contents) != 0) {
1251 CBS proto;
1252 if (!CBS_get_u8_length_prefixed(contents, &proto) ||
1253 CBS_len(&proto) == 0) {
David Benjamin31640932017-10-11 13:22:39 -04001254 return false;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001255 }
1256 }
1257
David Benjamin9d64d8d2022-08-31 19:27:56 -04001258 // |orig_len| fits in |unsigned| because TLS extensions use 16-bit lengths.
Adam Langley97dfcbf2015-07-01 18:35:20 -07001259 uint8_t *selected;
1260 uint8_t selected_len;
1261 if (ssl->ctx->next_proto_select_cb(
David Benjamin9d64d8d2022-08-31 19:27:56 -04001262 ssl, &selected, &selected_len, orig_contents,
1263 static_cast<unsigned>(orig_len),
David Benjamin8e7bbba2017-10-13 17:18:35 -04001264 ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK ||
1265 !ssl->s3->next_proto_negotiated.CopyFrom(
1266 MakeConstSpan(selected, selected_len))) {
Adam Langley97dfcbf2015-07-01 18:35:20 -07001267 *out_alert = SSL_AD_INTERNAL_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04001268 return false;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001269 }
1270
David Benjaminfd45ee72017-08-31 14:49:09 -04001271 hs->next_proto_neg_seen = true;
David Benjamin31640932017-10-11 13:22:39 -04001272 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001273}
1274
David Benjamin31640932017-10-11 13:22:39 -04001275static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1276 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001277 SSL *const ssl = hs->ssl;
David Benjamind1e3ce12017-10-06 18:31:15 -04001278 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001279 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04001280 }
1281
Adam Langley97dfcbf2015-07-01 18:35:20 -07001282 if (contents != NULL && CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001283 return false;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001284 }
1285
1286 if (contents == NULL ||
1287 ssl->s3->initial_handshake_complete ||
Adam Langley97dfcbf2015-07-01 18:35:20 -07001288 ssl->ctx->next_protos_advertised_cb == NULL ||
David Benjamince079fd2016-08-02 16:22:34 -04001289 SSL_is_dtls(ssl)) {
David Benjamin31640932017-10-11 13:22:39 -04001290 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001291 }
1292
David Benjaminfd45ee72017-08-31 14:49:09 -04001293 hs->next_proto_neg_seen = true;
David Benjamin31640932017-10-11 13:22:39 -04001294 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001295}
1296
David Benjamin31640932017-10-11 13:22:39 -04001297static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001298 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -04001299 // |next_proto_neg_seen| might have been cleared when an ALPN extension was
1300 // parsed.
David Benjamin8c880a22016-12-03 02:20:34 -05001301 if (!hs->next_proto_neg_seen) {
David Benjamin31640932017-10-11 13:22:39 -04001302 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001303 }
1304
1305 const uint8_t *npa;
1306 unsigned npa_len;
1307
1308 if (ssl->ctx->next_protos_advertised_cb(
1309 ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
1310 SSL_TLSEXT_ERR_OK) {
David Benjaminfd45ee72017-08-31 14:49:09 -04001311 hs->next_proto_neg_seen = false;
David Benjamin31640932017-10-11 13:22:39 -04001312 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001313 }
1314
1315 CBB contents;
1316 if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
1317 !CBB_add_u16_length_prefixed(out, &contents) ||
1318 !CBB_add_bytes(&contents, npa, npa_len) ||
1319 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04001320 return false;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001321 }
1322
David Benjamin31640932017-10-11 13:22:39 -04001323 return true;
Adam Langley97dfcbf2015-07-01 18:35:20 -07001324}
1325
1326
David Benjaminc11ea9422017-08-29 16:33:21 -04001327// Signed certificate timestamps.
1328//
1329// https://tools.ietf.org/html/rfc6962#section-3.3.1
Adam Langleyab8d87d2015-07-10 12:21:39 -07001330
David Benjamin83a49932021-05-20 15:57:09 -04001331static bool ext_sct_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1332 CBB *out_compressible,
1333 ssl_client_hello_type_t type) {
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001334 if (!hs->config->signed_cert_timestamps_enabled) {
David Benjamin31640932017-10-11 13:22:39 -04001335 return true;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001336 }
1337
David Benjamin83a49932021-05-20 15:57:09 -04001338 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_certificate_timestamp) ||
1339 !CBB_add_u16(out_compressible, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -04001340 return false;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001341 }
1342
David Benjamin31640932017-10-11 13:22:39 -04001343 return true;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001344}
1345
David Benjamin31640932017-10-11 13:22:39 -04001346static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1347 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001348 SSL *const ssl = hs->ssl;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001349 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001350 return true;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001351 }
1352
David Benjaminc11ea9422017-08-29 16:33:21 -04001353 // TLS 1.3 SCTs are included in the Certificate extensions.
David Benjamind1e3ce12017-10-06 18:31:15 -04001354 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
Adam Langleycfa08c32016-11-17 13:21:27 -08001355 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04001356 return false;
Steven Valdeza833c352016-11-01 13:39:36 -04001357 }
1358
David Benjaminc11ea9422017-08-29 16:33:21 -04001359 // If this is false then we should never have sent the SCT extension in the
1360 // ClientHello and thus this function should never have been called.
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001361 assert(hs->config->signed_cert_timestamps_enabled);
Adam Langleyab8d87d2015-07-10 12:21:39 -07001362
Adam Langleycfa08c32016-11-17 13:21:27 -08001363 if (!ssl_is_sct_list_valid(contents)) {
Adam Langleyab8d87d2015-07-10 12:21:39 -07001364 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04001365 return false;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001366 }
1367
David Benjaminc11ea9422017-08-29 16:33:21 -04001368 // Session resumption uses the original session information. The extension
1369 // should not be sent on resumption, but RFC 6962 did not make it a
1370 // requirement, so tolerate this.
1371 //
1372 // TODO(davidben): Enforce this anyway.
David Benjamin8fc2dc02017-08-22 15:07:51 -07001373 if (!ssl->s3->session_reused) {
David Benjaminbfdd1a92018-06-29 16:26:38 -04001374 hs->new_session->signed_cert_timestamp_list.reset(
1375 CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool));
David Benjamin8fc2dc02017-08-22 15:07:51 -07001376 if (hs->new_session->signed_cert_timestamp_list == nullptr) {
1377 *out_alert = SSL_AD_INTERNAL_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04001378 return false;
David Benjamin8fc2dc02017-08-22 15:07:51 -07001379 }
Adam Langleyab8d87d2015-07-10 12:21:39 -07001380 }
1381
David Benjamin31640932017-10-11 13:22:39 -04001382 return true;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001383}
1384
David Benjamin31640932017-10-11 13:22:39 -04001385static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1386 CBS *contents) {
David Benjamin53210cb2016-11-16 09:01:48 +09001387 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001388 return true;
David Benjamin53210cb2016-11-16 09:01:48 +09001389 }
1390
1391 if (CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001392 return false;
David Benjamin53210cb2016-11-16 09:01:48 +09001393 }
1394
David Benjaminfd45ee72017-08-31 14:49:09 -04001395 hs->scts_requested = true;
David Benjamin31640932017-10-11 13:22:39 -04001396 return true;
Adam Langleyab8d87d2015-07-10 12:21:39 -07001397}
1398
David Benjamin31640932017-10-11 13:22:39 -04001399static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001400 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -04001401 // The extension shouldn't be sent when resuming sessions.
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001402 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || ssl->s3->session_reused ||
1403 hs->config->cert->signed_cert_timestamp_list == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001404 return true;
Paul Lietar4fac72e2015-09-09 13:44:55 +01001405 }
1406
1407 CBB contents;
1408 return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) &&
1409 CBB_add_u16_length_prefixed(out, &contents) &&
David Benjamin83a32122017-02-14 18:34:54 -05001410 CBB_add_bytes(
1411 &contents,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001412 CRYPTO_BUFFER_data(
1413 hs->config->cert->signed_cert_timestamp_list.get()),
1414 CRYPTO_BUFFER_len(
1415 hs->config->cert->signed_cert_timestamp_list.get())) &&
Paul Lietar4fac72e2015-09-09 13:44:55 +01001416 CBB_flush(out);
Adam Langleyab8d87d2015-07-10 12:21:39 -07001417}
1418
1419
David Benjaminc11ea9422017-08-29 16:33:21 -04001420// Application-level Protocol Negotiation.
1421//
1422// https://tools.ietf.org/html/rfc7301
Adam Langleyf18e4532015-07-10 13:39:53 -07001423
David Benjamin83a49932021-05-20 15:57:09 -04001424static bool ext_alpn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1425 CBB *out_compressible,
1426 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04001427 const SSL *const ssl = hs->ssl;
Nick Harper74161f42020-07-24 15:35:27 -07001428 if (hs->config->alpn_client_proto_list.empty() && ssl->quic_method) {
1429 // ALPN MUST be used with QUIC.
David Benjaminc02c19e2021-02-10 17:49:20 -05001430 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
Nick Harper74161f42020-07-24 15:35:27 -07001431 return false;
1432 }
1433
David Benjamin0ce090a2018-07-02 20:24:40 -04001434 if (hs->config->alpn_client_proto_list.empty() ||
Adam Langleyf18e4532015-07-10 13:39:53 -07001435 ssl->s3->initial_handshake_complete) {
David Benjamin31640932017-10-11 13:22:39 -04001436 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001437 }
1438
1439 CBB contents, proto_list;
David Benjamin83a49932021-05-20 15:57:09 -04001440 if (!CBB_add_u16(out_compressible,
1441 TLSEXT_TYPE_application_layer_protocol_negotiation) ||
1442 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
Adam Langleyf18e4532015-07-10 13:39:53 -07001443 !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
David Benjamin0ce090a2018-07-02 20:24:40 -04001444 !CBB_add_bytes(&proto_list, hs->config->alpn_client_proto_list.data(),
1445 hs->config->alpn_client_proto_list.size()) ||
David Benjamin83a49932021-05-20 15:57:09 -04001446 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04001447 return false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001448 }
1449
David Benjamin31640932017-10-11 13:22:39 -04001450 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001451}
1452
David Benjamin31640932017-10-11 13:22:39 -04001453static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1454 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001455 SSL *const ssl = hs->ssl;
Adam Langleyf18e4532015-07-10 13:39:53 -07001456 if (contents == NULL) {
Nick Harper74161f42020-07-24 15:35:27 -07001457 if (ssl->quic_method) {
1458 // ALPN is required when QUIC is used.
David Benjaminc02c19e2021-02-10 17:49:20 -05001459 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
Nick Harper74161f42020-07-24 15:35:27 -07001460 *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL;
1461 return false;
1462 }
David Benjamin31640932017-10-11 13:22:39 -04001463 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001464 }
1465
1466 assert(!ssl->s3->initial_handshake_complete);
David Benjamin0ce090a2018-07-02 20:24:40 -04001467 assert(!hs->config->alpn_client_proto_list.empty());
Adam Langleyf18e4532015-07-10 13:39:53 -07001468
David Benjamin8c880a22016-12-03 02:20:34 -05001469 if (hs->next_proto_neg_seen) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001470 // NPN and ALPN may not be negotiated in the same connection.
David Benjamin76c2efc2015-08-31 14:24:29 -04001471 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
1472 OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
David Benjamin31640932017-10-11 13:22:39 -04001473 return false;
David Benjamin76c2efc2015-08-31 14:24:29 -04001474 }
1475
David Benjaminc11ea9422017-08-29 16:33:21 -04001476 // The extension data consists of a ProtocolNameList which must have
1477 // exactly one ProtocolName. Each of these is length-prefixed.
Adam Langleyf18e4532015-07-10 13:39:53 -07001478 CBS protocol_name_list, protocol_name;
1479 if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
1480 CBS_len(contents) != 0 ||
1481 !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
David Benjaminc11ea9422017-08-29 16:33:21 -04001482 // Empty protocol names are forbidden.
Adam Langleyf18e4532015-07-10 13:39:53 -07001483 CBS_len(&protocol_name) == 0 ||
1484 CBS_len(&protocol_name_list) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001485 return false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001486 }
1487
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001488 if (!ssl_is_alpn_protocol_allowed(hs, protocol_name)) {
David Benjamindd6c2e82017-10-17 15:48:46 -04001489 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
1490 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
1491 return false;
David Benjamin3e51757d2016-08-11 11:52:23 -04001492 }
1493
David Benjamin8e7bbba2017-10-13 17:18:35 -04001494 if (!ssl->s3->alpn_selected.CopyFrom(protocol_name)) {
Adam Langleyf18e4532015-07-10 13:39:53 -07001495 *out_alert = SSL_AD_INTERNAL_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04001496 return false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001497 }
1498
David Benjamin31640932017-10-11 13:22:39 -04001499 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001500}
1501
David Benjamin12a3e7e2021-04-13 11:47:36 -04001502bool ssl_is_valid_alpn_list(Span<const uint8_t> in) {
1503 CBS protocol_name_list = in;
1504 if (CBS_len(&protocol_name_list) == 0) {
1505 return false;
1506 }
1507 while (CBS_len(&protocol_name_list) > 0) {
1508 CBS protocol_name;
1509 if (!CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
1510 // Empty protocol names are forbidden.
1511 CBS_len(&protocol_name) == 0) {
1512 return false;
1513 }
1514 }
1515 return true;
1516}
1517
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001518bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs,
David Benjamindd6c2e82017-10-17 15:48:46 -04001519 Span<const uint8_t> protocol) {
David Benjamin0ce090a2018-07-02 20:24:40 -04001520 if (hs->config->alpn_client_proto_list.empty()) {
David Benjamindd6c2e82017-10-17 15:48:46 -04001521 return false;
1522 }
1523
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001524 if (hs->ssl->ctx->allow_unknown_alpn_protos) {
David Benjamindd6c2e82017-10-17 15:48:46 -04001525 return true;
1526 }
1527
1528 // Check that the protocol name is one of the ones we advertised.
David Benjamin0ce090a2018-07-02 20:24:40 -04001529 CBS client_protocol_name_list =
1530 MakeConstSpan(hs->config->alpn_client_proto_list),
1531 client_protocol_name;
David Benjamindd6c2e82017-10-17 15:48:46 -04001532 while (CBS_len(&client_protocol_name_list) > 0) {
1533 if (!CBS_get_u8_length_prefixed(&client_protocol_name_list,
1534 &client_protocol_name)) {
1535 return false;
1536 }
1537
1538 if (client_protocol_name == protocol) {
1539 return true;
1540 }
1541 }
1542
1543 return false;
1544}
1545
David Benjamin31640932017-10-11 13:22:39 -04001546bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1547 const SSL_CLIENT_HELLO *client_hello) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +09001548 SSL *const ssl = hs->ssl;
David Benjamin9ef31f02016-10-31 18:01:13 -04001549 CBS contents;
Adam Langleyf18e4532015-07-10 13:39:53 -07001550 if (ssl->ctx->alpn_select_cb == NULL ||
David Benjamin731058e2016-12-03 23:15:13 -05001551 !ssl_client_hello_get_extension(
David Benjamin9ef31f02016-10-31 18:01:13 -04001552 client_hello, &contents,
1553 TLSEXT_TYPE_application_layer_protocol_negotiation)) {
Nick Harper74161f42020-07-24 15:35:27 -07001554 if (ssl->quic_method) {
1555 // ALPN is required when QUIC is used.
David Benjaminc02c19e2021-02-10 17:49:20 -05001556 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
Nick Harper74161f42020-07-24 15:35:27 -07001557 *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL;
1558 return false;
1559 }
David Benjaminc11ea9422017-08-29 16:33:21 -04001560 // Ignore ALPN if not configured or no extension was supplied.
David Benjamin31640932017-10-11 13:22:39 -04001561 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001562 }
1563
David Benjaminc11ea9422017-08-29 16:33:21 -04001564 // ALPN takes precedence over NPN.
David Benjaminfd45ee72017-08-31 14:49:09 -04001565 hs->next_proto_neg_seen = false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001566
1567 CBS protocol_name_list;
David Benjamin9ef31f02016-10-31 18:01:13 -04001568 if (!CBS_get_u16_length_prefixed(&contents, &protocol_name_list) ||
1569 CBS_len(&contents) != 0 ||
David Benjamin12a3e7e2021-04-13 11:47:36 -04001570 !ssl_is_valid_alpn_list(protocol_name_list)) {
David Benjamin9ef31f02016-10-31 18:01:13 -04001571 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
1572 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04001573 return false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001574 }
1575
David Benjamin9d64d8d2022-08-31 19:27:56 -04001576 // |protocol_name_list| fits in |unsigned| because TLS extensions use 16-bit
1577 // lengths.
Adam Langleyf18e4532015-07-10 13:39:53 -07001578 const uint8_t *selected;
1579 uint8_t selected_len;
David Benjaminc02c19e2021-02-10 17:49:20 -05001580 int ret = ssl->ctx->alpn_select_cb(
1581 ssl, &selected, &selected_len, CBS_data(&protocol_name_list),
David Benjamin9d64d8d2022-08-31 19:27:56 -04001582 static_cast<unsigned>(CBS_len(&protocol_name_list)),
1583 ssl->ctx->alpn_select_cb_arg);
David Benjaminc02c19e2021-02-10 17:49:20 -05001584 // ALPN is required when QUIC is used.
1585 if (ssl->quic_method &&
1586 (ret == SSL_TLSEXT_ERR_NOACK || ret == SSL_TLSEXT_ERR_ALERT_WARNING)) {
1587 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
1588 }
1589 switch (ret) {
1590 case SSL_TLSEXT_ERR_OK:
1591 if (selected_len == 0) {
1592 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
1593 *out_alert = SSL_AD_INTERNAL_ERROR;
1594 return false;
1595 }
1596 if (!ssl->s3->alpn_selected.CopyFrom(
1597 MakeConstSpan(selected, selected_len))) {
1598 *out_alert = SSL_AD_INTERNAL_ERROR;
1599 return false;
1600 }
1601 break;
1602 case SSL_TLSEXT_ERR_NOACK:
1603 case SSL_TLSEXT_ERR_ALERT_WARNING:
1604 break;
1605 case SSL_TLSEXT_ERR_ALERT_FATAL:
1606 *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL;
1607 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
David Benjaminfa544f12018-05-15 15:06:28 -04001608 return false;
David Benjaminc02c19e2021-02-10 17:49:20 -05001609 default:
1610 // Invalid return value.
Adam Langleyf18e4532015-07-10 13:39:53 -07001611 *out_alert = SSL_AD_INTERNAL_ERROR;
David Benjaminc02c19e2021-02-10 17:49:20 -05001612 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin31640932017-10-11 13:22:39 -04001613 return false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001614 }
1615
David Benjamin31640932017-10-11 13:22:39 -04001616 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001617}
1618
David Benjamin31640932017-10-11 13:22:39 -04001619static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001620 SSL *const ssl = hs->ssl;
David Benjamin8e7bbba2017-10-13 17:18:35 -04001621 if (ssl->s3->alpn_selected.empty()) {
David Benjamin31640932017-10-11 13:22:39 -04001622 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001623 }
1624
1625 CBB contents, proto_list, proto;
1626 if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
1627 !CBB_add_u16_length_prefixed(out, &contents) ||
1628 !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
1629 !CBB_add_u8_length_prefixed(&proto_list, &proto) ||
David Benjamin8e7bbba2017-10-13 17:18:35 -04001630 !CBB_add_bytes(&proto, ssl->s3->alpn_selected.data(),
1631 ssl->s3->alpn_selected.size()) ||
Adam Langleyf18e4532015-07-10 13:39:53 -07001632 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04001633 return false;
Adam Langleyf18e4532015-07-10 13:39:53 -07001634 }
1635
David Benjamin31640932017-10-11 13:22:39 -04001636 return true;
Adam Langleyf18e4532015-07-10 13:39:53 -07001637}
1638
1639
David Benjaminc11ea9422017-08-29 16:33:21 -04001640// Channel ID.
1641//
1642// https://tools.ietf.org/html/draft-balfanz-tls-channelid-01
Adam Langley49c7af12015-07-10 14:33:46 -07001643
David Benjamin83a49932021-05-20 15:57:09 -04001644static bool ext_channel_id_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1645 CBB *out_compressible,
1646 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04001647 const SSL *const ssl = hs->ssl;
David Benjaminba423c92021-06-15 16:26:58 -04001648 if (!hs->config->channel_id_private || SSL_is_dtls(ssl) ||
1649 // Don't offer Channel ID in ClientHelloOuter. ClientHelloOuter handshakes
1650 // are not authenticated for the name that can learn the Channel ID.
1651 //
1652 // We could alternatively offer the extension but sign with a random key.
1653 // For other extensions, we try to align |ssl_client_hello_outer| and
1654 // |ssl_client_hello_unencrypted|, to improve the effectiveness of ECH
1655 // GREASE. However, Channel ID is deprecated and unlikely to be used with
1656 // ECH, so do the simplest thing.
1657 type == ssl_client_hello_outer) {
David Benjamin31640932017-10-11 13:22:39 -04001658 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001659 }
1660
David Benjaminba423c92021-06-15 16:26:58 -04001661 if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
1662 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -04001663 return false;
Adam Langley49c7af12015-07-10 14:33:46 -07001664 }
1665
David Benjamin31640932017-10-11 13:22:39 -04001666 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001667}
1668
David Benjamin31640932017-10-11 13:22:39 -04001669static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
1670 uint8_t *out_alert,
1671 CBS *contents) {
Adam Langley49c7af12015-07-10 14:33:46 -07001672 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001673 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001674 }
1675
David Benjamin8acec002021-05-19 13:03:34 -04001676 assert(!SSL_is_dtls(hs->ssl));
David Benjaminb5879112021-05-18 17:10:18 -04001677 assert(hs->config->channel_id_private);
Adam Langley49c7af12015-07-10 14:33:46 -07001678
1679 if (CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001680 return false;
Adam Langley49c7af12015-07-10 14:33:46 -07001681 }
1682
David Benjamin8acec002021-05-19 13:03:34 -04001683 hs->channel_id_negotiated = true;
David Benjamin31640932017-10-11 13:22:39 -04001684 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001685}
1686
David Benjamin31640932017-10-11 13:22:39 -04001687static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
1688 uint8_t *out_alert,
1689 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001690 SSL *const ssl = hs->ssl;
David Benjamin46853762018-07-03 14:01:26 -04001691 if (contents == NULL || !hs->config->channel_id_enabled || SSL_is_dtls(ssl)) {
David Benjamin31640932017-10-11 13:22:39 -04001692 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001693 }
1694
1695 if (CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001696 return false;
Adam Langley49c7af12015-07-10 14:33:46 -07001697 }
1698
David Benjamin8acec002021-05-19 13:03:34 -04001699 hs->channel_id_negotiated = true;
David Benjamin31640932017-10-11 13:22:39 -04001700 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001701}
1702
David Benjamin31640932017-10-11 13:22:39 -04001703static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8acec002021-05-19 13:03:34 -04001704 if (!hs->channel_id_negotiated) {
David Benjamin31640932017-10-11 13:22:39 -04001705 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001706 }
1707
1708 if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
1709 !CBB_add_u16(out, 0 /* length */)) {
David Benjamin31640932017-10-11 13:22:39 -04001710 return false;
Adam Langley49c7af12015-07-10 14:33:46 -07001711 }
1712
David Benjamin31640932017-10-11 13:22:39 -04001713 return true;
Adam Langley49c7af12015-07-10 14:33:46 -07001714}
1715
Adam Langley391250d2015-07-15 19:06:07 -07001716
David Benjaminc11ea9422017-08-29 16:33:21 -04001717// Secure Real-time Transport Protocol (SRTP) extension.
1718//
1719// https://tools.ietf.org/html/rfc5764
Adam Langley391250d2015-07-15 19:06:07 -07001720
David Benjamin83a49932021-05-20 15:57:09 -04001721static bool ext_srtp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1722 CBB *out_compressible,
1723 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04001724 const SSL *const ssl = hs->ssl;
David Benjaminb778b9c2021-05-20 11:31:05 -04001725 const STACK_OF(SRTP_PROTECTION_PROFILE) *profiles =
1726 SSL_get_srtp_profiles(ssl);
David Benjaminee910bf2017-07-25 22:36:00 -04001727 if (profiles == NULL ||
David Benjaminbc4c91a2021-05-18 16:06:30 -04001728 sk_SRTP_PROTECTION_PROFILE_num(profiles) == 0 ||
1729 !SSL_is_dtls(ssl)) {
David Benjamin31640932017-10-11 13:22:39 -04001730 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001731 }
1732
1733 CBB contents, profile_ids;
David Benjamin83a49932021-05-20 15:57:09 -04001734 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_srtp) ||
1735 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
Adam Langley391250d2015-07-15 19:06:07 -07001736 !CBB_add_u16_length_prefixed(&contents, &profile_ids)) {
David Benjamin31640932017-10-11 13:22:39 -04001737 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001738 }
1739
David Benjaminee910bf2017-07-25 22:36:00 -04001740 for (const SRTP_PROTECTION_PROFILE *profile : profiles) {
1741 if (!CBB_add_u16(&profile_ids, profile->id)) {
David Benjamin31640932017-10-11 13:22:39 -04001742 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001743 }
1744 }
1745
1746 if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) ||
David Benjamin83a49932021-05-20 15:57:09 -04001747 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04001748 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001749 }
1750
David Benjamin31640932017-10-11 13:22:39 -04001751 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001752}
1753
David Benjamin31640932017-10-11 13:22:39 -04001754static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1755 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001756 SSL *const ssl = hs->ssl;
Adam Langley391250d2015-07-15 19:06:07 -07001757 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001758 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001759 }
1760
David Benjaminc11ea9422017-08-29 16:33:21 -04001761 // The extension consists of a u16-prefixed profile ID list containing a
1762 // single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
1763 //
1764 // See https://tools.ietf.org/html/rfc5764#section-4.1.1
David Benjaminbc4c91a2021-05-18 16:06:30 -04001765 assert(SSL_is_dtls(ssl));
Adam Langley391250d2015-07-15 19:06:07 -07001766 CBS profile_ids, srtp_mki;
1767 uint16_t profile_id;
1768 if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
1769 !CBS_get_u16(&profile_ids, &profile_id) ||
1770 CBS_len(&profile_ids) != 0 ||
1771 !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
1772 CBS_len(contents) != 0) {
1773 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
David Benjamin31640932017-10-11 13:22:39 -04001774 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001775 }
1776
1777 if (CBS_len(&srtp_mki) != 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001778 // Must be no MKI, since we never offer one.
Adam Langley391250d2015-07-15 19:06:07 -07001779 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE);
1780 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -04001781 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001782 }
1783
David Benjaminb778b9c2021-05-20 11:31:05 -04001784 // Check to see if the server gave us something we support and offered.
1785 for (const SRTP_PROTECTION_PROFILE *profile : SSL_get_srtp_profiles(ssl)) {
Adam Langley391250d2015-07-15 19:06:07 -07001786 if (profile->id == profile_id) {
David Benjaminfceca8e2018-04-12 16:37:19 -04001787 ssl->s3->srtp_profile = profile;
David Benjamin31640932017-10-11 13:22:39 -04001788 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001789 }
1790 }
1791
1792 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
1793 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -04001794 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001795}
1796
David Benjamin31640932017-10-11 13:22:39 -04001797static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1798 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05001799 SSL *const ssl = hs->ssl;
David Benjaminbc4c91a2021-05-18 16:06:30 -04001800 // DTLS-SRTP is only defined for DTLS.
1801 if (contents == NULL || !SSL_is_dtls(ssl)) {
David Benjamin31640932017-10-11 13:22:39 -04001802 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001803 }
1804
1805 CBS profile_ids, srtp_mki;
1806 if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
1807 CBS_len(&profile_ids) < 2 ||
1808 !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
1809 CBS_len(contents) != 0) {
1810 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
David Benjamin31640932017-10-11 13:22:39 -04001811 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001812 }
David Benjaminc11ea9422017-08-29 16:33:21 -04001813 // Discard the MKI value for now.
Adam Langley391250d2015-07-15 19:06:07 -07001814
1815 const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles =
1816 SSL_get_srtp_profiles(ssl);
1817
David Benjaminc11ea9422017-08-29 16:33:21 -04001818 // Pick the server's most preferred profile.
David Benjaminee910bf2017-07-25 22:36:00 -04001819 for (const SRTP_PROTECTION_PROFILE *server_profile : server_profiles) {
Adam Langley391250d2015-07-15 19:06:07 -07001820 CBS profile_ids_tmp;
1821 CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids));
1822
1823 while (CBS_len(&profile_ids_tmp) > 0) {
1824 uint16_t profile_id;
1825 if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) {
David Benjamin31640932017-10-11 13:22:39 -04001826 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001827 }
1828
1829 if (server_profile->id == profile_id) {
David Benjaminfceca8e2018-04-12 16:37:19 -04001830 ssl->s3->srtp_profile = server_profile;
David Benjamin31640932017-10-11 13:22:39 -04001831 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001832 }
1833 }
1834 }
1835
David Benjamin31640932017-10-11 13:22:39 -04001836 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001837}
1838
David Benjamin31640932017-10-11 13:22:39 -04001839static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001840 SSL *const ssl = hs->ssl;
David Benjaminfceca8e2018-04-12 16:37:19 -04001841 if (ssl->s3->srtp_profile == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001842 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001843 }
1844
David Benjaminbc4c91a2021-05-18 16:06:30 -04001845 assert(SSL_is_dtls(ssl));
Adam Langley391250d2015-07-15 19:06:07 -07001846 CBB contents, profile_ids;
1847 if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
1848 !CBB_add_u16_length_prefixed(out, &contents) ||
1849 !CBB_add_u16_length_prefixed(&contents, &profile_ids) ||
David Benjaminfceca8e2018-04-12 16:37:19 -04001850 !CBB_add_u16(&profile_ids, ssl->s3->srtp_profile->id) ||
Adam Langley391250d2015-07-15 19:06:07 -07001851 !CBB_add_u8(&contents, 0 /* empty MKI */) ||
1852 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04001853 return false;
Adam Langley391250d2015-07-15 19:06:07 -07001854 }
1855
David Benjamin31640932017-10-11 13:22:39 -04001856 return true;
Adam Langley391250d2015-07-15 19:06:07 -07001857}
1858
Adam Langleybdd5d662015-07-20 16:19:08 -07001859
David Benjaminc11ea9422017-08-29 16:33:21 -04001860// EC point formats.
1861//
1862// https://tools.ietf.org/html/rfc4492#section-5.1.2
Adam Langleybdd5d662015-07-20 16:19:08 -07001863
David Benjamin14e51ad2021-05-19 15:24:34 -04001864static bool ext_ec_point_add_extension(const SSL_HANDSHAKE *hs, CBB *out) {
David Benjaminfc059942015-07-30 23:01:59 -04001865 CBB contents, formats;
Adam Langleybdd5d662015-07-20 16:19:08 -07001866 if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
1867 !CBB_add_u16_length_prefixed(out, &contents) ||
David Benjaminfc059942015-07-30 23:01:59 -04001868 !CBB_add_u8_length_prefixed(&contents, &formats) ||
1869 !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) ||
Adam Langleybdd5d662015-07-20 16:19:08 -07001870 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04001871 return false;
Adam Langleybdd5d662015-07-20 16:19:08 -07001872 }
1873
David Benjamin31640932017-10-11 13:22:39 -04001874 return true;
Adam Langleybdd5d662015-07-20 16:19:08 -07001875}
1876
David Benjamin83a49932021-05-20 15:57:09 -04001877static bool ext_ec_point_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
1878 CBB *out_compressible,
1879 ssl_client_hello_type_t type) {
Adam Langleyffe384c2019-05-01 11:13:12 -07001880 // The point format extension is unnecessary in TLS 1.3.
David Benjamin83a49932021-05-20 15:57:09 -04001881 if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner) {
David Benjamin31640932017-10-11 13:22:39 -04001882 return true;
David Benjamin70aba262016-11-01 12:08:15 -04001883 }
1884
David Benjamin8c880a22016-12-03 02:20:34 -05001885 return ext_ec_point_add_extension(hs, out);
Adam Langleybdd5d662015-07-20 16:19:08 -07001886}
1887
David Benjamin31640932017-10-11 13:22:39 -04001888static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
1889 CBS *contents) {
Adam Langleybdd5d662015-07-20 16:19:08 -07001890 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04001891 return true;
Adam Langleybdd5d662015-07-20 16:19:08 -07001892 }
1893
David Benjamind1e3ce12017-10-06 18:31:15 -04001894 if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001895 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04001896 }
1897
Adam Langleybdd5d662015-07-20 16:19:08 -07001898 CBS ec_point_format_list;
1899 if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) ||
1900 CBS_len(contents) != 0) {
David Benjamin31640932017-10-11 13:22:39 -04001901 return false;
Adam Langleybdd5d662015-07-20 16:19:08 -07001902 }
1903
David Benjaminc11ea9422017-08-29 16:33:21 -04001904 // Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed
1905 // point format.
David Benjamin17cf2cb2016-12-13 01:07:13 -05001906 if (OPENSSL_memchr(CBS_data(&ec_point_format_list),
1907 TLSEXT_ECPOINTFORMAT_uncompressed,
1908 CBS_len(&ec_point_format_list)) == NULL) {
David Benjaminfc059942015-07-30 23:01:59 -04001909 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -04001910 return false;
Adam Langleybdd5d662015-07-20 16:19:08 -07001911 }
1912
David Benjamin31640932017-10-11 13:22:39 -04001913 return true;
Adam Langleybdd5d662015-07-20 16:19:08 -07001914}
1915
David Benjamin31640932017-10-11 13:22:39 -04001916static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
Adam Langleybdd5d662015-07-20 16:19:08 -07001917 CBS *contents) {
David Benjamind1e3ce12017-10-06 18:31:15 -04001918 if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001919 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04001920 }
1921
David Benjamin8c880a22016-12-03 02:20:34 -05001922 return ext_ec_point_parse_serverhello(hs, out_alert, contents);
Adam Langleybdd5d662015-07-20 16:19:08 -07001923}
1924
David Benjamin31640932017-10-11 13:22:39 -04001925static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05001926 SSL *const ssl = hs->ssl;
David Benjamind1e3ce12017-10-06 18:31:15 -04001927 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04001928 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04001929 }
1930
David Benjamin45738dd2017-02-09 20:01:26 -05001931 const uint32_t alg_k = hs->new_cipher->algorithm_mkey;
1932 const uint32_t alg_a = hs->new_cipher->algorithm_auth;
David Benjamin31640932017-10-11 13:22:39 -04001933 const bool using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
Adam Langleybdd5d662015-07-20 16:19:08 -07001934
1935 if (!using_ecc) {
David Benjamin31640932017-10-11 13:22:39 -04001936 return true;
Adam Langleybdd5d662015-07-20 16:19:08 -07001937 }
1938
David Benjamin8c880a22016-12-03 02:20:34 -05001939 return ext_ec_point_add_extension(hs, out);
Adam Langleybdd5d662015-07-20 16:19:08 -07001940}
1941
Steven Valdeza833c352016-11-01 13:39:36 -04001942
David Benjaminc11ea9422017-08-29 16:33:21 -04001943// Pre Shared Key
1944//
David Benjamina130ce02018-08-14 22:26:39 -05001945// https://tools.ietf.org/html/rfc8446#section-4.2.11
Steven Valdez4aa154e2016-07-29 14:32:55 -04001946
David Benjamin83a49932021-05-20 15:57:09 -04001947static bool should_offer_psk(const SSL_HANDSHAKE *hs,
1948 ssl_client_hello_type_t type) {
David Benjamin350fe3b2021-06-02 17:58:53 -04001949 const SSL *const ssl = hs->ssl;
David Benjamin50596f82018-07-02 19:47:27 -04001950 if (hs->max_version < TLS1_3_VERSION || ssl->session == nullptr ||
David Benjamin83a49932021-05-20 15:57:09 -04001951 ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION ||
David Benjamin18b68362021-06-18 23:13:46 -04001952 // TODO(https://crbug.com/boringssl/275): Should we synthesize a
1953 // placeholder PSK, at least when we offer early data? Otherwise
1954 // ClientHelloOuter will contain an early_data extension without a
1955 // pre_shared_key extension and potentially break the recovery flow.
David Benjamin83a49932021-05-20 15:57:09 -04001956 type == ssl_client_hello_outer) {
David Benjamin350fe3b2021-06-02 17:58:53 -04001957 return false;
1958 }
1959
1960 // Per RFC 8446 section 4.1.4, skip offering the session if the selected
1961 // cipher in HelloRetryRequest does not match. This avoids performing the
1962 // transcript hash transformation for multiple hashes.
1963 if (ssl->s3->used_hello_retry_request &&
1964 ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) {
1965 return false;
1966 }
1967
1968 return true;
1969}
1970
David Benjamin83a49932021-05-20 15:57:09 -04001971static size_t ext_pre_shared_key_clienthello_length(
1972 const SSL_HANDSHAKE *hs, ssl_client_hello_type_t type) {
David Benjamin350fe3b2021-06-02 17:58:53 -04001973 const SSL *const ssl = hs->ssl;
David Benjamin83a49932021-05-20 15:57:09 -04001974 if (!should_offer_psk(hs, type)) {
Steven Valdeza833c352016-11-01 13:39:36 -04001975 return 0;
1976 }
1977
David Benjamin50596f82018-07-02 19:47:27 -04001978 size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session.get()));
David Benjaminbfdd1a92018-06-29 16:26:38 -04001979 return 15 + ssl->session->ticket.size() + binder_len;
Steven Valdeza833c352016-11-01 13:39:36 -04001980}
1981
David Benjamin5acf9f42021-05-24 14:23:38 -04001982static bool ext_pre_shared_key_add_clienthello(const SSL_HANDSHAKE *hs,
David Benjamin83a49932021-05-20 15:57:09 -04001983 CBB *out, bool *out_needs_binder,
1984 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04001985 const SSL *const ssl = hs->ssl;
David Benjamin5acf9f42021-05-24 14:23:38 -04001986 *out_needs_binder = false;
David Benjamin83a49932021-05-20 15:57:09 -04001987 if (!should_offer_psk(hs, type)) {
Steven Valdezcd8470f2017-10-11 12:29:36 -04001988 return true;
1989 }
1990
David Benjaminad8f5e12017-02-20 17:00:20 -05001991 struct OPENSSL_timeval now;
Steven Valdeza833c352016-11-01 13:39:36 -04001992 ssl_get_current_time(ssl, &now);
1993 uint32_t ticket_age = 1000 * (now.tv_sec - ssl->session->time);
1994 uint32_t obfuscated_ticket_age = ticket_age + ssl->session->ticket_age_add;
1995
David Benjaminc11ea9422017-08-29 16:33:21 -04001996 // Fill in a placeholder zero binder of the appropriate length. It will be
1997 // computed and filled in later after length prefixes are computed.
David Benjamin50596f82018-07-02 19:47:27 -04001998 size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session.get()));
Steven Valdeza833c352016-11-01 13:39:36 -04001999
2000 CBB contents, identity, ticket, binders, binder;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002001 if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
2002 !CBB_add_u16_length_prefixed(out, &contents) ||
Steven Valdez5b986082016-09-01 12:29:49 -04002003 !CBB_add_u16_length_prefixed(&contents, &identity) ||
Steven Valdez5b986082016-09-01 12:29:49 -04002004 !CBB_add_u16_length_prefixed(&identity, &ticket) ||
David Benjaminbfdd1a92018-06-29 16:26:38 -04002005 !CBB_add_bytes(&ticket, ssl->session->ticket.data(),
2006 ssl->session->ticket.size()) ||
Steven Valdeza833c352016-11-01 13:39:36 -04002007 !CBB_add_u32(&identity, obfuscated_ticket_age) ||
2008 !CBB_add_u16_length_prefixed(&contents, &binders) ||
2009 !CBB_add_u8_length_prefixed(&binders, &binder) ||
David Benjamin95450622021-07-16 18:24:02 -04002010 !CBB_add_zeros(&binder, binder_len)) {
David Benjamin31640932017-10-11 13:22:39 -04002011 return false;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002012 }
2013
David Benjamin5acf9f42021-05-24 14:23:38 -04002014 *out_needs_binder = true;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002015 return CBB_flush(out);
2016}
2017
David Benjamin31640932017-10-11 13:22:39 -04002018bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
2019 uint8_t *out_alert,
2020 CBS *contents) {
Steven Valdez4aa154e2016-07-29 14:32:55 -04002021 uint16_t psk_id;
2022 if (!CBS_get_u16(contents, &psk_id) ||
2023 CBS_len(contents) != 0) {
David Benjamin7f78df42016-10-05 22:33:19 -04002024 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
Steven Valdez4aa154e2016-07-29 14:32:55 -04002025 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002026 return false;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002027 }
2028
David Benjaminc11ea9422017-08-29 16:33:21 -04002029 // We only advertise one PSK identity, so the only legal index is zero.
Steven Valdez4aa154e2016-07-29 14:32:55 -04002030 if (psk_id != 0) {
David Benjamin7f78df42016-10-05 22:33:19 -04002031 OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
Steven Valdez4aa154e2016-07-29 14:32:55 -04002032 *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY;
David Benjamin31640932017-10-11 13:22:39 -04002033 return false;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002034 }
2035
David Benjamin31640932017-10-11 13:22:39 -04002036 return true;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002037}
2038
David Benjamin31640932017-10-11 13:22:39 -04002039bool ssl_ext_pre_shared_key_parse_clienthello(
David Benjamin707af292017-03-10 17:47:18 -05002040 SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders,
David Benjamin9806ae02019-08-16 15:32:03 -04002041 uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert,
2042 const SSL_CLIENT_HELLO *client_hello, CBS *contents) {
2043 // Verify that the pre_shared_key extension is the last extension in
2044 // ClientHello.
2045 if (CBS_data(contents) + CBS_len(contents) !=
2046 client_hello->extensions + client_hello->extensions_len) {
2047 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
2048 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
2049 return false;
2050 }
2051
David Benjaminc11ea9422017-08-29 16:33:21 -04002052 // We only process the first PSK identity since we don't support pure PSK.
David Benjamin707af292017-03-10 17:47:18 -05002053 CBS identities, binders;
David Benjaminaedf3032016-12-01 16:47:56 -05002054 if (!CBS_get_u16_length_prefixed(contents, &identities) ||
David Benjamin707af292017-03-10 17:47:18 -05002055 !CBS_get_u16_length_prefixed(&identities, out_ticket) ||
David Benjamin35ac5b72017-03-03 15:05:56 -05002056 !CBS_get_u32(&identities, out_obfuscated_ticket_age) ||
Steven Valdeza833c352016-11-01 13:39:36 -04002057 !CBS_get_u16_length_prefixed(contents, &binders) ||
David Benjaminaedf3032016-12-01 16:47:56 -05002058 CBS_len(&binders) == 0 ||
Steven Valdezaf3b8a92016-11-01 12:49:22 -04002059 CBS_len(contents) != 0) {
Steven Valdeza833c352016-11-01 13:39:36 -04002060 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
Steven Valdez4aa154e2016-07-29 14:32:55 -04002061 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002062 return false;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002063 }
2064
Steven Valdeza833c352016-11-01 13:39:36 -04002065 *out_binders = binders;
2066
David Benjaminc11ea9422017-08-29 16:33:21 -04002067 // Check the syntax of the remaining identities, but do not process them.
David Benjaminaedf3032016-12-01 16:47:56 -05002068 size_t num_identities = 1;
2069 while (CBS_len(&identities) != 0) {
2070 CBS unused_ticket;
2071 uint32_t unused_obfuscated_ticket_age;
2072 if (!CBS_get_u16_length_prefixed(&identities, &unused_ticket) ||
2073 !CBS_get_u32(&identities, &unused_obfuscated_ticket_age)) {
2074 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
2075 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002076 return false;
David Benjaminaedf3032016-12-01 16:47:56 -05002077 }
2078
2079 num_identities++;
2080 }
2081
David Benjaminc11ea9422017-08-29 16:33:21 -04002082 // Check the syntax of the binders. The value will be checked later if
2083 // resuming.
David Benjaminaedf3032016-12-01 16:47:56 -05002084 size_t num_binders = 0;
2085 while (CBS_len(&binders) != 0) {
2086 CBS binder;
2087 if (!CBS_get_u8_length_prefixed(&binders, &binder)) {
2088 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
2089 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002090 return false;
David Benjaminaedf3032016-12-01 16:47:56 -05002091 }
2092
2093 num_binders++;
2094 }
2095
2096 if (num_identities != num_binders) {
2097 OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH);
2098 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -04002099 return false;
Steven Valdez5b986082016-09-01 12:29:49 -04002100 }
2101
David Benjamin31640932017-10-11 13:22:39 -04002102 return true;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002103}
2104
David Benjamin31640932017-10-11 13:22:39 -04002105bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8baf9632016-11-17 17:11:16 +09002106 if (!hs->ssl->s3->session_reused) {
David Benjamin31640932017-10-11 13:22:39 -04002107 return true;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002108 }
2109
2110 CBB contents;
2111 if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
2112 !CBB_add_u16_length_prefixed(out, &contents) ||
David Benjaminc11ea9422017-08-29 16:33:21 -04002113 // We only consider the first identity for resumption
Steven Valdez4aa154e2016-07-29 14:32:55 -04002114 !CBB_add_u16(&contents, 0) ||
2115 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04002116 return false;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002117 }
2118
David Benjamin31640932017-10-11 13:22:39 -04002119 return true;
Steven Valdez4aa154e2016-07-29 14:32:55 -04002120}
2121
2122
David Benjaminc11ea9422017-08-29 16:33:21 -04002123// Pre-Shared Key Exchange Modes
2124//
David Benjamina130ce02018-08-14 22:26:39 -05002125// https://tools.ietf.org/html/rfc8446#section-4.2.9
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002126
David Benjamin83a49932021-05-20 15:57:09 -04002127static bool ext_psk_key_exchange_modes_add_clienthello(
2128 const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
2129 ssl_client_hello_type_t type) {
David Benjamin68161cb2017-06-20 14:49:43 -04002130 if (hs->max_version < TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04002131 return true;
Steven Valdeza833c352016-11-01 13:39:36 -04002132 }
2133
2134 CBB contents, ke_modes;
David Benjamin83a49932021-05-20 15:57:09 -04002135 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_psk_key_exchange_modes) ||
2136 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
Steven Valdeza833c352016-11-01 13:39:36 -04002137 !CBB_add_u8_length_prefixed(&contents, &ke_modes) ||
2138 !CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE)) {
David Benjamin31640932017-10-11 13:22:39 -04002139 return false;
Steven Valdeza833c352016-11-01 13:39:36 -04002140 }
2141
David Benjamin83a49932021-05-20 15:57:09 -04002142 return CBB_flush(out_compressible);
Steven Valdeza833c352016-11-01 13:39:36 -04002143}
2144
David Benjamin31640932017-10-11 13:22:39 -04002145static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
2146 uint8_t *out_alert,
2147 CBS *contents) {
David Benjamin4eb95cc2016-11-16 17:08:23 +09002148 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04002149 return true;
David Benjamin4eb95cc2016-11-16 17:08:23 +09002150 }
2151
Steven Valdeza833c352016-11-01 13:39:36 -04002152 CBS ke_modes;
2153 if (!CBS_get_u8_length_prefixed(contents, &ke_modes) ||
2154 CBS_len(&ke_modes) == 0 ||
2155 CBS_len(contents) != 0) {
2156 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002157 return false;
Steven Valdeza833c352016-11-01 13:39:36 -04002158 }
2159
David Benjaminc11ea9422017-08-29 16:33:21 -04002160 // We only support tickets with PSK_DHE_KE.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002161 hs->accept_psk_mode = OPENSSL_memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE,
2162 CBS_len(&ke_modes)) != NULL;
Steven Valdeza833c352016-11-01 13:39:36 -04002163
David Benjamin31640932017-10-11 13:22:39 -04002164 return true;
Steven Valdeza833c352016-11-01 13:39:36 -04002165}
2166
2167
David Benjaminc11ea9422017-08-29 16:33:21 -04002168// Early Data Indication
2169//
David Benjamina130ce02018-08-14 22:26:39 -05002170// https://tools.ietf.org/html/rfc8446#section-4.2.10
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002171
David Benjamin83a49932021-05-20 15:57:09 -04002172static bool ext_early_data_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
2173 CBB *out_compressible,
2174 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04002175 const SSL *const ssl = hs->ssl;
David Benjamin64770122019-05-04 11:00:04 -05002176 // The second ClientHello never offers early data, and we must have already
2177 // filled in |early_data_reason| by this point.
Kris Kwiatkowskib11902a2019-08-24 11:01:04 +01002178 if (ssl->s3->used_hello_retry_request) {
David Benjamin64770122019-05-04 11:00:04 -05002179 assert(ssl->s3->early_data_reason != ssl_early_data_unknown);
David Benjamin31640932017-10-11 13:22:39 -04002180 return true;
Steven Valdez2d850622017-01-11 11:34:52 -05002181 }
2182
David Benjamin4e93cd42021-05-18 13:38:25 -04002183 if (!hs->early_data_offered) {
David Benjamin64770122019-05-04 11:00:04 -05002184 return true;
2185 }
2186
David Benjamin83a49932021-05-20 15:57:09 -04002187 // If offering ECH, the extension only applies to ClientHelloInner, but we
2188 // send the extension in both ClientHellos. This ensures that, if the server
2189 // handshakes with ClientHelloOuter, it can skip past early data. See
David Benjamin0fa30302021-09-03 17:23:28 -04002190 // draft-ietf-tls-esni-13, section 6.1.
David Benjamin83a49932021-05-20 15:57:09 -04002191 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_early_data) ||
2192 !CBB_add_u16(out_compressible, 0) ||
2193 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04002194 return false;
Steven Valdez2d850622017-01-11 11:34:52 -05002195 }
2196
David Benjamin31640932017-10-11 13:22:39 -04002197 return true;
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002198}
2199
David Benjamin31640932017-10-11 13:22:39 -04002200static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
David Benjamin64770122019-05-04 11:00:04 -05002201 uint8_t *out_alert,
2202 CBS *contents) {
David Benjamin8c880a22016-12-03 02:20:34 -05002203 SSL *const ssl = hs->ssl;
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002204 if (contents == NULL) {
Kris Kwiatkowskib11902a2019-08-24 11:01:04 +01002205 if (hs->early_data_offered && !ssl->s3->used_hello_retry_request) {
David Benjamin64770122019-05-04 11:00:04 -05002206 ssl->s3->early_data_reason = ssl->s3->session_reused
2207 ? ssl_early_data_peer_declined
2208 : ssl_early_data_session_not_resumed;
2209 } else {
2210 // We already filled in |early_data_reason| when declining to offer 0-RTT
2211 // or handling the implicit HelloRetryRequest reject.
2212 assert(ssl->s3->early_data_reason != ssl_early_data_unknown);
2213 }
David Benjamin31640932017-10-11 13:22:39 -04002214 return true;
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002215 }
2216
David Benjamin64770122019-05-04 11:00:04 -05002217 // If we received an HRR, the second ClientHello never offers early data, so
2218 // the extensions logic will automatically reject early data extensions as
2219 // unsolicited. This covered by the ServerAcceptsEarlyDataOnHRR test.
Kris Kwiatkowskib11902a2019-08-24 11:01:04 +01002220 assert(!ssl->s3->used_hello_retry_request);
David Benjamin64770122019-05-04 11:00:04 -05002221
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002222 if (CBS_len(contents) != 0) {
2223 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002224 return false;
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002225 }
2226
Steven Valdez2d850622017-01-11 11:34:52 -05002227 if (!ssl->s3->session_reused) {
2228 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
2229 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
David Benjamin31640932017-10-11 13:22:39 -04002230 return false;
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002231 }
Steven Valdez2d850622017-01-11 11:34:52 -05002232
David Benjamin64770122019-05-04 11:00:04 -05002233 ssl->s3->early_data_reason = ssl_early_data_accepted;
David Benjamin02e62562017-12-18 18:04:01 -05002234 ssl->s3->early_data_accepted = true;
David Benjamin31640932017-10-11 13:22:39 -04002235 return true;
Steven Valdez2d850622017-01-11 11:34:52 -05002236}
2237
David Benjamin31640932017-10-11 13:22:39 -04002238static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
2239 uint8_t *out_alert, CBS *contents) {
Steven Valdez2d850622017-01-11 11:34:52 -05002240 SSL *const ssl = hs->ssl;
2241 if (contents == NULL ||
David Benjamind1e3ce12017-10-06 18:31:15 -04002242 ssl_protocol_version(ssl) < TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04002243 return true;
Steven Valdez2d850622017-01-11 11:34:52 -05002244 }
2245
2246 if (CBS_len(contents) != 0) {
2247 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002248 return false;
Steven Valdez2d850622017-01-11 11:34:52 -05002249 }
2250
David Benjaminfd45ee72017-08-31 14:49:09 -04002251 hs->early_data_offered = true;
David Benjamin31640932017-10-11 13:22:39 -04002252 return true;
Steven Valdez2d850622017-01-11 11:34:52 -05002253}
2254
David Benjamin31640932017-10-11 13:22:39 -04002255static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin02e62562017-12-18 18:04:01 -05002256 if (!hs->ssl->s3->early_data_accepted) {
David Benjamin31640932017-10-11 13:22:39 -04002257 return true;
Steven Valdez2d850622017-01-11 11:34:52 -05002258 }
2259
2260 if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) ||
2261 !CBB_add_u16(out, 0) ||
2262 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04002263 return false;
Steven Valdez2d850622017-01-11 11:34:52 -05002264 }
2265
David Benjamin31640932017-10-11 13:22:39 -04002266 return true;
Steven Valdeza4ee74d2016-11-29 13:36:45 -05002267}
2268
2269
David Benjaminc11ea9422017-08-29 16:33:21 -04002270// Key Share
2271//
David Benjamina130ce02018-08-14 22:26:39 -05002272// https://tools.ietf.org/html/rfc8446#section-4.2.8
Steven Valdez143e8b32016-07-11 13:19:03 -04002273
David Benjamin97ede402021-05-18 14:17:52 -04002274bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) {
David Benjamin8c880a22016-12-03 02:20:34 -05002275 SSL *const ssl = hs->ssl;
David Benjamin97ede402021-05-18 14:17:52 -04002276 hs->key_shares[0].reset();
2277 hs->key_shares[1].reset();
2278 hs->key_share_bytes.Reset();
2279
David Benjamin68161cb2017-06-20 14:49:43 -04002280 if (hs->max_version < TLS1_3_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04002281 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04002282 }
2283
David Benjamin97ede402021-05-18 14:17:52 -04002284 bssl::ScopedCBB cbb;
2285 if (!CBB_init(cbb.get(), 64)) {
David Benjamin31640932017-10-11 13:22:39 -04002286 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002287 }
2288
David Benjamin97ede402021-05-18 14:17:52 -04002289 if (override_group_id == 0 && ssl->ctx->grease_enabled) {
David Benjamin3675eb32021-05-18 14:01:07 -04002290 // Add a fake group. See RFC 8701.
David Benjamin97ede402021-05-18 14:17:52 -04002291 if (!CBB_add_u16(cbb.get(), ssl_get_grease_value(hs, ssl_grease_group)) ||
2292 !CBB_add_u16(cbb.get(), 1 /* length */) ||
2293 !CBB_add_u8(cbb.get(), 0 /* one byte key share */)) {
David Benjamin31640932017-10-11 13:22:39 -04002294 return false;
David Benjamin65ac9972016-09-02 21:35:25 -04002295 }
David Benjamin97ede402021-05-18 14:17:52 -04002296 }
David Benjamin65ac9972016-09-02 21:35:25 -04002297
David Benjamin97ede402021-05-18 14:17:52 -04002298 uint16_t group_id = override_group_id;
2299 uint16_t second_group_id = 0;
2300 if (override_group_id == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -04002301 // Predict the most preferred group.
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002302 Span<const uint16_t> groups = tls1_get_grouplist(hs);
David Benjaminb9493552017-09-27 19:02:51 -04002303 if (groups.empty()) {
David Benjaminc8b6b4f2016-09-08 23:47:48 -04002304 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED);
David Benjamin31640932017-10-11 13:22:39 -04002305 return false;
Steven Valdez5440fe02016-07-18 12:40:30 -04002306 }
David Benjaminc8b6b4f2016-09-08 23:47:48 -04002307
2308 group_id = groups[0];
Adam Langley7b935932018-11-12 13:53:42 -08002309
Adam Langley1e97ce32023-01-23 21:11:44 +00002310 // We'll try to include one post-quantum and one classical initial key
2311 // share.
2312 for (size_t i = 1; i < groups.size() && second_group_id == 0; i++) {
2313 if (is_post_quantum_group(group_id) != is_post_quantum_group(groups[i])) {
2314 second_group_id = groups[i];
2315 assert(second_group_id != group_id);
2316 }
Adam Langley7b935932018-11-12 13:53:42 -08002317 }
Steven Valdez5440fe02016-07-18 12:40:30 -04002318 }
Steven Valdez143e8b32016-07-11 13:19:03 -04002319
David Benjaminc8b6b4f2016-09-08 23:47:48 -04002320 CBB key_exchange;
Adam Langley7b935932018-11-12 13:53:42 -08002321 hs->key_shares[0] = SSLKeyShare::Create(group_id);
David Benjamin97ede402021-05-18 14:17:52 -04002322 if (!hs->key_shares[0] || //
2323 !CBB_add_u16(cbb.get(), group_id) ||
2324 !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) ||
2325 !hs->key_shares[0]->Offer(&key_exchange)) {
David Benjamin31640932017-10-11 13:22:39 -04002326 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002327 }
Steven Valdez143e8b32016-07-11 13:19:03 -04002328
Adam Langley7b935932018-11-12 13:53:42 -08002329 if (second_group_id != 0) {
2330 hs->key_shares[1] = SSLKeyShare::Create(second_group_id);
David Benjamin97ede402021-05-18 14:17:52 -04002331 if (!hs->key_shares[1] || //
2332 !CBB_add_u16(cbb.get(), second_group_id) ||
2333 !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) ||
2334 !hs->key_shares[1]->Offer(&key_exchange)) {
Adam Langley7b935932018-11-12 13:53:42 -08002335 return false;
2336 }
2337 }
2338
David Benjamin97ede402021-05-18 14:17:52 -04002339 return CBBFinishArray(cbb.get(), &hs->key_share_bytes);
2340}
2341
David Benjamin83a49932021-05-20 15:57:09 -04002342static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
2343 CBB *out_compressible,
2344 ssl_client_hello_type_t type) {
David Benjamin97ede402021-05-18 14:17:52 -04002345 if (hs->max_version < TLS1_3_VERSION) {
2346 return true;
2347 }
2348
2349 assert(!hs->key_share_bytes.empty());
2350 CBB contents, kse_bytes;
David Benjamin83a49932021-05-20 15:57:09 -04002351 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_key_share) ||
2352 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
David Benjamin97ede402021-05-18 14:17:52 -04002353 !CBB_add_u16_length_prefixed(&contents, &kse_bytes) ||
2354 !CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(),
2355 hs->key_share_bytes.size()) ||
David Benjamin83a49932021-05-20 15:57:09 -04002356 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04002357 return false;
Steven Valdez5440fe02016-07-18 12:40:30 -04002358 }
2359
David Benjamin97ede402021-05-18 14:17:52 -04002360 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04002361}
2362
David Benjamin31640932017-10-11 13:22:39 -04002363bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
2364 Array<uint8_t> *out_secret,
2365 uint8_t *out_alert, CBS *contents) {
Steven Valdez143e8b32016-07-11 13:19:03 -04002366 CBS peer_key;
David Benjamin5c4e8572016-08-19 17:44:53 -04002367 uint16_t group_id;
2368 if (!CBS_get_u16(contents, &group_id) ||
David Benjamina70de142016-08-02 16:52:57 -04002369 !CBS_get_u16_length_prefixed(contents, &peer_key) ||
2370 CBS_len(contents) != 0) {
David Benjaminac4d5342017-11-17 01:42:04 +08002371 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -04002372 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002373 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002374 }
2375
Adam Langley7b935932018-11-12 13:53:42 -08002376 SSLKeyShare *key_share = hs->key_shares[0].get();
2377 if (key_share->GroupID() != group_id) {
2378 if (!hs->key_shares[1] || hs->key_shares[1]->GroupID() != group_id) {
2379 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
2380 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
2381 return false;
2382 }
2383 key_share = hs->key_shares[1].get();
Steven Valdez143e8b32016-07-11 13:19:03 -04002384 }
2385
Adam Langley7b935932018-11-12 13:53:42 -08002386 if (!key_share->Finish(out_secret, out_alert, peer_key)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04002387 *out_alert = SSL_AD_INTERNAL_ERROR;
David Benjamin31640932017-10-11 13:22:39 -04002388 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002389 }
2390
David Benjamin45738dd2017-02-09 20:01:26 -05002391 hs->new_session->group_id = group_id;
Adam Langley7b935932018-11-12 13:53:42 -08002392 hs->key_shares[0].reset();
2393 hs->key_shares[1].reset();
David Benjamin31640932017-10-11 13:22:39 -04002394 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04002395}
2396
David Benjamin31640932017-10-11 13:22:39 -04002397bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002398 Span<const uint8_t> *out_peer_key,
2399 uint8_t *out_alert,
2400 const SSL_CLIENT_HELLO *client_hello) {
2401 // We only support connections that include an ECDHE key exchange.
2402 CBS contents;
2403 if (!ssl_client_hello_get_extension(client_hello, &contents,
2404 TLSEXT_TYPE_key_share)) {
2405 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
2406 *out_alert = SSL_AD_MISSING_EXTENSION;
David Benjamin31640932017-10-11 13:22:39 -04002407 return false;
Steven Valdez803c77a2016-09-06 14:13:43 -04002408 }
2409
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002410 CBS key_shares;
2411 if (!CBS_get_u16_length_prefixed(&contents, &key_shares) ||
2412 CBS_len(&contents) != 0) {
David Benjamin7e1f9842016-09-20 19:24:40 -04002413 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
David Benjamin31640932017-10-11 13:22:39 -04002414 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002415 }
2416
David Benjaminc11ea9422017-08-29 16:33:21 -04002417 // Find the corresponding key share.
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002418 const uint16_t group_id = hs->new_session->group_id;
David Benjamin7e1f9842016-09-20 19:24:40 -04002419 CBS peer_key;
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002420 CBS_init(&peer_key, nullptr, 0);
Steven Valdez143e8b32016-07-11 13:19:03 -04002421 while (CBS_len(&key_shares) > 0) {
2422 uint16_t id;
David Benjamin7e1f9842016-09-20 19:24:40 -04002423 CBS peer_key_tmp;
Steven Valdez143e8b32016-07-11 13:19:03 -04002424 if (!CBS_get_u16(&key_shares, &id) ||
Steven Valdez619c8ce2017-10-16 13:12:33 -04002425 !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp) ||
2426 CBS_len(&peer_key_tmp) == 0) {
David Benjamin7e1f9842016-09-20 19:24:40 -04002427 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
David Benjamin31640932017-10-11 13:22:39 -04002428 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002429 }
2430
David Benjamin7e1f9842016-09-20 19:24:40 -04002431 if (id == group_id) {
Steven Valdez619c8ce2017-10-16 13:12:33 -04002432 if (CBS_len(&peer_key) != 0) {
David Benjamin7e1f9842016-09-20 19:24:40 -04002433 OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_KEY_SHARE);
2434 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
David Benjamin31640932017-10-11 13:22:39 -04002435 return false;
David Benjamin7e1f9842016-09-20 19:24:40 -04002436 }
Steven Valdez143e8b32016-07-11 13:19:03 -04002437
David Benjamin7e1f9842016-09-20 19:24:40 -04002438 peer_key = peer_key_tmp;
David Benjaminc11ea9422017-08-29 16:33:21 -04002439 // Continue parsing the structure to keep peers honest.
Steven Valdez143e8b32016-07-11 13:19:03 -04002440 }
Steven Valdez143e8b32016-07-11 13:19:03 -04002441 }
2442
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002443 if (out_peer_key != nullptr) {
2444 *out_peer_key = peer_key;
David Benjamin7e1f9842016-09-20 19:24:40 -04002445 }
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002446 *out_found = CBS_len(&peer_key) != 0;
David Benjamin31640932017-10-11 13:22:39 -04002447 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04002448}
2449
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002450bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
Steven Valdez143e8b32016-07-11 13:19:03 -04002451 CBB kse_bytes, public_key;
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002452 if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) ||
Steven Valdez143e8b32016-07-11 13:19:03 -04002453 !CBB_add_u16_length_prefixed(out, &kse_bytes) ||
David Benjamin3b8c5ec2021-04-12 17:43:23 -04002454 !CBB_add_u16(&kse_bytes, hs->new_session->group_id) ||
Steven Valdez143e8b32016-07-11 13:19:03 -04002455 !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) ||
David Benjamin879efc32017-09-21 11:20:53 -04002456 !CBB_add_bytes(&public_key, hs->ecdh_public_key.data(),
2457 hs->ecdh_public_key.size()) ||
Steven Valdez143e8b32016-07-11 13:19:03 -04002458 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04002459 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04002460 }
David Benjamin31640932017-10-11 13:22:39 -04002461 return true;
Steven Valdez143e8b32016-07-11 13:19:03 -04002462}
2463
2464
David Benjaminc11ea9422017-08-29 16:33:21 -04002465// Supported Versions
2466//
David Benjamina130ce02018-08-14 22:26:39 -05002467// https://tools.ietf.org/html/rfc8446#section-4.2.1
Steven Valdezfdd10992016-09-15 16:27:05 -04002468
David Benjamin83a49932021-05-20 15:57:09 -04002469static bool ext_supported_versions_add_clienthello(
2470 const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
2471 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04002472 const SSL *const ssl = hs->ssl;
David Benjamin68161cb2017-06-20 14:49:43 -04002473 if (hs->max_version <= TLS1_2_VERSION) {
David Benjamin31640932017-10-11 13:22:39 -04002474 return true;
Steven Valdezfdd10992016-09-15 16:27:05 -04002475 }
2476
David Benjamin83a49932021-05-20 15:57:09 -04002477 // supported_versions is compressible in ECH if ClientHelloOuter already
2478 // requires TLS 1.3. Otherwise the extensions differ in the older versions.
2479 if (hs->min_version >= TLS1_3_VERSION) {
2480 out = out_compressible;
2481 }
2482
Steven Valdezfdd10992016-09-15 16:27:05 -04002483 CBB contents, versions;
2484 if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
2485 !CBB_add_u16_length_prefixed(out, &contents) ||
2486 !CBB_add_u8_length_prefixed(&contents, &versions)) {
David Benjamin31640932017-10-11 13:22:39 -04002487 return false;
Steven Valdezfdd10992016-09-15 16:27:05 -04002488 }
2489
David Benjamin3675eb32021-05-18 14:01:07 -04002490 // Add a fake version. See RFC 8701.
David Benjamind9791bf2016-09-27 16:39:52 -04002491 if (ssl->ctx->grease_enabled &&
David Benjamina7bc9442018-01-18 10:08:53 -05002492 !CBB_add_u16(&versions, ssl_get_grease_value(hs, ssl_grease_version))) {
David Benjamin31640932017-10-11 13:22:39 -04002493 return false;
David Benjamind9791bf2016-09-27 16:39:52 -04002494 }
2495
David Benjamin83a49932021-05-20 15:57:09 -04002496 // Encrypted ClientHellos requires TLS 1.3 or later.
2497 uint16_t extra_min_version =
2498 type == ssl_client_hello_inner ? TLS1_3_VERSION : 0;
2499 if (!ssl_add_supported_versions(hs, &versions, extra_min_version) ||
Steven Valdez8f36c512017-06-20 10:55:02 -04002500 !CBB_flush(out)) {
David Benjamin31640932017-10-11 13:22:39 -04002501 return false;
Steven Valdezfdd10992016-09-15 16:27:05 -04002502 }
2503
David Benjamin31640932017-10-11 13:22:39 -04002504 return true;
Steven Valdezfdd10992016-09-15 16:27:05 -04002505}
2506
2507
David Benjaminc11ea9422017-08-29 16:33:21 -04002508// Cookie
2509//
David Benjamina130ce02018-08-14 22:26:39 -05002510// https://tools.ietf.org/html/rfc8446#section-4.2.2
David Benjamin3baa6e12016-10-07 21:10:38 -04002511
David Benjamin83a49932021-05-20 15:57:09 -04002512static bool ext_cookie_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
2513 CBB *out_compressible,
2514 ssl_client_hello_type_t type) {
David Benjaminb9493552017-09-27 19:02:51 -04002515 if (hs->cookie.empty()) {
David Benjamin31640932017-10-11 13:22:39 -04002516 return true;
David Benjamin3baa6e12016-10-07 21:10:38 -04002517 }
2518
2519 CBB contents, cookie;
David Benjamin83a49932021-05-20 15:57:09 -04002520 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_cookie) ||
2521 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
David Benjamin3baa6e12016-10-07 21:10:38 -04002522 !CBB_add_u16_length_prefixed(&contents, &cookie) ||
David Benjamin08f5c762017-09-21 02:43:05 -04002523 !CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) ||
David Benjamin83a49932021-05-20 15:57:09 -04002524 !CBB_flush(out_compressible)) {
David Benjamin31640932017-10-11 13:22:39 -04002525 return false;
David Benjamin3baa6e12016-10-07 21:10:38 -04002526 }
2527
David Benjamin31640932017-10-11 13:22:39 -04002528 return true;
David Benjamin3baa6e12016-10-07 21:10:38 -04002529}
2530
2531
David Benjamina130ce02018-08-14 22:26:39 -05002532// Supported Groups
David Benjaminc11ea9422017-08-29 16:33:21 -04002533//
David Benjamina130ce02018-08-14 22:26:39 -05002534// https://tools.ietf.org/html/rfc4492#section-5.1.1
2535// https://tools.ietf.org/html/rfc8446#section-4.2.7
Adam Langley273d49c2015-07-20 16:38:52 -07002536
David Benjamin14e51ad2021-05-19 15:24:34 -04002537static bool ext_supported_groups_add_clienthello(const SSL_HANDSHAKE *hs,
David Benjamin83a49932021-05-20 15:57:09 -04002538 CBB *out,
2539 CBB *out_compressible,
2540 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04002541 const SSL *const ssl = hs->ssl;
Steven Valdezce902a92016-05-17 11:47:53 -04002542 CBB contents, groups_bytes;
David Benjamin83a49932021-05-20 15:57:09 -04002543 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_supported_groups) ||
2544 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
Steven Valdezce902a92016-05-17 11:47:53 -04002545 !CBB_add_u16_length_prefixed(&contents, &groups_bytes)) {
David Benjamin31640932017-10-11 13:22:39 -04002546 return false;
Adam Langley273d49c2015-07-20 16:38:52 -07002547 }
2548
David Benjamin3675eb32021-05-18 14:01:07 -04002549 // Add a fake group. See RFC 8701.
David Benjamin65ac9972016-09-02 21:35:25 -04002550 if (ssl->ctx->grease_enabled &&
2551 !CBB_add_u16(&groups_bytes,
David Benjamina7bc9442018-01-18 10:08:53 -05002552 ssl_get_grease_value(hs, ssl_grease_group))) {
David Benjamin31640932017-10-11 13:22:39 -04002553 return false;
David Benjamin65ac9972016-09-02 21:35:25 -04002554 }
2555
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002556 for (uint16_t group : tls1_get_grouplist(hs)) {
Kris Kwiatkowski78c88c92019-03-11 14:40:59 +00002557 if (is_post_quantum_group(group) &&
Adam Langley7b935932018-11-12 13:53:42 -08002558 hs->max_version < TLS1_3_VERSION) {
2559 continue;
2560 }
David Benjamincf0ce672017-09-21 02:25:59 -04002561 if (!CBB_add_u16(&groups_bytes, group)) {
David Benjamin31640932017-10-11 13:22:39 -04002562 return false;
Adam Langley273d49c2015-07-20 16:38:52 -07002563 }
2564 }
2565
David Benjamin83a49932021-05-20 15:57:09 -04002566 return CBB_flush(out_compressible);
Adam Langley273d49c2015-07-20 16:38:52 -07002567}
2568
David Benjamin31640932017-10-11 13:22:39 -04002569static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs,
2570 uint8_t *out_alert,
2571 CBS *contents) {
David Benjaminc11ea9422017-08-29 16:33:21 -04002572 // This extension is not expected to be echoed by servers in TLS 1.2, but some
2573 // BigIP servers send it nonetheless, so do not enforce this.
David Benjamin31640932017-10-11 13:22:39 -04002574 return true;
Adam Langley273d49c2015-07-20 16:38:52 -07002575}
2576
David Benjaminb1cf48e2017-09-21 11:37:46 -04002577static bool parse_u16_array(const CBS *cbs, Array<uint16_t> *out) {
2578 CBS copy = *cbs;
2579 if ((CBS_len(&copy) & 1) != 0) {
2580 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
2581 return false;
2582 }
2583
2584 Array<uint16_t> ret;
2585 if (!ret.Init(CBS_len(&copy) / 2)) {
2586 return false;
2587 }
2588 for (size_t i = 0; i < ret.size(); i++) {
2589 if (!CBS_get_u16(&copy, &ret[i])) {
2590 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
2591 return false;
2592 }
2593 }
2594
2595 assert(CBS_len(&copy) == 0);
2596 *out = std::move(ret);
Anton Bikineev50e7ea52022-01-23 22:35:48 +01002597 return true;
David Benjaminb1cf48e2017-09-21 11:37:46 -04002598}
2599
David Benjamin31640932017-10-11 13:22:39 -04002600static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
David Benjamin8c880a22016-12-03 02:20:34 -05002601 uint8_t *out_alert,
David Benjamin31640932017-10-11 13:22:39 -04002602 CBS *contents) {
Adam Langley273d49c2015-07-20 16:38:52 -07002603 if (contents == NULL) {
David Benjamin31640932017-10-11 13:22:39 -04002604 return true;
Adam Langley273d49c2015-07-20 16:38:52 -07002605 }
2606
Steven Valdezce902a92016-05-17 11:47:53 -04002607 CBS supported_group_list;
2608 if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) ||
2609 CBS_len(&supported_group_list) == 0 ||
David Benjaminb1cf48e2017-09-21 11:37:46 -04002610 CBS_len(contents) != 0 ||
2611 !parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) {
David Benjamin31640932017-10-11 13:22:39 -04002612 return false;
Adam Langley273d49c2015-07-20 16:38:52 -07002613 }
2614
David Benjamin31640932017-10-11 13:22:39 -04002615 return true;
Adam Langley273d49c2015-07-20 16:38:52 -07002616}
2617
2618
Nick Harper3c034b22017-12-22 15:50:43 -08002619// QUIC Transport Parameters
2620
David Schinazi3d8b8c32021-01-14 11:25:49 -08002621static bool ext_quic_transport_params_add_clienthello_impl(
David Benjamin14e51ad2021-05-19 15:24:34 -04002622 const SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) {
Nick Harper72cff812020-03-26 18:06:16 -07002623 if (hs->config->quic_transport_params.empty() && !hs->ssl->quic_method) {
Nick Harper3c034b22017-12-22 15:50:43 -08002624 return true;
2625 }
Nick Harper72cff812020-03-26 18:06:16 -07002626 if (hs->config->quic_transport_params.empty() || !hs->ssl->quic_method) {
2627 // QUIC Transport Parameters must be sent over QUIC, and they must not be
2628 // sent over non-QUIC transports. If transport params are set, then
2629 // SSL(_CTX)_set_quic_method must also be called.
2630 OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED);
2631 return false;
2632 }
2633 assert(hs->min_version > TLS1_2_VERSION);
David Schinazi3d8b8c32021-01-14 11:25:49 -08002634 if (use_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
2635 // Do nothing, we'll send the other codepoint.
2636 return true;
2637 }
2638
David Benjamina1d3bfb2021-06-01 12:12:44 -04002639 uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters;
David Schinazi3d8b8c32021-01-14 11:25:49 -08002640 if (hs->config->quic_use_legacy_codepoint) {
2641 extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
2642 }
Nick Harper3c034b22017-12-22 15:50:43 -08002643
2644 CBB contents;
David Schinazi3d8b8c32021-01-14 11:25:49 -08002645 if (!CBB_add_u16(out, extension_type) ||
Nick Harper3c034b22017-12-22 15:50:43 -08002646 !CBB_add_u16_length_prefixed(out, &contents) ||
David Benjamin0ce090a2018-07-02 20:24:40 -04002647 !CBB_add_bytes(&contents, hs->config->quic_transport_params.data(),
2648 hs->config->quic_transport_params.size()) ||
Nick Harper3c034b22017-12-22 15:50:43 -08002649 !CBB_flush(out)) {
2650 return false;
2651 }
2652 return true;
2653}
2654
David Benjamin83a49932021-05-20 15:57:09 -04002655static bool ext_quic_transport_params_add_clienthello(
2656 const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
2657 ssl_client_hello_type_t type) {
David Schinazi3d8b8c32021-01-14 11:25:49 -08002658 return ext_quic_transport_params_add_clienthello_impl(
David Benjamin83a49932021-05-20 15:57:09 -04002659 hs, out_compressible, /*use_legacy_codepoint=*/false);
David Schinazi3d8b8c32021-01-14 11:25:49 -08002660}
2661
David Benjamin14e51ad2021-05-19 15:24:34 -04002662static bool ext_quic_transport_params_add_clienthello_legacy(
David Benjamin83a49932021-05-20 15:57:09 -04002663 const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
2664 ssl_client_hello_type_t type) {
David Schinazi3d8b8c32021-01-14 11:25:49 -08002665 return ext_quic_transport_params_add_clienthello_impl(
David Benjamin83a49932021-05-20 15:57:09 -04002666 hs, out_compressible, /*use_legacy_codepoint=*/true);
David Schinazi3d8b8c32021-01-14 11:25:49 -08002667}
2668
2669static bool ext_quic_transport_params_parse_serverhello_impl(
2670 SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
2671 bool used_legacy_codepoint) {
Adam Langleyca058c02020-12-16 10:11:08 -08002672 SSL *const ssl = hs->ssl;
2673 if (contents == nullptr) {
David Schinazi3d8b8c32021-01-14 11:25:49 -08002674 if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
2675 // Silently ignore because we expect the other QUIC codepoint.
2676 return true;
2677 }
Adam Langleyca058c02020-12-16 10:11:08 -08002678 if (!ssl->quic_method) {
2679 return true;
2680 }
Adam Langleyca058c02020-12-16 10:11:08 -08002681 *out_alert = SSL_AD_MISSING_EXTENSION;
2682 return false;
David Schinazi7ba96a62020-12-14 14:46:56 -08002683 }
David Schinazi3d8b8c32021-01-14 11:25:49 -08002684 // The extensions parser will check for unsolicited extensions before
2685 // calling the callback.
2686 assert(ssl->quic_method != nullptr);
Adam Langleyca058c02020-12-16 10:11:08 -08002687 assert(ssl_protocol_version(ssl) == TLS1_3_VERSION);
David Schinazi3d8b8c32021-01-14 11:25:49 -08002688 assert(used_legacy_codepoint == hs->config->quic_use_legacy_codepoint);
Adam Langleyca058c02020-12-16 10:11:08 -08002689 return ssl->s3->peer_quic_transport_params.CopyFrom(*contents);
2690}
2691
David Schinazi3d8b8c32021-01-14 11:25:49 -08002692static bool ext_quic_transport_params_parse_serverhello(SSL_HANDSHAKE *hs,
Adam Langleyca058c02020-12-16 10:11:08 -08002693 uint8_t *out_alert,
2694 CBS *contents) {
David Schinazi3d8b8c32021-01-14 11:25:49 -08002695 return ext_quic_transport_params_parse_serverhello_impl(
2696 hs, out_alert, contents, /*used_legacy_codepoint=*/false);
2697}
2698
2699static bool ext_quic_transport_params_parse_serverhello_legacy(
2700 SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) {
2701 return ext_quic_transport_params_parse_serverhello_impl(
2702 hs, out_alert, contents, /*used_legacy_codepoint=*/true);
2703}
2704
2705static bool ext_quic_transport_params_parse_clienthello_impl(
2706 SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
2707 bool used_legacy_codepoint) {
Nick Harper3c034b22017-12-22 15:50:43 -08002708 SSL *const ssl = hs->ssl;
Nick Harper72cff812020-03-26 18:06:16 -07002709 if (!contents) {
2710 if (!ssl->quic_method) {
2711 if (hs->config->quic_transport_params.empty()) {
2712 return true;
2713 }
2714 // QUIC transport parameters must not be set if |ssl| is not configured
2715 // for QUIC.
2716 OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED);
2717 *out_alert = SSL_AD_INTERNAL_ERROR;
David Schinazi3d8b8c32021-01-14 11:25:49 -08002718 return false;
2719 }
2720 if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
2721 // Silently ignore because we expect the other QUIC codepoint.
2722 return true;
Nick Harper72cff812020-03-26 18:06:16 -07002723 }
2724 *out_alert = SSL_AD_MISSING_EXTENSION;
2725 return false;
2726 }
2727 if (!ssl->quic_method) {
David Schinazi3d8b8c32021-01-14 11:25:49 -08002728 if (used_legacy_codepoint) {
2729 // Ignore the legacy private-use codepoint because that could be sent
2730 // to mean something else than QUIC transport parameters.
2731 return true;
2732 }
2733 // Fail if we received the codepoint registered with IANA for QUIC
2734 // because that is not allowed outside of QUIC.
Nick Harper72cff812020-03-26 18:06:16 -07002735 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
2736 return false;
Nick Harper3c034b22017-12-22 15:50:43 -08002737 }
Nick Harper80ddfc72020-03-11 18:26:31 -07002738 assert(ssl_protocol_version(ssl) == TLS1_3_VERSION);
David Schinazi3d8b8c32021-01-14 11:25:49 -08002739 if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
2740 // Silently ignore because we expect the other QUIC codepoint.
2741 return true;
2742 }
Nick Harper3c034b22017-12-22 15:50:43 -08002743 return ssl->s3->peer_quic_transport_params.CopyFrom(*contents);
2744}
2745
David Schinazi3d8b8c32021-01-14 11:25:49 -08002746static bool ext_quic_transport_params_parse_clienthello(SSL_HANDSHAKE *hs,
2747 uint8_t *out_alert,
2748 CBS *contents) {
2749 return ext_quic_transport_params_parse_clienthello_impl(
2750 hs, out_alert, contents, /*used_legacy_codepoint=*/false);
2751}
2752
2753static bool ext_quic_transport_params_parse_clienthello_legacy(
2754 SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) {
2755 return ext_quic_transport_params_parse_clienthello_impl(
2756 hs, out_alert, contents, /*used_legacy_codepoint=*/true);
2757}
2758
2759static bool ext_quic_transport_params_add_serverhello_impl(
2760 SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) {
2761 if (hs->ssl->quic_method == nullptr && use_legacy_codepoint) {
2762 // Ignore the legacy private-use codepoint because that could be sent
2763 // to mean something else than QUIC transport parameters.
2764 return true;
2765 }
Nick Harper72cff812020-03-26 18:06:16 -07002766 assert(hs->ssl->quic_method != nullptr);
David Benjamin0ce090a2018-07-02 20:24:40 -04002767 if (hs->config->quic_transport_params.empty()) {
Nick Harper72cff812020-03-26 18:06:16 -07002768 // Transport parameters must be set when using QUIC.
2769 OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED);
2770 return false;
Nick Harper3c034b22017-12-22 15:50:43 -08002771 }
David Schinazi3d8b8c32021-01-14 11:25:49 -08002772 if (use_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
2773 // Do nothing, we'll send the other codepoint.
2774 return true;
2775 }
2776
David Benjamina1d3bfb2021-06-01 12:12:44 -04002777 uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters;
David Schinazi3d8b8c32021-01-14 11:25:49 -08002778 if (hs->config->quic_use_legacy_codepoint) {
2779 extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
2780 }
Nick Harper3c034b22017-12-22 15:50:43 -08002781
2782 CBB contents;
David Schinazi3d8b8c32021-01-14 11:25:49 -08002783 if (!CBB_add_u16(out, extension_type) ||
Nick Harper3c034b22017-12-22 15:50:43 -08002784 !CBB_add_u16_length_prefixed(out, &contents) ||
David Benjamin0ce090a2018-07-02 20:24:40 -04002785 !CBB_add_bytes(&contents, hs->config->quic_transport_params.data(),
2786 hs->config->quic_transport_params.size()) ||
Nick Harper3c034b22017-12-22 15:50:43 -08002787 !CBB_flush(out)) {
2788 return false;
2789 }
2790
2791 return true;
2792}
2793
David Schinazi3d8b8c32021-01-14 11:25:49 -08002794static bool ext_quic_transport_params_add_serverhello(SSL_HANDSHAKE *hs,
2795 CBB *out) {
2796 return ext_quic_transport_params_add_serverhello_impl(
2797 hs, out, /*use_legacy_codepoint=*/false);
2798}
2799
2800static bool ext_quic_transport_params_add_serverhello_legacy(SSL_HANDSHAKE *hs,
2801 CBB *out) {
2802 return ext_quic_transport_params_add_serverhello_impl(
2803 hs, out, /*use_legacy_codepoint=*/true);
2804}
2805
Christopher Patton6c1b3762018-07-17 12:49:41 -07002806// Delegated credentials.
2807//
2808// https://tools.ietf.org/html/draft-ietf-tls-subcerts
2809
David Benjamin83a49932021-05-20 15:57:09 -04002810static bool ext_delegated_credential_add_clienthello(
2811 const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
2812 ssl_client_hello_type_t type) {
Christopher Patton6c1b3762018-07-17 12:49:41 -07002813 return true;
2814}
2815
2816static bool ext_delegated_credential_parse_clienthello(SSL_HANDSHAKE *hs,
2817 uint8_t *out_alert,
2818 CBS *contents) {
Christopher Patton6c1b3762018-07-17 12:49:41 -07002819 if (contents == nullptr || ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
2820 // Don't use delegated credentials unless we're negotiating TLS 1.3 or
2821 // higher.
2822 return true;
2823 }
2824
Watson Ladddcd6e442020-08-10 15:12:45 -04002825 // The contents of the extension are the signature algorithms the client will
2826 // accept for a delegated credential.
2827 CBS sigalg_list;
2828 if (!CBS_get_u16_length_prefixed(contents, &sigalg_list) ||
2829 CBS_len(&sigalg_list) == 0 ||
2830 CBS_len(contents) != 0 ||
2831 !parse_u16_array(&sigalg_list, &hs->peer_delegated_credential_sigalgs)) {
2832 return false;
2833 }
2834
Christopher Patton6c1b3762018-07-17 12:49:41 -07002835 hs->delegated_credential_requested = true;
2836 return true;
2837}
2838
Adam Langleya307cb72018-05-02 09:06:48 -07002839// Certificate compression
2840
David Benjamin83a49932021-05-20 15:57:09 -04002841static bool cert_compression_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
2842 CBB *out_compressible,
2843 ssl_client_hello_type_t type) {
Adam Langley0080d832018-06-07 16:39:49 -07002844 bool first = true;
2845 CBB contents, algs;
2846
David Benjamin8fe15842019-10-08 16:57:38 -04002847 for (const auto &alg : hs->ssl->ctx->cert_compression_algs) {
2848 if (alg.decompress == nullptr) {
Adam Langley0080d832018-06-07 16:39:49 -07002849 continue;
2850 }
2851
David Benjamin83a49932021-05-20 15:57:09 -04002852 if (first &&
2853 (!CBB_add_u16(out_compressible, TLSEXT_TYPE_cert_compression) ||
2854 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
2855 !CBB_add_u8_length_prefixed(&contents, &algs))) {
Adam Langley0080d832018-06-07 16:39:49 -07002856 return false;
2857 }
2858 first = false;
David Benjamin8fe15842019-10-08 16:57:38 -04002859 if (!CBB_add_u16(&algs, alg.alg_id)) {
Adam Langley0080d832018-06-07 16:39:49 -07002860 return false;
2861 }
2862 }
2863
David Benjamin83a49932021-05-20 15:57:09 -04002864 return first || CBB_flush(out_compressible);
Adam Langleya307cb72018-05-02 09:06:48 -07002865}
2866
2867static bool cert_compression_parse_serverhello(SSL_HANDSHAKE *hs,
2868 uint8_t *out_alert,
2869 CBS *contents) {
2870 if (contents == nullptr) {
2871 return true;
2872 }
2873
2874 // The server may not echo this extension. Any server to client negotiation is
2875 // advertised in the CertificateRequest message.
2876 return false;
2877}
2878
2879static bool cert_compression_parse_clienthello(SSL_HANDSHAKE *hs,
2880 uint8_t *out_alert,
2881 CBS *contents) {
2882 if (contents == nullptr) {
2883 return true;
2884 }
2885
David Benjamin8fe15842019-10-08 16:57:38 -04002886 const SSL_CTX *ctx = hs->ssl->ctx.get();
2887 const size_t num_algs = ctx->cert_compression_algs.size();
Adam Langleya307cb72018-05-02 09:06:48 -07002888
2889 CBS alg_ids;
2890 if (!CBS_get_u8_length_prefixed(contents, &alg_ids) ||
2891 CBS_len(contents) != 0 ||
2892 CBS_len(&alg_ids) == 0 ||
2893 CBS_len(&alg_ids) % 2 == 1) {
2894 return false;
2895 }
2896
2897 const size_t num_given_alg_ids = CBS_len(&alg_ids) / 2;
2898 Array<uint16_t> given_alg_ids;
2899 if (!given_alg_ids.Init(num_given_alg_ids)) {
2900 return false;
2901 }
2902
2903 size_t best_index = num_algs;
2904 size_t given_alg_idx = 0;
2905
2906 while (CBS_len(&alg_ids) > 0) {
2907 uint16_t alg_id;
2908 if (!CBS_get_u16(&alg_ids, &alg_id)) {
2909 return false;
2910 }
2911
2912 given_alg_ids[given_alg_idx++] = alg_id;
2913
2914 for (size_t i = 0; i < num_algs; i++) {
David Benjamin8fe15842019-10-08 16:57:38 -04002915 const auto &alg = ctx->cert_compression_algs[i];
2916 if (alg.alg_id == alg_id && alg.compress != nullptr) {
Adam Langleya307cb72018-05-02 09:06:48 -07002917 if (i < best_index) {
2918 best_index = i;
2919 }
2920 break;
2921 }
2922 }
2923 }
2924
2925 qsort(given_alg_ids.data(), given_alg_ids.size(), sizeof(uint16_t),
2926 compare_uint16_t);
2927 for (size_t i = 1; i < num_given_alg_ids; i++) {
2928 if (given_alg_ids[i - 1] == given_alg_ids[i]) {
2929 return false;
2930 }
2931 }
2932
2933 if (best_index < num_algs &&
2934 ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
2935 hs->cert_compression_negotiated = true;
David Benjamin8fe15842019-10-08 16:57:38 -04002936 hs->cert_compression_alg_id = ctx->cert_compression_algs[best_index].alg_id;
Adam Langleya307cb72018-05-02 09:06:48 -07002937 }
2938
2939 return true;
2940}
2941
2942static bool cert_compression_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
2943 return true;
2944}
Nick Harper3c034b22017-12-22 15:50:43 -08002945
Steven Valdez51607f12020-08-05 10:46:05 -04002946// Application-level Protocol Settings
2947//
2948// https://tools.ietf.org/html/draft-vvv-tls-alps-01
2949
David Benjamin4e93cd42021-05-18 13:38:25 -04002950bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
2951 Span<const uint8_t> *out_settings,
2952 Span<const uint8_t> protocol) {
2953 for (const ALPSConfig &config : hs->config->alps_configs) {
2954 if (protocol == config.protocol) {
2955 *out_settings = config.settings;
2956 return true;
2957 }
2958 }
2959 return false;
2960}
2961
David Benjamin83a49932021-05-20 15:57:09 -04002962static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
2963 CBB *out_compressible,
2964 ssl_client_hello_type_t type) {
David Benjamin14e51ad2021-05-19 15:24:34 -04002965 const SSL *const ssl = hs->ssl;
Steven Valdez51607f12020-08-05 10:46:05 -04002966 if (// ALPS requires TLS 1.3.
2967 hs->max_version < TLS1_3_VERSION ||
2968 // Do not offer ALPS without ALPN.
2969 hs->config->alpn_client_proto_list.empty() ||
2970 // Do not offer ALPS if not configured.
2971 hs->config->alps_configs.empty() ||
2972 // Do not offer ALPS on renegotiation handshakes.
2973 ssl->s3->initial_handshake_complete) {
2974 return true;
2975 }
2976
2977 CBB contents, proto_list, proto;
David Benjamin83a49932021-05-20 15:57:09 -04002978 if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_application_settings) ||
2979 !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
Steven Valdez51607f12020-08-05 10:46:05 -04002980 !CBB_add_u16_length_prefixed(&contents, &proto_list)) {
2981 return false;
2982 }
2983
2984 for (const ALPSConfig &config : hs->config->alps_configs) {
2985 if (!CBB_add_u8_length_prefixed(&proto_list, &proto) ||
2986 !CBB_add_bytes(&proto, config.protocol.data(),
2987 config.protocol.size())) {
2988 return false;
2989 }
2990 }
2991
David Benjamin83a49932021-05-20 15:57:09 -04002992 return CBB_flush(out_compressible);
Steven Valdez51607f12020-08-05 10:46:05 -04002993}
2994
2995static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
2996 CBS *contents) {
2997 SSL *const ssl = hs->ssl;
2998 if (contents == nullptr) {
2999 return true;
3000 }
3001
3002 assert(!ssl->s3->initial_handshake_complete);
3003 assert(!hs->config->alpn_client_proto_list.empty());
3004 assert(!hs->config->alps_configs.empty());
3005
3006 // ALPS requires TLS 1.3.
3007 if (ssl_protocol_version(ssl) < TLS1_3_VERSION) {
3008 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
3009 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
3010 return false;
3011 }
3012
3013 // Note extension callbacks may run in any order, so we defer checking
3014 // consistency with ALPN to |ssl_check_serverhello_tlsext|.
3015 if (!hs->new_session->peer_application_settings.CopyFrom(*contents)) {
3016 *out_alert = SSL_AD_INTERNAL_ERROR;
3017 return false;
3018 }
3019
3020 hs->new_session->has_application_settings = true;
3021 return true;
3022}
3023
3024static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
3025 SSL *const ssl = hs->ssl;
3026 // If early data is accepted, we omit the ALPS extension. It is implicitly
3027 // carried over from the previous connection.
3028 if (hs->new_session == nullptr ||
3029 !hs->new_session->has_application_settings ||
3030 ssl->s3->early_data_accepted) {
3031 return true;
3032 }
3033
3034 CBB contents;
3035 if (!CBB_add_u16(out, TLSEXT_TYPE_application_settings) ||
3036 !CBB_add_u16_length_prefixed(out, &contents) ||
3037 !CBB_add_bytes(&contents,
3038 hs->new_session->local_application_settings.data(),
3039 hs->new_session->local_application_settings.size()) ||
3040 !CBB_flush(out)) {
3041 return false;
3042 }
3043
3044 return true;
3045}
3046
3047bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert,
3048 const SSL_CLIENT_HELLO *client_hello) {
3049 SSL *const ssl = hs->ssl;
3050 if (ssl->s3->alpn_selected.empty()) {
3051 return true;
3052 }
3053
3054 // If we negotiate ALPN over TLS 1.3, try to negotiate ALPS.
3055 CBS alps_contents;
3056 Span<const uint8_t> settings;
3057 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION &&
3058 ssl_get_local_application_settings(hs, &settings,
3059 ssl->s3->alpn_selected) &&
3060 ssl_client_hello_get_extension(client_hello, &alps_contents,
3061 TLSEXT_TYPE_application_settings)) {
3062 // Check if the client supports ALPS with the selected ALPN.
3063 bool found = false;
3064 CBS alps_list;
3065 if (!CBS_get_u16_length_prefixed(&alps_contents, &alps_list) ||
3066 CBS_len(&alps_contents) != 0 ||
3067 CBS_len(&alps_list) == 0) {
3068 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
3069 *out_alert = SSL_AD_DECODE_ERROR;
3070 return false;
3071 }
3072 while (CBS_len(&alps_list) > 0) {
3073 CBS protocol_name;
3074 if (!CBS_get_u8_length_prefixed(&alps_list, &protocol_name) ||
3075 // Empty protocol names are forbidden.
3076 CBS_len(&protocol_name) == 0) {
3077 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
3078 *out_alert = SSL_AD_DECODE_ERROR;
3079 return false;
3080 }
3081 if (protocol_name == MakeConstSpan(ssl->s3->alpn_selected)) {
3082 found = true;
3083 }
3084 }
3085
3086 // Negotiate ALPS if both client also supports ALPS for this protocol.
3087 if (found) {
3088 hs->new_session->has_application_settings = true;
3089 if (!hs->new_session->local_application_settings.CopyFrom(settings)) {
3090 *out_alert = SSL_AD_INTERNAL_ERROR;
3091 return false;
3092 }
3093 }
3094 }
3095
3096 return true;
3097}
Adam Langleya86c6982019-07-16 15:26:21 -07003098
David Benjaminc11ea9422017-08-29 16:33:21 -04003099// kExtensions contains all the supported extensions.
Adam Langley614c66a2015-06-12 15:26:58 -07003100static const struct tls_extension kExtensions[] = {
3101 {
3102 TLSEXT_TYPE_server_name,
Adam Langley614c66a2015-06-12 15:26:58 -07003103 ext_sni_add_clienthello,
3104 ext_sni_parse_serverhello,
3105 ext_sni_parse_clienthello,
3106 ext_sni_add_serverhello,
3107 },
Adam Langley0a056712015-07-01 15:03:33 -07003108 {
Dan McArdle1920c6f2020-03-11 17:29:40 -04003109 TLSEXT_TYPE_encrypted_client_hello,
Dan McArdle1920c6f2020-03-11 17:29:40 -04003110 ext_ech_add_clienthello,
3111 ext_ech_parse_serverhello,
Dan McArdlec2959352020-10-29 14:31:31 -04003112 ext_ech_parse_clienthello,
Daniel McArdle00e434d2021-02-18 11:47:18 -05003113 ext_ech_add_serverhello,
Dan McArdlec2959352020-10-29 14:31:31 -04003114 },
3115 {
Adam Langley0a056712015-07-01 15:03:33 -07003116 TLSEXT_TYPE_extended_master_secret,
Adam Langley0a056712015-07-01 15:03:33 -07003117 ext_ems_add_clienthello,
3118 ext_ems_parse_serverhello,
3119 ext_ems_parse_clienthello,
3120 ext_ems_add_serverhello,
3121 },
Adam Langley9b05bc52015-07-01 15:25:33 -07003122 {
Adam Langleyd6680952018-08-23 08:01:23 -07003123 TLSEXT_TYPE_renegotiate,
Adam Langleyd6680952018-08-23 08:01:23 -07003124 ext_ri_add_clienthello,
3125 ext_ri_parse_serverhello,
3126 ext_ri_parse_clienthello,
3127 ext_ri_add_serverhello,
3128 },
3129 {
3130 TLSEXT_TYPE_supported_groups,
Adam Langleyd6680952018-08-23 08:01:23 -07003131 ext_supported_groups_add_clienthello,
3132 ext_supported_groups_parse_serverhello,
3133 ext_supported_groups_parse_clienthello,
3134 dont_add_serverhello,
3135 },
3136 {
3137 TLSEXT_TYPE_ec_point_formats,
Adam Langleyd6680952018-08-23 08:01:23 -07003138 ext_ec_point_add_clienthello,
3139 ext_ec_point_parse_serverhello,
3140 ext_ec_point_parse_clienthello,
3141 ext_ec_point_add_serverhello,
3142 },
3143 {
Adam Langley9b05bc52015-07-01 15:25:33 -07003144 TLSEXT_TYPE_session_ticket,
Adam Langley9b05bc52015-07-01 15:25:33 -07003145 ext_ticket_add_clienthello,
3146 ext_ticket_parse_serverhello,
David Benjaminc11ea9422017-08-29 16:33:21 -04003147 // Ticket extension client parsing is handled in ssl_session.c
Steven Valdez6b8509a2016-07-12 13:38:32 -04003148 ignore_parse_clienthello,
Adam Langley9b05bc52015-07-01 15:25:33 -07003149 ext_ticket_add_serverhello,
3150 },
Adam Langley2e857bd2015-07-01 16:09:19 -07003151 {
Adam Langleyd6680952018-08-23 08:01:23 -07003152 TLSEXT_TYPE_application_layer_protocol_negotiation,
Adam Langleyd6680952018-08-23 08:01:23 -07003153 ext_alpn_add_clienthello,
3154 ext_alpn_parse_serverhello,
3155 // ALPN is negotiated late in |ssl_negotiate_alpn|.
3156 ignore_parse_clienthello,
3157 ext_alpn_add_serverhello,
3158 },
3159 {
3160 TLSEXT_TYPE_status_request,
Adam Langleyd6680952018-08-23 08:01:23 -07003161 ext_ocsp_add_clienthello,
3162 ext_ocsp_parse_serverhello,
3163 ext_ocsp_parse_clienthello,
3164 ext_ocsp_add_serverhello,
3165 },
3166 {
Adam Langley2e857bd2015-07-01 16:09:19 -07003167 TLSEXT_TYPE_signature_algorithms,
Adam Langley2e857bd2015-07-01 16:09:19 -07003168 ext_sigalgs_add_clienthello,
Steven Valdez6b8509a2016-07-12 13:38:32 -04003169 forbid_parse_serverhello,
Adam Langley2e857bd2015-07-01 16:09:19 -07003170 ext_sigalgs_parse_clienthello,
Steven Valdez6b8509a2016-07-12 13:38:32 -04003171 dont_add_serverhello,
Adam Langley2e857bd2015-07-01 16:09:19 -07003172 },
Adam Langleybb0bd042015-07-01 16:21:03 -07003173 {
Adam Langley97dfcbf2015-07-01 18:35:20 -07003174 TLSEXT_TYPE_next_proto_neg,
Adam Langley97dfcbf2015-07-01 18:35:20 -07003175 ext_npn_add_clienthello,
3176 ext_npn_parse_serverhello,
3177 ext_npn_parse_clienthello,
3178 ext_npn_add_serverhello,
3179 },
Adam Langleyab8d87d2015-07-10 12:21:39 -07003180 {
3181 TLSEXT_TYPE_certificate_timestamp,
Adam Langleyab8d87d2015-07-10 12:21:39 -07003182 ext_sct_add_clienthello,
3183 ext_sct_parse_serverhello,
3184 ext_sct_parse_clienthello,
3185 ext_sct_add_serverhello,
3186 },
Adam Langleyf18e4532015-07-10 13:39:53 -07003187 {
Adam Langley49c7af12015-07-10 14:33:46 -07003188 TLSEXT_TYPE_channel_id,
Adam Langley49c7af12015-07-10 14:33:46 -07003189 ext_channel_id_add_clienthello,
3190 ext_channel_id_parse_serverhello,
3191 ext_channel_id_parse_clienthello,
3192 ext_channel_id_add_serverhello,
3193 },
Adam Langley391250d2015-07-15 19:06:07 -07003194 {
3195 TLSEXT_TYPE_srtp,
Adam Langley391250d2015-07-15 19:06:07 -07003196 ext_srtp_add_clienthello,
3197 ext_srtp_parse_serverhello,
3198 ext_srtp_parse_clienthello,
3199 ext_srtp_add_serverhello,
3200 },
Adam Langleybdd5d662015-07-20 16:19:08 -07003201 {
Steven Valdez7e5dd252018-01-22 15:20:31 -05003202 TLSEXT_TYPE_key_share,
Steven Valdez143e8b32016-07-11 13:19:03 -04003203 ext_key_share_add_clienthello,
3204 forbid_parse_serverhello,
3205 ignore_parse_clienthello,
3206 dont_add_serverhello,
3207 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04003208 {
Steven Valdeza833c352016-11-01 13:39:36 -04003209 TLSEXT_TYPE_psk_key_exchange_modes,
Steven Valdeza833c352016-11-01 13:39:36 -04003210 ext_psk_key_exchange_modes_add_clienthello,
Steven Valdez4aa154e2016-07-29 14:32:55 -04003211 forbid_parse_serverhello,
David Benjamin4eb95cc2016-11-16 17:08:23 +09003212 ext_psk_key_exchange_modes_parse_clienthello,
Steven Valdez4aa154e2016-07-29 14:32:55 -04003213 dont_add_serverhello,
3214 },
Steven Valdezfdd10992016-09-15 16:27:05 -04003215 {
Steven Valdeza4ee74d2016-11-29 13:36:45 -05003216 TLSEXT_TYPE_early_data,
Steven Valdeza4ee74d2016-11-29 13:36:45 -05003217 ext_early_data_add_clienthello,
Steven Valdez2d850622017-01-11 11:34:52 -05003218 ext_early_data_parse_serverhello,
Steven Valdeza4ee74d2016-11-29 13:36:45 -05003219 ext_early_data_parse_clienthello,
Steven Valdez2d850622017-01-11 11:34:52 -05003220 ext_early_data_add_serverhello,
Steven Valdeza4ee74d2016-11-29 13:36:45 -05003221 },
3222 {
Steven Valdezfdd10992016-09-15 16:27:05 -04003223 TLSEXT_TYPE_supported_versions,
Steven Valdezfdd10992016-09-15 16:27:05 -04003224 ext_supported_versions_add_clienthello,
3225 forbid_parse_serverhello,
3226 ignore_parse_clienthello,
3227 dont_add_serverhello,
3228 },
David Benjamin3baa6e12016-10-07 21:10:38 -04003229 {
3230 TLSEXT_TYPE_cookie,
David Benjamin3baa6e12016-10-07 21:10:38 -04003231 ext_cookie_add_clienthello,
3232 forbid_parse_serverhello,
3233 ignore_parse_clienthello,
3234 dont_add_serverhello,
3235 },
Adam Langley512a2892017-12-30 08:04:39 -08003236 {
David Benjamina1d3bfb2021-06-01 12:12:44 -04003237 TLSEXT_TYPE_quic_transport_parameters,
Nick Harper3c034b22017-12-22 15:50:43 -08003238 ext_quic_transport_params_add_clienthello,
3239 ext_quic_transport_params_parse_serverhello,
3240 ext_quic_transport_params_parse_clienthello,
3241 ext_quic_transport_params_add_serverhello,
3242 },
Adam Langley273d49c2015-07-20 16:38:52 -07003243 {
David Schinazi3d8b8c32021-01-14 11:25:49 -08003244 TLSEXT_TYPE_quic_transport_parameters_legacy,
David Schinazi3d8b8c32021-01-14 11:25:49 -08003245 ext_quic_transport_params_add_clienthello_legacy,
3246 ext_quic_transport_params_parse_serverhello_legacy,
3247 ext_quic_transport_params_parse_clienthello_legacy,
3248 ext_quic_transport_params_add_serverhello_legacy,
3249 },
3250 {
Adam Langleya307cb72018-05-02 09:06:48 -07003251 TLSEXT_TYPE_cert_compression,
Adam Langleya307cb72018-05-02 09:06:48 -07003252 cert_compression_add_clienthello,
3253 cert_compression_parse_serverhello,
3254 cert_compression_parse_clienthello,
3255 cert_compression_add_serverhello,
3256 },
Christopher Patton6c1b3762018-07-17 12:49:41 -07003257 {
3258 TLSEXT_TYPE_delegated_credential,
Christopher Patton6c1b3762018-07-17 12:49:41 -07003259 ext_delegated_credential_add_clienthello,
3260 forbid_parse_serverhello,
3261 ext_delegated_credential_parse_clienthello,
3262 dont_add_serverhello,
3263 },
Steven Valdez51607f12020-08-05 10:46:05 -04003264 {
3265 TLSEXT_TYPE_application_settings,
Steven Valdez51607f12020-08-05 10:46:05 -04003266 ext_alps_add_clienthello,
3267 ext_alps_parse_serverhello,
3268 // ALPS is negotiated late in |ssl_negotiate_alpn|.
3269 ignore_parse_clienthello,
3270 ext_alps_add_serverhello,
3271 },
Adam Langley614c66a2015-06-12 15:26:58 -07003272};
3273
3274#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
3275
David Benjamina3d76d02017-07-14 19:36:07 -04003276static_assert(kNumExtensions <=
3277 sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8,
3278 "too many extensions for sent bitset");
3279static_assert(kNumExtensions <=
3280 sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8,
3281 "too many extensions for received bitset");
Adam Langley4cfa96b2015-07-01 11:56:55 -07003282
David Benjamine9c5d722021-06-09 17:43:16 -04003283bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs) {
3284 if (!hs->config->permute_extensions) {
3285 return true;
3286 }
3287
3288 static_assert(kNumExtensions <= UINT8_MAX,
3289 "extensions_permutation type is too small");
3290 uint32_t seeds[kNumExtensions - 1];
3291 Array<uint8_t> permutation;
3292 if (!RAND_bytes(reinterpret_cast<uint8_t *>(seeds), sizeof(seeds)) ||
3293 !permutation.Init(kNumExtensions)) {
3294 return false;
3295 }
3296 for (size_t i = 0; i < kNumExtensions; i++) {
3297 permutation[i] = i;
3298 }
3299 for (size_t i = kNumExtensions - 1; i > 0; i--) {
3300 // Set element |i| to a randomly-selected element 0 <= j <= i.
3301 std::swap(permutation[i], permutation[seeds[i - 1] % (i + 1)]);
3302 }
3303 hs->extension_permutation = std::move(permutation);
3304 return true;
3305}
3306
Adam Langley614c66a2015-06-12 15:26:58 -07003307static const struct tls_extension *tls_extension_find(uint32_t *out_index,
3308 uint16_t value) {
3309 unsigned i;
3310 for (i = 0; i < kNumExtensions; i++) {
3311 if (kExtensions[i].value == value) {
3312 *out_index = i;
3313 return &kExtensions[i];
3314 }
3315 }
3316
3317 return NULL;
3318}
3319
David Benjaminfb4d2572021-06-01 15:58:30 -04003320static bool add_padding_extension(CBB *cbb, uint16_t ext, size_t len) {
3321 CBB child;
David Benjaminfb4d2572021-06-01 15:58:30 -04003322 if (!CBB_add_u16(cbb, ext) || //
3323 !CBB_add_u16_length_prefixed(cbb, &child) ||
David Benjamin95450622021-07-16 18:24:02 -04003324 !CBB_add_zeros(&child, len)) {
David Benjaminfb4d2572021-06-01 15:58:30 -04003325 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
3326 return false;
3327 }
David Benjaminfb4d2572021-06-01 15:58:30 -04003328 return CBB_flush(cbb);
3329}
3330
David Benjamin83a49932021-05-20 15:57:09 -04003331static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out,
3332 CBB *out_encoded,
3333 bool *out_needs_psk_binder) {
3334 // When writing ClientHelloInner, we construct the real and encoded
3335 // ClientHellos concurrently, to handle compression. Uncompressed extensions
3336 // are written to |extensions| and copied to |extensions_encoded|. Compressed
3337 // extensions are buffered in |compressed| and written to the end. (ECH can
3338 // only compress continguous extensions.)
3339 SSL *const ssl = hs->ssl;
3340 bssl::ScopedCBB compressed, outer_extensions;
3341 CBB extensions, extensions_encoded;
3342 if (!CBB_add_u16_length_prefixed(out, &extensions) ||
3343 !CBB_add_u16_length_prefixed(out_encoded, &extensions_encoded) ||
3344 !CBB_init(compressed.get(), 64) ||
3345 !CBB_init(outer_extensions.get(), 64)) {
3346 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
3347 return false;
3348 }
3349
3350 hs->inner_extensions_sent = 0;
3351
3352 if (ssl->ctx->grease_enabled) {
3353 // Add a fake empty extension. See RFC 8701. This always matches
3354 // |ssl_add_clienthello_tlsext|, so compress it.
3355 uint16_t grease_ext = ssl_get_grease_value(hs, ssl_grease_extension1);
3356 if (!add_padding_extension(compressed.get(), grease_ext, 0) ||
3357 !CBB_add_u16(outer_extensions.get(), grease_ext)) {
3358 return false;
3359 }
3360 }
3361
David Benjamine9c5d722021-06-09 17:43:16 -04003362 for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) {
3363 size_t i = hs->extension_permutation.empty()
3364 ? unpermuted
3365 : hs->extension_permutation[unpermuted];
David Benjamin83a49932021-05-20 15:57:09 -04003366 const size_t len_before = CBB_len(&extensions);
3367 const size_t len_compressed_before = CBB_len(compressed.get());
3368 if (!kExtensions[i].add_clienthello(hs, &extensions, compressed.get(),
3369 ssl_client_hello_inner)) {
3370 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
3371 ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
3372 return false;
3373 }
3374
3375 const size_t bytes_written = CBB_len(&extensions) - len_before;
3376 const size_t bytes_written_compressed =
3377 CBB_len(compressed.get()) - len_compressed_before;
3378 // The callback may write to at most one output.
3379 assert(bytes_written == 0 || bytes_written_compressed == 0);
3380 if (bytes_written != 0 || bytes_written_compressed != 0) {
3381 hs->inner_extensions_sent |= (1u << i);
3382 }
3383 // If compressed, update the running ech_outer_extensions extension.
3384 if (bytes_written_compressed != 0 &&
3385 !CBB_add_u16(outer_extensions.get(), kExtensions[i].value)) {
3386 return false;
3387 }
3388 }
3389
3390 if (ssl->ctx->grease_enabled) {
3391 // Add a fake non-empty extension. See RFC 8701. This always matches
3392 // |ssl_add_clienthello_tlsext|, so compress it.
3393 uint16_t grease_ext = ssl_get_grease_value(hs, ssl_grease_extension2);
3394 if (!add_padding_extension(compressed.get(), grease_ext, 1) ||
3395 !CBB_add_u16(outer_extensions.get(), grease_ext)) {
3396 return false;
3397 }
3398 }
3399
David Benjamin83a49932021-05-20 15:57:09 -04003400 // Uncompressed extensions are encoded as-is.
3401 if (!CBB_add_bytes(&extensions_encoded, CBB_data(&extensions),
3402 CBB_len(&extensions))) {
3403 return false;
3404 }
3405
3406 // Flush all the compressed extensions.
3407 if (CBB_len(compressed.get()) != 0) {
3408 CBB extension, child;
3409 // Copy them as-is in the real ClientHelloInner.
3410 if (!CBB_add_bytes(&extensions, CBB_data(compressed.get()),
3411 CBB_len(compressed.get())) ||
3412 // Replace with ech_outer_extensions in the encoded form.
3413 !CBB_add_u16(&extensions_encoded, TLSEXT_TYPE_ech_outer_extensions) ||
3414 !CBB_add_u16_length_prefixed(&extensions_encoded, &extension) ||
3415 !CBB_add_u8_length_prefixed(&extension, &child) ||
3416 !CBB_add_bytes(&child, CBB_data(outer_extensions.get()),
3417 CBB_len(outer_extensions.get())) ||
3418 !CBB_flush(&extensions_encoded)) {
3419 return false;
3420 }
3421 }
3422
3423 // The PSK extension must be last. It is never compressed. Note, if there is a
3424 // binder, the caller will need to update both ClientHelloInner and
3425 // EncodedClientHelloInner after computing it.
3426 const size_t len_before = CBB_len(&extensions);
3427 if (!ext_pre_shared_key_add_clienthello(hs, &extensions, out_needs_psk_binder,
3428 ssl_client_hello_inner) ||
3429 !CBB_add_bytes(&extensions_encoded, CBB_data(&extensions) + len_before,
3430 CBB_len(&extensions) - len_before) ||
3431 !CBB_flush(out) || //
3432 !CBB_flush(out_encoded)) {
3433 return false;
3434 }
3435
3436 return true;
3437}
3438
3439bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
3440 bool *out_needs_psk_binder,
David Benjamin18b68362021-06-18 23:13:46 -04003441 ssl_client_hello_type_t type,
3442 size_t header_len) {
David Benjamin83a49932021-05-20 15:57:09 -04003443 *out_needs_psk_binder = false;
3444
3445 if (type == ssl_client_hello_inner) {
3446 return ssl_add_clienthello_tlsext_inner(hs, out, out_encoded,
3447 out_needs_psk_binder);
3448 }
3449
3450 assert(out_encoded == nullptr); // Only ClientHelloInner needs two outputs.
David Benjamin8c880a22016-12-03 02:20:34 -05003451 SSL *const ssl = hs->ssl;
David Benjamine8d53502015-10-10 14:13:23 -04003452 CBB extensions;
3453 if (!CBB_add_u16_length_prefixed(out, &extensions)) {
David Benjamin81678aa2017-07-12 22:43:42 -04003454 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin861abcc2018-07-14 17:40:26 -04003455 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003456 }
Adam Langley95c29f32014-06-20 12:00:00 -07003457
David Benjamin64770122019-05-04 11:00:04 -05003458 // Note we may send multiple ClientHellos for DTLS HelloVerifyRequest and TLS
3459 // 1.3 HelloRetryRequest. For the latter, the extensions may change, so it is
3460 // important to reset this value.
David Benjamin8c880a22016-12-03 02:20:34 -05003461 hs->extensions.sent = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07003462
David Benjaminfb4d2572021-06-01 15:58:30 -04003463 // Add a fake empty extension. See RFC 8701.
3464 if (ssl->ctx->grease_enabled &&
3465 !add_padding_extension(
3466 &extensions, ssl_get_grease_value(hs, ssl_grease_extension1), 0)) {
3467 return false;
David Benjamin65ac9972016-09-02 21:35:25 -04003468 }
3469
Adam Langley7f4f41f2018-08-23 08:58:49 -07003470 bool last_was_empty = false;
David Benjamine9c5d722021-06-09 17:43:16 -04003471 for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) {
3472 size_t i = hs->extension_permutation.empty()
3473 ? unpermuted
3474 : hs->extension_permutation[unpermuted];
David Benjamin18b68362021-06-18 23:13:46 -04003475 const size_t len_before = CBB_len(&extensions);
3476 if (!kExtensions[i].add_clienthello(hs, &extensions, &extensions, type)) {
3477 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
3478 ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
3479 return false;
David Benjamin83a49932021-05-20 15:57:09 -04003480 }
David Benjamin18b68362021-06-18 23:13:46 -04003481
3482 const size_t bytes_written = CBB_len(&extensions) - len_before;
Adam Langley7f4f41f2018-08-23 08:58:49 -07003483 if (bytes_written != 0) {
David Benjamin8c880a22016-12-03 02:20:34 -05003484 hs->extensions.sent |= (1u << i);
Adam Langley614c66a2015-06-12 15:26:58 -07003485 }
Adam Langley7f4f41f2018-08-23 08:58:49 -07003486 // If the difference in lengths is only four bytes then the extension had
3487 // an empty body.
3488 last_was_empty = (bytes_written == 4);
Adam Langleyfcf25832014-12-18 17:42:32 -08003489 }
Adam Langley75712922014-10-10 16:23:43 -07003490
David Benjamin65ac9972016-09-02 21:35:25 -04003491 if (ssl->ctx->grease_enabled) {
David Benjamin3675eb32021-05-18 14:01:07 -04003492 // Add a fake non-empty extension. See RFC 8701.
David Benjaminfb4d2572021-06-01 15:58:30 -04003493 if (!add_padding_extension(
3494 &extensions, ssl_get_grease_value(hs, ssl_grease_extension2), 1)) {
David Benjamin861abcc2018-07-14 17:40:26 -04003495 return false;
David Benjamin65ac9972016-09-02 21:35:25 -04003496 }
Adam Langley7f4f41f2018-08-23 08:58:49 -07003497 last_was_empty = false;
David Benjamin65ac9972016-09-02 21:35:25 -04003498 }
3499
David Benjamin83a49932021-05-20 15:57:09 -04003500 // In cleartext ClientHellos, we add the padding extension to work around
3501 // bugs. We also apply this padding to ClientHelloOuter, to keep the wire
3502 // images aligned.
3503 size_t psk_extension_len = ext_pre_shared_key_clienthello_length(hs, type);
David Benjamincd890042021-06-02 18:35:31 -04003504 if (!SSL_is_dtls(ssl) && !ssl->quic_method &&
3505 !ssl->s3->used_hello_retry_request) {
David Benjamin18b68362021-06-18 23:13:46 -04003506 header_len +=
3507 SSL3_HM_HEADER_LENGTH + 2 + CBB_len(&extensions) + psk_extension_len;
Adam Langley7f4f41f2018-08-23 08:58:49 -07003508 size_t padding_len = 0;
3509
3510 // The final extension must be non-empty. WebSphere Application
3511 // Server 7.0 is intolerant to the last extension being zero-length. See
3512 // https://crbug.com/363583.
3513 if (last_was_empty && psk_extension_len == 0) {
3514 padding_len = 1;
3515 // The addition of the padding extension may push us into the F5 bug.
3516 header_len += 4 + padding_len;
3517 }
3518
3519 // Add padding to workaround bugs in F5 terminators. See RFC 7685.
3520 //
3521 // NB: because this code works out the length of all existing extensions
3522 // it MUST always appear last (save for any PSK extension).
Adam Langleyfcf25832014-12-18 17:42:32 -08003523 if (header_len > 0xff && header_len < 0x200) {
Adam Langley7f4f41f2018-08-23 08:58:49 -07003524 // If our calculations already included a padding extension, remove that
3525 // factor because we're about to change its length.
3526 if (padding_len != 0) {
3527 header_len -= 4 + padding_len;
3528 }
3529 padding_len = 0x200 - header_len;
David Benjaminc11ea9422017-08-29 16:33:21 -04003530 // Extensions take at least four bytes to encode. Always include at least
3531 // one byte of data if including the extension. WebSphere Application
3532 // Server 7.0 is intolerant to the last extension being zero-length. See
3533 // https://crbug.com/363583.
Adam Langleyfcf25832014-12-18 17:42:32 -08003534 if (padding_len >= 4 + 1) {
3535 padding_len -= 4;
3536 } else {
3537 padding_len = 1;
3538 }
Adam Langley7f4f41f2018-08-23 08:58:49 -07003539 }
Adam Langley95c29f32014-06-20 12:00:00 -07003540
David Benjaminfb4d2572021-06-01 15:58:30 -04003541 if (padding_len != 0 &&
3542 !add_padding_extension(&extensions, TLSEXT_TYPE_padding, padding_len)) {
3543 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003544 }
3545 }
Adam Langley75712922014-10-10 16:23:43 -07003546
David Benjaminc11ea9422017-08-29 16:33:21 -04003547 // The PSK extension must be last, including after the padding.
David Benjamin350fe3b2021-06-02 17:58:53 -04003548 const size_t len_before = CBB_len(&extensions);
David Benjamin83a49932021-05-20 15:57:09 -04003549 if (!ext_pre_shared_key_add_clienthello(hs, &extensions, out_needs_psk_binder,
3550 type)) {
David Benjamin81678aa2017-07-12 22:43:42 -04003551 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin861abcc2018-07-14 17:40:26 -04003552 return false;
Steven Valdeza833c352016-11-01 13:39:36 -04003553 }
David Benjamin350fe3b2021-06-02 17:58:53 -04003554 assert(psk_extension_len == CBB_len(&extensions) - len_before);
3555 (void)len_before; // |assert| is omitted in release builds.
Steven Valdeza833c352016-11-01 13:39:36 -04003556
David Benjaminc11ea9422017-08-29 16:33:21 -04003557 // Discard empty extensions blocks.
David Benjamina01deee2015-12-08 18:56:31 -05003558 if (CBB_len(&extensions) == 0) {
David Benjamine8d53502015-10-10 14:13:23 -04003559 CBB_discard_child(out);
Adam Langley33ad2b52015-07-20 17:43:53 -07003560 }
3561
David Benjamine8d53502015-10-10 14:13:23 -04003562 return CBB_flush(out);
Adam Langleyfcf25832014-12-18 17:42:32 -08003563}
Adam Langley95c29f32014-06-20 12:00:00 -07003564
David Benjamin861abcc2018-07-14 17:40:26 -04003565bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) {
David Benjamin8c880a22016-12-03 02:20:34 -05003566 SSL *const ssl = hs->ssl;
David Benjamin56380462015-10-10 14:59:09 -04003567 CBB extensions;
3568 if (!CBB_add_u16_length_prefixed(out, &extensions)) {
Adam Langley33ad2b52015-07-20 17:43:53 -07003569 goto err;
Adam Langley614c66a2015-06-12 15:26:58 -07003570 }
3571
David Benjamin8c880a22016-12-03 02:20:34 -05003572 for (unsigned i = 0; i < kNumExtensions; i++) {
3573 if (!(hs->extensions.received & (1u << i))) {
David Benjaminc11ea9422017-08-29 16:33:21 -04003574 // Don't send extensions that were not received.
Adam Langley614c66a2015-06-12 15:26:58 -07003575 continue;
Adam Langleyfcf25832014-12-18 17:42:32 -08003576 }
Adam Langley95c29f32014-06-20 12:00:00 -07003577
David Benjamin8c880a22016-12-03 02:20:34 -05003578 if (!kExtensions[i].add_serverhello(hs, &extensions)) {
Adam Langley33ad2b52015-07-20 17:43:53 -07003579 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
Adam Langleyfbbef122016-11-17 12:55:14 -08003580 ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
Adam Langley33ad2b52015-07-20 17:43:53 -07003581 goto err;
Adam Langley614c66a2015-06-12 15:26:58 -07003582 }
Adam Langleyfcf25832014-12-18 17:42:32 -08003583 }
Adam Langley95c29f32014-06-20 12:00:00 -07003584
David Benjaminc11ea9422017-08-29 16:33:21 -04003585 // Discard empty extensions blocks before TLS 1.3.
David Benjamind1e3ce12017-10-06 18:31:15 -04003586 if (ssl_protocol_version(ssl) < TLS1_3_VERSION &&
Steven Valdez143e8b32016-07-11 13:19:03 -04003587 CBB_len(&extensions) == 0) {
David Benjamin56380462015-10-10 14:59:09 -04003588 CBB_discard_child(out);
Adam Langley33ad2b52015-07-20 17:43:53 -07003589 }
3590
David Benjamin56380462015-10-10 14:59:09 -04003591 return CBB_flush(out);
Adam Langley33ad2b52015-07-20 17:43:53 -07003592
3593err:
Adam Langley33ad2b52015-07-20 17:43:53 -07003594 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin861abcc2018-07-14 17:40:26 -04003595 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003596}
Adam Langley95c29f32014-06-20 12:00:00 -07003597
David Benjamin861abcc2018-07-14 17:40:26 -04003598static bool ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs,
3599 const SSL_CLIENT_HELLO *client_hello,
3600 int *out_alert) {
David Benjamin8c880a22016-12-03 02:20:34 -05003601 hs->extensions.received = 0;
David Benjamine14ff062016-08-09 16:21:24 -04003602 CBS extensions;
3603 CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
3604 while (CBS_len(&extensions) != 0) {
3605 uint16_t type;
3606 CBS extension;
3607
David Benjaminc11ea9422017-08-29 16:33:21 -04003608 // Decode the next extension.
David Benjamine14ff062016-08-09 16:21:24 -04003609 if (!CBS_get_u16(&extensions, &type) ||
3610 !CBS_get_u16_length_prefixed(&extensions, &extension)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08003611 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin861abcc2018-07-14 17:40:26 -04003612 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003613 }
Adam Langley95c29f32014-06-20 12:00:00 -07003614
David Benjamine14ff062016-08-09 16:21:24 -04003615 unsigned ext_index;
3616 const struct tls_extension *const ext =
3617 tls_extension_find(&ext_index, type);
David Benjamine14ff062016-08-09 16:21:24 -04003618 if (ext == NULL) {
David Benjamine14ff062016-08-09 16:21:24 -04003619 continue;
3620 }
3621
David Benjamin8c880a22016-12-03 02:20:34 -05003622 hs->extensions.received |= (1u << ext_index);
David Benjamine14ff062016-08-09 16:21:24 -04003623 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8c880a22016-12-03 02:20:34 -05003624 if (!ext->parse_clienthello(hs, &alert, &extension)) {
David Benjamine14ff062016-08-09 16:21:24 -04003625 *out_alert = alert;
3626 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
Adam Langleyfbbef122016-11-17 12:55:14 -08003627 ERR_add_error_dataf("extension %u", (unsigned)type);
David Benjamin861abcc2018-07-14 17:40:26 -04003628 return false;
Adam Langley614c66a2015-06-12 15:26:58 -07003629 }
Adam Langleyfcf25832014-12-18 17:42:32 -08003630 }
Adam Langley75712922014-10-10 16:23:43 -07003631
David Benjamin1deb41b2016-08-09 19:36:38 -04003632 for (size_t i = 0; i < kNumExtensions; i++) {
David Benjamin8c880a22016-12-03 02:20:34 -05003633 if (hs->extensions.received & (1u << i)) {
David Benjamin1deb41b2016-08-09 19:36:38 -04003634 continue;
3635 }
3636
3637 CBS *contents = NULL, fake_contents;
3638 static const uint8_t kFakeRenegotiateExtension[] = {0};
3639 if (kExtensions[i].value == TLSEXT_TYPE_renegotiate &&
3640 ssl_client_cipher_list_contains_cipher(client_hello,
3641 SSL3_CK_SCSV & 0xffff)) {
David Benjaminc11ea9422017-08-29 16:33:21 -04003642 // The renegotiation SCSV was received so pretend that we received a
3643 // renegotiation extension.
David Benjamin1deb41b2016-08-09 19:36:38 -04003644 CBS_init(&fake_contents, kFakeRenegotiateExtension,
3645 sizeof(kFakeRenegotiateExtension));
3646 contents = &fake_contents;
David Benjamin8c880a22016-12-03 02:20:34 -05003647 hs->extensions.received |= (1u << i);
David Benjamin1deb41b2016-08-09 19:36:38 -04003648 }
3649
David Benjaminc11ea9422017-08-29 16:33:21 -04003650 // Extension wasn't observed so call the callback with a NULL
3651 // parameter.
David Benjamin1deb41b2016-08-09 19:36:38 -04003652 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8c880a22016-12-03 02:20:34 -05003653 if (!kExtensions[i].parse_clienthello(hs, &alert, contents)) {
David Benjamin1deb41b2016-08-09 19:36:38 -04003654 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
Adam Langleyfbbef122016-11-17 12:55:14 -08003655 ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
David Benjamin1deb41b2016-08-09 19:36:38 -04003656 *out_alert = alert;
David Benjamin861abcc2018-07-14 17:40:26 -04003657 return false;
Adam Langley614c66a2015-06-12 15:26:58 -07003658 }
3659 }
3660
David Benjamin861abcc2018-07-14 17:40:26 -04003661 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08003662}
Adam Langley95c29f32014-06-20 12:00:00 -07003663
David Benjamin861abcc2018-07-14 17:40:26 -04003664bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs,
3665 const SSL_CLIENT_HELLO *client_hello) {
David Benjamin8c880a22016-12-03 02:20:34 -05003666 SSL *const ssl = hs->ssl;
Adam Langleyc68e5b92017-02-08 13:33:15 -08003667 int alert = SSL_AD_DECODE_ERROR;
David Benjamin861abcc2018-07-14 17:40:26 -04003668 if (!ssl_scan_clienthello_tlsext(hs, client_hello, &alert)) {
David Benjamind1e3ce12017-10-06 18:31:15 -04003669 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin861abcc2018-07-14 17:40:26 -04003670 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003671 }
Adam Langley95c29f32014-06-20 12:00:00 -07003672
David Benjamin861abcc2018-07-14 17:40:26 -04003673 if (!ssl_check_clienthello_tlsext(hs)) {
David Benjamin3570d732015-06-29 00:28:17 -04003674 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT);
David Benjamin861abcc2018-07-14 17:40:26 -04003675 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003676 }
Adam Langley95c29f32014-06-20 12:00:00 -07003677
David Benjamin861abcc2018-07-14 17:40:26 -04003678 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08003679}
Adam Langley95c29f32014-06-20 12:00:00 -07003680
David Benjamine2cb4232021-06-23 18:14:22 -04003681static bool ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs,
David Benjamin861abcc2018-07-14 17:40:26 -04003682 int *out_alert) {
David Benjamine2cb4232021-06-23 18:14:22 -04003683 CBS extensions = *cbs;
3684 if (!tls1_check_duplicate_extensions(&extensions)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04003685 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin861abcc2018-07-14 17:40:26 -04003686 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04003687 }
3688
3689 uint32_t received = 0;
3690 while (CBS_len(&extensions) != 0) {
3691 uint16_t type;
3692 CBS extension;
3693
David Benjaminc11ea9422017-08-29 16:33:21 -04003694 // Decode the next extension.
Steven Valdez143e8b32016-07-11 13:19:03 -04003695 if (!CBS_get_u16(&extensions, &type) ||
3696 !CBS_get_u16_length_prefixed(&extensions, &extension)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08003697 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamin861abcc2018-07-14 17:40:26 -04003698 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003699 }
Adam Langley95c29f32014-06-20 12:00:00 -07003700
Steven Valdez143e8b32016-07-11 13:19:03 -04003701 unsigned ext_index;
3702 const struct tls_extension *const ext =
3703 tls_extension_find(&ext_index, type);
Adam Langley614c66a2015-06-12 15:26:58 -07003704
Steven Valdez143e8b32016-07-11 13:19:03 -04003705 if (ext == NULL) {
David Benjamin0a3e07a2018-07-09 16:28:22 -04003706 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
3707 ERR_add_error_dataf("extension %u", (unsigned)type);
3708 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
David Benjamin861abcc2018-07-14 17:40:26 -04003709 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04003710 }
Adam Langley33ad2b52015-07-20 17:43:53 -07003711
David Benjamina3d76d02017-07-14 19:36:07 -04003712 static_assert(kNumExtensions <= sizeof(hs->extensions.sent) * 8,
3713 "too many bits");
David Benjamin5db7c9b2017-01-24 16:17:03 -05003714
David Benjaminc59b9aa2018-07-16 21:34:03 -04003715 if (!(hs->extensions.sent & (1u << ext_index))) {
3716 // If the extension was never sent then it is illegal.
Steven Valdez143e8b32016-07-11 13:19:03 -04003717 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
3718 ERR_add_error_dataf("extension :%u", (unsigned)type);
David Benjamin0c40a962016-08-01 12:05:50 -04003719 *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
David Benjamin861abcc2018-07-14 17:40:26 -04003720 return false;
Steven Valdez143e8b32016-07-11 13:19:03 -04003721 }
Adam Langley33ad2b52015-07-20 17:43:53 -07003722
Steven Valdez143e8b32016-07-11 13:19:03 -04003723 received |= (1u << ext_index);
Adam Langley09505632015-07-30 18:10:13 -07003724
Steven Valdez143e8b32016-07-11 13:19:03 -04003725 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8c880a22016-12-03 02:20:34 -05003726 if (!ext->parse_serverhello(hs, &alert, &extension)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04003727 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
Adam Langleyfbbef122016-11-17 12:55:14 -08003728 ERR_add_error_dataf("extension %u", (unsigned)type);
Steven Valdez143e8b32016-07-11 13:19:03 -04003729 *out_alert = alert;
David Benjamin861abcc2018-07-14 17:40:26 -04003730 return false;
Adam Langley614c66a2015-06-12 15:26:58 -07003731 }
Adam Langleyfcf25832014-12-18 17:42:32 -08003732 }
Adam Langley95c29f32014-06-20 12:00:00 -07003733
David Benjamin54091232016-09-05 12:47:25 -04003734 for (size_t i = 0; i < kNumExtensions; i++) {
Adam Langley614c66a2015-06-12 15:26:58 -07003735 if (!(received & (1u << i))) {
David Benjaminc11ea9422017-08-29 16:33:21 -04003736 // Extension wasn't observed so call the callback with a NULL
3737 // parameter.
Adam Langley614c66a2015-06-12 15:26:58 -07003738 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8c880a22016-12-03 02:20:34 -05003739 if (!kExtensions[i].parse_serverhello(hs, &alert, NULL)) {
Adam Langley33ad2b52015-07-20 17:43:53 -07003740 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
Adam Langleyfbbef122016-11-17 12:55:14 -08003741 ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
Adam Langley614c66a2015-06-12 15:26:58 -07003742 *out_alert = alert;
David Benjamin861abcc2018-07-14 17:40:26 -04003743 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003744 }
Adam Langleyfcf25832014-12-18 17:42:32 -08003745 }
3746 }
Adam Langley95c29f32014-06-20 12:00:00 -07003747
David Benjamin861abcc2018-07-14 17:40:26 -04003748 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08003749}
Adam Langley95c29f32014-06-20 12:00:00 -07003750
David Benjamin861abcc2018-07-14 17:40:26 -04003751static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
David Benjamin8c880a22016-12-03 02:20:34 -05003752 SSL *const ssl = hs->ssl;
Adam Langleyfcf25832014-12-18 17:42:32 -08003753 int ret = SSL_TLSEXT_ERR_NOACK;
3754 int al = SSL_AD_UNRECOGNIZED_NAME;
David Benjamin46853762018-07-03 14:01:26 -04003755 if (ssl->ctx->servername_callback != 0) {
3756 ret = ssl->ctx->servername_callback(ssl, &al, ssl->ctx->servername_arg);
3757 } else if (ssl->session_ctx->servername_callback != 0) {
3758 ret = ssl->session_ctx->servername_callback(
3759 ssl, &al, ssl->session_ctx->servername_arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08003760 }
Adam Langley95c29f32014-06-20 12:00:00 -07003761
Adam Langleyfcf25832014-12-18 17:42:32 -08003762 switch (ret) {
3763 case SSL_TLSEXT_ERR_ALERT_FATAL:
David Benjamind1e3ce12017-10-06 18:31:15 -04003764 ssl_send_alert(ssl, SSL3_AL_FATAL, al);
David Benjamin861abcc2018-07-14 17:40:26 -04003765 return false;
Adam Langley95c29f32014-06-20 12:00:00 -07003766
Adam Langleyfcf25832014-12-18 17:42:32 -08003767 case SSL_TLSEXT_ERR_NOACK:
David Benjaminfd45ee72017-08-31 14:49:09 -04003768 hs->should_ack_sni = false;
David Benjamin861abcc2018-07-14 17:40:26 -04003769 return true;
Adam Langley95c29f32014-06-20 12:00:00 -07003770
Adam Langleyfcf25832014-12-18 17:42:32 -08003771 default:
David Benjamin861abcc2018-07-14 17:40:26 -04003772 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08003773 }
3774}
Adam Langleyed8270a2014-09-02 13:52:56 -07003775
Steven Valdez51607f12020-08-05 10:46:05 -04003776static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) {
3777 SSL *const ssl = hs->ssl;
3778 // ALPS and ALPN have a dependency between each other, so we defer checking
3779 // consistency to after the callbacks run.
3780 if (hs->new_session != nullptr && hs->new_session->has_application_settings) {
3781 // ALPN must be negotiated.
3782 if (ssl->s3->alpn_selected.empty()) {
3783 OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_ALPS_WITHOUT_ALPN);
3784 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
3785 return false;
3786 }
3787
3788 // The negotiated protocol must be one of the ones we advertised for ALPS.
3789 Span<const uint8_t> settings;
3790 if (!ssl_get_local_application_settings(hs, &settings,
3791 ssl->s3->alpn_selected)) {
3792 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
3793 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
3794 return false;
3795 }
3796
3797 if (!hs->new_session->local_application_settings.CopyFrom(settings)) {
3798 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
3799 return false;
3800 }
3801 }
3802
3803 return true;
3804}
3805
David Benjamine2cb4232021-06-23 18:14:22 -04003806bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs) {
David Benjamin8c880a22016-12-03 02:20:34 -05003807 SSL *const ssl = hs->ssl;
Adam Langleyc68e5b92017-02-08 13:33:15 -08003808 int alert = SSL_AD_DECODE_ERROR;
David Benjamin861abcc2018-07-14 17:40:26 -04003809 if (!ssl_scan_serverhello_tlsext(hs, cbs, &alert)) {
David Benjamind1e3ce12017-10-06 18:31:15 -04003810 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin861abcc2018-07-14 17:40:26 -04003811 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08003812 }
3813
Steven Valdez51607f12020-08-05 10:46:05 -04003814 if (!ssl_check_serverhello_tlsext(hs)) {
3815 return false;
3816 }
3817
David Benjamin861abcc2018-07-14 17:40:26 -04003818 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08003819}
Adam Langley95c29f32014-06-20 12:00:00 -07003820
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003821static enum ssl_ticket_aead_result_t decrypt_ticket_with_cipher_ctx(
David Benjamin28655672018-07-18 23:23:25 -04003822 Array<uint8_t> *out, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hmac_ctx,
3823 Span<const uint8_t> ticket) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003824 size_t iv_len = EVP_CIPHER_CTX_iv_length(cipher_ctx);
Adam Langleyfcf25832014-12-18 17:42:32 -08003825
David Benjaminc11ea9422017-08-29 16:33:21 -04003826 // Check the MAC at the end of the ticket.
David Benjamine3aa1d92015-06-16 15:34:50 -04003827 uint8_t mac[EVP_MAX_MD_SIZE];
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003828 size_t mac_len = HMAC_size(hmac_ctx);
David Benjamin28655672018-07-18 23:23:25 -04003829 if (ticket.size() < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) {
David Benjaminc11ea9422017-08-29 16:33:21 -04003830 // The ticket must be large enough for key name, IV, data, and MAC.
David Benjamin81678aa2017-07-12 22:43:42 -04003831 return ssl_ticket_aead_ignore_ticket;
Adam Langleyfcf25832014-12-18 17:42:32 -08003832 }
David Benjamin28655672018-07-18 23:23:25 -04003833 // Split the ticket into the ticket and the MAC.
David Benjamin006f20a2021-06-22 23:00:49 -04003834 auto ticket_mac = ticket.last(mac_len);
3835 ticket = ticket.first(ticket.size() - mac_len);
David Benjamin28655672018-07-18 23:23:25 -04003836 HMAC_Update(hmac_ctx, ticket.data(), ticket.size());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003837 HMAC_Final(hmac_ctx, mac, NULL);
David Benjamin28655672018-07-18 23:23:25 -04003838 assert(mac_len == ticket_mac.size());
3839 bool mac_ok = CRYPTO_memcmp(mac, ticket_mac.data(), mac_len) == 0;
David Benjaminfbc45d72016-09-22 01:21:24 -04003840#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
David Benjamin861abcc2018-07-14 17:40:26 -04003841 mac_ok = true;
David Benjaminfbc45d72016-09-22 01:21:24 -04003842#endif
3843 if (!mac_ok) {
David Benjamin81678aa2017-07-12 22:43:42 -04003844 return ssl_ticket_aead_ignore_ticket;
Adam Langleyfcf25832014-12-18 17:42:32 -08003845 }
3846
David Benjaminc11ea9422017-08-29 16:33:21 -04003847 // Decrypt the session data.
David Benjamin28655672018-07-18 23:23:25 -04003848 auto ciphertext = ticket.subspan(SSL_TICKET_KEY_NAME_LEN + iv_len);
3849 Array<uint8_t> plaintext;
3850#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
3851 if (!plaintext.CopyFrom(ciphertext)) {
David Benjamin81678aa2017-07-12 22:43:42 -04003852 return ssl_ticket_aead_error;
Adam Langleyfcf25832014-12-18 17:42:32 -08003853 }
David Benjaminfbc45d72016-09-22 01:21:24 -04003854#else
David Benjamin28655672018-07-18 23:23:25 -04003855 if (ciphertext.size() >= INT_MAX) {
David Benjamin81678aa2017-07-12 22:43:42 -04003856 return ssl_ticket_aead_ignore_ticket;
Adam Langleyfcf25832014-12-18 17:42:32 -08003857 }
David Benjamin28655672018-07-18 23:23:25 -04003858 if (!plaintext.Init(ciphertext.size())) {
3859 return ssl_ticket_aead_error;
3860 }
David Benjamine3aa1d92015-06-16 15:34:50 -04003861 int len1, len2;
David Benjamin28655672018-07-18 23:23:25 -04003862 if (!EVP_DecryptUpdate(cipher_ctx, plaintext.data(), &len1, ciphertext.data(),
3863 (int)ciphertext.size()) ||
3864 !EVP_DecryptFinal_ex(cipher_ctx, plaintext.data() + len1, &len2)) {
Adam Langley4c341d02017-03-08 19:33:21 -08003865 ERR_clear_error();
David Benjamin81678aa2017-07-12 22:43:42 -04003866 return ssl_ticket_aead_ignore_ticket;
Adam Langleyfcf25832014-12-18 17:42:32 -08003867 }
David Benjamin28655672018-07-18 23:23:25 -04003868 plaintext.Shrink(static_cast<size_t>(len1) + len2);
David Benjaminfbc45d72016-09-22 01:21:24 -04003869#endif
Adam Langleyfcf25832014-12-18 17:42:32 -08003870
David Benjamin28655672018-07-18 23:23:25 -04003871 *out = std::move(plaintext);
David Benjamin81678aa2017-07-12 22:43:42 -04003872 return ssl_ticket_aead_success;
Adam Langley4c341d02017-03-08 19:33:21 -08003873}
3874
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003875static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_cb(
David Benjamin28655672018-07-18 23:23:25 -04003876 SSL_HANDSHAKE *hs, Array<uint8_t> *out, bool *out_renew_ticket,
3877 Span<const uint8_t> ticket) {
3878 assert(ticket.size() >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003879 ScopedEVP_CIPHER_CTX cipher_ctx;
3880 ScopedHMAC_CTX hmac_ctx;
David Benjamin28655672018-07-18 23:23:25 -04003881 auto name = ticket.subspan(0, SSL_TICKET_KEY_NAME_LEN);
3882 // The actual IV is shorter, but the length is determined by the callback's
3883 // chosen cipher. Instead we pass in |EVP_MAX_IV_LENGTH| worth of IV to ensure
3884 // the callback has enough.
3885 auto iv = ticket.subspan(SSL_TICKET_KEY_NAME_LEN, EVP_MAX_IV_LENGTH);
David Benjamin7bb0fbf2018-07-03 13:55:42 -04003886 int cb_ret = hs->ssl->session_ctx->ticket_key_cb(
David Benjamin28655672018-07-18 23:23:25 -04003887 hs->ssl, const_cast<uint8_t *>(name.data()),
3888 const_cast<uint8_t *>(iv.data()), cipher_ctx.get(), hmac_ctx.get(),
3889 0 /* decrypt */);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003890 if (cb_ret < 0) {
3891 return ssl_ticket_aead_error;
3892 } else if (cb_ret == 0) {
3893 return ssl_ticket_aead_ignore_ticket;
3894 } else if (cb_ret == 2) {
David Benjaminfd45ee72017-08-31 14:49:09 -04003895 *out_renew_ticket = true;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003896 } else {
3897 assert(cb_ret == 1);
3898 }
David Benjamin28655672018-07-18 23:23:25 -04003899 return decrypt_ticket_with_cipher_ctx(out, cipher_ctx.get(), hmac_ctx.get(),
3900 ticket);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003901}
3902
3903static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_ticket_keys(
David Benjamin28655672018-07-18 23:23:25 -04003904 SSL_HANDSHAKE *hs, Array<uint8_t> *out, Span<const uint8_t> ticket) {
3905 assert(ticket.size() >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH);
David Benjamin50596f82018-07-02 19:47:27 -04003906 SSL_CTX *ctx = hs->ssl->session_ctx.get();
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003907
David Benjaminc11ea9422017-08-29 16:33:21 -04003908 // Rotate the ticket key if necessary.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003909 if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) {
3910 return ssl_ticket_aead_error;
3911 }
3912
David Benjamin28655672018-07-18 23:23:25 -04003913 const EVP_CIPHER *cipher = EVP_aes_128_cbc();
3914 auto name = ticket.subspan(0, SSL_TICKET_KEY_NAME_LEN);
3915 auto iv =
3916 ticket.subspan(SSL_TICKET_KEY_NAME_LEN, EVP_CIPHER_iv_length(cipher));
3917
David Benjaminc11ea9422017-08-29 16:33:21 -04003918 // Pick the matching ticket key and decrypt.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003919 ScopedEVP_CIPHER_CTX cipher_ctx;
3920 ScopedHMAC_CTX hmac_ctx;
3921 {
3922 MutexReadLock lock(&ctx->lock);
David Benjamin7bb0fbf2018-07-03 13:55:42 -04003923 const TicketKey *key;
David Benjamin28655672018-07-18 23:23:25 -04003924 if (ctx->ticket_key_current && name == ctx->ticket_key_current->name) {
David Benjamin7bb0fbf2018-07-03 13:55:42 -04003925 key = ctx->ticket_key_current.get();
David Benjamin28655672018-07-18 23:23:25 -04003926 } else if (ctx->ticket_key_prev && name == ctx->ticket_key_prev->name) {
David Benjamin7bb0fbf2018-07-03 13:55:42 -04003927 key = ctx->ticket_key_prev.get();
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003928 } else {
3929 return ssl_ticket_aead_ignore_ticket;
3930 }
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003931 if (!HMAC_Init_ex(hmac_ctx.get(), key->hmac_key, sizeof(key->hmac_key),
3932 tlsext_tick_md(), NULL) ||
David Benjamin28655672018-07-18 23:23:25 -04003933 !EVP_DecryptInit_ex(cipher_ctx.get(), cipher, NULL,
3934 key->aes_key, iv.data())) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003935 return ssl_ticket_aead_error;
3936 }
3937 }
David Benjamin28655672018-07-18 23:23:25 -04003938 return decrypt_ticket_with_cipher_ctx(out, cipher_ctx.get(), hmac_ctx.get(),
3939 ticket);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003940}
3941
Adam Langley4c341d02017-03-08 19:33:21 -08003942static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method(
David Benjamin28655672018-07-18 23:23:25 -04003943 SSL_HANDSHAKE *hs, Array<uint8_t> *out, bool *out_renew_ticket,
3944 Span<const uint8_t> ticket) {
3945 Array<uint8_t> plaintext;
3946 if (!plaintext.Init(ticket.size())) {
Adam Langley4c341d02017-03-08 19:33:21 -08003947 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
3948 return ssl_ticket_aead_error;
3949 }
3950
3951 size_t plaintext_len;
3952 const enum ssl_ticket_aead_result_t result =
David Benjamin98472cb2018-05-02 16:05:36 -04003953 hs->ssl->session_ctx->ticket_aead_method->open(
David Benjamin28655672018-07-18 23:23:25 -04003954 hs->ssl, plaintext.data(), &plaintext_len, ticket.size(),
3955 ticket.data(), ticket.size());
3956 if (result != ssl_ticket_aead_success) {
3957 return result;
Adam Langley4c341d02017-03-08 19:33:21 -08003958 }
3959
David Benjamin28655672018-07-18 23:23:25 -04003960 plaintext.Shrink(plaintext_len);
3961 *out = std::move(plaintext);
3962 return ssl_ticket_aead_success;
Adam Langley4c341d02017-03-08 19:33:21 -08003963}
3964
3965enum ssl_ticket_aead_result_t ssl_process_ticket(
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003966 SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
David Benjamin28655672018-07-18 23:23:25 -04003967 bool *out_renew_ticket, Span<const uint8_t> ticket,
3968 Span<const uint8_t> session_id) {
David Benjaminb571e772021-03-25 19:42:16 -04003969 SSL *const ssl = hs->ssl;
David Benjaminfd45ee72017-08-31 14:49:09 -04003970 *out_renew_ticket = false;
David Benjamin37af90f2017-07-29 01:42:16 -04003971 out_session->reset();
Adam Langley4c341d02017-03-08 19:33:21 -08003972
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003973 if ((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) ||
David Benjamin28655672018-07-18 23:23:25 -04003974 session_id.size() > SSL_MAX_SSL_SESSION_ID_LENGTH) {
Adam Langley4c341d02017-03-08 19:33:21 -08003975 return ssl_ticket_aead_ignore_ticket;
3976 }
3977
David Benjaminb571e772021-03-25 19:42:16 -04003978 // Tickets in TLS 1.3 are tied into pre-shared keys (PSKs), unlike in TLS 1.2
3979 // where that concept doesn't exist. The |decrypted_psk| and |ignore_psk|
3980 // hints only apply to PSKs. We check the version to determine which this is.
3981 const bool is_psk = ssl_protocol_version(ssl) >= TLS1_3_VERSION;
3982
David Benjamin28655672018-07-18 23:23:25 -04003983 Array<uint8_t> plaintext;
Adam Langley4c341d02017-03-08 19:33:21 -08003984 enum ssl_ticket_aead_result_t result;
David Benjaminb571e772021-03-25 19:42:16 -04003985 SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
3986 if (is_psk && hints && !hs->hints_requested &&
3987 !hints->decrypted_psk.empty()) {
3988 result = plaintext.CopyFrom(hints->decrypted_psk) ? ssl_ticket_aead_success
3989 : ssl_ticket_aead_error;
3990 } else if (is_psk && hints && !hs->hints_requested && hints->ignore_psk) {
3991 result = ssl_ticket_aead_ignore_ticket;
David Benjaminadaa3222022-08-02 17:10:53 -07003992 } else if (!is_psk && hints && !hs->hints_requested &&
3993 !hints->decrypted_ticket.empty()) {
3994 if (plaintext.CopyFrom(hints->decrypted_ticket)) {
3995 result = ssl_ticket_aead_success;
3996 *out_renew_ticket = hints->renew_ticket;
3997 } else {
3998 result = ssl_ticket_aead_error;
3999 }
4000 } else if (!is_psk && hints && !hs->hints_requested && hints->ignore_ticket) {
4001 result = ssl_ticket_aead_ignore_ticket;
David Benjaminb571e772021-03-25 19:42:16 -04004002 } else if (ssl->session_ctx->ticket_aead_method != NULL) {
David Benjamin28655672018-07-18 23:23:25 -04004003 result = ssl_decrypt_ticket_with_method(hs, &plaintext, out_renew_ticket,
4004 ticket);
Adam Langley4c341d02017-03-08 19:33:21 -08004005 } else {
David Benjamin7bb0fbf2018-07-03 13:55:42 -04004006 // Ensure there is room for the key name and the largest IV |ticket_key_cb|
4007 // may try to consume. The real limit may be lower, but the maximum IV
4008 // length should be well under the minimum size for the session material and
4009 // HMAC.
David Benjamin28655672018-07-18 23:23:25 -04004010 if (ticket.size() < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) {
David Benjaminb571e772021-03-25 19:42:16 -04004011 result = ssl_ticket_aead_ignore_ticket;
4012 } else if (ssl->session_ctx->ticket_key_cb != NULL) {
David Benjamin28655672018-07-18 23:23:25 -04004013 result =
4014 ssl_decrypt_ticket_with_cb(hs, &plaintext, out_renew_ticket, ticket);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004015 } else {
David Benjamin28655672018-07-18 23:23:25 -04004016 result = ssl_decrypt_ticket_with_ticket_keys(hs, &plaintext, ticket);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004017 }
Adam Langley4c341d02017-03-08 19:33:21 -08004018 }
4019
David Benjaminadaa3222022-08-02 17:10:53 -07004020 if (hints && hs->hints_requested) {
David Benjaminb571e772021-03-25 19:42:16 -04004021 if (result == ssl_ticket_aead_ignore_ticket) {
David Benjaminadaa3222022-08-02 17:10:53 -07004022 if (is_psk) {
4023 hints->ignore_psk = true;
4024 } else {
4025 hints->ignore_ticket = true;
4026 }
4027 } else if (result == ssl_ticket_aead_success) {
4028 if (is_psk) {
4029 if (!hints->decrypted_psk.CopyFrom(plaintext)) {
4030 return ssl_ticket_aead_error;
4031 }
4032 } else {
4033 if (!hints->decrypted_ticket.CopyFrom(plaintext)) {
4034 return ssl_ticket_aead_error;
4035 }
4036 hints->renew_ticket = *out_renew_ticket;
4037 }
David Benjaminb571e772021-03-25 19:42:16 -04004038 }
4039 }
4040
Adam Langley4c341d02017-03-08 19:33:21 -08004041 if (result != ssl_ticket_aead_success) {
4042 return result;
4043 }
4044
David Benjaminc11ea9422017-08-29 16:33:21 -04004045 // Decode the session.
David Benjamin28655672018-07-18 23:23:25 -04004046 UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(
David Benjaminb571e772021-03-25 19:42:16 -04004047 plaintext.data(), plaintext.size(), ssl->ctx.get()));
David Benjamin37af90f2017-07-29 01:42:16 -04004048 if (!session) {
David Benjaminc11ea9422017-08-29 16:33:21 -04004049 ERR_clear_error(); // Don't leave an error on the queue.
Adam Langley4c341d02017-03-08 19:33:21 -08004050 return ssl_ticket_aead_ignore_ticket;
David Benjamine3aa1d92015-06-16 15:34:50 -04004051 }
4052
Adam Langley47cefed2021-05-26 13:36:40 -07004053 // Envoy's tests expect the session to have a session ID that matches the
4054 // placeholder used by the client. It's unclear whether this is a good idea,
4055 // but we maintain it for now.
4056 SHA256(ticket.data(), ticket.size(), session->session_id);
4057 // Other consumers may expect a non-empty session ID to indicate resumption.
4058 session->session_id_length = SHA256_DIGEST_LENGTH;
David Benjamine3aa1d92015-06-16 15:34:50 -04004059
David Benjamin37af90f2017-07-29 01:42:16 -04004060 *out_session = std::move(session);
Adam Langley4c341d02017-03-08 19:33:21 -08004061 return ssl_ticket_aead_success;
Adam Langleyfcf25832014-12-18 17:42:32 -08004062}
Adam Langley95c29f32014-06-20 12:00:00 -07004063
David Benjamin610cdbb2018-01-22 19:08:38 -05004064bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) {
David Benjaminc11ea9422017-08-29 16:33:21 -04004065 // Extension ignored for inappropriate versions
David Benjamind1e3ce12017-10-06 18:31:15 -04004066 if (ssl_protocol_version(hs->ssl) < TLS1_2_VERSION) {
David Benjamin610cdbb2018-01-22 19:08:38 -05004067 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08004068 }
David Benjamincd996942014-07-20 16:23:51 -04004069
David Benjamin602f4662018-12-07 12:06:22 -06004070 // In all contexts, the signature algorithms list may not be empty. (It may be
4071 // omitted by clients in TLS 1.2, but then the entire extension is omitted.)
4072 return CBS_len(in_sigalgs) != 0 &&
4073 parse_u16_array(in_sigalgs, &hs->peer_sigalgs);
Adam Langleyfcf25832014-12-18 17:42:32 -08004074}
David Benjaminec2f27d2014-11-13 19:17:25 -05004075
David Benjamin610cdbb2018-01-22 19:08:38 -05004076bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) {
David Benjamina3651382017-04-20 17:49:36 -04004077 switch (EVP_PKEY_id(pkey)) {
4078 case EVP_PKEY_RSA:
4079 *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
David Benjamin610cdbb2018-01-22 19:08:38 -05004080 return true;
David Benjamina3651382017-04-20 17:49:36 -04004081 case EVP_PKEY_EC:
4082 *out = SSL_SIGN_ECDSA_SHA1;
David Benjamin610cdbb2018-01-22 19:08:38 -05004083 return true;
David Benjamina3651382017-04-20 17:49:36 -04004084 default:
David Benjamin610cdbb2018-01-22 19:08:38 -05004085 return false;
David Benjamina3651382017-04-20 17:49:36 -04004086 }
4087}
4088
David Benjamin610cdbb2018-01-22 19:08:38 -05004089bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +09004090 SSL *const ssl = hs->ssl;
David Benjamin0ce090a2018-07-02 20:24:40 -04004091 CERT *cert = hs->config->cert.get();
Christopher Patton6c1b3762018-07-17 12:49:41 -07004092 DC *dc = cert->dc.get();
David Benjaminec2f27d2014-11-13 19:17:25 -05004093
David Benjaminc11ea9422017-08-29 16:33:21 -04004094 // Before TLS 1.2, the signature algorithm isn't negotiated as part of the
4095 // handshake.
David Benjamind1e3ce12017-10-06 18:31:15 -04004096 if (ssl_protocol_version(ssl) < TLS1_2_VERSION) {
David Benjamin31b0c9b2017-07-20 14:49:15 -04004097 if (!tls1_get_legacy_signature_algorithm(out, hs->local_pubkey.get())) {
David Benjamina3651382017-04-20 17:49:36 -04004098 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
David Benjamin610cdbb2018-01-22 19:08:38 -05004099 return false;
Steven Valdezf0451ca2016-06-29 13:16:27 -04004100 }
David Benjamin610cdbb2018-01-22 19:08:38 -05004101 return true;
Steven Valdezf0451ca2016-06-29 13:16:27 -04004102 }
4103
David Benjaminb1cf48e2017-09-21 11:37:46 -04004104 Span<const uint16_t> sigalgs = kSignSignatureAlgorithms;
Christopher Patton6c1b3762018-07-17 12:49:41 -07004105 if (ssl_signing_with_dc(hs)) {
4106 sigalgs = MakeConstSpan(&dc->expected_cert_verify_algorithm, 1);
4107 } else if (!cert->sigalgs.empty()) {
David Benjamine325c3f2018-04-12 16:11:15 -04004108 sigalgs = cert->sigalgs;
Steven Valdez0d62f262015-09-04 12:41:04 -04004109 }
4110
Christopher Patton6c1b3762018-07-17 12:49:41 -07004111 Span<const uint16_t> peer_sigalgs = tls1_get_peer_verify_algorithms(hs);
David Benjaminea9a0d52016-07-08 15:52:59 -07004112
David Benjaminb1cf48e2017-09-21 11:37:46 -04004113 for (uint16_t sigalg : sigalgs) {
David Benjamine8f57ca2022-11-29 18:40:11 -05004114 if (!ssl_private_key_supports_signature_algorithm(hs, sigalg)) {
David Benjamin1fb125c2016-07-08 18:52:12 -07004115 continue;
4116 }
4117
David Benjaminb1cf48e2017-09-21 11:37:46 -04004118 for (uint16_t peer_sigalg : peer_sigalgs) {
4119 if (sigalg == peer_sigalg) {
David Benjamin1fb125c2016-07-08 18:52:12 -07004120 *out = sigalg;
David Benjamin610cdbb2018-01-22 19:08:38 -05004121 return true;
Steven Valdezf0451ca2016-06-29 13:16:27 -04004122 }
Adam Langleyfcf25832014-12-18 17:42:32 -08004123 }
Adam Langleyfcf25832014-12-18 17:42:32 -08004124 }
Adam Langley95c29f32014-06-20 12:00:00 -07004125
David Benjaminea9a0d52016-07-08 15:52:59 -07004126 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
David Benjamin610cdbb2018-01-22 19:08:38 -05004127 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08004128}
Adam Langley95c29f32014-06-20 12:00:00 -07004129
Christopher Patton6c1b3762018-07-17 12:49:41 -07004130Span<const uint16_t> tls1_get_peer_verify_algorithms(const SSL_HANDSHAKE *hs) {
4131 Span<const uint16_t> peer_sigalgs = hs->peer_sigalgs;
4132 if (peer_sigalgs.empty() && ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
4133 // If the client didn't specify any signature_algorithms extension then
4134 // we can assume that it supports SHA1. See
4135 // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
4136 static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1,
4137 SSL_SIGN_ECDSA_SHA1};
4138 peer_sigalgs = kDefaultPeerAlgorithms;
4139 }
4140 return peer_sigalgs;
4141}
4142
David Benjamin861abcc2018-07-14 17:40:26 -04004143bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
Steven Valdez908ac192017-01-12 13:17:07 -05004144 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -04004145 // A Channel ID handshake message is structured to contain multiple
4146 // extensions, but the only one that can be present is Channel ID.
David Benjamin7934f082017-08-01 16:32:25 -04004147 uint16_t extension_type;
4148 CBS channel_id = msg.body, extension;
Nick Harper60a85cb2016-09-23 16:25:11 -07004149 if (!CBS_get_u16(&channel_id, &extension_type) ||
4150 !CBS_get_u16_length_prefixed(&channel_id, &extension) ||
4151 CBS_len(&channel_id) != 0 ||
4152 extension_type != TLSEXT_TYPE_channel_id ||
4153 CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) {
4154 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
David Benjamind1e3ce12017-10-06 18:31:15 -04004155 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
David Benjamin861abcc2018-07-14 17:40:26 -04004156 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004157 }
4158
David Benjamin86e95b82017-07-18 16:34:25 -04004159 UniquePtr<EC_GROUP> p256(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
Nick Harper60a85cb2016-09-23 16:25:11 -07004160 if (!p256) {
4161 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT);
David Benjamin861abcc2018-07-14 17:40:26 -04004162 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004163 }
4164
David Benjamin86e95b82017-07-18 16:34:25 -04004165 UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
4166 UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
David Benjamin81678aa2017-07-12 22:43:42 -04004167 if (!sig || !x || !y) {
David Benjamin861abcc2018-07-14 17:40:26 -04004168 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004169 }
4170
4171 const uint8_t *p = CBS_data(&extension);
David Benjamin81678aa2017-07-12 22:43:42 -04004172 if (BN_bin2bn(p + 0, 32, x.get()) == NULL ||
4173 BN_bin2bn(p + 32, 32, y.get()) == NULL ||
4174 BN_bin2bn(p + 64, 32, sig->r) == NULL ||
4175 BN_bin2bn(p + 96, 32, sig->s) == NULL) {
David Benjamin861abcc2018-07-14 17:40:26 -04004176 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004177 }
4178
David Benjamin86e95b82017-07-18 16:34:25 -04004179 UniquePtr<EC_KEY> key(EC_KEY_new());
4180 UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
David Benjamin81678aa2017-07-12 22:43:42 -04004181 if (!key || !point ||
4182 !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
4183 y.get(), nullptr) ||
4184 !EC_KEY_set_group(key.get(), p256.get()) ||
4185 !EC_KEY_set_public_key(key.get(), point.get())) {
David Benjamin861abcc2018-07-14 17:40:26 -04004186 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004187 }
4188
4189 uint8_t digest[EVP_MAX_MD_SIZE];
4190 size_t digest_len;
Steven Valdez908ac192017-01-12 13:17:07 -05004191 if (!tls1_channel_id_hash(hs, digest, &digest_len)) {
David Benjamin861abcc2018-07-14 17:40:26 -04004192 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004193 }
4194
David Benjamin861abcc2018-07-14 17:40:26 -04004195 bool sig_ok = ECDSA_do_verify(digest, digest_len, sig.get(), key.get());
Nick Harper60a85cb2016-09-23 16:25:11 -07004196#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
David Benjamin861abcc2018-07-14 17:40:26 -04004197 sig_ok = true;
David Benjamind90b8032017-12-18 16:47:51 -05004198 ERR_clear_error();
Nick Harper60a85cb2016-09-23 16:25:11 -07004199#endif
4200 if (!sig_ok) {
4201 OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
David Benjamind1e3ce12017-10-06 18:31:15 -04004202 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
David Benjamin861abcc2018-07-14 17:40:26 -04004203 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004204 }
4205
David Benjamin46853762018-07-03 14:01:26 -04004206 OPENSSL_memcpy(ssl->s3->channel_id, p, 64);
David Benjamin8acec002021-05-19 13:03:34 -04004207 ssl->s3->channel_id_valid = true;
David Benjamin861abcc2018-07-14 17:40:26 -04004208 return true;
Nick Harper60a85cb2016-09-23 16:25:11 -07004209}
4210
David Benjaminf1db1a32017-10-27 01:12:34 -04004211bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) {
Nick Harper60a85cb2016-09-23 16:25:11 -07004212 uint8_t digest[EVP_MAX_MD_SIZE];
4213 size_t digest_len;
Steven Valdez908ac192017-01-12 13:17:07 -05004214 if (!tls1_channel_id_hash(hs, digest, &digest_len)) {
David Benjaminf1db1a32017-10-27 01:12:34 -04004215 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004216 }
4217
David Benjamin46853762018-07-03 14:01:26 -04004218 EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(hs->config->channel_id_private.get());
David Benjaminf1db1a32017-10-27 01:12:34 -04004219 if (ec_key == nullptr) {
Nick Harper60a85cb2016-09-23 16:25:11 -07004220 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjaminf1db1a32017-10-27 01:12:34 -04004221 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004222 }
4223
David Benjaminf1db1a32017-10-27 01:12:34 -04004224 UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
4225 if (!x || !y ||
Nick Harper60a85cb2016-09-23 16:25:11 -07004226 !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key),
4227 EC_KEY_get0_public_key(ec_key),
David Benjaminf1db1a32017-10-27 01:12:34 -04004228 x.get(), y.get(), nullptr)) {
4229 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004230 }
4231
David Benjaminf1db1a32017-10-27 01:12:34 -04004232 UniquePtr<ECDSA_SIG> sig(ECDSA_do_sign(digest, digest_len, ec_key));
4233 if (!sig) {
4234 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004235 }
4236
4237 CBB child;
4238 if (!CBB_add_u16(cbb, TLSEXT_TYPE_channel_id) ||
4239 !CBB_add_u16_length_prefixed(cbb, &child) ||
David Benjaminf1db1a32017-10-27 01:12:34 -04004240 !BN_bn2cbb_padded(&child, 32, x.get()) ||
4241 !BN_bn2cbb_padded(&child, 32, y.get()) ||
Nick Harper60a85cb2016-09-23 16:25:11 -07004242 !BN_bn2cbb_padded(&child, 32, sig->r) ||
4243 !BN_bn2cbb_padded(&child, 32, sig->s) ||
4244 !CBB_flush(cbb)) {
David Benjaminf1db1a32017-10-27 01:12:34 -04004245 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004246 }
4247
David Benjaminf1db1a32017-10-27 01:12:34 -04004248 return true;
Nick Harper60a85cb2016-09-23 16:25:11 -07004249}
4250
David Benjamin861abcc2018-07-14 17:40:26 -04004251bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) {
Steven Valdez908ac192017-01-12 13:17:07 -05004252 SSL *const ssl = hs->ssl;
David Benjamind1e3ce12017-10-06 18:31:15 -04004253 if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
David Benjamin75a1f232017-10-11 17:19:19 -04004254 Array<uint8_t> msg;
4255 if (!tls13_get_cert_verify_signature_input(hs, &msg,
Nick Harper60a85cb2016-09-23 16:25:11 -07004256 ssl_cert_verify_channel_id)) {
David Benjamin861abcc2018-07-14 17:40:26 -04004257 return false;
Nick Harper60a85cb2016-09-23 16:25:11 -07004258 }
David Benjamin75a1f232017-10-11 17:19:19 -04004259 SHA256(msg.data(), msg.size(), out);
Nick Harper60a85cb2016-09-23 16:25:11 -07004260 *out_len = SHA256_DIGEST_LENGTH;
David Benjamin861abcc2018-07-14 17:40:26 -04004261 return true;
Nick Harper60a85cb2016-09-23 16:25:11 -07004262 }
4263
Nick Harper95594012016-10-20 14:07:13 -07004264 SHA256_CTX ctx;
Adam Langleyfcf25832014-12-18 17:42:32 -08004265
Nick Harper95594012016-10-20 14:07:13 -07004266 SHA256_Init(&ctx);
David Benjamind6a4ae92015-08-06 11:10:51 -04004267 static const char kClientIDMagic[] = "TLS Channel ID signature";
Nick Harper95594012016-10-20 14:07:13 -07004268 SHA256_Update(&ctx, kClientIDMagic, sizeof(kClientIDMagic));
David Benjamind6a4ae92015-08-06 11:10:51 -04004269
Steven Valdez87eab492016-06-27 16:34:59 -04004270 if (ssl->session != NULL) {
David Benjamind6a4ae92015-08-06 11:10:51 -04004271 static const char kResumptionMagic[] = "Resumption";
Nick Harper95594012016-10-20 14:07:13 -07004272 SHA256_Update(&ctx, kResumptionMagic, sizeof(kResumptionMagic));
David Benjamind6a4ae92015-08-06 11:10:51 -04004273 if (ssl->session->original_handshake_hash_len == 0) {
4274 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin861abcc2018-07-14 17:40:26 -04004275 return false;
David Benjamind6a4ae92015-08-06 11:10:51 -04004276 }
Nick Harper95594012016-10-20 14:07:13 -07004277 SHA256_Update(&ctx, ssl->session->original_handshake_hash,
4278 ssl->session->original_handshake_hash_len);
David Benjamind6a4ae92015-08-06 11:10:51 -04004279 }
4280
Steven Valdez908ac192017-01-12 13:17:07 -05004281 uint8_t hs_hash[EVP_MAX_MD_SIZE];
4282 size_t hs_hash_len;
David Benjamin6dc8bf62017-07-19 16:38:21 -04004283 if (!hs->transcript.GetHash(hs_hash, &hs_hash_len)) {
David Benjamin861abcc2018-07-14 17:40:26 -04004284 return false;
David Benjamind6a4ae92015-08-06 11:10:51 -04004285 }
Steven Valdez908ac192017-01-12 13:17:07 -05004286 SHA256_Update(&ctx, hs_hash, (size_t)hs_hash_len);
Nick Harper95594012016-10-20 14:07:13 -07004287 SHA256_Final(out, &ctx);
4288 *out_len = SHA256_DIGEST_LENGTH;
David Benjamin861abcc2018-07-14 17:40:26 -04004289 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08004290}
Adam Langley1258b6a2014-06-20 12:00:00 -07004291
David Benjamin861abcc2018-07-14 17:40:26 -04004292bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) {
Steven Valdez908ac192017-01-12 13:17:07 -05004293 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -04004294 // This function should never be called for a resumed session because the
4295 // handshake hashes that we wish to record are for the original, full
4296 // handshake.
Steven Valdez87eab492016-06-27 16:34:59 -04004297 if (ssl->session != NULL) {
David Benjamin861abcc2018-07-14 17:40:26 -04004298 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08004299 }
Adam Langley1258b6a2014-06-20 12:00:00 -07004300
David Benjamina3d76d02017-07-14 19:36:07 -04004301 static_assert(
David Benjamin45738dd2017-02-09 20:01:26 -05004302 sizeof(hs->new_session->original_handshake_hash) == EVP_MAX_MD_SIZE,
David Benjamina3d76d02017-07-14 19:36:07 -04004303 "original_handshake_hash is too small");
Steven Valdez908ac192017-01-12 13:17:07 -05004304
4305 size_t digest_len;
David Benjamin6dc8bf62017-07-19 16:38:21 -04004306 if (!hs->transcript.GetHash(hs->new_session->original_handshake_hash,
4307 &digest_len)) {
David Benjamin861abcc2018-07-14 17:40:26 -04004308 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08004309 }
Adam Langley1258b6a2014-06-20 12:00:00 -07004310
David Benjamina3d76d02017-07-14 19:36:07 -04004311 static_assert(EVP_MAX_MD_SIZE <= 0xff,
4312 "EVP_MAX_MD_SIZE does not fit in uint8_t");
David Benjamin45738dd2017-02-09 20:01:26 -05004313 hs->new_session->original_handshake_hash_len = (uint8_t)digest_len;
Adam Langley1258b6a2014-06-20 12:00:00 -07004314
David Benjamin861abcc2018-07-14 17:40:26 -04004315 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08004316}
Nick Harper60a85cb2016-09-23 16:25:11 -07004317
David Benjamin861abcc2018-07-14 17:40:26 -04004318bool ssl_is_sct_list_valid(const CBS *contents) {
David Benjaminc11ea9422017-08-29 16:33:21 -04004319 // Shallow parse the SCT list for sanity. By the RFC
4320 // (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any
4321 // of the SCTs may be empty.
Adam Langleycfa08c32016-11-17 13:21:27 -08004322 CBS copy = *contents;
4323 CBS sct_list;
4324 if (!CBS_get_u16_length_prefixed(&copy, &sct_list) ||
4325 CBS_len(&copy) != 0 ||
4326 CBS_len(&sct_list) == 0) {
David Benjamin861abcc2018-07-14 17:40:26 -04004327 return false;
Adam Langleycfa08c32016-11-17 13:21:27 -08004328 }
4329
4330 while (CBS_len(&sct_list) > 0) {
4331 CBS sct;
4332 if (!CBS_get_u16_length_prefixed(&sct_list, &sct) ||
4333 CBS_len(&sct) == 0) {
David Benjamin861abcc2018-07-14 17:40:26 -04004334 return false;
Adam Langleycfa08c32016-11-17 13:21:27 -08004335 }
4336 }
4337
David Benjamin861abcc2018-07-14 17:40:26 -04004338 return true;
Adam Langleycfa08c32016-11-17 13:21:27 -08004339}
David Benjamin86e95b82017-07-18 16:34:25 -04004340
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07004341BSSL_NAMESPACE_END
David Benjamin86e95b82017-07-18 16:34:25 -04004342
4343using namespace bssl;
4344
4345int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello,
4346 uint16_t extension_type,
4347 const uint8_t **out_data,
4348 size_t *out_len) {
4349 CBS cbs;
4350 if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) {
4351 return 0;
4352 }
4353
4354 *out_data = CBS_data(&cbs);
4355 *out_len = CBS_len(&cbs);
4356 return 1;
4357}