Coverage Report

Created: 2025-07-23 07:18

/src/gnutls/lib/algorithms/sign.c
Line
Count
Source (jump to first uncovered line)
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
#include "pk.h"
31
32
/* signature algorithms;
33
 */
34
35
#ifdef ALLOW_SHA1
36
#define SHA1_SECURE_VAL _SECURE
37
#else
38
#define SHA1_SECURE_VAL _INSECURE_FOR_CERTS
39
#endif
40
41
static SYSTEM_CONFIG_OR_CONST 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 =
70
      GNUTLS_PK_RSA, /* PKCS#11 doesn't separate RSA from RSA-PSS privkeys */
71
    .hash = GNUTLS_DIG_SHA256,
72
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
73
    .aid = { { 8, 9 }, SIG_SEM_DEFAULT } },
74
  { .name = "RSA-PSS-RSAE-SHA256",
75
    .oid = PK_PKIX1_RSA_PSS_OID,
76
    .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA256,
77
    .pk = GNUTLS_PK_RSA_PSS,
78
    .cert_pk = GNUTLS_PK_RSA,
79
    .priv_pk = GNUTLS_PK_RSA,
80
    .hash = GNUTLS_DIG_SHA256,
81
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
82
    .aid = { { 8, 4 }, SIG_SEM_DEFAULT } },
83
  { .name = "RSA-PSS-SHA384",
84
    .oid = PK_PKIX1_RSA_PSS_OID,
85
    .id = GNUTLS_SIGN_RSA_PSS_SHA384,
86
    .pk = GNUTLS_PK_RSA_PSS,
87
    .priv_pk = GNUTLS_PK_RSA,
88
    .hash = GNUTLS_DIG_SHA384,
89
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
90
    .aid = { { 8, 0x0A }, SIG_SEM_DEFAULT } },
91
  { .name = "RSA-PSS-RSAE-SHA384",
92
    .oid = PK_PKIX1_RSA_PSS_OID,
93
    .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA384,
94
    .pk = GNUTLS_PK_RSA_PSS,
95
    .cert_pk = GNUTLS_PK_RSA,
96
    .priv_pk = GNUTLS_PK_RSA,
97
    .hash = GNUTLS_DIG_SHA384,
98
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
99
    .aid = { { 8, 5 }, SIG_SEM_DEFAULT } },
100
  { .name = "RSA-PSS-SHA512",
101
    .oid = PK_PKIX1_RSA_PSS_OID,
102
    .id = GNUTLS_SIGN_RSA_PSS_SHA512,
103
    .pk = GNUTLS_PK_RSA_PSS,
104
    .priv_pk = GNUTLS_PK_RSA,
105
    .hash = GNUTLS_DIG_SHA512,
106
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
107
    .aid = { { 8, 0x0B }, SIG_SEM_DEFAULT } },
108
  { .name = "RSA-PSS-RSAE-SHA512",
109
    .oid = PK_PKIX1_RSA_PSS_OID,
110
    .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA512,
111
    .pk = GNUTLS_PK_RSA_PSS,
112
    .cert_pk = GNUTLS_PK_RSA,
113
    .priv_pk = GNUTLS_PK_RSA,
114
    .hash = GNUTLS_DIG_SHA512,
115
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
116
    .aid = { { 8, 6 }, SIG_SEM_DEFAULT } },
117
118
  /* Ed25519: The hash algorithm here is set to be SHA512, although that is
119
   * an internal detail of Ed25519; we set it, because CMS/PKCS#7 requires
120
   * that mapping. */
121
  { .name = "EdDSA-Ed25519",
122
    .oid = SIG_EDDSA_SHA512_OID,
123
    .id = GNUTLS_SIGN_EDDSA_ED25519,
124
    .pk = GNUTLS_PK_EDDSA_ED25519,
125
    .hash = GNUTLS_DIG_SHA512,
126
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
127
    .aid = { { 8, 7 }, SIG_SEM_DEFAULT } },
