Coverage Report

Created: 2025-07-23 07:16

/src/gnutls/lib/x509/x509.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2003-2018 Free Software Foundation, Inc.
3
 * Copyright (C) 2018 Red Hat, Inc.
4
 *
5
 * Authors: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* Functions on X.509 Certificate parsing
25
 */
26
27
#include "gnutls_int.h"
28
#include "datum.h"
29
#include "global.h"
30
#include "errors.h"
31
#include "common.h"
32
#include <gnutls/x509-ext.h>
33
#include "x509.h"
34
#include "x509_b64.h"
35
#include "x509_int.h"
36
#include <libtasn1.h>
37
#include "pk.h"
38
#include "pkcs11_int.h"
39
#include "urls.h"
40
#include "system-keys.h"
41
#include "gl_linkedhash_list.h"
42
#include "gl_list.h"
43
#include "hash-pjw-bare.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
0
{
95
0
  int ret;
96
0
  bool result;
97
98
0
  if (cert1->modified == 0 && cert2->modified == 0 &&
99
0
      cert1->raw_dn.size > 0 && cert2->raw_dn.size > 0) {
100
0
    ret = _gnutls_is_same_dn(cert1, cert2);
101
0
    if (ret == 0)
102
0
      return 0;
103
0
  }
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
0
{
201
0
  gnutls_x509_crt_t tmp;
202
0
  int result;
203
204
0
  *cert = NULL;
205
0
  FAIL_IF_LIB_ERROR;
206
207
0
  tmp = gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
208
209
0
  if (!tmp)
210
0
    return GNUTLS_E_MEMORY_ERROR;
211
212
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Certificate",
213
0
             &tmp->cert);
214
0
  if (result != ASN1_SUCCESS) {
215
0
    gnutls_assert();
216
0
    gnutls_free(tmp);
217
0
    return _gnutls_asn2err(result);
218
0
  }
219
220
0
  result = gnutls_subject_alt_names_init(&tmp->san);
221
0
  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
0
  result = gnutls_subject_alt_names_init(&tmp->ian);
229
0
  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
0
  *cert = tmp;
241
242
0
  return 0; /* success */
243
0
}
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
0
{
292
0
  if (!cert)
293
0
    return;
294
295
0
  if (cert->cert)
296
0
    asn1_delete_structure(&cert->cert);
297
0
  gnutls_free(cert->der.data);
298
0
  gnutls_subject_alt_names_deinit(cert->san);
299
0
  gnutls_subject_alt_names_deinit(cert->ian);
300
0
  gnutls_free(cert);
301
0
}
302
303
static int compare_sig_algorithm(gnutls_x509_crt_t cert)
304
0
{
305
0
  int ret, len1, len2, result;
306
0
  char oid1[MAX_OID_SIZE];
307
0
  char oid2[MAX_OID_SIZE];
308
0
  gnutls_datum_t sp1 = { NULL, 0 };
309
0
  gnutls_datum_t sp2 = { NULL, 0 };
310
0
  unsigned empty1 = 0, empty2 = 0;
311
312
0
  len1 = sizeof(oid1);
313
0
  result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm",
314
0
         oid1, &len1);
315
0
  if (result != ASN1_SUCCESS) {
316
0
    gnutls_assert();
317
0
    return _gnutls_asn2err(result);
318
0
  }
319
320
0
  len2 = sizeof(oid2);
321
0
  result = asn1_read_value(
322
0
    cert->cert, "tbsCertificate.signature.algorithm", oid2, &len2);
323
0
  if (result != ASN1_SUCCESS) {
324
0
    gnutls_assert();
325
0
    return _gnutls_asn2err(result);
326
0
  }
327
328
0
  if (len1 != len2 || memcmp(oid1, oid2, len1) != 0) {
329
0
    _gnutls_debug_log(
330
0
      "signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n",
331
0
      oid1, oid2);
332
0
    gnutls_assert();
333
0
    return GNUTLS_E_CERTIFICATE_ERROR;
334
0
  }
335
336
  /* compare the parameters */
337
0
  ret = _gnutls_x509_read_value(cert->cert,
338
0
              "signatureAlgorithm.parameters", &sp1);
339
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
340
0
    empty1 = 1;
341
0
  } else if (ret < 0) {
342
0
    gnutls_assert();
343
0
    return ret;
344
0
  }
345
346
0
  ret = _gnutls_x509_read_value(
347
0
    cert->cert, "tbsCertificate.signature.parameters", &sp2);
348
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
349
0
    empty2 = 1;
350
0
  } else if (ret < 0) {
351
0
    gnutls_assert();
352
0
    return ret;
353
0
  }
354
355
  /* handle equally empty parameters with missing parameters */
356
0
  if (sp1.size == 2 && memcmp(sp1.data, "\x05\x00", 2) == 0) {
357
0
    empty1 = 1;
358
0
    _gnutls_free_datum(&sp1);
359
0
  }
360
361
0
  if (sp2.size == 2 && memcmp(sp2.data, "\x05\x00", 2) == 0) {
362
0
    empty2 = 1;
363
0
    _gnutls_free_datum(&sp2);
364
0
  }
365
366
0
  if (empty1 != empty2 || sp1.size != sp2.size ||
367
0
      (sp1.size > 0 && memcmp(sp1.data, sp2.data, sp1.size) != 0)) {
368
0
    gnutls_assert();
369
0
    ret = GNUTLS_E_CERTIFICATE_ERROR;
370
0
    goto cleanup;
371
0
  }
372
373
0
  ret = 0;
374
0
cleanup:
375
0
  _gnutls_free_datum(&sp1);
376
0
  _gnutls_free_datum(&sp2);
377
0
  return ret;
378
0
}
379
380
static int cache_alt_names(gnutls_x509_crt_t cert)
381
0
{
382
0
  gnutls_datum_t tmpder = { NULL, 0 };
383
0
  int ret;
384
385
  /* pre-parse subject alt name */
386
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.17", 0, &tmpder,
387
0
               NULL);
388
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
389
0
    gnutls_free(tmpder.data);
390
0
    return gnutls_assert_val(ret);
391
0
  }
392
393
0
  if (ret >= 0) {
394
0
    ret = gnutls_x509_ext_import_subject_alt_names(&tmpder,
395
0
                     cert->san, 0);
396
0
    gnutls_free(tmpder.data);
397
0
    if (ret < 0)
398
0
      return gnutls_assert_val(ret);
399
0
  }
400
401
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.18", 0, &tmpder,
402
0
               NULL);
403
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
404
0
    return gnutls_assert_val(ret);
405
406
0
  if (ret >= 0) {
407
0
    ret = gnutls_x509_ext_import_subject_alt_names(&tmpder,
408
0
                     cert->ian, 0);
409
0
    gnutls_free(tmpder.data);
410
0
    if (ret < 0)
411
0
      return gnutls_assert_val(ret);
412
0
  }
413
414
0
  return 0;
415
0
}
416
417
static bool hcomparator(const void *v1, const void *v2)
418
0
{
419
0
  return strcmp(v1, v2) == 0;
420
0
}
421
422
static size_t hhasher(const void *entry)
423
0
{
424
0
  const char *e = entry;
425
0
  if (e == NULL || e[0] == 0)
426
0
    return 0;
427
428
0
  return hash_pjw_bare(e, strlen(e));
429
0
}
430
431
static void hdisposer(const void *entry)
432
0
{
433
0
  void *e = (void *)entry;
434
0
  gnutls_free(e);
435
0
}
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
0
{
573
0
  int ret = 0, version;
574
0
  gnutls_datum_t exts;
575
0
  gl_list_t htable = NULL;
576
577
0
  if (cert->flags & GNUTLS_X509_CRT_FLAG_IGNORE_SANITY)
578
0
    return 0;
579
580
  /* enforce the rule that only version 3 certificates carry extensions */
581
0
  ret = gnutls_x509_crt_get_version(cert);
582
0
  if (ret < 0) {
583
0
    return gnutls_assert_val(ret);
584
0
  }
585
586
0
  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
0
  if (version < 3) {
598
0
    if (!cert->modified) {
599
0
      ret = _gnutls_x509_get_raw_field2(
600
0
        cert->cert, &cert->der,
601
0
        "tbsCertificate.extensions", &exts);
602
0
      if (ret >= 0 && exts.size > 0) {
603
0
        _gnutls_debug_log(
604
0
          "error: extensions present in certificate with version %d\n",
605
0
          version);
606
0
        return gnutls_assert_val(
607
0
          GNUTLS_E_X509_CERTIFICATE_ERROR);
608
0
      }
609
0
    } 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
0
  } else {
619
    /* Version is 3; ensure no duplicate extensions are present. */
620
0
    unsigned i, critical;
621
0
    char oid[MAX_OID_SIZE];
622
0
    size_t oid_size;
623
0
    char *o;
624
625
0
    htable = gl_list_nx_create_empty(GL_LINKEDHASH_LIST,
626
0
             hcomparator, hhasher,
627
0
             hdisposer, false);
628
0
    if (htable == NULL)
629
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
630
631
0
    for (i = 0;; i++) {
632
0
      oid_size = sizeof(oid);
633
0
      ret = gnutls_x509_crt_get_extension_info(
634
0
        cert, i, oid, &oid_size, &critical);
635
0
      if (ret < 0) {
636
0
        if (ret ==
637
0
            GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
638
0
          break;
639
0
        gnutls_assert();
640
0
        goto cleanup;
641
0
      }
642
0
      o = gnutls_strdup(oid);
643
0
      if (o == NULL) {
644
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
645
0
        goto cleanup;
646
0
      }
647
648
0
      if (gl_list_search(htable, o)) {
649
        /* duplicate */
650
0
        gnutls_free(o);
651
0
        _gnutls_debug_log(
652
0
          "error: duplicate extension (%s) detected\n",
653
0
          oid);
654
0
        ret = gnutls_assert_val(
655
0
          GNUTLS_E_X509_DUPLICATE_EXTENSION);
656
0
        goto cleanup;
657
0
      } 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
0
    }
680
681
0
    gl_list_free(htable);
682
0
    htable = NULL;
683
0
  }
684
685
0
  if (version < 2) {
686
0
    char id[128];
687
0
    size_t id_size;
688
689
0
    id_size = sizeof(id);
690
0
    ret = gnutls_x509_crt_get_subject_unique_id(cert, id, &id_size);
691
0
    if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
692
0
      _gnutls_debug_log(
693
0
        "error: subjectUniqueID present in certificate with version %d\n",
694
0
        version);
695
0
      ret = gnutls_assert_val(
696
0
        GNUTLS_E_X509_CERTIFICATE_ERROR);
697
0
      goto cleanup;
698
0
    }
699
700
0
    id_size = sizeof(id);
701
0
    ret = gnutls_x509_crt_get_issuer_unique_id(cert, id, &id_size);
702
0
    if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
703
0
      _gnutls_debug_log(
704
0
        "error: subjectUniqueID present in certificate with version %d\n",
705
0
        version);
706
0
      ret = gnutls_assert_val(
707
0
        GNUTLS_E_X509_CERTIFICATE_ERROR);
708
0
      goto cleanup;
709
0
    }
710
0
  }
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
0
  if (gnutls_x509_crt_get_expiration_time(cert) == -1 ||
720
0
      gnutls_x509_crt_get_activation_time(cert) == -1) {
721
0
    _gnutls_debug_log(
722
0
      "error: invalid expiration or activation time in certificate\n");
723
0
    ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_TIME_ERROR);
724
0
    goto cleanup;
725
0
  }
726
727
0
  ret = 0;
728
729
0
cleanup:
730
0
  if (htable)
731
0
    gl_list_free(htable);
732
0
  return ret;
733
0
}
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
0
{
754
0
  int result;
755
756
0
  if (cert == NULL) {
757
0
    gnutls_assert();
758
0
    return GNUTLS_E_INVALID_REQUEST;
759
0
  }
760
761
0
  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
0
  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
0
  } else {
791
0
    result = _gnutls_set_datum(&cert->der, data->data, data->size);
792
0
    if (result < 0) {
793
0
      gnutls_assert();
794
0
      return result;
795
0
    }
796
0
  }
797
798
0
  cert->expanded = 1;
799
0
  cert->modified = 0;
800
801
0
  result = _asn1_strict_der_decode(&cert->cert, cert->der.data,
802
0
           cert->der.size, NULL);
803
0
  if (result != ASN1_SUCCESS) {
804
0
    result = _gnutls_asn2err(result);
805
0
    gnutls_assert();
806
0
    goto cleanup;
807
0
  }
808
809
0
  result = compare_sig_algorithm(cert);
810
0
  if (result < 0) {
811
0
    gnutls_assert();
812
0
    goto cleanup;
813
0
  }
814
815
  /* The following do not allocate but rather point to DER data */
816
0
  result = _gnutls_x509_get_raw_field2(
817
0
    cert->cert, &cert->der, "tbsCertificate.issuer.rdnSequence",
818
0
    &cert->raw_issuer_dn);
819
0
  if (result < 0) {
820
0
    gnutls_assert();
821
0
    goto cleanup;
822
0
  }
823
824
0
  result = _gnutls_x509_get_raw_field2(
825
0
    cert->cert, &cert->der, "tbsCertificate.subject.rdnSequence",
826
0
    &cert->raw_dn);
827
0
  if (result < 0) {
828
0
    gnutls_assert();
829
0
    goto cleanup;
830
0
  }
831
832
0
  result = _gnutls_x509_get_raw_field2(
833
0
    cert->cert, &cert->der, "tbsCertificate.subjectPublicKeyInfo",
834
0
    &cert->raw_spki);
835
0
  if (result < 0) {
836
0
    gnutls_assert();
837
0
    goto cleanup;
838
0
  }
839
840
0
  result = cache_alt_names(cert);
841
0
  if (result < 0) {
842
0
    gnutls_assert();
843
0
    goto cleanup;
844
0
  }
845
846
0
  result = _gnutls_check_cert_sanity(cert);
847
0
  if (result < 0) {
848
0
    gnutls_assert();
849
0
    goto cleanup;
850
0
  }
851
852
  /* Since we do not want to disable any extension
853
   */
854
0
  cert->use_extensions = 1;
855
856
0
  return 0;
857
858
0
cleanup:
859
0
  _gnutls_free_datum(&cert->der);
860
0
  return result;
861
0
}
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
0
{
950
0
  if (cert == NULL) {
951
0
    gnutls_assert();
952
0
    return GNUTLS_E_INVALID_REQUEST;
953
0
  }
954
955
0
  return _gnutls_x509_get_dn(
956
0
    cert->cert, "tbsCertificate.issuer.rdnSequence", dn, flags);
957
0
}
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
0
{
1129
0
  if (cert == NULL) {
1130
0
    gnutls_assert();
1131
0
    return GNUTLS_E_INVALID_REQUEST;
1132
0
  }
1133
1134
0
  return _gnutls_x509_get_dn(
1135
0
    cert->cert, "tbsCertificate.subject.rdnSequence", dn, flags);
1136
0
}
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
0
{
1171
0
  gnutls_datum_t td;
1172
0
  int ret;
1173
1174
0
  if (cert == NULL) {
1175
0
    gnutls_assert();
1176
0
    return GNUTLS_E_INVALID_REQUEST;
1177
0
  }
1178
1179
0
  ret = _gnutls_x509_parse_dn_oid(cert->cert,
1180
0
          "tbsCertificate.subject.rdnSequence",
1181
0
          oid, indx, raw_flag, &td);
1182
0
  if (ret < 0)
1183
0
    return gnutls_assert_val(ret);
1184
1185
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
1186
0
}
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
0
{
1236
0
  return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(
1237
0
    cert->cert, "signatureAlgorithm"));
1238
0
}
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
0
{
1258
0
  char str[MAX_OID_SIZE];
1259
0
  int len, result, ret;
1260
0
  gnutls_datum_t out;
1261
1262
0
  len = sizeof(str);
1263
0
  result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm",
1264
0
         str, &len);
1265
0
  if (result != ASN1_SUCCESS) {
1266
0
    gnutls_assert();
1267
0
    return _gnutls_asn2err(result);
1268
0
  }
1269
1270
0
  out.data = (void *)str;
1271
0
  out.size = len;
1272
1273
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1274
0
  if (ret < 0) {
1275
0
    gnutls_assert();
1276
0
    return ret;
1277
0
  }
1278
1279
0
  return 0;
