Coverage Report

Created: 2024-07-23 07:36

/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
int _gnutls_x509_write_pubkey_params(const gnutls_pk_params_st *params,
261
             gnutls_datum_t *der)
262
0
{
263
0
  switch (params->algo) {
264
0
  case GNUTLS_PK_DSA:
265
0
    return _gnutls_x509_write_dsa_params(params, der);
266
0
  case GNUTLS_PK_RSA:
267
0
    der->data = gnutls_malloc(ASN1_NULL_SIZE);
268
0
    if (der->data == NULL)
269
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
270
271
0
    memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE);
272
0
    der->size = ASN1_NULL_SIZE;
273
0
    return 0;
274
0
  case GNUTLS_PK_RSA_PSS:
275
0
    return _gnutls_x509_write_rsa_pss_params(&params->spki, der);
276
0
  case GNUTLS_PK_RSA_OAEP:
277
0
    return _gnutls_x509_write_rsa_oaep_params(&params->spki, der);
278
0
  case GNUTLS_PK_ECDSA:
279
0
    return _gnutls_x509_write_ecc_params(params->curve, der);
280
0
  case GNUTLS_PK_EDDSA_ED25519:
281
0
  case GNUTLS_PK_EDDSA_ED448:
282
0
  case GNUTLS_PK_ECDH_X25519:
283
0
  case GNUTLS_PK_ECDH_X448:
284
0
    der->data = NULL;
285
0
    der->size = 0;
286
287
0
    return 0;
288
0
  case GNUTLS_PK_GOST_01:
289
0
  case GNUTLS_PK_GOST_12_256:
290
0
  case GNUTLS_PK_GOST_12_512:
291
0
    return _gnutls_x509_write_gost_params(params, der);
292
0
  default:
293
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
294
0
  }
295
0
}
296
297
int _gnutls_x509_write_pubkey(const gnutls_pk_params_st *params,
298
            gnutls_datum_t *der)
299
0
{
300
0
  switch (params->algo) {
301
0
  case GNUTLS_PK_DSA:
302
0
    return _gnutls_x509_write_dsa_pubkey(params, der);
303
0
  case GNUTLS_PK_RSA:
304
0
  case GNUTLS_PK_RSA_PSS:
305
0
  case GNUTLS_PK_RSA_OAEP:
306
0
    return _gnutls_x509_write_rsa_pubkey(params, der);
307
0
  case GNUTLS_PK_ECDSA:
308
0
    return _gnutls_x509_write_ecc_pubkey(params, der);
309
0
  case GNUTLS_PK_EDDSA_ED25519:
310
0
  case GNUTLS_PK_EDDSA_ED448:
311
0
    return _gnutls_x509_write_eddsa_pubkey(params, der);
312
0
  case GNUTLS_PK_ECDH_X25519:
313
0
  case GNUTLS_PK_ECDH_X448:
314
0
    return _gnutls_x509_write_modern_ecdh_pubkey(params, der);
315
0
  case GNUTLS_PK_GOST_01:
316
0
  case GNUTLS_PK_GOST_12_256:
317
0
  case GNUTLS_PK_GOST_12_512:
318
0
    return _gnutls_x509_write_gost_pubkey(params, der);
319
0
  default:
320
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
321
0
  }
322
0
}
323
324
/*
325
 * This function writes the parameters for DSS keys.
326
 * Needs 3 parameters (p,q,g).
327
 *
328
 * Allocates the space used to store the DER data.
329
 */
330
static int _gnutls_x509_write_dsa_params(const gnutls_pk_params_st *params,
331
           gnutls_datum_t *der)
332
0
{
333
0
  int result;
334
0
  asn1_node spk = NULL;
335
336
0
  der->data = NULL;
337
0
  der->size = 0;
338
339
0
  if (params->params_nr < DSA_PUBLIC_PARAMS - 1) {
340
0
    gnutls_assert();
341
0
    result = GNUTLS_E_INVALID_REQUEST;
342
0
    goto cleanup;
343
0
  }
344
345
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
346
0
            "GNUTLS.DSAParameters", &spk)) !=
347
0
      ASN1_SUCCESS) {
348
0
    gnutls_assert();
349
0
    return _gnutls_asn2err(result);
350
0
  }
351
352
0
  result = _gnutls_x509_write_int(spk, "p", params->params[0], 1);
