Coverage Report

Created: 2024-06-20 06:28

/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
void _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
1406
            gnutls_x509_spki_st *params)
1407
0
{
1408
0
  memcpy(params, &key->params.spki, sizeof(gnutls_x509_spki_st));
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
  _gnutls_x509_privkey_get_spki_params(key, spki);
1434
1435
0
  return 0;
1436
0
}
1437
1438
/**
1439
 * gnutls_x509_privkey_set_spki:
1440
 * @key: should contain a #gnutls_x509_privkey_t type
1441
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1442
 * @flags: must be zero
1443
 *
1444
 * This function will return the public key information of a private
1445
 * key. The provided @spki must be initialized.
1446
 *
1447
 * Returns: Zero on success, or a negative error code on error.
1448
 **/
1449
int gnutls_x509_privkey_set_spki(gnutls_x509_privkey_t key,
1450
         const gnutls_x509_spki_t spki,
1451
         unsigned int flags)
1452
0
{
1453
0
  gnutls_pk_params_st tparams;
1454
0
  int ret;
1455
1456
0
  if (key == NULL) {
1457
0
    gnutls_assert();
1458
0
    return GNUTLS_E_INVALID_REQUEST;
1459
0
  }
1460
1461
0
  if (!_gnutls_pk_are_compat(key->params.algo, spki->pk))
1462
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1463
1464
0
  memcpy(&tparams, &key->params, sizeof(gnutls_pk_params_st));
1465
0
  memcpy(&tparams.spki, spki, sizeof(gnutls_x509_spki_st));
1466
0
  ret = _gnutls_x509_check_pubkey_params(&tparams);
1467
0
  if (ret < 0)
1468
0
    return gnutls_assert_val(ret);
1469
1470
0
  memcpy(&key->params.spki, spki, sizeof(gnutls_x509_spki_st));
1471
1472
0
  key->params.algo = spki->pk;
1473
1474
0
  return 0;
1475
0
}
1476
1477
static const char *set_msg(gnutls_x509_privkey_t key)
1478
0
{
1479
0
  if (GNUTLS_PK_IS_RSA(key->params.algo)) {
1480
0
    return PEM_KEY_RSA;
1481
0
  } else if (key->params.algo == GNUTLS_PK_DSA) {
1482
0
    return PEM_KEY_DSA;
1483
0
  } else if (key->params.algo == GNUTLS_PK_EC)
1484
0
    return PEM_KEY_ECC;
1485
0
  else
1486
0
    return "UNKNOWN";
1487
0
}
1488
1489
/**
1490
 * gnutls_x509_privkey_export:
1491
 * @key: Holds the key
1492
 * @format: the format of output params. One of PEM or DER.
1493
 * @output_data: will contain a private key PEM or DER encoded
1494
 * @output_data_size: holds the size of output_data (and will be
1495
 *   replaced by the actual size of parameters)
1496
 *
1497
 * This function will export the private key to a PKCS#1 structure for
1498
 * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1499
 * will be exported in PKCS#8 form.
1500
 *
1501
 * If the structure is PEM encoded, it will have a header
1502
 * of "BEGIN RSA PRIVATE KEY".
1503
 *
1504
 * It is recommended to use gnutls_x509_privkey_export_pkcs8() instead
1505
 * of this function, when a consistent output format is required.
1506
 *
1507
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1508
 *   negative error value.
1509
 **/
1510
int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
1511
             gnutls_x509_crt_fmt_t format, void *output_data,
1512
             size_t *output_data_size)
1513
0
{
1514
0
  gnutls_datum_t out;
1515
0
  int ret;
1516
1517
0
  ret = gnutls_x509_privkey_export2(key, format, &out);
1518
0
  if (ret < 0)
1519
0
    return gnutls_assert_val(ret);
1520
1521
0
  if (format == GNUTLS_X509_FMT_PEM)
1522
0
    ret = _gnutls_copy_string(&out, output_data, output_data_size);
1523
0
  else
1524
0
    ret = _gnutls_copy_data(&out, output_data, output_data_size);
1525
0
  gnutls_free(out.data);
1526
1527
0
  return ret;
1528
0
}
1529
1530
/**
1531
 * gnutls_x509_privkey_export2:
1532
 * @key: Holds the key
1533
 * @format: the format of output params. One of PEM or DER.
1534
 * @out: will contain a private key PEM or DER encoded
1535
 *
1536
 * This function will export the private key to a PKCS#1 structure for
1537
 * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1538
 * will be exported in PKCS#8 form.
1539
 *
1540
 * The output buffer is allocated using gnutls_malloc().
1541
 *
1542
 * It is recommended to use gnutls_x509_privkey_export2_pkcs8() instead
1543
 * of this function, when a consistent output format is required.
1544
 *
1545
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1546
 *   negative error value.
1547
 *
1548
 * Since 3.1.3
1549
 **/
1550
int gnutls_x509_privkey_export2(gnutls_x509_privkey_t key,
1551
        gnutls_x509_crt_fmt_t format,
1552
        gnutls_datum_t *out)
