Coverage Report

Created: 2024-07-23 07:36

/src/gnutls/lib/pubkey.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * GnuTLS public key support
3
 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4
 * Copyright (C) 2017 Red Hat, Inc.
5
 * 
6
 * Author: Nikos Mavrogiannopoulos
7
 *
8
 * The GnuTLS is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 */
21
22
#include "gnutls_int.h"
23
#include <gnutls/pkcs11.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include "errors.h"
27
#include "datum.h"
28
#include "pkcs11_int.h"
29
#include <gnutls/abstract.h>
30
#include "tls-sig.h"
31
#include "pk.h"
32
#include "x509_int.h"
33
#include "num.h"
34
#include "x509/common.h"
35
#include "x509_b64.h"
36
#include "abstract_int.h"
37
#include "fips.h"
38
#include "urls.h"
39
#include "ecc.h"
40
41
static int pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
42
             const mac_entry_st *me,
43
             const gnutls_datum_t *hash,
44
             const gnutls_datum_t *signature,
45
             gnutls_pk_params_st *params,
46
             gnutls_x509_spki_st *sign_params,
47
             unsigned flags);
48
49
static int pubkey_supports_sig(gnutls_pubkey_t pubkey,
50
             const gnutls_sign_entry_st *se);
51
52
unsigned pubkey_to_bits(const gnutls_pk_params_st *params)
53
0
{
54
0
  switch (params->algo) {
55
0
  case GNUTLS_PK_RSA:
56
0
  case GNUTLS_PK_RSA_PSS:
57
0
  case GNUTLS_PK_RSA_OAEP:
58
0
    return _gnutls_mpi_get_nbits(params->params[RSA_MODULUS]);
59
0
  case GNUTLS_PK_DSA:
60
0
    return _gnutls_mpi_get_nbits(params->params[DSA_P]);
61
0
  case GNUTLS_PK_ECDSA:
62
0
  case GNUTLS_PK_EDDSA_ED25519:
63
0
  case GNUTLS_PK_EDDSA_ED448:
64
0
  case GNUTLS_PK_ECDH_X25519:
65
0
  case GNUTLS_PK_ECDH_X448:
66
0
  case GNUTLS_PK_GOST_01:
67
0
  case GNUTLS_PK_GOST_12_256:
68
0
  case GNUTLS_PK_GOST_12_512:
69
0
    return gnutls_ecc_curve_get_size(params->curve) * 8;
70
0
  default:
71
0
    return 0;
72
0
  }
73
0
}
74
75
/**
76
 * gnutls_pubkey_get_pk_algorithm:
77
 * @key: should contain a #gnutls_pubkey_t type
78
 * @bits: If set will return the number of bits of the parameters (may be NULL)
79
 *
80
 * This function will return the public key algorithm of a public
81
 * key and if possible will return a number of bits that indicates
82
 * the security parameter of the key.
83
 *
84
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
85
 *   success, or a negative error code on error.
86
 *
87
 * Since: 2.12.0
88
 **/
89
int gnutls_pubkey_get_pk_algorithm(gnutls_pubkey_t key, unsigned int *bits)
90
0
{
91
0
  if (bits)
92
0
    *bits = key->bits;
93
94
0
  return key->params.algo;
95
0
}
96
97
/**
98
 * gnutls_pubkey_get_key_usage:
99
 * @key: should contain a #gnutls_pubkey_t type
100
 * @usage: If set will return the number of bits of the parameters (may be NULL)
101
 *
102
 * This function will return the key usage of the public key.
103
 *
104
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
105
 *   negative error value.
106
 *
107
 * Since: 2.12.0
108
 **/
109
int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage)
110
0
{
111
0
  if (usage)
112
0
    *usage = key->key_usage;
113
114
0
  return 0;
115
0
}
116
117
/**
118
 * gnutls_pubkey_init:
119
 * @key: A pointer to the type to be initialized
120
 *
121
 * This function will initialize a public key.
122
 *
123
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
124
 *   negative error value.
125
 *
126
 * Since: 2.12.0
127
 **/
128
int gnutls_pubkey_init(gnutls_pubkey_t *key)
129
0
{
130
0
  *key = NULL;
131
0
  FAIL_IF_LIB_ERROR;
132
133
0
  *key = gnutls_calloc(1, sizeof(struct gnutls_pubkey_st));
134
0
  if (*key == NULL) {
135
0
    gnutls_assert();
136
0
    return GNUTLS_E_MEMORY_ERROR;
137
0
  }
138
139
0
  return 0;
140
0
}
141
142
/**
143
 * gnutls_pubkey_deinit:
144
 * @key: The key to be deinitialized
145
 *
146
 * This function will deinitialize a public key structure.
147
 *
148
 * Since: 2.12.0
149
 **/
150
void gnutls_pubkey_deinit(gnutls_pubkey_t key)
151
0
{
152
0
  if (!key)
153
0
    return;
154
0
  gnutls_pk_params_release(&key->params);
155
0
  gnutls_free(key);
156
0
}
157
158
/**
159
 * gnutls_pubkey_import_x509:
160
 * @key: The public key
161
 * @crt: The certificate to be imported
162
 * @flags: should be zero
163
 *
164
 * This function will import the given public key to the abstract
165
 * #gnutls_pubkey_t type.
166
 *
167
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
168
 *   negative error value.
169
 *
170
 * Since: 2.12.0
171
 **/
172
int gnutls_pubkey_import_x509(gnutls_pubkey_t key, gnutls_x509_crt_t crt,
173
            unsigned int flags)
174
0
{
175
0
  int ret;
176
177
0
  gnutls_pk_params_release(&key->params);
178
  /* params initialized in _gnutls_x509_crt_get_mpis */
179
180
0
  ret = gnutls_x509_crt_get_pk_algorithm(crt, &key->bits);
181
0
  if (ret < 0)
182
0
    return gnutls_assert_val(ret);
183
184
0
  key->params.algo = ret;
185
186
0
  ret = gnutls_x509_crt_get_key_usage(crt, &key->key_usage, NULL);
187
0
  if (ret < 0)
188
0
    key->key_usage = 0;
189
190
0
  ret = _gnutls_x509_crt_get_mpis(crt, &key->params);
191
0
  if (ret < 0) {
192
0
    gnutls_assert();
193
0
    return ret;
194
0
  }
195
196
0
  return 0;
197
0
}
198
199
/**
200
 * gnutls_pubkey_import_x509_crq:
201
 * @key: The public key
202
 * @crq: The certificate to be imported
203
 * @flags: should be zero
204
 *
205
 * This function will import the given public key to the abstract
206
 * #gnutls_pubkey_t type.
207
 *
208
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
209
 *   negative error value.
210
 *
211
 * Since: 3.1.5
212
 **/
213
int gnutls_pubkey_import_x509_crq(gnutls_pubkey_t key, gnutls_x509_crq_t crq,
214
          unsigned int flags)
215
0
{
216
0
  int ret;
217
218
0
  gnutls_pk_params_release(&key->params);
219
  /* params initialized in _gnutls_x509_crq_get_mpis */
220
221
0
  key->params.algo = gnutls_x509_crq_get_pk_algorithm(crq, &key->bits);
222
223
0
  ret = gnutls_x509_crq_get_key_usage(crq, &key->key_usage, NULL);
224
0
  if (ret < 0)
225
0
    key->key_usage = 0;
226
227
0
  ret = _gnutls_x509_crq_get_mpis(crq, &key->params);
228
0
  if (ret < 0) {
229
0
    gnutls_assert();
230
0
    return ret;
231
0
  }
232
233
0
  return 0;
234
0
}
235
236
/**
237
 * gnutls_pubkey_import_privkey:
238
 * @key: The public key
239
 * @pkey: The private key
240
 * @usage: GNUTLS_KEY_* key usage flags.
241
 * @flags: should be zero
242
 *
243
 * Imports the public key from a private.  This function will import
244
 * the given public key to the abstract #gnutls_pubkey_t type.
245
 *
246
 * Note that in certain keys this operation may not be possible, e.g.,
247
 * in other than RSA PKCS#11 keys.
248
 *
249
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
250
 *   negative error value.
251
 *
252
 * Since: 2.12.0
253
 **/
254
int gnutls_pubkey_import_privkey(gnutls_pubkey_t key, gnutls_privkey_t pkey,
255
         unsigned int usage, unsigned int flags)
256
0
{
257
0
  gnutls_pk_params_release(&key->params);
258
0
  gnutls_pk_params_init(&key->params);
259
260
0
  key->key_usage = usage;
261
0
  key->params.algo = gnutls_privkey_get_pk_algorithm(pkey, &key->bits);
262
263
0
  return _gnutls_privkey_get_public_mpis(pkey, &key->params);
264
0
}
265
266
/**
267
 * gnutls_pubkey_get_preferred_hash_algorithm:
268
 * @key: Holds the certificate
269
 * @hash: The result of the call with the hash algorithm used for signature
270
 * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
271
 *
272
 * This function will read the certificate and return the appropriate digest
273
 * algorithm to use for signing with this certificate. Some certificates (i.e.
274
 * DSA might not be able to sign without the preferred algorithm).
275
 *
276
 * To get the signature algorithm instead of just the hash use gnutls_pk_to_sign()
277
 * with the algorithm of the certificate/key and the provided @hash.
278
 *
279
 * Returns: the 0 if the hash algorithm is found. A negative error code is
280
 * returned on error.
281
 *
282
 * Since: 2.12.0
283
 **/
284
int gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key,
285
                 gnutls_digest_algorithm_t *hash,
286
                 unsigned int *mand)
287
0
{
288
0
  int ret;
289
0
  const mac_entry_st *me;
290
291
0
  if (key == NULL) {
292
0
    gnutls_assert();
293
0
    return GNUTLS_E_INVALID_REQUEST;
294
0
  }
295
296
0
  if (mand)
297
0
    *mand = 0;
298
299
0
  switch (key->params.algo) {
300
0
  case GNUTLS_PK_DSA:
301
0
    if (mand)
302
0
      *mand = 1;
303
0
    FALLTHROUGH;
304
0
  case GNUTLS_PK_ECDSA:
305
306
0
    me = _gnutls_dsa_q_to_hash(&key->params, NULL);
307
0
    if (hash)
308
0
      *hash = (gnutls_digest_algorithm_t)me->id;
309
310
0
    ret = 0;
311
0
    break;
312
0
  case GNUTLS_PK_EDDSA_ED25519:
313
0
    if (hash)
314
0
      *hash = GNUTLS_DIG_SHA512;
315
316
0
    ret = 0;
317
0
    break;
318
0
  case GNUTLS_PK_EDDSA_ED448:
319
0
    if (hash)
320
0
      *hash = GNUTLS_DIG_SHAKE_256;
321
322
0
    ret = 0;
323
0
    break;
324
0
  case GNUTLS_PK_GOST_01:
325
0
  case GNUTLS_PK_GOST_12_256:
326
0
  case GNUTLS_PK_GOST_12_512:
327
0
    if (hash)
328
0
      *hash = _gnutls_gost_digest(key->params.algo);
329
0
    if (mand)
330
0
      *mand = 1;
331
332
0
    ret = 0;
333
0
    break;
334
0
  case GNUTLS_PK_RSA_PSS:
335
0
    if (mand && key->params.spki.rsa_pss_dig)
336
0
      *mand = 1;
337
338
0
    if (hash) {
339
0
      if (key->params.spki.rsa_pss_dig) {
340
0
        *hash = key->params.spki.rsa_pss_dig;
341
0
      } else {
342
0
        *hash = _gnutls_pk_bits_to_sha_hash(
343
0
          pubkey_to_bits(&key->params));
344
0
      }
345
0
    }
346
0
    ret = 0;
347
0
    break;
348
0
  case GNUTLS_PK_RSA:
349
0
    if (hash)
350
0
      *hash = _gnutls_pk_bits_to_sha_hash(
351
0
        pubkey_to_bits(&key->params));
352
0
    ret = 0;
353
0
    break;
354
355
0
  default:
356
0
    gnutls_assert();
357
0
    ret = GNUTLS_E_INTERNAL_ERROR;
358
0
  }
359
360
0
  return ret;
361
0
}
362
363
#ifdef ENABLE_PKCS11
364
365
/* The EC_PARAMS attribute can contain either printable string with curve name
366
 * or OID defined in RFC 8410 */
367
int _gnutls_pubkey_parse_ecc_eddsa_params(const gnutls_datum_t *parameters,
368
            gnutls_ecc_curve_t *outcurve)
