Coverage Report

Created: 2026-03-31 07:20

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 (strcmp(str, "oId") == 0) {
417
    etype = ASN1_ETYPE_OBJECT_ID;
418
  } else if (strcmp(str, "curveName") == 0) {
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 (strcmp(str, "oId") == 0) {
587
    etype = ASN1_ETYPE_OBJECT_ID;
588
  } else if (strcmp(str, "curveName") == 0) {
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_import:
1425
 * @key: The public key. 
1426
 * @data: The DER or PEM encoded certificate. 
1427
 * @format: One of DER or PEM 
1428
 * 
1429
 * This function will import the provided public key in
1430
 * a SubjectPublicKeyInfo X.509 structure to a native
1431
 * %gnutls_pubkey_t type. The output will be stored 
1432
 * in @key. If the public key is PEM encoded it should have a header 
1433
 * of "PUBLIC KEY". 
1434
 * 
1435
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1436
 * negative error value.
1437
 *
1438
 * Since: 2.12.0
1439
 **/
1440
int gnutls_pubkey_import(gnutls_pubkey_t key, const gnutls_datum_t *data,
1441
       gnutls_x509_crt_fmt_t format)
1442
0
{
1443
0
  int result = 0, need_free = 0;
1444
0
  gnutls_datum_t _data;
1445
0
  asn1_node spk;
1446
1447
0
  if (key == NULL) {
1448
0
    gnutls_assert();
1449
0
    return GNUTLS_E_INVALID_REQUEST;
1450
0
  }
1451
1452
0
  _data.data = data->data;
1453
0
  _data.size = data->size;
1454
1455
  /* If the Certificate is in PEM format then decode it
1456
   */
1457
0
  if (format == GNUTLS_X509_FMT_PEM) {
1458
    /* Try the first header */
1459
0
    result = _gnutls_fbase64_decode(PEM_PK, data->data, data->size,
1460
0
            &_data);
1461
1462
0
    if (result < 0) {
1463
0
      gnutls_assert();
1464
0
      return result;
1465
0
    }
1466
1467
0
    need_free = 1;
1468
0
  }
1469
1470
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
1471
0
            "PKIX1.SubjectPublicKeyInfo",
1472
0
            &spk)) != ASN1_SUCCESS) {
1473
0
    gnutls_assert();
1474
0
    result = _gnutls_asn2err(result);
1475
0
    goto cleanup;
1476
0
  }
1477
1478
0
  result = _asn1_strict_der_decode(&spk, _data.data, _data.size, NULL);
1479
0
  if (result != ASN1_SUCCESS) {
1480
0
    gnutls_assert();
1481
0
    result = _gnutls_asn2err(result);
1482
0
    goto cleanup;
1483
0
  }
1484
1485
0
  result = _gnutls_get_asn_mpis(spk, "", &key->params);
1486
0
  if (result < 0) {
1487
0
    gnutls_assert();
1488
0
    goto cleanup;
1489
0
  }
1490
1491
0
  key->bits = pubkey_to_bits(&key->params);
1492
0
  result = 0;
1493
1494
0
cleanup:
1495
0
  asn1_delete_structure(&spk);
1496
1497
0
  if (need_free)
1498
0
    _gnutls_free_datum(&_data);
1499
0
  return result;
1500
0
}
1501
1502
/**
1503
 * gnutls_x509_crt_set_pubkey:
1504
 * @crt: should contain a #gnutls_x509_crt_t type
1505
 * @key: holds a public key
1506
 *
1507
 * This function will set the public parameters from the given public
1508
 * key to the certificate. The @key can be deallocated after that.
1509
 *
1510
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1511
 *   negative error value.
1512
 *
1513
 * Since: 2.12.0
1514
 **/
1515
int gnutls_x509_crt_set_pubkey(gnutls_x509_crt_t crt, gnutls_pubkey_t key)
1516
0
{
1517
0
  int result;
1518
1519
0
  if (crt == NULL) {
1520
0
    gnutls_assert();
1521
0
    return GNUTLS_E_INVALID_REQUEST;
1522
0
  }
1523
1524
0
  result = _gnutls_x509_encode_and_copy_PKI_params(
1525
0
    crt->cert, "tbsCertificate.subjectPublicKeyInfo", &key->params);
1526
1527
0
  if (result < 0) {
1528
0
    gnutls_assert();
1529
0
    return result;
1530
0
  }
1531
1532
0
  if (key->key_usage)
1533
0
    gnutls_x509_crt_set_key_usage(crt, key->key_usage);
1534
1535
0
  return 0;
1536
0
}
1537
1538
/**
1539
 * gnutls_x509_crq_set_pubkey:
1540
 * @crq: should contain a #gnutls_x509_crq_t type
1541
 * @key: holds a public key
1542
 *
1543
 * This function will set the public parameters from the given public
1544
 * key to the request. The @key can be deallocated after that.
1545
 *
1546
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1547
 *   negative error value.
1548
 *
1549
 * Since: 2.12.0
1550
 **/
1551
int gnutls_x509_crq_set_pubkey(gnutls_x509_crq_t crq, gnutls_pubkey_t key)
1552
0
{
1553
0
  int result;
1554
1555
0
  if (crq == NULL) {
1556
0
    gnutls_assert();
1557
0
    return GNUTLS_E_INVALID_REQUEST;
1558
0
  }
1559
1560
0
  result = _gnutls_x509_encode_and_copy_PKI_params(
1561
0
    crq->crq, "certificationRequestInfo.subjectPKInfo",
1562
0
    &key->params);
1563
1564
0
  if (result < 0) {
1565
0
    gnutls_assert();
1566
0
    return result;
1567
0
  }
1568
1569
0
  if (key->key_usage)
1570
0
    gnutls_x509_crq_set_key_usage(crq, key->key_usage);
1571
1572
0
  return 0;
1573
0
}
1574
1575
/**
1576
 * gnutls_pubkey_set_key_usage:
1577
 * @key: a certificate of type #gnutls_x509_crt_t
1578
 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1579
 *
1580
 * This function will set the key usage flags of the public key. This
1581
 * is only useful if the key is to be exported to a certificate or
1582
 * certificate request.
1583
 *
1584
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1585
 *   negative error value.
1586
 *
1587
 * Since: 2.12.0
1588
 **/
1589
int gnutls_pubkey_set_key_usage(gnutls_pubkey_t key, unsigned int usage)
1590
0
{
1591
0
  key->key_usage = usage;
1592
1593
0
  return 0;
1594
0
}
1595
1596
#ifdef ENABLE_PKCS11
1597
1598
#if 0
1599
/**
1600
 * gnutls_pubkey_import_pkcs11_url:
1601
 * @key: A key of type #gnutls_pubkey_t
1602
 * @url: A PKCS 11 url
1603
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1604
 *
1605
 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1606
 * structure.
1607
 *
1608
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1609
 *   negative error value.
1610
 *
1611
 * Since: 2.12.0
1612
 **/
1613
int
1614
gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
1615
        unsigned int flags)
