Coverage Report

Created: 2026-08-14 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/x509.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2003-2018 Free Software Foundation, Inc.
3
 * Copyright (C) 2018 Red Hat, Inc.
4
 *
5
 * Authors: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* Functions on X.509 Certificate parsing
25
 */
26
27
#include "gnutls_int.h"
28
#include "datum.h"
29
#include "global.h"
30
#include "errors.h"
31
#include "common.h"
32
#include <gnutls/x509-ext.h>
33
#include "x509.h"
34
#include "x509_b64.h"
35
#include "x509_int.h"
36
#include <libtasn1.h>
37
#include "pk.h"
38
#include "pkcs11_int.h"
39
#include "urls.h"
40
#include "system-keys.h"
41
#include "gl_linkedhash_list.h"
42
#include "gl_list.h"
43
#include <hashcode-mem.h>
44
45
static int crt_reinit(gnutls_x509_crt_t crt)
46
0
{
47
0
  int result;
48
49
0
  _gnutls_free_datum(&crt->der);
50
0
  crt->raw_dn.size = 0;
51
0
  crt->raw_issuer_dn.size = 0;
52
0
  crt->raw_spki.size = 0;
53
54
0
  asn1_delete_structure(&crt->cert);
55
56
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Certificate",
57
0
             &crt->cert);
58
0
  if (result != ASN1_SUCCESS) {
59
0
    result = _gnutls_asn2err(result);
60
0
    gnutls_assert();
61
0
    return result;
62
0
  }
63
64
0
  gnutls_subject_alt_names_deinit(crt->san);
65
0
  result = gnutls_subject_alt_names_init(&crt->san);
66
0
  if (result < 0) {
67
0
    gnutls_assert();
68
0
    return result;
69
0
  }
70
71
0
  gnutls_subject_alt_names_deinit(crt->ian);
72
0
  result = gnutls_subject_alt_names_init(&crt->ian);
73
0
  if (result < 0) {
74
0
    gnutls_assert();
75
0
    return result;
76
0
  }
77
78
0
  return 0;
79
0
}
80
81
/**
82
 * gnutls_x509_crt_equals - This function compares two gnutls_x509_crt_t certificates
83
 * @cert1: The first certificate
84
 * @cert2: The second certificate
85
 *
86
 * This function will compare two X.509 certificate structures.
87
 *
88
 * Returns: On equality non-zero is returned, otherwise zero.
89
 *
90
 * Since: 3.5.0
91
 **/
92
unsigned gnutls_x509_crt_equals(gnutls_x509_crt_t cert1,
93
        gnutls_x509_crt_t cert2)
94
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
        memeq(tmp1.data, tmp2.data, tmp1.size))
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
        memeq(cert1->der.data, cert2->der.data, cert1->der.size))
133
0
      result = 1;
134
0
    else
135
0
      result = 0;
136
0
  }
137
138
0
  return result;
139
0
}
140
141
/**
142
 * gnutls_x509_crt_equals2 - This function compares a gnutls_x509_crt_t cert with DER data
143
 * @cert1: The first certificate
144
 * @der: A DER encoded certificate
145
 *
146
 * This function will compare an X.509 certificate structures, with DER
147
 * encoded certificate data.
148
 *
149
 * Returns: On equality non-zero is returned, otherwise zero.
150
 *
151
 * Since: 3.5.0
152
 **/
153
unsigned gnutls_x509_crt_equals2(gnutls_x509_crt_t cert1,
154
         const gnutls_datum_t *der)
155
0
{
156
0
  bool result;
157
158
0
  if (cert1 == NULL || der == NULL)
159
0
    return 0;
160
161
0
  if (cert1->der.size == 0 || cert1->modified) {
162
0
    gnutls_datum_t tmp1;
163
0
    int ret;
164
165
    /* on uninitialized or modified certificates, we have to re-encode */
166
0
    ret = gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER,
167
0
                &tmp1);
168
0
    if (ret < 0)
169
0
      return gnutls_assert_val(0);
170
171
0
    if ((tmp1.size == der->size) &&
172
0
        memeq(tmp1.data, der->data, tmp1.size))
173
0
      result = 1;
174
0
    else
175
0
      result = 0;
176
177
0
    gnutls_free(tmp1.data);
178
0
  } else {
179
0
    if ((cert1->der.size == der->size) &&
180
0
        memeq(cert1->der.data, der->data, cert1->der.size))
181
0
      result = 1;
182
0
    else
183
0
      result = 0;
184
0
  }
185
186
0
  return result;
187
0
}
188
189
/**
190
 * gnutls_x509_crt_init:
191
 * @cert: A pointer to the type to be initialized
192
 *
193
 * This function will initialize an X.509 certificate structure.
194
 *
195
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
196
 *   negative error value.
197
 **/
198
int gnutls_x509_crt_init(gnutls_x509_crt_t *cert)
199
0
{
200
0
  gnutls_x509_crt_t tmp;
201
0
  int result;
202
203
0
  *cert = NULL;
204
0
  FAIL_IF_LIB_ERROR;
205
206
0
  tmp = gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
207
208
0
  if (!tmp)
209
0
    return GNUTLS_E_MEMORY_ERROR;
210
211
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Certificate",
212
0
             &tmp->cert);
213
0
  if (result != ASN1_SUCCESS) {
214
0
    gnutls_assert();
215
0
    gnutls_free(tmp);
216
0
    return _gnutls_asn2err(result);
217
0
  }
218
219
0
  result = gnutls_subject_alt_names_init(&tmp->san);
220
0
  if (result < 0) {
221
0
    gnutls_assert();
222
0
    asn1_delete_structure(&tmp->cert);
223
0
    gnutls_free(tmp);
224
0
    return result;
225
0
  }
226
227
0
  result = gnutls_subject_alt_names_init(&tmp->ian);
228
0
  if (result < 0) {
229
0
    gnutls_assert();
230
0
    asn1_delete_structure(&tmp->cert);
231
0
    gnutls_subject_alt_names_deinit(tmp->san);
232
0
    gnutls_free(tmp);
233
0
    return result;
234
0
  }
235
236
  /* If you add anything here, be sure to check if it has to be added
237
     to gnutls_x509_crt_import as well. */
238
239
0
  *cert = tmp;
240
241
0
  return 0; /* success */
242
0
}
243
244
/*-
245
 * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t type
246
 * @dest: The data where to copy
247
 * @src: The data to be copied
248
 * @flags: zero or CRT_CPY_FAST
249
 *
250
 * This function will copy an X.509 certificate structure.
251
 *
252
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
253
 *   negative error value.
254
 -*/
255
int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
256
0
{
257
0
  int ret;
258
0
  gnutls_datum_t tmp;
259
0
  unsigned dealloc = 0;
260
261
0
  if (src->der.size == 0 || src->modified) {
262
0
    ret = gnutls_x509_crt_export2(src, GNUTLS_X509_FMT_DER, &tmp);
263
0
    if (ret < 0)
264
0
      return gnutls_assert_val(ret);
265
0
    dealloc = 1;
266
0
  } else {
267
0
    tmp.data = src->der.data;
268
0
    tmp.size = src->der.size;
269
0
  }
270
271
0
  ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
272
273
0
  if (dealloc) {
274
0
    gnutls_free(tmp.data);
275
0
  }
276
277
0
  if (ret < 0)
278
0
    return gnutls_assert_val(ret);
279
280
0
  return 0;
281
0
}
282
283
/**
284
 * gnutls_x509_crt_deinit:
285
 * @cert: The data to be deinitialized
286
 *
287
 * This function will deinitialize a certificate structure.
288
 **/
289
void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert)
290
0
{
291
0
  if (!cert)
292
0
    return;
293
294
0
  if (cert->cert)
295
0
    asn1_delete_structure(&cert->cert);
296
0
  gnutls_free(cert->der.data);
297
0
  gnutls_subject_alt_names_deinit(cert->san);
298
0
  gnutls_subject_alt_names_deinit(cert->ian);
299
0
  gnutls_free(cert);
300
0
}
301
302
static int compare_sig_algorithm(gnutls_x509_crt_t cert)
303
0
{
304
0
  int ret, len1, len2, result;
305
0
  char oid1[MAX_OID_SIZE];
306
0
  char oid2[MAX_OID_SIZE];
307
0
  gnutls_datum_t sp1 = { NULL, 0 };
308
0
  gnutls_datum_t sp2 = { NULL, 0 };
309
0
  unsigned empty1 = 0, empty2 = 0;
310
311
0
  len1 = sizeof(oid1);
312
0
  result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm",
313
0
         oid1, &len1);
314
0
  if (result != ASN1_SUCCESS) {
315
0
    gnutls_assert();
316
0
    return _gnutls_asn2err(result);
317
0
  }
318
319
0
  len2 = sizeof(oid2);
320
0
  result = asn1_read_value(
321
0
    cert->cert, "tbsCertificate.signature.algorithm", oid2, &len2);
322
0
  if (result != ASN1_SUCCESS) {
323
0
    gnutls_assert();
324
0
    return _gnutls_asn2err(result);
325
0
  }
326
327
0
  if (len1 != len2 || !memeq(oid1, oid2, len1)) {
328
0
    _gnutls_debug_log(
329
0
      "signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n",
330
0
      oid1, oid2);
331
0
    gnutls_assert();
332
0
    return GNUTLS_E_CERTIFICATE_ERROR;
333
0
  }
334
335
  /* compare the parameters */
336
0
  ret = _gnutls_x509_read_value(cert->cert,
337
0
              "signatureAlgorithm.parameters", &sp1);
338
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
339
0
    empty1 = 1;
340
0
  } else if (ret < 0) {
341
0
    gnutls_assert();
342
0
    return ret;
343
0
  }
344
345
0
  ret = _gnutls_x509_read_value(
346
0
    cert->cert, "tbsCertificate.signature.parameters", &sp2);
347
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
348
0
    empty2 = 1;
349
0
  } else if (ret < 0) {
350
0
    gnutls_assert();
351
0
    return ret;
352
0
  }
353
354
  /* handle equally empty parameters with missing parameters */
355
0
  if (sp1.size == 2 && memeq(sp1.data, "\x05\x00", 2)) {
356
0
    empty1 = 1;
357
0
    _gnutls_free_datum(&sp1);
358
0
  }
359
360
0
  if (sp2.size == 2 && memeq(sp2.data, "\x05\x00", 2)) {
361
0
    empty2 = 1;
362
0
    _gnutls_free_datum(&sp2);
363
0
  }
364
365
0
  if (empty1 != empty2 || sp1.size != sp2.size ||
366
0
      (sp1.size > 0 && !memeq(sp1.data, sp2.data, sp1.size))) {
367
0
    gnutls_assert();
368
0
    ret = GNUTLS_E_CERTIFICATE_ERROR;
369
0
    goto cleanup;
370
0
  }
371
372
0
  ret = 0;
373
0
cleanup:
374
0
  _gnutls_free_datum(&sp1);
375
0
  _gnutls_free_datum(&sp2);
376
0
  return ret;
377
0
}
378
379
static int cache_alt_names(gnutls_x509_crt_t cert)
380
0
{
381
0
  gnutls_datum_t tmpder = { NULL, 0 };
382
0
  int ret;
383
384
  /* pre-parse subject alt name */
385
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.17", 0, &tmpder,
386
0
               NULL);
387
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
388
0
    gnutls_free(tmpder.data);
389
0
    return gnutls_assert_val(ret);
390
0
  }
391
392
0
  if (ret >= 0) {
393
0
    ret = gnutls_x509_ext_import_subject_alt_names(&tmpder,
394
0
                     cert->san, 0);
395
0
    gnutls_free(tmpder.data);
396
0
    if (ret < 0)
397
0
      return gnutls_assert_val(ret);
398
0
  }
399
400
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.18", 0, &tmpder,
401
0
               NULL);
402
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
403
0
    return gnutls_assert_val(ret);
404
405
0
  if (ret >= 0) {
406
0
    ret = gnutls_x509_ext_import_subject_alt_names(&tmpder,
407
0
                     cert->ian, 0);
408
0
    gnutls_free(tmpder.data);
409
0
    if (ret < 0)
410
0
      return gnutls_assert_val(ret);
411
0
  }
412
413
0
  return 0;