369
{
370
  gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
371
  asn1_node asn1 = NULL;
372
  unsigned int etype = ASN1_ETYPE_INVALID;
373
  char str[MAX_OID_SIZE];
374
  int str_size;
375
  int ret;
376
377
  ret = asn1_create_element(_gnutls_get_gnutls_asn(),
378
          "GNUTLS.pkcs-11-ec-Parameters", &asn1);
379
  if (ret != ASN1_SUCCESS) {
380
    gnutls_assert();
381
    return _gnutls_asn2err(ret);
382
  }
383
384
  ret = asn1_der_decoding(&asn1, parameters->data, parameters->size,
385
        NULL);
386
  if (ret != ASN1_SUCCESS) {
387
    gnutls_assert();
388
    ret = _gnutls_asn2err(ret);
389
    goto cleanup;
390
  }
391
392
  /* Read the type of choice.
393
   */
394
  str_size = sizeof(str) - 1;
395
  ret = asn1_read_value(asn1, "", str, &str_size);
396
  if (ret != ASN1_SUCCESS) {
397
    gnutls_assert();
398
    ret = _gnutls_asn2err(ret);
399
    goto cleanup;
400
  }
401
  str[str_size] = 0;
402
403
  /* Convert the choice to enum type */
404
  if (strcmp(str, "oId") == 0) {
405
    etype = ASN1_ETYPE_OBJECT_ID;
406
  } else if (strcmp(str, "curveName") == 0) {
407
    etype = ASN1_ETYPE_PRINTABLE_STRING;
408
  }
409
410
  str_size = sizeof(str) - 1;
411
  switch (etype) {
412
  case ASN1_ETYPE_OBJECT_ID:
413
    ret = asn1_read_value(asn1, "oId", str, &str_size);
414
    if (ret != ASN1_SUCCESS) {
415
      gnutls_assert();
416
      ret = _gnutls_asn2err(ret);
417
      break;
418
    }
419
420
    curve = gnutls_oid_to_ecc_curve(str);
421
    if (curve != GNUTLS_ECC_CURVE_ED25519 &&
422
        curve != GNUTLS_ECC_CURVE_ED448) {
423
      _gnutls_debug_log(
424
        "Curve %s is not supported for EdDSA\n", str);
425
      gnutls_assert();
426
      curve = GNUTLS_ECC_CURVE_INVALID;
427
      ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
428
      break;
429
    }
430
431
    ret = GNUTLS_E_SUCCESS;
432
    break;
433
434
  case ASN1_ETYPE_PRINTABLE_STRING:
435
    ret = asn1_read_value(asn1, "curveName", str, &str_size);
436
    if (ret != ASN1_SUCCESS) {
437
      gnutls_assert();
438
      ret = _gnutls_asn2err(ret);
439
      break;
440
    }
441
442
    if (str_size == strlen("edwards25519") &&
443
        strncmp(str, "edwards25519", str_size) == 0) {
444
      curve = GNUTLS_ECC_CURVE_ED25519;
445
      ret = GNUTLS_E_SUCCESS;
446
      break;
447
    } else if (str_size == strlen("edwards448") &&
448
         strncmp(str, "edwards448", str_size) == 0) {
449
      curve = GNUTLS_ECC_CURVE_ED448;
450
      ret = GNUTLS_E_SUCCESS;
451
      break;
452
    }
453
    /* FALLTHROUGH */
454
455
  default:
456
    /* Neither of CHOICEs found. Fail */
457
    gnutls_assert();
458
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
459
    curve = GNUTLS_ECC_CURVE_INVALID;
460
    break;
461
  }
462
463
cleanup:
464
  asn1_delete_structure(&asn1);
465
  *outcurve = curve;
466
  return ret;
467
}
468
469
static int gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
470
            const gnutls_datum_t *parameters,
471
            const gnutls_datum_t *ecpoint)
472
{
473
  int ret;
474
475
  gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
476
  gnutls_datum_t raw_point = { NULL, 0 };
477
478
  ret = _gnutls_pubkey_parse_ecc_eddsa_params(parameters, &curve);
479
  if (ret < 0) {
480
    return gnutls_assert_val(ret);
481
  }
482
483
  ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, ecpoint->data,
484
           ecpoint->size, &raw_point, 0);
485
  if (ret < 0) {
486
    gnutls_assert();
487
    gnutls_free(raw_point.data);
488
    return ret;
489
  }
490
  ret = gnutls_pubkey_import_ecc_raw(key, curve, &raw_point, NULL);
491
492
  gnutls_free(raw_point.data);
493
  return ret;
494
}
495
496
/* Same as above, but for Edwards key agreement */
497
static int gnutls_pubkey_parse_ecc_ecdh_params(const gnutls_datum_t *parameters,
498
                 gnutls_ecc_curve_t *outcurve)
499
{
500
  gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
501
  asn1_node asn1 = NULL;
502
  unsigned int etype = ASN1_ETYPE_INVALID;
503
  char str[MAX_OID_SIZE];
504
  int str_size;
505
  int ret;
506
507
  ret = asn1_create_element(_gnutls_get_gnutls_asn(),
508
          "GNUTLS.pkcs-11-ec-Parameters", &asn1);
509
  if (ret != ASN1_SUCCESS) {
510
    gnutls_assert();
511
    return _gnutls_asn2err(ret);
512
  }
513
514
  ret = asn1_der_decoding(&asn1, parameters->data, parameters->size,
515
        NULL);
516
  if (ret != ASN1_SUCCESS) {
517
    gnutls_assert();
518
    ret = _gnutls_asn2err(ret);
519
    goto cleanup;
520
  }
521
522
  /* Read the type of choice.
523
   */
524
  str_size = sizeof(str) - 1;
525
  ret = asn1_read_value(asn1, "", str, &str_size);
526
  if (ret != ASN1_SUCCESS) {
527
    gnutls_assert();
528
    ret = _gnutls_asn2err(ret);
529
    goto cleanup;
530
  }
531
  str[str_size] = 0;
532
533
  /* Convert the choice to enum type */
534
  if (strcmp(str, "oId") == 0) {
535
    etype = ASN1_ETYPE_OBJECT_ID;
536
  } else if (strcmp(str, "curveName") == 0) {
537
    etype = ASN1_ETYPE_PRINTABLE_STRING;
538
  }
539
540
  str_size = sizeof(str) - 1;
541
  switch (etype) {
542
  case ASN1_ETYPE_OBJECT_ID:
543
    ret = asn1_read_value(asn1, "oId", str, &str_size);
544
    if (ret != ASN1_SUCCESS) {
545
      gnutls_assert();
546
      ret = _gnutls_asn2err(ret);
547
      break;
548
    }
549
550
    curve = gnutls_oid_to_ecc_curve(str);
551
    if (curve != GNUTLS_ECC_CURVE_X25519 &&
552
        curve != GNUTLS_ECC_CURVE_X448) {
553
      _gnutls_debug_log(
554
        "Curve %s is not supported for Edwards-based key agreement\n",
555
        str);
556
      gnutls_assert();
557
      curve = GNUTLS_ECC_CURVE_INVALID;
558
      ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
559
      break;
560
    }
561
562
    ret = GNUTLS_E_SUCCESS;
563
    break;
564
565
  case ASN1_ETYPE_PRINTABLE_STRING:
566
    ret = asn1_read_value(asn1, "curveName", str, &str_size);
567
    if (ret != ASN1_SUCCESS) {
568
      gnutls_assert();
569
      ret = _gnutls_asn2err(ret);
570
      break;
571
    }
572
573
    if (str_size == strlen("x25519") &&
574
        strncmp(str, "x25519", str_size) == 0) {
575
      curve = GNUTLS_ECC_CURVE_X25519;
576
      ret = GNUTLS_E_SUCCESS;
577
      break;
578
    } else if (str_size == strlen("x448") &&
579
         strncmp(str, "x448", str_size) == 0) {
580
      curve = GNUTLS_ECC_CURVE_X448;
581
      ret = GNUTLS_E_SUCCESS;
582
      break;
583
    }
584
    /* FALLTHROUGH */
585
586
  default:
587
    /* Neither of CHOICEs found. Fail */
588
    gnutls_assert();
589
    ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
590
    curve = GNUTLS_ECC_CURVE_INVALID;
591
    break;
592
  }
593
594
cleanup:
595
  asn1_delete_structure(&asn1);
596
  *outcurve = curve;
597
  return ret;
598
}
599
600
static int gnutls_pubkey_import_ecc_ecdh(gnutls_pubkey_t key,
601
           const gnutls_datum_t *parameters,
602
           const gnutls_datum_t *ecpoint)
603
{
604
  int ret;
605
606
  gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
607
  gnutls_datum_t raw_point = { NULL, 0 };
608
609
  ret = gnutls_pubkey_parse_ecc_ecdh_params(parameters, &curve);
610
  if (ret < 0) {
611
    return gnutls_assert_val(ret);
612
  }
613
614
  ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, ecpoint->data,
615
           ecpoint->size, &raw_point, 0);
616
  if (ret < 0) {
617
    gnutls_assert();
618
    gnutls_free(raw_point.data);
619
    return ret;
620
  }
621
  ret = gnutls_pubkey_import_ecc_raw(key, curve, &raw_point, NULL);
622
623
  gnutls_free(raw_point.data);
624
  return ret;
625
}
626
627
/**
628
 * gnutls_pubkey_import_pkcs11:
629
 * @key: The public key
630
 * @obj: The parameters to be imported
631
 * @flags: should be zero
632
 *
633
 * Imports a public key from a pkcs11 key. This function will import
634
 * the given public key to the abstract #gnutls_pubkey_t type.
635
 *
636
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
637
 *   negative error value.
638
 *
639
 * Since: 2.12.0
640
 **/
641
int gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key, gnutls_pkcs11_obj_t obj,
642
        unsigned int flags)
643
{
644
  int ret, type;
645
646
  type = gnutls_pkcs11_obj_get_type(obj);
647
  if (type != GNUTLS_PKCS11_OBJ_PUBKEY &&
648
      type != GNUTLS_PKCS11_OBJ_X509_CRT) {
649
    gnutls_assert();
650
    return GNUTLS_E_INVALID_REQUEST;
651
  }
652
653
  if (type == GNUTLS_PKCS11_OBJ_X509_CRT) {
654
    gnutls_x509_crt_t xcrt;
655
656
    ret = gnutls_x509_crt_init(&xcrt);
657
    if (ret < 0) {
658
      gnutls_assert() return ret;
659
    }
660
661
    ret = gnutls_x509_crt_import_pkcs11(xcrt, obj);
662
    if (ret < 0) {
663
      gnutls_assert();
664
      goto cleanup_crt;
665
    }
666
667
    ret = gnutls_pubkey_import_x509(key, xcrt, 0);
668
    if (ret < 0) {
669
      gnutls_assert();
670
      goto cleanup_crt;
671
    }
672
673
    ret = gnutls_x509_crt_get_key_usage(xcrt, &key->key_usage,
674
                NULL);
675
    if (ret < 0)
676
      key->key_usage = 0;
677
678
    ret = 0;
679
  cleanup_crt:
680
    gnutls_x509_crt_deinit(xcrt);
681
    return ret;
682
  }
683
684
  key->key_usage = obj->key_usage;
685
686
  switch (obj->pk_algorithm) {
687
  case GNUTLS_PK_RSA:
688
  case GNUTLS_PK_RSA_PSS:
689
    ret = gnutls_pubkey_import_rsa_raw(key, &obj->pubkey[0],
690
               &obj->pubkey[1]);
691
    break;
692
  case GNUTLS_PK_DSA:
693
    ret = gnutls_pubkey_import_dsa_raw(key, &obj->pubkey[0],
694
               &obj->pubkey[1],
695
               &obj->pubkey[2],
696
               &obj->pubkey[3]);
697
    break;
698
  case GNUTLS_PK_EC:
699
    ret = gnutls_pubkey_import_ecc_x962(key, &obj->pubkey[0],
700
                &obj->pubkey[1]);
701
    break;
702
  case GNUTLS_PK_EDDSA_ED25519:
703
  case GNUTLS_PK_EDDSA_ED448:
704
    ret = gnutls_pubkey_import_ecc_eddsa(key, &obj->pubkey[0],
705
                 &obj->pubkey[1]);
706
    break;
707
  case GNUTLS_PK_ECDH_X25519:
708
    ret = gnutls_pubkey_import_ecc_ecdh(key, &obj->pubkey[0],
709
                &obj->pubkey[1]);
710
    break;
711
  default:
712
    gnutls_assert();
713
    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
714
  }
715
716
  if (ret < 0) {
717
    gnutls_assert();
718
    return ret;
719
  }
720
721
  return 0;
722
}
723
724
#endif /* ENABLE_PKCS11 */
725
726
/**
727
 * gnutls_pubkey_export:
728
 * @key: Holds the certificate
729
 * @format: the format of output params. One of PEM or DER.
730
 * @output_data: will contain a certificate PEM or DER encoded
731
 * @output_data_size: holds the size of output_data (and will be
732
 *   replaced by the actual size of parameters)
733
 *
734
 * This function will export the public key to DER or PEM format.
735
 * The contents of the exported data is the SubjectPublicKeyInfo
736
 * X.509 structure.
737
 *
738
 * If the buffer provided is not long enough to hold the output, then
739
 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
740
 * be returned.
741
 *
742
 * If the structure is PEM encoded, it will have a header
743
 * of "BEGIN CERTIFICATE".
744
 *
745
 * Returns: In case of failure a negative error code will be
746
 *   returned, and 0 on success.
747
 *
748
 * Since: 2.12.0
749
 **/