1616
{
1617
  int x;
1618
}
1619
#endif
1620
1621
static int _gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key,
1622
              const char *url, unsigned int flags)
1623
{
1624
  gnutls_pkcs11_obj_t pcrt;
1625
  int ret;
1626
1627
  ret = gnutls_pkcs11_obj_init(&pcrt);
1628
  if (ret < 0) {
1629
    gnutls_assert();
1630
    return ret;
1631
  }
1632
1633
  if (key->pin.cb)
1634
    gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb,
1635
               key->pin.data);
1636
1637
  ret = gnutls_pkcs11_obj_import_url(
1638
    pcrt, url, flags | GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PUBKEY);
1639
  if (ret < 0) {
1640
    gnutls_assert();
1641
    goto cleanup;
1642
  }
1643
1644
  ret = gnutls_pubkey_import_pkcs11(key, pcrt, flags);
1645
  if (ret < 0) {
1646
    gnutls_assert();
1647
    goto cleanup;
1648
  }
1649
1650
  ret = 0;
1651
cleanup:
1652
1653
  gnutls_pkcs11_obj_deinit(pcrt);
1654
1655
  return ret;
1656
}
1657
1658
#endif /* ENABLE_PKCS11 */
1659
1660
/**
1661
 * gnutls_pubkey_import_url:
1662
 * @key: A key of type #gnutls_pubkey_t
1663
 * @url: A PKCS 11 url
1664
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1665
 *
1666
 * This function will import a public key from the provided URL.
1667
 *
1668
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1669
 *   negative error value.
1670
 *
1671
 * Since: 3.1.0
1672
 **/
1673
int gnutls_pubkey_import_url(gnutls_pubkey_t key, const char *url,
1674
           unsigned int flags)
1675
0
{
1676
0
  unsigned i;
1677
1678
0
  for (i = 0; i < _gnutls_custom_urls_size; i++) {
1679
0
    if (strncmp(url, _gnutls_custom_urls[i].name,
1680
0
          _gnutls_custom_urls[i].name_size) == 0) {
1681
0
      if (_gnutls_custom_urls[i].import_pubkey)
1682
0
        return _gnutls_custom_urls[i].import_pubkey(
1683
0
          key, url, flags);
1684
0
    }
1685
0
  }
1686
1687
0
  if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0)
1688
#ifdef ENABLE_PKCS11
1689
    return _gnutls_pubkey_import_pkcs11_url(key, url, flags);
1690
#else
1691
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1692
0
#endif
1693
1694
0
  if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0)
1695
#ifdef HAVE_TROUSERS
1696
    return gnutls_pubkey_import_tpm_url(key, url, NULL, 0);
1697
#else
1698
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1699
0
#endif
1700
1701
0
  return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1702
0
}
1703
1704
/**
1705
 * gnutls_pubkey_import_rsa_raw:
1706
 * @key: The key
1707
 * @m: holds the modulus
1708
 * @e: holds the public exponent
1709
 *
1710
 * This function will replace the parameters in the given structure.
1711
 * The new parameters should be stored in the appropriate
1712
 * gnutls_datum.
1713
 *
1714
 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1715
 *
1716
 * Since: 2.12.0
1717
 **/
1718
int gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m,
1719
         const gnutls_datum_t *e)
1720
0
{
1721
0
  if (key == NULL) {
1722
0
    gnutls_assert();
1723
0
    return GNUTLS_E_INVALID_REQUEST;
1724
0
  }
1725
1726
0
  gnutls_pk_params_release(&key->params);
1727
0
  gnutls_pk_params_init(&key->params);
1728
1729
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[0], m->data,
1730
0
             m->size)) {
1731
0
    gnutls_assert();
1732
0
    return GNUTLS_E_MPI_SCAN_FAILED;
1733
0
  }
1734
1735
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[1], e->data,
1736
0
             e->size)) {
1737
0
    gnutls_assert();
1738
0
    _gnutls_mpi_release(&key->params.params[0]);
1739
0
    return GNUTLS_E_MPI_SCAN_FAILED;
1740
0
  }
1741
1742
0
  key->params.params_nr = RSA_PUBLIC_PARAMS;
1743
0
  key->params.algo = GNUTLS_PK_RSA;
1744
0
  key->bits = pubkey_to_bits(&key->params);
1745
1746
0
  return 0;
1747
0
}
1748
1749
/**
1750
 * gnutls_pubkey_import_ecc_raw:
1751
 * @key: The structure to store the parsed key
1752
 * @curve: holds the curve
1753
 * @x: holds the x-coordinate
1754
 * @y: holds the y-coordinate
1755
 *
1756
 * This function will convert the given elliptic curve parameters to a
1757
 * #gnutls_pubkey_t.  The output will be stored in @key.
1758
 *
1759
 * In EdDSA curves the @y parameter should be %NULL and the @x parameter must
1760
 * be the value in the native format for the curve.
1761
 *
1762
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1763
 *   negative error value.
1764
 *
1765
 * Since: 3.0
1766
 **/
1767
int gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
1768
         const gnutls_datum_t *x,
1769
         const gnutls_datum_t *y)
1770
0
{
1771
0
  int ret;
1772
1773
0
  if (key == NULL || x == NULL) {
1774
0
    gnutls_assert();
1775
0
    return GNUTLS_E_INVALID_REQUEST;
1776
0
  }
1777
1778
0
  gnutls_pk_params_release(&key->params);
1779
0
  gnutls_pk_params_init(&key->params);
1780
1781
0
  if (curve_is_eddsa(curve) || curve_is_modern_ecdh(curve)) {
1782
0
    unsigned size = gnutls_ecc_curve_get_size(curve);
1783
0
    if (x->size != size) {
1784
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1785
0
      goto cleanup;
1786
0
    }
1787
1788
0
    ret = _gnutls_set_datum(&key->params.raw_pub, x->data, x->size);
1789
0
    if (ret < 0) {
1790
0
      gnutls_assert();
1791
0
      goto cleanup;
1792
0
    }
1793
1794
0
    switch (curve) {
1795
0
    case GNUTLS_ECC_CURVE_ED25519:
1796
0
      key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1797
0
      break;
1798
0
    case GNUTLS_ECC_CURVE_ED448:
1799
0
      key->params.algo = GNUTLS_PK_EDDSA_ED448;
1800
0
      break;
1801
0
    case GNUTLS_ECC_CURVE_X25519:
1802
0
      key->params.algo = GNUTLS_PK_ECDH_X25519;
1803
0
      break;
1804
0
    case GNUTLS_ECC_CURVE_X448:
1805
0
      key->params.algo = GNUTLS_PK_ECDH_X448;
1806
0
      break;
1807
0
    default:
1808
0
      break;
1809
0
    }
1810
0
    key->params.curve = curve;
1811
0
    key->bits = pubkey_to_bits(&key->params);
1812
1813
0
    return 0;
1814
0
  }
1815
1816
  /* ECDSA */
1817
0
  if (y == NULL) {
1818
0
    gnutls_assert();
1819
0
    return GNUTLS_E_INVALID_REQUEST;
1820
0
  }
1821
1822
0
  key->params.curve = curve;
1823
1824
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[ECC_X], x->data,
1825
0
             x->size)) {
1826
0
    gnutls_assert();
1827
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1828
0
    goto cleanup;
1829
0
  }
