Coverage Report

Created: 2025-07-23 07:16

/src/gnutls/lib/pk.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2014 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
/* This file contains the functions needed for RSA/DSA public key
25
 * encryption and signatures. 
26
 */
27
28
#include "gnutls_int.h"
29
#include "mpi.h"
30
#include "pk.h"
31
#include "errors.h"
32
#include "datum.h"
33
#include "global.h"
34
#include "num.h"
35
#include "debug.h"
36
#include "x509/x509_int.h"
37
#include "x509/common.h"
38
#include "random.h"
39
#include <gnutls/crypto.h>
40
41
/**
42
 * gnutls_encode_rs_value:
43
 * @sig_value: will hold a Dss-Sig-Value DER encoded structure
44
 * @r: must contain the r value
45
 * @s: must contain the s value
46
 *
47
 * This function will encode the provided r and s values, 
48
 * into a Dss-Sig-Value structure, used for DSA and ECDSA
49
 * signatures.
50
 *
51
 * The output value should be deallocated using gnutls_free().
52
 *
53
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
54
 *   an error code is returned.
55
 *
56
 * Since: 3.6.0
57
 *
58
 **/
59
int gnutls_encode_rs_value(gnutls_datum_t *sig_value, const gnutls_datum_t *r,
60
         const gnutls_datum_t *s)
61
0
{
62
0
  return _gnutls_encode_ber_rs_raw(sig_value, r, s);
63
0
}
64
65
/* same as gnutls_encode_rs_value(), but kept since it used
66
 * to be exported for FIPS140 CAVS testing.
67
 */
68
int _gnutls_encode_ber_rs_raw(gnutls_datum_t *sig_value,
69
            const gnutls_datum_t *r, const gnutls_datum_t *s)
70
0
{
71
0
  asn1_node sig;
72
0
  int result, ret;
73
0
  uint8_t *tmp = NULL;
74
75
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
76
0
            "GNUTLS.DSASignatureValue", &sig)) !=
77
0
      ASN1_SUCCESS) {
78
0
    gnutls_assert();
79
0
    return _gnutls_asn2err(result);
80
0
  }
81
82
0
  if (s->data[0] >= 0x80 || r->data[0] >= 0x80) {
83
0
    tmp = gnutls_malloc(MAX(r->size, s->size) + 1);
84
0
    if (tmp == NULL) {
85
0
      ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
86
0
      goto cleanup;
87
0
    }
88
0
  }
89
90
0
  if (r->data[0] >= 0x80) {
91
0
    assert(tmp);
92
0
    tmp[0] = 0;
93
0
    memcpy(&tmp[1], r->data, r->size);
94
0
    result = asn1_write_value(sig, "r", tmp, 1 + r->size);
95
0
  } else {
96
0
    result = asn1_write_value(sig, "r", r->data, r->size);
97
0
  }
98
99
0
  if (result != ASN1_SUCCESS) {
100
0
    gnutls_assert();
101
0
    ret = _gnutls_asn2err(result);
102
0
    goto cleanup;
103
0
  }
104
105
0
  if (s->data[0] >= 0x80) {
106
0
    assert(tmp);
107
0
    tmp[0] = 0;
108
0
    memcpy(&tmp[1], s->data, s->size);
109
0
    result = asn1_write_value(sig, "s", tmp, 1 + s->size);
110
0
  } else {
111
0
    result = asn1_write_value(sig, "s", s->data, s->size);
112
0
  }
113
114
0
  if (result != ASN1_SUCCESS) {
115
0
    gnutls_assert();
116
0
    ret = _gnutls_asn2err(result);
117
0
    goto cleanup;
118
0
  }
119
120
0
  ret = _gnutls_x509_der_encode(sig, "", sig_value, 0);
121
0
  if (ret < 0) {
122
0
    gnutls_assert();
123
0
    goto cleanup;
124
0
  }
125
126
0
  ret = 0;
127
0
cleanup:
128
0
  gnutls_free(tmp);
129
0
  asn1_delete_structure(&sig);
130
0
  return ret;
131
0
}
132
133
int _gnutls_encode_ber_rs(gnutls_datum_t *sig_value, bigint_t r, bigint_t s)
134
0
{
135
0
  asn1_node sig;
136
0
  int result;
137
138
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
139
0
            "GNUTLS.DSASignatureValue", &sig)) !=
140
0
      ASN1_SUCCESS) {
141
0
    gnutls_assert();
142
0
    return _gnutls_asn2err(result);
143
0
  }
144
145
0
  result = _gnutls_x509_write_int(sig, "r", r, 1);
146
0
  if (result < 0) {
147
0
    gnutls_assert();
148
0
    asn1_delete_structure(&sig);
149
0
    return result;
150
0
  }
151
152
0
  result = _gnutls_x509_write_int(sig, "s", s, 1);
153
0
  if (result < 0) {
154
0
    gnutls_assert();
155
0
    asn1_delete_structure(&sig);
156
0
    return result;
157
0
  }
158
159
0
  result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
160
0
  asn1_delete_structure(&sig);
161
162
0
  if (result < 0)
163
0
    return gnutls_assert_val(result);
164
165
0
  return 0;
166
0
}
167
168
/* decodes the Dss-Sig-Value structure
169
 */
170
int _gnutls_decode_ber_rs(const gnutls_datum_t *sig_value, bigint_t *r,
171
        bigint_t *s)