128
129
  /* Ed448: The hash algorithm here is set to be SHAKE256, although that is
130
   * an internal detail of Ed448; we set it, because CMS/PKCS#7 requires
131
   * that mapping. */
132
  { .name = "EdDSA-Ed448",
133
    .oid = SIG_ED448_OID,
134
    .id = GNUTLS_SIGN_EDDSA_ED448,
135
    .pk = GNUTLS_PK_EDDSA_ED448,
136
    .hash = GNUTLS_DIG_SHAKE_256,
137
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
138
    .aid = { { 8, 8 }, SIG_SEM_DEFAULT },
139
    .hash_output_size = 114 },
140
141
  /* ECDSA */
142
  /* The following three signature algorithms
143
   * have different semantics when used under TLS 1.2
144
   * or TLS 1.3. Under the former they behave as the
145
   * as ECDSA signed by SHAXXX by any curve, but under the
146
   * latter they are restricted to a single curve.
147
   * For this reason the ECDSA-SHAXXX algorithms act
148
   * as an alias to them. */
149
  /* we have intentionally the ECDSA-SHAXXX algorithms first
150
   * so that gnutls_pk_to_sign() will return these. */
151
  { .name = "ECDSA-SHA256",
152
    .oid = "1.2.840.10045.4.3.2",
153
    .id = GNUTLS_SIGN_ECDSA_SHA256,
154
    .pk = GNUTLS_PK_ECDSA,
155
    .hash = GNUTLS_DIG_SHA256,
156
    .aid = { { 4, 3 }, SIG_SEM_PRE_TLS12 } },
157
  { .name = "ECDSA-SHA384",
158
    .oid = "1.2.840.10045.4.3.3",
159
    .id = GNUTLS_SIGN_ECDSA_SHA384,
160
    .pk = GNUTLS_PK_ECDSA,
161
    .hash = GNUTLS_DIG_SHA384,
162
    .aid = { { 5, 3 }, SIG_SEM_PRE_TLS12 } },
163
  { .name = "ECDSA-SHA512",
164
    .oid = "1.2.840.10045.4.3.4",
165
    .id = GNUTLS_SIGN_ECDSA_SHA512,
166
    .pk = GNUTLS_PK_ECDSA,
167
    .hash = GNUTLS_DIG_SHA512,
168
    .aid = { { 6, 3 }, SIG_SEM_PRE_TLS12 } },
169
170
  { .name = "ECDSA-SECP256R1-SHA256",
171
    .id = GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
172
    .pk = GNUTLS_PK_ECDSA,
173
    .curve = GNUTLS_ECC_CURVE_SECP256R1,
174
    .hash = GNUTLS_DIG_SHA256,
175
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
176
    .aid = { { 4, 3 }, SIG_SEM_TLS13 } },
177
  { .name = "ECDSA-SECP384R1-SHA384",
178
    .id = GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
179
    .pk = GNUTLS_PK_ECDSA,
180
    .curve = GNUTLS_ECC_CURVE_SECP384R1,
181
    .hash = GNUTLS_DIG_SHA384,
182
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
183
    .aid = { { 5, 3 }, SIG_SEM_TLS13 } },
184
  { .name = "ECDSA-SECP521R1-SHA512",
185
    .id = GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
186
    .pk = GNUTLS_PK_ECDSA,
187
    .curve = GNUTLS_ECC_CURVE_SECP521R1,
188
    .hash = GNUTLS_DIG_SHA512,
189
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
190
    .aid = { { 6, 3 }, SIG_SEM_TLS13 } },
191
192
  /* ECDSA-SHA3 */
193
  { .name = "ECDSA-SHA3-224",
194
    .oid = SIG_ECDSA_SHA3_224_OID,
195
    .id = GNUTLS_SIGN_ECDSA_SHA3_224,
196
    .pk = GNUTLS_PK_EC,
197
    .hash = GNUTLS_DIG_SHA3_224,
198
    .aid = TLS_SIGN_AID_UNKNOWN },
