Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/privkey_pkcs8.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2014-2017 Red Hat
4
 * Copyright (C) 2014-2016 Nikos Mavrogiannopoulos
5
 *
6
 * Author: Nikos Mavrogiannopoulos
7
 *
8
 * This file is part of GnuTLS.
9
 *
10
 * The GnuTLS is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public License
12
 * as published by the Free Software Foundation; either version 2.1 of
13
 * the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
22
 *
23
 */
24
25
#include "gnutls_int.h"
26
27
#include <datum.h>
28
#include <global.h>
29
#include "errors.h"
30
#include <common.h>
31
#include <x509.h>
32
#include <x509_b64.h>
33
#include "x509_int.h"
34
#include "pkcs7_int.h"
35
#include <algorithms.h>
36
#include <num.h>
37
#include <random.h>
38
#include <pk.h>
39
#include "attributes.h"
40
#include "prov-seed.h"
41
42
static int _decode_pkcs8_ecc_key(asn1_node pkcs8_asn,
43
         gnutls_x509_privkey_t pkey);
44
static
45
int pkcs8_key_info(const gnutls_datum_t * raw_key,
46
       const struct pkcs_cipher_schema_st **p,
47
       struct pbkdf2_params *kdf_params, char **oid);
48
49
static int decode_private_key_info(const gnutls_datum_t * der,
50
           gnutls_x509_privkey_t pkey);
51
52
0
#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
53
0
#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
54
55
/* Returns a negative error code if the encryption schema in
56
 * the OID is not supported. The schema ID is returned.
57
 */
58
/* Encodes a private key to the raw format PKCS #8 needs.
59
 * For RSA it is a PKCS #1 DER private key and for DSA it is
60
 * an ASN.1 INTEGER of the x value.
61
 */
62
inline static int
63
_encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
64
0
{
65
0
  int ret;
66
0
  asn1_node spk = NULL;
67
68
0
  switch (pkey->params.algo) {
69
0
  case GNUTLS_PK_EDDSA_ED25519:
70
0
  case GNUTLS_PK_EDDSA_ED448:
71
0
  case GNUTLS_PK_ECDH_X25519:
72
0
  case GNUTLS_PK_ECDH_X448:
73
    /* we encode as octet string (which is going to be stored inside
74
     * another octet string). No comments. */
75
0
    ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
76
0
             pkey->params.raw_priv.data,
77
0
             pkey->params.raw_priv.size,
78
0
             raw);
79
0
    if (ret < 0)
80
0
      gnutls_assert();
81
0
    return ret;
82
83
0
  case GNUTLS_PK_GOST_01:
84
0
  case GNUTLS_PK_GOST_12_256:
85
0
  case GNUTLS_PK_GOST_12_512:
86
0
    if ((ret = asn1_create_element
87
0
         (_gnutls_get_gnutls_asn(), "GNUTLS.GOSTPrivateKey", &spk))
88
0
        != ASN1_SUCCESS) {
89
0
      gnutls_assert();
90
0
      ret = _gnutls_asn2err(ret);
91
0
      goto error;
92
0
    }
93
94
0
    ret =
95
0
        _gnutls_x509_write_key_int_le(spk, "",
96
0
              pkey->params.params[GOST_K]);
97
0
    if (ret < 0) {
98
0
      gnutls_assert();
99
0
      goto error;
100
0
    }
101
102
0
    ret = _gnutls_x509_der_encode(spk, "", raw, 0);
103
0
    if (ret < 0) {
104
0
      gnutls_assert();
105
0
      goto error;
106
0
    }
107
108
0
    asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
109
0
    break;
110
111
0
  case GNUTLS_PK_RSA:
112
0
  case GNUTLS_PK_RSA_PSS:
113
0
  case GNUTLS_PK_ECDSA:
114
0
    ret =
115
0
        _gnutls_x509_export_int2(pkey->key, GNUTLS_X509_FMT_DER,
116
0
               "", raw);
117
0
    if (ret < 0) {
118
0
      gnutls_assert();
119
0
      goto error;
120
0
    }
121
122
0
    break;
123
0
  case GNUTLS_PK_DSA:
124
    /* DSAPublicKey == INTEGER */
125
0
    if ((ret = asn1_create_element
126
0
         (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk))
127
0
        != ASN1_SUCCESS) {
128
0
      gnutls_assert();
129
0
      return _gnutls_asn2err(ret);
130
0
    }
131
132
0
    ret =
133
0
        _gnutls_x509_write_int(spk, "", pkey->params.params[4], 1);
134
0
    if (ret < 0) {
135
0
      gnutls_assert();
136
0
      goto error;
137
0
    }
138
0
    ret = _gnutls_x509_der_encode(spk, "", raw, 0);
139
0
    if (ret < 0) {
140
0
      gnutls_assert();
141
0
      goto error;
142
0
    }
143
144
0
    asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
145
0
    break;
146
147
0
  default:
148
0
    gnutls_assert();
149
0
    return GNUTLS_E_INVALID_REQUEST;
150
0
  }
151
152
0
  return 0;
153
154
0
 error:
155
0
  asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
156
0
  asn1_delete_structure(&spk);
157
0
  return ret;
158
159
0
}
160
161
/* 
162
 * Encodes a PKCS #1 private key to a PKCS #8 private key
163
 * info. The output will be allocated and stored into der. Also
164
 * the asn1_node of private key info will be returned.
165
 */
166
static int
167
encode_to_private_key_info(gnutls_x509_privkey_t pkey,
168
         gnutls_datum_t * der, asn1_node * pkey_info)
