Coverage Report

Created: 2026-08-14 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/privkey.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2012-2016 Nikos Mavrogiannopoulos
4
 * Copyright (C) 2015-2017 Red Hat, Inc.
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
#include "datum.h"
27
#include "global.h"
28
#include "errors.h"
29
#include "tls-sig.h"
30
#include "common.h"
31
#include "x509.h"
32
#include "x509_b64.h"
33
#include "x509_int.h"
34
#include "pk.h"
35
#include "mpi.h"
36
#include "ecc.h"
37
#include "pin.h"
38
39
/**
40
 * gnutls_x509_privkey_init:
41
 * @key: A pointer to the type to be initialized
42
 *
43
 * This function will initialize a private key type.
44
 *
45
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
46
 *   negative error value.
47
 **/
48
int gnutls_x509_privkey_init(gnutls_x509_privkey_t *key)
49
0
{
50
0
  *key = NULL;
51
0
  FAIL_IF_LIB_ERROR;
52
53
0
  *key = gnutls_calloc(1, sizeof(gnutls_x509_privkey_int));
54
55
0
  if (*key) {
56
0
    (*key)->key = NULL;
57
0
    return 0; /* success */
58
0
  }
59
60
0
  return GNUTLS_E_MEMORY_ERROR;
61
0
}
62
63
void _gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key)
64
0
{
65
0
  gnutls_pk_params_clear(&key->params);
66
0
  gnutls_pk_params_release(&key->params);
67
  /* avoid reuse of fields which may have had some sensible value */
68
0
  zeroize_key(&key->params, sizeof(key->params));
69
70
0
  if (key->key)
71
0
    asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
72
0
  key->key = NULL;
73
0
}
74
75
/**
76
 * gnutls_x509_privkey_deinit:
77
 * @key: The key to be deinitialized
78
 *
79
 * This function will deinitialize a private key structure.
80
 **/
81
void gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key)
82
0
{
83
0
  if (!key)
84
0
    return;
85
86
0
  _gnutls_x509_privkey_reinit(key);
87
0
  gnutls_free(key);
88
0
}
89
90
/**
91
 * gnutls_x509_privkey_cpy:
92
 * @dst: The destination key, which should be initialized.
93
 * @src: The source key
94
 *
95
 * This function will copy a private key from source to destination
96
 * key. Destination has to be initialized.
97
 *
98
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
99
 *   negative error value.
100
 **/
101
int gnutls_x509_privkey_cpy(gnutls_x509_privkey_t dst,
102
          gnutls_x509_privkey_t src)
103
0
{
104
0
  int ret;
105
106
0
  if (!src || !dst)
107
0
    return GNUTLS_E_INVALID_REQUEST;
108
109
0
  ret = _gnutls_pk_params_copy(&dst->params, &src->params);
110
0
  if (ret < 0) {
111
0
    return gnutls_assert_val(ret);
112
0
  }
113
114
0
  ret = _gnutls_asn1_encode_privkey(&dst->key, &dst->params);
115
0
  if (ret < 0) {
116
0
    gnutls_assert();
117
0
    gnutls_pk_params_release(&dst->params);
118
0
    return ret;
119
0
  }
120
121
0
  return 0;
122
0
}
123
124
/* Converts an RSA PKCS#1 key to
125
 * an internal structure (gnutls_private_key)
126
 */
127
asn1_node _gnutls_privkey_decode_pkcs1_rsa_key(const gnutls_datum_t *raw_key,
128
                 gnutls_x509_privkey_t pkey)
129
0
{
130
0
  int result;
131
0
  asn1_node pkey_asn;
132
133
0
  gnutls_pk_params_init(&pkey->params);
134
135
0
  if (asn1_create_element(_gnutls_get_gnutls_asn(),
136
0
        "GNUTLS.RSAPrivateKey",
137
0
        &pkey_asn) != ASN1_SUCCESS) {
138
0
    gnutls_assert();
139
0
    return NULL;
140
0
  }
141
142
0
  result = _asn1_strict_der_decode(&pkey_asn, raw_key->data,
143
0
           raw_key->size, NULL);
144
0
  if (result != ASN1_SUCCESS) {
145
0
    gnutls_assert();
146
0
    goto error;
147
0
  }
148
149
0
  if (_gnutls_x509_read_int(pkey_asn, "modulus",
150
0
          &pkey->params.params[0]) < 0) {
151
0
    gnutls_assert();
152
0
    goto error;
153
0
  }
154
0
  pkey->params.params_nr++;
155
156
0
  if (_gnutls_x509_read_int(pkey_asn, "publicExponent",
157
0
          &pkey->params.params[1]) < 0) {
158
0
    gnutls_assert();
159
0
    goto error;
160
0
  }
161
0
  pkey->params.params_nr++;
162
163
0
  if (_gnutls_x509_read_key_int(pkey_asn, "privateExponent",
164
0
              &pkey->params.params[2]) < 0) {
165
0
    gnutls_assert();
166
0
    goto error;
167
0
  }
168
0
  pkey->params.params_nr++;
169
170
0
  if (_gnutls_x509_read_key_int(pkey_asn, "prime1",
171
0
              &pkey->params.params[3]) < 0) {
172
0
    gnutls_assert();
173
0
    goto error;
174
0
  }
175
0
  pkey->params.params_nr++;
176
177
0
  if (_gnutls_x509_read_key_int(pkey_asn, "prime2",
178
0
              &pkey->params.params[4]) < 0) {
179
0
    gnutls_assert();
180
0
    goto error;
181
0
  }
182
0
  pkey->params.params_nr++;
183
184
0
  if (_gnutls_x509_read_key_int(pkey_asn, "coefficient",
185
0
              &pkey->params.params[5]) < 0) {
186
0
    gnutls_assert();
187
0
    goto error;
188
0
  }
189
0
  pkey->params.params_nr++;
190
191
0
  if (_gnutls_x509_read_key_int(pkey_asn, "exponent1",
192
0
              &pkey->params.params[6]) < 0) {
193
0
    gnutls_assert();
194
0
    goto error;
195
0
  }
196
0
  pkey->params.params_nr++;
197
198
0
  if (_gnutls_x509_read_key_int(pkey_asn, "exponent2",
199
0
              &pkey->params.params[7]) < 0) {
200
0
    gnutls_assert();
201
0
    goto error;
202
0
  }
203
0
  pkey->params.params_nr++;
204
205
0
  pkey->params.params_nr = RSA_PRIVATE_PARAMS;
206
0
  pkey->params.algo = GNUTLS_PK_RSA;
207
208
0
  return pkey_asn;
209
210
0
error:
211
0
  asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
212
0
  gnutls_pk_params_clear(&pkey->params);
213
0
  gnutls_pk_params_release(&pkey->params);
214
0
  return NULL;
215
0
}
216
217
/* Converts an ECC key to
218
 * an internal structure (gnutls_private_key)
219
 */
220
int _gnutls_privkey_decode_ecc_key(asn1_node *pkey_asn,
221
           const gnutls_datum_t *raw_key,
222
           gnutls_x509_privkey_t pkey,
223
           gnutls_ecc_curve_t curve)
224
0
{
225
0
  int ret;
226
0
  unsigned int version;
227
0
  char oid[MAX_OID_SIZE];
228
0
  int oid_size;
229
0
  gnutls_datum_t out;
230
231
0
  if (curve_is_eddsa(curve)) {
232
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
233
0
  }
234
235
0
  gnutls_pk_params_init(&pkey->params);
236
237
0
  if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
238
0
               "GNUTLS.ECPrivateKey", pkey_asn)) !=
239
0
      ASN1_SUCCESS) {
240
0
    gnutls_assert();
241
0
    return _gnutls_asn2err(ret);
242
0
  }
243
244
0
  ret = _asn1_strict_der_decode(pkey_asn, raw_key->data, raw_key->size,
245
0
              NULL);
246
0
  if (ret != ASN1_SUCCESS) {
247
0
    gnutls_assert();
248
0
    ret = _gnutls_asn2err(ret);
249
0
    goto error;
250
0
  }
251
252
0
  ret = _gnutls_x509_read_uint(*pkey_asn, "Version", &version);
253
0
  if (ret < 0) {
254
0
    gnutls_assert();
255
0
    goto error;
256
0
  }
257
258
0
  if (version != 1) {
259
0
    _gnutls_debug_log(
260
0
      "ECC private key version %u is not supported\n",
261
0
      version);
262
0
    gnutls_assert();
263
0
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
264
0
    goto error;
265
0
  }
266
267
  /* read the curve */
268
0
  if (curve == GNUTLS_ECC_CURVE_INVALID) {
269
0
    oid_size = sizeof(oid);
270
0
    ret = asn1_read_value(*pkey_asn, "parameters.namedCurve", oid,
271
0
              &oid_size);
272
0
    if (ret != ASN1_SUCCESS) {
273
0
      gnutls_assert();
274
0
      ret = _gnutls_asn2err(ret);
275
0
      goto error;
276
0
    }
277
278
0
    pkey->params.curve = gnutls_oid_to_ecc_curve(oid);
279
280
0
    if (pkey->params.curve == GNUTLS_ECC_CURVE_INVALID) {
281
0
      _gnutls_debug_log("Curve %s is not supported\n", oid);
282
0
      gnutls_assert();
283
0
      ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
284
0
      goto error;
285
0
    }
286
0
  } else {
287
0
    pkey->params.curve = curve;
288
0
  }
289
290
  /* read the public key */
291
0
  ret = _gnutls_x509_read_value(*pkey_asn, "publicKey", &out);
292
0
  if (ret < 0) {
293
0
    gnutls_assert();
294
0
    goto error;
295
0
  }
296
297
0
  ret = _gnutls_ecc_ansi_x962_import(out.data, out.size,
298
0
             &pkey->params.params[ECC_X],
299
0
             &pkey->params.params[ECC_Y]);
300
301
0
  _gnutls_free_datum(&out);
302
0
  if (ret < 0) {
303
0
    gnutls_assert();
304
0
    goto error;
305
0
  }
306
0
  pkey->params.params_nr += 2;
307
308
  /* read the private key */
309
0
  ret = _gnutls_x509_read_key_int(*pkey_asn, "privateKey",
310
0
          &pkey->params.params[ECC_K]);
311
0
  if (ret < 0) {
312
0
    gnutls_assert();
313
0
    goto error;
314
0
  }
315
0
  pkey->params.params_nr++;
316
0
  pkey->params.algo = GNUTLS_PK_EC;
317
318
0
  return 0;
319
320
0
error:
321
0
  asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
322
0
  gnutls_pk_params_clear(&pkey->params);
323
0
  gnutls_pk_params_release(&pkey->params);
324
0
  return ret;
325
0
}
326
327
static int decode_ml_dsa_key(asn1_node *pkey_asn, const gnutls_datum_t *raw_key,
328
           gnutls_x509_privkey_t pkey)