750
int gnutls_pubkey_export(gnutls_pubkey_t key, gnutls_x509_crt_fmt_t format,
751
       void *output_data, size_t *output_data_size)
752
0
{
753
0
  int result;
754
0
  asn1_node spk = NULL;
755
756
0
  if (key == NULL) {
757
0
    gnutls_assert();
758
0
    return GNUTLS_E_INVALID_REQUEST;
759
0
  }
760
761
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
762
0
            "PKIX1.SubjectPublicKeyInfo",
763
0
            &spk)) != ASN1_SUCCESS) {
764
0
    gnutls_assert();
765
0
    return _gnutls_asn2err(result);
766
0
  }
767
768
0
  result = _gnutls_x509_encode_and_copy_PKI_params(spk, "", &key->params);
769
0
  if (result < 0) {
770
0
    gnutls_assert();
771
0
    goto cleanup;
772
0
  }
773
774
0
  result = _gnutls_x509_export_int_named(spk, "", format, PEM_PK,
775
0
                 output_data, output_data_size);
776
0
  if (result < 0) {
777
0
    gnutls_assert();
778
0
    goto cleanup;
779
0
  }
780
781
0
  result = 0;
782
783
0
cleanup:
784
0
  asn1_delete_structure(&spk);
785
786
0
  return result;
787
0
}
788
789
/**
790
 * gnutls_pubkey_export2:
791
 * @key: Holds the certificate
792
 * @format: the format of output params. One of PEM or DER.
793
 * @out: will contain a certificate PEM or DER encoded
794
 *
795
 * This function will export the public key to DER or PEM format.
796
 * The contents of the exported data is the SubjectPublicKeyInfo
797
 * X.509 structure.
798
 *
799
 * The output buffer will be allocated using gnutls_malloc().
800
 *
801
 * If the structure is PEM encoded, it will have a header
802
 * of "BEGIN CERTIFICATE".
803
 *
804
 * Returns: In case of failure a negative error code will be
805
 *   returned, and 0 on success.
806
 *
807
 * Since: 3.1.3
808
 **/
809
int gnutls_pubkey_export2(gnutls_pubkey_t key, gnutls_x509_crt_fmt_t format,
810
        gnutls_datum_t *out)
811
0
{
812
0
  int result;
813
0
  asn1_node spk = NULL;
814
815
0
  if (key == NULL) {
816
0
    gnutls_assert();
817
0
    return GNUTLS_E_INVALID_REQUEST;
818
0
  }
819
820
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
821
0
            "PKIX1.SubjectPublicKeyInfo",
822
0
            &spk)) != ASN1_SUCCESS) {
823
0
    gnutls_assert();
824
0
    return _gnutls_asn2err(result);
825
0
  }
826
827
0
  result = _gnutls_x509_encode_and_copy_PKI_params(spk, "", &key->params);
828
0
  if (result < 0) {
829
0
    gnutls_assert();
830
0
    goto cleanup;
831
0
  }
832
833
0
  result = _gnutls_x509_export_int_named2(spk, "", format, PEM_PK, out);
834
0
  if (result < 0) {
835
0
    gnutls_assert();
836
0
    goto cleanup;
837
0
  }
838
839
0
  result = 0;
840
841
0
cleanup:
842
0
  asn1_delete_structure(&spk);
843
844
0
  return result;
845
0
}
846
847
/**
848
 * gnutls_pubkey_get_key_id:
849
 * @key: Holds the public key
850
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
851
 * @output_data: will contain the key ID
852
 * @output_data_size: holds the size of output_data (and will be
853
 *   replaced by the actual size of parameters)
854
 *
855
 * This function will return a unique ID that depends on the public
856
 * key parameters. This ID can be used in checking whether a
857
 * certificate corresponds to the given public key.
858
 *
859
 * If the buffer provided is not long enough to hold the output, then
860
 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
861
 * be returned.  The output will normally be a SHA-1 hash output,
862
 * which is 20 bytes.
863
 *
864
 * Returns: In case of failure a negative error code will be
865
 *   returned, and 0 on success.
866
 *
867
 * Since: 2.12.0
868
 **/
869
int gnutls_pubkey_get_key_id(gnutls_pubkey_t key, unsigned int flags,
870
           unsigned char *output_data,
871
           size_t *output_data_size)
872
0
{
873
0
  int ret = 0;
874
875
0
  if (key == NULL) {
876
0
    gnutls_assert();
877
0
    return GNUTLS_E_INVALID_REQUEST;
878
0
  }
879
880
0
  ret = _gnutls_get_key_id(&key->params, output_data, output_data_size,
881
0
         flags);
882
0
  if (ret < 0) {
883
0
    gnutls_assert();
884
0
    return ret;
885
0
  }
886
887
0
  return 0;
888
0
}
889
890
/**
891
 * gnutls_pubkey_export_rsa_raw2:
892
 * @key: Holds the certificate
893
 * @m: will hold the modulus (may be %NULL)
894
 * @e: will hold the public exponent (may be %NULL)
895
 * @flags: flags from %gnutls_abstract_export_flags_t
896
 *
897
 * This function will export the RSA public key's parameters found in
898
 * the given structure.  The new parameters will be allocated using
899
 * gnutls_malloc() and will be stored in the appropriate datum.
900
 *
901
 * This function allows for %NULL parameters since 3.4.1.
902
 *
903
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
904
 *
905
 * Since: 3.6.0
906
 **/
907
int gnutls_pubkey_export_rsa_raw2(gnutls_pubkey_t key, gnutls_datum_t *m,
908
          gnutls_datum_t *e, unsigned flags)
909
0
{
910
0
  int ret;
911
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
912
913
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
914
0
    dprint = _gnutls_mpi_dprint;
915
916
0
  if (key == NULL) {
917
0
    gnutls_assert();
918
0
    return GNUTLS_E_INVALID_REQUEST;
919
0
  }
920
921
0
  if (!GNUTLS_PK_IS_RSA(key->params.algo)) {
922
0
    gnutls_assert();
923
0
    return GNUTLS_E_INVALID_REQUEST;
924
0
  }
925
926
0
  if (m) {
927
0
    ret = dprint(key->params.params[0], m);
928
0
    if (ret < 0) {
929
0
      gnutls_assert();
930
0
      return ret;
931
0
    }
932
0
  }
933
934
0
  if (e) {
935
0
    ret = dprint(key->params.params[1], e);
936
0
    if (ret < 0) {
937
0
      gnutls_assert();
938
0
      _gnutls_free_datum(m);
939
0
      return ret;
940
0
    }
941
0
  }
942
943
0
  return 0;
944
0
}
945
946
/**
947
 * gnutls_pubkey_export_rsa_raw:
948
 * @key: Holds the certificate
949
 * @m: will hold the modulus (may be %NULL)
950
 * @e: will hold the public exponent (may be %NULL)
951
 *
952
 * This function will export the RSA public key's parameters found in
953
 * the given structure.  The new parameters will be allocated using
954
 * gnutls_malloc() and will be stored in the appropriate datum.
955
 *
956
 * This function allows for %NULL parameters since 3.4.1.
957
 *
958
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
959
 *
960
 * Since: 3.3.0
961
 **/
962
int gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m,
963
         gnutls_datum_t *e)
964
0
{
965
0
  return gnutls_pubkey_export_rsa_raw2(key, m, e, 0);
966
0
}
967
968
/**
969
 * gnutls_pubkey_export_dsa_raw:
970
 * @key: Holds the public key
971
 * @p: will hold the p (may be %NULL)
972
 * @q: will hold the q (may be %NULL)
973
 * @g: will hold the g (may be %NULL)
974
 * @y: will hold the y (may be %NULL)
975
 *
976
 * This function will export the DSA public key's parameters found in
977
 * the given certificate.  The new parameters will be allocated using
978
 * gnutls_malloc() and will be stored in the appropriate datum.
979
 *
980
 * This function allows for %NULL parameters since 3.4.1.
981
 *
982
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
983
 *
984
 * Since: 3.3.0
985
 **/
986
int gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p,
987
         gnutls_datum_t *q, gnutls_datum_t *g,
988
         gnutls_datum_t *y)
989
0
{
990
0
  return gnutls_pubkey_export_dsa_raw2(key, p, q, g, y, 0);
991
0
}
992
993
/**
994
 * gnutls_pubkey_export_dsa_raw2:
995
 * @key: Holds the public key
996
 * @p: will hold the p (may be %NULL)
997
 * @q: will hold the q (may be %NULL)
998
 * @g: will hold the g (may be %NULL)
999
 * @y: will hold the y (may be %NULL)
1000
 * @flags: flags from %gnutls_abstract_export_flags_t
1001
 *
1002
 * This function will export the DSA public key's parameters found in
1003
 * the given certificate.  The new parameters will be allocated using
1004
 * gnutls_malloc() and will be stored in the appropriate datum.
1005
 *
1006
 * This function allows for %NULL parameters since 3.4.1.
1007
 *
1008
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1009
 *
1010
 * Since: 3.6.0
1011
 **/
1012
int gnutls_pubkey_export_dsa_raw2(gnutls_pubkey_t key, gnutls_datum_t *p,
1013
          gnutls_datum_t *q, gnutls_datum_t *g,
1014
          gnutls_datum_t *y, unsigned flags)
1015
0
{
1016
0
  int ret;
1017
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1018
1019
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1020
0
    dprint = _gnutls_mpi_dprint;
1021
1022
0
  if (key == NULL) {
1023
0
    gnutls_assert();
1024
0
    return GNUTLS_E_INVALID_REQUEST;
1025
0
  }
1026
1027
0
  if (key->params.algo != GNUTLS_PK_DSA) {
1028
0
    gnutls_assert();
1029
0
    return GNUTLS_E_INVALID_REQUEST;
1030
0
  }
1031
1032
  /* P */
1033
0
  if (p) {
1034
0
    ret = dprint(key->params.params[0], p);
1035
0
    if (ret < 0) {
1036
0
      gnutls_assert();
1037
0
      return ret;
1038
0
    }
1039
0
  }
1040
1041
  /* Q */
1042
0
  if (q) {
1043
0
    ret = dprint(key->params.params[1], q);
1044
0
    if (ret < 0) {
1045
0
      gnutls_assert();
1046
0
      _gnutls_free_datum(p);
1047
0
      return ret;
1048
0
    }
1049
0
  }
1050
1051
  /* G */
1052
0
  if (g) {
1053
0
    ret = dprint(key->params.params[2], g);
1054
0
    if (ret < 0) {
1055
0
      gnutls_assert();
1056
0
      _gnutls_free_datum(p);
1057
0
      _gnutls_free_datum(q);
1058
0
      return ret;
1059
0
    }
1060
0
  }
1061
1062
  /* Y */
1063
0
  if (y) {
1064
0
    ret = dprint(key->params.params[3], y);
1065
0
    if (ret < 0) {
1066
0
      gnutls_assert();
1067
0
      _gnutls_free_datum(p);
1068
0
      _gnutls_free_datum(g);
1069
0
      _gnutls_free_datum(q);
1070
0
      return ret;
1071
0
    }
1072
0
  }
1073
1074
0
  return 0;
1075
0
}
1076
1077
/**
1078
 * gnutls_pubkey_export_dh_raw:
1079
 * @key: Holds the public key
1080
 * @params: will hold the Diffie-Hellman parameter (optional), must be initialized
1081
 * @y: will hold the y
1082
 * @flags: flags from %gnutls_abstract_export_flags_t
1083
 *
1084
 * This function will export the Diffie-Hellman public key parameter
1085
 * found in the given public key.  The new parameter will be allocated
1086
 * using gnutls_malloc() and will be stored in the appropriate datum.
1087
 *
1088
 * To retrieve other parameters common in both public key and private
1089
 * key, use gnutls_dh_params_export_raw().
1090
 *
1091
 * This function allows for %NULL parameters since 3.4.1.
1092
 *
1093
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1094
 *
1095
 * Since: 3.8.2
1096
 **/
1097
int gnutls_pubkey_export_dh_raw(gnutls_pubkey_t key, gnutls_dh_params_t params,
1098
        gnutls_datum_t *y, unsigned flags)
1099
0
{
1100
0
  int ret;
1101
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1102
1103
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ) {
1104
0
    dprint = _gnutls_mpi_dprint;
1105
0
  }
1106
1107
0
  if (key == NULL) {
1108
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1109
0
  }