169
0
{
170
0
  int result, len;
171
0
  uint8_t null = 0;
172
0
  const char *oid;
173
0
  gnutls_datum_t algo_params = { NULL, 0 };
174
0
  gnutls_datum_t algo_privkey = { NULL, 0 };
175
176
0
  oid = gnutls_pk_get_oid(pkey->params.algo);
177
0
  if (oid == NULL) {
178
0
    gnutls_assert();
179
0
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
180
0
  }
181
182
0
  result = _gnutls_x509_write_pubkey_params(&pkey->params, &algo_params);
183
0
  if (result < 0) {
184
0
    gnutls_assert();
185
0
    return result;
186
0
  }
187
188
0
  if ((result =
189
0
       asn1_create_element(_gnutls_get_pkix(),
190
0
         "PKIX1.pkcs-8-PrivateKeyInfo",
191
0
         pkey_info)) != ASN1_SUCCESS) {
192
0
    gnutls_assert();
193
0
    result = _gnutls_asn2err(result);
194
0
    goto error;
195
0
  }
196
197
  /* Write the version.
198
   */
199
0
  result = asn1_write_value(*pkey_info, "version", &null, 1);
200
0
  if (result != ASN1_SUCCESS) {
201
0
    gnutls_assert();
202
0
    result = _gnutls_asn2err(result);
203
0
    goto error;
204
0
  }
205
206
  /* write the privateKeyAlgorithm
207
   * fields. (OID+NULL data)
208
   */
209
0
  result =
210
0
      asn1_write_value(*pkey_info, "privateKeyAlgorithm.algorithm",
211
0
           oid, 1);
212
0
  if (result != ASN1_SUCCESS) {
213
0
    gnutls_assert();
214
0
    result = _gnutls_asn2err(result);
215
0
    goto error;
216
0
  }
217
218
0
  result =
219
0
      asn1_write_value(*pkey_info, "privateKeyAlgorithm.parameters",
220
0
           algo_params.data, algo_params.size);
221
0
  _gnutls_free_key_datum(&algo_params);
222
223
0
  if (result != ASN1_SUCCESS) {
224
0
    gnutls_assert();
225
0
    result = _gnutls_asn2err(result);
226
0
    goto error;
227
0
  }
228
229
  /* Write the raw private key
230
   */
231
0
  result = _encode_privkey(pkey, &algo_privkey);
232
0
  if (result < 0) {
233
0
    gnutls_assert();
234
0
    goto error;
235
0
  }
236
237
0
  result =
238
0
      asn1_write_value(*pkey_info, "privateKey", algo_privkey.data,
239
0
           algo_privkey.size);
240
0
  _gnutls_free_key_datum(&algo_privkey);
241
242
0
  if (result != ASN1_SUCCESS) {
243
0
    gnutls_assert();
244
0
    result = _gnutls_asn2err(result);
245
0
    goto error;
246
0
  }
247
248
0
  if ((pkey->params.pkflags & GNUTLS_PK_FLAG_PROVABLE)
249
0
      && pkey->params.seed_size > 0) {
250
0
    gnutls_datum_t seed_info;
251
    /* rfc8479 attribute encoding */
252
253
0
    result = _x509_encode_provable_seed(pkey, &seed_info);
254
0
    if (result < 0) {
255
0
      gnutls_assert();
256
0
      goto error;
257
0
    }
258
259
0
    result =
260
0
        _x509_set_attribute(*pkey_info, "attributes",
261
0
          OID_ATTR_PROV_SEED, &seed_info);
262
0
    gnutls_free(seed_info.data);
263
0
    if (result < 0) {
264
0
      gnutls_assert();
265
0
      goto error;
266
0
    }
267
0
  } else {
268
    /* Append an empty Attributes field.
269
     */
270
0
    result = asn1_write_value(*pkey_info, "attributes", NULL, 0);
271
0
    if (result != ASN1_SUCCESS) {
272
0
      gnutls_assert();
273
0
      result = _gnutls_asn2err(result);
274
0
      goto error;
275
0
    }
276
0
  }
277
278
  /* DER Encode the generated private key info.
279
   */
280
0
  len = 0;
281
0
  result = asn1_der_coding(*pkey_info, "", NULL, &len, NULL);
282
0
  if (result != ASN1_MEM_ERROR) {
283
0
    gnutls_assert();
284
0
    result = _gnutls_asn2err(result);
285
0
    goto error;
286
0
  }
287
288
  /* allocate data for the der
289
   */
290
0
  der->size = len;
291
0
  der->data = gnutls_malloc(len);
292
0
  if (der->data == NULL) {
293
0
    gnutls_assert();
294
0
    return GNUTLS_E_MEMORY_ERROR;
295
0
  }
296
297
0
  result = asn1_der_coding(*pkey_info, "", der->data, &len, NULL);
298
0
  if (result != ASN1_SUCCESS) {
299
0
    gnutls_assert();
300
0
    result = _gnutls_asn2err(result);
301
0
    goto error;
302
0
  }
303
304
0
  return 0;
305
306
0
 error:
307
0
  asn1_delete_structure2(pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
308
0
  _gnutls_free_datum(&algo_params);
309
0
  _gnutls_free_key_datum(&algo_privkey);
310
0
  return result;
311
312
0
}
313
314
/* Converts a PKCS #8 private key info to
315
 * a PKCS #8 EncryptedPrivateKeyInfo.
316
 */
317
static int
318
encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
319
        const char *password, asn1_node * out)
320
0
{
321
0
  int result;
322
0
  gnutls_datum_t key = { NULL, 0 };
323
0
  gnutls_datum_t tmp = { NULL, 0 };
324
0
  asn1_node pkcs8_asn = NULL;
325
0
  struct pbkdf2_params kdf_params;
326
0
  struct pbe_enc_params enc_params;
327
0
  const struct pkcs_cipher_schema_st *s;
328
329
0
  s = _gnutls_pkcs_schema_get(schema);
330
0
  if (s == NULL || s->decrypt_only) {
331
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
332
0
  }
333
334
0
  if ((result =
335
0
       asn1_create_element(_gnutls_get_pkix(),
336
0
         "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
337
0
         &pkcs8_asn)) != ASN1_SUCCESS) {
338
0
    gnutls_assert();
339
0
    return _gnutls_asn2err(result);
340
0
  }
341
342
  /* Write the encryption schema OID
343
   */
344
0
  result =
345
0
      asn1_write_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
346
0
           s->write_oid, 1);
347
348
0
  if (result != ASN1_SUCCESS) {
349
0
    gnutls_assert();
350
0
    result = _gnutls_asn2err(result);
351
0
    goto error;
352
0
  }
353
354
  /* Generate a symmetric key.
355
   */
356
357
0
  result =
358
0
      _gnutls_pkcs_generate_key(schema, password, &kdf_params,
359
0
              &enc_params, &key);
360
0
  if (result < 0) {
361
0
    gnutls_assert();
362
0
    goto error;
363
0
  }
364
365
0
  result =
366
0
      _gnutls_pkcs_write_schema_params(schema, pkcs8_asn,
367
0
               "encryptionAlgorithm.parameters",
368
0
               &kdf_params, &enc_params);
369
0
  if (result < 0) {
370
0
    gnutls_assert();
371
0
    goto error;
372
0
  }
373
374
  /* Parameters have been encoded. Now
375
   * encrypt the Data.
376
   */
377
0
  result =
378
0
      _gnutls_pkcs_raw_encrypt_data(der_key, &enc_params, &key, &tmp);
379
0
  if (result < 0) {
380
0
    gnutls_assert();
381
0
    goto error;
382
0
  }
383
384
  /* write the encrypted data.
385
   */
386
0
  result =
387
0
      asn1_write_value(pkcs8_asn, "encryptedData", tmp.data, tmp.size);
388
0
  if (result != ASN1_SUCCESS) {
389
0
    gnutls_assert();
390
0
    result = _gnutls_asn2err(result);
391
0
    goto error;
392
0
  }
393
394
0
  _gnutls_free_datum(&tmp);
395
0
  _gnutls_free_key_datum(&key);
396
397
0
  *out = pkcs8_asn;
398
399
0
  return 0;
400
401
0
 error:
402
0
  _gnutls_free_key_datum(&key);
403
0
  _gnutls_free_datum(&tmp);
404
0
  asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
405
0
  return result;
406
0
}
407
408
/**
409
 * gnutls_x509_privkey_export_pkcs8:
410
 * @key: Holds the key
411
 * @format: the format of output params. One of PEM or DER.
412
 * @password: the password that will be used to encrypt the key.
413
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
414
 * @output_data: will contain a private key PEM or DER encoded
415
 * @output_data_size: holds the size of output_data (and will be
416
 *   replaced by the actual size of parameters)
417
 *
418
 * This function will export the private key to a PKCS8 structure.
419
 * Both RSA and DSA keys can be exported. For DSA keys we use
420
 * PKCS #11 definitions. If the flags do not specify the encryption
421
 * cipher, then the default 3DES (PBES2) will be used.
422
 *
423
 * The @password can be either ASCII or UTF-8 in the default PBES2
424
 * encryption schemas, or ASCII for the PKCS12 schemas.
425
 *
426
 * If the buffer provided is not long enough to hold the output, then
427
 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
428
 * be returned.
429
 *
430
 * If the structure is PEM encoded, it will have a header
431
 * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
432
 * encryption is not used.
433
 *
434
 * Returns: In case of failure a negative error code will be
435
 *   returned, and 0 on success.
436
 **/
437
int
438
gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
439
         gnutls_x509_crt_fmt_t format,
440
         const char *password,
441
         unsigned int flags,
442
         void *output_data, size_t *output_data_size)
