Coverage Report

Created: 2026-05-16 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/privkey.c
Line
Count
Source
1
/*
2
 * GnuTLS PKCS#11 support
3
 * Copyright (C) 2010-2014 Free Software Foundation, Inc.
4
 * Copyright (C) 2012-2015 Nikos Mavrogiannopoulos
5
 * Copyright (C) 2016-2017 Red Hat, Inc.
6
 * 
7
 * Author: Nikos Mavrogiannopoulos
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 */
22
23
#include "gnutls_int.h"
24
#include <gnutls/pkcs11.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include "errors.h"
28
#include "datum.h"
29
#include "pkcs11_int.h"
30
#include <gnutls/abstract.h>
31
#include "pk.h"
32
#include "x509_int.h"
33
#include "tls-sig.h"
34
#include "algorithms.h"
35
#include "fips.h"
36
#include "system-keys.h"
37
#include "urls.h"
38
#include "tpm2/tpm2.h"
39
#include "pkcs11_int.h"
40
#include "abstract_int.h"
41
42
static int privkey_sign_prehashed(gnutls_privkey_t signer,
43
          const gnutls_sign_entry_st *se,
44
          const gnutls_datum_t *hash_data,
45
          gnutls_datum_t *signature,
46
          gnutls_x509_spki_st *params);
47
48
/**
49
 * gnutls_privkey_get_type:
50
 * @key: should contain a #gnutls_privkey_t type
51
 *
52
 * This function will return the type of the private key. This is
53
 * actually the type of the subsystem used to set this private key.
54
 *
55
 * Returns: a member of the #gnutls_privkey_type_t enumeration on
56
 *   success, or a negative error code on error.
57
 *
58
 * Since: 2.12.0
59
 **/
60
gnutls_privkey_type_t gnutls_privkey_get_type(gnutls_privkey_t key)
61
0
{
62
0
  return key->type;
63
0
}
64
65
/**
66
 * gnutls_privkey_get_seed:
67
 * @key: should contain a #gnutls_privkey_t type
68
 * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
69
 * @seed: where seed will be copied to
70
 * @seed_size: originally holds the size of @seed, will be updated with actual size
71
 *
72
 * This function will return the seed that was used to generate the
73
 * given private key. That function will succeed only if the key was generated
74
 * as a provable key.
75
 *
76
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
77
 *   negative error value.
78
 *
79
 * Since: 3.5.0
80
 **/
81
int gnutls_privkey_get_seed(gnutls_privkey_t key,
82
          gnutls_digest_algorithm_t *digest, void *seed,
83
          size_t *seed_size)
84
0
{
85
0
  if (key->type != GNUTLS_PRIVKEY_X509)
86
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
87
0
  return gnutls_x509_privkey_get_seed(key->key.x509, digest, seed,
88
0
              seed_size);
89
0
}
90
91
/**
92
 * gnutls_privkey_verify_seed:
93
 * @key: should contain a #gnutls_privkey_t type
94
 * @digest: it contains the digest algorithm used for key generation (if applicable)
95
 * @seed: the seed of the key to be checked with
96
 * @seed_size: holds the size of @seed
97
 *
98
 * This function will verify that the given private key was generated from
99
 * the provided seed.
100
 *
101
 * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
102
 * is returned, and zero or positive code on success.
103
 *
104
 * Since: 3.5.0
105
 **/
106
int gnutls_privkey_verify_seed(gnutls_privkey_t key,
107
             gnutls_digest_algorithm_t digest,
108
             const void *seed, size_t seed_size)
109
0
{
110
0
  if (key->type != GNUTLS_PRIVKEY_X509)
111
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
112
0
  return gnutls_x509_privkey_verify_seed(key->key.x509, digest, seed,
113
0
                 seed_size);
114
0
}
115
116
/**
117
 * gnutls_privkey_get_pk_algorithm:
118
 * @key: should contain a #gnutls_privkey_t type
119
 * @bits: If set will return the number of bits of the parameters (may be NULL)
120
 *
121
 * This function will return the public key algorithm of a private
122
 * key and if possible will return a number of bits that indicates
123
 * the security parameter of the key.
124
 *
125
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
126
 *   success, or a negative error code on error.
127
 *
128
 * Since: 2.12.0
129
 **/
130
int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits)
131
0
{
132
0
  switch (key->type) {
133
#ifdef ENABLE_PKCS11
134
  case GNUTLS_PRIVKEY_PKCS11:
135
    return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11,
136
                    bits);
137
#endif
138
0
  case GNUTLS_PRIVKEY_X509:
139
0
    if (bits) {
140
0
      *bits = pubkey_to_bits(&key->key.x509->params);
141
0
    }
142
143
0
    return gnutls_x509_privkey_get_pk_algorithm(key->key.x509);
144
0
  case GNUTLS_PRIVKEY_EXT:
145
0
    if (bits)
146
0
      *bits = key->key.ext.bits;
147
148
0
    return key->pk_algorithm;
149
0
  default:
150
0
    gnutls_assert();
151
0
    return GNUTLS_E_INVALID_REQUEST;
152
0
  }
153
0
}
154
155
static int privkey_to_pubkey(gnutls_pk_algorithm_t pk,
156
           const gnutls_pk_params_st *priv,
157
           gnutls_pk_params_st *pub)
158
0
{
159
0
  int ret;
160
161
0
  pub->algo = priv->algo;
162
0
  pub->pkflags = priv->pkflags;
163
0
  pub->curve = priv->curve;
164
0
  pub->gost_params = priv->gost_params;
165
0
  pub->qbits = priv->qbits;
166
0
  ret = _gnutls_x509_spki_copy(&pub->spki, &priv->spki);
167
0
  if (ret < 0) {
168
0
    gnutls_assert();
169
0
    goto cleanup;
170
0
  }
171
172
0
  switch (pk) {
173
0
  case GNUTLS_PK_RSA_PSS:
174
0
  case GNUTLS_PK_RSA_OAEP:
175
0
  case GNUTLS_PK_RSA:
176
0
    pub->params[RSA_MODULUS] =
177
0
      _gnutls_mpi_copy(priv->params[RSA_MODULUS]);
178
0
    pub->params[RSA_PUB] = _gnutls_mpi_copy(priv->params[RSA_PUB]);
179
180
0
    pub->params_nr = RSA_PUBLIC_PARAMS;
181
182
0
    if (pub->params[RSA_MODULUS] == NULL ||
183
0
        pub->params[RSA_PUB] == NULL) {
184
0
      gnutls_assert();
185
0
      ret = GNUTLS_E_MEMORY_ERROR;
186
0
      goto cleanup;
187
0
    }
188
189
0
    break;
190
0
  case GNUTLS_PK_DSA:
191
0
    pub->params[DSA_P] = _gnutls_mpi_copy(priv->params[DSA_P]);
192
0
    pub->params[DSA_Q] = _gnutls_mpi_copy(priv->params[DSA_Q]);
193
0
    pub->params[DSA_G] = _gnutls_mpi_copy(priv->params[DSA_G]);
194
0
    pub->params[DSA_Y] = _gnutls_mpi_copy(priv->params[DSA_Y]);
195
196
0
    pub->params_nr = DSA_PUBLIC_PARAMS;
197
198
0
    if (pub->params[DSA_P] == NULL || pub->params[DSA_Q] == NULL ||
199
0
        pub->params[DSA_G] == NULL || pub->params[DSA_Y] == NULL) {
200
0
      gnutls_assert();
201
0
      ret = GNUTLS_E_MEMORY_ERROR;
202
0
      goto cleanup;
203
0
    }
204
205
0
    break;
206
0
  case GNUTLS_PK_DH:
207
0
    pub->params[DH_P] = _gnutls_mpi_copy(priv->params[DH_P]);
208
0
    pub->params[DH_G] = _gnutls_mpi_copy(priv->params[DH_G]);
209
0
    pub->params[DH_Y] = _gnutls_mpi_copy(priv->params[DH_Y]);
210
211
0
    if (pub->params[DH_P] == NULL || pub->params[DH_G] == NULL ||
212
0
        pub->params[DH_Y] == NULL) {
213
0
      gnutls_assert();
214
0
      ret = GNUTLS_E_MEMORY_ERROR;
215
0
      goto cleanup;
216
0
    }
217
218
0
    if (priv->params[DH_Q]) {
219
0
      pub->params[DH_Q] =
220
0
        _gnutls_mpi_copy(priv->params[DH_Q]);
221
0
      if (pub->params[DH_Q] == NULL) {
222
0
        gnutls_assert();
223
0
        ret = GNUTLS_E_MEMORY_ERROR;
224
0
        goto cleanup;
225
0
      }
226
0
    }
227
228
0
    pub->params_nr = DH_PUBLIC_PARAMS;
229
230
0
    break;
231
0
  case GNUTLS_PK_ECDSA:
232
0
    pub->params[ECC_X] = _gnutls_mpi_copy(priv->params[ECC_X]);
233
0
    pub->params[ECC_Y] = _gnutls_mpi_copy(priv->params[ECC_Y]);
234
235
0
    pub->params_nr = ECC_PUBLIC_PARAMS;
236
237
0
    if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL) {
238
0
      gnutls_assert();
239
0
      ret = GNUTLS_E_MEMORY_ERROR;
240
0
      goto cleanup;
241
0
    }
242
243
0
    break;
244
0
  case GNUTLS_PK_EDDSA_ED25519:
245
0
  case GNUTLS_PK_EDDSA_ED448:
246
0
  case GNUTLS_PK_ECDH_X25519:
247
0
  case GNUTLS_PK_ECDH_X448:
248
0
  case GNUTLS_PK_MLDSA44:
249
0
  case GNUTLS_PK_MLDSA65:
250
0
  case GNUTLS_PK_MLDSA87:
251
0
    ret = _gnutls_set_datum(&pub->raw_pub, priv->raw_pub.data,
252
0
          priv->raw_pub.size);
253
0
    if (ret < 0)
254
0
      return gnutls_assert_val(ret);
255
256
0
    break;
257
0
  case GNUTLS_PK_GOST_01:
258
0
  case GNUTLS_PK_GOST_12_256:
259
0
  case GNUTLS_PK_GOST_12_512:
260
0
    pub->params[GOST_X] = _gnutls_mpi_copy(priv->params[GOST_X]);
261
0
    pub->params[GOST_Y] = _gnutls_mpi_copy(priv->params[GOST_Y]);
262
263
0
    pub->params_nr = GOST_PUBLIC_PARAMS;
264
265
0
    if (pub->params[GOST_X] == NULL ||
266
0
        pub->params[GOST_Y] == NULL) {
267
0
      gnutls_assert();
268
0
      ret = GNUTLS_E_MEMORY_ERROR;
269
0
      goto cleanup;
270
0
    }
271
272
0
    break;
273
0
  default:
274
0
    gnutls_assert();
275
0
    return GNUTLS_E_INVALID_REQUEST;
276
0
  }
