Coverage Report

Created: 2025-03-06 07:58

/src/gnutls/lib/x509/key_decode.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2013-2017 Red Hat
4
 *
5
 * Author: Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
#include "gnutls_int.h"
25
#include "errors.h"
26
#include "global.h"
27
#include <libtasn1.h>
28
#include "datum.h"
29
#include "common.h"
30
#include "x509_int.h"
31
#include "pk.h"
32
#include "num.h"
33
#include "ecc.h"
34
35
static int _gnutls_x509_read_rsa_pubkey(uint8_t *der, int dersize,
36
          gnutls_pk_params_st *params);
37
static int _gnutls_x509_read_dsa_pubkey(uint8_t *der, int dersize,
38
          gnutls_pk_params_st *params);
39
static int _gnutls_x509_read_ecc_pubkey(uint8_t *der, int dersize,
40
          gnutls_pk_params_st *params);
41
static int _gnutls_x509_read_eddsa_pubkey(gnutls_ecc_curve_t curve,
42
            uint8_t *der, int dersize,
43
            gnutls_pk_params_st *params);
44
static int _gnutls_x509_read_ecdh_pubkey(gnutls_ecc_curve_t curve, uint8_t *der,
45
           int dersize,
46
           gnutls_pk_params_st *params);
47
static int _gnutls_x509_read_gost_pubkey(uint8_t *der, int dersize,
48
           gnutls_pk_params_st *params);
49
50
static int _gnutls_x509_read_dsa_params(uint8_t *der, int dersize,
51
          gnutls_pk_params_st *params);
52
53
/*
54
 * some x509 certificate parsing functions that relate to MPI parameter
55
 * extraction. This reads the BIT STRING subjectPublicKey.
56
 * Returns 2 parameters (m,e). It does not set params_nr.
57
 */
58
int _gnutls_x509_read_rsa_pubkey(uint8_t *der, int dersize,
59
         gnutls_pk_params_st *params)
60
0
{
61
0
  int result;
62
0
  asn1_node spk = NULL;
63
64
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
65
0
            "GNUTLS.RSAPublicKey", &spk)) !=
66
0
      ASN1_SUCCESS) {
67
0
    gnutls_assert();
68
0
    return _gnutls_asn2err(result);
69
0
  }
70
71
0
  result = asn1_der_decoding(&spk, der, dersize, NULL);
72
73
0
  if (result != ASN1_SUCCESS) {
74
0
    gnutls_assert();
75
0
    asn1_delete_structure(&spk);
76
0
    return _gnutls_asn2err(result);
77
0
  }
78
79
0
  if (_gnutls_x509_read_int(spk, "modulus", &params->params[0]) < 0) {
80
0
    gnutls_assert();
81
0
    asn1_delete_structure(&spk);
82
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
83
0
  }
84
85
0
  if (_gnutls_x509_read_int(spk, "publicExponent", &params->params[1]) <
86
0
      0) {
87
0
    gnutls_assert();
88
0
    _gnutls_mpi_release(&params->params[0]);
89
0
    asn1_delete_structure(&spk);
90
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
91
0
  }
92
93
0
  asn1_delete_structure(&spk);
94
95
0
  return 0;
96
0
}
97
98
/*
99
 * some x509 certificate parsing functions that relate to MPI parameter
100
 * extraction. This reads the BIT STRING subjectPublicKey.
101
 * Returns 2 parameters (m,e). It does not set params_nr.
102
 */
103
int _gnutls_x509_read_ecc_pubkey(uint8_t *der, int dersize,
104
         gnutls_pk_params_st *params)
105
0
{
106
  /* RFC5480 defines the public key to be an ECPoint (i.e. OCTET STRING),
107
   * Then it says that the OCTET STRING _value_ is converted to BIT STRING.
108
   * That means that the value we place there is the raw X9.62 one. */
109
0
  return _gnutls_ecc_ansi_x962_import(
110
0
    der, dersize, &params->params[ECC_X], &params->params[ECC_Y]);
111
0
}
112
113
int _gnutls_x509_read_eddsa_pubkey(gnutls_ecc_curve_t curve, uint8_t *der,
114
           int dersize, gnutls_pk_params_st *params)