1830
0
  key->params.params_nr++;
1831
1832
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[ECC_Y], y->data,
1833
0
             y->size)) {
1834
0
    gnutls_assert();
1835
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1836
0
    goto cleanup;
1837
0
  }
1838
0
  key->params.params_nr++;
1839
0
  key->params.algo = GNUTLS_PK_ECDSA;
1840
0
  key->bits = pubkey_to_bits(&key->params);
1841
1842
0
  return 0;
1843
1844
0
cleanup:
1845
0
  gnutls_pk_params_release(&key->params);
1846
0
  return ret;
1847
0
}
1848
1849
/**
1850
 * gnutls_pubkey_import_ecc_x962:
1851
 * @key: The structure to store the parsed key
1852
 * @parameters: DER encoding of an ANSI X9.62 parameters
1853
 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1854
 *
1855
 * This function will convert the given elliptic curve parameters to a
1856
 * #gnutls_pubkey_t.  The output will be stored in @key.
1857
 *
1858
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1859
 *   negative error value.
1860
 *
1861
 * Since: 3.0
1862
 **/
1863
int gnutls_pubkey_import_ecc_x962(gnutls_pubkey_t key,
1864
          const gnutls_datum_t *parameters,
1865
          const gnutls_datum_t *ecpoint)
1866
0
{
1867
0
  int ret;
1868
0
  gnutls_datum_t raw_point = { NULL, 0 };
1869
1870
0
  if (key == NULL) {
1871
0
    gnutls_assert();
1872
0
    return GNUTLS_E_INVALID_REQUEST;
1873
0
  }
1874
1875
0
  gnutls_pk_params_release(&key->params);
1876
0
  gnutls_pk_params_init(&key->params);
1877
1878
0
  key->params.params_nr = 0;
1879
1880
0
  ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size,
1881
0
             &key->params.curve);
1882
0
  if (ret < 0) {
1883
0
    gnutls_assert();
1884
0
    goto cleanup;
1885
0
  }
1886
1887
0
  ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, ecpoint->data,
1888
0
           ecpoint->size, &raw_point, 0);
1889
0
  if (ret < 0) {
1890
0
    gnutls_assert();
1891
0
    goto cleanup;
1892
0
  }
1893
1894
0
  ret = _gnutls_ecc_ansi_x962_import(raw_point.data, raw_point.size,
1895
0
             &key->params.params[ECC_X],
1896
0
             &key->params.params[ECC_Y]);
1897
0
  if (ret < 0) {
1898
0
    gnutls_assert();
1899
0
    goto cleanup;
1900
0
  }
1901
0
  key->params.params_nr += 2;
1902
0
  key->params.algo = GNUTLS_PK_EC;
1903
1904
0
  gnutls_free(raw_point.data);
1905
0
  return 0;
1906
1907
0
cleanup:
1908
0
  gnutls_pk_params_release(&key->params);
1909
0
  gnutls_free(raw_point.data);
1910
0
  return ret;
1911
0
}
1912
1913
/**
1914
 * gnutls_pubkey_import_gost_raw:
1915
 * @key: The structure to store the parsed key
1916
 * @curve: holds the curve
1917
 * @digest: holds the digest
1918
 * @paramset: holds the parameters id
1919
 * @x: holds the x-coordinate
1920
 * @y: holds the y-coordinate
1921
 *
1922
 * This function will convert the given GOST public key's parameters to a
1923
 * #gnutls_pubkey_t.  The output will be stored in @key.  @digest should be
1924
 * one of GNUTLS_DIG_GOSR_94, GNUTLS_DIG_STREEBOG_256 or
1925
 * GNUTLS_DIG_STREEBOG_512.  If @paramset is set to GNUTLS_GOST_PARAMSET_UNKNOWN
1926
 * default one will be selected depending on @digest.
1927
 *
1928
 * Note: parameters should be stored with least significant byte first. On
1929
 * version 3.6.3 big-endian format was used incorrectly.
1930
 *
1931
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1932
 *   negative error value.
1933
 *
1934
 * Since: 3.6.3
1935
 **/
1936
int gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
1937
          gnutls_digest_algorithm_t digest,
1938
          gnutls_gost_paramset_t paramset,
1939
          const gnutls_datum_t *x,
1940
          const gnutls_datum_t *y)
1941
0
{
1942
0
  int ret;
1943
0
  gnutls_pk_algorithm_t pk_algo;
1944
1945
0
  if (key == NULL) {
1946
0
    gnutls_assert();
1947
0
    return GNUTLS_E_INVALID_REQUEST;
1948
0
  }
1949
1950
0
  pk_algo = _gnutls_digest_gost(digest);
1951
0
  if (pk_algo == GNUTLS_PK_UNKNOWN)
1952
0
    return GNUTLS_E_ILLEGAL_PARAMETER;
1953
1954
0
  if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1955
0
    paramset = _gnutls_gost_paramset_default(pk_algo);
1956
1957
0
  gnutls_pk_params_release(&key->params);
1958
0
  gnutls_pk_params_init(&key->params);
1959
1960
0
  key->params.curve = curve;
1961
0
  key->params.gost_params = paramset;
1962
1963
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_X], x->data,
1964
0
             x->size)) {
1965
0
    gnutls_assert();
1966
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1967
0
    goto cleanup;
1968
0
  }
1969
0
  key->params.params_nr++;
1970
1971
0
  if (_gnutls_mpi_init_scan_le(&key->params.params[GOST_Y], y->data,
1972
0
             y->size)) {
1973
0
    gnutls_assert();
1974
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
1975
0
    goto cleanup;
1976
0
  }
1977
0
  key->params.params_nr++;
1978
0
  key->params.algo = pk_algo;
1979
1980
0
  return 0;
1981
1982
0
cleanup:
1983
0
  gnutls_pk_params_release(&key->params);
1984
0
  return ret;
1985
0
}
1986
1987
/**
1988
 * gnutls_pubkey_import_dsa_raw:
1989
 * @key: The structure to store the parsed key
1990
 * @p: holds the p
1991
 * @q: holds the q
1992
 * @g: holds the g
1993
 * @y: holds the y
1994
 *
1995
 * This function will convert the given DSA raw parameters to the
1996
 * native #gnutls_pubkey_t format.  The output will be stored
1997
 * in @key.
1998
 *
1999
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2000
 *   negative error value.
2001
 *
2002
 * Since: 2.12.0
2003
 **/
2004
int gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p,
2005
         const gnutls_datum_t *q,
2006
         const gnutls_datum_t *g,
2007
         const gnutls_datum_t *y)
