Coverage Report

Created: 2025-03-06 07:58

/src/gnutls/lib/x509/key_encode.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 "num.h"
32
#include "pk.h"
33
#include "mpi.h"
34
#include "ecc.h"
35
36
static int _gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st *params,
37
           gnutls_datum_t *der);
38
static int _gnutls_x509_write_dsa_params(const gnutls_pk_params_st *params,
39
           gnutls_datum_t *der);
40
static int _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st *params,
41
           gnutls_datum_t *der);
42
static int _gnutls_x509_write_gost_params(const gnutls_pk_params_st *params,
43
            gnutls_datum_t *der);
44
static int _gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st *params,
45
            gnutls_datum_t *der);
46
47
/*
48
 * some x509 certificate functions that relate to MPI parameter
49
 * setting. This writes the BIT STRING subjectPublicKey.
50
 * Needs 2 parameters (m,e).
51
 *
52
 * Allocates the space used to store the DER data.
53
 */
54
static int _gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st *params,
55
           gnutls_datum_t *der)
56
0
{
57
0
  int result;
58
0
  asn1_node spk = NULL;
59
60
0
  der->data = NULL;
61
0
  der->size = 0;
62
63
0
  if (params->params_nr < RSA_PUBLIC_PARAMS) {
64
0
    gnutls_assert();
65
0
    result = GNUTLS_E_INVALID_REQUEST;
66
0
    goto cleanup;
67
0
  }
68
69
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
70
0
            "GNUTLS.RSAPublicKey", &spk)) !=
71
0
      ASN1_SUCCESS) {
72
0
    gnutls_assert();
73
0
    return _gnutls_asn2err(result);
74
0
  }
75
76
0
  result = _gnutls_x509_write_int(spk, "modulus", params->params[0], 1);
77
0
  if (result < 0) {
78
0
    gnutls_assert();
79
0
    goto cleanup;
80
0
  }
81
82
0
  result = _gnutls_x509_write_int(spk, "publicExponent",
83
0
          params->params[1], 1);
84
0
  if (result < 0) {
85
0
    gnutls_assert();
86
0
    goto cleanup;
87
0
  }
88
89
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
90
0
  if (result < 0) {
91
0
    gnutls_assert();
92
0
    goto cleanup;
93
0
  }
94
95
0
  result = 0;
96
97
0
cleanup:
98
0
  asn1_delete_structure(&spk);
99
100
0
  return result;
101
0
}
102
103
/*
104
 * some x509 certificate functions that relate to MPI parameter
105
 * setting. This writes an ECPoint.
106
 *
107
 * Allocates the space used to store the DER data.
108
 */
109
int _gnutls_x509_write_ecc_pubkey(const gnutls_pk_params_st *params,
110
          gnutls_datum_t *der)
111
0
{
112
0
  int result;
113
114
0
  der->data = NULL;
115
0
  der->size = 0;
116
117
0
  if (params->params_nr < ECC_PUBLIC_PARAMS)
118
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
119
120
0
  result = _gnutls_ecc_ansi_x962_export(params->curve,
121
0
                params->params[ECC_X],
122
0
                params->params[ECC_Y], /*&out */
123
0
                der);
124
0
  if (result < 0)
125
0
    return gnutls_assert_val(result);
126
127
0
  return 0;
128
0
}
129
130
/*
131
 * some x509 certificate functions that relate to MPI parameter
132
 * setting. This writes a raw public key.
133
 *
134
 * Allocates the space used to store the data.
135
 */
136
int _gnutls_x509_write_eddsa_pubkey(const gnutls_pk_params_st *params,
137
            gnutls_datum_t *raw)
138
0
{
139
0
  int ret;
140
141
0
  raw->data = NULL;
142
0
  raw->size = 0;
143
144
0
  if (params->raw_pub.size == 0)
145
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
146
147
0
  if (params->curve != GNUTLS_ECC_CURVE_ED25519 &&
148
0
      params->curve != GNUTLS_ECC_CURVE_ED448)
149
0
    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
150
151
0
  ret = _gnutls_set_datum(raw, params->raw_pub.data,
152
0
        params->raw_pub.size);
153
0
  if (ret < 0)
154
0
    return gnutls_assert_val(ret);
155
156
0
  return 0;
157
0
}
158
159
/*
160
 * some x509 certificate functions that relate to MPI parameter
161
 * setting. This writes a raw public key.
162
 *
163
 * Allocates the space used to store the data.
164
 */
165
static int
166
_gnutls_x509_write_modern_ecdh_pubkey(const gnutls_pk_params_st *params,
167
              gnutls_datum_t *raw)
168
0
{
169
0
  int ret;
170
171
0
  raw->data = NULL;
172
0
  raw->size = 0;
173
174
0
  if (params->raw_pub.size == 0)
175
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
176
177
0
  if (params->curve != GNUTLS_ECC_CURVE_X25519 &&
178
0
      params->curve != GNUTLS_ECC_CURVE_X448)
179
0
    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
180
181
0
  ret = _gnutls_set_datum(raw, params->raw_pub.data,
182
0
        params->raw_pub.size);
183
0
  if (ret < 0)
184
0
    return gnutls_assert_val(ret);
185
186
0
  return 0;
187
0
}
188
189
int _gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st *params,
190
           gnutls_datum_t *der)