1553
0
{
1554
0
  const char *msg;
1555
0
  int ret;
1556
1557
0
  if (key == NULL) {
1558
0
    gnutls_assert();
1559
0
    return GNUTLS_E_INVALID_REQUEST;
1560
0
  }
1561
1562
0
  if (key->key == NULL) { /* can only export in PKCS#8 form */
1563
0
    return gnutls_x509_privkey_export2_pkcs8(key, format, NULL, 0,
1564
0
               out);
1565
0
  }
1566
1567
0
  msg = set_msg(key);
1568
1569
0
  if (key->flags & GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT) {
1570
0
    ret = gnutls_x509_privkey_fix(key);
1571
0
    if (ret < 0)
1572
0
      return gnutls_assert_val(ret);
1573
0
  }
1574
1575
0
  return _gnutls_x509_export_int2(key->key, format, msg, out);
1576
0
}
1577
1578
/**
1579
 * gnutls_x509_privkey_sec_param:
1580
 * @key: a key
1581
 *
1582
 * This function will return the security parameter appropriate with
1583
 * this private key.
1584
 *
1585
 * Returns: On success, a valid security parameter is returned otherwise
1586
 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1587
 *
1588
 * Since: 2.12.0
1589
 **/
1590
gnutls_sec_param_t gnutls_x509_privkey_sec_param(gnutls_x509_privkey_t key)
1591
0
{
1592
0
  int bits;
1593
1594
0
  bits = pubkey_to_bits(&key->params);
1595
0
  if (bits <= 0)
1596
0
    return GNUTLS_SEC_PARAM_UNKNOWN;
1597
1598
0
  return gnutls_pk_bits_to_sec_param(key->params.algo, bits);
1599
0
}
1600
1601
/**
1602
 * gnutls_x509_privkey_export_ecc_raw:
1603
 * @key: a key
1604
 * @curve: will hold the curve
1605
 * @x: will hold the x-coordinate
1606
 * @y: will hold the y-coordinate
1607
 * @k: will hold the private key
1608
 *
1609
 * This function will export the ECC private key's parameters found
1610
 * in the given structure. The new parameters will be allocated using
1611
 * gnutls_malloc() and will be stored in the appropriate datum.
1612
 *
1613
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
1614
 * will be in the native format for the curve.
1615
 *
1616
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1617
 *   negative error value.
1618
 *
1619
 * Since: 3.0
1620
 **/
1621
int gnutls_x509_privkey_export_ecc_raw(gnutls_x509_privkey_t key,
1622
               gnutls_ecc_curve_t *curve,
1623
               gnutls_datum_t *x, gnutls_datum_t *y,
1624
               gnutls_datum_t *k)
1625
0
{
1626
0
  if (key == NULL) {
1627
0
    gnutls_assert();
1628
0
    return GNUTLS_E_INVALID_REQUEST;
1629
0
  }
1630
1631
0
  return _gnutls_params_get_ecc_raw(&key->params, curve, x, y, k, 0);
1632
0
}
1633
1634
/**
1635
 * gnutls_x509_privkey_export_gost_raw:
1636
 * @key: a key
1637
 * @curve: will hold the curve
1638
 * @digest: will hold the digest
1639
 * @paramset: will hold the GOST parameter set ID
1640
 * @x: will hold the x-coordinate
1641
 * @y: will hold the y-coordinate
1642
 * @k: will hold the private key
1643
 *
1644
 * This function will export the GOST private key's parameters found
1645
 * in the given structure. The new parameters will be allocated using
1646
 * gnutls_malloc() and will be stored in the appropriate datum.
1647
 *
1648
 * Note: parameters will be stored with least significant byte first. On
1649
 * version 3.6.3 this was incorrectly returned in big-endian format.
1650
 *
1651
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1652
 *   negative error value.
1653
 *
1654
 * Since: 3.6.3
1655
 **/
1656
int gnutls_x509_privkey_export_gost_raw(gnutls_x509_privkey_t key,
1657
          gnutls_ecc_curve_t *curve,
1658
          gnutls_digest_algorithm_t *digest,
1659
          gnutls_gost_paramset_t *paramset,
1660
          gnutls_datum_t *x, gnutls_datum_t *y,
1661
          gnutls_datum_t *k)
1662
0
{
1663
0
  if (key == NULL) {
1664
0
    gnutls_assert();
1665
0
    return GNUTLS_E_INVALID_REQUEST;
1666
0
  }
1667
1668
0
  return _gnutls_params_get_gost_raw(&key->params, curve, digest,
1669
0
             paramset, x, y, k, 0);
1670
0
}
1671
1672
/**
1673
 * gnutls_x509_privkey_export_rsa_raw:
1674
 * @key: a key
1675
 * @m: will hold the modulus
1676
 * @e: will hold the public exponent
1677
 * @d: will hold the private exponent
1678
 * @p: will hold the first prime (p)
1679
 * @q: will hold the second prime (q)
1680
 * @u: will hold the coefficient
1681
 *
1682
 * This function will export the RSA private key's parameters found
1683
 * in the given structure. The new parameters will be allocated using
1684
 * gnutls_malloc() and will be stored in the appropriate datum.
1685
 *
1686
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1687
 *   negative error value.
1688
 **/
