Coverage Report

Created: 2024-06-20 06:28

/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
/* Reads RSA-PSS parameters.
289
 */
290
int _gnutls_x509_read_rsa_pss_params(uint8_t *der, int dersize,
291
             gnutls_x509_spki_st *params)
292
0
{
293
0
  int result;
294
0
  asn1_node spk = NULL;
295
0
  asn1_node c2 = NULL;
296
0
  gnutls_digest_algorithm_t digest;
297
0
  char oid[MAX_OID_SIZE] = "";
298
0
  int size;
299
0
  unsigned int trailer;
300
0
  gnutls_datum_t value = { NULL, 0 };
301
302
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
303
0
            "GNUTLS.RSAPSSParameters", &spk)) !=
304
0
      ASN1_SUCCESS) {
305
0
    gnutls_assert();
306
0
    result = _gnutls_asn2err(result);
307
0
    goto cleanup;
308
0
  }
309
310
0
  result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
311
312
0
  if (result != ASN1_SUCCESS) {
313
0
    gnutls_assert();
314
0
    result = _gnutls_asn2err(result);
315
0
    goto cleanup;
316
0
  }
317
318
0
  size = sizeof(oid);
319
0
  result = asn1_read_value(spk, "hashAlgorithm.algorithm", oid, &size);
320
0
  if (result == ASN1_SUCCESS)
321
0
    digest = gnutls_oid_to_digest(oid);
322
0
  else if (result == ASN1_ELEMENT_NOT_FOUND)
323
    /* The default hash algorithm is SHA-1 */
324
0
    digest = GNUTLS_DIG_SHA1;
325
0
  else {
326
0
    gnutls_assert();
327
0
    result = _gnutls_asn2err(result);
328
0
    goto cleanup;
329
0
  }
330
331
0
  if (digest == GNUTLS_DIG_UNKNOWN) {
332
0
    gnutls_assert();
333
0
    _gnutls_debug_log("Unknown RSA-PSS hash: %s\n", oid);
334
0
    result = GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
335
0
    goto cleanup;
336
0
  }
337
338
0
  size = sizeof(oid);
339
0
  result = asn1_read_value(spk, "maskGenAlgorithm.algorithm", oid, &size);
340
0
  if (result == ASN1_SUCCESS) {
341
0
    gnutls_digest_algorithm_t digest2;
342
343
    /* Error out if algorithm other than mgf1 is specified */
344
0
    if (strcmp(oid, PKIX1_RSA_PSS_MGF1_OID) != 0) {
345
0
      gnutls_assert();
346
0
      _gnutls_debug_log("Unknown mask algorithm: %s\n", oid);
347
0
      result = GNUTLS_E_UNKNOWN_ALGORITHM;
348
0
      goto cleanup;
349
0
    }
350
351
    /* Check if maskGenAlgorithm.parameters does exist and
352
     * is identical to hashAlgorithm */
353
0
    result = _gnutls_x509_read_value(
354
0
      spk, "maskGenAlgorithm.parameters", &value);
355
0
    if (result < 0) {
356
0
      gnutls_assert();
357
0
      goto cleanup;
358
0
    }
359
360
0
    if ((result = asn1_create_element(_gnutls_get_pkix(),
361
0
              "PKIX1.AlgorithmIdentifier",
362
0
              &c2)) != ASN1_SUCCESS) {
363
0
      gnutls_assert();
364
0
      result = _gnutls_asn2err(result);
365
0
      goto cleanup;
366
0
    }
367
368
0
    result = _asn1_strict_der_decode(&c2, value.data, value.size,
369
0
             NULL);
370
0
    if (result != ASN1_SUCCESS) {
371
0
      gnutls_assert();
372
0
      result = _gnutls_asn2err(result);
373
0
      goto cleanup;
374
0
    }
375
376
0
    size = sizeof(oid);
377
0
    result = asn1_read_value(c2, "algorithm", oid, &size);
378
0
    if (result == ASN1_SUCCESS)
379
0
      digest2 = gnutls_oid_to_digest(oid);
380
0
    else if (result == ASN1_ELEMENT_NOT_FOUND)
381
      /* The default hash algorithm for mgf1 is SHA-1 */
382
0
      digest2 = GNUTLS_DIG_SHA1;
383
0
    else {
384
0
      gnutls_assert();
385
0
      result = _gnutls_asn2err(result);
386
0
      goto cleanup;
387
0
    }
388
389
0
    if (digest != digest2) {
390
0
      gnutls_assert();
391
0
      result = GNUTLS_E_CONSTRAINT_ERROR;
392
0
      goto cleanup;
393
0
    }
394
0
  } else if (result != ASN1_ELEMENT_NOT_FOUND) {
395
0
    gnutls_assert();
396
0
    result = _gnutls_asn2err(result);
397
0
    goto cleanup;
398
0
  }