353
0
  if (result < 0) {
354
0
    gnutls_assert();
355
0
    goto cleanup;
356
0
  }
357
358
0
  result = _gnutls_x509_write_int(spk, "q", params->params[1], 1);
359
0
  if (result < 0) {
360
0
    gnutls_assert();
361
0
    goto cleanup;
362
0
  }
363
364
0
  result = _gnutls_x509_write_int(spk, "g", params->params[2], 1);
365
0
  if (result < 0) {
366
0
    gnutls_assert();
367
0
    goto cleanup;
368
0
  }
369
370
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
371
0
  if (result < 0) {
372
0
    gnutls_assert();
373
0
    goto cleanup;
374
0
  }
375
376
0
  result = 0;
377
378
0
cleanup:
379
0
  asn1_delete_structure(&spk);
380
0
  return result;
381
0
}
382
383
/*
384
 * This function writes the parameters for ECC keys.
385
 * That is the ECParameters struct.
386
 *
387
 * Allocates the space used to store the DER data.
388
 */
389
int _gnutls_x509_write_ecc_params(const gnutls_ecc_curve_t curve,
390
          gnutls_datum_t *der)
391
0
{
392
0
  int result;
393
0
  asn1_node spk = NULL;
394
0
  const char *oid;
395
396
0
  der->data = NULL;
397
0
  der->size = 0;
398
399
0
  oid = gnutls_ecc_curve_get_oid(curve);
400
0
  if (oid == NULL)
401
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
402
403
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
404
0
            "GNUTLS.ECParameters", &spk)) !=
405
0
      ASN1_SUCCESS) {
406
0
    gnutls_assert();
407
0
    return _gnutls_asn2err(result);
408
0
  }
409
410
0
  if ((result = asn1_write_value(spk, "", "namedCurve", 1)) !=
411
0
      ASN1_SUCCESS) {
412
0
    gnutls_assert();
413
0
    result = _gnutls_asn2err(result);
414
0
    goto cleanup;
415
0
  }
416
417
0
  if ((result = asn1_write_value(spk, "namedCurve", oid, 1)) !=
418
0
      ASN1_SUCCESS) {
419
0
    gnutls_assert();
420
0
    result = _gnutls_asn2err(result);
421
0
    goto cleanup;
422
0
  }
423
424
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
425
0
  if (result < 0) {
426
0
    gnutls_assert();
427
0
    goto cleanup;
428
0
  }
429
430
0
  result = 0;
431
432
0
cleanup:
433
0
  asn1_delete_structure(&spk);
434
0
  return result;
435
0
}
436
437
int _gnutls_x509_write_rsa_pss_params(const gnutls_x509_spki_st *params,
438
              gnutls_datum_t *der)
439
0
{
440
0
  int result;
441
0
  asn1_node spk = NULL;
442
0
  asn1_node c2 = NULL;
443
0
  const char *oid;
444
0
  gnutls_datum_t tmp = { NULL, 0 };
445
446
0
  der->data = NULL;
447
0
  der->size = 0;
448
449
0
  if (params->pk != GNUTLS_PK_RSA_PSS)
450
0
    return 0;
451
452
  /* refuse to write parameters we cannot read */
453
0
  if (gnutls_pk_to_sign(GNUTLS_PK_RSA_PSS, params->rsa_pss_dig) ==
454
0
      GNUTLS_SIGN_UNKNOWN)
455
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
456
457
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
458
0
            "GNUTLS.RSAPSSParameters", &spk)) !=
459
0
      ASN1_SUCCESS) {
460
0
    gnutls_assert();
461
0
    result = _gnutls_asn2err(result);
462
0
    goto cleanup;
463
0
  }
464
465
0
  oid = gnutls_digest_get_oid(params->rsa_pss_dig);
466
467
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid,
468
0
               1)) != ASN1_SUCCESS) {
469
0
    gnutls_assert();
470
0
    result = _gnutls_asn2err(result);
471
0
    goto cleanup;
472
0
  }
473
474
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL,
475
0
               0)) != ASN1_SUCCESS) {
476
0
    gnutls_assert();
477
0
    result = _gnutls_asn2err(result);
478
0
    goto cleanup;
479
0
  }
480
481
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.algorithm",
482
0
               PKIX1_RSA_PSS_MGF1_OID, 1)) !=