1689
int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
1690
               gnutls_datum_t *m, gnutls_datum_t *e,
1691
               gnutls_datum_t *d, gnutls_datum_t *p,
1692
               gnutls_datum_t *q, gnutls_datum_t *u)
1693
0
{
1694
0
  return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, NULL,
1695
0
            NULL, 0);
1696
0
}
1697
1698
/**
1699
 * gnutls_x509_privkey_export_rsa_raw2:
1700
 * @key: a key
1701
 * @m: will hold the modulus
1702
 * @e: will hold the public exponent
1703
 * @d: will hold the private exponent
1704
 * @p: will hold the first prime (p)
1705
 * @q: will hold the second prime (q)
1706
 * @u: will hold the coefficient
1707
 * @e1: will hold e1 = d mod (p-1)
1708
 * @e2: will hold e2 = d mod (q-1)
1709
 *
1710
 * This function will export the RSA private key's parameters found
1711
 * in the given structure. The new parameters will be allocated using
1712
 * gnutls_malloc() and will be stored in the appropriate datum.
1713
 *
1714
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1715
 *   negative error value.
1716
 *
1717
 * Since: 2.12.0
1718
 **/
1719
int gnutls_x509_privkey_export_rsa_raw2(gnutls_x509_privkey_t key,
1720
          gnutls_datum_t *m, gnutls_datum_t *e,
1721
          gnutls_datum_t *d, gnutls_datum_t *p,
1722
          gnutls_datum_t *q, gnutls_datum_t *u,
1723
          gnutls_datum_t *e1, gnutls_datum_t *e2)
1724
0
{
1725
0
  return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, e1,
1726
0
            e2, 0);
1727
0
}
1728
1729
/**
1730
 * gnutls_x509_privkey_export_dsa_raw:
1731
 * @key: a key
1732
 * @p: will hold the p
1733
 * @q: will hold the q
1734
 * @g: will hold the g
1735
 * @y: will hold the y
1736
 * @x: will hold the x
1737
 *
1738
 * This function will export the DSA private key's parameters found
1739
 * in the given structure. The new parameters will be allocated using
1740
 * gnutls_malloc() and will be stored in the appropriate datum.
1741
 *
1742
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1743
 *   negative error value.
1744
 **/
1745
int gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,
1746
               gnutls_datum_t *p, gnutls_datum_t *q,
1747
               gnutls_datum_t *g, gnutls_datum_t *y,
1748
               gnutls_datum_t *x)
1749
0
{
1750
0
  return _gnutls_params_get_dsa_raw(&key->params, p, q, g, y, x, 0);
1751
0
}
1752
1753
/**
1754
 * gnutls_x509_privkey_generate:
1755
 * @key: an initialized key
1756
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1757
 * @bits: the size of the parameters to generate
1758
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1759
 *
1760
 * This function will generate a random private key. Note that this
1761
 * function must be called on an initialized private key.
1762
 *
1763
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1764
 * instructs the key generation process to use algorithms like Shawe-Taylor
1765
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1766
 * for RSA and DSA keys. See gnutls_x509_privkey_generate2() for more
1767
 * information.
1768
 *
1769
 * Note that when generating an elliptic curve key, the curve
1770
 * can be substituted in the place of the bits parameter using the
1771
 * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
1772
 * %gnutls_ecc_curve_t.
1773
 *
1774
 * For DSA keys, if the subgroup size needs to be specified check
1775
 * the GNUTLS_SUBGROUP_TO_BITS() macro.
1776
 *
1777
 * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
1778
 *
1779
 * See also gnutls_privkey_generate(), gnutls_x509_privkey_generate2().
1780
 *
1781
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1782
 *   negative error value.
1783
 **/
1784
int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
1785
         gnutls_pk_algorithm_t algo, unsigned int bits,
1786
         unsigned int flags)
1787
0
{
1788
0
  return gnutls_x509_privkey_generate2(key, algo, bits, flags, NULL, 0);
1789
0
}
1790
1791
/**
1792
 * gnutls_x509_privkey_generate2:
1793
 * @key: a key
1794
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1795
 * @bits: the size of the modulus
1796
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1797
 * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
1798
 * @data_size: The number of @data available.
1799
 *
1800
 * This function will generate a random private key. Note that this
1801
 * function must be called on an initialized private key.
1802
 *
1803
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1804
 * instructs the key generation process to use algorithms like Shawe-Taylor
1805
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1806
 * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
1807
 * seed, while on RSA the two primes. To specify an explicit seed
1808
 * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
1809
 * type.
1810
 *
1811
 * Note that when generating an elliptic curve key, the curve
1812
 * can be substituted in the place of the bits parameter using the
1813
 * GNUTLS_CURVE_TO_BITS() macro.
1814
 *
1815
 * To export the generated keys in memory or in files it is recommended to use the
1816
 * PKCS#8 form as it can handle all key types, and can store additional parameters
1817
 * such as the seed, in case of provable RSA or DSA keys.
1818
 * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
1819
 * and then with gnutls_x509_privkey_export2_pkcs8().
1820
 *
1821
 * If key generation is part of your application, avoid setting the number
1822
 * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
1823
 * That way the generated keys will adapt to the security levels
1824
 * of the underlying GnuTLS library.
1825
 *
1826
 * See also gnutls_privkey_generate2().
1827
 *
1828
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1829
 *   negative error value.
1830
 **/
