Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/x509.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2003-2018 Free Software Foundation, Inc.
3
 * Copyright (C) 2018 Red Hat, Inc.
4
 *
5
 * Authors: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* Functions on X.509 Certificate parsing
25
 */
26
27
#include "gnutls_int.h"
28
#include <datum.h>
29
#include <global.h>
30
#include "errors.h"
31
#include <common.h>
32
#include <gnutls/x509-ext.h>
33
#include <x509.h>
34
#include <x509_b64.h>
35
#include <x509_int.h>
36
#include <libtasn1.h>
37
#include <pk.h>
38
#include <pkcs11_int.h>
39
#include "urls.h"
40
#include "system-keys.h"
41
#include "hash.h"
42
#include "hash-pjw-bare.h"
43
44
static int crt_reinit(gnutls_x509_crt_t crt)
45
0
{
46
0
  int result;
47
48
0
  _gnutls_free_datum(&crt->der);
49
0
  crt->raw_dn.size = 0;
50
0
  crt->raw_issuer_dn.size = 0;
51
0
  crt->raw_spki.size = 0;
52
53
0
  asn1_delete_structure(&crt->cert);
54
55
0
  result = asn1_create_element(_gnutls_get_pkix(),
56
0
             "PKIX1.Certificate", &crt->cert);
57
0
  if (result != ASN1_SUCCESS) {
58
0
    result = _gnutls_asn2err(result);
59
0
    gnutls_assert();
60
0
    return result;
61
0
  }
62
63
0
  gnutls_subject_alt_names_deinit(crt->san);
64
0
  result = gnutls_subject_alt_names_init(&crt->san);
65
0
  if (result < 0) {
66
0
    gnutls_assert();
67
0
    return result;
68
0
  }
69
70
0
  gnutls_subject_alt_names_deinit(crt->ian);
71
0
  result = gnutls_subject_alt_names_init(&crt->ian);
72
0
  if (result < 0) {
73
0
    gnutls_assert();
74
0
    return result;
75
0
  }
76
77
0
  return 0;
78
0
}
79
80
/**
81
 * gnutls_x509_crt_equals - This function compares two gnutls_x509_crt_t certificates
82
 * @cert1: The first certificate
83
 * @cert2: The second certificate
84
 *
85
 * This function will compare two X.509 certificate structures.
86
 *
87
 * Returns: On equality non-zero is returned, otherwise zero.
88
 *
89
 * Since: 3.5.0
90
 **/
91
unsigned gnutls_x509_crt_equals(gnutls_x509_crt_t cert1,
92
        gnutls_x509_crt_t cert2)
93
0
{
94
0
  int ret;
95
0
  bool result;
96
97
0
  if (cert1->modified == 0 && cert2->modified == 0 &&
98
0
      cert1->raw_dn.size > 0 && cert2->raw_dn.size > 0) {
99
0
    ret = _gnutls_is_same_dn(cert1, cert2);
100
0
    if (ret == 0)
101
0
      return 0;
102
0
  }
103
104
0
  if (cert1->der.size == 0 || cert2->der.size == 0 ||
105
0
      cert1->modified != 0 || cert2->modified != 0) {
106
0
    gnutls_datum_t tmp1, tmp2;
107
108
    /* on uninitialized or modified certificates, we have to re-encode */
109
0
    ret =
110
0
        gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER, &tmp1);
111
0
    if (ret < 0)
112
0
      return gnutls_assert_val(0);
113
114
0
    ret =
115
0
        gnutls_x509_crt_export2(cert2, GNUTLS_X509_FMT_DER, &tmp2);
116
0
    if (ret < 0) {
117
0
      gnutls_free(tmp1.data);
118
0
      return gnutls_assert_val(0);
119
0
    }
120
121
0
    if ((tmp1.size == tmp2.size) &&
122
0
        (memcmp(tmp1.data, tmp2.data, tmp1.size) == 0))
123
0
      result = 1;
124
0
    else
125
0
      result = 0;
126
127
0
    gnutls_free(tmp1.data);
128
0
    gnutls_free(tmp2.data);
129
0
  } else {
130
0
    if ((cert1->der.size == cert2->der.size) &&
131
0
        (memcmp(cert1->der.data, cert2->der.data, cert1->der.size)
132
0
         == 0))
133
0
      result = 1;
134
0
    else
135
0
      result = 0;
136
0
  }
137
138
0
  return result;
139
0
}
140
141
/**
142
 * gnutls_x509_crt_equals2 - This function compares a gnutls_x509_crt_t cert with DER data
143
 * @cert1: The first certificate
144
 * @der: A DER encoded certificate
145
 *
146
 * This function will compare an X.509 certificate structures, with DER
147
 * encoded certificate data.
148
 *
149
 * Returns: On equality non-zero is returned, otherwise zero.
150
 *
151
 * Since: 3.5.0
152
 **/
153
unsigned
154
gnutls_x509_crt_equals2(gnutls_x509_crt_t cert1, const gnutls_datum_t * der)
155
0
{
156
0
  bool result;
157
158
0
  if (cert1 == NULL || der == NULL)
159
0
    return 0;
160
161
0
  if (cert1->der.size == 0 || cert1->modified) {
162
0
    gnutls_datum_t tmp1;
163
0
    int ret;
164
165
    /* on uninitialized or modified certificates, we have to re-encode */
166
0
    ret =
167
0
        gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER, &tmp1);
168
0
    if (ret < 0)
169
0
      return gnutls_assert_val(0);
170
171
0
    if ((tmp1.size == der->size) &&
172
0
        (memcmp(tmp1.data, der->data, tmp1.size) == 0))
173
0
      result = 1;
174
0
    else
175
0
      result = 0;
176
177
0
    gnutls_free(tmp1.data);
178
0
  } else {
179
0
    if ((cert1->der.size == der->size) &&
180
0
        (memcmp(cert1->der.data, der->data, cert1->der.size) == 0))
181
0
      result = 1;
182
0
    else
183
0
      result = 0;
184
0
  }
185
186
0
  return result;
187
0
}
188
189
/**
190
 * gnutls_x509_crt_init:
191
 * @cert: A pointer to the type to be initialized
192
 *
193
 * This function will initialize an X.509 certificate structure.
194
 *
195
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
196
 *   negative error value.
197
 **/
198
int gnutls_x509_crt_init(gnutls_x509_crt_t * cert)
199
0
{
200
0
  gnutls_x509_crt_t tmp;
201
0
  int result;
202
203
0
  *cert = NULL;
204
0
  FAIL_IF_LIB_ERROR;
205
206
0
  tmp = gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
207
208
0
  if (!tmp)
209
0
    return GNUTLS_E_MEMORY_ERROR;
210
211
0
  result = asn1_create_element(_gnutls_get_pkix(),
212
0
             "PKIX1.Certificate", &tmp->cert);
213
0
  if (result != ASN1_SUCCESS) {
214
0
    gnutls_assert();
215
0
    gnutls_free(tmp);
216
0
    return _gnutls_asn2err(result);
217
0
  }
218
219
0
  result = gnutls_subject_alt_names_init(&tmp->san);
220
0
  if (result < 0) {
221
0
    gnutls_assert();
222
0
    asn1_delete_structure(&tmp->cert);
223
0
    gnutls_free(tmp);
224
0
    return result;
225
0
  }
226
227
0
  result = gnutls_subject_alt_names_init(&tmp->ian);
228
0
  if (result < 0) {
229
0
    gnutls_assert();
230
0
    asn1_delete_structure(&tmp->cert);
231
0
    gnutls_subject_alt_names_deinit(tmp->san);
232
0
    gnutls_free(tmp);
233
0
    return result;
234
0
  }
235
236
  /* If you add anything here, be sure to check if it has to be added
237
     to gnutls_x509_crt_import as well. */
238
239
0
  *cert = tmp;
240
241
0
  return 0;   /* success */
242
0
}
243
244
/*-
245
 * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t type
246
 * @dest: The data where to copy
247
 * @src: The data to be copied
248
 * @flags: zero or CRT_CPY_FAST
249
 *
250
 * This function will copy an X.509 certificate structure.
251
 *
252
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
253
 *   negative error value.
254
 -*/
255
int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
256
0
{
257
0
  int ret;
258
0
  gnutls_datum_t tmp;
259
0
  unsigned dealloc = 0;
260
261
0
  if (src->der.size == 0 || src->modified) {
262
0
    ret = gnutls_x509_crt_export2(src, GNUTLS_X509_FMT_DER, &tmp);
263
0
    if (ret < 0)
264
0
      return gnutls_assert_val(ret);
265
0
    dealloc = 1;
266
0
  } else {
267
0
    tmp.data = src->der.data;
268
0
    tmp.size = src->der.size;
269
0
  }
270
271
0
  ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
272
273
0
  if (dealloc) {
274
0
    gnutls_free(tmp.data);
275
0
  }
276
277
0
  if (ret < 0)
278
0
    return gnutls_assert_val(ret);
279
280
0
  return 0;
281
0
}
282
283
/**
284
 * gnutls_x509_crt_deinit:
285
 * @cert: The data to be deinitialized
286
 *
287
 * This function will deinitialize a certificate structure.
288
 **/
289
void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert)
290
0
{
291
0
  if (!cert)
292
0
    return;
293
294
0
  if (cert->cert)
295
0
    asn1_delete_structure(&cert->cert);
296
0
  gnutls_free(cert->der.data);
297
0
  gnutls_subject_alt_names_deinit(cert->san);
298
0
  gnutls_subject_alt_names_deinit(cert->ian);
299
0
  gnutls_free(cert);
300
0
}
301
302
static int compare_sig_algorithm(gnutls_x509_crt_t cert)
303
0
{
304
0
  int ret, len1, len2, result;
305
0
  char oid1[MAX_OID_SIZE];
306
0
  char oid2[MAX_OID_SIZE];
307
0
  gnutls_datum_t sp1 = { NULL, 0 };
308
0
  gnutls_datum_t sp2 = { NULL, 0 };
309
0
  unsigned empty1 = 0, empty2 = 0;
310
311
0
  len1 = sizeof(oid1);
312
0
  result =
313
0
      asn1_read_value(cert->cert, "signatureAlgorithm.algorithm", oid1,
314
0
          &len1);
315
0
  if (result != ASN1_SUCCESS) {
316
0
    gnutls_assert();
317
0
    return _gnutls_asn2err(result);
318
0
  }
319
320
0
  len2 = sizeof(oid2);
321
0
  result =
322
0
      asn1_read_value(cert->cert, "tbsCertificate.signature.algorithm",
323
0
          oid2, &len2);
324
0
  if (result != ASN1_SUCCESS) {
325
0
    gnutls_assert();
326
0
    return _gnutls_asn2err(result);
327
0
  }
328
329
0
  if (len1 != len2 || memcmp(oid1, oid2, len1) != 0) {
330
0
    _gnutls_debug_log
331
0
        ("signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n",
332
0
         oid1, oid2);
333
0
    gnutls_assert();
334
0
    return GNUTLS_E_CERTIFICATE_ERROR;
335
0
  }
336
337
  /* compare the parameters */
338
0
  ret =
339
0
      _gnutls_x509_read_value(cert->cert, "signatureAlgorithm.parameters",
340
0
            &sp1);
341
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
342
0
    empty1 = 1;
343
0
  } else if (ret < 0) {
344
0
    gnutls_assert();
345
0
    return ret;
346
0
  }
347
348
0
  ret =
349
0
      _gnutls_x509_read_value(cert->cert,
350
0
            "tbsCertificate.signature.parameters",
351
0
            &sp2);
352
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
353
0
    empty2 = 1;
354
0
  } else if (ret < 0) {
355
0
    gnutls_assert();
356
0
    return ret;
357
0
  }
358
359
  /* handle equally empty parameters with missing parameters */
360
0
  if (sp1.size == 2 && memcmp(sp1.data, "\x05\x00", 2) == 0) {
361
0
    empty1 = 1;
362
0
    _gnutls_free_datum(&sp1);
363
0
  }
364
365
0
  if (sp2.size == 2 && memcmp(sp2.data, "\x05\x00", 2) == 0) {
366
0
    empty2 = 1;
367
0
    _gnutls_free_datum(&sp2);
368
0
  }
369
370
0
  if (empty1 != empty2 ||
371
0
      sp1.size != sp2.size ||
372
0
      (sp1.size > 0 && memcmp(sp1.data, sp2.data, sp1.size) != 0)) {
373
0
    gnutls_assert();
374
0
    ret = GNUTLS_E_CERTIFICATE_ERROR;
375
0
    goto cleanup;
376
0
  }
377
378
0
  ret = 0;
379
0
 cleanup:
380
0
  _gnutls_free_datum(&sp1);
381
0
  _gnutls_free_datum(&sp2);
382
0
  return ret;
383
0
}
384
385
static int cache_alt_names(gnutls_x509_crt_t cert)
386
0
{
387
0
  gnutls_datum_t tmpder = { NULL, 0 };
388
0
  int ret;
389
390
  /* pre-parse subject alt name */
391
0
  ret =
392
0
      _gnutls_x509_crt_get_extension(cert, "2.5.29.17", 0, &tmpder, NULL);
393
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
394
0
    gnutls_free(tmpder.data);
395
0
    return gnutls_assert_val(ret);
396
0
  }
397
398
0
  if (ret >= 0) {
399
0
    ret =
400
0
        gnutls_x509_ext_import_subject_alt_names(&tmpder, cert->san,
401
0
                   0);
402
0
    gnutls_free(tmpder.data);
403
0
    if (ret < 0)
404
0
      return gnutls_assert_val(ret);
405
0
  }
406
407
0
  ret =
408
0
      _gnutls_x509_crt_get_extension(cert, "2.5.29.18", 0, &tmpder, NULL);
409
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
410
0
    return gnutls_assert_val(ret);
411
412
0
  if (ret >= 0) {
413
0
    ret =
414
0
        gnutls_x509_ext_import_subject_alt_names(&tmpder, cert->ian,
415
0
                   0);
416
0
    gnutls_free(tmpder.data);
417
0
    if (ret < 0)
418
0
      return gnutls_assert_val(ret);
419
0
  }
420
421
0
  return 0;
422
0
}
423
424
static bool hcomparator(const void *v1, const void *v2)
425
0
{
426
0
  return (strcmp(v1, v2) == 0);
427
0
}
428
429
static size_t hhasher(const void *entry, size_t n)
430
0
{
431
0
  const char *e = entry;
432
0
  if (e == NULL || e[0] == 0)
433
0
    return 0;
434
435
0
  return hash_pjw_bare(e, strlen(e)) % n;
436
0
}
437
438
#ifdef STRICT_X509
439
440
/* Check whether certificates serial number is RFC5280 compliant */
441
static bool has_valid_serial(gnutls_x509_crt_t cert)
442
{
443
  int err, is_zero;
444
  unsigned i;
445
  unsigned char serial[128];
446
  size_t serial_size = sizeof(serial);
447
448
  err = gnutls_x509_crt_get_serial(cert, serial, &serial_size);
449
  if (err < 0) {
450
    _gnutls_debug_log("error: could not read serial number\n");
451
    return false;
452
  }
453
454
  if (serial_size > 20) {
455
    _gnutls_debug_log
456
        ("error: serial number value is longer than 20 octets\n");
457
    return false;
458
  }
459
460
  if (serial[0] & 0x80) {
461
    _gnutls_debug_log("error: serial number is negative\n");
462
    return false;
463
  }
464
465
  is_zero = 1;
466
  for (i = 0; i < serial_size; ++i) {
467
    if (serial[i]) {
468
      is_zero = 0;
469
      break;
470
    }
471
  }
472
473
  if (is_zero) {
474
    _gnutls_debug_log("error: serial number is zero\n");
475
    return false;
476
  }
477
478
  return true;
479
}
480
481
/* Check if extension can be successfully parsed */
482
static bool is_valid_extension(const char *oid, gnutls_datum_t * der)
483
{
484
  int err = 0, i;
485
  unsigned u;
486
  size_t sz;
487
  time_t t1, t2;
488
  char *s1 = NULL, *s2 = NULL;
489
  gnutls_datum_t datum = { NULL, 0 };
490
491
  if (!strcmp(oid, GNUTLS_X509EXT_OID_BASIC_CONSTRAINTS)) {
492
    err = gnutls_x509_ext_import_basic_constraints(der, &u, &i);
493
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_SUBJECT_KEY_ID)) {
494
    err = gnutls_x509_ext_import_subject_key_id(der, &datum);
495
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_CRT_POLICY)) {
496
    gnutls_x509_policies_t policies;
497
    if (gnutls_x509_policies_init(&policies) < 0)
498
      return false;
499
    err = gnutls_x509_ext_import_policies(der, policies, 0);
500
    gnutls_x509_policies_deinit(policies);
501
  } else if (!strcmp(oid, GNUTLS_X509_OID_POLICY_ANY)) {
502
    err = gnutls_x509_ext_import_inhibit_anypolicy(der, &u);
503
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_AUTHORITY_KEY_ID)) {
504
    gnutls_x509_aki_t aki;
505
    if (gnutls_x509_aki_init(&aki) < 0)
506
      return false;
507
    err = gnutls_x509_ext_import_authority_key_id(der, aki, 0);
508
    gnutls_x509_aki_deinit(aki);
509
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_KEY_USAGE)) {
510
    err = gnutls_x509_ext_import_key_usage(der, &u);
511
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_PRIVATE_KEY_USAGE_PERIOD)) {
512
    err =
513
        gnutls_x509_ext_import_private_key_usage_period(der, &t1,
514
                    &t2);
515
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_EXTENDED_KEY_USAGE)) {
516
    gnutls_x509_key_purposes_t purposes;
517
    if (gnutls_x509_key_purpose_init(&purposes) < 0)
518
      return false;
519
    err = gnutls_x509_ext_import_key_purposes(der, purposes, 0);
520
    gnutls_x509_key_purpose_deinit(purposes);
521
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_SAN) ||
522
       !strcmp(oid, GNUTLS_X509EXT_OID_IAN)) {
523
    gnutls_subject_alt_names_t names;
524
    if (gnutls_subject_alt_names_init(&names) < 0)
525
      return false;
526
    err = gnutls_x509_ext_import_subject_alt_names(der, names, 0);
527
    gnutls_subject_alt_names_deinit(names);
528
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_CRL_DIST_POINTS)) {
529
    gnutls_x509_crl_dist_points_t dp;
530
    if (gnutls_x509_crl_dist_points_init(&dp) < 0)
531
      return false;
532
    err = gnutls_x509_ext_import_crl_dist_points(der, dp, 0);
533
    gnutls_x509_crl_dist_points_deinit(dp);
534
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_PROXY_CRT_INFO)) {
535
    err = gnutls_x509_ext_import_proxy(der, &i, &s1, &s2, &sz);
536
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_AUTHORITY_INFO_ACCESS)) {
537
    gnutls_x509_aia_t aia;
538
    if (gnutls_x509_aia_init(&aia) < 0)
539
      return false;
540
    err = gnutls_x509_ext_import_aia(der, aia, 0);
541
    gnutls_x509_aia_deinit(aia);
542
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_CT_SCT_V1)) {
543
    gnutls_x509_ct_scts_t scts;
544
    if (gnutls_x509_ext_ct_scts_init(&scts) < 0)
545
      return false;
546
    err = gnutls_x509_ext_ct_import_scts(der, scts, 0);
547
    gnutls_x509_ext_ct_scts_deinit(scts);
548
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_NAME_CONSTRAINTS)) {
549
    gnutls_x509_name_constraints_t nc;
550
    if (gnutls_x509_name_constraints_init(&nc) < 0)
551
      return false;
552
    err = gnutls_x509_ext_import_name_constraints(der, nc, 0);
553
    gnutls_x509_name_constraints_deinit(nc);
554
  } else if (!strcmp(oid, GNUTLS_X509EXT_OID_TLSFEATURES)) {
555
    gnutls_x509_tlsfeatures_t features;
556
    if (gnutls_x509_tlsfeatures_init(&features) < 0)
557
      return false;
558
    err = gnutls_x509_ext_import_tlsfeatures(der, features, 0);
559
    gnutls_x509_tlsfeatures_deinit(features);
560
  } else {
561
    return true;
562
  }
563
564
  gnutls_free(s1);
565
  gnutls_free(s2);
566
  _gnutls_free_datum(&datum);
567
568
  return err == 0;