443
0
{
444
0
  asn1_node pkcs8_asn = NULL, pkey_info;
445
0
  int ret;
446
0
  gnutls_datum_t tmp = { NULL, 0 };
447
0
  schema_id schema;
448
449
0
  if (key == NULL) {
450
0
    gnutls_assert();
451
0
    return GNUTLS_E_INVALID_REQUEST;
452
0
  }
453
454
  /* Get the private key info
455
   * tmp holds the DER encoding.
456
   */
457
0
  ret = encode_to_private_key_info(key, &tmp, &pkey_info);
458
0
  if (ret < 0) {
459
0
    gnutls_assert();
460
0
    return ret;
461
0
  }
462
463
0
  schema = _gnutls_pkcs_flags_to_schema(flags);
464
465
0
  if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
466
0
      && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
467
0
    _gnutls_free_datum(&tmp);
468
469
0
    ret =
470
0
        _gnutls_x509_export_int(pkey_info, format,
471
0
              PEM_UNENCRYPTED_PKCS8,
472
0
              output_data, output_data_size);
473
474
0
    asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
475
0
  } else {
476
0
    asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);  /* we don't need it */
477
478
0
    ret = encode_to_pkcs8_key(schema, &tmp, password, &pkcs8_asn);
479
0
    _gnutls_free_key_datum(&tmp);
480
481
0
    if (ret < 0) {
482
0
      gnutls_assert();
483
0
      return ret;
484
0
    }
485
486
0
    ret =
487
0
        _gnutls_x509_export_int(pkcs8_asn, format, PEM_PKCS8,
488
0
              output_data, output_data_size);
489
490
0
    asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
491
0
  }
492
493
0
  return ret;
494
0
}
495
496
/**
497
 * gnutls_pkcs8_info:
498
 * @data: Holds the PKCS #8 data
499
 * @format: the format of the PKCS #8 data
500
 * @schema: indicate the schema as one of %gnutls_pkcs_encrypt_flags_t
501
 * @cipher: the cipher used as %gnutls_cipher_algorithm_t
502
 * @salt: PBKDF2 salt (if non-NULL then @salt_size initially holds its size)
503
 * @salt_size: PBKDF2 salt size
504
 * @iter_count: PBKDF2 iteration count
505
 * @oid: if non-NULL it will contain an allocated null-terminated variable with the OID
506
 *
507
 * This function will provide information on the algorithms used
508
 * in a particular PKCS #8 structure. If the structure algorithms
509
 * are unknown the code %GNUTLS_E_UNKNOWN_CIPHER_TYPE will be returned,
510
 * and only @oid, will be set. That is, @oid will be set on encrypted PKCS #8
511
 * structures whether supported or not. It must be deinitialized using gnutls_free().
512
 * The other variables are only set on supported structures.
513
 *
514
 * Returns: %GNUTLS_E_INVALID_REQUEST if the provided structure isn't an encrypted key,
515
 *  %GNUTLS_E_UNKNOWN_CIPHER_TYPE if the structure's encryption isn't supported, or
516
 *  another negative error code in case of a failure. Zero on success.
517
 *
518
 * Since: 3.4.0
519
 **/
520
int
521
gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
522
      unsigned int *schema, unsigned int *cipher,
523
      void *salt, unsigned int *salt_size,
524
      unsigned int *iter_count, char **oid)
525
0
{
526
0
  int ret = 0, need_free = 0;
527
0
  gnutls_datum_t _data;
528
0
  const struct pkcs_cipher_schema_st *p = NULL;
529
0
  struct pbkdf2_params kdf;
530
531
0
  memset(&kdf, 0, sizeof(kdf));
532
533
0
  if (oid)
534
0
    *oid = NULL;
535
536
0
  _data.data = data->data;
537
0
  _data.size = data->size;
538
539
  /* If the Certificate is in PEM format then decode it
540
   */
541
0
  if (format == GNUTLS_X509_FMT_PEM) {
542
    /* Try the first header 
543
     */
544
0
    ret =
545
0
        _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
546
0
             data->data, data->size, &_data);
547
548
0
    if (ret < 0) { /* Try the encrypted header 
549
         */
550
0
      ret =
551
0
          _gnutls_fbase64_decode(PEM_PKCS8, data->data,
552
0
               data->size, &_data);
553
554
0
      if (ret < 0) {
555
0
        gnutls_assert();
556
0
        return ret;
557
0
      }
558
0
    }
559
560
0
    need_free = 1;
561
0
  }
562
563
0
  ret = pkcs8_key_info(&_data, &p, &kdf, oid);
564
0
  if (ret == GNUTLS_E_DECRYPTION_FAILED)
565
0
    ret = GNUTLS_E_INVALID_REQUEST;
566
0
  if (ret < 0) {
567
0
    gnutls_assert();
568
0
    goto cleanup;
569
0
  }
570
571
0
  assert(p != NULL);
572
573
0
  if (need_free)
574
0
    _gnutls_free_datum(&_data);
575
576
0
  if (schema)
577
0
    *schema = p->flag;
578
579
0
  if (cipher)
580
0
    *cipher = p->cipher;
581
582
0
  if (iter_count)
583
0
    *iter_count = kdf.iter_count;
584
585
0
  if (salt) {
586
0
    if (*salt_size >= (unsigned)kdf.salt_size) {
587
0
      memcpy(salt, kdf.salt, kdf.salt_size);
588
0
    } else {
589
0
      *salt_size = kdf.salt_size;
590
0
      ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
591
0
      goto cleanup;
592
0
    }
593
0
  }
594
595
0
  if (salt_size)
596
0
    *salt_size = kdf.salt_size;
597
598
0
  return 0;
599
600
0
 cleanup:
601
0
  if (ret != GNUTLS_E_UNKNOWN_CIPHER_TYPE && oid) {
602
0
    gnutls_free(*oid);
603
0
  }
604
0
  if (need_free)
605
0
    _gnutls_free_datum(&_data);
606
0
  return ret;
607
0
}
608
609
/**
610
 * gnutls_x509_privkey_export2_pkcs8:
611
 * @key: Holds the key
612
 * @format: the format of output params. One of PEM or DER.
613
 * @password: the password that will be used to encrypt the key.
614
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
615
 * @out: will contain a private key PEM or DER encoded
616
 *
617
 * This function will export the private key to a PKCS8 structure.
618
 * Both RSA and DSA keys can be exported. For DSA keys we use
619
 * PKCS #11 definitions. If the flags do not specify the encryption
620
 * cipher, then the default 3DES (PBES2) will be used.
621
 *
622
 * The @password can be either ASCII or UTF-8 in the default PBES2
623
 * encryption schemas, or ASCII for the PKCS12 schemas.
624
 *
625
 * The output buffer is allocated using gnutls_malloc().
626
 *
627
 * If the structure is PEM encoded, it will have a header
628
 * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
629
 * encryption is not used.
630
 *
631
 * Returns: In case of failure a negative error code will be
632
 *   returned, and 0 on success.
633
 *
634
 * Since 3.1.3
635
 **/
636
int
637
gnutls_x509_privkey_export2_pkcs8(gnutls_x509_privkey_t key,
638
          gnutls_x509_crt_fmt_t format,
639
          const char *password,
640
          unsigned int flags, gnutls_datum_t * out)
641
0
{
642
0
  asn1_node pkcs8_asn = NULL, pkey_info;
643
0
  int ret;
644
0
  gnutls_datum_t tmp = { NULL, 0 };
645
0
  schema_id schema;
646
647
0
  if (key == NULL) {
648
0
    gnutls_assert();
649
0
    return GNUTLS_E_INVALID_REQUEST;
650
0
  }
651
652
  /* Get the private key info
653
   * tmp holds the DER encoding.
654
   */
655
0
  ret = encode_to_private_key_info(key, &tmp, &pkey_info);
656
0
  if (ret < 0) {
657
0
    gnutls_assert();
658
0
    return ret;
659
0
  }
660
661
0
  schema = _gnutls_pkcs_flags_to_schema(flags);
662
663
0
  if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
664
0
      && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
665
0
    _gnutls_free_key_datum(&tmp);
666
667
0
    ret =
668
0
        _gnutls_x509_export_int2(pkey_info, format,
669
0
               PEM_UNENCRYPTED_PKCS8, out);
670
671
0
    asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
672
0
  } else {
673
0
    asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);  /* we don't need it */
