xref: /openbsd-src/lib/libssl/ssl_versions.c (revision 097a140d792de8b2bbe59ad827d39eabf9b4280a)
1 /* $OpenBSD: ssl_versions.c,v 1.18 2021/03/19 19:52:55 tb 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 
20 static uint16_t
21 ssl_dtls_to_tls_version(uint16_t dtls_ver)
22 {
23 	if (dtls_ver == DTLS1_VERSION)
24 		return TLS1_1_VERSION;
25 	if (dtls_ver == DTLS1_2_VERSION)
26 		return TLS1_2_VERSION;
27 	return 0;
28 }
29 
30 static uint16_t
31 ssl_tls_to_dtls_version(uint16_t tls_ver)
32 {
33 	if (tls_ver == TLS1_1_VERSION)
34 		return DTLS1_VERSION;
35 	if (tls_ver == TLS1_2_VERSION)
36 		return DTLS1_2_VERSION;
37 	return 0;
38 }
39 
40 static int
41 ssl_clamp_tls_version_range(uint16_t *min_ver, uint16_t *max_ver,
42     uint16_t clamp_min, uint16_t clamp_max)
43 {
44 	if (clamp_min > clamp_max || *min_ver > *max_ver)
45 		return 0;
46 	if (clamp_max < *min_ver || clamp_min > *max_ver)
47 		return 0;
48 
49 	if (*min_ver < clamp_min)
50 		*min_ver = clamp_min;
51 	if (*max_ver > clamp_max)
52 		*max_ver = clamp_max;
53 
54 	return 1;
55 }
56 
57 int
58 ssl_version_set_min(const SSL_METHOD *meth, uint16_t proto_ver,
59     uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
60 {
61 	uint16_t min_proto, min_version, max_version;
62 
63 	if (proto_ver == 0) {
64 		*out_tls_ver = meth->internal->min_tls_version;
65 		*out_proto_ver = 0;
66 		return 1;
67 	}
68 
69 	min_version = proto_ver;
70 	max_version = max_tls_ver;
71 
72 	if (meth->internal->dtls) {
73 		if ((min_version = ssl_dtls_to_tls_version(proto_ver)) == 0)
74 			return 0;
75 	}
76 
77 	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
78 	    meth->internal->min_tls_version, meth->internal->max_tls_version))
79 		return 0;
80 
81 	min_proto = min_version;
82 	if (meth->internal->dtls) {
83 		if ((min_proto = ssl_tls_to_dtls_version(min_version)) == 0)
84 			return 0;
85 	}
86 	*out_tls_ver = min_version;
87 	*out_proto_ver = min_proto;
88 
89 	return 1;
90 }
91 
92 int
93 ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver,
94     uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
95 {
96 	uint16_t max_proto, min_version, max_version;
97 
98 	if (proto_ver == 0) {
99 		*out_tls_ver = meth->internal->max_tls_version;
100 		*out_proto_ver = 0;
101 		return 1;
102 	}
103 
104 	min_version = min_tls_ver;
105 	max_version = proto_ver;
106 
107 	if (meth->internal->dtls) {
108 		if ((max_version = ssl_dtls_to_tls_version(proto_ver)) == 0)
109 			return 0;
110 	}
111 
112 	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
113 	    meth->internal->min_tls_version, meth->internal->max_tls_version))
114 		return 0;
115 
116 	max_proto = max_version;
117 	if (meth->internal->dtls) {
118 		if ((max_proto = ssl_tls_to_dtls_version(max_version)) == 0)
119 			return 0;
120 	}
121 	*out_tls_ver = max_version;
122 	*out_proto_ver = max_proto;
123 
124 	return 1;
125 }
126 
127 int
128 ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
129 {
130 	uint16_t min_version, max_version;
131 	unsigned long options;
132 
133 	/*
134 	 * The enabled versions have to be a contiguous range, which means we
135 	 * cannot enable and disable single versions at our whim, even though
136 	 * this is what the OpenSSL flags allow. The historical way this has
137 	 * been handled is by making a flag mean that all higher versions
138 	 * are disabled, if any version lower than the flag is enabled.
139 	 */
140 
141 	min_version = 0;
142 	max_version = TLS1_3_VERSION;
143 	options = s->internal->options;
144 
145 	if (SSL_is_dtls(s)) {
146 		options = 0;
147 		if (s->internal->options & SSL_OP_NO_DTLSv1)
148 			options |= SSL_OP_NO_TLSv1_1;
149 		if (s->internal->options & SSL_OP_NO_DTLSv1_2)
150 			options |= SSL_OP_NO_TLSv1_2;
151 	}
152 
153 	if ((options & SSL_OP_NO_TLSv1) == 0)
154 		min_version = TLS1_VERSION;
155 	else if ((options & SSL_OP_NO_TLSv1_1) == 0)
156 		min_version = TLS1_1_VERSION;
157 	else if ((options & SSL_OP_NO_TLSv1_2) == 0)
158 		min_version = TLS1_2_VERSION;
159 	else if ((options & SSL_OP_NO_TLSv1_3) == 0)
160 		min_version = TLS1_3_VERSION;
161 
162 	if ((options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
163 		max_version = TLS1_2_VERSION;
164 	if ((options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
165 		max_version = TLS1_1_VERSION;
166 	if ((options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
167 		max_version = TLS1_VERSION;
168 	if ((options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
169 		max_version = 0;
170 
171 	/* Everything has been disabled... */
172 	if (min_version == 0 || max_version == 0)
173 		return 0;
174 
175 	/* Limit to configured version range. */
176 	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
177 	    s->internal->min_tls_version, s->internal->max_tls_version))
178 		return 0;
179 
180 	if (min_ver != NULL)
181 		*min_ver = min_version;
182 	if (max_ver != NULL)
183 		*max_ver = max_version;
184 
185 	return 1;
186 }
187 
188 int
189 ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
190 {
191 	uint16_t min_version, max_version;
192 
193 	if (!ssl_enabled_tls_version_range(s, &min_version, &max_version))
194 		return 0;
195 
196 	/* Limit to the versions supported by this method. */
197 	if (!ssl_clamp_tls_version_range(&min_version, &max_version,
198 	    s->method->internal->min_tls_version,
199 	    s->method->internal->max_tls_version))
200 		return 0;
201 
202 	if (min_ver != NULL)
203 		*min_ver = min_version;
204 	if (max_ver != NULL)
205 		*max_ver = max_version;
206 
207 	return 1;
208 }
209 
210 uint16_t
211 ssl_tls_version(uint16_t version)
212 {
213 	if (version == TLS1_VERSION || version == TLS1_1_VERSION ||
214 	    version == TLS1_2_VERSION || version == TLS1_3_VERSION)
215 		return version;
216 
217 	if (version == DTLS1_VERSION)
218 		return TLS1_1_VERSION;
219 	if (version == DTLS1_2_VERSION)
220 		return TLS1_2_VERSION;
221 
222 	return 0;
223 }
224 
225 uint16_t
226 ssl_effective_tls_version(SSL *s)
227 {
228 	if (S3I(s)->hs.negotiated_tls_version > 0)
229 		return S3I(s)->hs.negotiated_tls_version;
230 
231 	return S3I(s)->hs.our_max_tls_version;
232 }
233 
234 int
235 ssl_max_supported_version(SSL *s, uint16_t *max_ver)
236 {
237 	uint16_t max_version;
238 
239 	*max_ver = 0;
240 
241 	if (!ssl_supported_tls_version_range(s, NULL, &max_version))
242 		return 0;
243 
244 	if (SSL_is_dtls(s)) {
245 		if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0)
246 			return 0;
247 	}
248 
249 	*max_ver = max_version;
250 
251 	return 1;
252 }
253 
254 int
255 ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
256 {
257 	uint16_t min_version, max_version, peer_tls_version, shared_version;
258 
259 	*max_ver = 0;
260 	peer_tls_version = peer_ver;
261 
262 	if (SSL_is_dtls(s)) {
263 		if ((peer_ver >> 8) != DTLS1_VERSION_MAJOR)
264 			return 0;
265 
266 		/*
267 		 * Convert the peer version to a TLS version - DTLS versions are
268 		 * the 1's complement of TLS version numbers (but not the actual
269 		 * protocol version numbers, that would be too sensible). Not to
270 		 * mention that DTLSv1.0 is really equivalent to DTLSv1.1.
271 		 */
272 		peer_tls_version = ssl_dtls_to_tls_version(peer_ver);
273 
274 		/*
275 		 * This may be a version that we do not know about, if it is
276 		 * newer than DTLS1_2_VERSION (yes, less than is correct due
277 		 * to the "clever" versioning scheme), use TLS1_2_VERSION.
278 		 */
279 		if (peer_tls_version == 0) {
280 			if (peer_ver < DTLS1_2_VERSION)
281 				peer_tls_version = TLS1_2_VERSION;
282 		}
283 	}
284 
285 	if (peer_tls_version >= TLS1_3_VERSION)
286 		shared_version = TLS1_3_VERSION;
287 	else if (peer_tls_version >= TLS1_2_VERSION)
288 		shared_version = TLS1_2_VERSION;
289 	else if (peer_tls_version >= TLS1_1_VERSION)
290 		shared_version = TLS1_1_VERSION;
291 	else if (peer_tls_version >= TLS1_VERSION)
292 		shared_version = TLS1_VERSION;
293 	else
294 		return 0;
295 
296 	if (!ssl_supported_tls_version_range(s, &min_version, &max_version))
297 		return 0;
298 
299 	if (shared_version < min_version)
300 		return 0;
301 
302 	if (shared_version > max_version)
303 		shared_version = max_version;
304 
305 	if (SSL_is_dtls(s)) {
306 		/*
307 		 * The resulting shared version will by definition be something
308 		 * that we know about. Switch back from TLS to DTLS.
309 		 */
310 		shared_version = ssl_tls_to_dtls_version(shared_version);
311 		if (shared_version == 0)
312 			return 0;
313 	}
314 
315 	*max_ver = shared_version;
316 
317 	return 1;
318 }
319 
320 int
321 ssl_check_version_from_server(SSL *s, uint16_t server_version)
322 {
323 	uint16_t min_tls_version, max_tls_version, server_tls_version;
324 
325 	/* Ensure that the version selected by the server is valid. */
326 
327 	server_tls_version = server_version;
328 	if (SSL_is_dtls(s)) {
329 		server_tls_version = ssl_dtls_to_tls_version(server_version);
330 		if (server_tls_version == 0)
331 			return 0;
332 	}
333 
334 	if (!ssl_supported_tls_version_range(s, &min_tls_version,
335 	    &max_tls_version))
336 		return 0;
337 
338 	return (server_tls_version >= min_tls_version &&
339 	    server_tls_version <= max_tls_version);
340 }
341 
342 int
343 ssl_legacy_stack_version(SSL *s, uint16_t version)
344 {
345 	if (SSL_is_dtls(s))
346 		return version == DTLS1_VERSION || version == DTLS1_2_VERSION;
347 
348 	return version == TLS1_VERSION || version == TLS1_1_VERSION ||
349 	    version == TLS1_2_VERSION;
350 }
351