Coverage Report

Created: 2026-05-16 07:57

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
            memcmp(ptr, PEM_KEY_RSA,
605
0
             sizeof(PEM_KEY_RSA) - 1) == 0) {
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
             memcmp(ptr, PEM_KEY_ECC,
614
0
              sizeof(PEM_KEY_ECC) - 1) ==
615
0
               0) {
616
0
          result = _gnutls_fbase64_decode(
617
0
            PEM_KEY_ECC, begin_ptr, left,
618
0
            &_data);
619
0
          if (result >= 0)
620
0
            key->params.algo = GNUTLS_PK_EC;
621
0
        } else if (left > sizeof(PEM_KEY_DSA) &&
622
0
             memcmp(ptr, PEM_KEY_DSA,
623
0
              sizeof(PEM_KEY_DSA) - 1) ==
624
0
               0) {
625
0
          result = _gnutls_fbase64_decode(
626
0
            PEM_KEY_DSA, begin_ptr, left,
627
0
            &_data);
628
0
          if (result >= 0)
629
0
            key->params.algo =
630
0
              GNUTLS_PK_DSA;
631
0
        } else if (left > sizeof(PEM_KEY_ML_DSA) &&
632
0
             memcmp(ptr, PEM_KEY_ML_DSA,
633
0
              sizeof(PEM_KEY_ML_DSA) - 1) ==
634
0
               0) {
635
0
          result = _gnutls_fbase64_decode(
636
0
            PEM_KEY_ML_DSA, begin_ptr, left,
637
0
            &_data);
638
0
          if (result >= 0) {
639
0
            key->params.algo =
640
0
              GNUTLS_PK_MLDSA44;
641
0
          }
642
0
        }
643
644
0
        if (key->params.algo == GNUTLS_PK_UNKNOWN &&
645
0
            left >= sizeof(PEM_KEY_PKCS8)) {
646
0
          if (memcmp(ptr, PEM_KEY_PKCS8,
647
0
               sizeof(PEM_KEY_PKCS8) - 1) ==
648
0
              0) {
649
0
            result = _gnutls_fbase64_decode(
650
0
              PEM_KEY_PKCS8,
651
0
              begin_ptr, left,
652
0
              &_data);
653
0
            if (result >= 0) {
654
              /* signal for PKCS #8 keys */
655
0
              key->params.algo = -1;
656
0
            }
657
0
          }
658
0
        }
659
0
      }
660
0
    }
661
662
0
    if (result < 0) {
663
0
      gnutls_assert();
664
0
      return result;
665
0
    }
666
667
0
    need_free = 1;
668
0
  }
669
670
0
  if (key->expanded) {
671
0
    _gnutls_x509_privkey_reinit(key);
672
0
  }
673
0
  key->expanded = 1;
674
675
0
  if (key->params.algo == (gnutls_pk_algorithm_t)-1) {
676
0
    result = gnutls_x509_privkey_import_pkcs8(
677
0
      key, data, format, NULL, GNUTLS_PKCS_PLAIN);
678
0
    if (result < 0) {
679
0
      gnutls_assert();
680
0
      key->key = NULL;
681
0
      goto cleanup;
682
0
    } else {
683
      /* some keys under PKCS#8 don't set key->key */
684
0
      goto finish;
685
0
    }
686
0
  } else if (key->params.algo == GNUTLS_PK_RSA) {
687
0
    key->key = _gnutls_privkey_decode_pkcs1_rsa_key(&_data, key);
688
0
    if (key->key == NULL)
689
0
      gnutls_assert();
690
0
  } else if (key->params.algo == GNUTLS_PK_DSA) {
691
0
    key->key = decode_dsa_key(&_data, key);
692
0
    if (key->key == NULL)
693
0
      gnutls_assert();
694
0
  } else if (key->params.algo == GNUTLS_PK_EC) {
695
0
    result = _gnutls_privkey_decode_ecc_key(&key->key, &_data, key,
696
0
              0);
697
0
    if (result < 0) {
698
0
      gnutls_assert();
699
0
      key->key = NULL;
700
0
    }
701
0
  } else if (IS_ML_DSA(key->params.algo)) {
702
0
    result = _gnutls_privkey_decode_ml_dsa_key(&key->key, &_data,
703
0
                 key);
704
0
    if (result < 0) {
705
0
      gnutls_assert();
706
0
      key->key = NULL;
707
0
    }
708
0
  } else {
709
    /* Try decoding each of the keys, and accept the one that
710
     * succeeds.
711
     */
712
0
    key->params.algo = GNUTLS_PK_RSA;
713
0
    key->key = _gnutls_privkey_decode_pkcs1_rsa_key(&_data, key);
714
715
0
    if (key->key == NULL) {
716
0
      key->params.algo = GNUTLS_PK_DSA;
717
0
      key->key = decode_dsa_key(&_data, key);
718
0
      if (key->key == NULL) {
719
0
        key->params.algo = GNUTLS_PK_EC;
720
0
        result = _gnutls_privkey_decode_ecc_key(
721
0
          &key->key, &_data, key, 0);
722
0
        if (result < 0) {
723
0
          result =
724
0
            gnutls_x509_privkey_import_pkcs8(
725
0
              key, data, format, NULL,
726
0
              GNUTLS_PKCS_PLAIN);
727
0
          if (result >= 0) {
728
            /* there are keys (ed25519) which leave key->key NULL */
729
0
            goto finish;
730
0
          }
731
732
          /* result < 0 */
733
0
          gnutls_assert();
734
0
          key->key = NULL;
735
736
0
          if (result ==
737
0
              GNUTLS_E_PK_INVALID_PRIVKEY)
738
0
            goto cleanup;
739
0
        }
740
0
      }
741
0
    }
742
0
  }
743
744
0
  if (key->key == NULL) {
745
0
    gnutls_assert();
746
0
    result = GNUTLS_E_ASN1_DER_ERROR;
747
0
    goto cleanup;
748
0
  }
749
750
0
finish:
751
0
  result =
752
0
    _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
753
0
  if (result < 0) {
754
0
    gnutls_assert();
755
0
  }
756
757
0
cleanup:
758
0
  if (need_free) {
759
0
    zeroize_key(_data.data, _data.size);
760
0
    _gnutls_free_datum(&_data);
761
0
  }
762
763
  /* The key has now been decoded.
764
   */
765
766
0
  return result;
767
0
}
768
769
static int import_pkcs12_privkey(gnutls_x509_privkey_t key,
770
         const gnutls_datum_t *data,
771
         gnutls_x509_crt_fmt_t format,
772
         const char *password, unsigned int flags)
773
0
{
774
0
  int ret;
775
0
  gnutls_pkcs12_t p12;
776
0
  gnutls_x509_privkey_t newkey;
777
778
0
  ret = gnutls_pkcs12_init(&p12);
779
0
  if (ret < 0)
780
0
    return gnutls_assert_val(ret);
781
782
0
  ret = gnutls_pkcs12_import(p12, data, format, flags);
783
0
  if (ret < 0) {
784
0
    gnutls_assert();
785
0
    goto fail;
786
0
  }
787
788
0
  ret = gnutls_pkcs12_simple_parse(p12, password, &newkey, NULL, NULL,
789
0
           NULL, NULL, NULL, 0);
790
0
  if (ret < 0) {
791
0
    gnutls_assert();
792
0
    goto fail;
793
0
  }
794
795
0
  ret = gnutls_x509_privkey_cpy(key, newkey);
796
0
  gnutls_x509_privkey_deinit(newkey);
797
0
  if (ret < 0) {
798
0
    gnutls_assert();
799
0
    goto fail;
800
0
  }
801
802
0
  ret = 0;
803
0
fail:
804
805
0
  gnutls_pkcs12_deinit(p12);
806
807
0
  return ret;
808
0
}
809
810
0
#define MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER 21
811
812
/**
813
 * gnutls_x509_privkey_import2:
814
 * @key: The data to store the parsed key
815
 * @data: The DER or PEM encoded key.
816
 * @format: One of DER or PEM
817
 * @password: A password (optional)
818
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
819
 *
820
 * This function will import the given DER or PEM encoded key, to 
821
 * the native #gnutls_x509_privkey_t format, irrespective of the
822
 * input format. The input format is auto-detected.
823
 *
824
 * The supported formats are basic unencrypted key, PKCS8, PKCS12,
825
 * and the openssl format.
826
 *
827
 * If the provided key is encrypted but no password was given, then
828
 * %GNUTLS_E_DECRYPTION_FAILED is returned. Since GnuTLS 3.4.0 this
829
 * function will utilize the PIN callbacks if any.
830
 *
831
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
832
 *   negative error value.
833
 **/
834
int gnutls_x509_privkey_import2(gnutls_x509_privkey_t key,
835
        const gnutls_datum_t *data,
836
        gnutls_x509_crt_fmt_t format,
837
        const char *password, unsigned int flags)