1280
0
}
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
0
{
1300
0
  char str[MAX_OID_SIZE];
1301
0
  int len, result, ret;
1302
0
  gnutls_datum_t out;
1303
1304
0
  len = sizeof(str);
1305
0
  result = asn1_read_value(
1306
0
    cert->cert,
1307
0
    "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", str,
1308
0
    &len);
1309
0
  if (result != ASN1_SUCCESS) {
1310
0
    gnutls_assert();
1311
0
    return _gnutls_asn2err(result);
1312
0
  }
1313
1314
0
  out.data = (void *)str;
1315
0
  out.size = len;
1316
1317
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1318
0
  if (ret < 0) {
1319
0
    gnutls_assert();
1320
0
    return ret;
1321
0
  }
1322
1323
0
  return 0;
1324
0
}
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
0
{
1340
0
  gnutls_datum_t dsig = { NULL, 0 };
1341
0
  int ret;
1342
1343
0
  if (cert == NULL)
1344
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1345
1346
0
  ret = _gnutls_x509_get_signature(cert->cert, "signature", &dsig);
1347
0
  if (ret < 0)
1348
0
    return gnutls_assert_val(ret);
1349
1350
0
  ret = _gnutls_copy_data(&dsig, (uint8_t *)sig, sig_size);
1351
0
  if (ret < 0) {
1352
0
    gnutls_assert();
1353
0
    goto cleanup;
1354
0
  }
1355
1356
0
  ret = 0;
1357
0
cleanup:
1358
0
  gnutls_free(dsig.data);
1359
0
  return ret;
1360
0
}
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
0
{
1372
0
  if (cert == NULL) {
1373
0
    gnutls_assert();
1374
0
    return GNUTLS_E_INVALID_REQUEST;
1375
0
  }
1376
1377
0
  return _gnutls_x509_get_version(cert->cert, "tbsCertificate.version");
1378
0
}
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
0
{
1391
0
  if (cert == NULL) {
1392
0
    gnutls_assert();
1393
0
    return (time_t)-1;
1394
0
  }
1395
1396
0
  return _gnutls_x509_get_time(cert->cert,
1397
0
             "tbsCertificate.validity.notBefore", 0);
1398
0
}
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
0
{
1411
0
  if (cert == NULL) {
1412
0
    gnutls_assert();
1413
0
    return (time_t)-1;
1414
0
  }
1415
1416
0
  return _gnutls_x509_get_time(cert->cert,
1417
0
             "tbsCertificate.validity.notAfter", 0);
1418
0
}
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
0
{
1487
0
  int ret, len;
1488
1489
0
  if (cert == NULL) {
1490
0
    gnutls_assert();
1491
0
    return GNUTLS_E_INVALID_REQUEST;
1492
0
  }
1493
1494
0
  len = *result_size;
1495
0
  ret = asn1_read_value(cert->cert, "tbsCertificate.serialNumber", result,
1496
0
            &len);
1497
0
  *result_size = len;
1498
1499
0
  if (ret != ASN1_SUCCESS) {
1500
0
    gnutls_assert();
1501
0
    return _gnutls_asn2err(ret);
1502
0
  }
1503
1504
0
  return 0;
1505
0
}
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
0
{
1524
0
  int result;
1525
0
  gnutls_datum_t id = { NULL, 0 };
1526
0
  gnutls_datum_t der = { NULL, 0 };
1527
1528
0
  if (cert == NULL) {
1529
0
    gnutls_assert();
1530
0
    return GNUTLS_E_INVALID_REQUEST;
1531
0
  }
1532
1533
0
  if (ret == NULL)
1534
0
    *ret_size = 0;
1535
1536
0
  if ((result = _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &der,
1537
0
                 critical)) < 0) {
1538
0
    return result;
1539
0
  }
1540
1541
0
  result = gnutls_x509_ext_import_subject_key_id(&der, &id);
1542
0
  if (result < 0) {
1543
0
    gnutls_assert();
1544
0
    goto cleanup;
1545
0
  }
1546
1547
0
  result = _gnutls_copy_data(&id, ret, ret_size);
1548
0
  if (result < 0) {
1549
0
    gnutls_assert();
1550
0
    goto cleanup;
1551
0
  }
1552
1553
0
  result = 0;
1554
1555
0
cleanup:
1556
0
  gnutls_free(der.data);
1557
0
  gnutls_free(id.data);
1558
0
  return result;
1559
0
}
1560
1561
inline static int is_type_printable(int type)
1562
0
{
1563
0
  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 || type == GNUTLS_SAN_REGISTERED_ID)
1566
0
    return 1;
1567
0
  else
1568
0
    return 0;
1569
0
}
1570
1571
/**
1572
 * gnutls_x509_crt_get_authority_key_gn_serial:
1573
 * @cert: should contain a #gnutls_x509_crt_t type
1574
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1575
 * @alt: is the place where the alternative name will be copied to
1576
 * @alt_size: holds the size of alt.
1577
 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1578
 * @serial: buffer to store the serial number (may be null)
1579
 * @serial_size: Holds the size of the serial field (may be null)
1580
 * @critical: will be non-zero if the extension is marked as critical (may be null)
1581
 *
1582
 * This function will return the X.509 authority key
1583
 * identifier when stored as a general name (authorityCertIssuer)
1584
 * and serial number.
1585
 *
1586
 * Because more than one general names might be stored
1587
 * @seq can be used as a counter to request them all until
1588
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1589
 *
1590
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1591
 * if the extension is not present, otherwise a negative error value.
1592
 *
1593
 * Since: 3.0
1594
 **/
1595
int gnutls_x509_crt_get_authority_key_gn_serial(
1596
  gnutls_x509_crt_t cert, unsigned int seq, void *alt, size_t *alt_size,
1597
  unsigned int *alt_type, void *serial, size_t *serial_size,
1598
  unsigned int *critical)
1599
0
{
1600
0
  int ret;
1601
0
  gnutls_datum_t der, san, iserial;
1602
0
  gnutls_x509_aki_t aki = NULL;
1603
0
  unsigned san_type;
1604
1605
0
  if (cert == NULL) {
1606
0
    gnutls_assert();
1607
0
    return GNUTLS_E_INVALID_REQUEST;
1608
0
  }
1609
1610
0
  if ((ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1611
0
              critical)) < 0) {
1612
0
    return gnutls_assert_val(ret);
1613
0
  }
1614
1615
0
  if (der.size == 0 || der.data == NULL) {
1616
0
    gnutls_assert();
1617
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1618
0
  }
1619
1620
0
  ret = gnutls_x509_aki_init(&aki);
1621
0
  if (ret < 0) {
1622
0
    gnutls_assert();
1623
0
    goto cleanup;
1624
0
  }
1625
1626
0
  ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1627
0
  if (ret < 0) {
1628
0
    gnutls_assert();
1629
0
    goto cleanup;
1630
0
  }
1631
1632
0
  ret = gnutls_x509_aki_get_cert_issuer(aki, seq, &san_type, &san, NULL,
1633
0
                &iserial);
1634
0
  if (ret < 0) {
1635
0
    gnutls_assert();
1636
0
    goto cleanup;
1637
0
  }
1638
1639
0
  if (is_type_printable(san_type))
1640
0
    ret = _gnutls_copy_string(&san, alt, alt_size);
1641
0
  else
1642
0
    ret = _gnutls_copy_data(&san, alt, alt_size);
1643
0
  if (ret < 0) {
1644
0
    gnutls_assert();
1645
0
    goto cleanup;
1646
0
  }
1647
1648
0
  if (alt_type)
1649
0
    *alt_type = san_type;
1650
1651
0
  ret = _gnutls_copy_data(&iserial, serial, serial_size);
1652
0
  if (ret < 0) {
1653
0
    gnutls_assert();
1654
0
    goto cleanup;
1655
0
  }
1656
1657
0
  ret = 0;
1658
0
cleanup:
1659
0
  if (aki != NULL)
1660
0
    gnutls_x509_aki_deinit(aki);
1661
0
  gnutls_free(der.data);
1662
0
  return ret;
1663
0
}
1664
1665
/**
1666
 * gnutls_x509_crt_get_authority_key_id:
1667
 * @cert: should contain a #gnutls_x509_crt_t type
1668
 * @id: The place where the identifier will be copied
1669
 * @id_size: Holds the size of the id field.
1670
 * @critical: will be non-zero if the extension is marked as critical (may be null)
1671
 *
1672
 * This function will return the X.509v3 certificate authority's key
1673
 * identifier.  This is obtained by the X.509 Authority Key
1674
 * identifier extension field (2.5.29.35). Note that this function
1675
 * only returns the keyIdentifier field of the extension and
1676
 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
1677
 * the name and serial number of the certificate. In that case
1678
 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
1679
 *
1680
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1681
 * if the extension is not present, otherwise a negative error value.
1682
 **/
1683
int gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert, void *id,
1684
           size_t *id_size,
1685
           unsigned int *critical)
1686
0
{
1687
0
  int ret;
1688
0
  gnutls_datum_t der, l_id;
1689
0
  gnutls_x509_aki_t aki = NULL;
1690
1691
0
  if (cert == NULL) {
1692
0
    gnutls_assert();
1693
0
    return GNUTLS_E_INVALID_REQUEST;
1694
0
  }
1695
1696
0
  if ((ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1697
0
              critical)) < 0) {
1698
0
    return gnutls_assert_val(ret);
1699
0
  }
1700
1701
0
  if (der.size == 0 || der.data == NULL) {
1702
0
    gnutls_assert();
1703
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1704
0
  }
1705
1706
0
  ret = gnutls_x509_aki_init(&aki);
1707
0
  if (ret < 0) {
1708
0
    gnutls_assert();
1709
0
    goto cleanup;
1710
0
  }
1711
1712
0
  ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1713
0
  if (ret < 0) {
1714
0
    gnutls_assert();
1715
0
    goto cleanup;
1716
0
  }
1717
1718
0
  ret = gnutls_x509_aki_get_id(aki, &l_id);
1719
1720
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1721
0
    gnutls_datum_t serial;
1722
0
    ret = gnutls_x509_aki_get_cert_issuer(aki, 0, NULL, NULL, NULL,
1723
0
                  &serial);
1724
0
    if (ret >= 0) {
1725
0
      ret = gnutls_assert_val(
1726
0
        GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1727
0
    } else {
1728
0
      ret = gnutls_assert_val(
1729
0
        GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1730
0
    }
1731
0
  }
1732
1733
0
  if (ret < 0) {
1734
0
    gnutls_assert();
1735
0
    goto cleanup;
1736
0
  }
1737
1738
0
  ret = _gnutls_copy_data(&l_id, id, id_size);
1739
0
  if (ret < 0) {
1740
0
    gnutls_assert();
1741
0
    goto cleanup;
1742
0
  }
1743
1744
0
  ret = 0;
1745
0
cleanup:
1746
0
  if (aki != NULL)
1747
0
    gnutls_x509_aki_deinit(aki);
1748
0
  gnutls_free(der.data);
1749
0
  return ret;
1750
0
}
1751
1752
/**
1753
 * gnutls_x509_crt_get_pk_algorithm:
1754
 * @cert: should contain a #gnutls_x509_crt_t type
1755
 * @bits: if bits is non null it will hold the size of the parameters' in bits
1756
 *
1757
 * This function will return the public key algorithm of an X.509
1758
 * certificate.
1759
 *
1760
 * If bits is non null, it should have enough size to hold the parameters
1761
 * size in bits. For RSA the bits returned is the modulus.
1762
 * For DSA the bits returned are of the public
1763
 * exponent.
1764
 *
1765
 * Unknown/unsupported algorithms are mapped to %GNUTLS_PK_UNKNOWN.
1766
 *
1767
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1768
 * success, or a negative error code on error.
1769
 **/
1770
int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert, unsigned int *bits)
1771
0
{
1772
0
  int result;
1773
1774
0
  if (cert == NULL) {
1775
0
    gnutls_assert();
1776
0
    return GNUTLS_E_INVALID_REQUEST;
1777
0
  }
1778
1779
0
  if (bits)
1780
0
    *bits = 0;
1781
1782
0
  result = _gnutls_x509_get_pk_algorithm(
1783
0
    cert->cert, "tbsCertificate.subjectPublicKeyInfo", NULL, bits);
1784
1785
0
  if (result < 0) {
1786
0
    gnutls_assert();
1787
0
    return result;
1788
0
  }
1789
1790
0
  return result;
1791
0
}
1792
1793
/**
1794
 * gnutls_x509_crt_get_spki:
1795
 * @cert: a certificate of type #gnutls_x509_crt_t
1796
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1797
 * @flags: must be zero
1798
 *
1799
 * This function will return the public key information of an X.509
1800
 * certificate. The provided @spki must be initialized.
1801
 *
1802
 * Since: 3.6.0
1803
 **/
1804
int gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert, gnutls_x509_spki_t spki,
1805
           unsigned int flags)
1806
0
{
1807
0
  int result;
1808
0
  gnutls_x509_spki_st params;
1809
1810
0
  if (cert == NULL) {
1811
0
    gnutls_assert();
1812
0
    return GNUTLS_E_INVALID_REQUEST;
1813
0
  }
1814
1815
0
  spki->pk = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
1816
1817
0
  memset(&params, 0, sizeof(params));
1818
1819
0
  result = _gnutls_x509_crt_read_spki_params(cert, &params);
1820
0
  if (result < 0) {
1821
0
    gnutls_assert();
1822
0
    return result;
1823
0
  }
1824
1825
0
  if (params.pk == GNUTLS_PK_UNKNOWN)
1826
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1827
1828
0
  spki->rsa_pss_dig = params.rsa_pss_dig;
1829
0
  spki->salt_size = params.salt_size;
1830
1831
0
  return 0;
1832
0
}
1833
1834
/* returns the type and the name on success.
1835
 * Type is also returned as a parameter in case of an error.
1836
 *
1837
 * @seq: in case of GeneralNames it will return the corresponding name.
1838
 *       in case of GeneralName, it must be -1
1839
 * @dname: the name returned
1840
 * @ret_type: The type of the name
1841
 * @othername_oid: if the name is otherName return the OID
1842
 *
1843
 */
1844
int _gnutls_parse_general_name2(asn1_node src, const char *src_name, int seq,
1845
        gnutls_datum_t *dname, unsigned int *ret_type,
1846
        int othername_oid)
1847
0
{
1848
0
  int len, ret;
1849
0
  char nptr[MAX_NAME_SIZE];
1850
0
  int result;
1851
0
  gnutls_datum_t tmp = { NULL, 0 };
1852
0
  char choice_type[128];
1853
0
  gnutls_x509_subject_alt_name_t type;
1854
1855
0
  if (seq != -1) {
1856
0
    seq++; /* 0->1, 1->2 etc */
1857
1858
0
    if (src_name[0] != 0)
1859
0
      snprintf(nptr, sizeof(nptr), "%s.?%d", src_name, seq);
1860
0
    else
1861
0
      snprintf(nptr, sizeof(nptr), "?%d", seq);
1862
0
  } else {
1863
0
    snprintf(nptr, sizeof(nptr), "%s", src_name);
1864
0
  }
1865
1866
0
  len = sizeof(choice_type);
1867
0
  result = asn1_read_value(src, nptr, choice_type, &len);
1868
0
  if (result == ASN1_VALUE_NOT_FOUND ||
1869
0
      result == ASN1_ELEMENT_NOT_FOUND) {
1870
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1871
0
  }
1872
1873
0
  if (result != ASN1_SUCCESS) {
1874
0
    gnutls_assert();
1875
0
    return _gnutls_asn2err(result);
1876
0
  }
1877
1878
0
  type = _gnutls_x509_san_find_type(choice_type);
1879
0
  if (type == (gnutls_x509_subject_alt_name_t)-1) {
1880
0
    gnutls_assert();
1881
0
    return GNUTLS_E_X509_UNKNOWN_SAN;
1882
0
  }
1883
1884
0
  if (ret_type)
1885
0
    *ret_type = type;
1886
1887
0
  if (type == GNUTLS_SAN_OTHERNAME) {
1888
0
    if (othername_oid)
1889
0
      _gnutls_str_cat(nptr, sizeof(nptr),
1890
0
          ".otherName.type-id");
1891
0
    else
1892
0
      _gnutls_str_cat(nptr, sizeof(nptr), ".otherName.value");
1893
1894
0
    ret = _gnutls_x509_read_value(src, nptr, &tmp);
1895
0
    if (ret < 0) {
1896
0
      gnutls_assert();
1897
0
      return ret;
1898
0
    }
1899
1900
0
    if (othername_oid) {
1901
0
      dname->size = tmp.size;
1902
0
      dname->data = tmp.data;
1903
0
    } else {
1904
0
      char oid[MAX_OID_SIZE];
1905
1906
0
      if (src_name[0] != 0 && seq != -1)
1907
0
        snprintf(nptr, sizeof(nptr),
1908
0
           "%s.?%d.otherName.type-id", src_name,
1909
0
           seq);
1910
0
      else if (src_name[0] != 0)
1911
0
        snprintf(nptr, sizeof(nptr),
1912
0
           "%s.otherName.type-id", src_name);
1913
0
      else
1914
0
        snprintf(nptr, sizeof(nptr),
1915
0
           "?%d.otherName.type-id", seq);
1916
1917
0
      len = sizeof(oid);
1918
1919
0
      result = asn1_read_value(src, nptr, oid, &len);
1920
0
      if (result != ASN1_SUCCESS) {
1921
0
        gnutls_assert();
1922
0
        ret = _gnutls_asn2err(result);
1923
0
        goto cleanup;
1924
0
      }
1925
0
      if (len > 0)
1926
0
        len--;
1927
1928
0
      dname->size = tmp.size;
1929
0
      dname->data = tmp.data;
1930
0
    }
1931
0
  } else if (type == GNUTLS_SAN_DN) {
1932
0
    _gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
1933
0
    ret = _gnutls_x509_get_dn(src, nptr, dname, 0);
1934
0
    if (ret < 0) {
1935
0
      gnutls_assert();
1936
0
      goto cleanup;
1937
0
    }
1938
0
  } else if (othername_oid) {
1939
0
    gnutls_assert();
1940
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1941
0
    goto cleanup;
1942
0
  } else {
1943
0
    _gnutls_str_cat(nptr, sizeof(nptr), ".");
1944
0
    _gnutls_str_cat(nptr, sizeof(nptr), choice_type);
1945
1946
0
    ret = _gnutls_x509_read_null_value(src, nptr, &tmp);
1947
0
    if (ret < 0) {
1948
0
      gnutls_assert();
1949
0
      return ret;
1950
0
    }
1951
1952
    /* _gnutls_x509_read_value() null terminates */
1953
0
    dname->size = tmp.size;
1954
0
    dname->data = tmp.data;
1955
0
  }
1956
1957
0
  return type;
1958
1959
0
cleanup:
1960
0
  gnutls_free(tmp.data);
1961
0
  return ret;
1962
0
}
1963
1964
/* returns the type and the name on success.
1965
 * Type is also returned as a parameter in case of an error.
1966
 */