483
0
      ASN1_SUCCESS) {
484
0
    gnutls_assert();
485
0
    result = _gnutls_asn2err(result);
486
0
    goto cleanup;
487
0
  }
488
489
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
490
0
            "PKIX1.AlgorithmIdentifier", &c2)) !=
491
0
      ASN1_SUCCESS) {
492
0
    gnutls_assert();
493
0
    result = _gnutls_asn2err(result);
494
0
    goto cleanup;
495
0
  }
496
497
0
  if ((result = asn1_write_value(c2, "algorithm", oid, 1)) !=
498
0
      ASN1_SUCCESS) {
499
0
    gnutls_assert();
500
0
    result = _gnutls_asn2err(result);
501
0
    goto cleanup;
502
0
  }
503
504
0
  if ((result = asn1_write_value(c2, "parameters", NULL, 0)) !=
505
0
      ASN1_SUCCESS) {
506
0
    gnutls_assert();
507
0
    result = _gnutls_asn2err(result);
508
0
    goto cleanup;
509
0
  }
510
511
0
  result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
512
0
  if (result < 0) {
513
0
    gnutls_assert();
514
0
    goto cleanup;
515
0
  }
516
517
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.parameters",
518
0
               tmp.data, tmp.size)) != ASN1_SUCCESS) {
519
0
    gnutls_assert();
520
0
    result = _gnutls_asn2err(result);
521
0
    goto cleanup;
522
0
  }
523
524
0
  result =
525
0
    _gnutls_x509_write_uint32(spk, "saltLength", params->salt_size);
526
0
  if (result < 0) {
527
0
    gnutls_assert();
528
0
    goto cleanup;
529
0
  }
530
531
0
  result = _gnutls_x509_write_uint32(spk, "trailerField", 1);
532
0
  if (result < 0) {
533
0
    gnutls_assert();
534
0
    goto cleanup;
535
0
  }
536
537
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
538
0
  if (result < 0) {
539
0
    gnutls_assert();
540
0
    goto cleanup;
541
0
  }
542
543
0
  result = 0;
544
545
0
cleanup:
546
0
  _gnutls_free_datum(&tmp);
547
0
  asn1_delete_structure(&c2);
548
0
  asn1_delete_structure(&spk);
549
0
  return result;
550
0
}
551
552
int _gnutls_x509_write_rsa_oaep_params(const gnutls_x509_spki_st *params,
553
               gnutls_datum_t *der)
554
0
{
555
0
  int result;
556
0
  asn1_node spk = NULL;
557
0
  asn1_node c2 = NULL;
558
0
  const char *oid;
559
0
  gnutls_datum_t tmp = { NULL, 0 };
560
0
  gnutls_datum_t label = { NULL, 0 };
561
562
0
  der->data = NULL;
563
0
  der->size = 0;
564
565
0
  if (params->pk != GNUTLS_PK_RSA_OAEP)
566
0
    return 0;
567
568
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
569
0
            "GNUTLS.RSAOAEPParameters", &spk)) !=
570
0
      ASN1_SUCCESS) {
571
0
    gnutls_assert();
572
0
    result = _gnutls_asn2err(result);
573
0
    goto cleanup;
574
0
  }
575
576
0
  oid = gnutls_digest_get_oid(params->rsa_oaep_dig);
577
578
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid,
579
0
               1)) != ASN1_SUCCESS) {
580
0
    gnutls_assert();
581
0
    result = _gnutls_asn2err(result);
582
0
    goto cleanup;
583
0
  }
584
585
0
  if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL,
586
0
               0)) != ASN1_SUCCESS) {
587
0
    gnutls_assert();
588
0
    result = _gnutls_asn2err(result);
589
0
    goto cleanup;
590
0
  }
591
592
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.algorithm",
593
0
               PKIX1_RSA_PSS_MGF1_OID, 1)) !=
594
0
      ASN1_SUCCESS) {
595
0
    gnutls_assert();
596
0
    result = _gnutls_asn2err(result);
597
0
    goto cleanup;
598
0
  }
599
600
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
601
0
            "PKIX1.AlgorithmIdentifier", &c2)) !=
602
0
      ASN1_SUCCESS) {
603
0
    gnutls_assert();
604
0
    result = _gnutls_asn2err(result);
605
0
    goto cleanup;
606
0
  }