838
0
{
839
0
  int ret = 0;
840
0
  int saved_ret = GNUTLS_E_PARSING_ERROR;
841
0
  char pin[GNUTLS_PKCS11_MAX_PIN_LEN];
842
0
  unsigned head_enc = 1;
843
844
0
  if (format == GNUTLS_X509_FMT_PEM) {
845
0
    size_t left;
846
0
    char *ptr;
847
848
0
    ptr = memmem(data->data, data->size, "PRIVATE KEY-----",
849
0
           sizeof("PRIVATE KEY-----") - 1);
850
851
0
    if (ptr != NULL) {
852
0
      left = data->size -
853
0
             ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
854
855
0
      if (data->size - left >
856
0
          MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER) {
857
0
        ptr -= MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER;
858
0
        left += MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER;
859
0
      } else {
860
0
        ptr = (char *)data->data;
861
0
        left = data->size;
862
0
      }
863
864
0
      ptr = memmem(ptr, left, "-----BEGIN ",
865
0
             sizeof("-----BEGIN ") - 1);
866
0
      if (ptr != NULL) {
867
0
        ptr += sizeof("-----BEGIN ") - 1;
868
0
        left = data->size -
869
0
               ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
870
0
      }
871
872
0
      if (ptr != NULL) {
873
0
        if ((left > sizeof(PEM_KEY_RSA) &&
874
0
             memcmp(ptr, PEM_KEY_RSA,
875
0
              sizeof(PEM_KEY_RSA) - 1) == 0) ||
876
0
            (left > sizeof(PEM_KEY_ECC) &&
877
0
             memcmp(ptr, PEM_KEY_ECC,
878
0
              sizeof(PEM_KEY_ECC) - 1) == 0) ||
879
0
            (left > sizeof(PEM_KEY_DSA) &&
880
0
             memcmp(ptr, PEM_KEY_DSA,
881
0
              sizeof(PEM_KEY_DSA) - 1) == 0) ||
882
0
            (left > sizeof(PEM_KEY_ML_DSA) &&
883
0
             memcmp(ptr, PEM_KEY_ML_DSA,
884
0
              sizeof(PEM_KEY_ML_DSA) - 1) == 0)) {
885
0
          head_enc = 0;
886
0
        }
887
0
      }
888
0
    }
889
0
  }
890
891
0
  if (head_enc == 0 ||
892
0
      (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD))) {
893
0
    ret = gnutls_x509_privkey_import(key, data, format);
894
0
    if (ret >= 0)
895
0
      return ret;
896
897
0
    gnutls_assert();
898
0
    saved_ret = ret;
899
    /* fall through to PKCS #8 decoding */
900
0
  }
901
902
0
  if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD)) ||
903
0
      ret < 0) {
904
0
    ret = gnutls_x509_privkey_import_pkcs8(key, data, format,
905
0
                   password, flags);
906
907
0
    if (ret == GNUTLS_E_DECRYPTION_FAILED && password == NULL &&
908
0
        (!(flags & GNUTLS_PKCS_PLAIN))) {
909
      /* use the callback if any */
910
0
      ret = _gnutls_retrieve_pin(&key->pin, "key:", "", 0,
911
0
               pin, sizeof(pin));
912
0
      if (ret == 0) {
913
0
        password = pin;
914
0
      }
915
916
0
      ret = gnutls_x509_privkey_import_pkcs8(
917
0
        key, data, format, password, flags);
918
0
    }
919
920
0
    if (saved_ret == GNUTLS_E_PARSING_ERROR)
921
0
      saved_ret = ret;
922
923
0
    if (ret < 0) {
924
0
      if (ret == GNUTLS_E_DECRYPTION_FAILED)
925
0
        goto cleanup;
926
0
      ret = import_pkcs12_privkey(key, data, format, password,
927
0
                flags);
928
0
      if (ret < 0 && format == GNUTLS_X509_FMT_PEM) {
929
0
        if (ret == GNUTLS_E_DECRYPTION_FAILED)
930
0
          goto cleanup;
931
932
0
        ret = gnutls_x509_privkey_import_openssl(
933
0
          key, data, password);
934
935
0
        if (ret == GNUTLS_E_DECRYPTION_FAILED &&
936
0
            password == NULL &&
937
0
            (key->pin.cb || _gnutls_pin_func)) {
938
          /* use the callback if any */
939
0
          memset(pin, 0,
940
0
                 GNUTLS_PKCS11_MAX_PIN_LEN);
941
0
          ret = _gnutls_retrieve_pin(&key->pin,
942
0
                   "key:", "",
943
0
                   0, pin,
944
0
                   sizeof(pin));
945
0
          if (ret == 0) {
946
0
            ret = gnutls_x509_privkey_import_openssl(
947
0
              key, data, pin);
948
0
          }
949
0
        }
950
951
0
        if (ret < 0) {
952
0
          gnutls_assert();
953
0
          goto cleanup;
954
0
        }
955
0
      } else {
956
0
        gnutls_assert();
957
0
        goto cleanup;
958
0
      }
959
0
    }
960
0
  }
961
962
0
  ret = 0;
963
964
0
cleanup:
965
0
  if (ret == GNUTLS_E_PARSING_ERROR)
966
0
    ret = saved_ret;
967
968
0
  return ret;
969
0
}
970
971
/**
972
 * gnutls_x509_privkey_import_rsa_raw:
973
 * @key: The data to store the parsed key
974
 * @m: holds the modulus
975
 * @e: holds the public exponent
976
 * @d: holds the private exponent
977
 * @p: holds the first prime (p)
978
 * @q: holds the second prime (q)
979
 * @u: holds the coefficient
980
 *
981
 * This function will convert the given RSA raw parameters to the
982
 * native #gnutls_x509_privkey_t format.  The output will be stored in
983
 * @key.
984
 *
985
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
986
 *   negative error value.
987
 **/
988
int gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
989
               const gnutls_datum_t *m,
990
               const gnutls_datum_t *e,
991
               const gnutls_datum_t *d,
992
               const gnutls_datum_t *p,
993
               const gnutls_datum_t *q,
994
               const gnutls_datum_t *u)
995
0
{
996
0
  return gnutls_x509_privkey_import_rsa_raw2(key, m, e, d, p, q, u, NULL,
997
0
               NULL);
998
0
}
999
1000
/**
1001
 * gnutls_x509_privkey_import_rsa_raw2:
1002
 * @key: The data to store the parsed key
1003
 * @m: holds the modulus
1004
 * @e: holds the public exponent
1005
 * @d: holds the private exponent
1006
 * @p: holds the first prime (p)
1007
 * @q: holds the second prime (q)
1008
 * @u: holds the coefficient (optional)
1009
 * @e1: holds e1 = d mod (p-1) (optional)
1010
 * @e2: holds e2 = d mod (q-1) (optional)
1011
 *
1012
 * This function will convert the given RSA raw parameters to the
1013
 * native #gnutls_x509_privkey_t format.  The output will be stored in
1014
 * @key.
1015
 *
1016
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1017
 *   negative error value.
1018
 **/
1019
int gnutls_x509_privkey_import_rsa_raw2(
1020
  gnutls_x509_privkey_t key, const gnutls_datum_t *m,
1021
  const gnutls_datum_t *e, const gnutls_datum_t *d,
1022
  const gnutls_datum_t *p, const gnutls_datum_t *q,
1023
  const gnutls_datum_t *u, const gnutls_datum_t *e1,
1024
  const gnutls_datum_t *e2)
1025
0
{
1026
0
  int ret;
1027
1028
0
  if (key == NULL) {
1029
0
    gnutls_assert();
1030
0
    return GNUTLS_E_INVALID_REQUEST;
1031
0
  }
1032
1033
0
  gnutls_pk_params_init(&key->params);
1034
1035
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_MODULUS], m->data,
1036
0
             m->size)) {
1037
0
    gnutls_assert();
1038
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1039
0
    goto cleanup;
1040
0
  }
1041
0
  key->params.params_nr++;
1042
1043
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PUB], e->data,
1044
0
             e->size)) {
1045
0
    gnutls_assert();
1046
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1047
0
    goto cleanup;
1048
0
  }
1049
0
  key->params.params_nr++;
1050
1051
0
  if (d) {
1052
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIV],
1053
0
               d->data, d->size)) {
1054
0
      gnutls_assert();
1055
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1056
0
      goto cleanup;
1057
0
    }
1058
0
    key->params.params_nr++;
1059
0
  }
1060
1061
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIME1], p->data,
1062
0
             p->size)) {
1063
0
    gnutls_assert();
1064
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1065
0
    goto cleanup;
1066
0
  }
1067
0
  key->params.params_nr++;
1068
1069
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIME2], q->data,
1070
0
             q->size)) {
1071
0
    gnutls_assert();
1072
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1073
0
    goto cleanup;
1074
0
  }
1075
0
  key->params.params_nr++;
1076
1077
0
  if (u) {
1078
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_COEF],
1079
0
               u->data, u->size)) {
1080
0
      gnutls_assert();
1081
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1082
0
      goto cleanup;
1083
0
    }
1084
0
    key->params.params_nr++;
1085
0
  }
1086
1087
0
  if (e1 && e2) {
1088
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_E1],
1089
0
               e1->data, e1->size)) {
1090
0
      gnutls_assert();
1091
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1092
0
      goto cleanup;
1093
0
    }
1094
0
    key->params.params_nr++;
1095
1096
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_E2],
1097
0
               e2->data, e2->size)) {
1098
0
      gnutls_assert();
1099
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1100
0
      goto cleanup;
1101
0
    }
1102
0
    key->params.params_nr++;
1103
0
  }
1104
1105
0
  key->params.algo = GNUTLS_PK_RSA;
1106
1107
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
1108
0
  if (ret < 0) {
1109
0
    gnutls_assert();
1110
0
    goto cleanup;
1111
0
  }
1112
1113
0
  key->params.params_nr = RSA_PRIVATE_PARAMS;
1114
0
  key->params.algo = GNUTLS_PK_RSA;
1115
1116
0
  ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1117
