Coverage Report

Created: 2023-11-27 06:16

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