updated libtasn1
[gnutls.git] / lib / gnutls_priority.c
blobbd8cb5af0476bb770ec76c97b9f7a837b16607dd
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 * Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* Here lies the code of the gnutls_*_set_priority() functions.
29 #include "gnutls_int.h"
30 #include "gnutls_algorithms.h"
31 #include "gnutls_errors.h"
32 #include <gnutls_num.h>
34 static void
35 break_comma_list (char *etag,
36 char **broken_etag, int *elements, int max_elements,
37 char sep);
39 /**
40 * gnutls_cipher_set_priority:
41 * @session: is a #gnutls_session_t structure.
42 * @list: is a 0 terminated list of gnutls_cipher_algorithm_t elements.
44 * Sets the priority on the ciphers supported by gnutls. Priority is
45 * higher for elements specified before others. After specifying the
46 * ciphers you want, you must append a 0. Note that the priority is
47 * set on the client. The server does not use the algorithm's
48 * priority except for disabling algorithms that were not specified.
50 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
51 **/
52 int
53 gnutls_cipher_set_priority (gnutls_session_t session, const int *list)
55 int num = 0, i;
57 while (list[num] != 0)
58 num++;
59 if (num > MAX_ALGOS)
60 num = MAX_ALGOS;
61 session->internals.priorities.cipher.algorithms = num;
63 for (i = 0; i < num; i++)
65 session->internals.priorities.cipher.priority[i] = list[i];
68 return 0;
71 typedef void (bulk_rmadd_func) (priority_st * priority_list, const int *);
73 inline static void
74 _set_priority (priority_st * st, const int *list)
76 int num = 0, i;
78 while (list[num] != 0)
79 num++;
80 if (num > MAX_ALGOS)
81 num = MAX_ALGOS;
82 st->algorithms = num;
84 for (i = 0; i < num; i++)
86 st->priority[i] = list[i];
89 return;
92 static void
93 _clear_priorities (priority_st * st, const int *list)
95 memset(st, 0, sizeof(*st));
98 /**
99 * gnutls_kx_set_priority:
100 * @session: is a #gnutls_session_t structure.
101 * @list: is a 0 terminated list of gnutls_kx_algorithm_t elements.
103 * Sets the priority on the key exchange algorithms supported by
104 * gnutls. Priority is higher for elements specified before others.
105 * After specifying the algorithms you want, you must append a 0.
106 * Note that the priority is set on the client. The server does not
107 * use the algorithm's priority except for disabling algorithms that
108 * were not specified.
110 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
113 gnutls_kx_set_priority (gnutls_session_t session, const int *list)
115 _set_priority (&session->internals.priorities.kx, list);
116 return 0;
120 * gnutls_mac_set_priority:
121 * @session: is a #gnutls_session_t structure.
122 * @list: is a 0 terminated list of gnutls_mac_algorithm_t elements.
124 * Sets the priority on the mac algorithms supported by gnutls.
125 * Priority is higher for elements specified before others. After
126 * specifying the algorithms you want, you must append a 0. Note
127 * that the priority is set on the client. The server does not use
128 * the algorithm's priority except for disabling algorithms that were
129 * not specified.
131 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
134 gnutls_mac_set_priority (gnutls_session_t session, const int *list)
136 _set_priority (&session->internals.priorities.mac, list);
137 return 0;
141 * gnutls_compression_set_priority:
142 * @session: is a #gnutls_session_t structure.
143 * @list: is a 0 terminated list of gnutls_compression_method_t elements.
145 * Sets the priority on the compression algorithms supported by
146 * gnutls. Priority is higher for elements specified before others.
147 * After specifying the algorithms you want, you must append a 0.
148 * Note that the priority is set on the client. The server does not
149 * use the algorithm's priority except for disabling algorithms that
150 * were not specified.
152 * TLS 1.0 does not define any compression algorithms except
153 * NULL. Other compression algorithms are to be considered as gnutls
154 * extensions.
156 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
159 gnutls_compression_set_priority (gnutls_session_t session, const int *list)
161 _set_priority (&session->internals.priorities.compression, list);
162 return 0;
166 * gnutls_protocol_set_priority:
167 * @session: is a #gnutls_session_t structure.
168 * @list: is a 0 terminated list of gnutls_protocol_t elements.
170 * Sets the priority on the protocol versions supported by gnutls.
171 * This function actually enables or disables protocols. Newer protocol
172 * versions always have highest priority.
174 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
177 gnutls_protocol_set_priority (gnutls_session_t session, const int *list)
179 _set_priority (&session->internals.priorities.protocol, list);
181 /* set the current version to the first in the chain.
182 * This will be overridden later.
184 if (list)
185 _gnutls_set_current_version (session, list[0]);
187 return 0;
191 * gnutls_certificate_type_set_priority:
192 * @session: is a #gnutls_session_t structure.
193 * @list: is a 0 terminated list of gnutls_certificate_type_t elements.
195 * Sets the priority on the certificate types supported by gnutls.
196 * Priority is higher for elements specified before others.
197 * After specifying the types you want, you must append a 0.
198 * Note that the certificate type priority is set on the client.
199 * The server does not use the cert type priority except for disabling
200 * types that were not specified.
202 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
205 gnutls_certificate_type_set_priority (gnutls_session_t session,
206 const int *list)
208 #ifdef ENABLE_OPENPGP
209 _set_priority (&session->internals.priorities.cert_type, list);
210 return 0;
211 #else
213 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
215 #endif
218 static const int protocol_priority[] = {
219 GNUTLS_TLS1_2,
220 GNUTLS_TLS1_1,
221 GNUTLS_TLS1_0,
222 GNUTLS_SSL3,
226 static const int kx_priority_performance[] = {
227 GNUTLS_KX_RSA,
228 GNUTLS_KX_DHE_RSA,
229 GNUTLS_KX_DHE_DSS,
230 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
231 * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
236 static const int kx_priority_export[] = {
237 GNUTLS_KX_RSA,
238 GNUTLS_KX_DHE_RSA,
239 GNUTLS_KX_DHE_DSS,
240 GNUTLS_KX_RSA_EXPORT,
244 static const int kx_priority_secure[] = {
245 /* The ciphersuites that offer forward secrecy take
246 * precendance
248 GNUTLS_KX_DHE_RSA,
249 GNUTLS_KX_DHE_DSS,
250 GNUTLS_KX_RSA,
251 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
252 * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
257 static const int cipher_priority_performance[] = {
258 GNUTLS_CIPHER_ARCFOUR_128,
259 #ifdef ENABLE_CAMELLIA
260 GNUTLS_CIPHER_CAMELLIA_128_CBC,
261 #endif
262 GNUTLS_CIPHER_AES_128_CBC,
263 GNUTLS_CIPHER_3DES_CBC,
264 GNUTLS_CIPHER_AES_256_CBC,
265 #ifdef ENABLE_CAMELLIA
266 GNUTLS_CIPHER_CAMELLIA_256_CBC,
267 #endif
268 /* GNUTLS_CIPHER_ARCFOUR_40: Insecure, don't add! */
272 static const int cipher_priority_normal[] = {
273 GNUTLS_CIPHER_AES_128_CBC,
274 #ifdef ENABLE_CAMELLIA
275 GNUTLS_CIPHER_CAMELLIA_128_CBC,
276 #endif
277 GNUTLS_CIPHER_AES_256_CBC,
278 #ifdef ENABLE_CAMELLIA
279 GNUTLS_CIPHER_CAMELLIA_256_CBC,
280 #endif
281 GNUTLS_CIPHER_3DES_CBC,
282 GNUTLS_CIPHER_ARCFOUR_128,
283 /* GNUTLS_CIPHER_ARCFOUR_40: Insecure, don't add! */
287 static const int cipher_priority_secure128[] = {
288 GNUTLS_CIPHER_AES_128_CBC,
289 #ifdef ENABLE_CAMELLIA
290 GNUTLS_CIPHER_CAMELLIA_128_CBC,
291 #endif
292 GNUTLS_CIPHER_3DES_CBC,
293 GNUTLS_CIPHER_ARCFOUR_128,
294 /* GNUTLS_CIPHER_ARCFOUR_40: Insecure, don't add! */
299 static const int cipher_priority_secure256[] = {
300 GNUTLS_CIPHER_AES_256_CBC,
301 #ifdef ENABLE_CAMELLIA
302 GNUTLS_CIPHER_CAMELLIA_256_CBC,
303 #endif
304 GNUTLS_CIPHER_AES_128_CBC,
305 #ifdef ENABLE_CAMELLIA
306 GNUTLS_CIPHER_CAMELLIA_128_CBC,
307 #endif
308 GNUTLS_CIPHER_3DES_CBC,
309 GNUTLS_CIPHER_ARCFOUR_128,
310 /* GNUTLS_CIPHER_ARCFOUR_40: Insecure, don't add! */
314 /* The same as cipher_priority_security_normal + arcfour-40. */
315 static const int cipher_priority_export[] = {
316 GNUTLS_CIPHER_AES_128_CBC,
317 GNUTLS_CIPHER_AES_256_CBC,
318 #ifdef ENABLE_CAMELLIA
319 GNUTLS_CIPHER_CAMELLIA_128_CBC,
320 GNUTLS_CIPHER_CAMELLIA_256_CBC,
321 #endif
322 GNUTLS_CIPHER_3DES_CBC,
323 GNUTLS_CIPHER_ARCFOUR_128,
324 GNUTLS_CIPHER_ARCFOUR_40,
328 static const int comp_priority[] = {
329 /* compression should be explicitely requested to be enabled */
330 GNUTLS_COMP_NULL,
334 static const int sign_priority_default[] = {
335 GNUTLS_SIGN_DSA_SHA224,
336 GNUTLS_SIGN_DSA_SHA256,
337 GNUTLS_SIGN_RSA_SHA256,
338 GNUTLS_SIGN_RSA_SHA384,
339 GNUTLS_SIGN_RSA_SHA512,
340 GNUTLS_SIGN_RSA_SHA1,
341 GNUTLS_SIGN_DSA_SHA1,
345 static const int sign_priority_secure128[] = {
346 GNUTLS_SIGN_RSA_SHA256,
347 GNUTLS_SIGN_RSA_SHA384,
348 GNUTLS_SIGN_RSA_SHA512,
349 GNUTLS_SIGN_DSA_SHA1,
353 static const int sign_priority_secure256[] = {
354 GNUTLS_SIGN_RSA_SHA512,
358 static const int mac_priority_normal[] = {
359 GNUTLS_MAC_SHA1,
360 GNUTLS_MAC_SHA256,
361 GNUTLS_MAC_MD5,
366 static const int mac_priority_secure[] = {
367 GNUTLS_MAC_SHA256,
368 GNUTLS_MAC_SHA1,
372 static const int cert_type_priority_default[] = {
373 GNUTLS_CRT_X509,
377 static const int cert_type_priority_all[] = {
378 GNUTLS_CRT_X509,
379 GNUTLS_CRT_OPENPGP,
383 typedef void (rmadd_func) (priority_st * priority_list, unsigned int alg);
385 static void
386 prio_remove (priority_st * priority_list, unsigned int algo)
388 int i = 0;
389 int pos = -1; /* the position of the cipher to remove */
391 while (priority_list->priority[i] != 0)
393 if (priority_list->priority[i] == algo)
394 pos = i;
395 i++;
398 if (pos >= 0)
400 priority_list->priority[pos] = priority_list->priority[i - 1];
401 priority_list->priority[i - 1] = 0;
402 priority_list->algorithms--;
405 return;
408 static void
409 prio_add (priority_st * priority_list, unsigned int algo)
411 register int i = 0;
412 while (priority_list->priority[i] != 0)
414 if (algo == priority_list->priority[i])
415 return; /* if it exists */
416 i++;
419 if (i < MAX_ALGOS)
421 priority_list->priority[i] = algo;
422 priority_list->algorithms++;
425 return;
430 * gnutls_priority_set:
431 * @session: is a #gnutls_session_t structure.
432 * @priority: is a #gnutls_priority_t structure.
434 * Sets the priorities to use on the ciphers, key exchange methods,
435 * macs and compression methods.
437 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
440 gnutls_priority_set (gnutls_session_t session, gnutls_priority_t priority)
442 if (priority == NULL)
444 gnutls_assert ();
445 return GNUTLS_E_NO_CIPHER_SUITES;
448 memcpy (&session->internals.priorities, priority,
449 sizeof (struct gnutls_priority_st));
451 /* set the current version to the first in the chain.
452 * This will be overridden later.
454 if (session->internals.priorities.protocol.algorithms > 0)
455 _gnutls_set_current_version (session,
456 session->internals.priorities.protocol.
457 priority[0]);
459 return 0;
463 #define MAX_ELEMENTS 48
466 * gnutls_priority_init:
467 * @priority_cache: is a #gnutls_prioritity_t structure.
468 * @priorities: is a string describing priorities
469 * @err_pos: In case of an error this will have the position in the string the error occured
471 * Sets priorities for the ciphers, key exchange methods, macs and
472 * compression methods.
474 * The #priorities option allows you to specify a colon
475 * separated list of the cipher priorities to enable.
477 * Common keywords: Some keywords are defined to provide quick access
478 * to common preferences.
480 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
481 * limited to 128 bit ciphers and sorted by terms of speed
482 * performance.
484 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
485 * included as a fallback only. The ciphers are sorted by security
486 * margin.
488 * "SECURE128" means all "secure" ciphersuites with ciphers up to 128
489 * bits, sorted by security margin.
491 * "SECURE256" means all "secure" ciphersuites including the 256 bit
492 * ciphers, sorted by security margin.
494 * "EXPORT" means all ciphersuites are enabled, including the
495 * low-security 40 bit ciphers.
497 * "NONE" means nothing is enabled. This disables even protocols and
498 * compression methods.
500 * Special keywords:
501 * "!" or "-" appended with an algorithm will remove this algorithm.
503 * "+" appended with an algorithm will add this algorithm.
505 * Check the GnuTLS manual section "Priority strings" for detailed
506 * information.
508 * Examples:
510 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
512 * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128.
514 * "SECURE:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
515 * enabled, SSL3.0 is disabled, and libz compression enabled.
517 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1",
519 * "NORMAL:%COMPAT" is the most compatible mode.
521 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
522 * %GNUTLS_E_SUCCESS on success, or an error code.
525 gnutls_priority_init (gnutls_priority_t * priority_cache,
526 const char *priorities, const char **err_pos)
528 char *broken_list[MAX_ELEMENTS];
529 int broken_list_size = 0, i = 0, j;
530 char *darg = NULL;
531 int algo;
532 rmadd_func *fn;
533 bulk_rmadd_func *bulk_fn;
535 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
536 if (*priority_cache == NULL)
538 gnutls_assert ();
539 return GNUTLS_E_MEMORY_ERROR;
542 /* for now unsafe renegotiation is default on everyone. To be removed
543 * when we make it the default.
545 (*priority_cache)->sr = SR_PARTIAL;
546 (*priority_cache)->ssl3_record_version = 1;
548 if (priorities == NULL)
549 priorities = "NORMAL";
551 darg = gnutls_strdup (priorities);
552 if (darg == NULL)
554 gnutls_assert ();
555 goto error;
558 break_comma_list (darg, broken_list, &broken_list_size, MAX_ELEMENTS, ':');
559 /* This is our default set of protocol version, certificate types and
560 * compression methods.
562 if (strcasecmp (broken_list[0], "NONE") != 0)
564 _set_priority (&(*priority_cache)->protocol, protocol_priority);
565 _set_priority (&(*priority_cache)->compression, comp_priority);
566 _set_priority (&(*priority_cache)->cert_type, cert_type_priority_default);
567 _set_priority (&(*priority_cache)->sign_algo, sign_priority_default);
568 i = 0;
570 else
572 i = 1;
575 for (; i < broken_list_size; i++)
577 if (strcasecmp (broken_list[i], "PERFORMANCE") == 0)
579 _set_priority (&(*priority_cache)->cipher,
580 cipher_priority_performance);
581 _set_priority (&(*priority_cache)->kx, kx_priority_performance);
582 _set_priority (&(*priority_cache)->mac, mac_priority_normal);
583 _set_priority (&(*priority_cache)->sign_algo,
584 sign_priority_default);
586 else if (strcasecmp (broken_list[i], "NORMAL") == 0)
588 _set_priority (&(*priority_cache)->cipher, cipher_priority_normal);
589 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
590 _set_priority (&(*priority_cache)->mac, mac_priority_normal);
591 _set_priority (&(*priority_cache)->sign_algo,
592 sign_priority_default);
594 else if (strcasecmp (broken_list[i], "SECURE256") == 0
595 || strcasecmp (broken_list[i], "SECURE") == 0)
597 _set_priority (&(*priority_cache)->cipher,
598 cipher_priority_secure256);
599 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
600 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
601 _set_priority (&(*priority_cache)->sign_algo,
602 sign_priority_secure256);
604 else if (strcasecmp (broken_list[i], "SECURE128") == 0)
606 _set_priority (&(*priority_cache)->cipher,
607 cipher_priority_secure128);
608 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
609 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
610 _set_priority (&(*priority_cache)->sign_algo,
611 sign_priority_secure128);
613 else if (strcasecmp (broken_list[i], "EXPORT") == 0)
615 _set_priority (&(*priority_cache)->cipher, cipher_priority_export);
616 _set_priority (&(*priority_cache)->kx, kx_priority_export);
617 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
618 _set_priority (&(*priority_cache)->sign_algo,
619 sign_priority_default);
620 } /* now check if the element is something like -ALGO */
621 else if (broken_list[i][0] == '!' || broken_list[i][0] == '+'
622 || broken_list[i][0] == '-')
624 if (broken_list[i][0] == '+')
626 fn = prio_add;
627 bulk_fn = _set_priority;
629 else
631 fn = prio_remove;
632 bulk_fn = _clear_priorities;
635 if ((algo =
636 gnutls_mac_get_id (&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN)
637 fn (&(*priority_cache)->mac, algo);
638 else if ((algo = gnutls_cipher_get_id (&broken_list[i][1])) !=
639 GNUTLS_CIPHER_UNKNOWN)
640 fn (&(*priority_cache)->cipher, algo);
641 else if ((algo = gnutls_kx_get_id (&broken_list[i][1])) !=
642 GNUTLS_KX_UNKNOWN)
643 fn (&(*priority_cache)->kx, algo);
644 else if (strncasecmp (&broken_list[i][1], "VERS-", 5) == 0)
646 if (strncasecmp (&broken_list[i][1], "VERS-TLS-ALL", 12) == 0)
648 bulk_fn (&(*priority_cache)->protocol,
649 protocol_priority);
651 else
653 if ((algo =
654 gnutls_protocol_get_id (&broken_list[i][6])) !=
655 GNUTLS_VERSION_UNKNOWN)
656 fn (&(*priority_cache)->protocol, algo);
657 else
658 goto error;
661 } /* now check if the element is something like -ALGO */
662 else if (strncasecmp (&broken_list[i][1], "COMP-", 5) == 0)
664 if (strncasecmp (&broken_list[i][1], "COMP-ALL", 8) == 0)
666 bulk_fn (&(*priority_cache)->compression,
667 comp_priority);
669 else
671 if ((algo =
672 gnutls_compression_get_id (&broken_list[i][6])) !=
673 GNUTLS_COMP_UNKNOWN)
674 fn (&(*priority_cache)->compression, algo);
675 else
676 goto error;
678 } /* now check if the element is something like -ALGO */
679 else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0)
681 if (strncasecmp (&broken_list[i][1], "CTYPE-ALL", 9) == 0)
683 bulk_fn (&(*priority_cache)->cert_type,
684 cert_type_priority_all);
686 else
688 if ((algo =
689 gnutls_certificate_type_get_id (&broken_list[i][7])) !=
690 GNUTLS_CRT_UNKNOWN)
691 fn (&(*priority_cache)->cert_type, algo);
692 else
693 goto error;
695 } /* now check if the element is something like -ALGO */
696 else if (strncasecmp (&broken_list[i][1], "SIGN-", 5) == 0)
698 if (strncasecmp (&broken_list[i][1], "SIGN-ALL", 8) == 0)
700 bulk_fn (&(*priority_cache)->sign_algo,
701 sign_priority_default);
703 else
705 if ((algo =
706 gnutls_sign_get_id (&broken_list[i][6])) !=
707 GNUTLS_SIGN_UNKNOWN)
708 fn (&(*priority_cache)->sign_algo, algo);
709 else
710 goto error;
713 else if (strncasecmp (&broken_list[i][1], "MAC-ALL", 7) == 0)
715 bulk_fn (&(*priority_cache)->mac,
716 mac_priority_secure);
718 else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 7) == 0)
720 bulk_fn (&(*priority_cache)->cipher,
721 cipher_priority_normal);
723 else
724 goto error;
726 else if (broken_list[i][0] == '%')
728 if (strcasecmp (&broken_list[i][1], "COMPAT") == 0)
730 (*priority_cache)->no_padding = 1;
731 (*priority_cache)->allow_large_records = 1;
733 else if (strcasecmp (&broken_list[i][1],
734 "VERIFY_ALLOW_SIGN_RSA_MD5") == 0)
736 prio_add (&(*priority_cache)->sign_algo, GNUTLS_SIGN_RSA_MD5);
737 (*priority_cache)->additional_verify_flags |=
738 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
740 else if (strcasecmp (&broken_list[i][1],
741 "SSL3_RECORD_VERSION") == 0)
742 (*priority_cache)->ssl3_record_version = 1;
743 else if (strcasecmp (&broken_list[i][1],
744 "LATEST_RECORD_VERSION") == 0)
745 (*priority_cache)->ssl3_record_version = 0;
746 else if (strcasecmp (&broken_list[i][1],
747 "VERIFY_ALLOW_X509_V1_CA_CRT") == 0)
748 (*priority_cache)->additional_verify_flags |=
749 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
750 else if (strcasecmp (&broken_list[i][1],
751 "UNSAFE_RENEGOTIATION") == 0)
753 (*priority_cache)->sr = SR_UNSAFE;
755 else if (strcasecmp (&broken_list[i][1], "SAFE_RENEGOTIATION") == 0)
757 (*priority_cache)->sr = SR_SAFE;
759 else if (strcasecmp (&broken_list[i][1],
760 "PARTIAL_RENEGOTIATION") == 0)
762 (*priority_cache)->sr = SR_PARTIAL;
764 else if (strcasecmp (&broken_list[i][1],
765 "DISABLE_SAFE_RENEGOTIATION") == 0)
767 (*priority_cache)->sr = SR_DISABLED;
769 else
770 goto error;
772 else
773 goto error;
776 gnutls_free (darg);
777 return 0;
779 error:
780 if (err_pos != NULL && i < broken_list_size)
782 *err_pos = priorities;
783 for (j = 0; j < i; j++)
785 (*err_pos) += strlen (broken_list[j]) + 1;
788 gnutls_free (darg);
789 gnutls_free (*priority_cache);
791 return GNUTLS_E_INVALID_REQUEST;
796 * gnutls_priority_deinit:
797 * @priority_cache: is a #gnutls_prioritity_t structure.
799 * Deinitializes the priority cache.
801 void
802 gnutls_priority_deinit (gnutls_priority_t priority_cache)
804 gnutls_free (priority_cache);
809 * gnutls_priority_set_direct:
810 * @session: is a #gnutls_session_t structure.
811 * @priorities: is a string describing priorities
812 * @err_pos: In case of an error this will have the position in the string the error occured
814 * Sets the priorities to use on the ciphers, key exchange methods,
815 * macs and compression methods. This function avoids keeping a
816 * priority cache and is used to directly set string priorities to a
817 * TLS session. For documentation check the gnutls_priority_init().
819 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
820 * %GNUTLS_E_SUCCESS on success, or an error code.
823 gnutls_priority_set_direct (gnutls_session_t session,
824 const char *priorities, const char **err_pos)
826 gnutls_priority_t prio;
827 int ret;
829 ret = gnutls_priority_init (&prio, priorities, err_pos);
830 if (ret < 0)
832 gnutls_assert ();
833 return ret;
836 ret = gnutls_priority_set (session, prio);
837 if (ret < 0)
839 gnutls_assert ();
840 return ret;
843 gnutls_priority_deinit (prio);
845 return 0;
848 /* Breaks a list of "xxx", "yyy", to a character array, of
849 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
851 static void
852 break_comma_list (char *etag,
853 char **broken_etag, int *elements, int max_elements,
854 char sep)
856 char *p = etag;
857 if (sep == 0)
858 sep = ',';
860 *elements = 0;
864 broken_etag[*elements] = p;
866 (*elements)++;
868 p = strchr (p, sep);
869 if (p)
871 *p = 0;
872 p++; /* move to next entry and skip white
873 * space.
875 while (*p == ' ')
876 p++;
879 while (p != NULL && *elements < max_elements);
883 * gnutls_set_default_priority:
884 * @session: is a #gnutls_session_t structure.
886 * Sets some default priority on the ciphers, key exchange methods,
887 * macs and compression methods.
889 * This is the same as calling:
891 * gnutls_priority_set_direct (session, "NORMAL", NULL);
893 * This function is kept around for backwards compatibility, but
894 * because of its wide use it is still fully supported. If you wish
895 * to allow users to provide a string that specify which ciphers to
896 * use (which is recommended), you should use
897 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
899 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
902 gnutls_set_default_priority (gnutls_session_t session)
904 return gnutls_priority_set_direct (session, "NORMAL", NULL);
908 * gnutls_set_default_export_priority:
909 * @session: is a #gnutls_session_t structure.
911 * Sets some default priority on the ciphers, key exchange methods, macs
912 * and compression methods. This function also includes weak algorithms.
914 * This is the same as calling:
916 * gnutls_priority_set_direct (session, "EXPORT", NULL);
918 * This function is kept around for backwards compatibility, but
919 * because of its wide use it is still fully supported. If you wish
920 * to allow users to provide a string that specify which ciphers to
921 * use (which is recommended), you should use
922 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
924 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
927 gnutls_set_default_export_priority (gnutls_session_t session)
929 return gnutls_priority_set_direct (session, "EXPORT", NULL);