1 /* $OpenBSD: ssl_versions.c,v 1.3 2017/05/06 20:37:25 jsing Exp $ */
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.
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
)
26 if (clamp_max
< *min_ver
|| clamp_min
> *max_ver
)
29 if (*min_ver
< clamp_min
)
31 if (*max_ver
> clamp_max
)
38 ssl_version_set_min(const SSL_METHOD
*meth
, uint16_t ver
, uint16_t max_ver
,
41 uint16_t min_version
, max_version
;
44 *out_ver
= meth
->internal
->min_version
;
49 max_version
= max_ver
;
51 if (!ssl_clamp_version_range(&min_version
, &max_version
,
52 meth
->internal
->min_version
, meth
->internal
->max_version
))
55 *out_ver
= min_version
;
61 ssl_version_set_max(const SSL_METHOD
*meth
, uint16_t ver
, uint16_t min_ver
,
64 uint16_t min_version
, max_version
;
67 *out_ver
= meth
->internal
->max_version
;
71 min_version
= min_ver
;
74 if (!ssl_clamp_version_range(&min_version
, &max_version
,
75 meth
->internal
->min_version
, meth
->internal
->max_version
))
78 *out_ver
= max_version
;
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.
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
)
113 /* Everything has been disabled... */
114 if (min_version
== 0 || max_version
== 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
))
123 *min_ver
= min_version
;
125 *max_ver
= max_version
;
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
;
141 if (!ssl_enabled_version_range(s
, &min_version
, &max_version
))
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
))
152 *min_ver
= min_version
;
154 *max_ver
= max_version
;
160 ssl_max_shared_version(SSL
*s
, uint16_t peer_ver
, uint16_t *max_ver
)
162 uint16_t min_version
, max_version
, shared_version
;
166 if (SSL_IS_DTLS(s
)) {
167 if (peer_ver
>= DTLS1_VERSION
) {
168 *max_ver
= DTLS1_VERSION
;
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
;
183 if (!ssl_supported_version_range(s
, &min_version
, &max_version
))
186 if (shared_version
< min_version
)
189 if (shared_version
> max_version
)
190 shared_version
= max_version
;
192 *max_ver
= shared_version
;
198 ssl_max_server_version(SSL
*s
)
200 uint16_t max_version
, min_version
= 0;
203 return (DTLS1_VERSION
);
205 if (!ssl_enabled_version_range(s
, &min_version
, &max_version
))
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
))
218 return (max_version
);