414
0
}
415
416
static bool hcomparator(const void *v1, const void *v2)
417
0
{
418
0
  return streq(v1, v2);
419
0
}
420
421
static size_t hhasher(const void *entry)
422
0
{
423
0
  const char *e = entry;
424
0
  if (e == NULL || e[0] == 0)
425
0
    return 0;
426
427
0
  return hash_pjw_bare(e, strlen(e));
428
0
}
429
430
static void hdisposer(const void *entry)
431
0
{
432
0
  void *e = (void *)entry;
433
0
  gnutls_free(e);
434
0
}
435
436
#ifdef STRICT_X509
437
438
/* Check whether certificates serial number is RFC5280 compliant */
439
static bool has_valid_serial(gnutls_x509_crt_t cert)
440
{
441
  int err, is_zero;
442
  unsigned i;
443
  unsigned char serial[128];
444
  size_t serial_size = sizeof(serial);
445
446
  err = gnutls_x509_crt_get_serial(cert, serial, &serial_size);
447
  if (err < 0) {
448
    _gnutls_debug_log("error: could not read serial number\n");
449
    return false;
450
  }
451
452
  if (serial_size > 20) {
453
    _gnutls_debug_log(
454
      "error: serial number value is longer than 20 octets\n");
455
    return false;
456
  }
457
458
  if (serial[0] & 0x80) {
459
    _gnutls_debug_log("error: serial number is negative\n");
460
    return false;
461
  }
462
463
  is_zero = 1;
464
  for (i = 0; i < serial_size; ++i) {
465
    if (serial[i]) {
466
      is_zero = 0;
467
      break;
468
    }
469
  }
470
471
  if (is_zero) {
472
    _gnutls_debug_log("error: serial number is zero\n");
473
    return false;
474
  }
475
476
  return true;
477
}
478
479
/* Check if extension can be successfully parsed */
480
static bool is_valid_extension(const char *oid, gnutls_datum_t *der)
481
{
482
  int err = 0, i;
483
  unsigned u;
484
  size_t sz;
485
  time_t t1, t2;
486
  char *s1 = NULL, *s2 = NULL;
487
  gnutls_datum_t datum = { NULL, 0 };
488
489
  if (streq(oid, GNUTLS_X509EXT_OID_BASIC_CONSTRAINTS)) {
490
    err = gnutls_x509_ext_import_basic_constraints(der, &u, &i);
491
  } else if (streq(oid, GNUTLS_X509EXT_OID_SUBJECT_KEY_ID)) {
492
    err = gnutls_x509_ext_import_subject_key_id(der, &datum);
493
  } else if (streq(oid, GNUTLS_X509EXT_OID_CRT_POLICY)) {
494
    gnutls_x509_policies_t policies;
495
    if (gnutls_x509_policies_init(&policies) < 0)
496
      return false;
497
    err = gnutls_x509_ext_import_policies(der, policies, 0);
498
    gnutls_x509_policies_deinit(policies);
499
  } else if (streq(oid, GNUTLS_X509_OID_POLICY_ANY)) {
500
    err = gnutls_x509_ext_import_inhibit_anypolicy(der, &u);
501
  } else if (streq(oid, GNUTLS_X509EXT_OID_AUTHORITY_KEY_ID)) {
502
    gnutls_x509_aki_t aki;
503
    if (gnutls_x509_aki_init(&aki) < 0)
504
      return false;
505
    err = gnutls_x509_ext_import_authority_key_id(der, aki, 0);
506
    gnutls_x509_aki_deinit(aki);
507
  } else if (streq(oid, GNUTLS_X509EXT_OID_KEY_USAGE)) {
508
    err = gnutls_x509_ext_import_key_usage(der, &u);
509
  } else if (streq(oid, GNUTLS_X509EXT_OID_PRIVATE_KEY_USAGE_PERIOD)) {
510
    err = gnutls_x509_ext_import_private_key_usage_period(der, &t1,
511
                      &t2);
512
  } else if (streq(oid, GNUTLS_X509EXT_OID_EXTENDED_KEY_USAGE)) {
513
    gnutls_x509_key_purposes_t purposes;
514
    if (gnutls_x509_key_purpose_init(&purposes) < 0)
515
      return false;
516
    err = gnutls_x509_ext_import_key_purposes(der, purposes, 0);
517
    gnutls_x509_key_purpose_deinit(purposes);
518
  } else if (streq(oid, GNUTLS_X509EXT_OID_SAN) ||
519
       streq(oid, GNUTLS_X509EXT_OID_IAN)) {
520
    gnutls_subject_alt_names_t names;
521
    if (gnutls_subject_alt_names_init(&names) < 0)
522
      return false;
523
    err = gnutls_x509_ext_import_subject_alt_names(der, names, 0);
524
    gnutls_subject_alt_names_deinit(names);
525
  } else if (streq(oid, GNUTLS_X509EXT_OID_CRL_DIST_POINTS)) {
526
    gnutls_x509_crl_dist_points_t dp;
527
    if (gnutls_x509_crl_dist_points_init(&dp) < 0)
528
      return false;
529
    err = gnutls_x509_ext_import_crl_dist_points(der, dp, 0);
530
    gnutls_x509_crl_dist_points_deinit(dp);
531
  } else if (streq(oid, GNUTLS_X509EXT_OID_PROXY_CRT_INFO)) {
532
    err = gnutls_x509_ext_import_proxy(der, &i, &s1, &s2, &sz);
533
  } else if (streq(oid, GNUTLS_X509EXT_OID_AUTHORITY_INFO_ACCESS)) {
534
    gnutls_x509_aia_t aia;
535
    if (gnutls_x509_aia_init(&aia) < 0)
536
      return false;
537
    err = gnutls_x509_ext_import_aia(der, aia, 0);
538
    gnutls_x509_aia_deinit(aia);
539
  } else if (streq(oid, GNUTLS_X509EXT_OID_CT_SCT_V1)) {
540
    gnutls_x509_ct_scts_t scts;
541
    if (gnutls_x509_ext_ct_scts_init(&scts) < 0)
542
      return false;
543
    err = gnutls_x509_ext_ct_import_scts(der, scts, 0);
544
    gnutls_x509_ext_ct_scts_deinit(scts);
545
  } else if (streq(oid, GNUTLS_X509EXT_OID_NAME_CONSTRAINTS)) {
546
    gnutls_x509_name_constraints_t nc;
547
    if (gnutls_x509_name_constraints_init(&nc) < 0)
548
      return false;
549
    err = gnutls_x509_ext_import_name_constraints(der, nc, 0);
550
    gnutls_x509_name_constraints_deinit(nc);
551
  } else if (streq(oid, GNUTLS_X509EXT_OID_TLSFEATURES)) {
552
    gnutls_x509_tlsfeatures_t features;
553
    if (gnutls_x509_tlsfeatures_init(&features) < 0)
554
      return false;
555
    err = gnutls_x509_ext_import_tlsfeatures(der, features, 0);
556
    gnutls_x509_tlsfeatures_deinit(features);
557
  } else {
558
    return true;
559
  }
560
561
  gnutls_free(s1);
562
  gnutls_free(s2);
563
  _gnutls_free_datum(&datum);
564
565
  return err == 0;
566
}
567
568
#endif /* STRICT_X509 */
569
570
int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert)
571
0
{
572
0
  int ret = 0, version;
573
0
  gnutls_datum_t exts;
574
0
  gl_list_t htable = NULL;
575
576
0
  if (cert->flags & GNUTLS_X509_CRT_FLAG_IGNORE_SANITY)
577
0
    return 0;
578
579
  /* enforce the rule that only version 3 certificates carry extensions */
580
0
  ret = gnutls_x509_crt_get_version(cert);
581
0
  if (ret < 0) {
582
0
    return gnutls_assert_val(ret);
583
0
  }
584
585
0
  version = ret;
586
587
#ifdef STRICT_X509
588
  /* enforce upper bound on certificate version (RFC5280 compliant) */
589
  if (version > 3) {
590
    _gnutls_debug_log("error: invalid certificate version %d\n",
591
          version);
592
    return gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
593
  }
594
#endif
595
596
0
  if (version < 3) {
597
0
    if (!cert->modified) {
598
0
      ret = _gnutls_x509_get_raw_field2(
599
0
        cert->cert, &cert->der,
600
0
        "tbsCertificate.extensions", &exts);
601
0
      if (ret >= 0 && exts.size > 0) {
602
0
        _gnutls_debug_log(
603
0
          "error: extensions present in certificate with version %d\n",
604
0
          version);
605
0
        return gnutls_assert_val(
606
0
          GNUTLS_E_X509_CERTIFICATE_ERROR);
607
0
      }
608
0
    } else {
609
0
      if (cert->use_extensions) {
610
0
        _gnutls_debug_log(
611
0
          "error: extensions set in certificate with version %d\n",
612
0
          version);
613
0
        return gnutls_assert_val(
614
0
          GNUTLS_E_X509_CERTIFICATE_ERROR);
615
0
      }
616
0
    }
617
0
  } else {
618
    /* Version is 3; ensure no duplicate extensions are present. */
619
0
    unsigned i, critical;
620
0
    char oid[MAX_OID_SIZE];
621
0
    size_t oid_size;
622
0
    char *o;
623
624
0
    htable = gl_list_nx_create_empty(GL_LINKEDHASH_LIST,
625
0
             hcomparator, hhasher,
626
0
             hdisposer, false);
627
0
    if (htable == NULL)
628
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
629
630
0
    for (i = 0;; i++) {
631
0
      oid_size = sizeof(oid);
632
0
      ret = gnutls_x509_crt_get_extension_info(
633
0
        cert, i, oid, &oid_size, &critical);
634
0
      if (ret < 0) {
635
0
        if (ret ==
636
0
            GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
637
0
          break;
638
0
        gnutls_assert();
639
0
        goto cleanup;
640
0
      }
641
0
      o = gnutls_strdup(oid);
642
0
      if (o == NULL) {
643
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
644
0
        goto cleanup;
645
0
      }
646
647
0
      if (gl_list_search(htable, o)) {
648
        /* duplicate */
649
0
        gnutls_free(o);
650
0
        _gnutls_debug_log(
651
0
          "error: duplicate extension (%s) detected\n",
652
0
          oid);
653
0
        ret = gnutls_assert_val(
654
0
          GNUTLS_E_X509_DUPLICATE_EXTENSION);
655
0
        goto cleanup;
656
0
      } else if (!gl_list_nx_add_last(htable, o)) {
657
0
        gnutls_free(o);
658
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
659
0
        goto cleanup;
660
0
      }
661
662
#ifdef STRICT_X509
663
      gnutls_datum_t der = { NULL, 0 };
664
      ret = gnutls_x509_crt_get_extension_data2(cert, i,
665
                  &der);
666
      if (ret < 0)
667
        continue;
668
      if (critical && !is_valid_extension(oid, &der)) {
669
        _gnutls_free_datum(&der);
670
        _gnutls_debug_log(
671
          "error: could not parse extension (%s)\n",
672
          oid);
673
        return gnutls_assert_val(
674
          GNUTLS_E_X509_CERTIFICATE_ERROR);
675
      }
676
      _gnutls_free_datum(&der);
677
#endif
678
0
    }
679
680
0
    gl_list_free(htable);
681
0
    htable = NULL;
682
0
  }
683
684
0
  if (version < 2) {
685
0
    char id[128];
686
0
    size_t id_size;
687
688
0
    id_size = sizeof(id);
689
0
    ret = gnutls_x509_crt_get_subject_unique_id(cert, id, &id_size);
690
0
    if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
691
0
      _gnutls_debug_log(
692
0
        "error: subjectUniqueID present in certificate with version %d\n",
693
0
        version);
694
0
      ret = gnutls_assert_val(
695
0
        GNUTLS_E_X509_CERTIFICATE_ERROR);
696
0
      goto cleanup;
697
0
    }
698
699
0
    id_size = sizeof(id);
700
0
    ret = gnutls_x509_crt_get_issuer_unique_id(cert, id, &id_size);
701
0
    if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
702
0
      _gnutls_debug_log(
703
0
        "error: subjectUniqueID present in certificate with version %d\n",
704
0
        version);
705
0
      ret = gnutls_assert_val(
706
0
        GNUTLS_E_X509_CERTIFICATE_ERROR);
707
0
      goto cleanup;
708
0
    }
709
0
  }
710
711
#ifdef STRICT_X509
712
  if (!has_valid_serial(cert)) {
713
    ret = gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
714
    goto cleanup;
715
  }
716
#endif
717
718
0
  if (gnutls_x509_crt_get_expiration_time(cert) == -1 ||
719
0
      gnutls_x509_crt_get_activation_time(cert) == -1) {
720
0
    _gnutls_debug_log(
721
0
      "error: invalid expiration or activation time in certificate\n");
722
0
    ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_TIME_ERROR);
723
0
    goto cleanup;
724
0
  }
725
726
0
  ret = 0;
727
728
0
cleanup:
729
0
  if (htable)
730
0
    gl_list_free(htable);
731
0
  return ret;
732
0
}
733
734
/**
735
 * gnutls_x509_crt_import:
736
 * @cert: The data to store the parsed certificate.
737
 * @data: The DER or PEM encoded certificate.
738
 * @format: One of DER or PEM
739
 *
740
 * This function will convert the given DER or PEM encoded Certificate
741
 * to the native gnutls_x509_crt_t format. The output will be stored
742
 * in @cert.
743
 *
744
 * If the Certificate is PEM encoded it should have a header of "X509
745
 * CERTIFICATE", or "CERTIFICATE".
746
 *
747
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
748
 *   negative error value.
749
 **/
750
int gnutls_x509_crt_import(gnutls_x509_crt_t cert, const gnutls_datum_t *data,
751
         gnutls_x509_crt_fmt_t format)