1110
1111
0
  if (key->params.algo != GNUTLS_PK_DH) {
1112
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1113
0
  }
1114
1115
0
  if (params) {
1116
0
    params->params[0] = _gnutls_mpi_copy(key->params.params[DH_P]);
1117
0
    params->params[1] = _gnutls_mpi_copy(key->params.params[DH_G]);
1118
0
    if (key->params.params[DH_Q]) {
1119
0
      params->params[2] =
1120
0
        _gnutls_mpi_copy(key->params.params[DH_Q]);
1121
0
    }
1122
0
    params->q_bits = key->params.qbits;
1123
0
  }
1124
1125
  /* Y */
1126
0
  if (y) {
1127
0
    ret = dprint(key->params.params[DH_Y], y);
1128
0
    if (ret < 0) {
1129
0
      return gnutls_assert_val(ret);
1130
0
    }
1131
0
  }
1132
1133
0
  return 0;
1134
0
}
1135
1136
/**
1137
 * gnutls_pubkey_export_ecc_raw:
1138
 * @key: Holds the public key
1139
 * @curve: will hold the curve (may be %NULL)
1140
 * @x: will hold x-coordinate (may be %NULL)
1141
 * @y: will hold y-coordinate (may be %NULL)
1142
 *
1143
 * This function will export the ECC public key's parameters found in
1144
 * the given key.  The new parameters will be allocated using
1145
 * gnutls_malloc() and will be stored in the appropriate datum.
1146
 *
1147
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
1148
 * will be in the native format for the curve.
1149
 *
1150
 * This function allows for %NULL parameters since 3.4.1.
1151
 *
1152
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1153
 *
1154
 * Since: 3.0
1155
 **/
1156
int gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
1157
         gnutls_datum_t *x, gnutls_datum_t *y)
1158
0
{
1159
0
  return gnutls_pubkey_export_ecc_raw2(key, curve, x, y, 0);
1160
0
}
1161
1162
/**
1163
 * gnutls_pubkey_export_ecc_raw2:
1164
 * @key: Holds the public key
1165
 * @curve: will hold the curve (may be %NULL)
1166
 * @x: will hold x-coordinate (may be %NULL)
1167
 * @y: will hold y-coordinate (may be %NULL)
1168
 * @flags: flags from %gnutls_abstract_export_flags_t
1169
 *
1170
 * This function will export the ECC public key's parameters found in
1171
 * the given key.  The new parameters will be allocated using
1172
 * gnutls_malloc() and will be stored in the appropriate datum.
1173
 *
1174
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
1175
 * will be in the native format for the curve.
1176
 *
1177
 * This function allows for %NULL parameters since 3.4.1.
1178
 *
1179
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1180
 *
1181
 * Since: 3.6.0
1182
 **/
1183
int gnutls_pubkey_export_ecc_raw2(gnutls_pubkey_t key,
1184
          gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
1185
          gnutls_datum_t *y, unsigned int flags)
1186
0
{
1187
0
  int ret;
1188
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1189
1190
0
  if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1191
0
    dprint = _gnutls_mpi_dprint;
1192
1193
0
  if (key == NULL) {
1194
0
    gnutls_assert();
1195
0
    return GNUTLS_E_INVALID_REQUEST;
1196
0
  }
1197
1198
0
  if (!IS_EC(key->params.algo)) {
1199
0
    gnutls_assert();
1200
0
    return GNUTLS_E_INVALID_REQUEST;
1201
0
  }
1202
1203
0
  if (curve)
1204
0
    *curve = key->params.curve;
1205
1206
0
  if (key->params.algo == GNUTLS_PK_EDDSA_ED25519 ||
1207
0
      key->params.algo == GNUTLS_PK_EDDSA_ED448 ||
1208
0
      key->params.algo == GNUTLS_PK_ECDH_X25519 ||
1209
0
      key->params.algo == GNUTLS_PK_ECDH_X448) {
1210
0
    if (x) {
1211
0
      ret = _gnutls_set_datum(x, key->params.raw_pub.data,
1212
0
            key->params.raw_pub.size);
1213
0
      if (ret < 0)
1214
0
        return gnutls_assert_val(ret);
1215
0
    }
1216
0
    if (y) {
1217
0
      y->data = NULL;
1218
0
      y->size = 0;
1219
0
    }
1220
0
    return 0;
1221
0
  }
1222
1223
  /* ECDSA */
1224
1225
  /* X */
1226
0
  if (x) {
1227
0
    ret = dprint(key->params.params[ECC_X], x);
1228
0
    if (ret < 0) {
1229
0
      gnutls_assert();
1230
0
      return ret;
1231
0
    }
1232
0
  }
1233
1234
  /* Y */
1235
0
  if (y) {
1236
0
    ret = dprint(key->params.params[ECC_Y], y);
1237
0
    if (ret < 0) {
1238
0
      gnutls_assert();
1239
0
      _gnutls_free_datum(x);
1240
0
      return ret;
1241
0
    }
1242
0
  }
1243
1244
0
  return 0;
1245
0
}
1246
1247
/**
1248
 * gnutls_pubkey_export_ecc_x962:
1249
 * @key: Holds the public key
1250
 * @parameters: DER encoding of an ANSI X9.62 parameters
1251
 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1252
 *
1253
 * This function will export the ECC public key's parameters found in
1254
 * the given certificate.  The new parameters will be allocated using
1255
 * gnutls_malloc() and will be stored in the appropriate datum.
1256
 *
1257
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1258
 *
1259
 * Since: 3.3.0
1260
 **/
1261
int gnutls_pubkey_export_ecc_x962(gnutls_pubkey_t key,
1262
          gnutls_datum_t *parameters,
1263
          gnutls_datum_t *ecpoint)
1264
0
{
1265
0
  int ret;
1266
0
  gnutls_datum_t raw_point = { NULL, 0 };
1267
1268
0
  if (key == NULL || key->params.algo != GNUTLS_PK_EC)
1269
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1270
1271
0
  ret = _gnutls_x509_write_ecc_pubkey(&key->params, &raw_point);
1272
0
  if (ret < 0)
1273
0
    return gnutls_assert_val(ret);
1274
1275
0
  ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
1276
0
           raw_point.data, raw_point.size,
1277
0
           ecpoint);
1278
0
  if (ret < 0) {
1279
0
    gnutls_assert();
1280
0
    goto cleanup;
1281
0
  }
1282
1283
0
  ret = _gnutls_x509_write_ecc_params(key->params.curve, parameters);
1284
0
  if (ret < 0) {
1285
0
    _gnutls_free_datum(ecpoint);
1286
0
    gnutls_assert();
1287
0
    goto cleanup;
1288
0
  }
1289
1290
0
  ret = 0;
1291
0
cleanup:
1292
0
  gnutls_free(raw_point.data);
1293
0
  return ret;
1294
0
}
1295
1296
/**
1297
 * gnutls_pubkey_export_gost_raw2:
1298
 * @key: Holds the public key
1299
 * @curve: will hold the curve (may be %NULL)
1300
 * @digest: will hold the curve (may be %NULL)
1301
 * @paramset: will hold the parameters id (may be %NULL)
1302
 * @x: will hold the x-coordinate (may be %NULL)
1303
 * @y: will hold the y-coordinate (may be %NULL)
1304
 * @flags: flags from %gnutls_abstract_export_flags_t
1305
 *
1306
 * This function will export the GOST public key's parameters found in
1307
 * the given key.  The new parameters will be allocated using
1308
 * gnutls_malloc() and will be stored in the appropriate datum.
1309
 *
1310
 * Note: parameters will be stored with least significant byte first. On
1311
 * version 3.6.3 this was incorrectly returned in big-endian format.
1312
 *
1313
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1314
 *
1315
 * Since: 3.6.3
1316
 **/
1317
int gnutls_pubkey_export_gost_raw2(gnutls_pubkey_t key,
1318
           gnutls_ecc_curve_t *curve,
1319
           gnutls_digest_algorithm_t *digest,
1320
           gnutls_gost_paramset_t *paramset,
1321
           gnutls_datum_t *x, gnutls_datum_t *y,
1322
           unsigned int flags)
1323
0
{
1324
0
  int ret;
1325
1326
0
  mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1327
1328
0
  if (key == NULL) {
1329
0
    gnutls_assert();
1330
0
    return GNUTLS_E_INVALID_REQUEST;
1331
0
  }
1332
1333
0
  if (key->params.algo != GNUTLS_PK_GOST_01 &&
1334
0
      key->params.algo != GNUTLS_PK_GOST_12_256 &&
1335
0
      key->params.algo != GNUTLS_PK_GOST_12_512) {
1336
0
    gnutls_assert();
1337
0
    return GNUTLS_E_INVALID_REQUEST;
1338
0
  }
1339
1340
0
  if (curve)
1341
0
    *curve = key->params.curve;
1342
1343
0
  if (digest)
1344
0
    *digest = _gnutls_gost_digest(key->params.algo);
1345
1346
0
  if (paramset)
1347
0
    *paramset = key->params.gost_params;
1348
1349
  /* X */
1350
0
  if (x) {
1351
0
    ret = dprint(key->params.params[GOST_X], x);
1352
0
    if (ret < 0) {
1353
0
      gnutls_assert();
1354
0
      return ret;
1355
0
    }
1356
0
  }
1357
1358
  /* Y */
1359
0
  if (y) {
1360
0
    ret = dprint(key->params.params[GOST_Y], y);
1361
0
    if (ret < 0) {
1362
0
      gnutls_assert();
1363
0
      _gnutls_free_datum(x);
1364
0
      return ret;
1365
0
    }
1366
0
  }
1367
1368
0
  return 0;
1369
0
}
1370
1371
/**
1372
 * gnutls_pubkey_import:
1373
 * @key: The public key. 
1374
 * @data: The DER or PEM encoded certificate. 
1375
 * @format: One of DER or PEM 
1376
 * 
1377
 * This function will import the provided public key in
1378
 * a SubjectPublicKeyInfo X.509 structure to a native
1379
 * %gnutls_pubkey_t type. The output will be stored 
1380
 * in @key. If the public key is PEM encoded it should have a header 
1381
 * of "PUBLIC KEY". 
1382
 * 
1383
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1384
 * negative error value.
1385
 *
1386
 * Since: 2.12.0
1387
 **/
1388
int gnutls_pubkey_import(gnutls_pubkey_t key, const gnutls_datum_t *data,
1389
       gnutls_x509_crt_fmt_t format)
1390
0
{
1391
0
  int result = 0, need_free = 0;
1392
0
  gnutls_datum_t _data;
1393
0
  asn1_node spk;
1394
1395
0
  if (key == NULL) {
1396
0
    gnutls_assert();
1397
0
    return GNUTLS_E_INVALID_REQUEST;
1398
0
  }
1399
1400
0
  _data.data = data->data;
1401
0
  _data.size = data->size;
1402
1403
  /* If the Certificate is in PEM format then decode it
1404
   */
1405
0
  if (format == GNUTLS_X509_FMT_PEM) {
1406
    /* Try the first header */
1407
0
    result = _gnutls_fbase64_decode(PEM_PK, data->data, data->size,
1408
0
            &_data);
1409
1410
0
    if (result < 0) {
1411
0
      gnutls_assert();
1412
0
      return result;
1413
0
    }
1414
1415
0
    need_free = 1;
1416
0
  }
1417
1418
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
1419
0
            "PKIX1.SubjectPublicKeyInfo",
1420
0
            &spk)) != ASN1_SUCCESS) {
1421
0
    gnutls_assert();
1422
0
    result = _gnutls_asn2err(result);
1423
0
    goto cleanup;
1424
0
  }
1425
1426
0
  result = _asn1_strict_der_decode(&spk, _data.data, _data.size, NULL);
1427
0
  if (result != ASN1_SUCCESS) {
1428
0
    gnutls_assert();
1429
0
    result = _gnutls_asn2err(result);
1430
0
    goto cleanup;
1431
0
  }
1432
1433
0
  result = _gnutls_get_asn_mpis(spk, "", &key->params);
1434
0
  if (result < 0) {
1435
0
    gnutls_assert();
1436
0
    goto cleanup;
1437
0
  }
1438
1439
0
  key->bits = pubkey_to_bits(&key->params);
1440
0
  result = 0;
1441
1442
0
cleanup:
1443
0
  asn1_delete_structure(&spk);
1444
1445
0
  if (need_free)
1446
0
    _gnutls_free_datum(&_data);
1447
0
  return result;
1448
0
}
1449
1450
/**
1451
 * gnutls_x509_crt_set_pubkey:
1452
 * @crt: should contain a #gnutls_x509_crt_t type
1453
 * @key: holds a public key
1454
 *
1455
 * This function will set the public parameters from the given public
1456
 * key to the certificate. The @key can be deallocated after that.
1457
 *
1458
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1459
 *   negative error value.
1460
 *
1461
 * Since: 2.12.0
1462
 **/