607
608
0
  if ((result = asn1_write_value(c2, "algorithm", oid, 1)) !=
609
0
      ASN1_SUCCESS) {
610
0
    gnutls_assert();
611
0
    result = _gnutls_asn2err(result);
612
0
    goto cleanup;
613
0
  }
614
615
0
  if ((result = asn1_write_value(c2, "parameters", NULL, 0)) !=
616
0
      ASN1_SUCCESS) {
617
0
    gnutls_assert();
618
0
    result = _gnutls_asn2err(result);
619
0
    goto cleanup;
620
0
  }
621
622
0
  result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
623
0
  if (result < 0) {
624
0
    gnutls_assert();
625
0
    goto cleanup;
626
0
  }
627
628
0
  if ((result = asn1_write_value(spk, "maskGenAlgorithm.parameters",
629
0
               tmp.data, tmp.size)) != ASN1_SUCCESS) {
630
0
    gnutls_assert();
631
0
    result = _gnutls_asn2err(result);
632
0
    goto cleanup;
633
0
  }
634
635
0
  if ((result = asn1_write_value(spk, "pSourceFunc.algorithm",
636
0
               PKIX1_RSA_OAEP_P_SPECIFIED_OID, 1)) !=
637
0
      ASN1_SUCCESS) {
638
0
    gnutls_assert();
639
0
    result = _gnutls_asn2err(result);
640
0
    goto cleanup;
641
0
  }
642
643
0
  if (params->rsa_oaep_label.data) {
644
0
    result = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
645
0
                params->rsa_oaep_label.data,
646
0
                params->rsa_oaep_label.size,
647
0
                &label);
648
0
  } else {
649
0
    result = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING, "",
650
0
                0, &label);
651
0
  }
652
0
  if (result < 0) {
653
0
    gnutls_assert();
654
0
    goto cleanup;
655
0
  }
656
657
0
  result = asn1_write_value(spk, "pSourceFunc.parameters", label.data,
658
0
          label.size);
659
0
  if (result != ASN1_SUCCESS) {
660
0
    gnutls_assert();
661
0
    result = _gnutls_asn2err(result);
662
0
    goto cleanup;
663
0
  }
664
665
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
666
0
  if (result < 0) {
667
0
    gnutls_assert();
668
0
    goto cleanup;
669
0
  }
670
671
0
  result = 0;
672
673
0
cleanup:
674
0
  _gnutls_free_datum(&tmp);
675
0
  _gnutls_free_datum(&label);
676
0
  asn1_delete_structure(&c2);
677
0
  asn1_delete_structure(&spk);
678
0
  return result;
679
0
}
680
681
static int _gnutls_x509_write_gost_params(const gnutls_pk_params_st *params,
682
            gnutls_datum_t *der)
683
0
{
684
0
  int result;
685
0
  asn1_node spk = NULL;
686
0
  const char *oid;
687
688
0
  der->data = NULL;
689
0
  der->size = 0;
690
691
0
  oid = gnutls_ecc_curve_get_oid(params->curve);
692
0
  if (oid == NULL)
693
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
694
695
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
696
0
            params->algo == GNUTLS_PK_GOST_01 ?
697
0
              "GNUTLS.GOSTParametersOld" :
698
0
              "GNUTLS.GOSTParameters",
699
0
            &spk)) != ASN1_SUCCESS) {
700
0
    gnutls_assert();
701
0
    return _gnutls_asn2err(result);
702
0
  }
703
704
0
  if ((result = asn1_write_value(spk, "publicKeyParamSet", oid, 1)) !=
705
0
      ASN1_SUCCESS) {
706
0
    gnutls_assert();
707
0
    result = _gnutls_asn2err(result);
708
0
    goto cleanup;
709
0
  }
710
711
  /* For compatibility per R 1323565.1.023—2018 provide digest OID only
712
   * for GOST-2001 keys or GOST-2012 keys with CryptoPro curves. Do not
713
   * set this optional parameter for TC26 curves */
714
0
  if (params->algo == GNUTLS_PK_GOST_01)
715
0
    oid = HASH_OID_GOST_R_3411_94_CRYPTOPRO_PARAMS;