752
0
{
753
0
  int result;
754
755
0
  if (cert == NULL) {
756
0
    gnutls_assert();
757
0
    return GNUTLS_E_INVALID_REQUEST;
758
0
  }
759
760
0
  if (cert->expanded) {
761
    /* Any earlier _asn1_strict_der_decode will modify the ASN.1
762
       structure, so we need to replace it with a fresh
763
       structure. */
764
0
    result = crt_reinit(cert);
765
0
    if (result < 0) {
766
0
      gnutls_assert();
767
0
      goto cleanup;
768
0
    }
769
0
  }
770
771
  /* If the Certificate is in PEM format then decode it
772
   */
773
0
  if (format == GNUTLS_X509_FMT_PEM) {
774
    /* Try the first header */
775
0
    result = _gnutls_fbase64_decode(PEM_X509_CERT2, data->data,
776
0
            data->size, &cert->der);
777
778
0
    if (result < 0) {
779
      /* try for the second header */
780
0
      result = _gnutls_fbase64_decode(PEM_X509_CERT,
781
0
              data->data, data->size,
782
0
              &cert->der);
783
784
0
      if (result < 0) {
785
0
        gnutls_assert();
786
0
        return result;
787
0
      }
788
0
    }
789
0
  } else {
790
0
    result = _gnutls_set_datum(&cert->der, data->data, data->size);
791
0
    if (result < 0) {
792
0
      gnutls_assert();
793
0
      return result;
794
0
    }
795
0
  }
796
797
0
  cert->expanded = 1;
798
0
  cert->modified = 0;
799
800
0
  result = _asn1_strict_der_decode(&cert->cert, cert->der.data,
801
0
           cert->der.size, NULL);
802
0
  if (result != ASN1_SUCCESS) {
803
0
    result = _gnutls_asn2err(result);
804
0
    gnutls_assert();
805
0
    goto cleanup;
806
0
  }
807
808
0
  result = compare_sig_algorithm(cert);
809
0
  if (result < 0) {
810
0
    gnutls_assert();
811
0
    goto cleanup;
812
0
  }
813
814
  /* The following do not allocate but rather point to DER data */
815
0
  result = _gnutls_x509_get_raw_field2(
816
0
    cert->cert, &cert->der, "tbsCertificate.issuer.rdnSequence",
817
0
    &cert->raw_issuer_dn);
818
0
  if (result < 0) {
819
0
    gnutls_assert();
820
0
    goto cleanup;
821
0
  }
822
823
0
  result = _gnutls_x509_get_raw_field2(
824
0
    cert->cert, &cert->der, "tbsCertificate.subject.rdnSequence",
825
0
    &cert->raw_dn);
826
0
  if (result < 0) {
827
0
    gnutls_assert();
828
0
    goto cleanup;
829
0
  }
830
831
0
  result = _gnutls_x509_get_raw_field2(
832
0
    cert->cert, &cert->der, "tbsCertificate.subjectPublicKeyInfo",
833
0
    &cert->raw_spki);
834
0
  if (result < 0) {
835
0
    gnutls_assert();
836
0
    goto cleanup;
837
0
  }
838
839
0
  result = cache_alt_names(cert);
840
0
  if (result < 0) {
841
0
    gnutls_assert();
842
0
    goto cleanup;
843
0
  }
844
845
0
  result = _gnutls_check_cert_sanity(cert);
846
0
  if (result < 0) {
847
0
    gnutls_assert();
848
0
    goto cleanup;
849
0
  }
850
851
  /* Since we do not want to disable any extension
852
   */
853
0
  cert->use_extensions = 1;
854
855
0
  return 0;
856
857
0
cleanup:
858
0
  _gnutls_free_datum(&cert->der);
859
0
  return result;
860
0
}
861
862
/**
863
 * gnutls_x509_crt_get_issuer_dn:
864
 * @cert: should contain a #gnutls_x509_crt_t type
865
 * @buf: a pointer to a structure to hold the name (may be null)
866
 * @buf_size: initially holds the size of @buf
867
 *
868
 * This function will copy the name of the Certificate issuer in the
869
 * provided buffer. The name will be in the form
870
 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
871
 * will be ASCII or UTF-8 encoded, depending on the certificate data.
872
 *
873
 * If @buf is null then only the size will be filled.
874
 *
875
 * This function does not output a fully RFC4514 compliant string, if
876
 * that is required see gnutls_x509_crt_get_issuer_dn3().
877
 *
878
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
879
 *   long enough, and in that case the @buf_size will be updated
880
 *   with the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if
881
 *   the DN does not exist, or another error value on error. On success 0 is returned.
882
 **/
883
int gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert, char *buf,
884
          size_t *buf_size)
885
0
{
886
0
  if (cert == NULL) {
887
0
    gnutls_assert();
888
0
    return GNUTLS_E_INVALID_REQUEST;
889
0
  }
890
891
0
  return _gnutls_x509_parse_dn(cert->cert,
892
0
             "tbsCertificate.issuer.rdnSequence", buf,
893
0
             buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
894
0
}
895
896
/**
897
 * gnutls_x509_crt_get_issuer_dn2:
898
 * @cert: should contain a #gnutls_x509_crt_t type
899
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
900
 *
901
 * This function will allocate buffer and copy the name of issuer of the Certificate.
902
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
903
 * described in RFC4514. The output string will be ASCII or UTF-8
904
 * encoded, depending on the certificate data.
905
 *
906
 * This function does not output a fully RFC4514 compliant string, if
907
 * that is required see gnutls_x509_crt_get_issuer_dn3().
908
 *
909
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
910
 *   negative error value.
911
 *
912
 * Since: 3.1.10
913
 **/
914
int gnutls_x509_crt_get_issuer_dn2(gnutls_x509_crt_t cert, gnutls_datum_t *dn)
915
0
{
916
0
  if (cert == NULL) {
917
0
    gnutls_assert();
918
0
    return GNUTLS_E_INVALID_REQUEST;
919
0
  }
920
921
0
  return _gnutls_x509_get_dn(cert->cert,
922
0
           "tbsCertificate.issuer.rdnSequence", dn,
923
0
           GNUTLS_X509_DN_FLAG_COMPAT);
924
0
}
925
926
/**
927
 * gnutls_x509_crt_get_issuer_dn3:
928
 * @cert: should contain a #gnutls_x509_crt_t type
929
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
930
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
931
 *
932
 * This function will allocate buffer and copy the name of issuer of the Certificate.
933
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
934
 * described in RFC4514. The output string will be ASCII or UTF-8
935
 * encoded, depending on the certificate data.
936
 *
937
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
938
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
939
 * which was not not fully RFC4514-compliant.
940
 *
941
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
942
 *   negative error value.
943
 *
944
 * Since: 3.5.7
945
 **/
946
int gnutls_x509_crt_get_issuer_dn3(gnutls_x509_crt_t cert, gnutls_datum_t *dn,
947
           unsigned flags)
948
0
{
949
0
  if (cert == NULL) {
950
0
    gnutls_assert();
951
0
    return GNUTLS_E_INVALID_REQUEST;
952
0
  }
953
954
0
  return _gnutls_x509_get_dn(
955
0
    cert->cert, "tbsCertificate.issuer.rdnSequence", dn, flags);
956
0
}
957
958
/**
959
 * gnutls_x509_crt_get_issuer_dn_by_oid:
960
 * @cert: should contain a #gnutls_x509_crt_t type
961
 * @oid: holds an Object Identified in null terminated string
962
 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
963
 * @raw_flag: If non-zero returns the raw DER data of the DN part.
964
 * @buf: a pointer to a structure to hold the name (may be null)
965
 * @buf_size: initially holds the size of @buf
966
 *
967
 * This function will extract the part of the name of the Certificate
968
 * issuer specified by the given OID. The output, if the raw flag is not
969
 * used, will be encoded as described in RFC4514. Thus a string that is
970
 * ASCII or UTF-8 encoded, depending on the certificate data.
971
 *
972
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
973
 * If raw flag is (0), this function will only return known OIDs as
974
 * text. Other OIDs will be DER encoded, as described in RFC4514 --
975
 * in hex format with a '#' prefix.  You can check about known OIDs
976
 * using gnutls_x509_dn_oid_known().
977
 *
978
 * If @buf is null then only the size will be filled. If the @raw_flag
979
 * is not specified the output is always null terminated, although the
980
 * @buf_size will not include the null character.
981
 *
982
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
983
 *   long enough, and in that case the @buf_size will be updated with
984
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
985
 *   are no data in the current index. On success 0 is returned.
986
 **/
987
int gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
988
           const char *oid, unsigned indx,
989
           unsigned int raw_flag, void *buf,
990
           size_t *buf_size)
991
0
{
992
0
  gnutls_datum_t td;
993
0
  int ret;
994
995
0
  if (cert == NULL) {
996
0
    gnutls_assert();
997
0
    return GNUTLS_E_INVALID_REQUEST;
998
0
  }
999
1000
0
  ret = _gnutls_x509_parse_dn_oid(cert->cert,
1001
0
          "tbsCertificate.issuer.rdnSequence",
1002
0
          oid, indx, raw_flag, &td);
1003
0
  if (ret < 0)
1004
0
    return gnutls_assert_val(ret);
1005
1006
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
1007
0
}
1008
1009
/**
1010
 * gnutls_x509_crt_get_issuer_dn_oid:
1011
 * @cert: should contain a #gnutls_x509_crt_t type
1012
 * @indx: This specifies which OID to return. Use (0) to get the first one.
1013
 * @oid: a pointer to a buffer to hold the OID (may be null)
1014
 * @oid_size: initially holds the size of @oid
1015
 *
1016
 * This function will extract the OIDs of the name of the Certificate
1017
 * issuer specified by the given index.
1018
 *
1019
 * If @oid is null then only the size will be filled. The @oid
1020
 * returned will be null terminated, although @oid_size will not
1021
 * account for the trailing null.
1022
 *
1023
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1024
 *   long enough, and in that case the @buf_size will be updated with
1025
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1026
 *   are no data in the current index. On success 0 is returned.
1027
 **/
1028
int gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert, unsigned indx,
1029
              void *oid, size_t *oid_size)
1030
0
{
1031
0
  if (cert == NULL) {
1032
0
    gnutls_assert();
1033
0
    return GNUTLS_E_INVALID_REQUEST;
1034
0
  }
1035
1036
0
  return _gnutls_x509_get_dn_oid(cert->cert,
1037
0
               "tbsCertificate.issuer.rdnSequence",
1038
0
               indx, oid, oid_size);
1039
0
}
1040
1041
/**
1042
 * gnutls_x509_crt_get_dn:
1043
 * @cert: should contain a #gnutls_x509_crt_t type
1044
 * @buf: a pointer to a structure to hold the name (may be null)
1045
 * @buf_size: initially holds the size of @buf
1046
 *
1047
 * This function will copy the name of the Certificate in the provided
1048
 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
1049
 * described in RFC4514. The output string will be ASCII or UTF-8
1050
 * encoded, depending on the certificate data.
1051
 *
1052
 * The @buf returned will be null terminated and the @buf_size will account
1053
 * for the trailing null. If @buf is null then only the size will be filled.
1054
 *
1055
 * This function does not output a fully RFC4514 compliant string, if
1056
 * that is required see gnutls_x509_crt_get_dn3().
1057
 *
1058
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1059
 *   long enough, and in that case the @buf_size will be updated
1060
 *   with the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if
1061
 *   the DN does not exist, or another error value on error. On success 0 is returned.
1062
 **/