277
278
0
  return 0;
279
0
cleanup:
280
0
  gnutls_pk_params_release(pub);
281
0
  return ret;
282
0
}
283
284
/* Returns the public key of the private key (if possible)
285
 */
286
int _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st *params)
287
0
{
288
0
  int ret;
289
290
0
  switch (key->type) {
291
0
  case GNUTLS_PRIVKEY_X509:
292
0
    ret = _gnutls_pk_params_copy(params, &key->key.x509->params);
293
0
    break;
294
#ifdef ENABLE_PKCS11
295
  case GNUTLS_PRIVKEY_PKCS11: {
296
    gnutls_pubkey_t pubkey;
297
298
    ret = _pkcs11_privkey_get_pubkey(key->key.pkcs11, &pubkey, 0);
299
    if (ret < 0)
300
      return gnutls_assert_val(ret);
301
302
    ret = _gnutls_pubkey_get_mpis(pubkey, params);
303
    gnutls_pubkey_deinit(pubkey);
304
305
    break;
306
  }
307
#endif
308
0
  default:
309
0
    if (key->key.ext.pk_params_func) {
310
0
      ret = key->key.ext.pk_params_func(
311
0
        key, key->key.ext.userdata, params);
312
0
      if (ret < 0)
313
0
        return gnutls_assert_val(ret);
314
0
      return ret;
315
0
    }
316
0
    gnutls_assert();
317
0
    return GNUTLS_E_INVALID_REQUEST;
318
0
  }
319
320
0
  return ret;
321
0
}
322
323
int _gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
324
            gnutls_pk_params_st *params)
325
0
{
326
0
  int ret;
327
0
  gnutls_pk_params_st tmp1;
328
329
0
  gnutls_pk_params_init(&tmp1);
330
331
0
  ret = _gnutls_privkey_get_mpis(key, &tmp1);
332
0
  if (ret < 0)
333
0
    return gnutls_assert_val(ret);
334
335
0
  ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params);
336
337
0
  gnutls_pk_params_release(&tmp1);
338
339
0
  if (ret < 0)
340
0
    gnutls_assert();
341
342
0
  return ret;
343
0
}
344
345
/* This function retrieves default sign parameters from KEY. */
346
int _gnutls_privkey_get_spki_params(gnutls_privkey_t key,
347
            gnutls_x509_spki_st *params)
348
0
{
349
0
  switch (key->type) {
350
#ifdef ENABLE_PKCS11
351
  case GNUTLS_PRIVKEY_PKCS11:
352
    break;
353
#endif
354
0
  case GNUTLS_PRIVKEY_EXT:
355
0
    break;
356
0
  case GNUTLS_PRIVKEY_X509:
357
0
    return _gnutls_x509_privkey_get_spki_params(key->key.x509,
358
0
                  params);
359
0
  default:
360
0
    gnutls_assert();
361
0
    return GNUTLS_E_INVALID_REQUEST;
362
0
  }
363
364
0
  memset(params, 0, sizeof(gnutls_x509_spki_st));
365
366
0
  return 0;
367
0
}
368
369
/* This function fills in PARAMS with the necessary parameters to sign
370
 * with PK and DIG. PARAMS must be initialized with
371
 * _gnutls_privkey_get_spki_params in advance.
372
 *
373
 * After calling this function the params structure will
374
 * be initialized even if the original SubjectPublicKeyInfo was empty.
375
 */
376
int _gnutls_privkey_update_spki_params(gnutls_privkey_t key,
377
               gnutls_pk_algorithm_t pk,
378
               gnutls_digest_algorithm_t dig,
379
               unsigned flags,
380
               gnutls_x509_spki_st *params)
381
0
{
382
0
  unsigned salt_size = 0;
383
0
  unsigned bits = 0;
384
0
  gnutls_pk_algorithm_t key_pk;
385
386
0
  if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS) {
387
0
    if (!GNUTLS_PK_IS_RSA(pk))
388
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
389
0
    pk = GNUTLS_PK_RSA_PSS;
390
0
  }
391
392
0
  key_pk = gnutls_privkey_get_pk_algorithm(key, &bits);
393
0
  if ((key_pk != pk) &&
394
0
      !(key_pk == GNUTLS_PK_RSA && pk == GNUTLS_PK_RSA_PSS)) {
395
0
    gnutls_assert();
396
0
    return GNUTLS_E_CONSTRAINT_ERROR;
397
0
  }
398
399
0
  if (pk == GNUTLS_PK_RSA_PSS) {
400
0
    const mac_entry_st *me;
401
0
    int ret;
402
403
0
    me = hash_to_entry(dig);
404
0
    if (unlikely(me == NULL))
405
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
406
407
0
    if (params->pk == GNUTLS_PK_RSA)
408
0
      salt_size = 0;
409
0
    else if (params->pk == GNUTLS_PK_RSA_PSS) {
410
0
      if (params->rsa_pss_dig != GNUTLS_DIG_UNKNOWN &&
411
0
          dig != params->rsa_pss_dig) {
412
0
        return gnutls_assert_val(
413
0
          GNUTLS_E_CONSTRAINT_ERROR);
414
0
      }
415
416
0
      salt_size = params->salt_size;
417
0
    }
418
419
0
    if (flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE)
420
0
      params->salt_size = 0;
421
0
    else {
422
0
      ret = _gnutls_find_rsa_pss_salt_size(bits, me,
423
0
                   salt_size);
424
0
      if (ret < 0)
425
0
        return gnutls_assert_val(ret);
426
0
      if (flags & GNUTLS_PRIVKEY_FLAG_RSA_PSS_FIXED_SALT_LENGTH &&
427
0
          (size_t)ret != _gnutls_hash_get_algo_len(me)) {
428
0
        return gnutls_assert_val(
429
0
          GNUTLS_E_CONSTRAINT_ERROR);
430
0
      }
431
0
      params->salt_size = ret;
432
0
    }
433
0
    params->rsa_pss_dig = dig;
434
0
  }
435
436
0
  params->pk = pk;
437
438
0
  return 0;
439
0
}
440
441
/**
442
 * gnutls_privkey_init:
443
 * @key: A pointer to the type to be initialized
444
 *
445
 * This function will initialize a private key object. The object can
446
 * be used to generate, import, and perform cryptographic operations
447
 * on the associated private key.
448
 *
449
 * Note that when the underlying private key is a PKCS#11 key (i.e.,
450
 * when imported with a PKCS#11 URI), the limitations of gnutls_pkcs11_privkey_init()
451
 * apply to this object as well. In versions of GnuTLS later than 3.5.11 the object
452
 * is protected using locks and a single %gnutls_privkey_t can be re-used
453
 * by many threads. However, for performance it is recommended to utilize
454
 * one object per key per thread.
455
 *
456
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
457
 *   negative error value.
458
 *
459
 * Since: 2.12.0
460
 **/
461
int gnutls_privkey_init(gnutls_privkey_t *key)
462
0
{
463
0
  *key = NULL;
464
0
  FAIL_IF_LIB_ERROR;
465
466
0
  *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st));
467
0
  if (*key == NULL) {
468
0
    gnutls_assert();
469
0
    return GNUTLS_E_MEMORY_ERROR;
470
0
  }
471
472
0
  return 0;
473
0
}
474
475
/**
476
 * gnutls_privkey_deinit:
477
 * @key: The key to be deinitialized
478
 *
479
 * This function will deinitialize a private key structure.
480
 *
481
 * Since: 2.12.0
482
 **/
483
void gnutls_privkey_deinit(gnutls_privkey_t key)
484
0
{
485
0
  if (key == NULL)
486
0
    return;
487
488
0
  if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE ||
489
0
      key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
490
0
    switch (key->type) {
491
#ifdef ENABLE_PKCS11
492
    case GNUTLS_PRIVKEY_PKCS11:
493
      gnutls_pkcs11_privkey_deinit(key->key.pkcs11);
494
      break;
495
#endif
496
0
    case GNUTLS_PRIVKEY_X509:
497
0
      gnutls_x509_privkey_deinit(key->key.x509);
498
0
      break;
499
0
    case GNUTLS_PRIVKEY_EXT:
500
0
      if (key->key.ext.deinit_func != NULL)
501
0
        key->key.ext.deinit_func(key,
502
0
               key->key.ext.userdata);
503
0
      break;
504
0
    default:
505
0
      break;
506
0
    }
507
0
  gnutls_free(key);
508
0
}
509
510
/* Will erase all private key information, except PIN */
511
void _gnutls_privkey_cleanup(gnutls_privkey_t key)
512
0
{
513
0
  memset(&key->key, 0, sizeof(key->key));
514
0
  key->type = 0;
515
0
  key->pk_algorithm = 0;
516
0
  key->flags = 0;
517
0
}
518
519
/* will fail if the private key contains an actual key.
520
 */