115
0
{
116
0
  int size = gnutls_ecc_curve_get_size(curve);
117
0
  if (dersize != size)
118
0
    return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
119
120
0
  return _gnutls_set_datum(&params->raw_pub, der, dersize);
121
0
}
122
123
int _gnutls_x509_read_ecdh_pubkey(gnutls_ecc_curve_t curve, uint8_t *der,
124
          int dersize, gnutls_pk_params_st *params)
125
0
{
126
0
  int size = gnutls_ecc_curve_get_size(curve);
127
0
  if (dersize != size)
128
0
    return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
129
130
0
  return _gnutls_set_datum(&params->raw_pub, der, dersize);
131
0
}
132
133
/* Pubkey is a concatenation of X (in little endian) and Y (also LE)
134
 * encoded into OCTET STRING. */
135
static int _gnutls_x509_read_gost_pubkey(uint8_t *der, int dersize,
136
           gnutls_pk_params_st *params)
137
0
{
138
0
  int ret;
139
0
  int len;
140
0
  bigint_t *x = &params->params[GOST_X];
141
0
  bigint_t *y = &params->params[GOST_Y];
142
143
  /* Quick and dirty parsing of OCTET STRING of 0x40 or 0x80 bytes */
144
0
  if (dersize < 1 || der[0] != ASN1_TAG_OCTET_STRING) {
145
0
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
146
0
  }
147
148
0
  der++;
149
0
  dersize--;
150
151
0
  ret = asn1_get_length_der(der, dersize, &len);
152
0
  if (ret <= 0 || ret % 2 != 0 || dersize != len + ret) {
153
0
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
154
0
  }
155
156
0
  der += len;
157
0
  dersize -= len;
158
159
  /* read data */
160
0
  ret = _gnutls_mpi_init_scan_le(x, der, dersize / 2);
161
0
  if (ret < 0)
162
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
163
164
0
  ret = _gnutls_mpi_init_scan_le(y, der + dersize / 2, dersize / 2);
165
0
  if (ret < 0) {
166
0
    _gnutls_mpi_release(y);
167
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
168
0
  }
169
170
0
  return 0;
171
0
}
172
173
/* reads p,q and g 
174
 * from the certificate (subjectPublicKey BIT STRING).
175
 * params[0-2]. It does NOT set params_nr.
176
 */
177
static int _gnutls_x509_read_dsa_params(uint8_t *der, int dersize,
178
          gnutls_pk_params_st *params)
179
0
{
180
0
  int result;
181
0
  asn1_node spk = NULL;
182
183
0
  if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Dss-Parms",
184
0
            &spk)) != ASN1_SUCCESS) {
185
0
    gnutls_assert();
186
0
    return _gnutls_asn2err(result);
187
0
  }
188
189
0
  result = asn1_der_decoding(&spk, der, dersize, NULL);
190
191
0
  if (result != ASN1_SUCCESS) {
192
0
    gnutls_assert();
193
0
    asn1_delete_structure(&spk);
194
0
    return _gnutls_asn2err(result);
195
0
  }
196
197
  /* If the parameters are not included in the certificate
198
   * then the issuer's parameters should be used. This is not
199
   * implemented, and is not used in practice (along with DSA).
200
   */
201
202
  /* Read p */
203
204
0
  if (_gnutls_x509_read_int(spk, "p", &params->params[0]) < 0) {
205
0
    gnutls_assert();
206
0
    asn1_delete_structure(&spk);
207
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
208
0
  }
209
210
  /* Read q */
211
212
0
  if (_gnutls_x509_read_int(spk, "q", &params->params[1]) < 0) {
213
0
    gnutls_assert();
214
0
    asn1_delete_structure(&spk);
215
0
    _gnutls_mpi_release(&params->params[0]);
216
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
217
0
  }
218
219
  /* Read g */
220
221
0
  if (_gnutls_x509_read_int(spk, "g", &params->params[2]) < 0) {
222
0
    gnutls_assert();
223
0
    asn1_delete_structure(&spk);
224
0
    _gnutls_mpi_release(&params->params[0]);
225
0
    _gnutls_mpi_release(&params->params[1]);
226
0
    return GNUTLS_E_ASN1_GENERIC_ERROR;
227
0
  }
228
229
0
  asn1_delete_structure(&spk);