1967
int _gnutls_parse_general_name(asn1_node src, const char *src_name, int seq,
1968
             void *name, size_t *name_size,
1969
             unsigned int *ret_type, int othername_oid)
1970
0
{
1971
0
  int ret;
1972
0
  gnutls_datum_t res = { NULL, 0 };
1973
0
  unsigned type;
1974
1975
0
  ret = _gnutls_parse_general_name2(src, src_name, seq, &res, ret_type,
1976
0
            othername_oid);
1977
0
  if (ret < 0)
1978
0
    return gnutls_assert_val(ret);
1979
1980
0
  type = ret;
1981
1982
0
  if (is_type_printable(type)) {
1983
0
    ret = _gnutls_copy_string(&res, name, name_size);
1984
0
  } else {
1985
0
    ret = _gnutls_copy_data(&res, name, name_size);
1986
0
  }
1987
1988
0
  if (ret < 0) {
1989
0
    gnutls_assert();
1990
0
    goto cleanup;
1991
0
  }
1992
1993
0
  ret = type;
1994
0
cleanup:
1995
0
  gnutls_free(res.data);
1996
0
  return ret;
1997
0
}
1998
1999
static int get_alt_name(gnutls_subject_alt_names_t san, unsigned int seq,
2000
      uint8_t *alt, size_t *alt_size, unsigned int *alt_type,
2001
      unsigned int *critical, int othername_oid)
2002
0
{
2003
0
  int ret;
2004
0
  gnutls_datum_t ooid = { NULL, 0 };
2005
0
  gnutls_datum_t oname;
2006
0
  gnutls_datum_t virt = { NULL, 0 };
2007
0
  unsigned int type;
2008
2009
0
  if (san == NULL) {
2010
0
    gnutls_assert();
2011
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2012
0
  }
2013
2014
0
  if (alt == NULL)
2015
0
    *alt_size = 0;
2016
2017
0
  ret = gnutls_subject_alt_names_get(san, seq, &type, &oname, &ooid);
2018
0
  if (ret < 0) {
2019
0
    gnutls_assert();
2020
0
    goto cleanup;
2021
0
  }
2022
2023
0
  if (type == GNUTLS_SAN_OTHERNAME && ooid.data) {
2024
0
    unsigned vtype;
2025
0
    ret = gnutls_x509_othername_to_virtual((char *)ooid.data,
2026
0
                   &oname, &vtype, &virt);
2027
0
    if (ret >= 0) {
2028
0
      type = vtype;
2029
0
      oname.data = virt.data;
2030
0
      oname.size = virt.size;
2031
0
    }
2032
0
  }
2033
2034
0
  if (alt_type)
2035
0
    *alt_type = type;
2036
2037
0
  if (othername_oid) {
2038
0
    ret = _gnutls_copy_string(&ooid, alt, alt_size);
2039
0
  } else {
2040
0
    if (is_type_printable(type)) {
2041
0
      ret = _gnutls_copy_string(&oname, alt, alt_size);
2042
0
    } else {
2043
0
      ret = _gnutls_copy_data(&oname, alt, alt_size);
2044
0
    }
2045
0
  }
2046
2047
0
  if (ret < 0) {
2048
0
    gnutls_assert();
2049
0
    goto cleanup;
2050
0
  }
2051
2052
0
  ret = type;
2053
0
cleanup:
2054
0
  gnutls_free(virt.data);
2055
2056
0
  return ret;
2057
0
}
2058
2059
/**
2060
 * gnutls_x509_crt_get_subject_alt_name:
2061
 * @cert: should contain a #gnutls_x509_crt_t type
2062
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2063
 * @san: is the place where the alternative name will be copied to
2064
 * @san_size: holds the size of san.
2065
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2066
 *
2067
 * This function retrieves the Alternative Name (2.5.29.17), contained
2068
 * in the given certificate in the X509v3 Certificate Extensions.
2069
 *
2070
 * When the SAN type is otherName, it will extract the data in the
2071
 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
2072
 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
2073
 * the corresponding OID and the "virtual" SAN types (e.g.,
2074
 * %GNUTLS_SAN_OTHERNAME_XMPP).
2075
 *
2076
 * If an otherName OID is known, the data will be decoded.  Otherwise
2077
 * the returned data will be DER encoded, and you will have to decode
2078
 * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr SAN is
2079
 * recognized.
2080
 *
2081
 * Returns: the alternative subject name type on success, one of the
2082
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2083
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
2084
 *   hold the value.  In that case @san_size will be updated with the
2085
 *   required size.  If the certificate does not have an Alternative
2086
 *   name with the specified sequence number then
2087
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2088
 **/
2089
int gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
2090
           unsigned int seq, void *san,
2091
           size_t *san_size,
2092
           unsigned int *critical)
2093
0
{
2094
0
  return get_alt_name(cert->san, seq, san, san_size, NULL, critical, 0);
2095
0
}
2096
2097
/**
2098
 * gnutls_x509_crt_get_issuer_alt_name:
2099
 * @cert: should contain a #gnutls_x509_crt_t type
2100
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2101
 * @ian: is the place where the alternative name will be copied to
2102
 * @ian_size: holds the size of ian.
2103
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2104
 *
2105
 * This function retrieves the Issuer Alternative Name (2.5.29.18),
2106
 * contained in the given certificate in the X509v3 Certificate
2107
 * Extensions.
2108
 *
2109
 * When the SAN type is otherName, it will extract the data in the
2110
 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
2111
 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
2112
 * the corresponding OID and the "virtual" SAN types (e.g.,
2113
 * %GNUTLS_SAN_OTHERNAME_XMPP).
2114
 *
2115
 * If an otherName OID is known, the data will be decoded.  Otherwise
2116
 * the returned data will be DER encoded, and you will have to decode
2117
 * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr Issuer
2118
 * AltName is recognized.
2119
 *
2120
 * Returns: the alternative issuer name type on success, one of the
2121
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2122
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
2123
 *   to hold the value.  In that case @ian_size will be updated with
2124
 *   the required size.  If the certificate does not have an
2125
 *   Alternative name with the specified sequence number then
2126
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2127
 *
2128
 * Since: 2.10.0
2129
 **/
2130
int gnutls_x509_crt_get_issuer_alt_name(gnutls_x509_crt_t cert,
2131
          unsigned int seq, void *ian,
2132
          size_t *ian_size,
2133
          unsigned int *critical)
2134
0
{
2135
0
  return get_alt_name(cert->ian, seq, ian, ian_size, NULL, critical, 0);
2136
0
}
2137
2138
/**
2139
 * gnutls_x509_crt_get_subject_alt_name2:
2140
 * @cert: should contain a #gnutls_x509_crt_t type
2141
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2142
 * @san: is the place where the alternative name will be copied to
2143
 * @san_size: holds the size of ret.
2144
 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
2145
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2146
 *
2147
 * This function will return the alternative names, contained in the
2148
 * given certificate. It is the same as
2149
 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
2150
 * will return the type of the alternative name in @san_type even if
2151
 * the function fails for some reason (i.e.  the buffer provided is
2152
 * not enough).
2153
 *
2154
 * Returns: the alternative subject name type on success, one of the
2155
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2156
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
2157
 *   to hold the value.  In that case @san_size will be updated with
2158
 *   the required size.  If the certificate does not have an
2159
 *   Alternative name with the specified sequence number then
2160
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2161
 **/
2162
int gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,
2163
            unsigned int seq, void *san,
2164
            size_t *san_size,
2165
            unsigned int *san_type,
2166
            unsigned int *critical)
2167
0
{
2168
0
  return get_alt_name(cert->san, seq, san, san_size, san_type, critical,
2169
0
          0);
2170
0
}
2171
2172
/**
2173
 * gnutls_x509_crt_get_issuer_alt_name2:
2174
 * @cert: should contain a #gnutls_x509_crt_t type
2175
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2176
 * @ian: is the place where the alternative name will be copied to
2177
 * @ian_size: holds the size of ret.
2178
 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
2179
 * @critical: will be non-zero if the extension is marked as critical (may be null)
2180
 *
2181
 * This function will return the alternative names, contained in the
2182
 * given certificate. It is the same as
2183
 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
2184
 * will return the type of the alternative name in @ian_type even if
2185
 * the function fails for some reason (i.e.  the buffer provided is
2186
 * not enough).
2187
 *
2188
 * Returns: the alternative issuer name type on success, one of the
2189
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2190
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
2191
 *   to hold the value.  In that case @ian_size will be updated with
2192
 *   the required size.  If the certificate does not have an
2193
 *   Alternative name with the specified sequence number then
2194
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2195
 *
2196
 * Since: 2.10.0
2197
 *
2198
 **/
2199
int gnutls_x509_crt_get_issuer_alt_name2(gnutls_x509_crt_t cert,
2200
           unsigned int seq, void *ian,
2201
           size_t *ian_size,
2202
           unsigned int *ian_type,
2203
           unsigned int *critical)
2204
0
{
2205
0
  return get_alt_name(cert->ian, seq, ian, ian_size, ian_type, critical,
2206
0
          0);
2207
0
}
2208
2209
/**
2210
 * gnutls_x509_crt_get_subject_alt_othername_oid:
2211
 * @cert: should contain a #gnutls_x509_crt_t type
2212
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2213
 * @oid: is the place where the otherName OID will be copied to
2214
 * @oid_size: holds the size of ret.
2215
 *
2216
 * This function will extract the type OID of an otherName Subject
2217
 * Alternative Name, contained in the given certificate, and return
2218
 * the type as an enumerated element.
2219
 *
2220
 * This function is only useful if
2221
 * gnutls_x509_crt_get_subject_alt_name() returned
2222
 * %GNUTLS_SAN_OTHERNAME.
2223
 *
2224
 * If @oid is null then only the size will be filled. The @oid
2225
 * returned will be null terminated, although @oid_size will not
2226
 * account for the trailing null.
2227
 *
2228
 * Returns: the alternative subject name type on success, one of the
2229
 * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
2230
 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
2231
 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
2232
 * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
2233
 * @ian_size is not large enough to hold the value.  In that case
2234
 * @ian_size will be updated with the required size.  If the
2235
 * certificate does not have an Alternative name with the specified
2236
 * sequence number and with the otherName type then
2237
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2238
 **/
2239
int gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,
2240
              unsigned int seq, void *oid,
2241
              size_t *oid_size)
2242
0
{
2243
0
  return get_alt_name(cert->san, seq, oid, oid_size, NULL, NULL, 1);
2244
0
}
2245
2246
/**
2247
 * gnutls_x509_crt_get_issuer_alt_othername_oid:
2248
 * @cert: should contain a #gnutls_x509_crt_t type
2249
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2250
 * @ret: is the place where the otherName OID will be copied to
2251
 * @ret_size: holds the size of ret.
2252
 *
2253
 * This function will extract the type OID of an otherName Subject
2254
 * Alternative Name, contained in the given certificate, and return
2255
 * the type as an enumerated element.
2256
 *
2257
 * If @oid is null then only the size will be filled. The @oid
2258
 * returned will be null terminated, although @oid_size will not
2259
 * account for the trailing null.
2260
 *
2261
 * This function is only useful if
2262
 * gnutls_x509_crt_get_issuer_alt_name() returned
2263
 * %GNUTLS_SAN_OTHERNAME.
2264
 *
2265
 * Returns: the alternative issuer name type on success, one of the
2266
 * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
2267
 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
2268
 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
2269
 * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
2270
 * @ret_size is not large enough to hold the value.  In that case
2271
 * @ret_size will be updated with the required size.  If the
2272
 * certificate does not have an Alternative name with the specified
2273
 * sequence number and with the otherName type then
2274
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2275
 *
2276
 * Since: 2.10.0
2277
 **/
2278
int gnutls_x509_crt_get_issuer_alt_othername_oid(gnutls_x509_crt_t cert,
2279
             unsigned int seq, void *ret,
2280
             size_t *ret_size)
2281
0
{
2282
0
  return get_alt_name(cert->ian, seq, ret, ret_size, NULL, NULL, 1);
2283
0
}
2284
2285
/**
2286
 * gnutls_x509_crt_get_basic_constraints:
2287
 * @cert: should contain a #gnutls_x509_crt_t type
2288
 * @critical: will be non-zero if the extension is marked as critical
2289
 * @ca: pointer to output integer indicating CA status, may be NULL,
2290
 *   value is 1 if the certificate CA flag is set, 0 otherwise.
2291
 * @pathlen: pointer to output integer indicating path length (may be
2292
 *   NULL), non-negative error codes indicate a present pathLenConstraint
2293
 *   field and the actual value, -1 indicate that the field is absent.
2294
 *
2295
 * This function will read the certificate's basic constraints, and
2296
 * return the certificates CA status.  It reads the basicConstraints
2297
 * X.509 extension (2.5.29.19).
2298
 *
2299
 * Returns: If the certificate is a CA a positive value will be
2300
 * returned, or (0) if the certificate does not have CA flag set.  A
2301
 * negative error code may be returned in case of errors.  If the
2302
 * certificate does not contain the basicConstraints extension
2303
 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2304
 **/
2305
int gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
2306
            unsigned int *critical,
2307
            unsigned int *ca, int *pathlen)
2308
0
{
2309
0
  int result;
2310
0
  gnutls_datum_t basicConstraints;
2311
0
  unsigned int tmp_ca;
2312
2313
0
  if (cert == NULL) {
2314
0
    gnutls_assert();
2315
0
    return GNUTLS_E_INVALID_REQUEST;
2316
0
  }
2317
2318
0
  if ((result = _gnutls_x509_crt_get_extension(
2319
0
         cert, "2.5.29.19", 0, &basicConstraints, critical)) < 0) {
2320
0
    return result;
2321
0
  }
2322
2323
0
  if (basicConstraints.size == 0 || basicConstraints.data == NULL) {
2324
0
    gnutls_assert();
2325
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2326
0
  }
2327
2328
0
  result = gnutls_x509_ext_import_basic_constraints(&basicConstraints,
2329
0
                &tmp_ca, pathlen);
2330
0
  if (ca)
2331
0
    *ca = tmp_ca;
2332
2333
0
  _gnutls_free_datum(&basicConstraints);
2334
2335
0
  if (result < 0) {
2336
0
    gnutls_assert();
2337
0
    return result;
2338
0
  }
2339
2340
0
  return tmp_ca;
2341
0
}
2342
2343
/**
2344
 * gnutls_x509_crt_get_ca_status:
2345
 * @cert: should contain a #gnutls_x509_crt_t type
2346
 * @critical: will be non-zero if the extension is marked as critical
2347
 *
2348
 * This function will return certificates CA status, by reading the
2349
 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
2350
 * a CA a positive value will be returned, or (0) if the certificate
2351
 * does not have CA flag set.
2352
 *
2353
 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
2354
 * pathLenConstraint field too.
2355
 *
2356
 * Returns: If the certificate is a CA a positive value will be
2357
 * returned, or (0) if the certificate does not have CA flag set.  A
2358
 * negative error code may be returned in case of errors.  If the
2359
 * certificate does not contain the basicConstraints extension
2360
 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2361
 **/