2008
0
{
2009
0
  int ret;
2010
2011
0
  if (unlikely(key == NULL || p == NULL || q == NULL || g == NULL ||
2012
0
         y == NULL)) {
2013
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2014
0
  }
2015
2016
0
  gnutls_pk_params_release(&key->params);
2017
0
  gnutls_pk_params_init(&key->params);
2018
2019
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_P], p->data,
2020
0
             p->size)) {
2021
0
    gnutls_assert();
2022
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
2023
0
    goto cleanup;
2024
0
  }
2025
2026
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Q], q->data,
2027
0
             q->size)) {
2028
0
    gnutls_assert();
2029
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
2030
0
    goto cleanup;
2031
0
  }
2032
2033
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_G], g->data,
2034
0
             g->size)) {
2035
0
    gnutls_assert();
2036
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
2037
0
    goto cleanup;
2038
0
  }
2039
2040
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DSA_Y], y->data,
2041
0
             y->size)) {
2042
0
    gnutls_assert();
2043
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
2044
0
    goto cleanup;
2045
0
  }
2046
2047
0
  key->params.params_nr = DSA_PUBLIC_PARAMS;
2048
0
  key->params.algo = GNUTLS_PK_DSA;
2049
0
  key->bits = pubkey_to_bits(&key->params);
2050
2051
0
  return 0;
2052
2053
0
cleanup:
2054
0
  gnutls_pk_params_clear(&key->params);
2055
0
  gnutls_pk_params_release(&key->params);
2056
2057
0
  return ret;
2058
0
}
2059
2060
/**
2061
 * gnutls_pubkey_import_dh_raw:
2062
 * @key: The structure to store the parsed key
2063
 * @params: holds the %gnutls_dh_params_t
2064
 * @y: holds the y
2065
 *
2066
 * This function will convert the given Diffie-Hellman raw parameters
2067
 * to the native #gnutls_pubkey_t format.  The output will be stored
2068
 * in @key.
2069
 *
2070
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2071
 *   negative error value.
2072
 *
2073
 * Since: 3.8.2
2074
 **/
2075
int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key,
2076
        const gnutls_dh_params_t params,
2077
        const gnutls_datum_t *y)
2078
0
{
2079
0
  int ret;
2080
2081
0
  if (unlikely(key == NULL || params == NULL || y == NULL)) {
2082
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2083
0
  }
2084
2085
0
  gnutls_pk_params_release(&key->params);
2086
0
  gnutls_pk_params_init(&key->params);
2087
2088
0
  key->params.params[DH_P] = _gnutls_mpi_copy(params->params[0]);
2089
0
  key->params.params[DH_G] = _gnutls_mpi_copy(params->params[1]);
2090
0
  if (params->params[2]) {
2091
0
    key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
2092
0
  }
2093
0
  key->params.qbits = params->q_bits;
2094
0
  key->params.params_nr = DH_PUBLIC_PARAMS;
2095
2096
0
  if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
2097
0
             y->size)) {
2098
0
    gnutls_assert();
2099
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
2100
0
    goto cleanup;
2101
0
  }
2102
2103
0
  key->params.algo = GNUTLS_PK_DH;
2104
0
  key->bits = pubkey_to_bits(&key->params);
2105
2106
0
  return 0;
2107
2108
0
cleanup:
2109
0
  gnutls_pk_params_clear(&key->params);
2110
0
  gnutls_pk_params_release(&key->params);
2111
0
  return ret;
2112
0
}
2113
2114
/* Updates the gnutls_x509_spki_st parameters based on the signature
2115
 * information, and reports any incompatibilities between the existing
2116
 * parameters (if any) with the signature algorithm */
2117
static int fixup_spki_params(const gnutls_pk_params_st *key_params,
2118
           const gnutls_sign_entry_st *se,
2119
           const mac_entry_st *me,
2120
           gnutls_x509_spki_st *params)
2121
0
{
2122
0
  unsigned bits;
2123
2124
0
  if (se->pk != key_params->algo) {
2125
0
    if (!sign_supports_priv_pk_algorithm(se, key_params->algo)) {
2126
0
      _gnutls_debug_log("have key: %s/%d, with sign %s/%d\n",
2127
0
            gnutls_pk_get_name(key_params->algo),
2128
0
            key_params->algo, se->name, se->id);
2129
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2130
0
    }
2131
0
  }
2132
2133
0
  if (params->pk == GNUTLS_PK_RSA_PSS) {
2134
0
    int ret;
2135
0
    if (!GNUTLS_PK_IS_RSA(key_params->algo))
2136
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2137
2138
    /* The requested sign algorithm is RSA-PSS, while the
2139
     * pubkey doesn't include parameter information. Fill
2140
     * it with the same way as gnutls_privkey_sign*. */
2141
0
    if (key_params->algo == GNUTLS_PK_RSA ||
2142
0
        params->rsa_pss_dig == 0) {
2143
0
      bits = pubkey_to_bits(key_params);
2144
0
      params->rsa_pss_dig = se->hash;
2145
0
      ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
2146
0
      if (ret < 0)
2147
0
        return gnutls_assert_val(ret);
2148
2149
0
      params->salt_size = ret;
2150
0
    }
2151
2152
0
    if (params->rsa_pss_dig != se->hash)
2153
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2154
0
  } else if (params->pk == GNUTLS_PK_DSA ||
2155
0
       params->pk == GNUTLS_PK_ECDSA) {
2156
0
    params->dsa_dig = se->hash;
2157
0
  }
2158
2159
0
  return 0;
2160
0
}
2161
2162
/**
2163
 * gnutls_pubkey_verify_data2:
2164
 * @pubkey: Holds the public key
2165
 * @algo: The signature algorithm used
2166
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
2167
 * @data: holds the signed data
2168
 * @signature: contains the signature
2169
 *
2170
 * This function will verify the given signed data, using the
2171
 * parameters from the certificate.
2172
 *
2173
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
2174
 * is returned, and zero or positive code on success. For known to be insecure
2175
 * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
2176
 * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
2177
 *
2178
 * Since: 3.0
2179
 **/
2180
int gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,
2181
             gnutls_sign_algorithm_t algo, unsigned int flags,
2182
             const gnutls_datum_t *data,
2183
             const gnutls_datum_t *signature)