399
400
0
  memset(params, 0, sizeof(gnutls_x509_spki_st));
401
0
  params->pk = GNUTLS_PK_RSA_PSS;
402
0
  params->rsa_pss_dig = digest;
403
404
0
  result = _gnutls_x509_read_uint(spk, "saltLength", &params->salt_size);
405
0
  if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
406
0
      result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
407
0
    params->salt_size = 20;
408
0
  else if (result < 0) {
409
0
    gnutls_assert();
410
0
    goto cleanup;
411
0
  }
412
413
0
  result = _gnutls_x509_read_uint(spk, "trailerField", &trailer);
414
0
  if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
415
0
      result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
416
0
    trailer = 1;
417
0
  else if (result < 0) {
418
0
    gnutls_assert();
419
0
    goto cleanup;
420
0
  }
421
0
  if (trailer != 1) {
422
0
    gnutls_assert();
423
0
    result = GNUTLS_E_CERTIFICATE_ERROR;
424
0
    goto cleanup;
425
0
  }
426
427
0
  result = 0;
428
0
cleanup:
429
0
  _gnutls_free_datum(&value);
430
0
  asn1_delete_structure(&c2);
431
0
  asn1_delete_structure(&spk);
432
0
  return result;
433
0
}
434
435
/* reads the curve from the certificate.
436
 * It does NOT set params_nr.
437
 */
438
int _gnutls_x509_read_gost_params(uint8_t *der, int dersize,
439
          gnutls_pk_params_st *params,
440
          gnutls_pk_algorithm_t algo)
441
0
{
442
0
  int ret;
443
0
  asn1_node spk = NULL;
444
0
  char oid[MAX_OID_SIZE];
445
0
  int oid_size;
446
0
  gnutls_ecc_curve_t curve;
447
0
  gnutls_gost_paramset_t param;
448
449
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
450
0
               algo == GNUTLS_PK_GOST_01 ?
451
0
                 "GNUTLS.GOSTParametersOld" :
452
0
                 "GNUTLS.GOSTParameters",
453
0
               &spk)) != ASN1_SUCCESS) {
454
0
    gnutls_assert();
455
0
    return _gnutls_asn2err(ret);
456
0
  }
457
458
0
  ret = _asn1_strict_der_decode(&spk, der, dersize, NULL);
459
460
0
  if (ret != ASN1_SUCCESS) {
461
0
    gnutls_assert();
462
0
    ret = _gnutls_asn2err(ret);
463
0
    goto cleanup;
464
0
  }
465
466
  /* read the curve */
467
0
  oid_size = sizeof(oid);
468
0
  ret = asn1_read_value(spk, "publicKeyParamSet", oid, &oid_size);
469
0
  if (ret != ASN1_SUCCESS) {
470
0
    gnutls_assert();
471
0
    ret = _gnutls_asn2err(ret);
472
0
    goto cleanup;
473
0
  }
474
475
0
  curve = gnutls_oid_to_ecc_curve(oid);
476
0
  if (curve == GNUTLS_ECC_CURVE_INVALID) {
477
0
    _gnutls_debug_log("Curve %s is not supported\n", oid);
478
0
    gnutls_assert();
479
0
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
480
0
    goto cleanup;
481
0
  }
482
483
  /* Read the digest */
