2 * Copyright (C) 2004-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Here lies the code of the gnutls_*_set_priority() functions.
26 #include "gnutls_int.h"
27 #include "algorithms.h"
28 #include "gnutls_errors.h"
29 #include <gnutls_num.h>
30 #include <gnutls/x509.h>
32 #include <gnutls_extensions.h>
34 #define MAX_ELEMENTS 64
36 static void prio_remove(priority_st * priority_list, unsigned int algo);
37 static void prio_add(priority_st * priority_list, unsigned int algo);
39 break_list(char *etag,
40 char *broken_etag[MAX_ELEMENTS], int *size);
42 typedef void (bulk_rmadd_func) (priority_st * priority_list, const int *);
44 inline static void _set_priority(priority_st * st, const int *list)
48 while (list[num] != 0)
54 for (i = 0; i < num; i++) {
55 st->priority[i] = list[i];
61 inline static void _add_priority(priority_st * st, const int *list)
65 init = i = st->algorithms;
67 for (num = 0; list[num] != 0; ++num) {
68 if (i + 1 > MAX_ALGOS) {
72 for (j = 0; j < init; j++) {
73 if (st->priority[j] == (unsigned) list[num]) {
79 st->priority[i++] = list[num];
87 static void _clear_priorities(priority_st * st, const int *list)
89 memset(st, 0, sizeof(*st));
92 static void _clear_given_priorities(priority_st * st, const int *list)
96 for (i=0;list[i]!=0;i++) {
97 prio_remove(st, list[i]);
101 static const int _supported_ecc_normal[] = {
102 GNUTLS_ECC_CURVE_SECP256R1,
103 GNUTLS_ECC_CURVE_SECP384R1,
104 GNUTLS_ECC_CURVE_SECP521R1,
105 #ifdef ENABLE_NON_SUITEB_CURVES
106 GNUTLS_ECC_CURVE_SECP224R1,
107 GNUTLS_ECC_CURVE_SECP192R1,
111 static const int* supported_ecc_normal = _supported_ecc_normal;
113 static const int _supported_ecc_secure128[] = {
114 GNUTLS_ECC_CURVE_SECP256R1,
115 GNUTLS_ECC_CURVE_SECP384R1,
116 GNUTLS_ECC_CURVE_SECP521R1,
119 static const int* supported_ecc_secure128 = _supported_ecc_secure128;
121 static const int _supported_ecc_suiteb128[] = {
122 GNUTLS_ECC_CURVE_SECP256R1,
123 GNUTLS_ECC_CURVE_SECP384R1,
126 static const int* supported_ecc_suiteb128 = _supported_ecc_suiteb128;
128 static const int _supported_ecc_suiteb192[] = {
129 GNUTLS_ECC_CURVE_SECP384R1,
132 static const int* supported_ecc_suiteb192 = _supported_ecc_suiteb192;
134 static const int _supported_ecc_secure192[] = {
135 GNUTLS_ECC_CURVE_SECP384R1,
136 GNUTLS_ECC_CURVE_SECP521R1,
139 static const int* supported_ecc_secure192 = _supported_ecc_secure192;
141 static const int protocol_priority[] = {
150 static const int stream_protocol_priority[] = {
157 static const int dgram_protocol_priority[] = {
164 static const int dtls_protocol_priority[] = {
170 static const int _protocol_priority_suiteb[] = {
174 static const int* protocol_priority_suiteb = _protocol_priority_suiteb;
176 static const int _kx_priority_performance[] = {
179 GNUTLS_KX_ECDHE_ECDSA,
187 static const int* kx_priority_performance = _kx_priority_performance;
189 static const int _kx_priority_pfs[] = {
191 GNUTLS_KX_ECDHE_ECDSA,
199 static const int* kx_priority_pfs = _kx_priority_pfs;
201 static const int _kx_priority_suiteb[] = {
202 GNUTLS_KX_ECDHE_ECDSA,
205 static const int* kx_priority_suiteb = _kx_priority_suiteb;
207 static const int _kx_priority_secure[] = {
208 /* The ciphersuites that offer forward secrecy take
212 GNUTLS_KX_ECDHE_ECDSA,
216 /* KX-RSA is now ahead of DHE-RSA and DHE-DSS due to the compatibility
217 * issues the DHE ciphersuites have. That is, one cannot enforce a specific
218 * security level without dropping the connection.
223 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
227 static const int* kx_priority_secure = _kx_priority_secure;
229 static const int _cipher_priority_performance_default[] = {
230 GNUTLS_CIPHER_AES_128_GCM,
231 GNUTLS_CIPHER_AES_256_GCM,
232 GNUTLS_CIPHER_CAMELLIA_128_GCM,
233 GNUTLS_CIPHER_CAMELLIA_256_GCM,
234 GNUTLS_CIPHER_AES_128_CBC,
235 GNUTLS_CIPHER_AES_256_CBC,
236 GNUTLS_CIPHER_CAMELLIA_128_CBC,
237 GNUTLS_CIPHER_CAMELLIA_256_CBC,
238 GNUTLS_CIPHER_AES_128_CCM,
239 GNUTLS_CIPHER_AES_256_CCM,
240 GNUTLS_CIPHER_3DES_CBC,
244 /* If GCM and AES acceleration is available then prefer
245 * them over anything else.
247 static const int _cipher_priority_normal_default[] = {
248 GNUTLS_CIPHER_AES_128_GCM,
249 GNUTLS_CIPHER_AES_256_GCM,
250 GNUTLS_CIPHER_CAMELLIA_128_GCM,
251 GNUTLS_CIPHER_CAMELLIA_256_GCM,
252 GNUTLS_CIPHER_AES_128_CBC,
253 GNUTLS_CIPHER_AES_256_CBC,
254 GNUTLS_CIPHER_CAMELLIA_128_CBC,
255 GNUTLS_CIPHER_CAMELLIA_256_CBC,
256 GNUTLS_CIPHER_AES_128_CCM,
257 GNUTLS_CIPHER_AES_256_CCM,
258 GNUTLS_CIPHER_3DES_CBC,
262 static const int cipher_priority_performance_fips[] = {
263 GNUTLS_CIPHER_AES_128_GCM,
264 GNUTLS_CIPHER_AES_256_GCM,
265 GNUTLS_CIPHER_AES_128_CBC,
266 GNUTLS_CIPHER_AES_256_CBC,
267 GNUTLS_CIPHER_AES_128_CCM,
268 GNUTLS_CIPHER_AES_256_CCM,
269 GNUTLS_CIPHER_3DES_CBC,
273 static const int cipher_priority_normal_fips[] = {
274 GNUTLS_CIPHER_AES_128_GCM,
275 GNUTLS_CIPHER_AES_256_GCM,
276 GNUTLS_CIPHER_AES_128_CBC,
277 GNUTLS_CIPHER_AES_256_CBC,
278 GNUTLS_CIPHER_AES_128_CCM,
279 GNUTLS_CIPHER_AES_256_CCM,
280 GNUTLS_CIPHER_3DES_CBC,
285 static const int _cipher_priority_suiteb128[] = {
286 GNUTLS_CIPHER_AES_128_GCM,
287 GNUTLS_CIPHER_AES_256_GCM,
290 static const int* cipher_priority_suiteb128 = _cipher_priority_suiteb128;
292 static const int _cipher_priority_suiteb192[] = {
293 GNUTLS_CIPHER_AES_256_GCM,
296 static const int* cipher_priority_suiteb192 = _cipher_priority_suiteb192;
299 static const int _cipher_priority_secure128[] = {
300 GNUTLS_CIPHER_AES_128_GCM,
301 GNUTLS_CIPHER_CAMELLIA_128_GCM,
303 GNUTLS_CIPHER_AES_256_GCM,
304 GNUTLS_CIPHER_CAMELLIA_256_GCM,
306 GNUTLS_CIPHER_AES_128_CBC,
307 GNUTLS_CIPHER_CAMELLIA_128_CBC,
308 GNUTLS_CIPHER_AES_256_CBC,
309 GNUTLS_CIPHER_CAMELLIA_256_CBC,
311 GNUTLS_CIPHER_AES_128_CCM,
312 GNUTLS_CIPHER_AES_256_CCM,
315 static const int *cipher_priority_secure128 = _cipher_priority_secure128;
318 static const int _cipher_priority_secure192[] = {
319 GNUTLS_CIPHER_AES_256_GCM,
320 GNUTLS_CIPHER_CAMELLIA_256_GCM,
321 GNUTLS_CIPHER_AES_256_CBC,
322 GNUTLS_CIPHER_CAMELLIA_256_CBC,
323 GNUTLS_CIPHER_AES_256_CCM,
326 static const int* cipher_priority_secure192 = _cipher_priority_secure192;
328 static const int comp_priority[] = {
329 /* compression should be explicitly requested to be enabled */
334 static const int _sign_priority_default[] = {
335 GNUTLS_SIGN_RSA_SHA256,
336 GNUTLS_SIGN_ECDSA_SHA256,
338 GNUTLS_SIGN_RSA_SHA384,
339 GNUTLS_SIGN_ECDSA_SHA384,
341 GNUTLS_SIGN_RSA_SHA512,
342 GNUTLS_SIGN_ECDSA_SHA512,
344 GNUTLS_SIGN_RSA_SHA224,
345 GNUTLS_SIGN_ECDSA_SHA224,
347 GNUTLS_SIGN_RSA_SHA1,
348 GNUTLS_SIGN_ECDSA_SHA1,
351 static const int* sign_priority_default = _sign_priority_default;
353 static const int _sign_priority_suiteb128[] = {
354 GNUTLS_SIGN_ECDSA_SHA256,
355 GNUTLS_SIGN_ECDSA_SHA384,
358 static const int* sign_priority_suiteb128 = _sign_priority_suiteb128;
360 static const int _sign_priority_suiteb192[] = {
361 GNUTLS_SIGN_ECDSA_SHA384,
364 static const int* sign_priority_suiteb192 = _sign_priority_suiteb192;
366 static const int _sign_priority_secure128[] = {
367 GNUTLS_SIGN_RSA_SHA256,
368 GNUTLS_SIGN_ECDSA_SHA256,
369 GNUTLS_SIGN_RSA_SHA384,
370 GNUTLS_SIGN_ECDSA_SHA384,
371 GNUTLS_SIGN_RSA_SHA512,
372 GNUTLS_SIGN_ECDSA_SHA512,
375 static const int* sign_priority_secure128 = _sign_priority_secure128;
377 static const int _sign_priority_secure192[] = {
378 GNUTLS_SIGN_RSA_SHA384,
379 GNUTLS_SIGN_ECDSA_SHA384,
380 GNUTLS_SIGN_RSA_SHA512,
381 GNUTLS_SIGN_ECDSA_SHA512,
384 static const int* sign_priority_secure192 = _sign_priority_secure192;
386 static const int mac_priority_normal_default[] = {
395 static const int mac_priority_normal_fips[] = {
403 static const int *cipher_priority_performance = _cipher_priority_performance_default;
404 static const int *cipher_priority_normal = _cipher_priority_normal_default;
405 static const int *mac_priority_normal = mac_priority_normal_default;
407 /* if called with replace the default priorities with the FIPS140 ones */
408 void _gnutls_priority_update_fips(void)
410 cipher_priority_performance = cipher_priority_performance_fips;
411 cipher_priority_normal = cipher_priority_normal_fips;
412 mac_priority_normal = mac_priority_normal_fips;
415 static const int _mac_priority_suiteb[] = {
419 static const int* mac_priority_suiteb = _mac_priority_suiteb;
421 static const int _mac_priority_secure128[] = {
428 static const int* mac_priority_secure128 = _mac_priority_secure128;
430 static const int _mac_priority_secure192[] = {
436 static const int* mac_priority_secure192 = _mac_priority_secure192;
438 static const int cert_type_priority_default[] = {
443 static const int cert_type_priority_all[] = {
449 typedef void (rmadd_func) (priority_st * priority_list, unsigned int alg);
451 static void prio_remove(priority_st * priority_list, unsigned int algo)
455 for (i = 0; i < priority_list->algorithms; i++) {
456 if (priority_list->priority[i] == algo) {
457 priority_list->algorithms--;
458 if ((priority_list->algorithms - i) > 0)
459 memmove(&priority_list->priority[i],
460 &priority_list->priority[i + 1],
461 (priority_list->algorithms -
463 sizeof(priority_list->
465 priority_list->priority[priority_list->
474 static void prio_add(priority_st * priority_list, unsigned int algo)
476 unsigned int i, l = priority_list->algorithms;
479 return; /* can't add it anyway */
481 for (i = 0; i < l; ++i) {
482 if (algo == priority_list->priority[i])
483 return; /* if it exists */
486 priority_list->priority[l] = algo;
487 priority_list->algorithms++;
494 * gnutls_priority_set:
495 * @session: is a #gnutls_session_t structure.
496 * @priority: is a #gnutls_priority_t structure.
498 * Sets the priorities to use on the ciphers, key exchange methods,
499 * macs and compression methods.
501 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
504 gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority)
506 if (priority == NULL) {
508 return GNUTLS_E_NO_CIPHER_SUITES;
511 memcpy(&session->internals.priorities, priority,
512 sizeof(struct gnutls_priority_st));
514 /* set the current version to the first in the chain.
515 * This will be overridden later.
517 if (session->internals.priorities.protocol.algorithms > 0) {
518 if (_gnutls_set_current_version(session,
519 session->internals.priorities.
520 protocol.priority[0]) < 0) {
521 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
525 if (priority->no_tickets != 0) {
526 /* when PFS is explicitly requested, disable session tickets */
527 _gnutls_ext_unset_session_data(session, GNUTLS_EXTENSION_SESSION_TICKET);
530 if (session->internals.priorities.protocol.algorithms == 0 ||
531 session->internals.priorities.cipher.algorithms == 0 ||
532 session->internals.priorities.mac.algorithms == 0 ||
533 session->internals.priorities.kx.algorithms == 0 ||
534 session->internals.priorities.compression.algorithms == 0)
535 return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
541 #define LEVEL_NONE "NONE"
542 #define LEVEL_NORMAL "NORMAL"
543 #define LEVEL_PFS "PFS"
544 #define LEVEL_PERFORMANCE "PERFORMANCE"
545 #define LEVEL_SECURE128 "SECURE128"
546 #define LEVEL_SECURE192 "SECURE192"
547 #define LEVEL_SECURE256 "SECURE256"
548 #define LEVEL_SUITEB128 "SUITEB128"
549 #define LEVEL_SUITEB192 "SUITEB192"
550 #define LEVEL_LEGACY "LEGACY"
552 struct priority_groups_st {
555 const int **proto_list;
556 const int **cipher_list;
557 const int **mac_list;
559 const int **sign_list;
560 const int **ecc_list;
566 static const struct priority_groups_st pgroups[] =
568 {.name = LEVEL_NORMAL,
569 .cipher_list = &cipher_priority_normal,
570 .mac_list = &mac_priority_normal,
571 .kx_list = &kx_priority_secure,
572 .sign_list = &sign_priority_default,
573 .ecc_list = &supported_ecc_normal,
574 .profile = GNUTLS_PROFILE_LOW,
575 .sec_param = GNUTLS_SEC_PARAM_WEAK
578 .cipher_list = &cipher_priority_normal,
579 .mac_list = &mac_priority_secure128,
580 .kx_list = &kx_priority_pfs,
581 .sign_list = &sign_priority_default,
582 .ecc_list = &supported_ecc_normal,
583 .profile = GNUTLS_PROFILE_LOW,
584 .sec_param = GNUTLS_SEC_PARAM_WEAK,
587 {.name = LEVEL_SECURE128,
589 .cipher_list = &cipher_priority_secure128,
590 .mac_list = &mac_priority_secure128,
591 .kx_list = &kx_priority_secure,
592 .sign_list = &sign_priority_secure128,
593 .ecc_list = &supported_ecc_secure128,
594 /* The profile should have been HIGH but if we don't allow
595 * SHA-1 (80-bits) as signature algorithm we are not able
596 * to connect anywhere with this level */
597 .profile = GNUTLS_PROFILE_LOW,
598 .sec_param = GNUTLS_SEC_PARAM_LOW
600 {.name = LEVEL_SECURE192,
601 .alias = LEVEL_SECURE256,
602 .cipher_list = &cipher_priority_secure192,
603 .mac_list = &mac_priority_secure192,
604 .kx_list = &kx_priority_secure,
605 .sign_list = &sign_priority_secure192,
606 .ecc_list = &supported_ecc_secure192,
607 .profile = GNUTLS_PROFILE_HIGH,
608 .sec_param = GNUTLS_SEC_PARAM_HIGH
610 {.name = LEVEL_SUITEB128,
611 .proto_list = &protocol_priority_suiteb,
612 .cipher_list = &cipher_priority_suiteb128,
613 .mac_list = &mac_priority_suiteb,
614 .kx_list = &kx_priority_suiteb,
615 .sign_list = &sign_priority_suiteb128,
616 .ecc_list = &supported_ecc_suiteb128,
617 .profile = GNUTLS_PROFILE_SUITEB128,
618 .sec_param = GNUTLS_SEC_PARAM_HIGH
620 {.name = LEVEL_SUITEB192,
621 .proto_list = &protocol_priority_suiteb,
622 .cipher_list = &cipher_priority_suiteb192,
623 .mac_list = &mac_priority_suiteb,
624 .kx_list = &kx_priority_suiteb,
625 .sign_list = &sign_priority_suiteb192,
626 .ecc_list = &supported_ecc_suiteb192,
627 .profile = GNUTLS_PROFILE_SUITEB192,
628 .sec_param = GNUTLS_SEC_PARAM_ULTRA
630 {.name = LEVEL_LEGACY,
631 .cipher_list = &cipher_priority_normal,
632 .mac_list = &mac_priority_normal,
633 .kx_list = &kx_priority_secure,
634 .sign_list = &sign_priority_default,
635 .ecc_list = &supported_ecc_normal,
636 .sec_param = GNUTLS_SEC_PARAM_VERY_WEAK
638 {.name = LEVEL_PERFORMANCE,
639 .cipher_list = &cipher_priority_performance,
640 .mac_list = &mac_priority_normal,
641 .kx_list = &kx_priority_performance,
642 .sign_list = &sign_priority_default,
643 .ecc_list = &supported_ecc_normal,
644 .profile = GNUTLS_PROFILE_LOW,
645 .sec_param = GNUTLS_SEC_PARAM_WEAK
652 #define SET_PROFILE(to_set) \
653 profile = GNUTLS_VFLAGS_TO_PROFILE(priority_cache->additional_verify_flags); \
654 if (profile == 0 || profile > to_set) { \
655 priority_cache->additional_verify_flags &= ~GNUTLS_VFLAGS_PROFILE_MASK; \
656 priority_cache->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(to_set); \
659 #define SET_LEVEL(to_set) \
660 if (priority_cache->level == 0 || (unsigned)priority_cache->level > (unsigned)to_set) \
661 priority_cache->level = to_set
664 int check_level(const char *level, gnutls_priority_t priority_cache,
667 bulk_rmadd_func *func;
668 unsigned profile = 0;
672 func = _add_priority;
674 func = _set_priority;
677 if (pgroups[i].name == NULL)
680 if (strcasecmp(level, pgroups[i].name) == 0 ||
681 (pgroups[i].alias != NULL && strcasecmp(level, pgroups[i].alias) == 0)) {
682 if (pgroups[i].proto_list != NULL)
683 func(&priority_cache->protocol, *pgroups[i].proto_list);
684 func(&priority_cache->cipher, *pgroups[i].cipher_list);
685 func(&priority_cache->kx, *pgroups[i].kx_list);
686 func(&priority_cache->mac, *pgroups[i].mac_list);
687 func(&priority_cache->sign_algo, *pgroups[i].sign_list);
688 func(&priority_cache->supported_ecc, *pgroups[i].ecc_list);
690 if (pgroups[i].profile != 0) {
691 SET_PROFILE(pgroups[i].profile); /* set certificate level */
693 SET_LEVEL(pgroups[i].sec_param); /* set DH params level */
694 priority_cache->no_tickets = pgroups[i].no_tickets;
700 static void enable_compat(gnutls_priority_t c)
704 static void enable_dumbfw(gnutls_priority_t c)
708 static void enable_no_extensions(gnutls_priority_t c)
710 c->no_extensions = 1;
712 static void enable_no_ext_master_secret(gnutls_priority_t c)
714 c->no_ext_master_secret = 1;
716 static void enable_no_etm(gnutls_priority_t c)
720 static void enable_no_tickets(gnutls_priority_t c)
724 static void enable_stateless_compression(gnutls_priority_t c)
726 c->stateless_compression = 1;
728 static void disable_wildcards(gnutls_priority_t c)
730 c->additional_verify_flags |= GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS;
732 static void enable_profile_very_weak(gnutls_priority_t c)
734 c->additional_verify_flags &= 0x00ffffff;
735 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_VERY_WEAK);
736 c->level = GNUTLS_SEC_PARAM_VERY_WEAK;
738 static void enable_profile_low(gnutls_priority_t c)
740 c->additional_verify_flags &= 0x00ffffff;
741 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_LOW);
742 c->level = GNUTLS_SEC_PARAM_LOW;
744 static void enable_profile_legacy(gnutls_priority_t c)
746 c->additional_verify_flags &= 0x00ffffff;
747 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_LEGACY);
748 c->level = GNUTLS_SEC_PARAM_LEGACY;
750 static void enable_profile_high(gnutls_priority_t c)
752 c->additional_verify_flags &= 0x00ffffff;
753 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_HIGH);
754 c->level = GNUTLS_SEC_PARAM_HIGH;
756 static void enable_profile_ultra(gnutls_priority_t c)
758 c->additional_verify_flags &= 0x00ffffff;
759 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_ULTRA);
760 c->level = GNUTLS_SEC_PARAM_ULTRA;
762 static void enable_profile_medium(gnutls_priority_t c)
764 c->additional_verify_flags &= 0x00ffffff;
765 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM);
766 c->level = GNUTLS_SEC_PARAM_MEDIUM;
768 static void enable_profile_suiteb128(gnutls_priority_t c)
770 c->additional_verify_flags &= 0x00ffffff;
771 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_SUITEB128);
772 c->level = GNUTLS_SEC_PARAM_HIGH;
774 static void enable_profile_suiteb192(gnutls_priority_t c)
776 c->additional_verify_flags &= 0x00ffffff;
777 c->additional_verify_flags |= GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_SUITEB192);
778 c->level = GNUTLS_SEC_PARAM_ULTRA;
780 static void enable_safe_renegotiation(gnutls_priority_t c)
785 static void enable_unsafe_renegotiation(gnutls_priority_t c)
789 static void enable_partial_safe_renegotiation(gnutls_priority_t c)
793 static void disable_safe_renegotiation(gnutls_priority_t c)
797 static void enable_latest_record_version(gnutls_priority_t c)
799 c->min_record_version = 0;
801 static void enable_ssl3_record_version(gnutls_priority_t c)
803 c->min_record_version = 1;
805 static void enable_verify_allow_rsa_md5(gnutls_priority_t c)
807 c->additional_verify_flags |=
808 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
810 static void disable_crl_checks(gnutls_priority_t c)
812 c->additional_verify_flags |=
813 GNUTLS_VERIFY_DISABLE_CRL_CHECKS;
815 static void enable_server_precedence(gnutls_priority_t c)
817 c->server_precedence = 1;
819 static void dummy_func(gnutls_priority_t c)
823 #include <priority_options.h>
825 static char *check_str(char *line, size_t line_size, const char *needle, size_t needle_size)
830 while (c_isspace(*line)) {
835 if (line[0] == '#' || needle_size >= line_size)
838 if (memcmp(line, needle, needle_size) == 0) {
839 p = &line[needle_size];
840 while (c_isspace(*p)) {
848 while (c_isspace(*p)) {
854 if (n > 1 && p[n-1] == '\n') {
859 if (n > 1 && p[n-1] == '\r') {
869 /* Returns the new priorities if SYSTEM is specified in
870 * an allocated string, or just a copy of the provided
871 * priorities, appended with any additional present in
872 * the priorities string.
874 * The returned string must be released using free().
876 static char *resolve_priorities(const char* priorities)
878 char *p = (char*)priorities;
879 char *additional = NULL;
881 char *ss, *line = NULL;
885 size_t n, n2 = 0, line_size;
887 while (c_isspace(*p))
893 additional = strchr(p, ':');
894 if (additional != NULL) {
895 ss_len = additional - ss;
901 fp = fopen(SYSTEM_PRIORITY_FILE, "r");
902 if (fp == NULL) {/* fail */
908 l = getline(&line, &line_size, fp);
910 p = check_str(line, line_size, ss, ss_len);
923 n2 = strlen(additional);
925 ret = malloc(n+n2+1+1);
931 if (additional != NULL) {
933 memcpy(&ret[n+1], additional, n2);
944 _gnutls_debug_log("selected priority string: %s\n", ret);
954 * gnutls_priority_init:
955 * @priority_cache: is a #gnutls_prioritity_t structure.
956 * @priorities: is a string describing priorities
957 * @err_pos: In case of an error this will have the position in the string the error occurred
959 * Sets priorities for the ciphers, key exchange methods, macs and
960 * compression methods.
962 * The #priorities option allows you to specify a colon
963 * separated list of the cipher priorities to enable.
964 * Some keywords are defined to provide quick access
965 * to common preferences.
967 * Unless there is a special need, use the "NORMAL" keyword to
968 * apply a reasonable security level, or "NORMAL:%COMPAT" for compatibility.
970 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
971 * limited to 128 bit ciphers and sorted by terms of speed
974 * "LEGACY" the NORMAL settings for GnuTLS 3.2.x or earlier. There is
975 * no verification profile set, and the allowed DH primes are considered
978 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
979 * included as a fallback only. The ciphers are sorted by security
982 * "PFS" means all "secure" ciphersuites that support perfect forward secrecy.
983 * The 256-bit ciphers are included as a fallback only.
984 * The ciphers are sorted by security margin.
986 * "SECURE128" means all "secure" ciphersuites of security level 128-bit
989 * "SECURE192" means all "secure" ciphersuites of security level 192-bit
992 * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
995 * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
998 * "NONE" means nothing is enabled. This disables even protocols and
999 * compression methods.
1001 * "@KEYWORD" The system administrator imposed settings. The provided keywords
1002 * will be expanded from a configuration-time provided file - default is:
1003 * /etc/gnutls/default-priorities. Any keywords that follow it, will
1004 * be appended to the expanded string. If there is no system string,
1005 * then the function will fail. The system file should be formatted
1006 * as "KEYWORD=VALUE", e.g., "SYSTEM=NORMAL:+ARCFOUR-128".
1008 * Special keywords are "!", "-" and "+".
1009 * "!" or "-" appended with an algorithm will remove this algorithm.
1010 * "+" appended with an algorithm will add this algorithm.
1012 * Check the GnuTLS manual section "Priority strings" for detailed
1017 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
1019 * "NORMAL:+ARCFOUR-128" means normal ciphers plus ARCFOUR-128.
1021 * "SECURE128:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
1022 * enabled, SSL3.0 is disabled, and libz compression enabled.
1024 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1",
1026 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1",
1028 * "SECURE256:+SECURE128",
1030 * Note that "NORMAL:%COMPAT" is the most compatible mode.
1032 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
1033 * %GNUTLS_E_SUCCESS on success, or an error code.
1036 gnutls_priority_init(gnutls_priority_t * priority_cache,
1037 const char *priorities, const char **err_pos)
1039 char *broken_list[MAX_ELEMENTS];
1040 int broken_list_size = 0, i = 0, j;
1042 unsigned ikeyword_set = 0;
1045 bulk_rmadd_func *bulk_fn;
1046 bulk_rmadd_func *bulk_given_fn;
1049 *err_pos = priorities;
1052 gnutls_calloc(1, sizeof(struct gnutls_priority_st));
1053 if (*priority_cache == NULL) {
1055 return GNUTLS_E_MEMORY_ERROR;
1058 /* for now unsafe renegotiation is default on everyone. To be removed
1059 * when we make it the default.
1061 (*priority_cache)->sr = SR_PARTIAL;
1062 (*priority_cache)->min_record_version = 1;
1064 (*priority_cache)->max_empty_records = DEFAULT_MAX_EMPTY_RECORDS;
1066 if (priorities == NULL)
1067 priorities = "NORMAL";
1069 darg = resolve_priorities(priorities);
1075 break_list(darg, broken_list, &broken_list_size);
1076 /* This is our default set of protocol version, certificate types and
1077 * compression methods.
1079 if (strcasecmp(broken_list[0], LEVEL_NONE) != 0) {
1080 _set_priority(&(*priority_cache)->protocol,
1082 _set_priority(&(*priority_cache)->compression,
1084 _set_priority(&(*priority_cache)->cert_type,
1085 cert_type_priority_default);
1086 _set_priority(&(*priority_cache)->sign_algo,
1087 sign_priority_default);
1088 _set_priority(&(*priority_cache)->supported_ecc,
1089 supported_ecc_normal);
1096 for (; i < broken_list_size; i++) {
1097 if (check_level(broken_list[i], *priority_cache, ikeyword_set) != 0) {
1100 } else if (broken_list[i][0] == '!'
1101 || broken_list[i][0] == '+'
1102 || broken_list[i][0] == '-') {
1103 if (broken_list[i][0] == '+') {
1105 bulk_fn = _add_priority;
1106 bulk_given_fn = _add_priority;
1109 bulk_fn = _clear_priorities;
1110 bulk_given_fn = _clear_given_priorities;
1113 if (broken_list[i][0] == '+'
1114 && check_level(&broken_list[i][1],
1115 *priority_cache, 1) != 0) {
1118 gnutls_mac_get_id(&broken_list[i][1]))
1119 != GNUTLS_MAC_UNKNOWN)
1120 fn(&(*priority_cache)->mac, algo);
1122 gnutls_cipher_get_id(&broken_list[i][1]))
1123 != GNUTLS_CIPHER_UNKNOWN)
1124 fn(&(*priority_cache)->cipher, algo);
1126 gnutls_kx_get_id(&broken_list[i][1])) !=
1128 fn(&(*priority_cache)->kx, algo);
1129 else if (strncasecmp
1130 (&broken_list[i][1], "VERS-", 5) == 0) {
1132 (&broken_list[i][1], "VERS-TLS-ALL",
1134 bulk_given_fn(&(*priority_cache)->
1136 stream_protocol_priority);
1137 } else if (strncasecmp
1138 (&broken_list[i][1],
1139 "VERS-DTLS-ALL", 13) == 0) {
1140 bulk_given_fn(&(*priority_cache)->
1142 (bulk_given_fn==_add_priority)?dtls_protocol_priority:dgram_protocol_priority);
1143 } else if (strncasecmp
1144 (&broken_list[i][1],
1145 "VERS-ALL", 8) == 0) {
1146 bulk_fn(&(*priority_cache)->
1151 gnutls_protocol_get_id
1152 (&broken_list[i][6])) !=
1153 GNUTLS_VERSION_UNKNOWN)
1154 fn(&(*priority_cache)->
1160 } /* now check if the element is something like -ALGO */
1161 else if (strncasecmp
1162 (&broken_list[i][1], "COMP-", 5) == 0) {
1164 (&broken_list[i][1], "COMP-ALL",
1166 bulk_fn(&(*priority_cache)->
1171 gnutls_compression_get_id
1172 (&broken_list[i][6])) !=
1173 GNUTLS_COMP_UNKNOWN)
1174 fn(&(*priority_cache)->
1179 } /* now check if the element is something like -ALGO */
1180 else if (strncasecmp
1181 (&broken_list[i][1], "CURVE-", 6) == 0) {
1183 (&broken_list[i][1], "CURVE-ALL",
1185 bulk_fn(&(*priority_cache)->
1187 supported_ecc_normal);
1190 _gnutls_ecc_curve_get_id
1191 (&broken_list[i][7])) !=
1192 GNUTLS_ECC_CURVE_INVALID)
1193 fn(&(*priority_cache)->
1194 supported_ecc, algo);
1198 } /* now check if the element is something like -ALGO */
1199 else if (strncasecmp
1200 (&broken_list[i][1], "CTYPE-", 6) == 0) {
1202 (&broken_list[i][1], "CTYPE-ALL",
1204 bulk_fn(&(*priority_cache)->
1206 cert_type_priority_all);
1209 gnutls_certificate_type_get_id
1210 (&broken_list[i][7])) !=
1212 fn(&(*priority_cache)->
1217 } /* now check if the element is something like -ALGO */
1218 else if (strncasecmp
1219 (&broken_list[i][1], "SIGN-", 5) == 0) {
1221 (&broken_list[i][1], "SIGN-ALL",
1223 bulk_fn(&(*priority_cache)->
1225 sign_priority_default);
1229 (&broken_list[i][6])) !=
1230 GNUTLS_SIGN_UNKNOWN)
1231 fn(&(*priority_cache)->
1238 (&broken_list[i][1], "MAC-ALL", 7) == 0) {
1239 bulk_fn(&(*priority_cache)->mac,
1240 mac_priority_normal);
1243 (&broken_list[i][1], "CIPHER-ALL",
1245 bulk_fn(&(*priority_cache)->cipher,
1246 cipher_priority_normal);
1249 (&broken_list[i][1], "KX-ALL", 6) == 0) {
1250 bulk_fn(&(*priority_cache)->kx,
1251 kx_priority_secure);
1254 } else if (broken_list[i][0] == '%') {
1255 const struct priority_options_st * o;
1256 /* to add a new option modify
1257 * priority_options.gperf */
1258 o = in_word_set(&broken_list[i][1], strlen(&broken_list[i][1]));
1262 o->func(*priority_cache);
1271 if (err_pos != NULL && i < broken_list_size) {
1272 *err_pos = priorities;
1273 for (j = 0; j < i; j++) {
1274 (*err_pos) += strlen(broken_list[j]) + 1;
1278 gnutls_free(*priority_cache);
1279 *priority_cache = NULL;
1281 return GNUTLS_E_INVALID_REQUEST;
1286 * gnutls_priority_deinit:
1287 * @priority_cache: is a #gnutls_prioritity_t structure.
1289 * Deinitializes the priority cache.
1291 void gnutls_priority_deinit(gnutls_priority_t priority_cache)
1293 gnutls_free(priority_cache);
1298 * gnutls_priority_set_direct:
1299 * @session: is a #gnutls_session_t structure.
1300 * @priorities: is a string describing priorities
1301 * @err_pos: In case of an error this will have the position in the string the error occured
1303 * Sets the priorities to use on the ciphers, key exchange methods,
1304 * macs and compression methods. This function avoids keeping a
1305 * priority cache and is used to directly set string priorities to a
1306 * TLS session. For documentation check the gnutls_priority_init().
1308 * To simply use a reasonable default, consider using gnutls_set_default_priority().
1310 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
1311 * %GNUTLS_E_SUCCESS on success, or an error code.
1314 gnutls_priority_set_direct(gnutls_session_t session,
1315 const char *priorities, const char **err_pos)
1317 gnutls_priority_t prio;
1320 ret = gnutls_priority_init(&prio, priorities, err_pos);
1326 ret = gnutls_priority_set(session, prio);
1332 gnutls_priority_deinit(prio);
1337 /* Breaks a list of "xxx", "yyy", to a character array, of
1338 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
1341 break_list(char *list,
1342 char *broken_list[MAX_ELEMENTS], int *size)
1349 broken_list[*size] = p;
1356 p++; /* move to next entry and skip white
1363 while (p != NULL && *size < MAX_ELEMENTS);
1367 * gnutls_set_default_priority:
1368 * @session: is a #gnutls_session_t structure.
1370 * Sets some default priority on the ciphers, key exchange methods,
1371 * macs and compression methods.
1373 * This typically sets a default priority that is considered
1374 * sufficiently secure to establish encrypted sessions.
1376 * This function is kept around for backwards compatibility, but
1377 * because of its wide use it is still fully supported. If you wish
1378 * to allow users to provide a string that specify which ciphers to
1379 * use (which is recommended), you should use
1380 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
1382 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1384 int gnutls_set_default_priority(gnutls_session_t session)
1386 return gnutls_priority_set_direct(session, NULL, NULL);
1390 * gnutls_priority_ecc_curve_list:
1391 * @pcache: is a #gnutls_prioritity_t structure.
1392 * @list: will point to an integer list
1394 * Get a list of available elliptic curves in the priority
1397 * Returns: the number of curves, or an error code.
1401 gnutls_priority_ecc_curve_list(gnutls_priority_t pcache,
1402 const unsigned int **list)
1404 if (pcache->supported_ecc.algorithms == 0)
1407 *list = pcache->supported_ecc.priority;
1408 return pcache->supported_ecc.algorithms;
1412 * gnutls_priority_kx_list:
1413 * @pcache: is a #gnutls_prioritity_t structure.
1414 * @list: will point to an integer list
1416 * Get a list of available key exchange methods in the priority
1419 * Returns: the number of curves, or an error code.
1423 gnutls_priority_kx_list(gnutls_priority_t pcache,
1424 const unsigned int **list)
1426 if (pcache->kx.algorithms == 0)
1429 *list = pcache->kx.priority;
1430 return pcache->kx.algorithms;
1434 * gnutls_priority_cipher_list:
1435 * @pcache: is a #gnutls_prioritity_t structure.
1436 * @list: will point to an integer list
1438 * Get a list of available ciphers in the priority
1441 * Returns: the number of curves, or an error code.
1445 gnutls_priority_cipher_list(gnutls_priority_t pcache,
1446 const unsigned int **list)
1448 if (pcache->cipher.algorithms == 0)
1451 *list = pcache->cipher.priority;
1452 return pcache->cipher.algorithms;
1456 * gnutls_priority_mac_list:
1457 * @pcache: is a #gnutls_prioritity_t structure.
1458 * @list: will point to an integer list
1460 * Get a list of available MAC algorithms in the priority
1463 * Returns: the number of curves, or an error code.
1467 gnutls_priority_mac_list(gnutls_priority_t pcache,
1468 const unsigned int **list)
1470 if (pcache->mac.algorithms == 0)
1473 *list = pcache->mac.priority;
1474 return pcache->mac.algorithms;
1478 * gnutls_priority_compression_list:
1479 * @pcache: is a #gnutls_prioritity_t structure.
1480 * @list: will point to an integer list
1482 * Get a list of available compression method in the priority
1485 * Returns: the number of methods, or an error code.
1489 gnutls_priority_compression_list(gnutls_priority_t pcache,
1490 const unsigned int **list)
1492 if (pcache->compression.algorithms == 0)
1495 *list = pcache->compression.priority;
1496 return pcache->compression.algorithms;
1500 * gnutls_priority_protocol_list:
1501 * @pcache: is a #gnutls_prioritity_t structure.
1502 * @list: will point to an integer list
1504 * Get a list of available TLS version numbers in the priority
1507 * Returns: the number of protocols, or an error code.
1511 gnutls_priority_protocol_list(gnutls_priority_t pcache,
1512 const unsigned int **list)
1514 if (pcache->protocol.algorithms == 0)
1517 *list = pcache->protocol.priority;
1518 return pcache->protocol.algorithms;
1522 * gnutls_priority_sign_list:
1523 * @pcache: is a #gnutls_prioritity_t structure.
1524 * @list: will point to an integer list
1526 * Get a list of available signature algorithms in the priority
1529 * Returns: the number of algorithms, or an error code.
1533 gnutls_priority_sign_list(gnutls_priority_t pcache,
1534 const unsigned int **list)
1536 if (pcache->sign_algo.algorithms == 0)
1539 *list = pcache->sign_algo.priority;
1540 return pcache->sign_algo.algorithms;
1544 * gnutls_priority_certificate_type_list:
1545 * @pcache: is a #gnutls_prioritity_t structure.
1546 * @list: will point to an integer list
1548 * Get a list of available certificate types in the priority
1551 * Returns: the number of certificate types, or an error code.
1555 gnutls_priority_certificate_type_list(gnutls_priority_t pcache,
1556 const unsigned int **list)
1558 if (pcache->cert_type.algorithms == 0)
1561 *list = pcache->cert_type.priority;
1562 return pcache->cert_type.algorithms;
1566 * gnutls_priority_string_list:
1567 * @iter: an integer counter starting from zero
1568 * @flags: one of %GNUTLS_PRIORITY_LIST_INIT_KEYWORDS, %GNUTLS_PRIORITY_LIST_SPECIAL
1570 * Can be used to iterate all available priority strings.
1571 * Due to internal implementation details, there are cases where this
1572 * function can return the empty string. In that case that string should be ignored.
1573 * When no strings are available it returns %NULL.
1575 * Returns: a priority string
1579 gnutls_priority_string_list(unsigned iter, unsigned int flags)
1581 if (flags & GNUTLS_PRIORITY_LIST_INIT_KEYWORDS) {
1582 if (iter >= (sizeof(pgroups)/sizeof(pgroups[0]))-1)
1584 return pgroups[iter].name;
1585 } else if (flags & GNUTLS_PRIORITY_LIST_SPECIAL) {
1586 if (iter >= (sizeof(wordlist)/sizeof(wordlist[0]))-1)
1588 return wordlist[iter].name;