2362
int gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
2363
          unsigned int *critical)
2364
0
{
2365
0
  int pathlen;
2366
0
  unsigned int ca;
2367
0
  return gnutls_x509_crt_get_basic_constraints(cert, critical, &ca,
2368
0
                 &pathlen);
2369
0
}
2370
2371
/**
2372
 * gnutls_x509_crt_get_key_usage:
2373
 * @cert: should contain a #gnutls_x509_crt_t type
2374
 * @key_usage: where the key usage bits will be stored
2375
 * @critical: will be non-zero if the extension is marked as critical
2376
 *
2377
 * This function will return certificate's key usage, by reading the
2378
 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
2379
 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
2380
 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
2381
 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
2382
 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
2383
 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
2384
 *
2385
 * Returns: zero on success, or a negative error code in case of
2386
 *   parsing error.  If the certificate does not contain the keyUsage
2387
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
2388
 *   returned.
2389
 **/
2390
int gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
2391
          unsigned int *key_usage,
2392
          unsigned int *critical)
2393
0
{
2394
0
  int result;
2395
0
  gnutls_datum_t keyUsage;
2396
2397
0
  if (cert == NULL) {
2398
0
    gnutls_assert();
2399
0
    return GNUTLS_E_INVALID_REQUEST;
2400
0
  }
2401
2402
0
  if ((result = _gnutls_x509_crt_get_extension(
2403
0
         cert, "2.5.29.15", 0, &keyUsage, critical)) < 0) {
2404
0
    return result;
2405
0
  }
2406
2407
0
  if (keyUsage.size == 0 || keyUsage.data == NULL) {
2408
0
    gnutls_assert();
2409
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2410
0
  }
2411
2412
0
  result = gnutls_x509_ext_import_key_usage(&keyUsage, key_usage);
2413
0
  _gnutls_free_datum(&keyUsage);
2414
2415
0
  if (result < 0) {
2416
0
    gnutls_assert();
2417
0
    return result;
2418
0
  }
2419
2420
0
  return 0;
2421
0
}
2422
2423
/**
2424
 * gnutls_x509_crt_get_inhibit_anypolicy:
2425
 * @cert: should contain a #gnutls_x509_crt_t type
2426
 * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable.
2427
 * @critical: will be non-zero if the extension is marked as critical
2428
 *
2429
 * This function will return certificate's value of the SkipCerts, i.e.,
2430
 * the Inhibit anyPolicy X.509 extension (2.5.29.54).
2431
 *
2432
 * The returned value is the number of additional certificates that
2433
 * may appear in the path before the anyPolicy is no longer acceptable.
2434
2435
 * Returns: zero on success, or a negative error code in case of
2436
 *   parsing error.  If the certificate does not contain the Inhibit anyPolicy
2437
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
2438
 *   returned.
2439
 *
2440
 * Since: 3.6.0
2441
 **/
2442
int gnutls_x509_crt_get_inhibit_anypolicy(gnutls_x509_crt_t cert,
2443
            unsigned int *skipcerts,
2444
            unsigned int *critical)
2445
0
{
2446
0
  int ret;
2447
0
  gnutls_datum_t ext;
2448
2449
0
  if (cert == NULL) {
2450
0
    gnutls_assert();
2451
0
    return GNUTLS_E_INVALID_REQUEST;
2452
0
  }
2453
2454
0
  if ((ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.54", 0, &ext,
2455
0
              critical)) < 0) {
2456
0
    return ret;
2457
0
  }
2458
2459
0
  if (ext.size == 0 || ext.data == NULL) {
2460
0
    gnutls_assert();
2461
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2462
0
  }
2463
2464
0
  ret = gnutls_x509_ext_import_key_usage(&ext, skipcerts);
2465
0
  _gnutls_free_datum(&ext);
2466
2467
0
  if (ret < 0) {
2468
0
    gnutls_assert();
2469
0
    return ret;
2470
0
  }
2471
2472
0
  return 0;
2473
0
}
2474
2475
/**
2476
 * gnutls_x509_crt_get_proxy:
2477
 * @cert: should contain a #gnutls_x509_crt_t type
2478
 * @critical: will be non-zero if the extension is marked as critical
2479
 * @pathlen: pointer to output integer indicating path length (may be
2480
 *   NULL), non-negative error codes indicate a present pCPathLenConstraint
2481
 *   field and the actual value, -1 indicate that the field is absent.
2482
 * @policyLanguage: output variable with OID of policy language
2483
 * @policy: output variable with policy data
2484
 * @sizeof_policy: output variable size of policy data
2485
 *
2486
 * This function will get information from a proxy certificate.  It
2487
 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
2488
 *
2489
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2490
 *   otherwise a negative error code is returned.
2491
 **/
2492
int gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert, unsigned int *critical,
2493
            int *pathlen, char **policyLanguage,
2494
            char **policy, size_t *sizeof_policy)
2495
0
{
2496
0
  int result;
2497
0
  gnutls_datum_t proxyCertInfo;
2498
2499
0
  if (cert == NULL) {
2500
0
    gnutls_assert();
2501
0
    return GNUTLS_E_INVALID_REQUEST;
2502
0
  }
2503
2504
0
  if ((result = _gnutls_x509_crt_get_extension(cert, "1.3.6.1.5.5.7.1.14",
2505
0
                 0, &proxyCertInfo,
2506
0
                 critical)) < 0) {
2507
0
    return result;
2508
0
  }
2509
2510
0
  if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL) {
2511
0
    gnutls_assert();
2512
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2513
0
  }
2514
2515
0
  result = gnutls_x509_ext_import_proxy(
2516
0
    &proxyCertInfo, pathlen, policyLanguage, policy, sizeof_policy);
2517
0
  _gnutls_free_datum(&proxyCertInfo);
2518
0
  if (result < 0) {
2519
0
    gnutls_assert();
2520
0
    return result;
2521
0
  }
2522
2523
0
  return 0;
2524
0
}
2525
2526
/**
2527
 * gnutls_x509_policy_release:
2528
 * @policy: a certificate policy
2529
 *
2530
 * This function will deinitialize all memory associated with the provided
2531
 * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
2532
 *
2533
 * Since: 3.1.5
2534
 **/
2535
void gnutls_x509_policy_release(struct gnutls_x509_policy_st *policy)
2536
0
{
2537
0
  unsigned i;
2538
2539
0
  gnutls_free(policy->oid);
2540
0
  for (i = 0; i < policy->qualifiers; i++)
2541
0
    gnutls_free(policy->qualifier[i].data);
2542
0
}
2543
2544
/**
2545
 * gnutls_x509_crt_get_policy:
2546
 * @crt: should contain a #gnutls_x509_crt_t type
2547
 * @indx: This specifies which policy to return. Use (0) to get the first one.
2548
 * @policy: A pointer to a policy structure.
2549
 * @critical: will be non-zero if the extension is marked as critical
2550
 *
2551
 * This function will extract the certificate policy (extension 2.5.29.32)
2552
 * specified by the given index.
2553
 *
2554
 * The policy returned by this function must be deinitialized by using
2555
 * gnutls_x509_policy_release().
2556
 *
2557
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2558
 * if the extension is not present, otherwise a negative error value.
2559
 *
2560
 * Since: 3.1.5
2561
 **/
2562
int gnutls_x509_crt_get_policy(gnutls_x509_crt_t crt, unsigned indx,
2563
             struct gnutls_x509_policy_st *policy,
2564
             unsigned int *critical)
2565
0
{
2566
0
  gnutls_datum_t tmpd = { NULL, 0 };
2567
0
  int ret;
2568
0
  gnutls_x509_policies_t policies = NULL;
2569
2570
0
  if (crt == NULL) {
2571
0
    gnutls_assert();
2572
0
    return GNUTLS_E_INVALID_REQUEST;
2573
0
  }
2574
2575
0
  memset(policy, 0, sizeof(*policy));
2576
2577
0
  ret = gnutls_x509_policies_init(&policies);
2578
0
  if (ret < 0)
2579
0
    return gnutls_assert_val(ret);
2580
2581
0
  if ((ret = _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &tmpd,
2582
0
              critical)) < 0) {
2583
0
    goto cleanup;
2584
0
  }
2585
2586
0
  if (tmpd.size == 0 || tmpd.data == NULL) {
2587
0
    gnutls_assert();
2588
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2589
0
    goto cleanup;
2590
0
  }
2591
2592
0
  ret = gnutls_x509_ext_import_policies(&tmpd, policies, 0);
2593
0
  if (ret < 0) {
2594
0
    gnutls_assert();
2595
0
    goto cleanup;
2596
0
  }
2597
2598
0
  ret = gnutls_x509_policies_get(policies, indx, policy);
2599
0
  if (ret < 0) {
2600
0
    gnutls_assert();
2601
0
    goto cleanup;
2602
0
  }
2603
2604
0
  _gnutls_x509_policies_erase(policies, indx);
2605
2606
0
  ret = 0;
2607
2608
0
cleanup:
2609
0
  if (policies != NULL)
2610
0
    gnutls_x509_policies_deinit(policies);
2611
0
  _gnutls_free_datum(&tmpd);
2612
2613
0
  return ret;
2614
0
}
2615
2616
/**
2617
 * gnutls_x509_crt_get_extension_by_oid:
2618
 * @cert: should contain a #gnutls_x509_crt_t type
2619
 * @oid: holds an Object Identified in null terminated string
2620
 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2621
 * @buf: a pointer to a structure to hold the name (may be null)
2622
 * @buf_size: initially holds the size of @buf
2623
 * @critical: will be non-zero if the extension is marked as critical
2624
 *
2625
 * This function will return the extension specified by the OID in the
2626
 * certificate.  The extensions will be returned as binary data DER
2627
 * encoded, in the provided buffer.
2628
 *
2629
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2630
 *   otherwise a negative error code is returned. If the certificate does not
2631
 *   contain the specified extension
2632
 *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2633
 **/
2634
int gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,
2635
           const char *oid, unsigned indx,
2636
           void *buf, size_t *buf_size,
2637
           unsigned int *critical)
2638
0
{
2639
0
  int result;
2640
0
  gnutls_datum_t output;
2641
2642
0
  if (cert == NULL) {
2643
0
    gnutls_assert();
2644
0
    return GNUTLS_E_INVALID_REQUEST;
2645
0
  }
2646
2647
0
  if ((result = _gnutls_x509_crt_get_extension(cert, oid, indx, &output,
2648
0
                 critical)) < 0) {
2649
0
    gnutls_assert();
2650
0
    return result;
2651
0
  }
2652
2653
0
  if (output.size == 0 || output.data == NULL) {
2654
0
    gnutls_assert();
2655
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2656
0
  }
2657
2658
0
  if (output.size > (unsigned int)*buf_size) {
2659
0
    *buf_size = output.size;
2660
0
    _gnutls_free_datum(&output);
2661
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
2662
0
  }
2663
2664
0
  *buf_size = output.size;
2665
2666
0
  if (buf)
2667
0
    memcpy(buf, output.data, output.size);
2668
2669
0
  _gnutls_free_datum(&output);
2670
2671
0
  return 0;
2672
0
}
2673
2674
/**
2675
 * gnutls_x509_crt_get_extension_by_oid2:
2676
 * @cert: should contain a #gnutls_x509_crt_t type
2677
 * @oid: holds an Object Identified in null terminated string
2678
 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2679
 * @output: will hold the allocated extension data
2680
 * @critical: will be non-zero if the extension is marked as critical
2681
 *
2682
 * This function will return the extension specified by the OID in the
2683
 * certificate.  The extensions will be returned as binary data DER
2684
 * encoded, in the provided buffer.
2685
 *
2686
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2687
 *   otherwise a negative error code is returned. If the certificate does not
2688
 *   contain the specified extension
2689
 *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2690
 *
2691
 * Since: 3.3.8
2692
 **/
2693
int gnutls_x509_crt_get_extension_by_oid2(gnutls_x509_crt_t cert,
2694
            const char *oid, unsigned indx,
2695
            gnutls_datum_t *output,
2696
            unsigned int *critical)
2697
0
{
2698
0
  int ret;
2699
2700
0
  if (cert == NULL) {
2701
0
    gnutls_assert();
2702
0
    return GNUTLS_E_INVALID_REQUEST;
2703
0
  }
2704
2705
0
  if ((ret = _gnutls_x509_crt_get_extension(cert, oid, indx, output,
2706
0
              critical)) < 0) {
2707
0
    gnutls_assert();
2708
0
    return ret;
2709
0
  }
2710
2711
0
  if (output->size == 0 || output->data == NULL) {
2712
0
    gnutls_assert();
2713
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2714
0
  }
2715
2716
0
  return 0;
2717
0
}
2718
2719
/**
2720
 * gnutls_x509_crt_get_extension_oid:
2721
 * @cert: should contain a #gnutls_x509_crt_t type
2722
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2723
 * @oid: a pointer to a structure to hold the OID (may be null)
2724
 * @oid_size: initially holds the size of @oid
2725
 *
2726
 * This function will return the requested extension OID in the certificate.
2727
 * The extension OID will be stored as a string in the provided buffer.
2728
 *
2729
 * The @oid returned will be null terminated, although @oid_size will not
2730
 * account for the trailing null.
2731
 *
2732
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2733
 *   otherwise a negative error code is returned.  If you have reached the
2734
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2735
 *   will be returned.
2736
 **/
2737
int gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert, unsigned indx,
2738
              void *oid, size_t *oid_size)
2739
0
{
2740
0
  int result;
2741
2742
0
  if (cert == NULL) {
2743
0
    gnutls_assert();
2744
0
    return GNUTLS_E_INVALID_REQUEST;
2745
0
  }
2746
2747
0
  result = _gnutls_x509_crt_get_extension_oid(cert, indx, oid, oid_size);
2748
0
  if (result < 0) {
2749
0
    return result;
2750
0
  }
2751
2752
0
  return 0;
2753
0
}
2754
2755
/**
2756
 * gnutls_x509_crt_get_extension_info:
2757
 * @cert: should contain a #gnutls_x509_crt_t type
2758
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2759
 * @oid: a pointer to a structure to hold the OID
2760
 * @oid_size: initially holds the maximum size of @oid, on return
2761
 *   holds actual size of @oid.
2762
 * @critical: output variable with critical flag, may be NULL.
2763
 *
2764
 * This function will return the requested extension OID in the
2765
 * certificate, and the critical flag for it.  The extension OID will
2766
 * be stored as a string in the provided buffer.  Use
2767
 * gnutls_x509_crt_get_extension() to extract the data.
2768
 *
2769
 * If the buffer provided is not long enough to hold the output, then
2770
 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2771
 * returned. The @oid returned will be null terminated, although
2772
 * @oid_size will not account for the trailing null (the latter is not
2773
 * true for GnuTLS prior to 3.6.0).
2774
 *
2775
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2776
 *   otherwise a negative error code is returned.  If you have reached the
2777
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2778
 *   will be returned.
2779
 **/
2780
int gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert, unsigned indx,
2781
               void *oid, size_t *oid_size,
2782
               unsigned int *critical)
2783
0
{
2784
0
  int result;
2785
0
  char str_critical[10];
2786
0
  char name[MAX_NAME_SIZE];
2787
0
  int len;
2788
2789
0
  if (!cert) {
2790
0
    gnutls_assert();
2791
0
    return GNUTLS_E_INVALID_REQUEST;
2792
0
  }
2793
2794
0
  snprintf(name, sizeof(name), "tbsCertificate.extensions.?%u.extnID",
2795
0
     indx + 1);
2796
2797
0
  len = *oid_size;
2798
0
  result = asn1_read_value(cert->cert, name, oid, &len);
2799
0
  *oid_size = len;
2800
2801
0
  if (result == ASN1_ELEMENT_NOT_FOUND)
2802
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2803
0
  else if (result != ASN1_SUCCESS) {
2804
0
    gnutls_assert();
2805
0
    return _gnutls_asn2err(result);
2806
0
  }
2807
2808
  /* remove any trailing null */
2809
0
  if (oid && len > 0 && ((uint8_t *)oid)[len - 1] == 0)
2810
0
    (*oid_size)--;
2811
2812
0
  if (critical) {
2813
0
    snprintf(name, sizeof(name),
2814
0
       "tbsCertificate.extensions.?%u.critical", indx + 1);
2815
0
    len = sizeof(str_critical);
2816
0
    result = asn1_read_value(cert->cert, name, str_critical, &len);
2817
0
    if (result != ASN1_SUCCESS) {
2818
0
      gnutls_assert();
2819
0
      return _gnutls_asn2err(result);
2820
0
    }
2821
2822
0
    if (str_critical[0] == 'T')
2823
0
      *critical = 1;
2824
0
    else
2825
0
      *critical = 0;
2826
0
  }
2827
2828
0
  return 0;
2829
0
}
2830
2831
/**
2832
 * gnutls_x509_crt_get_extension_data:
2833
 * @cert: should contain a #gnutls_x509_crt_t type
2834
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2835
 * @data: a pointer to a structure to hold the data (may be null)
2836
 * @sizeof_data: initially holds the size of @data
2837
 *
2838
 * This function will return the requested extension data in the
2839
 * certificate.  The extension data will be stored in the
2840
 * provided buffer.
2841
 *
2842
 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2843
 * critical flag.  Use gnutls_x509_crt_get_extension_by_oid() instead,
2844
 * if you want to get data indexed by the extension OID rather than
2845
 * sequence.
2846
 *
2847
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2848
 *   otherwise a negative error code is returned.  If you have reached the
2849
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2850
 *   will be returned.
2851
 **/
