ssl_versions.c revision 1.13
1/* $OpenBSD: ssl_versions.c,v 1.13 2021/02/25 17:06:05 jsing Exp $ */
2/*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "ssl_locl.h"
19
20static int
21ssl_clamp_tls_version_range(uint16_t *min_ver, uint16_t *max_ver,
22    uint16_t clamp_min, uint16_t clamp_max)
23{
24	if (clamp_min > clamp_max || *min_ver > *max_ver)
25		return 0;
26	if (clamp_max < *min_ver || clamp_min > *max_ver)
27		return 0;
28
29	if (*min_ver < clamp_min)
30		*min_ver = clamp_min;
31	if (*max_ver > clamp_max)
32		*max_ver = clamp_max;
33
34	return 1;
35}
36
37int
38ssl_version_set_min(const SSL_METHOD *meth, uint16_t proto_ver,
39    uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
40{
41	uint16_t min_version, max_version;
42
43	if (proto_ver == 0) {
44		*out_tls_ver = meth->internal->min_tls_version;
45		*out_proto_ver = 0;
46		return 1;
47	}
48	if (meth->internal->dtls) {
49		if (proto_ver != DTLS1_VERSION)
50			return 0;
51		*out_tls_ver = TLS1_1_VERSION;
52		*out_proto_ver = proto_ver;
53		return 1;
54	}
55
56	min_version = proto_ver;
57	max_version = max_tls_ver;
58
59	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
60	    meth->internal->min_tls_version, meth->internal->max_tls_version))
61		return 0;
62
63	*out_tls_ver = min_version;
64	*out_proto_ver = min_version;
65
66	return 1;
67}
68
69int
70ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver,
71    uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
72{
73	uint16_t min_version, max_version;
74
75	if (proto_ver == 0) {
76		*out_tls_ver = meth->internal->max_tls_version;
77		*out_proto_ver = 0;
78		return 1;
79	}
80	if (meth->internal->dtls) {
81		if (proto_ver != DTLS1_VERSION)
82			return 0;
83		*out_tls_ver = TLS1_1_VERSION;
84		*out_proto_ver = proto_ver;
85		return 1;
86	}
87
88	min_version = min_tls_ver;
89	max_version = proto_ver;
90
91	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
92	    meth->internal->min_tls_version, meth->internal->max_tls_version))
93		return 0;
94
95	*out_tls_ver = max_version;
96	*out_proto_ver = max_version;
97
98	return 1;
99}
100
101int
102ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
103{
104	uint16_t min_version, max_version;
105
106	/*
107	 * The enabled versions have to be a contiguous range, which means we
108	 * cannot enable and disable single versions at our whim, even though
109	 * this is what the OpenSSL flags allow. The historical way this has
110	 * been handled is by making a flag mean that all higher versions
111	 * are disabled, if any version lower than the flag is enabled.
112	 */
113
114	min_version = 0;
115	max_version = TLS1_3_VERSION;
116
117	if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
118		min_version = TLS1_VERSION;
119	else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
120		min_version = TLS1_1_VERSION;
121	else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
122		min_version = TLS1_2_VERSION;
123	else if ((s->internal->options & SSL_OP_NO_TLSv1_3) == 0)
124		min_version = TLS1_3_VERSION;
125
126	if ((s->internal->options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
127		max_version = TLS1_2_VERSION;
128	if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
129		max_version = TLS1_1_VERSION;
130	if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
131		max_version = TLS1_VERSION;
132	if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
133		max_version = 0;
134
135	/* Everything has been disabled... */
136	if (min_version == 0 || max_version == 0)
137		return 0;
138
139	/* Limit to configured version range. */
140	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
141	    s->internal->min_tls_version, s->internal->max_tls_version))
142		return 0;
143
144	if (min_ver != NULL)
145		*min_ver = min_version;
146	if (max_ver != NULL)
147		*max_ver = max_version;
148
149	return 1;
150}
151
152int
153ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
154{
155	uint16_t min_version, max_version;
156
157	if (!ssl_enabled_tls_version_range(s, &min_version, &max_version))
158		return 0;
159
160	/* Limit to the versions supported by this method. */
161	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
162	    s->method->internal->min_tls_version,
163	    s->method->internal->max_tls_version))
164		return 0;
165
166	if (min_ver != NULL)
167		*min_ver = min_version;
168	if (max_ver != NULL)
169		*max_ver = max_version;
170
171	return 1;
172}
173
174int
175ssl_max_supported_version(SSL *s, uint16_t *max_ver)
176{
177	*max_ver = 0;
178
179	if (SSL_is_dtls(s)) {
180		*max_ver = DTLS1_VERSION;
181		return 1;
182	}
183
184	if (!ssl_supported_tls_version_range(s, NULL, max_ver))
185		return 0;
186
187	return 1;
188}
189
190int
191ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
192{
193	uint16_t min_version, max_version, shared_version;
194
195	*max_ver = 0;
196
197	if (SSL_is_dtls(s)) {
198		if (peer_ver >= DTLS1_VERSION) {
199			*max_ver = DTLS1_VERSION;
200			return 1;
201		}
202		return 0;
203	}
204
205	if (peer_ver >= TLS1_3_VERSION)
206		shared_version = TLS1_3_VERSION;
207	else if (peer_ver >= TLS1_2_VERSION)
208		shared_version = TLS1_2_VERSION;
209	else if (peer_ver >= TLS1_1_VERSION)
210		shared_version = TLS1_1_VERSION;
211	else if (peer_ver >= TLS1_VERSION)
212		shared_version = TLS1_VERSION;
213	else
214		return 0;
215
216	if (!ssl_supported_tls_version_range(s, &min_version, &max_version))
217		return 0;
218
219	if (shared_version < min_version)
220		return 0;
221
222	if (shared_version > max_version)
223		shared_version = max_version;
224
225	*max_ver = shared_version;
226
227	return 1;
228}
229
230int
231ssl_downgrade_max_version(SSL *s, uint16_t *max_ver)
232{
233	uint16_t min_version, max_version;
234
235	/*
236	 * The downgrade maximum version is based on the versions that are
237	 * enabled, however we also have to then limit to the versions
238	 * supported by the method. The SSL method will be changed during
239	 * version negotiation and when switching from the new stack to
240	 * the legacy context, as such we want to use the method from the
241	 * context.
242	 */
243
244	if (SSL_is_dtls(s)) {
245		*max_ver = DTLS1_VERSION;
246		return 1;
247	}
248
249	if (!ssl_enabled_tls_version_range(s, &min_version, &max_version))
250		return 0;
251
252	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
253	    s->ctx->method->internal->min_tls_version,
254	    s->ctx->method->internal->max_tls_version))
255		return 0;
256
257	*max_ver = max_version;
258
259	return 1;
260}
261
262int
263ssl_check_version_from_server(SSL *s, uint16_t server_version)
264{
265	uint16_t min_version, max_version;
266
267	/* Ensure that the version selected by the server is valid. */
268
269	if (SSL_is_dtls(s))
270		return (server_version == DTLS1_VERSION);
271
272	if (!ssl_supported_tls_version_range(s, &min_version, &max_version))
273		return 0;
274
275	return (server_version >= min_version && server_version <= max_version);
276}
277
278int
279ssl_legacy_stack_version(SSL *s, uint16_t version)
280{
281	if (SSL_is_dtls(s))
282		return version == DTLS1_VERSION || version == DTLS1_2_VERSION;
283
284	return version == TLS1_VERSION || version == TLS1_1_VERSION ||
285	    version == TLS1_2_VERSION;
286}
287