199
  { .name = "ECDSA-SHA3-256",
200
    .oid = SIG_ECDSA_SHA3_256_OID,
201
    .id = GNUTLS_SIGN_ECDSA_SHA3_256,
202
    .pk = GNUTLS_PK_EC,
203
    .hash = GNUTLS_DIG_SHA3_256,
204
    .aid = TLS_SIGN_AID_UNKNOWN },
205
  { .name = "ECDSA-SHA3-384",
206
    .oid = SIG_ECDSA_SHA3_384_OID,
207
    .id = GNUTLS_SIGN_ECDSA_SHA3_384,
208
    .pk = GNUTLS_PK_EC,
209
    .hash = GNUTLS_DIG_SHA3_384,
210
    .aid = TLS_SIGN_AID_UNKNOWN },
211
  { .name = "ECDSA-SHA3-512",
212
    .oid = SIG_ECDSA_SHA3_512_OID,
213
    .id = GNUTLS_SIGN_ECDSA_SHA3_512,
214
    .pk = GNUTLS_PK_EC,
215
    .hash = GNUTLS_DIG_SHA3_512,
216
    .aid = TLS_SIGN_AID_UNKNOWN },
217
  { .name = "RSA-SHA3-224",
218
    .oid = SIG_RSA_SHA3_224_OID,
219
    .id = GNUTLS_SIGN_RSA_SHA3_224,
220
    .pk = GNUTLS_PK_RSA,
221
    .hash = GNUTLS_DIG_SHA3_224,
222
    .aid = TLS_SIGN_AID_UNKNOWN },
223
  { .name = "RSA-SHA3-256",
224
    .oid = SIG_RSA_SHA3_256_OID,
225
    .id = GNUTLS_SIGN_RSA_SHA3_256,
226
    .pk = GNUTLS_PK_RSA,
227
    .hash = GNUTLS_DIG_SHA3_256,
228
    .aid = TLS_SIGN_AID_UNKNOWN },
229
  { .name = "RSA-SHA3-384",
230
    .oid = SIG_RSA_SHA3_384_OID,
231
    .id = GNUTLS_SIGN_RSA_SHA3_384,
232
    .pk = GNUTLS_PK_RSA,
233
    .hash = GNUTLS_DIG_SHA3_384,
234
    .aid = TLS_SIGN_AID_UNKNOWN },
235
  { .name = "RSA-SHA3-512",
236
    .oid = SIG_RSA_SHA3_512_OID,
237
    .id = GNUTLS_SIGN_RSA_SHA3_512,
238
    .pk = GNUTLS_PK_RSA,
239
    .hash = GNUTLS_DIG_SHA3_512,
240
    .aid = TLS_SIGN_AID_UNKNOWN },
241
242
  /* DSA-SHA3 */
243
  { .name = "DSA-SHA3-224",
244
    .oid = SIG_DSA_SHA3_224_OID,
245
    .id = GNUTLS_SIGN_DSA_SHA3_224,
246
    .pk = GNUTLS_PK_DSA,
247
    .hash = GNUTLS_DIG_SHA3_224,
248
    .aid = TLS_SIGN_AID_UNKNOWN },
249
  { .name = "DSA-SHA3-256",
250
    .oid = SIG_DSA_SHA3_256_OID,
251
    .id = GNUTLS_SIGN_DSA_SHA3_256,
252
    .pk = GNUTLS_PK_DSA,
253
    .hash = GNUTLS_DIG_SHA3_256,
254
    .aid = TLS_SIGN_AID_UNKNOWN },
