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