Coverage Report

Created: 2024-06-20 06:28

/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
  memcpy(&dst->spki, &src->spki, sizeof(gnutls_x509_spki_st));
510
511
0
  return 0;
512
513
0
fail:
514
0
  for (j = 0; j < i; j++)
515
0
    _gnutls_mpi_release(&dst->params[j]);
516
0
  return GNUTLS_E_MEMORY_ERROR;
517
0
}
518
519
void gnutls_pk_params_init(gnutls_pk_params_st *p)
520
0
{
521
0
  memset(p, 0, sizeof(gnutls_pk_params_st));
522
0
}
523
524
void gnutls_pk_params_release(gnutls_pk_params_st *p)
525
0
{
526
0
  unsigned int i;
527
0
  for (i = 0; i < p->params_nr; i++) {
528
0
    _gnutls_mpi_release(&p->params[i]);
529
0
  }
530
0
  gnutls_free(p->raw_priv.data);
531
0
  gnutls_free(p->raw_pub.data);
532
533
0
  p->params_nr = 0;
534
0
}
535
536
void gnutls_pk_params_clear(gnutls_pk_params_st *p)
537
0
{
538
0
  unsigned int i;
539
0
  for (i = 0; i < p->params_nr; i++) {
540
0
    if (p->params[i] != NULL)
541
0
      _gnutls_mpi_clear(p->params[i]);
542
0
  }
543
0
  gnutls_memset(p->seed, 0, p->seed_size);
544
0
  p->seed_size = 0;
545
0
  if (p->raw_priv.data != NULL) {
546
0
    gnutls_memset(p->raw_priv.data, 0, p->raw_priv.size);
547
0
    p->raw_priv.size = 0;
548
0
  }
549
0
}
550
551
int _gnutls_find_rsa_pss_salt_size(unsigned bits, const mac_entry_st *me,
552
           unsigned salt_size)
553
0
{
554
0
  unsigned digest_size;
555
0
  int max_salt_size;
556
0
  unsigned key_size;
557
558
0
  digest_size = _gnutls_hash_get_algo_len(me);
559
0
  key_size = (bits + 7) / 8;
560
561
0
  if (key_size == 0) {
562
0
    return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY);
563
0
  } else {
564
0
    max_salt_size = key_size - digest_size - 2;
565
0
    if (max_salt_size < 0)
566
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
567
0
  }
568
569
0
  if (salt_size < digest_size)
570
0
    salt_size = digest_size;
571
572
0
  if (salt_size > (unsigned)max_salt_size)
573
0
    salt_size = max_salt_size;
574
575
0
  return salt_size;
576
0
}
577
578
/* Writes the digest information and the digest in a DER encoded
579
 * structure. The digest info is allocated and stored into the info structure.
580
 */
581
int encode_ber_digest_info(const mac_entry_st *e, const gnutls_datum_t *digest,
582
         gnutls_datum_t *output)
583
0
{
584
0
  asn1_node dinfo = NULL;
585
0
  int result;
586
0
  const char *algo;
587
0
  uint8_t *tmp_output;
588
0
  int tmp_output_size;
589
590
0
  if (unlikely(e == NULL)) {
591
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
592
0
  }
593
594
  /* prevent asn1_write_value() treating input as string */
595
0
  if (digest->size == 0)
596
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
597
598
0
  algo = _gnutls_x509_mac_to_oid(e);
599
0
  if (algo == NULL) {
600
0
    gnutls_assert();
601
0
    _gnutls_debug_log("Hash algorithm: %d has no OID\n", e->id);
602
0
    return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
603
0
  }
604
605
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
606
0
            "GNUTLS.DigestInfo", &dinfo)) !=
607
0
      ASN1_SUCCESS) {
608
0
    gnutls_assert();
609
0
    return _gnutls_asn2err(result);
610
0
  }
611
612
0
  result = asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
613
0
  if (result != ASN1_SUCCESS) {
614
0
    gnutls_assert();
615
0
    asn1_delete_structure(&dinfo);
616
0
    return _gnutls_asn2err(result);
617
0
  }