255
  { .name = "DSA-SHA3-384",
256
    .oid = SIG_DSA_SHA3_384_OID,
257
    .id = GNUTLS_SIGN_DSA_SHA3_384,
258
    .pk = GNUTLS_PK_DSA,
259
    .hash = GNUTLS_DIG_SHA3_384,
260
    .aid = TLS_SIGN_AID_UNKNOWN },
261
  { .name = "DSA-SHA3-512",
262
    .oid = SIG_DSA_SHA3_512_OID,
263
    .id = GNUTLS_SIGN_DSA_SHA3_512,
264
    .pk = GNUTLS_PK_DSA,
265
    .hash = GNUTLS_DIG_SHA3_512,
266
    .aid = TLS_SIGN_AID_UNKNOWN },
267
268
  /* legacy */
269
  { .name = "RSA-RAW",
270
    .oid = NULL,
271
    .id = GNUTLS_SIGN_RSA_RAW,
272
    .pk = GNUTLS_PK_RSA,
273
    .hash = GNUTLS_DIG_UNKNOWN,
274
    .aid = TLS_SIGN_AID_UNKNOWN },
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
  { .name = "ML-DSA-44",
406
    .oid = MLDSA44_OID,
407
    .id = GNUTLS_SIGN_MLDSA44,
408
    .pk = GNUTLS_PK_MLDSA44,
409
    .hash = GNUTLS_DIG_SHAKE_256,
410
    .hash_output_size = 128,
411
    .aid = { { 9, 4 }, SIG_SEM_TLS13 },
412
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK },
413
  { .name = "ML-DSA-65",
414
    .oid = MLDSA65_OID,
415
    .id = GNUTLS_SIGN_MLDSA65,
416
    .pk = GNUTLS_PK_MLDSA65,
417
    .hash = GNUTLS_DIG_SHAKE_256,
418
    .hash_output_size = 192,
419
    .aid = { { 9, 5 }, SIG_SEM_TLS13 },
420
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK },
421
  { .name = "ML-DSA-87",
422
    .oid = MLDSA87_OID,
423
    .id = GNUTLS_SIGN_MLDSA87,
424
    .pk = GNUTLS_PK_MLDSA87,
425
    .hash = GNUTLS_DIG_SHAKE_256,
426
    .hash_output_size = 256,
427
    .aid = { { 9, 6 }, SIG_SEM_TLS13 },
428
    .flags = GNUTLS_SIGN_FLAG_TLS13_OK },
429
  { .name = 0,
430
    .oid = 0,
431
    .id = 0,
432
    .pk = 0,
433
    .hash = 0,
434
    .aid = TLS_SIGN_AID_UNKNOWN }
435
};
436
437
#define GNUTLS_SIGN_LOOP(b)                                       \
438
0
  do {                                                      \
439
0
    const gnutls_sign_entry_st *p;                    \
440
0
    for (p = sign_algorithms; p->name != NULL; p++) { \
441
0
      b;                                        \
442
0
    }                                                 \
443
0
  } while (0)
444
445
#define GNUTLS_SIGN_ALG_LOOP(a)                        \
446
0
  GNUTLS_SIGN_LOOP(if (p->id && p->id == sign) { \
447
0
    a;                                     \
448
0
    break;                                 \
449
0
  })
450
451
/**
452
 * gnutls_sign_get_name:
453
 * @algorithm: is a sign algorithm
454
 *
455
 * Convert a #gnutls_sign_algorithm_t value to a string.
456
 *
457
 * Returns: a string that contains the name of the specified sign
458
 *   algorithm, or %NULL.
459
 **/
460
const char *gnutls_sign_get_name(gnutls_sign_algorithm_t algorithm)
461
0
{
462
0
  gnutls_sign_algorithm_t sign = algorithm;
463
0
  const char *ret = NULL;
464
465
  /* avoid prefix */
466
0
  GNUTLS_SIGN_ALG_LOOP(ret = p->name);
467
468
0
  return ret;
469
0
}
470
471
/**
472
 * gnutls_sign_is_secure:
473
 * @algorithm: is a sign algorithm
474
 *
475
 * Returns: Non-zero if the provided signature algorithm is considered to be secure.
476
 **/