172
0
{
173
0
  asn1_node sig;
174
0
  int result;
175
176
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
177
0
            "GNUTLS.DSASignatureValue", &sig)) !=
178
0
      ASN1_SUCCESS) {
179
0
    gnutls_assert();
180
0
    return _gnutls_asn2err(result);
181
0
  }
182
183
  /* rfc3279 doesn't specify whether Dss-Sig-Value is encoded
184
   * as DER or BER. As such we do not restrict to the DER subset. */
185
0
  result =
186
0
    asn1_der_decoding(&sig, sig_value->data, sig_value->size, NULL);
187
0
  if (result != ASN1_SUCCESS) {
188
0
    gnutls_assert();
189
0
    asn1_delete_structure(&sig);
190
0
    return _gnutls_asn2err(result);
191
0
  }
192
193
0
  result = _gnutls_x509_read_int(sig, "r", r);
194
0
  if (result < 0) {
195
0
    gnutls_assert();
196
0
    asn1_delete_structure(&sig);
197
0
    return result;
198
0
  }
199
200
0
  result = _gnutls_x509_read_int(sig, "s", s);
201
0
  if (result < 0) {
202
0
    gnutls_assert();
203
0
    _gnutls_mpi_release(r);
204
0
    asn1_delete_structure(&sig);
205
0
    return result;
206
0
  }
207
208
0
  asn1_delete_structure(&sig);
209
210
0
  return 0;
211
0
}
212
213
/**
214
 * gnutls_decode_rs_value:
215
 * @sig_value: holds a Dss-Sig-Value DER or BER encoded structure
216
 * @r: will contain the r value
217
 * @s: will contain the s value
218
 *
219
 * This function will decode the provided @sig_value, 
220
 * into @r and @s elements. The Dss-Sig-Value is used for DSA and ECDSA
221
 * signatures.
222
 *
223
 * The output values may be padded with a zero byte to prevent them
224
 * from being interpreted as negative values. The value
225
 * should be deallocated using gnutls_free().
226
 *
227
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
228
 *   an error code is returned.
229
 *
230
 * Since: 3.6.0
231
 *
232
 **/
233
int gnutls_decode_rs_value(const gnutls_datum_t *sig_value, gnutls_datum_t *r,
234
         gnutls_datum_t *s)
235
0
{
236
0
  return _gnutls_decode_ber_rs_raw(sig_value, r, s);
237
0
}
238
239
/* same as gnutls_decode_rs_value(), but kept since it used
240
 * to be exported for FIPS140 CAVS testing.
241
 */
242
int _gnutls_decode_ber_rs_raw(const gnutls_datum_t *sig_value,
243
            gnutls_datum_t *r, gnutls_datum_t *s)
244
0
{
245
0
  asn1_node sig;
246
0
  int result;
247
248
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
249
0
            "GNUTLS.DSASignatureValue", &sig)) !=
250
0
      ASN1_SUCCESS) {
251
0
    gnutls_assert();
252
0
    return _gnutls_asn2err(result);
253
0
  }
254
255
  /* rfc3279 doesn't specify whether Dss-Sig-Value is encoded
256
   * as DER or BER. As such we do not restrict to the DER subset. */
257
0
  result =
258
0
    asn1_der_decoding(&sig, sig_value->data, sig_value->size, NULL);
259
0
  if (result != ASN1_SUCCESS) {
260
0
    gnutls_assert();
261
0
    asn1_delete_structure(&sig);
262
0
    return _gnutls_asn2err(result);
263
0
  }
264
265
0
  result = _gnutls_x509_read_value(sig, "r", r);
266
0
  if (result < 0) {
267
0
    gnutls_assert();
268
0
    asn1_delete_structure(&sig);
269
0
    return result;
270
0
  }
271
272
0
  result = _gnutls_x509_read_value(sig, "s", s);
273
0
  if (result < 0) {
274
0
    gnutls_assert();
275
0
    gnutls_free(r->data);
276
0
    asn1_delete_structure(&sig);
277
0
    return result;
278
0
  }
279
280
0
  asn1_delete_structure(&sig);
281
282
0
  return 0;
283
0
}
284
285
int _gnutls_encode_gost_rs(gnutls_datum_t *sig_value, bigint_t r, bigint_t s,
286
         size_t intsize)
287
0
{
288
0
  uint8_t *data;
289
0
  int result;
290
291
0
  data = gnutls_malloc(intsize * 2);
292
0
  if (data == NULL) {
293
0
    gnutls_assert();
294
0
    return GNUTLS_E_MEMORY_ERROR;
295
0
  }
296
297
0
  if ((result = _gnutls_mpi_bprint_size(s, data, intsize)) < 0) {
298
0
    gnutls_assert();
299
0
    gnutls_free(data);
300
0
    return result;
301
0
  }
302
303
0
  if ((result = _gnutls_mpi_bprint_size(r, data + intsize, intsize)) <
304
0
      0) {
305
0
    gnutls_assert();
306
0
    gnutls_free(data);
307
0
    return result;
308
0
  }
309
310
0
  sig_value->data = data;
311
0
  sig_value->size = intsize * 2;
312
313
0
  return 0;
314
0
}
315
316
int _gnutls_decode_gost_rs(const gnutls_datum_t *sig_value, bigint_t *r,
317
         bigint_t *s)