521
static int check_if_clean(gnutls_privkey_t key)
522
0
{
523
0
  if (key->type != 0)
524
0
    return GNUTLS_E_INVALID_REQUEST;
525
526
0
  return 0;
527
0
}
528
529
#ifdef ENABLE_PKCS11
530
531
/**
532
 * gnutls_privkey_import_pkcs11:
533
 * @pkey: The private key
534
 * @key: The private key to be imported
535
 * @flags: Flags for the import
536
 *
537
 * This function will import the given private key to the abstract
538
 * #gnutls_privkey_t type.
539
 *
540
 * The #gnutls_pkcs11_privkey_t object must not be deallocated
541
 * during the lifetime of this structure.
542
 *
543
 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
544
 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
545
 *
546
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
547
 *   negative error value.
548
 *
549
 * Since: 2.12.0
550
 **/
551
int gnutls_privkey_import_pkcs11(gnutls_privkey_t pkey,
552
         gnutls_pkcs11_privkey_t key,
553
         unsigned int flags)
554
{
555
  int ret;
556
557
  ret = check_if_clean(pkey);
558
  if (ret < 0) {
559
    gnutls_assert();
560
    return ret;
561
  }
562
563
  if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
564
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
565
566
  pkey->key.pkcs11 = key;
567
  pkey->type = GNUTLS_PRIVKEY_PKCS11;
568
  pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm(key, NULL);
569
  pkey->flags = flags;
570
571
  if (pkey->pin.data)
572
    gnutls_pkcs11_privkey_set_pin_function(key, pkey->pin.cb,
573
                   pkey->pin.data);
574
575
  return 0;
576
}
577
578
#if 0
579
/**
580
 * gnutls_privkey_import_pkcs11_url:
581
 * @key: A key of type #gnutls_pubkey_t
582
 * @url: A PKCS 11 url
583
 *
584
 * This function will import a PKCS 11 private key to a #gnutls_privkey_t
585
 * type.
586
 *
587
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
588
 *   negative error value.
589
 *
590
 * Since: 3.1.0
591
 **/
592
593
int gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url)
594
{
595
  int x;
596
}
597
#endif
598
599
static int _gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key,
600
               const char *url, unsigned flags)
601
{
602
  gnutls_pkcs11_privkey_t pkey;
603
  int ret;
604
605
  ret = gnutls_pkcs11_privkey_init(&pkey);
606
  if (ret < 0) {
607
    gnutls_assert();
608
    return ret;
609
  }
610
611
  if (key->pin.cb)
612
    gnutls_pkcs11_privkey_set_pin_function(pkey, key->pin.cb,
613
                   key->pin.data);
614
615
  ret = gnutls_pkcs11_privkey_import_url(pkey, url, flags);
616
  if (ret < 0) {
617
    gnutls_assert();
618
    goto cleanup;
619
  }
620
621
  ret = gnutls_privkey_import_pkcs11(key, pkey,
622
             GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
623
  if (ret < 0) {
624
    gnutls_assert();
625
    goto cleanup;
626
  }
627
628
  return 0;
629
630
cleanup:
631
  gnutls_pkcs11_privkey_deinit(pkey);
632
633
  return ret;
634
}
635
636
/**
637
 * gnutls_privkey_export_pkcs11:
638
 * @pkey: The private key
639
 * @key: Location for the key to be exported.
640
 *
641
 * Converts the given abstract private key to a #gnutls_pkcs11_privkey_t
642
 * type. The key must be of type %GNUTLS_PRIVKEY_PKCS11. The key
643
 * returned in @key must be deinitialized with
644
 * gnutls_pkcs11_privkey_deinit().
645
 *
646
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
647
 *   negative error value.
648
 *
649
 * Since: 3.4.0
650
 */
651
int gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,
652
         gnutls_pkcs11_privkey_t *key)
653
{
654
  int ret;
655
656
  *key = NULL;
657
  if (pkey->type != GNUTLS_PRIVKEY_PKCS11) {
658
    gnutls_assert();
659
    return GNUTLS_E_INVALID_REQUEST;
660
  }
661
662
  ret = gnutls_pkcs11_privkey_init(key);
663
  if (ret < 0)
664
    return gnutls_assert_val(ret);
665
666
  ret = gnutls_pkcs11_privkey_cpy(*key, pkey->key.pkcs11);
667
  if (ret < 0) {
668
    gnutls_pkcs11_privkey_deinit(*key);
669
    *key = NULL;
670
671
    return gnutls_assert_val(ret);
672
  }
673
674
  return 0;
675
}
676
#endif /* ENABLE_PKCS11 */
677
678
/**
679
 * gnutls_privkey_import_ext:
680
 * @pkey: The private key
681
 * @pk: The public key algorithm
682
 * @userdata: private data to be provided to the callbacks
683
 * @sign_func: callback for signature operations
684
 * @decrypt_func: callback for decryption operations
685
 * @flags: Flags for the import
686
 *
687
 * This function will associate the given callbacks with the
688
 * #gnutls_privkey_t type. At least one of the two callbacks
689
 * must be non-null.
690
 *
691
 * Note that the signing function is supposed to "raw" sign data, i.e.,
692
 * without any hashing or preprocessing. In case of RSA the DigestInfo
693
 * will be provided, and the signing function is expected to do the PKCS #1
694
 * 1.5 padding and the exponentiation.
695
 *
696
 * See also gnutls_privkey_import_ext3().
697
 *
698
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
699
 *   negative error value.
700
 *
701
 * Since: 3.0
702
 **/
703
int gnutls_privkey_import_ext(gnutls_privkey_t pkey, gnutls_pk_algorithm_t pk,
704
            void *userdata,
705
            gnutls_privkey_sign_func sign_func,
706
            gnutls_privkey_decrypt_func decrypt_func,
707
            unsigned int flags)
708
0
{
709
0
  return gnutls_privkey_import_ext2(pkey, pk, userdata, sign_func,
710
0
            decrypt_func, NULL, flags);
711
0
}
712
713
#define PK_IS_OK_FOR_EXT2(pk)                                \
714
0
  ((pk == GNUTLS_PK_RSA) || (pk == GNUTLS_PK_ECDSA) || \
715
0
   (pk == GNUTLS_PK_DSA))
716
717
/**
718
 * gnutls_privkey_import_ext2:
719
 * @pkey: The private key
720
 * @pk: The public key algorithm
721
 * @userdata: private data to be provided to the callbacks
722
 * @sign_fn: callback for signature operations
723
 * @decrypt_fn: callback for decryption operations
724
 * @deinit_fn: a deinitialization function
725
 * @flags: Flags for the import
726
 *
727
 * This function will associate the given callbacks with the
728
 * #gnutls_privkey_t type. At least one of the two callbacks
729
 * must be non-null. If a deinitialization function is provided
730
 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
731
 *
732
 * Note that the signing function is supposed to "raw" sign data, i.e.,
733
 * without any hashing or preprocessing. In case of RSA the DigestInfo
734
 * will be provided, and the signing function is expected to do the PKCS #1
735
 * 1.5 padding and the exponentiation.
736
 *
737
 * See also gnutls_privkey_import_ext3().
738
 *
739
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
740
 *   negative error value.
741
 *
742
 * Since: 3.1
743
 **/
744
int gnutls_privkey_import_ext2(gnutls_privkey_t pkey, gnutls_pk_algorithm_t pk,
745
             void *userdata, gnutls_privkey_sign_func sign_fn,
746
             gnutls_privkey_decrypt_func decrypt_fn,
747
             gnutls_privkey_deinit_func deinit_fn,
748
             unsigned int flags)
749
0
{
750
0
  int ret;
751
752
0
  ret = check_if_clean(pkey);
753
0
  if (ret < 0) {
754
0
    gnutls_assert();
755
0
    return ret;
756
0
  }
757
758
0
  if (!PK_IS_OK_FOR_EXT2(pk))
759
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
760
761
0
  if (sign_fn == NULL && decrypt_fn == NULL)
762
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
763
764
0
  pkey->key.ext.sign_func = sign_fn;
765
0
  pkey->key.ext.decrypt_func = decrypt_fn;
766
0
  pkey->key.ext.deinit_func = deinit_fn;
767
0
  pkey->key.ext.userdata = userdata;
768
0
  pkey->type = GNUTLS_PRIVKEY_EXT;
769
0
  pkey->pk_algorithm = pk;
770
0
  pkey->flags = flags;
771
772
  /* Ensure gnutls_privkey_deinit() calls the deinit_func */
773
0
  if (deinit_fn)
774
0
    pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
775
776
0
  return 0;
777
0
}
778
779
/**
780
 * gnutls_privkey_import_ext3:
781
 * @pkey: The private key
782
 * @userdata: private data to be provided to the callbacks
783
 * @sign_fn: callback for signature operations
784
 * @decrypt_fn: callback for decryption operations
785
 * @deinit_fn: a deinitialization function
786
 * @info_fn: returns info about the public key algorithm (should not be %NULL)
787
 * @flags: Flags for the import
788
 *
789
 * This function will associate the given callbacks with the
790
 * #gnutls_privkey_t type. At least one of the two callbacks
791
 * must be non-null. If a deinitialization function is provided
792
 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
793
 *
794
 * Note that the signing function is supposed to "raw" sign data, i.e.,
795
 * without any hashing or preprocessing. In case of RSA the DigestInfo
796
 * will be provided, and the signing function is expected to do the PKCS #1
797
 * 1.5 padding and the exponentiation.
798
 *
799
 * The @info_fn must provide information on the algorithms supported by
800
 * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO and
801
 * %GNUTLS_PRIVKEY_INFO_SIGN_ALGO. It must return -1 on unknown flags.
802
 *
803
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
804
 *   negative error value.
805
 *
806
 * Since: 3.4.0
807
 **/