230
231
0
  params->params_nr = 3; /* public key is missing */
232
0
  params->algo = GNUTLS_PK_DSA;
233
234
0
  return 0;
235
0
}
236
237
/* reads the curve from the certificate.
238
 * params[0-4]. It does NOT set params_nr.
239
 */
240
int _gnutls_x509_read_ecc_params(uint8_t *der, int dersize, unsigned int *curve)
241
0
{
242
0
  int ret;
243
0
  asn1_node spk = NULL;
244
0
  char oid[MAX_OID_SIZE];
245
0
  int oid_size;
246
247
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
248
0
               "GNUTLS.ECParameters", &spk)) !=
249
0
      ASN1_SUCCESS) {
250
0
    gnutls_assert();
251
0
    return _gnutls_asn2err(ret);
252
0
  }
253
254
0
  ret = asn1_der_decoding(&spk, der, dersize, NULL);
255
256
0
  if (ret != ASN1_SUCCESS) {
257
0
    gnutls_assert();
258
0
    ret = _gnutls_asn2err(ret);
259
0
    goto cleanup;
260
0
  }
261
262
  /* read the curve */
263
0
  oid_size = sizeof(oid);
264
0
  ret = asn1_read_value(spk, "namedCurve", oid, &oid_size);
265
0
  if (ret != ASN1_SUCCESS) {
266
0
    gnutls_assert();
267
0
    ret = _gnutls_asn2err(ret);
268
0
    goto cleanup;
269
0
  }
270
271
0
  *curve = gnutls_oid_to_ecc_curve(oid);
272
0
  if (*curve == GNUTLS_ECC_CURVE_INVALID) {
273
0
    _gnutls_debug_log("Curve %s is not supported\n", oid);
274
0
    gnutls_assert();
275
0
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
276
0
    goto cleanup;
277
0
  }
278
279
0
  ret = 0;
280
281
0
cleanup:
282
283
0
  asn1_delete_structure(&spk);
284
285
0
  return ret;
286
0
}
287
288
static int check_mgf1(asn1_node root, const char *name,
289
          gnutls_digest_algorithm_t digest, bool allow_null)
290
0
{
291
0
  char buffer[MAX_NAME_SIZE];
292
0
  char oid[MAX_OID_SIZE];
293
0
  gnutls_digest_algorithm_t digest2;
294
0
  asn1_node ai = NULL;
295
0
  int size;
296
0
  int result;
297
0
  gnutls_datum_t value = { NULL, 0 };
298
299
0
  result = snprintf(buffer, sizeof(buffer), "%s.algorithm", name);
300
0
  if (result < 0 || (size_t)result >= sizeof(buffer))
301
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
302
303
0
  size = sizeof(oid);
304
0
  result = asn1_read_value(root, buffer, oid, &size);
305
0
  if (result != ASN1_SUCCESS) {
306
0
    if (result == ASN1_ELEMENT_NOT_FOUND && allow_null)
307
0
      return 0;
308
0
    gnutls_assert();
309
0
    return _gnutls_asn2err(result);
310
0
  }
311
312
  /* Error out if algorithm other than mgf1 is specified */
313
0
  if (strcmp(oid, PKIX1_RSA_PSS_MGF1_OID) != 0) {
314
0
    gnutls_assert();
315
0
    _gnutls_debug_log("Unknown mask algorithm: %s\n", oid);
316
0
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
317
0
  }
318
319
  /* Check if maskGenAlgorithm.parameters does exist and
320
   * is identical to hashAlgorithm */
321
0
  result = snprintf(buffer, sizeof(buffer), "%s.parameters", name);
322
0
  if (result < 0 || (size_t)result >= sizeof(buffer))
323
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
324
325
0
  result = _gnutls_x509_read_value(root, buffer, &value);
326
0
  if (result < 0)
327
0
    return gnutls_assert_val(result);
328
329
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
330
0
            "PKIX1.AlgorithmIdentifier", &ai)) !=
331
0
      ASN1_SUCCESS) {
332
0
    gnutls_assert();
333
0
    result = _gnutls_asn2err(result);
334
0
    goto cleanup;
335
0
  }
336
337
0
  result = _asn1_strict_der_decode(&ai, value.data, value.size, NULL);