1463
int gnutls_x509_crt_set_pubkey(gnutls_x509_crt_t crt, gnutls_pubkey_t key)
1464
0
{
1465
0
  int result;
1466
1467
0
  if (crt == NULL) {
1468
0
    gnutls_assert();
1469
0
    return GNUTLS_E_INVALID_REQUEST;
1470
0
  }
1471
1472
0
  result = _gnutls_x509_encode_and_copy_PKI_params(
1473
0
    crt->cert, "tbsCertificate.subjectPublicKeyInfo", &key->params);
1474
1475
0
  if (result < 0) {
1476
0
    gnutls_assert();
1477
0
    return result;
1478
0
  }
1479
1480
0
  if (key->key_usage)
1481
0
    gnutls_x509_crt_set_key_usage(crt, key->key_usage);
1482
1483
0
  return 0;
1484
0
}
1485
1486
/**
1487
 * gnutls_x509_crq_set_pubkey:
1488
 * @crq: should contain a #gnutls_x509_crq_t type
1489
 * @key: holds a public key
1490
 *
1491
 * This function will set the public parameters from the given public
1492
 * key to the request. The @key can be deallocated after that.
1493
 *
1494
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1495
 *   negative error value.
1496
 *
1497
 * Since: 2.12.0
1498
 **/
1499
int gnutls_x509_crq_set_pubkey(gnutls_x509_crq_t crq, gnutls_pubkey_t key)
1500
0
{
1501
0
  int result;
1502
1503
0
  if (crq == NULL) {
1504
0
    gnutls_assert();
1505
0
    return GNUTLS_E_INVALID_REQUEST;
1506
0
  }
1507
1508
0
  result = _gnutls_x509_encode_and_copy_PKI_params(
1509
0
    crq->crq, "certificationRequestInfo.subjectPKInfo",
1510
0
    &key->params);
1511
1512
0
  if (result < 0) {
1513
0
    gnutls_assert();
1514
0
    return result;
1515
0
  }
1516
1517
0
  if (key->key_usage)
1518
0
    gnutls_x509_crq_set_key_usage(crq, key->key_usage);
1519
1520
0
  return 0;
1521
0
}
1522
1523
/**
1524
 * gnutls_pubkey_set_key_usage:
1525
 * @key: a certificate of type #gnutls_x509_crt_t
1526
 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1527
 *
1528
 * This function will set the key usage flags of the public key. This
1529
 * is only useful if the key is to be exported to a certificate or
1530
 * certificate request.
1531
 *
1532
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1533
 *   negative error value.
1534
 *
1535
 * Since: 2.12.0
1536
 **/
1537
int gnutls_pubkey_set_key_usage(gnutls_pubkey_t key, unsigned int usage)
1538
0
{
1539
0
  key->key_usage = usage;
1540
1541
0
  return 0;
1542
0
}
1543
1544
#ifdef ENABLE_PKCS11
1545
1546
#if 0
1547
/**
1548
 * gnutls_pubkey_import_pkcs11_url:
1549
 * @key: A key of type #gnutls_pubkey_t
1550
 * @url: A PKCS 11 url
1551
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1552
 *
1553
 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1554
 * structure.
1555
 *
1556
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1557
 *   negative error value.
1558
 *
1559
 * Since: 2.12.0
1560
 **/
1561
int
1562
gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
1563
        unsigned int flags)
1564
{
1565
  int x;
1566
}
1567
#endif
1568
1569
static int _gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key,
1570
              const char *url, unsigned int flags)
1571
{
1572
  gnutls_pkcs11_obj_t pcrt;
1573
  int ret;
1574
1575
  ret = gnutls_pkcs11_obj_init(&pcrt);
1576
  if (ret < 0) {
1577
    gnutls_assert();
1578
    return ret;
1579
  }
1580
1581
  if (key->pin.cb)
1582
    gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb,
1583
               key->pin.data);
1584
1585
  ret = gnutls_pkcs11_obj_import_url(
1586
    pcrt, url, flags | GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PUBKEY);
1587
  if (ret < 0) {
1588
    gnutls_assert();
1589
    goto cleanup;
1590
  }
1591
1592
  ret = gnutls_pubkey_import_pkcs11(key, pcrt, flags);
1593
  if (ret < 0) {
1594
    gnutls_assert();
1595
    goto cleanup;
1596
  }
1597
1598
  ret = 0;
1599
cleanup:
1600
1601
  gnutls_pkcs11_obj_deinit(pcrt);
1602
1603
  return ret;
1604
}
1605
1606
#endif /* ENABLE_PKCS11 */
1607
1608
/**
1609
 * gnutls_pubkey_import_url:
1610
 * @key: A key of type #gnutls_pubkey_t
1611
 * @url: A PKCS 11 url
1612
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1613
 *
1614
 * This function will import a public key from the provided URL.
1615
 *
1616
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1617
 *   negative error value.
1618
 *
1619
 * Since: 3.1.0
1620
 **/
1621
int gnutls_pubkey_import_url(gnutls_pubkey_t key, const char *url,
1622
           unsigned int flags)
1623
0
{
1624
0
  unsigned i;
1625
1626
0
  for (i = 0; i < _gnutls_custom_urls_size; i++) {
1627
0
    if (strncmp(url, _gnutls_custom_urls[i].name,
1628
0
          _gnutls_custom_urls[i].name_size) == 0) {
1629
0
      if (_gnutls_custom_urls[i].import_pubkey)
1630
0
        return _gnutls_custom_urls[i].import_pubkey(
1631
0
          key, url, flags);
1632
0
    }
1633
0
  }
1634
1635
0
  if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0)
1636
#ifdef ENABLE_PKCS11
1637
    return _gnutls_pubkey_import_pkcs11_url(key, url, flags);
1638
#else
1639
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1640
0
#endif
1641
1642
0
  if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0)
1643
#ifdef HAVE_TROUSERS
1644
    return gnutls_pubkey_import_tpm_url(key, url, NULL, 0);
1645
#else
1646
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1647
0
#endif
1648
1649
0
  return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1650
0
}
1651
1652
/**
1653
 * gnutls_pubkey_import_rsa_raw:
1654
 * @key: The key
1655
 * @m: holds the modulus
1656
 * @e: holds the public exponent
1657
 *
1658
 * This function will replace the parameters in the given structure.
1659
 * The new parameters should be stored in the appropriate
1660
 * gnutls_datum.
1661
 *
1662
 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1663
 *
1664
 * Since: 2.12.0
1665
 **/
1666
int gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m,
1667
         const gnutls_datum_t *e)
1668
0
{
1669
0
  if (key == NULL) {
1670
0
    gnutls_assert();
1671
0
    return GNUTLS_E_INVALID_REQUEST;
1672
0
  }
1673
1674
0
  gnutls_pk_params_release(&key->params);
1675
0
  gnutls_pk_params_init(&key->params);
1676
1677
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[0], m->data,
1678
0
             m->size)) {
1679
0
    gnutls_assert();
1680
0
    return GNUTLS_E_MPI_SCAN_FAILED;
1681
0
  }
1682
1683
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[1], e->data,
1684
0
             e->size)) {
1685
0
    gnutls_assert();
1686
0
    _gnutls_mpi_release(&key->params.params[0]);
1687
0
    return GNUTLS_E_MPI_SCAN_FAILED;
1688
0
  }
1689
1690
0
  key->params.params_nr = RSA_PUBLIC_PARAMS;
1691
0
  key->params.algo = GNUTLS_PK_RSA;
1692
0
  key->bits = pubkey_to_bits(&key->params);
1693
1694
0
  return 0;
1695
0
}
1696
1697
/**
1698
 * gnutls_pubkey_import_ecc_raw:
1699
 * @key: The structure to store the parsed key
1700
 * @curve: holds the curve
1701
 * @x: holds the x-coordinate
1702
 * @y: holds the y-coordinate
1703
 *
1704
 * This function will convert the given elliptic curve parameters to a
1705
 * #gnutls_pubkey_t.  The output will be stored in @key.
1706
 *
1707
 * In EdDSA curves the @y parameter should be %NULL and the @x parameter must
1708
 * be the value in the native format for the curve.
1709
 *
1710
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1711
 *   negative error value.
1712
 *
1713
 * Since: 3.0
1714
 **/
1715
int gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
1716
         const gnutls_datum_t *x,
1717
         const gnutls_datum_t *y)
1718
0
{
1719
0
  int ret;
1720
1721
0
  if (key == NULL || x == NULL) {
1722
0
    gnutls_assert();
1723
0
    return GNUTLS_E_INVALID_REQUEST;
1724
0
  }
1725
1726
0
  gnutls_pk_params_release(&key->params);
1727
0
  gnutls_pk_params_init(&key->params);
1728
1729
0
  if (curve_is_eddsa(curve) || curve_is_modern_ecdh(curve)) {
1730
0
    unsigned size = gnutls_ecc_curve_get_size(curve);
1731
0
    if (x->size != size) {
1732
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1733
0
      goto cleanup;
1734
0
    }
1735
1736
0
    ret = _gnutls_set_datum(&key->params.raw_pub, x->data, x->size);
1737
0
    if (ret < 0) {
1738
0
      gnutls_assert();
1739
0
      goto cleanup;
1740
0
    }
1741
1742
0
    switch (curve) {
1743
0
    case GNUTLS_ECC_CURVE_ED25519:
1744
0
      key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1745
0
      break;
1746
0
    case GNUTLS_ECC_CURVE_ED448:
1747
0
      key->params.algo = GNUTLS_PK_EDDSA_ED448;
1748
0
      break;
1749
0
    case GNUTLS_ECC_CURVE_X25519:
1750
0
      key->params.algo = GNUTLS_PK_ECDH_X25519;
1751
0
      break;
1752
0
    case GNUTLS_ECC_CURVE_X448:
1753
0
      key->params.algo = GNUTLS_PK_ECDH_X448;
1754
0
      break;
1755
0
    default:
1756
0
      break;
1757
0
    }
1758
0
    key->params.curve = curve;
1759
0
    key->bits = pubkey_to_bits(&key->params);
1760
1761
0
    return 0;
1762
0
  }
1763
1764
  /* ECDSA */
1765
0
  if (y == NULL) {
1766
0
    gnutls_assert();
1767
0
    return GNUTLS_E_INVALID_REQUEST;
1768
0
  }
1769
1770
0
  key->params.curve = curve;
1771
1772
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[ECC_X], x->data,
1773
0
             x->size)) {
1774
0
    gnutls_assert();
1775
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1776
0
    goto cleanup;
1777
0
  }
1778
0
  key->params.params_nr++;
1779
1780
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[ECC_Y], y->data,
1781
0
             y->size)) {
1782
0
    gnutls_assert();
1783
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1784
0
    goto cleanup;
1785
0
  }
1786
0
  key->params.params_nr++;
1787
0
  key->params.algo = GNUTLS_PK_ECDSA;
1788
0
  key->bits = pubkey_to_bits(&key->params);
1789
1790
0
  return 0;
1791
1792
0
cleanup:
1793
0
  gnutls_pk_params_release(&key->params);
1794
0
  return ret;
1795
0
}
1796
1797
/**
1798
 * gnutls_pubkey_import_ecc_x962:
1799
 * @key: The structure to store the parsed key
1800
 * @parameters: DER encoding of an ANSI X9.62 parameters
1801
 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1802
 *
1803
 * This function will convert the given elliptic curve parameters to a
1804
 * #gnutls_pubkey_t.  The output will be stored in @key.
1805
 *
1806
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1807
 *   negative error value.
1808
 *
1809
 * Since: 3.0
1810
 **/
1811
int gnutls_pubkey_import_ecc_x962(gnutls_pubkey_t key,
1812
          const gnutls_datum_t *parameters,
1813
          const gnutls_datum_t *ecpoint)
1814
0
{
1815
0
  int ret;
1816
0
  gnutls_datum_t raw_point = { NULL, 0 };
1817
1818
0
  if (key == NULL) {
1819
0
    gnutls_assert();
1820
0
    return GNUTLS_E_INVALID_REQUEST;
1821
0
  }
1822
1823
0
  gnutls_pk_params_release(&key->params);
1824
0
  gnutls_pk_params_init(&key->params);
1825
1826
0
  key->params.params_nr = 0;
1827
1828
0
  ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size,
1829
0
             &key->params.curve);
1830
0
  if (ret < 0) {
1831
0
    gnutls_assert();
1832
0
    goto cleanup;
1833
0
  }
1834
1835
0
  ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, ecpoint->data,
1836
0
           ecpoint->size, &raw_point, 0);
1837
0
  if (ret < 0) {
1838
0
    gnutls_assert();
1839
0
    goto cleanup;
1840
0
  }
1841
1842
0
  ret = _gnutls_ecc_ansi_x962_import(raw_point.data, raw_point.size,
1843
0
             &key->params.params[ECC_X],
1844
0
             &key->params.params[ECC_Y]);