477
unsigned gnutls_sign_is_secure(gnutls_sign_algorithm_t algorithm)
478
0
{
479
0
  return gnutls_sign_is_secure2(algorithm, 0);
480
0
}
481
482
bool _gnutls_sign_is_secure2(const gnutls_sign_entry_st *se, unsigned int flags)
483
0
{
484
0
  if (se->hash != GNUTLS_DIG_UNKNOWN &&
485
0
      _gnutls_digest_is_insecure2(
486
0
        se->hash,
487
0
        flags & GNUTLS_SIGN_FLAG_ALLOW_INSECURE_REVERTIBLE ?
488
0
          GNUTLS_MAC_FLAG_ALLOW_INSECURE_REVERTIBLE :
489
0
          0)) {
490
0
    return gnutls_assert_val(false);
491
0
  }
492
493
0
  return (flags & GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS ?
494
0
      se->slevel == _SECURE :
495
0
      (se->slevel == _SECURE ||
496
0
       se->slevel == _INSECURE_FOR_CERTS)) ||
497
0
         (flags & GNUTLS_SIGN_FLAG_ALLOW_INSECURE_REVERTIBLE &&
498
0
    se->flags & GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE);
499
0
}
500
501
/* This is only called by cfg_apply in priority.c, in blocklisting mode. */
502
int _gnutls_sign_mark_insecure(gnutls_sign_algorithm_t sign,
503
             hash_security_level_t level)
504
0
{
505
0
#ifndef DISABLE_SYSTEM_CONFIG
506
0
  gnutls_sign_entry_st *p;
507
508
0
  if (unlikely(level == _SECURE))
509
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
510
511
0
  for (p = sign_algorithms; p->name != NULL; p++) {
512
0
    if (p->id && p->id == sign) {
513
0
      if (p->slevel < level)
514
0
        p->slevel = level;
515
0
      return 0;
516
0
    }
517
0
  }
518
0
#endif
519
0
  return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
520
0
}
521
522
/* This is only called by cfg_apply in priority.c, in allowlisting mode. */
523
void _gnutls_sign_mark_insecure_all(hash_security_level_t level)
524
0
{
525
0
#ifndef DISABLE_SYSTEM_CONFIG
526
0
  gnutls_sign_entry_st *p;
527
528
0
  for (p = sign_algorithms; p->name != NULL; p++) {
529
0
    if (p->slevel < level)
530
0
      p->slevel = level;
531
0
    p->flags |= GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE;
532
0
  }
533
0
#endif
534
0
}
535
536
int _gnutls_sign_set_secure(gnutls_sign_algorithm_t sign,
537
          hash_security_level_t slevel)
538
0
{
539
0
#ifndef DISABLE_SYSTEM_CONFIG
540
0
  gnutls_sign_entry_st *p;
541
542
0
  for (p = sign_algorithms; p->name != NULL; p++) {
543
0
    if (p->id && p->id == sign) {
544
0
      if (!(p->flags &
545
0
            GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE)) {
546
0
        return gnutls_assert_val(
547
0
          GNUTLS_E_INVALID_REQUEST);
548
0
      }
549
0
      p->slevel = slevel;
550
0
      return 0;
551
0
    }
552
0
  }
553
0
#endif
554
0
  return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
555
0
}
556
557
/**
558
 * gnutls_sign_is_secure2:
559
 * @algorithm: is a sign algorithm
560
 * @flags: zero or %GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS
561
 *
562
 * Returns: Non-zero if the provided signature algorithm is considered to be secure.
563
 **/
564
unsigned gnutls_sign_is_secure2(gnutls_sign_algorithm_t algorithm,
565
        unsigned int flags)