191
0
{
192
0
  bigint_t x, y;
193
0
  int numlen;
194
0
  int byte_size, ret;
195
0
  size_t size;
196
0
  int pos;
197
198
0
  der->data = NULL;
199
0
  der->size = 0;
200
201
0
  if (params->params_nr < GOST_PUBLIC_PARAMS)
202
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
203
204
0
  x = params->params[GOST_X];
205
0
  y = params->params[GOST_Y];
206
0
  numlen = gnutls_ecc_curve_get_size(params->curve);
207
208
0
  if (numlen == 0)
209
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
210
211
0
  der->size = 1 + ASN1_MAX_LENGTH_SIZE + 2 * numlen;
212
213
0
  der->data = gnutls_malloc(der->size);
214
0
  if (der->data == NULL)
215
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
216
217
0
  memset(der->data, 0, der->size);
218
219
0
  der->data[0] = ASN1_TAG_OCTET_STRING;
220
0
  asn1_length_der(2 * numlen, &der->data[1], &pos);
221
0
  pos += 1;
222
223
  /* pad and store x */
224
0
  byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8;
225
0
  if (numlen < byte_size) {
226
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
227
0
    goto cleanup;
228
0
  }
229
230
0
  size = numlen;
231
0
  ret = _gnutls_mpi_print_le(x, &der->data[pos], &size);
232
0
  if (ret < 0) {
233
0
    gnutls_assert();
234
0
    goto cleanup;
235
0
  }
236
237
  /* pad and store y */
238
0
  byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8;
239
0
  if (numlen < byte_size) {
240
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
241
0
    goto cleanup;
242
0
  }
243
244
0
  size = numlen;
245
0
  ret = _gnutls_mpi_print_le(y, &der->data[pos + numlen], &size);
246
0
  if (ret < 0) {
247
0
    gnutls_assert();
248
0
    goto cleanup;
249
0
  }
250
251
0
  der->size = pos + 2 * numlen;
252
253
0
  return 0;
254
255
0
cleanup:
256
0
  _gnutls_free_datum(der);
257
0
  return ret;
258
0
}
259
260
static int _gnutls_x509_write_ml_dsa_pubkey(const gnutls_pk_params_st *params,
261
              gnutls_datum_t *raw)
262
0
{
263
0
  int ret;
264
265
0
  raw->data = NULL;
266
0
  raw->size = 0;
267
268
0
  if (params->raw_pub.size == 0)
269
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
270
271
0
  ret = _gnutls_set_datum(raw, params->raw_pub.data,
272
0
        params->raw_pub.size);
273
0
  if (ret < 0)
274
0
    return gnutls_assert_val(ret);
275
276
0
  return 0;
277
0
}
278
279
int _gnutls_x509_write_pubkey_params(const gnutls_pk_params_st *params,
280
             gnutls_datum_t *der)
281
0
{
282
0
  switch (params->algo) {
283
0
  case GNUTLS_PK_DSA:
284
0
    return _gnutls_x509_write_dsa_params(params, der);
285
0
  case GNUTLS_PK_RSA:
286
0
    der->data = gnutls_malloc(ASN1_NULL_SIZE);
287
0
    if (der->data == NULL)
288
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
289
290
0
    memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE);
291
0
    der->size = ASN1_NULL_SIZE;
292
0
    return 0;
293
0
  case GNUTLS_PK_RSA_PSS:
294
0
    return _gnutls_x509_write_rsa_pss_params(&params->spki, der);
295
0
  case GNUTLS_PK_RSA_OAEP:
296
0
    return _gnutls_x509_write_rsa_oaep_params(&params->spki, der);
297
0
  case GNUTLS_PK_ECDSA:
298
0
    return _gnutls_x509_write_ecc_params(params->curve, der);
299
0
  case GNUTLS_PK_EDDSA_ED25519:
300
0
  case GNUTLS_PK_EDDSA_ED448:
301
0
  case GNUTLS_PK_ECDH_X25519:
302
0
  case GNUTLS_PK_ECDH_X448:
303
0
  case GNUTLS_PK_MLDSA44:
304
0
  case GNUTLS_PK_MLDSA65:
305
0
  case GNUTLS_PK_MLDSA87:
306
0
    der->data = NULL;
307
0
    der->size = 0;
308
309
0
    return 0;
310
0
  case GNUTLS_PK_GOST_01:
311
0
  case GNUTLS_PK_GOST_12_256:
312
0
  case GNUTLS_PK_GOST_12_512:
313
0
    return _gnutls_x509_write_gost_params(params, der);
314
0
  default:
315
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
316
0
  }
317
0
}
318
319
int _gnutls_x509_write_pubkey(const gnutls_pk_params_st *params,
320
            gnutls_datum_t *der)
321
0
{
322
0
  switch (params->algo) {
323
0
  case GNUTLS_PK_DSA:
324
0
    return _gnutls_x509_write_dsa_pubkey(params, der);
325
0
  case GNUTLS_PK_RSA:
326
0
  case GNUTLS_PK_RSA_PSS:
327
0
  case GNUTLS_PK_RSA_OAEP:
328
0
    return _gnutls_x509_write_rsa_pubkey(params, der);
329
0
  case GNUTLS_PK_ECDSA:
330
0
    return _gnutls_x509_write_ecc_pubkey(params, der);
331
0
  case GNUTLS_PK_EDDSA_ED25519:
332
0
  case GNUTLS_PK_EDDSA_ED448:
333
0
    return _gnutls_x509_write_eddsa_pubkey(params, der);
334
0
  case GNUTLS_PK_ECDH_X25519:
335
0
  case GNUTLS_PK_ECDH_X448:
336
0
    return _gnutls_x509_write_modern_ecdh_pubkey(params, der);
337
0
  case GNUTLS_PK_GOST_01:
338
0
  case GNUTLS_PK_GOST_12_256:
339
0
  case GNUTLS_PK_GOST_12_512:
340
0
    return _gnutls_x509_write_gost_pubkey(params, der);
341
0
  case GNUTLS_PK_MLDSA44:
342
0
  case GNUTLS_PK_MLDSA65:
343
0
  case GNUTLS_PK_MLDSA87:
344
0
    return _gnutls_x509_write_ml_dsa_pubkey(params, der);
345
0
  default:
346
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
347
0
  }
348
0
}
349
350
/*
351
 * This function writes the parameters for DSS keys.
352
 * Needs 3 parameters (p,q,g).
353
 *
354
 * Allocates the space used to store the DER data.
355
 */