0
  if (ret < 0) {
1118
0
    gnutls_assert();
1119
0
    goto cleanup;
1120
0
  }
1121
1122
0
  return 0;
1123
1124
0
cleanup:
1125
0
  gnutls_pk_params_clear(&key->params);
1126
0
  gnutls_pk_params_release(&key->params);
1127
0
  return ret;
1128
0
}
1129
1130
/**
1131
 * gnutls_x509_privkey_import_dsa_raw:
1132
 * @key: The data to store the parsed key
1133
 * @p: holds the p
1134
 * @q: holds the q
1135
 * @g: holds the g
1136
 * @y: holds the y (optional)
1137
 * @x: holds the x
1138
 *
1139
 * This function will convert the given DSA raw parameters to the
1140
 * native #gnutls_x509_privkey_t format.  The output will be stored
1141
 * in @key.
1142
 *
1143
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1144
 *   negative error value.
1145
 **/
1146
int gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
1147
               const gnutls_datum_t *p,
1148
               const gnutls_datum_t *q,
1149
               const gnutls_datum_t *g,
1150
               const gnutls_datum_t *y,
1151
               const gnutls_datum_t *x)
1152
0
{
1153
0
  int ret;
1154
1155
0
  if (unlikely(key == NULL || p == NULL || q == NULL || g == NULL ||
1156
0
         x == NULL)) {
1157
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1158
0
  }
1159
1160
0
  gnutls_pk_params_init(&key->params);
1161
1162
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_P], p->data,
1163
0
             p->size)) {
1164
0
    gnutls_assert();
1165
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1166
0
    goto cleanup;
1167
0
  }
1168
1169
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Q], q->data,
1170
0
             q->size)) {
1171
0
    gnutls_assert();
1172
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1173
0
    goto cleanup;
1174
0
  }
1175
1176
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_G], g->data,
1177
0
             g->size)) {
1178
0
    gnutls_assert();
1179
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1180
0
    goto cleanup;
1181
0
  }
1182
1183
0
  if (y) {
1184
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Y],
1185
0
               y->data, y->size)) {
1186
0
      gnutls_assert();
1187
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1188
0
      goto cleanup;
1189
0
    }
1190
0
  }
1191
1192
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_X], x->data,
1193
0
             x->size)) {
1194
0
    gnutls_assert();
1195
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1196
0
    goto cleanup;
1197
0
  }
1198
1199
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_DSA, GNUTLS_IMPORT, &key->params);
1200
0
  if (ret < 0) {
1201
0
    gnutls_assert();
1202
0
    goto cleanup;
1203
0
  }
1204
1205
0
  key->params.algo = GNUTLS_PK_DSA;
1206
0
  key->params.params_nr = DSA_PRIVATE_PARAMS;
1207
1208
0
  ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1209
0
  if (ret < 0) {
1210
0
    gnutls_assert();
1211
0
    goto cleanup;
1212
0
  }
1213
1214
0
  return 0;
1215
1216
0
cleanup:
1217
0
  gnutls_pk_params_clear(&key->params);
1218
0
  gnutls_pk_params_release(&key->params);
1219
0
  return ret;
1220
0
}
1221
1222
/**
1223
 * gnutls_x509_privkey_import_dh_raw:
1224
 * @key: The data to store the parsed key
1225
 * @params: holds the %gnutls_dh_params_t
1226
 * @y: holds the y (optional)
1227
 * @x: holds the x
1228
 *
1229
 * This function will convert the given Diffie-Hellman raw parameters
1230
 * to the native #gnutls_x509_privkey_t format.  The output will be
1231
 * stored in @key.
1232
 *
1233
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1234
 *   negative error value.
1235
 **/
1236
int gnutls_x509_privkey_import_dh_raw(gnutls_x509_privkey_t key,
1237
              const gnutls_dh_params_t params,
1238
              const gnutls_datum_t *y,
1239
              const gnutls_datum_t *x)
1240
0
{
1241
0
  int ret;
1242
1243
0
  if (unlikely(key == NULL || params == NULL || x == NULL)) {
1244
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1245
0
  }
1246
1247
0
  gnutls_pk_params_init(&key->params);
1248
1249
0
  key->params.params[DH_P] = _gnutls_mpi_copy(params->params[0]);
1250
0
  key->params.params[DH_G] = _gnutls_mpi_copy(params->params[1]);
1251
0
  if (params->params[2]) {
1252
0
    key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
1253
0
  }
1254
0
  key->params.qbits = params->q_bits;
1255
1256
0
  if (y) {
1257
0
    if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
1258
0
               y->size)) {
1259
0
      gnutls_assert();
1260
0
      ret = GNUTLS_E_MPI_SCAN_FAILED;
1261
0
      goto cleanup;
1262
0
    }
1263
0
  }
1264
1265
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_X], x->data,
1266
0
             x->size)) {
1267
0
    gnutls_assert();
1268
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1269
0
    goto cleanup;
1270
0
  }
1271
1272
0
  ret = _gnutls_pk_fixup(GNUTLS_PK_DH, GNUTLS_IMPORT, &key->params);
1273
0
  if (ret < 0) {
1274
0
    gnutls_assert();
1275
0
    goto cleanup;
1276
0
  }
1277
1278
0
  key->params.algo = GNUTLS_PK_DH;
1279
0
  key->params.params_nr = DH_PRIVATE_PARAMS;
1280
1281
0
  return 0;
1282
1283
0
cleanup:
1284
0
  gnutls_pk_params_clear(&key->params);
1285
0
  gnutls_pk_params_release(&key->params);
1286
0
  return ret;
1287
0
}
1288
1289
/**
1290
 * gnutls_x509_privkey_import_ecc_raw:
1291
 * @key: The data to store the parsed key
1292
 * @curve: holds the curve
1293
 * @x: holds the x-coordinate
1294
 * @y: holds the y-coordinate
1295
 * @k: holds the k
1296
 *
1297
 * This function will convert the given elliptic curve parameters to the
1298
 * native #gnutls_x509_privkey_t format.  The output will be stored
1299
 * in @key. For EdDSA keys, the @x and @k values must be in the
1300
 * native to curve format.
1301
 *
1302
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1303
 *   negative error value.
1304
 *
1305
 * Since: 3.0
1306
 **/
1307
int gnutls_x509_privkey_import_ecc_raw(gnutls_x509_privkey_t key,
1308
               gnutls_ecc_curve_t curve,
1309
               const gnutls_datum_t *x,
1310
               const gnutls_datum_t *y,
1311
               const gnutls_datum_t *k)
1312
0
{
1313
0
  int ret;
1314
1315
0
  if (key == NULL) {
1316
0
    gnutls_assert();
1317
0
    return GNUTLS_E_INVALID_REQUEST;
1318
0
  }
1319
1320
0
  gnutls_pk_params_init(&key->params);
1321
1322
0
  key->params.curve = curve;
1323
1324
0
  if (curve_is_eddsa(curve) || curve_is_modern_ecdh(curve)) {
1325
0
    unsigned size;
1326
0
    switch (curve) {
1327
0
    case GNUTLS_ECC_CURVE_ED25519:
1328
0
      key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1329
0
      break;
1330
0
    case GNUTLS_ECC_CURVE_ED448:
1331
0
      key->params.algo = GNUTLS_PK_EDDSA_ED448;
1332
0
      break;
1333
0
    case GNUTLS_ECC_CURVE_X25519:
1334
0
      key->params.algo = GNUTLS_PK_ECDH_X25519;
1335
0
      break;
1336
0
    case GNUTLS_ECC_CURVE_X448:
1337
0
      key->params.algo = GNUTLS_PK_ECDH_X448;
1338
0
      break;
1339
0
    default:
1340
0
      ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1341
0
      goto cleanup;
1342
0
    }
1343
1344
0
    size = gnutls_ecc_curve_get_size(curve);
1345
0
    if ((x && x->size != size) || k->size != size) {
1346
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1347
0
      goto cleanup;
1348
0
    }
1349
1350
0
    ret = _gnutls_set_datum(&key->params.raw_priv, k->data,
1351
0
          k->size);
1352
0
    if (ret < 0) {
1353
0
      gnutls_assert();
1354
0
      goto cleanup;
1355
0
    }
1356
1357
0
    if (x) {
1358
0
      ret = _gnutls_set_datum(&key->params.raw_pub, x->data,
1359
0
            x->size);
1360
0
      if (ret < 0) {
1361
0
        gnutls_assert();
1362
0
        goto cleanup;
1363
0
      }
1364
0
    } else {
1365
0
      ret = _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT,
1366
0
                 &key->params);
1367
0
      if (ret < 0) {
1368
0
        gnutls_assert();
1369
0
        goto cleanup;
1370
0
      }
1371
0
    }
1372
1373
0
    return 0;
1374
0
  }
1375
1376
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[ECC_K], k->data,
1377
0
             k->size)) {
1378
0
    gnutls_assert();
1379
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1380
0
    goto cleanup;
1381
0
  }
1382
0
  key->params.params_nr++;
1383
1384
0
  key->params.algo = GNUTLS_PK_EC;