338
0
  if (result != ASN1_SUCCESS) {
339
0
    gnutls_assert();
340
0
    result = _gnutls_asn2err(result);
341
0
    goto cleanup;
342
0
  }
343
344
0
  size = sizeof(oid);
345
0
  result = asn1_read_value(ai, "algorithm", oid, &size);
346
0
  if (result == ASN1_SUCCESS)
347
0
    digest2 = gnutls_oid_to_digest(oid);
348
0
  else if (result == ASN1_ELEMENT_NOT_FOUND)
349
    /* The default hash algorithm for mgf1 is SHA-1 */
350
0
    digest2 = GNUTLS_DIG_SHA1;
351
0
  else {
352
0
    gnutls_assert();
353
0
    result = _gnutls_asn2err(result);
354
0
    goto cleanup;
355
0
  }
356
357
0
  if (digest != digest2) {
358
0
    gnutls_assert();
359
0
    result = GNUTLS_E_CONSTRAINT_ERROR;
360
0
    goto cleanup;
361
0
  }
362
363
0
  result = 0;
364
365
0
cleanup:
366
0
  _gnutls_free_datum(&value);
367
0
  asn1_delete_structure(&ai);
368
369
0
  return result;
370
0
}
371
372
/* Reads RSA-PSS parameters.
373
 */
374
int _gnutls_x509_read_rsa_pss_params(uint8_t *der, int dersize,
375
             gnutls_x509_spki_st *params)
376
0
{
377
0
  int result;
378
0
  asn1_node spk = NULL;
379
0
  gnutls_digest_algorithm_t digest;
380
0
  char oid[MAX_OID_SIZE] = "";
381
0
  int size;
382
0
  unsigned int trailer;
383
384
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
385
0
            "GNUTLS.RSAPSSParameters", &spk)) !=
386
0
      ASN1_SUCCESS) {
387
0
    gnutls_assert();
388
0
    result = _gnutls_asn2err(result);
389
0
    goto cleanup;
390
0
  }
391
392
0
  result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
393
394
0
  if (result != ASN1_SUCCESS) {
395
0
    gnutls_assert();
396
0
    result = _gnutls_asn2err(result);
397
0
    goto cleanup;
398
0
  }
399
400
0
  size = sizeof(oid);
401
0
  result = asn1_read_value(spk, "hashAlgorithm.algorithm", oid, &size);
402
0
  if (result == ASN1_SUCCESS)
403
0
    digest = gnutls_oid_to_digest(oid);
404
0
  else if (result == ASN1_ELEMENT_NOT_FOUND)
405
    /* The default hash algorithm is SHA-1 */
406
0
    digest = GNUTLS_DIG_SHA1;
407
0
  else {
408
0
    gnutls_assert();
409
0
    result = _gnutls_asn2err(result);
410
0
    goto cleanup;
411
0
  }
412
413
0
  if (digest == GNUTLS_DIG_UNKNOWN) {
414
0
    gnutls_assert();
415
0
    _gnutls_debug_log("Unknown RSA-PSS hash: %s\n", oid);
416
0
    result = GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
417
0
    goto cleanup;
418
0
  }
419
420
0
  result = check_mgf1(spk, "maskGenAlgorithm", digest, true);
421
0
  if (result < 0) {
422
0
    gnutls_assert();
423
0
    goto cleanup;
424
0
  }
425
426
0
  memset(params, 0, sizeof(gnutls_x509_spki_st));
427
0
  params->pk = GNUTLS_PK_RSA_PSS;
428
0
  params->rsa_pss_dig = digest;
429
430
0
  result = _gnutls_x509_read_uint(spk, "saltLength", &params->salt_size);
431
0
  if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
432
0
      result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
433
0
    params->salt_size = 20;
434
0
  else if (result < 0) {
435
0
    gnutls_assert();
436
0
    goto cleanup;
437
0
  }
438
439
0
  result = _gnutls_x509_read_uint(spk, "trailerField", &trailer);
440
0
  if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
441
0
      result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
442
0
    trailer = 1;
443
0
  else if (result < 0) {
444
0
    gnutls_assert();
445
0
    goto cleanup;
446
0
  }
447
0
  if (trailer != 1) {
448
0
    gnutls_assert();
449
0
    result = GNUTLS_E_CERTIFICATE_ERROR;
450
0
    goto cleanup;
451
0
  }
