Coverage Report

Created: 2024-02-25 06:35

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