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 3 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>
32 break_comma_list (char *etag
,
33 char **broken_etag
, int *elements
, int max_elements
,
37 * gnutls_cipher_set_priority:
38 * @session: is a #gnutls_session_t structure.
39 * @list: is a 0 terminated list of gnutls_cipher_algorithm_t elements.
41 * Sets the priority on the ciphers supported by gnutls. Priority is
42 * higher for elements specified before others. After specifying the
43 * ciphers you want, you must append a 0. Note that the priority is
44 * set on the client. The server does not use the algorithm's
45 * priority except for disabling algorithms that were not specified.
47 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
50 gnutls_cipher_set_priority (gnutls_session_t session
, const int *list
)
54 while (list
[num
] != 0)
58 session
->internals
.priorities
.cipher
.algorithms
= num
;
60 for (i
= 0; i
< num
; i
++)
62 session
->internals
.priorities
.cipher
.priority
[i
] = list
[i
];
68 typedef void (bulk_rmadd_func
) (priority_st
* priority_list
, const int *);
71 _set_priority (priority_st
* st
, const int *list
)
75 while (list
[num
] != 0)
81 for (i
= 0; i
< num
; i
++)
83 st
->priority
[i
] = list
[i
];
90 _add_priority (priority_st
* st
, const int *list
)
92 int num
= 0, i
, j
, init
;
94 init
= i
= st
->algorithms
;
96 while (list
[num
] != 0)
105 if (st
->priority
[j
] == (unsigned)list
[num
])
112 st
->priority
[i
++] = list
[num
];
121 _clear_priorities (priority_st
* st
, const int *list
)
123 memset(st
, 0, sizeof(*st
));
127 * gnutls_kx_set_priority:
128 * @session: is a #gnutls_session_t structure.
129 * @list: is a 0 terminated list of gnutls_kx_algorithm_t elements.
131 * Sets the priority on the key exchange algorithms supported by
132 * gnutls. Priority is higher for elements specified before others.
133 * After specifying the algorithms you want, you must append a 0.
134 * Note that the priority is set on the client. The server does not
135 * use the algorithm's priority except for disabling algorithms that
136 * were not specified.
138 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
141 gnutls_kx_set_priority (gnutls_session_t session
, const int *list
)
143 _set_priority (&session
->internals
.priorities
.kx
, list
);
148 * gnutls_mac_set_priority:
149 * @session: is a #gnutls_session_t structure.
150 * @list: is a 0 terminated list of gnutls_mac_algorithm_t elements.
152 * Sets the priority on the mac algorithms supported by gnutls.
153 * Priority is higher for elements specified before others. After
154 * specifying the algorithms you want, you must append a 0. Note
155 * that the priority is set on the client. The server does not use
156 * the algorithm's priority except for disabling algorithms that were
159 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
162 gnutls_mac_set_priority (gnutls_session_t session
, const int *list
)
164 _set_priority (&session
->internals
.priorities
.mac
, list
);
169 * gnutls_compression_set_priority:
170 * @session: is a #gnutls_session_t structure.
171 * @list: is a 0 terminated list of gnutls_compression_method_t elements.
173 * Sets the priority on the compression algorithms supported by
174 * gnutls. Priority is higher for elements specified before others.
175 * After specifying the algorithms you want, you must append a 0.
176 * Note that the priority is set on the client. The server does not
177 * use the algorithm's priority except for disabling algorithms that
178 * were not specified.
180 * TLS 1.0 does not define any compression algorithms except
181 * NULL. Other compression algorithms are to be considered as gnutls
184 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
187 gnutls_compression_set_priority (gnutls_session_t session
, const int *list
)
189 _set_priority (&session
->internals
.priorities
.compression
, list
);
194 * gnutls_protocol_set_priority:
195 * @session: is a #gnutls_session_t structure.
196 * @list: is a 0 terminated list of gnutls_protocol_t elements.
198 * Sets the priority on the protocol versions supported by gnutls.
199 * This function actually enables or disables protocols. Newer protocol
200 * versions always have highest priority.
202 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
205 gnutls_protocol_set_priority (gnutls_session_t session
, const int *list
)
207 _set_priority (&session
->internals
.priorities
.protocol
, list
);
209 /* set the current version to the first in the chain.
210 * This will be overridden later.
213 _gnutls_set_current_version (session
, list
[0]);
219 * gnutls_certificate_type_set_priority:
220 * @session: is a #gnutls_session_t structure.
221 * @list: is a 0 terminated list of gnutls_certificate_type_t elements.
223 * Sets the priority on the certificate types supported by gnutls.
224 * Priority is higher for elements specified before others.
225 * After specifying the types you want, you must append a 0.
226 * Note that the certificate type priority is set on the client.
227 * The server does not use the cert type priority except for disabling
228 * types that were not specified.
230 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
233 gnutls_certificate_type_set_priority (gnutls_session_t session
,
236 #ifdef ENABLE_OPENPGP
237 _set_priority (&session
->internals
.priorities
.cert_type
, list
);
241 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
246 static const int supported_ecc_normal
[] = {
247 GNUTLS_ECC_CURVE_SECP192R1
,
248 GNUTLS_ECC_CURVE_SECP224R1
,
249 GNUTLS_ECC_CURVE_SECP256R1
,
250 GNUTLS_ECC_CURVE_SECP384R1
,
251 GNUTLS_ECC_CURVE_SECP521R1
,
255 static const int supported_ecc_secure128
[] = {
256 GNUTLS_ECC_CURVE_SECP256R1
,
257 GNUTLS_ECC_CURVE_SECP384R1
,
258 GNUTLS_ECC_CURVE_SECP521R1
,
262 static const int supported_ecc_suiteb128
[] = {
263 GNUTLS_ECC_CURVE_SECP256R1
,
264 GNUTLS_ECC_CURVE_SECP384R1
,
268 static const int supported_ecc_suiteb192
[] = {
269 GNUTLS_ECC_CURVE_SECP384R1
,
273 static const int supported_ecc_secure192
[] = {
274 GNUTLS_ECC_CURVE_SECP384R1
,
275 GNUTLS_ECC_CURVE_SECP521R1
,
279 static const int protocol_priority
[] = {
288 static const int protocol_priority_suiteb
[] = {
293 static const int kx_priority_performance
[] = {
295 GNUTLS_KX_ECDHE_ECDSA
,
302 static const int kx_priority_suiteb
[] = {
303 GNUTLS_KX_ECDHE_ECDSA
,
307 static const int kx_priority_export
[] = {
309 GNUTLS_KX_ECDHE_ECDSA
,
313 GNUTLS_KX_RSA_EXPORT
,
317 static const int kx_priority_secure
[] = {
318 /* The ciphersuites that offer forward secrecy take
321 GNUTLS_KX_ECDHE_ECDSA
,
326 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
327 * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
332 static const int cipher_priority_performance_sw
[] = {
333 GNUTLS_CIPHER_ARCFOUR_128
,
334 GNUTLS_CIPHER_AES_128_CBC
,
335 GNUTLS_CIPHER_CAMELLIA_128_CBC
,
336 GNUTLS_CIPHER_AES_256_CBC
,
337 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
338 GNUTLS_CIPHER_3DES_CBC
,
339 GNUTLS_CIPHER_AES_128_GCM
,
340 GNUTLS_CIPHER_AES_256_GCM
,
344 /* If GCM and AES acceleration is available then prefer
345 * them over anything else.
347 static const int cipher_priority_performance_hw_aes
[] = {
348 GNUTLS_CIPHER_AES_128_GCM
,
349 GNUTLS_CIPHER_AES_128_CBC
,
350 GNUTLS_CIPHER_AES_256_GCM
,
351 GNUTLS_CIPHER_AES_256_CBC
,
352 GNUTLS_CIPHER_ARCFOUR_128
,
353 GNUTLS_CIPHER_CAMELLIA_128_CBC
,
354 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
355 GNUTLS_CIPHER_3DES_CBC
,
359 static const int cipher_priority_normal_sw
[] = {
360 GNUTLS_CIPHER_AES_128_CBC
,
361 GNUTLS_CIPHER_CAMELLIA_128_CBC
,
362 GNUTLS_CIPHER_AES_128_GCM
,
363 GNUTLS_CIPHER_AES_256_CBC
,
364 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
365 GNUTLS_CIPHER_AES_256_GCM
,
366 GNUTLS_CIPHER_3DES_CBC
,
367 GNUTLS_CIPHER_ARCFOUR_128
,
371 static const int cipher_priority_normal_hw_aes
[] = {
372 GNUTLS_CIPHER_AES_128_GCM
,
373 GNUTLS_CIPHER_AES_128_CBC
,
374 GNUTLS_CIPHER_AES_256_GCM
,
375 GNUTLS_CIPHER_AES_256_CBC
,
376 GNUTLS_CIPHER_CAMELLIA_128_CBC
,
377 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
378 GNUTLS_CIPHER_3DES_CBC
,
379 GNUTLS_CIPHER_ARCFOUR_128
,
383 static const int *cipher_priority_performance
= cipher_priority_performance_sw
;
384 static const int *cipher_priority_normal
= cipher_priority_normal_sw
;
387 static const int cipher_priority_suiteb128
[] = {
388 GNUTLS_CIPHER_AES_128_GCM
,
389 GNUTLS_CIPHER_AES_256_GCM
,
393 static const int cipher_priority_suiteb192
[] = {
394 GNUTLS_CIPHER_AES_256_GCM
,
399 static const int cipher_priority_secure128
[] = {
400 GNUTLS_CIPHER_AES_128_CBC
,
401 GNUTLS_CIPHER_CAMELLIA_128_CBC
,
402 GNUTLS_CIPHER_AES_128_GCM
,
403 GNUTLS_CIPHER_AES_256_CBC
,
404 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
405 GNUTLS_CIPHER_AES_256_GCM
,
410 static const int cipher_priority_secure192
[] = {
411 GNUTLS_CIPHER_AES_256_CBC
,
412 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
413 GNUTLS_CIPHER_AES_256_GCM
,
417 /* The same as cipher_priority_security_normal + arcfour-40. */
418 static const int cipher_priority_export
[] = {
419 GNUTLS_CIPHER_AES_128_CBC
,
420 GNUTLS_CIPHER_AES_256_CBC
,
421 GNUTLS_CIPHER_CAMELLIA_128_CBC
,
422 GNUTLS_CIPHER_CAMELLIA_256_CBC
,
423 GNUTLS_CIPHER_AES_128_GCM
,
424 GNUTLS_CIPHER_3DES_CBC
,
425 GNUTLS_CIPHER_ARCFOUR_128
,
426 GNUTLS_CIPHER_ARCFOUR_40
,
430 static const int comp_priority
[] = {
431 /* compression should be explicitly requested to be enabled */
436 static const int sign_priority_default
[] = {
437 GNUTLS_SIGN_RSA_SHA256
,
438 GNUTLS_SIGN_DSA_SHA256
,
439 GNUTLS_SIGN_ECDSA_SHA256
,
441 GNUTLS_SIGN_RSA_SHA384
,
442 GNUTLS_SIGN_ECDSA_SHA384
,
444 GNUTLS_SIGN_RSA_SHA512
,
445 GNUTLS_SIGN_ECDSA_SHA512
,
447 GNUTLS_SIGN_RSA_SHA224
,
448 GNUTLS_SIGN_DSA_SHA224
,
449 GNUTLS_SIGN_ECDSA_SHA224
,
451 GNUTLS_SIGN_RSA_SHA1
,
452 GNUTLS_SIGN_DSA_SHA1
,
453 GNUTLS_SIGN_ECDSA_SHA1
,
457 static const int sign_priority_suiteb128
[] = {
458 GNUTLS_SIGN_ECDSA_SHA256
,
459 GNUTLS_SIGN_ECDSA_SHA384
,
463 static const int sign_priority_suiteb192
[] = {
464 GNUTLS_SIGN_ECDSA_SHA384
,
468 static const int sign_priority_secure128
[] = {
469 GNUTLS_SIGN_RSA_SHA256
,
470 GNUTLS_SIGN_DSA_SHA256
,
471 GNUTLS_SIGN_ECDSA_SHA256
,
472 GNUTLS_SIGN_RSA_SHA384
,
473 GNUTLS_SIGN_ECDSA_SHA384
,
474 GNUTLS_SIGN_RSA_SHA512
,
475 GNUTLS_SIGN_ECDSA_SHA512
,
479 static const int sign_priority_secure192
[] = {
480 GNUTLS_SIGN_RSA_SHA384
,
481 GNUTLS_SIGN_ECDSA_SHA384
,
482 GNUTLS_SIGN_RSA_SHA512
,
483 GNUTLS_SIGN_ECDSA_SHA512
,
487 static const int mac_priority_normal
[] = {
496 static const int mac_priority_suiteb128
[] = {
501 static const int mac_priority_suiteb192
[] = {
506 static const int mac_priority_secure128
[] = {
514 static const int mac_priority_secure192
[] = {
521 static const int cert_type_priority_default
[] = {
526 static const int cert_type_priority_all
[] = {
532 typedef void (rmadd_func
) (priority_st
* priority_list
, unsigned int alg
);
535 prio_remove (priority_st
* priority_list
, unsigned int algo
)
538 int pos
= -1; /* the position of the cipher to remove */
540 while (priority_list
->priority
[i
] != 0)
542 if (priority_list
->priority
[i
] == algo
)
549 priority_list
->priority
[pos
] = priority_list
->priority
[i
- 1];
550 priority_list
->priority
[i
- 1] = 0;
551 priority_list
->algorithms
--;
558 prio_add (priority_st
* priority_list
, unsigned int algo
)
561 while (priority_list
->priority
[i
] != 0)
563 if (algo
== priority_list
->priority
[i
])
564 return; /* if it exists */
570 priority_list
->priority
[i
] = algo
;
571 priority_list
->algorithms
++;
579 * gnutls_priority_set:
580 * @session: is a #gnutls_session_t structure.
581 * @priority: is a #gnutls_priority_t structure.
583 * Sets the priorities to use on the ciphers, key exchange methods,
584 * macs and compression methods.
586 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
589 gnutls_priority_set (gnutls_session_t session
, gnutls_priority_t priority
)
591 if (priority
== NULL
)
594 return GNUTLS_E_NO_CIPHER_SUITES
;
597 memcpy (&session
->internals
.priorities
, priority
,
598 sizeof (struct gnutls_priority_st
));
600 /* set the current version to the first in the chain.
601 * This will be overridden later.
603 if (session
->internals
.priorities
.protocol
.algorithms
> 0)
604 _gnutls_set_current_version (session
,
605 session
->internals
.priorities
.protocol
.
608 if (session
->internals
.priorities
.protocol
.algorithms
== 0 ||
609 session
->internals
.priorities
.cipher
.algorithms
== 0 ||
610 session
->internals
.priorities
.mac
.algorithms
== 0 ||
611 session
->internals
.priorities
.kx
.algorithms
== 0 ||
612 session
->internals
.priorities
.compression
.algorithms
== 0)
613 return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET
);
619 #define MAX_ELEMENTS 48
621 #define LEVEL_NONE "NONE"
622 #define LEVEL_NORMAL "NORMAL"
623 #define LEVEL_PERFORMANCE "PERFORMANCE"
624 #define LEVEL_SECURE128 "SECURE128"
625 #define LEVEL_SECURE192 "SECURE192"
626 #define LEVEL_SECURE256 "SECURE256"
627 #define LEVEL_SUITEB128 "SUITEB128"
628 #define LEVEL_SUITEB192 "SUITEB192"
629 #define LEVEL_EXPORT "EXPORT"
632 int check_level(const char* level
, gnutls_priority_t priority_cache
, int add
)
634 bulk_rmadd_func
*func
;
636 if (add
) func
= _add_priority
;
637 else func
= _set_priority
;
639 if (strcasecmp (level
, LEVEL_PERFORMANCE
) == 0)
641 func (&priority_cache
->cipher
,
642 cipher_priority_performance
);
643 func (&priority_cache
->kx
, kx_priority_performance
);
644 func (&priority_cache
->mac
, mac_priority_normal
);
645 func (&priority_cache
->sign_algo
,
646 sign_priority_default
);
647 func (&priority_cache
->supported_ecc
, supported_ecc_normal
);
650 else if (strcasecmp (level
, LEVEL_NORMAL
) == 0)
652 func (&priority_cache
->cipher
, cipher_priority_normal
);
653 func (&priority_cache
->kx
, kx_priority_secure
);
654 func (&priority_cache
->mac
, mac_priority_normal
);
655 func (&priority_cache
->sign_algo
,
656 sign_priority_default
);
657 func (&priority_cache
->supported_ecc
, supported_ecc_normal
);
660 else if (strcasecmp (level
, LEVEL_SECURE256
) == 0
661 || strcasecmp (level
, LEVEL_SECURE192
) == 0)
663 func (&priority_cache
->cipher
,
664 cipher_priority_secure192
);
665 func (&priority_cache
->kx
, kx_priority_secure
);
666 func (&priority_cache
->mac
, mac_priority_secure192
);
667 func (&priority_cache
->sign_algo
,
668 sign_priority_secure192
);
669 func (&priority_cache
->supported_ecc
, supported_ecc_secure192
);
672 else if (strcasecmp (level
, LEVEL_SECURE128
) == 0
673 || strcasecmp (level
, "SECURE") == 0)
675 func (&priority_cache
->cipher
,
676 cipher_priority_secure128
);
677 func (&priority_cache
->kx
, kx_priority_secure
);
678 func (&priority_cache
->mac
, mac_priority_secure128
);
679 func (&priority_cache
->sign_algo
,
680 sign_priority_secure128
);
681 func (&priority_cache
->supported_ecc
, supported_ecc_secure128
);
684 else if (strcasecmp (level
, LEVEL_SUITEB128
) == 0)
686 func (&priority_cache
->protocol
, protocol_priority_suiteb
);
687 func (&priority_cache
->cipher
,
688 cipher_priority_suiteb128
);
689 func (&priority_cache
->kx
, kx_priority_suiteb
);
690 func (&priority_cache
->mac
, mac_priority_suiteb128
);
691 func (&priority_cache
->sign_algo
,
692 sign_priority_suiteb128
);
693 func (&priority_cache
->supported_ecc
, supported_ecc_suiteb128
);
696 else if (strcasecmp (level
, LEVEL_SUITEB192
) == 0)
698 func (&priority_cache
->protocol
, protocol_priority_suiteb
);
699 func (&priority_cache
->cipher
,
700 cipher_priority_suiteb192
);
701 func (&priority_cache
->kx
, kx_priority_suiteb
);
702 func (&priority_cache
->mac
, mac_priority_suiteb192
);
703 func (&priority_cache
->sign_algo
,
704 sign_priority_suiteb192
);
705 func (&priority_cache
->supported_ecc
, supported_ecc_suiteb192
);
708 else if (strcasecmp (level
, LEVEL_EXPORT
) == 0)
710 func (&priority_cache
->cipher
, cipher_priority_export
);
711 func (&priority_cache
->kx
, kx_priority_export
);
712 func (&priority_cache
->mac
, mac_priority_secure128
);
713 func (&priority_cache
->sign_algo
,
714 sign_priority_default
);
715 func (&priority_cache
->supported_ecc
, supported_ecc_normal
);
722 * gnutls_priority_init:
723 * @priority_cache: is a #gnutls_prioritity_t structure.
724 * @priorities: is a string describing priorities
725 * @err_pos: In case of an error this will have the position in the string the error occured
727 * Sets priorities for the ciphers, key exchange methods, macs and
728 * compression methods.
730 * The #priorities option allows you to specify a colon
731 * separated list of the cipher priorities to enable.
732 * Some keywords are defined to provide quick access
733 * to common preferences.
735 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
736 * limited to 128 bit ciphers and sorted by terms of speed
739 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
740 * included as a fallback only. The ciphers are sorted by security
743 * "SECURE128" means all "secure" ciphersuites of security level 128-bit
746 * "SECURE192" means all "secure" ciphersuites of security level 192-bit
749 * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
752 * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
755 * "EXPORT" means all ciphersuites are enabled, including the
756 * low-security 40 bit ciphers.
758 * "NONE" means nothing is enabled. This disables even protocols and
759 * compression methods.
761 * Special keywords are "!", "-" and "+".
762 * "!" or "-" appended with an algorithm will remove this algorithm.
763 * "+" appended with an algorithm will add this algorithm.
765 * Check the GnuTLS manual section "Priority strings" for detailed
770 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
772 * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128.
774 * "SECURE:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
775 * enabled, SSL3.0 is disabled, and libz compression enabled.
777 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1",
779 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1",
781 * "SECURE256:+SECURE128",
783 * Note that "NORMAL:%COMPAT" is the most compatible mode.
785 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
786 * %GNUTLS_E_SUCCESS on success, or an error code.
789 gnutls_priority_init (gnutls_priority_t
* priority_cache
,
790 const char *priorities
, const char **err_pos
)
792 char *broken_list
[MAX_ELEMENTS
];
793 int broken_list_size
= 0, i
= 0, j
;
797 bulk_rmadd_func
*bulk_fn
;
799 *priority_cache
= gnutls_calloc (1, sizeof (struct gnutls_priority_st
));
800 if (*priority_cache
== NULL
)
803 return GNUTLS_E_MEMORY_ERROR
;
806 /* for now unsafe renegotiation is default on everyone. To be removed
807 * when we make it the default.
809 (*priority_cache
)->sr
= SR_PARTIAL
;
810 (*priority_cache
)->ssl3_record_version
= 1;
812 if (priorities
== NULL
)
813 priorities
= LEVEL_NORMAL
;
815 darg
= gnutls_strdup (priorities
);
822 break_comma_list (darg
, broken_list
, &broken_list_size
, MAX_ELEMENTS
, ':');
823 /* This is our default set of protocol version, certificate types and
824 * compression methods.
826 if (strcasecmp (broken_list
[0], LEVEL_NONE
) != 0)
828 _set_priority (&(*priority_cache
)->protocol
, protocol_priority
);
829 _set_priority (&(*priority_cache
)->compression
, comp_priority
);
830 _set_priority (&(*priority_cache
)->cert_type
, cert_type_priority_default
);
831 _set_priority (&(*priority_cache
)->sign_algo
, sign_priority_default
);
832 _set_priority (&(*priority_cache
)->supported_ecc
, supported_ecc_normal
);
840 for (; i
< broken_list_size
; i
++)
842 if (check_level(broken_list
[i
], *priority_cache
, 0) != 0)
846 else if (broken_list
[i
][0] == '!' || broken_list
[i
][0] == '+'
847 || broken_list
[i
][0] == '-')
849 if (broken_list
[i
][0] == '+')
852 bulk_fn
= _set_priority
;
857 bulk_fn
= _clear_priorities
;
860 if (broken_list
[i
][0] == '+' && check_level(&broken_list
[i
][1], *priority_cache
, 1) != 0)
865 gnutls_mac_get_id (&broken_list
[i
][1])) != GNUTLS_MAC_UNKNOWN
)
866 fn (&(*priority_cache
)->mac
, algo
);
867 else if ((algo
= gnutls_cipher_get_id (&broken_list
[i
][1])) !=
868 GNUTLS_CIPHER_UNKNOWN
)
869 fn (&(*priority_cache
)->cipher
, algo
);
870 else if ((algo
= gnutls_kx_get_id (&broken_list
[i
][1])) !=
872 fn (&(*priority_cache
)->kx
, algo
);
873 else if (strncasecmp (&broken_list
[i
][1], "VERS-", 5) == 0)
875 if (strncasecmp (&broken_list
[i
][1], "VERS-TLS-ALL", 12) == 0)
877 bulk_fn (&(*priority_cache
)->protocol
,
883 gnutls_protocol_get_id (&broken_list
[i
][6])) !=
884 GNUTLS_VERSION_UNKNOWN
)
885 fn (&(*priority_cache
)->protocol
, algo
);
890 } /* now check if the element is something like -ALGO */
891 else if (strncasecmp (&broken_list
[i
][1], "COMP-", 5) == 0)
893 if (strncasecmp (&broken_list
[i
][1], "COMP-ALL", 8) == 0)
895 bulk_fn (&(*priority_cache
)->compression
,
901 gnutls_compression_get_id (&broken_list
[i
][6])) !=
903 fn (&(*priority_cache
)->compression
, algo
);
907 } /* now check if the element is something like -ALGO */
908 else if (strncasecmp (&broken_list
[i
][1], "CURVE-", 6) == 0)
910 if (strncasecmp (&broken_list
[i
][1], "CURVE-ALL", 9) == 0)
912 bulk_fn (&(*priority_cache
)->supported_ecc
,
913 supported_ecc_normal
);
918 _gnutls_ecc_curve_get_id (&broken_list
[i
][7])) !=
919 GNUTLS_ECC_CURVE_INVALID
)
920 fn (&(*priority_cache
)->supported_ecc
, algo
);
924 } /* now check if the element is something like -ALGO */
925 else if (strncasecmp (&broken_list
[i
][1], "CTYPE-", 6) == 0)
927 if (strncasecmp (&broken_list
[i
][1], "CTYPE-ALL", 9) == 0)
929 bulk_fn (&(*priority_cache
)->cert_type
,
930 cert_type_priority_all
);
935 gnutls_certificate_type_get_id (&broken_list
[i
][7])) !=
937 fn (&(*priority_cache
)->cert_type
, algo
);
941 } /* now check if the element is something like -ALGO */
942 else if (strncasecmp (&broken_list
[i
][1], "SIGN-", 5) == 0)
944 if (strncasecmp (&broken_list
[i
][1], "SIGN-ALL", 8) == 0)
946 bulk_fn (&(*priority_cache
)->sign_algo
,
947 sign_priority_default
);
952 gnutls_sign_get_id (&broken_list
[i
][6])) !=
954 fn (&(*priority_cache
)->sign_algo
, algo
);
959 else if (strncasecmp (&broken_list
[i
][1], "MAC-ALL", 7) == 0)
961 bulk_fn (&(*priority_cache
)->mac
,
962 mac_priority_normal
);
964 else if (strncasecmp (&broken_list
[i
][1], "CIPHER-ALL", 10) == 0)
966 bulk_fn (&(*priority_cache
)->cipher
,
967 cipher_priority_normal
);
969 else if (strncasecmp (&broken_list
[i
][1], "KX-ALL", 6) == 0)
971 bulk_fn (&(*priority_cache
)->kx
,
977 else if (broken_list
[i
][0] == '%')
979 if (strcasecmp (&broken_list
[i
][1], "COMPAT") == 0)
981 ENABLE_COMPAT((*priority_cache
));
983 else if (strcasecmp (&broken_list
[i
][1], "NO_EXTENSIONS") == 0)
985 (*priority_cache
)->no_extensions
= 1;
987 else if (strcasecmp (&broken_list
[i
][1], "STATELESS_COMPRESSION") == 0)
989 (*priority_cache
)->stateless_compression
= 1;
991 else if (strcasecmp (&broken_list
[i
][1],
992 "VERIFY_ALLOW_SIGN_RSA_MD5") == 0)
994 prio_add (&(*priority_cache
)->sign_algo
, GNUTLS_SIGN_RSA_MD5
);
995 (*priority_cache
)->additional_verify_flags
|=
996 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5
;
998 else if (strcasecmp (&broken_list
[i
][1],
999 "VERIFY_DISABLE_CRL_CHECKS") == 0)
1001 (*priority_cache
)->additional_verify_flags
|=
1002 GNUTLS_VERIFY_DISABLE_CRL_CHECKS
;
1004 else if (strcasecmp (&broken_list
[i
][1],
1005 "SSL3_RECORD_VERSION") == 0)
1006 (*priority_cache
)->ssl3_record_version
= 1;
1007 else if (strcasecmp (&broken_list
[i
][1],
1008 "LATEST_RECORD_VERSION") == 0)
1009 (*priority_cache
)->ssl3_record_version
= 0;
1010 else if (strcasecmp (&broken_list
[i
][1],
1011 "VERIFY_ALLOW_X509_V1_CA_CRT") == 0)
1012 (*priority_cache
)->additional_verify_flags
|=
1013 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
;
1014 else if (strcasecmp (&broken_list
[i
][1],
1015 "UNSAFE_RENEGOTIATION") == 0)
1017 (*priority_cache
)->sr
= SR_UNSAFE
;
1019 else if (strcasecmp (&broken_list
[i
][1], "SAFE_RENEGOTIATION") == 0)
1021 (*priority_cache
)->sr
= SR_SAFE
;
1023 else if (strcasecmp (&broken_list
[i
][1],
1024 "PARTIAL_RENEGOTIATION") == 0)
1026 (*priority_cache
)->sr
= SR_PARTIAL
;
1028 else if (strcasecmp (&broken_list
[i
][1],
1029 "DISABLE_SAFE_RENEGOTIATION") == 0)
1031 (*priority_cache
)->sr
= SR_DISABLED
;
1033 else if (strcasecmp (&broken_list
[i
][1],
1034 "SERVER_PRECEDENCE") == 0)
1036 (*priority_cache
)->server_precedence
= 1;
1049 if (err_pos
!= NULL
&& i
< broken_list_size
)
1051 *err_pos
= priorities
;
1052 for (j
= 0; j
< i
; j
++)
1054 (*err_pos
) += strlen (broken_list
[j
]) + 1;
1058 gnutls_free (*priority_cache
);
1060 return GNUTLS_E_INVALID_REQUEST
;
1065 * gnutls_priority_deinit:
1066 * @priority_cache: is a #gnutls_prioritity_t structure.
1068 * Deinitializes the priority cache.
1071 gnutls_priority_deinit (gnutls_priority_t priority_cache
)
1073 gnutls_free (priority_cache
);
1078 * gnutls_priority_set_direct:
1079 * @session: is a #gnutls_session_t structure.
1080 * @priorities: is a string describing priorities
1081 * @err_pos: In case of an error this will have the position in the string the error occured
1083 * Sets the priorities to use on the ciphers, key exchange methods,
1084 * macs and compression methods. This function avoids keeping a
1085 * priority cache and is used to directly set string priorities to a
1086 * TLS session. For documentation check the gnutls_priority_init().
1088 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
1089 * %GNUTLS_E_SUCCESS on success, or an error code.
1092 gnutls_priority_set_direct (gnutls_session_t session
,
1093 const char *priorities
, const char **err_pos
)
1095 gnutls_priority_t prio
;
1098 ret
= gnutls_priority_init (&prio
, priorities
, err_pos
);
1105 ret
= gnutls_priority_set (session
, prio
);
1112 gnutls_priority_deinit (prio
);
1117 /* Breaks a list of "xxx", "yyy", to a character array, of
1118 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
1121 break_comma_list (char *etag
,
1122 char **broken_etag
, int *elements
, int max_elements
,
1133 broken_etag
[*elements
] = p
;
1137 p
= strchr (p
, sep
);
1141 p
++; /* move to next entry and skip white
1148 while (p
!= NULL
&& *elements
< max_elements
);
1152 * gnutls_set_default_priority:
1153 * @session: is a #gnutls_session_t structure.
1155 * Sets some default priority on the ciphers, key exchange methods,
1156 * macs and compression methods.
1158 * This is the same as calling:
1160 * gnutls_priority_set_direct (session, "NORMAL", NULL);
1162 * This function is kept around for backwards compatibility, but
1163 * because of its wide use it is still fully supported. If you wish
1164 * to allow users to provide a string that specify which ciphers to
1165 * use (which is recommended), you should use
1166 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
1168 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1171 gnutls_set_default_priority (gnutls_session_t session
)
1173 return gnutls_priority_set_direct (session
, "NORMAL", NULL
);
1177 * gnutls_set_default_export_priority:
1178 * @session: is a #gnutls_session_t structure.
1180 * Sets some default priority on the ciphers, key exchange methods, macs
1181 * and compression methods. This function also includes weak algorithms.
1183 * This is the same as calling:
1185 * gnutls_priority_set_direct (session, "EXPORT", NULL);
1187 * This function is kept around for backwards compatibility, but
1188 * because of its wide use it is still fully supported. If you wish
1189 * to allow users to provide a string that specify which ciphers to
1190 * use (which is recommended), you should use
1191 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
1193 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1196 gnutls_set_default_export_priority (gnutls_session_t session
)
1198 return gnutls_priority_set_direct (session
, "EXPORT", NULL
);
1201 /* Increases the priority of AES-GCM as it is much faster
1202 * than anything else if hardware support is there.
1204 void _gnutls_priority_prefer_aes_gcm(void)
1206 cipher_priority_performance
= cipher_priority_performance_hw_aes
;
1207 cipher_priority_normal
= cipher_priority_normal_hw_aes
;
1211 * gnutls_priority_ecc_curve_list:
1212 * @pcache: is a #gnutls_prioritity_t structure.
1213 * @list: will point to an integer list
1215 * Get a list of available elliptic curves in the priority
1218 * Returns: the number of curves, or an error code.
1222 gnutls_priority_ecc_curve_list (gnutls_priority_t pcache
, const unsigned int** list
)
1224 if (pcache
->supported_ecc
.algorithms
== 0)
1227 *list
= pcache
->supported_ecc
.priority
;
1228 return pcache
->supported_ecc
.algorithms
;
1232 * gnutls_priority_compression_list:
1233 * @pcache: is a #gnutls_prioritity_t structure.
1234 * @list: will point to an integer list
1236 * Get a list of available compression method in the priority
1239 * Returns: the number of methods, or an error code.
1243 gnutls_priority_compression_list (gnutls_priority_t pcache
, const unsigned int** list
)
1245 if (pcache
->compression
.algorithms
== 0)
1248 *list
= pcache
->compression
.priority
;
1249 return pcache
->compression
.algorithms
;
1253 * gnutls_priority_protocol_list:
1254 * @pcache: is a #gnutls_prioritity_t structure.
1255 * @list: will point to an integer list
1257 * Get a list of available TLS version numbers in the priority
1260 * Returns: the number of protocols, or an error code.
1264 gnutls_priority_protocol_list (gnutls_priority_t pcache
, const unsigned int** list
)
1266 if (pcache
->protocol
.algorithms
== 0)
1269 *list
= pcache
->protocol
.priority
;
1270 return pcache
->protocol
.algorithms
;
1274 * gnutls_priority_sign_list:
1275 * @pcache: is a #gnutls_prioritity_t structure.
1276 * @list: will point to an integer list
1278 * Get a list of available signature algorithms in the priority
1281 * Returns: the number of algorithms, or an error code.
1285 gnutls_priority_sign_list (gnutls_priority_t pcache
, const unsigned int** list
)
1287 if (pcache
->sign_algo
.algorithms
== 0)
1290 *list
= pcache
->sign_algo
.priority
;
1291 return pcache
->sign_algo
.algorithms
;
1295 * gnutls_priority_certificate_type_list:
1296 * @pcache: is a #gnutls_prioritity_t structure.
1297 * @list: will point to an integer list
1299 * Get a list of available certificate types in the priority
1302 * Returns: the number of certificate types, or an error code.
1306 gnutls_priority_certificate_type_list (gnutls_priority_t pcache
, const unsigned int** list
)
1308 if (pcache
->cert_type
.algorithms
== 0)
1311 *list
= pcache
->cert_type
.priority
;
1312 return pcache
->cert_type
.algorithms
;