716
0
  else if (params->algo == GNUTLS_PK_GOST_12_256 &&
717
0
     (params->curve == GNUTLS_ECC_CURVE_GOST256CPA ||
718
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPB ||
719
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPC ||
720
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPXA ||
721
0
      params->curve == GNUTLS_ECC_CURVE_GOST256CPXB))
722
0
    oid = HASH_OID_STREEBOG_256;
723
0
  else if (params->algo == GNUTLS_PK_GOST_12_512 &&
724
0
     (params->curve == GNUTLS_ECC_CURVE_GOST512A ||
725
0
      params->curve == GNUTLS_ECC_CURVE_GOST512B))
726
0
    oid = HASH_OID_STREEBOG_512;
727
0
  else
728
0
    oid = NULL;
729
730
0
  if ((result = asn1_write_value(spk, "digestParamSet", oid,
731
0
               oid ? 1 : 0)) != ASN1_SUCCESS) {
732
0
    gnutls_assert();
733
0
    result = _gnutls_asn2err(result);
734
0
    goto cleanup;
735
0
  }
736
737
0
  oid = gnutls_gost_paramset_get_oid(params->gost_params);
738
0
  if (oid == NULL) {
739
0
    gnutls_assert();
740
0
    result = GNUTLS_E_INVALID_REQUEST;
741
0
    goto cleanup;
742
0
  }
743
744
0
  if (params->algo == GNUTLS_PK_GOST_01) {
745
0
    if (params->gost_params ==
746
0
        _gnutls_gost_paramset_default(params->algo))
747
0
      oid = NULL;
748
749
0
    if ((result = asn1_write_value(spk, "encryptionParamSet", oid,
750
0
                 oid ? 1 : 0)) != ASN1_SUCCESS) {
751
0
      gnutls_assert();
752
0
      result = _gnutls_asn2err(result);
753
0
      goto cleanup;
754
0
    }
755
0
  }
756
757
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
758
0
  if (result < 0) {
759
0
    gnutls_assert();
760
0
    goto cleanup;
761
0
  }
762
763
0
  result = 0;
764
765
0
cleanup:
766
0
  asn1_delete_structure(&spk);
767
0
  return result;
768
0
}
769
770
/*
771
 * This function writes the public parameters for DSS keys.
772
 * Needs 1 parameter (y).
773
 *
774
 * Allocates the space used to store the DER data.
775
 */
776
static int _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st *params,
777
           gnutls_datum_t *der)
778
0
{
779
0
  int result;
780
0
  asn1_node spk = NULL;
781
782
0
  der->data = NULL;
783
0
  der->size = 0;
784
785
0
  if (params->params_nr < DSA_PUBLIC_PARAMS) {
786
0
    gnutls_assert();
787
0
    result = GNUTLS_E_INVALID_REQUEST;
788
0
    goto cleanup;
789
0
  }
790
791
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
792
0
            "GNUTLS.DSAPublicKey", &spk)) !=
793
0
      ASN1_SUCCESS) {
794
0
    gnutls_assert();
795
0
    return _gnutls_asn2err(result);
796
0
  }
797
798
0
  result = _gnutls_x509_write_int(spk, "", params->params[3], 1);
799
0
  if (result < 0) {
800
0
    gnutls_assert();
801
0
    goto cleanup;
802
0
  }
803
804
0
  result = _gnutls_x509_der_encode(spk, "", der, 0);
805
0
  if (result < 0) {
806
0
    gnutls_assert();
807
0
    goto cleanup;
808
0
  }
809
810
0
  result = 0;
811
812
0
cleanup:
813
0
  asn1_delete_structure(&spk);
814
0
  return result;
815
0
}
816
817
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
818
 */
819
static int _gnutls_asn1_encode_rsa(asn1_node *c2, gnutls_pk_params_st *params)
820
0
{
821
0
  int result, ret;
822
0
  uint8_t null = '\0';
823
0
  gnutls_pk_params_st pk_params;
824
825
  /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
826
   * i.e., regenerate some parameters in case they were broken */
827
0
  gnutls_pk_params_init(&pk_params);
828
829
0
  ret = _gnutls_pk_params_copy(&pk_params, params);
830
0
  if (ret < 0) {
831
0
    gnutls_assert();
832
0
    return ret;
833
0
  }
834
835
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
836
0
  if (ret < 0) {
837
0
    gnutls_assert();
838
0
    goto cleanup;
839
0
  }
840
841
  /* Ok. Now we have the data. Create the asn1 structures
842
   */
843
844
  /* first make sure that no previously allocated data are leaked */
845
0
  if (*c2 != NULL) {
846
0
    asn1_delete_structure(c2);
847
0
    *c2 = NULL;
848
0
  }
849
850
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
851
0
            "GNUTLS.RSAPrivateKey", c2)) !=