808
int gnutls_privkey_import_ext3(gnutls_privkey_t pkey, void *userdata,
809
             gnutls_privkey_sign_func sign_fn,
810
             gnutls_privkey_decrypt_func decrypt_fn,
811
             gnutls_privkey_deinit_func deinit_fn,
812
             gnutls_privkey_info_func info_fn,
813
             unsigned int flags)
814
0
{
815
0
  int ret;
816
817
0
  ret = check_if_clean(pkey);
818
0
  if (ret < 0) {
819
0
    gnutls_assert();
820
0
    return ret;
821
0
  }
822
823
0
  if (sign_fn == NULL && decrypt_fn == NULL)
824
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
825
826
0
  if (info_fn == NULL)
827
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
828
829
0
  pkey->key.ext.sign_func = sign_fn;
830
0
  pkey->key.ext.decrypt_func = decrypt_fn;
831
0
  pkey->key.ext.deinit_func = deinit_fn;
832
0
  pkey->key.ext.info_func = info_fn;
833
0
  pkey->key.ext.userdata = userdata;
834
0
  pkey->type = GNUTLS_PRIVKEY_EXT;
835
0
  pkey->flags = flags;
836
837
0
  pkey->pk_algorithm = pkey->key.ext.info_func(
838
0
    pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
839
840
0
  if (!PK_IS_OK_FOR_EXT2(pkey->pk_algorithm))
841
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
842
843
  /* Ensure gnutls_privkey_deinit() calls the deinit_func */
844
0
  if (deinit_fn)
845
0
    pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
846
847
0
  return 0;
848
0
}
849
850
/**
851
 * gnutls_privkey_import_ext4:
852
 * @pkey: The private key
853
 * @userdata: private data to be provided to the callbacks
854
 * @sign_data_fn: callback for signature operations (may be %NULL)
855
 * @sign_hash_fn: callback for signature operations (may be %NULL)
856
 * @decrypt_fn: callback for decryption operations (may be %NULL)
857
 * @deinit_fn: a deinitialization function
858
 * @info_fn: returns info about the public key algorithm (should not be %NULL)
859
 * @flags: Flags for the import
860
 *
861
 * This function will associate the given callbacks with the
862
 * #gnutls_privkey_t type. At least one of the callbacks
863
 * must be non-null. If a deinitialization function is provided
864
 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
865
 *
866
 * Note that in contrast with the signing function of
867
 * gnutls_privkey_import_ext3(), the signing functions provided to this
868
 * function take explicitly the signature algorithm as parameter and
869
 * different functions are provided to sign the data and hashes.
870
 *
871
 * The @sign_hash_fn is to be called to sign pre-hashed data. The input
872
 * to the callback is the output of the hash (such as SHA256) corresponding
873
 * to the signature algorithm. For RSA PKCS#1 signatures, the signature
874
 * algorithm can be set to %GNUTLS_SIGN_RSA_RAW, and in that case the data
875
 * should be handled as if they were an RSA PKCS#1 DigestInfo structure.
876
 *
877
 * The @sign_data_fn is to be called to sign data. The input data will be
878
 * he data to be signed (and hashed), with the provided signature
879
 * algorithm. This function is to be used for signature algorithms like
880
 * Ed25519 which cannot take pre-hashed data as input.
881
 *
882
 * When both @sign_data_fn and @sign_hash_fn functions are provided they
883
 * must be able to operate on all the supported signature algorithms,
884
 * unless prohibited by the type of the algorithm (e.g., as with Ed25519).
885
 *
886
 * The @info_fn must provide information on the signature algorithms supported by
887
 * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO,
888
 * %GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO and %GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS.
889
 * It must return -1 on unknown flags.
890
 *
891
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
892
 *   negative error value.
893
 *
894
 * Since: 3.6.0
895
 **/
896
int gnutls_privkey_import_ext4(gnutls_privkey_t pkey, void *userdata,
897
             gnutls_privkey_sign_data_func sign_data_fn,
898
             gnutls_privkey_sign_hash_func sign_hash_fn,
899
             gnutls_privkey_decrypt_func decrypt_fn,
900
             gnutls_privkey_deinit_func deinit_fn,
901
             gnutls_privkey_info_func info_fn,
902
             unsigned int flags)
903
0
{
904
0
  int ret;
905
906
0
  ret = check_if_clean(pkey);
907
0
  if (ret < 0) {
908
0
    gnutls_assert();
909
0
    return ret;
910
0
  }
911
912
0
  if (sign_data_fn == NULL && sign_hash_fn == NULL && decrypt_fn == NULL)
913
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
914
915
0
  if (info_fn == NULL)
916
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
917
918
0
  pkey->key.ext.sign_data_func = sign_data_fn;
919
0
  pkey->key.ext.sign_hash_func = sign_hash_fn;
920
0
  pkey->key.ext.decrypt_func = decrypt_fn;
921
0
  pkey->key.ext.deinit_func = deinit_fn;
922
0
  pkey->key.ext.info_func = info_fn;
923
0
  pkey->key.ext.userdata = userdata;
924
0
  pkey->type = GNUTLS_PRIVKEY_EXT;
925
0
  pkey->flags = flags;
926
927
0
  pkey->pk_algorithm = pkey->key.ext.info_func(
928
0
    pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
929
930
0
  ret = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS,
931
0
              pkey->key.ext.userdata);
932
0
  if (ret >= 0)
933
0
    pkey->key.ext.bits = ret;
934
935
  /* Ensure gnutls_privkey_deinit() calls the deinit_func */
936
0
  if (deinit_fn)
937
0
    pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
938
939
0
  return 0;
940
0
}
941
942
/**
943
 * gnutls_privkey_import_x509:
944
 * @pkey: The private key
945
 * @key: The private key to be imported
946
 * @flags: Flags for the import
947
 *
948
 * This function will import the given private key to the abstract
949
 * #gnutls_privkey_t type.
950
 *
951
 * The #gnutls_x509_privkey_t object must not be deallocated
952
 * during the lifetime of this structure.
953
 *
954
 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
955
 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
956
 *
957
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
958
 *   negative error value.
959
 *
960
 * Since: 2.12.0
961
 **/
962
int gnutls_privkey_import_x509(gnutls_privkey_t pkey, gnutls_x509_privkey_t key,
963
             unsigned int flags)
964
0
{
965
0
  int ret;
966
967
0
  ret = check_if_clean(pkey);
968
0
  if (ret < 0) {
969
0
    gnutls_assert();
970
0
    return ret;
971
0
  }
972
973
0
  if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) {
974
0
    ret = gnutls_x509_privkey_init(&pkey->key.x509);
975
0
    if (ret < 0)
976
0
      return gnutls_assert_val(ret);
977
978
0
    ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
979
0
    if (ret < 0) {
980
0
      gnutls_x509_privkey_deinit(pkey->key.x509);
981
0
      return gnutls_assert_val(ret);
982
0
    }
983
0
  } else
984
0
    pkey->key.x509 = key;
985
986
0
  pkey->type = GNUTLS_PRIVKEY_X509;
987
0
  pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm(key);
988
0
  pkey->flags = flags;
989
990
0
  return 0;
991
0
}
992
993
/**
994
 * gnutls_privkey_export_x509:
995
 * @pkey: The private key
996
 * @key: Location for the key to be exported.
997
 *
998
 * Converts the given abstract private key to a #gnutls_x509_privkey_t
999
 * type. The abstract key must be of type %GNUTLS_PRIVKEY_X509. The input
1000
 * @key must not be initialized. The key returned in @key should be deinitialized
1001
 * using gnutls_x509_privkey_deinit().
1002
 *
1003
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1004
 *   negative error value.
1005
 *
1006
 * Since: 3.4.0
1007
 */
1008
int gnutls_privkey_export_x509(gnutls_privkey_t pkey,
1009
             gnutls_x509_privkey_t *key)
1010
0
{
1011
0
  int ret;
1012
1013
0
  *key = NULL;
1014
0
  if (pkey->type != GNUTLS_PRIVKEY_X509) {
1015
0
    gnutls_assert();
1016
0
    return GNUTLS_E_INVALID_REQUEST;
1017
0
  }
1018
1019
0
  ret = gnutls_x509_privkey_init(key);
1020
0
  if (ret < 0)
1021
0
    return gnutls_assert_val(ret);
1022
1023
0
  ret = gnutls_x509_privkey_cpy(*key, pkey->key.x509);
1024
0
  if (ret < 0) {
1025
0
    gnutls_x509_privkey_deinit(*key);
1026
0
    *key = NULL;
1027
1028
0
    return gnutls_assert_val(ret);
1029
0
  }
1030
1031
0
  return 0;
1032
0
}
1033
1034
/**
1035
 * gnutls_privkey_generate:
1036
 * @pkey: An initialized private key
1037
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1038
 * @bits: the size of the parameters to generate
1039
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1040
 *
1041
 * This function will generate a random private key. Note that this
1042
 * function must be called on an initialized private key.
1043
 *
1044
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1045
 * instructs the key generation process to use algorithms like Shawe-Taylor
1046
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1047
 * for RSA and DSA keys. See gnutls_privkey_generate2() for more
1048
 * information.
1049
 *
1050
 * Note that when generating an elliptic curve key, the curve
1051
 * can be substituted in the place of the bits parameter using the
1052
 * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
1053
 * %gnutls_ecc_curve_t.
1054
 *
1055
 * For DSA keys, if the subgroup size needs to be specified check
1056
 * the GNUTLS_SUBGROUP_TO_BITS() macro.
1057
 *
1058
 * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
1059
 *
1060
 * See also gnutls_privkey_generate2().
1061
 *
1062
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1063
 *   negative error value.
1064
 *
1065
 * Since: 3.3.0
1066
 **/