452
453
0
  result = 0;
454
0
cleanup:
455
0
  asn1_delete_structure(&spk);
456
0
  return result;
457
0
}
458
459
static int read_rsa_oaep_label(asn1_node root, const char *name,
460
             gnutls_datum_t *label, bool allow_null)
461
0
{
462
0
  char buffer[MAX_NAME_SIZE];
463
0
  char oid[MAX_OID_SIZE] = "";
464
0
  int size;
465
0
  int result;
466
0
  gnutls_datum_t der = { NULL, 0 };
467
468
0
  result = snprintf(buffer, sizeof(buffer), "%s.algorithm", name);
469
0
  if (result < 0 || (size_t)result >= sizeof(buffer))
470
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
471
472
0
  size = sizeof(oid);
473
0
  result = asn1_read_value(root, buffer, oid, &size);
474
0
  if (result != ASN1_SUCCESS) {
475
0
    if (result != ASN1_ELEMENT_NOT_FOUND && allow_null)
476
0
      return 0;
477
478
0
    gnutls_assert();
479
0
    return _gnutls_asn2err(result);
480
0
  }
481
482
  /* Error out if algorithm other than mgf1 is specified */
483
0
  if (strcmp(oid, PKIX1_RSA_OAEP_P_SPECIFIED_OID) != 0) {
484
0
    gnutls_assert();
485
0
    _gnutls_debug_log("Unknown pSourceFunc algorithm: %s\n", oid);
486
0
    return GNUTLS_E_UNKNOWN_ALGORITHM;
487
0
  }
488
489
  /* Extract label from pSourceFunc.parameters */
490
0
  result = snprintf(buffer, sizeof(buffer), "%s.parameters", name);
491
0
  if (result < 0 || (size_t)result >= sizeof(buffer))
492
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
493
494
0
  result = _gnutls_x509_read_null_value(root, buffer, &der);
495
0
  if (result < 0) {
496
0
    gnutls_assert();
497
0
    goto cleanup;
498
0
  }
499
500
0
  result = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, der.data,
501
0
              der.size, label, 0);
502
0
  if (result < 0) {
503
0
    gnutls_assert();
504
0
    goto cleanup;
505
0
  }
506
507
0
  result = 0;
508
509
0
cleanup:
510
0
  _gnutls_free_datum(&der);
511
512
0
  return result;
513
0
}
514
515
/* Reads RSA-OAEP parameters.
516
 */
517
int _gnutls_x509_read_rsa_oaep_params(uint8_t *der, int dersize,
518
              gnutls_x509_spki_st *params)
519
0
{
520
0
  int result;
521
0
  asn1_node spk = NULL;
522
0
  gnutls_digest_algorithm_t digest;
523
0
  char oid[MAX_OID_SIZE] = "";
524
0
  int size;
525
0
  gnutls_datum_t label = { NULL, 0 };
526
527
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
528
0
            "GNUTLS.RSAOAEPParameters", &spk)) !=
529
0
      ASN1_SUCCESS) {
530
0
    gnutls_assert();
531
0
    result = _gnutls_asn2err(result);
532
0
    goto cleanup;
533
0
  }
534
535
0
  result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
536
537
0
  if (result != ASN1_SUCCESS) {
538
0
    gnutls_assert();
539
0
    result = _gnutls_asn2err(result);
540
0
    goto cleanup;
541
0
  }
542
543
0
  size = sizeof(oid);
544
0
  result = asn1_read_value(spk, "hashAlgorithm.algorithm", oid, &size);
545
0
  if (result == ASN1_SUCCESS)
546
0
    digest = gnutls_oid_to_digest(oid);
547
0
  else if (result == ASN1_ELEMENT_NOT_FOUND)
548
    /* The default hash algorithm is SHA-1 */
549
0
    digest = GNUTLS_DIG_SHA1;
550
0
  else {
551
0
    gnutls_assert();
552
0
    result = _gnutls_asn2err(result);
553
0
    goto cleanup;
554
0
  }
555
556
0
  if (digest == GNUTLS_DIG_UNKNOWN) {
557
0
    gnutls_assert();
558
0
    _gnutls_debug_log("Unknown RSA-OAEP hash: %s\n", oid);
559
0
    result = GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
560
0
    goto cleanup;
561
0
  }
