Add `gnutls/dtls.h' to the distribution.
[gnutls.git] / lib / gnutls_priority.c
blobc91b0d33046678dcb46a58708dd5f3abd403a5aa
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,
223 GNUTLS_DTLS1_0,
227 static const int kx_priority_performance[] = {
228 GNUTLS_KX_RSA,
229 GNUTLS_KX_DHE_RSA,
230 GNUTLS_KX_DHE_DSS,
231 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
232 * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
237 static const int kx_priority_export[] = {
238 GNUTLS_KX_RSA,
239 GNUTLS_KX_DHE_RSA,
240 GNUTLS_KX_DHE_DSS,
241 GNUTLS_KX_RSA_EXPORT,
245 static const int kx_priority_secure[] = {
246 /* The ciphersuites that offer forward secrecy take
247 * precendance
249 GNUTLS_KX_DHE_RSA,
250 GNUTLS_KX_DHE_DSS,
251 GNUTLS_KX_RSA,
252 /* GNUTLS_KX_ANON_DH: Man-in-the-middle prone, don't add!
253 * GNUTLS_KX_RSA_EXPORT: Deprecated, don't add!
258 static const int cipher_priority_performance[] = {
259 GNUTLS_CIPHER_ARCFOUR_128,
260 #ifdef ENABLE_CAMELLIA
261 GNUTLS_CIPHER_CAMELLIA_128_CBC,
262 #endif
263 GNUTLS_CIPHER_AES_128_CBC,
264 GNUTLS_CIPHER_3DES_CBC,
265 GNUTLS_CIPHER_AES_256_CBC,
266 #ifdef ENABLE_CAMELLIA
267 GNUTLS_CIPHER_CAMELLIA_256_CBC,
268 #endif
269 #ifdef NETTLE_GCM
270 GNUTLS_CIPHER_AES_128_GCM,
271 #endif
275 static const int cipher_priority_normal[] = {
276 GNUTLS_CIPHER_AES_128_CBC,
277 #ifdef ENABLE_CAMELLIA
278 GNUTLS_CIPHER_CAMELLIA_128_CBC,
279 #endif
280 GNUTLS_CIPHER_AES_256_CBC,
281 #ifdef ENABLE_CAMELLIA
282 GNUTLS_CIPHER_CAMELLIA_256_CBC,
283 #endif
284 #ifdef NETTLE_GCM
285 GNUTLS_CIPHER_AES_128_GCM,
286 #endif
287 GNUTLS_CIPHER_3DES_CBC,
288 GNUTLS_CIPHER_ARCFOUR_128,
292 static const int cipher_priority_secure128[] = {
293 GNUTLS_CIPHER_AES_128_CBC,
294 #ifdef ENABLE_CAMELLIA
295 GNUTLS_CIPHER_CAMELLIA_128_CBC,
296 #endif
297 #ifdef NETTLE_GCM
298 GNUTLS_CIPHER_AES_128_GCM,
299 #endif
300 GNUTLS_CIPHER_3DES_CBC,
305 static const int cipher_priority_secure256[] = {
306 GNUTLS_CIPHER_AES_256_CBC,
307 #ifdef ENABLE_CAMELLIA
308 GNUTLS_CIPHER_CAMELLIA_256_CBC,
309 #endif
310 GNUTLS_CIPHER_AES_128_CBC,
311 #ifdef ENABLE_CAMELLIA
312 GNUTLS_CIPHER_CAMELLIA_128_CBC,
313 #endif
314 #ifdef NETTLE_GCM
315 GNUTLS_CIPHER_AES_128_GCM,
316 #endif
317 GNUTLS_CIPHER_3DES_CBC,
321 /* The same as cipher_priority_security_normal + arcfour-40. */
322 static const int cipher_priority_export[] = {
323 GNUTLS_CIPHER_AES_128_CBC,
324 GNUTLS_CIPHER_AES_256_CBC,
325 #ifdef ENABLE_CAMELLIA
326 GNUTLS_CIPHER_CAMELLIA_128_CBC,
327 GNUTLS_CIPHER_CAMELLIA_256_CBC,
328 #endif
329 GNUTLS_CIPHER_AES_128_GCM,
330 GNUTLS_CIPHER_3DES_CBC,
331 GNUTLS_CIPHER_ARCFOUR_128,
332 GNUTLS_CIPHER_ARCFOUR_40,
336 static const int comp_priority[] = {
337 /* compression should be explicitely requested to be enabled */
338 GNUTLS_COMP_NULL,
342 static const int sign_priority_default[] = {
343 GNUTLS_SIGN_DSA_SHA224,
344 GNUTLS_SIGN_DSA_SHA256,
345 GNUTLS_SIGN_RSA_SHA256,
346 GNUTLS_SIGN_RSA_SHA384,
347 GNUTLS_SIGN_RSA_SHA512,
348 GNUTLS_SIGN_RSA_SHA1,
349 GNUTLS_SIGN_DSA_SHA1,
353 static const int sign_priority_secure128[] = {
354 GNUTLS_SIGN_RSA_SHA256,
355 GNUTLS_SIGN_RSA_SHA384,
356 GNUTLS_SIGN_RSA_SHA512,
357 GNUTLS_SIGN_DSA_SHA1,
361 static const int sign_priority_secure256[] = {
362 GNUTLS_SIGN_RSA_SHA512,
366 static const int mac_priority_performance[] = {
367 GNUTLS_MAC_SHA1,
368 GNUTLS_MAC_SHA256,
369 GNUTLS_MAC_AEAD,
374 static const int mac_priority_secure[] = {
375 GNUTLS_MAC_SHA256,
376 GNUTLS_MAC_AEAD,
377 GNUTLS_MAC_SHA1,
381 static int cert_type_priority[] = {
382 GNUTLS_CRT_X509,
383 GNUTLS_CRT_OPENPGP,
387 typedef void (rmadd_func) (priority_st * priority_list, unsigned int alg);
389 static void
390 prio_remove (priority_st * priority_list, unsigned int algo)
392 int i = 0;
393 int pos = -1; /* the position of the cipher to remove */
395 while (priority_list->priority[i] != 0)
397 if (priority_list->priority[i] == algo)
398 pos = i;
399 i++;
402 if (pos >= 0)
404 priority_list->priority[pos] = priority_list->priority[i - 1];
405 priority_list->priority[i - 1] = 0;
406 priority_list->algorithms--;
409 return;
412 static void
413 prio_add (priority_st * priority_list, unsigned int algo)
415 register int i = 0;
416 while (priority_list->priority[i] != 0)
418 if (algo == priority_list->priority[i])
419 return; /* if it exists */
420 i++;
423 if (i < MAX_ALGOS)
425 priority_list->priority[i] = algo;
426 priority_list->algorithms++;
429 return;
434 * gnutls_priority_set:
435 * @session: is a #gnutls_session_t structure.
436 * @priority: is a #gnutls_priority_t structure.
438 * Sets the priorities to use on the ciphers, key exchange methods,
439 * macs and compression methods.
441 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
444 gnutls_priority_set (gnutls_session_t session, gnutls_priority_t priority)
446 if (priority == NULL)
448 gnutls_assert ();
449 return GNUTLS_E_NO_CIPHER_SUITES;
452 memcpy (&session->internals.priorities, priority,
453 sizeof (struct gnutls_priority_st));
455 /* set the current version to the first in the chain.
456 * This will be overridden later.
458 if (session->internals.priorities.protocol.algorithms > 0)
459 _gnutls_set_current_version (session,
460 session->internals.priorities.protocol.
461 priority[0]);
463 return 0;
467 #define MAX_ELEMENTS 48
470 * gnutls_priority_init:
471 * @priority_cache: is a #gnutls_prioritity_t structure.
472 * @priorities: is a string describing priorities
473 * @err_pos: In case of an error this will have the position in the string the error occured
475 * Sets priorities for the ciphers, key exchange methods, macs and
476 * compression methods.
478 * The #priorities option allows you to specify a colon
479 * separated list of the cipher priorities to enable.
481 * Common keywords: Some keywords are defined to provide quick access
482 * to common preferences.
484 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
485 * limited to 128 bit ciphers and sorted by terms of speed
486 * performance.
488 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
489 * included as a fallback only. The ciphers are sorted by security
490 * margin.
492 * "SECURE128" means all "secure" ciphersuites with ciphers up to 128
493 * bits, sorted by security margin.
495 * "SECURE256" means all "secure" ciphersuites including the 256 bit
496 * ciphers, sorted by security margin.
498 * "EXPORT" means all ciphersuites are enabled, including the
499 * low-security 40 bit ciphers.
501 * "NONE" means nothing is enabled. This disables even protocols and
502 * compression methods.
504 * Special keywords:
505 * "!" or "-" appended with an algorithm will remove this algorithm.
507 * "+" appended with an algorithm will add this algorithm.
509 * Check the GnuTLS manual section "Priority strings" for detailed
510 * information.
512 * Examples:
514 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
516 * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128.
518 * "SECURE:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
519 * enabled, SSL3.0 is disabled, and libz compression enabled.
521 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1",
523 * "NORMAL:%COMPAT" is the most compatible mode.
525 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
526 * %GNUTLS_E_SUCCESS on success, or an error code.
529 gnutls_priority_init (gnutls_priority_t * priority_cache,
530 const char *priorities, const char **err_pos)
532 char *broken_list[MAX_ELEMENTS];
533 int broken_list_size = 0, i = 0, j;
534 char *darg = NULL;
535 int algo;
536 rmadd_func *fn;
537 bulk_rmadd_func *bulk_fn;
539 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
540 if (*priority_cache == NULL)
542 gnutls_assert ();
543 return GNUTLS_E_MEMORY_ERROR;
546 /* for now unsafe renegotiation is default on everyone. To be removed
547 * when we make it the default.
549 (*priority_cache)->sr = SR_PARTIAL;
551 if (priorities == NULL)
552 priorities = "NORMAL";
554 darg = gnutls_strdup (priorities);
555 if (darg == NULL)
557 gnutls_assert ();
558 goto error;
561 break_comma_list (darg, broken_list, &broken_list_size, MAX_ELEMENTS, ':');
562 /* This is our default set of protocol version, certificate types and
563 * compression methods.
565 if (strcasecmp (broken_list[0], "NONE") != 0)
567 _set_priority (&(*priority_cache)->protocol, protocol_priority);
568 _set_priority (&(*priority_cache)->compression, comp_priority);
569 _set_priority (&(*priority_cache)->cert_type, cert_type_priority);
570 _set_priority (&(*priority_cache)->sign_algo, sign_priority_default);
571 i = 0;
573 else
575 i = 1;
578 for (; i < broken_list_size; i++)
580 if (strcasecmp (broken_list[i], "PERFORMANCE") == 0)
582 _set_priority (&(*priority_cache)->cipher,
583 cipher_priority_performance);
584 _set_priority (&(*priority_cache)->kx, kx_priority_performance);
585 _set_priority (&(*priority_cache)->mac, mac_priority_performance);
586 _set_priority (&(*priority_cache)->sign_algo,
587 sign_priority_default);
589 else if (strcasecmp (broken_list[i], "NORMAL") == 0)
591 _set_priority (&(*priority_cache)->cipher, cipher_priority_normal);
592 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
593 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
594 _set_priority (&(*priority_cache)->sign_algo,
595 sign_priority_default);
597 else if (strcasecmp (broken_list[i], "SECURE256") == 0
598 || strcasecmp (broken_list[i], "SECURE") == 0)
600 _set_priority (&(*priority_cache)->cipher,
601 cipher_priority_secure256);
602 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
603 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
604 _set_priority (&(*priority_cache)->sign_algo,
605 sign_priority_secure256);
607 else if (strcasecmp (broken_list[i], "SECURE128") == 0)
609 _set_priority (&(*priority_cache)->cipher,
610 cipher_priority_secure128);
611 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
612 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
613 _set_priority (&(*priority_cache)->sign_algo,
614 sign_priority_secure128);
616 else if (strcasecmp (broken_list[i], "EXPORT") == 0)
618 _set_priority (&(*priority_cache)->cipher, cipher_priority_export);
619 _set_priority (&(*priority_cache)->kx, kx_priority_export);
620 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
621 _set_priority (&(*priority_cache)->sign_algo,
622 sign_priority_default);
623 } /* now check if the element is something like -ALGO */
624 else if (broken_list[i][0] == '!' || broken_list[i][0] == '+'
625 || broken_list[i][0] == '-')
627 if (broken_list[i][0] == '+')
629 fn = prio_add;
630 bulk_fn = _set_priority;
632 else
634 fn = prio_remove;
635 bulk_fn = _clear_priorities;
638 if ((algo =
639 gnutls_mac_get_id (&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN)
640 fn (&(*priority_cache)->mac, algo);
641 else if ((algo = gnutls_cipher_get_id (&broken_list[i][1])) !=
642 GNUTLS_CIPHER_UNKNOWN)
643 fn (&(*priority_cache)->cipher, algo);
644 else if ((algo = gnutls_kx_get_id (&broken_list[i][1])) !=
645 GNUTLS_KX_UNKNOWN)
646 fn (&(*priority_cache)->kx, algo);
647 else if (strncasecmp (&broken_list[i][1], "VERS-", 5) == 0)
649 if (strncasecmp (&broken_list[i][1], "VERS-TLS-ALL", 12) == 0)
651 bulk_fn (&(*priority_cache)->protocol,
652 protocol_priority);
654 else
656 if ((algo =
657 gnutls_protocol_get_id (&broken_list[i][6])) !=
658 GNUTLS_VERSION_UNKNOWN)
659 fn (&(*priority_cache)->protocol, algo);
660 else
661 goto error;
664 } /* now check if the element is something like -ALGO */
665 else if (strncasecmp (&broken_list[i][1], "COMP-", 5) == 0)
667 if (strncasecmp (&broken_list[i][1], "COMP-ALL", 8) == 0)
669 bulk_fn (&(*priority_cache)->compression,
670 comp_priority);
672 else
674 if ((algo =
675 gnutls_compression_get_id (&broken_list[i][6])) !=
676 GNUTLS_COMP_UNKNOWN)
677 fn (&(*priority_cache)->compression, algo);
678 else
679 goto error;
681 } /* now check if the element is something like -ALGO */
682 else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0)
684 if (strncasecmp (&broken_list[i][1], "CTYPE-ALL", 9) == 0)
686 bulk_fn (&(*priority_cache)->cert_type,
687 cert_type_priority);
689 else
691 if ((algo =
692 gnutls_certificate_type_get_id (&broken_list[i][7])) !=
693 GNUTLS_CRT_UNKNOWN)
694 fn (&(*priority_cache)->cert_type, algo);
695 else
696 goto error;
698 } /* now check if the element is something like -ALGO */
699 else if (strncasecmp (&broken_list[i][1], "SIGN-", 5) == 0)
701 if (strncasecmp (&broken_list[i][1], "SIGN-ALL", 8) == 0)
703 bulk_fn (&(*priority_cache)->sign_algo,
704 sign_priority_default);
706 else
708 if ((algo =
709 gnutls_sign_get_id (&broken_list[i][6])) !=
710 GNUTLS_SIGN_UNKNOWN)
711 fn (&(*priority_cache)->sign_algo, algo);
712 else
713 goto error;
716 else if (strncasecmp (&broken_list[i][1], "MAC-ALL", 7) == 0)
718 bulk_fn (&(*priority_cache)->mac,
719 mac_priority_secure);
721 else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 7) == 0)
723 bulk_fn (&(*priority_cache)->cipher,
724 cipher_priority_normal);
726 else
727 goto error;
729 else if (broken_list[i][0] == '%')
731 if (strcasecmp (&broken_list[i][1], "COMPAT") == 0)
733 (*priority_cache)->no_padding = 1;
734 (*priority_cache)->allow_large_records = 1;
736 else if (strcasecmp (&broken_list[i][1],
737 "VERIFY_ALLOW_SIGN_RSA_MD5") == 0)
739 prio_add (&(*priority_cache)->sign_algo, GNUTLS_SIGN_RSA_MD5);
740 (*priority_cache)->additional_verify_flags |=
741 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
743 else if (strcasecmp (&broken_list[i][1],
744 "SSL3_RECORD_VERSION") == 0)
745 (*priority_cache)->no_ssl3_record_version = 0;
746 else if (strcasecmp (&broken_list[i][1],
747 "LATEST_RECORD_VERSION") == 0)
748 (*priority_cache)->no_ssl3_record_version = 1;
749 else if (strcasecmp (&broken_list[i][1],
750 "VERIFY_ALLOW_X509_V1_CA_CRT") == 0)
751 (*priority_cache)->additional_verify_flags |=
752 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
753 else if (strcasecmp (&broken_list[i][1],
754 "UNSAFE_RENEGOTIATION") == 0)
756 (*priority_cache)->sr = SR_UNSAFE;
758 else if (strcasecmp (&broken_list[i][1], "SAFE_RENEGOTIATION") == 0)
760 (*priority_cache)->sr = SR_SAFE;
762 else if (strcasecmp (&broken_list[i][1],
763 "PARTIAL_RENEGOTIATION") == 0)
765 (*priority_cache)->sr = SR_PARTIAL;
767 else if (strcasecmp (&broken_list[i][1],
768 "DISABLE_SAFE_RENEGOTIATION") == 0)
770 (*priority_cache)->sr = SR_DISABLED;
772 else
773 goto error;
775 else
776 goto error;
779 gnutls_free (darg);
780 return 0;
782 error:
783 if (err_pos != NULL && i < broken_list_size)
785 *err_pos = priorities;
786 for (j = 0; j < i; j++)
788 (*err_pos) += strlen (broken_list[j]) + 1;
791 gnutls_free (darg);
792 gnutls_free (*priority_cache);
794 return GNUTLS_E_INVALID_REQUEST;
799 * gnutls_priority_deinit:
800 * @priority_cache: is a #gnutls_prioritity_t structure.
802 * Deinitializes the priority cache.
804 void
805 gnutls_priority_deinit (gnutls_priority_t priority_cache)
807 gnutls_free (priority_cache);
812 * gnutls_priority_set_direct:
813 * @session: is a #gnutls_session_t structure.
814 * @priorities: is a string describing priorities
815 * @err_pos: In case of an error this will have the position in the string the error occured
817 * Sets the priorities to use on the ciphers, key exchange methods,
818 * macs and compression methods. This function avoids keeping a
819 * priority cache and is used to directly set string priorities to a
820 * TLS session. For documentation check the gnutls_priority_init().
822 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
823 * %GNUTLS_E_SUCCESS on success, or an error code.
826 gnutls_priority_set_direct (gnutls_session_t session,
827 const char *priorities, const char **err_pos)
829 gnutls_priority_t prio;
830 int ret;
832 ret = gnutls_priority_init (&prio, priorities, err_pos);
833 if (ret < 0)
835 gnutls_assert ();
836 return ret;
839 ret = gnutls_priority_set (session, prio);
840 if (ret < 0)
842 gnutls_assert ();
843 return ret;
846 gnutls_priority_deinit (prio);
848 return 0;
851 /* Breaks a list of "xxx", "yyy", to a character array, of
852 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
854 static void
855 break_comma_list (char *etag,
856 char **broken_etag, int *elements, int max_elements,
857 char sep)
859 char *p = etag;
860 if (sep == 0)
861 sep = ',';
863 *elements = 0;
867 broken_etag[*elements] = p;
869 (*elements)++;
871 p = strchr (p, sep);
872 if (p)
874 *p = 0;
875 p++; /* move to next entry and skip white
876 * space.
878 while (*p == ' ')
879 p++;
882 while (p != NULL && *elements < max_elements);
886 * gnutls_set_default_priority:
887 * @session: is a #gnutls_session_t structure.
889 * Sets some default priority on the ciphers, key exchange methods,
890 * macs and compression methods.
892 * This is the same as calling:
894 * gnutls_priority_set_direct (session, "NORMAL", NULL);
896 * This function is kept around for backwards compatibility, but
897 * because of its wide use it is still fully supported. If you wish
898 * to allow users to provide a string that specify which ciphers to
899 * use (which is recommended), you should use
900 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
902 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
905 gnutls_set_default_priority (gnutls_session_t session)
907 return gnutls_priority_set_direct (session, "NORMAL", NULL);
911 * gnutls_set_default_export_priority:
912 * @session: is a #gnutls_session_t structure.
914 * Sets some default priority on the ciphers, key exchange methods, macs
915 * and compression methods. This function also includes weak algorithms.
917 * This is the same as calling:
919 * gnutls_priority_set_direct (session, "EXPORT", NULL);
921 * This function is kept around for backwards compatibility, but
922 * because of its wide use it is still fully supported. If you wish
923 * to allow users to provide a string that specify which ciphers to
924 * use (which is recommended), you should use
925 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
927 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
930 gnutls_set_default_export_priority (gnutls_session_t session)
932 return gnutls_priority_set_direct (session, "EXPORT", NULL);