356
static int _gnutls_x509_write_dsa_params(const gnutls_pk_params_st *params,
357
           gnutls_datum_t *der)
358
0
{
359
0
  int result;
360
0
  asn1_node spk = NULL;
361
362
0
  der->data = NULL;
363
0
  der->size = 0;
364
365
0
  if (params->params_nr < DSA_PUBLIC_PARAMS - 1) {
366
0
    gnutls_assert();
367
0
    result = GNUTLS_E_INVALID_REQUEST;
368
0
    goto cleanup;
369
0
  }
370
371
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
372
0
            "GNUTLS.DSAParameters", &spk)) !=
373
0
      ASN1_SUCCESS) {
374
0
    gnutls_assert();
375
0
    return _gnutls_asn2err(result);
376
0
  }
377
378
0
  result = _gnutls_x509_write_int(spk, "p", params->params[0], 1);
379
0
  if (result < 0) {
380
0
    gnutls_assert();
381
0
    goto cleanup;
382
0
  }
383
384
0
  result = _gnutls_x509_write_int(spk, "q", params->params[1], 1);
385
0
  if (result < 0) {
386
0
    gnutls_assert();
387
0
    goto cleanup;
388
0
  }
389
390
0
  result = _gnutls_x509_write_int(spk, "g", params->params[2], 1);
391
0
  if (result < 0) {
392
0
    gnutls_assert();
393
0
    goto cleanup;
394
0
  }
395
396
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
397
0
  if (result < 0) {
398
0
    gnutls_assert();
399
0
    goto cleanup;
400
0
  }
401
402
0
  result = 0;
403
404
0
cleanup:
405
0
  asn1_delete_structure(&spk);
406
0
  return result;
407
0
}
408
409
/*
410
 * This function writes the parameters for ECC keys.
411
 * That is the ECParameters struct.
412
 *
413
 * Allocates the space used to store the DER data.
414
 */
415
int _gnutls_x509_write_ecc_params(const gnutls_ecc_curve_t curve,
416
          gnutls_datum_t *der)
417
0
{
418
0
  int result;
419
0
  asn1_node spk = NULL;
420
0
  const char *oid;
421
422
0
  der->data = NULL;
423
0
  der->size = 0;
424
425
0
  oid = gnutls_ecc_curve_get_oid(curve);
426
0
  if (oid == NULL)
427
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
428
429
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
430
0
            "GNUTLS.ECParameters", &spk)) !=
431
0
      ASN1_SUCCESS) {
432
0
    gnutls_assert();
433
0
    return _gnutls_asn2err(result);
434
0
  }
435
436
0
  if ((result = asn1_write_value(spk, "", "namedCurve", 1)) !=
437
0
      ASN1_SUCCESS) {
438
0
    gnutls_assert();
439
0
    result = _gnutls_asn2err(result);
440
0
    goto cleanup;
441
0
  }
442
443
0
  if ((result = asn1_write_value(spk, "namedCurve", oid, 1)) !=
444
0
      ASN1_SUCCESS) {
445
0
    gnutls_assert();
446
0
    result = _gnutls_asn2err(result);
447
0
    goto cleanup;
448
0
  }
449
450
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
451
0
  if (result < 0) {
452
0
    gnutls_assert();
453
0
    goto cleanup;
454
0
  }
455
456
0
  result = 0;
457
458
0
cleanup:
459
0
  asn1_delete_structure(&spk);
460
0
  return result;
461
0
}
462
463
int _gnutls_x509_write_rsa_pss_params(const gnutls_x509_spki_st *params,
464
              gnutls_datum_t *der)
465
0
{
466
0
  int result;
467
0
  asn1_node spk = NULL;
468
0
  asn1_node c2 = NULL;
469
0
  const char *oid;
470
0
  gnutls_datum_t tmp = { NULL, 0 };
471
472
0
  der->data = NULL;
473
0
  der->size = 0;
474
475
0
  if (params->pk != GNUTLS_PK_RSA_PSS)
476
0
    return 0;
477
478
  /* refuse to write parameters we cannot read */
479
0
  if (gnutls_pk_to_sign(GNUTLS_PK_RSA_PSS, params->rsa_pss_dig) ==
480
0
      GNUTLS_SIGN_UNKNOWN)
481
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
482
483
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
484
0
            "GNUTLS.RSAPSSParameters", &spk)) !=
485
0
      ASN1_SUCCESS) {
486
0
    gnutls_assert();
487
0
    result = _gnutls_asn2err(result);
488
0
    goto cleanup;
489
0
  }
490
491
0
  oid = gnutls_digest_get_oid(params->rsa_pss_dig);
492
493
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid,
494
0
               1)) != ASN1_SUCCESS) {
495
0
    gnutls_assert();
496
0
    result = _gnutls_asn2err(result);
497
0
    goto cleanup;
498
0
  }
499
500
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL,
501
0
               0)) != ASN1_SUCCESS) {
502
0
    gnutls_assert();
503
0
    result = _gnutls_asn2err(result);
504
0
    goto cleanup;
505
0
  }
506
507
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.algorithm",
508
0
               PKIX1_RSA_PSS_MGF1_OID, 1)) !=
509
0
      ASN1_SUCCESS) {
510
0
    gnutls_assert();
511
0
    result = _gnutls_asn2err(result);
512
0
    goto cleanup;
513
0
  }
514
515
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
516
0
            "PKIX1.AlgorithmIdentifier", &c2)) !=