566
0
{
567
0
  const gnutls_sign_entry_st *se;
568
569
0
  se = _gnutls_sign_to_entry(algorithm);
570
0
  if (se == NULL)
571
0
    return 0;
572
573
0
  return _gnutls_sign_is_secure2(se, flags);
574
0
}
575
576
/**
577
 * gnutls_sign_list:
578
 *
579
 * Get a list of supported public key signature algorithms.
580
 * This function is not thread safe.
581
 *
582
 * Returns: a (0)-terminated list of #gnutls_sign_algorithm_t
583
 *   integers indicating the available ciphers.
584
 *
585
 **/
586
const gnutls_sign_algorithm_t *gnutls_sign_list(void)
587
0
{
588
0
  static gnutls_sign_algorithm_t supported_sign[MAX_ALGOS + 1] = { 0 };
589
590
0
  if (supported_sign[0] == 0) {
591
0
    int i = 0;
592
593
0
    GNUTLS_SIGN_LOOP(
594
      /* list all algorithms, but not duplicates */
595
0
      if (supported_sign[i] != p->id &&
596
0
          _gnutls_pk_sign_exists(p->id)) {
597
0
        assert(i + 1 < MAX_ALGOS);
598
0
        supported_sign[i++] = p->id;
599
0
        supported_sign[i + 1] = 0;
600
0
      });
601
0
  }
602
603
0
  return supported_sign;
604
0
}
605
606
/**
607
 * gnutls_sign_get_id:
608
 * @name: is a sign algorithm name
609
 *
610
 * The names are compared in a case insensitive way.
611
 *
612
 * Returns: return a #gnutls_sign_algorithm_t value corresponding to
613
 *   the specified algorithm, or %GNUTLS_SIGN_UNKNOWN on error.
614
 **/
615
gnutls_sign_algorithm_t gnutls_sign_get_id(const char *name)
616
0
{
617
0
  gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
618
619
0
  GNUTLS_SIGN_LOOP(if (c_strcasecmp(p->name, name) == 0) {
620
0
    ret = p->id;
621
0
    break;
622
0
  });
623
624
0
  return ret;
625
0
}
626
627
const gnutls_sign_entry_st *_gnutls_oid_to_sign_entry(const char *oid)
628
0
{
629
0
  GNUTLS_SIGN_LOOP(if (p->oid && strcmp(oid, p->oid) == 0) { return p; });
630
0
  return NULL;
631
0
}
632
633
/**
634
 * gnutls_oid_to_sign:
635
 * @oid: is an object identifier
636
 *
637
 * Converts a textual object identifier to a #gnutls_sign_algorithm_t value.
638
 *
639
 * Returns: a #gnutls_sign_algorithm_t id of the specified digest
640
 *   algorithm, or %GNUTLS_SIGN_UNKNOWN on failure.
641
 *
642
 * Since: 3.4.3
643
 **/
644
gnutls_sign_algorithm_t gnutls_oid_to_sign(const char *oid)
645
0
{
646
0
  const gnutls_sign_entry_st *se;
647
648
0
  se = _gnutls_oid_to_sign_entry(oid);
649
0
  if (se == NULL) {
650
0
    _gnutls_debug_log("Unknown SIGN OID: '%s'\n", oid);
651
0
    return GNUTLS_SIGN_UNKNOWN;
652
0
  }
653
0
  return se->id;
654
0
}
655
656
const gnutls_sign_entry_st *
657
_gnutls_pk_to_sign_entry(gnutls_pk_algorithm_t pk,
658
       gnutls_digest_algorithm_t hash)
659
0
{
660
0
  GNUTLS_SIGN_LOOP(if (pk == p->pk && hash == p->hash) { return p; });
661
662
0
  return NULL;
663
0
}
664
665
/**
666
 * gnutls_pk_to_sign:
667
 * @pk: is a public key algorithm
668
 * @hash: a hash algorithm
669
 *
670
 * This function maps public key and hash algorithms combinations
671
 * to signature algorithms.
672
 *
673
 * Returns: return a #gnutls_sign_algorithm_t value, or %GNUTLS_SIGN_UNKNOWN on error.
674
 **/
