Coverage Report

Created: 2023-03-26 08:33

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