517
0
      ASN1_SUCCESS) {
518
0
    gnutls_assert();
519
0
    result = _gnutls_asn2err(result);
520
0
    goto cleanup;
521
0
  }
522
523
0
  if ((result = asn1_write_value(c2, "algorithm", oid, 1)) !=
524
0
      ASN1_SUCCESS) {
525
0
    gnutls_assert();
526
0
    result = _gnutls_asn2err(result);
527
0
    goto cleanup;
528
0
  }
529
530
0
  if ((result = asn1_write_value(c2, "parameters", NULL, 0)) !=
531
0
      ASN1_SUCCESS) {
532
0
    gnutls_assert();
533
0
    result = _gnutls_asn2err(result);
534
0
    goto cleanup;
535
0
  }
536
537
0
  result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
538
0
  if (result < 0) {
539
0
    gnutls_assert();
540
0
    goto cleanup;
541
0
  }
542
543
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.parameters",
544
0
               tmp.data, tmp.size)) != ASN1_SUCCESS) {
545
0
    gnutls_assert();
546
0
    result = _gnutls_asn2err(result);
547
0
    goto cleanup;
548
0
  }
549
550
0
  result =
551
0
    _gnutls_x509_write_uint32(spk, "saltLength", params->salt_size);
552
0
  if (result < 0) {
553
0
    gnutls_assert();
554
0
    goto cleanup;
555
0
  }
556
557
0
  result = _gnutls_x509_write_uint32(spk, "trailerField", 1);
558
0
  if (result < 0) {
559
0
    gnutls_assert();
560
0
    goto cleanup;
561
0
  }
562
563
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
564
0
  if (result < 0) {
565
0
    gnutls_assert();
566
0
    goto cleanup;
567
0
  }
568
569
0
  result = 0;
570
571
0
cleanup:
572
0
  _gnutls_free_datum(&tmp);
573
0
  asn1_delete_structure(&c2);
574
0
  asn1_delete_structure(&spk);
575
0
  return result;
576
0
}
577
578
int _gnutls_x509_write_rsa_oaep_params(const gnutls_x509_spki_st *params,
579
               gnutls_datum_t *der)
580
0
{
581
0
  int result;
582
0
  asn1_node spk = NULL;
583
0
  asn1_node c2 = NULL;
584
0
  const char *oid;
585
0
  gnutls_datum_t tmp = { NULL, 0 };
586
0
  gnutls_datum_t label = { NULL, 0 };
587
588
0
  der->data = NULL;
589
0
  der->size = 0;
590
591
0
  if (params->pk != GNUTLS_PK_RSA_OAEP)
592
0
    return 0;
593
594
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
595
0
            "GNUTLS.RSAOAEPParameters", &spk)) !=
596
0
      ASN1_SUCCESS) {
597
0
    gnutls_assert();
598
0
    result = _gnutls_asn2err(result);
599
0
    goto cleanup;
600
0
  }
601
602
0
  oid = gnutls_digest_get_oid(params->rsa_oaep_dig);
603
604
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid,
605
0
               1)) != ASN1_SUCCESS) {
606
0
    gnutls_assert();
607
0
    result = _gnutls_asn2err(result);
608
0
    goto cleanup;
609
0
  }
610
611
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL,
612
0
               0)) != ASN1_SUCCESS) {
613
0
    gnutls_assert();
614
0
    result = _gnutls_asn2err(result);
615
0
    goto cleanup;
616
0
  }
617
618
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.algorithm",
619
0
               PKIX1_RSA_PSS_MGF1_OID, 1)) !=
620
0
      ASN1_SUCCESS) {
621
0
    gnutls_assert();
622
0
    result = _gnutls_asn2err(result);
623
0
    goto cleanup;
624
0
  }
625
626
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
627
0
            "PKIX1.AlgorithmIdentifier", &c2)) !=
628
0
      ASN1_SUCCESS) {
629
0
    gnutls_assert();
630
0
    result = _gnutls_asn2err(result);
631
0
    goto cleanup;
632
0
  }
633
634
0
  if ((result = asn1_write_value(c2, "algorithm", oid, 1)) !=
635
0
      ASN1_SUCCESS) {
636
0
    gnutls_assert();
637
0
    result = _gnutls_asn2err(result);
638
0
    goto cleanup;
639
0
  }
640
641
0
  if ((result = asn1_write_value(c2, "parameters", NULL, 0)) !=
642
0
      ASN1_SUCCESS) {
643
0
    gnutls_assert();
644
0
    result = _gnutls_asn2err(result);
645
0
    goto cleanup;
646
0
  }
647
648
0
  result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
649
0
  if (result < 0) {
650
0
    gnutls_assert();
651
0
    goto cleanup;
652
0
  }
653
654
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.parameters",
655
0
               tmp.data, tmp.size)) != ASN1_SUCCESS) {
656
0
    gnutls_assert();
657
0
    result = _gnutls_asn2err(result);
658
0
    goto cleanup;
659
0
  }
660
661
0
  if ((result = asn1_write_value(spk, "pSourceFunc.algorithm",
662
0
               PKIX1_RSA_OAEP_P_SPECIFIED_OID, 1)) !=
663
0
      ASN1_SUCCESS) {
664
0
    gnutls_assert();
665
0
    result = _gnutls_asn2err(result);
666
0
    goto cleanup;
667
0
  }
668
669
0
  if (params->rsa_oaep_label.data) {
670
0
    result = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
671
0
                params->rsa_oaep_label.data,
672
0
                params->rsa_oaep_label.size,
673
0
                &label);
674
0
  } else {
675
0
    result = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING, "",
676
0
                0, &label);
677
0
  }
