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