xref: /openbsd-src/lib/libssl/ssl_versions.c (revision 58fbf5d6aa35e3d66f2c32c61d2f38824a990e85)
1 /* $OpenBSD: ssl_versions.c,v 1.11 2021/02/20 09:43:29 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 
20 static int
21 ssl_clamp_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 
37 int
38 ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
39     uint16_t *out_ver, uint16_t *out_proto_ver)
40 {
41 	uint16_t min_version, max_version;
42 
43 	if (ver == 0) {
44 		*out_ver = meth->internal->min_version;
45 		*out_proto_ver = 0;
46 		return 1;
47 	}
48 
49 	min_version = ver;
50 	max_version = max_ver;
51 
52 	if (!ssl_clamp_version_range(&min_version, &max_version,
53 	    meth->internal->min_version, meth->internal->max_version))
54 		return 0;
55 
56 	*out_ver = *out_proto_ver = min_version;
57 
58 	return 1;
59 }
60 
61 int
62 ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
63     uint16_t *out_ver, uint16_t *out_proto_ver)
64 {
65 	uint16_t min_version, max_version;
66 
67 	if (ver == 0) {
68 		*out_ver = meth->internal->max_version;
69 		*out_proto_ver = 0;
70 		return 1;
71 	}
72 
73 	min_version = min_ver;
74 	max_version = ver;
75 
76 	if (!ssl_clamp_version_range(&min_version, &max_version,
77 	    meth->internal->min_version, meth->internal->max_version))
78 		return 0;
79 
80 	*out_ver = *out_proto_ver = max_version;
81 
82 	return 1;
83 }
84 
85 int
86 ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
87 {
88 	uint16_t min_version, max_version;
89 
90 	/*
91 	 * The enabled versions have to be a contiguous range, which means we
92 	 * cannot enable and disable single versions at our whim, even though
93 	 * this is what the OpenSSL flags allow. The historical way this has
94 	 * been handled is by making a flag mean that all higher versions
95 	 * are disabled, if any version lower than the flag is enabled.
96 	 */
97 
98 	min_version = 0;
99 	max_version = TLS1_3_VERSION;
100 
101 	if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
102 		min_version = TLS1_VERSION;
103 	else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
104 		min_version = TLS1_1_VERSION;
105 	else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
106 		min_version = TLS1_2_VERSION;
107 	else if ((s->internal->options & SSL_OP_NO_TLSv1_3) == 0)
108 		min_version = TLS1_3_VERSION;
109 
110 	if ((s->internal->options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
111 		max_version = TLS1_2_VERSION;
112 	if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
113 		max_version = TLS1_1_VERSION;
114 	if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
115 		max_version = TLS1_VERSION;
116 	if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
117 		max_version = 0;
118 
119 	/* Everything has been disabled... */
120 	if (min_version == 0 || max_version == 0)
121 		return 0;
122 
123 	/* Limit to configured version range. */
124 	if (!ssl_clamp_version_range(&min_version, &max_version,
125 	    s->internal->min_version, s->internal->max_version))
126 		return 0;
127 
128 	if (min_ver != NULL)
129 		*min_ver = min_version;
130 	if (max_ver != NULL)
131 		*max_ver = max_version;
132 
133 	return 1;
134 }
135 
136 int
137 ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
138 {
139 	uint16_t min_version, max_version;
140 
141 	/* DTLS cannot currently be disabled... */
142 	if (SSL_is_dtls(s)) {
143 		min_version = max_version = DTLS1_VERSION;
144 		goto done;
145 	}
146 
147 	if (!ssl_enabled_version_range(s, &min_version, &max_version))
148 		return 0;
149 
150 	/* Limit to the versions supported by this method. */
151 	if (!ssl_clamp_version_range(&min_version, &max_version,
152 	    s->method->internal->min_version,
153 	    s->method->internal->max_version))
154 		return 0;
155 
156  done:
157 	if (min_ver != NULL)
158 		*min_ver = min_version;
159 	if (max_ver != NULL)
160 		*max_ver = max_version;
161 
162 	return 1;
163 }
164 
165 int
166 ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
167 {
168 	uint16_t min_version, max_version, shared_version;
169 
170 	*max_ver = 0;
171 
172 	if (SSL_is_dtls(s)) {
173 		if (peer_ver >= DTLS1_VERSION) {
174 			*max_ver = DTLS1_VERSION;
175 			return 1;
176 		}
177 		return 0;
178 	}
179 
180 	if (peer_ver >= TLS1_3_VERSION)
181 		shared_version = TLS1_3_VERSION;
182 	else if (peer_ver >= TLS1_2_VERSION)
183 		shared_version = TLS1_2_VERSION;
184 	else if (peer_ver >= TLS1_1_VERSION)
185 		shared_version = TLS1_1_VERSION;
186 	else if (peer_ver >= TLS1_VERSION)
187 		shared_version = TLS1_VERSION;
188 	else
189 		return 0;
190 
191 	if (!ssl_supported_version_range(s, &min_version, &max_version))
192 		return 0;
193 
194 	if (shared_version < min_version)
195 		return 0;
196 
197 	if (shared_version > max_version)
198 		shared_version = max_version;
199 
200 	*max_ver = shared_version;
201 
202 	return 1;
203 }
204 
205 int
206 ssl_downgrade_max_version(SSL *s, uint16_t *max_ver)
207 {
208 	uint16_t min_version, max_version;
209 
210 	/*
211 	 * The downgrade maximum version is based on the versions that are
212 	 * enabled, however we also have to then limit to the versions
213 	 * supported by the method. The SSL method will be changed during
214 	 * version negotiation and when switching from the new stack to
215 	 * the legacy context, as such we want to use the method from the
216 	 * context.
217 	 */
218 
219 	if (SSL_is_dtls(s)) {
220 		*max_ver = DTLS1_VERSION;
221 		return 1;
222 	}
223 
224 	if (!ssl_enabled_version_range(s, &min_version, &max_version))
225 		return 0;
226 
227 	if (!ssl_clamp_version_range(&min_version, &max_version,
228 	    s->ctx->method->internal->min_version,
229 	    s->ctx->method->internal->max_version))
230 		return 0;
231 
232 	*max_ver = max_version;
233 
234 	return 1;
235 }
236 
237 int
238 ssl_legacy_stack_version(SSL *s, uint16_t version)
239 {
240 	if (SSL_is_dtls(s))
241 		return version == DTLS1_VERSION || version == DTLS1_2_VERSION;
242 
243 	return version == TLS1_VERSION || version == TLS1_1_VERSION ||
244 	    version == TLS1_2_VERSION;
245 }
246