1063
int gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert, char *buf, size_t *buf_size)
1064
0
{
1065
0
  if (cert == NULL) {
1066
0
    gnutls_assert();
1067
0
    return GNUTLS_E_INVALID_REQUEST;
1068
0
  }
1069
1070
0
  return _gnutls_x509_parse_dn(cert->cert,
1071
0
             "tbsCertificate.subject.rdnSequence", buf,
1072
0
             buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
1073
0
}
1074
1075
/**
1076
 * gnutls_x509_crt_get_dn2:
1077
 * @cert: should contain a #gnutls_x509_crt_t type
1078
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
1079
 *
1080
 * This function will allocate buffer and copy the name of the Certificate.
1081
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
1082
 * described in RFC4514. The output string will be ASCII or UTF-8
1083
 * encoded, depending on the certificate data.
1084
 *
1085
 * This function does not output a fully RFC4514 compliant string, if
1086
 * that is required see gnutls_x509_crt_get_dn3().
1087
 *
1088
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1089
 *   negative error value.
1090
 *
1091
 * Since: 3.1.10
1092
 **/
1093
int gnutls_x509_crt_get_dn2(gnutls_x509_crt_t cert, gnutls_datum_t *dn)
1094
0
{
1095
0
  if (cert == NULL) {
1096
0
    gnutls_assert();
1097
0
    return GNUTLS_E_INVALID_REQUEST;
1098
0
  }
1099
1100
0
  return _gnutls_x509_get_dn(cert->cert,
1101
0
           "tbsCertificate.subject.rdnSequence", dn,
1102
0
           GNUTLS_X509_DN_FLAG_COMPAT);
1103
0
}
1104
1105
/**
1106
 * gnutls_x509_crt_get_dn3:
1107
 * @cert: should contain a #gnutls_x509_crt_t type
1108
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
1109
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
1110
 *
1111
 * This function will allocate buffer and copy the name of the Certificate.
1112
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
1113
 * described in RFC4514. The output string will be ASCII or UTF-8
1114
 * encoded, depending on the certificate data.
1115
 *
1116
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
1117
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
1118
 * which was not not fully RFC4514-compliant.
1119
 *
1120
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1121
 *   negative error value.
1122
 *
1123
 * Since: 3.5.7
1124
 **/
1125
int gnutls_x509_crt_get_dn3(gnutls_x509_crt_t cert, gnutls_datum_t *dn,
1126
          unsigned flags)
1127
0
{
1128
0
  if (cert == NULL) {
1129
0
    gnutls_assert();
1130
0
    return GNUTLS_E_INVALID_REQUEST;
1131
0
  }
1132
1133
0
  return _gnutls_x509_get_dn(
1134
0
    cert->cert, "tbsCertificate.subject.rdnSequence", dn, flags);
1135
0
}
1136
1137
/**
1138
 * gnutls_x509_crt_get_dn_by_oid:
1139
 * @cert: should contain a #gnutls_x509_crt_t type
1140
 * @oid: holds an Object Identified in null terminated string
1141
 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
1142
 * @raw_flag: If non-zero returns the raw DER data of the DN part.
1143
 * @buf: a pointer where the DN part will be copied (may be null).
1144
 * @buf_size: initially holds the size of @buf
1145
 *
1146
 * This function will extract the part of the name of the Certificate
1147
 * subject specified by the given OID. The output, if the raw flag is
1148
 * not used, will be encoded as described in RFC4514. Thus a string
1149
 * that is ASCII or UTF-8 encoded, depending on the certificate data.
1150
 *
1151
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
1152
 * If raw flag is (0), this function will only return known OIDs as
1153
 * text. Other OIDs will be DER encoded, as described in RFC4514 --
1154
 * in hex format with a '#' prefix.  You can check about known OIDs
1155
 * using gnutls_x509_dn_oid_known().
1156
 *
1157
 * If @buf is null then only the size will be filled. If the @raw_flag
1158
 * is not specified the output is always null terminated, although the
1159
 * @buf_size will not include the null character.
1160
 *
1161
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1162
 *   long enough, and in that case the @buf_size will be updated with
1163
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1164
 *   are no data in the current index. On success 0 is returned.
1165
 **/
1166
int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert, const char *oid,
1167
          unsigned indx, unsigned int raw_flag,
1168
          void *buf, size_t *buf_size)
1169
0
{
1170
0
  gnutls_datum_t td;
1171
0
  int ret;
1172
1173
0
  if (cert == NULL) {
1174
0
    gnutls_assert();
1175
0
    return GNUTLS_E_INVALID_REQUEST;
1176
0
  }
1177
1178
0
  ret = _gnutls_x509_parse_dn_oid(cert->cert,
1179
0
          "tbsCertificate.subject.rdnSequence",
1180
0
          oid, indx, raw_flag, &td);
1181
0
  if (ret < 0)
1182
0
    return gnutls_assert_val(ret);
1183
1184
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
1185
0
}
1186
1187
/**
1188
 * gnutls_x509_crt_get_dn_oid:
1189
 * @cert: should contain a #gnutls_x509_crt_t type
1190
 * @indx: This specifies which OID to return. Use (0) to get the first one.
1191
 * @oid: a pointer to a buffer to hold the OID (may be null)
1192
 * @oid_size: initially holds the size of @oid
1193
 *
1194
 * This function will extract the OIDs of the name of the Certificate
1195
 * subject specified by the given index.
1196
 *
1197
 * If @oid is null then only the size will be filled. The @oid
1198
 * returned will be null terminated, although @oid_size will not
1199
 * account for the trailing null.
1200
 *
1201
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1202
 *   long enough, and in that case the @buf_size will be updated with
1203
 *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1204
 *   are no data in the current index. On success 0 is returned.
1205
 **/
1206
int gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert, unsigned indx, void *oid,
1207
             size_t *oid_size)
1208
0
{
1209
0
  if (cert == NULL) {
1210
0
    gnutls_assert();
1211
0
    return GNUTLS_E_INVALID_REQUEST;
1212
0
  }
1213
1214
0
  return _gnutls_x509_get_dn_oid(cert->cert,
1215
0
               "tbsCertificate.subject.rdnSequence",
1216
0
               indx, oid, oid_size);
1217
0
}
1218
1219
/**
1220
 * gnutls_x509_crt_get_signature_algorithm:
1221
 * @cert: should contain a #gnutls_x509_crt_t type
1222
 *
1223
 * This function will return a value of the #gnutls_sign_algorithm_t
1224
 * enumeration that is the signature algorithm that has been used to
1225
 * sign this certificate.
1226
 *
1227
 * Since 3.6.0 this function never returns a negative error code.
1228
 * Error cases and unknown/unsupported signature algorithms are
1229
 * mapped to %GNUTLS_SIGN_UNKNOWN.
1230
 *
1231
 * Returns: a #gnutls_sign_algorithm_t value
1232
 **/
1233
int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert)
1234
0
{
1235
0
  return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(
1236
0
    cert->cert, "signatureAlgorithm"));
1237
0
}
1238
1239
/**
1240
 * gnutls_x509_crt_get_signature_oid:
1241
 * @cert: should contain a #gnutls_x509_crt_t type
1242
 * @oid: a pointer to a buffer to hold the OID (may be null)
1243
 * @oid_size: initially holds the size of @oid
1244
 *
1245
 * This function will return the OID of the signature algorithm
1246
 * that has been used to sign this certificate. This is function
1247
 * is useful in the case gnutls_x509_crt_get_signature_algorithm()
1248
 * returned %GNUTLS_SIGN_UNKNOWN.
1249
 *
1250
 * Returns: zero or a negative error code on error.
1251
 *
1252
 * Since: 3.5.0
1253
 **/
1254
int gnutls_x509_crt_get_signature_oid(gnutls_x509_crt_t cert, char *oid,
1255
              size_t *oid_size)
1256
0
{
1257
0
  char str[MAX_OID_SIZE];
1258
0
  int len, result, ret;
1259
0
  gnutls_datum_t out;
1260
1261
0
  len = sizeof(str);
1262
0
  result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm",
1263
0
         str, &len);
1264
0
  if (result != ASN1_SUCCESS) {
1265
0
    gnutls_assert();
1266
0
    return _gnutls_asn2err(result);
1267
0
  }
1268
1269
0
  out.data = (void *)str;
1270
0
  out.size = len;
1271
1272
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1273
0
  if (ret < 0) {
1274
0
    gnutls_assert();
1275
0
    return ret;
1276
0
  }
1277
1278
0
  return 0;
1279
0
}
1280
1281
/**
1282
 * gnutls_x509_crt_get_pk_oid:
1283
 * @cert: should contain a #gnutls_x509_crt_t type
1284
 * @oid: a pointer to a buffer to hold the OID (may be null)
1285
 * @oid_size: initially holds the size of @oid
1286
 *
1287
 * This function will return the OID of the public key algorithm
1288
 * on that certificate. This is function
1289
 * is useful in the case gnutls_x509_crt_get_pk_algorithm()
1290
 * returned %GNUTLS_PK_UNKNOWN.
1291
 *
1292
 * Returns: zero or a negative error code on error.
1293
 *
1294
 * Since: 3.5.0
1295
 **/
1296
int gnutls_x509_crt_get_pk_oid(gnutls_x509_crt_t cert, char *oid,
1297
             size_t *oid_size)
1298
0
{
1299
0
  char str[MAX_OID_SIZE];
1300
0
  int len, result, ret;
1301
0
  gnutls_datum_t out;
1302
1303
0
  len = sizeof(str);
1304
0
  result = asn1_read_value(
1305
0
    cert->cert,
1306
0
    "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", str,
1307
0
    &len);
1308
0
  if (result != ASN1_SUCCESS) {
1309
0
    gnutls_assert();
1310
0
    return _gnutls_asn2err(result);
1311
0
  }
1312
1313
0
  out.data = (void *)str;
1314
0
  out.size = len;
1315
1316
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1317
0
  if (ret < 0) {
1318
0
    gnutls_assert();
1319
0
    return ret;
1320
0
  }
1321
1322
0
  return 0;
1323
0
}
1324
1325
/**
1326
 * gnutls_x509_crt_get_signature:
1327
 * @cert: should contain a #gnutls_x509_crt_t type
1328
 * @sig: a pointer where the signature part will be copied (may be null).
1329
 * @sig_size: initially holds the size of @sig
1330
 *
1331
 * This function will extract the signature field of a certificate.
1332
 *
1333
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1334
 *   negative error value.
1335
 **/
1336
int gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert, char *sig,
1337
          size_t *sig_size)
1338
0
{
1339
0
  gnutls_datum_t dsig = { NULL, 0 };
1340
0
  int ret;
1341
1342
0
  if (cert == NULL)
1343
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1344
1345
0
  ret = _gnutls_x509_get_signature(cert->cert, "signature", &dsig);
1346
0
  if (ret < 0)
1347
0
    return gnutls_assert_val(ret);
1348
1349
0
  ret = _gnutls_copy_data(&dsig, (uint8_t *)sig, sig_size);
1350
0
  if (ret < 0) {
1351
0
    gnutls_assert();
1352
0
    goto cleanup;
1353
0
  }
1354
1355
0
  ret = 0;
1356
0
cleanup:
1357
0
  gnutls_free(dsig.data);
1358
0
  return ret;
1359
0
}
1360
1361
/**
1362
 * gnutls_x509_crt_get_version:
1363
 * @cert: should contain a #gnutls_x509_crt_t type
1364
 *
1365
 * This function will return the version of the specified Certificate.
1366
 *
1367
 * Returns: version of certificate, or a negative error code on error.
1368
 **/
1369
int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)
1370
0
{
1371
0
  if (cert == NULL) {
1372
0
    gnutls_assert();
1373
0
    return GNUTLS_E_INVALID_REQUEST;
1374
0
  }
1375
1376
0
  return _gnutls_x509_get_version(cert->cert, "tbsCertificate.version");
1377
0
}
1378
1379
/**
1380
 * gnutls_x509_crt_get_activation_time:
1381
 * @cert: should contain a #gnutls_x509_crt_t type
1382
 *
1383
 * This function will return the time this Certificate was or will be
1384
 * activated.
1385
 *
1386
 * Returns: activation time, or (time_t)-1 on error.
1387
 **/
1388
time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert)
1389
0
{
1390
0
  if (cert == NULL) {
1391
0
    gnutls_assert();
1392
0
    return (time_t)-1;
1393
0
  }
1394
1395
0
  return _gnutls_x509_get_time(cert->cert,
1396
0
             "tbsCertificate.validity.notBefore", 0);
1397
0
}
1398
1399
/**
1400
 * gnutls_x509_crt_get_expiration_time:
1401
 * @cert: should contain a #gnutls_x509_crt_t type
1402
 *
1403
 * This function will return the time this certificate was or will be
1404
 * expired.
1405
 *
1406
 * Returns: expiration time, or (time_t)-1 on error.
1407
 **/
1408
time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert)
1409
0
{
1410
0
  if (cert == NULL) {
1411
0
    gnutls_assert();
1412
0
    return (time_t)-1;
1413
0
  }
1414
1415
0
  return _gnutls_x509_get_time(cert->cert,
1416
0
             "tbsCertificate.validity.notAfter", 0);
1417
0
}
1418
1419
/**
1420
 * gnutls_x509_crt_get_private_key_usage_period:
1421
 * @cert: should contain a #gnutls_x509_crt_t type
1422
 * @activation: The activation time
1423
 * @expiration: The expiration time
1424
 * @critical: the extension status
1425
 *
1426
 * This function will return the expiration and activation
1427
 * times of the private key of the certificate. It relies on
1428
 * the PKIX extension 2.5.29.16 being present.
1429
 *
1430
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1431
 * if the extension is not present, otherwise a negative error value.
1432
 **/
1433
int gnutls_x509_crt_get_private_key_usage_period(gnutls_x509_crt_t cert,
1434
             time_t *activation,
1435
             time_t *expiration,
1436
             unsigned int *critical)
1437
0
{
1438
0
  int ret;
1439
0
  gnutls_datum_t der = { NULL, 0 };
1440
1441
0
  if (cert == NULL) {
1442
0
    gnutls_assert();
1443
0
    return GNUTLS_E_INVALID_REQUEST;
1444
0
  }
1445
1446
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.16", 0, &der,
1447
0
               critical);
1448
0
  if (ret < 0)
1449
0
    return gnutls_assert_val(ret);
1450
1451
0
  if (der.size == 0 || der.data == NULL)
1452
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1453
1454
0
  ret = gnutls_x509_ext_import_private_key_usage_period(&der, activation,
1455
0
                    expiration);
1456
0
  if (ret < 0) {
1457
0
    gnutls_assert();
1458
0
    goto cleanup;
1459
0
  }
1460
1461
0
  ret = 0;
1462
1463
0
cleanup:
1464
0
  _gnutls_free_datum(&der);
1465
1466
0
  return ret;