852
0
      ASN1_SUCCESS) {
853
0
    gnutls_assert();
854
0
    ret = _gnutls_asn2err(result);
855
0
    goto cleanup;
856
0
  }
857
858
  /* Write PRIME
859
   */
860
0
  ret = _gnutls_x509_write_int(*c2, "modulus",
861
0
             params->params[RSA_MODULUS], 1);
862
0
  if (ret < 0) {
863
0
    gnutls_assert();
864
0
    goto cleanup;
865
0
  }
866
867
0
  ret = _gnutls_x509_write_int(*c2, "publicExponent",
868
0
             params->params[RSA_PUB], 1);
869
0
  if (ret < 0) {
870
0
    gnutls_assert();
871
0
    goto cleanup;
872
0
  }
873
874
0
  ret = _gnutls_x509_write_key_int(*c2, "privateExponent",
875
0
           params->params[RSA_PRIV], 1);
876
0
  if (ret < 0) {
877
0
    gnutls_assert();
878
0
    goto cleanup;
879
0
  }
880
881
0
  ret = _gnutls_x509_write_key_int(*c2, "prime1",
882
0
           params->params[RSA_PRIME1], 1);
883
0
  if (ret < 0) {
884
0
    gnutls_assert();
885
0
    goto cleanup;
886
0
  }
887
888
0
  ret = _gnutls_x509_write_key_int(*c2, "prime2",
889
0
           params->params[RSA_PRIME2], 1);
890
0
  if (ret < 0) {
891
0
    gnutls_assert();
892
0
    goto cleanup;
893
0
  }
894
895
0
  ret = _gnutls_x509_write_key_int(*c2, "coefficient",
896
0
           params->params[RSA_COEF], 1);
897
0
  if (ret < 0) {
898
0
    gnutls_assert();
899
0
    goto cleanup;
900
0
  }
901
902
0
  ret = _gnutls_x509_write_key_int(*c2, "exponent1",
903
0
           params->params[RSA_E1], 1);
904
0
  if (ret < 0) {
905
0
    gnutls_assert();
906
0
    goto cleanup;
907
0
  }
908
909
0
  ret = _gnutls_x509_write_key_int(*c2, "exponent2",
910
0
           params->params[RSA_E2], 1);
911
0
  if (ret < 0) {
912
0
    gnutls_assert();
913
0
    goto cleanup;
914
0
  }
915
916
0
  if ((result = asn1_write_value(*c2, "otherPrimeInfos", NULL, 0)) !=
917
0
      ASN1_SUCCESS) {
918
0
    gnutls_assert();
919
0
    ret = _gnutls_asn2err(result);
920
0
    goto cleanup;
921
0
  }
922
923
0
  if ((result = asn1_write_value(*c2, "version", &null, 1)) !=
924
0
      ASN1_SUCCESS) {
925
0
    gnutls_assert();
926
0
    ret = _gnutls_asn2err(result);
927
0
    goto cleanup;
928
0
  }
929
930
0
  ret = 0;
931
932
0
cleanup:
933
0
  if (ret < 0)
934
0
    asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
935
936
0
  gnutls_pk_params_clear(&pk_params);
937
0
  gnutls_pk_params_release(&pk_params);
938
0
  return ret;
939
0
}
940
941
/* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
942
 */
943
static int _gnutls_asn1_encode_ecc(asn1_node *c2, gnutls_pk_params_st *params)
944
0
{
945
0
  int ret;
946
0
  uint8_t one = '\x01';
947
0
  gnutls_datum_t pubkey = { NULL, 0 };
948
0
  const char *oid;
949
950
0
  oid = gnutls_ecc_curve_get_oid(params->curve);
951
0
  if (oid == NULL)
952
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
953
954
  /* first make sure that no previously allocated data are leaked */
955
0
  if (*c2 != NULL) {
956
0
    asn1_delete_structure(c2);
957
0
    *c2 = NULL;
958
0
  }
959
960
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
961
0
               "GNUTLS.ECPrivateKey", c2)) !=
