1 /*
2  * Copyright (C) 2004-2015 Free Software Foundation, Inc.
3  * Copyright (C) 2015-2019 Red Hat, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <https://www.gnu.org/licenses/>
21  *
22  */
23 
24 /* Here lies the code of the gnutls_*_set_priority() functions.
25  */
26 
27 #include "gnutls_int.h"
28 #include "algorithms.h"
29 #include "errors.h"
30 #include <num.h>
31 #include <gnutls/x509.h>
32 #include <c-ctype.h>
33 #include <hello_ext.h>
34 #include <c-strcase.h>
35 #include "fips.h"
36 #include "errno.h"
37 #include "ext/srp.h"
38 #include <gnutls/gnutls.h>
39 #include "profiles.h"
40 #include "c-strcase.h"
41 #include "inih/ini.h"
42 #include "profiles.h"
43 #include "name_val_array.h"
44 
45 #define MAX_ELEMENTS 64
46 
47 #define ENABLE_PROFILE(c, profile) do { \
48 	c->additional_verify_flags &= 0x00ffffff; \
49 	c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(profile); \
50 	c->level = _gnutls_profile_to_sec_level(profile); \
51 	} while(0)
52 
53 /* This function is used by the test suite */
54 char *_gnutls_resolve_priorities(const char* priorities);
55 const char *_gnutls_default_priority_string = DEFAULT_PRIORITY_STRING;
56 
57 static void prio_remove(priority_st * priority_list, unsigned int algo);
58 static void prio_add(priority_st * priority_list, unsigned int algo);
59 static void
60 break_list(char *etag,
61 		 char *broken_etag[MAX_ELEMENTS], int *size);
62 
63 typedef void (bulk_rmadd_func) (priority_st * priority_list, const int *);
64 
_set_priority(priority_st * st,const int * list)65 inline static void _set_priority(priority_st * st, const int *list)
66 {
67 	int num = 0, i;
68 
69 	while (list[num] != 0)
70 		num++;
71 	if (num > MAX_ALGOS)
72 		num = MAX_ALGOS;
73 	st->num_priorities = num;
74 
75 	for (i = 0; i < num; i++) {
76 		st->priorities[i] = list[i];
77 	}
78 
79 	return;
80 }
81 
_add_priority(priority_st * st,const int * list)82 inline static void _add_priority(priority_st * st, const int *list)
83 {
84 	int num, i, j, init;
85 
86 	init = i = st->num_priorities;
87 
88 	for (num = 0; list[num] != 0; ++num) {
89 		if (i + 1 > MAX_ALGOS) {
90 			return;
91 		}
92 
93 		for (j = 0; j < init; j++) {
94 			if (st->priorities[j] == (unsigned) list[num]) {
95 				break;
96 			}
97 		}
98 
99 		if (j == init) {
100 			st->priorities[i++] = list[num];
101 			st->num_priorities++;
102 		}
103 	}
104 
105 	return;
106 }
107 
_clear_priorities(priority_st * st,const int * list)108 static void _clear_priorities(priority_st * st, const int *list)
109 {
110 	memset(st, 0, sizeof(*st));
111 }
112 
_clear_given_priorities(priority_st * st,const int * list)113 static void _clear_given_priorities(priority_st * st, const int *list)
114 {
115 	unsigned i;
116 
117 	for (i=0;list[i]!=0;i++) {
118 		prio_remove(st, list[i]);
119 	}
120 }
121 
122 static const int _supported_groups_dh[] = {
123 	GNUTLS_GROUP_FFDHE2048,
124 	GNUTLS_GROUP_FFDHE3072,
125 	GNUTLS_GROUP_FFDHE4096,
126 	GNUTLS_GROUP_FFDHE6144,
127 	GNUTLS_GROUP_FFDHE8192,
128 	0
129 };
130 
131 static const int _supported_groups_ecdh[] = {
132 	GNUTLS_GROUP_SECP256R1,
133 	GNUTLS_GROUP_SECP384R1,
134 	GNUTLS_GROUP_SECP521R1,
135 	GNUTLS_GROUP_X25519, /* RFC 8422 */
136 	GNUTLS_GROUP_X448, /* RFC 8422 */
137 	0
138 };
139 
140 static const int _supported_groups_gost[] = {
141 #ifdef ENABLE_GOST
142 	GNUTLS_GROUP_GC256A,
143 	GNUTLS_GROUP_GC256B,
144 	GNUTLS_GROUP_GC256C,
145 	GNUTLS_GROUP_GC256D,
146 	GNUTLS_GROUP_GC512A,
147 	GNUTLS_GROUP_GC512B,
148 	GNUTLS_GROUP_GC512C,
149 #endif
150 	0
151 };
152 
153 static const int _supported_groups_normal[] = {
154 	GNUTLS_GROUP_SECP256R1,
155 	GNUTLS_GROUP_SECP384R1,
156 	GNUTLS_GROUP_SECP521R1,
157 	GNUTLS_GROUP_X25519, /* RFC 8422 */
158 	GNUTLS_GROUP_X448, /* RFC 8422 */
159 
160 	/* These should stay last as our default behavior
161 	 * is to send key shares for two top types (GNUTLS_KEY_SHARE_TOP2)
162 	 * and we wouldn't want to have these sent by all clients
163 	 * by default as they are quite expensive CPU-wise. */
164 	GNUTLS_GROUP_FFDHE2048,
165 	GNUTLS_GROUP_FFDHE3072,
166 	GNUTLS_GROUP_FFDHE4096,
167 	GNUTLS_GROUP_FFDHE6144,
168 	GNUTLS_GROUP_FFDHE8192,
169 	0
170 };
171 static const int* supported_groups_normal = _supported_groups_normal;
172 
173 static const int _supported_groups_secure128[] = {
174 	GNUTLS_GROUP_SECP256R1,
175 	GNUTLS_GROUP_SECP384R1,
176 	GNUTLS_GROUP_SECP521R1,
177 	GNUTLS_GROUP_X25519, /* RFC 8422 */
178 	GNUTLS_GROUP_X448, /* RFC 8422 */
179 	GNUTLS_GROUP_FFDHE2048,
180 	GNUTLS_GROUP_FFDHE3072,
181 	GNUTLS_GROUP_FFDHE4096,
182 	GNUTLS_GROUP_FFDHE6144,
183 	GNUTLS_GROUP_FFDHE8192,
184 	0
185 };
186 static const int* supported_groups_secure128 = _supported_groups_secure128;
187 
188 static const int _supported_groups_suiteb128[] = {
189 	GNUTLS_GROUP_SECP256R1,
190 	GNUTLS_GROUP_SECP384R1,
191 	0
192 };
193 static const int* supported_groups_suiteb128 = _supported_groups_suiteb128;
194 
195 static const int _supported_groups_suiteb192[] = {
196 	GNUTLS_GROUP_SECP384R1,
197 	0
198 };
199 static const int* supported_groups_suiteb192 = _supported_groups_suiteb192;
200 
201 static const int _supported_groups_secure192[] = {
202 	GNUTLS_GROUP_SECP384R1,
203 	GNUTLS_GROUP_SECP521R1,
204 	GNUTLS_GROUP_FFDHE8192,
205 	0
206 };
207 static const int* supported_groups_secure192 = _supported_groups_secure192;
208 
209 static const int protocol_priority[] = {
210 	GNUTLS_TLS1_3,
211 	GNUTLS_TLS1_2,
212 	GNUTLS_TLS1_1,
213 	GNUTLS_TLS1_0,
214 	GNUTLS_DTLS1_2,
215 	GNUTLS_DTLS1_0,
216 	0
217 };
218 
219 /* contains all the supported TLS protocols, intended to be used for eliminating them
220  */
221 static const int stream_protocol_priority[] = {
222 	GNUTLS_TLS1_3,
223 	GNUTLS_TLS1_2,
224 	GNUTLS_TLS1_1,
225 	GNUTLS_TLS1_0,
226 	0
227 };
228 
229 /* contains all the supported DTLS protocols, intended to be used for eliminating them
230  */
231 static const int dgram_protocol_priority[] = {
232 	GNUTLS_DTLS1_2,
233 	GNUTLS_DTLS1_0,
234 	GNUTLS_DTLS0_9,
235 	0
236 };
237 
238 static const int dtls_protocol_priority[] = {
239 	GNUTLS_DTLS1_2,
240 	GNUTLS_DTLS1_0,
241 	0
242 };
243 
244 static const int _protocol_priority_suiteb[] = {
245 	GNUTLS_TLS1_2,
246 	0
247 };
248 static const int* protocol_priority_suiteb = _protocol_priority_suiteb;
249 
250 static const int _kx_priority_performance[] = {
251 	GNUTLS_KX_RSA,
252 #ifdef ENABLE_ECDHE
253 	GNUTLS_KX_ECDHE_ECDSA,
254 	GNUTLS_KX_ECDHE_RSA,
255 #endif
256 #ifdef ENABLE_DHE
257 	GNUTLS_KX_DHE_RSA,
258 #endif
259 	0
260 };
261 static const int* kx_priority_performance = _kx_priority_performance;
262 
263 static const int _kx_priority_pfs[] = {
264 #ifdef ENABLE_ECDHE
265 	GNUTLS_KX_ECDHE_ECDSA,
266 	GNUTLS_KX_ECDHE_RSA,
267 #endif
268 #ifdef ENABLE_DHE
269 	GNUTLS_KX_DHE_RSA,
270 #endif
271 	0
272 };
273 static const int* kx_priority_pfs = _kx_priority_pfs;
274 
275 static const int _kx_priority_suiteb[] = {
276 	GNUTLS_KX_ECDHE_ECDSA,
277 	0
278 };
279 static const int* kx_priority_suiteb = _kx_priority_suiteb;
280 
281 static const int _kx_priority_secure[] = {
282 	/* The ciphersuites that offer forward secrecy take
283 	 * precedence
284 	 */
285 #ifdef ENABLE_ECDHE
286 	GNUTLS_KX_ECDHE_ECDSA,
287 	GNUTLS_KX_ECDHE_RSA,
288 #endif
289 	GNUTLS_KX_RSA,
290 	/* KX-RSA is now ahead of DHE-RSA and DHE-DSS due to the compatibility
291 	 * issues the DHE ciphersuites have. That is, one cannot enforce a specific
292 	 * security level without dropping the connection.
293 	 */
294 #ifdef ENABLE_DHE
295 	GNUTLS_KX_DHE_RSA,
296 #endif
297 	/* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
298 	 */
299 	0
300 };
301 static const int* kx_priority_secure = _kx_priority_secure;
302 
303 static const int _kx_priority_gost[] = {
304 	GNUTLS_KX_VKO_GOST_12,
305 	0,
306 };
307 static const int* kx_priority_gost = _kx_priority_gost;
308 
309 static const int _cipher_priority_performance_default[] = {
310 	GNUTLS_CIPHER_AES_128_GCM,
311 	GNUTLS_CIPHER_AES_256_GCM,
312 	GNUTLS_CIPHER_CHACHA20_POLY1305,
313 	GNUTLS_CIPHER_AES_128_CCM,
314 	GNUTLS_CIPHER_AES_256_CCM,
315 	GNUTLS_CIPHER_AES_128_CBC,
316 	GNUTLS_CIPHER_AES_256_CBC,
317 	0
318 };
319 
320 static const int _cipher_priority_performance_no_aesni[] = {
321 	GNUTLS_CIPHER_CHACHA20_POLY1305,
322 	GNUTLS_CIPHER_AES_128_GCM,
323 	GNUTLS_CIPHER_AES_256_GCM,
324 	GNUTLS_CIPHER_AES_128_CCM,
325 	GNUTLS_CIPHER_AES_256_CCM,
326 	GNUTLS_CIPHER_AES_128_CBC,
327 	GNUTLS_CIPHER_AES_256_CBC,
328 	0
329 };
330 
331 /* If GCM and AES acceleration is available then prefer
332  * them over anything else. Overall we prioritise AEAD
333  * over legacy ciphers, and 256-bit over 128 (for future
334  * proof).
335  */
336 static const int _cipher_priority_normal_default[] = {
337 	GNUTLS_CIPHER_AES_256_GCM,
338 	GNUTLS_CIPHER_CHACHA20_POLY1305,
339 	GNUTLS_CIPHER_AES_256_CCM,
340 
341 	GNUTLS_CIPHER_AES_256_CBC,
342 
343 	GNUTLS_CIPHER_AES_128_GCM,
344 	GNUTLS_CIPHER_AES_128_CCM,
345 
346 	GNUTLS_CIPHER_AES_128_CBC,
347 	0
348 };
349 
350 static const int cipher_priority_performance_fips[] = {
351 	GNUTLS_CIPHER_AES_128_GCM,
352 	GNUTLS_CIPHER_AES_128_CCM,
353 	GNUTLS_CIPHER_AES_256_GCM,
354 	GNUTLS_CIPHER_AES_256_CCM,
355 
356 	GNUTLS_CIPHER_AES_128_CBC,
357 	GNUTLS_CIPHER_AES_256_CBC,
358 	0
359 };
360 
361 static const int cipher_priority_normal_fips[] = {
362 	GNUTLS_CIPHER_AES_256_GCM,
363 	GNUTLS_CIPHER_AES_256_CCM,
364 	GNUTLS_CIPHER_AES_256_CBC,
365 
366 	GNUTLS_CIPHER_AES_128_GCM,
367 	GNUTLS_CIPHER_AES_128_CBC,
368 	GNUTLS_CIPHER_AES_128_CCM,
369 	0
370 };
371 
372 
373 static const int _cipher_priority_suiteb128[] = {
374 	GNUTLS_CIPHER_AES_256_GCM,
375 	GNUTLS_CIPHER_AES_128_GCM,
376 	0
377 };
378 static const int* cipher_priority_suiteb128 = _cipher_priority_suiteb128;
379 
380 static const int _cipher_priority_suiteb192[] = {
381 	GNUTLS_CIPHER_AES_256_GCM,
382 	0
383 };
384 static const int* cipher_priority_suiteb192 = _cipher_priority_suiteb192;
385 
386 
387 static const int _cipher_priority_secure128[] = {
388 	GNUTLS_CIPHER_AES_256_GCM,
389 	GNUTLS_CIPHER_CHACHA20_POLY1305,
390 	GNUTLS_CIPHER_AES_256_CBC,
391 	GNUTLS_CIPHER_AES_256_CCM,
392 
393 	GNUTLS_CIPHER_AES_128_GCM,
394 	GNUTLS_CIPHER_AES_128_CBC,
395 	GNUTLS_CIPHER_AES_128_CCM,
396 	0
397 };
398 static const int *cipher_priority_secure128 = _cipher_priority_secure128;
399 
400 
401 static const int _cipher_priority_secure192[] = {
402 	GNUTLS_CIPHER_AES_256_GCM,
403 	GNUTLS_CIPHER_CHACHA20_POLY1305,
404 	GNUTLS_CIPHER_AES_256_CBC,
405 	GNUTLS_CIPHER_AES_256_CCM,
406 	0
407 };
408 static const int* cipher_priority_secure192 = _cipher_priority_secure192;
409 
410 static const int _sign_priority_default[] = {
411 	GNUTLS_SIGN_RSA_SHA256,
412 	GNUTLS_SIGN_RSA_PSS_SHA256,
413 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA256,
414 	GNUTLS_SIGN_ECDSA_SHA256,
415 	GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
416 
417 	GNUTLS_SIGN_EDDSA_ED25519,
418 
419 	GNUTLS_SIGN_RSA_SHA384,
420 	GNUTLS_SIGN_RSA_PSS_SHA384,
421 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA384,
422 	GNUTLS_SIGN_ECDSA_SHA384,
423 	GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
424 
425 	GNUTLS_SIGN_EDDSA_ED448,
426 
427 	GNUTLS_SIGN_RSA_SHA512,
428 	GNUTLS_SIGN_RSA_PSS_SHA512,
429 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA512,
430 
431 	GNUTLS_SIGN_ECDSA_SHA512,
432 	GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
433 
434 	GNUTLS_SIGN_RSA_SHA1,
435 	GNUTLS_SIGN_ECDSA_SHA1,
436 
437 	0
438 };
439 static const int* sign_priority_default = _sign_priority_default;
440 
441 static const int _sign_priority_suiteb128[] = {
442 	GNUTLS_SIGN_ECDSA_SHA256,
443 	GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
444 	GNUTLS_SIGN_ECDSA_SHA384,
445 	GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
446 	0
447 };
448 static const int* sign_priority_suiteb128 = _sign_priority_suiteb128;
449 
450 static const int _sign_priority_suiteb192[] = {
451 	GNUTLS_SIGN_ECDSA_SHA384,
452 	GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
453 	0
454 };
455 static const int* sign_priority_suiteb192 = _sign_priority_suiteb192;
456 
457 static const int _sign_priority_secure128[] = {
458 	GNUTLS_SIGN_RSA_SHA256,
459 	GNUTLS_SIGN_RSA_PSS_SHA256,
460 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA256,
461 	GNUTLS_SIGN_ECDSA_SHA256,
462 	GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
463 
464 	GNUTLS_SIGN_EDDSA_ED25519,
465 
466 	GNUTLS_SIGN_RSA_SHA384,
467 	GNUTLS_SIGN_RSA_PSS_SHA384,
468 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA384,
469 	GNUTLS_SIGN_ECDSA_SHA384,
470 	GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
471 
472 	GNUTLS_SIGN_EDDSA_ED448,
473 
474 	GNUTLS_SIGN_RSA_SHA512,
475 	GNUTLS_SIGN_RSA_PSS_SHA512,
476 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA512,
477 	GNUTLS_SIGN_ECDSA_SHA512,
478 	GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
479 
480 	0
481 };
482 static const int* sign_priority_secure128 = _sign_priority_secure128;
483 
484 static const int _sign_priority_secure192[] = {
485 	GNUTLS_SIGN_RSA_SHA384,
486 	GNUTLS_SIGN_RSA_PSS_SHA384,
487 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA384,
488 	GNUTLS_SIGN_ECDSA_SHA384,
489 	GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
490 	GNUTLS_SIGN_RSA_SHA512,
491 	GNUTLS_SIGN_RSA_PSS_SHA512,
492 	GNUTLS_SIGN_RSA_PSS_RSAE_SHA512,
493 	GNUTLS_SIGN_ECDSA_SHA512,
494 	GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
495 
496 	0
497 };
498 static const int* sign_priority_secure192 = _sign_priority_secure192;
499 
500 static const int _sign_priority_gost[] = {
501 	GNUTLS_SIGN_GOST_256,
502 	GNUTLS_SIGN_GOST_512,
503 
504 	0
505 };
506 static const int* sign_priority_gost = _sign_priority_gost;
507 
508 static const int mac_priority_normal_default[] = {
509 	GNUTLS_MAC_SHA1,
510 	GNUTLS_MAC_AEAD,
511 	0
512 };
513 
514 static const int mac_priority_normal_fips[] = {
515 	GNUTLS_MAC_SHA1,
516 	GNUTLS_MAC_AEAD,
517 	0
518 };
519 
520 static const int *cipher_priority_performance = _cipher_priority_performance_default;
521 static const int *cipher_priority_normal = _cipher_priority_normal_default;
522 static const int *mac_priority_normal = mac_priority_normal_default;
523 
524 static const int _cipher_priority_gost[] = {
525 	GNUTLS_CIPHER_GOST28147_TC26Z_CNT,
526 	0
527 };
528 static const int *cipher_priority_gost = _cipher_priority_gost;
529 
530 static const int _mac_priority_gost[] = {
531 	GNUTLS_MAC_GOST28147_TC26Z_IMIT,
532 	0
533 };
534 static const int *mac_priority_gost = _mac_priority_gost;
535 
536 /* if called with replace the default priorities with the FIPS140 ones */
_gnutls_priority_update_fips(void)537 void _gnutls_priority_update_fips(void)
538 {
539 	cipher_priority_performance = cipher_priority_performance_fips;
540 	cipher_priority_normal = cipher_priority_normal_fips;
541 	mac_priority_normal = mac_priority_normal_fips;
542 }
543 
_gnutls_priority_update_non_aesni(void)544 void _gnutls_priority_update_non_aesni(void)
545 {
546 	/* if we have no AES acceleration in performance mode
547 	 * prefer fast stream ciphers */
548 	if (_gnutls_fips_mode_enabled() == 0) {
549 		cipher_priority_performance = _cipher_priority_performance_no_aesni;
550 	}
551 }
552 
553 static const int _mac_priority_suiteb[] = {
554 	GNUTLS_MAC_AEAD,
555 	0
556 };
557 static const int* mac_priority_suiteb = _mac_priority_suiteb;
558 
559 static const int _mac_priority_secure128[] = {
560 	GNUTLS_MAC_SHA1,
561 	GNUTLS_MAC_AEAD,
562 	0
563 };
564 static const int* mac_priority_secure128 = _mac_priority_secure128;
565 
566 static const int _mac_priority_secure192[] = {
567 	GNUTLS_MAC_AEAD,
568 	0
569 };
570 static const int* mac_priority_secure192 = _mac_priority_secure192;
571 
572 static const int cert_type_priority_default[] = {
573 	GNUTLS_CRT_X509,
574 	0
575 };
576 
577 static const int cert_type_priority_all[] = {
578 	GNUTLS_CRT_X509,
579 	GNUTLS_CRT_RAWPK,
580 	0
581 };
582 
583 typedef void (rmadd_func) (priority_st * priority_list, unsigned int alg);
584 
prio_remove(priority_st * priority_list,unsigned int algo)585 static void prio_remove(priority_st * priority_list, unsigned int algo)
586 {
587 	unsigned int i;
588 
589 	for (i = 0; i < priority_list->num_priorities; i++) {
590 		if (priority_list->priorities[i] == algo) {
591 			priority_list->num_priorities--;
592 			if ((priority_list->num_priorities - i) > 0)
593 				memmove(&priority_list->priorities[i],
594 					&priority_list->priorities[i + 1],
595 					(priority_list->num_priorities -
596 					 i) *
597 					sizeof(priority_list->
598 					       priorities[0]));
599 			priority_list->priorities[priority_list->
600 						num_priorities] = 0;
601 			break;
602 		}
603 	}
604 
605 	return;
606 }
607 
prio_add(priority_st * priority_list,unsigned int algo)608 static void prio_add(priority_st * priority_list, unsigned int algo)
609 {
610 	unsigned int i, l = priority_list->num_priorities;
611 
612 	if (l >= MAX_ALGOS)
613 		return;		/* can't add it anyway */
614 
615 	for (i = 0; i < l; ++i) {
616 		if (algo == priority_list->priorities[i])
617 			return;	/* if it exists */
618 	}
619 
620 	priority_list->priorities[l] = algo;
621 	priority_list->num_priorities++;
622 
623 	return;
624 }
625 
626 
627 /**
628  * gnutls_priority_set:
629  * @session: is a #gnutls_session_t type.
630  * @priority: is a #gnutls_priority_t type.
631  *
632  * Sets the priorities to use on the ciphers, key exchange methods,
633  * and macs. Note that this function is expected to be called once
634  * per session; when called multiple times (e.g., before a re-handshake,
635  * the caller should make sure that any new settings are not incompatible
636  * with the original session).
637  *
638  * Returns: %GNUTLS_E_SUCCESS on success, or an error code on error.
639  **/
640 int
gnutls_priority_set(gnutls_session_t session,gnutls_priority_t priority)641 gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority)
642 {
643 	int ret;
644 
645 	if (priority == NULL || priority->protocol.num_priorities == 0 ||
646 	    priority->cs.size == 0)
647 		return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
648 
649 	/* set the current version to the first in the chain, if this is
650 	 * the call before the initial handshake. During a re-handshake
651 	 * we do not set the version to avoid overriding the currently
652 	 * negotiated version. */
653 	if (!session->internals.handshake_in_progress &&
654 	    !session->internals.initial_negotiation_completed) {
655 		ret = _gnutls_set_current_version(session,
656 						  priority->protocol.priorities[0]);
657 		if (ret < 0)
658 			return gnutls_assert_val(ret);
659 	}
660 
661 	/* At this point the provided priorities passed the sanity tests */
662 
663 	if (session->internals.priorities)
664 		gnutls_priority_deinit(session->internals.priorities);
665 
666 	gnutls_atomic_increment(&priority->usage_cnt);
667 	session->internals.priorities = priority;
668 
669 	if (priority->no_tickets != 0) {
670 		/* when PFS is explicitly requested, disable session tickets */
671 		session->internals.flags |= GNUTLS_NO_TICKETS;
672 	}
673 
674 	ADD_PROFILE_VFLAGS(session, priority->additional_verify_flags);
675 
676 	/* mirror variables */
677 #undef COPY_TO_INTERNALS
678 #define COPY_TO_INTERNALS(xx) session->internals.xx = priority->_##xx
679 	COPY_TO_INTERNALS(allow_large_records);
680 	COPY_TO_INTERNALS(allow_small_records);
681 	COPY_TO_INTERNALS(no_etm);
682 	COPY_TO_INTERNALS(no_ext_master_secret);
683 	COPY_TO_INTERNALS(allow_key_usage_violation);
684 	COPY_TO_INTERNALS(allow_wrong_pms);
685 	COPY_TO_INTERNALS(dumbfw);
686 	COPY_TO_INTERNALS(dh_prime_bits);
687 
688 	return 0;
689 }
690 
691 
692 #define LEVEL_NONE "NONE"
693 #define LEVEL_NORMAL "NORMAL"
694 #define LEVEL_PFS "PFS"
695 #define LEVEL_PERFORMANCE "PERFORMANCE"
696 #define LEVEL_SECURE128 "SECURE128"
697 #define LEVEL_SECURE192 "SECURE192"
698 #define LEVEL_SECURE256 "SECURE256"
699 #define LEVEL_SUITEB128 "SUITEB128"
700 #define LEVEL_SUITEB192 "SUITEB192"
701 #define LEVEL_LEGACY "LEGACY"
702 
703 struct priority_groups_st {
704 	const char *name;
705 	const char *alias;
706 	const int **proto_list;
707 	const int **cipher_list;
708 	const int **mac_list;
709 	const int **kx_list;
710 	const int **sign_list;
711 	const int **group_list;
712 	unsigned profile;
713 	int sec_param;
714 	bool no_tickets;
715 };
716 
717 static const struct priority_groups_st pgroups[] =
718 {
719 	{.name = LEVEL_NORMAL,
720 	 .cipher_list = &cipher_priority_normal,
721 	 .mac_list = &mac_priority_normal,
722 	 .kx_list = &kx_priority_secure,
723 	 .sign_list = &sign_priority_default,
724 	 .group_list = &supported_groups_normal,
725 	 .profile = GNUTLS_PROFILE_LOW,
726 	 .sec_param = GNUTLS_SEC_PARAM_WEAK
727 	},
728 	{.name = LEVEL_PFS,
729 	 .cipher_list = &cipher_priority_normal,
730 	 .mac_list = &mac_priority_secure128,
731 	 .kx_list = &kx_priority_pfs,
732 	 .sign_list = &sign_priority_default,
733 	 .group_list = &supported_groups_normal,
734 	 .profile = GNUTLS_PROFILE_LOW,
735 	 .sec_param = GNUTLS_SEC_PARAM_WEAK,
736 	 .no_tickets = 1
737 	},
738 	{.name = LEVEL_SECURE128,
739 	 .alias = "SECURE",
740 	 .cipher_list = &cipher_priority_secure128,
741 	 .mac_list = &mac_priority_secure128,
742 	 .kx_list = &kx_priority_secure,
743 	 .sign_list = &sign_priority_secure128,
744 	 .group_list = &supported_groups_secure128,
745 		/* The profile should have been HIGH but if we don't allow
746 		 * SHA-1 (80-bits) as signature algorithm we are not able
747 		 * to connect anywhere with this level */
748 	 .profile = GNUTLS_PROFILE_LOW,
749 	 .sec_param = GNUTLS_SEC_PARAM_LOW
750 	},
751 	{.name = LEVEL_SECURE192,
752 	 .alias = LEVEL_SECURE256,
753 	 .cipher_list = &cipher_priority_secure192,
754 	 .mac_list = &mac_priority_secure192,
755 	 .kx_list = &kx_priority_secure,
756 	 .sign_list = &sign_priority_secure192,
757 	 .group_list = &supported_groups_secure192,
758 	 .profile = GNUTLS_PROFILE_HIGH,
759 	 .sec_param = GNUTLS_SEC_PARAM_HIGH
760 	},
761 	{.name = LEVEL_SUITEB128,
762 	 .proto_list = &protocol_priority_suiteb,
763 	 .cipher_list = &cipher_priority_suiteb128,
764 	 .mac_list = &mac_priority_suiteb,
765 	 .kx_list = &kx_priority_suiteb,
766 	 .sign_list = &sign_priority_suiteb128,
767 	 .group_list = &supported_groups_suiteb128,
768 	 .profile = GNUTLS_PROFILE_SUITEB128,
769 	 .sec_param = GNUTLS_SEC_PARAM_HIGH
770 	},
771 	{.name = LEVEL_SUITEB192,
772 	 .proto_list = &protocol_priority_suiteb,
773 	 .cipher_list = &cipher_priority_suiteb192,
774 	 .mac_list = &mac_priority_suiteb,
775 	 .kx_list = &kx_priority_suiteb,
776 	 .sign_list = &sign_priority_suiteb192,
777 	 .group_list = &supported_groups_suiteb192,
778 	 .profile = GNUTLS_PROFILE_SUITEB192,
779 	 .sec_param = GNUTLS_SEC_PARAM_ULTRA
780 	},
781 	{.name = LEVEL_LEGACY,
782 	 .cipher_list = &cipher_priority_normal,
783 	 .mac_list = &mac_priority_normal,
784 	 .kx_list = &kx_priority_secure,
785 	 .sign_list = &sign_priority_default,
786 	 .group_list = &supported_groups_normal,
787 	 .sec_param = GNUTLS_SEC_PARAM_VERY_WEAK
788 	},
789 	{.name = LEVEL_PERFORMANCE,
790 	 .cipher_list = &cipher_priority_performance,
791 	 .mac_list = &mac_priority_normal,
792 	 .kx_list = &kx_priority_performance,
793 	 .sign_list = &sign_priority_default,
794 	 .group_list = &supported_groups_normal,
795 	 .profile = GNUTLS_PROFILE_LOW,
796 	 .sec_param = GNUTLS_SEC_PARAM_WEAK
797 	},
798 	{
799 	 .name = NULL,
800 	}
801 };
802 
803 #define SET_PROFILE(to_set) \
804 	profile = GNUTLS_VFLAGS_TO_PROFILE(priority_cache->additional_verify_flags); \
805 	if (profile == 0 || profile > to_set) { \
806 		priority_cache->additional_verify_flags &= ~GNUTLS_VFLAGS_PROFILE_MASK; \
807 		priority_cache->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(to_set); \
808 	}
809 
810 #define SET_LEVEL(to_set) \
811 		if (priority_cache->level == 0 || (unsigned)priority_cache->level > (unsigned)to_set) \
812 			priority_cache->level = to_set
813 
814 static
check_level(const char * level,gnutls_priority_t priority_cache,int add)815 int check_level(const char *level, gnutls_priority_t priority_cache,
816 		int add)
817 {
818 	bulk_rmadd_func *func;
819 	unsigned profile = 0;
820 	unsigned i;
821 	int j;
822 	const cipher_entry_st *centry;
823 
824 	if (add)
825 		func = _add_priority;
826 	else
827 		func = _set_priority;
828 
829 	for (i=0;;i++) {
830 		if (pgroups[i].name == NULL)
831 			return 0;
832 
833 		if (c_strcasecmp(level, pgroups[i].name) == 0 ||
834 			(pgroups[i].alias != NULL && c_strcasecmp(level, pgroups[i].alias) == 0)) {
835 			if (pgroups[i].proto_list != NULL)
836 				func(&priority_cache->protocol, *pgroups[i].proto_list);
837 			func(&priority_cache->_cipher, *pgroups[i].cipher_list);
838 			func(&priority_cache->_kx, *pgroups[i].kx_list);
839 			func(&priority_cache->_mac, *pgroups[i].mac_list);
840 			func(&priority_cache->_sign_algo, *pgroups[i].sign_list);
841 			func(&priority_cache->_supported_ecc, *pgroups[i].group_list);
842 
843 			if (pgroups[i].profile != 0) {
844 				SET_PROFILE(pgroups[i].profile); /* set certificate level */
845 			}
846 			SET_LEVEL(pgroups[i].sec_param); /* set DH params level */
847 			priority_cache->no_tickets = pgroups[i].no_tickets;
848 			if (priority_cache->have_cbc == 0) {
849 				for (j=0;(*pgroups[i].cipher_list)[j]!=0;j++) {
850 					centry = cipher_to_entry((*pgroups[i].cipher_list)[j]);
851 					if (centry != NULL && centry->type == CIPHER_BLOCK) {
852 						priority_cache->have_cbc = 1;
853 						break;
854 					}
855 				}
856 			}
857 			return 1;
858 		}
859 	}
860 }
861 
enable_compat(gnutls_priority_t c)862 static void enable_compat(gnutls_priority_t c)
863 {
864 	ENABLE_PRIO_COMPAT(c);
865 }
enable_server_key_usage_violations(gnutls_priority_t c)866 static void enable_server_key_usage_violations(gnutls_priority_t c)
867 {
868 	c->allow_server_key_usage_violation = 1;
869 }
enable_allow_small_records(gnutls_priority_t c)870 static void enable_allow_small_records(gnutls_priority_t c)
871 {
872 	c->_allow_small_records = 1;
873 }
enable_dumbfw(gnutls_priority_t c)874 static void enable_dumbfw(gnutls_priority_t c)
875 {
876 	c->_dumbfw = 1;
877 }
enable_no_extensions(gnutls_priority_t c)878 static void enable_no_extensions(gnutls_priority_t c)
879 {
880 	c->no_extensions = 1;
881 }
enable_no_ext_master_secret(gnutls_priority_t c)882 static void enable_no_ext_master_secret(gnutls_priority_t c)
883 {
884 	c->_no_ext_master_secret = 1;
885 }
enable_no_etm(gnutls_priority_t c)886 static void enable_no_etm(gnutls_priority_t c)
887 {
888 	c->_no_etm = 1;
889 }
enable_force_etm(gnutls_priority_t c)890 static void enable_force_etm(gnutls_priority_t c)
891 {
892 	c->force_etm = 1;
893 }
enable_no_tickets(gnutls_priority_t c)894 static void enable_no_tickets(gnutls_priority_t c)
895 {
896 	c->no_tickets = 1;
897 }
disable_wildcards(gnutls_priority_t c)898 static void disable_wildcards(gnutls_priority_t c)
899 {
900 	c->additional_verify_flags |= GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS;
901 }
enable_profile_very_weak(gnutls_priority_t c)902 static void enable_profile_very_weak(gnutls_priority_t c)
903 {
904 	ENABLE_PROFILE(c, GNUTLS_PROFILE_VERY_WEAK);
905 }
enable_profile_low(gnutls_priority_t c)906 static void enable_profile_low(gnutls_priority_t c)
907 {
908 	ENABLE_PROFILE(c, GNUTLS_PROFILE_LOW);
909 }
enable_profile_legacy(gnutls_priority_t c)910 static void enable_profile_legacy(gnutls_priority_t c)
911 {
912 	ENABLE_PROFILE(c, GNUTLS_PROFILE_LEGACY);
913 }
enable_profile_medium(gnutls_priority_t c)914 static void enable_profile_medium(gnutls_priority_t c)
915 {
916 	ENABLE_PROFILE(c, GNUTLS_PROFILE_MEDIUM);
917 }
enable_profile_high(gnutls_priority_t c)918 static void enable_profile_high(gnutls_priority_t c)
919 {
920 	ENABLE_PROFILE(c, GNUTLS_PROFILE_HIGH);
921 }
enable_profile_ultra(gnutls_priority_t c)922 static void enable_profile_ultra(gnutls_priority_t c)
923 {
924 	ENABLE_PROFILE(c, GNUTLS_PROFILE_ULTRA);
925 }
enable_profile_future(gnutls_priority_t c)926 static void enable_profile_future(gnutls_priority_t c)
927 {
928 	ENABLE_PROFILE(c, GNUTLS_PROFILE_FUTURE);
929 }
enable_profile_suiteb128(gnutls_priority_t c)930 static void enable_profile_suiteb128(gnutls_priority_t c)
931 {
932 	ENABLE_PROFILE(c, GNUTLS_PROFILE_SUITEB128);
933 }
enable_profile_suiteb192(gnutls_priority_t c)934 static void enable_profile_suiteb192(gnutls_priority_t c)
935 {
936 	ENABLE_PROFILE(c, GNUTLS_PROFILE_SUITEB128);
937 }
enable_safe_renegotiation(gnutls_priority_t c)938 static void enable_safe_renegotiation(gnutls_priority_t c)
939 {
940 	c->sr = SR_SAFE;
941 
942 }
enable_unsafe_renegotiation(gnutls_priority_t c)943 static void enable_unsafe_renegotiation(gnutls_priority_t c)
944 {
945 	c->sr = SR_UNSAFE;
946 }
enable_partial_safe_renegotiation(gnutls_priority_t c)947 static void enable_partial_safe_renegotiation(gnutls_priority_t c)
948 {
949 	c->sr = SR_PARTIAL;
950 }
disable_safe_renegotiation(gnutls_priority_t c)951 static void disable_safe_renegotiation(gnutls_priority_t c)
952 {
953 	c->sr = SR_DISABLED;
954 }
enable_fallback_scsv(gnutls_priority_t c)955 static void enable_fallback_scsv(gnutls_priority_t c)
956 {
957 	c->fallback = 1;
958 }
enable_latest_record_version(gnutls_priority_t c)959 static void enable_latest_record_version(gnutls_priority_t c)
960 {
961 	c->min_record_version = 0;
962 }
enable_ssl3_record_version(gnutls_priority_t c)963 static void enable_ssl3_record_version(gnutls_priority_t c)
964 {
965 	c->min_record_version = 1;
966 }
enable_verify_allow_rsa_md5(gnutls_priority_t c)967 static void enable_verify_allow_rsa_md5(gnutls_priority_t c)
968 {
969 	c->additional_verify_flags |=
970 	    GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
971 }
enable_verify_allow_sha1(gnutls_priority_t c)972 static void enable_verify_allow_sha1(gnutls_priority_t c)
973 {
974 	c->additional_verify_flags |=
975 	    GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1;
976 }
enable_verify_allow_broken(gnutls_priority_t c)977 static void enable_verify_allow_broken(gnutls_priority_t c)
978 {
979 	c->additional_verify_flags |=
980 	    GNUTLS_VERIFY_ALLOW_BROKEN;
981 }
disable_crl_checks(gnutls_priority_t c)982 static void disable_crl_checks(gnutls_priority_t c)
983 {
984 	c->additional_verify_flags |=
985 		GNUTLS_VERIFY_DISABLE_CRL_CHECKS;
986 }
enable_server_precedence(gnutls_priority_t c)987 static void enable_server_precedence(gnutls_priority_t c)
988 {
989 	c->server_precedence = 1;
990 }
dummy_func(gnutls_priority_t c)991 static void dummy_func(gnutls_priority_t c)
992 {
993 }
994 
995 #include <priority_options.h>
996 
997 static gnutls_certificate_verification_profiles_t system_wide_verification_profile = GNUTLS_PROFILE_UNKNOWN;
998 static name_val_array_t system_wide_priority_strings = NULL;
999 static unsigned system_wide_priority_strings_init = 0;
1000 static unsigned system_wide_default_priority_string = 0;
1001 static unsigned fail_on_invalid_config = 0;
1002 static unsigned system_wide_disabled_ciphers[MAX_ALGOS+1] = {0};
1003 static unsigned system_wide_disabled_macs[MAX_ALGOS+1] = {0};
1004 static unsigned system_wide_disabled_groups[MAX_ALGOS+1] = {0};
1005 static unsigned system_wide_disabled_kxs[MAX_ALGOS+1] = {0};
1006 
1007 static const char *system_priority_file = SYSTEM_PRIORITY_FILE;
1008 static time_t system_priority_last_mod = 0;
1009 
1010 #define CUSTOM_PRIORITY_SECTION "priorities"
1011 #define OVERRIDES_SECTION "overrides"
1012 #define MAX_ALGO_NAME 2048
1013 
_clear_default_system_priority(void)1014 static void _clear_default_system_priority(void)
1015 {
1016         if (system_wide_default_priority_string) {
1017                 gnutls_free(_gnutls_default_priority_string);
1018                 _gnutls_default_priority_string = DEFAULT_PRIORITY_STRING;
1019                 system_wide_default_priority_string = 0;
1020         }
1021 
1022 }
1023 
_gnutls_get_system_wide_verification_profile(void)1024 gnutls_certificate_verification_profiles_t _gnutls_get_system_wide_verification_profile(void)
1025 {
1026 	return system_wide_verification_profile;
1027 }
1028 
1029 /* removes spaces */
clear_spaces(const char * str,char out[MAX_ALGO_NAME])1030 static char *clear_spaces(const char *str, char out[MAX_ALGO_NAME])
1031 {
1032 	const char *p = str;
1033 	unsigned i = 0;
1034 
1035 	while (c_isspace(*p))
1036 		p++;
1037 
1038 	while (!c_isspace(*p) && *p != 0) {
1039 		out[i++] = *p;
1040 		p++;
1041 
1042 		if (i >= MAX_ALGO_NAME-1)
1043 			break;
1044 	}
1045 	out[i] = 0;
1046 	return out;
1047 }
1048 
1049 /* This function parses a gnutls configuration file and updates internal
1050  * settings accordingly.
1051  */
cfg_ini_handler(void * _ctx,const char * section,const char * name,const char * value)1052 static int cfg_ini_handler(void *_ctx, const char *section, const char *name, const char *value)
1053 {
1054 	char *p;
1055 	int ret, type;
1056 	unsigned i;
1057 	char str[MAX_ALGO_NAME];
1058 
1059 	/* Note that we intentionally overwrite the value above; inih does
1060 	 * not use that value after we handle it. */
1061 
1062 	/* Parse sections */
1063 	if (section == NULL || section[0] == 0 || c_strcasecmp(section, CUSTOM_PRIORITY_SECTION)==0) {
1064 		if (system_wide_priority_strings_init == 0) {
1065 			_name_val_array_init(&system_wide_priority_strings);
1066 			system_wide_priority_strings_init = 1;
1067 		}
1068 
1069 		_gnutls_debug_log("cfg: adding priority: %s -> %s\n", name, value);
1070 
1071 		ret = _name_val_array_append(&system_wide_priority_strings, name, value);
1072 		if (ret < 0)
1073 			return 0;
1074 	} else if (c_strcasecmp(section, OVERRIDES_SECTION)==0) {
1075 		if (c_strcasecmp(name, "default-priority-string")==0) {
1076 			_clear_default_system_priority();
1077 			p = clear_spaces(value, str);
1078 			_gnutls_debug_log("cfg: setting default-priority-string to %s\n", p);
1079 			if (strlen(p) > 0) {
1080 				_gnutls_default_priority_string = gnutls_strdup(p);
1081 				if (!_gnutls_default_priority_string) {
1082 					_gnutls_default_priority_string = DEFAULT_PRIORITY_STRING;
1083 					_gnutls_debug_log("cfg: failed setting default-priority-string\n");
1084 					return 0;
1085 				}
1086 				system_wide_default_priority_string = 1;
1087 			} else {
1088 				_gnutls_debug_log("cfg: empty default-priority-string, using default\n");
1089 				if (fail_on_invalid_config)
1090 					return 0;
1091 			}
1092 		} else if (c_strcasecmp(name, "insecure-hash")==0) {
1093 			p = clear_spaces(value, str);
1094 
1095 			_gnutls_debug_log("cfg: marking hash %s as insecure\n",
1096 					  p);
1097 
1098 			ret = _gnutls_digest_mark_insecure(p);
1099 			if (ret < 0) {
1100 				_gnutls_debug_log("cfg: found unknown hash %s in %s\n",
1101 						  p, name);
1102 				if (fail_on_invalid_config)
1103 					return 0;
1104 			}
1105 		} else if (c_strcasecmp(name, "insecure-sig")==0 || c_strcasecmp(name, "insecure-sig-for-cert")==0) {
1106 			p = clear_spaces(value, str);
1107 
1108 			if (c_strcasecmp(name, "insecure-sig")==0) {
1109 				type = _INSECURE;
1110 				_gnutls_debug_log("cfg: marking signature %s as insecure\n",
1111 						  p);
1112 			} else {
1113 				_gnutls_debug_log("cfg: marking signature %s as insecure for certs\n",
1114 						  p);
1115 				type = _INSECURE_FOR_CERTS;
1116 			}
1117 
1118 			ret = _gnutls_sign_mark_insecure(p, type);
1119 			if (ret < 0) {
1120 				_gnutls_debug_log("cfg: found unknown signature algorithm %s in %s\n",
1121 						  p, name);
1122 				if (fail_on_invalid_config)
1123 					return 0;
1124 			}
1125 		} else if (c_strcasecmp(name, "disabled-version")==0) {
1126 			p = clear_spaces(value, str);
1127 
1128 			_gnutls_debug_log("cfg: disabling version %s\n",
1129 					  p);
1130 
1131 			ret = _gnutls_version_mark_disabled(p);
1132 			if (ret < 0) {
1133 				_gnutls_debug_log("cfg: found unknown version %s in %s\n",
1134 						  p, name);
1135 				if (fail_on_invalid_config)
1136 					return 0;
1137 			}
1138 		} else if (c_strcasecmp(name, "disabled-curve")==0) {
1139 			p = clear_spaces(value, str);
1140 
1141 			_gnutls_debug_log("cfg: disabling curve %s\n",
1142 					  p);
1143 
1144 			ret = _gnutls_ecc_curve_mark_disabled(p);
1145 			if (ret < 0) {
1146 				_gnutls_debug_log("cfg: found unknown curve %s in %s\n",
1147 						  p, name);
1148 				if (fail_on_invalid_config)
1149 					return 0;
1150 			}
1151 		} else if (c_strcasecmp(name, "min-verification-profile")==0) {
1152 			gnutls_certificate_verification_profiles_t profile;
1153 			profile = gnutls_certificate_verification_profile_get_id(value);
1154 
1155 			if (profile == GNUTLS_PROFILE_UNKNOWN) {
1156 				_gnutls_debug_log("cfg: found unknown profile %s in %s\n",
1157 						  value, name);
1158 				if (fail_on_invalid_config)
1159 					return 0;
1160 			}
1161 
1162 			system_wide_verification_profile = profile;
1163 		} else if (c_strcasecmp(name, "tls-disabled-cipher")==0) {
1164 			unsigned algo;
1165 
1166 			p = clear_spaces(value, str);
1167 
1168 			_gnutls_debug_log("cfg: disabling cipher %s for TLS\n",
1169 					  p);
1170 
1171 
1172 			algo = gnutls_cipher_get_id(p);
1173 			if (algo == 0) {
1174 				_gnutls_debug_log("cfg: unknown algorithm %s listed at %s\n",
1175 						  p, name);
1176 				if (fail_on_invalid_config)
1177 					return 0;
1178 			}
1179 
1180 			i = 0;
1181 			while (system_wide_disabled_ciphers[i] != 0)
1182 				i++;
1183 
1184 			if (i > MAX_ALGOS-1) {
1185 				_gnutls_debug_log("cfg: too many (%d) disabled ciphers from %s\n",
1186 						  i, name);
1187 				if (fail_on_invalid_config)
1188 					return 0;
1189 				goto exit;
1190 			}
1191 			system_wide_disabled_ciphers[i] = algo;
1192 			system_wide_disabled_ciphers[i+1] = 0;
1193 
1194 		} else if (c_strcasecmp(name, "tls-disabled-mac")==0) {
1195 			unsigned algo;
1196 
1197 			p = clear_spaces(value, str);
1198 
1199 			_gnutls_debug_log("cfg: disabling MAC %s for TLS\n",
1200 					  p);
1201 
1202 			algo = gnutls_mac_get_id(p);
1203 			if (algo == 0) {
1204 				_gnutls_debug_log("cfg: unknown algorithm %s listed at %s\n",
1205 						  p, name);
1206 				if (fail_on_invalid_config)
1207 					return 0;
1208 				goto exit;
1209 			}
1210 
1211 			i = 0;
1212 			while (system_wide_disabled_macs[i] != 0)
1213 				i++;
1214 
1215 			if (i > MAX_ALGOS-1) {
1216 				_gnutls_debug_log("cfg: too many (%d) disabled MACs from %s\n",
1217 						  i, name);
1218 				if (fail_on_invalid_config)
1219 					return 0;
1220 				goto exit;
1221 			}
1222 			system_wide_disabled_macs[i] = algo;
1223 			system_wide_disabled_macs[i+1] = 0;
1224 		} else if (c_strcasecmp(name, "tls-disabled-group")==0) {
1225 			unsigned algo;
1226 
1227 			p = clear_spaces(value, str);
1228 
1229 			if (strlen(p) > 6)
1230 				p += 6; // skip GROUP-
1231 
1232 			_gnutls_debug_log("cfg: disabling group %s for TLS\n",
1233 					  p);
1234 
1235 			algo = gnutls_group_get_id(p);
1236 			if (algo == 0) {
1237 				_gnutls_debug_log("cfg: unknown group %s listed at %s\n",
1238 						  p, name);
1239 				if (fail_on_invalid_config)
1240 					return 0;
1241 				goto exit;
1242 			}
1243 
1244 			i = 0;
1245 			while (system_wide_disabled_groups[i] != 0)
1246 				i++;
1247 
1248 			if (i > MAX_ALGOS-1) {
1249 				_gnutls_debug_log("cfg: too many (%d) disabled groups from %s\n",
1250 						  i, name);
1251 				if (fail_on_invalid_config)
1252 					return 0;
1253 				goto exit;
1254 			}
1255 			system_wide_disabled_groups[i] = algo;
1256 			system_wide_disabled_groups[i+1] = 0;
1257 		} else if (c_strcasecmp(name, "tls-disabled-kx")==0) {
1258 			unsigned algo;
1259 
1260 			p = clear_spaces(value, str);
1261 
1262 			_gnutls_debug_log("cfg: disabling key exchange %s for TLS\n",
1263 					  p);
1264 
1265 			algo = gnutls_kx_get_id(p);
1266 			if (algo == 0) {
1267 				_gnutls_debug_log("cfg: unknown key exchange %s listed at %s\n",
1268 						  p, name);
1269 				if (fail_on_invalid_config)
1270 					return 0;
1271 				goto exit;
1272 			}
1273 
1274 			i = 0;
1275 			while (system_wide_disabled_kxs[i] != 0)
1276 				i++;
1277 
1278 			if (i > MAX_ALGOS-1) {
1279 				_gnutls_debug_log("cfg: too many (%d) disabled key exchanges from %s\n",
1280 						  i, name);
1281 				if (fail_on_invalid_config)
1282 					return 0;
1283 				goto exit;
1284 			}
1285 			system_wide_disabled_kxs[i] = algo;
1286 			system_wide_disabled_kxs[i+1] = 0;
1287 		} else {
1288 			_gnutls_debug_log("unknown parameter %s\n", name);
1289 			if (fail_on_invalid_config)
1290 				return 0;
1291 		}
1292 	} else {
1293 		_gnutls_debug_log("cfg: unknown section %s\n",
1294 				  section);
1295 		if (fail_on_invalid_config)
1296 			return 0;
1297 	}
1298 
1299  exit:
1300 	return 1;
1301 }
1302 
_gnutls_update_system_priorities(void)1303 static void _gnutls_update_system_priorities(void)
1304 {
1305 	int ret;
1306 	struct stat sb;
1307 	FILE *fp;
1308 
1309 	if (stat(system_priority_file, &sb) < 0) {
1310 		_gnutls_debug_log("cfg: unable to access: %s: %d\n",
1311 				  system_priority_file, errno);
1312 		return;
1313 	}
1314 
1315 	if (system_wide_priority_strings_init != 0 &&
1316 	    sb.st_mtime == system_priority_last_mod) {
1317 		_gnutls_debug_log("cfg: system priority %s has not changed\n",
1318 				  system_priority_file);
1319 		return;
1320 	}
1321 
1322 	if (system_wide_priority_strings_init != 0)
1323 		_name_val_array_clear(&system_wide_priority_strings);
1324 
1325 	fp = fopen(system_priority_file, "re");
1326 	if (fp == NULL) {
1327 		_gnutls_debug_log("cfg: unable to open: %s: %d\n",
1328 				  system_priority_file, errno);
1329 		return;
1330 	}
1331 	ret = ini_parse_file(fp, cfg_ini_handler, NULL);
1332 	fclose(fp);
1333 	if (ret != 0) {
1334 		_gnutls_debug_log("cfg: unable to parse: %s: %d\n",
1335 				  system_priority_file, ret);
1336 		if (fail_on_invalid_config)
1337 			exit(1);
1338 		return;
1339 	}
1340 
1341 	_gnutls_debug_log("cfg: loaded system priority %s mtime %lld\n",
1342 			  system_priority_file,
1343 			  (unsigned long long)sb.st_mtime);
1344 
1345 	system_priority_last_mod = sb.st_mtime;
1346 }
1347 
_gnutls_load_system_priorities(void)1348 void _gnutls_load_system_priorities(void)
1349 {
1350 	const char *p;
1351 
1352 	p = secure_getenv("GNUTLS_SYSTEM_PRIORITY_FILE");
1353 	if (p != NULL)
1354 		system_priority_file = p;
1355 
1356 	p = secure_getenv("GNUTLS_SYSTEM_PRIORITY_FAIL_ON_INVALID");
1357 	if (p != NULL && p[0] == '1' && p[1] == 0)
1358 		fail_on_invalid_config = 1;
1359 
1360 	_gnutls_update_system_priorities();
1361 }
1362 
_gnutls_unload_system_priorities(void)1363 void _gnutls_unload_system_priorities(void)
1364 {
1365 	_name_val_array_clear(&system_wide_priority_strings);
1366 	_clear_default_system_priority();
1367 	system_priority_last_mod = 0;
1368 }
1369 
1370 /**
1371  * gnutls_get_system_config_file:
1372  *
1373  * Returns the filename of the system wide configuration
1374  * file loaded by the library. The returned pointer is valid
1375  * until the library is unloaded.
1376  *
1377  * Returns: a constant pointer to the config file loaded, or %NULL if none
1378  *
1379  * Since: 3.6.9
1380  **/
gnutls_get_system_config_file(void)1381 const char *gnutls_get_system_config_file(void)
1382 {
1383 	if (system_wide_priority_strings_init)
1384 		return system_priority_file;
1385 	else
1386 		return NULL;
1387 }
1388 
1389 #define S(str) ((str!=NULL)?str:"")
1390 
1391 /* Returns the new priorities if a priority string prefixed
1392  * with '@' is provided, or just a copy of the provided
1393  * priorities, appended with any additional present in
1394  * the priorities string.
1395  *
1396  * The returned string must be released using gnutls_free().
1397  */
_gnutls_resolve_priorities(const char * priorities)1398 char *_gnutls_resolve_priorities(const char* priorities)
1399 {
1400 	const char *p = priorities;
1401 	char *additional = NULL;
1402 	char *ret = NULL;
1403 	const char *ss, *ss_next;
1404 	unsigned ss_len, ss_next_len;
1405 	size_t n, n2 = 0;
1406 
1407 	while (c_isspace(*p))
1408 		p++;
1409 
1410 	if (*p == '@') {
1411 		ss = p+1;
1412 		additional = strchr(ss, ':');
1413 		if (additional != NULL) {
1414 			additional++;
1415 		}
1416 
1417 		do {
1418 			ss_next = strchr(ss, ',');
1419 			if (ss_next != NULL) {
1420 				if (additional && ss_next > additional)
1421 					ss_next = NULL;
1422 				else
1423 					ss_next++;
1424 			}
1425 
1426 			if (ss_next) {
1427 				ss_len = ss_next - ss - 1;
1428 				ss_next_len = additional - ss_next - 1;
1429 			} else if (additional) {
1430 				ss_len = additional - ss - 1;
1431 				ss_next_len = 0;
1432 			} else {
1433 				ss_len = strlen(ss);
1434 				ss_next_len = 0;
1435 			}
1436 
1437 			/* Always try to refresh the cached data, to
1438 			 * allow it to be updated without restarting
1439 			 * all applications
1440 			 */
1441 			_gnutls_update_system_priorities();
1442 
1443 			p = _name_val_array_value(system_wide_priority_strings, ss, ss_len);
1444 
1445 			_gnutls_debug_log("resolved '%.*s' to '%s', next '%.*s'\n",
1446 					  ss_len, ss, S(p), ss_next_len, S(ss_next));
1447 			ss = ss_next;
1448 		} while (ss && p == NULL);
1449 
1450 		if (p == NULL) {
1451 			_gnutls_debug_log("unable to resolve %s\n", priorities);
1452 			ret = NULL;
1453 			goto finish;
1454 		}
1455 
1456 		n = strlen(p);
1457 		if (additional)
1458 			n2 = strlen(additional);
1459 
1460 		ret = gnutls_malloc(n+n2+1+1);
1461 		if (ret == NULL) {
1462 			goto finish;
1463 		}
1464 
1465 		memcpy(ret, p, n);
1466 		if (additional != NULL) {
1467 			ret[n] = ':';
1468 			memcpy(&ret[n+1], additional, n2);
1469 			ret[n+n2+1] = 0;
1470 		} else {
1471 			ret[n] = 0;
1472 		}
1473 	} else {
1474 		return gnutls_strdup(p);
1475 	}
1476 
1477 finish:
1478 	if (ret != NULL) {
1479 		_gnutls_debug_log("selected priority string: %s\n", ret);
1480 	}
1481 
1482 	return ret;
1483 }
1484 
add_ec(gnutls_priority_t priority_cache)1485 static void add_ec(gnutls_priority_t priority_cache)
1486 {
1487 	const gnutls_group_entry_st *ge;
1488 	unsigned i;
1489 
1490 	for (i = 0; i < priority_cache->_supported_ecc.num_priorities; i++) {
1491 		ge = _gnutls_id_to_group(priority_cache->_supported_ecc.priorities[i]);
1492 		if (ge != NULL && priority_cache->groups.size < sizeof(priority_cache->groups.entry)/sizeof(priority_cache->groups.entry[0])) {
1493 			/* do not add groups which do not correspond to enabled ciphersuites */
1494 			if (!ge->curve)
1495 				continue;
1496 			priority_cache->groups.entry[priority_cache->groups.size++] = ge;
1497 		}
1498 	}
1499 }
1500 
add_dh(gnutls_priority_t priority_cache)1501 static void add_dh(gnutls_priority_t priority_cache)
1502 {
1503 	const gnutls_group_entry_st *ge;
1504 	unsigned i;
1505 
1506 	for (i = 0; i < priority_cache->_supported_ecc.num_priorities; i++) {
1507 		ge = _gnutls_id_to_group(priority_cache->_supported_ecc.priorities[i]);
1508 		if (ge != NULL && priority_cache->groups.size < sizeof(priority_cache->groups.entry)/sizeof(priority_cache->groups.entry[0])) {
1509 			/* do not add groups which do not correspond to enabled ciphersuites */
1510 			if (!ge->prime)
1511 				continue;
1512 			priority_cache->groups.entry[priority_cache->groups.size++] = ge;
1513 			priority_cache->groups.have_ffdhe = 1;
1514 		}
1515 	}
1516 }
1517 
1518 /* This function was originally precalculating ciphersuite-specific items, however
1519  * it has now extended to much more than that. It provides a consistency check to
1520  * set parameters, and in cases it applies policy specific items.
1521  */
set_ciphersuite_list(gnutls_priority_t priority_cache)1522 static int set_ciphersuite_list(gnutls_priority_t priority_cache)
1523 {
1524 	unsigned i, j, z;
1525 	const gnutls_cipher_suite_entry_st *ce;
1526 	const gnutls_sign_entry_st *se;
1527 	unsigned have_ec = 0;
1528 	unsigned have_dh = 0;
1529 	unsigned tls_sig_sem = 0;
1530 	const version_entry_st *tlsmax = NULL, *vers;
1531 	const version_entry_st *dtlsmax = NULL;
1532 	const version_entry_st *tlsmin = NULL;
1533 	const version_entry_st *dtlsmin = NULL;
1534 	unsigned have_tls13 = 0, have_srp = 0;
1535 	unsigned have_pre_tls12 = 0, have_tls12 = 0;
1536 	unsigned have_psk = 0, have_null = 0, have_rsa_psk = 0;
1537 
1538 	/* have_psk indicates that a PSK key exchange compatible
1539 	 * with TLS1.3 is enabled. */
1540 
1541 	priority_cache->cs.size = 0;
1542 	priority_cache->sigalg.size = 0;
1543 	priority_cache->groups.size = 0;
1544 	priority_cache->groups.have_ffdhe = 0;
1545 
1546 	/* disable key exchanges which are globally disabled */
1547 	z = 0;
1548 	while (system_wide_disabled_kxs[z] != 0) {
1549 		for (i = j = 0; i < priority_cache->_kx.num_priorities; i++) {
1550 			if (priority_cache->_kx.priorities[i] != system_wide_disabled_kxs[z])
1551 				priority_cache->_kx.priorities[j++] = priority_cache->_kx.priorities[i];
1552 		}
1553 		priority_cache->_kx.num_priorities = j;
1554 		z++;
1555 	}
1556 
1557 	/* disable groups which are globally disabled */
1558 	z = 0;
1559 	while (system_wide_disabled_groups[z] != 0) {
1560 		for (i = j = 0; i < priority_cache->_supported_ecc.num_priorities; i++) {
1561 			if (priority_cache->_supported_ecc.priorities[i] != system_wide_disabled_groups[z])
1562 				priority_cache->_supported_ecc.priorities[j++] = priority_cache->_supported_ecc.priorities[i];
1563 		}
1564 		priority_cache->_supported_ecc.num_priorities = j;
1565 		z++;
1566 	}
1567 
1568 	/* disable ciphers which are globally disabled */
1569 	z = 0;
1570 	while (system_wide_disabled_ciphers[z] != 0) {
1571 		for (i = j = 0; i < priority_cache->_cipher.num_priorities; i++) {
1572 			if (priority_cache->_cipher.priorities[i] != system_wide_disabled_ciphers[z])
1573 				priority_cache->_cipher.priorities[j++] = priority_cache->_cipher.priorities[i];
1574 		}
1575 		priority_cache->_cipher.num_priorities = j;
1576 		z++;
1577 	}
1578 
1579 	/* disable MACs which are globally disabled */
1580 	z = 0;
1581 	while (system_wide_disabled_macs[z] != 0) {
1582 		for (i = j = 0; i < priority_cache->_mac.num_priorities; i++) {
1583 			if (priority_cache->_mac.priorities[i] != system_wide_disabled_macs[z])
1584 				priority_cache->_mac.priorities[j++] = priority_cache->_mac.priorities[i];
1585 		}
1586 		priority_cache->_mac.num_priorities = j;
1587 		z++;
1588 	}
1589 
1590 	for (j=0;j<priority_cache->_cipher.num_priorities;j++) {
1591 		if (priority_cache->_cipher.priorities[j] == GNUTLS_CIPHER_NULL) {
1592 			have_null = 1;
1593 			break;
1594 		}
1595 	}
1596 
1597 	for (i = 0; i < priority_cache->_kx.num_priorities; i++) {
1598 		if (IS_SRP_KX(priority_cache->_kx.priorities[i])) {
1599 			have_srp = 1;
1600 		} else if (_gnutls_kx_is_psk(priority_cache->_kx.priorities[i])) {
1601 			if (priority_cache->_kx.priorities[i] == GNUTLS_KX_RSA_PSK)
1602 				have_rsa_psk = 1;
1603 			else
1604 				have_psk = 1;
1605 		}
1606 	}
1607 
1608 	/* disable TLS versions which are added but are unsupported */
1609 	for (i = j = 0; i < priority_cache->protocol.num_priorities; i++) {
1610 		vers = version_to_entry(priority_cache->protocol.priorities[i]);
1611 		if (!vers || vers->supported)
1612 			priority_cache->protocol.priorities[j++] = priority_cache->protocol.priorities[i];
1613 	}
1614 	priority_cache->protocol.num_priorities = j;
1615 
1616 
1617 	/* if we have NULL ciphersuites, SRP, or RSA-PSK enabled remove TLS1.3+
1618 	 * protocol versions; they cannot be negotiated under TLS1.3. */
1619 	if (have_null || have_srp || have_rsa_psk || priority_cache->no_extensions) {
1620 		for (i = j = 0; i < priority_cache->protocol.num_priorities; i++) {
1621 			vers = version_to_entry(priority_cache->protocol.priorities[i]);
1622 			if (!vers || !vers->tls13_sem)
1623 				priority_cache->protocol.priorities[j++] = priority_cache->protocol.priorities[i];
1624 		}
1625 		priority_cache->protocol.num_priorities = j;
1626 	}
1627 
1628 	for (i = 0; i < priority_cache->protocol.num_priorities; i++) {
1629 		vers = version_to_entry(priority_cache->protocol.priorities[i]);
1630 		if (!vers)
1631 			continue;
1632 
1633 		if (vers->transport == GNUTLS_STREAM) { /* TLS */
1634 			tls_sig_sem |= vers->tls_sig_sem;
1635 			if (vers->tls13_sem)
1636 				have_tls13 = 1;
1637 
1638 			if (vers->id == GNUTLS_TLS1_2)
1639 				have_tls12 = 1;
1640 			else if (vers->id < GNUTLS_TLS1_2)
1641 				have_pre_tls12 = 1;
1642 
1643 			if (tlsmax == NULL || vers->age > tlsmax->age)
1644 				tlsmax = vers;
1645 			if (tlsmin == NULL || vers->age < tlsmin->age)
1646 				tlsmin = vers;
1647 		} else { /* dtls */
1648 			tls_sig_sem |= vers->tls_sig_sem;
1649 
1650 			/* we need to introduce similar handling to above
1651 			 * when DTLS1.3 is supported */
1652 
1653 			if (dtlsmax == NULL || vers->age > dtlsmax->age)
1654 				dtlsmax = vers;
1655 			if (dtlsmin == NULL || vers->age < dtlsmin->age)
1656 				dtlsmin = vers;
1657 		}
1658 	}
1659 
1660 	/* DTLS or TLS protocols must be present */
1661 	if ((!tlsmax || !tlsmin) && (!dtlsmax || !dtlsmin))
1662 		return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
1663 
1664 
1665 	priority_cache->have_psk = have_psk;
1666 
1667 	/* if we are have TLS1.3+ do not enable any key exchange algorithms,
1668 	 * the protocol doesn't require any. */
1669 	if (tlsmin && tlsmin->tls13_sem && !have_psk) {
1670 		if (!dtlsmin || (dtlsmin && dtlsmin->tls13_sem))
1671 			priority_cache->_kx.num_priorities = 0;
1672 	}
1673 
1674 	/* Add TLS 1.3 ciphersuites (no KX) */
1675 	for (j=0;j<priority_cache->_cipher.num_priorities;j++) {
1676 		for (z=0;z<priority_cache->_mac.num_priorities;z++) {
1677 			ce = cipher_suite_get(
1678 				0, priority_cache->_cipher.priorities[j],
1679 				priority_cache->_mac.priorities[z]);
1680 
1681 			if (ce != NULL && priority_cache->cs.size < MAX_CIPHERSUITE_SIZE) {
1682 				priority_cache->cs.entry[priority_cache->cs.size++] = ce;
1683 			}
1684 		}
1685 	}
1686 
1687 	for (i = 0; i < priority_cache->_kx.num_priorities; i++) {
1688 		for (j=0;j<priority_cache->_cipher.num_priorities;j++) {
1689 			for (z=0;z<priority_cache->_mac.num_priorities;z++) {
1690 				ce = cipher_suite_get(
1691 					priority_cache->_kx.priorities[i],
1692 					priority_cache->_cipher.priorities[j],
1693 					priority_cache->_mac.priorities[z]);
1694 
1695 				if (ce != NULL && priority_cache->cs.size < MAX_CIPHERSUITE_SIZE) {
1696 					priority_cache->cs.entry[priority_cache->cs.size++] = ce;
1697 					if (!have_ec && (_gnutls_kx_is_ecc(ce->kx_algorithm) ||
1698 							 _gnutls_kx_is_vko_gost(ce->kx_algorithm))) {
1699 						have_ec = 1;
1700 						add_ec(priority_cache);
1701 					}
1702 					if (!have_dh && _gnutls_kx_is_dhe(ce->kx_algorithm)) {
1703 						have_dh = 1;
1704 						add_dh(priority_cache);
1705 					}
1706 				}
1707 			}
1708 		}
1709 	}
1710 
1711 	if (have_tls13 && (!have_ec || !have_dh)) {
1712 		/* scan groups to determine have_ec and have_dh */
1713 		for (i=0; i < priority_cache->_supported_ecc.num_priorities; i++) {
1714 			const gnutls_group_entry_st *ge;
1715 			ge = _gnutls_id_to_group(priority_cache->_supported_ecc.priorities[i]);
1716 			if (ge) {
1717 				if (ge->curve && !have_ec) {
1718 					add_ec(priority_cache);
1719 					have_ec = 1;
1720 				} else if (ge->prime && !have_dh) {
1721 					add_dh(priority_cache);
1722 					have_dh = 1;
1723 				}
1724 
1725 				if (have_dh && have_ec)
1726 					break;
1727 			}
1728 		}
1729 
1730 	}
1731 
1732 	for (i = 0; i < priority_cache->_sign_algo.num_priorities; i++) {
1733 		se = _gnutls_sign_to_entry(priority_cache->_sign_algo.priorities[i]);
1734 		if (se != NULL && priority_cache->sigalg.size < sizeof(priority_cache->sigalg.entry)/sizeof(priority_cache->sigalg.entry[0])) {
1735 			/* if the signature algorithm semantics are not compatible with
1736 			 * the protocol's, then skip. */
1737 			if ((se->aid.tls_sem & tls_sig_sem) == 0)
1738 				continue;
1739 			priority_cache->sigalg.entry[priority_cache->sigalg.size++] = se;
1740 		}
1741 	}
1742 
1743 	_gnutls_debug_log("added %d protocols, %d ciphersuites, %d sig algos and %d groups into priority list\n",
1744 			  priority_cache->protocol.num_priorities,
1745 			  priority_cache->cs.size, priority_cache->sigalg.size,
1746 			  priority_cache->groups.size);
1747 
1748 	if (priority_cache->sigalg.size == 0) {
1749 		/* no signature algorithms; eliminate TLS 1.2 or DTLS 1.2 and later */
1750 		priority_st newp;
1751 		newp.num_priorities = 0;
1752 
1753 		/* we need to eliminate TLS 1.2 or DTLS 1.2 and later protocols */
1754 		for (i = 0; i < priority_cache->protocol.num_priorities; i++) {
1755 			if (priority_cache->protocol.priorities[i] < GNUTLS_TLS1_2) {
1756 				newp.priorities[newp.num_priorities++] = priority_cache->protocol.priorities[i];
1757 			} else if (priority_cache->protocol.priorities[i] >= GNUTLS_DTLS_VERSION_MIN &&
1758 				   priority_cache->protocol.priorities[i] < GNUTLS_DTLS1_2) {
1759 				newp.priorities[newp.num_priorities++] = priority_cache->protocol.priorities[i];
1760 			}
1761 		}
1762 		memcpy(&priority_cache->protocol, &newp, sizeof(newp));
1763 	}
1764 
1765 	if (unlikely(priority_cache->protocol.num_priorities == 0))
1766 		return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
1767 #ifndef ENABLE_SSL3
1768 	else if (unlikely(priority_cache->protocol.num_priorities == 1 && priority_cache->protocol.priorities[0] == GNUTLS_SSL3))
1769 		return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
1770 #endif
1771 
1772 	if (unlikely(priority_cache->cs.size == 0))
1773 		return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
1774 
1775 	/* when TLS 1.3 is available we must have groups set; additionally
1776 	 * we require TLS1.2 to be enabled if TLS1.3 is asked for, and
1777 	 * a pre-TLS1.2 protocol is there; that is because servers which
1778 	 * do not support TLS1.3 will negotiate TLS1.2 if seen a TLS1.3 handshake */
1779 	if (unlikely((!have_psk && tlsmax && tlsmax->id >= GNUTLS_TLS1_3 && priority_cache->groups.size == 0)) ||
1780 	    (!have_tls12 && have_pre_tls12 && have_tls13)) {
1781 		for (i = j = 0; i < priority_cache->protocol.num_priorities; i++) {
1782 			vers = version_to_entry(priority_cache->protocol.priorities[i]);
1783 			if (!vers || vers->transport != GNUTLS_STREAM || !vers->tls13_sem)
1784 				priority_cache->protocol.priorities[j++] = priority_cache->protocol.priorities[i];
1785 		}
1786 		priority_cache->protocol.num_priorities = j;
1787 	}
1788 
1789 	/* ensure that the verification profile is not lower from the configured */
1790 	if (system_wide_verification_profile) {
1791 		gnutls_sec_param_t level = priority_cache->level;
1792 		gnutls_sec_param_t system_wide_level = _gnutls_profile_to_sec_level(system_wide_verification_profile);
1793 
1794 		if (level < system_wide_level) {
1795 			ENABLE_PROFILE(priority_cache, system_wide_verification_profile);
1796 		}
1797 	}
1798 
1799 	return 0;
1800 }
1801 
1802 /**
1803  * gnutls_priority_init2:
1804  * @priority_cache: is a #gnutls_prioritity_t type.
1805  * @priorities: is a string describing priorities (may be %NULL)
1806  * @err_pos: In case of an error this will have the position in the string the error occurred
1807  * @flags: zero or %GNUTLS_PRIORITY_INIT_DEF_APPEND
1808  *
1809  * Sets priorities for the ciphers, key exchange methods, and macs.
1810  * The @priority_cache should be deinitialized
1811  * using gnutls_priority_deinit().
1812  *
1813  * The #priorities option allows you to specify a colon
1814  * separated list of the cipher priorities to enable.
1815  * Some keywords are defined to provide quick access
1816  * to common preferences.
1817  *
1818  * When @flags is set to %GNUTLS_PRIORITY_INIT_DEF_APPEND then the @priorities
1819  * specified will be appended to the default options.
1820  *
1821  * Unless there is a special need, use the "NORMAL" keyword to
1822  * apply a reasonable security level, or "NORMAL:%%COMPAT" for compatibility.
1823  *
1824  * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
1825  * limited to 128 bit ciphers and sorted by terms of speed
1826  * performance.
1827  *
1828  * "LEGACY" the NORMAL settings for GnuTLS 3.2.x or earlier. There is
1829  * no verification profile set, and the allowed DH primes are considered
1830  * weak today.
1831  *
1832  * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
1833  * included as a fallback only.  The ciphers are sorted by security
1834  * margin.
1835  *
1836  * "PFS" means all "secure" ciphersuites that support perfect forward secrecy.
1837  * The 256-bit ciphers are included as a fallback only.
1838  * The ciphers are sorted by security margin.
1839  *
1840  * "SECURE128" means all "secure" ciphersuites of security level 128-bit
1841  * or more.
1842  *
1843  * "SECURE192" means all "secure" ciphersuites of security level 192-bit
1844  * or more.
1845  *
1846  * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
1847  * of 128.
1848  *
1849  * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
1850  * of 192.
1851  *
1852  * "NONE" means nothing is enabled.  This disables everything, including protocols.
1853  *
1854  * "@@KEYWORD1,KEYWORD2,..." The system administrator imposed settings.
1855  * The provided keyword(s) will be expanded from a configuration-time
1856  * provided file - default is: /etc/gnutls/config.
1857  * Any attributes that follow it, will be appended to the expanded
1858  * string. If multiple keywords are provided, separated by commas,
1859  * then the first keyword that exists in the configuration file
1860  * will be used. At least one of the keywords must exist, or this
1861  * function will return an error. Typical usage would be to specify
1862  * an application specified keyword first, followed by "SYSTEM" as
1863  * a default fallback. e.g., "@LIBVIRT,SYSTEM:!-VERS-SSL3.0" will
1864  * first try to find a config file entry matching "LIBVIRT", but if
1865  * that does not exist will use the entry for "SYSTEM". If "SYSTEM"
1866  * does not exist either, an error will be returned. In all cases,
1867  * the SSL3.0 protocol will be disabled. The system priority file
1868  * entries should be formatted as "KEYWORD=VALUE", e.g.,
1869  * "SYSTEM=NORMAL:+ARCFOUR-128".
1870  *
1871  * Special keywords are "!", "-" and "+".
1872  * "!" or "-" appended with an algorithm will remove this algorithm.
1873  * "+" appended with an algorithm will add this algorithm.
1874  *
1875  * Check the GnuTLS manual section "Priority strings" for detailed
1876  * information.
1877  *
1878  * Examples:
1879  *
1880  * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
1881  *
1882  * "NORMAL:+ARCFOUR-128" means normal ciphers plus ARCFOUR-128.
1883  *
1884  * "SECURE128:-VERS-SSL3.0" means that only secure ciphers are
1885  * and enabled, SSL3.0 is disabled.
1886  *
1887  * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1",
1888  *
1889  * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1",
1890  *
1891  * "SECURE256:+SECURE128",
1892  *
1893  * Note that "NORMAL:%%COMPAT" is the most compatible mode.
1894  *
1895  * A %NULL @priorities string indicates the default priorities to be
1896  * used (this is available since GnuTLS 3.3.0).
1897  *
1898  * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
1899  * %GNUTLS_E_SUCCESS on success, or an error code.
1900  *
1901  * Since: 3.6.3
1902  **/
1903 int
gnutls_priority_init2(gnutls_priority_t * priority_cache,const char * priorities,const char ** err_pos,unsigned flags)1904 gnutls_priority_init2(gnutls_priority_t * priority_cache,
1905 		      const char *priorities, const char **err_pos,
1906 		      unsigned flags)
1907 {
1908 	gnutls_buffer_st buf;
1909 	const char *ep;
1910 	int ret;
1911 
1912 	if (flags & GNUTLS_PRIORITY_INIT_DEF_APPEND) {
1913 		if (priorities == NULL)
1914 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1915 
1916 		if (err_pos)
1917 			*err_pos = priorities;
1918 
1919 		_gnutls_buffer_init(&buf);
1920 
1921 		ret = _gnutls_buffer_append_str(&buf, _gnutls_default_priority_string);
1922 		if (ret < 0) {
1923 			_gnutls_buffer_clear(&buf);
1924 			return gnutls_assert_val(ret);
1925 		}
1926 
1927 		ret = _gnutls_buffer_append_str(&buf, ":");
1928 		if (ret < 0) {
1929 			_gnutls_buffer_clear(&buf);
1930 			return gnutls_assert_val(ret);
1931 		}
1932 
1933 		ret = _gnutls_buffer_append_str(&buf, priorities);
1934 		if (ret < 0) {
1935 			_gnutls_buffer_clear(&buf);
1936 			return gnutls_assert_val(ret);
1937 		}
1938 
1939 		ret = gnutls_priority_init(priority_cache, (const char*)buf.data, &ep);
1940 		if (ret < 0 && ep != (const char*)buf.data && ep != NULL) {
1941 			ptrdiff_t diff = (ptrdiff_t)ep-(ptrdiff_t)buf.data;
1942 			unsigned hlen = strlen(_gnutls_default_priority_string)+1;
1943 
1944 			if (err_pos && diff > hlen) {
1945 				*err_pos = priorities + diff - hlen;
1946 			}
1947 		}
1948 		_gnutls_buffer_clear(&buf);
1949 		return ret;
1950 	} else {
1951 		return gnutls_priority_init(priority_cache, priorities, err_pos);
1952 	}
1953 }
1954 
1955 #define PRIO_MATCH(name) c_strncasecmp(&broken_list[i][1], name, sizeof(name) - 1)
1956 
1957 /**
1958  * gnutls_priority_init:
1959  * @priority_cache: is a #gnutls_prioritity_t type.
1960  * @priorities: is a string describing priorities (may be %NULL)
1961  * @err_pos: In case of an error this will have the position in the string the error occurred
1962  *
1963  * For applications that do not modify their crypto settings per release, consider
1964  * using gnutls_priority_init2() with %GNUTLS_PRIORITY_INIT_DEF_APPEND flag
1965  * instead. We suggest to use centralized crypto settings handled by the GnuTLS
1966  * library, and applications modifying the default settings to their needs.
1967  *
1968  * This function is identical to gnutls_priority_init2() with zero
1969  * flags.
1970  *
1971  * A %NULL @priorities string indicates the default priorities to be
1972  * used (this is available since GnuTLS 3.3.0).
1973  *
1974  * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
1975  * %GNUTLS_E_SUCCESS on success, or an error code.
1976  **/
1977 int
gnutls_priority_init(gnutls_priority_t * priority_cache,const char * priorities,const char ** err_pos)1978 gnutls_priority_init(gnutls_priority_t * priority_cache,
1979 		     const char *priorities, const char **err_pos)
1980 {
1981 	char *broken_list[MAX_ELEMENTS];
1982 	int broken_list_size = 0, i = 0, j;
1983 	char *darg = NULL;
1984 	unsigned ikeyword_set = 0;
1985 	int algo;
1986 	int ret;
1987 	rmadd_func *fn;
1988 	bulk_rmadd_func *bulk_fn;
1989 	bulk_rmadd_func *bulk_given_fn;
1990 	const cipher_entry_st *centry;
1991 	unsigned resolved_match = 1;
1992 
1993 	if (err_pos)
1994 		*err_pos = priorities;
1995 
1996 	*priority_cache =
1997 	    gnutls_calloc(1, sizeof(struct gnutls_priority_st));
1998 	if (*priority_cache == NULL) {
1999 		gnutls_assert();
2000 		return GNUTLS_E_MEMORY_ERROR;
2001 	}
2002 
2003 	/* for now unsafe renegotiation is default on everyone. To be removed
2004 	 * when we make it the default.
2005 	 */
2006 	(*priority_cache)->sr = SR_PARTIAL;
2007 	(*priority_cache)->min_record_version = 1;
2008 	gnutls_atomic_init(&(*priority_cache)->usage_cnt);
2009 
2010 	if (priorities == NULL) {
2011 		priorities = _gnutls_default_priority_string;
2012 		resolved_match = 0;
2013 	}
2014 
2015 	darg = _gnutls_resolve_priorities(priorities);
2016 	if (darg == NULL) {
2017 		gnutls_assert();
2018 		goto error;
2019 	}
2020 
2021 	if (strcmp(darg, priorities) != 0)
2022 		resolved_match = 0;
2023 
2024 	break_list(darg, broken_list, &broken_list_size);
2025 	/* This is our default set of protocol version, certificate types.
2026 	 */
2027 	if (c_strcasecmp(broken_list[0], LEVEL_NONE) != 0) {
2028 		_set_priority(&(*priority_cache)->protocol,
2029 			      protocol_priority);
2030 		_set_priority(&(*priority_cache)->client_ctype,
2031 			      cert_type_priority_default);
2032 		_set_priority(&(*priority_cache)->server_ctype,
2033 			      cert_type_priority_default);
2034 		_set_priority(&(*priority_cache)->_sign_algo,
2035 			      sign_priority_default);
2036 		_set_priority(&(*priority_cache)->_supported_ecc,
2037 			      supported_groups_normal);
2038 		i = 0;
2039 	} else {
2040 		ikeyword_set = 1;
2041 		i = 1;
2042 	}
2043 
2044 	for (; i < broken_list_size; i++) {
2045 		if (check_level(broken_list[i], *priority_cache, ikeyword_set) != 0) {
2046 			ikeyword_set = 1;
2047 			continue;
2048 		} else if (broken_list[i][0] == '!'
2049 			   || broken_list[i][0] == '+'
2050 			   || broken_list[i][0] == '-') {
2051 			if (broken_list[i][0] == '+') {
2052 				fn = prio_add;
2053 				bulk_fn = _add_priority;
2054 				bulk_given_fn = _add_priority;
2055 			} else {
2056 				fn = prio_remove;
2057 				bulk_fn = _clear_priorities;
2058 				bulk_given_fn = _clear_given_priorities;
2059 			}
2060 
2061 			if (broken_list[i][0] == '+'
2062 			    && check_level(&broken_list[i][1],
2063 					   *priority_cache, 1) != 0) {
2064 				continue;
2065 			} else if ((algo =
2066 				    gnutls_mac_get_id(&broken_list[i][1]))
2067 				   != GNUTLS_MAC_UNKNOWN) {
2068 				fn(&(*priority_cache)->_mac, algo);
2069 			} else if ((centry = cipher_name_to_entry(&broken_list[i][1])) != NULL) {
2070 				if (_gnutls_cipher_exists(centry->id)) {
2071 					fn(&(*priority_cache)->_cipher, centry->id);
2072 					if (centry->type == CIPHER_BLOCK)
2073 						(*priority_cache)->have_cbc = 1;
2074 				}
2075 			} else if ((algo =
2076 				  _gnutls_kx_get_id(&broken_list[i][1])) !=
2077 				 GNUTLS_KX_UNKNOWN) {
2078 				if (algo != GNUTLS_KX_INVALID)
2079 					fn(&(*priority_cache)->_kx, algo);
2080 			} else if (PRIO_MATCH("VERS-") == 0) {
2081 				if (PRIO_MATCH("VERS-TLS-ALL") == 0) {
2082 					bulk_given_fn(&(*priority_cache)->
2083 						protocol,
2084 						stream_protocol_priority);
2085 				} else if (PRIO_MATCH("VERS-DTLS-ALL") == 0) {
2086 					bulk_given_fn(&(*priority_cache)->
2087 						protocol,
2088 						(bulk_given_fn==_add_priority)?dtls_protocol_priority:dgram_protocol_priority);
2089 				} else if (PRIO_MATCH("VERS-ALL") == 0) {
2090 					bulk_fn(&(*priority_cache)->
2091 						protocol,
2092 						protocol_priority);
2093 				} else {
2094 					if ((algo =
2095 					     gnutls_protocol_get_id
2096 					     (&broken_list[i][6])) !=
2097 					    GNUTLS_VERSION_UNKNOWN) {
2098 						fn(&(*priority_cache)->
2099 						   protocol, algo);
2100 					} else
2101 						goto error;
2102 
2103 				}
2104 			} /* now check if the element is something like -ALGO */
2105 			else if (PRIO_MATCH("COMP-") == 0) {
2106 				/* ignore all compression methods */
2107 				continue;
2108 			} /* now check if the element is something like -ALGO */
2109 			else if (PRIO_MATCH("CURVE-") == 0) {
2110 				if (PRIO_MATCH("CURVE-ALL") == 0) {
2111 					bulk_fn(&(*priority_cache)->
2112 						_supported_ecc,
2113 						supported_groups_normal);
2114 				} else {
2115 					if ((algo =
2116 					     gnutls_ecc_curve_get_id
2117 					     (&broken_list[i][7])) !=
2118 					    GNUTLS_ECC_CURVE_INVALID)
2119 						fn(&(*priority_cache)->
2120 						   _supported_ecc, algo);
2121 					else
2122 						goto error;
2123 				}
2124 			} else if (PRIO_MATCH("GROUP-") == 0) {
2125 				if (PRIO_MATCH("GROUP-ALL") == 0) {
2126 					bulk_fn(&(*priority_cache)->
2127 						_supported_ecc,
2128 						supported_groups_normal);
2129 				} else if (PRIO_MATCH("GROUP-DH-ALL") == 0) {
2130 					bulk_given_fn(&(*priority_cache)->
2131 						_supported_ecc,
2132 						_supported_groups_dh);
2133 				} else if (PRIO_MATCH("GROUP-EC-ALL") == 0) {
2134 					bulk_given_fn(&(*priority_cache)->
2135 						_supported_ecc,
2136 						_supported_groups_ecdh);
2137 				} else if (PRIO_MATCH("GROUP-GOST-ALL") == 0) {
2138 					bulk_given_fn(&(*priority_cache)->
2139 						_supported_ecc,
2140 						_supported_groups_gost);
2141 				} else {
2142 					if ((algo =
2143 					     gnutls_group_get_id
2144 					     (&broken_list[i][7])) !=
2145 					    GNUTLS_GROUP_INVALID)
2146 						fn(&(*priority_cache)->
2147 						   _supported_ecc, algo);
2148 					else
2149 						goto error;
2150 				}
2151 			} else if (PRIO_MATCH("CTYPE-") == 0) {
2152 				// Certificate types
2153 				if (PRIO_MATCH("CTYPE-ALL") == 0) {
2154 					// Symmetric cert types, all types allowed
2155 					bulk_fn(&(*priority_cache)->client_ctype,
2156 						cert_type_priority_all);
2157 					bulk_fn(&(*priority_cache)->server_ctype,
2158 						cert_type_priority_all);
2159 				} else if (PRIO_MATCH("CTYPE-CLI-") == 0) {
2160 					// Client certificate types
2161 					if (PRIO_MATCH("CTYPE-CLI-ALL") == 0) {
2162 						// All client cert types allowed
2163 						bulk_fn(&(*priority_cache)->client_ctype,
2164 							cert_type_priority_all);
2165 					} else if ((algo = gnutls_certificate_type_get_id
2166 							(&broken_list[i][11])) != GNUTLS_CRT_UNKNOWN) {
2167 						// Specific client cert type allowed
2168 						fn(&(*priority_cache)->client_ctype, algo);
2169 					} else goto error;
2170 				} else if (PRIO_MATCH("CTYPE-SRV-") == 0) {
2171 					// Server certificate types
2172 					if (PRIO_MATCH("CTYPE-SRV-ALL") == 0) {
2173 						// All server cert types allowed
2174 						bulk_fn(&(*priority_cache)->server_ctype,
2175 							cert_type_priority_all);
2176 					} else if ((algo = gnutls_certificate_type_get_id
2177 							(&broken_list[i][11])) != GNUTLS_CRT_UNKNOWN) {
2178 							// Specific server cert type allowed
2179 						fn(&(*priority_cache)->server_ctype, algo);
2180 					} else goto error;
2181 				} else { // Symmetric certificate type
2182 					if ((algo = gnutls_certificate_type_get_id
2183 					     (&broken_list[i][7])) != GNUTLS_CRT_UNKNOWN) {
2184 						fn(&(*priority_cache)->client_ctype, algo);
2185 						fn(&(*priority_cache)->server_ctype, algo);
2186 					} else if (PRIO_MATCH("CTYPE-OPENPGP") == 0) {
2187 						/* legacy openpgp option - ignore */
2188 						continue;
2189 					} else goto error;
2190 				}
2191 			} else if (PRIO_MATCH("SIGN-") == 0) {
2192 				if (PRIO_MATCH("SIGN-ALL") == 0) {
2193 					bulk_fn(&(*priority_cache)->
2194 						_sign_algo,
2195 						sign_priority_default);
2196 				} else if (PRIO_MATCH("SIGN-GOST-ALL") == 0) {
2197 					bulk_fn(&(*priority_cache)->
2198 						_sign_algo,
2199 						sign_priority_gost);
2200 				} else {
2201 					if ((algo =
2202 					     gnutls_sign_get_id
2203 					     (&broken_list[i][6])) !=
2204 					    GNUTLS_SIGN_UNKNOWN)
2205 						fn(&(*priority_cache)->
2206 						   _sign_algo, algo);
2207 					else
2208 						goto error;
2209 				}
2210 			} else if (PRIO_MATCH("MAC-") == 0) {
2211 				if (PRIO_MATCH("MAC-ALL") == 0) {
2212 					bulk_fn(&(*priority_cache)->_mac,
2213 							mac_priority_normal);
2214 				} else if (PRIO_MATCH("MAC-GOST-ALL") == 0) {
2215 					bulk_fn(&(*priority_cache)->_mac,
2216 							mac_priority_gost);
2217 				}
2218 			} else if (PRIO_MATCH("CIPHER-") == 0) {
2219 				if (PRIO_MATCH("CIPHER-ALL") == 0) {
2220 					bulk_fn(&(*priority_cache)->_cipher,
2221 							cipher_priority_normal);
2222 				} else if (PRIO_MATCH("CIPHER-GOST-ALL") == 0) {
2223 					bulk_fn(&(*priority_cache)->_cipher,
2224 							cipher_priority_gost);
2225 				}
2226 			} else if (PRIO_MATCH("KX-") == 0) {
2227 				if (PRIO_MATCH("KX-ALL") == 0) {
2228 					bulk_fn(&(*priority_cache)->_kx,
2229 							kx_priority_secure);
2230 				} else if (PRIO_MATCH("KX-GOST-ALL") == 0) {
2231 					bulk_fn(&(*priority_cache)->_kx,
2232 							kx_priority_gost);
2233 				}
2234 			} else if (PRIO_MATCH("GOST") == 0) {
2235 				bulk_given_fn(&(*priority_cache)->_supported_ecc,
2236 					_supported_groups_gost);
2237 				bulk_fn(&(*priority_cache)->_sign_algo,
2238 					sign_priority_gost);
2239 				bulk_fn(&(*priority_cache)->_mac,
2240 						mac_priority_gost);
2241 				bulk_fn(&(*priority_cache)->_cipher,
2242 						cipher_priority_gost);
2243 				bulk_fn(&(*priority_cache)->_kx,
2244 						kx_priority_gost);
2245 			} else
2246 				goto error;
2247 		} else if (broken_list[i][0] == '%') {
2248 			const struct priority_options_st * o;
2249 			/* to add a new option modify
2250 			 * priority_options.gperf */
2251 			o = in_word_set(&broken_list[i][1], strlen(&broken_list[i][1]));
2252 			if (o == NULL) {
2253 				goto error;
2254 			}
2255 			o->func(*priority_cache);
2256 		} else
2257 			goto error;
2258 	}
2259 
2260 	ret = set_ciphersuite_list(*priority_cache);
2261 	if (ret < 0) {
2262 		if (err_pos)
2263 			*err_pos = priorities;
2264 		goto error_cleanup;
2265 	}
2266 
2267 	gnutls_free(darg);
2268 
2269 	return 0;
2270 
2271  error:
2272 	if (err_pos != NULL && i < broken_list_size && resolved_match) {
2273 		*err_pos = priorities;
2274 		for (j = 0; j < i; j++) {
2275 			(*err_pos) += strlen(broken_list[j]) + 1;
2276 		}
2277 	}
2278 	ret = GNUTLS_E_INVALID_REQUEST;
2279 
2280  error_cleanup:
2281 	free(darg);
2282 	gnutls_priority_deinit(*priority_cache);
2283 	*priority_cache = NULL;
2284 
2285 	return ret;
2286 }
2287 
2288 /**
2289  * gnutls_priority_deinit:
2290  * @priority_cache: is a #gnutls_prioritity_t type.
2291  *
2292  * Deinitializes the priority cache.
2293  **/
gnutls_priority_deinit(gnutls_priority_t priority_cache)2294 void gnutls_priority_deinit(gnutls_priority_t priority_cache)
2295 {
2296 	if (priority_cache == NULL)
2297 		return;
2298 
2299 	/* Note that here we care about the following two cases:
2300 	 * 1. Multiple sessions or different threads holding a reference + a global reference
2301 	 * 2. One session holding a reference with a possible global reference
2302 	 *
2303 	 * As such, it will never be that two threads reach the
2304 	 * zero state at the same time, unless the global reference
2305 	 * is cleared too, which is invalid state.
2306 	 */
2307 	if (gnutls_atomic_val(&priority_cache->usage_cnt) == 0) {
2308 		gnutls_atomic_deinit(&priority_cache->usage_cnt);
2309 		gnutls_free(priority_cache);
2310 		return;
2311 	} else {
2312 		gnutls_atomic_decrement(&priority_cache->usage_cnt);
2313 	}
2314 }
2315 
2316 
2317 /**
2318  * gnutls_priority_set_direct:
2319  * @session: is a #gnutls_session_t type.
2320  * @priorities: is a string describing priorities
2321  * @err_pos: In case of an error this will have the position in the string the error occurred
2322  *
2323  * Sets the priorities to use on the ciphers, key exchange methods,
2324  * and macs.  This function avoids keeping a
2325  * priority cache and is used to directly set string priorities to a
2326  * TLS session.  For documentation check the gnutls_priority_init().
2327  *
2328  * To use a reasonable default, consider using gnutls_set_default_priority(),
2329  * or gnutls_set_default_priority_append() instead of this function.
2330  *
2331  * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
2332  * %GNUTLS_E_SUCCESS on success, or an error code.
2333  **/
2334 int
gnutls_priority_set_direct(gnutls_session_t session,const char * priorities,const char ** err_pos)2335 gnutls_priority_set_direct(gnutls_session_t session,
2336 			   const char *priorities, const char **err_pos)
2337 {
2338 	gnutls_priority_t prio;
2339 	int ret;
2340 
2341 	ret = gnutls_priority_init(&prio, priorities, err_pos);
2342 	if (ret < 0) {
2343 		gnutls_assert();
2344 		return ret;
2345 	}
2346 
2347 	ret = gnutls_priority_set(session, prio);
2348 	if (ret < 0) {
2349 		gnutls_assert();
2350 		return ret;
2351 	}
2352 
2353 	/* ensure that the session holds the only reference for the struct */
2354 	gnutls_priority_deinit(prio);
2355 
2356 	return 0;
2357 }
2358 
2359 /* Breaks a list of "xxx", "yyy", to a character array, of
2360  * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
2361   */
2362 static void
break_list(char * list,char * broken_list[MAX_ELEMENTS],int * size)2363 break_list(char *list,
2364 		 char *broken_list[MAX_ELEMENTS], int *size)
2365 {
2366 	char *p = list;
2367 
2368 	*size = 0;
2369 
2370 	do {
2371 		broken_list[*size] = p;
2372 
2373 		(*size)++;
2374 
2375 		p = strchr(p, ':');
2376 		if (p) {
2377 			*p = 0;
2378 			p++;	/* move to next entry and skip white
2379 				 * space.
2380 				 */
2381 			while (*p == ' ')
2382 				p++;
2383 		}
2384 	}
2385 	while (p != NULL && *size < MAX_ELEMENTS);
2386 }
2387 
2388 /**
2389  * gnutls_set_default_priority:
2390  * @session: is a #gnutls_session_t type.
2391  *
2392  * Sets the default priority on the ciphers, key exchange methods,
2393  * and macs. This is the recommended method of
2394  * setting the defaults, in order to promote consistency between applications
2395  * using GnuTLS, and to allow GnuTLS using applications to update settings
2396  * in par with the library. For client applications which require
2397  * maximum compatibility consider calling gnutls_session_enable_compatibility_mode()
2398  * after this function.
2399  *
2400  * For an application to specify additional options to priority string
2401  * consider using gnutls_set_default_priority_append().
2402  *
2403  * To allow a user to override the defaults (e.g., when a user interface
2404  * or configuration file is available), the functions
2405  * gnutls_priority_set_direct() or gnutls_priority_set() can
2406  * be used.
2407  *
2408  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
2409  *
2410  * Since: 2.1.4
2411  **/
gnutls_set_default_priority(gnutls_session_t session)2412 int gnutls_set_default_priority(gnutls_session_t session)
2413 {
2414 	return gnutls_priority_set_direct(session, NULL, NULL);
2415 }
2416 
2417 /**
2418  * gnutls_set_default_priority_append:
2419  * @session: is a #gnutls_session_t type.
2420  * @add_prio: is a string describing priorities to be appended to default
2421  * @err_pos: In case of an error this will have the position in the string the error occurred
2422  * @flags: must be zero
2423  *
2424  * Sets the default priority on the ciphers, key exchange methods,
2425  * and macs with the additional options in @add_prio. This is the recommended method of
2426  * setting the defaults when only few additional options are to be added. This promotes
2427  * consistency between applications using GnuTLS, and allows GnuTLS using applications
2428  * to update settings in par with the library.
2429  *
2430  * The @add_prio string should start as a normal priority string, e.g.,
2431  * '-VERS-TLS-ALL:+VERS-TLS1.3:%%COMPAT' or '%%FORCE_ETM'. That is, it must not start
2432  * with ':'.
2433  *
2434  * To allow a user to override the defaults (e.g., when a user interface
2435  * or configuration file is available), the functions
2436  * gnutls_priority_set_direct() or gnutls_priority_set() can
2437  * be used.
2438  *
2439  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
2440  *
2441  * Since: 3.6.3
2442  **/
gnutls_set_default_priority_append(gnutls_session_t session,const char * add_prio,const char ** err_pos,unsigned flags)2443 int gnutls_set_default_priority_append(gnutls_session_t session,
2444 				       const char *add_prio,
2445 				       const char **err_pos,
2446 				       unsigned flags)
2447 {
2448 	gnutls_priority_t prio;
2449 	int ret;
2450 
2451 	ret = gnutls_priority_init2(&prio, add_prio, err_pos, GNUTLS_PRIORITY_INIT_DEF_APPEND);
2452 	if (ret < 0) {
2453 		gnutls_assert();
2454 		return ret;
2455 	}
2456 
2457 	ret = gnutls_priority_set(session, prio);
2458 	if (ret < 0) {
2459 		gnutls_assert();
2460 		return ret;
2461 	}
2462 
2463 	/* ensure that the session holds the only reference for the struct */
2464 	gnutls_priority_deinit(prio);
2465 
2466 	return 0;
2467 }
2468 
2469 /**
2470  * gnutls_priority_ecc_curve_list:
2471  * @pcache: is a #gnutls_prioritity_t type.
2472  * @list: will point to an integer list
2473  *
2474  * Get a list of available elliptic curves in the priority
2475  * structure.
2476  *
2477  * Deprecated: This function has been replaced by
2478  * gnutls_priority_group_list() since 3.6.0.
2479  *
2480  * Returns: the number of items, or an error code.
2481  *
2482  * Since: 3.0
2483  **/
2484 int
gnutls_priority_ecc_curve_list(gnutls_priority_t pcache,const unsigned int ** list)2485 gnutls_priority_ecc_curve_list(gnutls_priority_t pcache,
2486 			       const unsigned int **list)
2487 {
2488 	unsigned i;
2489 
2490 	if (pcache->_supported_ecc.num_priorities == 0)
2491 		return 0;
2492 
2493 	*list = pcache->_supported_ecc.priorities;
2494 
2495 	/* to ensure we don't confuse the caller, we do not include
2496 	 * any FFDHE groups. This may return an incomplete list. */
2497 	for (i=0;i<pcache->_supported_ecc.num_priorities;i++)
2498 		if (pcache->_supported_ecc.priorities[i] > GNUTLS_ECC_CURVE_MAX)
2499 			return i;
2500 
2501 	return pcache->_supported_ecc.num_priorities;
2502 }
2503 
2504 /**
2505  * gnutls_priority_group_list:
2506  * @pcache: is a #gnutls_prioritity_t type.
2507  * @list: will point to an integer list
2508  *
2509  * Get a list of available groups in the priority
2510  * structure.
2511  *
2512  * Returns: the number of items, or an error code.
2513  *
2514  * Since: 3.6.0
2515  **/
2516 int
gnutls_priority_group_list(gnutls_priority_t pcache,const unsigned int ** list)2517 gnutls_priority_group_list(gnutls_priority_t pcache,
2518 			       const unsigned int **list)
2519 {
2520 	if (pcache->_supported_ecc.num_priorities == 0)
2521 		return 0;
2522 
2523 	*list = pcache->_supported_ecc.priorities;
2524 	return pcache->_supported_ecc.num_priorities;
2525 }
2526 
2527 /**
2528  * gnutls_priority_kx_list:
2529  * @pcache: is a #gnutls_prioritity_t type.
2530  * @list: will point to an integer list
2531  *
2532  * Get a list of available key exchange methods in the priority
2533  * structure.
2534  *
2535  * Returns: the number of items, or an error code.
2536  * Since: 3.2.3
2537  **/
2538 int
gnutls_priority_kx_list(gnutls_priority_t pcache,const unsigned int ** list)2539 gnutls_priority_kx_list(gnutls_priority_t pcache,
2540 			const unsigned int **list)
2541 {
2542 	if (pcache->_kx.num_priorities == 0)
2543 		return 0;
2544 
2545 	*list = pcache->_kx.priorities;
2546 	return pcache->_kx.num_priorities;
2547 }
2548 
2549 /**
2550  * gnutls_priority_cipher_list:
2551  * @pcache: is a #gnutls_prioritity_t type.
2552  * @list: will point to an integer list
2553  *
2554  * Get a list of available ciphers in the priority
2555  * structure.
2556  *
2557  * Returns: the number of items, or an error code.
2558  * Since: 3.2.3
2559  **/
2560 int
gnutls_priority_cipher_list(gnutls_priority_t pcache,const unsigned int ** list)2561 gnutls_priority_cipher_list(gnutls_priority_t pcache,
2562 			    const unsigned int **list)
2563 {
2564 	if (pcache->_cipher.num_priorities == 0)
2565 		return 0;
2566 
2567 	*list = pcache->_cipher.priorities;
2568 	return pcache->_cipher.num_priorities;
2569 }
2570 
2571 /**
2572  * gnutls_priority_mac_list:
2573  * @pcache: is a #gnutls_prioritity_t type.
2574  * @list: will point to an integer list
2575  *
2576  * Get a list of available MAC algorithms in the priority
2577  * structure.
2578  *
2579  * Returns: the number of items, or an error code.
2580  * Since: 3.2.3
2581  **/
2582 int
gnutls_priority_mac_list(gnutls_priority_t pcache,const unsigned int ** list)2583 gnutls_priority_mac_list(gnutls_priority_t pcache,
2584 			 const unsigned int **list)
2585 {
2586 	if (pcache->_mac.num_priorities == 0)
2587 		return 0;
2588 
2589 	*list = pcache->_mac.priorities;
2590 	return pcache->_mac.num_priorities;
2591 }
2592 
2593 /**
2594  * gnutls_priority_compression_list:
2595  * @pcache: is a #gnutls_prioritity_t type.
2596  * @list: will point to an integer list
2597  *
2598  * Get a list of available compression method in the priority
2599  * structure.
2600  *
2601  * Returns: the number of methods, or an error code.
2602  * Since: 3.0
2603  **/
2604 int
gnutls_priority_compression_list(gnutls_priority_t pcache,const unsigned int ** list)2605 gnutls_priority_compression_list(gnutls_priority_t pcache,
2606 				 const unsigned int **list)
2607 {
2608 	static const unsigned int priority[1] = {GNUTLS_COMP_NULL};
2609 
2610 	*list = priority;
2611 	return 1;
2612 }
2613 
2614 /**
2615  * gnutls_priority_protocol_list:
2616  * @pcache: is a #gnutls_prioritity_t type.
2617  * @list: will point to an integer list
2618  *
2619  * Get a list of available TLS version numbers in the priority
2620  * structure.
2621  *
2622  * Returns: the number of protocols, or an error code.
2623  * Since: 3.0
2624  **/
2625 int
gnutls_priority_protocol_list(gnutls_priority_t pcache,const unsigned int ** list)2626 gnutls_priority_protocol_list(gnutls_priority_t pcache,
2627 			      const unsigned int **list)
2628 {
2629 	if (pcache->protocol.num_priorities == 0)
2630 		return 0;
2631 
2632 	*list = pcache->protocol.priorities;
2633 	return pcache->protocol.num_priorities;
2634 }
2635 
2636 /**
2637  * gnutls_priority_sign_list:
2638  * @pcache: is a #gnutls_prioritity_t type.
2639  * @list: will point to an integer list
2640  *
2641  * Get a list of available signature algorithms in the priority
2642  * structure.
2643  *
2644  * Returns: the number of algorithms, or an error code.
2645  * Since: 3.0
2646  **/
2647 int
gnutls_priority_sign_list(gnutls_priority_t pcache,const unsigned int ** list)2648 gnutls_priority_sign_list(gnutls_priority_t pcache,
2649 			  const unsigned int **list)
2650 {
2651 	if (pcache->_sign_algo.num_priorities == 0)
2652 		return 0;
2653 
2654 	*list = pcache->_sign_algo.priorities;
2655 	return pcache->_sign_algo.num_priorities;
2656 }
2657 
2658 /**
2659  * gnutls_priority_certificate_type_list:
2660  * @pcache: is a #gnutls_prioritity_t type.
2661  * @list: will point to an integer list
2662  *
2663  * Get a list of available certificate types in the priority
2664  * structure.
2665  *
2666  * As of version 3.6.4 this function is an alias for
2667  * gnutls_priority_certificate_type_list2 with the target parameter
2668  * set to:
2669  * - GNUTLS_CTYPE_SERVER, if the %SERVER_PRECEDENCE option is set
2670  * - GNUTLS_CTYPE_CLIENT, otherwise.
2671  *
2672  * Returns: the number of certificate types, or an error code.
2673  * Since: 3.0
2674  **/
2675 int
gnutls_priority_certificate_type_list(gnutls_priority_t pcache,const unsigned int ** list)2676 gnutls_priority_certificate_type_list(gnutls_priority_t pcache,
2677 				      const unsigned int **list)
2678 {
2679 	gnutls_ctype_target_t target =
2680 		pcache->server_precedence ? GNUTLS_CTYPE_SERVER : GNUTLS_CTYPE_CLIENT;
2681 
2682 	return gnutls_priority_certificate_type_list2(pcache, list, target);
2683 }
2684 
2685 /**
2686  * gnutls_priority_certificate_type_list2:
2687  * @pcache: is a #gnutls_prioritity_t type.
2688  * @list: will point to an integer list.
2689  * @target: is a #gnutls_ctype_target_t type. Valid arguments are
2690  *   GNUTLS_CTYPE_CLIENT and GNUTLS_CTYPE_SERVER
2691  *
2692  * Get a list of available certificate types for the given target
2693  * in the priority structure.
2694  *
2695  * Returns: the number of certificate types, or an error code.
2696  *
2697  * Since: 3.6.4
2698  **/
2699 int
gnutls_priority_certificate_type_list2(gnutls_priority_t pcache,const unsigned int ** list,gnutls_ctype_target_t target)2700 gnutls_priority_certificate_type_list2(gnutls_priority_t pcache,
2701 				      const unsigned int **list, gnutls_ctype_target_t target)
2702 {
2703 	switch (target)	{
2704 		case GNUTLS_CTYPE_CLIENT:
2705 			if(pcache->client_ctype.num_priorities > 0) {
2706 				*list = pcache->client_ctype.priorities;
2707 				return pcache->client_ctype.num_priorities;
2708 			}
2709 			break;
2710 		case GNUTLS_CTYPE_SERVER:
2711 			if(pcache->server_ctype.num_priorities > 0)	{
2712 				*list = pcache->server_ctype.priorities;
2713 				return pcache->server_ctype.num_priorities;
2714 			}
2715 			break;
2716 		default:
2717 			// Invalid target given
2718 			gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2719 	}
2720 
2721 	// Found a matching target but non of them had any ctypes set
2722 	return 0;
2723 }
2724 
2725 /**
2726  * gnutls_priority_string_list:
2727  * @iter: an integer counter starting from zero
2728  * @flags: one of %GNUTLS_PRIORITY_LIST_INIT_KEYWORDS, %GNUTLS_PRIORITY_LIST_SPECIAL
2729  *
2730  * Can be used to iterate all available priority strings.
2731  * Due to internal implementation details, there are cases where this
2732  * function can return the empty string. In that case that string should be ignored.
2733  * When no strings are available it returns %NULL.
2734  *
2735  * Returns: a priority string
2736  * Since: 3.4.0
2737  **/
2738 const char *
gnutls_priority_string_list(unsigned iter,unsigned int flags)2739 gnutls_priority_string_list(unsigned iter, unsigned int flags)
2740 {
2741 	if (flags & GNUTLS_PRIORITY_LIST_INIT_KEYWORDS) {
2742 		if (iter >= (sizeof(pgroups)/sizeof(pgroups[0]))-1)
2743 			return NULL;
2744 		return pgroups[iter].name;
2745 	} else if (flags & GNUTLS_PRIORITY_LIST_SPECIAL) {
2746 		if (iter >= (sizeof(wordlist)/sizeof(wordlist[0]))-1)
2747 			return NULL;
2748 		return wordlist[iter].name;
2749 	}
2750 	return NULL;
2751 }
2752