Coverage Report

Created: 2024-07-23 07:36

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