678
0
  if (result < 0) {
679
0
    gnutls_assert();
680
0
    goto cleanup;
681
0
  }
682
683
0
  result = asn1_write_value(spk, "pSourceFunc.parameters", label.data,
684
0
          label.size);
685
0
  if (result != ASN1_SUCCESS) {
686
0
    gnutls_assert();
687
0
    result = _gnutls_asn2err(result);
688
0
    goto cleanup;
689
0
  }
690
691
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
692
0
  if (result < 0) {
693
0
    gnutls_assert();
694
0
    goto cleanup;
695
0
  }
696
697
0
  result = 0;
698
699
0
cleanup:
700
0
  _gnutls_free_datum(&tmp);
701
0
  _gnutls_free_datum(&label);
702
0
  asn1_delete_structure(&c2);
703
0
  asn1_delete_structure(&spk);
704
0
  return result;
705
0
}
706
707
static int _gnutls_x509_write_gost_params(const gnutls_pk_params_st *params,
708
            gnutls_datum_t *der)
709
0
{
710
0
  int result;
711
0
  asn1_node spk = NULL;
712
0
  const char *oid;
713
714
0
  der->data = NULL;
715
0
  der->size = 0;
716
717
0
  oid = gnutls_ecc_curve_get_oid(params->curve);
718
0
  if (oid == NULL)
719
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
720
721
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
722
0
            params->algo == GNUTLS_PK_GOST_01 ?
723
0
              "GNUTLS.GOSTParametersOld" :
724
0
              "GNUTLS.GOSTParameters",
725
0
            &spk)) != ASN1_SUCCESS) {
726
0
    gnutls_assert();
727
0
    return _gnutls_asn2err(result);
728
0
  }
729
730
0
  if ((result = asn1_write_value(spk, "publicKeyParamSet", oid, 1)) !=
731
0
      ASN1_SUCCESS) {
732
0
    gnutls_assert();
733
0
    result = _gnutls_asn2err(result);
734
0
    goto cleanup;
735
0
  }
736
737
  /* For compatibility per R 1323565.1.023—2018 provide digest OID only
738
   * for GOST-2001 keys or GOST-2012 keys with CryptoPro curves. Do not
739
   * set this optional parameter for TC26 curves */
740
0
  if (params->algo == GNUTLS_PK_GOST_01)
741
0
    oid = HASH_OID_GOST_R_3411_94_CRYPTOPRO_PARAMS;
742
0
  else if (params->algo == GNUTLS_PK_GOST_12_256 &&
743
0
     (params->curve == GNUTLS_ECC_CURVE_GOST256CPA ||
744
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPB ||
745
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPC ||
746
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPXA ||
747
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPXB))
748
0
    oid = HASH_OID_STREEBOG_256;
749
0
  else if (params->algo == GNUTLS_PK_GOST_12_512 &&
750
0
     (params->curve == GNUTLS_ECC_CURVE_GOST512A ||
751
0
      params->curve == GNUTLS_ECC_CURVE_GOST512B))
752
0
    oid = HASH_OID_STREEBOG_512;
753
0
  else
754
0
    oid = NULL;
755
756
0
  if ((result = asn1_write_value(spk, "digestParamSet", oid,
757
0
               oid ? 1 : 0)) != ASN1_SUCCESS) {
758
0
    gnutls_assert();
759
0
    result = _gnutls_asn2err(result);
760
0
    goto cleanup;
761
0
  }
762
763
0
  oid = gnutls_gost_paramset_get_oid(params->gost_params);
764
0
  if (oid == NULL) {
765
0
    gnutls_assert();
766
0
    result = GNUTLS_E_INVALID_REQUEST;
767
0
    goto cleanup;
768
0
  }
769
770
0
  if (params->algo == GNUTLS_PK_GOST_01) {
771
0
    if (params->gost_params ==
772
0
        _gnutls_gost_paramset_default(params->algo))
773
0
      oid = NULL;
774
775
0
    if ((result = asn1_write_value(spk, "encryptionParamSet", oid,
776
0
                 oid ? 1 : 0)) != ASN1_SUCCESS) {
777
0
      gnutls_assert();
778
0
      result = _gnutls_asn2err(result);
779
0
      goto cleanup;
780
0
    }
781
0
  }
782
783
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
784
0
  if (result < 0) {
785
0
    gnutls_assert();
786
0
    goto cleanup;
787
0
  }
788
789
0
  result = 0;
790
791
0
cleanup:
792
0
  asn1_delete_structure(&spk);
793
0
  return result;
794
0
}
795
796
/*
797
 * This function writes the public parameters for DSS keys.
798
 * Needs 1 parameter (y).
799
 *
800
 * Allocates the space used to store the DER data.
801
 */
802
static int _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st *params,
803
           gnutls_datum_t *der)
804
0
{
805
0
  int result;
806
0
  asn1_node spk = NULL;
807
808
0
  der->data = NULL;
809
0
  der->size = 0;
810
811
0
  if (params->params_nr < DSA_PUBLIC_PARAMS) {
812
0
    gnutls_assert();
813
0
    result = GNUTLS_E_INVALID_REQUEST;
814
0
    goto cleanup;
815
0
  }
816
817
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
818
0
            "GNUTLS.DSAPublicKey", &spk)) !=
819
0
      ASN1_SUCCESS) {
820
0
    gnutls_assert();
821
0
    return _gnutls_asn2err(result);
822
0
  }
823
824
0
  result = _gnutls_x509_write_int(spk, "", params->params[3], 1);
825
0
  if (result < 0) {
826
0
    gnutls_assert();
827
0
    goto cleanup;
828
0
  }
829
830
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
831
0
  if (result < 0) {
832
0
    gnutls_assert();
833
0
    goto cleanup;
834
0
  }