2852
int gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert, unsigned indx,
2853
               void *data, size_t *sizeof_data)
2854
0
{
2855
0
  int result, len;
2856
0
  char name[MAX_NAME_SIZE];
2857
2858
0
  if (!cert) {
2859
0
    gnutls_assert();
2860
0
    return GNUTLS_E_INVALID_REQUEST;
2861
0
  }
2862
2863
0
  snprintf(name, sizeof(name), "tbsCertificate.extensions.?%u.extnValue",
2864
0
     indx + 1);
2865
2866
0
  len = *sizeof_data;
2867
0
  result = asn1_read_value(cert->cert, name, data, &len);
2868
0
  *sizeof_data = len;
2869
2870
0
  if (result == ASN1_ELEMENT_NOT_FOUND) {
2871
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2872
0
  } else if (result == ASN1_MEM_ERROR && data == NULL) {
2873
    /* normally we should return GNUTLS_E_SHORT_MEMORY_BUFFER,
2874
     * but we haven't done that for long time, so use
2875
     * backwards compatible behavior */
2876
0
    return 0;
2877
0
  } else if (result != ASN1_SUCCESS) {
2878
0
    gnutls_assert();
2879
0
    return _gnutls_asn2err(result);
2880
0
  }
2881
2882
0
  return 0;
2883
0
}
2884
2885
/**
2886
 * gnutls_x509_crt_get_raw_issuer_dn:
2887
 * @cert: should contain a #gnutls_x509_crt_t type
2888
 * @dn: will hold the starting point of the DN
2889
 *
2890
 * This function will return a pointer to the DER encoded DN structure
2891
 * and the length. This points to allocated data that must be free'd using gnutls_free().
2892
 *
2893
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2894
 *   negative error value.or a negative error code on error.
2895
 *
2896
 **/
2897
int gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,
2898
              gnutls_datum_t *dn)
2899
0
{
2900
0
  if (cert->raw_issuer_dn.size > 0 && cert->modified == 0) {
2901
0
    return _gnutls_set_datum(dn, cert->raw_issuer_dn.data,
2902
0
           cert->raw_issuer_dn.size);
2903
0
  } else {
2904
0
    return _gnutls_x509_get_raw_field(
2905
0
      cert->cert, "tbsCertificate.issuer.rdnSequence", dn);
2906
0
  }
2907
0
}
2908
2909
/**
2910
 * gnutls_x509_crt_get_raw_dn:
2911
 * @cert: should contain a #gnutls_x509_crt_t type
2912
 * @dn: will hold the starting point of the DN
2913
 *
2914
 * This function will return a pointer to the DER encoded DN structure and
2915
 * the length. This points to allocated data that must be free'd using gnutls_free().
2916
 *
2917
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2918
 *   negative error value. or a negative error code on error.
2919
 *
2920
 **/
2921
int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert, gnutls_datum_t *dn)
2922
0
{
2923
0
  if (cert->raw_dn.size > 0 && cert->modified == 0) {
2924
0
    return _gnutls_set_datum(dn, cert->raw_dn.data,
2925
0
           cert->raw_dn.size);
2926
0
  } else {
2927
0
    return _gnutls_x509_get_raw_field(
2928
0
      cert->cert, "tbsCertificate.subject.rdnSequence", dn);
2929
0
  }
2930
0
}
2931
2932
static int get_dn(gnutls_x509_crt_t cert, const char *whom,
2933
      gnutls_x509_dn_t *dn, unsigned subject)
2934
0
{
2935
0
  gnutls_x509_dn_st *store;
2936
2937
0
  if (subject)
2938
0
    store = &cert->dn;
2939
0
  else
2940
0
    store = &cert->idn;
2941
2942
0
  store->asn = asn1_find_node(cert->cert, whom);
2943
0
  if (!store->asn)
2944
0
    return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2945
2946
0
  *dn = store;
2947
2948
0
  return 0;
2949
0
}
2950
2951
/**
2952
 * gnutls_x509_crt_get_subject:
2953
 * @cert: should contain a #gnutls_x509_crt_t type
2954
 * @dn: output variable with pointer to uint8_t DN.
2955
 *
2956
 * Return the Certificate's Subject DN as a %gnutls_x509_dn_t data type,
2957
 * that can be decoded using gnutls_x509_dn_get_rdn_ava().
2958
 *
2959
 * Note that @dn should be treated as constant. Because it points
2960
 * into the @cert object, you should not use @dn after @cert is
2961
 * deallocated.
2962
 *
2963
 * Returns: Returns 0 on success, or an error code.
2964
 **/
2965
int gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert, gnutls_x509_dn_t *dn)
2966
0
{
2967
0
  return get_dn(cert, "tbsCertificate.subject.rdnSequence", dn, 1);
2968
0
}
2969
2970
/**
2971
 * gnutls_x509_crt_get_issuer:
2972
 * @cert: should contain a #gnutls_x509_crt_t type
2973
 * @dn: output variable with pointer to uint8_t DN
2974
 *
2975
 * Return the Certificate's Issuer DN as a %gnutls_x509_dn_t data type,
2976
 * that can be decoded using gnutls_x509_dn_get_rdn_ava().
2977
 *
2978
 * Note that @dn should be treated as constant. Because it points
2979
 * into the @cert object, you should not use @dn after @cert is
2980
 * deallocated.
2981
 *
2982
 * Returns: Returns 0 on success, or an error code.
2983
 **/
2984
int gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert, gnutls_x509_dn_t *dn)
2985
0
{
2986
0
  return get_dn(cert, "tbsCertificate.issuer.rdnSequence", dn, 0);
2987
0
}
2988
2989
/**
2990
 * gnutls_x509_crt_get_fingerprint:
2991
 * @cert: should contain a #gnutls_x509_crt_t type
2992
 * @algo: is a digest algorithm
2993
 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2994
 * @buf_size: initially holds the size of @buf
2995
 *
2996
 * This function will calculate and copy the certificate's fingerprint
2997
 * in the provided buffer. The fingerprint is a hash of the DER-encoded
2998
 * data of the certificate.
2999
 *
3000
 * If the buffer is null then only the size will be filled.
3001
 *
3002
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3003
 *   not long enough, and in that case the *buf_size will be updated
3004
 *   with the required size.  On success 0 is returned.
3005
 **/
3006
int gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,
3007
            gnutls_digest_algorithm_t algo, void *buf,
3008
            size_t *buf_size)
3009
0
{
3010
0
  uint8_t *cert_buf;
3011
0
  int cert_buf_size;
3012
0
  int result;
3013
0
  gnutls_datum_t tmp;
3014
3015
0
  if (buf_size == 0 || cert == NULL) {
3016
0
    return GNUTLS_E_INVALID_REQUEST;
3017
0
  }
3018
3019
0
  cert_buf_size = 0;
3020
0
  result = asn1_der_coding(cert->cert, "", NULL, &cert_buf_size, NULL);
3021
0
  if (result != ASN1_MEM_ERROR) {
3022
0
    gnutls_assert();
3023
0
    return _gnutls_asn2err(result);
3024
0
  }
3025
3026
0
  cert_buf = gnutls_malloc(cert_buf_size);
3027
0
  if (cert_buf == NULL) {
3028
0
    gnutls_assert();
3029
0
    return GNUTLS_E_MEMORY_ERROR;
3030
0
  }
3031
3032
0
  result =
3033
0
    asn1_der_coding(cert->cert, "", cert_buf, &cert_buf_size, NULL);
3034
3035
0
  if (result != ASN1_SUCCESS) {
3036
0
    gnutls_assert();
3037
0
    gnutls_free(cert_buf);
3038
0
    return _gnutls_asn2err(result);
3039
0
  }
3040
3041
0
  tmp.data = cert_buf;
3042
0
  tmp.size = cert_buf_size;
3043
3044
0
  result = gnutls_fingerprint(algo, &tmp, buf, buf_size);
3045
0
  gnutls_free(cert_buf);
3046
3047
0
  return result;
3048
0
}
3049
3050
/**
3051
 * gnutls_x509_crt_export:
3052
 * @cert: Holds the certificate
3053
 * @format: the format of output params. One of PEM or DER.
3054
 * @output_data: will contain a certificate PEM or DER encoded
3055
 * @output_data_size: holds the size of output_data (and will be
3056
 *   replaced by the actual size of parameters)
3057
 *
3058
 * This function will export the certificate to DER or PEM format.
3059
 *
3060
 * If the buffer provided is not long enough to hold the output, then
3061
 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
3062
 * be returned.
3063
 *
3064
 * If the structure is PEM encoded, it will have a header
3065
 * of "BEGIN CERTIFICATE".
3066
 *
3067
 * Returns: In case of failure a negative error code will be
3068
 *   returned, and 0 on success.
3069
 **/
3070
int gnutls_x509_crt_export(gnutls_x509_crt_t cert, gnutls_x509_crt_fmt_t format,
3071
         void *output_data, size_t *output_data_size)
3072
0
{
3073
0
  gnutls_datum_t out;
3074
0
  int ret;
3075
3076
0
  ret = gnutls_x509_crt_export2(cert, format, &out);
3077
0
  if (ret < 0)
3078
0
    return gnutls_assert_val(ret);
3079
3080
0
  if (format == GNUTLS_X509_FMT_PEM)
3081
0
    ret = _gnutls_copy_string(&out, (uint8_t *)output_data,
3082
0
            output_data_size);
3083
0
  else
3084
0
    ret = _gnutls_copy_data(&out, (uint8_t *)output_data,
3085
0
          output_data_size);
3086
0
  if (ret < 0) {
3087
0
    gnutls_assert();
3088
0
    goto cleanup;
3089
0
  }
3090
3091
0
  ret = 0;
3092
0
cleanup:
3093
0
  gnutls_free(out.data);
3094
0
  return ret;
3095
0
}
3096
3097
/**
3098
 * gnutls_x509_crt_export2:
3099
 * @cert: Holds the certificate
3100
 * @format: the format of output params. One of PEM or DER.
3101
 * @out: will contain a certificate PEM or DER encoded
3102
 *
3103
 * This function will export the certificate to DER or PEM format.
3104
 * The output buffer is allocated using gnutls_malloc().
3105
 *
3106
 * If the structure is PEM encoded, it will have a header
3107
 * of "BEGIN CERTIFICATE".
3108
 *
3109
 * Returns: In case of failure a negative error code will be
3110
 *   returned, and 0 on success.
3111
 *
3112
 * Since: 3.1.3
3113
 **/
3114
int gnutls_x509_crt_export2(gnutls_x509_crt_t cert,
3115
          gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
3116
0
{
3117
0
  if (cert == NULL) {
3118
0
    gnutls_assert();
3119
0
    return GNUTLS_E_INVALID_REQUEST;
3120
0
  }
3121
3122
0
  if (!cert->modified && cert->der.size) {
3123
0
    if (format == GNUTLS_X509_FMT_DER)
3124
0
      return _gnutls_set_datum(out, cert->der.data,
3125
0
             cert->der.size);
3126
0
    else {
3127
0
      int ret = _gnutls_fbase64_encode(PEM_X509_CERT2,
3128
0
               cert->der.data,
3129
0
               cert->der.size, out);
3130
0
      if (ret < 0)
3131
0
        return ret;
3132
0
      return 0;
3133
0
    }
3134
0
  }
3135
3136
0
  return _gnutls_x509_export_int2(cert->cert, format, PEM_X509_CERT2,
3137
0
          out);
3138
0
}
3139
3140
int _gnutls_get_key_id(gnutls_pk_params_st *params, unsigned char *output_data,
3141
           size_t *output_data_size, unsigned flags)
3142
0
{
3143
0
  int ret = 0;
3144
0
  gnutls_datum_t der = { NULL, 0 };
3145
0
  gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
3146
0
  unsigned int digest_len;
3147
3148
0
  if ((flags & GNUTLS_KEYID_USE_SHA512) ||
3149
0
      (flags & GNUTLS_KEYID_USE_BEST_KNOWN))
3150
0
    hash = GNUTLS_DIG_SHA512;
3151
0
  else if (flags & GNUTLS_KEYID_USE_SHA256)
3152
0
    hash = GNUTLS_DIG_SHA256;
3153
3154
0
  digest_len = _gnutls_hash_get_algo_len(hash_to_entry(hash));
3155
3156
0
  if (output_data == NULL || *output_data_size < digest_len) {
3157
0
    gnutls_assert();
3158
0
    *output_data_size = digest_len;
3159
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
3160
0
  }
3161
3162
0
  ret = _gnutls_x509_encode_PKI_params(&der, params);
3163
0
  if (ret < 0)
3164
0
    return gnutls_assert_val(ret);
3165
3166
0
  ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
3167
0
  if (ret < 0) {
3168
0
    gnutls_assert();
3169
0
    goto cleanup;
3170
0
  }
3171
0
  *output_data_size = digest_len;
3172
3173
0
  ret = 0;
3174
3175
0
cleanup:
3176
3177
0
  _gnutls_free_datum(&der);
3178
0
  return ret;
3179
0
}
3180
3181
/**
3182
 * gnutls_x509_crt_get_key_id:
3183
 * @crt: Holds the certificate
3184
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
3185
 * @output_data: will contain the key ID
3186
 * @output_data_size: holds the size of output_data (and will be
3187
 *   replaced by the actual size of parameters)
3188
 *
3189
 * This function will return a unique ID that depends on the public
3190
 * key parameters. This ID can be used in checking whether a
3191
 * certificate corresponds to the given private key.
3192
 *
3193
 * If the buffer provided is not long enough to hold the output, then
3194
 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
3195
 * be returned.  The output will normally be a SHA-1 hash output,
3196
 * which is 20 bytes.
3197
 *
3198
 * Returns: In case of failure a negative error code will be
3199
 *   returned, and 0 on success.
3200
 **/
3201
int gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt, unsigned int flags,
3202
             unsigned char *output_data,
3203
             size_t *output_data_size)
3204
0
{
3205
0
  int ret = 0;
3206
0
  gnutls_pk_params_st params;
3207
3208
0
  if (crt == NULL) {
3209
0
    gnutls_assert();
3210
0
    return GNUTLS_E_INVALID_REQUEST;
3211
0
  }
3212
3213
  /* initializes params */
3214
0
  ret = _gnutls_x509_crt_get_mpis(crt, &params);
3215
0
  if (ret < 0) {
3216
0
    gnutls_assert();
3217
0
    return ret;
3218
0
  }
3219
3220
0
  ret = _gnutls_get_key_id(&params, output_data, output_data_size, flags);
3221
3222
0
  gnutls_pk_params_release(&params);
3223
3224
0
  return ret;
3225
0
}
3226
3227
static int crl_issuer_matches(gnutls_x509_crl_t crl, gnutls_x509_crt_t cert)
3228
0
{
3229
0
  if (_gnutls_x509_compare_raw_dn(&crl->raw_issuer_dn,
3230
0
          &cert->raw_issuer_dn) != 0)
3231
0
    return 1;
3232
0
  else
3233
0
    return 0;
3234
0
}
3235
3236
/* This is exactly as gnutls_x509_crt_check_revocation() except that
3237
 * it calls func.
3238
 */
3239
int _gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3240
              const gnutls_x509_crl_t *crl_list,
3241
              int crl_list_length,
3242
              gnutls_verify_output_function func)