329
0
{
330
0
  int result, ret;
331
0
  unsigned int version;
332
0
  char oid[MAX_OID_SIZE];
333
0
  int oid_size;
334
0
  size_t raw_pub_size, raw_priv_size;
335
336
0
  result = _asn1_strict_der_decode(pkey_asn, raw_key->data, raw_key->size,
337
0
           NULL);
338
0
  if (result != ASN1_SUCCESS) {
339
0
    gnutls_assert();
340
0
    return _gnutls_asn2err(result);
341
0
  }
342
343
0
  ret = _gnutls_x509_read_uint(*pkey_asn, "version", &version);
344
0
  if (ret < 0) {
345
0
    gnutls_assert();
346
0
    return ret;
347
0
  }
348
349
0
  oid_size = sizeof(oid);
350
0
  result = asn1_read_value(*pkey_asn, "privateKeyAlgorithm.algorithm",
351
0
         oid, &oid_size);
352
0
  if (result != ASN1_SUCCESS) {
353
0
    gnutls_assert();
354
0
    return _gnutls_asn2err(result);
355
0
  }
356
357
0
  pkey->params.algo = gnutls_oid_to_pk(oid);
358
359
0
  switch (pkey->params.algo) {
360
0
  case GNUTLS_PK_MLDSA44:
361
0
    raw_priv_size = MLDSA44_PRIVKEY_SIZE;
362
0
    raw_pub_size = MLDSA44_PUBKEY_SIZE;
363
0
    break;
364
0
  case GNUTLS_PK_MLDSA65:
365
0
    raw_priv_size = MLDSA65_PRIVKEY_SIZE;
366
0
    raw_pub_size = MLDSA65_PUBKEY_SIZE;
367
0
    break;
368
0
  case GNUTLS_PK_MLDSA87:
369
0
    raw_priv_size = MLDSA87_PRIVKEY_SIZE;
370
0
    raw_pub_size = MLDSA87_PUBKEY_SIZE;
371
0
    break;
372
0
  default:
373
0
    return gnutls_assert_val(
374
0
      GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
375
0
  }
376
377
0
  ret = _gnutls_x509_read_value(*pkey_asn, "privateKey",
378
0
              &pkey->params.raw_priv);
379
0
  if (ret < 0) {
380
0
    gnutls_assert();
381
0
    return ret;
382
0
  }
383
384
0
  switch (version) {
385
0
  case 0:
386
    /* if version is 0, public key is embedded in
387
     * privateKey field, concatenated after a private
388
     * key */
389
0
    if (pkey->params.raw_priv.size != raw_priv_size + raw_pub_size)
390
0
      return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
391
0
    ret = _gnutls_set_datum(
392
0
      &pkey->params.raw_pub,
393
0
      &pkey->params.raw_priv.data[raw_priv_size],
394
0
      raw_pub_size);
395
0
    if (ret < 0) {
396
0
      gnutls_assert();
397
0
      return ret;
398
0
    }
399
0
    pkey->params.raw_priv.size = raw_priv_size;
400
0
    break;
401
0
  case 1:
402
    /* if version is 1, public key is embedded in a
403
     * separate field */
404
0
    ret = _gnutls_x509_read_value(*pkey_asn, "publicKey",
405
0
                &pkey->params.raw_pub);
406
0
    if (ret < 0) {
407
0
      gnutls_assert();
408
0
      return ret;
409
0
    }
410
0
    break;
411
0
  default:
412
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
413
0
  }
414
415
0
  if (pkey->params.raw_pub.size != raw_pub_size ||
416
0
      pkey->params.raw_priv.size != raw_priv_size)
417
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
418
419
0
  return GNUTLS_E_SUCCESS;
420
0
}
421
422
static int _gnutls_privkey_decode_ml_dsa_key(asn1_node *pkey_asn,
423
               const gnutls_datum_t *raw_key,
424
               gnutls_x509_privkey_t pkey)
425
0
{
426
0
  int result;
427
428
0
  gnutls_pk_params_init(&pkey->params);
429
430
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
431
0
            "GNUTLS.MLDSAPrivateKey",
432
0
            pkey_asn)) != ASN1_SUCCESS) {
433
0
    gnutls_assert();
434
0
    return _gnutls_asn2err(result);
435
0
  }
436
437
0
  result = decode_ml_dsa_key(pkey_asn, raw_key, pkey);
438
0
  asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
439
0
  if (result < 0) {
440
0
    gnutls_pk_params_clear(&pkey->params);
441
0
    gnutls_pk_params_release(&pkey->params);
442
0
  }
443
444
0
  return result;
445
0
}
446
447
static asn1_node decode_dsa_key(const gnutls_datum_t *raw_key,
448
        gnutls_x509_privkey_t pkey)
449
0
{
450
0
  int result;
451
0
  asn1_node dsa_asn;
452
0
  gnutls_datum_t seed = { NULL, 0 };
453
0
  char oid[MAX_OID_SIZE];
454
0
  int oid_size;
455
456
0
  if (asn1_create_element(_gnutls_get_gnutls_asn(),
457
0
        "GNUTLS.DSAPrivateKey",
458
0
        &dsa_asn) != ASN1_SUCCESS) {
459
0
    gnutls_assert();
460
0
    return NULL;
461
0
  }
462
463
0
  gnutls_pk_params_init(&pkey->params);
464
465
0
  result = _asn1_strict_der_decode(&dsa_asn, raw_key->data, raw_key->size,
466
0
           NULL);
467
0
  if (result != ASN1_SUCCESS) {
468
0
    gnutls_assert();
469
0
    goto error;
470
0
  }
471
472
0
  if (_gnutls_x509_read_int(dsa_asn, "p", &pkey->params.params[0]) < 0) {
473
0
    gnutls_assert();
474
0
    goto error;
475
0
  }
476
0
  pkey->params.params_nr++;
477
478
0
  if (_gnutls_x509_read_int(dsa_asn, "q", &pkey->params.params[1]) < 0) {
479
0
    gnutls_assert();
480
0
    goto error;
481
0
  }
482
0
  pkey->params.params_nr++;
483
484
0
  if (_gnutls_x509_read_int(dsa_asn, "g", &pkey->params.params[2]) < 0) {
485
0
    gnutls_assert();
486
0
    goto error;
487
0
  }
488
0
  pkey->params.params_nr++;
489
490
0
  if (_gnutls_x509_read_int(dsa_asn, "Y", &pkey->params.params[3]) < 0) {
491
0
    gnutls_assert();
492
0
    goto error;
493
0
  }
494
0
  pkey->params.params_nr++;
495
496
0
  if (_gnutls_x509_read_key_int(dsa_asn, "priv",
497
0
              &pkey->params.params[4]) < 0) {
498
0
    gnutls_assert();
499
0
    goto error;
500
0
  }
501
0
  pkey->params.params_nr++;
502
0
  pkey->params.algo = GNUTLS_PK_DSA;
503
504
0
  oid_size = sizeof(oid);
505
0
  result = asn1_read_value(dsa_asn, "seed.algorithm", oid, &oid_size);
506
0
  if (result == ASN1_SUCCESS) {
507
0
    pkey->params.palgo = gnutls_oid_to_digest(oid);
508
509
0
    result = _gnutls_x509_read_value(dsa_asn, "seed.seed", &seed);
510
0
    if (result == ASN1_SUCCESS) {
511
0
      if (seed.size <= sizeof(pkey->params.seed)) {
512
0
        memcpy(pkey->params.seed, seed.data, seed.size);
513
0
        pkey->params.seed_size = seed.size;
514
0
      }
515
0
      gnutls_free(seed.data);
516
0
    }
517
0
  }
518
519
0
  return dsa_asn;
520
521
0
error:
522
0
  asn1_delete_structure2(&dsa_asn, ASN1_DELETE_FLAG_ZEROIZE);
523
0
  gnutls_pk_params_clear(&pkey->params);
524
0
  gnutls_pk_params_release(&pkey->params);
525
0
  return NULL;
526
0
}
527
528
0
#define PEM_KEY_DSA "DSA PRIVATE KEY"
529
0
#define PEM_KEY_RSA "RSA PRIVATE KEY"
530
0
#define PEM_KEY_ECC "EC PRIVATE KEY"
531
0
#define PEM_KEY_ML_DSA "ML-DSA PRIVATE KEY"
532
0
#define PEM_KEY_PKCS8 "PRIVATE KEY"
533
534
0
#define MAX_PEM_HEADER_SIZE 25
535
536
/**
537
 * gnutls_x509_privkey_import:
538
 * @key: The data to store the parsed key
539
 * @data: The DER or PEM encoded certificate.
540
 * @format: One of DER or PEM
541
 *
542
 * This function will convert the given DER or PEM encoded key to the
543
 * native #gnutls_x509_privkey_t format. The output will be stored in
544
 * @key .
545
 *
546
 * If the key is PEM encoded it should have a header that contains "PRIVATE
547
 * KEY". Note that this function falls back to PKCS #8 decoding without
548
 * password, if the default format fails to import.
549
 *
550
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
551
 *   negative error value.
552
 **/
553
int gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
554
             const gnutls_datum_t *data,
555
             gnutls_x509_crt_fmt_t format)
556
0
{
557
0
  int result = 0, need_free = 0;
558
0
  gnutls_datum_t _data;
559
560
0
  if (key == NULL) {
561
0
    gnutls_assert();
562
0
    return GNUTLS_E_INVALID_REQUEST;
563
0
  }
564
565
0
  _data.data = data->data;
566
0
  _data.size = data->size;
567
568
0
  key->params.algo = GNUTLS_PK_UNKNOWN;
569
570
  /* If the Certificate is in PEM format then decode it
571
   */
572
0
  if (format == GNUTLS_X509_FMT_PEM) {
573
0
    unsigned left;
574
0
    char *ptr;
575
0
    uint8_t *begin_ptr;
576
577
0
    ptr = memmem(data->data, data->size, "PRIVATE KEY-----",
578
0
           sizeof("PRIVATE KEY-----") - 1);
579
580
0
    result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
581
582
0
    if (ptr != NULL) {
583
0
      left = data->size -
584
0
             ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
585
586
0
      if (data->size - left > MAX_PEM_HEADER_SIZE) {
587
0
        ptr -= MAX_PEM_HEADER_SIZE;
588
0
        left += MAX_PEM_HEADER_SIZE;
589
0
      } else {
590
0
        ptr = (char *)data->data;
591
0
        left = data->size;
592
0
      }
593
594
0
      ptr = memmem(ptr, left, "-----BEGIN ",
595
0
             sizeof("-----BEGIN ") - 1);
596
0
      if (ptr != NULL) {
597
0
        begin_ptr = (uint8_t *)ptr;
598
0
        left = data->size - ((ptrdiff_t)begin_ptr -
599
0
                 (ptrdiff_t)data->data);
600
601
0
        ptr += sizeof("-----BEGIN ") - 1;
602
603
0
        if (left > sizeof(PEM_KEY_RSA) &&
604
0
            memeq(ptr, PEM_KEY_RSA,
605
0
            sizeof(PEM_KEY_RSA) - 1)) {
606
0
          result = _gnutls_fbase64_decode(
607
0
            PEM_KEY_RSA, begin_ptr, left,
608
0
            &_data);
609
0
          if (result >= 0)
610
0
            key->params.algo =
611
0
              GNUTLS_PK_RSA;
612
0
        } else if (left > sizeof(PEM_KEY_ECC) &&
613
0
             memeq(ptr, PEM_KEY_ECC,
614
0
             sizeof(PEM_KEY_ECC) - 1)) {
615
0
          result = _gnutls_fbase64_decode(
616
0
            PEM_KEY_ECC, begin_ptr, left,
617
0
            &_data);
618
0
          if (result >= 0)
619
0
            key->params.algo = GNUTLS_PK_EC;
620
0
        } else if (left > sizeof(PEM_KEY_DSA) &&
621
0
             memeq(ptr, PEM_KEY_DSA,
622
0
             sizeof(PEM_KEY_DSA) - 1)) {
623
0
          result = _gnutls_fbase64_decode(
624
0
            PEM_KEY_DSA, begin_ptr, left,
625
0
            &_data);
626
0
          if (result >= 0)
627
0
            key->params.algo =
628
0
              GNUTLS_PK_DSA;
629
0
        } else if (left > sizeof(PEM_KEY_ML_DSA) &&
630
0
             memeq(ptr, PEM_KEY_ML_DSA,
631
0
             sizeof(PEM_KEY_ML_DSA) - 1)) {
632
0
          result = _gnutls_fbase64_decode(
633
0
            PEM_KEY_ML_DSA, begin_ptr, left,
634
0
            &_data);
635
0
          if (result >= 0) {
636
0
            key->params.algo =
637
0
              GNUTLS_PK_MLDSA44;
638
0
          }
639
0
        }
640
641
0
        if (key->params.algo == GNUTLS_PK_UNKNOWN &&
642
0
            left >= sizeof(PEM_KEY_PKCS8)) {
643
0
          if (memeq(ptr, PEM_KEY_PKCS8,
644
0
              sizeof(PEM_KEY_PKCS8) - 1)) {
645
0
            result = _gnutls_fbase64_decode(
646
0
              PEM_KEY_PKCS8,
647
0
              begin_ptr, left,
648
0
              &_data);
649
0
            if (result >= 0) {
650
              /* signal for PKCS #8 keys */
651
0
              key->params.algo = -1;
652
0
            }
653
0
          }
654
0
        }
655
0
      }
656
0
    }
657
658
0
    if (result < 0) {
659
0
      gnutls_assert();
660
0
      return result;
661
0
    }
662
663
0
    need_free = 1;
664
0
  }
665
666
0
  if (key->expanded) {
667
0
    _gnutls_x509_privkey_reinit(key);
668
0
  }
669
0
  key->expanded = 1;
670
671
0
  if (key->params.algo == (gnutls_pk_algorithm_t)-1) {
672
0
    result = gnutls_x509_privkey_import_pkcs8(
673
0
      key, data, format, NULL, GNUTLS_PKCS_PLAIN);
674
0
    if (result < 0) {
675
0
      gnutls_assert();
676
0
      key->key = NULL;
677
0
      goto cleanup;
678
0
    } else {
679
      /* some keys under PKCS#8 don't set key->key */
680
0
      goto finish;
681
0
    }
682
0
  } else if (key->params.algo == GNUTLS_PK_RSA) {
683
0
    key->key = _gnutls_privkey_decode_pkcs1_rsa_key(&_data, key);
684
0
    if (key->key == NULL)
685
0
      gnutls_assert();
686
0
  } else if (key->params.algo == GNUTLS_PK_DSA) {
687
0
    key->key = decode_dsa_key(&_data, key);
688
0
    if (key->key == NULL)
689
0
      gnutls_assert();
690
0
  } else if (key->params.algo == GNUTLS_PK_EC) {
691
0
    result = _gnutls_privkey_decode_ecc_key(&key->key, &_data, key,
692
0
              0);
693
0
    if (result < 0) {
694
0
      gnutls_assert();
695
0
      key->key = NULL;
696
0
    }
697
0
  } else if (IS_ML_DSA(key->params.algo)) {
698
0
    result = _gnutls_privkey_decode_ml_dsa_key(&key->key, &_data,
699
0
                 key);
700
0
    if (result < 0) {
701
0
      gnutls_assert();
702
0
      key->key = NULL;
703
0
    }
704
0
  } else {
705
    /* Try decoding each of the keys, and accept the one that
706
     * succeeds.
707
     */
708
0
    key->params.algo = GNUTLS_PK_RSA;
709
0
    key->key = _gnutls_privkey_decode_pkcs1_rsa_key(&_data, key);
710
711
0
    if (key->key == NULL) {
712
0
      key->params.algo = GNUTLS_PK_DSA;
713
0
      key->key = decode_dsa_key(&_data, key);
714
0
      if (key->key == NULL) {
715
0
        key->params.algo = GNUTLS_PK_EC;
716
0
        result = _gnutls_privkey_decode_ecc_key(
717
0
          &key->key, &_data, key, 0);
718
0
        if (result < 0) {
719
0
          result =
720
0
            gnutls_x509_privkey_import_pkcs8(
721
0
              key, data, format, NULL,
722
0
              GNUTLS_PKCS_PLAIN);
723
0
          if (result >= 0) {
724
            /* there are keys (ed25519) which leave key->key NULL */
725
0
            goto finish;
726
0
          }
727
728
          /* result < 0 */
729
0
          gnutls_assert();
730
0
          key->key = NULL;
731
732
0
          if (result ==
733
0
              GNUTLS_E_PK_INVALID_PRIVKEY)
734
0
            goto cleanup;
735
0
        }
736
0
      }
737
0
    }
738
0
  }
739
740
0
  if (key->key == NULL) {
741
0
    gnutls_assert();
742
0
    result = GNUTLS_E_ASN1_DER_ERROR;
743
0
    goto cleanup;
744
0
  }
745
746
0
finish:
747
0
  result =
748
0
    _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
749
0
  if (result < 0) {
750
0
    gnutls_assert();
751
0
  }
752
753
0
cleanup:
754
0
  if (need_free) {
755
0
    zeroize_key(_data.data, _data.size);
756
0
    _gnutls_free_datum(&_data);
757
0
  }
758
759
  /* The key has now been decoded.
760
   */
761
762
0
  return result;
763
0
}
764
765
static int import_pkcs12_privkey(gnutls_x509_privkey_t key,
766
         const gnutls_datum_t *data,
767
         gnutls_x509_crt_fmt_t format,
768
         const char *password, unsigned int flags)