1067
int gnutls_privkey_generate(gnutls_privkey_t pkey, gnutls_pk_algorithm_t algo,
1068
          unsigned int bits, unsigned int flags)
1069
0
{
1070
0
  return gnutls_privkey_generate2(pkey, algo, bits, flags, NULL, 0);
1071
0
}
1072
1073
/**
1074
 * gnutls_privkey_generate2:
1075
 * @pkey: The private key
1076
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1077
 * @bits: the size of the modulus
1078
 * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1079
 * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
1080
 * @data_size: The number of @data available.
1081
 *
1082
 * This function will generate a random private key. Note that this
1083
 * function must be called on an initialized private key.
1084
 *
1085
 * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1086
 * instructs the key generation process to use algorithms like Shawe-Taylor
1087
 * (from FIPS PUB186-4) which generate provable parameters out of a seed
1088
 * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
1089
 * seed, while on RSA the two primes. To specify an explicit seed
1090
 * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
1091
 * type.
1092
 *
1093
 * Note that when generating an elliptic curve key, the curve
1094
 * can be substituted in the place of the bits parameter using the
1095
 * GNUTLS_CURVE_TO_BITS() macro.
1096
 *
1097
 * To export the generated keys in memory or in files it is recommended to use the
1098
 * PKCS#8 form as it can handle all key types, and can store additional parameters
1099
 * such as the seed, in case of provable RSA or DSA keys.
1100
 * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
1101
 * and then with gnutls_x509_privkey_export2_pkcs8().
1102
 *
1103
 * If key generation is part of your application, avoid setting the number
1104
 * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
1105
 * That way the generated keys will adapt to the security levels
1106
 * of the underlying GnuTLS library.
1107
 *
1108
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1109
 *   negative error value.
1110
 *
1111
 * Since: 3.5.0
1112
 **/
1113
int gnutls_privkey_generate2(gnutls_privkey_t pkey, gnutls_pk_algorithm_t algo,
1114
           unsigned int bits, unsigned int flags,
1115
           const gnutls_keygen_data_st *data,
1116
           unsigned data_size)
1117
0
{
1118
0
  int ret;
1119
1120
0
  ret = gnutls_x509_privkey_init(&pkey->key.x509);
1121
0
  if (ret < 0)
1122
0
    return gnutls_assert_val(ret);
1123
1124
0
  ret = gnutls_x509_privkey_generate2(pkey->key.x509, algo, bits, flags,
1125
0
              data, data_size);
1126
0
  if (ret < 0) {
1127
0
    gnutls_x509_privkey_deinit(pkey->key.x509);
1128
0
    pkey->key.x509 = NULL;
1129
0
    return gnutls_assert_val(ret);
1130
0
  }
1131
1132
0
  pkey->type = GNUTLS_PRIVKEY_X509;
1133
0
  pkey->pk_algorithm = algo;
1134
0
  pkey->flags = flags | GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
1135
1136
0
  return 0;
1137
0
}
1138
1139
/**
1140
 * gnutls_privkey_sign_data:
1141
 * @signer: Holds the key
1142
 * @hash: should be a digest algorithm
1143
 * @flags: Zero or one of %gnutls_privkey_flags_t
1144
 * @data: holds the data to be signed
1145
 * @signature: will contain the signature allocated with gnutls_malloc()
1146
 *
1147
 * This function will sign the given data using a signature algorithm
1148
 * supported by the private key. Signature algorithms are always used
1149
 * together with a hash functions.  Different hash functions may be
1150
 * used for the RSA algorithm, but only the SHA family for the DSA keys.
1151
 *
1152
 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
1153
 * the hash algorithm.
1154
 *
1155
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1156
 * negative error value.
1157
 *
1158
 * Since: 2.12.0
1159
 **/
1160
int gnutls_privkey_sign_data(gnutls_privkey_t signer,
1161
           gnutls_digest_algorithm_t hash, unsigned int flags,
1162
           const gnutls_datum_t *data,
1163
           gnutls_datum_t *signature)
1164
0
{
1165
0
  int ret;
1166
0
  gnutls_x509_spki_st params;
1167
1168
0
  if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1169
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1170
1171
0
  ret = _gnutls_privkey_get_spki_params(signer, &params);
1172
0
  if (ret < 0) {
1173
0
    gnutls_assert();
1174
0
    return ret;
1175
0
  }
1176
1177
0
  ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
1178
0
             hash, flags, &params);
1179
0
  if (ret < 0) {
1180
0
    gnutls_assert();
1181
0
    return ret;
1182
0
  }
1183
1184
0
  FIX_SIGN_PARAMS(params, flags, hash);
1185
1186
0
  return privkey_sign_and_hash_data(
1187
0
    signer, _gnutls_pk_to_sign_entry(params.pk, hash), data,
1188
0
    signature, &params);
1189
0
}
1190
1191
/**
1192
 * gnutls_privkey_sign_data2:
1193
 * @signer: Holds the key
1194
 * @algo: The signature algorithm used
1195
 * @flags: Zero or one of %gnutls_privkey_flags_t
1196
 * @data: holds the data to be signed
1197
 * @signature: will contain the signature allocated with gnutls_malloc()
1198
 *
1199
 * This function will sign the given data using the specified signature
1200
 * algorithm. This function is an enhancement of gnutls_privkey_sign_data(),
1201
 * as it allows utilizing a alternative signature algorithm where possible
1202
 * (e.g, use an RSA key with RSA-PSS).
1203
 *
1204
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1205
 * negative error value.
1206
 *
1207
 * Since: 3.6.0
1208
 **/
1209
int gnutls_privkey_sign_data2(gnutls_privkey_t signer,
1210
            gnutls_sign_algorithm_t algo, unsigned int flags,
1211
            const gnutls_datum_t *data,
1212
            gnutls_datum_t *signature)
1213
0
{
1214
0
  int ret;
1215
0
  gnutls_x509_spki_st params;
1216
0
  const gnutls_sign_entry_st *se;
1217
1218
0
  if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1219
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1220
1221
0
  se = _gnutls_sign_to_entry(algo);
1222
0
  if (se == NULL)
1223
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1224
1225
0
  ret = _gnutls_privkey_get_spki_params(signer, &params);
1226
0
  if (ret < 0) {
1227
0
    gnutls_assert();
1228
0
    return ret;
1229
0
  }
1230
1231
0
  ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
1232
0
             flags, &params);
1233
0
  if (ret < 0) {
1234
0
    gnutls_assert();
1235
0
    return ret;
1236
0
  }
1237
1238
0
  FIX_SIGN_PARAMS(params, flags, se->hash);
1239
1240
0
  return privkey_sign_and_hash_data(signer, se, data, signature, &params);
1241
0
}
1242
1243
/**
1244
 * gnutls_privkey_sign_hash2:
1245
 * @signer: Holds the signer's key
1246
 * @algo: The signature algorithm used
1247
 * @flags: Zero or one of %gnutls_privkey_flags_t
1248
 * @hash_data: holds the data to be signed
1249
 * @signature: will contain newly allocated signature
1250
 *
1251
 * This function will sign the given hashed data using the specified signature
1252
 * algorithm. This function is an enhancement of gnutls_privkey_sign_hash(),
1253
 * as it allows utilizing a alternative signature algorithm where possible
1254
 * (e.g, use an RSA key with RSA-PSS).
1255
 *
1256
 * The flags may be %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA.
1257
 * In that case this function will ignore @hash_algo and perform a raw PKCS1 signature.
1258
 * Note that this flag is supported since 3.6.9.
1259
 *
1260
 * Note also that, not all algorithm support signing already hashed data. When
1261
 * signing with Ed25519, gnutls_privkey_sign_data2() should be used instead.
1262
 *
1263
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1264
 *   negative error value.
1265
 *
1266
 * Since: 3.6.0
1267
 **/
1268
int gnutls_privkey_sign_hash2(gnutls_privkey_t signer,
1269
            gnutls_sign_algorithm_t algo, unsigned int flags,
1270
            const gnutls_datum_t *hash_data,
1271
            gnutls_datum_t *signature)
1272
0
{
1273
0
  int ret;
1274
0
  gnutls_x509_spki_st params;
1275
0
  const gnutls_sign_entry_st *se;
1276
1277
0
  if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) {
1278
    /* the corresponding signature algorithm is SIGN_RSA_RAW,
1279
     * irrespective of hash algorithm. */
1280
0
    se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1281
0
  } else {
1282
0
    se = _gnutls_sign_to_entry(algo);
1283
0
    if (unlikely(se == NULL)) {
1284
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1285
0
      goto cleanup;
1286
0
    }
1287
0
  }
1288
1289
0
  ret = _gnutls_privkey_get_spki_params(signer, &params);
1290
0
  if (ret < 0) {
1291
0
    gnutls_assert();
1292
0
    goto cleanup;
1293
0
  }
1294
1295
0
  ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
1296
0
             flags, &params);
1297
0
  if (ret < 0) {
1298
0
    gnutls_assert();
1299
0
    goto cleanup;
1300
0
  }
1301
1302
0
  FIX_SIGN_PARAMS(params, flags, se->hash);
1303
1304
0
  ret = privkey_sign_prehashed(signer, se, hash_data, signature, &params);
1305
1306
0
cleanup:
1307
0
  if (ret < 0) {
1308
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
1309
0
  } else {
1310
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
1311
0
  }