3243
0
{
3244
0
  uint8_t serial[128];
3245
0
  uint8_t cert_serial[128];
3246
0
  size_t serial_size, cert_serial_size;
3247
0
  int ret, j;
3248
0
  gnutls_x509_crl_iter_t iter = NULL;
3249
3250
0
  if (cert == NULL) {
3251
0
    gnutls_assert();
3252
0
    return GNUTLS_E_INVALID_REQUEST;
3253
0
  }
3254
3255
0
  for (j = 0; j < crl_list_length; j++) { /* do for all the crls */
3256
3257
    /* Step 1. check if issuer's DN match
3258
     */
3259
0
    ret = crl_issuer_matches(crl_list[j], cert);
3260
0
    if (ret == 0) {
3261
      /* issuers do not match so don't even
3262
       * bother checking.
3263
       */
3264
0
      gnutls_assert();
3265
0
      continue;
3266
0
    }
3267
3268
    /* Step 2. Read the certificate's serial number
3269
     */
3270
0
    cert_serial_size = sizeof(cert_serial);
3271
0
    ret = gnutls_x509_crt_get_serial(cert, cert_serial,
3272
0
             &cert_serial_size);
3273
0
    if (ret < 0) {
3274
0
      gnutls_assert();
3275
0
      return ret;
3276
0
    }
3277
3278
    /* Step 3. cycle through the CRL serials and compare with
3279
     *   certificate serial we have.
3280
     */
3281
3282
0
    iter = NULL;
3283
0
    do {
3284
0
      serial_size = sizeof(serial);
3285
0
      ret = gnutls_x509_crl_iter_crt_serial(
3286
0
        crl_list[j], &iter, serial, &serial_size, NULL);
3287
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
3288
0
        break;
3289
0
      } else if (ret < 0) {
3290
0
        gnutls_assert();
3291
0
        goto fail;
3292
0
      }
3293
3294
0
      if (serial_size == cert_serial_size) {
3295
0
        if (memcmp(serial, cert_serial, serial_size) ==
3296
0
            0) {
3297
          /* serials match */
3298
0
          if (func)
3299
0
            func(cert, NULL, crl_list[j],
3300
0
                 GNUTLS_CERT_REVOKED |
3301
0
                   GNUTLS_CERT_INVALID);
3302
0
          ret = 1; /* revoked! */
3303
0
          goto fail;
3304
0
        }
3305
0
      }
3306
0
    } while (1);
3307
3308
0
    gnutls_x509_crl_iter_deinit(iter);
3309
0
    iter = NULL;
3310
3311
0
    if (func)
3312
0
      func(cert, NULL, crl_list[j], 0);
3313
0
  }
3314
0
  return 0; /* not revoked. */
3315
3316
0
fail:
3317
0
  gnutls_x509_crl_iter_deinit(iter);
3318
0
  return ret;
3319
0
}
3320
3321
/**
3322
 * gnutls_x509_crt_check_revocation:
3323
 * @cert: should contain a #gnutls_x509_crt_t type
3324
 * @crl_list: should contain a list of gnutls_x509_crl_t types
3325
 * @crl_list_length: the length of the crl_list
3326
 *
3327
 * This function will check if the given certificate is
3328
 * revoked.  It is assumed that the CRLs have been verified before.
3329
 *
3330
 * Returns: 0 if the certificate is NOT revoked, and 1 if it is.  A
3331
 * negative error code is returned on error.
3332
 **/
3333
int gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3334
             const gnutls_x509_crl_t *crl_list,
3335
             unsigned crl_list_length)
3336
0
{
3337
0
  return _gnutls_x509_crt_check_revocation(cert, crl_list,
3338
0
             crl_list_length, NULL);
3339
0
}
3340
3341
/**
3342
 * gnutls_x509_crt_check_key_purpose:
3343
 * @cert: should contain a #gnutls_x509_crt_t type
3344
 * @purpose: a key purpose OID (e.g., %GNUTLS_KP_CODE_SIGNING)
3345
 * @flags: zero or %GNUTLS_KP_FLAG_DISALLOW_ANY
3346
 *
3347
 * This function will check whether the given certificate matches
3348
 * the provided key purpose. If @flags contains %GNUTLS_KP_FLAG_ALLOW_ANY then
3349
 * it a certificate marked for any purpose will not match.
3350
 *
3351
 * Returns: zero if the key purpose doesn't match, and non-zero otherwise.
3352
 *
3353
 * Since: 3.5.6
3354
 **/
3355
unsigned gnutls_x509_crt_check_key_purpose(gnutls_x509_crt_t cert,
3356
             const char *purpose, unsigned flags)
3357
0
{
3358
0
  return _gnutls_check_key_purpose(
3359
0
    cert, purpose, (flags & GNUTLS_KP_FLAG_DISALLOW_ANY) ? 1 : 0);
3360
0
}
3361
3362
/**
3363
 * gnutls_x509_crt_get_preferred_hash_algorithm:
3364
 * @crt: Holds the certificate
3365
 * @hash: The result of the call with the hash algorithm used for signature
3366
 * @mand: If non-zero it means that the algorithm MUST use this hash. May be %NULL.
3367
 *
3368
 * This function will read the certificate and return the appropriate digest
3369
 * algorithm to use for signing with this certificate. Some certificates (i.e.
3370
 * DSA might not be able to sign without the preferred algorithm).
3371
 *
3372
 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
3373
 *
3374
 * Returns: the 0 if the hash algorithm is found. A negative error code is
3375
 * returned on error.
3376
 *
3377
 * Since: 2.12.0
3378
 **/
3379
int gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,
3380
             gnutls_digest_algorithm_t *hash,
3381
             unsigned int *mand)
3382
0
{
3383
0
  int ret;
3384
0
  gnutls_pubkey_t pubkey;
3385
3386
0
  if (crt == NULL) {
3387
0
    gnutls_assert();
3388
0
    return GNUTLS_E_INVALID_REQUEST;
3389
0
  }
3390
3391
0
  ret = gnutls_pubkey_init(&pubkey);
3392
0
  if (ret < 0)
3393
0
    return gnutls_assert_val(ret);
3394
3395
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3396
0
  if (ret < 0) {
3397
0
    gnutls_assert();
3398
0
    goto cleanup;
3399
0
  }
3400
3401
0
  ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, hash, mand);
3402
0
  if (ret < 0) {
3403
0
    gnutls_assert();
3404
0
    goto cleanup;
3405
0
  }
3406
3407
0
cleanup:
3408
0
  gnutls_pubkey_deinit(pubkey);
3409
0
  return ret;
3410
0
}
3411
3412
/**
3413
 * gnutls_x509_crt_get_crl_dist_points:
3414
 * @cert: should contain a #gnutls_x509_crt_t type
3415
 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3416
 * @san: is the place where the distribution point will be copied to
3417
 * @san_size: holds the size of ret.
3418
 * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3419
 * @critical: will be non-zero if the extension is marked as critical (may be null)
3420
 *
3421
 * This function retrieves the CRL distribution points (2.5.29.31),
3422
 * contained in the given certificate in the X509v3 Certificate
3423
 * Extensions.
3424
 *
3425
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3426
 *   @ret_size is not enough to hold the distribution point, or the
3427
 *   type of the distribution point if everything was ok. The type is
3428
 *   one of the enumerated %gnutls_x509_subject_alt_name_t.  If the
3429
 *   certificate does not have an Alternative name with the specified
3430
 *   sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3431
 *   returned.
3432
 **/
3433
int gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
3434
          unsigned int seq, void *san,
3435
          size_t *san_size,
3436
          unsigned int *reason_flags,
3437
          unsigned int *critical)
3438
0
{
3439
0
  int ret;
3440
0
  gnutls_datum_t dist_points = { NULL, 0 };
3441
0
  unsigned type;
3442
0
  gnutls_x509_crl_dist_points_t cdp = NULL;
3443
0
  gnutls_datum_t t_san;
3444
3445
0
  if (cert == NULL) {
3446
0
    gnutls_assert();
3447
0
    return GNUTLS_E_INVALID_REQUEST;
3448
0
  }
3449
3450
0
  ret = gnutls_x509_crl_dist_points_init(&cdp);
3451
0
  if (ret < 0)
3452
0
    return gnutls_assert_val(ret);
3453
3454
0
  if (reason_flags)
3455
0
    *reason_flags = 0;
3456
3457
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.31", 0, &dist_points,
3458
0
               critical);
3459
0
  if (ret < 0) {
3460
0
    gnutls_assert();
3461
0
    goto cleanup;
3462
0
  }
3463
3464
0
  if (dist_points.size == 0 || dist_points.data == NULL) {
3465
0
    gnutls_assert();
3466
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3467
0
    goto cleanup;
3468
0
  }
3469
3470
0
  ret = gnutls_x509_ext_import_crl_dist_points(&dist_points, cdp, 0);
3471
0
  if (ret < 0) {
3472
0
    gnutls_assert();
3473
0
    goto cleanup;
3474
0
  }
3475
3476
0
  ret = gnutls_x509_crl_dist_points_get(cdp, seq, &type, &t_san,
3477
0
                reason_flags);
3478
0
  if (ret < 0) {
3479
0
    gnutls_assert();
3480
0
    goto cleanup;
3481
0
  }
3482
3483
0
  ret = _gnutls_copy_string(&t_san, san, san_size);
3484
0
  if (ret < 0) {
3485
0
    gnutls_assert();
3486
0
    goto cleanup;
3487
0
  }
3488
3489
0
  ret = type;
3490
3491
0
cleanup:
3492
0
  _gnutls_free_datum(&dist_points);
3493
0
  if (cdp != NULL)
3494
0
    gnutls_x509_crl_dist_points_deinit(cdp);
3495
3496
0
  return ret;
3497
0
}
3498
3499
/**
3500
 * gnutls_x509_crt_get_key_purpose_oid:
3501
 * @cert: should contain a #gnutls_x509_crt_t type
3502
 * @indx: This specifies which OID to return. Use (0) to get the first one.
3503
 * @oid: a pointer to a buffer to hold the OID (may be null)
3504
 * @oid_size: initially holds the size of @oid
3505
 * @critical: output flag to indicate criticality of extension
3506
 *
3507
 * This function will extract the key purpose OIDs of the Certificate
3508
 * specified by the given index.  These are stored in the Extended Key
3509
 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3510
 * human readable names.
3511
 *
3512
 * If @oid is null then only the size will be filled. The @oid
3513
 * returned will be null terminated, although @oid_size will not
3514
 * account for the trailing null.
3515
 *
3516
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3517
 *   not long enough, and in that case the *oid_size will be updated
3518
 *   with the required size.  On success 0 is returned.
3519
 **/
3520
int gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert, unsigned indx,
3521
          void *oid, size_t *oid_size,
3522
          unsigned int *critical)
3523
0
{
3524
0
  int ret;
3525
0
  gnutls_datum_t ext;
3526
0
  gnutls_x509_key_purposes_t p = NULL;
3527
0
  gnutls_datum_t out;
3528
3529
0
  if (cert == NULL) {
3530
0
    gnutls_assert();
3531
0
    return GNUTLS_E_INVALID_REQUEST;
3532
0
  }
3533
3534
0
  if (oid)
3535
0
    memset(oid, 0, *oid_size);
3536
0
  else
3537
0
    *oid_size = 0;
3538
3539
0
  if ((ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &ext,
3540
0
              critical)) < 0) {
3541
0
    return ret;
3542
0
  }
3543
3544
0
  if (ext.size == 0 || ext.data == NULL) {
3545
0
    gnutls_assert();
3546
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3547
0
  }
3548
3549
0
  ret = gnutls_x509_key_purpose_init(&p);
3550
0
  if (ret < 0) {
3551
0
    gnutls_assert();
3552
0
    goto cleanup;
3553
0
  }
3554
3555
0
  ret = gnutls_x509_ext_import_key_purposes(&ext, p, 0);
3556
0
  if (ret < 0) {
3557
0
    gnutls_assert();
3558
0
    goto cleanup;
3559
0
  }
3560
3561
0
  ret = gnutls_x509_key_purpose_get(p, indx, &out);
3562
0
  if (ret < 0) {
3563
0
    gnutls_assert();
3564
0
    goto cleanup;
3565
0
  }
3566
3567
0
  ret = _gnutls_copy_string(&out, oid, oid_size);
3568
0
  if (ret < 0) {
3569
0
    gnutls_assert();
3570
0
    goto cleanup;
3571
0
  }
3572
3573
0
  ret = 0;
3574
3575
0
cleanup:
3576
0
  gnutls_free(ext.data);
3577
0
  if (p != NULL)
3578
0
    gnutls_x509_key_purpose_deinit(p);
3579
0
  return ret;
3580
0
}
3581
3582
/**
3583
 * gnutls_x509_crt_get_pk_rsa_raw:
3584
 * @crt: Holds the certificate
3585
 * @m: will hold the modulus
3586
 * @e: will hold the public exponent
3587
 *
3588
 * This function will export the RSA public key's parameters found in
3589
 * the given structure.  The new parameters will be allocated using
3590
 * gnutls_malloc() and will be stored in the appropriate datum.
3591
 *
3592
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3593
 **/
3594
int gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt, gnutls_datum_t *m,
3595
           gnutls_datum_t *e)
3596
0
{
3597
0
  int ret;
3598
0
  gnutls_pubkey_t pubkey;
3599
3600
0
  if (crt == NULL) {
3601
0
    gnutls_assert();
3602
0
    return GNUTLS_E_INVALID_REQUEST;
3603
0
  }
3604
3605
0
  ret = gnutls_pubkey_init(&pubkey);
3606
0
  if (ret < 0)
3607
0
    return gnutls_assert_val(ret);
3608
3609
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3610
0
  if (ret < 0) {
3611
0
    gnutls_assert();
3612
0
    goto cleanup;
3613
0
  }
3614
3615
0
  ret = gnutls_pubkey_export_rsa_raw(pubkey, m, e);
3616
0
  if (ret < 0) {
3617
0
    gnutls_assert();
3618
0
    goto cleanup;
3619
0
  }
3620
3621
0
cleanup:
3622
0
  gnutls_pubkey_deinit(pubkey);
3623
0
  return ret;
3624
0
}
3625
3626
/**
3627
 * gnutls_x509_crt_get_pk_ecc_raw:
3628
 * @crt: Holds the certificate
3629
 * @curve: will hold the curve
3630
 * @x: will hold the x-coordinate
3631
 * @y: will hold the y-coordinate
3632
 *
3633
 * This function will export the ECC public key's parameters found in
3634
 * the given certificate.  The new parameters will be allocated using
3635
 * gnutls_malloc() and will be stored in the appropriate datum.
3636
 *
3637
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
3638
 * will be in the native format for the curve.
3639
 *
3640
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3641
 *
3642
 * Since: 3.4.1
3643
 **/
3644
int gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,
3645
           gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
3646
           gnutls_datum_t *y)
3647
0
{
3648
0
  int ret;
3649
0
  gnutls_pubkey_t pubkey;
3650
3651
0
  if (crt == NULL) {
3652
0
    gnutls_assert();
3653
0
    return GNUTLS_E_INVALID_REQUEST;
3654
0
  }
3655
3656
0
  ret = gnutls_pubkey_init(&pubkey);
3657
0
  if (ret < 0)
3658
0
    return gnutls_assert_val(ret);
3659
3660
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3661
0
  if (ret < 0) {
3662
0
    gnutls_assert();
3663
0
    goto cleanup;
3664
0
  }
3665
3666
0
  ret = gnutls_pubkey_export_ecc_raw(pubkey, curve, x, y);
3667
0
  if (ret < 0) {
3668
0
    gnutls_assert();
3669
0
    goto cleanup;
3670
0
  }
3671
3672
0
cleanup:
3673
0
  gnutls_pubkey_deinit(pubkey);
3674
0
  return ret;
3675
0
}
3676
3677
/**
3678
 * gnutls_x509_crt_get_pk_gost_raw:
3679
 * @crt: Holds the certificate
3680
 * @curve: will hold the curve
3681
 * @digest: will hold the digest
3682
 * @paramset: will hold the GOST parameter set ID
3683
 * @x: will hold the x-coordinate
3684
 * @y: will hold the y-coordinate
3685
 *
3686
 * This function will export the GOST public key's parameters found in
3687
 * the given certificate.  The new parameters will be allocated using
3688
 * gnutls_malloc() and will be stored in the appropriate datum.
3689
 *
3690
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3691
 *
3692
 * Since: 3.6.3
3693
 **/
3694
int gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,
3695
            gnutls_ecc_curve_t *curve,
3696
            gnutls_digest_algorithm_t *digest,
3697
            gnutls_gost_paramset_t *paramset,
3698
            gnutls_datum_t *x, gnutls_datum_t *y)