562
563
0
  result = check_mgf1(spk, "maskGenAlgorithm", digest, true);
564
0
  if (result < 0) {
565
0
    gnutls_assert();
566
0
    goto cleanup;
567
0
  }
568
569
0
  result = read_rsa_oaep_label(spk, "pSourceFunc", &label, true);
570
0
  if (result < 0) {
571
0
    gnutls_assert();
572
0
    goto cleanup;
573
0
  }
574
575
0
  memset(params, 0, sizeof(gnutls_x509_spki_st));
576
0
  params->pk = GNUTLS_PK_RSA_OAEP;
577
0
  params->rsa_oaep_dig = digest;
578
0
  if (label.data) {
579
0
    params->rsa_oaep_label = label;
580
0
    label.data = NULL;
581
0
  }
582
583
0
  result = 0;
584
0
cleanup:
585
0
  _gnutls_free_datum(&label);
586
0
  asn1_delete_structure(&spk);
587
0
  return result;
588
0
}
589
590
/* reads the curve from the certificate.
591
 * It does NOT set params_nr.
592
 */
593
int _gnutls_x509_read_gost_params(uint8_t *der, int dersize,
594
          gnutls_pk_params_st *params,
595
          gnutls_pk_algorithm_t algo)
596
0
{
597
0
  int ret;
598
0
  asn1_node spk = NULL;
599
0
  char oid[MAX_OID_SIZE];
600
0
  int oid_size;
601
0
  gnutls_ecc_curve_t curve;
602
0
  gnutls_gost_paramset_t param;
603
604
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
605
0
               algo == GNUTLS_PK_GOST_01 ?
606
0
                 "GNUTLS.GOSTParametersOld" :
607
0
                 "GNUTLS.GOSTParameters",
608
0
               &spk)) != ASN1_SUCCESS) {
609
0
    gnutls_assert();
610
0
    return _gnutls_asn2err(ret);
611
0
  }
612
613
0
  ret = _asn1_strict_der_decode(&spk, der, dersize, NULL);
614
615
0
  if (ret != ASN1_SUCCESS) {
616
0
    gnutls_assert();
617
0
    ret = _gnutls_asn2err(ret);
618
0
    goto cleanup;
619
0
  }
620
621
  /* read the curve */
622
0
  oid_size = sizeof(oid);
623
0
  ret = asn1_read_value(spk, "publicKeyParamSet", oid, &oid_size);
624
0
  if (ret != ASN1_SUCCESS) {
625
0
    gnutls_assert();
626
0
    ret = _gnutls_asn2err(ret);
627
0
    goto cleanup;
628
0
  }
629
630
0
  curve = gnutls_oid_to_ecc_curve(oid);
631
0
  if (curve == GNUTLS_ECC_CURVE_INVALID) {
632
0
    _gnutls_debug_log("Curve %s is not supported\n", oid);
633
0
    gnutls_assert();
634
0
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
635
0
    goto cleanup;
636
0
  }
637
638
  /* Read the digest */
639
0
  oid_size = sizeof(oid);
640
0
  ret = asn1_read_value(spk, "digestParamSet", oid, &oid_size);
641
0
  if (ret != ASN1_SUCCESS && ret != ASN1_ELEMENT_NOT_FOUND) {
642
0
    gnutls_assert();
643
0
    ret = _gnutls_asn2err(ret);
644
0
    goto cleanup;
645
0
  }
646
  /* For now ignore the OID: we use pk OID instead */
647
648
0
  oid_size = sizeof(oid);
649
0
  ret = asn1_read_value(spk, "encryptionParamSet", oid, &oid_size);
650
0
  if (ret != ASN1_SUCCESS && ret != ASN1_ELEMENT_NOT_FOUND) {
651
0
    gnutls_assert();
652
0
    ret = _gnutls_asn2err(ret);
653
0
    goto cleanup;
654
0
  }
655
656
0
  if (ret != ASN1_ELEMENT_NOT_FOUND)
657
0
    param = gnutls_oid_to_gost_paramset(oid);
658
0
  else
659
0
    param = _gnutls_gost_paramset_default(algo);