962
0
      ASN1_SUCCESS) {
963
0
    gnutls_assert();
964
0
    ret = _gnutls_asn2err(ret);
965
0
    goto cleanup;
966
0
  }
967
968
0
  if ((ret = asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) {
969
0
    gnutls_assert();
970
0
    ret = _gnutls_asn2err(ret);
971
0
    goto cleanup;
972
0
  }
973
974
0
  if (curve_is_eddsa(params->curve) ||
975
0
      curve_is_modern_ecdh(params->curve)) {
976
0
    if (params->raw_pub.size == 0 || params->raw_priv.size == 0)
977
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
978
0
    ret = asn1_write_value(*c2, "privateKey", params->raw_priv.data,
979
0
               params->raw_priv.size);
980
0
    if (ret != ASN1_SUCCESS) {
981
0
      gnutls_assert();
982
0
      ret = _gnutls_asn2err(ret);
983
0
      goto cleanup;
984
0
    }
985
986
0
    ret = asn1_write_value(*c2, "publicKey", params->raw_pub.data,
987
0
               params->raw_pub.size * 8);
988
0
    if (ret != ASN1_SUCCESS) {
989
0
      gnutls_assert();
990
0
      ret = _gnutls_asn2err(ret);
991
0
      goto cleanup;
992
0
    }
993
0
  } else {
994
0
    if (params->params_nr != ECC_PRIVATE_PARAMS)
995
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
996
997
0
    ret = _gnutls_ecc_ansi_x962_export(params->curve,
998
0
               params->params[ECC_X],
999
0
               params->params[ECC_Y],
1000
0
               &pubkey);
1001
0
    if (ret < 0)
1002
0
      return gnutls_assert_val(ret);
1003
1004
0
    ret = _gnutls_x509_write_key_int(*c2, "privateKey",
1005
0
             params->params[ECC_K], 1);
1006
0
    if (ret < 0) {
1007
0
      gnutls_assert();
1008
0
      goto cleanup;
1009
0
    }
1010
1011
0
    if ((ret = asn1_write_value(*c2, "publicKey", pubkey.data,
1012
0
              pubkey.size * 8)) != ASN1_SUCCESS) {
1013
0
      gnutls_assert();
1014
0
      ret = _gnutls_asn2err(ret);
1015
0
      goto cleanup;
1016
0
    }
1017
0
  }
1018
1019
  /* write our choice */
1020
0
  if ((ret = asn1_write_value(*c2, "parameters", "namedCurve", 1)) !=
1021
0
      ASN1_SUCCESS) {
1022
0
    gnutls_assert();
1023
0
    ret = _gnutls_asn2err(ret);
1024
0
    goto cleanup;
1025
0
  }
1026
1027
0
  if ((ret = asn1_write_value(*c2, "parameters.namedCurve", oid, 1)) !=
1028
0
      ASN1_SUCCESS) {
1029
0
    gnutls_assert();
1030
0
    ret = _gnutls_asn2err(ret);
1031
0
    goto cleanup;
1032
0
  }
1033
1034
0
  _gnutls_free_datum(&pubkey);
1035
0
  return 0;
1036
1037
0
cleanup:
1038
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1039
0
  _gnutls_free_datum(&pubkey);
1040
1041
0
  return ret;
1042
0
}
1043
1044
static int _gnutls_asn1_encode_gost(asn1_node *c2, gnutls_pk_params_st *params)
1045
0
{
1046
0
  int ret;
1047
0
  const char *oid;
1048
1049
0
  oid = gnutls_pk_get_oid(params->algo);
1050
1051
0
  if (params->params_nr != GOST_PRIVATE_PARAMS || oid == NULL)
1052
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1053
1054
  /* first make sure that no previously allocated data are leaked */
1055
0
  if (*c2 != NULL) {
1056
0
    asn1_delete_structure(c2);
1057
0
    *c2 = NULL;
1058
0
  }
1059
1060
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
1061
0
               "GNUTLS.GOSTPrivateKey", c2)) !=
1062
0
      ASN1_SUCCESS) {
1063
0
    gnutls_assert();
1064
0
    ret = _gnutls_asn2err(ret);
1065
0
    goto cleanup;
1066
0
  }
1067
1068
0
  ret = _gnutls_x509_write_key_int_le(*c2, "", params->params[GOST_K]);