769
0
{
770
0
  int ret;
771
0
  gnutls_pkcs12_t p12;
772
0
  gnutls_x509_privkey_t newkey;
773
774
0
  ret = gnutls_pkcs12_init(&p12);
775
0
  if (ret < 0)
776
0
    return gnutls_assert_val(ret);
777
778
0
  ret = gnutls_pkcs12_import(p12, data, format, flags);
779
0
  if (ret < 0) {
780
0
    gnutls_assert();
781
0
    goto fail;
782
0
  }
783
784
0
  ret = gnutls_pkcs12_simple_parse(p12, password, &newkey, NULL, NULL,
785
0
           NULL, NULL, NULL, 0);
786
0
  if (ret < 0) {
787
0
    gnutls_assert();
788
0
    goto fail;
789
0
  }
790
791
0
  ret = gnutls_x509_privkey_cpy(key, newkey);
792
0
  gnutls_x509_privkey_deinit(newkey);
793
0
  if (ret < 0) {
794
0
    gnutls_assert();
795
0
    goto fail;
796
0
  }
797
798
0
  ret = 0;
799
0
fail:
800
801
0
  gnutls_pkcs12_deinit(p12);
802
803
0
  return ret;
804
0
}
805
806
0
#define MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER 21
807
808
/**
809
 * gnutls_x509_privkey_import2:
810
 * @key: The data to store the parsed key
811
 * @data: The DER or PEM encoded key.
812
 * @format: One of DER or PEM
813
 * @password: A password (optional)
814
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
815
 *
816
 * This function will import the given DER or PEM encoded key, to 
817
 * the native #gnutls_x509_privkey_t format, irrespective of the
818
 * input format. The input format is auto-detected.
819
 *
820
 * The supported formats are basic unencrypted key, PKCS8, PKCS12,
821
 * and the openssl format.
822
 *
823
 * If the provided key is encrypted but no password was given, then
824
 * %GNUTLS_E_DECRYPTION_FAILED is returned. Since GnuTLS 3.4.0 this
825
 * function will utilize the PIN callbacks if any.
826
 *
827
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
828
 *   negative error value.
829
 **/
830
int gnutls_x509_privkey_import2(gnutls_x509_privkey_t key,
831
        const gnutls_datum_t *data,
832
        gnutls_x509_crt_fmt_t format,
833
        const char *password, unsigned int flags)
834
0
{
835
0
  int ret = 0;
836
0
  int saved_ret = GNUTLS_E_PARSING_ERROR;
837
0
  char pin[GNUTLS_PKCS11_MAX_PIN_LEN];
838
0
  unsigned head_enc = 1;
839
840
0
  if (format == GNUTLS_X509_FMT_PEM) {
841
0
    size_t left;
842
0
    char *ptr;
843
844
0
    ptr = memmem(data->data, data->size, "PRIVATE KEY-----",
845
0
           sizeof("PRIVATE KEY-----") - 1);
846
847
0
    if (ptr != NULL) {
848
0
      left = data->size -
849
0
             ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
850
851
0
      if (data->size - left >
852
0
          MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER) {
853
0
        ptr -= MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER;
854
0
        left += MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER;
855
0
      } else {
856
0
        ptr = (char *)data->data;
857
0
        left = data->size;
858
0
      }
859
860
0
      ptr = memmem(ptr, left, "-----BEGIN ",
861
0
             sizeof("-----BEGIN ") - 1);
862
0
      if (ptr != NULL) {
863
0
        ptr += sizeof("-----BEGIN ") - 1;
864
0
        left = data->size -
865
0
               ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
866
0
      }
867
868
0
      if (ptr != NULL) {
869
0
        if ((left > sizeof(PEM_KEY_RSA) &&
870
0
             memeq(ptr, PEM_KEY_RSA,
871
0
             sizeof(PEM_KEY_RSA) - 1)) ||
872
0
            (left > sizeof(PEM_KEY_ECC) &&
873
0
             memeq(ptr, PEM_KEY_ECC,
874
0
             sizeof(PEM_KEY_ECC) - 1)) ||
875
0
            (left > sizeof(PEM_KEY_DSA) &&
876
0
             memeq(ptr, PEM_KEY_DSA,
877
0
             sizeof(PEM_KEY_DSA) - 1)) ||
878
0
            (left > sizeof(PEM_KEY_ML_DSA) &&
879
0
             memeq(ptr, PEM_KEY_ML_DSA,
880
0
             sizeof(PEM_KEY_ML_DSA) - 1))) {
881
0
          head_enc = 0;
882
0
        }
883
0
      }
884
0
    }
885
0
  }
886
887
0
  if (head_enc == 0 ||
888
0
      (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD))) {
889
0
    ret = gnutls_x509_privkey_import(key, data, format);
890
0
    if (ret >= 0)
891
0
      return ret;
892
893
0
    gnutls_assert();
894
0
    saved_ret = ret;
895
    /* fall through to PKCS #8 decoding */
896
0
  }
897
898
0
  if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD)) ||
899
0
      ret < 0) {
900
0
    ret = gnutls_x509_privkey_import_pkcs8(key, data, format,
901
0
                   password, flags);
902
903
0
    if (ret == GNUTLS_E_DECRYPTION_FAILED && password == NULL &&
904
0
        (!(flags & GNUTLS_PKCS_PLAIN))) {
905
      /* use the callback if any */
906
0
      ret = _gnutls_retrieve_pin(&key->pin, "key:", "", 0,
907
0
               pin, sizeof(pin));
908
0
      if (ret == 0) {
909
0
        password = pin;
910
0
      }
911
912
0
      ret = gnutls_x509_privkey_import_pkcs8(
913
0
        key, data, format, password, flags);
914
0
    }
915
916
0
    if (saved_ret == GNUTLS_E_PARSING_ERROR)
917
0
      saved_ret = ret;
918
919
0
    if (ret < 0) {
920
0
      if (ret == GNUTLS_E_DECRYPTION_FAILED)
921
0
        goto cleanup;
922
0
      ret = import_pkcs12_privkey(key, data, format, password,
923
0
                flags);
924
0
      if (ret < 0 && format == GNUTLS_X509_FMT_PEM) {
925
0
        if (ret == GNUTLS_E_DECRYPTION_FAILED)
926
0
          goto cleanup;
927
928
0
        ret = gnutls_x509_privkey_import_openssl(
929
0
          key, data, password);
930
931
0
        if (ret == GNUTLS_E_DECRYPTION_FAILED &&
932
0
            password == NULL &&
933
0
            (key->pin.cb || _gnutls_pin_func)) {
934
          /* use the callback if any */
935
0
          memset(pin, 0,
936
0
                 GNUTLS_PKCS11_MAX_PIN_LEN);
937
0
          ret = _gnutls_retrieve_pin(&key->pin,
938
0
                   "key:", "",
939
0
                   0, pin,
940
0
                   sizeof(pin));
941
0
          if (ret == 0) {
942
0
            ret = gnutls_x509_privkey_import_openssl(
943
0
              key, data, pin);
944
0
          }
945
0
        }
946
947
0
        if (ret < 0) {
948
0
          gnutls_assert();
949
0
          goto cleanup;
950
0
        }
951
0
      } else {
952
0
        gnutls_assert();
953
0
        goto cleanup;
954
0
      }
955
0
    }
956
0
  }
957
958
0
  ret = 0;
959
960
0
cleanup:
961
0
  if (ret == GNUTLS_E_PARSING_ERROR)
962
0
    ret = saved_ret;
963
964
0
  return ret;
965
0
}
966
967
/**
968
 * gnutls_x509_privkey_import_rsa_raw:
969
 * @key: The data to store the parsed key
970
 * @m: holds the modulus
971
 * @e: holds the public exponent
972
 * @d: holds the private exponent
973
 * @p: holds the first prime (p)
974
 * @q: holds the second prime (q)
975
 * @u: holds the coefficient
976
 *
977
 * This function will convert the given RSA raw parameters to the
978
 * native #gnutls_x509_privkey_t format.  The output will be stored in
979
 * @key.
980
 *
981
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
982
 *   negative error value.
983
 **/