318
0
{
319
0
  int ret;
320
0
  unsigned halfsize = sig_value->size >> 1;
321
322
0
  if (sig_value->size % 2 != 0) {
323
0
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
324
0
  }
325
326
0
  ret = _gnutls_mpi_init_scan(s, sig_value->data, halfsize);
327
0
  if (ret < 0)
328
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
329
330
0
  ret = _gnutls_mpi_init_scan(r, sig_value->data + halfsize, halfsize);
331
0
  if (ret < 0) {
332
0
    _gnutls_mpi_release(s);
333
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
334
0
  }
335
336
0
  return 0;
337
0
}
338
339
/**
340
 * gnutls_encode_gost_rs_value:
341
 * @sig_value: will hold a GOST signature according to RFC 4491 section 2.2.2
342
 * @r: must contain the r value
343
 * @s: must contain the s value
344
 *
345
 * This function will encode the provided r and s values, into binary
346
 * representation according to RFC 4491 section 2.2.2, used for GOST R
347
 * 34.10-2001 (and thus also for GOST R 34.10-2012) signatures.
348
 *
349
 * The output value should be deallocated using gnutls_free().
350
 *
351
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
352
 *   an error code is returned.
353
 *
354
 * Since: 3.6.0
355
 */
356
int gnutls_encode_gost_rs_value(gnutls_datum_t *sig_value,
357
        const gnutls_datum_t *r,
358
        const gnutls_datum_t *s)
359
0
{
360
0
  uint8_t *data;
361
0
  size_t intsize = r->size;
362
363
0
  if (s->size != intsize) {
364
0
    gnutls_assert();
365
0
    return GNUTLS_E_ILLEGAL_PARAMETER;
366
0
  }
367
368
0
  data = gnutls_malloc(intsize * 2);
369
0
  if (data == NULL) {
370
0
    gnutls_assert();
371
0
    return GNUTLS_E_MEMORY_ERROR;
372
0
  }
373
374
0
  memcpy(data, s->data, intsize);
375
0
  memcpy(data + intsize, r->data, intsize);
376
377
0
  sig_value->data = data;
378
0
  sig_value->size = intsize * 2;
379
380
0
  return 0;
381
0
}
382
383
/**
384
 * gnutls_decode_gost_rs_value:
385
 * @sig_value: will holds a GOST signature according to RFC 4491 section 2.2.2
386
 * @r: will contain the r value
387
 * @s: will contain the s value
388
 *
389
 * This function will decode the provided @sig_value, into @r and @s elements.
390
 * See RFC 4491 section 2.2.2 for the format of signature value.
391
 *
392
 * The output values may be padded with a zero byte to prevent them
393
 * from being interpreted as negative values. The value
394
 * should be deallocated using gnutls_free().
395
 *
396
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
397
 *   an error code is returned.
398
 *
399
 * Since: 3.6.0
400
 */
401
int gnutls_decode_gost_rs_value(const gnutls_datum_t *sig_value,
402
        gnutls_datum_t *r, gnutls_datum_t *s)
403
0
{
404
0
  int ret;
405
0
  unsigned halfsize = sig_value->size >> 1;
406
407
0
  if (sig_value->size % 2 != 0)
408
0
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
409
410
0
  ret = _gnutls_set_datum(s, sig_value->data, halfsize);
411
0
  if (ret != 0)
412
0
    return gnutls_assert_val(ret);
413
414
0
  ret = _gnutls_set_datum(r, sig_value->data + halfsize, halfsize);
415
0
  if (ret != 0) {
416
0
    _gnutls_free_datum(s);
417
0
    return gnutls_assert_val(ret);
418
0
  }
419
420
0
  return 0;
421
0
}
422
423
gnutls_digest_algorithm_t _gnutls_gost_digest(gnutls_pk_algorithm_t pk)
424
0
{
425
0
  if (pk == GNUTLS_PK_GOST_01)
426
0
    return GNUTLS_DIG_GOSTR_94;
427
0
  else if (pk == GNUTLS_PK_GOST_12_256)
428
0
    return GNUTLS_DIG_STREEBOG_256;
429
0
  else if (pk == GNUTLS_PK_GOST_12_512)
430
0
    return GNUTLS_DIG_STREEBOG_512;
431
432
0
  gnutls_assert();
433
434
0
  return GNUTLS_DIG_UNKNOWN;
435
0
}
436
437
gnutls_pk_algorithm_t _gnutls_digest_gost(gnutls_digest_algorithm_t digest)
438
0
{
439
0
  if (digest == GNUTLS_DIG_GOSTR_94)
440
0
    return GNUTLS_PK_GOST_01;
441
0
  else if (digest == GNUTLS_DIG_STREEBOG_256)
442
0
    return GNUTLS_PK_GOST_12_256;
443
0
  else if (digest == GNUTLS_DIG_STREEBOG_512)
444
0
    return GNUTLS_PK_GOST_12_512;
445
446
0
  gnutls_assert();
447
448
0
  return GNUTLS_PK_UNKNOWN;
449
0
}
450
451
gnutls_gost_paramset_t _gnutls_gost_paramset_default(gnutls_pk_algorithm_t pk)
452
0
{
453
0
  if (pk == GNUTLS_PK_GOST_01)
454
0
    return GNUTLS_GOST_PARAMSET_CP_A;
455
0
  else if (pk == GNUTLS_PK_GOST_12_256 || pk == GNUTLS_PK_GOST_12_512)
456
0
    return GNUTLS_GOST_PARAMSET_TC26_Z;
457
0
  else
458
0
    return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN);