1385
1386
0
  if (x && y) {
1387
0
    ret = _gnutls_mpi_init_scan_nz(&key->params.params[ECC_X],
1388
0
                 x->data, x->size);
1389
0
    if (ret < 0) {
1390
0
      ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
1391
0
      goto cleanup;
1392
0
    }
1393
0
    key->params.params_nr++;
1394
1395
0
    ret = _gnutls_mpi_init_scan_nz(&key->params.params[ECC_Y],
1396
0
                 y->data, y->size);
1397
0
    if (ret < 0) {
1398
0
      ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
1399
0
      goto cleanup;
1400
0
    }
1401
0
    key->params.params_nr++;
1402
0
  } else {
1403
0
    ret = _gnutls_pk_fixup(GNUTLS_PK_EC, GNUTLS_IMPORT,
1404
0
               &key->params);
1405
0
    if (ret < 0) {
1406
0
      gnutls_assert();
1407
0
      goto cleanup;
1408
0
    }
1409
0
  }
1410
1411
0
  ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1412
0
  if (ret < 0) {
1413
0
    gnutls_assert();
1414
0
    goto cleanup;
1415
0
  }
1416
1417
0
  return 0;
1418
1419
0
cleanup:
1420
0
  gnutls_pk_params_clear(&key->params);
1421
0
  gnutls_pk_params_release(&key->params);
1422
0
  return ret;
1423
0
}
1424
1425
/**
1426
 * gnutls_x509_privkey_import_gost_raw:
1427
 * @key: The data to store the parsed key
1428
 * @curve: holds the curve
1429
 * @digest: will hold the digest
1430
 * @paramset: will hold the GOST parameter set ID
1431
 * @x: holds the x-coordinate
1432
 * @y: holds the y-coordinate
1433
 * @k: holds the k (private key)
1434
 *
1435
 * This function will convert the given GOST private key's parameters to the
1436
 * native #gnutls_x509_privkey_t format.  The output will be stored
1437
 * in @key.  @digest should be one of GNUTLS_DIG_GOSR_94,
1438
 * GNUTLS_DIG_STREEBOG_256 or GNUTLS_DIG_STREEBOG_512.  If @paramset is set to
1439
 * GNUTLS_GOST_PARAMSET_UNKNOWN default one will be selected depending on
1440
 * @digest.
1441
 *
1442
 * Note: parameters should be stored with least significant byte first. On
1443
 * version 3.6.3 big-endian format was used incorrectly.
1444
 *
1445
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1446
 *   negative error value.
1447
 *
1448
 * Since: 3.6.3
1449
 **/
1450
int gnutls_x509_privkey_import_gost_raw(gnutls_x509_privkey_t key,
1451
          gnutls_ecc_curve_t curve,
1452
          gnutls_digest_algorithm_t digest,
1453
          gnutls_gost_paramset_t paramset,
1454
          const gnutls_datum_t *x,
1455
          const gnutls_datum_t *y,
1456
          const gnutls_datum_t *k)
1457
0
{
1458
0
  int ret;
1459
1460
0
  if (key == NULL) {
1461
0
    gnutls_assert();
1462
0
    return GNUTLS_E_INVALID_REQUEST;
1463
0
  }
1464
1465
0
  key->params.curve = curve;
1466
0
  key->params.algo = _gnutls_digest_gost(digest);
1467
1468
0
  if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1469
0
    paramset = _gnutls_gost_paramset_default(key->params.algo);
1470
1471
0
  key->params.gost_params = paramset;
1472
1473
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_X], x->data,
1474
0
             x->size)) {
1475
0
    gnutls_assert();
1476
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1477
0
    goto cleanup;
1478
0
  }
1479
0
  key->params.params_nr++;
1480
1481
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_Y], y->data,
1482
0
             y->size)) {
1483
0
    gnutls_assert();
1484
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1485
0
    goto cleanup;
1486
0
  }
1487
0
  key->params.params_nr++;
1488
1489
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_K], k->data,
1490
0
             k->size)) {
1491
0
    gnutls_assert();
1492
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1493
0
    goto cleanup;
1494
0
  }
1495
0
  key->params.params_nr++;
1496
1497
0
  ret = _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
1498
0
  if (ret < 0) {
1499
0
    gnutls_assert();
1500
0
    goto cleanup;
1501
0
  }
1502
1503
0
  return 0;
1504
1505
0
cleanup:
1506
0
  gnutls_pk_params_clear(&key->params);
1507
0
  gnutls_pk_params_release(&key->params);
1508
0
  return ret;
1509
0
}
1510
1511
/**
1512
 * gnutls_x509_privkey_get_pk_algorithm:
1513
 * @key: should contain a #gnutls_x509_privkey_t type
1514
 *
1515
 * This function will return the public key algorithm of a private
1516
 * key.
1517
 *
1518
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1519
 *   success, or a negative error code on error.
1520
 **/
1521
int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key)
1522
0
{
1523
0
  if (key == NULL) {
1524
0
    gnutls_assert();
1525
0
    return GNUTLS_E_INVALID_REQUEST;
1526
0
  }
1527
1528
0
  return key->params.algo;
1529
0
}
1530
1531
/**
1532
 * gnutls_x509_privkey_get_pk_algorithm2:
1533
 * @key: should contain a #gnutls_x509_privkey_t type
1534
 * @bits: The number of bits in the public key algorithm
1535
 *
1536
 * This function will return the public key algorithm of a private
1537
 * key.
1538
 *
1539
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1540
 *   success, or a negative error code on error.
1541
 **/
1542
int gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t key,
1543
            unsigned int *bits)
1544
0
{
1545
0
  int ret;
1546
1547
0
  if (key == NULL) {
1548
0
    gnutls_assert();
1549
0
    return GNUTLS_E_INVALID_REQUEST;
1550
0
  }
1551
1552
0
  if (bits) {
1553
0
    ret = pubkey_to_bits(&key->params);
1554
0
    if (ret < 0)
1555
0
      ret = 0;
1556
0
    *bits = ret;
1557
0
  }
1558
1559
0
  return key->params.algo;
1560
0
}
1561
1562
int _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
1563
           gnutls_x509_spki_st *params)
1564
0
{
1565
0
  return _gnutls_x509_spki_copy(params, &key->params.spki);
1566
0
}
1567
1568
/**
1569
 * gnutls_x509_privkey_get_spki:
1570
 * @key: should contain a #gnutls_x509_privkey_t type
1571
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1572
 * @flags: must be zero
1573
 *
1574
 * This function will return the public key information of a private
1575
 * key. The provided @spki must be initialized.
1576
 *
1577
 * Returns: Zero on success, or a negative error code on error.
1578
 **/
1579
int gnutls_x509_privkey_get_spki(gnutls_x509_privkey_t key,
1580
         gnutls_x509_spki_t spki, unsigned int flags)
1581
0
{
1582
0
  if (key == NULL) {
1583
0
    gnutls_assert();
1584
0
    return GNUTLS_E_INVALID_REQUEST;
1585
0
  }
1586
1587
0
  if (key->params.spki.pk == GNUTLS_PK_UNKNOWN)
1588
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1589
1590
0
  return _gnutls_x509_privkey_get_spki_params(key, spki);
1591
0
}
1592
1593
/**
1594
 * gnutls_x509_privkey_set_spki:
1595
 * @key: should contain a #gnutls_x509_privkey_t type
1596
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1597
 * @flags: must be zero
1598
 *
1599
 * This function will return the public key information of a private
1600
 * key. The provided @spki must be initialized.
1601
 *
1602
 * Returns: Zero on success, or a negative error code on error.
1603
 **/
1604
int gnutls_x509_privkey_set_spki(gnutls_x509_privkey_t key,
1605
         const gnutls_x509_spki_t spki,
1606
         unsigned int flags)
1607
0
{
1608
0
  gnutls_pk_params_st tparams;
1609
0
  int ret;
1610
1611
0
  if (key == NULL) {
1612
0
    gnutls_assert();
1613
0
    return GNUTLS_E_INVALID_REQUEST;
1614
0
  }
1615
1616
0
  if (!_gnutls_pk_are_compat(key->params.algo, spki->pk))
1617
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1618
1619
0
  memcpy(&tparams, &key->params, sizeof(gnutls_pk_params_st));
1620
  /* No need for a deep copy, as this is only for one time check */
1621
0
  memcpy(&tparams.spki, spki, sizeof(gnutls_x509_spki_st));
1622
0
  ret = _gnutls_x509_check_pubkey_params(&tparams);
1623
0
  if (ret < 0)
1624
0
    return gnutls_assert_val(ret);
1625
1626
0
  ret = _gnutls_x509_spki_copy(&key->params.spki, spki);
1627
0
  if (ret < 0)
1628
0
    return gnutls_assert_val(ret);
1629
1630
0
  key->params.algo = spki->pk;
1631
1632
0
  return 0;
1633
0
}
1634
1635
static const char *set_msg(gnutls_x509_privkey_t key)
1636
0
{
1637
0
  switch (key->params.algo) {
1638
0
  case GNUTLS_PK_RSA:
1639
0
  case GNUTLS_PK_RSA_PSS:
1640
0
    return PEM_KEY_RSA;
1641
0
  case GNUTLS_PK_DSA:
1642
0
    return PEM_KEY_DSA;
1643
0
  case GNUTLS_PK_EC:
1644
0
    return PEM_KEY_ECC;
1645
0
  case GNUTLS_PK_MLDSA44:
1646
0
  case GNUTLS_PK_MLDSA65:
1647
0
  case GNUTLS_PK_MLDSA87:
1648
0
    return PEM_KEY_ML_DSA;
1649
0
  default:
1650
0
    return "UNKNOWN";
1651
0
  }
1652
0
}
1653
1654
/**
1655
 * gnutls_x509_privkey_export:
1656
 * @key: Holds the key
1657
 * @format: the format of output params. One of PEM or DER.
1658
 * @output_data: will contain a private key PEM or DER encoded
1659
 * @output_data_size: holds the size of output_data (and will be
1660
 *   replaced by the actual size of parameters)
1661
 *
1662
 * This function will export the private key to a PKCS#1 structure for
1663
 * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1664
 * will be exported in PKCS#8 form.
1665
 *
1666
 * If the structure is PEM encoded, it will have a header
1667
 * of "BEGIN RSA PRIVATE KEY".
1668
 *
1669
 * It is recommended to use gnutls_x509_privkey_export_pkcs8() instead
1670
 * of this function, when a consistent output format is required.
1671
 *
1672
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1673
 *   negative error value.
1674
 **/