984
int gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
985
               const gnutls_datum_t *m,
986
               const gnutls_datum_t *e,
987
               const gnutls_datum_t *d,
988
               const gnutls_datum_t *p,
989
               const gnutls_datum_t *q,
990
               const gnutls_datum_t *u)
991
0
{
992
0
  return gnutls_x509_privkey_import_rsa_raw2(key, m, e, d, p, q, u, NULL,
993
0
               NULL);
994
0
}
995
996
/**
997
 * gnutls_x509_privkey_import_rsa_raw2:
998
 * @key: The data to store the parsed key
999
 * @m: holds the modulus
1000
 * @e: holds the public exponent
1001
 * @d: holds the private exponent
1002
 * @p: holds the first prime (p)
1003
 * @q: holds the second prime (q)
1004
 * @u: holds the coefficient (optional)
1005
 * @e1: holds e1 = d mod (p-1) (optional)
1006
 * @e2: holds e2 = d mod (q-1) (optional)
1007
 *
1008
 * This function will convert the given RSA raw parameters to the
1009
 * native #gnutls_x509_privkey_t format.  The output will be stored in
1010
 * @key.
1011
 *
1012
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1013
 *   negative error value.
1014
 **/
1015
int gnutls_x509_privkey_import_rsa_raw2(
1016
  gnutls_x509_privkey_t key, const gnutls_datum_t *m,
1017
  const gnutls_datum_t *e, const gnutls_datum_t *d,
1018
  const gnutls_datum_t *p, const gnutls_datum_t *q,
1019
  const gnutls_datum_t *u, const gnutls_datum_t *e1,
1020
  const gnutls_datum_t *e2)
1021
0
{
1022
0
  int ret;
1023
1024
0
  if (key == NULL) {
1025
0
    gnutls_assert();
1026
0
    return GNUTLS_E_INVALID_REQUEST;
1027
0
  }
1028
1029
0
  gnutls_pk_params_init(&key->params);
1030
1031
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_MODULUS], m->data,
1032
0
             m->size)) {
1033
0
    gnutls_assert();
1034
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1035
0
    goto cleanup;
1036
0
  }
1037
0
  key->params.params_nr++;
1038
1039
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PUB], e->data,
1040
0
             e->size)) {
1041
0
    gnutls_assert();
1042
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1043
0
    goto cleanup;
1044
0
  }
1045
0
  key->params.params_nr++;
1046
1047
0
  if (d) {
1048
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIV],
1049
0
               d->data, d->size)) {
1050
0
      gnutls_assert();
1051
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1052
0
      goto cleanup;
1053
0
    }
1054
0
    key->params.params_nr++;
1055
0
  }
1056
1057
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIME1], p->data,
1058
0
             p->size)) {
1059
0
    gnutls_assert();
1060
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1061
0
    goto cleanup;
1062
0
  }
1063
0
  key->params.params_nr++;
1064
1065
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIME2], q->data,
1066
0
             q->size)) {
1067
0
    gnutls_assert();
1068
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1069
0
    goto cleanup;
1070
0
  }
1071
0
  key->params.params_nr++;
1072
1073
0
  if (u) {
1074
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_COEF],
1075
0
               u->data, u->size)) {
1076
0
      gnutls_assert();
1077
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1078
0
      goto cleanup;
1079
0
    }
1080
0
    key->params.params_nr++;
1081
0
  }
1082
1083
0
  if (e1 && e2) {
1084
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_E1],
1085
0
               e1->data, e1->size)) {
1086
0
      gnutls_assert();
1087
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1088
0
      goto cleanup;
1089
0
    }
1090
0
    key->params.params_nr++;
1091
1092
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_E2],
1093
0
               e2->data, e2->size)) {
1094
0
      gnutls_assert();
1095
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1096
0
      goto cleanup;
1097
0
    }
1098
0
    key->params.params_nr++;
1099
0
  }
1100
1101
0
  key->params.algo = GNUTLS_PK_RSA;
1102
1103
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
1104
0
  if (ret < 0) {
1105
0
    gnutls_assert();
1106
0
    goto cleanup;
1107
0
  }
1108
1109
0
  key->params.params_nr = RSA_PRIVATE_PARAMS;
1110
0
  key->params.algo = GNUTLS_PK_RSA;
1111
1112
0
  ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1113
0
  if (ret < 0) {
1114
0
    gnutls_assert();
1115
0
    goto cleanup;
1116
0
  }
1117
1118
0
  return 0;
1119
1120
0
cleanup:
1121
0
  gnutls_pk_params_clear(&key->params);
1122
0
  gnutls_pk_params_release(&key->params);
1123
0
  return ret;
1124
0
}
1125
1126
/**
1127
 * gnutls_x509_privkey_import_dsa_raw:
1128
 * @key: The data to store the parsed key
1129
 * @p: holds the p
1130
 * @q: holds the q
1131
 * @g: holds the g
1132
 * @y: holds the y (optional)
1133
 * @x: holds the x
1134
 *
1135
 * This function will convert the given DSA raw parameters to the
1136
 * native #gnutls_x509_privkey_t format.  The output will be stored
1137
 * in @key.
1138
 *
1139
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1140
 *   negative error value.
1141
 **/
1142
int gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
1143
               const gnutls_datum_t *p,
1144
               const gnutls_datum_t *q,
1145
               const gnutls_datum_t *g,
1146
               const gnutls_datum_t *y,
1147
               const gnutls_datum_t *x)
1148
0
{
1149
0
  int ret;
1150
1151
0
  if (unlikely(key == NULL || p == NULL || q == NULL || g == NULL ||
1152
0
         x == NULL)) {
1153
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1154
0
  }
1155
1156
0
  gnutls_pk_params_init(&key->params);
1157
1158
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_P], p->data,
1159
0
             p->size)) {
1160
0
    gnutls_assert();
1161
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1162
0
    goto cleanup;
1163
0
  }
1164
1165
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Q], q->data,
1166
0
             q->size)) {
1167
0
    gnutls_assert();
1168
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1169
0
    goto cleanup;
1170
0
  }
1171
1172
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_G], g->data,
1173
0
             g->size)) {
1174
0
    gnutls_assert();
1175
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1176
0
    goto cleanup;
1177
0
  }
1178
1179
0
  if (y) {
1180
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Y],
1181
0
               y->data, y->size)) {
1182
0
      gnutls_assert();
1183
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1184
0
      goto cleanup;
1185
0
    }
1186
0
  }
1187
1188
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_X], x->data,
1189
0
             x->size)) {
1190
0
    gnutls_assert();
1191
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1192
0
    goto cleanup;
1193
0
  }
1194
1195
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_DSA, GNUTLS_IMPORT, &key->params);
1196
0
  if (ret < 0) {
1197
0
    gnutls_assert();
1198
0
    goto cleanup;
1199
0
  }
1200
1201
0
  key->params.algo = GNUTLS_PK_DSA;
1202
0
  key->params.params_nr = DSA_PRIVATE_PARAMS;
1203
1204
0
  ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1205
0
  if (ret < 0) {
1206
0
    gnutls_assert();
1207
0
    goto cleanup;
1208
0
  }
1209
1210
0
  return 0;
1211
1212
0
cleanup:
1213
0
  gnutls_pk_params_clear(&key->params);
1214
0
  gnutls_pk_params_release(&key->params);
1215
0
  return ret;
1216
0
}
1217
1218
/**
1219
 * gnutls_x509_privkey_import_dh_raw:
1220
 * @key: The data to store the parsed key
1221
 * @params: holds the %gnutls_dh_params_t
1222
 * @y: holds the y (optional)
1223
 * @x: holds the x
1224
 *
1225
 * This function will convert the given Diffie-Hellman raw parameters
1226
 * to the native #gnutls_x509_privkey_t format.  The output will be
1227
 * stored in @key.
1228
 *
1229
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1230
 *   negative error value.
1231
 **/
1232
int gnutls_x509_privkey_import_dh_raw(gnutls_x509_privkey_t key,
1233
              const gnutls_dh_params_t params,
1234
              const gnutls_datum_t *y,
1235
              const gnutls_datum_t *x)
1236
0
{
1237
0
  int ret;
1238
1239
0
  if (unlikely(key == NULL || params == NULL || x == NULL)) {
1240
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1241
0
  }
1242
1243
0
  gnutls_pk_params_init(&key->params);
1244
1245
0
  key->params.params[DH_P] = _gnutls_mpi_copy(params->params[0]);
1246
0
  key->params.params[DH_G] = _gnutls_mpi_copy(params->params[1]);
1247
0
  if (params->params[2]) {
1248
0
    key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
1249
0
  }
1250
0
  key->params.qbits = params->q_bits;
1251
1252
0
  if (y) {
1253
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
1254
0
               y->size)) {
1255
0
      gnutls_assert();
1256
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1257
0
      goto cleanup;
1258
0
    }
1259
0
  }
1260
1261
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_X], x->data,
1262
0
             x->size)) {
1263
0
    gnutls_assert();
1264
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1265
0
    goto cleanup;
1266
0
  }
1267
1268
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_DH, GNUTLS_IMPORT, &key->params);
1269
0
  if (ret < 0) {
1270
0
    gnutls_assert();
1271
0
    goto cleanup;
1272
0
  }
1273
1274
0
  key->params.algo = GNUTLS_PK_DH;
1275
0
  key->params.params_nr = DH_PRIVATE_PARAMS;
1276
1277
0
  return 0;
1278
1279
0
cleanup:
1280
0
  gnutls_pk_params_clear(&key->params);
1281
0
  gnutls_pk_params_release(&key->params);
1282
0
  return ret;
1283
0
}
1284
1285
/**
1286
 * gnutls_x509_privkey_import_ecc_raw:
1287
 * @key: The data to store the parsed key
1288
 * @curve: holds the curve
1289
 * @x: holds the x-coordinate
1290
 * @y: holds the y-coordinate
1291
 * @k: holds the k
1292
 *
1293
 * This function will convert the given elliptic curve parameters to the
1294
 * native #gnutls_x509_privkey_t format.  The output will be stored
1295
 * in @key. For EdDSA keys, the @x and @k values must be in the
1296
 * native to curve format.
1297
 *
1298
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1299
 *   negative error value.
1300
 *
1301
 * Since: 3.0
1302
 **/
1303
int gnutls_x509_privkey_import_ecc_raw(gnutls_x509_privkey_t key,
1304
               gnutls_ecc_curve_t curve,
1305
               const gnutls_datum_t *x,
1306
               const gnutls_datum_t *y,
1307
               const gnutls_datum_t *k)
1308
0
{
1309
0
  int ret;
1310
1311
0
  if (key == NULL) {
1312
0
    gnutls_assert();
1313
0
    return GNUTLS_E_INVALID_REQUEST;
1314
0
  }
1315
1316
0
  gnutls_pk_params_init(&key->params);
1317
1318
0
  key->params.curve = curve;
1319
1320
0
  if (curve_is_eddsa(curve) || curve_is_modern_ecdh(curve)) {
1321
0
    unsigned size;
1322
0
    switch (curve) {
1323
0
    case GNUTLS_ECC_CURVE_ED25519:
1324
0
      key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1325
0
      break;
1326
0
    case GNUTLS_ECC_CURVE_ED448:
1327
0
      key->params.algo = GNUTLS_PK_EDDSA_ED448;
1328
0
      break;
1329
0
    case GNUTLS_ECC_CURVE_X25519:
1330
0
      key->params.algo = GNUTLS_PK_ECDH_X25519;
1331
0
      break;
1332
0
    case GNUTLS_ECC_CURVE_X448:
1333
0
      key->params.algo = GNUTLS_PK_ECDH_X448;
1334
0
      break;
1335
0
    default:
1336
0
      ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1337
0
      goto cleanup;
1338
0
    }
1339
1340
0
    size = gnutls_ecc_curve_get_size(curve);
1341
0
    if ((x && x->size != size) || k->size != size) {
1342
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1343
0
      goto cleanup;
1344
0
    }
1345
1346
0
    ret = _gnutls_set_datum(&key->params.raw_priv, k->data,
1347
0
          k->size);
1348
0
    if (ret < 0) {
1349
0
      gnutls_assert();
1350
0
      goto cleanup;
1351
0
    }
1352
1353
0
    if (x) {
1354
0
      ret = _gnutls_set_datum(&key->params.raw_pub, x->data,
1355
0
            x->size);
1356
0
      if (ret < 0) {
1357
0
        gnutls_assert();
1358
0
        goto cleanup;
1359
0
      }
1360
0
    } else {
1361
0
      ret = _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT,
1362
0
                 &key->params);
1363
0
      if (ret < 0) {
1364
0
        gnutls_assert();
1365
0
        goto cleanup;
1366
0
      }
1367
0
    }
1368
1369
0
    return 0;
1370
0
  }
