1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GnuTLS.
7 *
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>
20 *
21 */
22
23 #include "gnutls_int.h"
24 #include <algorithms.h>
25 #include "errors.h"
26 #include <x509/common.h>
27 #include "c-strcase.h"
28
29 /* TLS Versions */
30
31 static SYSTEM_CONFIG_OR_CONST
32 version_entry_st sup_versions[] = {
33 {.name = "SSL3.0",
34 .id = GNUTLS_SSL3,
35 .age = 0,
36 .major = 3,
37 .minor = 0,
38 .transport = GNUTLS_STREAM,
39 #ifdef ENABLE_SSL3
40 .supported = 1,
41 #endif
42 .explicit_iv = 0,
43 .extensions = 0,
44 .selectable_sighash = 0,
45 .selectable_prf = 0,
46 .obsolete = 1,
47 .only_extension = 0,
48 .tls_sig_sem = SIG_SEM_PRE_TLS12,
49 .false_start = 0
50 },
51 {.name = "TLS1.0",
52 .id = GNUTLS_TLS1,
53 .age = 1,
54 .major = 3,
55 .minor = 1,
56 .transport = GNUTLS_STREAM,
57 .supported = 1,
58 .explicit_iv = 0,
59 .extensions = 1,
60 .selectable_sighash = 0,
61 .selectable_prf = 0,
62 .obsolete = 0,
63 .only_extension = 0,
64 .tls_sig_sem = SIG_SEM_PRE_TLS12,
65 .false_start = 0
66 },
67 {.name = "TLS1.1",
68 .id = GNUTLS_TLS1_1,
69 .age = 2,
70 .major = 3,
71 .minor = 2,
72 .transport = GNUTLS_STREAM,
73 .supported = 1,
74 .explicit_iv = 1,
75 .extensions = 1,
76 .selectable_sighash = 0,
77 .selectable_prf = 0,
78 .obsolete = 0,
79 .only_extension = 0,
80 .tls_sig_sem = SIG_SEM_PRE_TLS12,
81 .false_start = 0
82 },
83 {.name = "TLS1.2",
84 .id = GNUTLS_TLS1_2,
85 .age = 3,
86 .major = 3,
87 .minor = 3,
88 .transport = GNUTLS_STREAM,
89 .supported = 1,
90 .explicit_iv = 1,
91 .extensions = 1,
92 .selectable_sighash = 1,
93 .selectable_prf = 1,
94 .obsolete = 0,
95 .only_extension = 0,
96 .tls_sig_sem = SIG_SEM_PRE_TLS12,
97 .false_start = 1
98 },
99 {.name = "TLS1.3",
100 .id = GNUTLS_TLS1_3,
101 .age = 5,
102 .major = 3,
103 .minor = 4,
104 .transport = GNUTLS_STREAM,
105 .supported = 1,
106 .explicit_iv = 0,
107 .extensions = 1,
108 .selectable_sighash = 1,
109 .selectable_prf = 1,
110 .tls13_sem = 1,
111 .obsolete = 0,
112 .only_extension = 1,
113 .post_handshake_auth = 1,
114 .multi_ocsp = 1,
115 .key_shares = 1,
116 .false_start = 0, /* doesn't make sense */
117 .tls_sig_sem = SIG_SEM_TLS13
118 },
119 {.name = "DTLS0.9", /* Cisco AnyConnect (based on about OpenSSL 0.9.8e) */
120 .id = GNUTLS_DTLS0_9,
121 .age = 200,
122 .major = 1,
123 .minor = 0,
124 .transport = GNUTLS_DGRAM,
125 .supported = 1,
126 .explicit_iv = 1,
127 .extensions = 1,
128 .selectable_sighash = 0,
129 .selectable_prf = 0,
130 .obsolete = 0,
131 .only_extension = 0,
132 .tls_sig_sem = SIG_SEM_PRE_TLS12,
133 .false_start = 0
134 },
135 {.name = "DTLS1.0",
136 .id = GNUTLS_DTLS1_0,
137 .age = 201,
138 .major = 254,
139 .minor = 255,
140 .transport = GNUTLS_DGRAM,
141 .supported = 1,
142 .explicit_iv = 1,
143 .extensions = 1,
144 .selectable_sighash = 0,
145 .selectable_prf = 0,
146 .obsolete = 0,
147 .only_extension = 0,
148 .tls_sig_sem = SIG_SEM_PRE_TLS12,
149 .false_start = 0
150 },
151 {.name = "DTLS1.2",
152 .id = GNUTLS_DTLS1_2,
153 .age = 202,
154 .major = 254,
155 .minor = 253,
156 .transport = GNUTLS_DGRAM,
157 .supported = 1,
158 .explicit_iv = 1,
159 .extensions = 1,
160 .selectable_sighash = 1,
161 .selectable_prf = 1,
162 .obsolete = 0,
163 .only_extension = 0,
164 .tls_sig_sem = SIG_SEM_PRE_TLS12,
165 .false_start = 1
166 },
167 {0, 0, 0, 0, 0}
168 };
169
version_to_entry(gnutls_protocol_t version)170 const version_entry_st *version_to_entry(gnutls_protocol_t version)
171 {
172 const version_entry_st *p;
173
174 for (p = sup_versions; p->name != NULL; p++)
175 if (p->id == version)
176 return p;
177 return NULL;
178 }
179
nversion_to_entry(uint8_t major,uint8_t minor)180 const version_entry_st *nversion_to_entry(uint8_t major, uint8_t minor)
181 {
182 const version_entry_st *p;
183
184 for (p = sup_versions; p->name != NULL; p++) {
185 if ((p->major == major) && (p->minor == minor))
186 return p;
187 }
188 return NULL;
189 }
190
191 static int
version_is_valid_for_session(gnutls_session_t session,const version_entry_st * v)192 version_is_valid_for_session(gnutls_session_t session,
193 const version_entry_st *v)
194 {
195 if (v->supported && v->transport == session->internals.transport) {
196 return 1;
197 }
198 return 0;
199 }
200
_gnutls_version_mark_disabled(const char * name)201 int _gnutls_version_mark_disabled(const char *name)
202 {
203 #ifndef DISABLE_SYSTEM_CONFIG
204 version_entry_st *p;
205
206 for (p = sup_versions; p->name != NULL; p++)
207 if (c_strcasecmp(p->name, name) == 0) {
208 p->supported = 0;
209 return 0;
210 }
211
212 #endif
213 return GNUTLS_E_INVALID_REQUEST;
214 }
215
216 /* Return the priority of the provided version number */
217 int
_gnutls_version_priority(gnutls_session_t session,gnutls_protocol_t version)218 _gnutls_version_priority(gnutls_session_t session,
219 gnutls_protocol_t version)
220 {
221 unsigned int i;
222
223 for (i = 0; i < session->internals.priorities->protocol.num_priorities;
224 i++) {
225 if (session->internals.priorities->protocol.priorities[i] ==
226 version)
227 return i;
228 }
229 return -1;
230 }
231
232 /* Returns the lowest TLS version number in the priorities.
233 */
_gnutls_version_lowest(gnutls_session_t session)234 const version_entry_st *_gnutls_version_lowest(gnutls_session_t session)
235 {
236 unsigned int i;
237 gnutls_protocol_t cur_prot;
238 const version_entry_st *v, *min_v = NULL;
239 const version_entry_st *backup = NULL;
240
241 for (i=0;i < session->internals.priorities->protocol.num_priorities;i++) {
242 cur_prot =
243 session->internals.priorities->protocol.priorities[i];
244 v = version_to_entry(cur_prot);
245
246 if (v != NULL && version_is_valid_for_session(session, v)) {
247 if (min_v == NULL) {
248 if (v->obsolete != 0)
249 backup = v;
250 else
251 min_v = v;
252 } else if (v->obsolete == 0 && v->age < min_v->age) {
253 min_v = v;
254 }
255 }
256 }
257
258 if (min_v == NULL)
259 return backup;
260
261 return min_v;
262 }
263
264 /* Returns the maximum version in the priorities
265 */
_gnutls_version_max(gnutls_session_t session)266 const version_entry_st *_gnutls_version_max(gnutls_session_t session)
267 {
268 unsigned int i;
269 gnutls_protocol_t cur_prot;
270 const version_entry_st *p, *max = NULL;
271
272 for (i = 0; i < session->internals.priorities->protocol.num_priorities;
273 i++) {
274 cur_prot =
275 session->internals.priorities->protocol.priorities[i];
276
277 for (p = sup_versions; p->name != NULL; p++) {
278 if(p->id == cur_prot) {
279 #ifndef ENABLE_SSL3
280 if (p->obsolete != 0)
281 break;
282 #endif
283 if (!p->supported || p->transport != session->internals.transport)
284 break;
285
286 if (p->tls13_sem && (session->internals.flags & INT_FLAG_NO_TLS13))
287 break;
288
289 if (max == NULL || cur_prot > max->id) {
290 max = p;
291 }
292
293 break;
294 }
295 }
296 }
297
298 return max;
299 }
300
_gnutls_legacy_version_max(gnutls_session_t session)301 const version_entry_st *_gnutls_legacy_version_max(gnutls_session_t session)
302 {
303 const version_entry_st *max = _gnutls_version_max(session);
304
305 if (max && max->only_extension != 0) {
306 /* TLS 1.3 or later found */
307 if (max->transport == GNUTLS_STREAM) {
308 return version_to_entry(GNUTLS_TLS1_2);
309 } else {
310 return version_to_entry(GNUTLS_DTLS1_2);
311 }
312 }
313
314 return max;
315 }
316
317 /* Returns the number of bytes written to buffer or a negative
318 * error code. It will return GNUTLS_E_UNSUPPORTED_VERSION_PACKET
319 * if there is no version >= TLS 1.3.
320 */
_gnutls_write_supported_versions(gnutls_session_t session,uint8_t * buffer,ssize_t buffer_size)321 int _gnutls_write_supported_versions(gnutls_session_t session, uint8_t *buffer, ssize_t buffer_size)
322 {
323 gnutls_protocol_t cur_prot;
324 size_t written_bytes = 0;
325 unsigned at_least_one_new = 0;
326 unsigned i;
327 const version_entry_st *p;
328
329 for (i = 0; i < session->internals.priorities->protocol.num_priorities; i++) {
330 cur_prot =
331 session->internals.priorities->protocol.priorities[i];
332
333 for (p = sup_versions; p->name != NULL; p++) {
334 if(p->id == cur_prot) {
335 if (p->obsolete != 0)
336 break;
337
338 if (!p->supported || p->transport != session->internals.transport)
339 break;
340
341 if (p->only_extension)
342 at_least_one_new = 1;
343
344 if (buffer_size > 2) {
345 _gnutls_debug_log("Advertizing version %d.%d\n", (int)p->major, (int)p->minor);
346 buffer[0] = p->major;
347 buffer[1] = p->minor;
348 written_bytes += 2;
349 buffer += 2;
350 }
351
352 buffer_size -= 2;
353
354 if (buffer_size <= 0)
355 goto finish;
356
357 break;
358 }
359 }
360 }
361
362 finish:
363 if (written_bytes == 0)
364 return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
365
366 if (at_least_one_new == 0)
367 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
368
369 return written_bytes;
370 }
371
372 /* Returns true (1) if the given version is higher than the highest supported
373 * and (0) otherwise */
_gnutls_version_is_too_high(gnutls_session_t session,uint8_t major,uint8_t minor)374 unsigned _gnutls_version_is_too_high(gnutls_session_t session, uint8_t major, uint8_t minor)
375 {
376 const version_entry_st *e;
377
378 e = _gnutls_legacy_version_max(session);
379 if (e == NULL) /* we don't know; but that means something is unconfigured */
380 return 1;
381
382 if (e->transport == GNUTLS_DGRAM) {
383 if (major < e->major)
384 return 1;
385
386 if (e->major == major && minor < e->minor)
387 return 1;
388 } else {
389 if (major > e->major)
390 return 1;
391
392 if (e->major == major && minor > e->minor)
393 return 1;
394 }
395
396 return 0;
397 }
398
399 /**
400 * gnutls_protocol_get_name:
401 * @version: is a (gnutls) version number
402 *
403 * Convert a #gnutls_protocol_t value to a string.
404 *
405 * Returns: a string that contains the name of the specified TLS
406 * version (e.g., "TLS1.0"), or %NULL.
407 **/
gnutls_protocol_get_name(gnutls_protocol_t version)408 const char *gnutls_protocol_get_name(gnutls_protocol_t version)
409 {
410 const version_entry_st *p;
411 /* avoid prefix */
412 for (p = sup_versions; p->name != NULL; p++)
413 if (p->id == version)
414 return p->name;
415 return NULL;
416 }
417
418 /**
419 * gnutls_protocol_get_id:
420 * @name: is a protocol name
421 *
422 * The names are compared in a case insensitive way.
423 *
424 * Returns: an id of the specified protocol, or
425 * %GNUTLS_VERSION_UNKNOWN on error.
426 **/
gnutls_protocol_get_id(const char * name)427 gnutls_protocol_t gnutls_protocol_get_id(const char *name)
428 {
429 const version_entry_st *p;
430 gnutls_protocol_t ret = GNUTLS_VERSION_UNKNOWN;
431
432 for (p = sup_versions; p->name != NULL; p++) {
433 if (c_strcasecmp(p->name, name) == 0) {
434 ret = p->id;
435 break;
436 }
437 }
438
439 return ret;
440 }
441
442 /**
443 * gnutls_protocol_list:
444 *
445 * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
446 *
447 * This function is not thread safe.
448 *
449 * Returns: a (0)-terminated list of #gnutls_protocol_t integers
450 * indicating the available protocols.
451 *
452 **/
gnutls_protocol_list(void)453 const gnutls_protocol_t *gnutls_protocol_list(void)
454 {
455 const version_entry_st *p;
456 static gnutls_protocol_t supported_protocols[MAX_ALGOS] = { 0 };
457
458 if (supported_protocols[0] == 0) {
459 int i = 0;
460
461 for (p = sup_versions; p->name != NULL; p++) {
462 if (!p->supported)
463 continue;
464 supported_protocols[i++] = p->id;
465 }
466 supported_protocols[i++] = 0;
467 }
468
469 return supported_protocols;
470 }
471
472 /* Returns a version number given the major and minor numbers.
473 */
_gnutls_version_get(uint8_t major,uint8_t minor)474 gnutls_protocol_t _gnutls_version_get(uint8_t major, uint8_t minor)
475 {
476 const version_entry_st *p;
477 int ret = GNUTLS_VERSION_UNKNOWN;
478
479 for (p = sup_versions; p->name != NULL; p++)
480 if ((p->major == major) && (p->minor == minor))
481 ret = p->id;
482 return ret;
483 }
484
485 /* Version Functions */
486
487 int
_gnutls_nversion_is_supported(gnutls_session_t session,unsigned char major,unsigned char minor)488 _gnutls_nversion_is_supported(gnutls_session_t session,
489 unsigned char major, unsigned char minor)
490 {
491 const version_entry_st *p;
492 int version = 0;
493
494 for (p = sup_versions; p->name != NULL; p++) {
495 if(p->major == major && p->minor == minor) {
496 #ifndef ENABLE_SSL3
497 if (p->obsolete != 0) return 0;
498 #endif
499 if (p->tls13_sem && (session->internals.flags & INT_FLAG_NO_TLS13))
500 return 0;
501
502 if (!p->supported || p->transport != session->internals.transport)
503 return 0;
504
505 version = p->id;
506 break;
507 }
508 }
509
510 if (version == 0)
511 return 0;
512
513 if (_gnutls_version_priority(session, version) < 0)
514 return 0; /* disabled by the user */
515 else
516 return 1;
517 }
518