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