674
675
0
    ret = encode_to_pkcs8_key(schema, &tmp, password, &pkcs8_asn);
676
0
    _gnutls_free_key_datum(&tmp);
677
678
0
    if (ret < 0) {
679
0
      gnutls_assert();
680
0
      return ret;
681
0
    }
682
683
0
    ret =
684
0
        _gnutls_x509_export_int2(pkcs8_asn, format, PEM_PKCS8, out);
685
686
0
    asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
687
0
  }
688
689
0
  return ret;
690
0
}
691
692
  /* We've gotten this far. In the real world it's almost certain
693
   * that we're dealing with a good file, but wrong password.
694
   * Sadly like 90% of random data is somehow valid DER for the
695
   * a first small number of bytes, so no easy way to guarantee. */
696
#define CHECK_ERR_FOR_ENCRYPTED(result) \
697
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND || \
698
0
        result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND || \
699
0
        result == GNUTLS_E_ASN1_DER_ERROR || \
700
0
        result == GNUTLS_E_ASN1_VALUE_NOT_FOUND || \
701
0
        result == GNUTLS_E_ASN1_GENERIC_ERROR || \
702
0
        result == GNUTLS_E_ASN1_VALUE_NOT_VALID || \
703
0
        result == GNUTLS_E_ASN1_TAG_ERROR || \
704
0
        result == GNUTLS_E_ASN1_TAG_IMPLICIT || \
705
0
        result == GNUTLS_E_ASN1_TYPE_ANY_ERROR || \
706
0
        result == GNUTLS_E_ASN1_SYNTAX_ERROR || \
707
0
        result == GNUTLS_E_ASN1_DER_OVERFLOW) { \
708
0
      result = GNUTLS_E_DECRYPTION_FAILED; \
709
0
    }
710
711
static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
712
           asn1_node pkcs8_asn, const char *password,
713
           gnutls_x509_privkey_t pkey)
714
0
{
715
0
  int result, len;
716
0
  char enc_oid[MAX_OID_SIZE];
717
0
  gnutls_datum_t tmp = { NULL, 0 };
718
0
  int params_start, params_end, params_len;
719
0
  struct pbkdf2_params kdf_params;
720
0
  struct pbe_enc_params enc_params;
721
0
  schema_id schema;
722
723
  /* Check the encryption schema OID
724
   */
725
0
  len = sizeof(enc_oid);
726
0
  result =
727
0
      asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
728
0
          enc_oid, &len);
729
0
  if (result != ASN1_SUCCESS) {
730
0
    gnutls_assert();
731
0
    goto error;
732
0
  }
733
734
0
  if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) {
735
0
    gnutls_assert();
736
0
    goto error;
737
0
  }
738
739
0
  schema = result;
740
741
  /* Get the DER encoding of the parameters.
742
   */
743
0
  result =
744
0
      asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data,
745
0
               raw_key->size,
746
0
               "encryptionAlgorithm.parameters",
747
0
               &params_start, &params_end);
748
0
  if (result != ASN1_SUCCESS) {
749
0
    gnutls_assert();
750
0
    result = _gnutls_asn2err(result);
751
0
    goto error;
752
0
  }
753
0
  params_len = params_end - params_start + 1;
754
755
0
  result =
756
0
      _gnutls_read_pkcs_schema_params(&schema, password,
757
0
              &raw_key->data[params_start],
758
0
              params_len, &kdf_params,
759
0
              &enc_params);
760
761
0
  if (result < 0) {
762
0
    gnutls_assert();
763
0
    goto error;
764
0
  }
765
766
  /* Parameters have been decoded. Now
767
   * decrypt the EncryptedData.
768
   */
769
0
  result =
770
0
      _gnutls_pkcs_raw_decrypt_data(schema, pkcs8_asn, "encryptedData",
771
0
            password, &kdf_params, &enc_params,
772
0
            &tmp);
773
0
  if (result < 0) {
774
0
    gnutls_assert();
775
0
    result = GNUTLS_E_DECRYPTION_FAILED;
776
0
    goto error;
777
0
  }
778
779
0
  result = decode_private_key_info(&tmp, pkey);
780
0
  _gnutls_free_key_datum(&tmp);
781
782
0
  CHECK_ERR_FOR_ENCRYPTED(result);
783
0
  if (result < 0) {
784
0
    gnutls_assert();
785
0
    goto error;
786
0
  }
787
788
0
  return 0;
789
790
0
 error:
791
0
  return result;
792
0
}
793
794
static int check_for_decrypted(const gnutls_datum_t * der)
795
0
{
796
0
  int result;
797
0
  asn1_node pkcs8_asn = NULL;
798
799
0
  if ((result =
800
0
       asn1_create_element(_gnutls_get_pkix(),
801
0
         "PKIX1.pkcs-8-PrivateKeyInfo",
802
0
         &pkcs8_asn)) != ASN1_SUCCESS) {
803
0
    gnutls_assert();
804
0
    return _gnutls_asn2err(result);
805
0
  }
806
807
0
  result =
808
0
      _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
809
0
  if (result != ASN1_SUCCESS) {
810
0
    gnutls_assert();
811
0
    result = _gnutls_asn2err(result);
812
0
    goto error;
813
0
  }
814
815
0
  result = 0;
816
0
 error:
817
0
  asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
818
0
  return result;
819
820
0
}
821
822
static
823
int pkcs8_key_info(const gnutls_datum_t * raw_key,
824
       const struct pkcs_cipher_schema_st **p,
825
       struct pbkdf2_params *kdf_params, char **oid)
826
0
{
827
0
  int result, len;
828
0
  char enc_oid[MAX_OID_SIZE * 2];
829
0
  int params_start, params_end, params_len;
830
0
  struct pbe_enc_params enc_params;
831
0
  schema_id schema;
832
0
  asn1_node pkcs8_asn = NULL;
833
834
0
  memset(&enc_params, 0, sizeof(enc_params));
835
836
0
  result = check_for_decrypted(raw_key);
837
0
  if (result == 0)
838
0
    return GNUTLS_E_INVALID_REQUEST;
839
840
0
  if ((result =
841
0
       asn1_create_element(_gnutls_get_pkix(),
842
0
         "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
843
0
         &pkcs8_asn)) != ASN1_SUCCESS) {
844
0
    gnutls_assert();
845
0
    result = _gnutls_asn2err(result);
846
0
    goto error;
847
0
  }
848
849
0
  result =
850
0
      _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
851
0
            NULL);
852
0
  if (result != ASN1_SUCCESS) {
853
0
    gnutls_assert();
854
0
    result = _gnutls_asn2err(result);
855
0
    goto error;
856
0
  }
857
858
  /* Check the encryption schema OID
859
   */
860
0
  len = sizeof(enc_oid);
861
0
  result =
862
0
      asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
863
0
          enc_oid, &len);
864
0
  if (result != ASN1_SUCCESS) {
865
0
    gnutls_assert();
866
0
    goto error;
867
0
  }
868
869
0
  if (oid) {
870
0
    *oid = gnutls_strdup(enc_oid);
871
0
  }
872
873
0
  if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) {
874
0
    gnutls_assert();
875
0
    goto error;
876
0
  }