569
}
570
571
#endif        /* STRICT_X509 */
572
573
int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert)
574
0
{
575
0
  int ret = 0, version;
576
0
  gnutls_datum_t exts;
577
0
  Hash_table *htable = NULL;
578
579
0
  if (cert->flags & GNUTLS_X509_CRT_FLAG_IGNORE_SANITY)
580
0
    return 0;
581
582
  /* enforce the rule that only version 3 certificates carry extensions */
583
0
  ret = gnutls_x509_crt_get_version(cert);
584
0
  if (ret < 0) {
585
0
    return gnutls_assert_val(ret);
586
0
  }
587
588
0
  version = ret;
589
590
#ifdef STRICT_X509
591
  /* enforce upper bound on certificate version (RFC5280 compliant) */
592
  if (version > 3) {
593
    _gnutls_debug_log("error: invalid certificate version %d\n",
594
          version);
595
    return gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
596
  }
597
#endif
598
599
0
  if (version < 3) {
600
0
    if (!cert->modified) {
601
0
      ret =
602
0
          _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
603
0
              "tbsCertificate.extensions",
604
0
              &exts);
605
0
      if (ret >= 0 && exts.size > 0) {
606
0
        _gnutls_debug_log
607
0
            ("error: extensions present in certificate with version %d\n",
608
0
             version);
609
0
        return
610
0
            gnutls_assert_val
611
0
            (GNUTLS_E_X509_CERTIFICATE_ERROR);
612
0
      }
613
0
    } else {
614
0
      if (cert->use_extensions) {
615
0
        _gnutls_debug_log
616
0
            ("error: extensions set in certificate with version %d\n",
617
0
             version);
618
0
        return
619
0
            gnutls_assert_val
620
0
            (GNUTLS_E_X509_CERTIFICATE_ERROR);
621
0
      }
622
0
    }
623
0
  } else {
624
    /* Version is 3; ensure no duplicate extensions are present. */
625
0
    unsigned i, critical;
626
0
    char oid[MAX_OID_SIZE];
627
0
    size_t oid_size;
628
0
    char *o;
629
630
0
    htable =
631
0
        hash_initialize(16, NULL, hhasher, hcomparator,
632
0
            gnutls_free);
633
0
    if (htable == NULL)
634
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
635
636
0
    for (i = 0;; i++) {
637
0
      oid_size = sizeof(oid);
638
0
      ret =
639
0
          gnutls_x509_crt_get_extension_info(cert, i, oid,
640
0
                     &oid_size,
641
0
                     &critical);
642
0
      if (ret < 0) {
643
0
        if (ret ==
644
0
            GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
645
0
          break;
646
0
        gnutls_assert();
647
0
        goto cleanup;
648
0
      }
649
0
      o = gnutls_strdup(oid);
650
0
      if (o == NULL) {
651
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
652
0
        goto cleanup;
653
0
      }
654
655
0
      ret = hash_insert_if_absent(htable, o, NULL);
656
0
      if (ret == -1) {
657
0
        gnutls_free(o);
658
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
659
0
        goto cleanup;
660
0
      } else if (ret == 0) {
661
        /* duplicate */
662
0
        gnutls_free(o);
663
0
        _gnutls_debug_log
664
0
            ("error: duplicate extension (%s) detected\n",
665
0
             oid);
666
0
        ret =
667
0
            gnutls_assert_val
668
0
            (GNUTLS_E_X509_DUPLICATE_EXTENSION);
669
0
        goto cleanup;
670
0
      }
671
672
#ifdef STRICT_X509
673
      gnutls_datum_t der = { NULL, 0 };
674
      ret =
675
          gnutls_x509_crt_get_extension_data2(cert, i, &der);
676
      if (ret < 0)
677
        continue;
678
      if (critical && !is_valid_extension(oid, &der)) {
679
        _gnutls_free_datum(&der);
680
        _gnutls_debug_log
681
            ("error: could not parse extension (%s)\n");
682
        return
683
            gnutls_assert_val
684
            (GNUTLS_E_X509_CERTIFICATE_ERROR);
685
      }
686
      _gnutls_free_datum(&der);
687
#endif
688
0
    }
689
690
0
    hash_free(htable);
691
0
    htable = NULL;
692
0
  }
693
694
0
  if (version < 2) {
695
0
    char id[128];
696
0
    size_t id_size;
697
698
0
    id_size = sizeof(id);
699
0
    ret = gnutls_x509_crt_get_subject_unique_id(cert, id, &id_size);
700
0
    if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
701
0
      _gnutls_debug_log
702
0
          ("error: subjectUniqueID present in certificate with version %d\n",
703
0
           version);
704
0
      ret =
705
0
          gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
706
0
      goto cleanup;
707
0
    }
708
709
0
    id_size = sizeof(id);
710
0
    ret = gnutls_x509_crt_get_issuer_unique_id(cert, id, &id_size);
711
0
    if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
712
0
      _gnutls_debug_log
713
0
          ("error: subjectUniqueID present in certificate with version %d\n",
714
0
           version);
715
0
      ret =
716
0
          gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
717
0
      goto cleanup;
718
0
    }
719
0
  }
720
721
#ifdef STRICT_X509
722
  if (!has_valid_serial(cert)) {
723
    ret = gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
724
    goto cleanup;
725
  }
726
#endif
727
728
0
  if (gnutls_x509_crt_get_expiration_time(cert) == -1 ||
729
0
      gnutls_x509_crt_get_activation_time(cert) == -1) {
730
0
    _gnutls_debug_log
731
0
        ("error: invalid expiration or activation time in certificate\n");
732
0
    ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_TIME_ERROR);
733
0
    goto cleanup;
734
0
  }
735
736
0
  ret = 0;
737
738
0
 cleanup:
739
0
  if (htable)
740
0
    hash_free(htable);
741
0
  return ret;
742
0
}
743
744
/**
745
 * gnutls_x509_crt_import:
746
 * @cert: The data to store the parsed certificate.
747
 * @data: The DER or PEM encoded certificate.
748
 * @format: One of DER or PEM
749
 *
750
 * This function will convert the given DER or PEM encoded Certificate
751
 * to the native gnutls_x509_crt_t format. The output will be stored
752
 * in @cert.
753
 *
754
 * If the Certificate is PEM encoded it should have a header of "X509
755
 * CERTIFICATE", or "CERTIFICATE".
756
 *
757
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
758
 *   negative error value.
759
 **/
760
int
761
gnutls_x509_crt_import(gnutls_x509_crt_t cert,
762
           const gnutls_datum_t * data,
763
           gnutls_x509_crt_fmt_t format)
764
0
{
765
0
  int result;
766
767
0
  if (cert == NULL) {
768
0
    gnutls_assert();
769
0
    return GNUTLS_E_INVALID_REQUEST;
770
0
  }
771
772
0
  if (cert->expanded) {
773
    /* Any earlier _asn1_strict_der_decode will modify the ASN.1
774
       structure, so we need to replace it with a fresh
775
       structure. */
776
0
    result = crt_reinit(cert);
777
0
    if (result < 0) {
778
0
      gnutls_assert();
779
0
      goto cleanup;
780
0
    }
781
0
  }
782
783
  /* If the Certificate is in PEM format then decode it
784
   */
785
0
  if (format == GNUTLS_X509_FMT_PEM) {
786
    /* Try the first header */
787
0
    result =
788
0
        _gnutls_fbase64_decode(PEM_X509_CERT2, data->data,
789
0
             data->size, &cert->der);
790
791
0
    if (result < 0) {
792
      /* try for the second header */
793
0
      result =
794
0
          _gnutls_fbase64_decode(PEM_X509_CERT,
795
0
               data->data, data->size,
796
0
               &cert->der);
797
798
0
      if (result < 0) {
799
0
        gnutls_assert();
800
0
        return result;
801
0
      }
802
0
    }
803
0
  } else {
804
0
    result = _gnutls_set_datum(&cert->der, data->data, data->size);
805
0
    if (result < 0) {
806
0
      gnutls_assert();
807
0
      return result;
808
0
    }
809
0
  }
810
811
0
  cert->expanded = 1;
812
0
  cert->modified = 0;
813
814
0
  result =
815
0
      _asn1_strict_der_decode(&cert->cert, cert->der.data, cert->der.size,
816
0
            NULL);
817
0
  if (result != ASN1_SUCCESS) {
818
0
    result = _gnutls_asn2err(result);
819
0
    gnutls_assert();
820
0
    goto cleanup;
821
0
  }
822
823
0
  result = compare_sig_algorithm(cert);
824
0
  if (result < 0) {
825
0
    gnutls_assert();
826
0
    goto cleanup;
827
0
  }
828
829
  /* The following do not allocate but rather point to DER data */
830
0
  result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
831
0
               "tbsCertificate.issuer.rdnSequence",
832
0
               &cert->raw_issuer_dn);
833
0
  if (result < 0) {
834
0
    gnutls_assert();
835
0
    goto cleanup;
836
0
  }
837
838
0
  result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
839
0
               "tbsCertificate.subject.rdnSequence",
840
0
               &cert->raw_dn);
841
0
  if (result < 0) {
842
0
    gnutls_assert();
843
0
    goto cleanup;
844
0
  }
845
846
0
  result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
847
0
               "tbsCertificate.subjectPublicKeyInfo",
848
0
               &cert->raw_spki);
849
0
  if (result < 0) {
850
0
    gnutls_assert();
851
0
    goto cleanup;
852
0
  }
853
854
0
  result = cache_alt_names(cert);
855
0
  if (result < 0) {
856
0
    gnutls_assert();
857
0
    goto cleanup;
858
0
  }
859
860
0
  result = _gnutls_check_cert_sanity(cert);
861
0
  if (result < 0) {
862
0
    gnutls_assert();
863
0
    goto cleanup;
864
0
  }
865
866
  /* Since we do not want to disable any extension
867
   */
868
0
  cert->use_extensions = 1;
869
870
0
  return 0;
871
872
0
 cleanup:
873
0
  _gnutls_free_datum(&cert->der);
874
0
  return result;
875
0
}
876
877
/**
878
 * gnutls_x509_crt_get_issuer_dn:
879
 * @cert: should contain a #gnutls_x509_crt_t type
880
 * @buf: a pointer to a structure to hold the name (may be null)
881
 * @buf_size: initially holds the size of @buf
882
 *
883
 * This function will copy the name of the Certificate issuer in the
884
 * provided buffer. The name will be in the form
885
 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
886
 * will be ASCII or UTF-8 encoded, depending on the certificate data.
887
 *
888
 * If @buf is null then only the size will be filled.
889
 *
890
 * This function does not output a fully RFC4514 compliant string, if
891
 * that is required see gnutls_x509_crt_get_issuer_dn3().
892
 *
893
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
894
 *   long enough, and in that case the @buf_size will be updated
895
 *   with the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if
896
 *   the DN does not exist, or another error value on error. On success 0 is returned.
897
 **/
898
int
899
gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert, char *buf,
900
            size_t *buf_size)
901
0
{
902
0
  if (cert == NULL) {
903
0
    gnutls_assert();
904
0
    return GNUTLS_E_INVALID_REQUEST;
905
0
  }
906
907
0
  return _gnutls_x509_parse_dn(cert->cert,
908
0
             "tbsCertificate.issuer.rdnSequence",
909
0
             buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
910
0
}
911
912
/**
913
 * gnutls_x509_crt_get_issuer_dn2:
914
 * @cert: should contain a #gnutls_x509_crt_t type
915
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
916
 *
917
 * This function will allocate buffer and copy the name of issuer of the Certificate.
918
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
919
 * described in RFC4514. The output string will be ASCII or UTF-8
920
 * encoded, depending on the certificate data.
921
 *
922
 * This function does not output a fully RFC4514 compliant string, if
923
 * that is required see gnutls_x509_crt_get_issuer_dn3().
924
 *
925
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
926
 *   negative error value.
927
 *
928
 * Since: 3.1.10
929
 **/
930
int gnutls_x509_crt_get_issuer_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
931
0
{
932
0
  if (cert == NULL) {
933
0
    gnutls_assert();
934
0
    return GNUTLS_E_INVALID_REQUEST;
935
0
  }
936
937
0
  return _gnutls_x509_get_dn(cert->cert,
938
0
           "tbsCertificate.issuer.rdnSequence",
939
0
           dn, GNUTLS_X509_DN_FLAG_COMPAT);
940
0
}
941
942
/**
943
 * gnutls_x509_crt_get_issuer_dn3:
944
 * @cert: should contain a #gnutls_x509_crt_t type
945
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
946
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
947
 *
948
 * This function will allocate buffer and copy the name of issuer of the Certificate.
949
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
950
 * described in RFC4514. The output string will be ASCII or UTF-8
951
 * encoded, depending on the certificate data.
952
 *
953
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
954
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
955
 * which was not not fully RFC4514-compliant.
956
 *
957
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
958
 *   negative error value.
959
 *
960
 * Since: 3.5.7
961
 **/
962
int
963
gnutls_x509_crt_get_issuer_dn3(gnutls_x509_crt_t cert, gnutls_datum_t * dn,
964
             unsigned flags)
965
0
{
966
0
  if (cert == NULL) {
967
0
    gnutls_assert();
968
0
    return GNUTLS_E_INVALID_REQUEST;
969
0
  }
970
971
0
  return _gnutls_x509_get_dn(cert->cert,
972
0
           "tbsCertificate.issuer.rdnSequence",
973
0
           dn, flags);
974
0
}
975
976
/**
977
 * gnutls_x509_crt_get_issuer_dn_by_oid:
978
 * @cert: should contain a #gnutls_x509_crt_t type
979
 * @oid: holds an Object Identified in null terminated string
980
 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
981
 * @raw_flag: If non-zero returns the raw DER data of the DN part.
982
 * @buf: a pointer to a structure to hold the name (may be null)
983
 * @buf_size: initially holds the size of @buf
984
 *
985
 * This function will extract the part of the name of the Certificate
986
 * issuer specified by the given OID. The output, if the raw flag is not
987
 * used, will be encoded as described in RFC4514. Thus a string that is
988
 * ASCII or UTF-8 encoded, depending on the certificate data.
989
 *
990
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
991
 * If raw flag is (0), this function will only return known OIDs as
992
 * text. Other OIDs will be DER encoded, as described in RFC4514 --
993
 * in hex format with a '#' prefix.  You can check about known OIDs
994
 * using gnutls_x509_dn_oid_known().
995
 *
996
 * If @buf is null then only the size will be filled. If the @raw_flag
997
 * is not specified the output is always null terminated, although the
998
 * @buf_size will not include the null character.
999
 *
1000
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1001
 *   long enough, and in that case the @buf_size will be updated with
1002
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1003
 *   are no data in the current index. On success 0 is returned.
1004
 **/
1005
int
1006
gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
1007
             const char *oid, unsigned indx,
1008
             unsigned int raw_flag, void *buf,
1009
             size_t *buf_size)
1010
0
{
1011
0
  gnutls_datum_t td;
1012
0
  int ret;
1013
1014
0
  if (cert == NULL) {
1015
0
    gnutls_assert();
1016
0
    return GNUTLS_E_INVALID_REQUEST;
1017
0
  }
1018
1019
0
  ret = _gnutls_x509_parse_dn_oid(cert->cert,
1020
0
          "tbsCertificate.issuer.rdnSequence",
1021
0
          oid, indx, raw_flag, &td);
1022
0
  if (ret < 0)
1023
0
    return gnutls_assert_val(ret);
1024
1025
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
1026
0
}
1027
1028
/**
1029
 * gnutls_x509_crt_get_issuer_dn_oid:
1030
 * @cert: should contain a #gnutls_x509_crt_t type
1031
 * @indx: This specifies which OID to return. Use (0) to get the first one.
1032
 * @oid: a pointer to a buffer to hold the OID (may be null)
1033
 * @oid_size: initially holds the size of @oid
1034
 *
1035
 * This function will extract the OIDs of the name of the Certificate
1036
 * issuer specified by the given index.
1037
 *
1038
 * If @oid is null then only the size will be filled. The @oid
1039
 * returned will be null terminated, although @oid_size will not
1040
 * account for the trailing null.
1041
 *
1042
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1043
 *   long enough, and in that case the @buf_size will be updated with
1044
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1045
 *   are no data in the current index. On success 0 is returned.
1046
 **/
1047
int
1048
gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,
1049
          unsigned indx, void *oid, size_t *oid_size)
1050
0
{
1051
0
  if (cert == NULL) {
1052
0
    gnutls_assert();
1053
0
    return GNUTLS_E_INVALID_REQUEST;
1054
0
  }
1055
1056
0
  return _gnutls_x509_get_dn_oid(cert->cert,
1057
0
               "tbsCertificate.issuer.rdnSequence",
1058
0
               indx, oid, oid_size);
1059
0
}
1060
1061
/**
1062
 * gnutls_x509_crt_get_dn:
1063
 * @cert: should contain a #gnutls_x509_crt_t type
1064
 * @buf: a pointer to a structure to hold the name (may be null)
1065
 * @buf_size: initially holds the size of @buf
1066
 *
1067
 * This function will copy the name of the Certificate in the provided
1068
 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
1069
 * described in RFC4514. The output string will be ASCII or UTF-8
1070
 * encoded, depending on the certificate data.
1071
 *
1072
 * The @buf returned will be null terminated and the @buf_size will account
1073
 * for the trailing null. If @buf is null then only the size will be filled.
1074
 *
1075
 * This function does not output a fully RFC4514 compliant string, if
1076
 * that is required see gnutls_x509_crt_get_dn3().
1077
 *
1078
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1079
 *   long enough, and in that case the @buf_size will be updated
1080
 *   with the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if
1081
 *   the DN does not exist, or another error value on error. On success 0 is returned.
1082
 **/
1083
int gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert, char *buf, size_t *buf_size)
1084
0
{
1085
0
  if (cert == NULL) {
1086
0
    gnutls_assert();
1087
0
    return GNUTLS_E_INVALID_REQUEST;
1088
0
  }
1089
1090
0
  return _gnutls_x509_parse_dn(cert->cert,
1091
0
             "tbsCertificate.subject.rdnSequence",
1092
0
             buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
1093
0
}
1094
1095
/**
1096
 * gnutls_x509_crt_get_dn2:
1097
 * @cert: should contain a #gnutls_x509_crt_t type
1098
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
1099
 *
1100
 * This function will allocate buffer and copy the name of the Certificate.
1101
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
1102
 * described in RFC4514. The output string will be ASCII or UTF-8
1103
 * encoded, depending on the certificate data.
1104
 *
1105
 * This function does not output a fully RFC4514 compliant string, if
1106
 * that is required see gnutls_x509_crt_get_dn3().
1107
 *
1108
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1109
 *   negative error value.
1110
 *
1111
 * Since: 3.1.10
1112
 **/
1113
int gnutls_x509_crt_get_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
1114
0
{
1115
0
  if (cert == NULL) {
1116
0
    gnutls_assert();
1117
0
    return GNUTLS_E_INVALID_REQUEST;
1118
0
  }
1119
1120
0
  return _gnutls_x509_get_dn(cert->cert,
1121
0
           "tbsCertificate.subject.rdnSequence",
1122
0
           dn, GNUTLS_X509_DN_FLAG_COMPAT);
1123
0
}
1124
1125
/**
1126
 * gnutls_x509_crt_get_dn3:
1127
 * @cert: should contain a #gnutls_x509_crt_t type
1128
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
1129
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
1130
 *
1131
 * This function will allocate buffer and copy the name of the Certificate.
1132
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
1133
 * described in RFC4514. The output string will be ASCII or UTF-8
1134
 * encoded, depending on the certificate data.
1135
 *
1136
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
1137
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
1138
 * which was not not fully RFC4514-compliant.
1139
 *
1140
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1141
 *   negative error value.
1142
 *
1143
 * Since: 3.5.7
1144
 **/
1145
int gnutls_x509_crt_get_dn3(gnutls_x509_crt_t cert, gnutls_datum_t * dn,
1146
          unsigned flags)
1147
0
{
1148
0
  if (cert == NULL) {
1149
0
    gnutls_assert();
1150
0
    return GNUTLS_E_INVALID_REQUEST;
1151
0
  }
1152
1153
0
  return _gnutls_x509_get_dn(cert->cert,
1154
0
           "tbsCertificate.subject.rdnSequence",
1155
0
           dn, flags);
1156
0
}
1157
1158
/**
1159
 * gnutls_x509_crt_get_dn_by_oid:
1160
 * @cert: should contain a #gnutls_x509_crt_t type
1161
 * @oid: holds an Object Identified in null terminated string
1162
 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
1163
 * @raw_flag: If non-zero returns the raw DER data of the DN part.
1164
 * @buf: a pointer where the DN part will be copied (may be null).
1165
 * @buf_size: initially holds the size of @buf
1166
 *
1167
 * This function will extract the part of the name of the Certificate
1168
 * subject specified by the given OID. The output, if the raw flag is
1169
 * not used, will be encoded as described in RFC4514. Thus a string
1170
 * that is ASCII or UTF-8 encoded, depending on the certificate data.
1171
 *
1172
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
1173
 * If raw flag is (0), this function will only return known OIDs as
1174
 * text. Other OIDs will be DER encoded, as described in RFC4514 --
1175
 * in hex format with a '#' prefix.  You can check about known OIDs
1176
 * using gnutls_x509_dn_oid_known().
1177
 *
1178
 * If @buf is null then only the size will be filled. If the @raw_flag
1179
 * is not specified the output is always null terminated, although the
1180
 * @buf_size will not include the null character.
1181
 *
1182
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1183
 *   long enough, and in that case the @buf_size will be updated with
1184
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1185
 *   are no data in the current index. On success 0 is returned.
1186
 **/
1187
int
1188
gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert, const char *oid,
1189
            unsigned indx, unsigned int raw_flag,
1190
            void *buf, size_t *buf_size)