1831
int gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
1832
          gnutls_pk_algorithm_t algo, unsigned int bits,
1833
          unsigned int flags,
1834
          const gnutls_keygen_data_st *data,
1835
          unsigned data_size)
1836
0
{
1837
0
  int ret;
1838
0
  unsigned i;
1839
0
  gnutls_x509_spki_t spki = NULL;
1840
0
  gnutls_dh_params_t dh_params = NULL;
1841
1842
0
  if (key == NULL) {
1843
0
    gnutls_assert();
1844
0
    return GNUTLS_E_INVALID_REQUEST;
1845
0
  }
1846
1847
0
  gnutls_pk_params_init(&key->params);
1848
1849
0
  for (i = 0; i < data_size; i++) {
1850
0
    switch (data[i].type) {
1851
0
    case GNUTLS_KEYGEN_SEED:
1852
0
      if (data[i].size < sizeof(key->params.seed)) {
1853
0
        key->params.seed_size = data[i].size;
1854
0
        memcpy(key->params.seed, data[i].data,
1855
0
               data[i].size);
1856
0
      }
1857
0
      break;
1858
0
    case GNUTLS_KEYGEN_DIGEST:
1859
0
      key->params.palgo = data[i].size;
1860
0
      break;
1861
0
    case GNUTLS_KEYGEN_SPKI:
1862
0
      spki = (void *)data[i].data;
1863
0
      break;
1864
0
    case GNUTLS_KEYGEN_DH:
1865
0
      if (algo != GNUTLS_PK_DH) {
1866
0
        return gnutls_assert_val(
1867
0
          GNUTLS_E_INVALID_REQUEST);
1868
0
      }
1869
0
      dh_params = (void *)data[i].data;
1870
0
      break;
1871
0
    }
1872
0
  }
1873
1874
0
  if (IS_EC(algo)) {
1875
0
    if (GNUTLS_BITS_ARE_CURVE(bits))
1876
0
      bits = GNUTLS_BITS_TO_CURVE(bits);
1877
0
    else
1878
0
      bits = _gnutls_ecc_bits_to_curve(algo, bits);
1879
1880
0
    if (gnutls_ecc_curve_get_pk(bits) != algo) {
1881
0
      _gnutls_debug_log(
1882
0
        "curve is incompatible with public key algorithm\n");
1883
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1884
0
    }
1885
0
  }
1886
1887
0
  if (IS_GOSTEC(algo)) {
1888
0
    int size;
1889
1890
0
    if (GNUTLS_BITS_ARE_CURVE(bits))
1891
0
      bits = GNUTLS_BITS_TO_CURVE(bits);
1892
0
    else
1893
0
      bits = _gnutls_ecc_bits_to_curve(algo, bits);
1894
1895
0
    size = gnutls_ecc_curve_get_size(bits);
1896
1897
0
    if ((algo == GNUTLS_PK_GOST_01 && size != 32) ||
1898
0
        (algo == GNUTLS_PK_GOST_12_256 && size != 32) ||
1899
0
        (algo == GNUTLS_PK_GOST_12_512 && size != 64)) {
1900
0
      _gnutls_debug_log(
1901
0
        "curve is incompatible with public key algorithm\n");
1902
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1903
0
    }
1904
1905
0
    key->params.gost_params = _gnutls_gost_paramset_default(algo);
1906
0
  }
1907
1908
0
  if (flags & GNUTLS_PRIVKEY_FLAG_PROVABLE) {
1909
0
    key->params.pkflags |= GNUTLS_PK_FLAG_PROVABLE;
1910
0
  }
1911
1912
0
  key->params.algo = algo;
1913
1914
  /* DH params are given, no need to regenerate */
1915
0
  if (algo == GNUTLS_PK_DH && dh_params != NULL) {
1916
0
    key->params.params[DH_P] =
1917
0
      _gnutls_mpi_copy(dh_params->params[0]);
1918
0
    key->params.params[DH_G] =
1919
0
      _gnutls_mpi_copy(dh_params->params[1]);
1920
0
    if (dh_params->params[2]) {
1921
0
      key->params.params[DH_Q] =
1922
0
        _gnutls_mpi_copy(dh_params->params[2]);
1923
0
    }
1924
    /* X and Y will be added by _gnutls_pk_generate_keys */
1925
0
    key->params.params_nr = 3;
1926
0
    key->params.qbits = dh_params->q_bits;
1927
0
  } else {
1928
0
    ret = _gnutls_pk_generate_params(algo, bits, &key->params);
1929
0
    if (ret < 0) {
1930
0
      gnutls_assert();
1931
0
      return ret;
1932
0
    }
1933
0
  }
1934
1935
0
  if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA) &&
