1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3 * Copyright (C) 2017 Red Hat, Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
6 *
7 * This file is part of GnuTLS.
8 *
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>
21 *
22 */
23
24 #include "gnutls_int.h"
25 #include <algorithms.h>
26 #include "errors.h"
27 #include <x509/common.h>
28 #include <assert.h>
29 #include "c-strcase.h"
30
31 /* signature algorithms;
32 */
33
34 #ifdef ALLOW_SHA1
35 # define SHA1_SECURE_VAL _SECURE
36 #else
37 # define SHA1_SECURE_VAL _INSECURE_FOR_CERTS
38 #endif
39
40 static SYSTEM_CONFIG_OR_CONST
41 gnutls_sign_entry_st sign_algorithms[] = {
42 /* RSA-PKCS#1 1.5: must be before PSS,
43 * so that gnutls_pk_to_sign() will return
44 * these first for backwards compatibility. */
45 {.name = "RSA-SHA256",
46 .oid = SIG_RSA_SHA256_OID,
47 .id = GNUTLS_SIGN_RSA_SHA256,
48 .pk = GNUTLS_PK_RSA,
49 .hash = GNUTLS_DIG_SHA256,
50 .aid = {{4, 1}, SIG_SEM_DEFAULT}},
51 {.name = "RSA-SHA384",
52 .oid = SIG_RSA_SHA384_OID,
53 .id = GNUTLS_SIGN_RSA_SHA384,
54 .pk = GNUTLS_PK_RSA,
55 .hash = GNUTLS_DIG_SHA384,
56 .aid = {{5, 1}, SIG_SEM_DEFAULT}},
57 {.name = "RSA-SHA512",
58 .oid = SIG_RSA_SHA512_OID,
59 .id = GNUTLS_SIGN_RSA_SHA512,
60 .pk = GNUTLS_PK_RSA,
61 .hash = GNUTLS_DIG_SHA512,
62 .aid = {{6, 1}, SIG_SEM_DEFAULT}},
63
64 /* RSA-PSS */
65 {.name = "RSA-PSS-SHA256",
66 .oid = PK_PKIX1_RSA_PSS_OID,
67 .id = GNUTLS_SIGN_RSA_PSS_SHA256,
68 .pk = GNUTLS_PK_RSA_PSS,
69 .priv_pk = GNUTLS_PK_RSA, /* PKCS#11 doesn't separate RSA from RSA-PSS privkeys */
70 .hash = GNUTLS_DIG_SHA256,
71 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
72 .aid = {{8, 9}, SIG_SEM_DEFAULT}},
73 {.name = "RSA-PSS-RSAE-SHA256",
74 .oid = PK_PKIX1_RSA_PSS_OID,
75 .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA256,
76 .pk = GNUTLS_PK_RSA_PSS,
77 .cert_pk = GNUTLS_PK_RSA,
78 .priv_pk = GNUTLS_PK_RSA,
79 .hash = GNUTLS_DIG_SHA256,
80 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
81 .aid = {{8, 4}, SIG_SEM_DEFAULT}},
82 {.name = "RSA-PSS-SHA384",
83 .oid = PK_PKIX1_RSA_PSS_OID,
84 .id = GNUTLS_SIGN_RSA_PSS_SHA384,
85 .pk = GNUTLS_PK_RSA_PSS,
86 .priv_pk = GNUTLS_PK_RSA,
87 .hash = GNUTLS_DIG_SHA384,
88 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
89 .aid = {{8, 0x0A}, SIG_SEM_DEFAULT}},
90 {.name = "RSA-PSS-RSAE-SHA384",
91 .oid = PK_PKIX1_RSA_PSS_OID,
92 .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA384,
93 .pk = GNUTLS_PK_RSA_PSS,
94 .cert_pk = GNUTLS_PK_RSA,
95 .priv_pk = GNUTLS_PK_RSA,
96 .hash = GNUTLS_DIG_SHA384,
97 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
98 .aid = {{8, 5}, SIG_SEM_DEFAULT}},
99 {.name = "RSA-PSS-SHA512",
100 .oid = PK_PKIX1_RSA_PSS_OID,
101 .id = GNUTLS_SIGN_RSA_PSS_SHA512,
102 .pk = GNUTLS_PK_RSA_PSS,
103 .priv_pk = GNUTLS_PK_RSA,
104 .hash = GNUTLS_DIG_SHA512,
105 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
106 .aid = {{8, 0x0B}, SIG_SEM_DEFAULT}},
107 {.name = "RSA-PSS-RSAE-SHA512",
108 .oid = PK_PKIX1_RSA_PSS_OID,
109 .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA512,
110 .pk = GNUTLS_PK_RSA_PSS,
111 .cert_pk = GNUTLS_PK_RSA,
112 .priv_pk = GNUTLS_PK_RSA,
113 .hash = GNUTLS_DIG_SHA512,
114 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
115 .aid = {{8, 6}, SIG_SEM_DEFAULT}},
116
117 /* Ed25519: The hash algorithm here is set to be SHA512, although that is
118 * an internal detail of Ed25519; we set it, because CMS/PKCS#7 requires
119 * that mapping. */
120 {.name = "EdDSA-Ed25519",
121 .oid = SIG_EDDSA_SHA512_OID,
122 .id = GNUTLS_SIGN_EDDSA_ED25519,
123 .pk = GNUTLS_PK_EDDSA_ED25519,
124 .hash = GNUTLS_DIG_SHA512,
125 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
126 .aid = {{8, 7}, SIG_SEM_DEFAULT}},
127
128 /* Ed448: The hash algorithm here is set to be SHAKE256, although that is
129 * an internal detail of Ed448; we set it, because CMS/PKCS#7 requires
130 * that mapping. */
131 {.name = "EdDSA-Ed448",
132 .oid = SIG_ED448_OID,
133 .id = GNUTLS_SIGN_EDDSA_ED448,
134 .pk = GNUTLS_PK_EDDSA_ED448,
135 .hash = GNUTLS_DIG_SHAKE_256,
136 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
137 .aid = {{8, 8}, SIG_SEM_DEFAULT},
138 .hash_output_size = 114},
139
140 /* ECDSA */
141 /* The following three signature algorithms
142 * have different semantics when used under TLS 1.2
143 * or TLS 1.3. Under the former they behave as the
144 * as ECDSA signed by SHAXXX by any curve, but under the
145 * latter they are restricted to a single curve.
146 * For this reason the ECDSA-SHAXXX algorithms act
147 * as an alias to them. */
148 /* we have intentionally the ECDSA-SHAXXX algorithms first
149 * so that gnutls_pk_to_sign() will return these. */
150 {.name = "ECDSA-SHA256",
151 .oid = "1.2.840.10045.4.3.2",
152 .id = GNUTLS_SIGN_ECDSA_SHA256,
153 .pk = GNUTLS_PK_ECDSA,
154 .hash = GNUTLS_DIG_SHA256,
155 .aid = {{4, 3}, SIG_SEM_PRE_TLS12}},
156 {.name = "ECDSA-SHA384",
157 .oid = "1.2.840.10045.4.3.3",
158 .id = GNUTLS_SIGN_ECDSA_SHA384,
159 .pk = GNUTLS_PK_ECDSA,
160 .hash = GNUTLS_DIG_SHA384,
161 .aid = {{5, 3}, SIG_SEM_PRE_TLS12}},
162 {.name = "ECDSA-SHA512",
163 .oid = "1.2.840.10045.4.3.4",
164 .id = GNUTLS_SIGN_ECDSA_SHA512,
165 .pk = GNUTLS_PK_ECDSA,
166 .hash = GNUTLS_DIG_SHA512,
167 .aid = {{6, 3}, SIG_SEM_PRE_TLS12}},
168
169 {.name = "ECDSA-SECP256R1-SHA256",
170 .id = GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
171 .pk = GNUTLS_PK_ECDSA,
172 .curve = GNUTLS_ECC_CURVE_SECP256R1,
173 .hash = GNUTLS_DIG_SHA256,
174 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
175 .aid = {{4, 3}, SIG_SEM_TLS13}},
176 {.name = "ECDSA-SECP384R1-SHA384",
177 .id = GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
178 .pk = GNUTLS_PK_ECDSA,
179 .curve = GNUTLS_ECC_CURVE_SECP384R1,
180 .hash = GNUTLS_DIG_SHA384,
181 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
182 .aid = {{5, 3}, SIG_SEM_TLS13}},
183 {.name = "ECDSA-SECP521R1-SHA512",
184 .id = GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
185 .pk = GNUTLS_PK_ECDSA,
186 .curve = GNUTLS_ECC_CURVE_SECP521R1,
187 .hash = GNUTLS_DIG_SHA512,
188 .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
189 .aid = {{6, 3}, SIG_SEM_TLS13}},
190
191 /* ECDSA-SHA3 */
192 {.name = "ECDSA-SHA3-224",
193 .oid = SIG_ECDSA_SHA3_224_OID,
194 .id = GNUTLS_SIGN_ECDSA_SHA3_224,
195 .pk = GNUTLS_PK_EC,
196 .hash = GNUTLS_DIG_SHA3_224,
197 .aid = TLS_SIGN_AID_UNKNOWN},
198 {.name = "ECDSA-SHA3-256",
199 .oid = SIG_ECDSA_SHA3_256_OID,
200 .id = GNUTLS_SIGN_ECDSA_SHA3_256,
201 .pk = GNUTLS_PK_EC,
202 .hash = GNUTLS_DIG_SHA3_256,
203 .aid = TLS_SIGN_AID_UNKNOWN},
204 {.name = "ECDSA-SHA3-384",
205 .oid = SIG_ECDSA_SHA3_384_OID,
206 .id = GNUTLS_SIGN_ECDSA_SHA3_384,
207 .pk = GNUTLS_PK_EC,
208 .hash = GNUTLS_DIG_SHA3_384,
209 .aid = TLS_SIGN_AID_UNKNOWN},
210 {.name = "ECDSA-SHA3-512",
211 .oid = SIG_ECDSA_SHA3_512_OID,
212 .id = GNUTLS_SIGN_ECDSA_SHA3_512,
213 .pk = GNUTLS_PK_EC,
214 .hash = GNUTLS_DIG_SHA3_512,
215 .aid = TLS_SIGN_AID_UNKNOWN},
216 {.name = "RSA-SHA3-224",
217 .oid = SIG_RSA_SHA3_224_OID,
218 .id = GNUTLS_SIGN_RSA_SHA3_224,
219 .pk = GNUTLS_PK_RSA,
220 .hash = GNUTLS_DIG_SHA3_224,
221 .aid = TLS_SIGN_AID_UNKNOWN},
222 {.name = "RSA-SHA3-256",
223 .oid = SIG_RSA_SHA3_256_OID,
224 .id = GNUTLS_SIGN_RSA_SHA3_256,
225 .pk = GNUTLS_PK_RSA,
226 .hash = GNUTLS_DIG_SHA3_256,
227 .aid = TLS_SIGN_AID_UNKNOWN},
228 {.name = "RSA-SHA3-384",
229 .oid = SIG_RSA_SHA3_384_OID,
230 .id = GNUTLS_SIGN_RSA_SHA3_384,
231 .pk = GNUTLS_PK_RSA,
232 .hash = GNUTLS_DIG_SHA3_384,
233 .aid = TLS_SIGN_AID_UNKNOWN},
234 {.name = "RSA-SHA3-512",
235 .oid = SIG_RSA_SHA3_512_OID,
236 .id = GNUTLS_SIGN_RSA_SHA3_512,
237 .pk = GNUTLS_PK_RSA,
238 .hash = GNUTLS_DIG_SHA3_512,
239 .aid = TLS_SIGN_AID_UNKNOWN},
240
241 /* DSA-SHA3 */
242 {.name = "DSA-SHA3-224",
243 .oid = SIG_DSA_SHA3_224_OID,
244 .id = GNUTLS_SIGN_DSA_SHA3_224,
245 .pk = GNUTLS_PK_DSA,
246 .hash = GNUTLS_DIG_SHA3_224,
247 .aid = TLS_SIGN_AID_UNKNOWN},
248 {.name = "DSA-SHA3-256",
249 .oid = SIG_DSA_SHA3_256_OID,
250 .id = GNUTLS_SIGN_DSA_SHA3_256,
251 .pk = GNUTLS_PK_DSA,
252 .hash = GNUTLS_DIG_SHA3_256,
253 .aid = TLS_SIGN_AID_UNKNOWN},
254 {.name = "DSA-SHA3-384",
255 .oid = SIG_DSA_SHA3_384_OID,
256 .id = GNUTLS_SIGN_DSA_SHA3_384,
257 .pk = GNUTLS_PK_DSA,
258 .hash = GNUTLS_DIG_SHA3_384,
259 .aid = TLS_SIGN_AID_UNKNOWN},
260 {.name = "DSA-SHA3-512",
261 .oid = SIG_DSA_SHA3_512_OID,
262 .id = GNUTLS_SIGN_DSA_SHA3_512,
263 .pk = GNUTLS_PK_DSA,
264 .hash = GNUTLS_DIG_SHA3_512,
265 .aid = TLS_SIGN_AID_UNKNOWN},
266
267 /* legacy */
268 {.name = "RSA-RAW",
269 .oid = NULL,
270 .id = GNUTLS_SIGN_RSA_RAW,
271 .pk = GNUTLS_PK_RSA,
272 .hash = GNUTLS_DIG_UNKNOWN,
273 .aid = TLS_SIGN_AID_UNKNOWN
274 },
275 {.name = "RSA-SHA1",
276 .oid = SIG_RSA_SHA1_OID,
277 .id = GNUTLS_SIGN_RSA_SHA1,
278 .pk = GNUTLS_PK_RSA,
279 .hash = GNUTLS_DIG_SHA1,
280 .slevel = SHA1_SECURE_VAL,
281 .aid = {{2, 1}, SIG_SEM_DEFAULT}},
282 {.name = "RSA-SHA1",
283 .oid = ISO_SIG_RSA_SHA1_OID,
284 .id = GNUTLS_SIGN_RSA_SHA1,
285 .pk = GNUTLS_PK_RSA,
286 .slevel = SHA1_SECURE_VAL,
287 .hash = GNUTLS_DIG_SHA1,
288 .aid = {{2, 1}, SIG_SEM_DEFAULT}},
289 {.name = "RSA-SHA224",
290 .oid = SIG_RSA_SHA224_OID,
291 .id = GNUTLS_SIGN_RSA_SHA224,
292 .pk = GNUTLS_PK_RSA,
293 .hash = GNUTLS_DIG_SHA224,
294 .aid = TLS_SIGN_AID_UNKNOWN},
295 {.name = "RSA-RMD160",
296 .oid = SIG_RSA_RMD160_OID,
297 .id = GNUTLS_SIGN_RSA_RMD160,
298 .pk = GNUTLS_PK_RSA,
299 .hash = GNUTLS_DIG_RMD160,
300 .slevel = _INSECURE_FOR_CERTS,
301 .aid = TLS_SIGN_AID_UNKNOWN},
302 {.name = "DSA-SHA1",
303 .oid = SIG_DSA_SHA1_OID,
304 .id = GNUTLS_SIGN_DSA_SHA1,
305 .pk = GNUTLS_PK_DSA,
306 .slevel = SHA1_SECURE_VAL,
307 .hash = GNUTLS_DIG_SHA1,
308 .aid = {{2, 2}, SIG_SEM_PRE_TLS12}},
309 {.name = "DSA-SHA1",
310 .oid = "1.3.14.3.2.27",
311 .id = GNUTLS_SIGN_DSA_SHA1,
312 .pk = GNUTLS_PK_DSA,
313 .hash = GNUTLS_DIG_SHA1,
314 .slevel = SHA1_SECURE_VAL,
315 .aid = {{2, 2}, SIG_SEM_PRE_TLS12}},
316 {.name = "DSA-SHA224",
317 .oid = SIG_DSA_SHA224_OID,
318 .id = GNUTLS_SIGN_DSA_SHA224,
319 .pk = GNUTLS_PK_DSA,
320 .hash = GNUTLS_DIG_SHA224,
321 .aid = TLS_SIGN_AID_UNKNOWN},
322 {.name = "DSA-SHA256",
323 .oid = SIG_DSA_SHA256_OID,
324 .id = GNUTLS_SIGN_DSA_SHA256,
325 .pk = GNUTLS_PK_DSA,
326 .hash = GNUTLS_DIG_SHA256,
327 .aid = TLS_SIGN_AID_UNKNOWN},
328 {.name = "RSA-MD5",
329 .oid = SIG_RSA_MD5_OID,
330 .id = GNUTLS_SIGN_RSA_MD5,
331 .pk = GNUTLS_PK_RSA,
332 .hash = GNUTLS_DIG_MD5,
333 .slevel = _INSECURE,
334 .aid = TLS_SIGN_AID_UNKNOWN},
335 {.name = "RSA-MD5",
336 .oid = "1.3.14.3.2.25",
337 .id = GNUTLS_SIGN_RSA_MD5,
338 .pk = GNUTLS_PK_RSA,
339 .hash = GNUTLS_DIG_MD5,
340 .slevel = _INSECURE,
341 .aid = TLS_SIGN_AID_UNKNOWN},
342 {.name = "RSA-MD2",
343 .oid = SIG_RSA_MD2_OID,
344 .id = GNUTLS_SIGN_RSA_MD2,
345 .pk = GNUTLS_PK_RSA,
346 .hash = GNUTLS_DIG_MD2,
347 .slevel = _INSECURE,
348 .aid = TLS_SIGN_AID_UNKNOWN},
349 {.name = "ECDSA-SHA1",
350 .oid = "1.2.840.10045.4.1",
351 .id = GNUTLS_SIGN_ECDSA_SHA1,
352 .pk = GNUTLS_PK_EC,
353 .slevel = SHA1_SECURE_VAL,
354 .hash = GNUTLS_DIG_SHA1,
355 .aid = {{2, 3}, SIG_SEM_DEFAULT}},
356 {.name = "ECDSA-SHA224",
357 .oid = "1.2.840.10045.4.3.1",
358 .id = GNUTLS_SIGN_ECDSA_SHA224,
359 .pk = GNUTLS_PK_EC,
360 .hash = GNUTLS_DIG_SHA224,
361 .aid = TLS_SIGN_AID_UNKNOWN},
362 /* GOST R 34.10-2012-512 */
363 {.name = "GOSTR341012-512",
364 .oid = SIG_GOST_R3410_2012_512_OID,
365 .id = GNUTLS_SIGN_GOST_512,
366 .pk = GNUTLS_PK_GOST_12_512,
367 .hash = GNUTLS_DIG_STREEBOG_512,
368 .flags = GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE,
369 .aid = {{8, 65}, SIG_SEM_PRE_TLS12}},
370 /* GOST R 34.10-2012-256 */
371 {.name = "GOSTR341012-256",
372 .oid = SIG_GOST_R3410_2012_256_OID,
373 .id = GNUTLS_SIGN_GOST_256,
374 .pk = GNUTLS_PK_GOST_12_256,
375 .hash = GNUTLS_DIG_STREEBOG_256,
376 .flags = GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE,
377 .aid = {{8, 64}, SIG_SEM_PRE_TLS12}},
378 /* GOST R 34.10-2001 */
379 {.name = "GOSTR341001",
380 .oid = SIG_GOST_R3410_2001_OID,
381 .id = GNUTLS_SIGN_GOST_94,
382 .pk = GNUTLS_PK_GOST_01,
383 .hash = GNUTLS_DIG_GOSTR_94,
384 .flags = GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE,
385 .aid = TLS_SIGN_AID_UNKNOWN},
386 /* GOST R 34.10-94 */
387 {.name = "GOSTR341094",
388 .oid = SIG_GOST_R3410_94_OID,
389 .id = 0,
390 .pk = 0,
391 .hash = 0,
392 .aid = TLS_SIGN_AID_UNKNOWN},
393 {.name = "DSA-SHA384",
394 .oid = SIG_DSA_SHA384_OID,
395 .id = GNUTLS_SIGN_DSA_SHA384,
396 .pk = GNUTLS_PK_DSA,
397 .hash = GNUTLS_DIG_SHA384,
398 .aid = TLS_SIGN_AID_UNKNOWN},
399 {.name = "DSA-SHA512",
400 .oid = SIG_DSA_SHA512_OID,
401 .id = GNUTLS_SIGN_DSA_SHA512,
402 .pk = GNUTLS_PK_DSA,
403 .hash = GNUTLS_DIG_SHA512,
404 .aid = TLS_SIGN_AID_UNKNOWN},
405
406 {.name = 0,
407 .oid = 0,
408 .id = 0,
409 .pk = 0,
410 .hash = 0,
411 .aid = TLS_SIGN_AID_UNKNOWN}
412 };
413
414 #define GNUTLS_SIGN_LOOP(b) \
415 do { \
416 const gnutls_sign_entry_st *p; \
417 for(p = sign_algorithms; p->name != NULL; p++) { b ; } \
418 } while (0)
419
420 #define GNUTLS_SIGN_ALG_LOOP(a) \
421 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
422
423 /**
424 * gnutls_sign_get_name:
425 * @algorithm: is a sign algorithm
426 *
427 * Convert a #gnutls_sign_algorithm_t value to a string.
428 *
429 * Returns: a string that contains the name of the specified sign
430 * algorithm, or %NULL.
431 **/
gnutls_sign_get_name(gnutls_sign_algorithm_t algorithm)432 const char *gnutls_sign_get_name(gnutls_sign_algorithm_t algorithm)
433 {
434 gnutls_sign_algorithm_t sign = algorithm;
435 const char *ret = NULL;
436
437 /* avoid prefix */
438 GNUTLS_SIGN_ALG_LOOP(ret = p->name);
439
440 return ret;
441 }
442
443 /**
444 * gnutls_sign_is_secure:
445 * @algorithm: is a sign algorithm
446 *
447 * Returns: Non-zero if the provided signature algorithm is considered to be secure.
448 **/
gnutls_sign_is_secure(gnutls_sign_algorithm_t algorithm)449 unsigned gnutls_sign_is_secure(gnutls_sign_algorithm_t algorithm)
450 {
451 return gnutls_sign_is_secure2(algorithm, 0);
452 }
453
_gnutls_sign_is_secure2(const gnutls_sign_entry_st * se,unsigned int flags)454 bool _gnutls_sign_is_secure2(const gnutls_sign_entry_st *se, unsigned int flags)
455 {
456 if (se->hash != GNUTLS_DIG_UNKNOWN && _gnutls_digest_is_insecure(se->hash))
457 return gnutls_assert_val(0);
458
459 if (flags & GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS)
460 return (se->slevel==_SECURE)?1:0;
461 else
462 return (se->slevel==_SECURE || se->slevel == _INSECURE_FOR_CERTS)?1:0;
463 }
464
_gnutls_sign_mark_insecure(const char * name,hash_security_level_t level)465 int _gnutls_sign_mark_insecure(const char *name, hash_security_level_t level)
466 {
467 #ifndef DISABLE_SYSTEM_CONFIG
468 gnutls_sign_entry_st *p;
469
470 if (unlikely(level == _SECURE))
471 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
472
473 for(p = sign_algorithms; p->name != NULL; p++) {
474 if (c_strcasecmp(p->name, name) == 0) {
475 p->slevel = level;
476 return 0;
477 }
478 }
479 #endif
480 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
481 }
482
483 /**
484 * gnutls_sign_is_secure2:
485 * @algorithm: is a sign algorithm
486 * @flags: zero or %GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS
487 *
488 * Returns: Non-zero if the provided signature algorithm is considered to be secure.
489 **/
gnutls_sign_is_secure2(gnutls_sign_algorithm_t algorithm,unsigned int flags)490 unsigned gnutls_sign_is_secure2(gnutls_sign_algorithm_t algorithm, unsigned int flags)
491 {
492 const gnutls_sign_entry_st *se;
493
494 se = _gnutls_sign_to_entry(algorithm);
495 if (se == NULL)
496 return 0;
497
498 return _gnutls_sign_is_secure2(se, flags);
499 }
500
501 /**
502 * gnutls_sign_list:
503 *
504 * Get a list of supported public key signature algorithms.
505 * This function is not thread safe.
506 *
507 * Returns: a (0)-terminated list of #gnutls_sign_algorithm_t
508 * integers indicating the available ciphers.
509 *
510 **/
gnutls_sign_list(void)511 const gnutls_sign_algorithm_t *gnutls_sign_list(void)
512 {
513 static gnutls_sign_algorithm_t supported_sign[MAX_ALGOS+1] = { 0 };
514
515 if (supported_sign[0] == 0) {
516 int i = 0;
517
518 GNUTLS_SIGN_LOOP(
519 /* list all algorithms, but not duplicates */
520 if (supported_sign[i] != p->id) {
521 assert(i+1 < MAX_ALGOS);
522 supported_sign[i++] = p->id;
523 supported_sign[i+1] = 0;
524 }
525 );
526 }
527
528 return supported_sign;
529 }
530
531 /**
532 * gnutls_sign_get_id:
533 * @name: is a sign algorithm name
534 *
535 * The names are compared in a case insensitive way.
536 *
537 * Returns: return a #gnutls_sign_algorithm_t value corresponding to
538 * the specified algorithm, or %GNUTLS_SIGN_UNKNOWN on error.
539 **/
gnutls_sign_get_id(const char * name)540 gnutls_sign_algorithm_t gnutls_sign_get_id(const char *name)
541 {
542 gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
543
544 GNUTLS_SIGN_LOOP(
545 if (c_strcasecmp(p->name, name) == 0) {
546 ret = p->id;
547 break;
548 }
549 );
550
551 return ret;
552
553 }
554
_gnutls_oid_to_sign_entry(const char * oid)555 const gnutls_sign_entry_st *_gnutls_oid_to_sign_entry(const char *oid)
556 {
557 GNUTLS_SIGN_LOOP(
558 if (p->oid && strcmp(oid, p->oid) == 0) {
559 return p;
560 }
561 );
562 return NULL;
563 }
564
565 /**
566 * gnutls_oid_to_sign:
567 * @oid: is an object identifier
568 *
569 * Converts a textual object identifier to a #gnutls_sign_algorithm_t value.
570 *
571 * Returns: a #gnutls_sign_algorithm_t id of the specified digest
572 * algorithm, or %GNUTLS_SIGN_UNKNOWN on failure.
573 *
574 * Since: 3.4.3
575 **/
gnutls_oid_to_sign(const char * oid)576 gnutls_sign_algorithm_t gnutls_oid_to_sign(const char *oid)
577 {
578 const gnutls_sign_entry_st *se;
579
580 se = _gnutls_oid_to_sign_entry(oid);
581 if (se == NULL) {
582 _gnutls_debug_log("Unknown SIGN OID: '%s'\n", oid);
583 return GNUTLS_SIGN_UNKNOWN;
584 }
585 return se->id;
586 }
587
_gnutls_pk_to_sign_entry(gnutls_pk_algorithm_t pk,gnutls_digest_algorithm_t hash)588 const gnutls_sign_entry_st *_gnutls_pk_to_sign_entry(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
589 {
590 GNUTLS_SIGN_LOOP(
591 if (pk == p->pk && hash == p->hash) {
592 return p;
593 }
594 );
595
596 return NULL;
597 }
598
599 /**
600 * gnutls_pk_to_sign:
601 * @pk: is a public key algorithm
602 * @hash: a hash algorithm
603 *
604 * This function maps public key and hash algorithms combinations
605 * to signature algorithms.
606 *
607 * Returns: return a #gnutls_sign_algorithm_t value, or %GNUTLS_SIGN_UNKNOWN on error.
608 **/
609 gnutls_sign_algorithm_t
gnutls_pk_to_sign(gnutls_pk_algorithm_t pk,gnutls_digest_algorithm_t hash)610 gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
611 {
612 const gnutls_sign_entry_st *e;
613
614 e = _gnutls_pk_to_sign_entry(pk, hash);
615 if (e == NULL)
616 return GNUTLS_SIGN_UNKNOWN;
617 return e->id;
618 }
619
620 /**
621 * gnutls_sign_get_oid:
622 * @sign: is a sign algorithm
623 *
624 * Convert a #gnutls_sign_algorithm_t value to its object identifier.
625 *
626 * Returns: a string that contains the object identifier of the specified sign
627 * algorithm, or %NULL.
628 *
629 * Since: 3.4.3
630 **/
gnutls_sign_get_oid(gnutls_sign_algorithm_t sign)631 const char *gnutls_sign_get_oid(gnutls_sign_algorithm_t sign)
632 {
633 const char *ret = NULL;
634
635 GNUTLS_SIGN_ALG_LOOP(ret = p->oid);
636
637 return ret;
638 }
639
640 /**
641 * gnutls_sign_get_hash_algorithm:
642 * @sign: is a signature algorithm
643 *
644 * This function returns the digest algorithm corresponding to
645 * the given signature algorithms.
646 *
647 * Since: 3.1.1
648 *
649 * Returns: return a #gnutls_digest_algorithm_t value, or %GNUTLS_DIG_UNKNOWN on error.
650 **/
651 gnutls_digest_algorithm_t
gnutls_sign_get_hash_algorithm(gnutls_sign_algorithm_t sign)652 gnutls_sign_get_hash_algorithm(gnutls_sign_algorithm_t sign)
653 {
654 gnutls_digest_algorithm_t ret = GNUTLS_DIG_UNKNOWN;
655
656 GNUTLS_SIGN_ALG_LOOP(ret = p->hash);
657
658 return ret;
659 }
660
661 /**
662 * gnutls_sign_get_pk_algorithm:
663 * @sign: is a signature algorithm
664 *
665 * This function returns the public key algorithm corresponding to
666 * the given signature algorithms. Note that there may be multiple
667 * public key algorithms supporting a particular signature type;
668 * when dealing with such algorithms use instead gnutls_sign_supports_pk_algorithm().
669 *
670 * Since: 3.1.1
671 *
672 * Returns: return a #gnutls_pk_algorithm_t value, or %GNUTLS_PK_UNKNOWN on error.
673 **/
674 gnutls_pk_algorithm_t
gnutls_sign_get_pk_algorithm(gnutls_sign_algorithm_t sign)675 gnutls_sign_get_pk_algorithm(gnutls_sign_algorithm_t sign)
676 {
677 gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
678
679 GNUTLS_SIGN_ALG_LOOP(ret = p->pk);
680
681 return ret;
682 }
683
684 /**
685 * gnutls_sign_supports_pk_algorithm:
686 * @sign: is a signature algorithm
687 * @pk: is a public key algorithm
688 *
689 * This function returns non-zero if the public key algorithm corresponds to
690 * the given signature algorithm. That is, if that signature can be generated
691 * from the given private key algorithm.
692 *
693 * Since: 3.6.0
694 *
695 * Returns: return non-zero when the provided algorithms are compatible.
696 **/
697 unsigned
gnutls_sign_supports_pk_algorithm(gnutls_sign_algorithm_t sign,gnutls_pk_algorithm_t pk)698 gnutls_sign_supports_pk_algorithm(gnutls_sign_algorithm_t sign, gnutls_pk_algorithm_t pk)
699 {
700 const gnutls_sign_entry_st *p;
701 unsigned r;
702
703 for(p = sign_algorithms; p->name != NULL; p++) {
704 if (p->id && p->id == sign) {
705 r = sign_supports_priv_pk_algorithm(p, pk);
706 if (r != 0)
707 return r;
708 }
709 }
710
711 return 0;
712 }
713
714 gnutls_sign_algorithm_t
_gnutls_tls_aid_to_sign(uint8_t id0,uint8_t id1,const version_entry_st * ver)715 _gnutls_tls_aid_to_sign(uint8_t id0, uint8_t id1, const version_entry_st *ver)
716 {
717 gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
718
719 if (id0 == 255 && id1 == 255)
720 return ret;
721
722 GNUTLS_SIGN_LOOP(
723 if (p->aid.id[0] == id0 &&
724 p->aid.id[1] == id1 &&
725 ((p->aid.tls_sem & ver->tls_sig_sem) != 0)) {
726
727 ret = p->id;
728 break;
729 }
730 );
731
732 return ret;
733 }
734
735 /* Returns NULL if a valid AID is not found
736 */
_gnutls_sign_to_tls_aid(gnutls_sign_algorithm_t sign)737 const sign_algorithm_st *_gnutls_sign_to_tls_aid(gnutls_sign_algorithm_t
738 sign)
739 {
740 const sign_algorithm_st *ret = NULL;
741
742 GNUTLS_SIGN_ALG_LOOP(ret = &p->aid);
743
744 if (ret != NULL && HAVE_UNKNOWN_SIGAID(ret))
745 return NULL;
746
747 return ret;
748 }
749
_gnutls_sign_to_entry(gnutls_sign_algorithm_t sign)750 const gnutls_sign_entry_st *_gnutls_sign_to_entry(gnutls_sign_algorithm_t sign)
751 {
752 const gnutls_sign_entry_st *ret = NULL;
753
754 GNUTLS_SIGN_ALG_LOOP(ret = p);
755
756 return ret;
757 }
758
759 const gnutls_sign_entry_st *
_gnutls_tls_aid_to_sign_entry(uint8_t id0,uint8_t id1,const version_entry_st * ver)760 _gnutls_tls_aid_to_sign_entry(uint8_t id0, uint8_t id1, const version_entry_st *ver)
761 {
762 if (id0 == 255 && id1 == 255)
763 return NULL;
764
765 GNUTLS_SIGN_LOOP(
766 if (p->aid.id[0] == id0 &&
767 p->aid.id[1] == id1 &&
768 ((p->aid.tls_sem & ver->tls_sig_sem) != 0)) {
769
770 return p;
771 }
772 );
773
774 return NULL;
775 }
776
777 const gnutls_sign_entry_st *
_gnutls13_sign_get_compatible_with_privkey(gnutls_privkey_t privkey)778 _gnutls13_sign_get_compatible_with_privkey(gnutls_privkey_t privkey)
779 {
780 GNUTLS_SIGN_LOOP(
781 if ((p->flags & GNUTLS_SIGN_FLAG_TLS13_OK) &&
782 _gnutls_privkey_compatible_with_sig(privkey, p->id)) {
783 return p;
784 }
785 );
786
787 return NULL;
788 }
789
790 unsigned
_gnutls_sign_get_hash_strength(gnutls_sign_algorithm_t sign)791 _gnutls_sign_get_hash_strength(gnutls_sign_algorithm_t sign)
792 {
793 const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign);
794 const mac_entry_st *me;
795 unsigned hash_output_size;
796
797 if (unlikely(se == NULL))
798 return 0;
799
800 me = hash_to_entry(se->hash);
801 if (unlikely(me == NULL))
802 return 0;
803
804 if (se->hash_output_size > 0)
805 hash_output_size = se->hash_output_size;
806 else
807 hash_output_size = _gnutls_mac_get_algo_len(me);
808
809 if (me->id == GNUTLS_MAC_SHAKE_128)
810 return MIN(hash_output_size*8/2, 128);
811 else if (me->id == GNUTLS_MAC_SHAKE_256)
812 return MIN(hash_output_size*8/2, 256);
813
814 return hash_output_size*8/2;
815 }
816