660
661
0
  if (param == GNUTLS_GOST_PARAMSET_UNKNOWN) {
662
0
    gnutls_assert();
663
0
    ret = param;
664
0
    goto cleanup;
665
0
  }
666
667
0
  params->curve = curve;
668
0
  params->gost_params = param;
669
0
  ret = 0;
670
671
0
cleanup:
672
673
0
  asn1_delete_structure(&spk);
674
675
0
  return ret;
676
0
}
677
678
/* This function must be called after _gnutls_x509_read_params()
679
 */
680
int _gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo, uint8_t *der,
681
           int dersize, gnutls_pk_params_st *params)
682
0
{
683
0
  int ret;
684
685
0
  switch (algo) {
686
0
  case GNUTLS_PK_RSA:
687
0
  case GNUTLS_PK_RSA_PSS:
688
0
  case GNUTLS_PK_RSA_OAEP:
689
0
    ret = _gnutls_x509_read_rsa_pubkey(der, dersize, params);
690
0
    if (ret >= 0) {
691
0
      params->algo = algo;
692
0
      params->params_nr = RSA_PUBLIC_PARAMS;
693
0
    }
694
0
    break;
695
0
  case GNUTLS_PK_DSA:
696
0
    if (params->params_nr !=
697
0
        3) /* _gnutls_x509_read_pubkey_params must have been called */
698
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
699
700
0
    ret = _gnutls_x509_read_dsa_pubkey(der, dersize, params);
701
0
    if (ret >= 0) {
702
0
      params->algo = GNUTLS_PK_DSA;
703
0
      params->params_nr = DSA_PUBLIC_PARAMS;
704
0
    }
705
0
    break;
706
0
  case GNUTLS_PK_ECDSA:
707
0
    ret = _gnutls_x509_read_ecc_pubkey(der, dersize, params);
708
0
    if (ret >= 0) {
709
0
      params->algo = GNUTLS_PK_ECDSA;
710
0
      params->params_nr = ECC_PUBLIC_PARAMS;
711
0
    }
712
0
    break;
713
0
  case GNUTLS_PK_EDDSA_ED25519:
714
0
    ret = _gnutls_x509_read_eddsa_pubkey(GNUTLS_ECC_CURVE_ED25519,
715
0
                 der, dersize, params);
716
0
    break;
717
0
  case GNUTLS_PK_EDDSA_ED448:
718
0
    ret = _gnutls_x509_read_eddsa_pubkey(GNUTLS_ECC_CURVE_ED448,
719
0
                 der, dersize, params);
720
0
    break;
721
0
  case GNUTLS_PK_ECDH_X25519:
722
0
    ret = _gnutls_x509_read_ecdh_pubkey(GNUTLS_ECC_CURVE_X25519,
723
0
                der, dersize, params);
724
0
    break;
725
0
  case GNUTLS_PK_ECDH_X448:
726
0
    ret = _gnutls_x509_read_ecdh_pubkey(GNUTLS_ECC_CURVE_X448, der,
727
0
                dersize, params);
728
0
    break;
729
0
  case GNUTLS_PK_GOST_01:
730
0
  case GNUTLS_PK_GOST_12_256:
731
0
  case GNUTLS_PK_GOST_12_512:
732
0
    ret = _gnutls_x509_read_gost_pubkey(der, dersize, params);
733
0
    if (ret >= 0) {
734
0
      params->algo = algo;
735
0
      params->params_nr = GOST_PUBLIC_PARAMS;
736
0
    }
737
0
    break;
738
0
  case GNUTLS_PK_MLDSA44:
739
0
  case GNUTLS_PK_MLDSA65:
740
0
  case GNUTLS_PK_MLDSA87:
741
0
    ret = _gnutls_set_datum(&params->raw_pub, der, dersize);
742
0
    break;
743
0
  default:
744
0
    ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
745
0
    break;
746
0
  }
747
0
  return ret;
748
0
}
749
750
/* This function must be called prior to _gnutls_x509_read_pubkey()
751
 */
752
int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo, uint8_t *der,
753
            int dersize, gnutls_pk_params_st *params)