2184
0
{
2185
0
  int ret;
2186
0
  const mac_entry_st *me;
2187
0
  gnutls_x509_spki_st params;
2188
0
  const gnutls_sign_entry_st *se;
2189
2190
0
  if (pubkey == NULL) {
2191
0
    gnutls_assert();
2192
0
    return GNUTLS_E_INVALID_REQUEST;
2193
0
  }
2194
2195
0
  if (flags & GNUTLS_VERIFY_USE_TLS1_RSA)
2196
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2197
2198
0
  se = _gnutls_sign_to_entry(algo);
2199
0
  if (se == NULL)
2200
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2201
2202
0
  ret = pubkey_supports_sig(pubkey, se);
2203
0
  if (ret < 0)
2204
0
    return gnutls_assert_val(ret);
2205
2206
0
  me = hash_to_entry(se->hash);
2207
0
  if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
2208
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2209
2210
0
  ret = _gnutls_x509_spki_copy(&params, &pubkey->params.spki);
2211
0
  if (ret < 0)
2212
0
    return gnutls_assert_val(ret);
2213
2214
0
  params.pk = se->pk;
2215
0
  if (flags & GNUTLS_VERIFY_RSA_PSS_FIXED_SALT_LENGTH) {
2216
0
    params.flags |= GNUTLS_PK_FLAG_RSA_PSS_FIXED_SALT_LENGTH;
2217
0
  }
2218
2219
0
  ret = pubkey_verify_data(se, me, data, signature, &pubkey->params,
2220
0
         &params, flags);
2221
0
  if (ret < 0) {
2222
0
    gnutls_assert();
2223
0
    _gnutls_x509_spki_clear(&params);
2224
0
    return ret;
2225
0
  }
2226
2227
0
  _gnutls_x509_spki_clear(&params);
2228
0
  return 0;
2229
0
}
2230
2231
/**
2232
 * gnutls_pubkey_verify_hash2:
2233
 * @key: Holds the public key
2234
 * @algo: The signature algorithm used
2235
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
2236
 * @hash: holds the hash digest to be verified
2237
 * @signature: contains the signature
2238
 *
2239
 * This function will verify the given signed digest, using the
2240
 * parameters from the public key. Note that unlike gnutls_privkey_sign_hash(),
2241
 * this function accepts a signature algorithm instead of a digest algorithm.
2242
 * You can use gnutls_pk_to_sign() to get the appropriate value.
2243
 *
2244
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
2245
 * is returned, and zero or positive code on success. For known to be insecure
2246
 * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
2247
 * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
2248
 *
2249
 * Since: 3.0
2250
 **/
2251
int gnutls_pubkey_verify_hash2(gnutls_pubkey_t key,
2252
             gnutls_sign_algorithm_t algo, unsigned int flags,
2253
             const gnutls_datum_t *hash,
2254
             const gnutls_datum_t *signature)
2255
0
{
2256
0
  const mac_entry_st *me;
2257
0
  gnutls_x509_spki_st params;
2258
0
  const gnutls_sign_entry_st *se;
2259
0
  int ret;
2260
2261
0
  if (key == NULL) {
2262
0
    gnutls_assert();
2263
0
    return GNUTLS_E_INVALID_REQUEST;
2264
0
  }
2265
2266
0
  if (_gnutls_pk_is_not_prehashed(key->params.algo)) {
2267
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2268
0
  }
2269
2270
0
  ret = _gnutls_x509_spki_copy(&params, &key->params.spki);
2271
0
  if (ret < 0)
2272
0
    return gnutls_assert_val(ret);
2273
2274
0
  if (flags & GNUTLS_VERIFY_USE_TLS1_RSA) {
2275
0
    if (!GNUTLS_PK_IS_RSA(key->params.algo)) {
2276
0
      gnutls_assert();
2277
0
      ret = GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY;
2278
0
      goto cleanup;
2279
0
    }
2280
0
    params.pk = GNUTLS_PK_RSA;
2281
    /* we do not check for insecure algorithms with this flag */
2282
0
    ret = _gnutls_pk_verify(params.pk, hash, signature,
2283
0
          &key->params, &params);
2284
0
    if (ret < 0) {
2285
0
      gnutls_assert();
2286
0
      goto cleanup;
2287
0
    }
2288
0
  } else {
2289
0
    se = _gnutls_sign_to_entry(algo);
2290
0
    if (se == NULL) {
2291
0
      gnutls_assert();
2292
0
      ret = GNUTLS_E_INVALID_REQUEST;
2293
0
      goto cleanup;
2294
0
    }
2295
2296
0
    ret = pubkey_supports_sig(key, se);
2297
0
    if (ret < 0) {
2298
0
      gnutls_assert();
2299
0
      goto cleanup;
2300
0
    }
2301
2302
0
    params.pk = se->pk;
2303
2304
0
    me = hash_to_entry(se->hash);
2305
0
    if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk)) {
2306
0
      gnutls_assert();
2307
0
      ret = GNUTLS_E_INVALID_REQUEST;
2308
0
      goto cleanup;
2309
0
    }
2310
2311
0
    ret = pubkey_verify_hashed_data(se, me, hash, signature,
2312
0
            &key->params, &params, flags);
2313
0
    if (ret < 0) {
2314
0
      gnutls_assert();
2315
0
      goto cleanup;
2316
0
    }
2317
0
  }
2318
2319
0
cleanup:
2320
0
  _gnutls_x509_spki_clear(&params);
2321
0
  return ret;
2322
0
}
2323
2324
/**
2325
 * gnutls_pubkey_encrypt_data:
2326
 * @key: Holds the public key
2327
 * @flags: should be 0 for now
2328
 * @plaintext: The data to be encrypted
2329
 * @ciphertext: contains the encrypted data
2330
 *
2331
 * This function will encrypt the given data, using the public
2332
 * key. On success the @ciphertext will be allocated using gnutls_malloc().
2333
 *
2334
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2335
 *   negative error value.
2336
 *
2337
 * Since: 3.0
2338
 **/
2339
int gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags,
2340
             const gnutls_datum_t *plaintext,
2341
             gnutls_datum_t *ciphertext)
2342
0
{
2343
0
  if (key == NULL) {
2344
0
    gnutls_assert();
2345
0
    return GNUTLS_E_INVALID_REQUEST;
2346
0
  }
2347
2348
0
  return _gnutls_pk_encrypt(key->params.algo, ciphertext, plaintext,
2349
0
          &key->params, &key->params.spki);
2350
0
}
2351
2352
static int pubkey_supports_sig(gnutls_pubkey_t pubkey,
2353
             const gnutls_sign_entry_st *se)