1191
0
{
1192
0
  gnutls_datum_t td;
1193
0
  int ret;
1194
1195
0
  if (cert == NULL) {
1196
0
    gnutls_assert();
1197
0
    return GNUTLS_E_INVALID_REQUEST;
1198
0
  }
1199
1200
0
  ret = _gnutls_x509_parse_dn_oid(cert->cert,
1201
0
          "tbsCertificate.subject.rdnSequence",
1202
0
          oid, indx, raw_flag, &td);
1203
0
  if (ret < 0)
1204
0
    return gnutls_assert_val(ret);
1205
1206
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
1207
0
}
1208
1209
/**
1210
 * gnutls_x509_crt_get_dn_oid:
1211
 * @cert: should contain a #gnutls_x509_crt_t type
1212
 * @indx: This specifies which OID to return. Use (0) to get the first one.
1213
 * @oid: a pointer to a buffer to hold the OID (may be null)
1214
 * @oid_size: initially holds the size of @oid
1215
 *
1216
 * This function will extract the OIDs of the name of the Certificate
1217
 * subject specified by the given index.
1218
 *
1219
 * If @oid is null then only the size will be filled. The @oid
1220
 * returned will be null terminated, although @oid_size will not
1221
 * account for the trailing null.
1222
 *
1223
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1224
 *   long enough, and in that case the @buf_size will be updated with
1225
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1226
 *   are no data in the current index. On success 0 is returned.
1227
 **/
1228
int
1229
gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,
1230
         unsigned indx, void *oid, size_t *oid_size)
1231
0
{
1232
0
  if (cert == NULL) {
1233
0
    gnutls_assert();
1234
0
    return GNUTLS_E_INVALID_REQUEST;
1235
0
  }
1236
1237
0
  return _gnutls_x509_get_dn_oid(cert->cert,
1238
0
               "tbsCertificate.subject.rdnSequence",
1239
0
               indx, oid, oid_size);
1240
0
}
1241
1242
/**
1243
 * gnutls_x509_crt_get_signature_algorithm:
1244
 * @cert: should contain a #gnutls_x509_crt_t type
1245
 *
1246
 * This function will return a value of the #gnutls_sign_algorithm_t
1247
 * enumeration that is the signature algorithm that has been used to
1248
 * sign this certificate.
1249
 *
1250
 * Since 3.6.0 this function never returns a negative error code.
1251
 * Error cases and unknown/unsupported signature algorithms are
1252
 * mapped to %GNUTLS_SIGN_UNKNOWN.
1253
 *
1254
 * Returns: a #gnutls_sign_algorithm_t value
1255
 **/
1256
int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert)
1257
0
{
1258
0
  return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(cert->cert,
1259
0
                     "signatureAlgorithm"));
1260
0
}
1261
1262
/**
1263
 * gnutls_x509_crt_get_signature_oid:
1264
 * @cert: should contain a #gnutls_x509_crt_t type
1265
 * @oid: a pointer to a buffer to hold the OID (may be null)
1266
 * @oid_size: initially holds the size of @oid
1267
 *
1268
 * This function will return the OID of the signature algorithm
1269
 * that has been used to sign this certificate. This is function
1270
 * is useful in the case gnutls_x509_crt_get_signature_algorithm()
1271
 * returned %GNUTLS_SIGN_UNKNOWN.
1272
 *
1273
 * Returns: zero or a negative error code on error.
1274
 *
1275
 * Since: 3.5.0
1276
 **/
1277
int gnutls_x509_crt_get_signature_oid(gnutls_x509_crt_t cert, char *oid,
1278
              size_t *oid_size)
1279
0
{
1280
0
  char str[MAX_OID_SIZE];
1281
0
  int len, result, ret;
1282
0
  gnutls_datum_t out;
1283
1284
0
  len = sizeof(str);
1285
0
  result =
1286
0
      asn1_read_value(cert->cert, "signatureAlgorithm.algorithm", str,
1287
0
          &len);
1288
0
  if (result != ASN1_SUCCESS) {
1289
0
    gnutls_assert();
1290
0
    return _gnutls_asn2err(result);
1291
0
  }
1292
1293
0
  out.data = (void *)str;
1294
0
  out.size = len;
1295
1296
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1297
0
  if (ret < 0) {
1298
0
    gnutls_assert();
1299
0
    return ret;
1300
0
  }
1301
1302
0
  return 0;
1303
0
}
1304
1305
/**
1306
 * gnutls_x509_crt_get_pk_oid:
1307
 * @cert: should contain a #gnutls_x509_crt_t type
1308
 * @oid: a pointer to a buffer to hold the OID (may be null)
1309
 * @oid_size: initially holds the size of @oid
1310
 *
1311
 * This function will return the OID of the public key algorithm
1312
 * on that certificate. This is function
1313
 * is useful in the case gnutls_x509_crt_get_pk_algorithm()
1314
 * returned %GNUTLS_PK_UNKNOWN.
1315
 *
1316
 * Returns: zero or a negative error code on error.
1317
 *
1318
 * Since: 3.5.0
1319
 **/
1320
int gnutls_x509_crt_get_pk_oid(gnutls_x509_crt_t cert, char *oid,
1321
             size_t *oid_size)
1322
0
{
1323
0
  char str[MAX_OID_SIZE];
1324
0
  int len, result, ret;
1325
0
  gnutls_datum_t out;
1326
1327
0
  len = sizeof(str);
1328
0
  result =
1329
0
      asn1_read_value(cert->cert,
1330
0
          "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
1331
0
          str, &len);
1332
0
  if (result != ASN1_SUCCESS) {
1333
0
    gnutls_assert();
1334
0
    return _gnutls_asn2err(result);
1335
0
  }
1336
1337
0
  out.data = (void *)str;
1338
0
  out.size = len;
1339
1340
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1341
0
  if (ret < 0) {
1342
0
    gnutls_assert();
1343
0
    return ret;
1344
0
  }
1345
1346
0
  return 0;
1347
0
}
1348
1349
/**
1350
 * gnutls_x509_crt_get_signature:
1351
 * @cert: should contain a #gnutls_x509_crt_t type
1352
 * @sig: a pointer where the signature part will be copied (may be null).
1353
 * @sig_size: initially holds the size of @sig
1354
 *
1355
 * This function will extract the signature field of a certificate.
1356
 *
1357
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1358
 *   negative error value.
1359
 **/
1360
int
1361
gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
1362
            char *sig, size_t *sig_size)
1363
0
{
1364
0
  gnutls_datum_t dsig = { NULL, 0 };
1365
0
  int ret;
1366
1367
0
  if (cert == NULL)
1368
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1369
1370
0
  ret = _gnutls_x509_get_signature(cert->cert, "signature", &dsig);
1371
0
  if (ret < 0)
1372
0
    return gnutls_assert_val(ret);
1373
1374
0
  ret = _gnutls_copy_data(&dsig, (uint8_t *) sig, sig_size);
1375
0
  if (ret < 0) {
1376
0
    gnutls_assert();
1377
0
    goto cleanup;
1378
0
  }
1379
1380
0
  ret = 0;
1381
0
 cleanup:
1382
0
  gnutls_free(dsig.data);
1383
0
  return ret;
1384
0
}
1385
1386
/**
1387
 * gnutls_x509_crt_get_version:
1388
 * @cert: should contain a #gnutls_x509_crt_t type
1389
 *
1390
 * This function will return the version of the specified Certificate.
1391
 *
1392
 * Returns: version of certificate, or a negative error code on error.
1393
 **/
1394
int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)
1395
0
{
1396
0
  if (cert == NULL) {
1397
0
    gnutls_assert();
1398
0
    return GNUTLS_E_INVALID_REQUEST;
1399
0
  }
1400
1401
0
  return _gnutls_x509_get_version(cert->cert, "tbsCertificate.version");
1402
0
}
1403
1404
/**
1405
 * gnutls_x509_crt_get_activation_time:
1406
 * @cert: should contain a #gnutls_x509_crt_t type
1407
 *
1408
 * This function will return the time this Certificate was or will be
1409
 * activated.
1410
 *
1411
 * Returns: activation time, or (time_t)-1 on error.
1412
 **/
1413
time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert)
1414
0
{
1415
0
  if (cert == NULL) {
1416
0
    gnutls_assert();
1417
0
    return (time_t) - 1;
1418
0
  }
1419
1420
0
  return _gnutls_x509_get_time(cert->cert,
1421
0
             "tbsCertificate.validity.notBefore", 0);
1422
0
}
1423
1424
/**
1425
 * gnutls_x509_crt_get_expiration_time:
1426
 * @cert: should contain a #gnutls_x509_crt_t type
1427
 *
1428
 * This function will return the time this certificate was or will be
1429
 * expired.
1430
 *
1431
 * Returns: expiration time, or (time_t)-1 on error.
1432
 **/
1433
time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert)
1434
0
{
1435
0
  if (cert == NULL) {
1436
0
    gnutls_assert();
1437
0
    return (time_t) - 1;
1438
0
  }
1439
1440
0
  return _gnutls_x509_get_time(cert->cert,
1441
0
             "tbsCertificate.validity.notAfter", 0);
1442
0
}
1443
1444
/**
1445
 * gnutls_x509_crt_get_private_key_usage_period:
1446
 * @cert: should contain a #gnutls_x509_crt_t type
1447
 * @activation: The activation time
1448
 * @expiration: The expiration time
1449
 * @critical: the extension status
1450
 *
1451
 * This function will return the expiration and activation
1452
 * times of the private key of the certificate. It relies on
1453
 * the PKIX extension 2.5.29.16 being present.
1454
 *
1455
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1456
 * if the extension is not present, otherwise a negative error value.
1457
 **/
1458
int
1459
gnutls_x509_crt_get_private_key_usage_period(gnutls_x509_crt_t cert,
1460
               time_t * activation,
1461
               time_t * expiration,
1462
               unsigned int *critical)
1463
0
{
1464
0
  int ret;
1465
0
  gnutls_datum_t der = { NULL, 0 };
1466
1467
0
  if (cert == NULL) {
1468
0
    gnutls_assert();
1469
0
    return GNUTLS_E_INVALID_REQUEST;
1470
0
  }
1471
1472
0
  ret =
1473
0
      _gnutls_x509_crt_get_extension(cert, "2.5.29.16", 0, &der,
1474
0
             critical);
1475
0
  if (ret < 0)
1476
0
    return gnutls_assert_val(ret);
1477
1478
0
  if (der.size == 0 || der.data == NULL)
1479
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1480
1481
0
  ret =
1482
0
      gnutls_x509_ext_import_private_key_usage_period(&der, activation,
1483
0
                  expiration);
1484
0
  if (ret < 0) {
1485
0
    gnutls_assert();
1486
0
    goto cleanup;
1487
0
  }
1488
1489
0
  ret = 0;
1490
1491
0
 cleanup:
1492
0
  _gnutls_free_datum(&der);
1493
1494
0
  return ret;
1495
0
}
1496
1497
/**
1498
 * gnutls_x509_crt_get_serial:
1499
 * @cert: should contain a #gnutls_x509_crt_t type
1500
 * @result: The place where the serial number will be copied
1501
 * @result_size: Holds the size of the result field.
1502
 *
1503
 * This function will return the X.509 certificate's serial number.
1504
 * This is obtained by the X509 Certificate serialNumber field. Serial
1505
 * is not always a 32 or 64bit number. Some CAs use large serial
1506
 * numbers, thus it may be wise to handle it as something uint8_t.
1507
 *
1508
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1509
 *   negative error value.
1510
 **/
1511
int
1512
gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert, void *result,
1513
         size_t *result_size)
1514
0
{
1515
0
  int ret, len;
1516
1517
0
  if (cert == NULL) {
1518
0
    gnutls_assert();
1519
0
    return GNUTLS_E_INVALID_REQUEST;
1520
0
  }
1521
1522
0
  len = *result_size;
1523
0
  ret =
1524
0
      asn1_read_value(cert->cert, "tbsCertificate.serialNumber",
1525
0
          result, &len);
1526
0
  *result_size = len;
1527
1528
0
  if (ret != ASN1_SUCCESS) {
1529
0
    gnutls_assert();
1530
0
    return _gnutls_asn2err(ret);
1531
0
  }
1532
1533
0
  return 0;
1534
0
}
1535
1536
/**
1537
 * gnutls_x509_crt_get_subject_key_id:
1538
 * @cert: should contain a #gnutls_x509_crt_t type
1539
 * @ret: The place where the identifier will be copied
1540
 * @ret_size: Holds the size of the result field.
1541
 * @critical: will be non-zero if the extension is marked as critical (may be null)
1542
 *
1543
 * This function will return the X.509v3 certificate's subject key
1544
 * identifier.  This is obtained by the X.509 Subject Key identifier
1545
 * extension field (2.5.29.14).
1546
 *
1547
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1548
 * if the extension is not present, otherwise a negative error value.
1549
 **/
1550
int
1551
gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert, void *ret,
1552
           size_t *ret_size, unsigned int *critical)
1553
0
{
1554
0
  int result;
1555
0
  gnutls_datum_t id = { NULL, 0 };
1556
0
  gnutls_datum_t der = { NULL, 0 };
1557
1558
0
  if (cert == NULL) {
1559
0
    gnutls_assert();
1560
0
    return GNUTLS_E_INVALID_REQUEST;
1561
0
  }
1562
1563
0
  if (ret == NULL)
1564
0
    *ret_size = 0;
1565
1566
0
  if ((result =
1567
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &der,
1568
0
              critical)) < 0) {
1569
0
    return result;
1570
0
  }
1571
1572
0
  result = gnutls_x509_ext_import_subject_key_id(&der, &id);
1573
0
  if (result < 0) {
1574
0
    gnutls_assert();
1575
0
    goto cleanup;
1576
0
  }
1577
1578
0
  result = _gnutls_copy_data(&id, ret, ret_size);
1579
0
  if (result < 0) {
1580
0
    gnutls_assert();
1581
0
    goto cleanup;
1582
0
  }
1583
1584
0
  result = 0;
1585
1586
0
 cleanup:
1587
0
  gnutls_free(der.data);
1588
0
  gnutls_free(id.data);
1589
0
  return result;
1590
0
}
1591
1592
inline static int is_type_printable(int type)
1593
0
{
1594
0
  if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1595
0
      type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP ||
1596
0
      type == GNUTLS_SAN_OTHERNAME || type == GNUTLS_SAN_REGISTERED_ID)
1597
0
    return 1;
1598
0
  else
1599
0
    return 0;
1600
0
}
1601
1602
/**
1603
 * gnutls_x509_crt_get_authority_key_gn_serial:
1604
 * @cert: should contain a #gnutls_x509_crt_t type
1605
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1606
 * @alt: is the place where the alternative name will be copied to
1607
 * @alt_size: holds the size of alt.
1608
 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1609
 * @serial: buffer to store the serial number (may be null)
1610
 * @serial_size: Holds the size of the serial field (may be null)
1611
 * @critical: will be non-zero if the extension is marked as critical (may be null)
1612
 *
1613
 * This function will return the X.509 authority key
1614
 * identifier when stored as a general name (authorityCertIssuer)
1615
 * and serial number.
1616
 *
1617
 * Because more than one general names might be stored
1618
 * @seq can be used as a counter to request them all until
1619
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1620
 *
1621
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1622
 * if the extension is not present, otherwise a negative error value.
1623
 *
1624
 * Since: 3.0
1625
 **/
1626
int
1627
gnutls_x509_crt_get_authority_key_gn_serial(gnutls_x509_crt_t cert,
1628
              unsigned int seq, void *alt,
1629
              size_t *alt_size,
1630
              unsigned int *alt_type,
1631
              void *serial,
1632
              size_t *serial_size,
1633
              unsigned int *critical)
1634
0
{
1635
0
  int ret;
1636
0
  gnutls_datum_t der, san, iserial;
1637
0
  gnutls_x509_aki_t aki = NULL;
1638
0
  unsigned san_type;
1639
1640
0
  if (cert == NULL) {
1641
0
    gnutls_assert();
1642
0
    return GNUTLS_E_INVALID_REQUEST;
1643
0
  }
1644
1645
0
  if ((ret =
1646
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1647
0
              critical)) < 0) {
1648
0
    return gnutls_assert_val(ret);
1649
0
  }
1650
1651
0
  if (der.size == 0 || der.data == NULL) {
1652
0
    gnutls_assert();
1653
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1654
0
  }
1655
1656
0
  ret = gnutls_x509_aki_init(&aki);
1657
0
  if (ret < 0) {
1658
0
    gnutls_assert();
1659
0
    goto cleanup;
1660
0
  }
1661
1662
0
  ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1663
0
  if (ret < 0) {
1664
0
    gnutls_assert();
1665
0
    goto cleanup;
1666
0
  }
1667
1668
0
  ret =
1669
0
      gnutls_x509_aki_get_cert_issuer(aki, seq, &san_type, &san, NULL,
1670
0
              &iserial);
1671
0
  if (ret < 0) {
1672
0
    gnutls_assert();
1673
0
    goto cleanup;
1674
0
  }
1675
1676
0
  if (is_type_printable(san_type))
1677
0
    ret = _gnutls_copy_string(&san, alt, alt_size);
1678
0
  else
1679
0
    ret = _gnutls_copy_data(&san, alt, alt_size);
1680
0
  if (ret < 0) {
1681
0
    gnutls_assert();
1682
0
    goto cleanup;
1683
0
  }
1684
1685
0
  if (alt_type)
1686
0
    *alt_type = san_type;
1687
1688
0
  ret = _gnutls_copy_data(&iserial, serial, serial_size);
1689
0
  if (ret < 0) {
1690
0
    gnutls_assert();
1691
0
    goto cleanup;
1692
0
  }
1693
1694
0
  ret = 0;
1695
0
 cleanup:
1696
0
  if (aki != NULL)
1697
0
    gnutls_x509_aki_deinit(aki);
1698
0
  gnutls_free(der.data);
1699
0
  return ret;
1700
0
}
1701
1702
/**
1703
 * gnutls_x509_crt_get_authority_key_id:
1704
 * @cert: should contain a #gnutls_x509_crt_t type
1705
 * @id: The place where the identifier will be copied
1706
 * @id_size: Holds the size of the id field.
1707
 * @critical: will be non-zero if the extension is marked as critical (may be null)
1708
 *
1709
 * This function will return the X.509v3 certificate authority's key
1710
 * identifier.  This is obtained by the X.509 Authority Key
1711
 * identifier extension field (2.5.29.35). Note that this function
1712
 * only returns the keyIdentifier field of the extension and
1713
 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
1714
 * the name and serial number of the certificate. In that case
1715
 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
1716
 *
1717
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1718
 * if the extension is not present, otherwise a negative error value.
1719
 **/
1720
int
1721
gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert, void *id,
1722
             size_t *id_size, unsigned int *critical)
1723
0
{
1724
0
  int ret;
1725
0
  gnutls_datum_t der, l_id;
1726
0
  gnutls_x509_aki_t aki = NULL;
1727
1728
0
  if (cert == NULL) {
1729
0
    gnutls_assert();
1730
0
    return GNUTLS_E_INVALID_REQUEST;
1731
0
  }
1732
1733
0
  if ((ret =
1734
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1735
0
              critical)) < 0) {
1736
0
    return gnutls_assert_val(ret);
1737
0
  }
1738
1739
0
  if (der.size == 0 || der.data == NULL) {
1740
0
    gnutls_assert();
1741
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1742
0
  }
1743
1744
0
  ret = gnutls_x509_aki_init(&aki);
1745
0
  if (ret < 0) {
1746
0
    gnutls_assert();
1747
0
    goto cleanup;
1748
0
  }
1749
1750
0
  ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1751
0
  if (ret < 0) {
1752
0
    gnutls_assert();
1753
0
    goto cleanup;
1754
0
  }
1755
1756
0
  ret = gnutls_x509_aki_get_id(aki, &l_id);
1757
1758
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1759
0
    gnutls_datum_t serial;
1760
0
    ret =
1761
0
        gnutls_x509_aki_get_cert_issuer(aki, 0, NULL, NULL, NULL,
1762
0
                &serial);
1763
0
    if (ret >= 0) {
1764
0
      ret =
1765
0
          gnutls_assert_val
1766
0
          (GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1767
0
    } else {
1768
0
      ret =
1769
0
          gnutls_assert_val
1770
0
          (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1771
0
    }
1772
0
  }
1773
1774
0
  if (ret < 0) {
1775
0
    gnutls_assert();
1776
0
    goto cleanup;
1777
0
  }
1778
1779
0
  ret = _gnutls_copy_data(&l_id, id, id_size);
1780
0
  if (ret < 0) {
1781
0
    gnutls_assert();
1782
0
    goto cleanup;
1783
0
  }
1784
1785
0
  ret = 0;
1786
0
 cleanup:
1787
0
  if (aki != NULL)
1788
0
    gnutls_x509_aki_deinit(aki);
1789
0
  gnutls_free(der.data);
1790
0
  return ret;
1791
0
}
1792
1793
/**
1794
 * gnutls_x509_crt_get_pk_algorithm:
1795
 * @cert: should contain a #gnutls_x509_crt_t type
1796
 * @bits: if bits is non null it will hold the size of the parameters' in bits
1797
 *
1798
 * This function will return the public key algorithm of an X.509
1799
 * certificate.
1800
 *
1801
 * If bits is non null, it should have enough size to hold the parameters
1802
 * size in bits. For RSA the bits returned is the modulus.
1803
 * For DSA the bits returned are of the public
1804
 * exponent.
1805
 *
1806
 * Unknown/unsupported algorithms are mapped to %GNUTLS_PK_UNKNOWN.
1807
 *
1808
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1809
 * success, or a negative error code on error.
1810
 **/
