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>
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 */
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 */
59 _gnutls_version_priority (gnutls_session_t session
, gnutls_protocol_t version
)
63 for (i
= 0; i
< session
->internals
.priorities
.protocol
.algorithms
; i
++)
65 if (session
->internals
.priorities
.protocol
.priority
[i
] == version
)
71 /* Returns the lowest TLS version number in the priorities.
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
))
88 return GNUTLS_VERSION_UNKNOWN
; /* unknown version */
93 /* Returns the maximum version in the priorities
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
))
110 return GNUTLS_VERSION_UNKNOWN
; /* unknown version */
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.
126 gnutls_protocol_get_name (gnutls_protocol_t version
)
128 const char *ret
= NULL
;
131 GNUTLS_VERSION_ALG_LOOP (ret
= p
->name
);
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.
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)
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)
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
)
192 GNUTLS_VERSION_ALG_LOOP (ret
= p
->minor
);
196 /* Returns a version number given the major and minor numbers.
199 _gnutls_version_get (int major
, int minor
)
203 GNUTLS_VERSION_LOOP (if ((p
->major
== major
) && (p
->minor
== minor
))
209 _gnutls_version_get_major (gnutls_protocol_t version
)
213 GNUTLS_VERSION_ALG_LOOP (ret
= p
->major
);
217 /* Version Functions */
220 _gnutls_version_is_supported (gnutls_session_t session
,
221 const gnutls_protocol_t version
)
225 GNUTLS_VERSION_ALG_LOOP (ret
= p
->supported
&& p
->transport
== session
->internals
.transport
);
230 if (_gnutls_version_priority (session
, version
) < 0)
231 return 0; /* disabled by the user */
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
)
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
)
272 /* This function determines if the version specified has support for
275 _gnutls_version_has_extensions (gnutls_protocol_t version
)
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.
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
)
301 /* All versions after TLS 1.1 have explicit IV */