cleaned up errno handling.
[gnutls.git] / lib / algorithms / kx.c
blob23811744d1064a5cb64ecb8953ff5e9022da50d1
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 extern mod_auth_st rsa_auth_struct;
30 extern mod_auth_st rsa_export_auth_struct;
31 extern mod_auth_st dhe_rsa_auth_struct;
32 extern mod_auth_st ecdhe_rsa_auth_struct;
33 extern mod_auth_st ecdhe_psk_auth_struct;
34 extern mod_auth_st ecdhe_ecdsa_auth_struct;
35 extern mod_auth_st dhe_dss_auth_struct;
36 extern mod_auth_st anon_auth_struct;
37 extern mod_auth_st anon_ecdh_auth_struct;
38 extern mod_auth_st srp_auth_struct;
39 extern mod_auth_st psk_auth_struct;
40 extern mod_auth_st dhe_psk_auth_struct;
41 extern mod_auth_st srp_rsa_auth_struct;
42 extern mod_auth_st srp_dss_auth_struct;
45 /* Cred type mappings to KX algorithms
46 * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
47 * more than one credentials type.
49 typedef struct
51 gnutls_kx_algorithm_t algorithm;
52 gnutls_credentials_type_t client_type;
53 gnutls_credentials_type_t server_type; /* The type of credentials a server
54 * needs to set */
55 } gnutls_cred_map;
57 static const gnutls_cred_map cred_mappings[] = {
58 {GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON, GNUTLS_CRD_ANON},
59 {GNUTLS_KX_ANON_ECDH, GNUTLS_CRD_ANON, GNUTLS_CRD_ANON},
60 {GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
61 {GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
62 {GNUTLS_KX_ECDHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
63 {GNUTLS_KX_ECDHE_ECDSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
64 {GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
65 {GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
66 {GNUTLS_KX_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
67 {GNUTLS_KX_DHE_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
68 {GNUTLS_KX_ECDHE_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
69 {GNUTLS_KX_SRP, GNUTLS_CRD_SRP, GNUTLS_CRD_SRP},
70 {GNUTLS_KX_SRP_RSA, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE},
71 {GNUTLS_KX_SRP_DSS, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE},
72 {0, 0, 0}
75 #define GNUTLS_KX_MAP_LOOP(b) \
76 const gnutls_cred_map *p; \
77 for(p = cred_mappings; p->algorithm != 0; p++) { b ; }
79 #define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
80 GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
82 struct gnutls_kx_algo_entry
84 const char *name;
85 gnutls_kx_algorithm_t algorithm;
86 mod_auth_st *auth_struct;
87 int needs_dh_params;
88 int needs_rsa_params;
90 typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
92 static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
93 #ifdef ENABLE_ANON
94 {"ANON-DH", GNUTLS_KX_ANON_DH, &anon_auth_struct, 1, 0},
95 {"ANON-ECDH", GNUTLS_KX_ANON_ECDH, &anon_ecdh_auth_struct, 0, 0},
96 #endif
97 {"RSA", GNUTLS_KX_RSA, &rsa_auth_struct, 0, 0},
98 {"RSA-EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct, 0,
99 1 /* needs RSA params */ },
100 {"DHE-RSA", GNUTLS_KX_DHE_RSA, &dhe_rsa_auth_struct, 1, 0},
101 {"ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, &ecdhe_rsa_auth_struct, 0, 0},
102 {"ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, &ecdhe_ecdsa_auth_struct, 0, 0},
103 {"DHE-DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0},
105 #ifdef ENABLE_SRP
106 {"SRP-DSS", GNUTLS_KX_SRP_DSS, &srp_dss_auth_struct, 0, 0},
107 {"SRP-RSA", GNUTLS_KX_SRP_RSA, &srp_rsa_auth_struct, 0, 0},
108 {"SRP", GNUTLS_KX_SRP, &srp_auth_struct, 0, 0},
109 #endif
110 #ifdef ENABLE_PSK
111 {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
112 {"DHE-PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
113 1 /* needs DHE params */ , 0},
114 {"ECDHE-PSK", GNUTLS_KX_ECDHE_PSK, &ecdhe_psk_auth_struct, 0 , 0},
115 #endif
116 {0, 0, 0, 0, 0}
119 #define GNUTLS_KX_LOOP(b) \
120 const gnutls_kx_algo_entry *p; \
121 for(p = _gnutls_kx_algorithms; p->name != NULL; p++) { b ; }
123 #define GNUTLS_KX_ALG_LOOP(a) \
124 GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } )
127 /* Key EXCHANGE functions */
128 mod_auth_st *
129 _gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm)
131 mod_auth_st *ret = NULL;
132 GNUTLS_KX_ALG_LOOP (ret = p->auth_struct);
133 return ret;
139 _gnutls_kx_priority (gnutls_session_t session,
140 gnutls_kx_algorithm_t algorithm)
142 unsigned int i;
143 for (i = 0; i < session->internals.priorities.kx.algorithms; i++)
145 if (session->internals.priorities.kx.priority[i] == algorithm)
146 return i;
148 return -1;
152 * gnutls_kx_get_name:
153 * @algorithm: is a key exchange algorithm
155 * Convert a #gnutls_kx_algorithm_t value to a string.
157 * Returns: a pointer to a string that contains the name of the
158 * specified key exchange algorithm, or %NULL.
160 const char *
161 gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm)
163 const char *ret = NULL;
165 /* avoid prefix */
166 GNUTLS_KX_ALG_LOOP (ret = p->name);
168 return ret;
172 * gnutls_kx_get_id:
173 * @name: is a KX name
175 * Convert a string to a #gnutls_kx_algorithm_t value. The names are
176 * compared in a case insensitive way.
178 * Returns: an id of the specified KX algorithm, or %GNUTLS_KX_UNKNOWN
179 * on error.
181 gnutls_kx_algorithm_t
182 gnutls_kx_get_id (const char *name)
184 gnutls_kx_algorithm_t ret = GNUTLS_KX_UNKNOWN;
186 GNUTLS_KX_LOOP (
187 if (strcasecmp (p->name, name) == 0)
189 ret = p->algorithm;
190 break;
194 return ret;
198 * gnutls_kx_list:
200 * Get a list of supported key exchange algorithms.
202 * This function is not thread safe.
204 * Returns: a (0)-terminated list of #gnutls_kx_algorithm_t integers
205 * indicating the available key exchange algorithms.
207 const gnutls_kx_algorithm_t *
208 gnutls_kx_list (void)
210 static gnutls_kx_algorithm_t supported_kxs[MAX_ALGOS] = {0};
212 if (supported_kxs[0] == 0)
214 int i = 0;
216 GNUTLS_KX_LOOP (supported_kxs[i++]=p->algorithm);
217 supported_kxs[i++]=0;
220 return supported_kxs;
224 _gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm)
226 ssize_t ret = -1;
227 GNUTLS_KX_ALG_LOOP (ret = p->algorithm);
228 if (ret >= 0)
229 ret = 0;
230 else
231 ret = 1;
232 return ret;
236 _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm)
238 ssize_t ret = 0;
239 GNUTLS_KX_ALG_LOOP (ret = p->needs_rsa_params);
240 return ret;
244 _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm)
246 ssize_t ret = 0;
247 GNUTLS_KX_ALG_LOOP (ret = p->needs_dh_params);
248 return ret;
251 /* Type to KX mappings */
252 gnutls_kx_algorithm_t
253 _gnutls_map_kx_get_kx (gnutls_credentials_type_t type, int server)
255 gnutls_kx_algorithm_t ret = -1;
257 if (server)
259 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
261 else
263 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
265 return ret;
268 /* Returns the credentials type required for this
269 * Key exchange method.
271 gnutls_credentials_type_t
272 _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t algorithm, int server)
274 gnutls_credentials_type_t ret = -1;
275 if (server)
277 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret =
278 p->server_type);
280 else
282 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret =
283 p->client_type);
286 return ret;