diff options
author | jsing <> | 2021-03-17 17:22:37 +0000 |
---|---|---|
committer | jsing <> | 2021-03-17 17:22:37 +0000 |
commit | 711af08cbe9bb90ae55d4c27ec386382f9839842 (patch) | |
tree | c7924ad9aad4539ea5e12c61599389215af6638e /src | |
parent | d14580de7d53e6c9e8f64e58e979f8d959902ad3 (diff) | |
download | openbsd-711af08cbe9bb90ae55d4c27ec386382f9839842.tar.gz openbsd-711af08cbe9bb90ae55d4c27ec386382f9839842.tar.bz2 openbsd-711af08cbe9bb90ae55d4c27ec386382f9839842.zip |
Add support for DTLSv1.2 version handling.
This teaches the version functions that handle protocol versions about
DTLSv1.2 and the SSL_OP_NO_DTLS* options. We effectively convert between
TLS and TLS protocol versions where necessary.
ok inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_versions.c | 162 |
1 files changed, 117 insertions, 45 deletions
diff --git a/src/lib/libssl/ssl_versions.c b/src/lib/libssl/ssl_versions.c index 45e468f0d8..4ea8dc58c4 100644 --- a/src/lib/libssl/ssl_versions.c +++ b/src/lib/libssl/ssl_versions.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_versions.c,v 1.15 2021/03/11 17:14:47 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_versions.c,v 1.16 2021/03/17 17:22:37 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -17,6 +17,26 @@ | |||
17 | 17 | ||
18 | #include "ssl_locl.h" | 18 | #include "ssl_locl.h" |
19 | 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 | |||
20 | static int | 40 | static int |
21 | ssl_clamp_tls_version_range(uint16_t *min_ver, uint16_t *max_ver, | 41 | ssl_clamp_tls_version_range(uint16_t *min_ver, uint16_t *max_ver, |
22 | uint16_t clamp_min, uint16_t clamp_max) | 42 | uint16_t clamp_min, uint16_t clamp_max) |
@@ -38,30 +58,33 @@ int | |||
38 | ssl_version_set_min(const SSL_METHOD *meth, uint16_t proto_ver, | 58 | ssl_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) | 59 | uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver) |
40 | { | 60 | { |
41 | uint16_t min_version, max_version; | 61 | uint16_t min_proto, min_version, max_version; |
42 | 62 | ||
43 | if (proto_ver == 0) { | 63 | if (proto_ver == 0) { |
44 | *out_tls_ver = meth->internal->min_tls_version; | 64 | *out_tls_ver = meth->internal->min_tls_version; |
45 | *out_proto_ver = 0; | 65 | *out_proto_ver = 0; |
46 | return 1; | 66 | return 1; |
47 | } | 67 | } |
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 | 68 | ||
56 | min_version = proto_ver; | 69 | min_version = proto_ver; |
57 | max_version = max_tls_ver; | 70 | max_version = max_tls_ver; |
58 | 71 | ||
72 | if (meth->internal->dtls) { | ||
73 | if ((min_version = ssl_dtls_to_tls_version(proto_ver)) == 0) | ||
74 | return 0; | ||
75 | } | ||
76 | |||
59 | if (!ssl_clamp_tls_version_range(&min_version, &max_version, | 77 | if (!ssl_clamp_tls_version_range(&min_version, &max_version, |
60 | meth->internal->min_tls_version, meth->internal->max_tls_version)) | 78 | meth->internal->min_tls_version, meth->internal->max_tls_version)) |
61 | return 0; | 79 | return 0; |
62 | 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 | } | ||
63 | *out_tls_ver = min_version; | 86 | *out_tls_ver = min_version; |
64 | *out_proto_ver = min_version; | 87 | *out_proto_ver = min_proto; |
65 | 88 | ||
66 | return 1; | 89 | return 1; |
67 | } | 90 | } |
@@ -70,30 +93,33 @@ int | |||
70 | ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver, | 93 | ssl_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) | 94 | uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver) |
72 | { | 95 | { |
73 | uint16_t min_version, max_version; | 96 | uint16_t max_proto, min_version, max_version; |
74 | 97 | ||
75 | if (proto_ver == 0) { | 98 | if (proto_ver == 0) { |
76 | *out_tls_ver = meth->internal->max_tls_version; | 99 | *out_tls_ver = meth->internal->max_tls_version; |
77 | *out_proto_ver = 0; | 100 | *out_proto_ver = 0; |
78 | return 1; | 101 | return 1; |
79 | } | 102 | } |
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 | 103 | ||
88 | min_version = min_tls_ver; | 104 | min_version = min_tls_ver; |
89 | max_version = proto_ver; | 105 | max_version = proto_ver; |
90 | 106 | ||
107 | if (meth->internal->dtls) { | ||
108 | if ((max_version = ssl_dtls_to_tls_version(proto_ver)) == 0) | ||
109 | return 0; | ||
110 | } | ||
111 | |||
91 | if (!ssl_clamp_tls_version_range(&min_version, &max_version, | 112 | if (!ssl_clamp_tls_version_range(&min_version, &max_version, |
92 | meth->internal->min_tls_version, meth->internal->max_tls_version)) | 113 | meth->internal->min_tls_version, meth->internal->max_tls_version)) |
93 | return 0; | 114 | return 0; |
94 | 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 | } | ||
95 | *out_tls_ver = max_version; | 121 | *out_tls_ver = max_version; |
96 | *out_proto_ver = max_version; | 122 | *out_proto_ver = max_proto; |
97 | 123 | ||
98 | return 1; | 124 | return 1; |
99 | } | 125 | } |
@@ -102,6 +128,7 @@ int | |||
102 | ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver) | 128 | ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver) |
103 | { | 129 | { |
104 | uint16_t min_version, max_version; | 130 | uint16_t min_version, max_version; |
131 | unsigned long options; | ||
105 | 132 | ||
106 | /* | 133 | /* |
107 | * The enabled versions have to be a contiguous range, which means we | 134 | * The enabled versions have to be a contiguous range, which means we |
@@ -113,23 +140,32 @@ ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver) | |||
113 | 140 | ||
114 | min_version = 0; | 141 | min_version = 0; |
115 | max_version = TLS1_3_VERSION; | 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 | } | ||
116 | 152 | ||
117 | if ((s->internal->options & SSL_OP_NO_TLSv1) == 0) | 153 | if ((options & SSL_OP_NO_TLSv1) == 0) |
118 | min_version = TLS1_VERSION; | 154 | min_version = TLS1_VERSION; |
119 | else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0) | 155 | else if ((options & SSL_OP_NO_TLSv1_1) == 0) |
120 | min_version = TLS1_1_VERSION; | 156 | min_version = TLS1_1_VERSION; |
121 | else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0) | 157 | else if ((options & SSL_OP_NO_TLSv1_2) == 0) |
122 | min_version = TLS1_2_VERSION; | 158 | min_version = TLS1_2_VERSION; |
123 | else if ((s->internal->options & SSL_OP_NO_TLSv1_3) == 0) | 159 | else if ((options & SSL_OP_NO_TLSv1_3) == 0) |
124 | min_version = TLS1_3_VERSION; | 160 | min_version = TLS1_3_VERSION; |
125 | 161 | ||
126 | if ((s->internal->options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION) | 162 | if ((options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION) |
127 | max_version = TLS1_2_VERSION; | 163 | max_version = TLS1_2_VERSION; |
128 | if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION) | 164 | if ((options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION) |
129 | max_version = TLS1_1_VERSION; | 165 | max_version = TLS1_1_VERSION; |
130 | if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION) | 166 | if ((options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION) |
131 | max_version = TLS1_VERSION; | 167 | max_version = TLS1_VERSION; |
132 | if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION) | 168 | if ((options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION) |
133 | max_version = 0; | 169 | max_version = 0; |
134 | 170 | ||
135 | /* Everything has been disabled... */ | 171 | /* Everything has been disabled... */ |
@@ -198,15 +234,19 @@ ssl_effective_tls_version(SSL *s) | |||
198 | int | 234 | int |
199 | ssl_max_supported_version(SSL *s, uint16_t *max_ver) | 235 | ssl_max_supported_version(SSL *s, uint16_t *max_ver) |
200 | { | 236 | { |
237 | uint16_t max_version; | ||
238 | |||
201 | *max_ver = 0; | 239 | *max_ver = 0; |
202 | 240 | ||
241 | if (!ssl_supported_tls_version_range(s, NULL, &max_version)) | ||
242 | return 0; | ||
243 | |||
203 | if (SSL_is_dtls(s)) { | 244 | if (SSL_is_dtls(s)) { |
204 | *max_ver = DTLS1_VERSION; | 245 | if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0) |
205 | return 1; | 246 | return 0; |
206 | } | 247 | } |
207 | 248 | ||
208 | if (!ssl_supported_tls_version_range(s, NULL, max_ver)) | 249 | *max_ver = max_version; |
209 | return 0; | ||
210 | 250 | ||
211 | return 1; | 251 | return 1; |
212 | } | 252 | } |
@@ -214,25 +254,41 @@ ssl_max_supported_version(SSL *s, uint16_t *max_ver) | |||
214 | int | 254 | int |
215 | ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) | 255 | ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) |
216 | { | 256 | { |
217 | uint16_t min_version, max_version, shared_version; | 257 | uint16_t min_version, max_version, peer_tls_version, shared_version; |
218 | 258 | ||
219 | *max_ver = 0; | 259 | *max_ver = 0; |
260 | peer_tls_version = peer_ver; | ||
220 | 261 | ||
221 | if (SSL_is_dtls(s)) { | 262 | if (SSL_is_dtls(s)) { |
222 | if (peer_ver >= DTLS1_VERSION) { | 263 | if ((peer_ver >> 8) != DTLS1_VERSION_MAJOR) |
223 | *max_ver = DTLS1_VERSION; | 264 | return 0; |
224 | return 1; | 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; | ||
225 | } | 282 | } |
226 | return 0; | ||
227 | } | 283 | } |
228 | 284 | ||
229 | if (peer_ver >= TLS1_3_VERSION) | 285 | if (peer_tls_version >= TLS1_3_VERSION) |
230 | shared_version = TLS1_3_VERSION; | 286 | shared_version = TLS1_3_VERSION; |
231 | else if (peer_ver >= TLS1_2_VERSION) | 287 | else if (peer_tls_version >= TLS1_2_VERSION) |
232 | shared_version = TLS1_2_VERSION; | 288 | shared_version = TLS1_2_VERSION; |
233 | else if (peer_ver >= TLS1_1_VERSION) | 289 | else if (peer_tls_version >= TLS1_1_VERSION) |
234 | shared_version = TLS1_1_VERSION; | 290 | shared_version = TLS1_1_VERSION; |
235 | else if (peer_ver >= TLS1_VERSION) | 291 | else if (peer_tls_version >= TLS1_VERSION) |
236 | shared_version = TLS1_VERSION; | 292 | shared_version = TLS1_VERSION; |
237 | else | 293 | else |
238 | return 0; | 294 | return 0; |
@@ -246,6 +302,16 @@ ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) | |||
246 | if (shared_version > max_version) | 302 | if (shared_version > max_version) |
247 | shared_version = max_version; | 303 | shared_version = max_version; |
248 | 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 | |||
249 | *max_ver = shared_version; | 315 | *max_ver = shared_version; |
250 | 316 | ||
251 | return 1; | 317 | return 1; |
@@ -254,17 +320,23 @@ ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) | |||
254 | int | 320 | int |
255 | ssl_check_version_from_server(SSL *s, uint16_t server_version) | 321 | ssl_check_version_from_server(SSL *s, uint16_t server_version) |
256 | { | 322 | { |
257 | uint16_t min_version, max_version; | 323 | uint16_t min_tls_version, max_tls_version, server_tls_version; |
258 | 324 | ||
259 | /* Ensure that the version selected by the server is valid. */ | 325 | /* Ensure that the version selected by the server is valid. */ |
260 | 326 | ||
261 | if (SSL_is_dtls(s)) | 327 | server_tls_version = server_version; |
262 | return (server_version == DTLS1_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 | } | ||
263 | 333 | ||
264 | if (!ssl_supported_tls_version_range(s, &min_version, &max_version)) | 334 | if (!ssl_supported_tls_version_range(s, &min_tls_version, |
335 | &max_tls_version)) | ||
265 | return 0; | 336 | return 0; |
266 | 337 | ||
267 | return (server_version >= min_version && server_version <= max_version); | 338 | return (server_tls_version >= min_tls_version && |
339 | server_tls_version <= max_tls_version); | ||
268 | } | 340 | } |
269 | 341 | ||
270 | int | 342 | int |