1936
0
      !key->params.spki.pk) {
1937
0
    const mac_entry_st *me;
1938
0
    key->params.spki.pk = GNUTLS_PK_RSA_PSS;
1939
1940
0
    key->params.spki.rsa_pss_dig =
1941
0
      _gnutls_pk_bits_to_sha_hash(bits);
1942
1943
0
    me = hash_to_entry(key->params.spki.rsa_pss_dig);
1944
0
    if (unlikely(me == NULL)) {
1945
0
      gnutls_assert();
1946
0
      ret = GNUTLS_E_INVALID_REQUEST;
1947
0
      goto cleanup;
1948
0
    }
1949
1950
0
    ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
1951
0
    if (ret < 0) {
1952
0
      gnutls_assert();
1953
0
      goto cleanup;
1954
0
    }
1955
1956
0
    key->params.spki.salt_size = ret;
1957
0
  }
1958
1959
0
  ret = _gnutls_pk_generate_keys(algo, bits, &key->params, 0);
1960
0
  if (ret < 0) {
1961
0
    gnutls_assert();
1962
0
    goto cleanup;
1963
0
  }
1964
1965
0
  ret = _gnutls_pk_verify_priv_params(algo, &key->params);
1966
0
  if (ret < 0) {
1967
0
    gnutls_assert();
1968
0
    goto cleanup;
1969
0
  }
1970
1971
0
  if (spki) {
1972
0
    ret = gnutls_x509_privkey_set_spki(key, spki, 0);
1973
0
    if (ret < 0) {
1974
0
      gnutls_assert();
1975
0
      goto cleanup;
1976
0
    }
1977
0
  }
1978
1979
  /* DH keys are only exportable in PKCS#8 format */
1980
0
  if (algo != GNUTLS_PK_DH) {
1981
0
    ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1982
0
    if (ret < 0) {
1983
0
      gnutls_assert();
1984
0
      goto cleanup;
1985
0
    }
1986
0
  }
1987
1988
0
  return 0;
1989
1990
0
cleanup:
1991
0
  key->params.algo = GNUTLS_PK_UNKNOWN;
1992
0
  gnutls_pk_params_clear(&key->params);
1993
0
  gnutls_pk_params_release(&key->params);
1994
1995
0
  return ret;
1996
0
}
1997
1998
/**
1999
 * gnutls_x509_privkey_get_seed:
2000
 * @key: should contain a #gnutls_x509_privkey_t type
2001
 * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
2002
 * @seed: where seed will be copied to
2003
 * @seed_size: originally holds the size of @seed, will be updated with actual size
2004
 *
2005
 * This function will return the seed that was used to generate the
2006
 * given private key. That function will succeed only if the key was generated
2007
 * as a provable key.
2008
 *
2009
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2010
 *   negative error value.
2011
 *
2012
 * Since: 3.5.0
2013
 **/
2014
int gnutls_x509_privkey_get_seed(gnutls_x509_privkey_t key,
2015
         gnutls_digest_algorithm_t *digest, void *seed,
2016
         size_t *seed_size)