1371
1372
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[ECC_K], k->data,
1373
0
             k->size)) {
1374
0
    gnutls_assert();
1375
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1376
0
    goto cleanup;
1377
0
  }
1378
0
  key->params.params_nr++;
1379
1380
0
  key->params.algo = GNUTLS_PK_EC;
1381
1382
0
  if (x && y) {
1383
0
    ret = _gnutls_mpi_init_scan_nz(&key->params.params[ECC_X],
1384
0
                 x->data, x->size);
1385
0
    if (ret < 0) {
1386
0
      ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
1387
0
      goto cleanup;
1388
0
    }
1389
0
    key->params.params_nr++;
1390
1391
0
    ret = _gnutls_mpi_init_scan_nz(&key->params.params[ECC_Y],
1392
0
                 y->data, y->size);
1393
0
    if (ret < 0) {
1394
0
      ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
1395
0
      goto cleanup;
1396
0
    }
1397
0
    key->params.params_nr++;
1398
0
  } else {
1399
0
    ret = _gnutls_pk_fixup(GNUTLS_PK_EC, GNUTLS_IMPORT,
1400
0
               &key->params);
1401
0
    if (ret < 0) {
1402
0
      gnutls_assert();
1403
0
      goto cleanup;
1404
0
    }
1405
0
  }
1406
1407
0
  ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1408
0
  if (ret < 0) {
1409
0
    gnutls_assert();
1410
0
    goto cleanup;
1411
0
  }
1412
1413
0
  return 0;
1414
1415
0
cleanup:
1416
0
  gnutls_pk_params_clear(&key->params);
1417
0
  gnutls_pk_params_release(&key->params);
1418
0
  return ret;
1419
0
}
1420
1421
/**
1422
 * gnutls_x509_privkey_import_gost_raw:
1423
 * @key: The data to store the parsed key
1424
 * @curve: holds the curve
1425
 * @digest: will hold the digest
1426
 * @paramset: will hold the GOST parameter set ID
1427
 * @x: holds the x-coordinate
1428
 * @y: holds the y-coordinate
1429
 * @k: holds the k (private key)
1430
 *
1431
 * This function will convert the given GOST private key's parameters to the
1432
 * native #gnutls_x509_privkey_t format.  The output will be stored
1433
 * in @key.  @digest should be one of GNUTLS_DIG_GOSR_94,
1434
 * GNUTLS_DIG_STREEBOG_256 or GNUTLS_DIG_STREEBOG_512.  If @paramset is set to
1435
 * GNUTLS_GOST_PARAMSET_UNKNOWN default one will be selected depending on
1436
 * @digest.
1437
 *
1438
 * Note: parameters should be stored with least significant byte first. On
1439
 * version 3.6.3 big-endian format was used incorrectly.
1440
 *
1441
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1442
 *   negative error value.
1443
 *
1444
 * Since: 3.6.3
1445
 **/
1446
int gnutls_x509_privkey_import_gost_raw(gnutls_x509_privkey_t key,
1447
          gnutls_ecc_curve_t curve,
1448
          gnutls_digest_algorithm_t digest,
1449
          gnutls_gost_paramset_t paramset,
1450
          const gnutls_datum_t *x,
1451
          const gnutls_datum_t *y,
1452
          const gnutls_datum_t *k)
1453
0
{
1454
0
  int ret;
1455
1456
0
  if (key == NULL) {
1457
0
    gnutls_assert();
1458
0
    return GNUTLS_E_INVALID_REQUEST;
1459
0
  }
1460
1461
0
  key->params.curve = curve;
1462
0
  key->params.algo = _gnutls_digest_gost(digest);
1463
1464
0
  if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1465
0
    paramset = _gnutls_gost_paramset_default(key->params.algo);
1466
1467
0
  key->params.gost_params = paramset;
1468
1469
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_X], x->data,
1470
0
             x->size)) {
1471
0
    gnutls_assert();
1472
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1473
0
    goto cleanup;
1474
0
  }
1475
0
  key->params.params_nr++;
1476
1477
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_Y], y->data,
1478
0
             y->size)) {
1479
0
    gnutls_assert();
1480
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1481
0
    goto cleanup;
1482
0
  }
1483
0
  key->params.params_nr++;
1484
1485
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_K], k->data,
1486
0
             k->size)) {
1487
0
    gnutls_assert();
1488
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1489
0
    goto cleanup;
1490
0
  }
1491
0
  key->params.params_nr++;
1492
1493
0
  ret = _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
1494
0
  if (ret < 0) {
1495
0
    gnutls_assert();
1496
0
    goto cleanup;
1497
0
  }
1498
1499
0
  return 0;
1500
1501
0
cleanup:
1502
0
  gnutls_pk_params_clear(&key->params);
1503
0
  gnutls_pk_params_release(&key->params);
1504
0
  return ret;
1505
0
}
1506
1507
/**
1508
 * gnutls_x509_privkey_get_pk_algorithm:
1509
 * @key: should contain a #gnutls_x509_privkey_t type
1510
 *
1511
 * This function will return the public key algorithm of a private
1512
 * key.
1513
 *
1514
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1515
 *   success, or a negative error code on error.
1516
 **/
1517
int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key)
1518
0
{
1519
0
  if (key == NULL) {
1520
0
    gnutls_assert();
1521
0
    return GNUTLS_E_INVALID_REQUEST;
1522
0
  }
1523
1524
0
  return key->params.algo;
1525
0
}
1526
1527
/**
1528
 * gnutls_x509_privkey_get_pk_algorithm2:
1529
 * @key: should contain a #gnutls_x509_privkey_t type
1530
 * @bits: The number of bits in the public key algorithm
1531
 *
1532
 * This function will return the public key algorithm of a private
1533
 * key.
1534
 *
1535
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1536
 *   success, or a negative error code on error.
1537
 **/
1538
int gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t key,
1539
            unsigned int *bits)
1540
0
{
1541
0
  int ret;
1542
1543
0
  if (key == NULL) {
1544
0
    gnutls_assert();
1545
0
    return GNUTLS_E_INVALID_REQUEST;
1546
0
  }
1547
1548
0
  if (bits) {
1549
0
    ret = pubkey_to_bits(&key->params);
1550
0
    if (ret < 0)
1551
0
      ret = 0;
1552
0
    *bits = ret;
1553
0
  }
1554
1555
0
  return key->params.algo;
1556
0
}
1557
1558
int _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
1559
           gnutls_x509_spki_st *params)
1560
0
{
1561
0
  return _gnutls_x509_spki_copy(params, &key->params.spki);
1562
0
}
1563
1564
/**
1565
 * gnutls_x509_privkey_get_spki:
1566
 * @key: should contain a #gnutls_x509_privkey_t type
1567
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1568
 * @flags: must be zero
1569
 *
1570
 * This function will return the public key information of a private
1571
 * key. The provided @spki must be initialized.
1572
 *
1573
 * Returns: Zero on success, or a negative error code on error.
1574
 **/
1575
int gnutls_x509_privkey_get_spki(gnutls_x509_privkey_t key,
1576
         gnutls_x509_spki_t spki, unsigned int flags)
1577
0
{
1578
0
  if (key == NULL) {
1579
0
    gnutls_assert();
1580
0
    return GNUTLS_E_INVALID_REQUEST;
1581
0
  }
1582
1583
0
  if (key->params.spki.pk == GNUTLS_PK_UNKNOWN)
1584
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1585
1586
0
  return _gnutls_x509_privkey_get_spki_params(key, spki);
1587
0
}
1588
1589
/**
1590
 * gnutls_x509_privkey_set_spki:
1591
 * @key: should contain a #gnutls_x509_privkey_t type
1592
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1593
 * @flags: must be zero
1594
 *
1595
 * This function will return the public key information of a private
1596
 * key. The provided @spki must be initialized.
1597
 *
1598
 * Returns: Zero on success, or a negative error code on error.
1599
 **/
1600
int gnutls_x509_privkey_set_spki(gnutls_x509_privkey_t key,
1601
         const gnutls_x509_spki_t spki,
1602
         unsigned int flags)
1603
0
{
1604
0
  gnutls_pk_params_st tparams;
1605
0
  int ret;
1606
1607
0
  if (key == NULL) {
1608
0
    gnutls_assert();
1609
0
    return GNUTLS_E_INVALID_REQUEST;
1610
0
  }
1611
1612
0
  if (!_gnutls_pk_are_compat(key->params.algo, spki->pk))
1613
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1614
1615
0
  memcpy(&tparams, &key->params, sizeof(gnutls_pk_params_st));
1616
  /* No need for a deep copy, as this is only for one time check */
1617
0
  memcpy(&tparams.spki, spki, sizeof(gnutls_x509_spki_st));
1618
0
  ret = _gnutls_x509_check_pubkey_params(&tparams);
1619
0
  if (ret < 0)
1620
0
    return gnutls_assert_val(ret);
1621
1622
0
  ret = _gnutls_x509_spki_copy(&key->params.spki, spki);
1623
0
  if (ret < 0)
1624
0
    return gnutls_assert_val(ret);
1625
1626
0
  key->params.algo = spki->pk;
1627
1628
0
  return 0;
1629
0
}
1630
1631
static const char *set_msg(gnutls_x509_privkey_t key)
1632
0
{
1633
0
  switch (key->params.algo) {
1634
0
  case GNUTLS_PK_RSA:
1635
0
  case GNUTLS_PK_RSA_PSS:
1636
0
    return PEM_KEY_RSA;
1637
0
  case GNUTLS_PK_DSA:
1638
0
    return PEM_KEY_DSA;
1639
0
  case GNUTLS_PK_EC:
1640
0
    return PEM_KEY_ECC;
1641
0
  case GNUTLS_PK_MLDSA44:
1642
0
  case GNUTLS_PK_MLDSA65:
1643
0
  case GNUTLS_PK_MLDSA87:
1644
0
    return PEM_KEY_ML_DSA;
1645
0
  default:
1646
0
    return "UNKNOWN";
1647
0
  }
1648
0
}
1649
1650
/**
1651
 * gnutls_x509_privkey_export:
1652
 * @key: Holds the key
1653
 * @format: the format of output params. One of PEM or DER.
1654
 * @output_data: will contain a private key PEM or DER encoded
1655
 * @output_data_size: holds the size of output_data (and will be
1656
 *   replaced by the actual size of parameters)
1657
 *
1658
 * This function will export the private key to a PKCS#1 structure for
1659
 * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1660
 * will be exported in PKCS#8 form.
1661
 *
1662
 * If the structure is PEM encoded, it will have a header
1663
 * of "BEGIN RSA PRIVATE KEY".
1664
 *
1665
 * It is recommended to use gnutls_x509_privkey_export_pkcs8() instead
1666
 * of this function, when a consistent output format is required.
1667
 *
1668
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1669
 *   negative error value.
1670
 **/
1671
int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
1672
             gnutls_x509_crt_fmt_t format, void *output_data,
1673
             size_t *output_data_size)