3699
0
{
3700
0
  int ret;
3701
0
  gnutls_pubkey_t pubkey;
3702
3703
0
  if (crt == NULL) {
3704
0
    gnutls_assert();
3705
0
    return GNUTLS_E_INVALID_REQUEST;
3706
0
  }
3707
3708
0
  ret = gnutls_pubkey_init(&pubkey);
3709
0
  if (ret < 0)
3710
0
    return gnutls_assert_val(ret);
3711
3712
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3713
0
  if (ret < 0) {
3714
0
    gnutls_assert();
3715
0
    goto cleanup;
3716
0
  }
3717
3718
0
  ret = gnutls_pubkey_export_gost_raw2(pubkey, curve, digest, paramset, x,
3719
0
               y, 0);
3720
0
  if (ret < 0) {
3721
0
    gnutls_assert();
3722
0
    goto cleanup;
3723
0
  }
3724
3725
0
cleanup:
3726
0
  gnutls_pubkey_deinit(pubkey);
3727
0
  return ret;
3728
0
}
3729
3730
/**
3731
 * gnutls_x509_crt_get_pk_dsa_raw:
3732
 * @crt: Holds the certificate
3733
 * @p: will hold the p
3734
 * @q: will hold the q
3735
 * @g: will hold the g
3736
 * @y: will hold the y
3737
 *
3738
 * This function will export the DSA public key's parameters found in
3739
 * the given certificate.  The new parameters will be allocated using
3740
 * gnutls_malloc() and will be stored in the appropriate datum.
3741
 *
3742
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3743
 **/
3744
int gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt, gnutls_datum_t *p,
3745
           gnutls_datum_t *q, gnutls_datum_t *g,
3746
           gnutls_datum_t *y)
3747
0
{
3748
0
  int ret;
3749
0
  gnutls_pubkey_t pubkey;
3750
3751
0
  if (crt == NULL) {
3752
0
    gnutls_assert();
3753
0
    return GNUTLS_E_INVALID_REQUEST;
3754
0
  }
3755
3756
0
  ret = gnutls_pubkey_init(&pubkey);
3757
0
  if (ret < 0)
3758
0
    return gnutls_assert_val(ret);
3759
3760
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3761
0
  if (ret < 0) {
3762
0
    gnutls_assert();
3763
0
    goto cleanup;
3764
0
  }
3765
3766
0
  ret = gnutls_pubkey_export_dsa_raw(pubkey, p, q, g, y);
3767
0
  if (ret < 0) {
3768
0
    gnutls_assert();
3769
0
    goto cleanup;
3770
0
  }
3771
3772
0
cleanup:
3773
0
  gnutls_pubkey_deinit(pubkey);
3774
0
  return ret;
3775
0
}
3776
3777
/**
3778
 * gnutls_x509_crt_list_import2:
3779
 * @certs: Will hold the parsed certificate list.
3780
 * @size: It will contain the size of the list.
3781
 * @data: The PEM encoded certificate.
3782
 * @format: One of DER or PEM.
3783
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3784
 *
3785
 * This function will convert the given PEM encoded certificate list
3786
 * to the native gnutls_x509_crt_t format. The output will be stored
3787
 * in @certs which will be allocated and initialized.
3788
 *
3789
 * If the Certificate is PEM encoded it should have a header of "X509
3790
 * CERTIFICATE", or "CERTIFICATE".
3791
 *
3792
 * To deinitialize @certs, you need to deinitialize each crt structure
3793
 * independently, and use gnutls_free() at @certs.
3794
 *
3795
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3796
 *
3797
 * Since: 3.0
3798
 **/
3799
int gnutls_x509_crt_list_import2(gnutls_x509_crt_t **certs, unsigned int *size,
3800
         const gnutls_datum_t *data,
3801
         gnutls_x509_crt_fmt_t format,
3802
         unsigned int flags)
3803
0
{
3804
0
  unsigned int init = 1024;
3805
0
  int ret;
3806
3807
0
  *certs = _gnutls_reallocarray(NULL, init, sizeof(gnutls_x509_crt_t));
3808
0
  if (*certs == NULL) {
3809
0
    gnutls_assert();
3810
0
    return GNUTLS_E_MEMORY_ERROR;
3811
0
  }
3812
3813
0
  ret = gnutls_x509_crt_list_import(
3814
0
    *certs, &init, data, format,
3815
0
    flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3816
0
  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
3817
0
    *certs = _gnutls_reallocarray_fast(*certs, init,
3818
0
               sizeof(gnutls_x509_crt_t));
3819
0
    if (*certs == NULL) {
3820
0
      gnutls_assert();
3821
0
      return GNUTLS_E_MEMORY_ERROR;
3822
0
    }
3823
3824
0
    ret = gnutls_x509_crt_list_import(*certs, &init, data, format,
3825
0
              flags);
3826
0
  }
3827
3828
0
  if (ret < 0) {
3829
0
    gnutls_free(*certs);
3830
0
    return ret;
3831
0
  }
3832
3833
0
  *size = init;
3834
0
  return 0;
3835
0
}
3836
3837
/**
3838
 * gnutls_x509_crt_list_import:
3839
 * @certs: Indicates where the parsed list will be copied to. Must not be initialized.
3840
 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3841
 * @data: The PEM encoded certificate.
3842
 * @format: One of DER or PEM.
3843
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3844
 *
3845
 * This function will convert the given PEM encoded certificate list
3846
 * to the native gnutls_x509_crt_t format. The output will be stored
3847
 * in @certs.  They will be automatically initialized.
3848
 *
3849
 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3850
 * import to fail if the certificates in the provided buffer are more
3851
 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3852
 * flag will cause the function to fail if the provided list is not
3853
 * sorted from subject to issuer.
3854
 *
3855
 * If the Certificate is PEM encoded it should have a header of "X509
3856
 * CERTIFICATE", or "CERTIFICATE".
3857
 *
3858
 * Returns: the number of certificates read or a negative error value.
3859
 **/
3860
int gnutls_x509_crt_list_import(gnutls_x509_crt_t *certs,
3861
        unsigned int *cert_max,
3862
        const gnutls_datum_t *data,
3863
        gnutls_x509_crt_fmt_t format,
3864
        unsigned int flags)
3865
0
{
3866
0
  int size;
3867
0
  const char *ptr;
3868
0
  gnutls_datum_t tmp;
3869
0
  int ret, nocopy = 0;
3870
0
  unsigned int count = 0, j, copied = 0;
3871
3872
0
  if (format == GNUTLS_X509_FMT_DER) {
3873
0
    if (*cert_max < 1) {
3874
0
      *cert_max = 1;
3875
0
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
3876
0
    }
3877
3878
0
    count = 1; /* import only the first one */
3879
3880
0
    ret = gnutls_x509_crt_init(&certs[0]);
3881
0
    if (ret < 0) {
3882
0
      gnutls_assert();
3883
0
      goto error;
3884
0
    }
3885
3886
0
    ret = gnutls_x509_crt_import(certs[0], data, format);
3887
0
    if (ret < 0) {
3888
0
      gnutls_assert();
3889
0
      goto error;
3890
0
    }
3891
3892
0
    *cert_max = 1;
3893
0
    return 1;
3894
0
  }
3895
3896
  /* move to the certificate
3897
   */
3898
0
  ptr = memmem(data->data, data->size, PEM_CERT_SEP,
3899
0
         sizeof(PEM_CERT_SEP) - 1);
3900
0
  if (ptr == NULL)
3901
0
    ptr = memmem(data->data, data->size, PEM_CERT_SEP2,
3902
0
           sizeof(PEM_CERT_SEP2) - 1);
3903
3904
0
  if (ptr == NULL)
3905
0
    return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3906
3907
0
  count = 0;
3908
3909
0
  do {
3910
0
    if (count >= *cert_max) {
3911
0
      if (!(flags &
3912
0
            GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3913
0
        break;
3914
0
      else
3915
0
        nocopy = 1;
3916
0
    }
3917
3918
0
    if (!nocopy) {
3919
0
      ret = gnutls_x509_crt_init(&certs[count]);
3920
0
      if (ret < 0) {
3921
0
        gnutls_assert();
3922
0
        goto error;
3923
0
      }
3924
3925
0
      tmp.data = (void *)ptr;
3926
0
      tmp.size = data->size - (ptr - (char *)data->data);
3927
3928
0
      ret = gnutls_x509_crt_import(certs[count], &tmp,
3929
0
                 GNUTLS_X509_FMT_PEM);
3930
0
      if (ret < 0) {
3931
0
        count++;
3932
0
        gnutls_assert();
3933
0
        goto error;
3934
0
      }
3935
3936
0
      copied++;
3937
0
    }
3938
3939
    /* now we move ptr after the pem header
3940
     */
3941
0
    ptr++;
3942
    /* find the next certificate (if any)
3943
     */
3944
0
    size = data->size - (ptr - (char *)data->data);
3945
3946
0
    if (size > 0) {
3947
0
      char *ptr2;
3948
3949
0
      ptr2 = memmem(ptr, size, PEM_CERT_SEP,
3950
0
              sizeof(PEM_CERT_SEP) - 1);
3951
0
      if (ptr2 == NULL)
3952
0
        ptr2 = memmem(ptr, size, PEM_CERT_SEP2,
3953
0
                sizeof(PEM_CERT_SEP2) - 1);
3954
3955
0
      ptr = ptr2;
3956
0
    } else
3957
0
      ptr = NULL;
3958
3959
0
    count++;
3960
0
  } while (ptr != NULL);
3961
3962
0
  *cert_max = count;
3963
3964
0
  if (nocopy == 0) {
3965
0
    if (flags & GNUTLS_X509_CRT_LIST_SORT && *cert_max > 1) {
3966
0
      if (*cert_max > DEFAULT_MAX_VERIFY_DEPTH) {
3967
0
        ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
3968
0
        goto error;
3969
0
      }
3970
0
      count = _gnutls_sort_clist(certs, *cert_max);
3971
0
      if (count < *cert_max) {
3972
0
        for (j = count; j < *cert_max; j++) {
3973
0
          gnutls_x509_crt_deinit(certs[j]);
3974
0
        }
3975
0
      }
3976
0
      *cert_max = count;
3977
0
    }
3978
3979
0
    if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) {
3980
0
      ret = _gnutls_check_if_sorted(certs, *cert_max);
3981
0
      if (ret < 0) {
3982
0
        gnutls_assert();
3983
0
        goto error;
3984
0
      }
3985
0
    }
3986
3987
0
    return count;
3988
0
  } else {
3989
0
    count = copied;
3990
0
    ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
3991
0
  }
3992
3993
0
error:
3994
0
  for (j = 0; j < count; j++)
3995
0
    gnutls_x509_crt_deinit(certs[j]);
3996
0
  return ret;
3997
0
}
3998
3999
/**
4000
 * gnutls_x509_crt_get_subject_unique_id:
4001
 * @crt: Holds the certificate
4002
 * @buf: user allocated memory buffer, will hold the unique id
4003
 * @buf_size: size of user allocated memory buffer (on input), will hold
4004
 * actual size of the unique ID on return.
4005
 *
4006
 * This function will extract the subjectUniqueID value (if present) for
4007
 * the given certificate.
4008
 *
4009
 * If the user allocated memory buffer is not large enough to hold the
4010
 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
4011
 * returned, and buf_size will be set to the actual length.
4012
 *
4013
 * This function had a bug prior to 3.4.8 that prevented the setting
4014
 * of %NULL @buf to discover the @buf_size. To use this function safely
4015
 * with the older versions the @buf must be a valid buffer that can hold
4016
 * at least a single byte if @buf_size is zero.
4017
 *
4018
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
4019
 **/
4020
int gnutls_x509_crt_get_subject_unique_id(gnutls_x509_crt_t crt, char *buf,
4021
            size_t *buf_size)
4022
0
{
4023
0
  int result;
4024
0
  gnutls_datum_t datum = { NULL, 0 };
4025
4026
0
  result = _gnutls_x509_read_value(
4027
0
    crt->cert, "tbsCertificate.subjectUniqueID", &datum);
4028
0
  if (result < 0)
4029
0
    return gnutls_assert_val(result);
4030
4031
0
  if (datum.size > *buf_size) { /* then we're not going to fit */
4032
0
    *buf_size = datum.size;
4033
0
    result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4034
0
  } else {
4035
0
    *buf_size = datum.size;
4036
0
    memcpy(buf, datum.data, datum.size);
4037
0
  }
4038
4039
0
  _gnutls_free_datum(&datum);
4040
4041
0
  return result;
4042
0
}
4043
4044
/**
4045
 * gnutls_x509_crt_get_issuer_unique_id:
4046
 * @crt: Holds the certificate
4047
 * @buf: user allocated memory buffer, will hold the unique id
4048
 * @buf_size: size of user allocated memory buffer (on input), will hold
4049
 * actual size of the unique ID on return.
4050
 *
4051
 * This function will extract the issuerUniqueID value (if present) for
4052
 * the given certificate.
4053
 *
4054
 * If the user allocated memory buffer is not large enough to hold the
4055
 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
4056
 * returned, and buf_size will be set to the actual length.
4057
 *
4058
 * This function had a bug prior to 3.4.8 that prevented the setting
4059
 * of %NULL @buf to discover the @buf_size. To use this function safely
4060
 * with the older versions the @buf must be a valid buffer that can hold
4061
 * at least a single byte if @buf_size is zero.
4062
 *
4063
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
4064
 *
4065
 * Since: 2.12.0
4066
 **/
4067
int gnutls_x509_crt_get_issuer_unique_id(gnutls_x509_crt_t crt, char *buf,
4068
           size_t *buf_size)
4069
0
{
4070
0
  int result;
4071
0
  gnutls_datum_t datum = { NULL, 0 };
4072
4073
0
  result = _gnutls_x509_read_value(
4074
0
    crt->cert, "tbsCertificate.issuerUniqueID", &datum);
4075
0
  if (result < 0)
4076
0
    return gnutls_assert_val(result);
4077
4078
0
  if (datum.size > *buf_size) { /* then we're not going to fit */
4079
0
    *buf_size = datum.size;
4080
0
    result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4081
0
  } else {
4082
0
    *buf_size = datum.size;
4083
0
    memcpy(buf, datum.data, datum.size);
4084
0
  }
4085
4086
0
  _gnutls_free_datum(&datum);
4087
4088
0
  return result;
4089
0
}
4090
4091
static int legacy_parse_aia(asn1_node src, unsigned int seq, int what,
4092
          gnutls_datum_t *data)
4093
0
{
4094
0
  int len;
4095
0
  char nptr[MAX_NAME_SIZE];
4096
0
  int result;
4097
0
  gnutls_datum_t d;
4098
0
  const char *oid = NULL;
4099
4100
0
  seq++; /* 0->1, 1->2 etc */
4101
0
  switch (what) {
4102
0
  case GNUTLS_IA_ACCESSMETHOD_OID:
4103
0
    snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4104
0
    break;
4105
4106
0
  case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
4107
0
    snprintf(nptr, sizeof(nptr), "?%u.accessLocation", seq);
4108
0
    break;
4109
4110
0
  case GNUTLS_IA_CAISSUERS_URI:
4111
0
    oid = GNUTLS_OID_AD_CAISSUERS;
4112
0
    FALLTHROUGH;
4113
4114
0
  case GNUTLS_IA_OCSP_URI:
4115
0
    if (oid == NULL)
4116
0
      oid = GNUTLS_OID_AD_OCSP;
4117
0
    {
4118
0
      char tmpoid[MAX_OID_SIZE];
4119
0
      snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4120
0
      len = sizeof(tmpoid);
4121
0
      result = asn1_read_value(src, nptr, tmpoid, &len);
4122
4123
0
      if (result == ASN1_VALUE_NOT_FOUND ||
4124
0
          result == ASN1_ELEMENT_NOT_FOUND)
4125
0
        return gnutls_assert_val(
4126
0
          GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4127
4128
0
      if (result != ASN1_SUCCESS) {
4129
0
        gnutls_assert();
4130
0
        return _gnutls_asn2err(result);
4131
0
      }
4132
0
      if ((unsigned)len != strlen(oid) + 1 ||
4133
0
          memcmp(tmpoid, oid, len) != 0)
4134
0
        return gnutls_assert_val(
4135
0
          GNUTLS_E_UNKNOWN_ALGORITHM);
4136
0
    }
4137
0
    FALLTHROUGH;
4138
4139
0
  case GNUTLS_IA_URI:
4140
0
    snprintf(nptr, sizeof(nptr),
4141
0
       "?%u.accessLocation.uniformResourceIdentifier", seq);
4142
0
    break;
4143
4144
0
  default:
4145
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4146
0
  }
4147
4148
0
  len = 0;
4149
0
  result = asn1_read_value(src, nptr, NULL, &len);
4150
0
  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
4151
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4152
4153
0
  if (result != ASN1_MEM_ERROR) {
4154
0
    gnutls_assert();
4155
0
    return _gnutls_asn2err(result);
4156
0
  }
4157
4158
0
  d.size = len;
4159
4160
0
  d.data = gnutls_malloc(d.size);
4161
0
  if (d.data == NULL)
4162
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
4163
4164
0
  result = asn1_read_value(src, nptr, d.data, &len);
4165
0
  if (result != ASN1_SUCCESS) {
4166
0
    gnutls_assert();
4167
0
    gnutls_free(d.data);
4168
0
    return _gnutls_asn2err(result);
4169
0
  }
4170
4171
0
  if (data) {
4172
0
    data->data = d.data;
4173
0
    data->size = d.size;
4174
0
  } else
4175
0
    gnutls_free(d.data);
4176
4177
0
  return 0;
4178
0
}
4179
4180
/**
4181
 * gnutls_x509_crt_get_authority_info_access:
4182
 * @crt: Holds the certificate
4183
 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
4184
 * @what: what data to get, a #gnutls_info_access_what_t type.
4185
 * @data: output data to be freed with gnutls_free().
4186
 * @critical: pointer to output integer that is set to non-zero if the extension is marked as critical (may be %NULL)
4187
 *
4188
 * Note that a simpler API to access the authority info data is provided
4189
 * by gnutls_x509_aia_get() and gnutls_x509_ext_import_aia().
4190
 *
4191
 * This function extracts the Authority Information Access (AIA)
4192
 * extension, see RFC 5280 section 4.2.2.1 for more information.  The
4193
 * AIA extension holds a sequence of AccessDescription (AD) data.
4194
 *
4195
 * The @seq input parameter is used to indicate which member of the
4196
 * sequence the caller is interested in.  The first member is 0, the
4197
 * second member 1 and so on.  When the @seq value is out of bounds,
4198
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
4199
 *
4200
 * The type of data returned in @data is specified via @what which
4201
 * should be #gnutls_info_access_what_t values.
4202
 *
4203
 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
4204
 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
4205
 *
4206
 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
4207
 * hold the accessLocation GeneralName type (e.g.,
4208
 * "uniformResourceIdentifier").
4209
 *
4210
 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
4211
 * data.  Requesting this @what value leads to an error if the
4212
 * accessLocation is not of the "uniformResourceIdentifier" type.
4213
 *
4214
 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
4215
 * Requesting this @what value leads to an error if the accessMethod
4216
 * is not 1.3.6.1.5.5.7.48.1 aka OCSP, or if accessLocation is not of
4217
 * the "uniformResourceIdentifier" type. In that case %GNUTLS_E_UNKNOWN_ALGORITHM
4218
 * will be returned, and @seq should be increased and this function
4219
 * called again.
4220
 *
4221
 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
4222
 * URI.  Requesting this @what value leads to an error if the
4223
 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
4224
 * accessLocation is not of the "uniformResourceIdentifier" type.
4225
 * In that case handle as in %GNUTLS_IA_OCSP_URI.
4226
 *
4227
 * More @what values may be allocated in the future as needed.
4228
 *
4229
 * If @data is NULL, the function does the same without storing the
4230
 * output data, that is, it will set @critical and do error checking
4231
 * as usual.
4232
 *
4233
 * The value of the critical flag is returned in *@critical.  Supply a
4234
 * NULL @critical if you want the function to make sure the extension
4235
 * is non-critical, as required by RFC 5280.
4236
 *
4237
 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
4238
 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
4239
 * incorrectly marked as critical (use a non-NULL @critical to
4240
 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
4241
 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
4242
 * negative error code.
4243
 *
4244
 * Since: 3.0
4245
 **/
4246
int gnutls_x509_crt_get_authority_info_access(gnutls_x509_crt_t crt,
4247
                unsigned int seq, int what,
4248
                gnutls_datum_t *data,
4249
                unsigned int *critical)
4250
0
{
4251
0
  int ret;
4252
0
  gnutls_datum_t aia;
4253
0
  asn1_node c2 = NULL;
4254
4255
0
  if (crt == NULL) {
4256
0
    gnutls_assert();
4257
0
    return GNUTLS_E_INVALID_REQUEST;
4258
0
  }
4259
4260
0
  if ((ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia,
4261
0
              critical)) < 0)
4262
0
    return ret;
4263
4264
0
  if (aia.size == 0 || aia.data == NULL) {
4265
0
    gnutls_assert();
4266
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
4267
0
  }
4268
4269
0
  if (critical && *critical)
4270
0
    return GNUTLS_E_CONSTRAINT_ERROR;
4271
4272
0
  ret = asn1_create_element(_gnutls_get_pkix(),
4273
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
4274
0
  if (ret != ASN1_SUCCESS) {
4275
0
    gnutls_assert();
4276
0
    _gnutls_free_datum(&aia);
4277
0
    return _gnutls_asn2err(ret);
4278
0
  }
4279
4280
0
  ret = _asn1_strict_der_decode(&c2, aia.data, aia.size, NULL);
4281
  /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
4282
0
  _gnutls_free_datum(&aia);
4283
0
  if (ret != ASN1_SUCCESS) {
4284
0
    gnutls_assert();
4285
0
    asn1_delete_structure(&c2);
4286
0
    return _gnutls_asn2err(ret);
4287
0
  }
4288
4289
0
  ret = legacy_parse_aia(c2, seq, what, data);
4290
4291
0
  asn1_delete_structure(&c2);
4292
0
  if (ret < 0)
4293
0
    gnutls_assert();
4294
4295
0
  return ret;
4296
0
}
4297
4298
/**
4299
 * gnutls_x509_crt_set_pin_function:
4300
 * @crt: The certificate structure
4301
 * @fn: the callback
4302
 * @userdata: data associated with the callback
4303
 *
4304
 * This function will set a callback function to be used when
4305
 * it is required to access a protected object. This function overrides
4306
 * the global function set using gnutls_pkcs11_set_pin_function().
4307
 *
4308
 * Note that this callback is currently used only during the import
4309
 * of a PKCS #11 certificate with gnutls_x509_crt_import_url().
4310
 *
4311
 * Since: 3.1.0
4312
 *
4313
 **/
4314
void gnutls_x509_crt_set_pin_function(gnutls_x509_crt_t crt,
4315
              gnutls_pin_callback_t fn, void *userdata)
4316
0
{
4317
0
  if (crt) {
4318
0
    crt->pin.cb = fn;
4319
0
    crt->pin.data = userdata;
4320
0
  }
4321
0
}
4322
4323
/**
4324
 * gnutls_x509_crt_import_url:
4325
 * @crt: A certificate of type #gnutls_x509_crt_t
4326
 * @url: A PKCS 11 url
4327
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4328
 *
4329
 * This function will import a certificate present in a PKCS#11 token
4330
 * or any type of back-end that supports URLs.
4331
 *
4332
 * In previous versions of gnutls this function was named
4333
 * gnutls_x509_crt_import_pkcs11_url, and the old name is
4334
 * an alias to this one.
4335
 *
4336
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4337
 *   negative error value.
4338
 *
4339
 * Since: 3.4.0
4340
 **/
4341
int gnutls_x509_crt_import_url(gnutls_x509_crt_t crt, const char *url,
4342
             unsigned int flags)
4343
0
{
4344
0
  int ret;
4345
0
  unsigned i;
4346
4347
0
  for (i = 0; i < _gnutls_custom_urls_size; i++) {
4348
0
    if (strncmp(url, _gnutls_custom_urls[i].name,
4349
0
          _gnutls_custom_urls[i].name_size) == 0) {
4350
0
      if (_gnutls_custom_urls[i].import_crt) {
4351
0
        ret = _gnutls_custom_urls[i].import_crt(
4352
0
          crt, url, flags);
4353
0
        goto cleanup;
4354
0
      }
4355
0
      break;
4356
0
    }
4357
0
  }
4358
4359
0
  if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
4360
0
    ret = _gnutls_x509_crt_import_system_url(crt, url);
4361
#ifdef ENABLE_PKCS11
4362
  } else if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
4363
    ret = _gnutls_x509_crt_import_pkcs11_url(crt, url, flags);
4364
#endif
4365
0
  } else {
4366
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4367
0
  }
4368
4369
0
cleanup:
4370
0
  return ret;
4371
0
}
4372
4373
/**
4374
 * gnutls_x509_crt_list_import_url:
4375
 * @certs: Will hold the allocated certificate list.
4376
 * @size: It will contain the size of the list.
4377
 * @url: A PKCS 11 url
4378
 * @pin_fn: a PIN callback if not globally set
4379
 * @pin_fn_userdata: parameter for the PIN callback
4380
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4381
 *
4382
 * This function will import a certificate chain present in a PKCS#11 token
4383
 * or any type of back-end that supports URLs. The certificates
4384
 * must be deinitialized afterwards using gnutls_x509_crt_deinit()
4385
 * and the returned pointer must be freed using gnutls_free().
4386
 *
4387
 * The URI provided must be the first certificate in the chain; subsequent
4388
 * certificates will be retrieved using gnutls_pkcs11_get_raw_issuer() or
4389
 * equivalent functionality for the supported URI.
4390
 *
4391
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4392
 *   negative error value.
4393
 *
4394
 * Since: 3.6.3
4395
 **/