2017
0
{
2018
0
  if (key->params.seed_size == 0)
2019
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2020
2021
0
  if (seed_size == NULL || seed == NULL) {
2022
0
    if (key->params.seed_size)
2023
0
      return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2024
0
    else
2025
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2026
0
  }
2027
2028
0
  if (*seed_size < key->params.seed_size) {
2029
0
    *seed_size = key->params.seed_size;
2030
0
    return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2031
0
  }
2032
2033
0
  if (digest)
2034
0
    *digest = key->params.palgo;
2035
2036
0
  memcpy(seed, key->params.seed, key->params.seed_size);
2037
0
  *seed_size = key->params.seed_size;
2038
0
  return 0;
2039
0
}
2040
2041
static int cmp_rsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2042
0
{
2043
0
  gnutls_datum_t m1 = { NULL, 0 }, e1 = { NULL, 0 }, d1 = { NULL, 0 },
2044
0
           p1 = { NULL, 0 }, q1 = { NULL, 0 };
2045
0
  gnutls_datum_t m2 = { NULL, 0 }, e2 = { NULL, 0 }, d2 = { NULL, 0 },
2046
0
           p2 = { NULL, 0 }, q2 = { NULL, 0 };
2047
0
  int ret;
2048
2049
0
  ret = gnutls_x509_privkey_export_rsa_raw(key1, &m1, &e1, &d1, &p1, &q1,
2050
0
             NULL);
2051
0
  if (ret < 0) {
2052
0
    gnutls_assert();
2053
0
    return ret;
2054
0
  }
2055
2056
0
  ret = gnutls_x509_privkey_export_rsa_raw(key2, &m2, &e2, &d2, &p2, &q2,
2057
0
             NULL);
2058
0
  if (ret < 0) {
2059
0
    gnutls_assert();
2060
0
    goto cleanup;
2061
0
  }
2062
2063
0
  if (m1.size != m2.size || memcmp(m1.data, m2.data, m1.size) != 0) {
2064
0
    gnutls_assert();
2065
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2066
0
    goto cleanup;
2067
0
  }
2068
2069
0
  if (d1.size != d2.size || memcmp(d1.data, d2.data, d1.size) != 0) {
2070
0
    gnutls_assert();
2071
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2072
0
    goto cleanup;
2073
0
  }
2074
2075
0
  if (e1.size != e2.size || memcmp(e1.data, e2.data, e1.size) != 0) {
2076
0
    gnutls_assert();
2077
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2078
0
    goto cleanup;
2079
0
  }
2080
2081
0
  if (p1.size != p2.size || memcmp(p1.data, p2.data, p1.size) != 0) {
2082
0
    gnutls_assert();
2083
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2084
0
    goto cleanup;
2085
0
  }
2086
2087
0
  if (q1.size != q2.size || memcmp(q1.data, q2.data, q1.size) != 0) {
2088
0
    gnutls_assert();
2089
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2090
0
    goto cleanup;
2091
0
  }
2092
2093
0
  ret = 0;
2094
0
cleanup:
2095
0
  gnutls_free(m1.data);
2096
0
  gnutls_free(e1.data);
2097
0
  gnutls_free(d1.data);
2098
0
  gnutls_free(p1.data);
2099
0
  gnutls_free(q1.data);
2100
0
  gnutls_free(m2.data);
2101
0
  gnutls_free(e2.data);
2102
0
  gnutls_free(d2.data);
2103
0
  gnutls_free(p2.data);
2104
0
  gnutls_free(q2.data);
2105
0
  return ret;
2106
0
}
2107
2108
static int cmp_dsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2109
0
{
2110
0
  gnutls_datum_t p1 = { NULL, 0 }, q1 = { NULL, 0 }, g1 = { NULL, 0 };
2111
0
  gnutls_datum_t p2 = { NULL, 0 }, q2 = { NULL, 0 }, g2 = { NULL, 0 };
2112
0
  int ret;
2113
2114
0
  ret = gnutls_x509_privkey_export_dsa_raw(key1, &p1, &q1, &g1, NULL,
2115
0
             NULL);
2116
0
  if (ret < 0) {
2117
0
    gnutls_assert();
2118
0
    return ret;
2119
0
  }
2120
2121
0
  ret = gnutls_x509_privkey_export_dsa_raw(key2, &p2, &q2, &g2, NULL,
2122
0
             NULL);
2123
0
  if (ret < 0) {
2124
0
    gnutls_assert();
2125
0
    goto cleanup;
2126
0
  }
2127
2128
0
  if (g1.size != g2.size || memcmp(g1.data, g2.data, g1.size) != 0) {
2129
0
    gnutls_assert();
2130
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2131
0
    goto cleanup;
2132
0
  }
2133
2134
0
  if (p1.size != p2.size || memcmp(p1.data, p2.data, p1.size) != 0) {
2135
0
    gnutls_assert();
2136
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2137
0
    goto cleanup;
2138
0
  }
2139
2140
0
  if (q1.size != q2.size || memcmp(q1.data, q2.data, q1.size) != 0) {
2141
0
    gnutls_assert();
2142
0
    ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2143
0
    goto cleanup;
2144
0
  }
2145
2146
0
  ret = 0;
2147
0
cleanup:
2148
0
  gnutls_free(g1.data);
2149
0
  gnutls_free(p1.data);
2150
0
  gnutls_free(q1.data);
2151
0
  gnutls_free(g2.data);
2152
0
  gnutls_free(p2.data);
2153
0
  gnutls_free(q2.data);
2154
0
  return ret;
2155
0
}
2156
2157
/**
2158
 * gnutls_x509_privkey_verify_seed:
2159
 * @key: should contain a #gnutls_x509_privkey_t type
2160
 * @digest: it contains the digest algorithm used for key generation (if applicable)
2161
 * @seed: the seed of the key to be checked with
2162
 * @seed_size: holds the size of @seed
2163
 *
2164
 * This function will verify that the given private key was generated from
2165
 * the provided seed. If @seed is %NULL then the seed stored in the @key's structure
2166
 * will be used for verification.
2167
 *
2168
 * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
2169
 * is returned, and zero or positive code on success.
2170
 *
2171
 * Since: 3.5.0
2172
 **/
2173
int gnutls_x509_privkey_verify_seed(gnutls_x509_privkey_t key,
2174
            gnutls_digest_algorithm_t digest,
2175
            const void *seed, size_t seed_size)