484
0
  oid_size = sizeof(oid);
485
0
  ret = asn1_read_value(spk, "digestParamSet", oid, &oid_size);
486
0
  if (ret != ASN1_SUCCESS && ret != ASN1_ELEMENT_NOT_FOUND) {
487
0
    gnutls_assert();
488
0
    ret = _gnutls_asn2err(ret);
489
0
    goto cleanup;
490
0
  }
491
  /* For now ignore the OID: we use pk OID instead */
492
493
0
  oid_size = sizeof(oid);
494
0
  ret = asn1_read_value(spk, "encryptionParamSet", oid, &oid_size);
495
0
  if (ret != ASN1_SUCCESS && ret != ASN1_ELEMENT_NOT_FOUND) {
496
0
    gnutls_assert();
497
0
    ret = _gnutls_asn2err(ret);
498
0
    goto cleanup;
499
0
  }
500
501
0
  if (ret != ASN1_ELEMENT_NOT_FOUND)
502
0
    param = gnutls_oid_to_gost_paramset(oid);
503
0
  else
504
0
    param = _gnutls_gost_paramset_default(algo);
505
506
0
  if (param == GNUTLS_GOST_PARAMSET_UNKNOWN) {
507
0
    gnutls_assert();
508
0
    ret = param;
509
0
    goto cleanup;
510
0
  }
511
512
0
  params->curve = curve;
513
0
  params->gost_params = param;
514
0
  ret = 0;
515
516
0
cleanup:
517
518
0
  asn1_delete_structure(&spk);
519
520
0
  return ret;
521
0
}
522
523
/* This function must be called after _gnutls_x509_read_params()
524
 */
525
int _gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo, uint8_t *der,
526
           int dersize, gnutls_pk_params_st *params)
527
0
{
528
0
  int ret;
529
530
0
  switch (algo) {
531
0
  case GNUTLS_PK_RSA:
532
0
  case GNUTLS_PK_RSA_PSS:
533
0
    ret = _gnutls_x509_read_rsa_pubkey(der, dersize, params);
534
0
    if (ret >= 0) {
535
0
      params->algo = algo;
536
0
      params->params_nr = RSA_PUBLIC_PARAMS;
537
0
    }
538
0
    break;
539
0
  case GNUTLS_PK_DSA:
540
0
    if (params->params_nr !=
541
0
        3) /* _gnutls_x509_read_pubkey_params must have been called */
542
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
543
544
0
    ret = _gnutls_x509_read_dsa_pubkey(der, dersize, params);
545
0
    if (ret >= 0) {
546
0
      params->algo = GNUTLS_PK_DSA;
547
0
      params->params_nr = DSA_PUBLIC_PARAMS;
548
0
    }
549
0
    break;
550
0
  case GNUTLS_PK_ECDSA:
551
0
    ret = _gnutls_x509_read_ecc_pubkey(der, dersize, params);
552
0
    if (ret >= 0) {
553
0
      params->algo = GNUTLS_PK_ECDSA;
554
0
      params->params_nr = ECC_PUBLIC_PARAMS;
555
0
    }
556
0
    break;
557
0
  case GNUTLS_PK_EDDSA_ED25519:
558
0
    ret = _gnutls_x509_read_eddsa_pubkey(GNUTLS_ECC_CURVE_ED25519,
559
0
                 der, dersize, params);
560
0
    break;
561
0
  case GNUTLS_PK_EDDSA_ED448:
562
0
    ret = _gnutls_x509_read_eddsa_pubkey(GNUTLS_ECC_CURVE_ED448,
563
0
                 der, dersize, params);
564
0
    break;
565
0
  case GNUTLS_PK_ECDH_X25519:
566
0
    ret = _gnutls_x509_read_ecdh_pubkey(GNUTLS_ECC_CURVE_X25519,
567
0
                der, dersize, params);
568
0
    break;
569
0
  case GNUTLS_PK_ECDH_X448:
570
0
    ret = _gnutls_x509_read_ecdh_pubkey(GNUTLS_ECC_CURVE_X448, der,
571
0
                dersize, params);
572
0
    break;
573
0
  case GNUTLS_PK_GOST_01:
574
0
  case GNUTLS_PK_GOST_12_256:
575
0
  case GNUTLS_PK_GOST_12_512:
576
0
    ret = _gnutls_x509_read_gost_pubkey(der, dersize, params);
577
0
    if (ret >= 0) {
578
0
      params->algo = algo;
579
0
      params->params_nr = GOST_PUBLIC_PARAMS;
580
0
    }
581
0
    break;
582
0
  default:
583
0
    ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
584
0
    break;
585
0
  }
586
0
  return ret;
587
0
}
588
589
/* This function must be called prior to _gnutls_x509_read_pubkey()
590
 */