1467
0
}
1468
1469
/**
1470
 * gnutls_x509_crt_get_serial:
1471
 * @cert: should contain a #gnutls_x509_crt_t type
1472
 * @result: The place where the serial number will be copied
1473
 * @result_size: Holds the size of the result field.
1474
 *
1475
 * This function will return the X.509 certificate's serial number.
1476
 * This is obtained by the X509 Certificate serialNumber field. Serial
1477
 * is not always a 32 or 64bit number. Some CAs use large serial
1478
 * numbers, thus it may be wise to handle it as something uint8_t.
1479
 *
1480
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1481
 *   negative error value.
1482
 **/
1483
int gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert, void *result,
1484
             size_t *result_size)
1485
0
{
1486
0
  int ret, len;
1487
1488
0
  if (cert == NULL) {
1489
0
    gnutls_assert();
1490
0
    return GNUTLS_E_INVALID_REQUEST;
1491
0
  }
1492
1493
0
  len = *result_size;
1494
0
  ret = asn1_read_value(cert->cert, "tbsCertificate.serialNumber", result,
1495
0
            &len);
1496
0
  *result_size = len;
1497
1498
0
  if (ret != ASN1_SUCCESS) {
1499
0
    gnutls_assert();
1500
0
    return _gnutls_asn2err(ret);
1501
0
  }
1502
1503
0
  return 0;
1504
0
}
1505
1506
/**
1507
 * gnutls_x509_crt_get_subject_key_id:
1508
 * @cert: should contain a #gnutls_x509_crt_t type
1509
 * @ret: The place where the identifier will be copied
1510
 * @ret_size: Holds the size of the result field.
1511
 * @critical: will be non-zero if the extension is marked as critical (may be null)
1512
 *
1513
 * This function will return the X.509v3 certificate's subject key
1514
 * identifier.  This is obtained by the X.509 Subject Key identifier
1515
 * extension field (2.5.29.14).
1516
 *
1517
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1518
 * if the extension is not present, otherwise a negative error value.
1519
 **/
1520
int gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert, void *ret,
1521
               size_t *ret_size, unsigned int *critical)
1522
0
{
1523
0
  int result;
1524
0
  gnutls_datum_t id = { NULL, 0 };
1525
0
  gnutls_datum_t der = { NULL, 0 };
1526
1527
0
  if (cert == NULL) {
1528
0
    gnutls_assert();
1529
0
    return GNUTLS_E_INVALID_REQUEST;
1530
0
  }
1531
1532
0
  if (ret == NULL)
1533
0
    *ret_size = 0;
1534
1535
0
  if ((result = _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &der,
1536
0
                 critical)) < 0) {
1537
0
    return result;
1538
0
  }
1539
1540
0
  result = gnutls_x509_ext_import_subject_key_id(&der, &id);
1541
0
  if (result < 0) {
1542
0
    gnutls_assert();
1543
0
    goto cleanup;
1544
0
  }
1545
1546
0
  result = _gnutls_copy_data(&id, ret, ret_size);
1547
0
  if (result < 0) {
1548
0
    gnutls_assert();
1549
0
    goto cleanup;
1550
0
  }
1551
1552
0
  result = 0;
1553
1554
0
cleanup:
1555
0
  gnutls_free(der.data);
1556
0
  gnutls_free(id.data);
1557
0
  return result;
1558
0
}
1559
1560
inline static int is_type_printable(int type)
1561
0
{
1562
0
  if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1563
0
      type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP ||
1564
0
      type == GNUTLS_SAN_OTHERNAME_SRV || type == GNUTLS_SAN_OTHERNAME ||
1565
0
      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 == NULL || 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 (memeq(serial, cert_serial, serial_size)) {
3296
          /* serials match */
3297
0
          if (func)
3298
0
            func(cert, NULL, crl_list[j],
3299
0
                 GNUTLS_CERT_REVOKED |
3300
0
                   GNUTLS_CERT_INVALID);
3301
0
          ret = 1; /* revoked! */
3302
0
          goto fail;
3303
0
        }
3304
0
      }
3305
0
    } while (1);
3306
3307
0
    gnutls_x509_crl_iter_deinit(iter);
3308
0
    iter = NULL;
3309
3310
0
    if (func)
3311
0
      func(cert, NULL, crl_list[j], 0);
3312
0
  }
3313
0
  return 0; /* not revoked. */
3314
3315
0
fail:
3316
0
  gnutls_x509_crl_iter_deinit(iter);
3317
0
  return ret;
3318
0
}
3319
3320
/**
3321
 * gnutls_x509_crt_check_revocation:
3322
 * @cert: should contain a #gnutls_x509_crt_t type
3323
 * @crl_list: should contain a list of gnutls_x509_crl_t types
3324
 * @crl_list_length: the length of the crl_list
3325
 *
3326
 * This function will check if the given certificate is
3327
 * revoked.  It is assumed that the CRLs have been verified before.
3328
 *
3329
 * Returns: 0 if the certificate is NOT revoked, and 1 if it is.  A
3330
 * negative error code is returned on error.
3331
 **/
3332
int gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3333
             const gnutls_x509_crl_t *crl_list,
3334
             unsigned crl_list_length)
3335
0
{
3336
0
  return _gnutls_x509_crt_check_revocation(cert, crl_list,
3337
0
             crl_list_length, NULL);
3338
0
}
3339
3340
/**
3341
 * gnutls_x509_crt_check_key_purpose:
3342
 * @cert: should contain a #gnutls_x509_crt_t type
3343
 * @purpose: a key purpose OID (e.g., %GNUTLS_KP_CODE_SIGNING)
3344
 * @flags: zero or %GNUTLS_KP_FLAG_DISALLOW_ANY
3345
 *
3346
 * This function will check whether the given certificate matches
3347
 * the provided key purpose. If @flags contains %GNUTLS_KP_FLAG_ALLOW_ANY then
3348
 * it a certificate marked for any purpose will not match.
3349
 *
3350
 * Returns: zero if the key purpose doesn't match, and non-zero otherwise.
3351
 *
3352
 * Since: 3.5.6
3353
 **/
3354
unsigned gnutls_x509_crt_check_key_purpose(gnutls_x509_crt_t cert,
3355
             const char *purpose, unsigned flags)
3356
0
{
3357
0
  return _gnutls_check_key_purpose(
3358
0
    cert, purpose, (flags & GNUTLS_KP_FLAG_DISALLOW_ANY) ? 1 : 0);
3359
0
}
3360
3361
/**
3362
 * gnutls_x509_crt_get_preferred_hash_algorithm:
3363
 * @crt: Holds the certificate
3364
 * @hash: The result of the call with the hash algorithm used for signature
3365
 * @mand: If non-zero it means that the algorithm MUST use this hash. May be %NULL.
3366
 *
3367
 * This function will read the certificate and return the appropriate digest
3368
 * algorithm to use for signing with this certificate. Some certificates (i.e.
3369
 * DSA might not be able to sign without the preferred algorithm).
3370
 *
3371
 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
3372
 *
3373
 * Returns: the 0 if the hash algorithm is found. A negative error code is
3374
 * returned on error.
3375
 *
3376
 * Since: 2.12.0
3377
 **/
3378
int gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,
3379
             gnutls_digest_algorithm_t *hash,
3380
             unsigned int *mand)
3381
0
{
3382
0
  int ret;
3383
0
  gnutls_pubkey_t pubkey;
3384
3385
0
  if (crt == NULL) {
3386
0
    gnutls_assert();
3387
0
    return GNUTLS_E_INVALID_REQUEST;
3388
0
  }
3389
3390
0
  ret = gnutls_pubkey_init(&pubkey);
3391
0
  if (ret < 0)
3392
0
    return gnutls_assert_val(ret);
3393
3394
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3395
0
  if (ret < 0) {
3396
0
    gnutls_assert();
3397
0
    goto cleanup;
3398
0
  }
3399
3400
0
  ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, hash, mand);
3401
0
  if (ret < 0) {
3402
0
    gnutls_assert();
3403
0
    goto cleanup;
3404
0
  }
3405
3406
0
cleanup:
3407
0
  gnutls_pubkey_deinit(pubkey);
3408
0
  return ret;
3409
0
}
3410
3411
/**
3412
 * gnutls_x509_crt_get_crl_dist_points:
3413
 * @cert: should contain a #gnutls_x509_crt_t type
3414
 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3415
 * @san: is the place where the distribution point will be copied to
3416
 * @san_size: holds the size of ret.
3417
 * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3418
 * @critical: will be non-zero if the extension is marked as critical (may be null)
3419
 *
3420
 * This function retrieves the CRL distribution points (2.5.29.31),
3421
 * contained in the given certificate in the X509v3 Certificate
3422
 * Extensions.
3423
 *
3424
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3425
 *   @ret_size is not enough to hold the distribution point, or the
3426
 *   type of the distribution point if everything was ok. The type is
3427
 *   one of the enumerated %gnutls_x509_subject_alt_name_t.  If the
3428
 *   certificate does not have an Alternative name with the specified
3429
 *   sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3430
 *   returned.
3431
 **/
3432
int gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
3433
          unsigned int seq, void *san,
3434
          size_t *san_size,
3435
          unsigned int *reason_flags,
3436
          unsigned int *critical)
3437
0
{
3438
0
  int ret;
3439
0
  gnutls_datum_t dist_points = { NULL, 0 };
3440
0
  unsigned type;
3441
0
  gnutls_x509_crl_dist_points_t cdp = NULL;
3442
0
  gnutls_datum_t t_san;
3443
3444
0
  if (cert == NULL) {
3445
0
    gnutls_assert();
3446
0
    return GNUTLS_E_INVALID_REQUEST;
3447
0
  }
3448
3449
0
  ret = gnutls_x509_crl_dist_points_init(&cdp);
3450
0
  if (ret < 0)
3451
0
    return gnutls_assert_val(ret);
3452
3453
0
  if (reason_flags)
3454
0
    *reason_flags = 0;
3455
3456
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.31", 0, &dist_points,
3457
0
               critical);
3458
0
  if (ret < 0) {
3459
0
    gnutls_assert();
3460
0
    goto cleanup;
3461
0
  }
3462
3463
0
  if (dist_points.size == 0 || dist_points.data == NULL) {
3464
0
    gnutls_assert();
3465
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3466
0
    goto cleanup;
3467
0
  }
3468
3469
0
  ret = gnutls_x509_ext_import_crl_dist_points(&dist_points, cdp, 0);
3470
0
  if (ret < 0) {
3471
0
    gnutls_assert();
3472
0
    goto cleanup;
3473
0
  }
3474
3475
0
  ret = gnutls_x509_crl_dist_points_get(cdp, seq, &type, &t_san,
3476
0
                reason_flags);
3477
0
  if (ret < 0) {
3478
0
    gnutls_assert();
3479
0
    goto cleanup;
3480
0
  }
3481
3482
0
  ret = _gnutls_copy_string(&t_san, san, san_size);
3483
0
  if (ret < 0) {
3484
0
    gnutls_assert();
3485
0
    goto cleanup;
3486
0
  }
3487
3488
0
  ret = type;
3489
3490
0
cleanup:
3491
0
  _gnutls_free_datum(&dist_points);
3492
0
  if (cdp != NULL)
3493
0
    gnutls_x509_crl_dist_points_deinit(cdp);
3494
3495
0
  return ret;
3496
0
}
3497
3498
/**
3499
 * gnutls_x509_crt_get_key_purpose_oid:
3500
 * @cert: should contain a #gnutls_x509_crt_t type
3501
 * @indx: This specifies which OID to return. Use (0) to get the first one.
3502
 * @oid: a pointer to a buffer to hold the OID (may be null)
3503
 * @oid_size: initially holds the size of @oid
3504
 * @critical: output flag to indicate criticality of extension
3505
 *
3506
 * This function will extract the key purpose OIDs of the Certificate
3507
 * specified by the given index.  These are stored in the Extended Key
3508
 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3509
 * human readable names.
3510
 *
3511
 * If @oid is null then only the size will be filled. The @oid
3512
 * returned will be null terminated, although @oid_size will not
3513
 * account for the trailing null.
3514
 *
3515
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3516
 *   not long enough, and in that case the *oid_size will be updated
3517
 *   with the required size.  On success 0 is returned.
3518
 **/
3519
int gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert, unsigned indx,
3520
          void *oid, size_t *oid_size,
3521
          unsigned int *critical)
3522
0
{
3523
0
  int ret;
3524
0
  gnutls_datum_t ext;
3525
0
  gnutls_x509_key_purposes_t p = NULL;
3526
0
  gnutls_datum_t out;
3527
3528
0
  if (cert == NULL) {
3529
0
    gnutls_assert();
3530
0
    return GNUTLS_E_INVALID_REQUEST;
3531
0
  }
3532
3533
0
  if (oid)
3534
0
    memset(oid, 0, *oid_size);
3535
0
  else
3536
0
    *oid_size = 0;
3537
3538
0
  if ((ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &ext,
3539
0
              critical)) < 0) {
3540
0
    return ret;
3541
0
  }
3542
3543
0
  if (ext.size == 0 || ext.data == NULL) {
3544
0
    gnutls_assert();
3545
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3546
0
  }