877
878
0
  schema = result;
879
880
  /* Get the DER encoding of the parameters.
881
   */
882
0
  result =
883
0
      asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data,
884
0
               raw_key->size,
885
0
               "encryptionAlgorithm.parameters",
886
0
               &params_start, &params_end);
887
0
  if (result != ASN1_SUCCESS) {
888
0
    gnutls_assert();
889
0
    result = _gnutls_asn2err(result);
890
0
    goto error;
891
0
  }
892
0
  params_len = params_end - params_start + 1;
893
894
0
  result =
895
0
      _gnutls_read_pkcs_schema_params(&schema, NULL,
896
0
              &raw_key->data[params_start],
897
0
              params_len, kdf_params,
898
0
              &enc_params);
899
900
0
  if (result < 0) {
901
0
    gnutls_assert();
902
0
    if (oid && enc_params.pbes2_oid[0] != 0) {
903
0
      snprintf(enc_oid, sizeof(enc_oid), "%s/%s", *oid,
904
0
         enc_params.pbes2_oid);
905
0
      gnutls_free(*oid);
906
0
      *oid = gnutls_strdup(enc_oid);
907
0
    }
908
0
    goto error;
909
0
  }
910
911
0
  *p = _gnutls_pkcs_schema_get(schema);
912
0
  if (*p == NULL) {
913
0
    gnutls_assert();
914
0
    result = GNUTLS_E_UNKNOWN_CIPHER_TYPE;
915
0
    goto error;
916
0
  }
917
918
0
  result = 0;
919
920
0
 error:
921
0
  asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
922
0
  return result;
923
0
}
924
925
/* Converts a PKCS #8 key to
926
 * an internal structure (gnutls_private_key)
927
 * (normally a PKCS #1 encoded RSA key)
928
 */
929
static int
930
pkcs8_key_decode(const gnutls_datum_t * raw_key,
931
     const char *password, gnutls_x509_privkey_t pkey,
932
     unsigned int decrypt)
933
0
{
934
0
  int result;
935
0
  asn1_node pkcs8_asn = NULL;
936
937
0
  if ((result =
938
0
       asn1_create_element(_gnutls_get_pkix(),
939
0
         "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
940
0
         &pkcs8_asn)) != ASN1_SUCCESS) {
941
0
    gnutls_assert();
942
0
    result = _gnutls_asn2err(result);
943
0
    goto error;
944
0
  }
945
946
0
  result =
947
0
      _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
948
0
            NULL);
949
0
  if (result != ASN1_SUCCESS) {
950
0
    gnutls_assert();
951
0
    result = _gnutls_asn2err(result);
952
0
    goto error;
953
0
  }
954
955
0
  if (decrypt)
956
0
    result = pkcs8_key_decrypt(raw_key, pkcs8_asn, password, pkey);
957
0
  else
958
0
    result = 0;
959
960
0
 error:
961
0
  asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
962
0
  return result;
963
964
0
}
965
966
/* Decodes an RSA privateKey from a PKCS8 structure.
967
 */
968
static int
969
_decode_pkcs8_rsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
970
0
{
971
0
  int ret;
972
0
  gnutls_datum_t tmp = { NULL, 0 };
973
974
0
  ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
975
0
  if (ret < 0) {
976
0
    gnutls_assert();
977
0
    goto error;
978
0
  }
979
980
0
  pkey->key = _gnutls_privkey_decode_pkcs1_rsa_key(&tmp, pkey);
981
0
  _gnutls_free_key_datum(&tmp);
982
983
0
  if (pkey->key == NULL) {
984
0
    ret = GNUTLS_E_PK_INVALID_PRIVKEY;
985
0
    gnutls_assert();
986
0
    goto error;
987
0
  }
988
989
0
  ret = 0;
990
991
0
 error:
992
0
  return ret;
993
0
}
994
995
/* Decodes an RSA-PSS privateKey from a PKCS8 structure.
996
 */
997
static int
998
_decode_pkcs8_rsa_pss_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
999
0
{
1000
0
  int ret;
1001
0
  gnutls_datum_t tmp = { NULL, 0 };
1002
0
  gnutls_x509_spki_st params;
1003
1004
0
  memset(&params, 0, sizeof(params));
1005
1006
0
  ret = _gnutls_x509_read_value(pkcs8_asn,
1007
0
              "privateKeyAlgorithm.parameters", &tmp);
1008
0
  if (ret < 0) {
1009
0
    if (ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND
1010
0
        || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1011
0
      goto skip_params;
1012
1013
0
    gnutls_assert();
1014
0
    goto error;
1015
0
  }
1016
1017
0
  ret = _gnutls_x509_read_rsa_pss_params(tmp.data, tmp.size, &params);
1018
0
  _gnutls_free_key_datum(&tmp);
1019
1020
0
  if (ret < 0) {
1021
0
    gnutls_assert();
1022
0
    goto error;
1023
0
  }
1024
1025
0
 skip_params:
1026
0
  ret = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
1027
0
  if (ret < 0) {
1028
0
    gnutls_assert();
1029
0
    goto error;
1030
0
  }
1031
1032
0
  pkey->params.algo = GNUTLS_PK_RSA_PSS;
1033
0
  memcpy(&pkey->params.spki, &params, sizeof(gnutls_x509_spki_st));
1034
1035
0
  ret = 0;
1036
1037
0
 error:
1038
0
  return ret;
1039
0
}
1040
1041
/* Decodes an ECC privateKey from a PKCS8 structure.
1042
 */
1043
static int
1044
_decode_pkcs8_ecc_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
1045
0
{
1046
0
  int ret;
1047
0
  gnutls_datum_t tmp = { NULL, 0 };
1048
0
  unsigned char oid[MAX_OID_SIZE];
1049
0
  unsigned curve = GNUTLS_ECC_CURVE_INVALID;
1050
0
  int len, result;
1051
1052
  /* openssl PKCS #8 files with ECC keys place the curve in
1053
   * privateKeyAlgorithm.parameters instead of the ECPrivateKey.parameters.
1054
   */
1055
0
  len = sizeof(oid);
1056
0
  result =
1057
0
      asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
1058
0
          oid, &len);
1059
0
  if (result == ASN1_SUCCESS) {
1060
0
    ret = _gnutls_x509_read_ecc_params(oid, len, &curve);
1061
0
    if (ret < 0) {
1062
0
      _gnutls_debug_log("PKCS#8: unknown curve OID %s\n",
1063
0
            oid);
1064
0
      curve = GNUTLS_ECC_CURVE_INVALID;
1065
0
    }
1066
0
  }
1067
1068
0
  ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
1069
0
  if (ret < 0) {
1070
0
    gnutls_assert();
1071
0
    goto error;
1072
0
  }
1073
1074
0
  ret = _gnutls_privkey_decode_ecc_key(&pkey->key, &tmp, pkey, curve);
1075
0
  _gnutls_free_key_datum(&tmp);
1076
1077
0
  if (ret < 0) {
1078
0
    gnutls_assert();
1079
0
    goto error;
1080
0
  }
1081
1082
0
  ret = 0;
1083
1084
0
 error:
1085
0
  return ret;
1086
0
}
1087
1088
static int
1089
_decode_pkcs8_eddsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
1090
      const char *oid)