2176
0
{
2177
0
  int ret;
2178
0
  gnutls_x509_privkey_t okey;
2179
0
  unsigned bits;
2180
0
  gnutls_keygen_data_st data;
2181
2182
0
  if (key == NULL) {
2183
0
    gnutls_assert();
2184
0
    return GNUTLS_E_INVALID_REQUEST;
2185
0
  }
2186
2187
0
  if (key->params.algo != GNUTLS_PK_RSA &&
2188
0
      key->params.algo != GNUTLS_PK_DSA)
2189
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
2190
2191
0
  ret = gnutls_x509_privkey_get_pk_algorithm2(key, &bits);
2192
0
  if (ret < 0)
2193
0
    return gnutls_assert_val(ret);
2194
2195
0
  ret = gnutls_x509_privkey_init(&okey);
2196
0
  if (ret < 0)
2197
0
    return gnutls_assert_val(ret);
2198
2199
0
  if (seed == NULL) {
2200
0
    seed = key->params.seed;
2201
0
    seed_size = key->params.seed_size;
2202
0
  }
2203
2204
0
  if (seed == NULL || seed_size == 0)
2205
0
    return gnutls_assert_val(GNUTLS_E_PK_NO_VALIDATION_PARAMS);
2206
2207
0
  data.type = GNUTLS_KEYGEN_SEED;
2208
0
  data.data = (void *)seed;
2209
0
  data.size = seed_size;
2210
2211
0
  ret = gnutls_x509_privkey_generate2(okey, key->params.algo, bits,
2212
0
              GNUTLS_PRIVKEY_FLAG_PROVABLE, &data,
2213
0
              1);
2214
0
  if (ret < 0) {
2215
0
    gnutls_assert();
2216
0
    goto cleanup;
2217
0
  }
2218
2219
0
  if (key->params.algo == GNUTLS_PK_RSA)
2220
0
    ret = cmp_rsa_key(key, okey);
2221
0
  else
2222
0
    ret = cmp_dsa_key(key, okey);
2223
2224
0
cleanup:
2225
0
  gnutls_x509_privkey_deinit(okey);
2226
2227
0
  return ret;
2228
0
}
2229
2230
/**
2231
 * gnutls_x509_privkey_verify_params:
2232
 * @key: a key
2233
 *
2234
 * This function will verify the private key parameters.
2235
 *
2236
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2237
 *   negative error value.
2238
 **/
2239
int gnutls_x509_privkey_verify_params(gnutls_x509_privkey_t key)
2240
0
{
2241
0
  int ret;
2242
2243
0
  ret = _gnutls_pk_verify_priv_params(key->params.algo, &key->params);
2244
0
  if (ret < 0) {
2245
0
    gnutls_assert();
2246
0
    return ret;
2247
0
  }
2248
2249
0
  return 0;
2250
0
}
2251
2252
/**
2253
 * gnutls_x509_privkey_get_key_id:
2254
 * @key: a key
2255
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
2256
 * @output_data: will contain the key ID
2257
 * @output_data_size: holds the size of output_data (and will be
2258
 *   replaced by the actual size of parameters)
2259
 *
2260
 * This function will return a unique ID that depends on the public key
2261
 * parameters. This ID can be used in checking whether a certificate
2262
 * corresponds to the given key.
2263
 *
2264
 * If the buffer provided is not long enough to hold the output, then
2265
 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2266
 * be returned.  The output will normally be a SHA-1 hash output,
2267
 * which is 20 bytes.
2268
 *
2269
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2270
 *   negative error value.
2271
 **/
2272
int gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,
2273
           unsigned int flags,
2274
           unsigned char *output_data,
2275
           size_t *output_data_size)
2276
0
{
2277
0
  int ret;
2278
2279
0
  if (key == NULL) {
2280
0
    gnutls_assert();
2281
0
    return GNUTLS_E_INVALID_REQUEST;
2282
0
  }
2283
2284
0
  ret = _gnutls_get_key_id(&key->params, output_data, output_data_size,
2285
0
         flags);
2286
0
  if (ret < 0) {
2287
0
    gnutls_assert();
2288
0
  }
2289
2290
0
  return ret;
2291
0
}
2292
2293
/**
2294
 * gnutls_x509_privkey_sign_hash:
2295
 * @key: a key
2296
 * @hash: holds the data to be signed
2297
 * @signature: will contain newly allocated signature
2298
 *
2299
 * This function will sign the given hash using the private key. Do not
2300
 * use this function directly unless you know what it is. Typical signing
2301
 * requires the data to be hashed and stored in special formats 
2302
 * (e.g. BER Digest-Info for RSA).
2303
 *
2304
 * This API is provided only for backwards compatibility, and thus
2305
 * restricted to RSA, DSA and ECDSA key types. For other key types please
2306
 * use gnutls_privkey_sign_hash() and gnutls_privkey_sign_data().
2307
 *
2308
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2309
 *   negative error value.
2310
 *
2311
 * Deprecated in: 2.12.0
2312
 */
2313
int gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,
2314
          const gnutls_datum_t *hash,
2315
          gnutls_datum_t *signature)
