libc: remove THIRDPARTYLICENSE/extract-copyright
[unleashed.git] / lib / libssl / ssl_versions.c
blob240a2498aa8fd1b1b241318a39affd21686d526b
1 /* $OpenBSD: ssl_versions.c,v 1.3 2017/05/06 20:37:25 jsing Exp $ */
2 /*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
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.
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.
18 #include "ssl_locl.h"
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)
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;
29 if (*min_ver < clamp_min)
30 *min_ver = clamp_min;
31 if (*max_ver > clamp_max)
32 *max_ver = clamp_max;
34 return 1;
37 int
38 ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
39 uint16_t *out_ver)
41 uint16_t min_version, max_version;
43 if (ver == 0) {
44 *out_ver = meth->internal->min_version;
45 return 1;
48 min_version = ver;
49 max_version = max_ver;
51 if (!ssl_clamp_version_range(&min_version, &max_version,
52 meth->internal->min_version, meth->internal->max_version))
53 return 0;
55 *out_ver = min_version;
57 return 1;
60 int
61 ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
62 uint16_t *out_ver)
64 uint16_t min_version, max_version;
66 if (ver == 0) {
67 *out_ver = meth->internal->max_version;
68 return 1;
71 min_version = min_ver;
72 max_version = ver;
74 if (!ssl_clamp_version_range(&min_version, &max_version,
75 meth->internal->min_version, meth->internal->max_version))
76 return 0;
78 *out_ver = max_version;
80 return 1;
83 int
84 ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
86 uint16_t min_version, max_version;
89 * The enabled versions have to be a contiguous range, which means we
90 * cannot enable and disable single versions at our whim, even though
91 * this is what the OpenSSL flags allow. The historical way this has
92 * been handled is by making a flag mean that all higher versions
93 * are disabled, if any version lower than the flag is enabled.
96 min_version = 0;
97 max_version = TLS1_2_VERSION;
99 if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
100 min_version = TLS1_VERSION;
101 else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
102 min_version = TLS1_1_VERSION;
103 else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
104 min_version = TLS1_2_VERSION;
106 if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
107 max_version = TLS1_1_VERSION;
108 if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
109 max_version = TLS1_VERSION;
110 if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
111 max_version = 0;
113 /* Everything has been disabled... */
114 if (min_version == 0 || max_version == 0)
115 return 0;
117 /* Limit to configured version range. */
118 if (!ssl_clamp_version_range(&min_version, &max_version,
119 s->internal->min_version, s->internal->max_version))
120 return 0;
122 if (min_ver != NULL)
123 *min_ver = min_version;
124 if (max_ver != NULL)
125 *max_ver = max_version;
127 return 1;
131 ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
133 uint16_t min_version, max_version;
135 /* DTLS cannot currently be disabled... */
136 if (SSL_IS_DTLS(s)) {
137 min_version = max_version = DTLS1_VERSION;
138 goto done;
141 if (!ssl_enabled_version_range(s, &min_version, &max_version))
142 return 0;
144 /* Limit to the versions supported by this method. */
145 if (!ssl_clamp_version_range(&min_version, &max_version,
146 s->method->internal->min_version,
147 s->method->internal->max_version))
148 return 0;
150 done:
151 if (min_ver != NULL)
152 *min_ver = min_version;
153 if (max_ver != NULL)
154 *max_ver = max_version;
156 return 1;
160 ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
162 uint16_t min_version, max_version, shared_version;
164 *max_ver = 0;
166 if (SSL_IS_DTLS(s)) {
167 if (peer_ver >= DTLS1_VERSION) {
168 *max_ver = DTLS1_VERSION;
169 return 1;
171 return 0;
174 if (peer_ver >= TLS1_2_VERSION)
175 shared_version = TLS1_2_VERSION;
176 else if (peer_ver >= TLS1_1_VERSION)
177 shared_version = TLS1_1_VERSION;
178 else if (peer_ver >= TLS1_VERSION)
179 shared_version = TLS1_VERSION;
180 else
181 return 0;
183 if (!ssl_supported_version_range(s, &min_version, &max_version))
184 return 0;
186 if (shared_version < min_version)
187 return 0;
189 if (shared_version > max_version)
190 shared_version = max_version;
192 *max_ver = shared_version;
194 return 1;
197 uint16_t
198 ssl_max_server_version(SSL *s)
200 uint16_t max_version, min_version = 0;
202 if (SSL_IS_DTLS(s))
203 return (DTLS1_VERSION);
205 if (!ssl_enabled_version_range(s, &min_version, &max_version))
206 return 0;
209 * Limit to the versions supported by this method. The SSL method
210 * will be changed during version negotiation, as such we want to
211 * use the SSL method from the context.
213 if (!ssl_clamp_version_range(&min_version, &max_version,
214 s->ctx->method->internal->min_version,
215 s->ctx->method->internal->max_version))
216 return 0;
218 return (max_version);