3547
3548
0
  ret = gnutls_x509_key_purpose_init(&p);
3549
0
  if (ret < 0) {
3550
0
    gnutls_assert();
3551
0
    goto cleanup;
3552
0
  }
3553
3554
0
  ret = gnutls_x509_ext_import_key_purposes(&ext, p, 0);
3555
0
  if (ret < 0) {
3556
0
    gnutls_assert();
3557
0
    goto cleanup;
3558
0
  }
3559
3560
0
  ret = gnutls_x509_key_purpose_get(p, indx, &out);
3561
0
  if (ret < 0) {
3562
0
    gnutls_assert();
3563
0
    goto cleanup;
3564
0
  }
3565
3566
0
  ret = _gnutls_copy_string(&out, oid, oid_size);
3567
0
  if (ret < 0) {
3568
0
    gnutls_assert();
3569
0
    goto cleanup;
3570
0
  }
3571
3572
0
  ret = 0;
3573
3574
0
cleanup:
3575
0
  gnutls_free(ext.data);
3576
0
  if (p != NULL)
3577
0
    gnutls_x509_key_purpose_deinit(p);
3578
0
  return ret;
3579
0
}
3580
3581
/**
3582
 * gnutls_x509_crt_get_pk_rsa_raw:
3583
 * @crt: Holds the certificate
3584
 * @m: will hold the modulus
3585
 * @e: will hold the public exponent
3586
 *
3587
 * This function will export the RSA public key's parameters found in
3588
 * the given structure.  The new parameters will be allocated using
3589
 * gnutls_malloc() and will be stored in the appropriate datum.
3590
 *
3591
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3592
 **/
3593
int gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt, gnutls_datum_t *m,
3594
           gnutls_datum_t *e)
3595
0
{
3596
0
  int ret;
3597
0
  gnutls_pubkey_t pubkey;
3598
3599
0
  if (crt == NULL) {
3600
0
    gnutls_assert();
3601
0
    return GNUTLS_E_INVALID_REQUEST;
3602
0
  }
3603
3604
0
  ret = gnutls_pubkey_init(&pubkey);
3605
0
  if (ret < 0)
3606
0
    return gnutls_assert_val(ret);
3607
3608
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3609
0
  if (ret < 0) {
3610
0
    gnutls_assert();
3611
0
    goto cleanup;
3612
0
  }
3613
3614
0
  ret = gnutls_pubkey_export_rsa_raw(pubkey, m, e);
3615
0
  if (ret < 0) {
3616
0
    gnutls_assert();
3617
0
    goto cleanup;
3618
0
  }
3619
3620
0
cleanup:
3621
0
  gnutls_pubkey_deinit(pubkey);
3622
0
  return ret;
3623
0
}
3624
3625
/**
3626
 * gnutls_x509_crt_get_pk_ecc_raw:
3627
 * @crt: Holds the certificate
3628
 * @curve: will hold the curve
3629
 * @x: will hold the x-coordinate
3630
 * @y: will hold the y-coordinate
3631
 *
3632
 * This function will export the ECC public key's parameters found in
3633
 * the given certificate.  The new parameters will be allocated using
3634
 * gnutls_malloc() and will be stored in the appropriate datum.
3635
 *
3636
 * In EdDSA curves the @y parameter will be %NULL and the other parameters
3637
 * will be in the native format for the curve.
3638
 *
3639
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3640
 *
3641
 * Since: 3.4.1
3642
 **/
3643
int gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,
3644
           gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
3645
           gnutls_datum_t *y)
3646
0
{
3647
0
  int ret;
3648
0
  gnutls_pubkey_t pubkey;
3649
3650
0
  if (crt == NULL) {
3651
0
    gnutls_assert();
3652
0
    return GNUTLS_E_INVALID_REQUEST;
3653
0
  }
3654
3655
0
  ret = gnutls_pubkey_init(&pubkey);
3656
0
  if (ret < 0)
3657
0
    return gnutls_assert_val(ret);
3658
3659
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3660
0
  if (ret < 0) {
3661
0
    gnutls_assert();
3662
0
    goto cleanup;
3663
0
  }
3664
3665
0
  ret = gnutls_pubkey_export_ecc_raw(pubkey, curve, x, y);
3666
0
  if (ret < 0) {
3667
0
    gnutls_assert();
3668
0
    goto cleanup;
3669
0
  }
3670
3671
0
cleanup:
3672
0
  gnutls_pubkey_deinit(pubkey);
3673
0
  return ret;
3674
0
}
3675
3676
/**
3677
 * gnutls_x509_crt_get_pk_gost_raw:
3678
 * @crt: Holds the certificate
3679
 * @curve: will hold the curve
3680
 * @digest: will hold the digest
3681
 * @paramset: will hold the GOST parameter set ID
3682
 * @x: will hold the x-coordinate
3683
 * @y: will hold the y-coordinate
3684
 *
3685
 * This function will export the GOST public key's parameters found in
3686
 * the given certificate.  The new parameters will be allocated using
3687
 * gnutls_malloc() and will be stored in the appropriate datum.
3688
 *
3689
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3690
 *
3691
 * Since: 3.6.3
3692
 **/
3693
int gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,
3694
            gnutls_ecc_curve_t *curve,
3695
            gnutls_digest_algorithm_t *digest,
3696
            gnutls_gost_paramset_t *paramset,
3697
            gnutls_datum_t *x, gnutls_datum_t *y)
3698
0
{
3699
0
  int ret;
3700
0
  gnutls_pubkey_t pubkey;
3701
3702
0
  if (crt == NULL) {
3703
0
    gnutls_assert();
3704
0
    return GNUTLS_E_INVALID_REQUEST;
3705
0
  }
3706
3707
0
  ret = gnutls_pubkey_init(&pubkey);
3708
0
  if (ret < 0)
3709
0
    return gnutls_assert_val(ret);
3710
3711
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3712
0
  if (ret < 0) {
3713
0
    gnutls_assert();
3714
0
    goto cleanup;
3715
0
  }
3716
3717
0
  ret = gnutls_pubkey_export_gost_raw2(pubkey, curve, digest, paramset, x,
3718
0
               y, 0);
3719
0
  if (ret < 0) {
3720
0
    gnutls_assert();
3721
0
    goto cleanup;
3722
0
  }
3723
3724
0
cleanup:
3725
0
  gnutls_pubkey_deinit(pubkey);
3726
0
  return ret;
3727
0
}
3728
3729
/**
3730
 * gnutls_x509_crt_get_pk_dsa_raw:
3731
 * @crt: Holds the certificate
3732
 * @p: will hold the p
3733
 * @q: will hold the q
3734
 * @g: will hold the g
3735
 * @y: will hold the y
3736
 *
3737
 * This function will export the DSA public key's parameters found in
3738
 * the given certificate.  The new parameters will be allocated using
3739
 * gnutls_malloc() and will be stored in the appropriate datum.
3740
 *
3741
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3742
 **/
3743
int gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt, gnutls_datum_t *p,
3744
           gnutls_datum_t *q, gnutls_datum_t *g,
3745
           gnutls_datum_t *y)
3746
0
{
3747
0
  int ret;
3748
0
  gnutls_pubkey_t pubkey;
3749
3750
0
  if (crt == NULL) {
3751
0
    gnutls_assert();
3752
0
    return GNUTLS_E_INVALID_REQUEST;
3753
0
  }
3754
3755
0
  ret = gnutls_pubkey_init(&pubkey);
3756
0
  if (ret < 0)
3757
0
    return gnutls_assert_val(ret);
3758
3759
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3760
0
  if (ret < 0) {
3761
0
    gnutls_assert();
3762
0
    goto cleanup;
3763
0
  }
3764
3765
0
  ret = gnutls_pubkey_export_dsa_raw(pubkey, p, q, g, y);
3766
0
  if (ret < 0) {
3767
0
    gnutls_assert();
3768
0
    goto cleanup;
3769
0
  }
3770
3771
0
cleanup:
3772
0
  gnutls_pubkey_deinit(pubkey);
3773
0
  return ret;
3774
0
}
3775
3776
/**
3777
 * gnutls_x509_crt_list_import2:
3778
 * @certs: Will hold the parsed certificate list.
3779
 * @size: It will contain the size of the list.
3780
 * @data: The PEM encoded certificate.
3781
 * @format: One of DER or PEM.
3782
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3783
 *
3784
 * This function will convert the given PEM encoded certificate list
3785
 * to the native gnutls_x509_crt_t format. The output will be stored
3786
 * in @certs which will be allocated and initialized.
3787
 *
3788
 * If the Certificate is PEM encoded it should have a header of "X509
3789
 * CERTIFICATE", or "CERTIFICATE".
3790
 *
3791
 * To deinitialize @certs, you need to deinitialize each crt structure
3792
 * independently, and use gnutls_free() at @certs.
3793
 *
3794
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3795
 *
3796
 * Since: 3.0
3797
 **/
3798
int gnutls_x509_crt_list_import2(gnutls_x509_crt_t **certs, unsigned int *size,
3799
         const gnutls_datum_t *data,
3800
         gnutls_x509_crt_fmt_t format,
3801
         unsigned int flags)
3802
0
{
3803
0
  unsigned int init = 1024;
3804
0
  int ret;
3805
3806
0
  *certs = _gnutls_reallocarray(NULL, init, sizeof(gnutls_x509_crt_t));
3807
0
  if (*certs == NULL) {
3808
0
    gnutls_assert();
3809
0
    return GNUTLS_E_MEMORY_ERROR;
3810
0
  }
3811
3812
0
  ret = gnutls_x509_crt_list_import(
3813
0
    *certs, &init, data, format,
3814
0
    flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3815
0
  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
3816
0
    *certs = _gnutls_reallocarray_fast(*certs, init,
3817
0
               sizeof(gnutls_x509_crt_t));
3818
0
    if (*certs == NULL) {
3819
0
      gnutls_assert();
3820
0
      return GNUTLS_E_MEMORY_ERROR;
3821
0
    }
3822
3823
0
    ret = gnutls_x509_crt_list_import(*certs, &init, data, format,
3824
0
              flags);
3825
0
  }
3826
3827
0
  if (ret < 0) {
3828
0
    gnutls_free(*certs);
3829
0
    return ret;
3830
0
  }
3831
3832
0
  *size = init;
3833
0
  return 0;
3834
0
}
3835
3836
/**
3837
 * gnutls_x509_crt_list_import:
3838
 * @certs: Indicates where the parsed list will be copied to. Must not be initialized.
3839
 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3840
 * @data: The PEM encoded certificate.
3841
 * @format: One of DER or PEM.
3842
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3843
 *
3844
 * This function will convert the given PEM encoded certificate list
3845
 * to the native gnutls_x509_crt_t format. The output will be stored
3846
 * in @certs.  They will be automatically initialized.
3847
 *
3848
 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3849
 * import to fail if the certificates in the provided buffer are more
3850
 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3851
 * flag will cause the function to fail if the provided list is not
3852
 * sorted from subject to issuer.
3853
 *
3854
 * If the Certificate is PEM encoded it should have a header of "X509
3855
 * CERTIFICATE", or "CERTIFICATE".
3856
 *
3857
 * Returns: the number of certificates read or a negative error value.
3858
 **/
3859
int gnutls_x509_crt_list_import(gnutls_x509_crt_t *certs,
3860
        unsigned int *cert_max,
3861
        const gnutls_datum_t *data,
3862
        gnutls_x509_crt_fmt_t format,
3863
        unsigned int flags)