459
0
}
460
461
/* some generic pk functions */
462
463
int _gnutls_pk_params_copy(gnutls_pk_params_st *dst,
464
         const gnutls_pk_params_st *src)
465
0
{
466
0
  unsigned int i, j;
467
0
  dst->params_nr = 0;
468
469
0
  if (src == NULL || (src->params_nr == 0 && src->raw_pub.size == 0)) {
470
0
    gnutls_assert();
471
0
    return GNUTLS_E_INVALID_REQUEST;
472
0
  }
473
474
0
  dst->pkflags = src->pkflags;
475
0
  dst->curve = src->curve;
476
0
  dst->gost_params = src->gost_params;
477
0
  dst->qbits = src->qbits;
478
0
  dst->algo = src->algo;
479
480
0
  for (i = 0; i < src->params_nr; i++) {
481
0
    if (src->params[i]) {
482
0
      dst->params[i] = _gnutls_mpi_copy(src->params[i]);
483
0
      if (dst->params[i] == NULL) {
484
0
        goto fail;
485
0
      }
486
0
    }
487
488
0
    dst->params_nr++;
489
0
  }
490
491
0
  if (_gnutls_set_datum(&dst->raw_priv, src->raw_priv.data,
492
0
            src->raw_priv.size) < 0) {
493
0
    gnutls_assert();
494
0
    goto fail;
495
0
  }
496
497
0
  if (_gnutls_set_datum(&dst->raw_pub, src->raw_pub.data,
498
0
            src->raw_pub.size) < 0) {
499
0
    gnutls_assert();
500
0
    goto fail;
501
0
  }
502
503
0
  if (src->seed_size) {
504
0
    dst->seed_size = src->seed_size;
505
0
    memcpy(dst->seed, src->seed, src->seed_size);
506
0
  }
507
0
  dst->palgo = src->palgo;
508
509
0
  if (_gnutls_x509_spki_copy(&dst->spki, &src->spki) < 0) {
510
0
    gnutls_assert();
511
0
    goto fail;
512
0
  }
513
514
0
  return 0;
515
516
0
fail:
517
0
  for (j = 0; j < i; j++)
518
0
    _gnutls_mpi_release(&dst->params[j]);
519
0
  return GNUTLS_E_MEMORY_ERROR;
520
0
}
521
522
void gnutls_pk_params_init(gnutls_pk_params_st *p)
523
0
{
524
0
  memset(p, 0, sizeof(gnutls_pk_params_st));
525
0
}
526
527
void gnutls_pk_params_release(gnutls_pk_params_st *p)
528
0
{
529
0
  unsigned int i;
530
0
  for (i = 0; i < p->params_nr; i++) {
531
0
    _gnutls_mpi_release(&p->params[i]);
532
0
  }
533
0
  gnutls_free(p->raw_priv.data);
534
0
  gnutls_free(p->raw_pub.data);
535
0
  gnutls_free(p->raw_seed.data);
536
0
  _gnutls_x509_spki_clear(&p->spki);
537
538
0
  p->params_nr = 0;
539
0
}
540
541
void gnutls_pk_params_clear(gnutls_pk_params_st *p)
542
0
{
543
0
  unsigned int i;
544
0
  for (i = 0; i < p->params_nr; i++) {
545
0
    if (p->params[i] != NULL)
546
0
      _gnutls_mpi_clear(p->params[i]);
547
0
  }
548
0
  gnutls_memset(p->seed, 0, p->seed_size);
549
0
  p->seed_size = 0;
550
0
  if (p->raw_priv.data != NULL) {
551
0
    gnutls_memset(p->raw_priv.data, 0, p->raw_priv.size);
552
0
    p->raw_priv.size = 0;
553
0
  }
554
0
  if (p->raw_seed.data != NULL) {
555
0
    gnutls_memset(p->raw_seed.data, 0, p->raw_seed.size);
556
0
    p->raw_seed.size = 0;
557
0
  }
558
0
}
559
560
int _gnutls_find_rsa_pss_salt_size(unsigned bits, const mac_entry_st *me,
561
           unsigned salt_size)
562
0
{
563
0
  unsigned digest_size;
564
0
  int max_salt_size;
565
0
  unsigned key_size;
566
567
0
  digest_size = _gnutls_hash_get_algo_len(me);
568
0
  key_size = (bits + 7) / 8;
569
570
0
  if (key_size == 0) {
571
0
    return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY);
572
0
  } else {
573
0
    max_salt_size = key_size - digest_size - 2;
574
0
    if (max_salt_size < 0)
575
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
576
0
  }
577
578
0
  if (salt_size < digest_size)
579
0
    salt_size = digest_size;
580
581
0
  if (salt_size > (unsigned)max_salt_size)
582
0
    salt_size = max_salt_size;
583
584
0
  return salt_size;
585
0
}
586
587
/* Writes the digest information and the digest in a DER encoded
588
 * structure. The digest info is allocated and stored into the info structure.
589
 */
590
int encode_ber_digest_info(const mac_entry_st *e, const gnutls_datum_t *digest,
591
         gnutls_datum_t *output)
