Key usage violations are allowed when the COMPAT keyword is specified.
[gnutls.git] / lib / gnutls_priority.c
blob6008276b7387265b6e3ed3c543094de228da9fc6
1 /*
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>
31 static void
32 break_comma_list (char *etag,
33 char **broken_etag, int *elements, int max_elements,
34 char sep);
36 /**
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.
48 **/
49 int
50 gnutls_cipher_set_priority (gnutls_session_t session, const int *list)
52 int num = 0, i;
54 while (list[num] != 0)
55 num++;
56 if (num > MAX_ALGOS)
57 num = MAX_ALGOS;
58 session->internals.priorities.cipher.algorithms = num;
60 for (i = 0; i < num; i++)
62 session->internals.priorities.cipher.priority[i] = list[i];
65 return 0;
68 typedef void (bulk_rmadd_func) (priority_st * priority_list, const int *);
70 inline static void
71 _set_priority (priority_st * st, const int *list)
73 int num = 0, i;
75 while (list[num] != 0)
76 num++;
77 if (num > MAX_ALGOS)
78 num = MAX_ALGOS;
79 st->algorithms = num;
81 for (i = 0; i < num; i++)
83 st->priority[i] = list[i];
86 return;
89 static void
90 _clear_priorities (priority_st * st, const int *list)
92 memset(st, 0, sizeof(*st));
95 /**
96 * gnutls_kx_set_priority:
97 * @session: is a #gnutls_session_t structure.
98 * @list: is a 0 terminated list of gnutls_kx_algorithm_t elements.
100 * Sets the priority on the key exchange algorithms supported by
101 * gnutls. Priority is higher for elements specified before others.
102 * After specifying the algorithms you want, you must append a 0.
103 * Note that the priority is set on the client. The server does not
104 * use the algorithm's priority except for disabling algorithms that
105 * were not specified.
107 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
110 gnutls_kx_set_priority (gnutls_session_t session, const int *list)
112 _set_priority (&session->internals.priorities.kx, list);
113 return 0;
117 * gnutls_mac_set_priority:
118 * @session: is a #gnutls_session_t structure.
119 * @list: is a 0 terminated list of gnutls_mac_algorithm_t elements.
121 * Sets the priority on the mac algorithms supported by gnutls.
122 * Priority is higher for elements specified before others. After
123 * specifying the algorithms you want, you must append a 0. Note
124 * that the priority is set on the client. The server does not use
125 * the algorithm's priority except for disabling algorithms that were
126 * not specified.
128 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
131 gnutls_mac_set_priority (gnutls_session_t session, const int *list)
133 _set_priority (&session->internals.priorities.mac, list);
134 return 0;
138 * gnutls_compression_set_priority:
139 * @session: is a #gnutls_session_t structure.
140 * @list: is a 0 terminated list of gnutls_compression_method_t elements.
142 * Sets the priority on the compression algorithms supported by
143 * gnutls. Priority is higher for elements specified before others.
144 * After specifying the algorithms you want, you must append a 0.
145 * Note that the priority is set on the client. The server does not
146 * use the algorithm's priority except for disabling algorithms that
147 * were not specified.
149 * TLS 1.0 does not define any compression algorithms except
150 * NULL. Other compression algorithms are to be considered as gnutls
151 * extensions.
153 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
156 gnutls_compression_set_priority (gnutls_session_t session, const int *list)
158 _set_priority (&session->internals.priorities.compression, list);
159 return 0;
163 * gnutls_protocol_set_priority:
164 * @session: is a #gnutls_session_t structure.
165 * @list: is a 0 terminated list of gnutls_protocol_t elements.
167 * Sets the priority on the protocol versions supported by gnutls.
168 * This function actually enables or disables protocols. Newer protocol
169 * versions always have highest priority.
171 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
174 gnutls_protocol_set_priority (gnutls_session_t session, const int *list)
176 _set_priority (&session->internals.priorities.protocol, list);
178 /* set the current version to the first in the chain.
179 * This will be overridden later.
181 if (list)
182 _gnutls_set_current_version (session, list[0]);
184 return 0;
188 * gnutls_certificate_type_set_priority:
189 * @session: is a #gnutls_session_t structure.
190 * @list: is a 0 terminated list of gnutls_certificate_type_t elements.
192 * Sets the priority on the certificate types supported by gnutls.
193 * Priority is higher for elements specified before others.
194 * After specifying the types you want, you must append a 0.
195 * Note that the certificate type priority is set on the client.
196 * The server does not use the cert type priority except for disabling
197 * types that were not specified.
199 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
202 gnutls_certificate_type_set_priority (gnutls_session_t session,
203 const int *list)
205 #ifdef ENABLE_OPENPGP
206 _set_priority (&session->internals.priorities.cert_type, list);
207 return 0;
208 #else
210 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
212 #endif
215 static const int supported_ecc_normal[] = {
216 GNUTLS_ECC_CURVE_SECP192R1,
217 GNUTLS_ECC_CURVE_SECP224R1,
218 GNUTLS_ECC_CURVE_SECP256R1,
219 GNUTLS_ECC_CURVE_SECP384R1,
220 GNUTLS_ECC_CURVE_SECP521R1,
224 static const int supported_ecc_secure128[] = {
225 GNUTLS_ECC_CURVE_SECP256R1,
226 GNUTLS_ECC_CURVE_SECP384R1,
227 GNUTLS_ECC_CURVE_SECP521R1,
231 static const int supported_ecc_suiteb128[] = {
232 GNUTLS_ECC_CURVE_SECP256R1,
233 GNUTLS_ECC_CURVE_SECP384R1,
237 static const int supported_ecc_suiteb192[] = {
238 GNUTLS_ECC_CURVE_SECP384R1,
242 static const int supported_ecc_secure192[] = {
243 GNUTLS_ECC_CURVE_SECP384R1,
244 GNUTLS_ECC_CURVE_SECP521R1,
248 static const int protocol_priority[] = {
249 GNUTLS_TLS1_2,
250 GNUTLS_TLS1_1,
251 GNUTLS_TLS1_0,
252 GNUTLS_SSL3,
253 GNUTLS_DTLS1_0,
257 static const int protocol_priority_suiteb[] = {
258 GNUTLS_TLS1_2,
262 static const int kx_priority_performance[] = {
263 GNUTLS_KX_RSA,
264 GNUTLS_KX_ECDHE_ECDSA,
265 GNUTLS_KX_ECDHE_RSA,
266 GNUTLS_KX_DHE_RSA,
267 GNUTLS_KX_DHE_DSS,
271 static const int kx_priority_suiteb[] = {
272 GNUTLS_KX_ECDHE_ECDSA,
276 static const int kx_priority_export[] = {
277 GNUTLS_KX_RSA,
278 GNUTLS_KX_ECDHE_ECDSA,
279 GNUTLS_KX_ECDHE_RSA,
280 GNUTLS_KX_DHE_RSA,
281 GNUTLS_KX_DHE_DSS,
282 GNUTLS_KX_RSA_EXPORT,
286 static const int kx_priority_secure[] = {
287 /* The ciphersuites that offer forward secrecy take
288 * precedence
290 GNUTLS_KX_ECDHE_ECDSA,
291 GNUTLS_KX_ECDHE_RSA,
292 GNUTLS_KX_DHE_RSA,
293 GNUTLS_KX_DHE_DSS,
294 GNUTLS_KX_RSA,
295 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
296 * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
301 static const int cipher_priority_performance_sw[] = {
302 GNUTLS_CIPHER_ARCFOUR_128,
303 GNUTLS_CIPHER_AES_128_CBC,
304 GNUTLS_CIPHER_CAMELLIA_128_CBC,
305 GNUTLS_CIPHER_AES_256_CBC,
306 GNUTLS_CIPHER_CAMELLIA_256_CBC,
307 GNUTLS_CIPHER_3DES_CBC,
308 GNUTLS_CIPHER_AES_128_GCM,
309 GNUTLS_CIPHER_AES_256_GCM,
313 /* If GCM and AES acceleration is available then prefer
314 * them over anything else.
316 static const int cipher_priority_performance_hw_aes[] = {
317 GNUTLS_CIPHER_AES_128_GCM,
318 GNUTLS_CIPHER_AES_128_CBC,
319 GNUTLS_CIPHER_AES_256_GCM,
320 GNUTLS_CIPHER_AES_256_CBC,
321 GNUTLS_CIPHER_ARCFOUR_128,
322 GNUTLS_CIPHER_CAMELLIA_128_CBC,
323 GNUTLS_CIPHER_CAMELLIA_256_CBC,
324 GNUTLS_CIPHER_3DES_CBC,
328 static const int cipher_priority_normal_sw[] = {
329 GNUTLS_CIPHER_AES_128_CBC,
330 GNUTLS_CIPHER_CAMELLIA_128_CBC,
331 GNUTLS_CIPHER_AES_128_GCM,
332 GNUTLS_CIPHER_AES_256_CBC,
333 GNUTLS_CIPHER_CAMELLIA_256_CBC,
334 GNUTLS_CIPHER_AES_256_GCM,
335 GNUTLS_CIPHER_3DES_CBC,
336 GNUTLS_CIPHER_ARCFOUR_128,
340 static const int cipher_priority_normal_hw_aes[] = {
341 GNUTLS_CIPHER_AES_128_GCM,
342 GNUTLS_CIPHER_AES_128_CBC,
343 GNUTLS_CIPHER_AES_256_GCM,
344 GNUTLS_CIPHER_AES_256_CBC,
345 GNUTLS_CIPHER_CAMELLIA_128_CBC,
346 GNUTLS_CIPHER_CAMELLIA_256_CBC,
347 GNUTLS_CIPHER_3DES_CBC,
348 GNUTLS_CIPHER_ARCFOUR_128,
352 static const int *cipher_priority_performance = cipher_priority_performance_sw;
353 static const int *cipher_priority_normal = cipher_priority_normal_sw;
356 static const int cipher_priority_suiteb128[] = {
357 GNUTLS_CIPHER_AES_128_GCM,
358 GNUTLS_CIPHER_AES_256_GCM,
362 static const int cipher_priority_suiteb192[] = {
363 GNUTLS_CIPHER_AES_256_GCM,
368 static const int cipher_priority_secure128[] = {
369 GNUTLS_CIPHER_AES_128_CBC,
370 GNUTLS_CIPHER_CAMELLIA_128_CBC,
371 GNUTLS_CIPHER_AES_128_GCM,
372 GNUTLS_CIPHER_AES_256_CBC,
373 GNUTLS_CIPHER_CAMELLIA_256_CBC,
374 GNUTLS_CIPHER_AES_256_GCM,
379 static const int cipher_priority_secure192[] = {
380 GNUTLS_CIPHER_AES_256_CBC,
381 GNUTLS_CIPHER_CAMELLIA_256_CBC,
382 GNUTLS_CIPHER_AES_256_GCM,
386 /* The same as cipher_priority_security_normal + arcfour-40. */
387 static const int cipher_priority_export[] = {
388 GNUTLS_CIPHER_AES_128_CBC,
389 GNUTLS_CIPHER_AES_256_CBC,
390 GNUTLS_CIPHER_CAMELLIA_128_CBC,
391 GNUTLS_CIPHER_CAMELLIA_256_CBC,
392 GNUTLS_CIPHER_AES_128_GCM,
393 GNUTLS_CIPHER_3DES_CBC,
394 GNUTLS_CIPHER_ARCFOUR_128,
395 GNUTLS_CIPHER_ARCFOUR_40,
399 static const int comp_priority[] = {
400 /* compression should be explicitly requested to be enabled */
401 GNUTLS_COMP_NULL,
405 static const int sign_priority_default[] = {
406 GNUTLS_SIGN_RSA_SHA256,
407 GNUTLS_SIGN_DSA_SHA256,
408 GNUTLS_SIGN_ECDSA_SHA256,
410 GNUTLS_SIGN_RSA_SHA384,
411 GNUTLS_SIGN_ECDSA_SHA384,
413 GNUTLS_SIGN_RSA_SHA512,
414 GNUTLS_SIGN_ECDSA_SHA512,
416 GNUTLS_SIGN_RSA_SHA224,
417 GNUTLS_SIGN_DSA_SHA224,
418 GNUTLS_SIGN_ECDSA_SHA224,
420 GNUTLS_SIGN_RSA_SHA1,
421 GNUTLS_SIGN_DSA_SHA1,
422 GNUTLS_SIGN_ECDSA_SHA1,
426 static const int sign_priority_suiteb128[] = {
427 GNUTLS_SIGN_ECDSA_SHA256,
428 GNUTLS_SIGN_ECDSA_SHA384,
432 static const int sign_priority_suiteb192[] = {
433 GNUTLS_SIGN_ECDSA_SHA384,
437 static const int sign_priority_secure128[] = {
438 GNUTLS_SIGN_RSA_SHA256,
439 GNUTLS_SIGN_DSA_SHA256,
440 GNUTLS_SIGN_ECDSA_SHA256,
441 GNUTLS_SIGN_RSA_SHA384,
442 GNUTLS_SIGN_ECDSA_SHA384,
443 GNUTLS_SIGN_RSA_SHA512,
444 GNUTLS_SIGN_ECDSA_SHA512,
448 static const int sign_priority_secure192[] = {
449 GNUTLS_SIGN_RSA_SHA384,
450 GNUTLS_SIGN_ECDSA_SHA384,
451 GNUTLS_SIGN_RSA_SHA512,
452 GNUTLS_SIGN_ECDSA_SHA512,
456 static const int mac_priority_normal[] = {
457 GNUTLS_MAC_SHA1,
458 GNUTLS_MAC_SHA256,
459 GNUTLS_MAC_SHA384,
460 GNUTLS_MAC_AEAD,
461 GNUTLS_MAC_MD5,
465 static const int mac_priority_suiteb128[] = {
466 GNUTLS_MAC_AEAD,
470 static const int mac_priority_suiteb192[] = {
471 GNUTLS_MAC_AEAD,
475 static const int mac_priority_secure128[] = {
476 GNUTLS_MAC_SHA1,
477 GNUTLS_MAC_SHA256,
478 GNUTLS_MAC_SHA384,
479 GNUTLS_MAC_AEAD,
483 static const int mac_priority_secure192[] = {
484 GNUTLS_MAC_SHA256,
485 GNUTLS_MAC_SHA384,
486 GNUTLS_MAC_AEAD,
490 static const int cert_type_priority_default[] = {
491 GNUTLS_CRT_X509,
495 static const int cert_type_priority_all[] = {
496 GNUTLS_CRT_X509,
497 GNUTLS_CRT_OPENPGP,
501 typedef void (rmadd_func) (priority_st * priority_list, unsigned int alg);
503 static void
504 prio_remove (priority_st * priority_list, unsigned int algo)
506 int i = 0;
507 int pos = -1; /* the position of the cipher to remove */
509 while (priority_list->priority[i] != 0)
511 if (priority_list->priority[i] == algo)
512 pos = i;
513 i++;
516 if (pos >= 0)
518 priority_list->priority[pos] = priority_list->priority[i - 1];
519 priority_list->priority[i - 1] = 0;
520 priority_list->algorithms--;
523 return;
526 static void
527 prio_add (priority_st * priority_list, unsigned int algo)
529 register int i = 0;
530 while (priority_list->priority[i] != 0)
532 if (algo == priority_list->priority[i])
533 return; /* if it exists */
534 i++;
537 if (i < MAX_ALGOS)
539 priority_list->priority[i] = algo;
540 priority_list->algorithms++;
543 return;
548 * gnutls_priority_set:
549 * @session: is a #gnutls_session_t structure.
550 * @priority: is a #gnutls_priority_t structure.
552 * Sets the priorities to use on the ciphers, key exchange methods,
553 * macs and compression methods.
555 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
558 gnutls_priority_set (gnutls_session_t session, gnutls_priority_t priority)
560 if (priority == NULL)
562 gnutls_assert ();
563 return GNUTLS_E_NO_CIPHER_SUITES;
566 memcpy (&session->internals.priorities, priority,
567 sizeof (struct gnutls_priority_st));
569 /* set the current version to the first in the chain.
570 * This will be overridden later.
572 if (session->internals.priorities.protocol.algorithms > 0)
573 _gnutls_set_current_version (session,
574 session->internals.priorities.protocol.
575 priority[0]);
577 if (session->internals.priorities.protocol.algorithms == 0 ||
578 session->internals.priorities.cipher.algorithms == 0 ||
579 session->internals.priorities.mac.algorithms == 0 ||
580 session->internals.priorities.kx.algorithms == 0 ||
581 session->internals.priorities.compression.algorithms == 0)
582 return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
584 return 0;
588 #define MAX_ELEMENTS 48
591 * gnutls_priority_init:
592 * @priority_cache: is a #gnutls_prioritity_t structure.
593 * @priorities: is a string describing priorities
594 * @err_pos: In case of an error this will have the position in the string the error occured
596 * Sets priorities for the ciphers, key exchange methods, macs and
597 * compression methods.
599 * The #priorities option allows you to specify a colon
600 * separated list of the cipher priorities to enable.
601 * Some keywords are defined to provide quick access
602 * to common preferences.
604 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
605 * limited to 128 bit ciphers and sorted by terms of speed
606 * performance.
608 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
609 * included as a fallback only. The ciphers are sorted by security
610 * margin.
612 * "SECURE128" means all "secure" ciphersuites of security level 128-bit
613 * or more.
615 * "SECURE192" means all "secure" ciphersuites of security level 192-bit
616 * or more.
618 * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
619 * of 128.
621 * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
622 * of 192.
624 * "EXPORT" means all ciphersuites are enabled, including the
625 * low-security 40 bit ciphers.
627 * "NONE" means nothing is enabled. This disables even protocols and
628 * compression methods.
630 * Special keywords are "!", "-" and "+".
631 * "!" or "-" appended with an algorithm will remove this algorithm.
632 * "+" appended with an algorithm will add this algorithm.
634 * Check the GnuTLS manual section "Priority strings" for detailed
635 * information.
637 * Examples:
639 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
641 * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128.
643 * "SECURE:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
644 * enabled, SSL3.0 is disabled, and libz compression enabled.
646 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1",
648 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1",
650 * "NORMAL:%COMPAT" is the most compatible mode.
652 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
653 * %GNUTLS_E_SUCCESS on success, or an error code.
656 gnutls_priority_init (gnutls_priority_t * priority_cache,
657 const char *priorities, const char **err_pos)
659 char *broken_list[MAX_ELEMENTS];
660 int broken_list_size = 0, i = 0, j;
661 char *darg = NULL;
662 int algo;
663 rmadd_func *fn;
664 bulk_rmadd_func *bulk_fn;
666 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
667 if (*priority_cache == NULL)
669 gnutls_assert ();
670 return GNUTLS_E_MEMORY_ERROR;
673 /* for now unsafe renegotiation is default on everyone. To be removed
674 * when we make it the default.
676 (*priority_cache)->sr = SR_PARTIAL;
677 (*priority_cache)->ssl3_record_version = 1;
679 if (priorities == NULL)
680 priorities = "NORMAL";
682 darg = gnutls_strdup (priorities);
683 if (darg == NULL)
685 gnutls_assert ();
686 goto error;
689 break_comma_list (darg, broken_list, &broken_list_size, MAX_ELEMENTS, ':');
690 /* This is our default set of protocol version, certificate types and
691 * compression methods.
693 if (strcasecmp (broken_list[0], "NONE") != 0)
695 _set_priority (&(*priority_cache)->protocol, protocol_priority);
696 _set_priority (&(*priority_cache)->compression, comp_priority);
697 _set_priority (&(*priority_cache)->cert_type, cert_type_priority_default);
698 _set_priority (&(*priority_cache)->sign_algo, sign_priority_default);
699 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal);
700 i = 0;
702 else
704 i = 1;
707 for (; i < broken_list_size; i++)
709 if (strcasecmp (broken_list[i], "PERFORMANCE") == 0)
711 _set_priority (&(*priority_cache)->cipher,
712 cipher_priority_performance);
713 _set_priority (&(*priority_cache)->kx, kx_priority_performance);
714 _set_priority (&(*priority_cache)->mac, mac_priority_normal);
715 _set_priority (&(*priority_cache)->sign_algo,
716 sign_priority_default);
717 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal);
719 else if (strcasecmp (broken_list[i], "NORMAL") == 0)
721 _set_priority (&(*priority_cache)->cipher, cipher_priority_normal);
722 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
723 _set_priority (&(*priority_cache)->mac, mac_priority_normal);
724 _set_priority (&(*priority_cache)->sign_algo,
725 sign_priority_default);
726 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal);
728 else if (strcasecmp (broken_list[i], "SECURE256") == 0
729 || strcasecmp (broken_list[i], "SECURE192") == 0)
731 _set_priority (&(*priority_cache)->cipher,
732 cipher_priority_secure192);
733 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
734 _set_priority (&(*priority_cache)->mac, mac_priority_secure192);
735 _set_priority (&(*priority_cache)->sign_algo,
736 sign_priority_secure192);
737 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_secure192);
739 else if (strcasecmp (broken_list[i], "SECURE128") == 0
740 || strcasecmp (broken_list[i], "SECURE") == 0)
742 _set_priority (&(*priority_cache)->cipher,
743 cipher_priority_secure128);
744 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
745 _set_priority (&(*priority_cache)->mac, mac_priority_secure128);
746 _set_priority (&(*priority_cache)->sign_algo,
747 sign_priority_secure128);
748 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_secure128);
750 else if (strcasecmp (broken_list[i], "SUITEB128") == 0)
752 _set_priority (&(*priority_cache)->protocol, protocol_priority_suiteb);
753 _set_priority (&(*priority_cache)->cipher,
754 cipher_priority_suiteb128);
755 _set_priority (&(*priority_cache)->kx, kx_priority_suiteb);
756 _set_priority (&(*priority_cache)->mac, mac_priority_suiteb128);
757 _set_priority (&(*priority_cache)->sign_algo,
758 sign_priority_suiteb128);
759 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_suiteb128);
761 else if (strcasecmp (broken_list[i], "SUITEB192") == 0)
763 _set_priority (&(*priority_cache)->protocol, protocol_priority_suiteb);
764 _set_priority (&(*priority_cache)->cipher,
765 cipher_priority_suiteb192);
766 _set_priority (&(*priority_cache)->kx, kx_priority_suiteb);
767 _set_priority (&(*priority_cache)->mac, mac_priority_suiteb192);
768 _set_priority (&(*priority_cache)->sign_algo,
769 sign_priority_suiteb192);
770 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_suiteb192);
772 else if (strcasecmp (broken_list[i], "EXPORT") == 0)
774 _set_priority (&(*priority_cache)->cipher, cipher_priority_export);
775 _set_priority (&(*priority_cache)->kx, kx_priority_export);
776 _set_priority (&(*priority_cache)->mac, mac_priority_secure128);
777 _set_priority (&(*priority_cache)->sign_algo,
778 sign_priority_default);
779 _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal);
780 } /* now check if the element is something like -ALGO */
781 else if (broken_list[i][0] == '!' || broken_list[i][0] == '+'
782 || broken_list[i][0] == '-')
784 if (broken_list[i][0] == '+')
786 fn = prio_add;
787 bulk_fn = _set_priority;
789 else
791 fn = prio_remove;
792 bulk_fn = _clear_priorities;
795 if ((algo =
796 gnutls_mac_get_id (&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN)
797 fn (&(*priority_cache)->mac, algo);
798 else if ((algo = gnutls_cipher_get_id (&broken_list[i][1])) !=
799 GNUTLS_CIPHER_UNKNOWN)
800 fn (&(*priority_cache)->cipher, algo);
801 else if ((algo = gnutls_kx_get_id (&broken_list[i][1])) !=
802 GNUTLS_KX_UNKNOWN)
803 fn (&(*priority_cache)->kx, algo);
804 else if (strncasecmp (&broken_list[i][1], "VERS-", 5) == 0)
806 if (strncasecmp (&broken_list[i][1], "VERS-TLS-ALL", 12) == 0)
808 bulk_fn (&(*priority_cache)->protocol,
809 protocol_priority);
811 else
813 if ((algo =
814 gnutls_protocol_get_id (&broken_list[i][6])) !=
815 GNUTLS_VERSION_UNKNOWN)
816 fn (&(*priority_cache)->protocol, algo);
817 else
818 goto error;
821 } /* now check if the element is something like -ALGO */
822 else if (strncasecmp (&broken_list[i][1], "COMP-", 5) == 0)
824 if (strncasecmp (&broken_list[i][1], "COMP-ALL", 8) == 0)
826 bulk_fn (&(*priority_cache)->compression,
827 comp_priority);
829 else
831 if ((algo =
832 gnutls_compression_get_id (&broken_list[i][6])) !=
833 GNUTLS_COMP_UNKNOWN)
834 fn (&(*priority_cache)->compression, algo);
835 else
836 goto error;
838 } /* now check if the element is something like -ALGO */
839 else if (strncasecmp (&broken_list[i][1], "CURVE-", 6) == 0)
841 if (strncasecmp (&broken_list[i][1], "CURVE-ALL", 9) == 0)
843 bulk_fn (&(*priority_cache)->supported_ecc,
844 supported_ecc_normal);
846 else
848 if ((algo =
849 _gnutls_ecc_curve_get_id (&broken_list[i][7])) !=
850 GNUTLS_ECC_CURVE_INVALID)
851 fn (&(*priority_cache)->supported_ecc, algo);
852 else
853 goto error;
855 } /* now check if the element is something like -ALGO */
856 else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0)
858 if (strncasecmp (&broken_list[i][1], "CTYPE-ALL", 9) == 0)
860 bulk_fn (&(*priority_cache)->cert_type,
861 cert_type_priority_all);
863 else
865 if ((algo =
866 gnutls_certificate_type_get_id (&broken_list[i][7])) !=
867 GNUTLS_CRT_UNKNOWN)
868 fn (&(*priority_cache)->cert_type, algo);
869 else
870 goto error;
872 } /* now check if the element is something like -ALGO */
873 else if (strncasecmp (&broken_list[i][1], "SIGN-", 5) == 0)
875 if (strncasecmp (&broken_list[i][1], "SIGN-ALL", 8) == 0)
877 bulk_fn (&(*priority_cache)->sign_algo,
878 sign_priority_default);
880 else
882 if ((algo =
883 gnutls_sign_get_id (&broken_list[i][6])) !=
884 GNUTLS_SIGN_UNKNOWN)
885 fn (&(*priority_cache)->sign_algo, algo);
886 else
887 goto error;
890 else if (strncasecmp (&broken_list[i][1], "MAC-ALL", 7) == 0)
892 bulk_fn (&(*priority_cache)->mac,
893 mac_priority_normal);
895 else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 10) == 0)
897 bulk_fn (&(*priority_cache)->cipher,
898 cipher_priority_normal);
900 else if (strncasecmp (&broken_list[i][1], "KX-ALL", 6) == 0)
902 bulk_fn (&(*priority_cache)->kx,
903 kx_priority_secure);
905 else
906 goto error;
908 else if (broken_list[i][0] == '%')
910 if (strcasecmp (&broken_list[i][1], "COMPAT") == 0)
912 (*priority_cache)->no_padding = 1;
913 (*priority_cache)->allow_large_records = 1;
914 (*priority_cache)->allow_key_usage_violation = 1;
916 else if (strcasecmp (&broken_list[i][1], "NO_EXTENSIONS") == 0)
918 (*priority_cache)->no_extensions = 1;
920 else if (strcasecmp (&broken_list[i][1],
921 "VERIFY_ALLOW_SIGN_RSA_MD5") == 0)
923 prio_add (&(*priority_cache)->sign_algo, GNUTLS_SIGN_RSA_MD5);
924 (*priority_cache)->additional_verify_flags |=
925 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
927 else if (strcasecmp (&broken_list[i][1],
928 "SSL3_RECORD_VERSION") == 0)
929 (*priority_cache)->ssl3_record_version = 1;
930 else if (strcasecmp (&broken_list[i][1],
931 "LATEST_RECORD_VERSION") == 0)
932 (*priority_cache)->ssl3_record_version = 0;
933 else if (strcasecmp (&broken_list[i][1],
934 "VERIFY_ALLOW_X509_V1_CA_CRT") == 0)
935 (*priority_cache)->additional_verify_flags |=
936 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
937 else if (strcasecmp (&broken_list[i][1],
938 "UNSAFE_RENEGOTIATION") == 0)
940 (*priority_cache)->sr = SR_UNSAFE;
942 else if (strcasecmp (&broken_list[i][1], "SAFE_RENEGOTIATION") == 0)
944 (*priority_cache)->sr = SR_SAFE;
946 else if (strcasecmp (&broken_list[i][1],
947 "PARTIAL_RENEGOTIATION") == 0)
949 (*priority_cache)->sr = SR_PARTIAL;
951 else if (strcasecmp (&broken_list[i][1],
952 "DISABLE_SAFE_RENEGOTIATION") == 0)
954 (*priority_cache)->sr = SR_DISABLED;
956 else if (strcasecmp (&broken_list[i][1],
957 "SERVER_PRECEDENCE") == 0)
959 (*priority_cache)->server_precedence = 1;
961 else
962 goto error;
964 else
965 goto error;
968 gnutls_free (darg);
969 return 0;
971 error:
972 if (err_pos != NULL && i < broken_list_size)
974 *err_pos = priorities;
975 for (j = 0; j < i; j++)
977 (*err_pos) += strlen (broken_list[j]) + 1;
980 gnutls_free (darg);
981 gnutls_free (*priority_cache);
983 return GNUTLS_E_INVALID_REQUEST;
988 * gnutls_priority_deinit:
989 * @priority_cache: is a #gnutls_prioritity_t structure.
991 * Deinitializes the priority cache.
993 void
994 gnutls_priority_deinit (gnutls_priority_t priority_cache)
996 gnutls_free (priority_cache);
1001 * gnutls_priority_set_direct:
1002 * @session: is a #gnutls_session_t structure.
1003 * @priorities: is a string describing priorities
1004 * @err_pos: In case of an error this will have the position in the string the error occured
1006 * Sets the priorities to use on the ciphers, key exchange methods,
1007 * macs and compression methods. This function avoids keeping a
1008 * priority cache and is used to directly set string priorities to a
1009 * TLS session. For documentation check the gnutls_priority_init().
1011 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
1012 * %GNUTLS_E_SUCCESS on success, or an error code.
1015 gnutls_priority_set_direct (gnutls_session_t session,
1016 const char *priorities, const char **err_pos)
1018 gnutls_priority_t prio;
1019 int ret;
1021 ret = gnutls_priority_init (&prio, priorities, err_pos);
1022 if (ret < 0)
1024 gnutls_assert ();
1025 return ret;
1028 ret = gnutls_priority_set (session, prio);
1029 if (ret < 0)
1031 gnutls_assert ();
1032 return ret;
1035 gnutls_priority_deinit (prio);
1037 return 0;
1040 /* Breaks a list of "xxx", "yyy", to a character array, of
1041 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
1043 static void
1044 break_comma_list (char *etag,
1045 char **broken_etag, int *elements, int max_elements,
1046 char sep)
1048 char *p = etag;
1049 if (sep == 0)
1050 sep = ',';
1052 *elements = 0;
1056 broken_etag[*elements] = p;
1058 (*elements)++;
1060 p = strchr (p, sep);
1061 if (p)
1063 *p = 0;
1064 p++; /* move to next entry and skip white
1065 * space.
1067 while (*p == ' ')
1068 p++;
1071 while (p != NULL && *elements < max_elements);
1075 * gnutls_set_default_priority:
1076 * @session: is a #gnutls_session_t structure.
1078 * Sets some default priority on the ciphers, key exchange methods,
1079 * macs and compression methods.
1081 * This is the same as calling:
1083 * gnutls_priority_set_direct (session, "NORMAL", NULL);
1085 * This function is kept around for backwards compatibility, but
1086 * because of its wide use it is still fully supported. If you wish
1087 * to allow users to provide a string that specify which ciphers to
1088 * use (which is recommended), you should use
1089 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
1091 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1094 gnutls_set_default_priority (gnutls_session_t session)
1096 return gnutls_priority_set_direct (session, "NORMAL", NULL);
1100 * gnutls_set_default_export_priority:
1101 * @session: is a #gnutls_session_t structure.
1103 * Sets some default priority on the ciphers, key exchange methods, macs
1104 * and compression methods. This function also includes weak algorithms.
1106 * This is the same as calling:
1108 * gnutls_priority_set_direct (session, "EXPORT", NULL);
1110 * This function is kept around for backwards compatibility, but
1111 * because of its wide use it is still fully supported. If you wish
1112 * to allow users to provide a string that specify which ciphers to
1113 * use (which is recommended), you should use
1114 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
1116 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1119 gnutls_set_default_export_priority (gnutls_session_t session)
1121 return gnutls_priority_set_direct (session, "EXPORT", NULL);
1124 /* Increases the priority of AES-GCM as it is much faster
1125 * than anything else if hardware support is there.
1127 void _gnutls_priority_prefer_aes_gcm(void)
1129 cipher_priority_performance = cipher_priority_performance_hw_aes;
1130 cipher_priority_normal = cipher_priority_normal_hw_aes;
1134 * gnutls_priority_ecc_curve_list:
1135 * @pcache: is a #gnutls_prioritity_t structure.
1136 * @list: will point to an integer list
1138 * Get a list of available elliptic curves in the priority
1139 * structure.
1141 * Returns: the number of curves, or an error code.
1142 * Since: 3.0
1145 gnutls_priority_ecc_curve_list (gnutls_priority_t pcache, const unsigned int** list)
1147 if (pcache->supported_ecc.algorithms == 0)
1148 return 0;
1150 *list = pcache->supported_ecc.priority;
1151 return pcache->supported_ecc.algorithms;
1155 * gnutls_priority_compression_list:
1156 * @pcache: is a #gnutls_prioritity_t structure.
1157 * @list: will point to an integer list
1159 * Get a list of available compression method in the priority
1160 * structure.
1162 * Returns: the number of methods, or an error code.
1163 * Since: 3.0
1166 gnutls_priority_compression_list (gnutls_priority_t pcache, const unsigned int** list)
1168 if (pcache->compression.algorithms == 0)
1169 return 0;
1171 *list = pcache->compression.priority;
1172 return pcache->compression.algorithms;
1176 * gnutls_priority_protocol_list:
1177 * @pcache: is a #gnutls_prioritity_t structure.
1178 * @list: will point to an integer list
1180 * Get a list of available TLS version numbers in the priority
1181 * structure.
1183 * Returns: the number of protocols, or an error code.
1184 * Since: 3.0
1187 gnutls_priority_protocol_list (gnutls_priority_t pcache, const unsigned int** list)
1189 if (pcache->protocol.algorithms == 0)
1190 return 0;
1192 *list = pcache->protocol.priority;
1193 return pcache->protocol.algorithms;
1197 * gnutls_priority_sign_list:
1198 * @pcache: is a #gnutls_prioritity_t structure.
1199 * @list: will point to an integer list
1201 * Get a list of available signature algorithms in the priority
1202 * structure.
1204 * Returns: the number of algorithms, or an error code.
1205 * Since: 3.0
1208 gnutls_priority_sign_list (gnutls_priority_t pcache, const unsigned int** list)
1210 if (pcache->sign_algo.algorithms == 0)
1211 return 0;
1213 *list = pcache->sign_algo.priority;
1214 return pcache->sign_algo.algorithms;
1218 * gnutls_priority_certificate_type_list:
1219 * @pcache: is a #gnutls_prioritity_t structure.
1220 * @list: will point to an integer list
1222 * Get a list of available certificate types in the priority
1223 * structure.
1225 * Returns: the number of certificate types, or an error code.
1226 * Since: 3.0
1229 gnutls_priority_certificate_type_list (gnutls_priority_t pcache, const unsigned int** list)
1231 if (pcache->cert_type.algorithms == 0)
1232 return 0;
1234 *list = pcache->cert_type.priority;
1235 return pcache->cert_type.algorithms;