3864
0
{
3865
0
  int size;
3866
0
  const char *ptr;
3867
0
  gnutls_datum_t tmp;
3868
0
  int ret, nocopy = 0;
3869
0
  unsigned int count = 0, j, copied = 0;
3870
3871
0
  if (format == GNUTLS_X509_FMT_DER) {
3872
0
    if (*cert_max < 1) {
3873
0
      *cert_max = 1;
3874
0
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
3875
0
    }
3876
3877
0
    count = 1; /* import only the first one */
3878
3879
0
    ret = gnutls_x509_crt_init(&certs[0]);
3880
0
    if (ret < 0) {
3881
0
      gnutls_assert();
3882
0
      goto error;
3883
0
    }
3884
3885
0
    ret = gnutls_x509_crt_import(certs[0], data, format);
3886
0
    if (ret < 0) {
3887
0
      gnutls_assert();
3888
0
      goto error;
3889
0
    }
3890
3891
0
    *cert_max = 1;
3892
0
    return 1;
3893
0
  }
3894
3895
  /* move to the certificate
3896
   */
3897
0
  ptr = memmem(data->data, data->size, PEM_CERT_SEP,
3898
0
         sizeof(PEM_CERT_SEP) - 1);
3899
0
  if (ptr == NULL)
3900
0
    ptr = memmem(data->data, data->size, PEM_CERT_SEP2,
3901
0
           sizeof(PEM_CERT_SEP2) - 1);
3902
3903
0
  if (ptr == NULL)
3904
0
    return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3905
3906
0
  count = 0;
3907
3908
0
  do {
3909
0
    if (count >= *cert_max) {
3910
0
      if (!(flags &
3911
0
            GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3912
0
        break;
3913
0
      else
3914
0
        nocopy = 1;
3915
0
    }
3916
3917
0
    if (!nocopy) {
3918
0
      ret = gnutls_x509_crt_init(&certs[count]);
3919
0
      if (ret < 0) {
3920
0
        gnutls_assert();
3921
0
        goto error;
3922
0
      }
3923
3924
0
      tmp.data = (void *)ptr;
3925
0
      tmp.size = data->size - (ptr - (char *)data->data);
3926
3927
0
      ret = gnutls_x509_crt_import(certs[count], &tmp,
3928
0
                 GNUTLS_X509_FMT_PEM);
3929
0
      if (ret < 0) {
3930
0
        count++;
3931
0
        gnutls_assert();
3932
0
        goto error;
3933
0
      }
3934
3935
0
      copied++;
3936
0
    }
3937
3938
    /* now we move ptr after the pem header
3939
     */
3940
0
    ptr++;
3941
    /* find the next certificate (if any)
3942
     */
3943
0
    size = data->size - (ptr - (char *)data->data);
3944
3945
0
    if (size > 0) {
3946
0
      char *ptr2;
3947
3948
0
      ptr2 = memmem(ptr, size, PEM_CERT_SEP,
3949
0
              sizeof(PEM_CERT_SEP) - 1);
3950
0
      if (ptr2 == NULL)
3951
0
        ptr2 = memmem(ptr, size, PEM_CERT_SEP2,
3952
0
                sizeof(PEM_CERT_SEP2) - 1);
3953
3954
0
      ptr = ptr2;
3955
0
    } else
3956
0
      ptr = NULL;
3957
3958
0
    count++;
3959
0
  } while (ptr != NULL);
3960
3961
0
  *cert_max = count;
3962
3963
0
  if (nocopy == 0) {
3964
0
    if (flags & GNUTLS_X509_CRT_LIST_SORT && *cert_max > 1) {
3965
0
      if (*cert_max > DEFAULT_MAX_VERIFY_DEPTH) {
3966
0
        ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
3967
0
        goto error;
3968
0
      }
3969
0
      count = _gnutls_sort_clist(certs, *cert_max);
3970
0
      if (count < *cert_max) {
3971
0
        for (j = count; j < *cert_max; j++) {
3972
0
          gnutls_x509_crt_deinit(certs[j]);
3973
0
        }
3974
0
      }
3975
0
      *cert_max = count;
3976
0
    }
3977
3978
0
    if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) {
3979
0
      ret = _gnutls_check_if_sorted(certs, *cert_max);
3980
0
      if (ret < 0) {
3981
0
        gnutls_assert();
3982
0
        goto error;
3983
0
      }
3984
0
    }
3985
3986
0
    return count;
3987
0
  } else {
3988
0
    count = copied;
3989
0
    ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
3990
0
  }
3991
3992
0
error:
3993
0
  for (j = 0; j < count; j++)
3994
0
    gnutls_x509_crt_deinit(certs[j]);
3995
0
  return ret;
3996
0
}
3997
3998
/**
3999
 * gnutls_x509_crt_get_subject_unique_id:
4000
 * @crt: Holds the certificate
4001
 * @buf: user allocated memory buffer, will hold the unique id
4002
 * @buf_size: size of user allocated memory buffer (on input), will hold
4003
 * actual size of the unique ID on return.
4004
 *
4005
 * This function will extract the subjectUniqueID value (if present) for
4006
 * the given certificate.
4007
 *
4008
 * If the user allocated memory buffer is not large enough to hold the
4009
 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
4010
 * returned, and buf_size will be set to the actual length.
4011
 *
4012
 * This function had a bug prior to 3.4.8 that prevented the setting
4013
 * of %NULL @buf to discover the @buf_size. To use this function safely
4014
 * with the older versions the @buf must be a valid buffer that can hold
4015
 * at least a single byte if @buf_size is zero.
4016
 *
4017
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
4018
 **/
4019
int gnutls_x509_crt_get_subject_unique_id(gnutls_x509_crt_t crt, char *buf,
4020
            size_t *buf_size)
4021
0
{
4022
0
  int result;
4023
0
  gnutls_datum_t datum = { NULL, 0 };
4024
4025
0
  result = _gnutls_x509_read_value(
4026
0
    crt->cert, "tbsCertificate.subjectUniqueID", &datum);
4027
0
  if (result < 0)
4028
0
    return gnutls_assert_val(result);
4029
4030
0
  if (datum.size > *buf_size) { /* then we're not going to fit */
4031
0
    *buf_size = datum.size;
4032
0
    result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4033
0
  } else {
4034
0
    *buf_size = datum.size;
4035
0
    memcpy(buf, datum.data, datum.size);
4036
0
  }
4037
4038
0
  _gnutls_free_datum(&datum);
4039
4040
0
  return result;
4041
0
}
4042
4043
/**
4044
 * gnutls_x509_crt_get_issuer_unique_id:
4045
 * @crt: Holds the certificate
4046
 * @buf: user allocated memory buffer, will hold the unique id
4047
 * @buf_size: size of user allocated memory buffer (on input), will hold
4048
 * actual size of the unique ID on return.
4049
 *
4050
 * This function will extract the issuerUniqueID value (if present) for
4051
 * the given certificate.
4052
 *
4053
 * If the user allocated memory buffer is not large enough to hold the
4054
 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
4055
 * returned, and buf_size will be set to the actual length.
4056
 *
4057
 * This function had a bug prior to 3.4.8 that prevented the setting
4058
 * of %NULL @buf to discover the @buf_size. To use this function safely
4059
 * with the older versions the @buf must be a valid buffer that can hold
4060
 * at least a single byte if @buf_size is zero.
4061
 *
4062
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
4063
 *
4064
 * Since: 2.12.0
4065
 **/
4066
int gnutls_x509_crt_get_issuer_unique_id(gnutls_x509_crt_t crt, char *buf,
4067
           size_t *buf_size)
4068
0
{
4069
0
  int result;
4070
0
  gnutls_datum_t datum = { NULL, 0 };
4071
4072
0
  result = _gnutls_x509_read_value(
4073
0
    crt->cert, "tbsCertificate.issuerUniqueID", &datum);
4074
0
  if (result < 0)
4075
0
    return gnutls_assert_val(result);
4076
4077
0
  if (datum.size > *buf_size) { /* then we're not going to fit */
4078
0
    *buf_size = datum.size;
4079
0
    result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4080
0
  } else {
4081
0
    *buf_size = datum.size;
4082
0
    memcpy(buf, datum.data, datum.size);
4083
0
  }
4084
4085
0
  _gnutls_free_datum(&datum);
4086
4087
0
  return result;
4088
0
}
4089
4090
static int legacy_parse_aia(asn1_node src, unsigned int seq, int what,
4091
          gnutls_datum_t *data)
4092
0
{
4093
0
  int len;
4094
0
  char nptr[MAX_NAME_SIZE];
4095
0
  int result;
4096
0
  gnutls_datum_t d;
4097
0
  const char *oid = NULL;
4098
4099
0
  seq++; /* 0->1, 1->2 etc */
4100
0
  switch (what) {
4101
0
  case GNUTLS_IA_ACCESSMETHOD_OID:
4102
0
    snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4103
0
    break;
4104
4105
0
  case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
4106
0
    snprintf(nptr, sizeof(nptr), "?%u.accessLocation", seq);
4107
0
    break;
4108
4109
0
  case GNUTLS_IA_CAISSUERS_URI:
4110
0
    oid = GNUTLS_OID_AD_CAISSUERS;
4111
0
    FALLTHROUGH;
4112
4113
0
  case GNUTLS_IA_OCSP_URI:
4114
0
    if (oid == NULL)
4115
0
      oid = GNUTLS_OID_AD_OCSP;
4116
0
    {
4117
0
      char tmpoid[MAX_OID_SIZE];
4118
0
      snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4119
0
      len = sizeof(tmpoid);
4120
0
      result = asn1_read_value(src, nptr, tmpoid, &len);
4121
4122
0
      if (result == ASN1_VALUE_NOT_FOUND ||
4123
0
          result == ASN1_ELEMENT_NOT_FOUND)
4124
0
        return gnutls_assert_val(
4125
0
          GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4126
4127
0
      if (result != ASN1_SUCCESS) {
4128
0
        gnutls_assert();
4129
0
        return _gnutls_asn2err(result);
4130
0
      }
4131
0
      if ((unsigned)len != strlen(oid) + 1 ||
4132
0
          !memeq(tmpoid, oid, len))
4133
0
        return gnutls_assert_val(
4134
0
          GNUTLS_E_UNKNOWN_ALGORITHM);
4135
0
    }
4136
0
    FALLTHROUGH;
4137
4138
0
  case GNUTLS_IA_URI:
4139
0
    snprintf(nptr, sizeof(nptr),
4140
0
       "?%u.accessLocation.uniformResourceIdentifier", seq);
4141
0
    break;
4142
4143
0
  default:
4144
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4145
0
  }
4146
4147
0
  len = 0;
4148
0
  result = asn1_read_value(src, nptr, NULL, &len);
4149
0
  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
4150
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4151
4152
0
  if (result != ASN1_MEM_ERROR) {
4153
0
    gnutls_assert();
4154
0
    return _gnutls_asn2err(result);
4155
0
  }
4156
4157
0
  d.size = len;
4158
4159
0
  d.data = gnutls_malloc(d.size);
4160
0
  if (d.data == NULL)
4161
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
4162
4163
0
  result = asn1_read_value(src, nptr, d.data, &len);
4164
0
  if (result != ASN1_SUCCESS) {
4165
0
    gnutls_assert();
4166
0
    gnutls_free(d.data);
4167
0
    return _gnutls_asn2err(result);
4168
0
  }
4169
4170
0
  if (data) {
4171
0
    data->data = d.data;
4172
0
    data->size = d.size;
4173
0
  } else
4174
0
    gnutls_free(d.data);
4175
4176
0
  return 0;
4177
0
}
4178
4179
/**
4180
 * gnutls_x509_crt_get_authority_info_access:
4181
 * @crt: Holds the certificate
4182
 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
4183
 * @what: what data to get, a #gnutls_info_access_what_t type.
4184
 * @data: output data to be freed with gnutls_free().
4185
 * @critical: pointer to output integer that is set to non-zero if the extension is marked as critical (may be %NULL)
4186
 *
4187
 * Note that a simpler API to access the authority info data is provided
4188
 * by gnutls_x509_aia_get() and gnutls_x509_ext_import_aia().
4189
 *
4190
 * This function extracts the Authority Information Access (AIA)
4191
 * extension, see RFC 5280 section 4.2.2.1 for more information.  The
4192
 * AIA extension holds a sequence of AccessDescription (AD) data.
4193
 *
4194
 * The @seq input parameter is used to indicate which member of the
4195
 * sequence the caller is interested in.  The first member is 0, the
4196
 * second member 1 and so on.  When the @seq value is out of bounds,
4197
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
4198
 *
4199
 * The type of data returned in @data is specified via @what which
4200
 * should be #gnutls_info_access_what_t values.
4201
 *
4202
 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
4203
 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
4204
 *
4205
 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
4206
 * hold the accessLocation GeneralName type (e.g.,
4207
 * "uniformResourceIdentifier").
4208
 *
4209
 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
4210
 * data.  Requesting this @what value leads to an error if the
4211
 * accessLocation is not of the "uniformResourceIdentifier" type.
4212
 *
4213
 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
4214
 * Requesting this @what value leads to an error if the accessMethod
4215
 * is not 1.3.6.1.5.5.7.48.1 aka OCSP, or if accessLocation is not of
4216
 * the "uniformResourceIdentifier" type. In that case %GNUTLS_E_UNKNOWN_ALGORITHM
4217
 * will be returned, and @seq should be increased and this function
4218
 * called again.
4219
 *
4220
 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
4221
 * URI.  Requesting this @what value leads to an error if the
4222
 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
4223
 * accessLocation is not of the "uniformResourceIdentifier" type.
4224
 * In that case handle as in %GNUTLS_IA_OCSP_URI.
4225
 *
4226
 * More @what values may be allocated in the future as needed.
4227
 *
4228
 * If @data is NULL, the function does the same without storing the
4229
 * output data, that is, it will set @critical and do error checking
4230
 * as usual.
4231
 *
4232
 * The value of the critical flag is returned in *@critical.  Supply a
4233
 * NULL @critical if you want the function to make sure the extension
4234
 * is non-critical, as required by RFC 5280.
4235
 *
4236
 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
4237
 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
4238
 * incorrectly marked as critical (use a non-NULL @critical to
4239
 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
4240
 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
4241
 * negative error code.
4242
 *
4243
 * Since: 3.0
4244
 **/
4245
int gnutls_x509_crt_get_authority_info_access(gnutls_x509_crt_t crt,
4246
                unsigned int seq, int what,
4247
                gnutls_datum_t *data,
4248
                unsigned int *critical)
4249
0
{
4250
0
  int ret;
4251
0
  gnutls_datum_t aia;
4252
0
  asn1_node c2 = NULL;
4253
4254
0
  if (crt == NULL) {
4255
0
    gnutls_assert();
4256
0
    return GNUTLS_E_INVALID_REQUEST;
4257
0
  }
4258
4259
0
  if ((ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia,
4260
0
              critical)) < 0)
4261
0
    return ret;
4262
4263
0
  if (aia.size == 0 || aia.data == NULL) {
4264
0
    gnutls_assert();
4265
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
4266
0
  }
4267
4268
0
  if (critical && *critical)
4269
0
    return GNUTLS_E_CONSTRAINT_ERROR;
4270
4271
0
  ret = asn1_create_element(_gnutls_get_pkix(),
4272
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
4273
0
  if (ret != ASN1_SUCCESS) {
4274
0
    gnutls_assert();
4275
0
    _gnutls_free_datum(&aia);
4276
0
    return _gnutls_asn2err(ret);
4277
0
  }
4278
4279
0
  ret = _asn1_strict_der_decode(&c2, aia.data, aia.size, NULL);
4280
  /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
4281
0
  _gnutls_free_datum(&aia);
4282
0
  if (ret != ASN1_SUCCESS) {
4283
0
    gnutls_assert();
4284
0
    asn1_delete_structure(&c2);
4285
0
    return _gnutls_asn2err(ret);
4286
0
  }
4287
4288
0
  ret = legacy_parse_aia(c2, seq, what, data);
4289
4290
0
  asn1_delete_structure(&c2);
4291
0
  if (ret < 0)
4292
0
    gnutls_assert();
4293
4294
0
  return ret;
4295
0
}
4296
4297
/**
4298
 * gnutls_x509_crt_set_pin_function:
4299
 * @crt: The certificate structure
4300
 * @fn: the callback
4301
 * @userdata: data associated with the callback
4302
 *
4303
 * This function will set a callback function to be used when
4304
 * it is required to access a protected object. This function overrides
4305
 * the global function set using gnutls_pkcs11_set_pin_function().
4306
 *
4307
 * Note that this callback is currently used only during the import
4308
 * of a PKCS #11 certificate with gnutls_x509_crt_import_url().
4309
 *
4310
 * Since: 3.1.0
4311
 *
4312
 **/
4313
void gnutls_x509_crt_set_pin_function(gnutls_x509_crt_t crt,
4314
              gnutls_pin_callback_t fn, void *userdata)
4315
0
{
4316
0
  if (crt) {
4317
0
    crt->pin.cb = fn;
4318
0
    crt->pin.data = userdata;
4319
0
  }
4320
0
}
4321
4322
/**
4323
 * gnutls_x509_crt_import_url:
4324
 * @crt: A certificate of type #gnutls_x509_crt_t
4325
 * @url: A PKCS 11 url
4326
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4327
 *
4328
 * This function will import a certificate present in a PKCS#11 token
4329
 * or any type of back-end that supports URLs.
4330
 *
4331
 * In previous versions of gnutls this function was named
4332
 * gnutls_x509_crt_import_pkcs11_url, and the old name is
4333
 * an alias to this one.
4334
 *
4335
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4336
 *   negative error value.
4337
 *
4338
 * Since: 3.4.0
4339
 **/
4340
int gnutls_x509_crt_import_url(gnutls_x509_crt_t crt, const char *url,
4341
             unsigned int flags)
4342
0
{
4343
0
  int ret;
4344
0
  unsigned i;
4345
4346
0
  for (i = 0; i < _gnutls_custom_urls_size; i++) {
4347
0
    if (strncmp(url, _gnutls_custom_urls[i].name,
4348
0
          _gnutls_custom_urls[i].name_size) == 0) {
4349
0
      if (_gnutls_custom_urls[i].import_crt) {
4350
0
        ret = _gnutls_custom_urls[i].import_crt(
4351
0
          crt, url, flags);
4352
0
        goto cleanup;
4353
0
      }
4354
0
      break;
4355
0
    }
4356
0
  }
4357
4358
0
  if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
4359
0
    ret = _gnutls_x509_crt_import_system_url(crt, url);
4360
#ifdef ENABLE_PKCS11
4361
  } else if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
4362
    ret = _gnutls_x509_crt_import_pkcs11_url(crt, url, flags);
4363
#endif
4364
0
  } else {
4365
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4366
0
  }
4367
4368
0
cleanup:
4369
0
  return ret;
4370
0
}
4371
4372
/**
4373
 * gnutls_x509_crt_list_import_url:
4374
 * @certs: Will hold the allocated certificate list.
4375
 * @size: It will contain the size of the list.
4376
 * @url: A PKCS 11 url
4377
 * @pin_fn: a PIN callback if not globally set
4378
 * @pin_fn_userdata: parameter for the PIN callback
4379
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4380
 *
4381
 * This function will import a certificate chain present in a PKCS#11 token
4382
 * or any type of back-end that supports URLs. The certificates
4383
 * must be deinitialized afterwards using gnutls_x509_crt_deinit()
4384
 * and the returned pointer must be freed using gnutls_free().
4385
 *
4386
 * The URI provided must be the first certificate in the chain; subsequent
4387
 * certificates will be retrieved using gnutls_pkcs11_get_raw_issuer() or
4388
 * equivalent functionality for the supported URI.
4389
 *
4390
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4391
 *   negative error value.
4392
 *
4393
 * Since: 3.6.3
4394
 **/