1091
0
{
1092
0
  int ret;
1093
0
  gnutls_datum_t tmp;
1094
0
  gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
1095
0
  const gnutls_ecc_curve_entry_st *ce;
1096
1097
0
  gnutls_pk_params_init(&pkey->params);
1098
1099
0
  curve = gnutls_oid_to_ecc_curve(oid);
1100
0
  if (curve == GNUTLS_ECC_CURVE_INVALID) {
1101
0
    _gnutls_debug_log("PKCS#8: unknown curve OID %s\n", oid);
1102
0
    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
1103
0
  }
1104
1105
0
  ce = _gnutls_ecc_curve_get_params(curve);
1106
0
  if (_curve_is_eddsa(ce)) {
1107
0
    ret =
1108
0
        _gnutls_x509_read_string(pkcs8_asn, "privateKey", &tmp,
1109
0
               ASN1_ETYPE_OCTET_STRING, 1);
1110
0
    if (ret < 0) {
1111
0
      gnutls_assert();
1112
0
      return gnutls_assert_val(ret);
1113
0
    }
1114
1115
0
    if (tmp.size != ce->size) {
1116
0
      gnutls_free(tmp.data);
1117
0
      return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
1118
0
    }
1119
0
    gnutls_free(pkey->params.raw_priv.data);
1120
0
    switch (curve) {
1121
0
    case GNUTLS_ECC_CURVE_ED25519:
1122
0
      pkey->params.algo = GNUTLS_PK_EDDSA_ED25519;
1123
0
      break;
1124
0
    case GNUTLS_ECC_CURVE_ED448:
1125
0
      pkey->params.algo = GNUTLS_PK_EDDSA_ED448;
1126
0
      break;
1127
0
    default:
1128
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1129
0
    }
1130
0
    pkey->params.raw_priv.data = tmp.data;
1131
0
    pkey->params.raw_priv.size = tmp.size;
1132
0
    pkey->params.curve = curve;
1133
1134
0
    tmp.data = NULL;
1135
0
    return 0;
1136
0
  } else {
1137
0
    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
1138
0
  }
1139
0
}
1140
1141
static int
1142
_decode_pkcs8_modern_ecdh_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
1143
            const char *oid)
1144
0
{
1145
0
  int ret;
1146
0
  gnutls_datum_t tmp;
1147
0
  gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
1148
0
  const gnutls_ecc_curve_entry_st *ce;
1149
1150
0
  gnutls_pk_params_init(&pkey->params);
1151
1152
0
  curve = gnutls_oid_to_ecc_curve(oid);
1153
0
  if (curve == GNUTLS_ECC_CURVE_INVALID) {
1154
0
    _gnutls_debug_log("PKCS#8: unknown curve OID %s\n", oid);
1155
0
    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
1156
0
  }
1157
1158
0
  ce = _gnutls_ecc_curve_get_params(curve);
1159
0
  if (_curve_is_modern_ecdh(ce)) {
1160
0
    ret =
1161
0
        _gnutls_x509_read_string(pkcs8_asn, "privateKey", &tmp,
1162
0
               ASN1_ETYPE_OCTET_STRING, 1);
1163
0
    if (ret < 0) {
1164
0
      gnutls_assert();
1165
0
      return gnutls_assert_val(ret);
1166
0
    }
1167
1168
0
    if (tmp.size != ce->size) {
1169
0
      gnutls_free(tmp.data);
1170
0
      return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
1171
0
    }
1172
0
    gnutls_free(pkey->params.raw_priv.data);
1173
0
    switch (curve) {
1174
0
    case GNUTLS_ECC_CURVE_X25519:
1175
0
      pkey->params.algo = GNUTLS_PK_ECDH_X25519;
1176
0
      break;
1177
0
    case GNUTLS_ECC_CURVE_X448:
1178
0
      pkey->params.algo = GNUTLS_PK_ECDH_X448;
1179
0
      break;
1180
0
    default:
1181
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1182
0
    }
1183
0
    pkey->params.raw_priv.data = tmp.data;
1184
0
    pkey->params.raw_priv.size = tmp.size;
1185
0
    pkey->params.curve = curve;
1186
1187
0
    tmp.data = NULL;
1188
0
    return 0;
1189
0
  } else {
1190
0
    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
1191
0
  }
1192
0
}
1193
1194
/* Converts a GOST key to
1195
 * an internal structure (gnutls_private_key)
1196
 */
1197
static int
1198
_privkey_decode_gost_key(const gnutls_datum_t * raw_key,
1199
       gnutls_x509_privkey_t pkey)
1200
0
{
1201
0
  int ret;
1202
0
  int ecc_size = gnutls_ecc_curve_get_size(pkey->params.curve);
1203
1204
  /* Just to be sure here */
1205
0
  if (ecc_size <= 0) {
1206
0
    gnutls_assert();
1207
0
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
1208
0
    goto error;
1209
0
  }
1210
1211
  /* Private key form described in R 50.1.112-2016.
1212
   * Private key can come up as masked value concatenated with several masks.
1213
   * each part is of ecc_size bytes. Key will be unmasked in pk_fixup */
1214
0
  if (raw_key->size % ecc_size == 0) {
1215
0
    ret = _gnutls_mpi_init_scan_le(&pkey->params.params[GOST_K],
1216
0
                 raw_key->data, raw_key->size);
1217
0
    if (ret < 0) {
1218
0
      gnutls_assert();
1219
0
      goto error;
1220
0
    }
1221
0
  } else if (raw_key->data[0] == ASN1_TAG_INTEGER) {
1222
0
    asn1_node pkey_asn;
1223
1224
    /* Very old format: INTEGER packed in OCTET STRING */
1225
0
    if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
1226
0
                 "GNUTLS.GOSTPrivateKeyOld",
1227
0
                 &pkey_asn)) != ASN1_SUCCESS) {
1228
0
      gnutls_assert();
1229
0
      ret = _gnutls_asn2err(ret);
1230
0
      goto error;
1231
0
    }
1232
1233
0
    ret = _asn1_strict_der_decode(&pkey_asn,
1234
0
                raw_key->data, raw_key->size,
1235
0
                NULL);
1236
0
    if (ret != ASN1_SUCCESS) {
1237
0
      gnutls_assert();
1238
0
      ret = _gnutls_asn2err(ret);
1239
0
      asn1_delete_structure2(&pkey_asn,
1240
0
                 ASN1_DELETE_FLAG_ZEROIZE);
1241
0
      goto error;
1242
0
    }
1243
1244
0
    ret = _gnutls_x509_read_key_int(pkey_asn, "",
1245
0
            &pkey->params.params[GOST_K]);
1246
0
    if (ret < 0) {
1247
0
      gnutls_assert();
1248
0
      asn1_delete_structure2(&pkey_asn,
1249
0
                 ASN1_DELETE_FLAG_ZEROIZE);
1250
0
      goto error;
1251
0
    }
1252
0
    asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
1253
0
  } else if (raw_key->data[0] == ASN1_TAG_OCTET_STRING) {
1254
0
    asn1_node pkey_asn;
1255
1256
    /* format: OCTET STRING packed in OCTET STRING */
1257
0
    if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
1258
0
                 "GNUTLS.GOSTPrivateKey",
1259
0
                 &pkey_asn)) != ASN1_SUCCESS) {
1260
0
      gnutls_assert();
1261
0
      ret = _gnutls_asn2err(ret);
1262
0
      goto error;
1263
0
    }
1264
1265
0
    ret = _asn1_strict_der_decode(&pkey_asn,
1266
0
                raw_key->data, raw_key->size,
1267
0
                NULL);
1268
0
    if (ret != ASN1_SUCCESS) {
1269
0
      gnutls_assert();
1270
0
      ret = _gnutls_asn2err(ret);
1271
0
      asn1_delete_structure2(&pkey_asn,
1272
0
                 ASN1_DELETE_FLAG_ZEROIZE);
1273
0
      goto error;
1274
0
    }
1275
1276
0
    ret = _gnutls_x509_read_key_int_le(pkey_asn, "",
1277
0
               &pkey->
1278
0
               params.params[GOST_K]);