1845
0
  if (ret < 0) {
1846
0
    gnutls_assert();
1847
0
    goto cleanup;
1848
0
  }
1849
0
  key->params.params_nr += 2;
1850
0
  key->params.algo = GNUTLS_PK_EC;
1851
1852
0
  gnutls_free(raw_point.data);
1853
0
  return 0;
1854
1855
0
cleanup:
1856
0
  gnutls_pk_params_release(&key->params);
1857
0
  gnutls_free(raw_point.data);
1858
0
  return ret;
1859
0
}
1860
1861
/**
1862
 * gnutls_pubkey_import_gost_raw:
1863
 * @key: The structure to store the parsed key
1864
 * @curve: holds the curve
1865
 * @digest: holds the digest
1866
 * @paramset: holds the parameters id
1867
 * @x: holds the x-coordinate
1868
 * @y: holds the y-coordinate
1869
 *
1870
 * This function will convert the given GOST public key's parameters to a
1871
 * #gnutls_pubkey_t.  The output will be stored in @key.  @digest should be
1872
 * one of GNUTLS_DIG_GOSR_94, GNUTLS_DIG_STREEBOG_256 or
1873
 * GNUTLS_DIG_STREEBOG_512.  If @paramset is set to GNUTLS_GOST_PARAMSET_UNKNOWN
1874
 * default one will be selected depending on @digest.
1875
 *
1876
 * Note: parameters should be stored with least significant byte first. On
1877
 * version 3.6.3 big-endian format was used incorrectly.
1878
 *
1879
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1880
 *   negative error value.
1881
 *
1882
 * Since: 3.6.3
1883
 **/
1884
int gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
1885
          gnutls_digest_algorithm_t digest,
1886
          gnutls_gost_paramset_t paramset,
1887
          const gnutls_datum_t *x,
1888
          const gnutls_datum_t *y)
1889
0
{
1890
0
  int ret;
1891
0
  gnutls_pk_algorithm_t pk_algo;
1892
1893
0
  if (key == NULL) {
1894
0
    gnutls_assert();
1895
0
    return GNUTLS_E_INVALID_REQUEST;
1896
0
  }
1897
1898
0
  pk_algo = _gnutls_digest_gost(digest);
1899
0
  if (pk_algo == GNUTLS_PK_UNKNOWN)
1900
0
    return GNUTLS_E_ILLEGAL_PARAMETER;
1901
1902
0
  if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1903
0
    paramset = _gnutls_gost_paramset_default(pk_algo);
1904
1905
0
  gnutls_pk_params_release(&key->params);
1906
0
  gnutls_pk_params_init(&key->params);
1907
1908
0
  key->params.curve = curve;
1909
0
  key->params.gost_params = paramset;
1910
1911
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_X], x->data,
1912
0
             x->size)) {
1913
0
    gnutls_assert();
1914
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1915
0
    goto cleanup;
1916
0
  }
1917
0
  key->params.params_nr++;
1918
1919
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_Y], y->data,
1920
0
             y->size)) {
1921
0
    gnutls_assert();
1922
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1923
0
    goto cleanup;
1924
0
  }
1925
0
  key->params.params_nr++;
1926
0
  key->params.algo = pk_algo;
1927
1928
0
  return 0;
1929
1930
0
cleanup:
1931
0
  gnutls_pk_params_release(&key->params);
1932
0
  return ret;
1933
0
}
1934
1935
/**
1936
 * gnutls_pubkey_import_dsa_raw:
1937
 * @key: The structure to store the parsed key
1938
 * @p: holds the p
1939
 * @q: holds the q
1940
 * @g: holds the g
1941
 * @y: holds the y
1942
 *
1943
 * This function will convert the given DSA raw parameters to the
1944
 * native #gnutls_pubkey_t format.  The output will be stored
1945
 * in @key.
1946
 *
1947
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1948
 *   negative error value.
1949
 *
1950
 * Since: 2.12.0
1951
 **/
1952
int gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p,
1953
         const gnutls_datum_t *q,
1954
         const gnutls_datum_t *g,
1955
         const gnutls_datum_t *y)
1956
0
{
1957
0
  int ret;
1958
1959
0
  if (unlikely(key == NULL || p == NULL || q == NULL || g == NULL ||
1960
0
         y == NULL)) {
1961
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1962
0
  }
1963
1964
0
  gnutls_pk_params_release(&key->params);
1965
0
  gnutls_pk_params_init(&key->params);
1966
1967
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_P], p->data,
1968
0
             p->size)) {
1969
0
    gnutls_assert();
1970
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1971
0
    goto cleanup;
1972
0
  }
1973
1974
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Q], q->data,
1975
0
             q->size)) {
1976
0
    gnutls_assert();
1977
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1978
0
    goto cleanup;
1979
0
  }
1980
1981
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_G], g->data,
1982
0
             g->size)) {
1983
0
    gnutls_assert();
1984
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1985
0
    goto cleanup;
1986
0
  }
1987
1988
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Y], y->data,
1989
0
             y->size)) {
1990
0
    gnutls_assert();
1991
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1992
0
    goto cleanup;
1993
0
  }
1994
1995
0
  key->params.params_nr = DSA_PUBLIC_PARAMS;
1996
0
  key->params.algo = GNUTLS_PK_DSA;
1997
0
  key->bits = pubkey_to_bits(&key->params);
1998
1999
0
  return 0;
2000
2001
0
cleanup:
2002
0
  gnutls_pk_params_clear(&key->params);
2003
0
  gnutls_pk_params_release(&key->params);
2004
2005
0
  return ret;
2006
0
}
2007
2008
/**
2009
 * gnutls_pubkey_import_dh_raw:
2010
 * @key: The structure to store the parsed key
2011
 * @params: holds the %gnutls_dh_params_t
2012
 * @y: holds the y
2013
 *
2014
 * This function will convert the given Diffie-Hellman raw parameters
2015
 * to the native #gnutls_pubkey_t format.  The output will be stored
2016
 * in @key.
2017
 *
2018
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2019
 *   negative error value.
2020
 *
2021
 * Since: 3.8.2
2022
 **/
2023
int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key,
2024
        const gnutls_dh_params_t params,
2025
        const gnutls_datum_t *y)
2026
0
{
2027
0
  int ret;
2028
2029
0
  if (unlikely(key == NULL || params == NULL || y == NULL)) {
2030
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2031
0
  }
2032
2033
0
  gnutls_pk_params_release(&key->params);
2034
0
  gnutls_pk_params_init(&key->params);
2035
2036
0
  key->params.params[DH_P] = _gnutls_mpi_copy(params->params[0]);
2037
0
  key->params.params[DH_G] = _gnutls_mpi_copy(params->params[1]);
2038
0
  if (params->params[2]) {
2039
0
    key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
2040
0
  }
2041
0
  key->params.qbits = params->q_bits;
2042
0
  key->params.params_nr = DH_PUBLIC_PARAMS;
2043
2044
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
2045
0
             y->size)) {
2046
0
    gnutls_assert();
2047
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
2048
0
    goto cleanup;
2049
0
  }
2050
2051
0
  key->params.algo = GNUTLS_PK_DH;
2052
0
  key->bits = pubkey_to_bits(&key->params);
2053
2054
0
  return 0;
2055
2056
0
cleanup:
2057
0
  gnutls_pk_params_clear(&key->params);
2058
0
  gnutls_pk_params_release(&key->params);
2059
0
  return ret;
2060
0
}
2061
2062
/* Updates the gnutls_x509_spki_st parameters based on the signature
2063
 * information, and reports any incompatibilities between the existing
2064
 * parameters (if any) with the signature algorithm */
2065
static int fixup_spki_params(const gnutls_pk_params_st *key_params,
2066
           const gnutls_sign_entry_st *se,
2067
           const mac_entry_st *me,
2068
           gnutls_x509_spki_st *params)
2069
0
{
2070
0
  unsigned bits;
2071
2072
0
  if (se->pk != key_params->algo) {
2073
0
    if (!sign_supports_priv_pk_algorithm(se, key_params->algo)) {
2074
0
      _gnutls_debug_log("have key: %s/%d, with sign %s/%d\n",
2075
0
            gnutls_pk_get_name(key_params->algo),
2076
0
            key_params->algo, se->name, se->id);
2077
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2078
0
    }
2079
0
  }
2080
2081
0
  if (params->pk == GNUTLS_PK_RSA_PSS) {
2082
0
    int ret;
2083
0
    if (!GNUTLS_PK_IS_RSA(key_params->algo))
2084
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2085
2086
    /* The requested sign algorithm is RSA-PSS, while the
2087
     * pubkey doesn't include parameter information. Fill
2088
     * it with the same way as gnutls_privkey_sign*. */
2089
0
    if (key_params->algo == GNUTLS_PK_RSA ||
2090
0
        params->rsa_pss_dig == 0) {
2091
0
      bits = pubkey_to_bits(key_params);
2092
0
      params->rsa_pss_dig = se->hash;
2093
0
      ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
2094
0
      if (ret < 0)
2095
0
        return gnutls_assert_val(ret);
2096
2097
0
      params->salt_size = ret;
2098
0
    }
2099
2100
0
    if (params->rsa_pss_dig != se->hash)
2101
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2102
0
  } else if (params->pk == GNUTLS_PK_DSA ||
2103
0
       params->pk == GNUTLS_PK_ECDSA) {
2104
0
    params->dsa_dig = se->hash;
2105
0
  }
2106
2107
0
  return 0;
2108
0
}
2109
2110
/**
2111
 * gnutls_pubkey_verify_data2:
2112
 * @pubkey: Holds the public key
2113
 * @algo: The signature algorithm used
2114
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
2115
 * @data: holds the signed data
2116
 * @signature: contains the signature
2117
 *
2118
 * This function will verify the given signed data, using the
2119
 * parameters from the certificate.
2120
 *
2121
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
2122
 * is returned, and zero or positive code on success. For known to be insecure
2123
 * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
2124
 * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
2125
 *
2126
 * Since: 3.0
2127
 **/
2128
int gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,
2129
             gnutls_sign_algorithm_t algo, unsigned int flags,
2130
             const gnutls_datum_t *data,
2131
             const gnutls_datum_t *signature)
2132
0
{
2133
0
  int ret;
2134
0
  const mac_entry_st *me;
2135
0
  gnutls_x509_spki_st params;
2136
0
  const gnutls_sign_entry_st *se;
2137
2138
0
  if (pubkey == NULL) {
2139
0
    gnutls_assert();
2140
0
    return GNUTLS_E_INVALID_REQUEST;
2141
0
  }
2142
2143
0
  if (flags & GNUTLS_VERIFY_USE_TLS1_RSA)
2144
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2145
2146
0
  se = _gnutls_sign_to_entry(algo);
2147
0
  if (se == NULL)
2148
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2149
2150
0
  ret = pubkey_supports_sig(pubkey, se);
2151
0
  if (ret < 0)
2152
0
    return gnutls_assert_val(ret);
2153
2154
0
  me = hash_to_entry(se->hash);
2155
0
  if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
2156
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2157
2158
0
  ret = _gnutls_x509_spki_copy(&params, &pubkey->params.spki);
2159
0
  if (ret < 0)
2160
0
    return gnutls_assert_val(ret);
2161
2162
0
  params.pk = se->pk;
2163
0
  if (flags & GNUTLS_VERIFY_RSA_PSS_FIXED_SALT_LENGTH) {
2164
0
    params.flags |= GNUTLS_PK_FLAG_RSA_PSS_FIXED_SALT_LENGTH;
2165
0
  }
2166
2167
0
  ret = pubkey_verify_data(se, me, data, signature, &pubkey->params,
2168
0
         &params, flags);
2169
0
  if (ret < 0) {
2170
0
    gnutls_assert();
2171
0
    _gnutls_x509_spki_clear(&params);
2172
0
    return ret;
2173
0
  }
2174
2175
0
  _gnutls_x509_spki_clear(&params);
2176
0
  return 0;
2177
0
}
2178
2179
/**
2180
 * gnutls_pubkey_verify_hash2:
2181
 * @key: Holds the public key
2182
 * @algo: The signature algorithm used
2183
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
2184
 * @hash: holds the hash digest to be verified
2185
 * @signature: contains the signature
2186
 *
2187
 * This function will verify the given signed digest, using the
2188
 * parameters from the public key. Note that unlike gnutls_privkey_sign_hash(),
2189
 * this function accepts a signature algorithm instead of a digest algorithm.
2190
 * You can use gnutls_pk_to_sign() to get the appropriate value.
2191
 *
2192
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
2193
 * is returned, and zero or positive code on success. For known to be insecure
2194
 * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
2195
 * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
2196
 *
2197
 * Since: 3.0
2198
 **/