1312
0
  return ret;
1313
0
}
1314
1315
int privkey_sign_and_hash_data(gnutls_privkey_t signer,
1316
             const gnutls_sign_entry_st *se,
1317
             const gnutls_datum_t *data,
1318
             gnutls_datum_t *signature,
1319
             gnutls_x509_spki_st *params)
1320
0
{
1321
0
  int ret;
1322
0
  gnutls_datum_t digest;
1323
0
  const mac_entry_st *me;
1324
1325
0
  if (unlikely(se == NULL))
1326
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1327
1328
0
  if (_gnutls_pk_is_not_prehashed(se->pk)) {
1329
0
    return privkey_sign_raw_data(signer, se, data, signature,
1330
0
               params);
1331
0
  }
1332
1333
0
  me = hash_to_entry(se->hash);
1334
0
  if (me == NULL)
1335
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1336
1337
0
  ret = pk_hash_data(se->pk, me, NULL, data, &digest);
1338
0
  if (ret < 0) {
1339
0
    gnutls_assert();
1340
0
    return ret;
1341
0
  }
1342
1343
0
  ret = pk_prepare_hash(se->pk, me, &digest);
1344
0
  if (ret < 0) {
1345
0
    gnutls_assert();
1346
0
    goto cleanup;
1347
0
  }
1348
1349
0
  ret = privkey_sign_raw_data(signer, se, &digest, signature, params);
1350
0
  _gnutls_free_datum(&digest);
1351
1352
0
  if (ret < 0) {
1353
0
    gnutls_assert();
1354
0
    return ret;
1355
0
  }
1356
1357
0
  return 0;
1358
1359
0
cleanup:
1360
0
  _gnutls_free_datum(&digest);
1361
0
  return ret;
1362
0
}
1363
1364
/**
1365
 * gnutls_privkey_sign_hash:
1366
 * @signer: Holds the signer's key
1367
 * @hash_algo: The hash algorithm used
1368
 * @flags: Zero or one of %gnutls_privkey_flags_t
1369
 * @hash_data: holds the data to be signed
1370
 * @signature: will contain newly allocated signature
1371
 *
1372
 * This function will sign the given hashed data using a signature algorithm
1373
 * supported by the private key. Signature algorithms are always used
1374
 * together with a hash functions.  Different hash functions may be
1375
 * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
1376
 *
1377
 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
1378
 * the hash algorithm.
1379
 *
1380
 * The flags may be %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA or %GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS.
1381
 * In the former case this function will ignore @hash_algo and perform a raw PKCS1 signature,
1382
 * and in the latter an RSA-PSS signature will be generated.
1383
 *
1384
 * Note that, not all algorithm support signing already hashed data. When
1385
 * signing with Ed25519, gnutls_privkey_sign_data() should be used.
1386
 *
1387
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1388
 *   negative error value.
1389
 *
1390
 * Since: 2.12.0
1391
 **/
1392
int gnutls_privkey_sign_hash(gnutls_privkey_t signer,
1393
           gnutls_digest_algorithm_t hash_algo,
1394
           unsigned int flags,
1395
           const gnutls_datum_t *hash_data,
1396
           gnutls_datum_t *signature)
1397
0
{
1398
0
  int ret;
1399
0
  gnutls_x509_spki_st params;
1400
0
  const gnutls_sign_entry_st *se;
1401
1402
0
  ret = _gnutls_privkey_get_spki_params(signer, &params);
1403
0
  if (ret < 0) {
1404
0
    gnutls_assert();
1405
0
    goto cleanup;
1406
0
  }
1407
1408
0
  ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
1409
0
             hash_algo, flags, &params);
1410
0
  if (ret < 0) {
1411
0
    gnutls_assert();
1412
0
    goto cleanup;
1413
0
  }
1414
1415
  /* legacy callers of this API could use a hash algorithm of 0 (unknown)
1416
   * to indicate raw hashing. As we now always want to know the signing
1417
   * algorithm involved, we try discovering the hash algorithm. */
1418
0
  if (hash_algo == 0 &&
1419
0
      (params.pk == GNUTLS_PK_DSA || params.pk == GNUTLS_PK_ECDSA)) {
1420
0
    hash_algo = _gnutls_hash_size_to_sha_hash(hash_data->size);
1421
0
  }
1422
1423
0
  if (params.pk == GNUTLS_PK_RSA &&
1424
0
      (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)) {
1425
    /* the corresponding signature algorithm is SIGN_RSA_RAW,
1426
     * irrespective of hash algorithm. */
1427
0
    se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1428
0
  } else {
1429
0
    se = _gnutls_pk_to_sign_entry(params.pk, hash_algo);
1430
0
  }
1431
1432
0
  if (unlikely(se == NULL)) {
1433
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1434
0
    goto cleanup;
1435
0
  }
1436
1437
0
  FIX_SIGN_PARAMS(params, flags, hash_algo);
1438
1439
0
  ret = privkey_sign_prehashed(signer, se, hash_data, signature, &params);
1440
0
cleanup:
1441
0
  if (ret < 0) {
1442
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
1443
0
  } else {
1444
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
1445
0
  }
1446
0
  return ret;
1447
0
}
1448
1449
static int privkey_sign_prehashed(gnutls_privkey_t signer,
1450
          const gnutls_sign_entry_st *se,
1451
          const gnutls_datum_t *hash_data,
1452
          gnutls_datum_t *signature,
1453
          gnutls_x509_spki_st *params)
1454
0
{
1455
0
  int ret;
1456
0
  gnutls_datum_t digest;
1457
1458
0
  if (unlikely(se == NULL))
1459
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1460
1461
0
  if (se->id == GNUTLS_SIGN_RSA_RAW) {
1462
0
    return privkey_sign_raw_data(signer, se, hash_data, signature,
1463
0
               params);
1464
0
  }
1465
1466
0
  if (_gnutls_pk_is_not_prehashed(signer->pk_algorithm)) {
1467
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1468
0
  }
1469
1470
0
  digest.data = gnutls_malloc(hash_data->size);
1471
0
  if (digest.data == NULL) {
1472
0
    gnutls_assert();
1473
0
    return GNUTLS_E_MEMORY_ERROR;
1474
0
  }
1475
0
  digest.size = hash_data->size;
1476
0
  memcpy(digest.data, hash_data->data, digest.size);
1477
1478
0
  ret = pk_prepare_hash(se->pk, hash_to_entry(se->hash), &digest);
1479
0
  if (ret < 0) {
1480
0
    gnutls_assert();
1481
0
    goto cleanup;
1482
0
  }
1483
1484
0
  ret = privkey_sign_raw_data(signer, se, &digest, signature, params);
1485
0
  if (ret < 0) {
1486
0
    gnutls_assert();
1487
0
    goto cleanup;
1488
0
  }
1489
1490
0
  ret = 0;
1491
1492
0
cleanup:
1493
0
  _gnutls_free_datum(&digest);
1494
0
  return ret;
1495
0
}
1496
1497
/*-
1498
 * privkey_sign_raw_data:
1499
 * @key: Holds the key
1500
 * @data: holds the data to be signed
1501
 * @signature: will contain the signature allocated with gnutls_malloc()
1502
 * @params: holds the signing parameters
1503
 *
1504
 * This function will sign the given data using a signature algorithm
1505
 * supported by the private key. Note that this is a low-level function
1506
 * and does not apply any preprocessing or hash on the signed data. 
1507
 * For example on an RSA key the input @data should be of the DigestInfo
1508
 * PKCS #1 1.5 format, on RSA-PSS, DSA or ECDSA the input should be a hash output
1509
 * and on Ed25519 the raw data to be signed.
1510
 *
1511
 * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
1512
 * flag with gnutls_privkey_sign_hash().
1513
 *
1514
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1515
 * negative error value.
1516
 *
1517
 * Since: 3.1.10
1518
 -*/
1519
int privkey_sign_raw_data(gnutls_privkey_t key, const gnutls_sign_entry_st *se,
1520
        const gnutls_datum_t *data, gnutls_datum_t *signature,
1521
        gnutls_x509_spki_st *params)
1522
0
{
1523
0
  if (unlikely(se == NULL))
1524
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1525
1526
0
  switch (key->type) {
1527
#ifdef ENABLE_PKCS11
1528
  case GNUTLS_PRIVKEY_PKCS11:
1529
    return _gnutls_pkcs11_privkey_sign(key->key.pkcs11, se, data,
1530
               signature, params);
1531
#endif
1532
0
  case GNUTLS_PRIVKEY_X509:
1533
0
    return _gnutls_pk_sign(se->pk, signature, data,
1534
0
               &key->key.x509->params, params);
1535
0
  case GNUTLS_PRIVKEY_EXT:
1536
0
    if (unlikely(key->key.ext.sign_data_func == NULL &&
1537
0
           key->key.ext.sign_hash_func == NULL &&
1538
0
           key->key.ext.sign_func == NULL))
1539
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1540
1541
0
    if (_gnutls_pk_is_not_prehashed(se->pk)) {
1542
0
      if (!key->key.ext.sign_data_func)
1543
0
        return gnutls_assert_val(
1544
0
          GNUTLS_E_INVALID_REQUEST);
1545
1546
0
      return key->key.ext.sign_data_func(
1547
0
        key, se->id, key->key.ext.userdata, 0, data,
1548
0
        signature);
1549
0
    } else if (key->key.ext.sign_hash_func) {
1550
0
      if (se->pk == GNUTLS_PK_RSA) {
1551
0
        se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1552
0
        assert(se != NULL);
1553
0
      }
1554
1555
      /* se may not be set here if we are doing legacy RSA */
1556
0
      return key->key.ext.sign_hash_func(
1557
0
        key, se->id, key->key.ext.userdata, 0, data,
1558
0
        signature);
1559
0
    } else {
1560
0
      if (!PK_IS_OK_FOR_EXT2(se->pk))
1561
0
        return gnutls_assert_val(
1562
0
          GNUTLS_E_INVALID_REQUEST);
1563
1564
0
      return key->key.ext.sign_func(
1565
0
        key, key->key.ext.userdata, data, signature);
1566
0
    }
1567
0
  default:
1568
0
    gnutls_assert();
1569
0
    return GNUTLS_E_INVALID_REQUEST;
1570
0
  }
1571
0
}
1572
1573
/**
1574
 * gnutls_privkey_decrypt_data:
1575
 * @key: Holds the key
1576
 * @flags: zero for now
1577
 * @ciphertext: holds the data to be decrypted
1578
 * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
1579
 *
1580
 * This function will decrypt the given data using the algorithm
1581
 * supported by the private key.
1582
 *
1583
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1584
 * negative error value.
1585
 *
1586
 * Since: 2.12.0
1587
 **/
