Coverage Report

Created: 2023-03-26 07:33

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