2199
int gnutls_pubkey_verify_hash2(gnutls_pubkey_t key,
2200
             gnutls_sign_algorithm_t algo, unsigned int flags,
2201
             const gnutls_datum_t *hash,
2202
             const gnutls_datum_t *signature)
2203
0
{
2204
0
  const mac_entry_st *me;
2205
0
  gnutls_x509_spki_st params;
2206
0
  const gnutls_sign_entry_st *se;
2207
0
  int ret;
2208
2209
0
  if (key == NULL) {
2210
0
    gnutls_assert();
2211
0
    return GNUTLS_E_INVALID_REQUEST;
2212
0
  }
2213
2214
0
  if (_gnutls_pk_is_not_prehashed(key->params.algo)) {
2215
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2216
0
  }
2217
2218
0
  ret = _gnutls_x509_spki_copy(&params, &key->params.spki);
2219
0
  if (ret < 0)
2220
0
    return gnutls_assert_val(ret);
2221
2222
0
  if (flags & GNUTLS_VERIFY_USE_TLS1_RSA) {
2223
0
    if (!GNUTLS_PK_IS_RSA(key->params.algo)) {
2224
0
      gnutls_assert();
2225
0
      ret = GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY;
2226
0
      goto cleanup;
2227
0
    }
2228
0
    params.pk = GNUTLS_PK_RSA;
2229
    /* we do not check for insecure algorithms with this flag */
2230
0
    ret = _gnutls_pk_verify(params.pk, hash, signature,
2231
0
          &key->params, &params);
2232
0
    if (ret < 0) {
2233
0
      gnutls_assert();
2234
0
      goto cleanup;
2235
0
    }
2236
0
  } else {
2237
0
    se = _gnutls_sign_to_entry(algo);
2238
0
    if (se == NULL) {
2239
0
      gnutls_assert();
2240
0
      ret = GNUTLS_E_INVALID_REQUEST;
2241
0
      goto cleanup;
2242
0
    }
2243
2244
0
    ret = pubkey_supports_sig(key, se);
2245
0
    if (ret < 0) {
2246
0
      gnutls_assert();
2247
0
      goto cleanup;
2248
0
    }
2249
2250
0
    params.pk = se->pk;
2251
2252
0
    me = hash_to_entry(se->hash);
2253
0
    if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk)) {
2254
0
      gnutls_assert();
2255
0
      ret = GNUTLS_E_INVALID_REQUEST;
2256
0
      goto cleanup;
2257
0
    }
2258
2259
0
    ret = pubkey_verify_hashed_data(se, me, hash, signature,
2260
0
            &key->params, &params, flags);
2261
0
    if (ret < 0) {
2262
0
      gnutls_assert();
2263
0
      goto cleanup;
2264
0
    }
2265
0
  }
2266
2267
0
cleanup:
2268
0
  _gnutls_x509_spki_clear(&params);
2269
0
  return ret;
2270
0
}
2271
2272
/**
2273
 * gnutls_pubkey_encrypt_data:
2274
 * @key: Holds the public key
2275
 * @flags: should be 0 for now
2276
 * @plaintext: The data to be encrypted
2277
 * @ciphertext: contains the encrypted data
2278
 *
2279
 * This function will encrypt the given data, using the public
2280
 * key. On success the @ciphertext will be allocated using gnutls_malloc().
2281
 *
2282
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2283
 *   negative error value.
2284
 *
2285
 * Since: 3.0
2286
 **/
2287
int gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags,
2288
             const gnutls_datum_t *plaintext,
2289
             gnutls_datum_t *ciphertext)
2290
0
{
2291
0
  if (key == NULL) {
2292
0
    gnutls_assert();
2293
0
    return GNUTLS_E_INVALID_REQUEST;
2294
0
  }
2295
2296
0
  return _gnutls_pk_encrypt(key->params.algo, ciphertext, plaintext,
2297
0
          &key->params);
2298
0
}
2299
2300
static int pubkey_supports_sig(gnutls_pubkey_t pubkey,
2301
             const gnutls_sign_entry_st *se)
2302
0
{
2303
0
  if (pubkey->params.algo == GNUTLS_PK_ECDSA && se->curve) {
2304
0
    gnutls_ecc_curve_t curve = pubkey->params.curve;
2305
2306
0
    if (curve != se->curve) {
2307
0
      _gnutls_handshake_log(
2308
0
        "have key: ECDSA with %s/%d, with sign %s/%d\n",
2309
0
        gnutls_ecc_curve_get_name(curve), (int)curve,
2310
0
        se->name, se->id);
2311
0
      return gnutls_assert_val(
2312
0
        GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2313
0
    }
2314
0
  }
2315
2316
0
  if (se->pk !=
2317
0
      pubkey->params
2318
0
        .algo) { /* if the PK algorithm of the signature differs to the one on the pubkey */
2319
0
    if (!sign_supports_priv_pk_algorithm(se, pubkey->params.algo)) {
2320
0
      _gnutls_handshake_log(
2321
0
        "have key: %s/%d, with sign %s/%d\n",
2322
0
        gnutls_pk_get_name(pubkey->params.algo),
2323
0
        pubkey->params.algo, se->name, se->id);
2324
0
      return gnutls_assert_val(
2325
0
        GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2326
0
    }
2327
0
  }
2328
2329
0
  return 0;
2330
0
}
2331
2332
/* Checks whether the public key given is compatible with the
2333
 * signature algorithm used. The session is only used for audit logging, and
2334
 * it may be null.
2335
 */
2336
int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
2337
               gnutls_pubkey_t pubkey,
2338
               const version_entry_st *ver,
2339
               gnutls_sign_algorithm_t sign)
2340
0
{
2341
0
  unsigned int hash_size = 0;
2342
0
  unsigned int sig_hash_size;
2343
0
  const mac_entry_st *me;
2344
0
  const gnutls_sign_entry_st *se;
2345
0
  int ret;
2346
2347
0
  se = _gnutls_sign_to_entry(sign);
2348
0
  if (se != NULL) {
2349
0
    ret = pubkey_supports_sig(pubkey, se);
2350
0
    if (ret < 0)
2351
0
      return gnutls_assert_val(ret);
2352
0
  } else if (_gnutls_version_has_selectable_sighash(ver)) {
2353
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2354
0
  }
2355
2356
0
  if (pubkey->params.algo == GNUTLS_PK_DSA) {
2357
0
    me = _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2358
2359
    /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
2360
0
    if (!_gnutls_version_has_selectable_sighash(ver)) {
2361
0
      if (me->id != GNUTLS_MAC_SHA1)
2362
0
        return gnutls_assert_val(
2363
0
          GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
2364
0
    } else if (se != NULL) {
2365
0
      me = hash_to_entry(se->hash);
2366
2367
0
      sig_hash_size = _gnutls_hash_get_algo_len(me);
2368
0
      if (sig_hash_size < hash_size)
2369
0
        _gnutls_audit_log(
2370
0
          session,
2371
0
          "The hash size used in signature (%u) is less than the expected (%u)\n",
2372
0
          sig_hash_size, hash_size);
2373
0
    }
2374
2375
0
  } else if (pubkey->params.algo == GNUTLS_PK_ECDSA) {
2376
0
    if (_gnutls_version_has_selectable_sighash(ver) && se != NULL) {
2377
0
      _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2378
2379
0
      me = hash_to_entry(se->hash);
2380
2381
0
      sig_hash_size = _gnutls_hash_get_algo_len(me);
2382
2383
0
      if (sig_hash_size < hash_size)
2384
0
        _gnutls_audit_log(
2385
0
          session,
2386
0
          "The hash size used in signature (%u) is less than the expected (%u)\n",
2387
0
          sig_hash_size, hash_size);
2388
0
    }
2389
2390
0
  } else if (pubkey->params.algo == GNUTLS_PK_GOST_01 ||
2391
0
       pubkey->params.algo == GNUTLS_PK_GOST_12_256 ||
2392
0
       pubkey->params.algo == GNUTLS_PK_GOST_12_512) {
2393
0
    if (_gnutls_version_has_selectable_sighash(ver) && se != NULL) {
2394
0
      if (_gnutls_gost_digest(pubkey->params.algo) !=
2395
0
          se->hash) {
2396
0
        _gnutls_audit_log(
2397
0
          session,
2398
0
          "The hash algo used in signature (%u) is not expected (%u)\n",
2399
0
          se->hash,
2400
0
          _gnutls_gost_digest(
2401
0
            pubkey->params.algo));
2402
0
        return gnutls_assert_val(
2403
0
          GNUTLS_E_CONSTRAINT_ERROR);
2404
0
      }
2405
0
    }
2406
2407
0
  } else if (pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
2408
0
    if (!_gnutls_version_has_selectable_sighash(ver))
2409
      /* this should not have happened */
2410
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
2411
2412
    /* RSA PSS public keys are restricted to a single digest, i.e., signature */
2413
2414
0
    if (pubkey->params.spki.rsa_pss_dig &&
2415
0
        pubkey->params.spki.rsa_pss_dig != se->hash) {
2416
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2417
0
    }
2418
0
  }
2419
2420
0
  return 0;
2421
0
}
2422
2423
/* Returns the public key. 
2424
 */
2425
int _gnutls_pubkey_get_mpis(gnutls_pubkey_t key, gnutls_pk_params_st *params)
2426
0
{
2427
0
  return _gnutls_pk_params_copy(params, &key->params);
2428
0
}
2429
2430
/* if hash==MD5 then we do RSA-MD5
2431
 * if hash==SHA then we do RSA-SHA
2432
 * params[0] is modulus
2433
 * params[1] is public key
2434
 */
2435
static int _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
2436
         const mac_entry_st *me,
2437
         const gnutls_datum_t *text,
2438
         const gnutls_datum_t *prehash,
2439
         const gnutls_datum_t *signature,
2440
         gnutls_pk_params_st *params,
2441
         gnutls_x509_spki_st *sign_params)
2442
0
{
2443
0
  int ret;
2444
0
  uint8_t md[MAX_HASH_SIZE], *cmp;
2445
0
  unsigned int digest_size;
2446
0
  gnutls_datum_t d, di;
2447
2448
0
  if (unlikely(me == NULL))
2449
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2450
2451
0
  digest_size = _gnutls_hash_get_algo_len(me);
2452
0
  if (prehash) {
2453
0
    if (prehash->data == NULL || prehash->size != digest_size)
2454
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2455
2456
0
    cmp = prehash->data;
2457
0
  } else {
2458
0
    if (!text) {
2459
0
      gnutls_assert();
2460
0
      return GNUTLS_E_INVALID_REQUEST;
2461
0
    }
2462
2463
0
    ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id,
2464
0
          text->data, text->size, md);
2465
0
    if (ret < 0) {
2466
0
      gnutls_assert();
2467
0
      return ret;
2468
0
    }
2469
2470
0
    cmp = md;
2471
0
  }
2472
2473
0
  d.data = cmp;
2474
0
  d.size = digest_size;
2475
2476
0
  if (pk == GNUTLS_PK_RSA) {
2477
    /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy
2478
     * mode */
2479
0
    switch (me->id) {
2480
0
    case GNUTLS_MAC_SHA1:
2481
0
    case GNUTLS_MAC_SHA256:
2482
0
    case GNUTLS_MAC_SHA384:
2483
0
    case GNUTLS_MAC_SHA512:
2484
0
    case GNUTLS_MAC_SHA224:
2485
0
      break;
2486
0
    default:
2487
0
      _gnutls_switch_fips_state(
2488
0
        GNUTLS_FIPS140_OP_NOT_APPROVED);
2489
0
    }
2490
2491
    /* decrypted is a BER encoded data of type DigestInfo
2492
     */
2493
0
    ret = encode_ber_digest_info(me, &d, &di);
2494
0
    if (ret < 0)
2495
0
      return gnutls_assert_val(ret);
2496
2497
0
    ret = _gnutls_pk_verify(pk, &di, signature, params,
2498
0
          sign_params);
2499
0
    _gnutls_free_datum(&di);
2500
0
  } else {
2501
0
    ret = _gnutls_pk_verify(pk, &d, signature, params, sign_params);
2502
0
  }
2503
2504
0
  return ret;
2505
0
}
2506
2507
/* Hashes input data and verifies a signature.
2508
 */
2509
static int dsa_verify_hashed_data(gnutls_pk_algorithm_t pk,
2510
          const mac_entry_st *algo,
2511
          const gnutls_datum_t *hash,
2512
          const gnutls_datum_t *signature,
2513
          gnutls_pk_params_st *params,
2514
          gnutls_x509_spki_st *sign_params)