1588
int gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags,
1589
        const gnutls_datum_t *ciphertext,
1590
        gnutls_datum_t *plaintext)
1591
0
{
1592
0
  switch (key->type) {
1593
0
  case GNUTLS_PRIVKEY_X509:
1594
0
    return _gnutls_pk_decrypt(key->pk_algorithm, plaintext,
1595
0
            ciphertext, &key->key.x509->params,
1596
0
            &key->key.x509->params.spki);
1597
#ifdef ENABLE_PKCS11
1598
  case GNUTLS_PRIVKEY_PKCS11:
1599
    return _gnutls_pkcs11_privkey_decrypt_data(
1600
      key->key.pkcs11, flags, ciphertext, plaintext);
1601
#endif
1602
0
  case GNUTLS_PRIVKEY_EXT:
1603
0
    if (key->key.ext.decrypt_func == NULL)
1604
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1605
1606
0
    return key->key.ext.decrypt_func(key, key->key.ext.userdata,
1607
0
             ciphertext, plaintext);
1608
0
  default:
1609
0
    gnutls_assert();
1610
0
    return GNUTLS_E_INVALID_REQUEST;
1611
0
  }
1612
0
}
1613
1614
/**
1615
 * gnutls_privkey_decrypt_data2:
1616
 * @key: Holds the key
1617
 * @flags: zero for now
1618
 * @ciphertext: holds the data to be decrypted
1619
 * @plaintext: a preallocated buffer that will be filled with the plaintext
1620
 * @plaintext_size: in/out size of the plaintext
1621
 *
1622
 * This function will decrypt the given data using the algorithm
1623
 * supported by the private key. Unlike with gnutls_privkey_decrypt_data()
1624
 * this function operates in constant time and constant memory access.
1625
 *
1626
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1627
 * negative error value.
1628
 *
1629
 * Since: 3.6.5
1630
 **/
1631
1632
int gnutls_privkey_decrypt_data2(gnutls_privkey_t key, unsigned int flags,
1633
         const gnutls_datum_t *ciphertext,
1634
         unsigned char *plaintext,
1635
         size_t plaintext_size)
1636
0
{
1637
  /* Note: except for the backwards compatibility function, no
1638
   * conditional code should be called after the decryption
1639
   * function call, to avoid creating oracle attacks based
1640
   * on cache/timing side channels */
1641
1642
  /* backwards compatibility */
1643
0
  if (key->type == GNUTLS_PRIVKEY_EXT &&
1644
0
      key->key.ext.decrypt_func2 == NULL &&
1645
0
      key->key.ext.decrypt_func != NULL) {
1646
0
    gnutls_datum_t plain;
1647
0
    int ret;
1648
0
    ret = key->key.ext.decrypt_func(key, key->key.ext.userdata,
1649
0
            ciphertext, &plain);
1650
0
    if (plain.size != plaintext_size) {
1651
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1652
0
    } else {
1653
0
      memcpy(plaintext, plain.data, plain.size);
1654
0
    }
1655
0
    gnutls_free(plain.data);
1656
0
    return ret;
1657
0
  }
1658
1659
0
  switch (key->type) {
1660
0
  case GNUTLS_PRIVKEY_X509:
1661
0
    return _gnutls_pk_decrypt2(key->pk_algorithm, ciphertext,
1662
0
             plaintext, plaintext_size,
1663
0
             &key->key.x509->params,
1664
0
             &key->key.x509->params.spki);
1665
#ifdef ENABLE_PKCS11
1666
  case GNUTLS_PRIVKEY_PKCS11:
1667
    return _gnutls_pkcs11_privkey_decrypt_data2(key->key.pkcs11,
1668
                  flags, ciphertext,
1669
                  plaintext,
1670
                  plaintext_size);
1671
#endif
1672
0
  case GNUTLS_PRIVKEY_EXT:
1673
0
    if (key->key.ext.decrypt_func2 == NULL)
1674
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1675
1676
0
    return key->key.ext.decrypt_func2(key, key->key.ext.userdata,
1677
0
              ciphertext, plaintext,
1678
0
              plaintext_size);
1679
0
  default:
1680
0
    gnutls_assert();
1681
0
    return GNUTLS_E_INVALID_REQUEST;
1682
0
  }
1683
0
}
1684
1685
/**
1686
 * gnutls_privkey_import_x509_raw:
1687
 * @pkey: The private key
1688
 * @data: The private key data to be imported
1689
 * @format: The format of the private key
1690
 * @password: A password (optional)
1691
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
1692
 *
1693
 * This function will import the given private key to the abstract
1694
 * #gnutls_privkey_t type. 
1695
 *
1696
 * The supported formats are basic unencrypted key, PKCS8, PKCS12, 
1697
 * TSS2, and the openssl format.
1698
 *
1699
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1700
 *   negative error value.
1701
 *
1702
 * Since: 3.1.0
1703
 **/
1704
int gnutls_privkey_import_x509_raw(gnutls_privkey_t pkey,
1705
           const gnutls_datum_t *data,
1706
           gnutls_x509_crt_fmt_t format,
1707
           const char *password, unsigned int flags)
1708
0
{
1709
0
  gnutls_x509_privkey_t xpriv;
1710
0
  int ret;
1711
1712
#ifdef HAVE_TSS2
1713
  if (format == GNUTLS_X509_FMT_PEM &&
1714
      memmem(data->data, data->size, "--BEGIN TSS2", 12) != NULL) {
1715
    ret = _gnutls_load_tpm2_key(pkey, data);
1716
    if (ret < 0)
1717
      return gnutls_assert_val(ret);
1718
1719
    return 0;
1720
  }
1721
#endif
1722
1723
0
  ret = gnutls_x509_privkey_init(&xpriv);
1724
0
  if (ret < 0)
1725
0
    return gnutls_assert_val(ret);
1726
1727
0
  if (pkey->pin.cb) {
1728
0
    gnutls_x509_privkey_set_pin_function(xpriv, pkey->pin.cb,
1729
0
                 pkey->pin.data);
1730
0
  }
1731
1732
0
  ret = gnutls_x509_privkey_import2(xpriv, data, format, password, flags);
1733
0
  if (ret < 0) {
1734
0
    gnutls_assert();
1735
0
    goto cleanup;
1736
0
  }
1737
1738
0
  ret = gnutls_privkey_import_x509(pkey, xpriv,
1739
0
           GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1740
0
  if (ret < 0) {
1741
0
    gnutls_assert();
1742
0
    goto cleanup;
1743
0
  }
1744
1745
0
  return 0;
1746
1747
0
cleanup:
1748
0
  gnutls_x509_privkey_deinit(xpriv);
1749
1750
0
  return ret;
1751
0
}
1752
1753
/**
1754
 * gnutls_privkey_import_url:
1755
 * @key: A key of type #gnutls_privkey_t
1756
 * @url: A PKCS 11 url
1757
 * @flags: should be zero
1758
 *
1759
 * This function will import a PKCS11 or TPM URL as a
1760
 * private key. The supported URL types can be checked
1761
 * using gnutls_url_is_supported().
1762
 *
1763
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1764
 *   negative error value.
1765
 *
1766
 * Since: 3.1.0
1767
 **/
1768
int gnutls_privkey_import_url(gnutls_privkey_t key, const char *url,
1769
            unsigned int flags)
1770
0
{
1771
0
  unsigned i;
1772
0
  int ret;
1773
1774
0
  for (i = 0; i < _gnutls_custom_urls_size; i++) {
1775
0
    if (strncmp(url, _gnutls_custom_urls[i].name,
1776
0
          _gnutls_custom_urls[i].name_size) == 0) {
1777
0
      if (_gnutls_custom_urls[i].import_key) {
1778
0
        ret = _gnutls_custom_urls[i].import_key(
1779
0
          key, url, flags);
1780
0
        goto cleanup;
1781
0
      }
1782
0
      break;
1783
0
    }
1784
0
  }
1785
1786
0
  if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
1787
#ifdef ENABLE_PKCS11
1788
    ret = _gnutls_privkey_import_pkcs11_url(key, url, flags);
1789
#else
1790
0
    ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1791
0
#endif
1792
0
    goto cleanup;
1793
0
  }
1794
1795
0
  if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0) {
1796
#ifdef HAVE_TROUSERS
1797
    ret = gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
1798
#else
1799
0
    ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1800
0
#endif
1801
0
    goto cleanup;
1802
0
  }
1803
1804
0
  if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
1805
0
    ret = _gnutls_privkey_import_system_url(key, url);
1806
0
    goto cleanup;
1807
0
  }
1808
1809
0
  ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1810
0
cleanup:
1811
0
  return ret;