2316
0
{
2317
0
  int result;
2318
2319
0
  if (key == NULL) {
2320
0
    gnutls_assert();
2321
0
    return GNUTLS_E_INVALID_REQUEST;
2322
0
  }
2323
2324
0
  if (key->params.algo != GNUTLS_PK_RSA &&
2325
0
      key->params.algo != GNUTLS_PK_ECDSA &&
2326
0
      key->params.algo != GNUTLS_PK_DSA) {
2327
    /* too primitive API - use only with legacy types */
2328
0
    gnutls_assert();
2329
0
    return GNUTLS_E_INVALID_REQUEST;
2330
0
  }
2331
2332
0
  result = _gnutls_pk_sign(key->params.algo, signature, hash,
2333
0
         &key->params, &key->params.spki);
2334
2335
0
  if (result < 0) {
2336
0
    gnutls_assert();
2337
0
    return result;
2338
0
  }
2339
2340
0
  return 0;
2341
0
}
2342
2343
/**
2344
 * gnutls_x509_privkey_sign_data:
2345
 * @key: a key
2346
 * @digest: should be a digest algorithm
2347
 * @flags: should be 0 for now
2348
 * @data: holds the data to be signed
2349
 * @signature: will contain the signature
2350
 * @signature_size: holds the size of signature (and will be replaced
2351
 *   by the new size)
2352
 *
2353
 * This function will sign the given data using a signature algorithm
2354
 * supported by the private key. Signature algorithms are always used
2355
 * together with a hash functions.  Different hash functions may be
2356
 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
2357
 *
2358
 * If the buffer provided is not long enough to hold the output, then
2359
 * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2360
 * be returned.
2361
 *
2362
 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
2363
 * the hash algorithm.
2364
 *
2365
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2366
 *   negative error value.
2367
 */
2368
int gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,
2369
          gnutls_digest_algorithm_t digest,
2370
          unsigned int flags,
2371
          const gnutls_datum_t *data, void *signature,
2372
          size_t *signature_size)
2373
0
{
2374
0
  gnutls_privkey_t privkey;
2375
0
  gnutls_datum_t sig = { NULL, 0 };
2376
0
  int ret;
2377
2378
0
  ret = gnutls_privkey_init(&privkey);
2379
0
  if (ret < 0)
2380
0
    return gnutls_assert_val(ret);
2381
2382
0
  ret = gnutls_privkey_import_x509(privkey, key, 0);
2383
0
  if (ret < 0) {
2384
0
    gnutls_assert();
2385
0
    goto cleanup;
2386
0
  }
2387
2388
0
  ret = gnutls_privkey_sign_data(privkey, digest, flags, data, &sig);
2389
0
  if (ret < 0) {
2390
0
    gnutls_assert();
2391
0
    goto cleanup;
2392
0
  }
2393
2394
0
  if (*signature_size < sig.size) {
2395
0
    *signature_size = sig.size;
2396
0
    ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2397
0
    goto cleanup;
2398
0
  }
2399
2400
0
  *signature_size = sig.size;
2401
0
  memcpy(signature, sig.data, sig.size);
2402
2403
0
cleanup:
2404
0
  _gnutls_free_datum(&sig);
2405
0
  gnutls_privkey_deinit(privkey);
2406
0
  return ret;
2407
0
}
2408
2409
/**
2410
 * gnutls_x509_privkey_fix:
2411
 * @key: a key
2412
 *
2413
 * This function will recalculate the secondary parameters in a key.
2414
 * In RSA keys, this can be the coefficient and exponent1,2.
2415
 *
2416
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2417
 *   negative error value.
2418
 **/
2419
int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key)
2420
0
{
2421
0
  int ret;
2422
2423
0
  if (key == NULL) {
2424
0
    gnutls_assert();
2425
0
    return GNUTLS_E_INVALID_REQUEST;
2426
0
  }
2427
2428
0
  if (key->key) {
2429
0
    asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
2430
2431
0
    ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
2432
0
    if (ret < 0) {
2433
0
      gnutls_assert();
2434
0
      return ret;
2435
0
    }
2436
0
  }
2437
2438
0
  return 0;
2439
0
}
2440
2441
/**
2442
 * gnutls_x509_privkey_set_pin_function:
2443
 * @privkey: The certificate structure
2444
 * @fn: the callback
2445
 * @userdata: data associated with the callback
2446
 *
2447
 * This function will set a callback function to be used when
2448
 * it is required to access a protected object. This function overrides 
2449
 * the global function set using gnutls_pkcs11_set_pin_function().
2450
 *
2451
 * Note that this callback is used when decrypting a key.
2452
 *
2453
 * Since: 3.4.0
2454
 *
2455
 **/
2456
void gnutls_x509_privkey_set_pin_function(gnutls_x509_privkey_t privkey,
2457
            gnutls_pin_callback_t fn,
2458
            void *userdata)
2459
0
{
2460
0
  privkey->pin.cb = fn;
2461
0
  privkey->pin.data = userdata;
2462
0
}
2463
2464
/**
2465
 * gnutls_x509_privkey_set_flags:
2466
 * @key: A key of type #gnutls_x509_privkey_t
2467
 * @flags: flags from the %gnutls_privkey_flags
2468
 *
2469
 * This function will set flags for the specified private key, after
2470
 * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
2471
 * to allow exporting a "provable" private key in backwards compatible way.
2472
 *
2473
 * Since: 3.5.0
2474
 *
2475
 **/
2476
void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key,
2477
           unsigned int flags)
2478
0
{
2479
0
  key->flags |= flags;
2480
0
}