2515
0
{
2516
0
  gnutls_datum_t digest;
2517
0
  unsigned int hash_len;
2518
2519
0
  if (algo == NULL)
2520
0
    algo = _gnutls_dsa_q_to_hash(params, &hash_len);
2521
0
  else
2522
0
    hash_len = _gnutls_hash_get_algo_len(algo);
2523
2524
  /* SHA1 or better allowed */
2525
0
  if (!hash->data || hash->size < hash_len) {
2526
0
    gnutls_assert();
2527
0
    _gnutls_debug_log(
2528
0
      "Hash size (%d) does not correspond to hash %s(%d) or better.\n",
2529
0
      (int)hash->size, _gnutls_mac_get_name(algo), hash_len);
2530
2531
0
    if (hash->size != 20) /* SHA1 is allowed */
2532
0
      return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
2533
0
  }
2534
2535
0
  digest.data = hash->data;
2536
0
  digest.size = hash->size;
2537
2538
0
  return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2539
0
}
2540
2541
static int dsa_verify_data(gnutls_pk_algorithm_t pk, const mac_entry_st *algo,
2542
         const gnutls_datum_t *data,
2543
         const gnutls_datum_t *signature,
2544
         gnutls_pk_params_st *params,
2545
         gnutls_x509_spki_st *sign_params)
2546
0
{
2547
0
  int ret;
2548
0
  uint8_t _digest[MAX_HASH_SIZE];
2549
0
  gnutls_datum_t digest;
2550
2551
0
  if (algo == NULL)
2552
0
    algo = _gnutls_dsa_q_to_hash(params, NULL);
2553
2554
0
  ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)algo->id, data->data,
2555
0
        data->size, _digest);
2556
0
  if (ret < 0)
2557
0
    return gnutls_assert_val(ret);
2558
2559
0
  digest.data = _digest;
2560
0
  digest.size = _gnutls_hash_get_algo_len(algo);
2561
2562
0
  return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2563
0
}
2564
2565
/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
2566
 * not verified, or 1 otherwise.
2567
 */
2568
static int pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
2569
             const mac_entry_st *me,
2570
             const gnutls_datum_t *hash,
2571
             const gnutls_datum_t *signature,
2572
             gnutls_pk_params_st *params,
2573
             gnutls_x509_spki_st *sign_params,
2574
             unsigned flags)
2575
0
{
2576
0
  int ret;
2577
2578
0
  if (unlikely(me == NULL))
2579
0
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2580
2581
0
  ret = fixup_spki_params(params, se, me, sign_params);
2582
0
  if (ret < 0)
2583
0
    return gnutls_assert_val(ret);
2584
2585
0
  switch (se->pk) {
2586
0
  case GNUTLS_PK_RSA:
2587
0
  case GNUTLS_PK_RSA_PSS:
2588
2589
0
    if (_pkcs1_rsa_verify_sig(se->pk, me, NULL, hash, signature,
2590
0
            params, sign_params) != 0) {
2591
0
      gnutls_assert();
2592
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2593
0
    }
2594
2595
0
    break;
2596
2597
0
  case GNUTLS_PK_ECDSA:
2598
0
  case GNUTLS_PK_GOST_01:
2599
0
  case GNUTLS_PK_GOST_12_256:
2600
0
  case GNUTLS_PK_GOST_12_512:
2601
0
  case GNUTLS_PK_DSA:
2602
0
    if (dsa_verify_hashed_data(se->pk, me, hash, signature, params,
2603
0
             sign_params) != 0) {
2604
0
      gnutls_assert();
2605
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2606
0
    }
2607
2608
0
    break;
2609
0
  default:
2610
0
    gnutls_assert();
2611
0
    return GNUTLS_E_INVALID_REQUEST;
2612
0
  }
2613
2614
0
  if (_gnutls_sign_is_secure2(se, 0) == 0 &&
2615
0
      _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2616
0
    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2617
0
  }
2618
2619
0
  return 1;
2620
0
}
2621
2622
/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
2623
 * not verified, or 1 otherwise.
2624
 */
2625
int pubkey_verify_data(const gnutls_sign_entry_st *se, const mac_entry_st *me,
2626
           const gnutls_datum_t *data,
2627
           const gnutls_datum_t *signature,
2628
           gnutls_pk_params_st *params,
2629
           gnutls_x509_spki_st *sign_params, unsigned flags)
2630
0
{
2631
0
  int ret;
2632
2633
0
  if (unlikely(me == NULL))
2634
0
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2635
2636
0
  ret = fixup_spki_params(params, se, me, sign_params);
2637
0
  if (ret < 0)
2638
0
    return gnutls_assert_val(ret);
2639
2640
0
  switch (se->pk) {
2641
0
  case GNUTLS_PK_RSA:
2642
0
  case GNUTLS_PK_RSA_PSS:
2643
0
    if (_pkcs1_rsa_verify_sig(se->pk, me, data, NULL, signature,
2644
0
            params, sign_params) != 0) {
2645
0
      gnutls_assert();
2646
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2647
0
    }
2648
2649
0
    break;
2650
2651
0
  case GNUTLS_PK_EDDSA_ED25519:
2652
0
  case GNUTLS_PK_EDDSA_ED448:
2653
0
    if (_gnutls_pk_verify(se->pk, data, signature, params,
2654
0
              sign_params) != 0) {
2655
0
      gnutls_assert();
2656
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2657
0
    }
2658
2659
0
    break;
2660
2661
0
  case GNUTLS_PK_EC:
2662
0
  case GNUTLS_PK_DSA:
2663
0
  case GNUTLS_PK_GOST_01:
2664
0
  case GNUTLS_PK_GOST_12_256:
2665
0
  case GNUTLS_PK_GOST_12_512:
2666
0
    if (dsa_verify_data(se->pk, me, data, signature, params,
2667
0
            sign_params) != 0) {
2668
0
      gnutls_assert();
2669
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2670
0
    }
2671
2672
0
    break;
2673
0
  default:
2674
0
    gnutls_assert();
2675
0
    return GNUTLS_E_INVALID_REQUEST;
2676
0
  }
2677
2678
0
  if (_gnutls_sign_is_secure2(se, 0) == 0 &&
2679
0
      _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2680
0
    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2681
0
  }
2682
2683
0
  return 1;
2684
0
}
2685
2686
const mac_entry_st *_gnutls_dsa_q_to_hash(const gnutls_pk_params_st *params,
2687
            unsigned int *hash_len)
2688
0
{
2689
0
  int bits = 0;
2690
0
  int ret;
2691
2692
0
  if (params->algo == GNUTLS_PK_DSA)
2693
0
    bits = _gnutls_mpi_get_nbits(params->params[1]);
2694
0
  else if (params->algo == GNUTLS_PK_EC)
2695
0
    bits = gnutls_ecc_curve_get_size(params->curve) * 8;
2696
2697
0
  if (bits <= 160) {
2698
0
    if (hash_len)
2699
0
      *hash_len = 20;
2700
0
    ret = GNUTLS_DIG_SHA1;
2701
0
  } else if (bits <= 192) {
2702
0
    if (hash_len)
2703
0
      *hash_len = 24;
2704
0
    ret = GNUTLS_DIG_SHA256;
2705
0
  } else if (bits <= 224) {
2706
0
    if (hash_len)
2707
0
      *hash_len = 28;
2708
0
    ret = GNUTLS_DIG_SHA256;
2709
0
  } else if (bits <= 256) {
2710
0
    if (hash_len)
2711
0
      *hash_len = 32;
2712
0
    ret = GNUTLS_DIG_SHA256;
2713
0
  } else if (bits <= 384) {
2714
0
    if (hash_len)
2715
0
      *hash_len = 48;
2716
0
    ret = GNUTLS_DIG_SHA384;
2717
0
  } else {
2718
0
    if (hash_len)
2719
0
      *hash_len = 64;
2720
0
    ret = GNUTLS_DIG_SHA512;
2721
0
  }
2722
2723
0
  return mac_to_entry(ret);
2724
0
}
2725
2726
/**
2727
 * gnutls_pubkey_set_pin_function:
2728
 * @key: A key of type #gnutls_pubkey_t
2729
 * @fn: the callback
2730
 * @userdata: data associated with the callback
2731
 *
2732
 * This function will set a callback function to be used when
2733
 * required to access the object. This function overrides any other
2734
 * global PIN functions.
2735
 *
2736
 * Note that this function must be called right after initialization
2737
 * to have effect.
2738
 *
2739
 * Since: 3.1.0
2740
 *
2741
 **/
2742
void gnutls_pubkey_set_pin_function(gnutls_pubkey_t key,
2743
            gnutls_pin_callback_t fn, void *userdata)
2744
0
{
2745
0
  key->pin.cb = fn;
2746
0
  key->pin.data = userdata;
2747
0
}
2748
2749
/**
2750
 * gnutls_pubkey_import_x509_raw:
2751
 * @pkey: The public key
2752
 * @data: The public key data to be imported
2753
 * @format: The format of the public key
2754
 * @flags: should be zero
2755
 *
2756
 * This function will import the given public key to the abstract
2757
 * #gnutls_pubkey_t type. 
2758
 *
2759
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2760
 *   negative error value.
2761
 *
2762
 * Since: 3.1.3
2763
 **/
2764
int gnutls_pubkey_import_x509_raw(gnutls_pubkey_t pkey,
2765
          const gnutls_datum_t *data,
2766
          gnutls_x509_crt_fmt_t format,
2767
          unsigned int flags)
2768
0
{
2769
0
  gnutls_x509_crt_t xpriv;
2770
0
  int ret;
2771
2772
0
  ret = gnutls_x509_crt_init(&xpriv);
2773
0
  if (ret < 0)
2774
0
    return gnutls_assert_val(ret);
2775
2776
0
  ret = gnutls_x509_crt_import(xpriv, data, format);
2777
0
  if (ret < 0) {
2778
0
    gnutls_assert();
2779
0
    goto cleanup;
2780
0
  }
2781
2782
0
  ret = gnutls_pubkey_import_x509(pkey, xpriv, flags);
2783
0
  if (ret < 0) {
2784
0
    gnutls_assert();
2785
0
    goto cleanup;
2786
0
  }
2787
2788
0
  ret = 0;
2789
2790
0
cleanup:
2791
0
  gnutls_x509_crt_deinit(xpriv);
2792
2793
0
  return ret;
2794
0
}
2795
2796
/**
2797
 * gnutls_pubkey_verify_params:
2798
 * @key: should contain a #gnutls_pubkey_t type
2799
 *
2800
 * This function will verify the public key parameters.
2801
 *
2802
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2803
 *   negative error value.
2804
 *
2805
 * Since: 3.3.0
2806
 **/
2807
int gnutls_pubkey_verify_params(gnutls_pubkey_t key)
2808
0
{
2809
0
  int ret;
2810
2811
0
  ret = _gnutls_pk_verify_pub_params(key->params.algo, &key->params);
2812
0
  if (ret < 0) {
2813
0
    gnutls_assert();
2814
0
    return ret;
2815
0
  }
2816
2817
0
  return 0;
2818
0
}
2819
2820
/**
2821
 * gnutls_pubkey_get_spki:
2822
 * @pubkey: a public key of type #gnutls_pubkey_t
2823
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2824
 * @flags: must be zero
2825
 *
2826
 * This function will return the public key information if available.
2827
 * The provided @spki must be initialized.
2828
 *
2829
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2830
 *   negative error value.
2831
 *
2832
 * Since: 3.6.0
2833
 **/
2834
int gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey, gnutls_x509_spki_t spki,
2835
         unsigned int flags)
2836
0
{
2837
0
  gnutls_x509_spki_t p = &pubkey->params.spki;
2838
2839
0
  if (pubkey == NULL) {
2840
0
    gnutls_assert();
2841
0
    return GNUTLS_E_INVALID_REQUEST;
2842
0
  }
2843
2844
0
  if (p->pk == GNUTLS_PK_UNKNOWN)
2845
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2846
2847
0
  return _gnutls_x509_spki_copy(spki, p);
2848
0
}
2849
2850
/**
2851
 * gnutls_pubkey_set_spki:
2852
 * @pubkey: a public key of type #gnutls_pubkey_t
2853
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2854
 * @flags: must be zero
2855
 *
2856
 * This function will set the public key information.
2857
 * The provided @spki must be initialized.
2858
 *
2859
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2860
 *   negative error value.
2861
 *
2862
 * Since: 3.6.0
2863
 **/
2864
int gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey,
2865
         const gnutls_x509_spki_t spki, unsigned int flags)
2866
0
{
2867
0
  int ret;
2868
2869
0
  if (pubkey == NULL) {
2870
0
    gnutls_assert();
2871
0
    return GNUTLS_E_INVALID_REQUEST;
2872
0
  }
2873
2874
0
  if (!_gnutls_pk_are_compat(pubkey->params.algo, spki->pk))
2875
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2876
2877
0
  ret = _gnutls_x509_spki_copy(&pubkey->params.spki, spki);
2878
0
  if (ret < 0)
2879
0
    return gnutls_assert_val(ret);
2880
2881
0
  pubkey->params.algo = spki->pk;
2882
2883
0
  return 0;
2884
0
}