1674
0
{
1675
0
  gnutls_datum_t out;
1676
0
  int ret;
1677
1678
0
  ret = gnutls_x509_privkey_export2(key, format, &out);
1679
0
  if (ret < 0)
1680
0
    return gnutls_assert_val(ret);
1681
1682
0
  if (format == GNUTLS_X509_FMT_PEM)
1683
0
    ret = _gnutls_copy_string(&out, output_data, output_data_size);
1684
0
  else
1685
0
    ret = _gnutls_copy_data(&out, output_data, output_data_size);
1686
0
  gnutls_free(out.data);
1687
1688
0
  return ret;
1689
0
}
1690
1691
/**
1692
 * gnutls_x509_privkey_export2:
1693
 * @key: Holds the key
1694
 * @format: the format of output params. One of PEM or DER.
1695
 * @out: will contain a private key PEM or DER encoded
1696
 *
1697
 * This function will export the private key to a PKCS#1 structure for
1698
 * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1699
 * will be exported in PKCS#8 form.
1700
 *
1701
 * The output buffer is allocated using gnutls_malloc().
1702
 *
1703
 * It is recommended to use gnutls_x509_privkey_export2_pkcs8() instead
1704
 * of this function, when a consistent output format is required.
1705
 *
1706
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1707
 *   negative error value.
1708
 *
1709
 * Since 3.1.3
1710
 **/
1711
int gnutls_x509_privkey_export2(gnutls_x509_privkey_t key,
1712
        gnutls_x509_crt_fmt_t format,
1713
        gnutls_datum_t *out)
1714
0
{
1715
0
  const char *msg;
1716
0
  int ret;
1717
1718
0
  if (key == NULL) {
1719
0
    gnutls_assert();
1720
0
    return GNUTLS_E_INVALID_REQUEST;
1721
0
  }
1722
1723
0
  if (key->key == NULL) { /* can only export in PKCS#8 form */
1724
0
    return gnutls_x509_privkey_export2_pkcs8(key, format, NULL, 0,
1725
0
               out);
1726
0
  }
1727
1728
0
  msg = set_msg(key);
1729
1730
0
  if (key->flags & GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT) {
1731
0
    ret = gnutls_x509_privkey_fix(key);
1732
0
    if (ret < 0)
1733
0
      return gnutls_assert_val(ret);
1734
0
  }
1735
1736
0
  return _gnutls_x509_export_int2(key->key, format, msg, out);
1737
0
}
1738
1739
/**
1740
 * gnutls_x509_privkey_sec_param:
1741
 * @key: a key
1742
 *
1743
 * This function will return the security parameter appropriate with
1744
 * this private key.
1745
 *
1746
 * Returns: On success, a valid security parameter is returned otherwise
1747
 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1748
 *
1749
 * Since: 2.12.0
1750
 **/
1751
gnutls_sec_param_t gnutls_x509_privkey_sec_param(gnutls_x509_privkey_t key)
1752
0
{
1753
0
  int bits;
1754
1755
0
  bits = pubkey_to_bits(&key->params);
1756
0
  if (bits <= 0)
1757
0
    return GNUTLS_SEC_PARAM_UNKNOWN;
1758
1759
0
  return gnutls_pk_bits_to_sec_param(key->params.algo, bits);
1760
0
}
1761
1762
/**
1763
 * gnutls_x509_privkey_export_ecc_raw:
1764
 * @key: a key
1765
 * @curve: will hold the curve
1766
 * @x: will hold the x-coordinate
1767
 * @y: will hold the y-coordinate
1768
 * @k: will hold the private key
1769
 *
1770
 * This function will export the ECC private key's parameters found
1771
 * in the given structure. The new parameters will be allocated using
1772
 * gnutls_malloc() and will be stored in the appropriate datum.
1773
 *
1774
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
1775
 * will be in the native format for the curve.
1776
 *
1777
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1778
 *   negative error value.
1779
 *
1780
 * Since: 3.0
1781
 **/
1782
int gnutls_x509_privkey_export_ecc_raw(gnutls_x509_privkey_t key,
1783
               gnutls_ecc_curve_t *curve,
1784
               gnutls_datum_t *x, gnutls_datum_t *y,
1785
               gnutls_datum_t *k)
1786
0
{
1787
0
  if (key == NULL) {
1788
0
    gnutls_assert();
1789
0
    return GNUTLS_E_INVALID_REQUEST;
1790
0
  }
1791
1792
0
  return _gnutls_params_get_ecc_raw(&key->params, curve, x, y, k, 0);
1793
0
}
1794
1795
/**
1796
 * gnutls_x509_privkey_export_gost_raw:
1797
 * @key: a key
1798
 * @curve: will hold the curve
1799
 * @digest: will hold the digest
1800
 * @paramset: will hold the GOST parameter set ID
1801
 * @x: will hold the x-coordinate
1802
 * @y: will hold the y-coordinate
1803
 * @k: will hold the private key
1804
 *
1805
 * This function will export the GOST private key's parameters found
1806
 * in the given structure. The new parameters will be allocated using
1807
 * gnutls_malloc() and will be stored in the appropriate datum.
1808
 *
1809
 * Note: parameters will be stored with least significant byte first. On
1810
 * version 3.6.3 this was incorrectly returned in big-endian format.
1811
 *
1812
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1813
 *   negative error value.
1814
 *
1815
 * Since: 3.6.3
1816
 **/
1817
int gnutls_x509_privkey_export_gost_raw(gnutls_x509_privkey_t key,
1818
          gnutls_ecc_curve_t *curve,
1819
          gnutls_digest_algorithm_t *digest,
1820
          gnutls_gost_paramset_t *paramset,
1821
          gnutls_datum_t *x, gnutls_datum_t *y,
1822
          gnutls_datum_t *k)
1823
0
{
1824
0
  if (key == NULL) {
1825
0
    gnutls_assert();
1826
0
    return GNUTLS_E_INVALID_REQUEST;
1827
0
  }
1828
1829
0
  return _gnutls_params_get_gost_raw(&key->params, curve, digest,
1830
0
             paramset, x, y, k, 0);
1831
0
}
1832
1833
/**
1834
 * gnutls_x509_privkey_export_rsa_raw:
1835
 * @key: a key
1836
 * @m: will hold the modulus
1837
 * @e: will hold the public exponent
1838
 * @d: will hold the private exponent
1839
 * @p: will hold the first prime (p)
1840
 * @q: will hold the second prime (q)
1841
 * @u: will hold the coefficient
1842
 *
1843
 * This function will export the RSA private key's parameters found
1844
 * in the given structure. The new parameters will be allocated using
1845
 * gnutls_malloc() and will be stored in the appropriate datum.
1846
 *
1847
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1848
 *   negative error value.
1849
 **/
1850
int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
1851
               gnutls_datum_t *m, gnutls_datum_t *e,
1852
               gnutls_datum_t *d, gnutls_datum_t *p,
1853
               gnutls_datum_t *q, gnutls_datum_t *u)
1854
0
{
1855
0
  return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, NULL,
1856
0
            NULL, 0);
1857
0
}
1858
1859
/**
1860
 * gnutls_x509_privkey_export_rsa_raw2:
1861
 * @key: a key
1862
 * @m: will hold the modulus
1863
 * @e: will hold the public exponent
1864
 * @d: will hold the private exponent
1865
 * @p: will hold the first prime (p)
1866
 * @q: will hold the second prime (q)
1867
 * @u: will hold the coefficient
1868
 * @e1: will hold e1 = d mod (p-1)
1869
 * @e2: will hold e2 = d mod (q-1)
1870
 *
1871
 * This function will export the RSA private key's parameters found
1872
 * in the given structure. The new parameters will be allocated using
1873
 * gnutls_malloc() and will be stored in the appropriate datum.
1874
 *
1875
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1876
 *   negative error value.
1877
 *
1878
 * Since: 2.12.0
1879
 **/
1880
int gnutls_x509_privkey_export_rsa_raw2(gnutls_x509_privkey_t key,
1881
          gnutls_datum_t *m, gnutls_datum_t *e,
1882
          gnutls_datum_t *d, gnutls_datum_t *p,
1883
          gnutls_datum_t *q, gnutls_datum_t *u,
1884
          gnutls_datum_t *e1, gnutls_datum_t *e2)
1885
0
{
1886
0
  return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, e1,
1887
0
            e2, 0);
1888
0
}
1889
1890
/**
1891
 * gnutls_x509_privkey_export_dsa_raw:
1892
 * @key: a key
1893
 * @p: will hold the p
1894
 * @q: will hold the q
1895
 * @g: will hold the g
1896
 * @y: will hold the y
1897
 * @x: will hold the x
1898
 *
1899
 * This function will export the DSA private key's parameters found
1900
 * in the given structure. The new parameters will be allocated using
1901
 * gnutls_malloc() and will be stored in the appropriate datum.
1902
 *
1903
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1904
 *   negative error value.
1905
 **/
1906
int gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,
1907
               gnutls_datum_t *p, gnutls_datum_t *q,
1908
               gnutls_datum_t *g, gnutls_datum_t *y,
1909
               gnutls_datum_t *x)
1910
0
{
1911
0
  return _gnutls_params_get_dsa_raw(&key->params, p, q, g, y, x, 0);
1912
0
}
1913
1914
/**
1915
 * gnutls_x509_privkey_generate:
1916
 * @key: an initialized key
1917
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1918
 * @bits: the size of the parameters to generate
1919
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1920
 *
1921
 * This function will generate a random private key. Note that this
1922
 * function must be called on an initialized private key.
1923
 *
1924
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1925
 * instructs the key generation process to use algorithms like Shawe-Taylor
1926
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1927
 * for RSA and DSA keys. See gnutls_x509_privkey_generate2() for more
1928
 * information.
1929
 *
1930
 * Note that when generating an elliptic curve key, the curve
1931
 * can be substituted in the place of the bits parameter using the
1932
 * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
1933
 * %gnutls_ecc_curve_t.
1934
 *
1935
 * For DSA keys, if the subgroup size needs to be specified check
1936
 * the GNUTLS_SUBGROUP_TO_BITS() macro.
1937
 *
1938
 * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
1939
 *
1940
 * See also gnutls_privkey_generate(), gnutls_x509_privkey_generate2().
1941
 *
1942
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1943
 *   negative error value.
1944
 **/
1945
int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
1946
         gnutls_pk_algorithm_t algo, unsigned int bits,
1947
         unsigned int flags)
1948
0
{
1949
0
  return gnutls_x509_privkey_generate2(key, algo, bits, flags, NULL, 0);
1950
0
}
1951
1952
/**
1953
 * gnutls_x509_privkey_generate2:
1954
 * @key: a key
1955
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1956
 * @bits: the size of the modulus
1957
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1958
 * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
1959
 * @data_size: The number of @data available.
1960
 *
1961
 * This function will generate a random private key. Note that this
1962
 * function must be called on an initialized private key.
1963
 *
1964
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1965
 * instructs the key generation process to use algorithms like Shawe-Taylor
1966
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1967
 * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
1968
 * seed, while on RSA the two primes. To specify an explicit seed
1969
 * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
1970
 * type.
1971
 *
1972
 * Note that when generating an elliptic curve key, the curve
1973
 * can be substituted in the place of the bits parameter using the
1974
 * GNUTLS_CURVE_TO_BITS() macro.
1975
 *
1976
 * To export the generated keys in memory or in files it is recommended to use the
1977
 * PKCS#8 form as it can handle all key types, and can store additional parameters
1978
 * such as the seed, in case of provable RSA or DSA keys.
1979
 * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
1980
 * and then with gnutls_x509_privkey_export2_pkcs8().
1981
 *
1982
 * If key generation is part of your application, avoid setting the number
1983
 * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
1984
 * That way the generated keys will adapt to the security levels
1985
 * of the underlying GnuTLS library.
1986
 *
1987
 * See also gnutls_privkey_generate2().
1988
 *
1989
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1990
 *   negative error value.
1991
 **/
1992
int gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
1993
          gnutls_pk_algorithm_t algo, unsigned int bits,
1994
          unsigned int flags,
1995
          const gnutls_keygen_data_st *data,
1996
          unsigned data_size)