754
0
{
755
0
  switch (algo) {
756
0
  case GNUTLS_PK_RSA:
757
0
  case GNUTLS_PK_EDDSA_ED25519:
758
0
  case GNUTLS_PK_EDDSA_ED448:
759
0
    return 0;
760
0
  case GNUTLS_PK_RSA_PSS:
761
0
    return _gnutls_x509_read_rsa_pss_params(der, dersize,
762
0
              &params->spki);
763
0
  case GNUTLS_PK_RSA_OAEP:
764
0
    return _gnutls_x509_read_rsa_oaep_params(der, dersize,
765
0
               &params->spki);
766
0
  case GNUTLS_PK_DSA:
767
0
    return _gnutls_x509_read_dsa_params(der, dersize, params);
768
0
  case GNUTLS_PK_EC:
769
0
    return _gnutls_x509_read_ecc_params(der, dersize,
770
0
                &params->curve);
771
0
  case GNUTLS_PK_GOST_01:
772
0
  case GNUTLS_PK_GOST_12_256:
773
0
  case GNUTLS_PK_GOST_12_512:
774
0
    return _gnutls_x509_read_gost_params(der, dersize, params,
775
0
                 algo);
776
0
  default:
777
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
778
0
  }
779
0
}
780
781
/* This function must be called after _gnutls_x509_read_pubkey()
782
 */
783
int _gnutls_x509_check_pubkey_params(gnutls_pk_params_st *params)
784
0
{
785
0
  switch (params->algo) {
786
0
  case GNUTLS_PK_RSA_PSS: {
787
0
    unsigned bits;
788
0
    const mac_entry_st *me;
789
0
    size_t hash_size;
790
791
0
    if (params->spki.pk ==
792
0
        GNUTLS_PK_UNKNOWN) /* no params present */
793
0
      return 0;
794
795
0
    bits = pubkey_to_bits(params);
796
797
0
    me = hash_to_entry(params->spki.rsa_pss_dig);
798
0
    if (unlikely(me == NULL))
799
0
      return gnutls_assert_val(
800
0
        GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
801
802
0
    hash_size = _gnutls_hash_get_algo_len(me);
803
0
    if (hash_size + params->spki.salt_size + 2 > (bits + 7) / 8)
804
0
      return gnutls_assert_val(
805
0
        GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
806
0
    return 0;
807
0
  }
808
0
  case GNUTLS_PK_RSA_OAEP: {
809
0
    unsigned bits;
810
0
    const mac_entry_st *me;
811
0
    size_t hash_size;
812
813
0
    if (params->spki.pk ==
814
0
        GNUTLS_PK_UNKNOWN) /* no params present */
815
0
      return 0;
816
817
0
    bits = pubkey_to_bits(params);
818
819
0
    me = hash_to_entry(params->spki.rsa_oaep_dig);
820
0
    if (unlikely(me == NULL))
821
0
      return gnutls_assert_val(
822
0
        GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
823
824
0
    hash_size = _gnutls_hash_get_algo_len(me);
825
0
    if (2 * hash_size + 2 > (bits + 7) / 8)
826
0
      return gnutls_assert_val(
827
0
        GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
828
0
    return 0;
829
0
  }
830
0
  case GNUTLS_PK_RSA:
831
0
  case GNUTLS_PK_DSA:
832
0
  case GNUTLS_PK_ECDSA:
833
0
  case GNUTLS_PK_EDDSA_ED25519:
834
0
  case GNUTLS_PK_EDDSA_ED448:
835
0
  case GNUTLS_PK_ECDH_X25519:
836
0
  case GNUTLS_PK_ECDH_X448:
837
0
  case GNUTLS_PK_GOST_01:
838
0
  case GNUTLS_PK_GOST_12_256:
839
0
  case GNUTLS_PK_GOST_12_512:
840
0
  case GNUTLS_PK_MLDSA44:
841
0
  case GNUTLS_PK_MLDSA65:
842
0
  case GNUTLS_PK_MLDSA87:
843
0
    return 0;
844
0
  default:
845
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
846
0
  }
847
0
}
848
849
/* reads DSA's Y
850
 * from the certificate 
851
 * only sets params[3]
852
 */
853
int _gnutls_x509_read_dsa_pubkey(uint8_t *der, int dersize,
854
         gnutls_pk_params_st *params)
855
0
{
856
0
  return _gnutls_x509_read_der_int(der, dersize, &params->params[3]);
857
0
}