618
619
  /* Write an ASN.1 NULL in the parameters field.  This matches RFC
620
     3279 and RFC 4055, although is arguable incorrect from a historic
621
     perspective (see those documents for more information).
622
     Regardless of what is correct, this appears to be what most
623
     implementations do.  */
624
0
  result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
625
0
          ASN1_NULL, ASN1_NULL_SIZE);
626
0
  if (result != ASN1_SUCCESS) {
627
0
    gnutls_assert();
628
0
    asn1_delete_structure(&dinfo);
629
0
    return _gnutls_asn2err(result);
630
0
  }
631
632
0
  result = asn1_write_value(dinfo, "digest", digest->data, digest->size);
633
0
  if (result != ASN1_SUCCESS) {
634
0
    gnutls_assert();
635
0
    asn1_delete_structure(&dinfo);
636
0
    return _gnutls_asn2err(result);
637
0
  }
638
639
0
  tmp_output_size = 0;
640
0
  result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
641
0
  if (result != ASN1_MEM_ERROR) {
642
0
    gnutls_assert();
643
0
    asn1_delete_structure(&dinfo);
644
0
    return _gnutls_asn2err(result);
645
0
  }
646
647
0
  tmp_output = gnutls_malloc(tmp_output_size);
648
0
  if (tmp_output == NULL) {
649
0
    gnutls_assert();
650
0
    asn1_delete_structure(&dinfo);
651
0
    return GNUTLS_E_MEMORY_ERROR;
652
0
  }
653
654
0
  result = asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
655
0
  if (result != ASN1_SUCCESS) {
656
0
    gnutls_assert();
657
0
    asn1_delete_structure(&dinfo);
658
0
    return _gnutls_asn2err(result);
659
0
  }
660
661
0
  asn1_delete_structure(&dinfo);
662
663
0
  output->size = tmp_output_size;
664
0
  output->data = tmp_output;
665
666
0
  return 0;
667
0
}
668
669
/**
670
 * gnutls_encode_ber_digest_info:
671
 * @info: an RSA BER encoded DigestInfo structure
672
 * @hash: the hash algorithm that was used to get the digest
673
 * @digest: must contain the digest data
674
 * @output: will contain the allocated DigestInfo BER encoded data
675
 *
676
 * This function will encode the provided digest data, and its
677
 * algorithm into an RSA PKCS#1 1.5 DigestInfo structure. 
678
 *
679
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
680
 *   an error code is returned.
681
 *
682
 * Since: 3.5.0
683
 *
684
 **/
685
int gnutls_encode_ber_digest_info(gnutls_digest_algorithm_t hash,
686
          const gnutls_datum_t *digest,
687
          gnutls_datum_t *output)
688
0
{
689
0
  const mac_entry_st *e = hash_to_entry(hash);
690
0
  if (unlikely(e == NULL))
691
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
692
693
0
  return encode_ber_digest_info(e, digest, output);
694
0
}
695
696
/**
697
 * gnutls_decode_ber_digest_info:
698
 * @info: an RSA BER encoded DigestInfo structure
699
 * @hash: will contain the hash algorithm of the structure
700
 * @digest: will contain the hash output of the structure
701
 * @digest_size: will contain the hash size of the structure; initially must hold the maximum size of @digest
702
 *
703
 * This function will parse an RSA PKCS#1 1.5 DigestInfo structure
704
 * and report the hash algorithm used as well as the digest data.
705
 *
706
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
707
 *   an error code is returned.
708
 *
709
 * Since: 3.5.0
710
 *
711
 **/
712
int gnutls_decode_ber_digest_info(const gnutls_datum_t *info,
713
          gnutls_digest_algorithm_t *hash,
714
          unsigned char *digest,
715
          unsigned int *digest_size)
716
0
{
717
0
  asn1_node dinfo = NULL;
718
0
  int result;
719
0
  char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
720
0
  int len;
721
722
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
723
0
            "GNUTLS.DigestInfo", &dinfo)) !=
724
0
      ASN1_SUCCESS) {
725
0
    gnutls_assert();
726
0
    return _gnutls_asn2err(result);
727
0
  }
728
729
  /* rfc2313 required BER encoding of that field, thus
730
   * we don't restrict libtasn1 to DER subset */