592
0
{
593
0
  asn1_node dinfo = NULL;
594
0
  int result;
595
0
  const char *algo;
596
0
  uint8_t *tmp_output;
597
0
  int tmp_output_size;
598
599
0
  if (unlikely(e == NULL)) {
600
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
601
0
  }
602
603
  /* prevent asn1_write_value() treating input as string */
604
0
  if (digest->size == 0)
605
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
606
607
0
  algo = _gnutls_x509_mac_to_oid(e);
608
0
  if (algo == NULL) {
609
0
    gnutls_assert();
610
0
    _gnutls_debug_log("Hash algorithm: %d has no OID\n", e->id);
611
0
    return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
612
0
  }
613
614
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
615
0
            "GNUTLS.DigestInfo", &dinfo)) !=
616
0
      ASN1_SUCCESS) {
617
0
    gnutls_assert();
618
0
    return _gnutls_asn2err(result);
619
0
  }
620
621
0
  result = asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
622
0
  if (result != ASN1_SUCCESS) {
623
0
    gnutls_assert();
624
0
    asn1_delete_structure(&dinfo);
625
0
    return _gnutls_asn2err(result);
626
0
  }
627
628
  /* Write an ASN.1 NULL in the parameters field.  This matches RFC
629
     3279 and RFC 4055, although is arguable incorrect from a historic
630
     perspective (see those documents for more information).
631
     Regardless of what is correct, this appears to be what most
632
     implementations do.  */
633
0
  result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
634
0
          ASN1_NULL, ASN1_NULL_SIZE);
635
0
  if (result != ASN1_SUCCESS) {
636
0
    gnutls_assert();
637
0
    asn1_delete_structure(&dinfo);
638
0
    return _gnutls_asn2err(result);
639
0
  }
640
641
0
  result = asn1_write_value(dinfo, "digest", digest->data, digest->size);
642
0
  if (result != ASN1_SUCCESS) {
643
0
    gnutls_assert();
644
0
    asn1_delete_structure(&dinfo);
645
0
    return _gnutls_asn2err(result);
646
0
  }
647
648
0
  tmp_output_size = 0;
649
0
  result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
650
0
  if (result != ASN1_MEM_ERROR) {
651
0
    gnutls_assert();
652
0
    asn1_delete_structure(&dinfo);
653
0
    return _gnutls_asn2err(result);
654
0
  }
655
656
0
  tmp_output = gnutls_malloc(tmp_output_size);
657
0
  if (tmp_output == NULL) {
658
0
    gnutls_assert();
659
0
    asn1_delete_structure(&dinfo);
660
0
    return GNUTLS_E_MEMORY_ERROR;
661
0
  }
662
663
0
  result = asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
664
0
  if (result != ASN1_SUCCESS) {
665
0
    gnutls_assert();
666
0
    gnutls_free(tmp_output);
667
0
    asn1_delete_structure(&dinfo);
668
0
    return _gnutls_asn2err(result);
669
0
  }
670
671
0
  asn1_delete_structure(&dinfo);
672
673
0
  output->size = tmp_output_size;
674
0
  output->data = tmp_output;
675
676
0
  return 0;
677
0
}
678
679
/**
680
 * gnutls_encode_ber_digest_info:
681
 * @info: an RSA BER encoded DigestInfo structure
682
 * @hash: the hash algorithm that was used to get the digest
683
 * @digest: must contain the digest data
684
 * @output: will contain the allocated DigestInfo BER encoded data
685
 *
686
 * This function will encode the provided digest data, and its
687
 * algorithm into an RSA PKCS#1 1.5 DigestInfo structure. 
688
 *
689
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
690
 *   an error code is returned.
691
 *
692
 * Since: 3.5.0
693
 *
694
 **/
695
int gnutls_encode_ber_digest_info(gnutls_digest_algorithm_t hash,
696
          const gnutls_datum_t *digest,
697
          gnutls_datum_t *output)
698
0
{
699
0
  const mac_entry_st *e = hash_to_entry(hash);
700
0
  if (unlikely(e == NULL))
701
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
702
703
0
  return encode_ber_digest_info(e, digest, output);
704
0
}
705
706
/**
707
 * gnutls_decode_ber_digest_info:
708
 * @info: an RSA BER encoded DigestInfo structure
709
 * @hash: will contain the hash algorithm of the structure
710
 * @digest: will contain the hash output of the structure
711
 * @digest_size: will contain the hash size of the structure; initially must hold the maximum size of @digest
712
 *
713
 * This function will parse an RSA PKCS#1 1.5 DigestInfo structure
714
 * and report the hash algorithm used as well as the digest data.
715
 *
716
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
717
 *   an error code is returned.
718
 *
719
 * Since: 3.5.0
720
 *
721
 **/
722
int gnutls_decode_ber_digest_info(const gnutls_datum_t *info,
723
          gnutls_digest_algorithm_t *hash,
724
          unsigned char *digest,
725
          unsigned int *digest_size)
726
0
{
727
0
  asn1_node dinfo = NULL;
728
0
  int result;
729
0
  char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
730
0
  int len;
731
732
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
733
0
            "GNUTLS.DigestInfo", &dinfo)) !=
734
0
      ASN1_SUCCESS) {
735
0
    gnutls_assert();
736
0
    return _gnutls_asn2err(result);
737
0
  }
738
739
  /* rfc2313 required BER encoding of that field, thus
740
   * we don't restrict libtasn1 to DER subset */
741
0
  result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
742
0
  if (result != ASN1_SUCCESS) {
743
0
    gnutls_assert();
744
0
    asn1_delete_structure(&dinfo);
745
0
    return _gnutls_asn2err(result);
746
0
  }
747
748
0
  len = sizeof(str) - 1;
749
0
  result = asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len);