1675
int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
1676
             gnutls_x509_crt_fmt_t format, void *output_data,
1677
             size_t *output_data_size)
1678
0
{
1679
0
  gnutls_datum_t out;
1680
0
  int ret;
1681
1682
0
  ret = gnutls_x509_privkey_export2(key, format, &out);
1683
0
  if (ret < 0)
1684
0
    return gnutls_assert_val(ret);
1685
1686
0
  if (format == GNUTLS_X509_FMT_PEM)
1687
0
    ret = _gnutls_copy_string(&out, output_data, output_data_size);
1688
0
  else
1689
0
    ret = _gnutls_copy_data(&out, output_data, output_data_size);
1690
0
  gnutls_free(out.data);
1691
1692
0
  return ret;
1693
0
}
1694
1695
/**
1696
 * gnutls_x509_privkey_export2:
1697
 * @key: Holds the key
1698
 * @format: the format of output params. One of PEM or DER.
1699
 * @out: will contain a private key PEM or DER encoded
1700
 *
1701
 * This function will export the private key to a PKCS#1 structure for
1702
 * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1703
 * will be exported in PKCS#8 form.
1704
 *
1705
 * The output buffer is allocated using gnutls_malloc().
1706
 *
1707
 * It is recommended to use gnutls_x509_privkey_export2_pkcs8() instead
1708
 * of this function, when a consistent output format is required.
1709
 *
1710
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1711
 *   negative error value.
1712
 *
1713
 * Since 3.1.3
1714
 **/
1715
int gnutls_x509_privkey_export2(gnutls_x509_privkey_t key,
1716
        gnutls_x509_crt_fmt_t format,
1717
        gnutls_datum_t *out)
1718
0
{
1719
0
  const char *msg;
1720
0
  int ret;
1721
1722
0
  if (key == NULL) {
1723
0
    gnutls_assert();
1724
0
    return GNUTLS_E_INVALID_REQUEST;
1725
0
  }
1726
1727
0
  if (key->key == NULL) { /* can only export in PKCS#8 form */
1728
0
    return gnutls_x509_privkey_export2_pkcs8(key, format, NULL, 0,
1729
0
               out);
1730
0
  }
1731
1732
0
  msg = set_msg(key);
1733
1734
0
  if (key->flags & GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT) {
1735
0
    ret = gnutls_x509_privkey_fix(key);
1736
0
    if (ret < 0)
1737
0
      return gnutls_assert_val(ret);
1738
0
  }
1739
1740
0
  return _gnutls_x509_export_int2(key->key, format, msg, out);
1741
0
}
1742
1743
/**
1744
 * gnutls_x509_privkey_sec_param:
1745
 * @key: a key
1746
 *
1747
 * This function will return the security parameter appropriate with
1748
 * this private key.
1749
 *
1750
 * Returns: On success, a valid security parameter is returned otherwise
1751
 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1752
 *
1753
 * Since: 2.12.0
1754
 **/
1755
gnutls_sec_param_t gnutls_x509_privkey_sec_param(gnutls_x509_privkey_t key)
1756
0
{
1757
0
  int bits;
1758
1759
0
  bits = pubkey_to_bits(&key->params);
1760
0
  if (bits <= 0)
1761
0
    return GNUTLS_SEC_PARAM_UNKNOWN;
1762
1763
0
  return gnutls_pk_bits_to_sec_param(key->params.algo, bits);
1764
0
}
1765
1766
/**
1767
 * gnutls_x509_privkey_export_ecc_raw:
1768
 * @key: a key
1769
 * @curve: will hold the curve
1770
 * @x: will hold the x-coordinate
1771
 * @y: will hold the y-coordinate
1772
 * @k: will hold the private key
1773
 *
1774
 * This function will export the ECC private key's parameters found
1775
 * in the given structure. The new parameters will be allocated using
1776
 * gnutls_malloc() and will be stored in the appropriate datum.
1777
 *
1778
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
1779
 * will be in the native format for the curve.
1780
 *
1781
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1782
 *   negative error value.
1783
 *
1784
 * Since: 3.0
1785
 **/
1786
int gnutls_x509_privkey_export_ecc_raw(gnutls_x509_privkey_t key,
1787
               gnutls_ecc_curve_t *curve,
1788
               gnutls_datum_t *x, gnutls_datum_t *y,
1789
               gnutls_datum_t *k)
1790
0
{
1791
0
  if (key == NULL) {
1792
0
    gnutls_assert();
1793
0
    return GNUTLS_E_INVALID_REQUEST;
1794
0
  }
1795
1796
0
  return _gnutls_params_get_ecc_raw(&key->params, curve, x, y, k, 0);
1797
0
}
1798
1799
/**
1800
 * gnutls_x509_privkey_export_gost_raw:
1801
 * @key: a key
1802
 * @curve: will hold the curve
1803
 * @digest: will hold the digest
1804
 * @paramset: will hold the GOST parameter set ID
1805
 * @x: will hold the x-coordinate
1806
 * @y: will hold the y-coordinate
1807
 * @k: will hold the private key
1808
 *
1809
 * This function will export the GOST private key's parameters found
1810
 * in the given structure. The new parameters will be allocated using
1811
 * gnutls_malloc() and will be stored in the appropriate datum.
1812
 *
1813
 * Note: parameters will be stored with least significant byte first. On
1814
 * version 3.6.3 this was incorrectly returned in big-endian format.
1815
 *
1816
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1817
 *   negative error value.
1818
 *
1819
 * Since: 3.6.3
1820
 **/
1821
int gnutls_x509_privkey_export_gost_raw(gnutls_x509_privkey_t key,
1822
          gnutls_ecc_curve_t *curve,
1823
          gnutls_digest_algorithm_t *digest,
1824
          gnutls_gost_paramset_t *paramset,
1825
          gnutls_datum_t *x, gnutls_datum_t *y,
1826
          gnutls_datum_t *k)
1827
0
{
1828
0
  if (key == NULL) {
1829
0
    gnutls_assert();
1830
0
    return GNUTLS_E_INVALID_REQUEST;
1831
0
  }
1832
1833
0
  return _gnutls_params_get_gost_raw(&key->params, curve, digest,
1834
0
             paramset, x, y, k, 0);
1835
0
}
1836
1837
/**
1838
 * gnutls_x509_privkey_export_rsa_raw:
1839
 * @key: a key
1840
 * @m: will hold the modulus
1841
 * @e: will hold the public exponent
1842
 * @d: will hold the private exponent
1843
 * @p: will hold the first prime (p)
1844
 * @q: will hold the second prime (q)
1845
 * @u: will hold the coefficient
1846
 *
1847
 * This function will export the RSA private key's parameters found
1848
 * in the given structure. The new parameters will be allocated using
1849
 * gnutls_malloc() and will be stored in the appropriate datum.
1850
 *
1851
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1852
 *   negative error value.
1853
 **/
1854
int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
1855
               gnutls_datum_t *m, gnutls_datum_t *e,
1856
               gnutls_datum_t *d, gnutls_datum_t *p,
1857
               gnutls_datum_t *q, gnutls_datum_t *u)
1858
0
{
1859
0
  return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, NULL,
1860
0
            NULL, 0);
1861
0
}
1862
1863
/**
1864
 * gnutls_x509_privkey_export_rsa_raw2:
1865
 * @key: a key
1866
 * @m: will hold the modulus
1867
 * @e: will hold the public exponent
1868
 * @d: will hold the private exponent
1869
 * @p: will hold the first prime (p)
1870
 * @q: will hold the second prime (q)
1871
 * @u: will hold the coefficient
1872
 * @e1: will hold e1 = d mod (p-1)
1873
 * @e2: will hold e2 = d mod (q-1)
1874
 *
1875
 * This function will export the RSA private key's parameters found
1876
 * in the given structure. The new parameters will be allocated using
1877
 * gnutls_malloc() and will be stored in the appropriate datum.
1878
 *
1879
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1880
 *   negative error value.
1881
 *
1882
 * Since: 2.12.0
1883
 **/
1884
int gnutls_x509_privkey_export_rsa_raw2(gnutls_x509_privkey_t key,
1885
          gnutls_datum_t *m, gnutls_datum_t *e,
1886
          gnutls_datum_t *d, gnutls_datum_t *p,
1887
          gnutls_datum_t *q, gnutls_datum_t *u,
1888
          gnutls_datum_t *e1, gnutls_datum_t *e2)
1889
0
{
1890
0
  return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, e1,
1891
0
            e2, 0);
1892
0
}
1893
1894
/**
1895
 * gnutls_x509_privkey_export_dsa_raw:
1896
 * @key: a key
1897
 * @p: will hold the p
1898
 * @q: will hold the q
1899
 * @g: will hold the g
1900
 * @y: will hold the y
1901
 * @x: will hold the x
1902
 *
1903
 * This function will export the DSA private key's parameters found
1904
 * in the given structure. The new parameters will be allocated using
1905
 * gnutls_malloc() and will be stored in the appropriate datum.
1906
 *
1907
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1908
 *   negative error value.
1909
 **/