2354
0
{
2355
0
  if (pubkey->params.algo == GNUTLS_PK_ECDSA && se->curve) {
2356
0
    gnutls_ecc_curve_t curve = pubkey->params.curve;
2357
2358
0
    if (curve != se->curve) {
2359
0
      _gnutls_handshake_log(
2360
0
        "have key: ECDSA with %s/%d, with sign %s/%d\n",
2361
0
        gnutls_ecc_curve_get_name(curve), (int)curve,
2362
0
        se->name, se->id);
2363
0
      return gnutls_assert_val(
2364
0
        GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2365
0
    }
2366
0
  }
2367
2368
0
  if (se->pk !=
2369
0
      pubkey->params
2370
0
        .algo) { /* if the PK algorithm of the signature differs to the one on the pubkey */
2371
0
    if (!sign_supports_priv_pk_algorithm(se, pubkey->params.algo)) {
2372
0
      _gnutls_handshake_log(
2373
0
        "have key: %s/%d, with sign %s/%d\n",
2374
0
        gnutls_pk_get_name(pubkey->params.algo),
2375
0
        pubkey->params.algo, se->name, se->id);
2376
0
      return gnutls_assert_val(
2377
0
        GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2378
0
    }
2379
0
  }
2380
2381
0
  return 0;
2382
0
}
2383
2384
/* Checks whether the public key given is compatible with the
2385
 * signature algorithm used. The session is only used for audit logging, and
2386
 * it may be null.
2387
 */
2388
int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
2389
               gnutls_pubkey_t pubkey,
2390
               const version_entry_st *ver,
2391
               gnutls_sign_algorithm_t sign)
2392
0
{
2393
0
  unsigned int hash_size = 0;
2394
0
  unsigned int sig_hash_size;
2395
0
  const mac_entry_st *me;
2396
0
  const gnutls_sign_entry_st *se;
2397
0
  int ret;
2398
2399
0
  se = _gnutls_sign_to_entry(sign);
2400
0
  if (se != NULL) {
2401
0
    ret = pubkey_supports_sig(pubkey, se);
2402
0
    if (ret < 0)
2403
0
      return gnutls_assert_val(ret);
2404
0
  } else if (_gnutls_version_has_selectable_sighash(ver)) {
2405
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2406
0
  }
2407
2408
0
  if (pubkey->params.algo == GNUTLS_PK_DSA) {
2409
0
    me = _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2410
2411
    /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
2412
0
    if (!_gnutls_version_has_selectable_sighash(ver)) {
2413
0
      if (me->id != GNUTLS_MAC_SHA1)
2414
0
        return gnutls_assert_val(
2415
0
          GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
2416
0
    } else if (se != NULL) {
2417
0
      me = hash_to_entry(se->hash);
2418
2419
0
      sig_hash_size = _gnutls_hash_get_algo_len(me);
2420
0
      if (sig_hash_size < hash_size)
2421
0
        _gnutls_audit_log(
2422
0
          session,
2423
0
          "The hash size used in signature (%u) is less than the expected (%u)\n",
2424
0
          sig_hash_size, hash_size);
2425
0
    }
2426
2427
0
  } else if (pubkey->params.algo == GNUTLS_PK_ECDSA) {
2428
0
    if (_gnutls_version_has_selectable_sighash(ver) && se != NULL) {
2429
0
      _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2430
2431
0
      me = hash_to_entry(se->hash);
2432
2433
0
      sig_hash_size = _gnutls_hash_get_algo_len(me);
2434
2435
0
      if (sig_hash_size < hash_size)
2436
0
        _gnutls_audit_log(
2437
0
          session,
2438
0
          "The hash size used in signature (%u) is less than the expected (%u)\n",
2439
0
          sig_hash_size, hash_size);
2440
0
    }
2441
2442
0
  } else if (pubkey->params.algo == GNUTLS_PK_GOST_01 ||
2443
0
       pubkey->params.algo == GNUTLS_PK_GOST_12_256 ||
2444
0
       pubkey->params.algo == GNUTLS_PK_GOST_12_512) {
2445
0
    if (_gnutls_version_has_selectable_sighash(ver) && se != NULL) {
2446
0
      if (_gnutls_gost_digest(pubkey->params.algo) !=
2447
0
          se->hash) {
2448
0
        _gnutls_audit_log(
2449
0
          session,
2450
0
          "The hash algo used in signature (%u) is not expected (%u)\n",
2451
0
          se->hash,
2452
0
          _gnutls_gost_digest(
2453
0
            pubkey->params.algo));
2454
0
        return gnutls_assert_val(
2455
0
          GNUTLS_E_CONSTRAINT_ERROR);
2456
0
      }
2457
0
    }
2458
2459
0
  } else if (pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
2460
0
    if (!_gnutls_version_has_selectable_sighash(ver))
2461
      /* this should not have happened */
2462
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
2463
2464
    /* RSA PSS public keys are restricted to a single digest, i.e., signature */
2465
2466
0
    if (pubkey->params.spki.rsa_pss_dig &&
2467
0
        pubkey->params.spki.rsa_pss_dig != se->hash) {
2468
0
      return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2469
0
    }
2470
0
  }
2471
2472
0
  return 0;
2473
0
}
2474
2475
/* Returns the public key. 
2476
 */
2477
int _gnutls_pubkey_get_mpis(gnutls_pubkey_t key, gnutls_pk_params_st *params)
2478
0
{
2479
0
  return _gnutls_pk_params_copy(params, &key->params);
2480
0
}
2481
2482
/* if hash==MD5 then we do RSA-MD5
2483
 * if hash==SHA then we do RSA-SHA
2484
 * params[0] is modulus
2485
 * params[1] is public key
2486
 */
2487
static int _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
2488
         const mac_entry_st *me,
2489
         const gnutls_datum_t *text,
2490
         const gnutls_datum_t *prehash,
2491
         const gnutls_datum_t *signature,
2492
         gnutls_pk_params_st *params,
2493
         gnutls_x509_spki_st *sign_params)
2494
0
{
2495
0
  int ret;
2496
0
  uint8_t md[MAX_HASH_SIZE], *cmp;
2497
0
  unsigned int digest_size;
2498
0
  gnutls_datum_t d, di;
2499
2500
0
  if (unlikely(me == NULL))
2501
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2502
2503
0
  digest_size = _gnutls_hash_get_algo_len(me);
2504
0
  if (prehash) {
2505
0
    if (prehash->data == NULL || prehash->size != digest_size)
2506
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2507
2508
0
    cmp = prehash->data;
2509
0
  } else {
2510
0
    if (!text) {
2511
0
      gnutls_assert();
2512
0
      return GNUTLS_E_INVALID_REQUEST;
2513
0
    }
2514
2515
0
    ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id,
2516
0
          text->data, text->size, md);
2517
0
    if (ret < 0) {
2518
0
      gnutls_assert();
2519
0
      return ret;
2520
0
    }
2521
2522
0
    cmp = md;
2523
0
  }
2524
2525
0
  d.data = cmp;
2526
0
  d.size = digest_size;
2527
2528
0
  if (pk == GNUTLS_PK_RSA) {
2529
0
    switch (me->id) {
2530
0
    case GNUTLS_MAC_SHA256:
2531
0
    case GNUTLS_MAC_SHA384:
2532
0
    case GNUTLS_MAC_SHA512:
2533
0
    case GNUTLS_MAC_SHA224:
2534
0
      break;
2535
0
    default:
2536
0
      _gnutls_switch_fips_state(
2537
0
        GNUTLS_FIPS140_OP_NOT_APPROVED);
2538
0
    }
2539
2540
    /* decrypted is a BER encoded data of type DigestInfo
2541
     */
2542
0
    ret = encode_ber_digest_info(me, &d, &di);
2543
0
    if (ret < 0)
2544
0
      return gnutls_assert_val(ret);
2545
2546
0
    ret = _gnutls_pk_verify(pk, &di, signature, params,
2547
0
          sign_params);
2548
0
    _gnutls_free_datum(&di);
2549
0
  } else {
2550
0
    ret = _gnutls_pk_verify(pk, &d, signature, params, sign_params);
2551
0
  }
2552
2553
0
  return ret;
2554
0
}
2555
2556
/* Hashes input data and verifies a signature.
2557
 */
