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.
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
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
},
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
85 gnutls_kx_algorithm_t algorithm
;
86 mod_auth_st
*auth_struct
;
90 typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry
;
92 static const gnutls_kx_algo_entry _gnutls_kx_algorithms
[] = {
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},
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},
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},
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},
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 */
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
);
139 _gnutls_kx_priority (gnutls_session_t session
,
140 gnutls_kx_algorithm_t algorithm
)
143 for (i
= 0; i
< session
->internals
.priorities
.kx
.algorithms
; i
++)
145 if (session
->internals
.priorities
.kx
.priority
[i
] == algorithm
)
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.
161 gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm
)
163 const char *ret
= NULL
;
166 GNUTLS_KX_ALG_LOOP (ret
= p
->name
);
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
181 gnutls_kx_algorithm_t
182 gnutls_kx_get_id (const char *name
)
184 gnutls_kx_algorithm_t ret
= GNUTLS_KX_UNKNOWN
;
187 if (strcasecmp (p
->name
, name
) == 0)
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)
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
)
227 GNUTLS_KX_ALG_LOOP (ret
= p
->algorithm
);
236 _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm
)
239 GNUTLS_KX_ALG_LOOP (ret
= p
->needs_rsa_params
);
244 _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm
)
247 GNUTLS_KX_ALG_LOOP (ret
= p
->needs_dh_params
);
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;
259 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret
= p
->algorithm
);
263 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret
= p
->algorithm
);
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;
277 GNUTLS_KX_MAP_LOOP (if (p
->algorithm
== algorithm
) ret
=
282 GNUTLS_KX_MAP_LOOP (if (p
->algorithm
== algorithm
) ret
=