1910
int gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,
1911
               gnutls_datum_t *p, gnutls_datum_t *q,
1912
               gnutls_datum_t *g, gnutls_datum_t *y,
1913
               gnutls_datum_t *x)
1914
0
{
1915
0
  return _gnutls_params_get_dsa_raw(&key->params, p, q, g, y, x, 0);
1916
0
}
1917
1918
/**
1919
 * gnutls_x509_privkey_generate:
1920
 * @key: an initialized key
1921
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1922
 * @bits: the size of the parameters to generate
1923
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1924
 *
1925
 * This function will generate a random private key. Note that this
1926
 * function must be called on an initialized private key.
1927
 *
1928
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1929
 * instructs the key generation process to use algorithms like Shawe-Taylor
1930
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1931
 * for RSA and DSA keys. See gnutls_x509_privkey_generate2() for more
1932
 * information.
1933
 *
1934
 * Note that when generating an elliptic curve key, the curve
1935
 * can be substituted in the place of the bits parameter using the
1936
 * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
1937
 * %gnutls_ecc_curve_t.
1938
 *
1939
 * For DSA keys, if the subgroup size needs to be specified check
1940
 * the GNUTLS_SUBGROUP_TO_BITS() macro.
1941
 *
1942
 * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
1943
 *
1944
 * See also gnutls_privkey_generate(), gnutls_x509_privkey_generate2().
1945
 *
1946
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1947
 *   negative error value.
1948
 **/
1949
int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
1950
         gnutls_pk_algorithm_t algo, unsigned int bits,
1951
         unsigned int flags)
1952
0
{
1953
0
  return gnutls_x509_privkey_generate2(key, algo, bits, flags, NULL, 0);
1954
0
}
1955
1956
/**
1957
 * gnutls_x509_privkey_generate2:
1958
 * @key: a key
1959
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1960
 * @bits: the size of the modulus
1961
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1962
 * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
1963
 * @data_size: The number of @data available.
1964
 *
1965
 * This function will generate a random private key. Note that this
1966
 * function must be called on an initialized private key.
1967
 *
1968
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1969
 * instructs the key generation process to use algorithms like Shawe-Taylor
1970
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1971
 * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
1972
 * seed, while on RSA the two primes. To specify an explicit seed
1973
 * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
1974
 * type.
1975
 *
1976
 * Note that when generating an elliptic curve key, the curve
1977
 * can be substituted in the place of the bits parameter using the
1978
 * GNUTLS_CURVE_TO_BITS() macro.
1979
 *
1980
 * To export the generated keys in memory or in files it is recommended to use the
1981
 * PKCS#8 form as it can handle all key types, and can store additional parameters
1982
 * such as the seed, in case of provable RSA or DSA keys.
1983
 * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
1984
 * and then with gnutls_x509_privkey_export2_pkcs8().
1985
 *
1986
 * If key generation is part of your application, avoid setting the number
1987
 * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
1988
 * That way the generated keys will adapt to the security levels
1989
 * of the underlying GnuTLS library.
1990
 *
1991
 * See also gnutls_privkey_generate2().
1992
 *
1993
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1994
 *   negative error value.
1995
 **/
1996
int gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
1997
          gnutls_pk_algorithm_t algo, unsigned int bits,
1998
          unsigned int flags,
1999
          const gnutls_keygen_data_st *data,
2000
          unsigned data_size)
2001
0
{
2002
0
  int ret;
2003
0
  unsigned i;
2004
0
  gnutls_x509_spki_t spki = NULL;
2005
0
  gnutls_dh_params_t dh_params = NULL;
2006
2007
0
  if (key == NULL) {
2008
0
    gnutls_assert();
2009
0
    return GNUTLS_E_INVALID_REQUEST;
2010
0
  }
2011
2012
0
  gnutls_pk_params_init(&key->params);
2013
2014
0
  for (i = 0; i < data_size; i++) {
2015
0
    switch (data[i].type) {
2016
0
    case GNUTLS_KEYGEN_SEED:
2017
0
      if (data[i].size < sizeof(key->params.seed)) {
2018
0
        key->params.seed_size = data[i].size;
2019
0
        memcpy(key->params.seed, data[i].data,
2020
0
               data[i].size);
2021
0
      }
2022
0
      break;
2023
0
    case GNUTLS_KEYGEN_DIGEST:
2024
0
      key->params.palgo = data[i].size;
2025
0
      break;
2026
0
    case GNUTLS_KEYGEN_SPKI:
2027
0
      spki = (void *)data[i].data;
2028
0
      break;
2029
0
    case GNUTLS_KEYGEN_DH:
2030
0
      if (algo != GNUTLS_PK_DH) {
2031
0
        return gnutls_assert_val(
2032
0
          GNUTLS_E_INVALID_REQUEST);
2033
0
      }
2034
0
      dh_params = (void *)data[i].data;
2035
0
      break;
2036
0
    }
2037
0
  }
2038
2039
0
  if (IS_EC(algo)) {
2040
0
    if (GNUTLS_BITS_ARE_CURVE(bits))
2041
0
      bits = GNUTLS_BITS_TO_CURVE(bits);
2042
0
    else
2043
0
      bits = _gnutls_ecc_bits_to_curve(algo, bits);
2044
2045
0
    if (gnutls_ecc_curve_get_pk(bits) != algo) {
2046
0
      _gnutls_debug_log(
2047
0
        "curve is incompatible with public key algorithm\n");
2048
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2049
0
    }
2050
0
  }
2051
2052
0
  if (IS_GOSTEC(algo)) {
2053
0
    int size;
2054
2055
0
    if (GNUTLS_BITS_ARE_CURVE(bits))
2056
0
      bits = GNUTLS_BITS_TO_CURVE(bits);
2057
0
    else
2058
0
      bits = _gnutls_ecc_bits_to_curve(algo, bits);
2059
2060
0
    size = gnutls_ecc_curve_get_size(bits);
2061
2062
0
    if ((algo == GNUTLS_PK_GOST_01 && size != 32) ||
2063
0
        (algo == GNUTLS_PK_GOST_12_256 && size != 32) ||
2064
0
        (algo == GNUTLS_PK_GOST_12_512 && size != 64)) {
2065
0
      _gnutls_debug_log(
2066
0
        "curve is incompatible with public key algorithm\n");
2067
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2068
0
    }
2069
2070
0
    key->params.gost_params = _gnutls_gost_paramset_default(algo);
2071
0
  }
2072
2073
0
  if (flags & GNUTLS_PRIVKEY_FLAG_PROVABLE) {
2074
0
    key->params.pkflags |= GNUTLS_PK_FLAG_PROVABLE;
2075
0
  }
2076
2077
0
  key->params.algo = algo;
2078
2079
  /* DH params are given, no need to regenerate */
2080
0
  if (algo == GNUTLS_PK_DH && dh_params != NULL) {
2081
0
    key->params.params[DH_P] =
2082
0
      _gnutls_mpi_copy(dh_params->params[0]);
2083
0
    key->params.params[DH_G] =
2084
0
      _gnutls_mpi_copy(dh_params->params[1]);
2085
0
    if (dh_params->params[2]) {
2086
0
      key->params.params[DH_Q] =
2087
0
        _gnutls_mpi_copy(dh_params->params[2]);
2088
0
    }
2089
    /* X and Y will be added by _gnutls_pk_generate_keys */
2090
0
    key->params.params_nr = 3;
2091
0
    key->params.qbits = dh_params->q_bits;
2092
0
  } else {
2093
0
    ret = _gnutls_pk_generate_params(algo, bits, &key->params);
2094
0
    if (ret < 0) {
2095
0
      gnutls_assert();
2096
0
      return ret;
2097
0
    }
2098
0
  }
2099
2100
0
  if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA) &&
2101
0
      !key->params.spki.pk) {
2102
0
    const mac_entry_st *me;
2103
0
    key->params.spki.pk = GNUTLS_PK_RSA_PSS;
2104
2105
0
    key->params.spki.rsa_pss_dig =
2106
0
      _gnutls_pk_bits_to_sha_hash(bits);
2107
2108
0
    me = hash_to_entry(key->params.spki.rsa_pss_dig);
2109
0
    if (unlikely(me == NULL)) {
2110
0
      gnutls_assert();
2111
0
      ret = GNUTLS_E_INVALID_REQUEST;
2112
0
      goto cleanup;
2113
0
    }
2114
2115
0
    ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
2116
0
    if (ret < 0) {
2117
0
      gnutls_assert();
2118
0
      goto cleanup;
2119
0
    }
2120
2121
0
    key->params.spki.salt_size = ret;
2122
0
  }
2123
2124
0
  if (algo == GNUTLS_PK_RSA_OAEP && !key->params.spki.pk) {
2125
0
    const mac_entry_st *me;
2126
0
    key->params.spki.pk = GNUTLS_PK_RSA_OAEP;
2127
2128
0
    key->params.spki.rsa_oaep_dig =
2129
0
      _gnutls_pk_bits_to_sha_hash(bits);
2130
2131
0
    me = hash_to_entry(key->params.spki.rsa_oaep_dig);
2132
0
    if (unlikely(me == NULL)) {
2133
0
      gnutls_assert();
2134
0
      ret = GNUTLS_E_INVALID_REQUEST;
2135
0
      goto cleanup;
2136
0
    }
2137
0
  }