731
0
  result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
732
0
  if (result != ASN1_SUCCESS) {
733
0
    gnutls_assert();
734
0
    asn1_delete_structure(&dinfo);
735
0
    return _gnutls_asn2err(result);
736
0
  }
737
738
0
  len = sizeof(str) - 1;
739
0
  result = asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len);
740
0
  if (result != ASN1_SUCCESS) {
741
0
    gnutls_assert();
742
0
    asn1_delete_structure(&dinfo);
743
0
    return _gnutls_asn2err(result);
744
0
  }
745
746
0
  *hash = gnutls_oid_to_digest(str);
747
748
0
  if (*hash == GNUTLS_DIG_UNKNOWN) {
749
0
    _gnutls_debug_log("verify.c: HASH OID: %s\n", str);
750
751
0
    gnutls_assert();
752
0
    asn1_delete_structure(&dinfo);
753
0
    return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
754
0
  }
755
756
0
  len = sizeof(str) - 1;
757
0
  result =
758
0
    asn1_read_value(dinfo, "digestAlgorithm.parameters", str, &len);
759
  /* To avoid permitting garbage in the parameters field, either the
760
     parameters field is not present, or it contains 0x05 0x00. */
761
0
  if (!(result == ASN1_ELEMENT_NOT_FOUND ||
762
0
        (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
763
0
         memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
764
0
    gnutls_assert();
765
0
    asn1_delete_structure(&dinfo);
766
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
767
0
  }
768
769
0
  len = *digest_size;
770
0
  result = asn1_read_value(dinfo, "digest", digest, &len);
771
772
0
  if (result != ASN1_SUCCESS) {
773
0
    gnutls_assert();
774
0
    *digest_size = len;
775
0
    asn1_delete_structure(&dinfo);
776
0
    return _gnutls_asn2err(result);
777
0
  }
778
779
0
  *digest_size = len;
780
0
  asn1_delete_structure(&dinfo);
781
782
0
  return 0;
783
0
}
784
785
int _gnutls_params_get_rsa_raw(const gnutls_pk_params_st *params,
786
             gnutls_datum_t *m, gnutls_datum_t *e,
787
             gnutls_datum_t *d, gnutls_datum_t *p,
788
             gnutls_datum_t *q, gnutls_datum_t *u,
789
             gnutls_datum_t *e1, gnutls_datum_t *e2,
790
             unsigned int flags)
791
0
{
792
0
  int ret;
793
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
794
795
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
796
0
    dprint = _gnutls_mpi_dprint;
797
798
0
  if (params == NULL) {
799
0
    gnutls_assert();
800
0
    return GNUTLS_E_INVALID_REQUEST;
801
0
  }
802
803
0
  if (!GNUTLS_PK_IS_RSA(params->algo)) {
804
0
    gnutls_assert();
805
0
    return GNUTLS_E_INVALID_REQUEST;
806
0
  }
807
808
0
  if (m) {
809
0
    ret = dprint(params->params[0], m);
810
0
    if (ret < 0) {
811
0
      gnutls_assert();
812
0
      goto error;
813
0
    }
814
0
  }
815
816
  /* E */
817
0
  if (e) {
818
0
    ret = dprint(params->params[1], e);
819
0
    if (ret < 0) {
820
0
      gnutls_assert();
821
0
      goto error;
822
0
    }
823
0
  }
824
825
  /* D */
826
0
  if (d && params->params[2]) {
827
0
    ret = dprint(params->params[2], d);
828
0
    if (ret < 0) {
829
0
      gnutls_assert();
830
0
      goto error;
831
0
    }
832
0
  } else if (d) {
833
0
    d->data = NULL;
834
0
    d->size = 0;
835
0
  }
836
837
  /* P */
838
0
  if (p && params->params[3]) {
839
0
    ret = dprint(params->params[3], p);
840
0
    if (ret < 0) {
841
0
      gnutls_assert();
842
0
      goto error;
843
0
    }
844
0
  } else if (p) {
845
0
    p->data = NULL;
846
0
    p->size = 0;
847
0
  }
848
849
  /* Q */
850
0
  if (q && params->params[4]) {
851
0
    ret = dprint(params->params[4], q);
852
0
    if (ret < 0) {
853
0
      gnutls_assert();
854
0
      goto error;
855
0
    }
856
0
  } else if (q) {
857
0
    q->data = NULL;
858
0
    q->size = 0;
859
0
  }
860
861
  /* U */
862
0
  if (u && params->params[5]) {
863
0
    ret = dprint(params->params[5], u);
864
0
    if (ret < 0) {
865
0
      gnutls_assert();
866
0
      goto error;
867
0
    }
868
0
  } else if (u) {
869
0
    u->data = NULL;
870
0
    u->size = 0;
871
0
  }
872
873
  /* E1 */
874
0
  if (e1 && params->params[6]) {
875
0
    ret = dprint(params->params[6], e1);
876
0
    if (ret < 0) {
877
0
      gnutls_assert();
878
0
      goto error;
879
0
    }
880
0
  } else if (e1) {
881
0
    e1->data = NULL;
882
0
    e1->size = 0;
883
0
  }
884
885
  /* E2 */
886
0
  if (e2 && params->params[7]) {
887
0
    ret = dprint(params->params[7], e2);
888
0
    if (ret < 0) {
889
0
      gnutls_assert();
890
0
      goto error;
891
0
    }
892
0
  } else if (e2) {
893
0
    e2->data = NULL;
894
0
    e2->size = 0;
895
0
  }
896
897
0
  return 0;
898
899
0
error:
900
0
  _gnutls_free_datum(m);
901
0
  _gnutls_free_datum(d);
902
0
  _gnutls_free_datum(e);
903
0
  _gnutls_free_datum(e1);
904
0
  _gnutls_free_datum(e2);
905
0
  _gnutls_free_datum(p);
906
0
  _gnutls_free_datum(q);
907
908
0
  return ret;
909
0
}
910
911
int _gnutls_params_get_dsa_raw(const gnutls_pk_params_st *params,
912
             gnutls_datum_t *p, gnutls_datum_t *q,
913
             gnutls_datum_t *g, gnutls_datum_t *y,
914
             gnutls_datum_t *x, unsigned int flags)
915
0
{
916
0
  int ret;
917
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
918
919
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
920
0
    dprint = _gnutls_mpi_dprint;
921
922
0
  if (params == NULL) {
923
0
    gnutls_assert();
924
0
    return GNUTLS_E_INVALID_REQUEST;
925
0
  }
926
927
0
  if (params->algo != GNUTLS_PK_DSA && params->algo != GNUTLS_PK_DH) {
928
0
    gnutls_assert();
929
0
    return GNUTLS_E_INVALID_REQUEST;
930
0
  }
931
932
  /* P */
933
0
  if (p) {
934
0
    ret = dprint(params->params[0], p);
935
0
    if (ret < 0) {
936
0
      gnutls_assert();
937
0
      return ret;
938
0
    }
939
0
  }
940
941
  /* Q */
942
0
  if (q) {
943
0
    ret = dprint(params->params[1], q);
944
0
    if (ret < 0) {
945
0
      gnutls_assert();
946
0
      _gnutls_free_datum(p);
947
0
      return ret;
948
0
    }
949
0
  }
950
951
  /* G */
952
0
  if (g) {
953
0
    ret = dprint(params->params[2], g);
954
0
    if (ret < 0) {
955
0
      gnutls_assert();
956
0
      _gnutls_free_datum(p);
957
0
      _gnutls_free_datum(q);
958
0
      return ret;
959
0
    }
960
0
  }
961
962
  /* Y */
963
0
  if (y) {
964
0
    ret = dprint(params->params[3], y);
965
0
    if (ret < 0) {
966
0
      gnutls_assert();
967
0
      _gnutls_free_datum(p);
968
0
      _gnutls_free_datum(g);
969
0
      _gnutls_free_datum(q);
970
0
      return ret;
971
0
    }
972
0
  }
973
974
  /* X */
975
0
  if (x) {
976
0
    ret = dprint(params->params[4], x);
977
0
    if (ret < 0) {
978
0
      gnutls_assert();
979
0
      _gnutls_free_datum(y);
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
0
  return 0;
988
0
}
989
990
int _gnutls_params_get_ecc_raw(const gnutls_pk_params_st *params,
991
             gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
992
             gnutls_datum_t *y, gnutls_datum_t *k,
993
             unsigned int flags)
994
0
{
995
0
  int ret;
996
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
997
0
  const gnutls_ecc_curve_entry_st *e;
998
999
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1000
0
    dprint = _gnutls_mpi_dprint;
1001
1002
0
  if (params == NULL) {
1003
0
    gnutls_assert();
1004
0
    return GNUTLS_E_INVALID_REQUEST;
1005
0
  }
1006
1007
0
  if (curve)
1008
0
    *curve = params->curve;
1009
1010
0
  e = _gnutls_ecc_curve_get_params(params->curve);
1011
1012
0
  if (_curve_is_eddsa(e) || _curve_is_modern_ecdh(e)) {
1013
0
    if (x) {
1014
0
      ret = _gnutls_set_datum(x, params->raw_pub.data,
1015
0
            params->raw_pub.size);
1016
0
      if (ret < 0) {
1017
0
        return gnutls_assert_val(ret);
1018
0
      }
1019
0
    }
1020
1021
0
    if (y) {
1022
0
      y->data = NULL;
1023
0
      y->size = 0;
1024
0
    }
1025
1026
0
    if (k) {
1027
0
      ret = _gnutls_set_datum(k, params->raw_priv.data,
1028
0
            params->raw_priv.size);
1029
0
      if (ret < 0) {
1030
0
        _gnutls_free_datum(x);
1031
0
        return gnutls_assert_val(ret);
1032
0
      }
1033
0
    }
1034
1035
0
    return 0;
1036
0
  }
1037
1038
0
  if (unlikely(e == NULL || e->pk != GNUTLS_PK_ECDSA))
1039
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1040
1041
  /* X */
1042
0
  if (x) {
1043
0
    ret = dprint(params->params[ECC_X], x);
1044
0
    if (ret < 0) {
1045
0
      gnutls_assert();
1046
0
      return ret;
1047
0
    }
1048
0
  }
1049
1050
  /* Y */
1051
0
  if (y) {
1052
0
    ret = dprint(params->params[ECC_Y], y);
1053
0
    if (ret < 0) {
1054
0
      gnutls_assert();
1055
0
      _gnutls_free_datum(x);
1056
0
      return ret;
1057
0
    }
1058
0
  }
1059
1060
  /* K */
1061
0
  if (k) {
1062
0
    ret = dprint(params->params[ECC_K], k);
1063
0
    if (ret < 0) {
1064
0
      gnutls_assert();
1065
0
      _gnutls_free_datum(x);
1066
0
      _gnutls_free_datum(y);
1067
0
      return ret;
1068
0
    }
1069
0
  }
1070
1071
0
  return 0;
1072
0
}
1073
1074
int _gnutls_params_get_gost_raw(const gnutls_pk_params_st *params,
1075
        gnutls_ecc_curve_t *curve,
1076
        gnutls_digest_algorithm_t *digest,
1077
        gnutls_gost_paramset_t *paramset,
1078
        gnutls_datum_t *x, gnutls_datum_t *y,
1079
        gnutls_datum_t *k, unsigned int flags)
1080
0
{
1081
0
  int ret;
1082
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1083
1084
0
  if (params == NULL) {
1085
0
    gnutls_assert();
1086
0
    return GNUTLS_E_INVALID_REQUEST;
1087
0
  }
1088
1089
0
  if (curve)
1090
0
    *curve = params->curve;
1091
1092
0
  if (digest)
1093
0
    *digest = _gnutls_gost_digest(params->algo);
1094
1095
0
  if (paramset)
1096
0
    *paramset = params->gost_params;
1097
1098
  /* X */
1099
0
  if (x) {
1100
0
    ret = dprint(params->params[GOST_X], x);
1101
0
    if (ret < 0) {
1102
0
      gnutls_assert();
1103
0
      return ret;
1104
0
    }
1105
0
  }
1106
1107
  /* Y */
1108
0
  if (y) {
1109
0
    ret = dprint(params->params[GOST_Y], y);
1110
0
    if (ret < 0) {
1111
0
      gnutls_assert();
1112
0
      _gnutls_free_datum(x);
1113
0
      return ret;
1114
0
    }
1115
0
  }
1116
1117
  /* K */
1118
0
  if (k) {
1119
0
    ret = dprint(params->params[GOST_K], k);
1120
0
    if (ret < 0) {
1121
0
      gnutls_assert();
1122
0
      _gnutls_free_datum(x);
1123
0
      _gnutls_free_datum(y);
1124
0
      return ret;
1125
0
    }
1126
0
  }
1127
1128
0
  return 0;
1129
0
}
1130
1131
int pk_hash_data(gnutls_pk_algorithm_t pk, const mac_entry_st *hash,
1132
     gnutls_pk_params_st *params, const gnutls_datum_t *data,
1133
     gnutls_datum_t *digest)
1134
0
{
1135
0
  int ret;
1136
1137
0
  digest->size = _gnutls_hash_get_algo_len(hash);
1138
0
  digest->data = gnutls_malloc(digest->size);
1139
0
  if (digest->data == NULL) {
1140
0
    gnutls_assert();
1141
0
    return GNUTLS_E_MEMORY_ERROR;
1142
0
  }
1143
1144
0
  ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)hash->id, data->data,
1145
0
        data->size, digest->data);
1146
0
  if (ret < 0) {
1147
0
    gnutls_assert();
1148
0
    goto cleanup;
1149
0
  }
1150
1151
0
  return 0;
1152
1153
0
cleanup:
1154
0
  gnutls_free(digest->data);
1155
0
  return ret;
1156
0
}
1157
1158
/* 
1159
 * This function will do RSA PKCS #1 1.5 encoding
1160
 * on the given digest. The given digest must be allocated
1161
 * and will be freed if replacement is required.
1162
 */
1163
int pk_prepare_hash(gnutls_pk_algorithm_t pk, const mac_entry_st *hash,
1164
        gnutls_datum_t *digest)
1165
0
{
1166
0
  int ret;
1167
0
  gnutls_datum_t old_digest = { digest->data, digest->size };
1168
1169
0
  switch (pk) {
1170
0
  case GNUTLS_PK_RSA:
1171
0
    if (unlikely(hash == NULL))
1172
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1173
1174
    /* Only SHA-2 is allowed in FIPS 140-3 */
1175
0
    switch (hash->id) {
1176
0
    case GNUTLS_MAC_SHA256:
1177
0
    case GNUTLS_MAC_SHA384:
1178
0
    case GNUTLS_MAC_SHA512:
1179
0
    case GNUTLS_MAC_SHA224:
1180
0
      break;
1181
0
    default:
1182
0
      _gnutls_switch_fips_state(
1183
0
        GNUTLS_FIPS140_OP_NOT_APPROVED);
1184
0
    }
1185
1186
    /* Encode the digest as a DigestInfo
1187
     */
1188
0
    if ((ret = encode_ber_digest_info(hash, &old_digest, digest)) !=
1189
0
        0) {
1190
0
      gnutls_assert();
1191
0
      return ret;
1192
0
    }
1193
1194
0
    _gnutls_free_datum(&old_digest);
1195
0
    break;
1196
0
  case GNUTLS_PK_RSA_PSS:
1197
0
  case GNUTLS_PK_DSA:
1198
0
  case GNUTLS_PK_ECDSA:
1199
0
  case GNUTLS_PK_EDDSA_ED25519:
1200
0
  case GNUTLS_PK_EDDSA_ED448:
1201
0
  case GNUTLS_PK_ECDH_X25519:
1202
0
  case GNUTLS_PK_ECDH_X448:
1203
0
  case GNUTLS_PK_GOST_01:
1204
0
  case GNUTLS_PK_GOST_12_256:
1205
0
  case GNUTLS_PK_GOST_12_512:
1206
0
    break;
1207
0
  default:
1208
0
    gnutls_assert();
1209
0
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1210
0
  }
1211
1212
0
  return 0;
1213
0
}