4396
int gnutls_x509_crt_list_import_url(gnutls_x509_crt_t **certs,
4397
            unsigned int *size, const char *url,
4398
            gnutls_pin_callback_t pin_fn,
4399
            void *pin_fn_userdata, unsigned int flags)
4400
0
{
4401
0
  int ret;
4402
0
  unsigned i;
4403
0
  gnutls_x509_crt_t crts[DEFAULT_MAX_VERIFY_DEPTH];
4404
0
  gnutls_datum_t issuer = { NULL, 0 };
4405
0
  unsigned total = 0;
4406
4407
0
  memset(crts, 0, sizeof(crts));
4408
4409
0
  ret = gnutls_x509_crt_init(&crts[0]);
4410
0
  if (ret < 0)
4411
0
    return gnutls_assert_val(ret);
4412
4413
0
  gnutls_x509_crt_set_pin_function(crts[0], pin_fn, pin_fn_userdata);
4414
4415
0
  total = 1;
4416
4417
0
  ret = gnutls_x509_crt_import_url(crts[0], url, flags);
4418
0
  if (ret < 0) {
4419
0
    gnutls_assert();
4420
0
    goto cleanup;
4421
0
  }
4422
4423
0
  for (i = 1; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
4424
0
    ret = _gnutls_get_raw_issuer(
4425
0
      url, crts[i - 1], &issuer,
4426
0
      flags | GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_ANY);
4427
0
    if (ret < 0) {
4428
0
      issuer.data = NULL;
4429
0
      break;
4430
0
    }
4431
4432
0
    if (gnutls_x509_crt_equals2(crts[i - 1], &issuer)) {
4433
0
      gnutls_free(issuer.data);
4434
0
      break;
4435
0
    }
4436
4437
0
    ret = gnutls_x509_crt_init(&crts[i]);
4438
0
    if (ret < 0) {
4439
0
      gnutls_assert();
4440
0
      goto cleanup;
4441
0
    }
4442
4443
0
    total++;
4444
4445
0
    gnutls_x509_crt_set_pin_function(crts[i], pin_fn,
4446
0
             pin_fn_userdata);
4447
4448
0
    ret = gnutls_x509_crt_import(crts[i], &issuer,
4449
0
               GNUTLS_X509_FMT_DER);
4450
0
    if (ret < 0) {
4451
0
      gnutls_assert();
4452
0
      goto cleanup;
4453
0
    }
4454
4455
0
    gnutls_free(issuer.data);
4456
0
  }
4457
4458
0
  *certs = _gnutls_reallocarray(NULL, total, sizeof(gnutls_x509_crt_t));
4459
0
  if (*certs == NULL) {
4460
0
    ret = GNUTLS_E_MEMORY_ERROR;
4461
0
    goto cleanup;
4462
0
  }
4463
4464
0
  memcpy(*certs, crts, total * sizeof(gnutls_x509_crt_t));
4465
0
  *size = total;
4466
4467
0
  return 0;
4468
0
cleanup:
4469
0
  gnutls_free(issuer.data);
4470
0
  for (i = 0; i < total; i++)
4471
0
    gnutls_x509_crt_deinit(crts[i]);
4472
4473
0
  return ret;
4474
0
}
4475
4476
/*-
4477
 * gnutls_x509_crt_verify_data3:
4478
 * @crt: Holds the certificate to verify with
4479
 * @algo: The signature algorithm used
4480
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4481
 * @data: holds the signed data
4482
 * @signature: contains the signature
4483
 *
4484
 * This function will verify the given signed data, using the
4485
 * parameters from the certificate.
4486
 *
4487
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4488
 * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4489
 * or not yet activated certificate and zero or positive code on success.
4490
 *
4491
 * Since: 3.5.6
4492
 -*/
4493
int gnutls_x509_crt_verify_data3(gnutls_x509_crt_t crt,
4494
         gnutls_sign_algorithm_t algo,
4495
         gnutls_typed_vdata_st *vdata,
4496
         unsigned int vdata_size,
4497
         const gnutls_datum_t *data,
4498
         const gnutls_datum_t *signature,
4499
         unsigned int flags)
4500
0
{
4501
0
  int ret;
4502
0
  gnutls_pubkey_t pubkey;
4503
4504
0
  if (crt == NULL) {
4505
0
    gnutls_assert();
4506
0
    return GNUTLS_E_INVALID_REQUEST;
4507
0
  }
4508
4509
0
  ret = gnutls_pubkey_init(&pubkey);
4510
0
  if (ret < 0)
4511
0
    return gnutls_assert_val(ret);
4512
4513
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
4514
0
  if (ret < 0)
4515
0
    return gnutls_assert_val(ret);
4516
4517
0
  ret = gnutls_pubkey_verify_data2(pubkey, algo, flags, data, signature);
4518
0
  gnutls_pubkey_deinit(pubkey);
4519
4520
0
  if (ret >= 0) {
4521
0
    time_t now = gnutls_time(0);
4522
0
    int res;
4523
0
    unsigned usage, i;
4524
4525
0
    if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) ||
4526
0
        !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
4527
0
      if (now > gnutls_x509_crt_get_expiration_time(crt)) {
4528
0
        return gnutls_assert_val(GNUTLS_E_EXPIRED);
4529
0
      }
4530
4531
0
      if (now < gnutls_x509_crt_get_activation_time(crt)) {
4532
0
        return gnutls_assert_val(
4533
0
          GNUTLS_E_NOT_YET_ACTIVATED);
4534
0
      }
4535
0
    }
4536
4537
0
    res = gnutls_x509_crt_get_key_usage(crt, &usage, NULL);
4538
0
    if (res >= 0) {
4539
0
      if (!(usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
4540
0
        return gnutls_assert_val(
4541
0
          GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4542
0
      }
4543
0
    }
4544
4545
0
    for (i = 0; i < vdata_size; i++) {
4546
0
      if (vdata[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
4547
0
        res = _gnutls_check_key_purpose(
4548
0
          crt, (char *)vdata[i].data, 0);
4549
0
        if (res == 0)
4550
0
          return gnutls_assert_val(
4551
0
            GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4552
0
        break;
4553
0
      }
4554
0
    }
4555
0
  }
4556
4557
0
  return ret;
4558
0
}
4559
4560
/**
4561
 * gnutls_x509_crt_verify_data2:
4562
 * @crt: Holds the certificate to verify with
4563
 * @algo: The signature algorithm used
4564
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4565
 * @data: holds the signed data
4566
 * @signature: contains the signature
4567
 *
4568
 * This function will verify the given signed data, using the
4569
 * parameters from the certificate.
4570
 *
4571
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4572
 * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4573
 * or not yet activated certificate and zero or positive code on success.
4574
 *
4575
 * Note that since GnuTLS 3.5.6 this function introduces checks in the
4576
 * end certificate (@crt), including time checks and key usage checks.
4577
 *
4578
 * Since: 3.4.0
4579
 **/
4580
int gnutls_x509_crt_verify_data2(gnutls_x509_crt_t crt,
4581
         gnutls_sign_algorithm_t algo,
4582
         unsigned int flags, const gnutls_datum_t *data,
4583
         const gnutls_datum_t *signature)
4584
0
{
4585
0
  return gnutls_x509_crt_verify_data3(crt, algo, NULL, 0, data, signature,
4586
0
              flags);
4587
0
}
4588
4589
/**
4590
 * gnutls_x509_crt_set_flags:
4591
 * @cert: A type #gnutls_x509_crt_t
4592
 * @flags: flags from the %gnutls_x509_crt_flags
4593
 *
4594
 * This function will set flags for the specified certificate.
4595
 * Currently this is useful for the %GNUTLS_X509_CRT_FLAG_IGNORE_SANITY
4596
 * which allows importing certificates even if they have known issues.
4597
 *
4598
 * Since: 3.6.0
4599
 *
4600
 **/
4601
void gnutls_x509_crt_set_flags(gnutls_x509_crt_t cert, unsigned int flags)
4602
0
{
4603
0
  cert->flags = flags;
4604
0
}