4395
int gnutls_x509_crt_list_import_url(gnutls_x509_crt_t **certs,
4396
            unsigned int *size, const char *url,
4397
            gnutls_pin_callback_t pin_fn,
4398
            void *pin_fn_userdata, unsigned int flags)
4399
0
{
4400
0
  int ret;
4401
0
  unsigned i;
4402
0
  gnutls_x509_crt_t crts[DEFAULT_MAX_VERIFY_DEPTH];
4403
0
  gnutls_datum_t issuer = { NULL, 0 };
4404
0
  unsigned total = 0;
4405
4406
0
  memset(crts, 0, sizeof(crts));
4407
4408
0
  ret = gnutls_x509_crt_init(&crts[0]);
4409
0
  if (ret < 0)
4410
0
    return gnutls_assert_val(ret);
4411
4412
0
  gnutls_x509_crt_set_pin_function(crts[0], pin_fn, pin_fn_userdata);
4413
4414
0
  total = 1;
4415
4416
0
  ret = gnutls_x509_crt_import_url(crts[0], url, flags);
4417
0
  if (ret < 0) {
4418
0
    gnutls_assert();
4419
0
    goto cleanup;
4420
0
  }
4421
4422
0
  for (i = 1; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
4423
0
    ret = _gnutls_get_raw_issuer(
4424
0
      url, crts[i - 1], &issuer,
4425
0
      flags | GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_ANY);
4426
0
    if (ret < 0) {
4427
0
      issuer.data = NULL;
4428
0
      break;
4429
0
    }
4430
4431
0
    if (gnutls_x509_crt_equals2(crts[i - 1], &issuer)) {
4432
0
      gnutls_free(issuer.data);
4433
0
      break;
4434
0
    }
4435
4436
0
    ret = gnutls_x509_crt_init(&crts[i]);
4437
0
    if (ret < 0) {
4438
0
      gnutls_assert();
4439
0
      goto cleanup;
4440
0
    }
4441
4442
0
    total++;
4443
4444
0
    gnutls_x509_crt_set_pin_function(crts[i], pin_fn,
4445
0
             pin_fn_userdata);
4446
4447
0
    ret = gnutls_x509_crt_import(crts[i], &issuer,
4448
0
               GNUTLS_X509_FMT_DER);
4449
0
    if (ret < 0) {
4450
0
      gnutls_assert();
4451
0
      goto cleanup;
4452
0
    }
4453
4454
0
    gnutls_free(issuer.data);
4455
0
  }
4456
4457
0
  *certs = _gnutls_reallocarray(NULL, total, sizeof(gnutls_x509_crt_t));
4458
0
  if (*certs == NULL) {
4459
0
    ret = GNUTLS_E_MEMORY_ERROR;
4460
0
    goto cleanup;
4461
0
  }
4462
4463
0
  memcpy(*certs, crts, total * sizeof(gnutls_x509_crt_t));
4464
0
  *size = total;
4465
4466
0
  return 0;
4467
0
cleanup:
4468
0
  gnutls_free(issuer.data);
4469
0
  for (i = 0; i < total; i++)
4470
0
    gnutls_x509_crt_deinit(crts[i]);
4471
4472
0
  return ret;
4473
0
}
4474
4475
/*-
4476
 * gnutls_x509_crt_verify_data3:
4477
 * @crt: Holds the certificate to verify with
4478
 * @algo: The signature algorithm used
4479
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4480
 * @data: holds the signed data
4481
 * @signature: contains the signature
4482
 *
4483
 * This function will verify the given signed data, using the
4484
 * parameters from the certificate.
4485
 *
4486
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4487
 * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4488
 * or not yet activated certificate and zero or positive code on success.
4489
 *
4490
 * Since: 3.5.6
4491
 -*/
4492
int gnutls_x509_crt_verify_data3(gnutls_x509_crt_t crt,
4493
         gnutls_sign_algorithm_t algo,
4494
         gnutls_typed_vdata_st *vdata,
4495
         unsigned int vdata_size,
4496
         const gnutls_datum_t *data,
4497
         const gnutls_datum_t *signature,
4498
         unsigned int flags)
4499
0
{
4500
0
  int ret;
4501
0
  gnutls_pubkey_t pubkey;
4502
4503
0
  if (crt == NULL) {
4504
0
    gnutls_assert();
4505
0
    return GNUTLS_E_INVALID_REQUEST;
4506
0
  }
4507
4508
0
  ret = gnutls_pubkey_init(&pubkey);
4509
0
  if (ret < 0)
4510
0
    return gnutls_assert_val(ret);
4511
4512
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
4513
0
  if (ret < 0)
4514
0
    return gnutls_assert_val(ret);
4515
4516
0
  ret = gnutls_pubkey_verify_data2(pubkey, algo, flags, data, signature);
4517
0
  gnutls_pubkey_deinit(pubkey);
4518
4519
0
  if (ret >= 0) {
4520
0
    time_t now = gnutls_time(NULL);
4521
0
    int res;
4522
0
    unsigned usage, i;
4523
4524
0
    if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) ||
4525
0
        !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
4526
0
      if (now > gnutls_x509_crt_get_expiration_time(crt)) {
4527
0
        return gnutls_assert_val(GNUTLS_E_EXPIRED);
4528
0
      }
4529
4530
0
      if (now < gnutls_x509_crt_get_activation_time(crt)) {
4531
0
        return gnutls_assert_val(
4532
0
          GNUTLS_E_NOT_YET_ACTIVATED);
4533
0
      }
4534
0
    }
4535
4536
0
    res = gnutls_x509_crt_get_key_usage(crt, &usage, NULL);
4537
0
    if (res >= 0) {
4538
0
      if (!(usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
4539
0
        return gnutls_assert_val(
4540
0
          GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4541
0
      }
4542
0
    }
4543
4544
0
    for (i = 0; i < vdata_size; i++) {
4545
0
      if (vdata[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
4546
0
        res = _gnutls_check_key_purpose(
4547
0
          crt, (char *)vdata[i].data, 0);
4548
0
        if (res == 0)
4549
0
          return gnutls_assert_val(
4550
0
            GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4551
0
        break;
4552
0
      }
4553
0
    }
4554
0
  }
4555
4556
0
  return ret;
4557
0
}
4558
4559
/**
4560
 * gnutls_x509_crt_verify_data2:
4561
 * @crt: Holds the certificate to verify with
4562
 * @algo: The signature algorithm used
4563
 * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4564
 * @data: holds the signed data
4565
 * @signature: contains the signature
4566
 *
4567
 * This function will verify the given signed data, using the
4568
 * parameters from the certificate.
4569
 *
4570
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4571
 * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4572
 * or not yet activated certificate and zero or positive code on success.
4573
 *
4574
 * Note that since GnuTLS 3.5.6 this function introduces checks in the
4575
 * end certificate (@crt), including time checks and key usage checks.
4576
 *
4577
 * Since: 3.4.0
4578
 **/
4579
int gnutls_x509_crt_verify_data2(gnutls_x509_crt_t crt,
4580
         gnutls_sign_algorithm_t algo,
4581
         unsigned int flags, const gnutls_datum_t *data,
4582
         const gnutls_datum_t *signature)
4583
0
{
4584
0
  return gnutls_x509_crt_verify_data3(crt, algo, NULL, 0, data, signature,
4585
0
              flags);
4586
0
}
4587
4588
/**
4589
 * gnutls_x509_crt_set_flags:
4590
 * @cert: A type #gnutls_x509_crt_t
4591
 * @flags: flags from the %gnutls_x509_crt_flags
4592
 *
4593
 * This function will set flags for the specified certificate.
4594
 * Currently this is useful for the %GNUTLS_X509_CRT_FLAG_IGNORE_SANITY
4595
 * which allows importing certificates even if they have known issues.
4596
 *
4597
 * Since: 3.6.0
4598
 *
4599
 **/
4600
void gnutls_x509_crt_set_flags(gnutls_x509_crt_t cert, unsigned int flags)
4601
0
{
4602
0
  cert->flags = flags;
4603
0
}