2558
static int dsa_verify_hashed_data(gnutls_pk_algorithm_t pk,
2559
          const mac_entry_st *algo,
2560
          const gnutls_datum_t *hash,
2561
          const gnutls_datum_t *signature,
2562
          gnutls_pk_params_st *params,
2563
          gnutls_x509_spki_st *sign_params)
2564
0
{
2565
0
  gnutls_datum_t digest;
2566
0
  unsigned int hash_len;
2567
2568
0
  if (algo == NULL)
2569
0
    algo = _gnutls_dsa_q_to_hash(params, &hash_len);
2570
0
  else
2571
0
    hash_len = _gnutls_hash_get_algo_len(algo);
2572
2573
  /* SHA1 or better allowed */
2574
0
  if (!hash->data || hash->size < hash_len) {
2575
0
    gnutls_assert();
2576
0
    _gnutls_debug_log(
2577
0
      "Hash size (%d) does not correspond to hash %s(%d) or better.\n",
2578
0
      (int)hash->size, _gnutls_mac_get_name(algo), hash_len);
2579
2580
0
    if (hash->size != 20) /* SHA1 is allowed */
2581
0
      return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
2582
0
  }
2583
2584
0
  digest.data = hash->data;
2585
0
  digest.size = hash->size;
2586
2587
0
  return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2588
0
}
2589
2590
static int dsa_verify_data(gnutls_pk_algorithm_t pk, const mac_entry_st *algo,
2591
         const gnutls_datum_t *data,
2592
         const gnutls_datum_t *signature,
2593
         gnutls_pk_params_st *params,
2594
         gnutls_x509_spki_st *sign_params)
2595
0
{
2596
0
  int ret;
2597
0
  uint8_t _digest[MAX_HASH_SIZE];
2598
0
  gnutls_datum_t digest;
2599
2600
0
  if (algo == NULL)
2601
0
    algo = _gnutls_dsa_q_to_hash(params, NULL);
2602
2603
0
  ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)algo->id, data->data,
2604
0
        data->size, _digest);
2605
0
  if (ret < 0)
2606
0
    return gnutls_assert_val(ret);
2607
2608
0
  digest.data = _digest;
2609
0
  digest.size = _gnutls_hash_get_algo_len(algo);
2610
2611
0
  return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2612
0
}
2613
2614
/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
2615
 * not verified, or 1 otherwise.
2616
 */
2617
static int pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
2618
             const mac_entry_st *me,
2619
             const gnutls_datum_t *hash,
2620
             const gnutls_datum_t *signature,
2621
             gnutls_pk_params_st *params,
2622
             gnutls_x509_spki_st *sign_params,
2623
             unsigned flags)
2624
0
{
2625
0
  int ret;
2626
2627
0
  if (unlikely(me == NULL))
2628
0
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2629
2630
0
  ret = fixup_spki_params(params, se, me, sign_params);
2631
0
  if (ret < 0)
2632
0
    return gnutls_assert_val(ret);
2633
2634
0
  switch (se->pk) {
2635
0
  case GNUTLS_PK_RSA:
2636
0
  case GNUTLS_PK_RSA_PSS:
2637
2638
0
    if (_pkcs1_rsa_verify_sig(se->pk, me, NULL, hash, signature,
2639
0
            params, sign_params) != 0) {
2640
0
      gnutls_assert();
2641
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2642
0
    }
2643
2644
0
    break;
2645
2646
0
  case GNUTLS_PK_ECDSA:
2647
0
  case GNUTLS_PK_GOST_01:
2648
0
  case GNUTLS_PK_GOST_12_256:
2649
0
  case GNUTLS_PK_GOST_12_512:
2650
0
  case GNUTLS_PK_DSA:
2651
0
    if (dsa_verify_hashed_data(se->pk, me, hash, signature, params,
2652
0
             sign_params) != 0) {
2653
0
      gnutls_assert();
2654
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2655
0
    }
2656
2657
0
    break;
2658
0
  default:
2659
0
    gnutls_assert();
2660
0
    return GNUTLS_E_INVALID_REQUEST;
2661
0
  }
2662
2663
0
  if (_gnutls_sign_is_secure2(se, 0) == 0 &&
2664
0
      _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2665
0
    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2666
0
  }
2667
2668
0
  return 1;
2669
0
}
2670
2671
/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
2672
 * not verified, or 1 otherwise.
2673
 */
2674
int pubkey_verify_data(const gnutls_sign_entry_st *se, const mac_entry_st *me,
2675
           const gnutls_datum_t *data,
2676
           const gnutls_datum_t *signature,
2677
           gnutls_pk_params_st *params,
2678
           gnutls_x509_spki_st *sign_params, unsigned flags)
2679
0
{
2680
0
  int ret;
2681
2682
0
  if (unlikely(me == NULL))
2683
0
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2684
2685
0
  ret = fixup_spki_params(params, se, me, sign_params);
2686
0
  if (ret < 0)
2687
0
    return gnutls_assert_val(ret);
2688
2689
0
  switch (se->pk) {
2690
0
  case GNUTLS_PK_RSA:
2691
0
  case GNUTLS_PK_RSA_PSS:
2692
0
    if (_pkcs1_rsa_verify_sig(se->pk, me, data, NULL, signature,
2693
0
            params, sign_params) != 0) {
2694
0
      gnutls_assert();
2695
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2696
0
    }
2697
2698
0
    break;
2699
2700
0
  case GNUTLS_PK_EDDSA_ED25519:
2701
0
  case GNUTLS_PK_EDDSA_ED448:
2702
0
  case GNUTLS_PK_MLDSA44:
2703
0
  case GNUTLS_PK_MLDSA65:
2704
0
  case GNUTLS_PK_MLDSA87:
2705
0
    if (_gnutls_pk_verify(se->pk, data, signature, params,
2706
0
              sign_params) != 0) {
2707
0
      gnutls_assert();
2708
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2709
0
    }
2710
2711
0
    break;
2712
2713
0
  case GNUTLS_PK_EC:
2714
0
  case GNUTLS_PK_DSA:
2715
0
  case GNUTLS_PK_GOST_01:
2716
0
  case GNUTLS_PK_GOST_12_256:
2717
0
  case GNUTLS_PK_GOST_12_512:
2718
0
    if (dsa_verify_data(se->pk, me, data, signature, params,
2719
0
            sign_params) != 0) {
2720
0
      gnutls_assert();
2721
0
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2722
0
    }
2723
2724
0
    break;
2725
0
  default:
2726
0
    gnutls_assert();
2727
0
    return GNUTLS_E_INVALID_REQUEST;
2728
0
  }
2729
2730
0
  if (_gnutls_sign_is_secure2(se, 0) == 0 &&
2731
0
      _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2732
0
    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2733
0
  }
2734
2735
0
  return 1;
2736
0
}
2737
2738
const mac_entry_st *_gnutls_dsa_q_to_hash(const gnutls_pk_params_st *params,
2739
            unsigned int *hash_len)