835
836
0
  result = 0;
837
838
0
cleanup:
839
0
  asn1_delete_structure(&spk);
840
0
  return result;
841
0
}
842
843
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
844
 */
845
static int _gnutls_asn1_encode_rsa(asn1_node *c2, gnutls_pk_params_st *params)
846
0
{
847
0
  int result, ret;
848
0
  uint8_t null = '\0';
849
0
  gnutls_pk_params_st pk_params;
850
851
  /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
852
   * i.e., regenerate some parameters in case they were broken */
853
0
  gnutls_pk_params_init(&pk_params);
854
855
0
  ret = _gnutls_pk_params_copy(&pk_params, params);
856
0
  if (ret < 0) {
857
0
    gnutls_assert();
858
0
    return ret;
859
0
  }
860
861
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
862
0
  if (ret < 0) {
863
0
    gnutls_assert();
864
0
    goto cleanup;
865
0
  }
866
867
  /* Ok. Now we have the data. Create the asn1 structures
868
   */
869
870
  /* first make sure that no previously allocated data are leaked */
871
0
  if (*c2 != NULL) {
872
0
    asn1_delete_structure(c2);
873
0
    *c2 = NULL;
874
0
  }
875
876
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
877
0
            "GNUTLS.RSAPrivateKey", c2)) !=
878
0
      ASN1_SUCCESS) {
879
0
    gnutls_assert();
880
0
    ret = _gnutls_asn2err(result);
881
0
    goto cleanup;
882
0
  }
883
884
  /* Write PRIME
885
   */
886
0
  ret = _gnutls_x509_write_int(*c2, "modulus",
887
0
             params->params[RSA_MODULUS], 1);
888
0
  if (ret < 0) {
889
0
    gnutls_assert();
890
0
    goto cleanup;
891
0
  }
892
893
0
  ret = _gnutls_x509_write_int(*c2, "publicExponent",
894
0
             params->params[RSA_PUB], 1);
895
0
  if (ret < 0) {
896
0
    gnutls_assert();
897
0
    goto cleanup;
898
0
  }
899
900
0
  ret = _gnutls_x509_write_key_int(*c2, "privateExponent",
901
0
           params->params[RSA_PRIV], 1);
902
0
  if (ret < 0) {
903
0
    gnutls_assert();
904
0
    goto cleanup;
905
0
  }
906
907
0
  ret = _gnutls_x509_write_key_int(*c2, "prime1",
908
0
           params->params[RSA_PRIME1], 1);
909
0
  if (ret < 0) {
910
0
    gnutls_assert();
911
0
    goto cleanup;
912
0
  }
913
914
0
  ret = _gnutls_x509_write_key_int(*c2, "prime2",
915
0
           params->params[RSA_PRIME2], 1);
916
0
  if (ret < 0) {
917
0
    gnutls_assert();
918
0
    goto cleanup;
919
0
  }
920
921
0
  ret = _gnutls_x509_write_key_int(*c2, "coefficient",
922
0
           params->params[RSA_COEF], 1);
923
0
  if (ret < 0) {
924
0
    gnutls_assert();
925
0
    goto cleanup;
926
0
  }
927
928
0
  ret = _gnutls_x509_write_key_int(*c2, "exponent1",
929
0
           params->params[RSA_E1], 1);
930
0
  if (ret < 0) {
931
0
    gnutls_assert();
932
0
    goto cleanup;
933
0
  }
934
935
0
  ret = _gnutls_x509_write_key_int(*c2, "exponent2",
936
0
           params->params[RSA_E2], 1);
937
0
  if (ret < 0) {
938
0
    gnutls_assert();
939
0
    goto cleanup;
940
0
  }
941
942
0
  if ((result = asn1_write_value(*c2, "otherPrimeInfos", NULL, 0)) !=
943
0
      ASN1_SUCCESS) {
944
0
    gnutls_assert();
945
0
    ret = _gnutls_asn2err(result);
946
0
    goto cleanup;
947
0
  }
948
949
0
  if ((result = asn1_write_value(*c2, "version", &null, 1)) !=
950
0
      ASN1_SUCCESS) {
951
0
    gnutls_assert();
952
0
    ret = _gnutls_asn2err(result);
953
0
    goto cleanup;
954
0
  }
955
956
0
  ret = 0;
957
958
0
cleanup:
959
0
  if (ret < 0)
960
0
    asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
961
962
0
  gnutls_pk_params_clear(&pk_params);
963
0
  gnutls_pk_params_release(&pk_params);
964
0
  return ret;
965
0
}
966
967
/* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
968
 */
969
static int _gnutls_asn1_encode_ecc(asn1_node *c2, gnutls_pk_params_st *params)
970
0
{
971
0
  int ret;
972
0
  uint8_t one = '\x01';
973
0
  gnutls_datum_t pubkey = { NULL, 0 };
974
0
  const char *oid;
975
976
0
  oid = gnutls_ecc_curve_get_oid(params->curve);
977
0
  if (oid == NULL)
978
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
979
980
  /* first make sure that no previously allocated data are leaked */
981
0
  if (*c2 != NULL) {
982
0
    asn1_delete_structure(c2);
983
0
    *c2 = NULL;
984
0
  }
985
986
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
987
0
               "GNUTLS.ECPrivateKey", c2)) !=
988
0
      ASN1_SUCCESS) {
989
0
    gnutls_assert();
990
0
    ret = _gnutls_asn2err(ret);
991
0
    goto cleanup;
992
0
  }