1811
int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert, unsigned int *bits)
1812
0
{
1813
0
  int result;
1814
1815
0
  if (cert == NULL) {
1816
0
    gnutls_assert();
1817
0
    return GNUTLS_E_INVALID_REQUEST;
1818
0
  }
1819
1820
0
  if (bits)
1821
0
    *bits = 0;
1822
1823
0
  result =
1824
0
      _gnutls_x509_get_pk_algorithm(cert->cert,
1825
0
            "tbsCertificate.subjectPublicKeyInfo",
1826
0
            NULL, bits);
1827
1828
0
  if (result < 0) {
1829
0
    gnutls_assert();
1830
0
    return result;
1831
0
  }
1832
1833
0
  return result;
1834
0
}
1835
1836
/**
1837
 * gnutls_x509_crt_get_spki:
1838
 * @cert: a certificate of type #gnutls_x509_crt_t
1839
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1840
 * @flags: must be zero
1841
 *
1842
 * This function will return the public key information of an X.509
1843
 * certificate. The provided @spki must be initialized.
1844
 *
1845
 * Since: 3.6.0
1846
 **/
1847
int
1848
gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert, gnutls_x509_spki_t spki,
1849
       unsigned int flags)
1850
0
{
1851
0
  int result;
1852
0
  gnutls_x509_spki_st params;
1853
1854
0
  if (cert == NULL) {
1855
0
    gnutls_assert();
1856
0
    return GNUTLS_E_INVALID_REQUEST;
1857
0
  }
1858
1859
0
  spki->pk = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
1860
1861
0
  memset(&params, 0, sizeof(params));
1862
1863
0
  result = _gnutls_x509_crt_read_spki_params(cert, &params);
1864
0
  if (result < 0) {
1865
0
    gnutls_assert();
1866
0
    return result;
1867
0
  }
1868
1869
0
  if (params.pk == GNUTLS_PK_UNKNOWN)
1870
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1871
1872
0
  spki->rsa_pss_dig = params.rsa_pss_dig;
1873
0
  spki->salt_size = params.salt_size;
1874
1875
0
  return 0;
1876
0
}
1877
1878
/* returns the type and the name on success.
1879
 * Type is also returned as a parameter in case of an error.
1880
 *
1881
 * @seq: in case of GeneralNames it will return the corresponding name.
1882
 *       in case of GeneralName, it must be -1
1883
 * @dname: the name returned
1884
 * @ret_type: The type of the name
1885
 * @othername_oid: if the name is otherName return the OID
1886
 *
1887
 */
1888
int
1889
_gnutls_parse_general_name2(asn1_node src, const char *src_name,
1890
          int seq, gnutls_datum_t * dname,
1891
          unsigned int *ret_type, int othername_oid)
1892
0
{
1893
0
  int len, ret;
1894
0
  char nptr[MAX_NAME_SIZE];
1895
0
  int result;
1896
0
  gnutls_datum_t tmp = { NULL, 0 };
1897
0
  char choice_type[128];
1898
0
  gnutls_x509_subject_alt_name_t type;
1899
1900
0
  if (seq != -1) {
1901
0
    seq++;    /* 0->1, 1->2 etc */
1902
1903
0
    if (src_name[0] != 0)
1904
0
      snprintf(nptr, sizeof(nptr), "%s.?%d", src_name, seq);
1905
0
    else
1906
0
      snprintf(nptr, sizeof(nptr), "?%d", seq);
1907
0
  } else {
1908
0
    snprintf(nptr, sizeof(nptr), "%s", src_name);
1909
0
  }
1910
1911
0
  len = sizeof(choice_type);
1912
0
  result = asn1_read_value(src, nptr, choice_type, &len);
1913
0
  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND) {
1914
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1915
0
  }
1916
1917
0
  if (result != ASN1_SUCCESS) {
1918
0
    gnutls_assert();
1919
0
    return _gnutls_asn2err(result);
1920
0
  }
1921
1922
0
  type = _gnutls_x509_san_find_type(choice_type);
1923
0
  if (type == (gnutls_x509_subject_alt_name_t) - 1) {
1924
0
    gnutls_assert();
1925
0
    return GNUTLS_E_X509_UNKNOWN_SAN;
1926
0
  }
1927
1928
0
  if (ret_type)
1929
0
    *ret_type = type;
1930
1931
0
  if (type == GNUTLS_SAN_OTHERNAME) {
1932
0
    if (othername_oid)
1933
0
      _gnutls_str_cat(nptr, sizeof(nptr),
1934
0
          ".otherName.type-id");
1935
0
    else
1936
0
      _gnutls_str_cat(nptr, sizeof(nptr), ".otherName.value");
1937
1938
0
    ret = _gnutls_x509_read_value(src, nptr, &tmp);
1939
0
    if (ret < 0) {
1940
0
      gnutls_assert();
1941
0
      return ret;
1942
0
    }
1943
1944
0
    if (othername_oid) {
1945
0
      dname->size = tmp.size;
1946
0
      dname->data = tmp.data;
1947
0
    } else {
1948
0
      char oid[MAX_OID_SIZE];
1949
1950
0
      if (src_name[0] != 0 && seq != -1)
1951
0
        snprintf(nptr, sizeof(nptr),
1952
0
           "%s.?%d.otherName.type-id",
1953
0
           src_name, seq);
1954
0
      else if (src_name[0] != 0)
1955
0
        snprintf(nptr, sizeof(nptr),
1956
0
           "%s.otherName.type-id", src_name);
1957
0
      else
1958
0
        snprintf(nptr, sizeof(nptr),
1959
0
           "?%d.otherName.type-id", seq);
1960
1961
0
      len = sizeof(oid);
1962
1963
0
      result = asn1_read_value(src, nptr, oid, &len);
1964
0
      if (result != ASN1_SUCCESS) {
1965
0
        gnutls_assert();
1966
0
        ret = _gnutls_asn2err(result);
1967
0
        goto cleanup;
1968
0
      }
1969
0
      if (len > 0)
1970
0
        len--;
1971
1972
0
      dname->size = tmp.size;
1973
0
      dname->data = tmp.data;
1974
0
    }
1975
0
  } else if (type == GNUTLS_SAN_DN) {
1976
0
    _gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
1977
0
    ret = _gnutls_x509_get_dn(src, nptr, dname, 0);
1978
0
    if (ret < 0) {
1979
0
      gnutls_assert();
1980
0
      goto cleanup;
1981
0
    }
1982
0
  } else if (othername_oid) {
1983
0
    gnutls_assert();
1984
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1985
0
    goto cleanup;
1986
0
  } else {
1987
0
    _gnutls_str_cat(nptr, sizeof(nptr), ".");
1988
0
    _gnutls_str_cat(nptr, sizeof(nptr), choice_type);
1989
1990
0
    ret = _gnutls_x509_read_null_value(src, nptr, &tmp);
1991
0
    if (ret < 0) {
1992
0
      gnutls_assert();
1993
0
      return ret;
1994
0
    }
1995
1996
    /* _gnutls_x509_read_value() null terminates */
1997
0
    dname->size = tmp.size;
1998
0
    dname->data = tmp.data;
1999
0
  }
2000
2001
0
  return type;
2002
2003
0
 cleanup:
2004
0
  gnutls_free(tmp.data);
2005
0
  return ret;
2006
0
}
2007
2008
/* returns the type and the name on success.
2009
 * Type is also returned as a parameter in case of an error.
2010
 */
2011
int
2012
_gnutls_parse_general_name(asn1_node src, const char *src_name,
2013
         int seq, void *name, size_t *name_size,
2014
         unsigned int *ret_type, int othername_oid)
2015
0
{
2016
0
  int ret;
2017
0
  gnutls_datum_t res = { NULL, 0 };
2018
0
  unsigned type;
2019
2020
0
  ret =
2021
0
      _gnutls_parse_general_name2(src, src_name, seq, &res, ret_type,
2022
0
          othername_oid);
2023
0
  if (ret < 0)
2024
0
    return gnutls_assert_val(ret);
2025
2026
0
  type = ret;
2027
2028
0
  if (is_type_printable(type)) {
2029
0
    ret = _gnutls_copy_string(&res, name, name_size);
2030
0
  } else {
2031
0
    ret = _gnutls_copy_data(&res, name, name_size);
2032
0
  }
2033
2034
0
  if (ret < 0) {
2035
0
    gnutls_assert();
2036
0
    goto cleanup;
2037
0
  }
2038
2039
0
  ret = type;
2040
0
 cleanup:
2041
0
  gnutls_free(res.data);
2042
0
  return ret;
2043
0
}
2044
2045
static int
2046
get_alt_name(gnutls_subject_alt_names_t san,
2047
       unsigned int seq, uint8_t * alt,
2048
       size_t *alt_size, unsigned int *alt_type,
2049
       unsigned int *critical, int othername_oid)
2050
0
{
2051
0
  int ret;
2052
0
  gnutls_datum_t ooid = { NULL, 0 };
2053
0
  gnutls_datum_t oname;
2054
0
  gnutls_datum_t virt = { NULL, 0 };
2055
0
  unsigned int type;
2056
2057
0
  if (san == NULL) {
2058
0
    gnutls_assert();
2059
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2060
0
  }
2061
2062
0
  if (alt == NULL)
2063
0
    *alt_size = 0;
2064
2065
0
  ret = gnutls_subject_alt_names_get(san, seq, &type, &oname, &ooid);
2066
0
  if (ret < 0) {
2067
0
    gnutls_assert();
2068
0
    goto cleanup;
2069
0
  }
2070
2071
0
  if (type == GNUTLS_SAN_OTHERNAME && ooid.data) {
2072
0
    unsigned vtype;
2073
0
    ret =
2074
0
        gnutls_x509_othername_to_virtual((char *)ooid.data, &oname,
2075
0
                 &vtype, &virt);
2076
0
    if (ret >= 0) {
2077
0
      type = vtype;
2078
0
      oname.data = virt.data;
2079
0
      oname.size = virt.size;
2080
0
    }
2081
0
  }
2082
2083
0
  if (alt_type)
2084
0
    *alt_type = type;
2085
2086
0
  if (othername_oid) {
2087
0
    ret = _gnutls_copy_string(&ooid, alt, alt_size);
2088
0
  } else {
2089
0
    if (is_type_printable(type)) {
2090
0
      ret = _gnutls_copy_string(&oname, alt, alt_size);
2091
0
    } else {
2092
0
      ret = _gnutls_copy_data(&oname, alt, alt_size);
2093
0
    }
2094
0
  }
2095
2096
0
  if (ret < 0) {
2097
0
    gnutls_assert();
2098
0
    goto cleanup;
2099
0
  }
2100
2101
0
  ret = type;
2102
0
 cleanup:
2103
0
  gnutls_free(virt.data);
2104
2105
0
  return ret;
2106
0
}
2107
2108
/**
2109
 * gnutls_x509_crt_get_subject_alt_name:
2110
 * @cert: should contain a #gnutls_x509_crt_t type
2111
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2112
 * @san: is the place where the alternative name will be copied to
2113
 * @san_size: holds the size of san.
2114
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2115
 *
2116
 * This function retrieves the Alternative Name (2.5.29.17), contained
2117
 * in the given certificate in the X509v3 Certificate Extensions.
2118
 *
2119
 * When the SAN type is otherName, it will extract the data in the
2120
 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
2121
 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
2122
 * the corresponding OID and the "virtual" SAN types (e.g.,
2123
 * %GNUTLS_SAN_OTHERNAME_XMPP).
2124
 *
2125
 * If an otherName OID is known, the data will be decoded.  Otherwise
2126
 * the returned data will be DER encoded, and you will have to decode
2127
 * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr SAN is
2128
 * recognized.
2129
 *
2130
 * Returns: the alternative subject name type on success, one of the
2131
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2132
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
2133
 *   hold the value.  In that case @san_size will be updated with the
2134
 *   required size.  If the certificate does not have an Alternative
2135
 *   name with the specified sequence number then
2136
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2137
 **/
2138
int
2139
gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
2140
             unsigned int seq, void *san,
2141
             size_t *san_size, unsigned int *critical)
2142
0
{
2143
0
  return get_alt_name(cert->san, seq, san, san_size, NULL, critical, 0);
2144
0
}
2145
2146
/**
2147
 * gnutls_x509_crt_get_issuer_alt_name:
2148
 * @cert: should contain a #gnutls_x509_crt_t type
2149
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2150
 * @ian: is the place where the alternative name will be copied to
2151
 * @ian_size: holds the size of ian.
2152
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2153
 *
2154
 * This function retrieves the Issuer Alternative Name (2.5.29.18),
2155
 * contained in the given certificate in the X509v3 Certificate
2156
 * Extensions.
2157
 *
2158
 * When the SAN type is otherName, it will extract the data in the
2159
 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
2160
 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
2161
 * the corresponding OID and the "virtual" SAN types (e.g.,
2162
 * %GNUTLS_SAN_OTHERNAME_XMPP).
2163
 *
2164
 * If an otherName OID is known, the data will be decoded.  Otherwise
2165
 * the returned data will be DER encoded, and you will have to decode
2166
 * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr Issuer
2167
 * AltName is recognized.
2168
 *
2169
 * Returns: the alternative issuer name type on success, one of the
2170
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2171
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
2172
 *   to hold the value.  In that case @ian_size will be updated with
2173
 *   the required size.  If the certificate does not have an
2174
 *   Alternative name with the specified sequence number then
2175
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2176
 *
2177
 * Since: 2.10.0
2178
 **/
2179
int
2180
gnutls_x509_crt_get_issuer_alt_name(gnutls_x509_crt_t cert,
2181
            unsigned int seq, void *ian,
2182
            size_t *ian_size, unsigned int *critical)
2183
0
{
2184
0
  return get_alt_name(cert->ian, seq, ian, ian_size, NULL, critical, 0);
2185
0
}
2186
2187
/**
2188
 * gnutls_x509_crt_get_subject_alt_name2:
2189
 * @cert: should contain a #gnutls_x509_crt_t type
2190
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2191
 * @san: is the place where the alternative name will be copied to
2192
 * @san_size: holds the size of ret.
2193
 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
2194
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2195
 *
2196
 * This function will return the alternative names, contained in the
2197
 * given certificate. It is the same as
2198
 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
2199
 * will return the type of the alternative name in @san_type even if
2200
 * the function fails for some reason (i.e.  the buffer provided is
2201
 * not enough).
2202
 *
2203
 * Returns: the alternative subject name type on success, one of the
2204
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2205
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
2206
 *   to hold the value.  In that case @san_size will be updated with
2207
 *   the required size.  If the certificate does not have an
2208
 *   Alternative name with the specified sequence number then
2209
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2210
 **/
2211
int
2212
gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,
2213
              unsigned int seq, void *san,
2214
              size_t *san_size,
2215
              unsigned int *san_type,
2216
              unsigned int *critical)
2217
0
{
2218
0
  return get_alt_name(cert->san, seq, san, san_size,
2219
0
          san_type, critical, 0);
2220
0
}
2221
2222
/**
2223
 * gnutls_x509_crt_get_issuer_alt_name2:
2224
 * @cert: should contain a #gnutls_x509_crt_t type
2225
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2226
 * @ian: is the place where the alternative name will be copied to
2227
 * @ian_size: holds the size of ret.
2228
 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
2229
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2230
 *
2231
 * This function will return the alternative names, contained in the
2232
 * given certificate. It is the same as
2233
 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
2234
 * will return the type of the alternative name in @ian_type even if
2235
 * the function fails for some reason (i.e.  the buffer provided is
2236
 * not enough).
2237
 *
2238
 * Returns: the alternative issuer name type on success, one of the
2239
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2240
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
2241
 *   to hold the value.  In that case @ian_size will be updated with
2242
 *   the required size.  If the certificate does not have an
2243
 *   Alternative name with the specified sequence number then
2244
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2245
 *
2246
 * Since: 2.10.0
2247
 *
2248
 **/
2249
int
2250
gnutls_x509_crt_get_issuer_alt_name2(gnutls_x509_crt_t cert,
2251
             unsigned int seq, void *ian,
2252
             size_t *ian_size,
2253
             unsigned int *ian_type,
2254
             unsigned int *critical)
2255
0
{
2256
0
  return get_alt_name(cert->ian, seq, ian, ian_size,
2257
0
          ian_type, critical, 0);
2258
0
}
2259
2260
/**
2261
 * gnutls_x509_crt_get_subject_alt_othername_oid:
2262
 * @cert: should contain a #gnutls_x509_crt_t type
2263
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2264
 * @oid: is the place where the otherName OID will be copied to
2265
 * @oid_size: holds the size of ret.
2266
 *
2267
 * This function will extract the type OID of an otherName Subject
2268
 * Alternative Name, contained in the given certificate, and return
2269
 * the type as an enumerated element.
2270
 *
2271
 * This function is only useful if
2272
 * gnutls_x509_crt_get_subject_alt_name() returned
2273
 * %GNUTLS_SAN_OTHERNAME.
2274
 *
2275
 * If @oid is null then only the size will be filled. The @oid
2276
 * returned will be null terminated, although @oid_size will not
2277
 * account for the trailing null.
2278
 *
2279
 * Returns: the alternative subject name type on success, one of the
2280
 * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
2281
 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
2282
 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
2283
 * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
2284
 * @ian_size is not large enough to hold the value.  In that case
2285
 * @ian_size will be updated with the required size.  If the
2286
 * certificate does not have an Alternative name with the specified
2287
 * sequence number and with the otherName type then
2288
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2289
 **/
2290
int
2291
gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,
2292
                unsigned int seq,
2293
                void *oid, size_t *oid_size)
2294
0
{
2295
0
  return get_alt_name(cert->san, seq, oid, oid_size, NULL, NULL, 1);
2296
0
}
2297
2298
/**
2299
 * gnutls_x509_crt_get_issuer_alt_othername_oid:
2300
 * @cert: should contain a #gnutls_x509_crt_t type
2301
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2302
 * @ret: is the place where the otherName OID will be copied to
2303
 * @ret_size: holds the size of ret.
2304
 *
2305
 * This function will extract the type OID of an otherName Subject
2306
 * Alternative Name, contained in the given certificate, and return
2307
 * the type as an enumerated element.
2308
 *
2309
 * If @oid is null then only the size will be filled. The @oid
2310
 * returned will be null terminated, although @oid_size will not
2311
 * account for the trailing null.
2312
 *
2313
 * This function is only useful if
2314
 * gnutls_x509_crt_get_issuer_alt_name() returned
2315
 * %GNUTLS_SAN_OTHERNAME.
2316
 *
2317
 * Returns: the alternative issuer name type on success, one of the
2318
 * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
2319
 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
2320
 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
2321
 * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
2322
 * @ret_size is not large enough to hold the value.  In that case
2323
 * @ret_size will be updated with the required size.  If the
2324
 * certificate does not have an Alternative name with the specified
2325
 * sequence number and with the otherName type then
2326
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2327
 *
2328
 * Since: 2.10.0
2329
 **/
2330
int
2331
gnutls_x509_crt_get_issuer_alt_othername_oid(gnutls_x509_crt_t cert,
2332
               unsigned int seq,
2333
               void *ret, size_t *ret_size)
2334
0
{
2335
0
  return get_alt_name(cert->ian, seq, ret, ret_size, NULL, NULL, 1);
2336
0
}
2337
2338
/**
2339
 * gnutls_x509_crt_get_basic_constraints:
2340
 * @cert: should contain a #gnutls_x509_crt_t type
2341
 * @critical: will be non-zero if the extension is marked as critical
2342
 * @ca: pointer to output integer indicating CA status, may be NULL,
2343
 *   value is 1 if the certificate CA flag is set, 0 otherwise.
2344
 * @pathlen: pointer to output integer indicating path length (may be
2345
 *   NULL), non-negative error codes indicate a present pathLenConstraint
2346
 *   field and the actual value, -1 indicate that the field is absent.
2347
 *
2348
 * This function will read the certificate's basic constraints, and
2349
 * return the certificates CA status.  It reads the basicConstraints
2350
 * X.509 extension (2.5.29.19).
2351
 *
2352
 * Returns: If the certificate is a CA a positive value will be
2353
 * returned, or (0) if the certificate does not have CA flag set.  A
2354
 * negative error code may be returned in case of errors.  If the
2355
 * certificate does not contain the basicConstraints extension
2356
 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2357
 **/
2358
int
2359
gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
2360
              unsigned int *critical,
2361
              unsigned int *ca, int *pathlen)
2362
0
{
2363
0
  int result;
2364
0
  gnutls_datum_t basicConstraints;
2365
0
  unsigned int tmp_ca;
2366
2367
0
  if (cert == NULL) {
2368
0
    gnutls_assert();
2369
0
    return GNUTLS_E_INVALID_REQUEST;
2370
0
  }
2371
2372
0
  if ((result =
2373
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.19", 0,
2374
0
              &basicConstraints, critical)) < 0) {
2375
0
    return result;
2376
0
  }
2377
2378
0
  if (basicConstraints.size == 0 || basicConstraints.data == NULL) {
2379
0
    gnutls_assert();
2380
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2381
0
  }
2382
2383
0
  result =
2384
0
      gnutls_x509_ext_import_basic_constraints(&basicConstraints, &tmp_ca,
2385
0
                 pathlen);
2386
0
  if (ca)
