Coverage Report

Created: 2023-03-26 08:33

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