2740
0
{
2741
0
  int bits = 0;
2742
0
  int ret;
2743
2744
0
  if (params->algo == GNUTLS_PK_DSA)
2745
0
    bits = _gnutls_mpi_get_nbits(params->params[1]);
2746
0
  else if (params->algo == GNUTLS_PK_EC)
2747
0
    bits = gnutls_ecc_curve_get_size(params->curve) * 8;
2748
2749
0
  if (bits <= 160) {
2750
0
    if (hash_len)
2751
0
      *hash_len = 20;
2752
0
    ret = GNUTLS_DIG_SHA1;
2753
0
  } else if (bits <= 192) {
2754
0
    if (hash_len)
2755
0
      *hash_len = 24;
2756
0
    ret = GNUTLS_DIG_SHA256;
2757
0
  } else if (bits <= 224) {
2758
0
    if (hash_len)
2759
0
      *hash_len = 28;
2760
0
    ret = GNUTLS_DIG_SHA256;
2761
0
  } else if (bits <= 256) {
2762
0
    if (hash_len)
2763
0
      *hash_len = 32;
2764
0
    ret = GNUTLS_DIG_SHA256;
2765
0
  } else if (bits <= 384) {
2766
0
    if (hash_len)
2767
0
      *hash_len = 48;
2768
0
    ret = GNUTLS_DIG_SHA384;
2769
0
  } else {
2770
0
    if (hash_len)
2771
0
      *hash_len = 64;
2772
0
    ret = GNUTLS_DIG_SHA512;
2773
0
  }
2774
2775
0
  return mac_to_entry(ret);
2776
0
}
2777
2778
/**
2779
 * gnutls_pubkey_set_pin_function:
2780
 * @key: A key of type #gnutls_pubkey_t
2781
 * @fn: the callback
2782
 * @userdata: data associated with the callback
2783
 *
2784
 * This function will set a callback function to be used when
2785
 * required to access the object. This function overrides any other
2786
 * global PIN functions.
2787
 *
2788
 * Note that this function must be called right after initialization
2789
 * to have effect.
2790
 *
2791
 * Since: 3.1.0
2792
 *
2793
 **/
2794
void gnutls_pubkey_set_pin_function(gnutls_pubkey_t key,
2795
            gnutls_pin_callback_t fn, void *userdata)
2796
0
{
2797
0
  key->pin.cb = fn;
2798
0
  key->pin.data = userdata;
2799
0
}
2800
2801
/**
2802
 * gnutls_pubkey_import_x509_raw:
2803
 * @pkey: The public key
2804
 * @data: The public key data to be imported
2805
 * @format: The format of the public key
2806
 * @flags: should be zero
2807
 *
2808
 * This function will import the given public key to the abstract
2809
 * #gnutls_pubkey_t type. 
2810
 *
2811
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2812
 *   negative error value.
2813
 *
2814
 * Since: 3.1.3
2815
 **/
2816
int gnutls_pubkey_import_x509_raw(gnutls_pubkey_t pkey,
2817
          const gnutls_datum_t *data,
2818
          gnutls_x509_crt_fmt_t format,
2819
          unsigned int flags)
2820
0
{
2821
0
  gnutls_x509_crt_t xpriv;
2822
0
  int ret;
2823
2824
0
  ret = gnutls_x509_crt_init(&xpriv);
2825
0
  if (ret < 0)
2826
0
    return gnutls_assert_val(ret);
2827
2828
0
  ret = gnutls_x509_crt_import(xpriv, data, format);
2829
0
  if (ret < 0) {
2830
0
    gnutls_assert();
2831
0
    goto cleanup;
2832
0
  }
2833
2834
0
  ret = gnutls_pubkey_import_x509(pkey, xpriv, flags);
2835
0
  if (ret < 0) {
2836
0
    gnutls_assert();
2837
0
    goto cleanup;
2838
0
  }
2839
2840
0
  ret = 0;
2841
2842
0
cleanup:
2843
0
  gnutls_x509_crt_deinit(xpriv);
2844
2845
0
  return ret;
2846
0
}
2847
2848
/**
2849
 * gnutls_pubkey_verify_params:
2850
 * @key: should contain a #gnutls_pubkey_t type
2851
 *
2852
 * This function will verify the public key parameters.
2853
 *
2854
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2855
 *   negative error value.
2856
 *
2857
 * Since: 3.3.0
2858
 **/
2859
int gnutls_pubkey_verify_params(gnutls_pubkey_t key)
2860
0
{
2861
0
  int ret;
2862
2863
0
  ret = _gnutls_pk_verify_pub_params(key->params.algo, &key->params);
2864
0
  if (ret < 0) {
2865
0
    gnutls_assert();
2866
0
    return ret;
2867
0
  }
2868
2869
0
  return 0;
2870
0
}
2871
2872
/**
2873
 * gnutls_pubkey_get_spki:
2874
 * @pubkey: a public key of type #gnutls_pubkey_t
2875
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2876
 * @flags: must be zero
2877
 *
2878
 * This function will return the public key information if available.
2879
 * The provided @spki must be initialized.
2880
 *
2881
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2882
 *   negative error value.
2883
 *
2884
 * Since: 3.6.0
2885
 **/
2886
int gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey, gnutls_x509_spki_t spki,
2887
         unsigned int flags)
2888
0
{
2889
0
  gnutls_x509_spki_t p = &pubkey->params.spki;
2890
2891
0
  if (pubkey == NULL) {
2892
0
    gnutls_assert();
2893
0
    return GNUTLS_E_INVALID_REQUEST;
2894
0
  }
2895
2896
0
  if (p->pk == GNUTLS_PK_UNKNOWN)
2897
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2898
2899
0
  return _gnutls_x509_spki_copy(spki, p);
2900
0
}
2901
2902
/**
2903
 * gnutls_pubkey_set_spki:
2904
 * @pubkey: a public key of type #gnutls_pubkey_t
2905
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2906
 * @flags: must be zero
2907
 *
2908
 * This function will set the public key information.
2909
 * The provided @spki must be initialized.
2910
 *
2911
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2912
 *   negative error value.
2913
 *
2914
 * Since: 3.6.0
2915
 **/
2916
int gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey,
2917
         const gnutls_x509_spki_t spki, unsigned int flags)
2918
0
{
2919
0
  int ret;
2920
2921
0
  if (pubkey == NULL) {
2922
0
    gnutls_assert();
2923
0
    return GNUTLS_E_INVALID_REQUEST;
2924
0
  }
2925
2926
0
  if (!_gnutls_pk_are_compat(pubkey->params.algo, spki->pk))
2927
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2928
2929
0
  ret = _gnutls_x509_spki_copy(&pubkey->params.spki, spki);
2930
0
  if (ret < 0)
2931
0
    return gnutls_assert_val(ret);
2932
2933
0
  pubkey->params.algo = spki->pk;
2934
2935
0
  return 0;
2936
0
}