Coverage Report

Created: 2026-11-12 06:28

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