2138
2139
0
  ret = _gnutls_pk_generate_keys(algo, bits, &key->params, 0);
2140
0
  if (ret < 0) {
2141
0
    gnutls_assert();
2142
0
    goto cleanup;
2143
0
  }
2144
2145
0
  ret = _gnutls_pk_verify_priv_params(algo, &key->params);
2146
0
  if (ret < 0) {
2147
0
    gnutls_assert();
2148
0
    goto cleanup;
2149
0
  }
2150
2151
0
  if (spki) {
2152
0
    ret = gnutls_x509_privkey_set_spki(key, spki, 0);
2153
0
    if (ret < 0) {
2154
0
      gnutls_assert();
2155
0
      goto cleanup;
2156
0
    }
2157
0
  }
2158
2159
  /* DH keys are only exportable in PKCS#8 format */
2160
0
  if (algo != GNUTLS_PK_DH) {
2161
0
    ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
2162
0
    if (ret < 0) {
2163
0
      gnutls_assert();
2164
0
      goto cleanup;
2165
0
    }
2166
0
  }
2167
2168
0
  return 0;
2169
2170
0
cleanup:
2171
0
  key->params.algo = GNUTLS_PK_UNKNOWN;
2172
0
  gnutls_pk_params_clear(&key->params);
2173
0
  gnutls_pk_params_release(&key->params);
2174
2175
0
  return ret;
2176
0
}
2177
2178
/**
2179
 * gnutls_x509_privkey_get_seed:
2180
 * @key: should contain a #gnutls_x509_privkey_t type
2181
 * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
2182
 * @seed: where seed will be copied to
2183
 * @seed_size: originally holds the size of @seed, will be updated with actual size
2184
 *
2185
 * This function will return the seed that was used to generate the
2186
 * given private key. That function will succeed only if the key was generated
2187
 * as a provable key.
2188
 *
2189
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2190
 *   negative error value.
2191
 *
2192
 * Since: 3.5.0
2193
 **/
2194
int gnutls_x509_privkey_get_seed(gnutls_x509_privkey_t key,
2195
         gnutls_digest_algorithm_t *digest, void *seed,
2196
         size_t *seed_size)
2197
0
{
2198
0
  if (key->params.seed_size == 0)
2199
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2200
2201
0
  if (seed_size == NULL || seed == NULL) {
2202
0
    if (key->params.seed_size)
2203
0
      return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2204
0
    else
2205
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2206
0
  }
2207
2208
0
  if (*seed_size < key->params.seed_size) {
2209
0
    *seed_size = key->params.seed_size;
2210
0
    return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2211
0
  }
2212
2213
0
  if (digest)
2214
0
    *digest = key->params.palgo;
2215
2216
0
  memcpy(seed, key->params.seed, key->params.seed_size);
2217
0
  *seed_size = key->params.seed_size;
2218
0
  return 0;
2219
0
}
2220
2221
static int cmp_rsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2222
0
{
2223
0
  gnutls_datum_t m1 = { NULL, 0 }, e1 = { NULL, 0 }, d1 = { NULL, 0 },
2224
0
           p1 = { NULL, 0 }, q1 = { NULL, 0 };
2225
0
  gnutls_datum_t m2 = { NULL, 0 }, e2 = { NULL, 0 }, d2 = { NULL, 0 },
2226
0
           p2 = { NULL, 0 }, q2 = { NULL, 0 };
2227
0
  int ret;
2228
2229
0
  ret = gnutls_x509_privkey_export_rsa_raw(key1, &m1, &e1, &d1, &p1, &q1,
2230
0
             NULL);
2231
0
  if (ret < 0) {
2232
0
    gnutls_assert();
2233
0
    return ret;
2234
0
  }
2235
2236
0
  ret = gnutls_x509_privkey_export_rsa_raw(key2, &m2, &e2, &d2, &p2, &q2,
2237
0
             NULL);
2238
0
  if (ret < 0) {
2239
0
    gnutls_assert();
2240
0
    goto cleanup;
2241
0
  }
2242
2243
0
  if (m1.size != m2.size || memcmp(m1.data, m2.data, m1.size) != 0) {
2244
0
    gnutls_assert();
2245
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2246
0
    goto cleanup;
2247
0
  }
2248
2249
0
  if (d1.size != d2.size || memcmp(d1.data, d2.data, d1.size) != 0) {
2250
0
    gnutls_assert();
2251
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2252
0
    goto cleanup;
2253
0
  }
2254
2255
0
  if (e1.size != e2.size || memcmp(e1.data, e2.data, e1.size) != 0) {
2256
0
    gnutls_assert();
2257
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2258
0
    goto cleanup;
2259
0
  }
2260
2261
0
  if (p1.size != p2.size || memcmp(p1.data, p2.data, p1.size) != 0) {
2262
0
    gnutls_assert();
2263
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2264
0
    goto cleanup;
2265
0
  }
2266
2267
0
  if (q1.size != q2.size || memcmp(q1.data, q2.data, q1.size) != 0) {
2268
0
    gnutls_assert();
2269
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2270
0
    goto cleanup;
2271
0
  }
2272
2273
0
  ret = 0;
2274
0
cleanup:
2275
0
  gnutls_free(m1.data);
2276
0
  gnutls_free(e1.data);
2277
0
  gnutls_free(d1.data);
2278
0
  gnutls_free(p1.data);
2279
0
  gnutls_free(q1.data);
2280
0
  gnutls_free(m2.data);
2281
0
  gnutls_free(e2.data);
2282
0
  gnutls_free(d2.data);
2283
0
  gnutls_free(p2.data);
2284
0
  gnutls_free(q2.data);
2285
0
  return ret;
2286
0
}
2287
2288
static int cmp_dsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2289
0
{
2290
0
  gnutls_datum_t p1 = { NULL, 0 }, q1 = { NULL, 0 }, g1 = { NULL, 0 };
2291
0
  gnutls_datum_t p2 = { NULL, 0 }, q2 = { NULL, 0 }, g2 = { NULL, 0 };
2292
0
  int ret;
2293
2294
0
  ret = gnutls_x509_privkey_export_dsa_raw(key1, &p1, &q1, &g1, NULL,
2295
0
             NULL);
2296
0
  if (ret < 0) {
2297
0
    gnutls_assert();
2298
0
    return ret;
2299
0
  }
2300
2301
0
  ret = gnutls_x509_privkey_export_dsa_raw(key2, &p2, &q2, &g2, NULL,
2302
0
             NULL);
2303
0
  if (ret < 0) {
2304
0
    gnutls_assert();
2305
0
    goto cleanup;
2306
0
  }
2307
2308
0
  if (g1.size != g2.size || memcmp(g1.data, g2.data, g1.size) != 0) {
2309
0
    gnutls_assert();
2310
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2311
0
    goto cleanup;
2312
0
  }
2313
2314
0
  if (p1.size != p2.size || memcmp(p1.data, p2.data, p1.size) != 0) {
2315
0
    gnutls_assert();
2316
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2317
0
    goto cleanup;
2318
0
  }
2319
2320
0
  if (q1.size != q2.size || memcmp(q1.data, q2.data, q1.size) != 0) {
2321
0
    gnutls_assert();
2322
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2323
0
    goto cleanup;
2324
0
  }
2325
2326
0
  ret = 0;
2327
0
cleanup:
2328
0
  gnutls_free(g1.data);
2329
0
  gnutls_free(p1.data);
2330
0
  gnutls_free(q1.data);
2331
0
  gnutls_free(g2.data);
2332
0
  gnutls_free(p2.data);
2333
0
  gnutls_free(q2.data);
2334
0
  return ret;
2335
0
}
2336
2337
/**
2338
 * gnutls_x509_privkey_verify_seed:
2339
 * @key: should contain a #gnutls_x509_privkey_t type
2340
 * @digest: it contains the digest algorithm used for key generation (if applicable)
2341
 * @seed: the seed of the key to be checked with
2342
 * @seed_size: holds the size of @seed
2343
 *
2344
 * This function will verify that the given private key was generated from
2345
 * the provided seed. If @seed is %NULL then the seed stored in the @key's structure
2346
 * will be used for verification.
2347
 *
2348
 * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
2349
 * is returned, and zero or positive code on success.
2350
 *
2351
 * Since: 3.5.0
2352
 **/
2353
int gnutls_x509_privkey_verify_seed(gnutls_x509_privkey_t key,
2354
            gnutls_digest_algorithm_t digest,
2355
            const void *seed, size_t seed_size)