993
994
0
  if ((ret = asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) {
995
0
    gnutls_assert();
996
0
    ret = _gnutls_asn2err(ret);
997
0
    goto cleanup;
998
0
  }
999
1000
0
  if (curve_is_eddsa(params->curve) ||
1001
0
      curve_is_modern_ecdh(params->curve)) {
1002
0
    if (params->raw_pub.size == 0 || params->raw_priv.size == 0)
1003
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1004
0
    ret = asn1_write_value(*c2, "privateKey", params->raw_priv.data,
1005
0
               params->raw_priv.size);
1006
0
    if (ret != ASN1_SUCCESS) {
1007
0
      gnutls_assert();
1008
0
      ret = _gnutls_asn2err(ret);
1009
0
      goto cleanup;
1010
0
    }
1011
1012
0
    ret = asn1_write_value(*c2, "publicKey", params->raw_pub.data,
1013
0
               params->raw_pub.size * 8);
1014
0
    if (ret != ASN1_SUCCESS) {
1015
0
      gnutls_assert();
1016
0
      ret = _gnutls_asn2err(ret);
1017
0
      goto cleanup;
1018
0
    }
1019
0
  } else {
1020
0
    if (params->params_nr != ECC_PRIVATE_PARAMS)
1021
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1022
1023
0
    ret = _gnutls_ecc_ansi_x962_export(params->curve,
1024
0
               params->params[ECC_X],
1025
0
               params->params[ECC_Y],
1026
0
               &pubkey);
1027
0
    if (ret < 0)
1028
0
      return gnutls_assert_val(ret);
1029
1030
0
    ret = _gnutls_x509_write_key_int(*c2, "privateKey",
1031
0
             params->params[ECC_K], 1);
1032
0
    if (ret < 0) {
1033
0
      gnutls_assert();
1034
0
      goto cleanup;
1035
0
    }
1036
1037
0
    if ((ret = asn1_write_value(*c2, "publicKey", pubkey.data,
1038
0
              pubkey.size * 8)) != ASN1_SUCCESS) {
1039
0
      gnutls_assert();
1040
0
      ret = _gnutls_asn2err(ret);
1041
0
      goto cleanup;
1042
0
    }
1043
0
  }
1044
1045
  /* write our choice */
1046
0
  if ((ret = asn1_write_value(*c2, "parameters", "namedCurve", 1)) !=
1047
0
      ASN1_SUCCESS) {
1048
0
    gnutls_assert();
1049
0
    ret = _gnutls_asn2err(ret);
1050
0
    goto cleanup;
1051
0
  }
1052
1053
0
  if ((ret = asn1_write_value(*c2, "parameters.namedCurve", oid, 1)) !=
1054
0
      ASN1_SUCCESS) {
1055
0
    gnutls_assert();
1056
0
    ret = _gnutls_asn2err(ret);
1057
0
    goto cleanup;
1058
0
  }
1059
1060
0
  _gnutls_free_datum(&pubkey);
1061
0
  return 0;
1062
1063
0
cleanup:
1064
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1065
0
  _gnutls_free_datum(&pubkey);
1066
1067
0
  return ret;
1068
0
}
1069
1070
static int _gnutls_asn1_encode_gost(asn1_node *c2, gnutls_pk_params_st *params)
1071
0
{
1072
0
  int ret;
1073
0
  const char *oid;
1074
1075
0
  oid = gnutls_pk_get_oid(params->algo);
1076
1077
0
  if (params->params_nr != GOST_PRIVATE_PARAMS || oid == NULL)
1078
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1079
1080
  /* first make sure that no previously allocated data are leaked */
1081
0
  if (*c2 != NULL) {
1082
0
    asn1_delete_structure(c2);
1083
0
    *c2 = NULL;
1084
0
  }
1085
1086
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
1087
0
               "GNUTLS.GOSTPrivateKey", c2)) !=
1088
0
      ASN1_SUCCESS) {
1089
0
    gnutls_assert();
1090
0
    ret = _gnutls_asn2err(ret);
1091
0
    goto cleanup;
1092
0
  }
1093
1094
0
  ret = _gnutls_x509_write_key_int_le(*c2, "", params->params[GOST_K]);
1095
0
  if (ret < 0) {
1096
0
    gnutls_assert();
1097
0
    goto cleanup;
1098
0
  }
1099
1100
0
  return 0;
1101
1102
0
cleanup:
1103
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1104
1105
0
  return ret;
1106
0
}
1107
1108
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
1109
 */
1110
static int _gnutls_asn1_encode_dsa(asn1_node *c2, gnutls_pk_params_st *params)
1111
0
{
1112
0
  int result, ret;
1113
0
  const uint8_t null = '\0';
1114
1115
  /* first make sure that no previously allocated data are leaked */
1116
0
  if (*c2 != NULL) {
1117
0
    asn1_delete_structure(c2);
1118
0
    *c2 = NULL;
1119
0
  }
1120
1121
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
1122
0
            "GNUTLS.DSAPrivateKey", c2)) !=
1123
0
      ASN1_SUCCESS) {
1124
0
    gnutls_assert();
1125
0
    return _gnutls_asn2err(result);
1126
0
  }
1127
1128
  /* Write PRIME
1129
   */
1130
0
  ret = _gnutls_x509_write_int(*c2, "p", params->params[DSA_P], 1);
1131
0
  if (ret < 0) {
1132
0
    gnutls_assert();
1133
0
    goto cleanup;
1134
0
  }
1135
1136
0
  ret = _gnutls_x509_write_int(*c2, "q", params->params[DSA_Q], 1);
1137
0
  if (ret < 0) {
1138
0
    gnutls_assert();
1139
0
    goto cleanup;
1140
0
  }
1141
1142
0
  ret = _gnutls_x509_write_int(*c2, "g", params->params[DSA_G], 1);
1143
0
  if (ret < 0) {
1144
0
    gnutls_assert();
1145
0
    goto cleanup;
1146
0
  }
