Coverage Report

Created: 2024-07-23 07:36

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