2356
0
{
2357
0
  int ret;
2358
0
  gnutls_x509_privkey_t okey;
2359
0
  unsigned bits;
2360
0
  gnutls_keygen_data_st data;
2361
2362
0
  if (key == NULL) {
2363
0
    gnutls_assert();
2364
0
    return GNUTLS_E_INVALID_REQUEST;
2365
0
  }
2366
2367
0
  if (key->params.algo != GNUTLS_PK_RSA &&
2368
0
      key->params.algo != GNUTLS_PK_DSA)
2369
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
2370
2371
0
  ret = gnutls_x509_privkey_get_pk_algorithm2(key, &bits);
2372
0
  if (ret < 0)
2373
0
    return gnutls_assert_val(ret);
2374
2375
0
  ret = gnutls_x509_privkey_init(&okey);
2376
0
  if (ret < 0)
2377
0
    return gnutls_assert_val(ret);
2378
2379
0
  if (seed == NULL) {
2380
0
    seed = key->params.seed;
2381
0
    seed_size = key->params.seed_size;
2382
0
  }
2383
2384
0
  if (seed == NULL || seed_size == 0)
2385
0
    return gnutls_assert_val(GNUTLS_E_PK_NO_VALIDATION_PARAMS);
2386
2387
0
  data.type = GNUTLS_KEYGEN_SEED;
2388
0
  data.data = (void *)seed;
2389
0
  data.size = seed_size;
2390
2391
0
  ret = gnutls_x509_privkey_generate2(okey, key->params.algo, bits,
2392
0
              GNUTLS_PRIVKEY_FLAG_PROVABLE, &data,
2393
0
              1);
2394
0
  if (ret < 0) {
2395
0
    gnutls_assert();
2396
0
    goto cleanup;
2397
0
  }
2398
2399
0
  if (key->params.algo == GNUTLS_PK_RSA)
2400
0
    ret = cmp_rsa_key(key, okey);
2401
0
  else
2402
0
    ret = cmp_dsa_key(key, okey);
2403
2404
0
cleanup:
2405
0
  gnutls_x509_privkey_deinit(okey);
2406
2407
0
  return ret;
2408
0
}
2409
2410
/**
2411
 * gnutls_x509_privkey_verify_params:
2412
 * @key: a key
2413
 *
2414
 * This function will verify the private key parameters.
2415
 *
2416
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2417
 *   negative error value.
2418
 **/
2419
int gnutls_x509_privkey_verify_params(gnutls_x509_privkey_t key)
2420
0
{
2421
0
  int ret;
2422
2423
0
  ret = _gnutls_pk_verify_priv_params(key->params.algo, &key->params);
2424
0
  if (ret < 0) {
2425
0
    gnutls_assert();
2426
0
    return ret;
2427
0
  }
2428
2429
0
  return 0;
2430
0
}
2431
2432
/**
2433
 * gnutls_x509_privkey_get_key_id:
2434
 * @key: a key
2435
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
2436
 * @output_data: will contain the key ID
2437
 * @output_data_size: holds the size of output_data (and will be
2438
 *   replaced by the actual size of parameters)
2439
 *
2440
 * This function will return a unique ID that depends on the public key
2441
 * parameters. This ID can be used in checking whether a certificate
2442
 * corresponds to the given key.
2443
 *
2444
 * If the buffer provided is not long enough to hold the output, then
2445
 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2446
 * be returned.  The output will normally be a SHA-1 hash output,
2447
 * which is 20 bytes.
2448
 *
2449
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2450
 *   negative error value.
2451
 **/
2452
int gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,
2453
           unsigned int flags,
2454
           unsigned char *output_data,
2455
           size_t *output_data_size)
2456
0
{
2457
0
  int ret;
2458
2459
0
  if (key == NULL) {
2460
0
    gnutls_assert();
2461
0
    return GNUTLS_E_INVALID_REQUEST;
2462
0
  }
2463
2464
0
  ret = _gnutls_get_key_id(&key->params, output_data, output_data_size,
2465
0
         flags);
2466
0
  if (ret < 0) {
2467
0
    gnutls_assert();
2468
0
  }
2469
2470
0
  return ret;
2471
0
}
2472
2473
/**
2474
 * gnutls_x509_privkey_sign_hash:
2475
 * @key: a key
2476
 * @hash: holds the data to be signed
2477
 * @signature: will contain newly allocated signature
2478
 *
2479
 * This function will sign the given hash using the private key. Do not
2480
 * use this function directly unless you know what it is. Typical signing
2481
 * requires the data to be hashed and stored in special formats 
2482
 * (e.g. BER Digest-Info for RSA).
2483
 *
2484
 * This API is provided only for backwards compatibility, and thus
2485
 * restricted to RSA, DSA and ECDSA key types. For other key types please
2486
 * use gnutls_privkey_sign_hash() and gnutls_privkey_sign_data().
2487
 *
2488
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2489
 *   negative error value.
2490
 *
2491
 * Deprecated in: 2.12.0
2492
 */
2493
int gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,
2494
          const gnutls_datum_t *hash,
2495
          gnutls_datum_t *signature)
2496
0
{
2497
0
  int result;
2498
2499
0
  if (key == NULL) {
2500
0
    gnutls_assert();
2501
0
    return GNUTLS_E_INVALID_REQUEST;
2502
0
  }
2503
2504
0
  if (key->params.algo != GNUTLS_PK_RSA &&
2505
0
      key->params.algo != GNUTLS_PK_ECDSA &&
2506
0
      key->params.algo != GNUTLS_PK_DSA) {
2507
    /* too primitive API - use only with legacy types */
2508
0
    gnutls_assert();
2509
0
    return GNUTLS_E_INVALID_REQUEST;
2510
0
  }
2511
2512
0
  result = _gnutls_pk_sign(key->params.algo, signature, hash,
2513
0
         &key->params, &key->params.spki);
2514
2515
0
  if (result < 0) {
2516
0
    gnutls_assert();
2517
0
    return result;
2518
0
  }
2519
2520
0
  return 0;
2521
0
}
2522
2523
/**
2524
 * gnutls_x509_privkey_sign_data:
2525
 * @key: a key
2526
 * @digest: should be a digest algorithm
2527
 * @flags: should be 0 for now
2528
 * @data: holds the data to be signed
2529
 * @signature: will contain the signature
2530
 * @signature_size: holds the size of signature (and will be replaced
2531
 *   by the new size)
2532
 *
2533
 * This function will sign the given data using a signature algorithm
2534
 * supported by the private key. Signature algorithms are always used
2535
 * together with a hash functions.  Different hash functions may be
2536
 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
2537
 *
2538
 * If the buffer provided is not long enough to hold the output, then
2539
 * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2540
 * be returned.
2541
 *
2542
 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
2543
 * the hash algorithm.
2544
 *
2545
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2546
 *   negative error value.
2547
 */
2548
int gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,
2549
          gnutls_digest_algorithm_t digest,
2550
          unsigned int flags,
2551
          const gnutls_datum_t *data, void *signature,
2552
          size_t *signature_size)
2553
0
{
2554
0
  gnutls_privkey_t privkey;
2555
0
  gnutls_datum_t sig = { NULL, 0 };
2556
0
  int ret;
2557
2558
0
  ret = gnutls_privkey_init(&privkey);
2559
0
  if (ret < 0)
2560
0
    return gnutls_assert_val(ret);
2561
2562
0
  ret = gnutls_privkey_import_x509(privkey, key, 0);
2563
0
  if (ret < 0) {
2564
0
    gnutls_assert();
2565
0
    goto cleanup;
2566
0
  }
2567
2568
0
  ret = gnutls_privkey_sign_data(privkey, digest, flags, data, &sig);
2569
0
  if (ret < 0) {
2570
0
    gnutls_assert();
2571
0
    goto cleanup;
2572
0
  }
2573
2574
0
  if (*signature_size < sig.size) {
2575
0
    *signature_size = sig.size;
2576
0
    ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2577
0
    goto cleanup;
2578
0
  }
2579
2580
0
  *signature_size = sig.size;
2581
0
  memcpy(signature, sig.data, sig.size);
2582
2583
0
cleanup:
2584
0
  _gnutls_free_datum(&sig);
2585
0
  gnutls_privkey_deinit(privkey);
2586
0
  return ret;
2587
0
}
2588
2589
/**
2590
 * gnutls_x509_privkey_fix:
2591
 * @key: a key
2592
 *
2593
 * This function will recalculate the secondary parameters in a key.
2594
 * In RSA keys, this can be the coefficient and exponent1,2.
2595
 *
2596
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2597
 *   negative error value.
2598
 **/
2599
int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key)
2600
0
{
2601
0
  int ret;
2602
2603
0
  if (key == NULL) {
2604
0
    gnutls_assert();
2605
0
    return GNUTLS_E_INVALID_REQUEST;
2606
0
  }
2607
2608
0
  if (key->key) {
2609
0
    asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
2610
2611
0
    ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
2612
0
    if (ret < 0) {
2613
0
      gnutls_assert();
2614
0
      return ret;
2615
0
    }
2616
0
  }
2617
2618
0
  return 0;
2619
0
}
2620
2621
/**
2622
 * gnutls_x509_privkey_set_pin_function:
2623
 * @privkey: The certificate structure
2624
 * @fn: the callback
2625
 * @userdata: data associated with the callback
2626
 *
2627
 * This function will set a callback function to be used when
2628
 * it is required to access a protected object. This function overrides 
2629
 * the global function set using gnutls_pkcs11_set_pin_function().
2630
 *
2631
 * Note that this callback is used when decrypting a key.
2632
 *
2633
 * Since: 3.4.0
2634
 *
2635
 **/
2636
void gnutls_x509_privkey_set_pin_function(gnutls_x509_privkey_t privkey,
2637
            gnutls_pin_callback_t fn,
2638
            void *userdata)
2639
0
{
2640
0
  privkey->pin.cb = fn;
2641
0
  privkey->pin.data = userdata;
2642
0
}
2643
2644
/**
2645
 * gnutls_x509_privkey_set_flags:
2646
 * @key: A key of type #gnutls_x509_privkey_t
2647
 * @flags: flags from the %gnutls_privkey_flags
2648
 *
2649
 * This function will set flags for the specified private key, after
2650
 * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
2651
 * to allow exporting a "provable" private key in backwards compatible way.
2652
 *
2653
 * Since: 3.5.0
2654
 *
2655
 **/
2656
void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key,
2657
           unsigned int flags)
2658
0
{
2659
0
  key->flags |= flags;
2660
0
}