1279
0
    if (ret < 0) {
1280
0
      gnutls_assert();
1281
0
      asn1_delete_structure2(&pkey_asn,
1282
0
                 ASN1_DELETE_FLAG_ZEROIZE);
1283
0
      goto error;
1284
0
    }
1285
0
    asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
1286
0
  } else {
1287
0
    gnutls_assert();
1288
0
    ret = GNUTLS_E_PARSING_ERROR;
1289
0
    goto error;
1290
0
  }
1291
1292
0
  pkey->params.params_nr++;
1293
1294
0
  return 0;
1295
1296
0
 error:
1297
0
  return ret;
1298
1299
0
}
1300
1301
/* Decodes a GOST privateKey from a PKCS8 structure.
1302
 */
1303
static int
1304
_decode_pkcs8_gost_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
1305
           gnutls_pk_algorithm_t algo)
1306
0
{
1307
0
  int ret;
1308
0
  gnutls_datum_t tmp;
1309
0
  unsigned char oid[3 * MAX_OID_SIZE];  /* GOST parameters can have 3 OIDs at most */
1310
0
  int len, result;
1311
1312
0
  gnutls_pk_params_init(&pkey->params);
1313
1314
0
  len = sizeof(oid);
1315
0
  result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
1316
0
         oid, &len);
1317
0
  if (result != ASN1_SUCCESS) {
1318
0
    gnutls_assert();
1319
0
    ret = GNUTLS_E_PARSING_ERROR;
1320
0
    goto error;
1321
0
  } else {
1322
0
    ret =
1323
0
        _gnutls_x509_read_gost_params(oid, len, &pkey->params,
1324
0
              algo);
1325
0
    if (ret < 0) {
1326
0
      gnutls_assert();
1327
0
      goto error;
1328
0
    }
1329
0
  }
1330
1331
  /* Will be fixed later by pk_fixup */
1332
0
  ret = _gnutls_mpi_init(&pkey->params.params[GOST_X]);
1333
0
  if (ret < 0) {
1334
0
    gnutls_assert();
1335
0
    goto error;
1336
0
  }
1337
0
  pkey->params.params_nr++;
1338
1339
0
  ret = _gnutls_mpi_init(&pkey->params.params[GOST_Y]);
1340
0
  if (ret < 0) {
1341
0
    gnutls_assert();
1342
0
    goto error;
1343
0
  }
1344
0
  pkey->params.params_nr++;
1345
1346
0
  _gnutls_mpi_set_ui(pkey->params.params[GOST_X], 0);
1347
0
  _gnutls_mpi_set_ui(pkey->params.params[GOST_Y], 0);
1348
1349
0
  ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
1350
0
  if (ret < 0) {
1351
0
    gnutls_assert();
1352
0
    goto error;
1353
0
  }
1354
1355
0
  ret = _privkey_decode_gost_key(&tmp, pkey);
1356
0
  _gnutls_free_key_datum(&tmp);
1357
1358
0
  if (ret < 0) {
1359
0
    gnutls_assert();
1360
0
    goto error;
1361
0
  }
1362
1363
0
  pkey->params.algo = algo;
1364
1365
0
  return 0;
1366
1367
0
 error:
1368
0
  gnutls_pk_params_clear(&pkey->params);
1369
0
  gnutls_pk_params_release(&pkey->params);
1370
1371
0
  return ret;
1372
0
}
1373
1374
/* Decodes an DSA privateKey and params from a PKCS8 structure.
1375
 */
1376
static int
1377
_decode_pkcs8_dsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
1378
0
{
1379
0
  int ret;
1380
0
  gnutls_datum_t tmp = { NULL, 0 };
1381
1382
0
  gnutls_pk_params_init(&pkey->params);
1383
1384
0
  ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
1385
0
  if (ret < 0) {
1386
0
    gnutls_assert();
1387
0
    goto error;
1388
0
  }
1389
1390
0
  ret =
1391
0
      _gnutls_x509_read_der_int(tmp.data, tmp.size,
1392
0
              &pkey->params.params[4]);
1393
0
  _gnutls_free_key_datum(&tmp);
1394
1395
0
  if (ret < 0) {
1396
0
    gnutls_assert();
1397
0
    goto error;
1398
0
  }
1399
1400
0
  ret =
1401
0
      _gnutls_x509_read_value(pkcs8_asn,
1402
0
            "privateKeyAlgorithm.parameters", &tmp);
1403
0
  if (ret < 0) {
1404
0
    gnutls_assert();
1405
0
    goto error;
1406
0
  }
1407
1408
0
  ret =
1409
0
      _gnutls_x509_read_pubkey_params(GNUTLS_PK_DSA, tmp.data,
1410
0
              tmp.size, &pkey->params);
1411
0
  _gnutls_free_datum(&tmp);
1412
0
  if (ret < 0) {
1413
0
    gnutls_assert();
1414
0
    goto error;
1415
0
  }
1416
1417
0
  if (_gnutls_mpi_cmp_ui(pkey->params.params[0], 0) == 0) {
1418
0
    gnutls_assert();
1419
0
    ret = GNUTLS_E_ILLEGAL_PARAMETER;
1420
0
    goto error;
1421
0
  }
1422
1423
  /* the public key can be generated as g^x mod p */
1424
0
  ret = _gnutls_mpi_init(&pkey->params.params[3]);
1425
0
  if (ret < 0) {
1426
0
    gnutls_assert();
1427
0
    goto error;
1428
0
  }
1429
1430
0
  ret = _gnutls_mpi_powm(pkey->params.params[3], pkey->params.params[2],
1431
0
             pkey->params.params[4], pkey->params.params[0]);
1432
0
  if (ret < 0) {
1433
0
    gnutls_assert();
1434
0
    goto error;
1435
0
  }
1436
1437
0
  pkey->params.algo = GNUTLS_PK_DSA;
1438
0
  pkey->params.params_nr = DSA_PRIVATE_PARAMS;
1439
1440
0
  ret = _gnutls_asn1_encode_privkey(&pkey->key, &pkey->params);
1441
0
  if (ret < 0) {
1442
0
    gnutls_assert();
1443
0
    goto error;
1444
0
  }
1445
1446
0
  return 0;
1447
1448
0
 error:
1449
0
  if (pkey->params.params_nr != DSA_PRIVATE_PARAMS)
1450
0
    _gnutls_mpi_release(&pkey->params.params[4]);
1451
0
  return ret;
1452
0
}
1453
1454
static int
1455
decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
1456
0
{
1457
0
  int result, len;
1458
0
  char oid[MAX_OID_SIZE];
1459
0
  asn1_node pkcs8_asn = NULL;
1460
0
  gnutls_datum_t sder;
1461
0
  int ret;
1462
1463
0
  if ((result =
1464
0
       asn1_create_element(_gnutls_get_pkix(),
1465
0
         "PKIX1.pkcs-8-PrivateKeyInfo",
1466
0
         &pkcs8_asn)) != ASN1_SUCCESS) {
1467
0
    gnutls_assert();
1468
0
    result = _gnutls_asn2err(result);
1469
0
    goto error;
1470
0
  }
1471
1472
0
  result =
1473
0
      _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
1474
0
  if (result != ASN1_SUCCESS) {
1475
0
    gnutls_assert();
1476
0
    result = _gnutls_asn2err(result);
1477
0
    goto error;
1478
0
  }
1479
1480
  /* Check the private key algorithm OID
1481
   */
1482
0
  len = sizeof(oid);
1483
0
  result =
1484
0
      asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm",
1485
0
          oid, &len);
1486
0
  if (result != ASN1_SUCCESS) {
1487
0
    gnutls_assert();
1488
0
    result = _gnutls_asn2err(result);
1489
0
    goto error;
1490
0
  }