750
0
  if (result != ASN1_SUCCESS) {
751
0
    gnutls_assert();
752
0
    asn1_delete_structure(&dinfo);
753
0
    return _gnutls_asn2err(result);
754
0
  }
755
756
0
  *hash = gnutls_oid_to_digest(str);
757
758
0
  if (*hash == GNUTLS_DIG_UNKNOWN) {
759
0
    _gnutls_debug_log("verify.c: HASH OID: %s\n", str);
760
761
0
    gnutls_assert();
762
0
    asn1_delete_structure(&dinfo);
763
0
    return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
764
0
  }
765
766
0
  len = sizeof(str) - 1;
767
0
  result =
768
0
    asn1_read_value(dinfo, "digestAlgorithm.parameters", str, &len);
769
  /* To avoid permitting garbage in the parameters field, either the
770
     parameters field is not present, or it contains 0x05 0x00. */
771
0
  if (!(result == ASN1_ELEMENT_NOT_FOUND ||
772
0
        (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
773
0
         memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
774
0
    gnutls_assert();
775
0
    asn1_delete_structure(&dinfo);
776
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
777
0
  }
778
779
0
  len = *digest_size;
780
0
  result = asn1_read_value(dinfo, "digest", digest, &len);
781
782
0
  if (result != ASN1_SUCCESS) {
783
0
    gnutls_assert();
784
0
    *digest_size = len;
785
0
    asn1_delete_structure(&dinfo);
786
0
    return _gnutls_asn2err(result);
787
0
  }
788
789
0
  *digest_size = len;
790
0
  asn1_delete_structure(&dinfo);
791
792
0
  return 0;
793
0
}
794
795
int _gnutls_params_get_rsa_raw(const gnutls_pk_params_st *params,
796
             gnutls_datum_t *m, gnutls_datum_t *e,
797
             gnutls_datum_t *d, gnutls_datum_t *p,
798
             gnutls_datum_t *q, gnutls_datum_t *u,
799
             gnutls_datum_t *e1, gnutls_datum_t *e2,
800
             unsigned int flags)
801
0
{
802
0
  int ret;
803
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
804
805
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
806
0
    dprint = _gnutls_mpi_dprint;
807
808
0
  if (params == NULL) {
809
0
    gnutls_assert();
810
0
    return GNUTLS_E_INVALID_REQUEST;
811
0
  }
812
813
0
  if (!GNUTLS_PK_IS_RSA(params->algo)) {
814
0
    gnutls_assert();
815
0
    return GNUTLS_E_INVALID_REQUEST;
816
0
  }
817
818
0
  if (m) {
819
0
    ret = dprint(params->params[0], m);
820
0
    if (ret < 0) {
821
0
      gnutls_assert();
822
0
      goto error;
823
0
    }
824
0
  }
825
826
  /* E */
827
0
  if (e) {
828
0
    ret = dprint(params->params[1], e);
829
0
    if (ret < 0) {
830
0
      gnutls_assert();
831
0
      goto error;
832
0
    }
833
0
  }
834
835
  /* D */
836
0
  if (d && params->params[2]) {
837
0
    ret = dprint(params->params[2], d);
838
0
    if (ret < 0) {
839
0
      gnutls_assert();
840
0
      goto error;
841
0
    }
842
0
  } else if (d) {
843
0
    d->data = NULL;
844
0
    d->size = 0;
845
0
  }
846
847
  /* P */
848
0
  if (p && params->params[3]) {
849
0
    ret = dprint(params->params[3], p);
850
0
    if (ret < 0) {
851
0
      gnutls_assert();
852
0
      goto error;
853
0
    }
854
0
  } else if (p) {
855
0
    p->data = NULL;
856
0
    p->size = 0;
857
0
  }
858
859
  /* Q */
860
0
  if (q && params->params[4]) {
861
0
    ret = dprint(params->params[4], q);
862
0
    if (ret < 0) {
863
0
      gnutls_assert();
864
0
      goto error;
865
0
    }
866
0
  } else if (q) {
867
0
    q->data = NULL;
868
0
    q->size = 0;
869
0
  }
870
871
  /* U */
872
0
  if (u && params->params[5]) {
873
0
    ret = dprint(params->params[5], u);
874
0
    if (ret < 0) {
875
0
      gnutls_assert();
876
0
      goto error;
877
0
    }
878
0
  } else if (u) {
879
0
    u->data = NULL;
880
0
    u->size = 0;
881
0
  }
882
883
  /* E1 */
884
0
  if (e1 && params->params[6]) {
885
0
    ret = dprint(params->params[6], e1);
886
0
    if (ret < 0) {
887
0
      gnutls_assert();
888
0
      goto error;
889
0
    }
890
0
  } else if (e1) {
891
0
    e1->data = NULL;
892
0
    e1->size = 0;
893
0
  }
894
895
  /* E2 */
896
0
  if (e2 && params->params[7]) {
897
0
    ret = dprint(params->params[7], e2);
898
0
    if (ret < 0) {
899
0
      gnutls_assert();
900
0
      goto error;
901
0
    }
902
0
  } else if (e2) {
903
0
    e2->data = NULL;
904
0
    e2->size = 0;
905
0
  }
906
907
0
  return 0;
908
909
0
error:
910
0
  _gnutls_free_datum(m);
911
0
  _gnutls_free_datum(d);
912
0
  _gnutls_free_datum(e);
913
0
  _gnutls_free_datum(e1);
914
0
  _gnutls_free_datum(e2);
915
0
  _gnutls_free_datum(p);
916
0
  _gnutls_free_datum(q);
917
918
0
  return ret;
919
0
}
920
921
int _gnutls_params_get_dsa_raw(const gnutls_pk_params_st *params,
922
             gnutls_datum_t *p, gnutls_datum_t *q,
923
             gnutls_datum_t *g, gnutls_datum_t *y,
924
             gnutls_datum_t *x, unsigned int flags)
925
0
{
926
0
  int ret;
927
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
928
929
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
930
0
    dprint = _gnutls_mpi_dprint;
931
932
0
  if (params == NULL) {
933
0
    gnutls_assert();
934
0
    return GNUTLS_E_INVALID_REQUEST;
935
0
  }
936
937
0
  if (params->algo != GNUTLS_PK_DSA && params->algo != GNUTLS_PK_DH) {
938
0
    gnutls_assert();
939
0
    return GNUTLS_E_INVALID_REQUEST;
940
0
  }
941
942
  /* P */
943
0
  if (p) {
944
0
    ret = dprint(params->params[0], p);
945
0
    if (ret < 0) {
946
0
      gnutls_assert();
947
0
      return ret;
948
0
    }
949
0
  }
950
951
  /* Q */
952
0
  if (q) {
953
0
    ret = dprint(params->params[1], q);
954
0
    if (ret < 0) {
955
0
      gnutls_assert();
956
0
      _gnutls_free_datum(p);
957
0
      return ret;
958
0
    }
959
0
  }
960
961
  /* G */
962
0
  if (g) {
963
0
    ret = dprint(params->params[2], g);
964
0
    if (ret < 0) {
965
0
      gnutls_assert();
966
0
      _gnutls_free_datum(p);
967
0
      _gnutls_free_datum(q);
968
0
      return ret;
969
0
    }
970
0
  }
971
972
  /* Y */
973
0
  if (y) {
974
0
    ret = dprint(params->params[3], y);
975
0
    if (ret < 0) {
976
0
      gnutls_assert();
977
0
      _gnutls_free_datum(p);
978
0
      _gnutls_free_datum(g);
979
0
      _gnutls_free_datum(q);
980
0
      return ret;
981
0
    }
982
0
  }
983
984
  /* X */
985
0
  if (x) {
986
0
    ret = dprint(params->params[4], x);
987
0
    if (ret < 0) {
988
0
      gnutls_assert();
989
0
      _gnutls_free_datum(y);
990
0
      _gnutls_free_datum(p);
991
0
      _gnutls_free_datum(g);
992
0
      _gnutls_free_datum(q);
993
0
      return ret;
994
0
    }
995
0
  }
996
997
0
  return 0;
998
0
}
999
1000
int _gnutls_params_get_ecc_raw(const gnutls_pk_params_st *params,
1001
             gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
1002
             gnutls_datum_t *y, gnutls_datum_t *k,
1003
             unsigned int flags)
1004
0
{
1005
0
  int ret;
1006
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1007
0
  const gnutls_ecc_curve_entry_st *e;
1008
1009
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1010
0
    dprint = _gnutls_mpi_dprint;
1011
1012
0
  if (params == NULL) {
1013
0
    gnutls_assert();
1014
0
    return GNUTLS_E_INVALID_REQUEST;
1015
0
  }
1016
1017
0
  if (curve)
1018
0
    *curve = params->curve;
1019
1020
0
  e = _gnutls_ecc_curve_get_params(params->curve);
1021
1022
0
  if (_curve_is_eddsa(e) || _curve_is_modern_ecdh(e)) {
1023
0
    if (x) {
1024
0
      ret = _gnutls_set_datum(x, params->raw_pub.data,
1025
0
            params->raw_pub.size);
1026
0
      if (ret < 0) {
1027
0
        return gnutls_assert_val(ret);
1028
0
      }
1029
0
    }
1030
1031
0
    if (y) {
1032
0
      y->data = NULL;
1033
0
      y->size = 0;
1034
0
    }
1035
1036
0
    if (k) {
1037
0
      ret = _gnutls_set_datum(k, params->raw_priv.data,
1038
0
            params->raw_priv.size);
1039
0
      if (ret < 0) {
1040
0
        _gnutls_free_datum(x);
1041
0
        return gnutls_assert_val(ret);
1042
0
      }
1043
0
    }
1044
1045
0
    return 0;
1046
0
  }
1047
1048
0
  if (unlikely(e == NULL || e->pk != GNUTLS_PK_ECDSA))
1049
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1050
1051
  /* X */
1052
0
  if (x) {
1053
0
    ret = dprint(params->params[ECC_X], x);
1054
0
    if (ret < 0) {
1055
0
      gnutls_assert();
1056
0
      return ret;
1057
0
    }
1058
0
  }
1059
1060
  /* Y */
1061
0
  if (y) {
1062
0
    ret = dprint(params->params[ECC_Y], y);
1063
0
    if (ret < 0) {
1064
0
      gnutls_assert();
1065
0
      _gnutls_free_datum(x);
1066
0
      return ret;
1067
0
    }
1068
0
  }
1069
1070
  /* K */
1071
0
  if (k) {
1072
0
    ret = dprint(params->params[ECC_K], k);
1073
0
    if (ret < 0) {
1074
0
      gnutls_assert();
1075
0
      _gnutls_free_datum(x);
1076
0
      _gnutls_free_datum(y);
1077
0
      return ret;
1078
0
    }
1079
0
  }
1080
1081
0
  return 0;
1082
0
}
1083
1084
int _gnutls_params_get_gost_raw(const gnutls_pk_params_st *params,
1085
        gnutls_ecc_curve_t *curve,
1086
        gnutls_digest_algorithm_t *digest,
1087
        gnutls_gost_paramset_t *paramset,
1088
        gnutls_datum_t *x, gnutls_datum_t *y,
1089
        gnutls_datum_t *k, unsigned int flags)
1090
0
{
1091
0
  int ret;
1092
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1093
1094
0
  if (params == NULL) {
1095
0
    gnutls_assert();
1096
0
    return GNUTLS_E_INVALID_REQUEST;
1097
0
  }
1098
1099
0
  if (curve)
1100
0
    *curve = params->curve;
1101
1102
0
  if (digest)
1103
0
    *digest = _gnutls_gost_digest(params->algo);
1104
1105
0
  if (paramset)
1106
0
    *paramset = params->gost_params;
1107
1108
  /* X */
1109
0
  if (x) {
1110
0
    ret = dprint(params->params[GOST_X], x);
1111
0
    if (ret < 0) {
1112
0
      gnutls_assert();
1113
0
      return ret;
1114
0
    }
1115
0
  }
1116
1117
  /* Y */
1118
0
  if (y) {
1119
0
    ret = dprint(params->params[GOST_Y], y);
1120
0
    if (ret < 0) {
1121
0
      gnutls_assert();
1122
0
      _gnutls_free_datum(x);
1123
0
      return ret;
1124
0
    }
1125
0
  }
1126
1127
  /* K */
1128
0
  if (k) {
1129
0
    ret = dprint(params->params[GOST_K], k);
1130
0
    if (ret < 0) {
1131
0
      gnutls_assert();
1132
0
      _gnutls_free_datum(x);
1133
0
      _gnutls_free_datum(y);
1134
0
      return ret;
1135
0
    }
1136
0
  }
1137
1138
0
  return 0;
1139
0
}
1140
1141
int pk_hash_data(gnutls_pk_algorithm_t pk, const mac_entry_st *hash,
1142
     gnutls_pk_params_st *params, const gnutls_datum_t *data,
1143
     gnutls_datum_t *digest)
1144
0
{
1145
0
  int ret;
1146
1147
0
  digest->size = _gnutls_hash_get_algo_len(hash);
1148
0
  digest->data = gnutls_malloc(digest->size);
1149
0
  if (digest->data == NULL) {
1150
0
    gnutls_assert();
1151
0
    return GNUTLS_E_MEMORY_ERROR;
1152
0
  }
1153
1154
0
  ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)hash->id, data->data,
1155
0
        data->size, digest->data);
