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