1069
0
  if (ret < 0) {
1070
0
    gnutls_assert();
1071
0
    goto cleanup;
1072
0
  }
1073
1074
0
  return 0;
1075
1076
0
cleanup:
1077
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1078
1079
0
  return ret;
1080
0
}
1081
1082
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
1083
 */
1084
static int _gnutls_asn1_encode_dsa(asn1_node *c2, gnutls_pk_params_st *params)
1085
0
{
1086
0
  int result, ret;
1087
0
  const uint8_t null = '\0';
1088
1089
  /* first make sure that no previously allocated data are leaked */
1090
0
  if (*c2 != NULL) {
1091
0
    asn1_delete_structure(c2);
1092
0
    *c2 = NULL;
1093
0
  }
1094
1095
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
1096
0
            "GNUTLS.DSAPrivateKey", c2)) !=
1097
0
      ASN1_SUCCESS) {
1098
0
    gnutls_assert();
1099
0
    return _gnutls_asn2err(result);
1100
0
  }
1101
1102
  /* Write PRIME
1103
   */
1104
0
  ret = _gnutls_x509_write_int(*c2, "p", params->params[DSA_P], 1);
1105
0
  if (ret < 0) {
1106
0
    gnutls_assert();
1107
0
    goto cleanup;
1108
0
  }
1109
1110
0
  ret = _gnutls_x509_write_int(*c2, "q", params->params[DSA_Q], 1);
1111
0
  if (ret < 0) {
1112
0
    gnutls_assert();
1113
0
    goto cleanup;
1114
0
  }
1115
1116
0
  ret = _gnutls_x509_write_int(*c2, "g", params->params[DSA_G], 1);
1117
0
  if (ret < 0) {
1118
0
    gnutls_assert();
1119
0
    goto cleanup;
1120
0
  }
1121
1122
0
  ret = _gnutls_x509_write_int(*c2, "Y", params->params[DSA_Y], 1);
1123
0
  if (ret < 0) {
1124
0
    gnutls_assert();
1125
0
    goto cleanup;
1126
0
  }
1127
1128
0
  ret = _gnutls_x509_write_key_int(*c2, "priv", params->params[DSA_X], 1);
1129
0
  if (ret < 0) {
1130
0
    gnutls_assert();
1131
0
    goto cleanup;
1132
0
  }
1133
1134
0
  if ((result = asn1_write_value(*c2, "version", &null, 1)) !=
1135
0
      ASN1_SUCCESS) {
1136
0
    gnutls_assert();
1137
0
    ret = _gnutls_asn2err(result);
1138
0
    goto cleanup;
1139
0
  }
1140
1141
0
  return 0;
1142
1143
0
cleanup:
1144
0
  asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1145
1146
0
  return ret;
1147
0
}
1148
1149
int _gnutls_asn1_encode_privkey(asn1_node *c2, gnutls_pk_params_st *params)
1150
0
{
1151
0
  switch (params->algo) {
1152
0
  case GNUTLS_PK_RSA:
1153
0
  case GNUTLS_PK_RSA_PSS:
1154
0
  case GNUTLS_PK_RSA_OAEP:
1155
0
    return _gnutls_asn1_encode_rsa(c2, params);
1156
0
  case GNUTLS_PK_DSA:
1157
0
    return _gnutls_asn1_encode_dsa(c2, params);
1158
0
  case GNUTLS_PK_ECDSA:
1159
0
  case GNUTLS_PK_EDDSA_ED25519:
1160
0
  case GNUTLS_PK_EDDSA_ED448:
1161
0
  case GNUTLS_PK_ECDH_X25519:
1162
0
  case GNUTLS_PK_ECDH_X448:
1163
0
    return _gnutls_asn1_encode_ecc(c2, params);
1164
0
  case GNUTLS_PK_GOST_01:
1165
0
  case GNUTLS_PK_GOST_12_256:
1166
0
  case GNUTLS_PK_GOST_12_512:
1167
0
    return _gnutls_asn1_encode_gost(c2, params);
1168
0
  case GNUTLS_PK_DH:
1169
    /* DH keys are only exportable in PKCS#8 format */
1170
0
    return GNUTLS_E_INVALID_REQUEST;
1171
0
  default:
1172
0
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1173
0
  }
1174
0
}