591
int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo, uint8_t *der,
592
            int dersize, gnutls_pk_params_st *params)
593
0
{
594
0
  switch (algo) {
595
0
  case GNUTLS_PK_RSA:
596
0
  case GNUTLS_PK_EDDSA_ED25519:
597
0
  case GNUTLS_PK_EDDSA_ED448:
598
0
    return 0;
599
0
  case GNUTLS_PK_RSA_PSS:
600
0
    return _gnutls_x509_read_rsa_pss_params(der, dersize,
601
0
              &params->spki);
602
0
  case GNUTLS_PK_DSA:
603
0
    return _gnutls_x509_read_dsa_params(der, dersize, params);
604
0
  case GNUTLS_PK_EC:
605
0
    return _gnutls_x509_read_ecc_params(der, dersize,
606
0
                &params->curve);
607
0
  case GNUTLS_PK_GOST_01:
608
0
  case GNUTLS_PK_GOST_12_256:
609
0
  case GNUTLS_PK_GOST_12_512:
610
0
    return _gnutls_x509_read_gost_params(der, dersize, params,
611
0
                 algo);
612
0
  default:
613
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
614
0
  }
615
0
}
616
617
/* This function must be called after _gnutls_x509_read_pubkey()
618
 */
619
int _gnutls_x509_check_pubkey_params(gnutls_pk_params_st *params)
620
0
{
621
0
  switch (params->algo) {
622
0
  case GNUTLS_PK_RSA_PSS: {
623
0
    unsigned bits;
624
0
    const mac_entry_st *me;
625
0
    size_t hash_size;
626
627
0
    if (params->spki.pk ==
628
0
        GNUTLS_PK_UNKNOWN) /* no params present */
629
0
      return 0;
630
631
0
    bits = pubkey_to_bits(params);
632
633
0
    me = hash_to_entry(params->spki.rsa_pss_dig);
634
0
    if (unlikely(me == NULL))
635
0
      return gnutls_assert_val(
636
0
        GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
637
638
0
    hash_size = _gnutls_hash_get_algo_len(me);
639
0
    if (hash_size + params->spki.salt_size + 2 > (bits + 7) / 8)
640
0
      return gnutls_assert_val(
641
0
        GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
642
0
    return 0;
643
0
  }
644
0
  case GNUTLS_PK_RSA:
645
0
  case GNUTLS_PK_DSA:
646
0
  case GNUTLS_PK_ECDSA:
647
0
  case GNUTLS_PK_EDDSA_ED25519:
648
0
  case GNUTLS_PK_EDDSA_ED448:
649
0
  case GNUTLS_PK_ECDH_X25519:
650
0
  case GNUTLS_PK_ECDH_X448:
651
0
  case GNUTLS_PK_GOST_01:
652
0
  case GNUTLS_PK_GOST_12_256:
653
0
  case GNUTLS_PK_GOST_12_512:
654
0
    return 0;
655
0
  default:
656
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
657
0
  }
658
0
}
659
660
/* reads DSA's Y
661
 * from the certificate 
662
 * only sets params[3]
663
 */
664
int _gnutls_x509_read_dsa_pubkey(uint8_t *der, int dersize,
665
         gnutls_pk_params_st *params)
666
0
{
667
0
  return _gnutls_x509_read_der_int(der, dersize, &params->params[3]);
668
0
}