2387
0
    *ca = tmp_ca;
2388
2389
0
  _gnutls_free_datum(&basicConstraints);
2390
2391
0
  if (result < 0) {
2392
0
    gnutls_assert();
2393
0
    return result;
2394
0
  }
2395
2396
0
  return tmp_ca;
2397
0
}
2398
2399
/**
2400
 * gnutls_x509_crt_get_ca_status:
2401
 * @cert: should contain a #gnutls_x509_crt_t type
2402
 * @critical: will be non-zero if the extension is marked as critical
2403
 *
2404
 * This function will return certificates CA status, by reading the
2405
 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
2406
 * a CA a positive value will be returned, or (0) if the certificate
2407
 * does not have CA flag set.
2408
 *
2409
 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
2410
 * pathLenConstraint field too.
2411
 *
2412
 * Returns: If the certificate is a CA a positive value will be
2413
 * returned, or (0) if the certificate does not have CA flag set.  A
2414
 * negative error code may be returned in case of errors.  If the
2415
 * certificate does not contain the basicConstraints extension
2416
 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2417
 **/
2418
int
2419
gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert, unsigned int *critical)
2420
0
{
2421
0
  int pathlen;
2422
0
  unsigned int ca;
2423
0
  return gnutls_x509_crt_get_basic_constraints(cert, critical, &ca,
2424
0
                 &pathlen);
2425
0
}
2426
2427
/**
2428
 * gnutls_x509_crt_get_key_usage:
2429
 * @cert: should contain a #gnutls_x509_crt_t type
2430
 * @key_usage: where the key usage bits will be stored
2431
 * @critical: will be non-zero if the extension is marked as critical
2432
 *
2433
 * This function will return certificate's key usage, by reading the
2434
 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
2435
 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
2436
 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
2437
 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
2438
 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
2439
 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
2440
 *
2441
 * Returns: zero on success, or a negative error code in case of
2442
 *   parsing error.  If the certificate does not contain the keyUsage
2443
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
2444
 *   returned.
2445
 **/
2446
int
2447
gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
2448
            unsigned int *key_usage, unsigned int *critical)
2449
0
{
2450
0
  int result;
2451
0
  gnutls_datum_t keyUsage;
2452
2453
0
  if (cert == NULL) {
2454
0
    gnutls_assert();
2455
0
    return GNUTLS_E_INVALID_REQUEST;
2456
0
  }
2457
2458
0
  if ((result =
2459
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.15", 0,
2460
0
              &keyUsage, critical)) < 0) {
2461
0
    return result;
2462
0
  }
2463
2464
0
  if (keyUsage.size == 0 || keyUsage.data == NULL) {
2465
0
    gnutls_assert();
2466
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2467
0
  }
2468
2469
0
  result = gnutls_x509_ext_import_key_usage(&keyUsage, key_usage);
2470
0
  _gnutls_free_datum(&keyUsage);
2471
2472
0
  if (result < 0) {
2473
0
    gnutls_assert();
2474
0
    return result;
2475
0
  }
2476
2477
0
  return 0;
2478
0
}
2479
2480
/**
2481
 * gnutls_x509_crt_get_inhibit_anypolicy:
2482
 * @cert: should contain a #gnutls_x509_crt_t type
2483
 * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable.
2484
 * @critical: will be non-zero if the extension is marked as critical
2485
 *
2486
 * This function will return certificate's value of the SkipCerts, i.e.,
2487
 * the Inhibit anyPolicy X.509 extension (2.5.29.54).
2488
 *
2489
 * The returned value is the number of additional certificates that
2490
 * may appear in the path before the anyPolicy is no longer acceptable.
2491
2492
 * Returns: zero on success, or a negative error code in case of
2493
 *   parsing error.  If the certificate does not contain the Inhibit anyPolicy
2494
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
2495
 *   returned.
2496
 *
2497
 * Since: 3.6.0
2498
 **/
2499
int
2500
gnutls_x509_crt_get_inhibit_anypolicy(gnutls_x509_crt_t cert,
2501
              unsigned int *skipcerts,
2502
              unsigned int *critical)
2503
0
{
2504
0
  int ret;
2505
0
  gnutls_datum_t ext;
2506
2507
0
  if (cert == NULL) {
2508
0
    gnutls_assert();
2509
0
    return GNUTLS_E_INVALID_REQUEST;
2510
0
  }
2511
2512
0
  if ((ret =
2513
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.54", 0,
2514
0
              &ext, critical)) < 0) {
2515
0
    return ret;
2516
0
  }
2517
2518
0
  if (ext.size == 0 || ext.data == NULL) {
2519
0
    gnutls_assert();
2520
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2521
0
  }
2522
2523
0
  ret = gnutls_x509_ext_import_key_usage(&ext, skipcerts);
2524
0
  _gnutls_free_datum(&ext);
2525
2526
0
  if (ret < 0) {
2527
0
    gnutls_assert();
2528
0
    return ret;
2529
0
  }
2530
2531
0
  return 0;
2532
0
}
2533
2534
/**
2535
 * gnutls_x509_crt_get_proxy:
2536
 * @cert: should contain a #gnutls_x509_crt_t type
2537
 * @critical: will be non-zero if the extension is marked as critical
2538
 * @pathlen: pointer to output integer indicating path length (may be
2539
 *   NULL), non-negative error codes indicate a present pCPathLenConstraint
2540
 *   field and the actual value, -1 indicate that the field is absent.
2541
 * @policyLanguage: output variable with OID of policy language
2542
 * @policy: output variable with policy data
2543
 * @sizeof_policy: output variable size of policy data
2544
 *
2545
 * This function will get information from a proxy certificate.  It
2546
 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
2547
 *
2548
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2549
 *   otherwise a negative error code is returned.
2550
 **/
2551
int
2552
gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert,
2553
        unsigned int *critical,
2554
        int *pathlen,
2555
        char **policyLanguage,
2556
        char **policy, size_t *sizeof_policy)
2557
0
{
2558
0
  int result;
2559
0
  gnutls_datum_t proxyCertInfo;
2560
2561
0
  if (cert == NULL) {
2562
0
    gnutls_assert();
2563
0
    return GNUTLS_E_INVALID_REQUEST;
2564
0
  }
2565
2566
0
  if ((result =
2567
0
       _gnutls_x509_crt_get_extension(cert, "1.3.6.1.5.5.7.1.14", 0,
2568
0
              &proxyCertInfo, critical)) < 0) {
2569
0
    return result;
2570
0
  }
2571
2572
0
  if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL) {
2573
0
    gnutls_assert();
2574
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2575
0
  }
2576
2577
0
  result = gnutls_x509_ext_import_proxy(&proxyCertInfo, pathlen,
2578
0
                policyLanguage,
2579
0
                policy, sizeof_policy);
2580
0
  _gnutls_free_datum(&proxyCertInfo);
2581
0
  if (result < 0) {
2582
0
    gnutls_assert();
2583
0
    return result;
2584
0
  }
2585
2586
0
  return 0;
2587
0
}
2588
2589
/**
2590
 * gnutls_x509_policy_release:
2591
 * @policy: a certificate policy
2592
 *
2593
 * This function will deinitialize all memory associated with the provided
2594
 * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
2595
 *
2596
 * Since: 3.1.5
2597
 **/
2598
void gnutls_x509_policy_release(struct gnutls_x509_policy_st *policy)
2599
0
{
2600
0
  unsigned i;
2601
2602
0
  gnutls_free(policy->oid);
2603
0
  for (i = 0; i < policy->qualifiers; i++)
2604
0
    gnutls_free(policy->qualifier[i].data);
2605
0
}
2606
2607
/**
2608
 * gnutls_x509_crt_get_policy:
2609
 * @crt: should contain a #gnutls_x509_crt_t type
2610
 * @indx: This specifies which policy to return. Use (0) to get the first one.
2611
 * @policy: A pointer to a policy structure.
2612
 * @critical: will be non-zero if the extension is marked as critical
2613
 *
2614
 * This function will extract the certificate policy (extension 2.5.29.32)
2615
 * specified by the given index.
2616
 *
2617
 * The policy returned by this function must be deinitialized by using
2618
 * gnutls_x509_policy_release().
2619
 *
2620
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2621
 * if the extension is not present, otherwise a negative error value.
2622
 *
2623
 * Since: 3.1.5
2624
 **/
2625
int
2626
gnutls_x509_crt_get_policy(gnutls_x509_crt_t crt, unsigned indx,
2627
         struct gnutls_x509_policy_st *policy,
2628
         unsigned int *critical)
2629
0
{
2630
0
  gnutls_datum_t tmpd = { NULL, 0 };
2631
0
  int ret;
2632
0
  gnutls_x509_policies_t policies = NULL;
2633
2634
0
  if (crt == NULL) {
2635
0
    gnutls_assert();
2636
0
    return GNUTLS_E_INVALID_REQUEST;
2637
0
  }
2638
2639
0
  memset(policy, 0, sizeof(*policy));
2640
2641
0
  ret = gnutls_x509_policies_init(&policies);
2642
0
  if (ret < 0)
2643
0
    return gnutls_assert_val(ret);
2644
2645
0
  if ((ret =
2646
0
       _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &tmpd,
2647
0
              critical)) < 0) {
2648
0
    goto cleanup;
2649
0
  }
2650
2651
0
  if (tmpd.size == 0 || tmpd.data == NULL) {
2652
0
    gnutls_assert();
2653
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2654
0
    goto cleanup;
2655
0
  }
2656
2657
0
  ret = gnutls_x509_ext_import_policies(&tmpd, policies, 0);
2658
0
  if (ret < 0) {
2659
0
    gnutls_assert();
2660
0
    goto cleanup;
2661
0
  }
2662
2663
0
  ret = gnutls_x509_policies_get(policies, indx, policy);
2664
0
  if (ret < 0) {
2665
0
    gnutls_assert();
2666
0
    goto cleanup;
2667
0
  }
2668
2669
0
  _gnutls_x509_policies_erase(policies, indx);
2670
2671
0
  ret = 0;
2672
2673
0
 cleanup:
2674
0
  if (policies != NULL)
2675
0
    gnutls_x509_policies_deinit(policies);
2676
0
  _gnutls_free_datum(&tmpd);
2677
2678
0
  return ret;
2679
0
}
2680
2681
/**
2682
 * gnutls_x509_crt_get_extension_by_oid:
2683
 * @cert: should contain a #gnutls_x509_crt_t type
2684
 * @oid: holds an Object Identified in null terminated string
2685
 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2686
 * @buf: a pointer to a structure to hold the name (may be null)
2687
 * @buf_size: initially holds the size of @buf
2688
 * @critical: will be non-zero if the extension is marked as critical
2689
 *
2690
 * This function will return the extension specified by the OID in the
2691
 * certificate.  The extensions will be returned as binary data DER
2692
 * encoded, in the provided buffer.
2693
 *
2694
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2695
 *   otherwise a negative error code is returned. If the certificate does not
2696
 *   contain the specified extension
2697
 *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2698
 **/
2699
int
2700
gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,
2701
             const char *oid, unsigned indx,
2702
             void *buf, size_t *buf_size,
2703
             unsigned int *critical)
2704
0
{
2705
0
  int result;
2706
0
  gnutls_datum_t output;
2707
2708
0
  if (cert == NULL) {
2709
0
    gnutls_assert();
2710
0
    return GNUTLS_E_INVALID_REQUEST;
2711
0
  }
2712
2713
0
  if ((result =
2714
0
       _gnutls_x509_crt_get_extension(cert, oid, indx, &output,
2715
0
              critical)) < 0) {
2716
0
    gnutls_assert();
2717
0
    return result;
2718
0
  }
2719
2720
0
  if (output.size == 0 || output.data == NULL) {
2721
0
    gnutls_assert();
2722
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2723
0
  }
2724
2725
0
  if (output.size > (unsigned int)*buf_size) {
2726
0
    *buf_size = output.size;
2727
0
    _gnutls_free_datum(&output);
2728
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
2729
0
  }
2730
2731
0
  *buf_size = output.size;
2732
2733
0
  if (buf)
2734
0
    memcpy(buf, output.data, output.size);
2735
2736
0
  _gnutls_free_datum(&output);
2737
2738
0
  return 0;
2739
0
}
2740
2741
/**
2742
 * gnutls_x509_crt_get_extension_by_oid2:
2743
 * @cert: should contain a #gnutls_x509_crt_t type
2744
 * @oid: holds an Object Identified in null terminated string
2745
 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2746
 * @output: will hold the allocated extension data
2747
 * @critical: will be non-zero if the extension is marked as critical
2748
 *
2749
 * This function will return the extension specified by the OID in the
2750
 * certificate.  The extensions will be returned as binary data DER
2751
 * encoded, in the provided buffer.
2752
 *
2753
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2754
 *   otherwise a negative error code is returned. If the certificate does not
2755
 *   contain the specified extension
2756
 *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2757
 *
2758
 * Since: 3.3.8
2759
 **/
2760
int
2761
gnutls_x509_crt_get_extension_by_oid2(gnutls_x509_crt_t cert,
2762
              const char *oid, unsigned indx,
2763
              gnutls_datum_t * output,
2764
              unsigned int *critical)
2765
0
{
2766
0
  int ret;
2767
2768
0
  if (cert == NULL) {
2769
0
    gnutls_assert();
2770
0
    return GNUTLS_E_INVALID_REQUEST;
2771
0
  }
2772
2773
0
  if ((ret =
2774
0
       _gnutls_x509_crt_get_extension(cert, oid, indx, output,
2775
0
              critical)) < 0) {
2776
0
    gnutls_assert();
2777
0
    return ret;
2778
0
  }
2779
2780
0
  if (output->size == 0 || output->data == NULL) {
2781
0
    gnutls_assert();
2782
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2783
0
  }
2784
2785
0
  return 0;
2786
0
}
2787
2788
/**
2789
 * gnutls_x509_crt_get_extension_oid:
2790
 * @cert: should contain a #gnutls_x509_crt_t type
2791
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2792
 * @oid: a pointer to a structure to hold the OID (may be null)
2793
 * @oid_size: initially holds the size of @oid
2794
 *
2795
 * This function will return the requested extension OID in the certificate.
2796
 * The extension OID will be stored as a string in the provided buffer.
2797
 *
2798
 * The @oid returned will be null terminated, although @oid_size will not
2799
 * account for the trailing null.
2800
 *
2801
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2802
 *   otherwise a negative error code is returned.  If you have reached the
2803
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2804
 *   will be returned.
2805
 **/
2806
int
2807
gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert, unsigned indx,
2808
          void *oid, size_t *oid_size)
2809
0
{
2810
0
  int result;
2811
2812
0
  if (cert == NULL) {
2813
0
    gnutls_assert();
2814
0
    return GNUTLS_E_INVALID_REQUEST;
2815
0
  }
2816
2817
0
  result = _gnutls_x509_crt_get_extension_oid(cert, indx, oid, oid_size);
2818
0
  if (result < 0) {
2819
0
    return result;
2820
0
  }
2821
2822
0
  return 0;
2823
2824
0
}
2825
2826
/**
2827
 * gnutls_x509_crt_get_extension_info:
2828
 * @cert: should contain a #gnutls_x509_crt_t type
2829
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2830
 * @oid: a pointer to a structure to hold the OID
2831
 * @oid_size: initially holds the maximum size of @oid, on return
2832
 *   holds actual size of @oid.
2833
 * @critical: output variable with critical flag, may be NULL.
2834
 *
2835
 * This function will return the requested extension OID in the
2836
 * certificate, and the critical flag for it.  The extension OID will
2837
 * be stored as a string in the provided buffer.  Use
2838
 * gnutls_x509_crt_get_extension() to extract the data.
2839
 *
2840
 * If the buffer provided is not long enough to hold the output, then
2841
 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2842
 * returned. The @oid returned will be null terminated, although
2843
 * @oid_size will not account for the trailing null (the latter is not
2844
 * true for GnuTLS prior to 3.6.0).
2845
 *
2846
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2847
 *   otherwise a negative error code is returned.  If you have reached the
2848
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2849
 *   will be returned.
2850
 **/
2851
int
2852
gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert, unsigned indx,
2853
           void *oid, size_t *oid_size,
2854
           unsigned int *critical)
2855
0
{
2856
0
  int result;
2857
0
  char str_critical[10];
2858
0
  char name[MAX_NAME_SIZE];
2859
0
  int len;
2860
2861
0
  if (!cert) {
2862
0
    gnutls_assert();
2863
0
    return GNUTLS_E_INVALID_REQUEST;
2864
0
  }
2865
2866
0
  snprintf(name, sizeof(name),
2867
0
     "tbsCertificate.extensions.?%u.extnID", indx + 1);
2868
2869
0
  len = *oid_size;
2870
0
  result = asn1_read_value(cert->cert, name, oid, &len);
2871
0
  *oid_size = len;
2872
2873
0
  if (result == ASN1_ELEMENT_NOT_FOUND)
2874
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2875
0
  else if (result != ASN1_SUCCESS) {
2876
0
    gnutls_assert();
2877
0
    return _gnutls_asn2err(result);
2878
0
  }
2879
2880
  /* remove any trailing null */
2881
0
  if (oid && len > 0 && ((uint8_t *) oid)[len - 1] == 0)
2882
0
    (*oid_size)--;
2883
2884
0
  if (critical) {
2885
0
    snprintf(name, sizeof(name),
2886
0
       "tbsCertificate.extensions.?%u.critical", indx + 1);
2887
0
    len = sizeof(str_critical);
2888
0
    result = asn1_read_value(cert->cert, name, str_critical, &len);
2889
0
    if (result != ASN1_SUCCESS) {
2890
0
      gnutls_assert();
2891
0
      return _gnutls_asn2err(result);
2892
0
    }
2893
2894
0
    if (str_critical[0] == 'T')
2895
0
      *critical = 1;
2896
0
    else
2897
0
      *critical = 0;
2898
0
  }
2899
2900
0
  return 0;
2901
2902
0
}
2903
2904
/**
2905
 * gnutls_x509_crt_get_extension_data:
2906
 * @cert: should contain a #gnutls_x509_crt_t type
2907
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2908
 * @data: a pointer to a structure to hold the data (may be null)
2909
 * @sizeof_data: initially holds the size of @data
2910
 *
2911
 * This function will return the requested extension data in the
2912
 * certificate.  The extension data will be stored in the
2913
 * provided buffer.
2914
 *
2915
 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2916
 * critical flag.  Use gnutls_x509_crt_get_extension_by_oid() instead,
2917
 * if you want to get data indexed by the extension OID rather than
2918
 * sequence.
2919
 *
2920
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2921
 *   otherwise a negative error code is returned.  If you have reached the
2922
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2923
 *   will be returned.
2924
 **/
2925
int
2926
gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert, unsigned indx,
2927
           void *data, size_t *sizeof_data)
2928
0
{
2929
0
  int result, len;
2930
0
  char name[MAX_NAME_SIZE];
2931
2932
0
  if (!cert) {
2933
0
    gnutls_assert();
2934
0
    return GNUTLS_E_INVALID_REQUEST;
2935
0
  }
2936
2937
0
  snprintf(name, sizeof(name),
2938
0
     "tbsCertificate.extensions.?%u.extnValue", indx + 1);
2939
2940
0
  len = *sizeof_data;
2941
0
  result = asn1_read_value(cert->cert, name, data, &len);
2942
0
  *sizeof_data = len;
2943
2944
0
  if (result == ASN1_ELEMENT_NOT_FOUND) {
2945
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2946
0
  } else if (result == ASN1_MEM_ERROR && data == NULL) {
2947
    /* normally we should return GNUTLS_E_SHORT_MEMORY_BUFFER,
2948
     * but we haven't done that for long time, so use
2949
     * backwards compatible behavior */
2950
0
    return 0;
2951
0
  } else if (result != ASN1_SUCCESS) {
2952
0
    gnutls_assert();
2953
0
    return _gnutls_asn2err(result);
2954
0
  }
2955
2956
0
  return 0;
2957
0
}
2958
2959
/**
2960
 * gnutls_x509_crt_get_raw_issuer_dn:
2961
 * @cert: should contain a #gnutls_x509_crt_t type
2962
 * @dn: will hold the starting point of the DN
2963
 *
2964
 * This function will return a pointer to the DER encoded DN structure
2965
 * and the length. This points to allocated data that must be free'd using gnutls_free().
2966
 *
2967
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2968
 *   negative error value.or a negative error code on error.
2969
 *
2970
 **/
2971
int
2972
gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
2973
0
{
2974
0
  if (cert->raw_issuer_dn.size > 0 && cert->modified == 0) {
2975
0
    return _gnutls_set_datum(dn, cert->raw_issuer_dn.data,
2976
0
           cert->raw_issuer_dn.size);
2977
0
  } else {
2978
0
    return _gnutls_x509_get_raw_field(cert->cert,
2979
0
              "tbsCertificate.issuer.rdnSequence",
2980
0
              dn);
2981
0
  }
2982
0
}
2983
2984
/**
2985
 * gnutls_x509_crt_get_raw_dn:
2986
 * @cert: should contain a #gnutls_x509_crt_t type
2987
 * @dn: will hold the starting point of the DN
2988
 *
2989
 * This function will return a pointer to the DER encoded DN structure and
2990
 * the length. This points to allocated data that must be free'd using gnutls_free().
2991
 *
2992
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2993
 *   negative error value. or a negative error code on error.
2994
 *
2995
 **/
