Coverage Report

Created: 2025-03-18 06:55

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