675
gnutls_sign_algorithm_t gnutls_pk_to_sign(gnutls_pk_algorithm_t pk,
676
            gnutls_digest_algorithm_t hash)
677
0
{
678
0
  const gnutls_sign_entry_st *e;
679
680
0
  e = _gnutls_pk_to_sign_entry(pk, hash);
681
0
  if (e == NULL)
682
0
    return GNUTLS_SIGN_UNKNOWN;
683
0
  return e->id;
684
0
}
685
686
/**
687
 * gnutls_sign_get_oid:
688
 * @sign: is a sign algorithm
689
 *
690
 * Convert a #gnutls_sign_algorithm_t value to its object identifier.
691
 *
692
 * Returns: a string that contains the object identifier of the specified sign
693
 *   algorithm, or %NULL.
694
 *
695
 * Since: 3.4.3
696
 **/
697
const char *gnutls_sign_get_oid(gnutls_sign_algorithm_t sign)
698
0
{
699
0
  const char *ret = NULL;
700
701
0
  GNUTLS_SIGN_ALG_LOOP(ret = p->oid);
702
703
0
  return ret;
704
0
}
705
706
/**
707
 * gnutls_sign_get_hash_algorithm:
708
 * @sign: is a signature algorithm
709
 *
710
 * This function returns the digest algorithm corresponding to
711
 * the given signature algorithms.
712
 *
713
 * Since: 3.1.1
714
 *
715
 * Returns: return a #gnutls_digest_algorithm_t value, or %GNUTLS_DIG_UNKNOWN on error.
716
 **/
717
gnutls_digest_algorithm_t
718
gnutls_sign_get_hash_algorithm(gnutls_sign_algorithm_t sign)
719
0
{
720
0
  gnutls_digest_algorithm_t ret = GNUTLS_DIG_UNKNOWN;
721
722
0
  GNUTLS_SIGN_ALG_LOOP(ret = p->hash);
723
724
0
  return ret;
725
0
}
726
727
/**
728
 * gnutls_sign_get_pk_algorithm:
729
 * @sign: is a signature algorithm
730
 *
731
 * This function returns the public key algorithm corresponding to
732
 * the given signature algorithms. Note that there may be multiple
733
 * public key algorithms supporting a particular signature type;
734
 * when dealing with such algorithms use instead gnutls_sign_supports_pk_algorithm().
735
 *
736
 * Since: 3.1.1
737
 *
738
 * Returns: return a #gnutls_pk_algorithm_t value, or %GNUTLS_PK_UNKNOWN on error.
739
 **/
740
gnutls_pk_algorithm_t gnutls_sign_get_pk_algorithm(gnutls_sign_algorithm_t sign)
741
0
{
742
0
  gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
743
744
0
  GNUTLS_SIGN_ALG_LOOP(ret = p->pk);
745
746
0
  return ret;
747
0
}
748
749
/**
750
 * gnutls_sign_supports_pk_algorithm:
751
 * @sign: is a signature algorithm
752
 * @pk: is a public key algorithm
753
 *
754
 * This function returns non-zero if the public key algorithm corresponds to
755
 * the given signature algorithm. That is, if that signature can be generated
756
 * from the given private key algorithm.
757
 *
758
 * Since: 3.6.0
759
 *
760
 * Returns: return non-zero when the provided algorithms are compatible.
761
 **/
762
unsigned gnutls_sign_supports_pk_algorithm(gnutls_sign_algorithm_t sign,
763
             gnutls_pk_algorithm_t pk)