1997
0
{
1998
0
  int ret;
1999
0
  unsigned i;
2000
0
  gnutls_x509_spki_t spki = NULL;
2001
0
  gnutls_dh_params_t dh_params = NULL;
2002
2003
0
  if (key == NULL) {
2004
0
    gnutls_assert();
2005
0
    return GNUTLS_E_INVALID_REQUEST;
2006
0
  }
2007
2008
0
  gnutls_pk_params_init(&key->params);
2009
2010
0
  for (i = 0; i < data_size; i++) {
2011
0
    switch (data[i].type) {
2012
0
    case GNUTLS_KEYGEN_SEED:
2013
0
      if (data[i].size < sizeof(key->params.seed)) {
2014
0
        key->params.seed_size = data[i].size;
2015
0
        memcpy(key->params.seed, data[i].data,
2016
0
               data[i].size);
2017
0
      }
2018
0
      break;
2019
0
    case GNUTLS_KEYGEN_DIGEST:
2020
0
      key->params.palgo = data[i].size;
2021
0
      break;
2022
0
    case GNUTLS_KEYGEN_SPKI:
2023
0
      spki = (void *)data[i].data;
2024
0
      break;
2025
0
    case GNUTLS_KEYGEN_DH:
2026
0
      if (algo != GNUTLS_PK_DH) {
2027
0
        return gnutls_assert_val(
2028
0
          GNUTLS_E_INVALID_REQUEST);
2029
0
      }
2030
0
      dh_params = (void *)data[i].data;
2031
0
      break;
2032
0
    }
2033
0
  }
2034
2035
0
  if (IS_EC(algo)) {
2036
0
    if (GNUTLS_BITS_ARE_CURVE(bits))
2037
0
      bits = GNUTLS_BITS_TO_CURVE(bits);
2038
0
    else
2039
0
      bits = _gnutls_ecc_bits_to_curve(algo, bits);
2040
2041
0
    if (gnutls_ecc_curve_get_pk(bits) != algo) {
2042
0
      _gnutls_debug_log(
2043
0
        "curve is incompatible with public key algorithm\n");
2044
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2045
0
    }
2046
0
  }
2047
2048
0
  if (IS_GOSTEC(algo)) {
2049
0
    int size;
2050
2051
0
    if (GNUTLS_BITS_ARE_CURVE(bits))
2052
0
      bits = GNUTLS_BITS_TO_CURVE(bits);
2053
0
    else
2054
0
      bits = _gnutls_ecc_bits_to_curve(algo, bits);
2055
2056
0
    size = gnutls_ecc_curve_get_size(bits);
2057
2058
0
    if ((algo == GNUTLS_PK_GOST_01 && size != 32) ||
2059
0
        (algo == GNUTLS_PK_GOST_12_256 && size != 32) ||
2060
0
        (algo == GNUTLS_PK_GOST_12_512 && size != 64)) {
2061
0
      _gnutls_debug_log(
2062
0
        "curve is incompatible with public key algorithm\n");
2063
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2064
0
    }
2065
2066
0
    key->params.gost_params = _gnutls_gost_paramset_default(algo);
2067
0
  }
2068
2069
0
  if (flags & GNUTLS_PRIVKEY_FLAG_PROVABLE) {
2070
0
    key->params.pkflags |= GNUTLS_PK_FLAG_PROVABLE;
2071
0
  }
2072
2073
0
  key->params.algo = algo;
2074
2075
  /* DH params are given, no need to regenerate */
2076
0
  if (algo == GNUTLS_PK_DH && dh_params != NULL) {
2077
0
    key->params.params[DH_P] =
2078
0
      _gnutls_mpi_copy(dh_params->params[0]);
2079
0
    key->params.params[DH_G] =
2080
0
      _gnutls_mpi_copy(dh_params->params[1]);
2081
0
    if (dh_params->params[2]) {
2082
0
      key->params.params[DH_Q] =
2083
0
        _gnutls_mpi_copy(dh_params->params[2]);
2084
0
    }
2085
    /* X and Y will be added by _gnutls_pk_generate_keys */
2086
0
    key->params.params_nr = 3;
2087
0
    key->params.qbits = dh_params->q_bits;
2088
0
  } else {
2089
0
    ret = _gnutls_pk_generate_params(algo, bits, &key->params);
2090
0
    if (ret < 0) {
2091
0
      gnutls_assert();
2092
0
      return ret;
2093
0
    }
2094
0
  }
2095
2096
0
  if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA) &&
2097
0
      !key->params.spki.pk) {
2098
0
    const mac_entry_st *me;
2099
0
    key->params.spki.pk = GNUTLS_PK_RSA_PSS;
2100
2101
0
    key->params.spki.rsa_pss_dig =
2102
0
      _gnutls_pk_bits_to_sha_hash(bits);
2103
2104
0
    me = hash_to_entry(key->params.spki.rsa_pss_dig);
2105
0
    if (unlikely(me == NULL)) {
2106
0
      gnutls_assert();
2107
0
      ret = GNUTLS_E_INVALID_REQUEST;
2108
0
      goto cleanup;
2109
0
    }
2110
2111
0
    ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
2112
0
    if (ret < 0) {
2113
0
      gnutls_assert();
2114
0
      goto cleanup;
2115
0
    }
2116
2117
0
    key->params.spki.salt_size = ret;
2118
0
  }
2119
2120
0
  if (algo == GNUTLS_PK_RSA_OAEP && !key->params.spki.pk) {
2121
0
    const mac_entry_st *me;
2122
0
    key->params.spki.pk = GNUTLS_PK_RSA_OAEP;
2123
2124
0
    key->params.spki.rsa_oaep_dig =
2125
0
      _gnutls_pk_bits_to_sha_hash(bits);
2126
2127
0
    me = hash_to_entry(key->params.spki.rsa_oaep_dig);
2128
0
    if (unlikely(me == NULL)) {
2129
0
      gnutls_assert();
2130
0
      ret = GNUTLS_E_INVALID_REQUEST;
2131
0
      goto cleanup;
2132
0
    }
2133
0
  }
2134
2135
0
  ret = _gnutls_pk_generate_keys(algo, bits, &key->params, 0);
2136
0
  if (ret < 0) {
2137
0
    gnutls_assert();
2138
0
    goto cleanup;
2139
0
  }
2140
2141
0
  ret = _gnutls_pk_verify_priv_params(algo, &key->params);
2142
0
  if (ret < 0) {
2143
0
    gnutls_assert();
2144
0
    goto cleanup;
2145
0
  }
2146
2147
0
  if (spki) {
2148
0
    ret = gnutls_x509_privkey_set_spki(key, spki, 0);
2149
0
    if (ret < 0) {
2150
0
      gnutls_assert();
2151
0
      goto cleanup;
2152
0
    }
2153
0
  }
2154
2155
  /* DH keys are only exportable in PKCS#8 format */
2156
0
  if (algo != GNUTLS_PK_DH) {
2157
0
    ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
2158
0
    if (ret < 0) {
2159
0
      gnutls_assert();
2160
0
      goto cleanup;
2161
0
    }
2162
0
  }
2163
2164
0
  return 0;
2165
2166
0
cleanup:
2167
0
  key->params.algo = GNUTLS_PK_UNKNOWN;
2168
0
  gnutls_pk_params_clear(&key->params);
2169
0
  gnutls_pk_params_release(&key->params);
2170
2171
0
  return ret;
2172
0
}
2173
2174
/**
2175
 * gnutls_x509_privkey_get_seed:
2176
 * @key: should contain a #gnutls_x509_privkey_t type
2177
 * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
2178
 * @seed: where seed will be copied to
2179
 * @seed_size: originally holds the size of @seed, will be updated with actual size
2180
 *
2181
 * This function will return the seed that was used to generate the
2182
 * given private key. That function will succeed only if the key was generated
2183
 * as a provable key.
2184
 *
2185
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2186
 *   negative error value.
2187
 *
2188
 * Since: 3.5.0
2189
 **/
2190
int gnutls_x509_privkey_get_seed(gnutls_x509_privkey_t key,
2191
         gnutls_digest_algorithm_t *digest, void *seed,
2192
         size_t *seed_size)
2193
0
{
2194
0
  if (key->params.seed_size == 0)
2195
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2196
2197
0
  if (seed_size == NULL || seed == NULL) {
2198
0
    if (key->params.seed_size)
2199
0
      return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2200
0
    else
2201
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2202
0
  }
2203
2204
0
  if (*seed_size < key->params.seed_size) {
2205
0
    *seed_size = key->params.seed_size;
2206
0
    return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2207
0
  }
2208
2209
0
  if (digest)
2210
0
    *digest = key->params.palgo;
2211
2212
0
  memcpy(seed, key->params.seed, key->params.seed_size);
2213
0
  *seed_size = key->params.seed_size;
2214
0
  return 0;
2215
0
}
2216
2217
static int cmp_rsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2218
0
{
2219
0
  gnutls_datum_t m1 = { NULL, 0 }, e1 = { NULL, 0 }, d1 = { NULL, 0 },
2220
0
           p1 = { NULL, 0 }, q1 = { NULL, 0 };
2221
0
  gnutls_datum_t m2 = { NULL, 0 }, e2 = { NULL, 0 }, d2 = { NULL, 0 },
2222
0
           p2 = { NULL, 0 }, q2 = { NULL, 0 };
2223
0
  int ret;
2224
2225
0
  ret = gnutls_x509_privkey_export_rsa_raw(key1, &m1, &e1, &d1, &p1, &q1,
2226
0
             NULL);
2227
0
  if (ret < 0) {
2228
0
    gnutls_assert();
2229
0
    return ret;
2230
0
  }
2231
2232
0
  ret = gnutls_x509_privkey_export_rsa_raw(key2, &m2, &e2, &d2, &p2, &q2,
2233
0
             NULL);
2234
0
  if (ret < 0) {
2235
0
    gnutls_assert();
2236
0
    goto cleanup;
2237
0
  }
2238
2239
0
  if (m1.size != m2.size || !memeq(m1.data, m2.data, m1.size)) {
2240
0
    gnutls_assert();
2241
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2242
0
    goto cleanup;
2243
0
  }
2244
2245
0
  if (d1.size != d2.size || !memeq(d1.data, d2.data, d1.size)) {
2246
0
    gnutls_assert();
2247
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2248
0
    goto cleanup;
2249
0
  }
2250
2251
0
  if (e1.size != e2.size || !memeq(e1.data, e2.data, e1.size)) {
2252
0
    gnutls_assert();
2253
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2254
0
    goto cleanup;
2255
0
  }
2256
2257
0
  if (p1.size != p2.size || !memeq(p1.data, p2.data, p1.size)) {
2258
0
    gnutls_assert();
2259
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2260
0
    goto cleanup;
2261
0
  }
2262
2263
0
  if (q1.size != q2.size || !memeq(q1.data, q2.data, q1.size)) {
2264
0
    gnutls_assert();
2265
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2266
0
    goto cleanup;
2267
0
  }
2268
2269
0
  ret = 0;
2270
0
cleanup:
2271
0
  gnutls_free(m1.data);
2272
0
  gnutls_free(e1.data);
2273
0
  gnutls_free(d1.data);
2274
0
  gnutls_free(p1.data);
2275
0
  gnutls_free(q1.data);
2276
0
  gnutls_free(m2.data);
2277
0
  gnutls_free(e2.data);
2278
0
  gnutls_free(d2.data);
2279
0
  gnutls_free(p2.data);
2280
0
  gnutls_free(q2.data);
2281
0
  return ret;
2282
0
}
2283
2284
static int cmp_dsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2285
0
{
2286
0
  gnutls_datum_t p1 = { NULL, 0 }, q1 = { NULL, 0 }, g1 = { NULL, 0 };
2287
0
  gnutls_datum_t p2 = { NULL, 0 }, q2 = { NULL, 0 }, g2 = { NULL, 0 };
2288
0
  int ret;
2289
2290
0
  ret = gnutls_x509_privkey_export_dsa_raw(key1, &p1, &q1, &g1, NULL,
2291
0
             NULL);
2292
0
  if (ret < 0) {
2293
0
    gnutls_assert();
2294
0
    return ret;
2295
0
  }
2296
2297
0
  ret = gnutls_x509_privkey_export_dsa_raw(key2, &p2, &q2, &g2, NULL,
2298
0
             NULL);
2299
0
  if (ret < 0) {
2300
0
    gnutls_assert();
2301
0
    goto cleanup;
2302
0
  }
2303
2304
0
  if (g1.size != g2.size || !memeq(g1.data, g2.data, g1.size)) {
2305
0
    gnutls_assert();
2306
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2307
0
    goto cleanup;
2308
0
  }
2309
2310
0
  if (p1.size != p2.size || !memeq(p1.data, p2.data, p1.size)) {
2311
0
    gnutls_assert();
2312
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2313
0
    goto cleanup;
2314
0
  }
2315
2316
0
  if (q1.size != q2.size || !memeq(q1.data, q2.data, q1.size)) {
2317
0
    gnutls_assert();
2318
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2319
0
    goto cleanup;
2320
0
  }
2321
2322
0
  ret = 0;
2323
0
cleanup:
2324
0
  gnutls_free(g1.data);
2325
0
  gnutls_free(p1.data);
2326
0
  gnutls_free(q1.data);
2327
0
  gnutls_free(g2.data);
2328
0
  gnutls_free(p2.data);
2329
0
  gnutls_free(q2.data);
2330
0
  return ret;
2331
0
}
2332
2333
/**
2334
 * gnutls_x509_privkey_verify_seed:
2335
 * @key: should contain a #gnutls_x509_privkey_t type
2336
 * @digest: it contains the digest algorithm used for key generation (if applicable)
2337
 * @seed: the seed of the key to be checked with
2338
 * @seed_size: holds the size of @seed
2339
 *
2340
 * This function will verify that the given private key was generated from
2341
 * the provided seed. If @seed is %NULL then the seed stored in the @key's structure
2342
 * will be used for verification.
2343
 *
2344
 * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
2345
 * is returned, and zero or positive code on success.
2346
 *
2347
 * Since: 3.5.0
2348
 **/
