Coverage Report

Created: 2026-05-16 06:52

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