corrected call to gnutls_error_is_fatal().
[gnutls.git] / lib / algorithms / protocols.c
bloba152901a5dec008b5558f53e7d19cec829c030bd
1 /*
2 * Copyright (C) 2011-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 #include <gnutls_int.h>
24 #include <algorithms.h>
25 #include <gnutls_errors.h>
26 #include <x509/common.h>
29 /* TLS Versions */
31 typedef struct
33 const char *name;
34 gnutls_protocol_t id; /* gnutls internal version number */
35 int major; /* defined by the protocol */
36 int minor; /* defined by the protocol */
37 transport_t transport; /* Type of transport, stream or datagram */
38 int supported; /* 0 not supported, > 0 is supported */
39 } gnutls_version_entry;
41 static const gnutls_version_entry sup_versions[] = {
42 {"SSL3.0", GNUTLS_SSL3, 3, 0, GNUTLS_STREAM, 1},
43 {"TLS1.0", GNUTLS_TLS1, 3, 1, GNUTLS_STREAM, 1},
44 {"TLS1.1", GNUTLS_TLS1_1, 3, 2, GNUTLS_STREAM, 1},
45 {"TLS1.2", GNUTLS_TLS1_2, 3, 3, GNUTLS_STREAM, 1},
46 {"DTLS1.0", GNUTLS_DTLS1_0, 254, 255, GNUTLS_DGRAM, 1}, /* 1.1 over datagram */
47 {0, 0, 0, 0, 0}
50 #define GNUTLS_VERSION_LOOP(b) \
51 const gnutls_version_entry *p; \
52 for(p = sup_versions; p->name != NULL; p++) { b ; }
54 #define GNUTLS_VERSION_ALG_LOOP(a) \
55 GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
57 /* Return the priority of the provided version number */
58 int
59 _gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version)
61 unsigned int i;
63 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
65 if (session->internals.priorities.protocol.priority[i] == version)
66 return i;
68 return -1;
71 /* Returns the lowest TLS version number in the priorities.
73 gnutls_protocol_t
74 _gnutls_version_lowest (gnutls_session_t session)
76 unsigned int i, min = 0xff;
77 gnutls_protocol_t cur_prot;
79 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
81 cur_prot = session->internals.priorities.protocol.priority[i];
83 if (cur_prot < min && _gnutls_version_is_supported(session, cur_prot))
84 min = cur_prot;
87 if (min == 0xff)
88 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
90 return min;
93 /* Returns the maximum version in the priorities
95 gnutls_protocol_t
96 _gnutls_version_max (gnutls_session_t session)
98 unsigned int i, max = 0x00;
99 gnutls_protocol_t cur_prot;
101 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
103 cur_prot = session->internals.priorities.protocol.priority[i];
105 if (cur_prot > max && _gnutls_version_is_supported(session, cur_prot))
106 max = cur_prot;
109 if (max == 0x00)
110 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
112 return max;
117 * gnutls_protocol_get_name:
118 * @version: is a (gnutls) version number
120 * Convert a #gnutls_protocol_t value to a string.
122 * Returns: a string that contains the name of the specified TLS
123 * version (e.g., "TLS1.0"), or %NULL.
125 const char *
126 gnutls_protocol_get_name (gnutls_protocol_t version)
128 const char *ret = NULL;
130 /* avoid prefix */
131 GNUTLS_VERSION_ALG_LOOP (ret = p->name);
132 return ret;
136 * gnutls_protocol_get_id:
137 * @name: is a protocol name
139 * The names are compared in a case insensitive way.
141 * Returns: an id of the specified protocol, or
142 * %GNUTLS_VERSION_UNKNOWN on error.
144 gnutls_protocol_t
145 gnutls_protocol_get_id (const char *name)
147 gnutls_protocol_t ret = GNUTLS_VERSION_UNKNOWN;
149 GNUTLS_VERSION_LOOP (
150 if (strcasecmp (p->name, name) == 0)
152 ret = p->id;
153 break;
157 return ret;
161 * gnutls_protocol_list:
163 * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
165 * This function is not thread safe.
167 * Returns: a (0)-terminated list of #gnutls_protocol_t integers
168 * indicating the available protocols.
171 const gnutls_protocol_t *
172 gnutls_protocol_list (void)
174 static gnutls_protocol_t supported_protocols[MAX_ALGOS] = {0};
176 if (supported_protocols[0] == 0)
178 int i = 0;
180 GNUTLS_VERSION_LOOP (supported_protocols[i++]=p->id);
181 supported_protocols[i++]=0;
184 return supported_protocols;
188 _gnutls_version_get_minor (gnutls_protocol_t version)
190 int ret = -1;
192 GNUTLS_VERSION_ALG_LOOP (ret = p->minor);
193 return ret;
196 /* Returns a version number given the major and minor numbers.
198 gnutls_protocol_t
199 _gnutls_version_get (int major, int minor)
201 int ret = -1;
203 GNUTLS_VERSION_LOOP (if ((p->major == major) && (p->minor == minor))
204 ret = p->id);
205 return ret;
209 _gnutls_version_get_major (gnutls_protocol_t version)
211 int ret = -1;
213 GNUTLS_VERSION_ALG_LOOP (ret = p->major);
214 return ret;
217 /* Version Functions */
220 _gnutls_version_is_supported (gnutls_session_t session,
221 const gnutls_protocol_t version)
223 int ret = 0;
225 GNUTLS_VERSION_ALG_LOOP (ret = p->supported && p->transport == session->internals.transport);
227 if (ret == 0)
228 return 0;
230 if (_gnutls_version_priority (session, version) < 0)
231 return 0; /* disabled by the user */
232 else
233 return 1;
237 /* This function determines if the version specified has a
238 cipher-suite selected PRF hash function instead of the old
239 hardcoded MD5+SHA1. */
241 _gnutls_version_has_selectable_prf (gnutls_protocol_t version)
243 switch (version)
245 case GNUTLS_DTLS1_0:
246 case GNUTLS_TLS1_1:
247 case GNUTLS_TLS1_0:
248 case GNUTLS_SSL3:
249 return 0;
250 default:
251 return 1;
255 /* This function determines if the version specified has selectable
256 signature/hash functions for certificate authentification. */
258 _gnutls_version_has_selectable_sighash (gnutls_protocol_t version)
260 switch (version)
262 case GNUTLS_DTLS1_0:
263 case GNUTLS_TLS1_1:
264 case GNUTLS_TLS1_0:
265 case GNUTLS_SSL3:
266 return 0;
267 default:
268 return 1;
272 /* This function determines if the version specified has support for
273 TLS extensions. */
275 _gnutls_version_has_extensions (gnutls_protocol_t version)
277 switch (version)
279 case GNUTLS_SSL3:
280 return 0;
281 default:
282 /* Versions after TLS 1.0 are required to handle extensions.
283 * SSL 3.0 also required extensions to be ignored, but
284 * some earlier draft didn't.
286 return 1;
290 /* This function determines if the version specified has explicit IVs
291 (for CBC attack prevention). */
293 _gnutls_version_has_explicit_iv (gnutls_protocol_t version)
295 switch (version)
297 case GNUTLS_TLS1_0:
298 case GNUTLS_SSL3:
299 return 0;
300 default:
301 /* All versions after TLS 1.1 have explicit IV */
302 return 1;