2996
int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
2997
0
{
2998
0
  if (cert->raw_dn.size > 0 && cert->modified == 0) {
2999
0
    return _gnutls_set_datum(dn, cert->raw_dn.data,
3000
0
           cert->raw_dn.size);
3001
0
  } else {
3002
0
    return _gnutls_x509_get_raw_field(cert->cert,
3003
0
              "tbsCertificate.subject.rdnSequence",
3004
0
              dn);
3005
0
  }
3006
0
}
3007
3008
static int
3009
get_dn(gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn,
3010
       unsigned subject)
3011
0
{
3012
0
  gnutls_x509_dn_st *store;
3013
3014
0
  if (subject)
3015
0
    store = &cert->dn;
3016
0
  else
3017
0
    store = &cert->idn;
3018
3019
0
  store->asn = asn1_find_node(cert->cert, whom);
3020
0
  if (!store->asn)
3021
0
    return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
3022
3023
0
  *dn = store;
3024
3025
0
  return 0;
3026
0
}
3027
3028
/**
3029
 * gnutls_x509_crt_get_subject:
3030
 * @cert: should contain a #gnutls_x509_crt_t type
3031
 * @dn: output variable with pointer to uint8_t DN.
3032
 *
3033
 * Return the Certificate's Subject DN as a %gnutls_x509_dn_t data type,
3034
 * that can be decoded using gnutls_x509_dn_get_rdn_ava().
3035
 *
3036
 * Note that @dn should be treated as constant. Because it points
3037
 * into the @cert object, you should not use @dn after @cert is
3038
 * deallocated.
3039
 *
3040
 * Returns: Returns 0 on success, or an error code.
3041
 **/
3042
int gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
3043
0
{
3044
0
  return get_dn(cert, "tbsCertificate.subject.rdnSequence", dn, 1);
3045
0
}
3046
3047
/**
3048
 * gnutls_x509_crt_get_issuer:
3049
 * @cert: should contain a #gnutls_x509_crt_t type
3050
 * @dn: output variable with pointer to uint8_t DN
3051
 *
3052
 * Return the Certificate's Issuer DN as a %gnutls_x509_dn_t data type,
3053
 * that can be decoded using gnutls_x509_dn_get_rdn_ava().
3054
 *
3055
 * Note that @dn should be treated as constant. Because it points
3056
 * into the @cert object, you should not use @dn after @cert is
3057
 * deallocated.
3058
 *
3059
 * Returns: Returns 0 on success, or an error code.
3060
 **/
3061
int gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
3062
0
{
3063
0
  return get_dn(cert, "tbsCertificate.issuer.rdnSequence", dn, 0);
3064
0
}
3065
3066
/**
3067
 * gnutls_x509_crt_get_fingerprint:
3068
 * @cert: should contain a #gnutls_x509_crt_t type
3069
 * @algo: is a digest algorithm
3070
 * @buf: a pointer to a structure to hold the fingerprint (may be null)
3071
 * @buf_size: initially holds the size of @buf
3072
 *
3073
 * This function will calculate and copy the certificate's fingerprint
3074
 * in the provided buffer. The fingerprint is a hash of the DER-encoded
3075
 * data of the certificate.
3076
 *
3077
 * If the buffer is null then only the size will be filled.
3078
 *
3079
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3080
 *   not long enough, and in that case the *buf_size will be updated
3081
 *   with the required size.  On success 0 is returned.
3082
 **/
3083
int
3084
gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,
3085
        gnutls_digest_algorithm_t algo,
3086
        void *buf, size_t *buf_size)
3087
0
{
3088
0
  uint8_t *cert_buf;
3089
0
  int cert_buf_size;
3090
0
  int result;
3091
0
  gnutls_datum_t tmp;
3092
3093
0
  if (buf_size == 0 || cert == NULL) {
3094
0
    return GNUTLS_E_INVALID_REQUEST;
3095
0
  }
3096
3097
0
  cert_buf_size = 0;
3098
0
  result = asn1_der_coding(cert->cert, "", NULL, &cert_buf_size, NULL);
3099
0
  if (result != ASN1_MEM_ERROR) {
3100
0
    gnutls_assert();
3101
0
    return _gnutls_asn2err(result);
3102
0
  }
3103
3104
0
  cert_buf = gnutls_malloc(cert_buf_size);
3105
0
  if (cert_buf == NULL) {
3106
0
    gnutls_assert();
3107
0
    return GNUTLS_E_MEMORY_ERROR;
3108
0
  }
3109
3110
0
  result =
3111
0
      asn1_der_coding(cert->cert, "", cert_buf, &cert_buf_size, NULL);
3112
3113
0
  if (result != ASN1_SUCCESS) {
3114
0
    gnutls_assert();
3115
0
    gnutls_free(cert_buf);
3116
0
    return _gnutls_asn2err(result);
3117
0
  }
3118
3119
0
  tmp.data = cert_buf;
3120
0
  tmp.size = cert_buf_size;
3121
3122
0
  result = gnutls_fingerprint(algo, &tmp, buf, buf_size);
3123
0
  gnutls_free(cert_buf);
3124
3125
0
  return result;
3126
0
}
3127
3128
/**
3129
 * gnutls_x509_crt_export:
3130
 * @cert: Holds the certificate
3131
 * @format: the format of output params. One of PEM or DER.
3132
 * @output_data: will contain a certificate PEM or DER encoded
3133
 * @output_data_size: holds the size of output_data (and will be
3134
 *   replaced by the actual size of parameters)
3135
 *
3136
 * This function will export the certificate to DER or PEM format.
3137
 *
3138
 * If the buffer provided is not long enough to hold the output, then
3139
 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
3140
 * be returned.
3141
 *
3142
 * If the structure is PEM encoded, it will have a header
3143
 * of "BEGIN CERTIFICATE".
3144
 *
3145
 * Returns: In case of failure a negative error code will be
3146
 *   returned, and 0 on success.
3147
 **/
3148
int
3149
gnutls_x509_crt_export(gnutls_x509_crt_t cert,
3150
           gnutls_x509_crt_fmt_t format, void *output_data,
3151
           size_t *output_data_size)
3152
0
{
3153
0
  gnutls_datum_t out;
3154
0
  int ret;
3155
3156
0
  ret = gnutls_x509_crt_export2(cert, format, &out);
3157
0
  if (ret < 0)
3158
0
    return gnutls_assert_val(ret);
3159
3160
0
  if (format == GNUTLS_X509_FMT_PEM)
3161
0
    ret =
3162
0
        _gnutls_copy_string(&out, (uint8_t *) output_data,
3163
0
          output_data_size);
3164
0
  else
3165
0
    ret =
3166
0
        _gnutls_copy_data(&out, (uint8_t *) output_data,
3167
0
              output_data_size);
3168
0
  if (ret < 0) {
3169
0
    gnutls_assert();
3170
0
    goto cleanup;
3171
0
  }
3172
3173
0
  ret = 0;
3174
0
 cleanup:
3175
0
  gnutls_free(out.data);
3176
0
  return ret;
3177
0
}
3178
3179
/**
3180
 * gnutls_x509_crt_export2:
3181
 * @cert: Holds the certificate
3182
 * @format: the format of output params. One of PEM or DER.
3183
 * @out: will contain a certificate PEM or DER encoded
3184
 *
3185
 * This function will export the certificate to DER or PEM format.
3186
 * The output buffer is allocated using gnutls_malloc().
3187
 *
3188
 * If the structure is PEM encoded, it will have a header
3189
 * of "BEGIN CERTIFICATE".
3190
 *
3191
 * Returns: In case of failure a negative error code will be
3192
 *   returned, and 0 on success.
3193
 *
3194
 * Since: 3.1.3
3195
 **/
3196
int
3197
gnutls_x509_crt_export2(gnutls_x509_crt_t cert,
3198
      gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
3199
0
{
3200
0
  if (cert == NULL) {
3201
0
    gnutls_assert();
3202
0
    return GNUTLS_E_INVALID_REQUEST;
3203
0
  }
3204
3205
0
  if (!cert->modified && cert->der.size) {
3206
0
    if (format == GNUTLS_X509_FMT_DER)
3207
0
      return _gnutls_set_datum(out, cert->der.data,
3208
0
             cert->der.size);
3209
0
    else {
3210
0
      int ret = _gnutls_fbase64_encode(PEM_X509_CERT2,
3211
0
               cert->der.data,
3212
0
               cert->der.size,
3213
0
               out);
3214
0
      if (ret < 0)
3215
0
        return ret;
3216
0
      return 0;
3217
0
    }
3218
0
  }
3219
3220
0
  return _gnutls_x509_export_int2(cert->cert, format, PEM_X509_CERT2,
3221
0
          out);
3222
0
}
3223
3224
int
3225
_gnutls_get_key_id(gnutls_pk_params_st * params,
3226
       unsigned char *output_data, size_t *output_data_size,
3227
       unsigned flags)
3228
0
{
3229
0
  int ret = 0;
3230
0
  gnutls_datum_t der = { NULL, 0 };
3231
0
  gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
3232
0
  unsigned int digest_len;
3233
3234
0
  if ((flags & GNUTLS_KEYID_USE_SHA512)
3235
0
      || (flags & GNUTLS_KEYID_USE_BEST_KNOWN))
3236
0
    hash = GNUTLS_DIG_SHA512;
3237
0
  else if (flags & GNUTLS_KEYID_USE_SHA256)
3238
0
    hash = GNUTLS_DIG_SHA256;
3239
3240
0
  digest_len = _gnutls_hash_get_algo_len(hash_to_entry(hash));
3241
3242
0
  if (output_data == NULL || *output_data_size < digest_len) {
3243
0
    gnutls_assert();
3244
0
    *output_data_size = digest_len;
3245
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
3246
0
  }
3247
3248
0
  ret = _gnutls_x509_encode_PKI_params(&der, params);
3249
0
  if (ret < 0)
3250
0
    return gnutls_assert_val(ret);
3251
3252
0
  ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
3253
0
  if (ret < 0) {
3254
0
    gnutls_assert();
3255
0
    goto cleanup;
3256
0
  }
3257
0
  *output_data_size = digest_len;
3258
3259
0
  ret = 0;
3260
3261
0
 cleanup:
3262
3263
0
  _gnutls_free_datum(&der);
3264
0
  return ret;
3265
0
}
3266
3267
/**
3268
 * gnutls_x509_crt_get_key_id:
3269
 * @crt: Holds the certificate
3270
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
3271
 * @output_data: will contain the key ID
3272
 * @output_data_size: holds the size of output_data (and will be
3273
 *   replaced by the actual size of parameters)
3274
 *
3275
 * This function will return a unique ID that depends on the public
3276
 * key parameters. This ID can be used in checking whether a
3277
 * certificate corresponds to the given private key.
3278
 *
3279
 * If the buffer provided is not long enough to hold the output, then
3280
 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
3281
 * be returned.  The output will normally be a SHA-1 hash output,
3282
 * which is 20 bytes.
3283
 *
3284
 * Returns: In case of failure a negative error code will be
3285
 *   returned, and 0 on success.
3286
 **/
3287
int
3288
gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt, unsigned int flags,
3289
         unsigned char *output_data, size_t *output_data_size)
3290
0
{
3291
0
  int ret = 0;
3292
0
  gnutls_pk_params_st params;
3293
3294
0
  if (crt == NULL) {
3295
0
    gnutls_assert();
3296
0
    return GNUTLS_E_INVALID_REQUEST;
3297
0
  }
3298
3299
  /* initializes params */
3300
0
  ret = _gnutls_x509_crt_get_mpis(crt, &params);
3301
0
  if (ret < 0) {
3302
0
    gnutls_assert();
3303
0
    return ret;
3304
0
  }
3305
3306
0
  ret = _gnutls_get_key_id(&params, output_data, output_data_size, flags);
3307
3308
0
  gnutls_pk_params_release(&params);
3309
3310
0
  return ret;
3311
0
}
3312
3313
static int crl_issuer_matches(gnutls_x509_crl_t crl, gnutls_x509_crt_t cert)
3314
0
{
3315
0
  if (_gnutls_x509_compare_raw_dn
3316
0
      (&crl->raw_issuer_dn, &cert->raw_issuer_dn) != 0)
3317
0
    return 1;
3318
0
  else
3319
0
    return 0;
3320
0
}
3321
3322
/* This is exactly as gnutls_x509_crt_check_revocation() except that
3323
 * it calls func.
3324
 */
3325
int
3326
_gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3327
          const gnutls_x509_crl_t * crl_list,
3328
          int crl_list_length,
3329
          gnutls_verify_output_function func)
3330
0
{
3331
0
  uint8_t serial[128];
3332
0
  uint8_t cert_serial[128];
3333
0
  size_t serial_size, cert_serial_size;
3334
0
  int ret, j;
3335
0
  gnutls_x509_crl_iter_t iter = NULL;
3336
3337
0
  if (cert == NULL) {
3338
0
    gnutls_assert();
3339
0
    return GNUTLS_E_INVALID_REQUEST;
3340
0
  }
3341
3342
0
  for (j = 0; j < crl_list_length; j++) { /* do for all the crls */
3343
3344
    /* Step 1. check if issuer's DN match
3345
     */
3346
0
    ret = crl_issuer_matches(crl_list[j], cert);
3347
0
    if (ret == 0) {
3348
      /* issuers do not match so don't even
3349
       * bother checking.
3350
       */
3351
0
      gnutls_assert();
3352
0
      continue;
3353
0
    }
3354
3355
    /* Step 2. Read the certificate's serial number
3356
     */
3357
0
    cert_serial_size = sizeof(cert_serial);
3358
0
    ret =
3359
0
        gnutls_x509_crt_get_serial(cert, cert_serial,
3360
0
                 &cert_serial_size);
3361
0
    if (ret < 0) {
3362
0
      gnutls_assert();
3363
0
      return ret;
3364
0
    }
3365
3366
    /* Step 3. cycle through the CRL serials and compare with
3367
     *   certificate serial we have.
3368
     */
3369
3370
0
    iter = NULL;
3371
0
    do {
3372
0
      serial_size = sizeof(serial);
3373
0
      ret =
3374
0
          gnutls_x509_crl_iter_crt_serial(crl_list[j],
3375
0
                  &iter,
3376
0
                  serial,
3377
0
                  &serial_size, NULL);
3378
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
3379
0
        break;
3380
0
      } else if (ret < 0) {
3381
0
        gnutls_assert();
3382
0
        goto fail;
3383
0
      }
3384
3385
0
      if (serial_size == cert_serial_size) {
3386
0
        if (memcmp
3387
0
            (serial, cert_serial, serial_size) == 0) {
3388
          /* serials match */
3389
0
          if (func)
3390
0
            func(cert, NULL,
3391
0
                 crl_list[j],
3392
0
                 GNUTLS_CERT_REVOKED |
3393
0
                 GNUTLS_CERT_INVALID);
3394
0
          ret = 1;  /* revoked! */
3395
0
          goto fail;
3396
0
        }
3397
0
      }
3398
0
    } while (1);
3399
3400
0
    gnutls_x509_crl_iter_deinit(iter);
3401
0
    iter = NULL;
3402
3403
0
    if (func)
3404
0
      func(cert, NULL, crl_list[j], 0);
3405
3406
0
  }
3407
0
  return 0;   /* not revoked. */
3408
3409
0
 fail:
3410
0
  gnutls_x509_crl_iter_deinit(iter);
3411
0
  return ret;
3412
0
}
3413
3414
/**
3415
 * gnutls_x509_crt_check_revocation:
3416
 * @cert: should contain a #gnutls_x509_crt_t type
3417
 * @crl_list: should contain a list of gnutls_x509_crl_t types
3418
 * @crl_list_length: the length of the crl_list
3419
 *
3420
 * This function will check if the given certificate is
3421
 * revoked.  It is assumed that the CRLs have been verified before.
3422
 *
3423
 * Returns: 0 if the certificate is NOT revoked, and 1 if it is.  A
3424
 * negative error code is returned on error.
3425
 **/
3426
int
3427
gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3428
         const gnutls_x509_crl_t * crl_list,
3429
         unsigned crl_list_length)
3430
0
{
3431
0
  return _gnutls_x509_crt_check_revocation(cert, crl_list,
3432
0
             crl_list_length, NULL);
3433
0
}
3434
3435
/**
3436
 * gnutls_x509_crt_check_key_purpose:
3437
 * @cert: should contain a #gnutls_x509_crt_t type
3438
 * @purpose: a key purpose OID (e.g., %GNUTLS_KP_CODE_SIGNING)
3439
 * @flags: zero or %GNUTLS_KP_FLAG_DISALLOW_ANY
3440
 *
3441
 * This function will check whether the given certificate matches
3442
 * the provided key purpose. If @flags contains %GNUTLS_KP_FLAG_ALLOW_ANY then
3443
 * it a certificate marked for any purpose will not match.
3444
 *
3445
 * Returns: zero if the key purpose doesn't match, and non-zero otherwise.
3446
 *
3447
 * Since: 3.5.6
3448
 **/
3449
unsigned
3450
gnutls_x509_crt_check_key_purpose(gnutls_x509_crt_t cert,
3451
          const char *purpose, unsigned flags)
3452
0
{
3453
0
  return _gnutls_check_key_purpose(cert, purpose,
3454
0
           (flags & GNUTLS_KP_FLAG_DISALLOW_ANY) ?
3455
0
           1 : 0);
3456
0
}
3457
3458
/**
3459
 * gnutls_x509_crt_get_preferred_hash_algorithm:
3460
 * @crt: Holds the certificate
3461
 * @hash: The result of the call with the hash algorithm used for signature
3462
 * @mand: If non-zero it means that the algorithm MUST use this hash. May be %NULL.
3463
 *
3464
 * This function will read the certificate and return the appropriate digest
3465
 * algorithm to use for signing with this certificate. Some certificates (i.e.
3466
 * DSA might not be able to sign without the preferred algorithm).
3467
 *
3468
 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
3469
 *
3470
 * Returns: the 0 if the hash algorithm is found. A negative error code is
3471
 * returned on error.
3472
 *
3473
 * Since: 2.12.0
3474
 **/
3475
int
3476
gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,
3477
               gnutls_digest_algorithm_t *
3478
               hash, unsigned int *mand)
3479
0
{
3480
0
  int ret;
3481
0
  gnutls_pubkey_t pubkey;
3482
3483
0
  if (crt == NULL) {
3484
0
    gnutls_assert();
3485
0
    return GNUTLS_E_INVALID_REQUEST;
3486
0
  }
3487
3488
0
  ret = gnutls_pubkey_init(&pubkey);
3489
0
  if (ret < 0)
3490
0
    return gnutls_assert_val(ret);
3491
3492
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3493
0
  if (ret < 0) {
3494
0
    gnutls_assert();
3495
0
    goto cleanup;
3496
0
  }
3497
3498
0
  ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, hash, mand);
3499
0
  if (ret < 0) {
3500
0
    gnutls_assert();
3501
0
    goto cleanup;
3502
0
  }
3503
3504
0
 cleanup:
3505
0
  gnutls_pubkey_deinit(pubkey);
3506
0
  return ret;
3507
0
}
3508
3509
/**
3510
 * gnutls_x509_crt_get_crl_dist_points:
3511
 * @cert: should contain a #gnutls_x509_crt_t type
3512
 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3513
 * @san: is the place where the distribution point will be copied to
3514
 * @san_size: holds the size of ret.
3515
 * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3516
 * @critical: will be non-zero if the extension is marked as critical (may be null)
3517
 *
3518
 * This function retrieves the CRL distribution points (2.5.29.31),
3519
 * contained in the given certificate in the X509v3 Certificate
3520
 * Extensions.
3521
 *
3522
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3523
 *   @ret_size is not enough to hold the distribution point, or the
3524
 *   type of the distribution point if everything was ok. The type is
3525
 *   one of the enumerated %gnutls_x509_subject_alt_name_t.  If the
3526
 *   certificate does not have an Alternative name with the specified
3527
 *   sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3528
 *   returned.
3529
 **/
3530
int
3531
gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
3532
            unsigned int seq, void *san,
3533
            size_t *san_size,
3534
            unsigned int *reason_flags,
3535
            unsigned int *critical)