1491
1492
0
  pkey->params.algo = gnutls_oid_to_pk(oid);
1493
0
  if (pkey->params.algo == GNUTLS_PK_UNKNOWN) {
1494
0
    gnutls_assert();
1495
0
    _gnutls_debug_log
1496
0
        ("PKCS #8 private key OID '%s' is unsupported.\n", oid);
1497
0
    result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1498
0
    goto error;
1499
0
  }
1500
1501
  /* Get the DER encoding of the actual private key.
1502
   */
1503
1504
0
  switch (pkey->params.algo) {
1505
0
  case GNUTLS_PK_RSA:
1506
0
    result = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
1507
0
    break;
1508
0
  case GNUTLS_PK_RSA_PSS:
1509
0
    result = _decode_pkcs8_rsa_pss_key(pkcs8_asn, pkey);
1510
0
    break;
1511
0
  case GNUTLS_PK_DSA:
1512
0
    result = _decode_pkcs8_dsa_key(pkcs8_asn, pkey);
1513
0
    break;
1514
0
  case GNUTLS_PK_ECDSA:
1515
0
    result = _decode_pkcs8_ecc_key(pkcs8_asn, pkey);
1516
0
    break;
1517
0
  case GNUTLS_PK_EDDSA_ED25519:
1518
0
  case GNUTLS_PK_EDDSA_ED448:
1519
0
    result = _decode_pkcs8_eddsa_key(pkcs8_asn, pkey, oid);
1520
0
    break;
1521
0
  case GNUTLS_PK_ECDH_X25519:
1522
0
  case GNUTLS_PK_ECDH_X448:
1523
0
    result = _decode_pkcs8_modern_ecdh_key(pkcs8_asn, pkey, oid);
1524
0
    break;
1525
0
  case GNUTLS_PK_GOST_01:
1526
0
  case GNUTLS_PK_GOST_12_256:
1527
0
  case GNUTLS_PK_GOST_12_512:
1528
0
    result = _decode_pkcs8_gost_key(pkcs8_asn,
1529
0
            pkey, pkey->params.algo);
1530
0
    break;
1531
0
  default:
1532
0
    result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1533
0
    goto error;
1534
0
  }
1535
1536
0
  if (result < 0) {
1537
0
    gnutls_assert();
1538
0
    goto error;
1539
0
  }
1540
1541
  /* check for provable parameters attribute */
1542
0
  ret =
1543
0
      _x509_parse_attribute(pkcs8_asn, "attributes", OID_ATTR_PROV_SEED,
1544
0
          0, 1, &sder);
1545
0
  if (ret >= 0) {   /* ignore it when not being present */
1546
0
    ret = _x509_decode_provable_seed(pkey, &sder);
1547
0
    gnutls_free(sder.data);
1548
0
    if (ret < 0) {
1549
0
      gnutls_assert();
1550
0
    }
1551
0
  }
1552
1553
0
  result = 0;
1554
1555
0
 error:
1556
0
  asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
1557
0
  return result;
1558
1559
0
}
1560
1561
/**
1562
 * gnutls_x509_privkey_import_pkcs8:
1563
 * @key: The data to store the parsed key
1564
 * @data: The DER or PEM encoded key.
1565
 * @format: One of DER or PEM
1566
 * @password: the password to decrypt the key (if it is encrypted).
1567
 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
1568
 *
1569
 * This function will convert the given DER or PEM encoded PKCS8 2.0
1570
 * encrypted key to the native gnutls_x509_privkey_t format. The
1571
 * output will be stored in @key.  Both RSA and DSA keys can be
1572
 * imported, and flags can only be used to indicate an unencrypted
1573
 * key.
1574
 *
1575
 * The @password can be either ASCII or UTF-8 in the default PBES2
1576
 * encryption schemas, or ASCII for the PKCS12 schemas.
1577
 *
1578
 * If the Certificate is PEM encoded it should have a header of
1579
 * "ENCRYPTED PRIVATE KEY", or "PRIVATE KEY". You only need to
1580
 * specify the flags if the key is DER encoded, since in that case
1581
 * the encryption status cannot be auto-detected.
1582
 *
1583
 * If the %GNUTLS_PKCS_PLAIN flag is specified and the supplied data
1584
 * are encrypted then %GNUTLS_E_DECRYPTION_FAILED is returned.
1585
 *
1586
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1587
 *   negative error value.
1588
 **/
1589
int
1590
gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
1591
         const gnutls_datum_t * data,
1592
         gnutls_x509_crt_fmt_t format,
1593
         const char *password, unsigned int flags)
1594
0
{
1595
0
  int result = 0, need_free = 0;
1596
0
  gnutls_datum_t _data;
1597
1598
0
  if (key == NULL) {
1599
0
    gnutls_assert();
1600
0
    return GNUTLS_E_INVALID_REQUEST;
1601
0
  }
1602
1603
0
  _data.data = data->data;
1604
0
  _data.size = data->size;
1605
1606
0
  key->params.algo = GNUTLS_PK_UNKNOWN;
1607
1608
  /* If the Certificate is in PEM format then decode it
1609
   */
1610
0
  if (format == GNUTLS_X509_FMT_PEM) {
1611
    /* Try the first header 
1612
     */
1613
0
    result =
1614
0
        _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
1615
0
             data->data, data->size, &_data);
1616
1617
0
    if (result < 0) { /* Try the encrypted header 
1618
           */
1619
0
      result =
1620
0
          _gnutls_fbase64_decode(PEM_PKCS8, data->data,
1621
0
               data->size, &_data);
1622
1623
0
      if (result < 0) {
1624
0
        gnutls_assert();
1625
0
        return result;
1626
0
      }
1627
0
    } else if (flags == 0)
1628
0
      flags |= GNUTLS_PKCS_PLAIN;
1629
1630
0
    need_free = 1;
1631
0
  }
1632
1633
0
  if (key->expanded) {
1634
0
    _gnutls_x509_privkey_reinit(key);
1635
0
  }
1636
0
  key->expanded = 1;
1637
1638
  /* Here we don't check for password == NULL to maintain a backwards
1639
   * compatibility behavior, with old versions that were encrypting using
1640
   * a NULL password.
1641
   */
1642
0
  if (flags & GNUTLS_PKCS_PLAIN) {
1643
0
    result = decode_private_key_info(&_data, key);
1644
0
    if (result < 0) { /* check if it is encrypted */
1645
0
      if (pkcs8_key_decode(&_data, "", key, 0) == 0)
1646
0
        result = GNUTLS_E_DECRYPTION_FAILED;
1647
0
    }
1648
0
  } else {   /* encrypted. */
1649
0
    result = pkcs8_key_decode(&_data, password, key, 1);
1650
0
  }
1651
1652
0
  if (result < 0) {
1653
0
    gnutls_assert();
1654
0
    goto cleanup;
1655
0
  }
1656
1657
  /* This part is necessary to get the public key on certain algorithms.
1658
   * In the import above we only get the private key. */
1659
0
  result =
1660
0
      _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
1661
0
  if (result < 0) {
1662
0
    gnutls_assert();
1663
0
    goto cleanup;
1664
0
  }
1665
1666
0
  if (need_free)
1667
0
    _gnutls_free_datum(&_data);
1668
1669
  /* The key has now been decoded.
1670
   */
1671
0
  return 0;
1672
1673
0
 cleanup:
1674
0
  asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
1675
0
  key->params.algo = GNUTLS_PK_UNKNOWN;
1676
0
  if (need_free) {
1677
0
    zeroize_temp_key(_data.data, _data.size);
1678
0
    _gnutls_free_datum(&_data);
1679
0
  }
1680
0
  return result;
1681
0
}