1156
0
  if (ret < 0) {
1157
0
    gnutls_assert();
1158
0
    goto cleanup;
1159
0
  }
1160
1161
0
  return 0;
1162
1163
0
cleanup:
1164
0
  gnutls_free(digest->data);
1165
0
  return ret;
1166
0
}
1167
1168
/* 
1169
 * This function will do RSA PKCS #1 1.5 encoding
1170
 * on the given digest. The given digest must be allocated
1171
 * and will be freed if replacement is required.
1172
 */
1173
int pk_prepare_hash(gnutls_pk_algorithm_t pk, const mac_entry_st *hash,
1174
        gnutls_datum_t *digest)
1175
0
{
1176
0
  int ret;
1177
0
  gnutls_datum_t old_digest = { digest->data, digest->size };
1178
1179
0
  switch (pk) {
1180
0
  case GNUTLS_PK_RSA:
1181
0
    if (unlikely(hash == NULL))
1182
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1183
1184
    /* Only SHA-2 is allowed in FIPS 140-3 */
1185
0
    switch (hash->id) {
1186
0
    case GNUTLS_MAC_SHA256:
1187
0
    case GNUTLS_MAC_SHA384:
1188
0
    case GNUTLS_MAC_SHA512:
1189
0
    case GNUTLS_MAC_SHA224:
1190
0
      break;
1191
0
    default:
1192
0
      _gnutls_switch_fips_state(
1193
0
        GNUTLS_FIPS140_OP_NOT_APPROVED);
1194
0
    }
1195
1196
    /* Encode the digest as a DigestInfo
1197
     */
1198
0
    if ((ret = encode_ber_digest_info(hash, &old_digest, digest)) !=
1199
0
        0) {
1200
0
      gnutls_assert();
1201
0
      return ret;
1202
0
    }
1203
1204
0
    _gnutls_free_datum(&old_digest);
1205
0
    break;
1206
0
  case GNUTLS_PK_RSA_PSS:
1207
0
  case GNUTLS_PK_DSA:
1208
0
  case GNUTLS_PK_ECDSA:
1209
0
  case GNUTLS_PK_EDDSA_ED25519:
1210
0
  case GNUTLS_PK_EDDSA_ED448:
1211
0
  case GNUTLS_PK_ECDH_X25519:
1212
0
  case GNUTLS_PK_ECDH_X448:
1213
0
  case GNUTLS_PK_GOST_01:
1214
0
  case GNUTLS_PK_GOST_12_256:
1215
0
  case GNUTLS_PK_GOST_12_512:
1216
0
    break;
1217
0
  default:
1218
0
    gnutls_assert();
1219
0
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1220
0
  }
1221
1222
0
  return 0;
1223
0
}