Coverage Report

Created: 2023-03-26 07:33

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