3536
0
{
3537
0
  int ret;
3538
0
  gnutls_datum_t dist_points = { NULL, 0 };
3539
0
  unsigned type;
3540
0
  gnutls_x509_crl_dist_points_t cdp = NULL;
3541
0
  gnutls_datum_t t_san;
3542
3543
0
  if (cert == NULL) {
3544
0
    gnutls_assert();
3545
0
    return GNUTLS_E_INVALID_REQUEST;
3546
0
  }
3547
3548
0
  ret = gnutls_x509_crl_dist_points_init(&cdp);
3549
0
  if (ret < 0)
3550
0
    return gnutls_assert_val(ret);
3551
3552
0
  if (reason_flags)
3553
0
    *reason_flags = 0;
3554
3555
0
  ret =
3556
0
      _gnutls_x509_crt_get_extension(cert, "2.5.29.31", 0,
3557
0
             &dist_points, critical);
3558
0
  if (ret < 0) {
3559
0
    gnutls_assert();
3560
0
    goto cleanup;
3561
0
  }
3562
3563
0
  if (dist_points.size == 0 || dist_points.data == NULL) {
3564
0
    gnutls_assert();
3565
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3566
0
    goto cleanup;
3567
0
  }
3568
3569
0
  ret = gnutls_x509_ext_import_crl_dist_points(&dist_points, cdp, 0);
3570
0
  if (ret < 0) {
3571
0
    gnutls_assert();
3572
0
    goto cleanup;
3573
0
  }
3574
3575
0
  ret =
3576
0
      gnutls_x509_crl_dist_points_get(cdp, seq, &type, &t_san,
3577
0
              reason_flags);
3578
0
  if (ret < 0) {
3579
0
    gnutls_assert();
3580
0
    goto cleanup;
3581
0
  }
3582
3583
0
  ret = _gnutls_copy_string(&t_san, san, san_size);
3584
0
  if (ret < 0) {
3585
0
    gnutls_assert();
3586
0
    goto cleanup;
3587
0
  }
3588
3589
0
  ret = type;
3590
3591
0
 cleanup:
3592
0
  _gnutls_free_datum(&dist_points);
3593
0
  if (cdp != NULL)
3594
0
    gnutls_x509_crl_dist_points_deinit(cdp);
3595
3596
0
  return ret;
3597
0
}
3598
3599
/**
3600
 * gnutls_x509_crt_get_key_purpose_oid:
3601
 * @cert: should contain a #gnutls_x509_crt_t type
3602
 * @indx: This specifies which OID to return. Use (0) to get the first one.
3603
 * @oid: a pointer to a buffer to hold the OID (may be null)
3604
 * @oid_size: initially holds the size of @oid
3605
 * @critical: output flag to indicate criticality of extension
3606
 *
3607
 * This function will extract the key purpose OIDs of the Certificate
3608
 * specified by the given index.  These are stored in the Extended Key
3609
 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3610
 * human readable names.
3611
 *
3612
 * If @oid is null then only the size will be filled. The @oid
3613
 * returned will be null terminated, although @oid_size will not
3614
 * account for the trailing null.
3615
 *
3616
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3617
 *   not long enough, and in that case the *oid_size will be updated
3618
 *   with the required size.  On success 0 is returned.
3619
 **/
3620
int
3621
gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert,
3622
            unsigned indx, void *oid, size_t *oid_size,
3623
            unsigned int *critical)
3624
0
{
3625
0
  int ret;
3626
0
  gnutls_datum_t ext;
3627
0
  gnutls_x509_key_purposes_t p = NULL;
3628
0
  gnutls_datum_t out;
3629
3630
0
  if (cert == NULL) {
3631
0
    gnutls_assert();
3632
0
    return GNUTLS_E_INVALID_REQUEST;
3633
0
  }
3634
3635
0
  if (oid)
3636
0
    memset(oid, 0, *oid_size);
3637
0
  else
3638
0
    *oid_size = 0;
3639
3640
0
  if ((ret =
3641
0
       _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &ext,
3642
0
              critical)) < 0) {
3643
0
    return ret;
3644
0
  }
3645
3646
0
  if (ext.size == 0 || ext.data == NULL) {
3647
0
    gnutls_assert();
3648
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3649
0
  }
3650
3651
0
  ret = gnutls_x509_key_purpose_init(&p);
3652
0
  if (ret < 0) {
3653
0
    gnutls_assert();
3654
0
    goto cleanup;
3655
0
  }
3656
3657
0
  ret = gnutls_x509_ext_import_key_purposes(&ext, p, 0);
3658
0
  if (ret < 0) {
3659
0
    gnutls_assert();
3660
0
    goto cleanup;
3661
0
  }
3662
3663
0
  ret = gnutls_x509_key_purpose_get(p, indx, &out);
3664
0
  if (ret < 0) {
3665
0
    gnutls_assert();
3666
0
    goto cleanup;
3667
0
  }
3668
3669
0
  ret = _gnutls_copy_string(&out, oid, oid_size);
3670
0
  if (ret < 0) {
3671
0
    gnutls_assert();
3672
0
    goto cleanup;
3673
0
  }
3674
3675
0
  ret = 0;
3676
3677
0
 cleanup:
3678
0
  gnutls_free(ext.data);
3679
0
  if (p != NULL)
3680
0
    gnutls_x509_key_purpose_deinit(p);
3681
0
  return ret;
3682
0
}
3683
3684
/**
3685
 * gnutls_x509_crt_get_pk_rsa_raw:
3686
 * @crt: Holds the certificate
3687
 * @m: will hold the modulus
3688
 * @e: will hold the public exponent
3689
 *
3690
 * This function will export the RSA public key's parameters found in
3691
 * the given structure.  The new parameters will be allocated using
3692
 * gnutls_malloc() and will be stored in the appropriate datum.
3693
 *
3694
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3695
 **/
3696
int
3697
gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt,
3698
             gnutls_datum_t * m, gnutls_datum_t * e)
3699
0
{
3700
0
  int ret;
3701
0
  gnutls_pubkey_t pubkey;
3702
3703
0
  if (crt == NULL) {
3704
0
    gnutls_assert();
3705
0
    return GNUTLS_E_INVALID_REQUEST;
3706
0
  }
3707
3708
0
  ret = gnutls_pubkey_init(&pubkey);
3709
0
  if (ret < 0)
3710
0
    return gnutls_assert_val(ret);
3711
3712
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3713
0
  if (ret < 0) {
3714
0
    gnutls_assert();
3715
0
    goto cleanup;
3716
0
  }
3717
3718
0
  ret = gnutls_pubkey_export_rsa_raw(pubkey, m, e);
3719
0
  if (ret < 0) {
3720
0
    gnutls_assert();
3721
0
    goto cleanup;
3722
0
  }
3723
3724
0
 cleanup:
3725
0
  gnutls_pubkey_deinit(pubkey);
3726
0
  return ret;
3727
0
}
3728
3729
/**
3730
 * gnutls_x509_crt_get_pk_ecc_raw:
3731
 * @crt: Holds the certificate
3732
 * @curve: will hold the curve
3733
 * @x: will hold the x-coordinate
3734
 * @y: will hold the y-coordinate
3735
 *
3736
 * This function will export the ECC public key's parameters found in
3737
 * the given certificate.  The new parameters will be allocated using
3738
 * gnutls_malloc() and will be stored in the appropriate datum.
3739
 *
3740
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
3741
 * will be in the native format for the curve.
3742
 *
3743
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3744
 *
3745
 * Since: 3.4.1
3746
 **/
3747
int
3748
gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,
3749
             gnutls_ecc_curve_t * curve,
3750
             gnutls_datum_t * x, gnutls_datum_t * y)
3751
0
{
3752
0
  int ret;
3753
0
  gnutls_pubkey_t pubkey;
3754
3755
0
  if (crt == NULL) {
3756
0
    gnutls_assert();
3757
0
    return GNUTLS_E_INVALID_REQUEST;
3758
0
  }
3759
3760
0
  ret = gnutls_pubkey_init(&pubkey);
3761
0
  if (ret < 0)
3762
0
    return gnutls_assert_val(ret);
3763
3764
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3765
0
  if (ret < 0) {
3766
0
    gnutls_assert();
3767
0
    goto cleanup;
3768
0
  }
3769
3770
0
  ret = gnutls_pubkey_export_ecc_raw(pubkey, curve, x, y);
3771
0
  if (ret < 0) {
3772
0
    gnutls_assert();
3773
0
    goto cleanup;
3774
0
  }
3775
3776
0
 cleanup:
3777
0
  gnutls_pubkey_deinit(pubkey);
3778
0
  return ret;
3779
0
}
3780
3781
/**
3782
 * gnutls_x509_crt_get_pk_gost_raw:
3783
 * @crt: Holds the certificate
3784
 * @curve: will hold the curve
3785
 * @digest: will hold the digest
3786
 * @paramset: will hold the GOST parameter set ID
3787
 * @x: will hold the x-coordinate
3788
 * @y: will hold the y-coordinate
3789
 *
3790
 * This function will export the GOST public key's parameters found in
3791
 * the given certificate.  The new parameters will be allocated using
3792
 * gnutls_malloc() and will be stored in the appropriate datum.
3793
 *
3794
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3795
 *
3796
 * Since: 3.6.3
3797
 **/
3798
int
3799
gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,
3800
        gnutls_ecc_curve_t * curve,
3801
        gnutls_digest_algorithm_t * digest,
3802
        gnutls_gost_paramset_t * paramset,
3803
        gnutls_datum_t * x, gnutls_datum_t * y)
3804
0
{
3805
0
  int ret;
3806
0
  gnutls_pubkey_t pubkey;
3807
3808
0
  if (crt == NULL) {
3809
0
    gnutls_assert();
3810
0
    return GNUTLS_E_INVALID_REQUEST;
3811
0
  }
3812
3813
0
  ret = gnutls_pubkey_init(&pubkey);
3814
0
  if (ret < 0)
3815
0
    return gnutls_assert_val(ret);
3816
3817
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3818
0
  if (ret < 0) {
3819
0
    gnutls_assert();
3820
0
    goto cleanup;
3821
0
  }
3822
3823
0
  ret = gnutls_pubkey_export_gost_raw2(pubkey, curve, digest,
3824
0
               paramset, x, y, 0);
3825
0
  if (ret < 0) {
3826
0
    gnutls_assert();
3827
0
    goto cleanup;
3828
0
  }
3829
3830
0
 cleanup:
3831
0
  gnutls_pubkey_deinit(pubkey);
3832
0
  return ret;
3833
0
}
3834
3835
/**
3836
 * gnutls_x509_crt_get_pk_dsa_raw:
3837
 * @crt: Holds the certificate
3838
 * @p: will hold the p
3839
 * @q: will hold the q
3840
 * @g: will hold the g
3841
 * @y: will hold the y
3842
 *
3843
 * This function will export the DSA public key's parameters found in
3844
 * the given certificate.  The new parameters will be allocated using
3845
 * gnutls_malloc() and will be stored in the appropriate datum.
3846
 *
3847
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3848
 **/
3849
int
3850
gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt,
3851
             gnutls_datum_t * p, gnutls_datum_t * q,
3852
             gnutls_datum_t * g, gnutls_datum_t * y)
3853
0
{
3854
0
  int ret;
3855
0
  gnutls_pubkey_t pubkey;
3856
3857
0
  if (crt == NULL) {
3858
0
    gnutls_assert();
3859
0
    return GNUTLS_E_INVALID_REQUEST;
3860
0
  }
3861
3862
0
  ret = gnutls_pubkey_init(&pubkey);
3863
0
  if (ret < 0)
3864
0
    return gnutls_assert_val(ret);
3865
3866
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3867
0
  if (ret < 0) {
3868
0
    gnutls_assert();
3869
0
    goto cleanup;
3870
0
  }
3871
3872
0
  ret = gnutls_pubkey_export_dsa_raw(pubkey, p, q, g, y);
3873
0
  if (ret < 0) {
3874
0
    gnutls_assert();
3875
0
    goto cleanup;
3876
0
  }
3877
3878
0
 cleanup:
3879
0
  gnutls_pubkey_deinit(pubkey);
3880
0
  return ret;
3881
0
}
3882
3883
/**
3884
 * gnutls_x509_crt_list_import2:
3885
 * @certs: Will hold the parsed certificate list.
3886
 * @size: It will contain the size of the list.
3887
 * @data: The PEM encoded certificate.
3888
 * @format: One of DER or PEM.
3889
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3890
 *
3891
 * This function will convert the given PEM encoded certificate list
3892
 * to the native gnutls_x509_crt_t format. The output will be stored
3893
 * in @certs which will be allocated and initialized.
3894
 *
3895
 * If the Certificate is PEM encoded it should have a header of "X509
3896
 * CERTIFICATE", or "CERTIFICATE".
3897
 *
3898
 * To deinitialize @certs, you need to deinitialize each crt structure
3899
 * independently, and use gnutls_free() at @certs.
3900
 *
3901
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3902
 *
3903
 * Since: 3.0
3904
 **/
3905
int
3906
gnutls_x509_crt_list_import2(gnutls_x509_crt_t ** certs,
3907
           unsigned int *size,
3908
           const gnutls_datum_t * data,
3909
           gnutls_x509_crt_fmt_t format, unsigned int flags)
3910
0
{
3911
0
  unsigned int init = 1024;
3912
0
  int ret;
3913
3914
0
  *certs = _gnutls_reallocarray(NULL, init, sizeof(gnutls_x509_crt_t));
3915
0
  if (*certs == NULL) {
3916
0
    gnutls_assert();
3917
0
    return GNUTLS_E_MEMORY_ERROR;
3918
0
  }
3919
3920
0
  ret =
3921
0
      gnutls_x509_crt_list_import(*certs, &init, data, format,
3922
0
          flags |
3923
0
          GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3924
0
  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
3925
0
    *certs = _gnutls_reallocarray_fast(*certs, init,
3926
0
               sizeof(gnutls_x509_crt_t));
3927
0
    if (*certs == NULL) {
3928
0
      gnutls_assert();
3929
0
      return GNUTLS_E_MEMORY_ERROR;
3930
0
    }
3931
3932
0
    ret =
3933
0
        gnutls_x509_crt_list_import(*certs, &init, data,
3934
0
            format, flags);
3935
0
  }
3936
3937
0
  if (ret < 0) {
3938
0
    gnutls_free(*certs);
3939
0
    return ret;
3940
0
  }
3941
3942
0
  *size = init;
3943
0
  return 0;
3944
0
}
3945
3946
/**
3947
 * gnutls_x509_crt_list_import:
3948
 * @certs: Indicates where the parsed list will be copied to. Must not be initialized.
3949
 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3950
 * @data: The PEM encoded certificate.
3951
 * @format: One of DER or PEM.
3952
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3953
 *
3954
 * This function will convert the given PEM encoded certificate list
3955
 * to the native gnutls_x509_crt_t format. The output will be stored
3956
 * in @certs.  They will be automatically initialized.
3957
 *
3958
 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3959
 * import to fail if the certificates in the provided buffer are more
3960
 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3961
 * flag will cause the function to fail if the provided list is not
3962
 * sorted from subject to issuer.
3963
 *
3964
 * If the Certificate is PEM encoded it should have a header of "X509
3965
 * CERTIFICATE", or "CERTIFICATE".
3966
 *
3967
 * Returns: the number of certificates read or a negative error value.
3968
 **/
3969
int
3970
gnutls_x509_crt_list_import(gnutls_x509_crt_t * certs,
3971
          unsigned int *cert_max,
3972
          const gnutls_datum_t * data,
3973
          gnutls_x509_crt_fmt_t format, unsigned int flags)