2349
int gnutls_x509_privkey_verify_seed(gnutls_x509_privkey_t key,
2350
            gnutls_digest_algorithm_t digest,
2351
            const void *seed, size_t seed_size)
2352
0
{
2353
0
  int ret;
2354
0
  gnutls_x509_privkey_t okey;
2355
0
  unsigned bits;
2356
0
  gnutls_keygen_data_st data;
2357
2358
0
  if (key == NULL) {
2359
0
    gnutls_assert();
2360
0
    return GNUTLS_E_INVALID_REQUEST;
2361
0
  }
2362
2363
0
  if (key->params.algo != GNUTLS_PK_RSA &&
2364
0
      key->params.algo != GNUTLS_PK_DSA)
2365
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
2366
2367
0
  ret = gnutls_x509_privkey_get_pk_algorithm2(key, &bits);
2368
0
  if (ret < 0)
2369
0
    return gnutls_assert_val(ret);
2370
2371
0
  ret = gnutls_x509_privkey_init(&okey);
2372
0
  if (ret < 0)
2373
0
    return gnutls_assert_val(ret);
2374
2375
0
  if (seed == NULL) {
2376
0
    seed = key->params.seed;
2377
0
    seed_size = key->params.seed_size;
2378
0
  }
2379
2380
0
  if (seed == NULL || seed_size == 0)
2381
0
    return gnutls_assert_val(GNUTLS_E_PK_NO_VALIDATION_PARAMS);
2382
2383
0
  data.type = GNUTLS_KEYGEN_SEED;
2384
0
  data.data = (void *)seed;
2385
0
  data.size = seed_size;
2386
2387
0
  ret = gnutls_x509_privkey_generate2(okey, key->params.algo, bits,
2388
0
              GNUTLS_PRIVKEY_FLAG_PROVABLE, &data,
2389
0
              1);
2390
0
  if (ret < 0) {
2391
0
    gnutls_assert();
2392
0
    goto cleanup;
2393
0
  }
2394
2395
0
  if (key->params.algo == GNUTLS_PK_RSA)
2396
0
    ret = cmp_rsa_key(key, okey);
2397
0
  else
2398
0
    ret = cmp_dsa_key(key, okey);
2399
2400
0
cleanup:
2401
0
  gnutls_x509_privkey_deinit(okey);
2402
2403
0
  return ret;
2404
0
}
2405
2406
/**
2407
 * gnutls_x509_privkey_verify_params:
2408
 * @key: a key
2409
 *
2410
 * This function will verify the private key parameters.
2411
 *
2412
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2413
 *   negative error value.
2414
 **/
2415
int gnutls_x509_privkey_verify_params(gnutls_x509_privkey_t key)
2416
0
{
2417
0
  int ret;
2418
2419
0
  ret = _gnutls_pk_verify_priv_params(key->params.algo, &key->params);
2420
0
  if (ret < 0) {
2421
0
    gnutls_assert();
2422
0
    return ret;
2423
0
  }
2424
2425
0
  return 0;
2426
0
}
2427
2428
/**
2429
 * gnutls_x509_privkey_get_key_id:
2430
 * @key: a key
2431
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
2432
 * @output_data: will contain the key ID
2433
 * @output_data_size: holds the size of output_data (and will be
2434
 *   replaced by the actual size of parameters)
2435
 *
2436
 * This function will return a unique ID that depends on the public key
2437
 * parameters. This ID can be used in checking whether a certificate
2438
 * corresponds to the given key.
2439
 *
2440
 * If the buffer provided is not long enough to hold the output, then
2441
 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2442
 * be returned.  The output will normally be a SHA-1 hash output,
2443
 * which is 20 bytes.
2444
 *
2445
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2446
 *   negative error value.
2447
 **/
2448
int gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,
2449
           unsigned int flags,
2450
           unsigned char *output_data,
2451
           size_t *output_data_size)
2452
0
{
2453
0
  int ret;
2454
2455
0
  if (key == NULL) {
2456
0
    gnutls_assert();
2457
0
    return GNUTLS_E_INVALID_REQUEST;
2458
0
  }
2459
2460
0
  ret = _gnutls_get_key_id(&key->params, output_data, output_data_size,
2461
0
         flags);
2462
0
  if (ret < 0) {
2463
0
    gnutls_assert();
2464
0
  }
2465
2466
0
  return ret;
2467
0
}
2468
2469
/**
2470
 * gnutls_x509_privkey_sign_hash:
2471
 * @key: a key
2472
 * @hash: holds the data to be signed
2473
 * @signature: will contain newly allocated signature
2474
 *
2475
 * This function will sign the given hash using the private key. Do not
2476
 * use this function directly unless you know what it is. Typical signing
2477
 * requires the data to be hashed and stored in special formats 
2478
 * (e.g. BER Digest-Info for RSA).
2479
 *
2480
 * This API is provided only for backwards compatibility, and thus
2481
 * restricted to RSA, DSA and ECDSA key types. For other key types please
2482
 * use gnutls_privkey_sign_hash() and gnutls_privkey_sign_data().
2483
 *
2484
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2485
 *   negative error value.
2486
 *
2487
 * Deprecated in: 2.12.0
2488
 */
2489
int gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,
2490
          const gnutls_datum_t *hash,
2491
          gnutls_datum_t *signature)
2492
0
{
2493
0
  int result;
2494
2495
0
  if (key == NULL) {
2496
0
    gnutls_assert();
2497
0
    return GNUTLS_E_INVALID_REQUEST;
2498
0
  }
2499
2500
0
  if (key->params.algo != GNUTLS_PK_RSA &&
2501
0
      key->params.algo != GNUTLS_PK_ECDSA &&
2502
0
      key->params.algo != GNUTLS_PK_DSA) {
2503
    /* too primitive API - use only with legacy types */
2504
0
    gnutls_assert();
2505
0
    return GNUTLS_E_INVALID_REQUEST;
2506
0
  }
2507
2508
0
  result = _gnutls_pk_sign(key->params.algo, signature, hash,
2509
0
         &key->params, &key->params.spki);
2510
2511
0
  if (result < 0) {
2512
0
    gnutls_assert();
2513
0
    return result;
2514
0
  }
2515
2516
0
  return 0;
2517
0
}
2518
2519
/**
2520
 * gnutls_x509_privkey_sign_data:
2521
 * @key: a key
2522
 * @digest: should be a digest algorithm
2523
 * @flags: should be 0 for now
2524
 * @data: holds the data to be signed
2525
 * @signature: will contain the signature
2526
 * @signature_size: holds the size of signature (and will be replaced
2527
 *   by the new size)
2528
 *
2529
 * This function will sign the given data using a signature algorithm
2530
 * supported by the private key. Signature algorithms are always used
2531
 * together with a hash functions.  Different hash functions may be
2532
 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
2533
 *
2534
 * If the buffer provided is not long enough to hold the output, then
2535
 * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2536
 * be returned.
2537
 *
2538
 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
2539
 * the hash algorithm.
2540
 *
2541
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2542
 *   negative error value.
2543
 */
2544
int gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,
2545
          gnutls_digest_algorithm_t digest,
2546
          unsigned int flags,
2547
          const gnutls_datum_t *data, void *signature,
2548
          size_t *signature_size)
2549
0
{
2550
0
  gnutls_privkey_t privkey;
2551
0
  gnutls_datum_t sig = { NULL, 0 };
2552
0
  int ret;
2553
2554
0
  ret = gnutls_privkey_init(&privkey);
2555
0
  if (ret < 0)
2556
0
    return gnutls_assert_val(ret);
2557
2558
0
  ret = gnutls_privkey_import_x509(privkey, key, 0);
2559
0
  if (ret < 0) {
2560
0
    gnutls_assert();
2561
0
    goto cleanup;
2562
0
  }
2563
2564
0
  ret = gnutls_privkey_sign_data(privkey, digest, flags, data, &sig);
2565
0
  if (ret < 0) {
2566
0
    gnutls_assert();
2567
0
    goto cleanup;
2568
0
  }
2569
2570
0
  if (*signature_size < sig.size) {
2571
0
    *signature_size = sig.size;
2572
0
    ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2573
0
    goto cleanup;
2574
0
  }
2575
2576
0
  *signature_size = sig.size;
2577
0
  memcpy(signature, sig.data, sig.size);
2578
2579
0
cleanup:
2580
0
  _gnutls_free_datum(&sig);
2581
0
  gnutls_privkey_deinit(privkey);
2582
0
  return ret;
2583
0
}
2584
2585
/**
2586
 * gnutls_x509_privkey_fix:
2587
 * @key: a key
2588
 *
2589
 * This function will recalculate the secondary parameters in a key.
2590
 * In RSA keys, this can be the coefficient and exponent1,2.
2591
 *
2592
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2593
 *   negative error value.
2594
 **/
2595
int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key)
2596
0
{
2597
0
  int ret;
2598
2599
0
  if (key == NULL) {
2600
0
    gnutls_assert();
2601
0
    return GNUTLS_E_INVALID_REQUEST;
2602
0
  }
2603
2604
0
  if (key->key) {
2605
0
    asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
2606
2607
0
    ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
2608
0
    if (ret < 0) {
2609
0
      gnutls_assert();
2610
0
      return ret;
2611
0
    }
2612
0
  }
2613
2614
0
  return 0;
2615
0
}
2616
2617
/**
2618
 * gnutls_x509_privkey_set_pin_function:
2619
 * @privkey: The certificate structure
2620
 * @fn: the callback
2621
 * @userdata: data associated with the callback
2622
 *
2623
 * This function will set a callback function to be used when
2624
 * it is required to access a protected object. This function overrides 
2625
 * the global function set using gnutls_pkcs11_set_pin_function().
2626
 *
2627
 * Note that this callback is used when decrypting a key.
2628
 *
2629
 * Since: 3.4.0
2630
 *
2631
 **/
2632
void gnutls_x509_privkey_set_pin_function(gnutls_x509_privkey_t privkey,
2633
            gnutls_pin_callback_t fn,
2634
            void *userdata)
2635
0
{
2636
0
  privkey->pin.cb = fn;
2637
0
  privkey->pin.data = userdata;
2638
0
}
2639
2640
/**
2641
 * gnutls_x509_privkey_set_flags:
2642
 * @key: A key of type #gnutls_x509_privkey_t
2643
 * @flags: flags from the %gnutls_privkey_flags
2644
 *
2645
 * This function will set flags for the specified private key, after
2646
 * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
2647
 * to allow exporting a "provable" private key in backwards compatible way.
2648
 *
2649
 * Since: 3.5.0
2650
 *
2651
 **/
2652
void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key,
2653
           unsigned int flags)
2654
0
{
2655
0
  key->flags |= flags;
2656
0
}