Line data Source code
1 : /*
2 : * Copyright (C) 2017 Red Hat, Inc.
3 : *
4 : * Author: Nikos Mavrogiannopoulos
5 : *
6 : * This file is part of GnuTLS.
7 : *
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 2.1 of
11 : * the License, or (at your option) any later version.
12 : *
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.
17 : *
18 : * You should have received a copy of the GNU Lesser General Public License
19 : * along with this program. If not, see <https://www.gnu.org/licenses/>
20 : *
21 : */
22 :
23 : #include "gnutls_int.h"
24 : #include <algorithms.h>
25 : #include "errors.h"
26 : #include <x509/common.h>
27 : #include <pk.h>
28 : #include "c-strcase.h"
29 :
30 : /* Supported ECC curves
31 : */
32 :
33 : static const gnutls_group_entry_st supported_groups[] = {
34 : {
35 : .name = "SECP192R1",
36 : .id = GNUTLS_GROUP_SECP192R1,
37 : .curve = GNUTLS_ECC_CURVE_SECP192R1,
38 : .tls_id = 19,
39 : .pk = GNUTLS_PK_ECDSA,
40 : },
41 : {
42 : .name = "SECP224R1",
43 : .id = GNUTLS_GROUP_SECP224R1,
44 : .curve = GNUTLS_ECC_CURVE_SECP224R1,
45 : .tls_id = 21,
46 : .pk = GNUTLS_PK_ECDSA,
47 : },
48 : {
49 : .name = "SECP256R1",
50 : .id = GNUTLS_GROUP_SECP256R1,
51 : .curve = GNUTLS_ECC_CURVE_SECP256R1,
52 : .tls_id = 23,
53 : .pk = GNUTLS_PK_ECDSA,
54 : },
55 : {
56 : .name = "SECP384R1",
57 : .id = GNUTLS_GROUP_SECP384R1,
58 : .curve = GNUTLS_ECC_CURVE_SECP384R1,
59 : .tls_id = 24,
60 : .pk = GNUTLS_PK_ECDSA,
61 : },
62 : {
63 : .name = "SECP521R1",
64 : .id = GNUTLS_GROUP_SECP521R1,
65 : .curve = GNUTLS_ECC_CURVE_SECP521R1,
66 : .tls_id = 25,
67 : .pk = GNUTLS_PK_ECDSA,
68 : },
69 : {
70 : .name = "X25519",
71 : .id = GNUTLS_GROUP_X25519,
72 : .curve = GNUTLS_ECC_CURVE_X25519,
73 : .tls_id = 29,
74 : .pk = GNUTLS_PK_ECDH_X25519
75 : },
76 : #ifdef ENABLE_GOST
77 : /* draft-smyshlyaev-tls12-gost-suites-06, Section 6 */
78 : {
79 : .name = "GC256A",
80 : .id = GNUTLS_GROUP_GC256A,
81 : .curve = GNUTLS_ECC_CURVE_GOST256A,
82 : .pk = GNUTLS_PK_GOST_12_256,
83 : .tls_id = 34,
84 : },
85 : {
86 : .name = "GC256B",
87 : .id = GNUTLS_GROUP_GC256B,
88 : .curve = GNUTLS_ECC_CURVE_GOST256B,
89 : .pk = GNUTLS_PK_GOST_12_256,
90 : .tls_id = 35,
91 : },
92 : {
93 : .name = "GC256C",
94 : .id = GNUTLS_GROUP_GC256C,
95 : .curve = GNUTLS_ECC_CURVE_GOST256C,
96 : .pk = GNUTLS_PK_GOST_12_256,
97 : .tls_id = 36,
98 : },
99 : {
100 : .name = "GC256D",
101 : .id = GNUTLS_GROUP_GC256D,
102 : .curve = GNUTLS_ECC_CURVE_GOST256D,
103 : .pk = GNUTLS_PK_GOST_12_256,
104 : .tls_id = 37,
105 : },
106 : {
107 : .name = "GC512A",
108 : .id = GNUTLS_GROUP_GC512A,
109 : .curve = GNUTLS_ECC_CURVE_GOST512A,
110 : .pk = GNUTLS_PK_GOST_12_512,
111 : .tls_id = 38,
112 : },
113 : {
114 : .name = "GC512B",
115 : .id = GNUTLS_GROUP_GC512B,
116 : .curve = GNUTLS_ECC_CURVE_GOST512B,
117 : .pk = GNUTLS_PK_GOST_12_512,
118 : .tls_id = 39,
119 : },
120 : {
121 : .name = "GC512C",
122 : .id = GNUTLS_GROUP_GC512C,
123 : .curve = GNUTLS_ECC_CURVE_GOST512C,
124 : .pk = GNUTLS_PK_GOST_12_512,
125 : .tls_id = 40,
126 : },
127 : #endif
128 : {
129 : .name = "X448",
130 : .id = GNUTLS_GROUP_X448,
131 : .curve = GNUTLS_ECC_CURVE_X448,
132 : .tls_id = 30,
133 : .pk = GNUTLS_PK_ECDH_X448
134 : },
135 : #ifdef ENABLE_DHE
136 : {
137 : .name = "FFDHE2048",
138 : .id = GNUTLS_GROUP_FFDHE2048,
139 : .generator = &gnutls_ffdhe_2048_group_generator,
140 : .prime = &gnutls_ffdhe_2048_group_prime,
141 : .q = &gnutls_ffdhe_2048_group_q,
142 : .q_bits = &gnutls_ffdhe_2048_key_bits,
143 : .pk = GNUTLS_PK_DH,
144 : .tls_id = 0x100
145 : },
146 : {
147 : .name = "FFDHE3072",
148 : .id = GNUTLS_GROUP_FFDHE3072,
149 : .generator = &gnutls_ffdhe_3072_group_generator,
150 : .prime = &gnutls_ffdhe_3072_group_prime,
151 : .q = &gnutls_ffdhe_3072_group_q,
152 : .q_bits = &gnutls_ffdhe_3072_key_bits,
153 : .pk = GNUTLS_PK_DH,
154 : .tls_id = 0x101
155 : },
156 : {
157 : .name = "FFDHE4096",
158 : .id = GNUTLS_GROUP_FFDHE4096,
159 : .generator = &gnutls_ffdhe_4096_group_generator,
160 : .prime = &gnutls_ffdhe_4096_group_prime,
161 : .q = &gnutls_ffdhe_4096_group_q,
162 : .q_bits = &gnutls_ffdhe_4096_key_bits,
163 : .pk = GNUTLS_PK_DH,
164 : .tls_id = 0x102
165 : },
166 : {
167 : .name = "FFDHE6144",
168 : .id = GNUTLS_GROUP_FFDHE6144,
169 : .generator = &gnutls_ffdhe_6144_group_generator,
170 : .prime = &gnutls_ffdhe_6144_group_prime,
171 : .q = &gnutls_ffdhe_6144_group_q,
172 : .q_bits = &gnutls_ffdhe_6144_key_bits,
173 : .pk = GNUTLS_PK_DH,
174 : .tls_id = 0x103
175 : },
176 : {
177 : .name = "FFDHE8192",
178 : .id = GNUTLS_GROUP_FFDHE8192,
179 : .generator = &gnutls_ffdhe_8192_group_generator,
180 : .prime = &gnutls_ffdhe_8192_group_prime,
181 : .q = &gnutls_ffdhe_8192_group_q,
182 : .q_bits = &gnutls_ffdhe_8192_key_bits,
183 : .pk = GNUTLS_PK_DH,
184 : .tls_id = 0x104
185 : },
186 : #endif
187 : {0, 0, 0}
188 : };
189 :
190 : #define GNUTLS_GROUP_LOOP(b) \
191 : { const gnutls_group_entry_st *p; \
192 : for(p = supported_groups; p->name != NULL; p++) { b ; } }
193 :
194 :
195 : /* Returns the TLS id of the given curve
196 : */
197 77224 : const gnutls_group_entry_st * _gnutls_tls_id_to_group(unsigned num)
198 : {
199 1014890 : GNUTLS_GROUP_LOOP(
200 : if (p->tls_id == num &&
201 : (p->curve == 0 || _gnutls_ecc_curve_is_supported(p->curve))) {
202 : return p;
203 : }
204 : );
205 :
206 : return NULL;
207 : }
208 :
209 392424 : const gnutls_group_entry_st * _gnutls_id_to_group(unsigned id)
210 : {
211 392424 : if (id == 0)
212 : return NULL;
213 :
214 4501040 : GNUTLS_GROUP_LOOP(
215 : if (p->id == id &&
216 : (p->curve == 0 || _gnutls_ecc_curve_is_supported(p->curve))) {
217 : return p;
218 : }
219 : );
220 :
221 : return NULL;
222 : }
223 :
224 : /**
225 : * gnutls_group_list:
226 : *
227 : * Get the list of supported elliptic curves.
228 : *
229 : * This function is not thread safe.
230 : *
231 : * Returns: Return a (0)-terminated list of #gnutls_group_t
232 : * integers indicating the available groups.
233 : *
234 : * Since: 3.6.0
235 : **/
236 2 : const gnutls_group_t *gnutls_group_list(void)
237 : {
238 2 : static gnutls_group_t groups[MAX_ALGOS] = { 0 };
239 :
240 2 : if (groups[0] == 0) {
241 : int i = 0;
242 :
243 40 : GNUTLS_GROUP_LOOP(
244 : if (p->curve == 0 || _gnutls_ecc_curve_is_supported(p->curve))
245 : groups[i++] = p->id;
246 2 : );
247 2 : groups[i++] = 0;
248 : }
249 :
250 2 : return groups;
251 : }
252 :
253 : /**
254 : * gnutls_group_get_id:
255 : * @name: is a group name
256 : *
257 : * The names are compared in a case insensitive way.
258 : *
259 : * Returns: return a #gnutls_group_t value corresponding to
260 : * the specified group, or %GNUTLS_GROUP_INVALID on error.
261 : *
262 : * Since: 3.6.0
263 : **/
264 299 : gnutls_group_t gnutls_group_get_id(const char *name)
265 : {
266 299 : gnutls_group_t ret = GNUTLS_GROUP_INVALID;
267 :
268 3170 : GNUTLS_GROUP_LOOP(
269 : if (c_strcasecmp(p->name, name) == 0 && (
270 : p->curve == 0 ||_gnutls_ecc_curve_is_supported(p->curve))) {
271 : ret = p->id;
272 : break;
273 : }
274 299 : );
275 :
276 299 : return ret;
277 : }
278 :
279 : /**
280 : * gnutls_group_get_name:
281 : * @group: is an element from %gnutls_group_t
282 : *
283 : * Convert a #gnutls_group_t value to a string.
284 : *
285 : * Returns: a string that contains the name of the specified
286 : * group or %NULL.
287 : *
288 : * Since: 3.6.0
289 : **/
290 82 : const char *gnutls_group_get_name(gnutls_group_t group)
291 : {
292 966 : GNUTLS_GROUP_LOOP(
293 : if (p->id == group) {
294 : return p->name;
295 : }
296 : );
297 :
298 : return NULL;
299 : }
|