3974
0
{
3975
0
  int size;
3976
0
  const char *ptr;
3977
0
  gnutls_datum_t tmp;
3978
0
  int ret, nocopy = 0;
3979
0
  unsigned int count = 0, j, copied = 0;
3980
3981
0
  if (format == GNUTLS_X509_FMT_DER) {
3982
0
    if (*cert_max < 1) {
3983
0
      *cert_max = 1;
3984
0
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
3985
0
    }
3986
3987
0
    count = 1;  /* import only the first one */
3988
3989
0
    ret = gnutls_x509_crt_init(&certs[0]);
3990
0
    if (ret < 0) {
3991
0
      gnutls_assert();
3992
0
      goto error;
3993
0
    }
3994
3995
0
    ret = gnutls_x509_crt_import(certs[0], data, format);
3996
0
    if (ret < 0) {
3997
0
      gnutls_assert();
3998
0
      goto error;
3999
0
    }
4000
4001
0
    *cert_max = 1;
4002
0
    return 1;
4003
0
  }
4004
4005
  /* move to the certificate
4006
   */
4007
0
  ptr = memmem(data->data, data->size,
4008
0
         PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
4009
0
  if (ptr == NULL)
4010
0
    ptr = memmem(data->data, data->size,
4011
0
           PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);
4012
4013
0
  if (ptr == NULL)
4014
0
    return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
4015
4016
0
  count = 0;
4017
4018
0
  do {
4019
0
    if (count >= *cert_max) {
4020
0
      if (!
4021
0
          (flags &
4022
0
           GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
4023
0
        break;
4024
0
      else
4025
0
        nocopy = 1;
4026
0
    }
4027
4028
0
    if (!nocopy) {
4029
0
      ret = gnutls_x509_crt_init(&certs[count]);
4030
0
      if (ret < 0) {
4031
0
        gnutls_assert();
4032
0
        goto error;
4033
0
      }
4034
4035
0
      tmp.data = (void *)ptr;
4036
0
      tmp.size = data->size - (ptr - (char *)data->data);
4037
4038
0
      ret =
4039
0
          gnutls_x509_crt_import(certs[count], &tmp,
4040
0
               GNUTLS_X509_FMT_PEM);
4041
0
      if (ret < 0) {
4042
0
        count++;
4043
0
        gnutls_assert();
4044
0
        goto error;
4045
0
      }
4046
4047
0
      copied++;
4048
0
    }
4049
4050
    /* now we move ptr after the pem header
4051
     */
4052
0
    ptr++;
4053
    /* find the next certificate (if any)
4054
     */
4055
0
    size = data->size - (ptr - (char *)data->data);
4056
4057
0
    if (size > 0) {
4058
0
      char *ptr2;
4059
4060
0
      ptr2 =
4061
0
          memmem(ptr, size, PEM_CERT_SEP,
4062
0
           sizeof(PEM_CERT_SEP) - 1);
4063
0
      if (ptr2 == NULL)
4064
0
        ptr2 = memmem(ptr, size, PEM_CERT_SEP2,
4065
0
                sizeof(PEM_CERT_SEP2) - 1);
4066
4067
0
      ptr = ptr2;
4068
0
    } else
4069
0
      ptr = NULL;
4070
4071
0
    count++;
4072
0
  }
4073
0
  while (ptr != NULL);
4074
4075
0
  *cert_max = count;
4076
4077
0
  if (nocopy == 0) {
4078
0
    if (flags & GNUTLS_X509_CRT_LIST_SORT && *cert_max > 1) {
4079
0
      if (*cert_max > DEFAULT_MAX_VERIFY_DEPTH) {
4080
0
        ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
4081
0
        goto error;
4082
0
      }
4083
0
      count = _gnutls_sort_clist(certs, *cert_max);
4084
0
      if (count < *cert_max) {
4085
0
        for (j = count; j < *cert_max; j++) {
4086
0
          gnutls_x509_crt_deinit(certs[j]);
4087
0
        }
4088
0
      }
4089
0
      *cert_max = count;
4090
0
    }
4091
4092
0
    if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) {
4093
0
      ret = _gnutls_check_if_sorted(certs, *cert_max);
4094
0
      if (ret < 0) {
4095
0
        gnutls_assert();
4096
0
        goto error;
4097
0
      }
4098
0
    }
4099
4100
0
    return count;
4101
0
  } else {
4102
0
    count = copied;
4103
0
    ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
4104
0
  }
4105
4106
0
 error:
4107
0
  for (j = 0; j < count; j++)
4108
0
    gnutls_x509_crt_deinit(certs[j]);
4109
0
  return ret;
4110
0
}
4111
4112
/**
4113
 * gnutls_x509_crt_get_subject_unique_id:
4114
 * @crt: Holds the certificate
4115
 * @buf: user allocated memory buffer, will hold the unique id
4116
 * @buf_size: size of user allocated memory buffer (on input), will hold
4117
 * actual size of the unique ID on return.
4118
 *
4119
 * This function will extract the subjectUniqueID value (if present) for
4120
 * the given certificate.
4121
 *
4122
 * If the user allocated memory buffer is not large enough to hold the
4123
 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
4124
 * returned, and buf_size will be set to the actual length.
4125
 *
4126
 * This function had a bug prior to 3.4.8 that prevented the setting
4127
 * of %NULL @buf to discover the @buf_size. To use this function safely
4128
 * with the older versions the @buf must be a valid buffer that can hold
4129
 * at least a single byte if @buf_size is zero.
4130
 *
4131
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
4132
 **/
4133
int
4134
gnutls_x509_crt_get_subject_unique_id(gnutls_x509_crt_t crt, char *buf,
4135
              size_t *buf_size)
4136
0
{
4137
0
  int result;
4138
0
  gnutls_datum_t datum = { NULL, 0 };
4139
4140
0
  result =
4141
0
      _gnutls_x509_read_value(crt->cert,
4142
0
            "tbsCertificate.subjectUniqueID", &datum);
4143
0
  if (result < 0)
4144
0
    return gnutls_assert_val(result);
4145
4146
0
  if (datum.size > *buf_size) { /* then we're not going to fit */
4147
0
    *buf_size = datum.size;
4148
0
    result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4149
0
  } else {
4150
0
    *buf_size = datum.size;
4151
0
    memcpy(buf, datum.data, datum.size);
4152
0
  }
4153
4154
0
  _gnutls_free_datum(&datum);
4155
4156
0
  return result;
4157
0
}
4158
4159
/**
4160
 * gnutls_x509_crt_get_issuer_unique_id:
4161
 * @crt: Holds the certificate
4162
 * @buf: user allocated memory buffer, will hold the unique id
4163
 * @buf_size: size of user allocated memory buffer (on input), will hold
4164
 * actual size of the unique ID on return.
4165
 *
4166
 * This function will extract the issuerUniqueID value (if present) for
4167
 * the given certificate.
4168
 *
4169
 * If the user allocated memory buffer is not large enough to hold the
4170
 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
4171
 * returned, and buf_size will be set to the actual length.
4172
 *
4173
 * This function had a bug prior to 3.4.8 that prevented the setting
4174
 * of %NULL @buf to discover the @buf_size. To use this function safely
4175
 * with the older versions the @buf must be a valid buffer that can hold
4176
 * at least a single byte if @buf_size is zero.
4177
 *
4178
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
4179
 *
4180
 * Since: 2.12.0
4181
 **/
4182
int
4183
gnutls_x509_crt_get_issuer_unique_id(gnutls_x509_crt_t crt, char *buf,
4184
             size_t *buf_size)
4185
0
{
4186
0
  int result;
4187
0
  gnutls_datum_t datum = { NULL, 0 };
4188
4189
0
  result =
4190
0
      _gnutls_x509_read_value(crt->cert,
4191
0
            "tbsCertificate.issuerUniqueID", &datum);
4192
0
  if (result < 0)
4193
0
    return gnutls_assert_val(result);
4194
4195
0
  if (datum.size > *buf_size) { /* then we're not going to fit */
4196
0
    *buf_size = datum.size;
4197
0
    result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4198
0
  } else {
4199
0
    *buf_size = datum.size;
4200
0
    memcpy(buf, datum.data, datum.size);
4201
0
  }
4202
4203
0
  _gnutls_free_datum(&datum);
4204
4205
0
  return result;
4206
0
}
4207
4208
static int
4209
legacy_parse_aia(asn1_node src,
4210
     unsigned int seq, int what, gnutls_datum_t * data)
4211
0
{
4212
0
  int len;
4213
0
  char nptr[MAX_NAME_SIZE];
4214
0
  int result;
4215
0
  gnutls_datum_t d;
4216
0
  const char *oid = NULL;
4217
4218
0
  seq++;      /* 0->1, 1->2 etc */
4219
0
  switch (what) {
4220
0
  case GNUTLS_IA_ACCESSMETHOD_OID:
4221
0
    snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4222
0
    break;
4223
4224
0
  case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
4225
0
    snprintf(nptr, sizeof(nptr), "?%u.accessLocation", seq);
4226
0
    break;
4227
4228
0
  case GNUTLS_IA_CAISSUERS_URI:
4229
0
    oid = GNUTLS_OID_AD_CAISSUERS;
4230
0
    FALLTHROUGH;
4231
4232
0
  case GNUTLS_IA_OCSP_URI:
4233
0
    if (oid == NULL)
4234
0
      oid = GNUTLS_OID_AD_OCSP;
4235
0
    {
4236
0
      char tmpoid[MAX_OID_SIZE];
4237
0
      snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4238
0
      len = sizeof(tmpoid);
4239
0
      result = asn1_read_value(src, nptr, tmpoid, &len);
4240
4241
0
      if (result == ASN1_VALUE_NOT_FOUND
4242
0
          || result == ASN1_ELEMENT_NOT_FOUND)
4243
0
        return
4244
0
            gnutls_assert_val
4245
0
            (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4246
4247
0
      if (result != ASN1_SUCCESS) {
4248
0
        gnutls_assert();
4249
0
        return _gnutls_asn2err(result);
4250
0
      }
4251
0
      if ((unsigned)len != strlen(oid) + 1
4252
0
          || memcmp(tmpoid, oid, len) != 0)
4253
0
        return
4254
0
            gnutls_assert_val
4255
0
            (GNUTLS_E_UNKNOWN_ALGORITHM);
4256
0
    }
4257
0
    FALLTHROUGH;
4258
4259
0
  case GNUTLS_IA_URI:
4260
0
    snprintf(nptr, sizeof(nptr),
4261
0
       "?%u.accessLocation.uniformResourceIdentifier", seq);
4262
0
    break;
4263
4264
0
  default:
4265
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4266
0
  }
4267
4268
0
  len = 0;
4269
0
  result = asn1_read_value(src, nptr, NULL, &len);
4270
0
  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
4271
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4272
4273
0
  if (result != ASN1_MEM_ERROR) {
4274
0
    gnutls_assert();
4275
0
    return _gnutls_asn2err(result);
4276
0
  }
4277
4278
0
  d.size = len;
4279
4280
0
  d.data = gnutls_malloc(d.size);
4281
0
  if (d.data == NULL)
4282
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
4283
4284
0
  result = asn1_read_value(src, nptr, d.data, &len);
4285
0
  if (result != ASN1_SUCCESS) {
4286
0
    gnutls_assert();
4287
0
    gnutls_free(d.data);
4288
0
    return _gnutls_asn2err(result);
4289
0
  }
4290
4291
0
  if (data) {
4292
0
    data->data = d.data;
4293
0
    data->size = d.size;
4294
0
  } else
4295
0
    gnutls_free(d.data);
4296
4297
0
  return 0;
4298
0
}
4299
4300
/**
4301
 * gnutls_x509_crt_get_authority_info_access:
4302
 * @crt: Holds the certificate
4303
 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
4304
 * @what: what data to get, a #gnutls_info_access_what_t type.
4305
 * @data: output data to be freed with gnutls_free().
4306
 * @critical: pointer to output integer that is set to non-zero if the extension is marked as critical (may be %NULL)
4307
 *
4308
 * Note that a simpler API to access the authority info data is provided
4309
 * by gnutls_x509_aia_get() and gnutls_x509_ext_import_aia().
4310
 *
4311
 * This function extracts the Authority Information Access (AIA)
4312
 * extension, see RFC 5280 section 4.2.2.1 for more information.  The
4313
 * AIA extension holds a sequence of AccessDescription (AD) data.
4314
 *
4315
 * The @seq input parameter is used to indicate which member of the
4316
 * sequence the caller is interested in.  The first member is 0, the
4317
 * second member 1 and so on.  When the @seq value is out of bounds,
4318
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
4319
 *
4320
 * The type of data returned in @data is specified via @what which
4321
 * should be #gnutls_info_access_what_t values.
4322
 *
4323
 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
4324
 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
4325
 *
4326
 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
4327
 * hold the accessLocation GeneralName type (e.g.,
4328
 * "uniformResourceIdentifier").
4329
 *
4330
 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
4331
 * data.  Requesting this @what value leads to an error if the
4332
 * accessLocation is not of the "uniformResourceIdentifier" type.
4333
 *
4334
 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
4335
 * Requesting this @what value leads to an error if the accessMethod
4336
 * is not 1.3.6.1.5.5.7.48.1 aka OCSP, or if accessLocation is not of
4337
 * the "uniformResourceIdentifier" type. In that case %GNUTLS_E_UNKNOWN_ALGORITHM
4338
 * will be returned, and @seq should be increased and this function
4339
 * called again.
4340
 *
4341
 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
4342
 * URI.  Requesting this @what value leads to an error if the
4343
 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
4344
 * accessLocation is not of the "uniformResourceIdentifier" type.
4345
 * In that case handle as in %GNUTLS_IA_OCSP_URI.
4346
 *
4347
 * More @what values may be allocated in the future as needed.
4348
 *
4349
 * If @data is NULL, the function does the same without storing the
4350
 * output data, that is, it will set @critical and do error checking
4351
 * as usual.
4352
 *
4353
 * The value of the critical flag is returned in *@critical.  Supply a
4354
 * NULL @critical if you want the function to make sure the extension
4355
 * is non-critical, as required by RFC 5280.
4356
 *
4357
 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
4358
 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
4359
 * incorrectly marked as critical (use a non-NULL @critical to
4360
 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
4361
 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
4362
 * negative error code.
4363
 *
4364
 * Since: 3.0
4365
 **/
4366
int
4367
gnutls_x509_crt_get_authority_info_access(gnutls_x509_crt_t crt,
4368
            unsigned int seq,
4369
            int what,
4370
            gnutls_datum_t * data,
4371
            unsigned int *critical)
4372
0
{
4373
0
  int ret;
4374
0
  gnutls_datum_t aia;
4375
0
  asn1_node c2 = NULL;
4376
4377
0
  if (crt == NULL) {
4378
0
    gnutls_assert();
4379
0
    return GNUTLS_E_INVALID_REQUEST;
4380
0
  }
4381
4382
0
  if ((ret =
4383
0
       _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia,
4384
0
              critical)) < 0)
4385
0
    return ret;
4386
4387
0
  if (aia.size == 0 || aia.data == NULL) {
4388
0
    gnutls_assert();
4389
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
4390
0
  }
4391
4392
0
  if (critical && *critical)
4393
0
    return GNUTLS_E_CONSTRAINT_ERROR;
4394
4395
0
  ret = asn1_create_element(_gnutls_get_pkix(),
4396
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
4397
0
  if (ret != ASN1_SUCCESS) {
4398
0
    gnutls_assert();
4399
0
    _gnutls_free_datum(&aia);
4400
0
    return _gnutls_asn2err(ret);
4401
0
  }
4402
4403
0
  ret = _asn1_strict_der_decode(&c2, aia.data, aia.size, NULL);
4404
  /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
4405
0
  _gnutls_free_datum(&aia);
4406
0
  if (ret != ASN1_SUCCESS) {
4407
0
    gnutls_assert();
4408
0
    asn1_delete_structure(&c2);
4409
0
    return _gnutls_asn2err(ret);
4410
0
  }
4411
4412
0
  ret = legacy_parse_aia(c2, seq, what, data);
4413
4414
0
  asn1_delete_structure(&c2);
4415
0
  if (ret < 0)
4416
0
    gnutls_assert();
4417
4418
0
  return ret;
4419
0
}
4420
4421
/**
4422
 * gnutls_x509_crt_set_pin_function:
4423
 * @crt: The certificate structure
4424
 * @fn: the callback
4425
 * @userdata: data associated with the callback
4426
 *
4427
 * This function will set a callback function to be used when
4428
 * it is required to access a protected object. This function overrides
4429
 * the global function set using gnutls_pkcs11_set_pin_function().
4430
 *
4431
 * Note that this callback is currently used only during the import
4432
 * of a PKCS #11 certificate with gnutls_x509_crt_import_url().
4433
 *
4434
 * Since: 3.1.0
4435
 *
4436
 **/
4437
void gnutls_x509_crt_set_pin_function(gnutls_x509_crt_t crt,
4438
              gnutls_pin_callback_t fn, void *userdata)
4439
0
{
4440
0
  if (crt) {
4441
0
    crt->pin.cb = fn;
4442
0
    crt->pin.data = userdata;
4443
0
  }
4444
0
}
4445
4446
/**
4447
 * gnutls_x509_crt_import_url:
4448
 * @crt: A certificate of type #gnutls_x509_crt_t
4449
 * @url: A PKCS 11 url
4450
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4451
 *
4452
 * This function will import a certificate present in a PKCS#11 token
4453
 * or any type of back-end that supports URLs.
4454
 *
4455
 * In previous versions of gnutls this function was named
4456
 * gnutls_x509_crt_import_pkcs11_url, and the old name is
4457
 * an alias to this one.
4458
 *
4459
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4460
 *   negative error value.
4461
 *
4462
 * Since: 3.4.0
4463
 **/
4464
int
4465
gnutls_x509_crt_import_url(gnutls_x509_crt_t crt,
4466
         const char *url, unsigned int flags)
4467
0
{
4468
0
  int ret;
4469
0
  unsigned i;
4470
4471
0
  for (i = 0; i < _gnutls_custom_urls_size; i++) {
4472
0
    if (strncmp
4473
0
        (url, _gnutls_custom_urls[i].name,
4474
0
         _gnutls_custom_urls[i].name_size) == 0) {
4475
0
      if (_gnutls_custom_urls[i].import_crt) {
4476
0
        ret =
4477
0
            _gnutls_custom_urls[i].import_crt(crt, url,
4478
0
                      flags);
4479
0
        goto cleanup;
4480
0
      }
4481
0
      break;
4482
0
    }
4483
0
  }
4484
4485
0
  if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
4486
0
    ret = _gnutls_x509_crt_import_system_url(crt, url);
4487
#ifdef ENABLE_PKCS11
4488
  } else if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
4489
    ret = _gnutls_x509_crt_import_pkcs11_url(crt, url, flags);
4490
#endif
4491
0
  } else {
4492
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4493
0
  }
4494
4495
0
 cleanup:
4496
0
  return ret;
4497
0
}
4498
4499
/**
4500
 * gnutls_x509_crt_list_import_url:
4501
 * @certs: Will hold the allocated certificate list.
4502
 * @size: It will contain the size of the list.
4503
 * @url: A PKCS 11 url
4504
 * @pin_fn: a PIN callback if not globally set
4505
 * @pin_fn_userdata: parameter for the PIN callback
4506
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4507
 *
4508
 * This function will import a certificate chain present in a PKCS#11 token
4509
 * or any type of back-end that supports URLs. The certificates
4510
 * must be deinitialized afterwards using gnutls_x509_crt_deinit()
4511
 * and the returned pointer must be freed using gnutls_free().
4512
 *
4513
 * The URI provided must be the first certificate in the chain; subsequent
4514
 * certificates will be retrieved using gnutls_pkcs11_get_raw_issuer() or
4515
 * equivalent functionality for the supported URI.
4516
 *
4517
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4518
 *   negative error value.
4519
 *
4520
 * Since: 3.6.3
4521
 **/
4522
int
4523
gnutls_x509_crt_list_import_url(gnutls_x509_crt_t ** certs,
4524
        unsigned int *size,
4525
        const char *url,
4526
        gnutls_pin_callback_t pin_fn,
4527
        void *pin_fn_userdata, unsigned int flags)
4528
0
{
4529
0
  int ret;
4530
0
  unsigned i;
4531
0
  gnutls_x509_crt_t crts[DEFAULT_MAX_VERIFY_DEPTH];
4532
0
  gnutls_datum_t issuer = { NULL, 0 };
4533
0
  unsigned total = 0;
4534
4535
0
  memset(crts, 0, sizeof(crts));
4536
4537
0
  ret = gnutls_x509_crt_init(&crts[0]);
4538
0
  if (ret < 0)
4539
0
    return gnutls_assert_val(ret);
4540
4541
0
  gnutls_x509_crt_set_pin_function(crts[0], pin_fn, pin_fn_userdata);
4542
4543
0
  total = 1;
4544
4545
0
  ret = gnutls_x509_crt_import_url(crts[0], url, flags);
4546
0
  if (ret < 0) {
4547
0
    gnutls_assert();
4548
0
    goto cleanup;
4549
0
  }
4550
4551
0
  for (i = 1; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
4552
0
    ret =
4553
0
        _gnutls_get_raw_issuer(url, crts[i - 1], &issuer,
4554
0
             flags |
4555
0
             GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_ANY);
4556
0
    if (ret < 0) {
4557
0
      issuer.data = NULL;
4558
0
      break;
4559
0
    }
4560
4561
0
    if (gnutls_x509_crt_equals2(crts[i - 1], &issuer)) {
4562
0
      gnutls_free(issuer.data);
4563
0
      break;
4564
0
    }
4565
4566
0
    ret = gnutls_x509_crt_init(&crts[i]);
4567
0
    if (ret < 0) {
4568
0
      gnutls_assert();
4569
0
      goto cleanup;
4570
0
    }
4571
4572
0
    total++;
4573
4574
0
    gnutls_x509_crt_set_pin_function(crts[i], pin_fn,
4575
0
             pin_fn_userdata);
4576
4577
0
    ret =
4578
0
        gnutls_x509_crt_import(crts[i], &issuer,
4579
0
             GNUTLS_X509_FMT_DER);
4580
0
    if (ret < 0) {
4581
0
      gnutls_assert();
4582
0
      goto cleanup;
4583
0
    }
4584
4585
0
    gnutls_free(issuer.data);
4586
0
  }
4587
4588
0
  *certs = _gnutls_reallocarray(NULL, total, sizeof(gnutls_x509_crt_t));
4589
0
  if (*certs == NULL) {
4590
0
    ret = GNUTLS_E_MEMORY_ERROR;
4591
0
    goto cleanup;
4592
0
  }
4593
4594
0
  memcpy(*certs, crts, total * sizeof(gnutls_x509_crt_t));
4595
0
  *size = total;
4596
4597
0
  return 0;
4598
0
 cleanup:
4599
0
  gnutls_free(issuer.data);
4600
0
  for (i = 0; i < total; i++)
4601
0
    gnutls_x509_crt_deinit(crts[i]);
4602
4603
0
  return ret;
4604
0
}
4605
4606
/*-
4607
 * gnutls_x509_crt_verify_data3:
4608
 * @crt: Holds the certificate to verify with
4609
 * @algo: The signature algorithm used
4610
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4611
 * @data: holds the signed data
4612
 * @signature: contains the signature
4613
 *
4614
 * This function will verify the given signed data, using the
4615
 * parameters from the certificate.
4616
 *
4617
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4618
 * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4619
 * or not yet activated certificate and zero or positive code on success.
4620
 *
4621
 * Since: 3.5.6
4622
 -*/
4623
int
4624
gnutls_x509_crt_verify_data3(gnutls_x509_crt_t crt,
4625
           gnutls_sign_algorithm_t algo,
4626
           gnutls_typed_vdata_st * vdata,
4627
           unsigned int vdata_size,
4628
           const gnutls_datum_t * data,
4629
           const gnutls_datum_t * signature,
4630
           unsigned int flags)
4631
0
{
4632
0
  int ret;
4633
0
  gnutls_pubkey_t pubkey;
4634
4635
0
  if (crt == NULL) {
4636
0
    gnutls_assert();
4637
0
    return GNUTLS_E_INVALID_REQUEST;
4638
0
  }
4639
4640
0
  ret = gnutls_pubkey_init(&pubkey);
4641
0
  if (ret < 0)
4642
0
    return gnutls_assert_val(ret);
4643
4644
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
4645
0
  if (ret < 0)
4646
0
    return gnutls_assert_val(ret);
4647
4648
0
  ret = gnutls_pubkey_verify_data2(pubkey, algo, flags, data, signature);
4649
0
  gnutls_pubkey_deinit(pubkey);
4650
4651
0
  if (ret >= 0) {
4652
0
    time_t now = gnutls_time(0);
4653
0
    int res;
4654
0
    unsigned usage, i;
4655
4656
0
    if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) ||
4657
0
        !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
4658
0
      if (now > gnutls_x509_crt_get_expiration_time(crt)) {
4659
0
        return gnutls_assert_val(GNUTLS_E_EXPIRED);
4660
0
      }
4661
4662
0
      if (now < gnutls_x509_crt_get_activation_time(crt)) {
4663
0
        return
4664
0
            gnutls_assert_val
4665
0
            (GNUTLS_E_NOT_YET_ACTIVATED);
4666
0
      }
4667
0
    }
4668
4669
0
    res = gnutls_x509_crt_get_key_usage(crt, &usage, NULL);
4670
0
    if (res >= 0) {
4671
0
      if (!(usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
4672
0
        return
4673
0
            gnutls_assert_val
4674
0
            (GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4675
0
      }
4676
0
    }
4677
4678
0
    for (i = 0; i < vdata_size; i++) {
4679
0
      if (vdata[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
4680
0
        res = _gnutls_check_key_purpose(crt, (char *)
4681
0
                vdata[i].data,
4682
0
                0);
4683
0
        if (res == 0)
4684
0
          return
4685
0
              gnutls_assert_val
4686
0
              (GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4687
0
        break;
4688
0
      }
4689
0
    }
4690
0
  }
4691
4692
0
  return ret;
4693
0
}
4694
4695
/**
4696
 * gnutls_x509_crt_verify_data2:
4697
 * @crt: Holds the certificate to verify with
4698
 * @algo: The signature algorithm used
4699
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4700
 * @data: holds the signed data
4701
 * @signature: contains the signature
4702
 *
4703
 * This function will verify the given signed data, using the
4704
 * parameters from the certificate.
4705
 *
4706
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4707
 * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4708
 * or not yet activated certificate and zero or positive code on success.
4709
 *
4710
 * Note that since GnuTLS 3.5.6 this function introduces checks in the
4711
 * end certificate (@crt), including time checks and key usage checks.
4712
 *
4713
 * Since: 3.4.0
4714
 **/
4715
int
4716
gnutls_x509_crt_verify_data2(gnutls_x509_crt_t crt,
4717
           gnutls_sign_algorithm_t algo,
4718
           unsigned int flags,
4719
           const gnutls_datum_t * data,
4720
           const gnutls_datum_t * signature)
4721
0
{
4722
0
  return gnutls_x509_crt_verify_data3(crt, algo, NULL, 0,
4723
0
              data, signature, flags);
4724
0
}
4725
4726
/**
4727
 * gnutls_x509_crt_set_flags:
4728
 * @cert: A type #gnutls_x509_crt_t
4729
 * @flags: flags from the %gnutls_x509_crt_flags
4730
 *
4731
 * This function will set flags for the specified certificate.
4732
 * Currently this is useful for the %GNUTLS_X509_CRT_FLAG_IGNORE_SANITY
4733
 * which allows importing certificates even if they have known issues.
4734
 *
4735
 * Since: 3.6.0
4736
 *
4737
 **/
4738
void gnutls_x509_crt_set_flags(gnutls_x509_crt_t cert, unsigned int flags)
4739
0
{
4740
0
  cert->flags = flags;
4741
0
}