1812
0
}
1813
1814
/**
1815
 * gnutls_privkey_set_pin_function:
1816
 * @key: A key of type #gnutls_privkey_t
1817
 * @fn: the callback
1818
 * @userdata: data associated with the callback
1819
 *
1820
 * This function will set a callback function to be used when
1821
 * required to access the object. This function overrides any other
1822
 * global PIN functions.
1823
 *
1824
 * Note that this function must be called right after initialization
1825
 * to have effect.
1826
 *
1827
 * Since: 3.1.0
1828
 *
1829
 **/
1830
void gnutls_privkey_set_pin_function(gnutls_privkey_t key,
1831
             gnutls_pin_callback_t fn, void *userdata)
1832
0
{
1833
0
  key->pin.cb = fn;
1834
0
  key->pin.data = userdata;
1835
0
}
1836
1837
/**
1838
 * gnutls_privkey_set_flags:
1839
 * @key: A key of type #gnutls_privkey_t
1840
 * @flags: flags from the %gnutls_privkey_flags
1841
 *
1842
 * This function will set flags for the specified private key, after
1843
 * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
1844
 * to allow exporting a "provable" private key in backwards compatible way.
1845
 *
1846
 * Since: 3.5.0
1847
 *
1848
 **/
1849
void gnutls_privkey_set_flags(gnutls_privkey_t key, unsigned int flags)
1850
0
{
1851
0
  key->flags |= flags;
1852
0
  if (key->type == GNUTLS_PRIVKEY_X509)
1853
0
    gnutls_x509_privkey_set_flags(key->key.x509, flags);
1854
0
}
1855
1856
/**
1857
 * gnutls_privkey_status:
1858
 * @key: Holds the key
1859
 *
1860
 * Checks the status of the private key token. This function
1861
 * is an actual wrapper over gnutls_pkcs11_privkey_status(), and
1862
 * if the private key is a PKCS #11 token it will check whether
1863
 * it is inserted or not.
1864
 *
1865
 * Returns: this function will return non-zero if the token 
1866
 * holding the private key is still available (inserted), and zero otherwise.
1867
 * 
1868
 * Since: 3.1.10
1869
 *
1870
 **/
1871
int gnutls_privkey_status(gnutls_privkey_t key)
1872
0
{
1873
0
  switch (key->type) {
1874
#ifdef ENABLE_PKCS11
1875
  case GNUTLS_PRIVKEY_PKCS11:
1876
    return gnutls_pkcs11_privkey_status(key->key.pkcs11);
1877
#endif
1878
0
  default:
1879
0
    return 1;
1880
0
  }
1881
0
}
1882
1883
/**
1884
 * gnutls_privkey_verify_params:
1885
 * @key: should contain a #gnutls_privkey_t type
1886
 *
1887
 * This function will verify the private key parameters.
1888
 *
1889
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1890
 *   negative error value.
1891
 *
1892
 * Since: 3.3.0
1893
 **/
1894
int gnutls_privkey_verify_params(gnutls_privkey_t key)
1895
0
{
1896
0
  gnutls_pk_params_st params;
1897
0
  int ret;
1898
1899
0
  gnutls_pk_params_init(&params);
1900
1901
0
  ret = _gnutls_privkey_get_mpis(key, &params);
1902
0
  if (ret < 0)
1903
0
    return gnutls_assert_val(ret);
1904
1905
0
  ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, &params);
1906
1907
0
  gnutls_pk_params_release(&params);
1908
1909
0
  if (ret < 0) {
1910
0
    gnutls_assert();
1911
0
    return ret;
1912
0
  }
1913
1914
0
  return 0;
1915
0
}
1916
1917
/**
1918
 * gnutls_privkey_get_spki:
1919
 * @privkey: a public key of type #gnutls_privkey_t
1920
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
1921
 * @flags: must be zero
1922
 *
1923
 * This function will return the public key information if available.
1924
 * The provided @spki must be initialized.
1925
 *
1926
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1927
 *   negative error value.
1928
 *
1929
 * Since: 3.6.0
1930
 **/
1931
int gnutls_privkey_get_spki(gnutls_privkey_t privkey, gnutls_x509_spki_t spki,
1932
          unsigned int flags)
1933
0
{
1934
0
  gnutls_x509_spki_t p;
1935
1936
0
  if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
1937
0
    gnutls_assert();
1938
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1939
0
  }
1940
1941
0
  p = &privkey->key.x509->params.spki;
1942
0
  if (p->pk == GNUTLS_PK_UNKNOWN)
1943
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1944
1945
0
  return _gnutls_x509_spki_copy(spki, p);
1946
0
}
1947
1948
/**
1949
 * gnutls_privkey_set_spki:
1950
 * @privkey: a public key of type #gnutls_privkey_t
1951
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
1952
 * @flags: must be zero
1953
 *
1954
 * This function will set the public key information.
1955
 * The provided @spki must be initialized.
1956
 *
1957
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1958
 *   negative error value.
1959
 *
1960
 * Since: 3.6.0
1961
 **/
1962
int gnutls_privkey_set_spki(gnutls_privkey_t privkey,
1963
          const gnutls_x509_spki_t spki, unsigned int flags)
1964
0
{
1965
0
  if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
1966
0
    gnutls_assert();
1967
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1968
0
  }
1969
1970
0
  return gnutls_x509_privkey_set_spki(privkey->key.x509, spki, flags);
1971
0
}
1972
1973
/* Checks whether the public key given is compatible with the
1974
 * signature algorithm used. The session is only used for audit logging, and
1975
 * it may be null.
1976
 */
1977
unsigned _gnutls_privkey_compatible_with_sig(gnutls_privkey_t privkey,
1978
               gnutls_sign_algorithm_t sign)
1979
0
{
1980
0
  const gnutls_sign_entry_st *se;
1981
1982
0
  if (unlikely(privkey == NULL))
1983
0
    return gnutls_assert_val(0);
1984
1985
0
  se = _gnutls_sign_to_entry(sign);
1986
0
  if (unlikely(se == NULL))
1987
0
    return gnutls_assert_val(0);
1988
1989
  /* Prevent RSA-PSS private keys from negotiating an RSA signature,
1990
   * and RSA keys which cannot do RSA-PSS (e.g., smart card) from
1991
   * negotiating RSA-PSS sig.
1992
   */
1993
1994
0
  if (se->pk !=
1995
0
      privkey->pk_algorithm) { /* if the PK algorithm of the signature differs to the one on the pubkey */
1996
0
    if (!sign_supports_priv_pk_algorithm(se,
1997
0
                 privkey->pk_algorithm)) {
1998
0
      _gnutls_handshake_log(
1999
0
        "cannot use privkey of %s with %s\n",
2000
0
        gnutls_pk_get_name(privkey->pk_algorithm),
2001
0
        se->name);
2002
0
      return 0;
2003
0
    }
2004
0
  }
2005
2006
0
  if (privkey->type == GNUTLS_PRIVKEY_EXT) {
2007
0
    if (privkey->key.ext.info_func) {
2008
0
      int ret;
2009
2010
0
      ret = privkey->key.ext.info_func(
2011
0
        privkey,
2012
0
        GNUTLS_SIGN_ALGO_TO_FLAGS(sign) |
2013
0
          GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO,
2014
0
        privkey->key.ext.userdata);
2015
0
      if (ret != -1)
2016
0
        return ret;
2017
2018
      /* use the old flag */
2019
0
      ret = privkey->key.ext.info_func(
2020
0
        privkey, GNUTLS_PRIVKEY_INFO_SIGN_ALGO,
2021
0
        privkey->key.ext.userdata);
2022
0
      if (ret == (int)sign)
2023
0
        return 1;
2024
0
    }
2025
2026
    /* This key type is very limited on what it can handle */
2027
0
    if (!PK_IS_OK_FOR_EXT2(se->pk))
2028
0
      return gnutls_assert_val(0);
2029
0
  }
2030
#ifdef ENABLE_PKCS11
2031
  else if (privkey->type == GNUTLS_PRIVKEY_PKCS11) {
2032
    if (privkey->pk_algorithm == GNUTLS_PK_RSA &&
2033
        se->pk == GNUTLS_PK_RSA_PSS) {
2034
      if (!privkey->key.pkcs11->rsa_pss_ok)
2035
        return 0;
2036
    }
2037
  }
2038
#endif
2039
2040
0
  return 1;
2041
0
}
2042
2043
/**
2044
 * gnutls_privkey_derive_secret:
2045
 * @privkey: a private key of type #gnutls_privkey_t
2046
 * @pubkey: a public key of type #gnutls_pubkey_t
2047
 * @nonce: an optional nonce value
2048
 * @secret: where shared secret will be stored
2049
 * @flags: must be zero
2050
 *
2051
 * This function will calculate a shared secret from our @privkey and
2052
 * peer's @pubkey. The result will be stored in @secret, whose data
2053
 * member should be freed after use using gnutls_free(). @privkey and
2054
 * @pubkey must be backed by the X.509 keys.
2055
 *
2056
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2057
 *   negative error value.
2058
 *
2059
 * Since: 3.8.2
2060
 **/
2061
int gnutls_privkey_derive_secret(gnutls_privkey_t privkey,
2062
         gnutls_pubkey_t pubkey,
2063
         const gnutls_datum_t *nonce,
2064
         gnutls_datum_t *secret, unsigned int flags)
2065
0
{
2066
0
  if (unlikely(privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509)) {
2067
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2068
0
  }
2069
2070
0
  if (unlikely(pubkey == NULL ||
2071
0
         pubkey->params.algo != privkey->pk_algorithm)) {
2072
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2073
0
  }
2074
2075
0
  return _gnutls_pk_derive_nonce(privkey->pk_algorithm, secret,
2076
0
               &privkey->key.x509->params,
2077
0
               &pubkey->params, nonce);
2078
0
}