1147
1148
0
  ret = _gnutls_x509_write_int(*c2, "Y", params->params[DSA_Y], 1);
1149
0
  if (ret < 0) {
1150
0
    gnutls_assert();
1151
0
    goto cleanup;
1152
0
  }
1153
1154
0
  ret = _gnutls_x509_write_key_int(*c2, "priv", params->params[DSA_X], 1);
1155
0
  if (ret < 0) {
1156
0
    gnutls_assert();
1157
0
    goto cleanup;
1158
0
  }
1159
1160
0
  if ((result = asn1_write_value(*c2, "version", &null, 1)) !=
1161
0
      ASN1_SUCCESS) {
1162
0
    gnutls_assert();
1163
0
    ret = _gnutls_asn2err(result);
1164
0
    goto cleanup;
1165
0
  }
1166
1167
0
  return 0;
1168
1169
0
cleanup:
1170
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1171
1172
0
  return ret;
1173
0
}
1174
1175
/* Encodes the ML-DSA parameters into an ASN.1 MLDSAPrivateKey structure.
1176
 */
1177
static int _gnutls_asn1_encode_ml_dsa(asn1_node *c2,
1178
              gnutls_pk_params_st *params)
1179
0
{
1180
0
  int result, ret;
1181
0
  const char *oid;
1182
0
  const uint8_t one = 1;
1183
1184
0
  if (unlikely(params->raw_pub.size == 0 || params->raw_priv.size == 0))
1185
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1186
1187
0
  oid = gnutls_pk_get_oid(params->algo);
1188
0
  if (oid == NULL)
1189
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1190
1191
  /* first make sure that no previously allocated data are leaked */
1192
0
  if (*c2 != NULL) {
1193
0
    asn1_delete_structure(c2);
1194
0
    *c2 = NULL;
1195
0
  }
1196
1197
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
1198
0
            "GNUTLS.MLDSAPrivateKey", c2)) !=
1199
0
      ASN1_SUCCESS) {
1200
0
    gnutls_assert();
1201
0
    ret = _gnutls_asn2err(result);
1202
0
    goto cleanup;
1203
0
  }
1204
1205
  /* signify publicKey is embedded in a separate field */
1206
0
  if ((result = asn1_write_value(*c2, "version", &one, 1)) !=
1207
0
      ASN1_SUCCESS) {
1208
0
    gnutls_assert();
1209
0
    ret = _gnutls_asn2err(result);
1210
0
    goto cleanup;
1211
0
  }
1212
1213
0
  if ((result = asn1_write_value(*c2, "privateKeyAlgorithm.algorithm",
1214
0
               oid, 1)) != ASN1_SUCCESS) {
1215
0
    gnutls_assert();
1216
0
    ret = _gnutls_asn2err(result);
1217
0
    goto cleanup;
1218
0
  }
1219
1220
0
  if ((result = asn1_write_value(*c2, "privateKeyAlgorithm.parameters",
1221
0
               NULL, 0)) != ASN1_SUCCESS) {
1222
0
    gnutls_assert();
1223
0
    ret = _gnutls_asn2err(result);
1224
0
    goto cleanup;
1225
0
  }
1226
1227
0
  result = asn1_write_value(*c2, "privateKey", params->raw_priv.data,
1228
0
          params->raw_priv.size);
1229
0
  if (result != ASN1_SUCCESS) {
1230
0
    gnutls_assert();
1231
0
    ret = _gnutls_asn2err(result);
1232
0
    goto cleanup;
1233
0
  }
1234
1235
0
  result = asn1_write_value(*c2, "publicKey", params->raw_pub.data,
1236
0
          params->raw_pub.size);
1237
0
  if (result != ASN1_SUCCESS) {
1238
0
    gnutls_assert();
1239
0
    ret = _gnutls_asn2err(result);
1240
0
    goto cleanup;
1241
0
  }
1242
1243
0
  ret = GNUTLS_E_SUCCESS;
1244
1245
0
cleanup:
1246
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1247
1248
0
  return ret;
1249
0
}
1250
1251
int _gnutls_asn1_encode_privkey(asn1_node *c2, gnutls_pk_params_st *params)
1252
0
{
1253
0
  switch (params->algo) {
1254
0
  case GNUTLS_PK_RSA:
1255
0
  case GNUTLS_PK_RSA_PSS:
1256
0
  case GNUTLS_PK_RSA_OAEP:
1257
0
    return _gnutls_asn1_encode_rsa(c2, params);
1258
0
  case GNUTLS_PK_DSA:
1259
0
    return _gnutls_asn1_encode_dsa(c2, params);
1260
0
  case GNUTLS_PK_ECDSA:
1261
0
  case GNUTLS_PK_EDDSA_ED25519:
1262
0
  case GNUTLS_PK_EDDSA_ED448:
1263
0
  case GNUTLS_PK_ECDH_X25519:
1264
0
  case GNUTLS_PK_ECDH_X448:
1265
0
    return _gnutls_asn1_encode_ecc(c2, params);
1266
0
  case GNUTLS_PK_GOST_01:
1267
0
  case GNUTLS_PK_GOST_12_256:
1268
0
  case GNUTLS_PK_GOST_12_512:
1269
0
    return _gnutls_asn1_encode_gost(c2, params);
1270
0
  case GNUTLS_PK_DH:
1271
    /* DH keys are only exportable in PKCS#8 format */
1272
0
    return GNUTLS_E_INVALID_REQUEST;
1273
0
  case GNUTLS_PK_MLDSA44:
1274
0
  case GNUTLS_PK_MLDSA65:
1275
0
  case GNUTLS_PK_MLDSA87:
1276
0
    return _gnutls_asn1_encode_ml_dsa(c2, params);
1277
0
  default:
1278
0
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1279
0
  }
1280
0
}