764
0
{
765
0
  const gnutls_sign_entry_st *p;
766
0
  unsigned r;
767
768
0
  for (p = sign_algorithms; p->name != NULL; p++) {
769
0
    if (p->id && p->id == sign) {
770
0
      r = sign_supports_priv_pk_algorithm(p, pk);
771
0
      if (r != 0)
772
0
        return r;
773
0
    }
774
0
  }
775
776
0
  return 0;
777
0
}
778
779
gnutls_sign_algorithm_t _gnutls_tls_aid_to_sign(uint8_t id0, uint8_t id1,
780
            const version_entry_st *ver)
781
0
{
782
0
  gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
783
784
0
  if (id0 == 255 && id1 == 255)
785
0
    return ret;
786
787
0
  GNUTLS_SIGN_LOOP(if (p->aid.id[0] == id0 && p->aid.id[1] == id1 &&
788
0
           ((p->aid.tls_sem & ver->tls_sig_sem) != 0)) {
789
0
    ret = p->id;
790
0
    break;
791
0
  });
792
793
0
  return ret;
794
0
}
795
796
/* Returns NULL if a valid AID is not found
797
 */
798
const sign_algorithm_st *_gnutls_sign_to_tls_aid(gnutls_sign_algorithm_t sign)
799
0
{
800
0
  const sign_algorithm_st *ret = NULL;
801
802
0
  GNUTLS_SIGN_ALG_LOOP(ret = &p->aid);
803
804
0
  if (ret != NULL && HAVE_UNKNOWN_SIGAID(ret))
805
0
    return NULL;
806
807
0
  return ret;
808
0
}
809
810
const gnutls_sign_entry_st *_gnutls_sign_to_entry(gnutls_sign_algorithm_t sign)
811
0
{
812
0
  const gnutls_sign_entry_st *ret = NULL;
813
814
0
  GNUTLS_SIGN_ALG_LOOP(ret = p);
815
816
0
  return ret;
817
0
}
818
819
const gnutls_sign_entry_st *
820
_gnutls_tls_aid_to_sign_entry(uint8_t id0, uint8_t id1,
821
            const version_entry_st *ver)
822
0
{
823
0
  if (id0 == 255 && id1 == 255)
824
0
    return NULL;
825
826
0
  GNUTLS_SIGN_LOOP(
827
0
    if (p->aid.id[0] == id0 && p->aid.id[1] == id1 &&
828
0
        ((p->aid.tls_sem & ver->tls_sig_sem) != 0)) { return p; });
829
830
0
  return NULL;
831
0
}
832
833
const gnutls_sign_entry_st *
834
_gnutls13_sign_get_compatible_with_privkey(gnutls_privkey_t privkey)
835
0
{
836
0
  GNUTLS_SIGN_LOOP(if ((p->flags & GNUTLS_SIGN_FLAG_TLS13_OK) &&
837
0
           _gnutls_privkey_compatible_with_sig(
838
0
             privkey, p->id)) { return p; });
839
840
0
  return NULL;
841
0
}
842
843
unsigned _gnutls_sign_get_hash_strength(gnutls_sign_algorithm_t sign)
844
0
{
845
0
  const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign);
846
0
  const mac_entry_st *me;
847
0
  unsigned hash_output_size;
848
849
0
  if (unlikely(se == NULL))
850
0
    return 0;
851
852
0
  me = hash_to_entry(se->hash);
853
0
  if (unlikely(me == NULL))
854
0
    return 0;
855
856
0
  if (se->hash_output_size > 0)
857
0
    hash_output_size = se->hash_output_size;
858
0
  else
859
0
    hash_output_size = _gnutls_mac_get_algo_len(me);
860
861
0
  if (me->id == GNUTLS_MAC_SHAKE_128)
862
0
    return MIN(hash_output_size * 8 / 2, 128);
863
0
  else if (me->id == GNUTLS_MAC_SHAKE_256)
864
0
    return MIN(hash_output_size * 8 / 2, 256);
865
866
0
  return hash_output_size * 8 / 2;
867
0
}