blob: 56653b16c83dba875ce6d45d282185b293876cb9 [file] [log] [blame]
Steven Valdez8f36c512017-06-20 10:55:02 -04001/* Copyright (c) 2017, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <openssl/ssl.h>
16
17#include <assert.h>
18
19#include <openssl/bytestring.h>
20#include <openssl/err.h>
21
22#include "internal.h"
23#include "../crypto/internal.h"
24
25
David Benjamin86e95b82017-07-18 16:34:25 -040026namespace bssl {
27
David Benjamined9aed12017-09-27 19:24:09 -040028bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) {
Steven Valdez8f36c512017-06-20 10:55:02 -040029 switch (version) {
30 case SSL3_VERSION:
31 case TLS1_VERSION:
32 case TLS1_1_VERSION:
33 case TLS1_2_VERSION:
34 *out = version;
David Benjamined9aed12017-09-27 19:24:09 -040035 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -040036
37 case TLS1_3_DRAFT_VERSION:
Steven Valdez520e1222017-06-13 12:45:25 -040038 case TLS1_3_EXPERIMENT_VERSION:
Steven Valdez16821262017-09-08 17:03:42 -040039 case TLS1_3_EXPERIMENT2_VERSION:
Steven Valdezc7d4d212017-09-11 13:53:08 -040040 case TLS1_3_EXPERIMENT3_VERSION:
Steven Valdez8f36c512017-06-20 10:55:02 -040041 *out = TLS1_3_VERSION;
David Benjamined9aed12017-09-27 19:24:09 -040042 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -040043
44 case DTLS1_VERSION:
David Benjaminc11ea9422017-08-29 16:33:21 -040045 // DTLS 1.0 is analogous to TLS 1.1, not TLS 1.0.
Steven Valdez8f36c512017-06-20 10:55:02 -040046 *out = TLS1_1_VERSION;
David Benjamined9aed12017-09-27 19:24:09 -040047 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -040048
49 case DTLS1_2_VERSION:
50 *out = TLS1_2_VERSION;
David Benjamined9aed12017-09-27 19:24:09 -040051 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -040052
53 default:
David Benjamined9aed12017-09-27 19:24:09 -040054 return false;
Steven Valdez8f36c512017-06-20 10:55:02 -040055 }
56}
57
David Benjaminc11ea9422017-08-29 16:33:21 -040058// The follow arrays are the supported versions for TLS and DTLS, in order of
59// decreasing preference.
Steven Valdez8f36c512017-06-20 10:55:02 -040060
61static const uint16_t kTLSVersions[] = {
Steven Valdezc7d4d212017-09-11 13:53:08 -040062 TLS1_3_EXPERIMENT3_VERSION,
Steven Valdez16821262017-09-08 17:03:42 -040063 TLS1_3_EXPERIMENT2_VERSION,
Steven Valdez520e1222017-06-13 12:45:25 -040064 TLS1_3_EXPERIMENT_VERSION,
Steven Valdezdbe01582017-07-14 10:39:28 -040065 TLS1_3_DRAFT_VERSION,
Steven Valdez8f36c512017-06-20 10:55:02 -040066 TLS1_2_VERSION,
67 TLS1_1_VERSION,
68 TLS1_VERSION,
69 SSL3_VERSION,
70};
71
72static const uint16_t kDTLSVersions[] = {
73 DTLS1_2_VERSION,
74 DTLS1_VERSION,
75};
76
77static void get_method_versions(const SSL_PROTOCOL_METHOD *method,
78 const uint16_t **out, size_t *out_num) {
79 if (method->is_dtls) {
80 *out = kDTLSVersions;
81 *out_num = OPENSSL_ARRAY_SIZE(kDTLSVersions);
82 } else {
83 *out = kTLSVersions;
84 *out_num = OPENSSL_ARRAY_SIZE(kTLSVersions);
85 }
86}
87
David Benjamined9aed12017-09-27 19:24:09 -040088static bool method_supports_version(const SSL_PROTOCOL_METHOD *method,
89 uint16_t version) {
Steven Valdez8f36c512017-06-20 10:55:02 -040090 const uint16_t *versions;
91 size_t num_versions;
92 get_method_versions(method, &versions, &num_versions);
93 for (size_t i = 0; i < num_versions; i++) {
94 if (versions[i] == version) {
David Benjamined9aed12017-09-27 19:24:09 -040095 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -040096 }
97 }
David Benjamined9aed12017-09-27 19:24:09 -040098 return false;
Steven Valdez8f36c512017-06-20 10:55:02 -040099}
100
David Benjamina4bafd32017-10-03 15:06:29 -0400101// The following functions map between API versions and wire versions. The
102// public API works on wire versions, except that TLS 1.3 draft versions all
103// appear as TLS 1.3. This will get collapsed back down when TLS 1.3 is
104// finalized.
105
106static const char *ssl_version_to_string(uint16_t version) {
107 switch (version) {
108 case TLS1_3_DRAFT_VERSION:
109 case TLS1_3_EXPERIMENT_VERSION:
110 case TLS1_3_EXPERIMENT2_VERSION:
111 case TLS1_3_EXPERIMENT3_VERSION:
112 return "TLSv1.3";
113
114 case TLS1_2_VERSION:
115 return "TLSv1.2";
116
117 case TLS1_1_VERSION:
118 return "TLSv1.1";
119
120 case TLS1_VERSION:
121 return "TLSv1";
122
123 case SSL3_VERSION:
124 return "SSLv3";
125
126 case DTLS1_VERSION:
127 return "DTLSv1";
128
129 case DTLS1_2_VERSION:
130 return "DTLSv1.2";
131
132 default:
133 return "unknown";
134 }
135}
136
137static uint16_t wire_version_to_api(uint16_t version) {
138 switch (version) {
139 // Report TLS 1.3 draft versions as TLS 1.3 in the public API.
140 case TLS1_3_DRAFT_VERSION:
141 case TLS1_3_EXPERIMENT_VERSION:
142 case TLS1_3_EXPERIMENT2_VERSION:
143 case TLS1_3_EXPERIMENT3_VERSION:
144 return TLS1_3_VERSION;
145 default:
146 return version;
147 }
148}
149
150// api_version_to_wire maps |version| to some representative wire version. In
151// particular, it picks an arbitrary TLS 1.3 representative. This should only be
152// used in context where that does not matter.
153static bool api_version_to_wire(uint16_t *out, uint16_t version) {
Steven Valdez520e1222017-06-13 12:45:25 -0400154 if (version == TLS1_3_DRAFT_VERSION ||
Steven Valdezdbe01582017-07-14 10:39:28 -0400155 version == TLS1_3_EXPERIMENT_VERSION ||
Steven Valdez16821262017-09-08 17:03:42 -0400156 version == TLS1_3_EXPERIMENT2_VERSION ||
Steven Valdez4c7f5fa2017-10-02 15:53:57 -0400157 version == TLS1_3_EXPERIMENT3_VERSION) {
David Benjamined9aed12017-09-27 19:24:09 -0400158 return false;
David Benjamin353577c2017-06-29 15:54:58 -0400159 }
Steven Valdez8f36c512017-06-20 10:55:02 -0400160 if (version == TLS1_3_VERSION) {
161 version = TLS1_3_DRAFT_VERSION;
162 }
163
David Benjamina4bafd32017-10-03 15:06:29 -0400164 // Check it is a real protocol version.
165 uint16_t unused;
166 if (!ssl_protocol_version_from_wire(&unused, version)) {
167 return false;
168 }
169
170 *out = version;
171 return true;
172}
173
174static bool set_version_bound(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
175 uint16_t version) {
176 if (!api_version_to_wire(&version, version) ||
177 !method_supports_version(method, version) ||
David Benjamin353577c2017-06-29 15:54:58 -0400178 !ssl_protocol_version_from_wire(out, version)) {
179 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
David Benjamined9aed12017-09-27 19:24:09 -0400180 return false;
David Benjamin353577c2017-06-29 15:54:58 -0400181 }
182
David Benjamined9aed12017-09-27 19:24:09 -0400183 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400184}
185
David Benjamined9aed12017-09-27 19:24:09 -0400186static bool set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
187 uint16_t version) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400188 // Zero is interpreted as the default minimum version.
Steven Valdez8f36c512017-06-20 10:55:02 -0400189 if (version == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400190 // SSL 3.0 is disabled by default and TLS 1.0 does not exist in DTLS.
Steven Valdez8f36c512017-06-20 10:55:02 -0400191 *out = method->is_dtls ? TLS1_1_VERSION : TLS1_VERSION;
David Benjamined9aed12017-09-27 19:24:09 -0400192 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400193 }
194
195 return set_version_bound(method, out, version);
196}
197
David Benjamined9aed12017-09-27 19:24:09 -0400198static bool set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
199 uint16_t version) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400200 // Zero is interpreted as the default maximum version.
Steven Valdez8f36c512017-06-20 10:55:02 -0400201 if (version == 0) {
202 *out = TLS1_2_VERSION;
David Benjamined9aed12017-09-27 19:24:09 -0400203 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400204 }
205
206 return set_version_bound(method, out, version);
207}
208
Steven Valdez8f36c512017-06-20 10:55:02 -0400209const struct {
210 uint16_t version;
211 uint32_t flag;
212} kProtocolVersions[] = {
213 {SSL3_VERSION, SSL_OP_NO_SSLv3},
214 {TLS1_VERSION, SSL_OP_NO_TLSv1},
215 {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1},
216 {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2},
217 {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3},
218};
219
David Benjamined9aed12017-09-27 19:24:09 -0400220bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version,
221 uint16_t *out_max_version) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400222 // For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but
223 // DTLS 1.0 should be mapped to TLS 1.1.
Steven Valdez8f36c512017-06-20 10:55:02 -0400224 uint32_t options = ssl->options;
225 if (SSL_is_dtls(ssl)) {
226 options &= ~SSL_OP_NO_TLSv1_1;
227 if (options & SSL_OP_NO_DTLSv1) {
228 options |= SSL_OP_NO_TLSv1_1;
229 }
230 }
231
232 uint16_t min_version = ssl->conf_min_version;
233 uint16_t max_version = ssl->conf_max_version;
234
David Benjaminc11ea9422017-08-29 16:33:21 -0400235 // OpenSSL's API for controlling versions entails blacklisting individual
236 // protocols. This has two problems. First, on the client, the protocol can
237 // only express a contiguous range of versions. Second, a library consumer
238 // trying to set a maximum version cannot disable protocol versions that get
239 // added in a future version of the library.
240 //
241 // To account for both of these, OpenSSL interprets the client-side bitmask
242 // as a min/max range by picking the lowest contiguous non-empty range of
243 // enabled protocols. Note that this means it is impossible to set a maximum
244 // version of the higest supported TLS version in a future-proof way.
David Benjamined9aed12017-09-27 19:24:09 -0400245 bool any_enabled = false;
Steven Valdez8f36c512017-06-20 10:55:02 -0400246 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kProtocolVersions); i++) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400247 // Only look at the versions already enabled.
Steven Valdez8f36c512017-06-20 10:55:02 -0400248 if (min_version > kProtocolVersions[i].version) {
249 continue;
250 }
251 if (max_version < kProtocolVersions[i].version) {
252 break;
253 }
254
255 if (!(options & kProtocolVersions[i].flag)) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400256 // The minimum version is the first enabled version.
Steven Valdez8f36c512017-06-20 10:55:02 -0400257 if (!any_enabled) {
David Benjamined9aed12017-09-27 19:24:09 -0400258 any_enabled = true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400259 min_version = kProtocolVersions[i].version;
260 }
261 continue;
262 }
263
David Benjaminc11ea9422017-08-29 16:33:21 -0400264 // If there is a disabled version after the first enabled one, all versions
265 // after it are implicitly disabled.
Steven Valdez8f36c512017-06-20 10:55:02 -0400266 if (any_enabled) {
267 max_version = kProtocolVersions[i-1].version;
268 break;
269 }
270 }
271
272 if (!any_enabled) {
273 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SUPPORTED_VERSIONS_ENABLED);
David Benjamined9aed12017-09-27 19:24:09 -0400274 return false;
Steven Valdez8f36c512017-06-20 10:55:02 -0400275 }
276
277 *out_min_version = min_version;
278 *out_max_version = max_version;
David Benjamined9aed12017-09-27 19:24:09 -0400279 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400280}
281
David Benjamind9cbb532017-07-07 13:17:19 -0400282static uint16_t ssl_version(const SSL *ssl) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400283 // In early data, we report the predicted version.
David Benjamind9cbb532017-07-07 13:17:19 -0400284 if (SSL_in_early_data(ssl) && !ssl->server) {
285 return ssl->s3->hs->early_session->ssl_version;
286 }
287 return ssl->version;
288}
289
Steven Valdez8f36c512017-06-20 10:55:02 -0400290uint16_t ssl3_protocol_version(const SSL *ssl) {
291 assert(ssl->s3->have_version);
292 uint16_t version;
293 if (!ssl_protocol_version_from_wire(&version, ssl->version)) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400294 // |ssl->version| will always be set to a valid version.
Steven Valdez8f36c512017-06-20 10:55:02 -0400295 assert(0);
296 return 0;
297 }
298
299 return version;
300}
301
David Benjamined9aed12017-09-27 19:24:09 -0400302bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) {
Steven Valdez520e1222017-06-13 12:45:25 -0400303 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -0400304 // As a client, only allow the configured TLS 1.3 variant. As a server,
305 // support all TLS 1.3 variants as long as tls13_variant is set to a
306 // non-default value.
Steven Valdez520e1222017-06-13 12:45:25 -0400307 if (ssl->server) {
Steven Valdez52586f92017-07-11 15:08:32 -0400308 if (ssl->tls13_variant == tls13_default &&
Steven Valdezdbe01582017-07-14 10:39:28 -0400309 (version == TLS1_3_EXPERIMENT_VERSION ||
Steven Valdez16821262017-09-08 17:03:42 -0400310 version == TLS1_3_EXPERIMENT2_VERSION ||
Steven Valdez4c7f5fa2017-10-02 15:53:57 -0400311 version == TLS1_3_EXPERIMENT3_VERSION)) {
David Benjamined9aed12017-09-27 19:24:09 -0400312 return false;
Steven Valdez520e1222017-06-13 12:45:25 -0400313 }
314 } else {
Steven Valdez52586f92017-07-11 15:08:32 -0400315 if ((ssl->tls13_variant != tls13_experiment &&
Steven Valdez520e1222017-06-13 12:45:25 -0400316 version == TLS1_3_EXPERIMENT_VERSION) ||
Steven Valdez16821262017-09-08 17:03:42 -0400317 (ssl->tls13_variant != tls13_experiment2 &&
318 version == TLS1_3_EXPERIMENT2_VERSION) ||
Steven Valdezc7d4d212017-09-11 13:53:08 -0400319 (ssl->tls13_variant != tls13_experiment3 &&
320 version == TLS1_3_EXPERIMENT3_VERSION) ||
Steven Valdez52586f92017-07-11 15:08:32 -0400321 (ssl->tls13_variant != tls13_default &&
Steven Valdez520e1222017-06-13 12:45:25 -0400322 version == TLS1_3_DRAFT_VERSION)) {
David Benjamined9aed12017-09-27 19:24:09 -0400323 return false;
Steven Valdez520e1222017-06-13 12:45:25 -0400324 }
325 }
326
Steven Valdez8f36c512017-06-20 10:55:02 -0400327 uint16_t protocol_version;
Steven Valdez520e1222017-06-13 12:45:25 -0400328 return method_supports_version(ssl->method, version) &&
Steven Valdez8f36c512017-06-20 10:55:02 -0400329 ssl_protocol_version_from_wire(&protocol_version, version) &&
330 hs->min_version <= protocol_version &&
331 protocol_version <= hs->max_version;
332}
333
David Benjamined9aed12017-09-27 19:24:09 -0400334bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb) {
Steven Valdez8f36c512017-06-20 10:55:02 -0400335 const uint16_t *versions;
336 size_t num_versions;
337 get_method_versions(hs->ssl->method, &versions, &num_versions);
338 for (size_t i = 0; i < num_versions; i++) {
339 if (ssl_supports_version(hs, versions[i]) &&
340 !CBB_add_u16(cbb, versions[i])) {
David Benjamined9aed12017-09-27 19:24:09 -0400341 return false;
Steven Valdez8f36c512017-06-20 10:55:02 -0400342 }
343 }
David Benjamined9aed12017-09-27 19:24:09 -0400344 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400345}
346
David Benjamined9aed12017-09-27 19:24:09 -0400347bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
348 uint16_t *out_version, const CBS *peer_versions) {
Steven Valdez8f36c512017-06-20 10:55:02 -0400349 const uint16_t *versions;
350 size_t num_versions;
351 get_method_versions(hs->ssl->method, &versions, &num_versions);
352 for (size_t i = 0; i < num_versions; i++) {
353 if (!ssl_supports_version(hs, versions[i])) {
354 continue;
355 }
356
357 CBS copy = *peer_versions;
358 while (CBS_len(&copy) != 0) {
359 uint16_t version;
360 if (!CBS_get_u16(&copy, &version)) {
361 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
362 *out_alert = SSL_AD_DECODE_ERROR;
David Benjamined9aed12017-09-27 19:24:09 -0400363 return false;
Steven Valdez8f36c512017-06-20 10:55:02 -0400364 }
365
366 if (version == versions[i]) {
367 *out_version = version;
David Benjamined9aed12017-09-27 19:24:09 -0400368 return true;
Steven Valdez8f36c512017-06-20 10:55:02 -0400369 }
370 }
371 }
372
373 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
374 *out_alert = SSL_AD_PROTOCOL_VERSION;
David Benjamined9aed12017-09-27 19:24:09 -0400375 return false;
Steven Valdez8f36c512017-06-20 10:55:02 -0400376}
David Benjamin86e95b82017-07-18 16:34:25 -0400377
Steven Valdez16821262017-09-08 17:03:42 -0400378bool ssl_is_resumption_experiment(uint16_t version) {
379 return version == TLS1_3_EXPERIMENT_VERSION ||
Steven Valdezc7d4d212017-09-11 13:53:08 -0400380 version == TLS1_3_EXPERIMENT2_VERSION ||
381 version == TLS1_3_EXPERIMENT3_VERSION;
382}
383
384bool ssl_is_resumption_variant(enum tls13_variant_t variant) {
385 return variant == tls13_experiment || variant == tls13_experiment2 ||
386 variant == tls13_experiment3;
387}
388
389bool ssl_is_resumption_client_ccs_experiment(uint16_t version) {
390 return version == TLS1_3_EXPERIMENT_VERSION ||
Steven Valdez16821262017-09-08 17:03:42 -0400391 version == TLS1_3_EXPERIMENT2_VERSION;
392}
393
Steven Valdezc7d4d212017-09-11 13:53:08 -0400394bool ssl_is_resumption_record_version_experiment(uint16_t version) {
395 return version == TLS1_3_EXPERIMENT2_VERSION ||
396 version == TLS1_3_EXPERIMENT3_VERSION;
397}
398
David Benjamin86e95b82017-07-18 16:34:25 -0400399} // namespace bssl
400
401using namespace bssl;
402
403int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) {
404 return set_min_version(ctx->method, &ctx->conf_min_version, version);
405}
406
407int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) {
408 return set_max_version(ctx->method, &ctx->conf_max_version, version);
409}
410
411int SSL_set_min_proto_version(SSL *ssl, uint16_t version) {
412 return set_min_version(ssl->method, &ssl->conf_min_version, version);
413}
414
415int SSL_set_max_proto_version(SSL *ssl, uint16_t version) {
416 return set_max_version(ssl->method, &ssl->conf_max_version, version);
417}
418
419int SSL_version(const SSL *ssl) {
David Benjamina4bafd32017-10-03 15:06:29 -0400420 return wire_version_to_api(ssl_version(ssl));
David Benjamin86e95b82017-07-18 16:34:25 -0400421}
422
423const char *SSL_get_version(const SSL *ssl) {
424 return ssl_version_to_string(ssl_version(ssl));
425}
426
427const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
428 return ssl_version_to_string(session->ssl_version);
429}
David Benjamina4bafd32017-10-03 15:06:29 -0400430
431uint16_t SSL_SESSION_get_protocol_version(const SSL_SESSION *session) {
432 return wire_version_to_api(session->ssl_version);
433}
434
435int SSL_SESSION_set_protocol_version(SSL_SESSION *session, uint16_t version) {
436 // This picks a representative TLS 1.3 version, but this API should only be
437 // used on unit test sessions anyway.
438 return api_version_to_wire(&session->ssl_version, version);
439}