Coverage Report

Created: 2024-06-20 06:28

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