Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/crl.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2015-2016 Red Hat, Inc.
4
 *
5
 * Author: Nikos Mavrogiannopoulos
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
#include "gnutls_int.h"
25
#include <libtasn1.h>
26
27
#include <datum.h>
28
#include <global.h>
29
#include "errors.h"
30
#include <common.h>
31
#include <x509_b64.h>
32
#include <x509_int.h>
33
#include <x509.h>
34
35
static int crl_reinit(gnutls_x509_crl_t crl)
36
0
{
37
0
  int result;
38
39
0
  if (crl->crl)
40
0
    asn1_delete_structure(&crl->crl);
41
42
0
  result = asn1_create_element(_gnutls_get_pkix(),
43
0
             "PKIX1.CertificateList", &crl->crl);
44
0
  if (result != ASN1_SUCCESS) {
45
0
    gnutls_assert();
46
0
    return _gnutls_asn2err(result);
47
0
  }
48
0
  crl->rcache = NULL;
49
0
  crl->rcache_idx = 0;
50
0
  crl->raw_issuer_dn.size = 0;
51
52
0
  return 0;
53
0
}
54
55
/**
56
 * gnutls_x509_crl_init:
57
 * @crl: A pointer to the type to be initialized
58
 *
59
 * This function will initialize a CRL structure. CRL stands for
60
 * Certificate Revocation List. A revocation list usually contains
61
 * lists of certificate serial numbers that have been revoked by an
62
 * Authority. The revocation lists are always signed with the
63
 * authority's private key.
64
 *
65
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
66
 *   negative error value.
67
 **/
68
int gnutls_x509_crl_init(gnutls_x509_crl_t * crl)
69
0
{
70
0
  *crl = NULL;
71
0
  FAIL_IF_LIB_ERROR;
72
73
0
  *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
74
75
0
  if (*crl) {
76
0
    int result = crl_reinit(*crl);
77
0
    if (result < 0) {
78
0
      gnutls_assert();
79
0
      gnutls_free(*crl);
80
0
      return result;
81
0
    }
82
0
    return 0; /* success */
83
0
  }
84
0
  return GNUTLS_E_MEMORY_ERROR;
85
0
}
86
87
/**
88
 * gnutls_x509_crl_deinit:
89
 * @crl: The data to be deinitialized
90
 *
91
 * This function will deinitialize a CRL structure.
92
 **/
93
void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl)
94
0
{
95
0
  if (!crl)
96
0
    return;
97
98
0
  if (crl->crl)
99
0
    asn1_delete_structure(&crl->crl);
100
0
  gnutls_free(crl->der.data);
101
102
0
  gnutls_free(crl);
103
0
}
104
105
/**
106
 * gnutls_x509_crl_import:
107
 * @crl: The data to store the parsed CRL.
108
 * @data: The DER or PEM encoded CRL.
109
 * @format: One of DER or PEM
110
 *
111
 * This function will convert the given DER or PEM encoded CRL
112
 * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'.
113
 *
114
 * If the CRL is PEM encoded it should have a header of "X509 CRL".
115
 *
116
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
117
 *   negative error value.
118
 **/
119
int
120
gnutls_x509_crl_import(gnutls_x509_crl_t crl,
121
           const gnutls_datum_t * data,
122
           gnutls_x509_crt_fmt_t format)
123
0
{
124
0
  int result = 0;
125
126
0
  if (crl == NULL) {
127
0
    gnutls_assert();
128
0
    return GNUTLS_E_INVALID_REQUEST;
129
0
  }
130
131
0
  _gnutls_free_datum(&crl->der);
132
133
  /* If the CRL is in PEM format then decode it
134
   */
135
0
  if (format == GNUTLS_X509_FMT_PEM) {
136
0
    result =
137
0
        _gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
138
0
             &crl->der);
139
140
0
    if (result < 0) {
141
0
      gnutls_assert();
142
0
      return result;
143
0
    }
144
0
  } else {
145
0
    result = _gnutls_set_datum(&crl->der, data->data, data->size);
146
0
    if (result < 0) {
147
0
      gnutls_assert();
148
0
      return result;
149
0
    }
150
0
  }
151
152
0
  if (crl->expanded) {
153
0
    result = crl_reinit(crl);
154
0
    if (result < 0) {
155
0
      gnutls_assert();
156
0
      goto cleanup;
157
0
    }
158
0
  }
159
0
  crl->expanded = 1;
160
161
0
  result =
162
0
      _asn1_strict_der_decode(&crl->crl, crl->der.data, crl->der.size,
163
0
            NULL);
164
0
  if (result != ASN1_SUCCESS) {
165
0
    result = _gnutls_asn2err(result);
166
0
    gnutls_assert();
167
0
    goto cleanup;
168
0
  }
169
170
0
  result = _gnutls_x509_get_raw_field2(crl->crl, &crl->der,
171
0
               "tbsCertList.issuer.rdnSequence",
172
0
               &crl->raw_issuer_dn);
173
0
  if (result < 0) {
174
0
    gnutls_assert();
175
0
    goto cleanup;
176
0
  }
177
178
0
  return 0;
179
180
0
 cleanup:
181
0
  _gnutls_free_datum(&crl->der);
182
0
  return result;
183
0
}
184
185
/**
186
 * gnutls_x509_crl_get_issuer_dn:
187
 * @crl: should contain a gnutls_x509_crl_t type
188
 * @buf: a pointer to a structure to hold the peer's name (may be null)
189
 * @sizeof_buf: initially holds the size of @buf
190
 *
191
 * This function will copy the name of the CRL issuer in the provided
192
 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
193
 * described in RFC4514. The output string will be ASCII or UTF-8
194
 * encoded, depending on the certificate data.
195
 *
196
 * If buf is %NULL then only the size will be filled.
197
 *
198
 * This function does not output a fully RFC4514 compliant string, if
199
 * that is required see gnutls_x509_crl_get_issuer_dn3().
200
 *
201
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
202
 * not long enough, and in that case the sizeof_buf will be updated
203
 * with the required size, and 0 on success.
204
 *
205
 **/
206
int
207
gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl_t crl, char *buf,
208
            size_t *sizeof_buf)
209
0
{
210
0
  if (crl == NULL) {
211
0
    gnutls_assert();
212
0
    return GNUTLS_E_INVALID_REQUEST;
213
0
  }
214
215
0
  return _gnutls_x509_parse_dn(crl->crl,
216
0
             "tbsCertList.issuer.rdnSequence",
217
0
             buf, sizeof_buf,
218
0
             GNUTLS_X509_DN_FLAG_COMPAT);
219
0
}
220
221
/**
222
 * gnutls_x509_crl_get_issuer_dn_by_oid:
223
 * @crl: should contain a gnutls_x509_crl_t type
224
 * @oid: holds an Object Identified in null terminated string
225
 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
226
 * @raw_flag: If non-zero returns the raw DER data of the DN part.
227
 * @buf: a pointer to a structure to hold the peer's name (may be null)
228
 * @sizeof_buf: initially holds the size of @buf
229
 *
230
 * This function will extract the part of the name of the CRL issuer
231
 * specified by the given OID. The output will be encoded as described
232
 * in RFC4514. The output string will be ASCII or UTF-8 encoded,
233
 * depending on the certificate data.
234
 *
235
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
236
 * If raw flag is (0), this function will only return known OIDs as
237
 * text. Other OIDs will be DER encoded, as described in RFC4514 -- in
238
 * hex format with a '#' prefix.  You can check about known OIDs
239
 * using gnutls_x509_dn_oid_known().
240
 *
241
 * If buf is null then only the size will be filled.
242
 *
243
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
244
 * not long enough, and in that case the sizeof_buf will be updated
245
 * with the required size, and 0 on success.
246
 **/
247
int
248
gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl_t crl,
249
             const char *oid, unsigned indx,
250
             unsigned int raw_flag, void *buf,
251
             size_t *sizeof_buf)
252
0
{
253
0
  gnutls_datum_t td;
254
0
  int ret;
255
256
0
  if (crl == NULL) {
257
0
    gnutls_assert();
258
0
    return GNUTLS_E_INVALID_REQUEST;
259
0
  }
260
261
0
  ret = _gnutls_x509_parse_dn_oid(crl->crl,
262
0
          "tbsCertList.issuer.rdnSequence",
263
0
          oid, indx, raw_flag, &td);
264
0
  if (ret < 0)
265
0
    return gnutls_assert_val(ret);
266
267
0
  return _gnutls_strdatum_to_buf(&td, buf, sizeof_buf);
268
0
}
269
270
/**
271
 * gnutls_x509_crl_get_dn_oid:
272
 * @crl: should contain a gnutls_x509_crl_t type
273
 * @indx: Specifies which DN OID to send. Use (0) to get the first one.
274
 * @oid: a pointer to store the OID (may be null)
275
 * @sizeof_oid: initially holds the size of 'oid'
276
 *
277
 * This function will extract the requested OID of the name of the CRL
278
 * issuer, specified by the given index.
279
 *
280
 * If oid is null then only the size will be filled.
281
 *
282
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
283
 * not long enough, and in that case the sizeof_oid will be updated
284
 * with the required size.  On success 0 is returned.
285
 **/
286
int
287
gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,
288
         unsigned indx, void *oid, size_t *sizeof_oid)
289
0
{
290
0
  if (crl == NULL) {
291
0
    gnutls_assert();
292
0
    return GNUTLS_E_INVALID_REQUEST;
293
0
  }
294
295
0
  return _gnutls_x509_get_dn_oid(crl->crl,
296
0
               "tbsCertList.issuer.rdnSequence",
297
0
               indx, oid, sizeof_oid);
298
0
}
299
300
/**
301
 * gnutls_x509_crl_get_issuer_dn2:
302
 * @crl: should contain a #gnutls_x509_crl_t type
303
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
304
 *
305
 * This function will allocate buffer and copy the name of the CRL issuer.
306
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
307
 * described in RFC4514. The output string will be ASCII or UTF-8
308
 * encoded, depending on the certificate data.
309
 *
310
 * This function does not output a fully RFC4514 compliant string, if
311
 * that is required see gnutls_x509_crl_get_issuer_dn3().
312
 *
313
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
314
 *   negative error value.
315
 *
316
 * Since: 3.1.10
317
 **/
318
int gnutls_x509_crl_get_issuer_dn2(gnutls_x509_crl_t crl, gnutls_datum_t * dn)
319
0
{
320
0
  if (crl == NULL) {
321
0
    gnutls_assert();
322
0
    return GNUTLS_E_INVALID_REQUEST;
323
0
  }
324
325
0
  return _gnutls_x509_get_dn(crl->crl,
326
0
           "tbsCertList.issuer.rdnSequence",
327
0
           dn, GNUTLS_X509_DN_FLAG_COMPAT);
328
0
}
329
330
/**
331
 * gnutls_x509_crl_get_issuer_dn3:
332
 * @crl: should contain a #gnutls_x509_crl_t type
333
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
334
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
335
 *
336
 * This function will allocate buffer and copy the name of the CRL issuer.
337
 * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
338
 * described in RFC4514. The output string will be ASCII or UTF-8
339
 * encoded, depending on the certificate data.
340
 *
341
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
342
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
343
 * which was not not fully RFC4514-compliant.
344
 *
345
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
346
 *   negative error value.
347
 *
348
 * Since: 3.5.7
349
 **/
350
int
351
gnutls_x509_crl_get_issuer_dn3(gnutls_x509_crl_t crl, gnutls_datum_t * dn,
352
             unsigned flags)
353
0
{
354
0
  if (crl == NULL) {
355
0
    gnutls_assert();
356
0
    return GNUTLS_E_INVALID_REQUEST;
357
0
  }
358
359
0
  return _gnutls_x509_get_dn(crl->crl,
360
0
           "tbsCertList.issuer.rdnSequence", dn, flags);
361
0
}
362
363
/**
364
 * gnutls_x509_crl_get_signature_algorithm:
365
 * @crl: should contain a #gnutls_x509_crl_t type
366
 *
367
 * This function will return a value of the #gnutls_sign_algorithm_t
368
 * enumeration that is the signature algorithm.
369
 *
370
 * Since 3.6.0 this function never returns a negative error code.
371
 * Error cases and unknown/unsupported signature algorithms are
372
 * mapped to %GNUTLS_SIGN_UNKNOWN.
373
 *
374
 * Returns: a #gnutls_sign_algorithm_t value
375
 **/
376
int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl)
377
0
{
378
0
  return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(crl->crl,
379
0
                     "signatureAlgorithm"));
380
0
}
381
382
/**
383
 * gnutls_x509_crl_get_signature_oid:
384
 * @crl: should contain a #gnutls_x509_crl_t type
385
 * @oid: a pointer to a buffer to hold the OID (may be null)
386
 * @oid_size: initially holds the size of @oid
387
 *
388
 * This function will return the OID of the signature algorithm
389
 * that has been used to sign this CRL. This is function
390
 * is useful in the case gnutls_x509_crl_get_signature_algorithm()
391
 * returned %GNUTLS_SIGN_UNKNOWN.
392
 *
393
 * Returns: zero or a negative error code on error.
394
 *
395
 * Since: 3.5.0
396
 **/
397
int gnutls_x509_crl_get_signature_oid(gnutls_x509_crl_t crl, char *oid,
398
              size_t *oid_size)
399
0
{
400
0
  char str[MAX_OID_SIZE];
401
0
  int len, result, ret;
402
0
  gnutls_datum_t out;
403
404
0
  len = sizeof(str);
405
0
  result =
406
0
      asn1_read_value(crl->crl, "signatureAlgorithm.algorithm", str,
407
0
          &len);
408
0
  if (result != ASN1_SUCCESS) {
409
0
    gnutls_assert();
410
0
    return _gnutls_asn2err(result);
411
0
  }
412
413
0
  out.data = (void *)str;
414
0
  out.size = len;
415
416
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
417
0
  if (ret < 0) {
418
0
    gnutls_assert();
419
0
    return ret;
420
0
  }
421
422
0
  return 0;
423
0
}
424
425
/**
426
 * gnutls_x509_crl_get_signature:
427
 * @crl: should contain a gnutls_x509_crl_t type
428
 * @sig: a pointer where the signature part will be copied (may be null).
429
 * @sizeof_sig: initially holds the size of @sig
430
 *
431
 * This function will extract the signature field of a CRL.
432
 *
433
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
434
 *   negative error value. 
435
 **/
436
int
437
gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
438
            char *sig, size_t *sizeof_sig)
439
0
{
440
0
  int result;
441
0
  unsigned int bits;
442
0
  int len;
443
444
0
  if (crl == NULL) {
445
0
    gnutls_assert();
446
0
    return GNUTLS_E_INVALID_REQUEST;
447
0
  }
448
449
0
  len = 0;
450
0
  result = asn1_read_value(crl->crl, "signature", NULL, &len);
451
452
0
  if (result != ASN1_MEM_ERROR) {
453
0
    gnutls_assert();
454
0
    return _gnutls_asn2err(result);
455
0
  }
456
457
0
  bits = len;
458
0
  if (bits % 8 != 0) {
459
0
    gnutls_assert();
460
0
    return GNUTLS_E_CERTIFICATE_ERROR;
461
0
  }
462
463
0
  len = bits / 8;
464
465
0
  if (*sizeof_sig < (unsigned)len) {
466
0
    *sizeof_sig = bits / 8;
467
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
468
0
  }
469
470
0
  result = asn1_read_value(crl->crl, "signature", sig, &len);
471
0
  if (result != ASN1_SUCCESS) {
472
0
    gnutls_assert();
473
0
    return _gnutls_asn2err(result);
474
0
  }
475
476
0
  return 0;
477
0
}
478
479
/**
480
 * gnutls_x509_crl_get_version:
481
 * @crl: should contain a #gnutls_x509_crl_t type
482
 *
483
 * This function will return the version of the specified CRL.
484
 *
485
 * Returns: The version number, or a negative error code on error.
486
 **/
487
int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl)
488
0
{
489
0
  if (crl == NULL) {
490
0
    gnutls_assert();
491
0
    return GNUTLS_E_INVALID_REQUEST;
492
0
  }
493
494
0
  return _gnutls_x509_get_version(crl->crl, "tbsCertList.version");
495
0
}
496
497
/**
498
 * gnutls_x509_crl_get_this_update:
499
 * @crl: should contain a #gnutls_x509_crl_t type
500
 *
501
 * This function will return the time this CRL was issued.
502
 *
503
 * Returns: when the CRL was issued, or (time_t)-1 on error.
504
 **/
505
time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl)
506
0
{
507
0
  if (crl == NULL) {
508
0
    gnutls_assert();
509
0
    return (time_t) - 1;
510
0
  }
511
512
0
  return _gnutls_x509_get_time(crl->crl, "tbsCertList.thisUpdate", 0);
513
0
}
514
515
/**
516
 * gnutls_x509_crl_get_next_update:
517
 * @crl: should contain a #gnutls_x509_crl_t type
518
 *
519
 * This function will return the time the next CRL will be issued.
520
 * This field is optional in a CRL so it might be normal to get an
521
 * error instead.
522
 *
523
 * Returns: when the next CRL will be issued, or (time_t)-1 on error.
524
 **/
525
time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl)
526
0
{
527
0
  if (crl == NULL) {
528
0
    gnutls_assert();
529
0
    return (time_t) - 1;
530
0
  }
531
532
0
  return _gnutls_x509_get_time(crl->crl, "tbsCertList.nextUpdate", 0);
533
0
}
534
535
/**
536
 * gnutls_x509_crl_get_crt_count:
537
 * @crl: should contain a #gnutls_x509_crl_t type
538
 *
539
 * This function will return the number of revoked certificates in the
540
 * given CRL.
541
 *
542
 * Returns: number of certificates, a negative error code on failure.
543
 **/
544
int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl)
545
0
{
546
547
0
  int count, result;
548
549
0
  if (crl == NULL) {
550
0
    gnutls_assert();
551
0
    return GNUTLS_E_INVALID_REQUEST;
552
0
  }
553
554
0
  result =
555
0
      asn1_number_of_elements(crl->crl,
556
0
            "tbsCertList.revokedCertificates", &count);
557
558
0
  if (result != ASN1_SUCCESS) {
559
0
    gnutls_assert();
560
0
    return 0; /* no certificates */
561
0
  }
562
563
0
  return count;
564
0
}
565
566
/**
567
 * gnutls_x509_crl_get_crt_serial:
568
 * @crl: should contain a #gnutls_x509_crl_t type
569
 * @indx: the index of the certificate to extract (starting from 0)
570
 * @serial: where the serial number will be copied
571
 * @serial_size: initially holds the size of serial
572
 * @t: if non null, will hold the time this certificate was revoked
573
 *
574
 * This function will retrieve the serial number of the specified, by
575
 * the index, revoked certificate.
576
 *
577
 * Note that this function will have performance issues in large sequences
578
 * of revoked certificates. In that case use gnutls_x509_crl_iter_crt_serial().
579
 *
580
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
581
 *   negative error value.
582
 **/
583
int
584
gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl, unsigned indx,
585
             unsigned char *serial,
586
             size_t *serial_size, time_t * t)
587
0
{
588
589
0
  int result, _serial_size;
590
0
  char serial_name[MAX_NAME_SIZE];
591
0
  char date_name[MAX_NAME_SIZE];
592
593
0
  if (crl == NULL) {
594
0
    gnutls_assert();
595
0
    return GNUTLS_E_INVALID_REQUEST;
596
0
  }
597
598
0
  snprintf(serial_name, sizeof(serial_name),
599
0
     "tbsCertList.revokedCertificates.?%u.userCertificate",
600
0
     indx + 1);
601
0
  snprintf(date_name, sizeof(date_name),
602
0
     "tbsCertList.revokedCertificates.?%u.revocationDate",
603
0
     indx + 1);
604
605
0
  _serial_size = *serial_size;
606
0
  result = asn1_read_value(crl->crl, serial_name, serial, &_serial_size);
607
608
0
  *serial_size = _serial_size;
609
0
  if (result != ASN1_SUCCESS) {
610
0
    gnutls_assert();
611
0
    if (result == ASN1_ELEMENT_NOT_FOUND)
612
0
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
613
0
    return _gnutls_asn2err(result);
614
0
  }
615
616
0
  if (t) {
617
0
    *t = _gnutls_x509_get_time(crl->crl, date_name, 0);
618
0
  }
619
620
0
  return 0;
621
0
}
622
623
/**
624
 * gnutls_x509_crl_iter_deinit:
625
 * @iter: The iterator to be deinitialized
626
 *
627
 * This function will deinitialize an iterator type.
628
 **/
629
void gnutls_x509_crl_iter_deinit(gnutls_x509_crl_iter_t iter)
630
0
{
631
0
  if (!iter)
632
0
    return;
633
634
0
  gnutls_free(iter);
635
0
}
636
637
/**
638
 * gnutls_x509_crl_iter_crt_serial:
639
 * @crl: should contain a #gnutls_x509_crl_t type
640
 * @iter: A pointer to an iterator (initially the iterator should be %NULL)
641
 * @serial: where the serial number will be copied
642
 * @serial_size: initially holds the size of serial
643
 * @t: if non null, will hold the time this certificate was revoked
644
 *
645
 * This function performs the same as gnutls_x509_crl_get_crt_serial(),
646
 * but reads sequentially and keeps state in the iterator 
647
 * between calls. That allows it to provide better performance in sequences 
648
 * with many elements (50000+).
649
 *
650
 * When past the last element is accessed %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
651
 * is returned and the iterator is reset.
652
 *
653
 * After use, the iterator must be deinitialized using gnutls_x509_crl_iter_deinit().
654
 *
655
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
656
 *   negative error value.
657
 **/
658
int
659
gnutls_x509_crl_iter_crt_serial(gnutls_x509_crl_t crl,
660
        gnutls_x509_crl_iter_t * iter,
661
        unsigned char *serial,
662
        size_t *serial_size, time_t * t)
663
0
{
664
665
0
  int result, _serial_size;
666
0
  char serial_name[MAX_NAME_SIZE];
667
0
  char date_name[MAX_NAME_SIZE];
668
669
0
  if (crl == NULL || iter == NULL) {
670
0
    gnutls_assert();
671
0
    return GNUTLS_E_INVALID_REQUEST;
672
0
  }
673
674
0
  if (*iter == NULL) {
675
0
    *iter = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_iter));
676
0
    if (*iter == NULL)
677
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
678
0
  }
679
680
0
  if ((*iter)->rcache == NULL) {
681
0
    (*iter)->rcache =
682
0
        asn1_find_node(crl->crl,
683
0
           "tbsCertList.revokedCertificates.?1");
684
0
    (*iter)->rcache_idx = 1;
685
0
  } else {
686
0
    snprintf(serial_name, sizeof(serial_name),
687
0
       "?%u", (*iter)->rcache_idx);
688
0
    (*iter)->rcache = asn1_find_node((*iter)->rcache, serial_name);
689
0
  }
690
0
  if ((*iter)->rcache == NULL) {
691
    /* reset */
692
0
    (*iter)->rcache = NULL;
693
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
694
0
  }
695
696
0
  snprintf(serial_name, sizeof(serial_name),
697
0
     "?%u.userCertificate", (*iter)->rcache_idx);
698
699
0
  _serial_size = *serial_size;
700
0
  result =
701
0
      asn1_read_value((*iter)->rcache, serial_name, serial,
702
0
          &_serial_size);
703
704
0
  *serial_size = _serial_size;
705
0
  if (result != ASN1_SUCCESS) {
706
0
    gnutls_assert();
707
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
708
      /* reset */
709
0
      (*iter)->rcache = NULL;
710
0
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
711
0
    }
712
0
    return _gnutls_asn2err(result);
713
0
  }
714
715
0
  if (t) {
716
0
    snprintf(date_name, sizeof(date_name),
717
0
       "?%u.revocationDate", (*iter)->rcache_idx);
718
0
    *t = _gnutls_x509_get_time((*iter)->rcache, date_name, 0);
719
0
  }
720
721
0
  (*iter)->rcache_idx++;
722
723
0
  return 0;
724
0
}
725
726
/**
727
 * gnutls_x509_crl_get_raw_issuer_dn:
728
 * @crl: should contain a gnutls_x509_crl_t type
729
 * @dn: will hold the starting point of the DN
730
 *
731
 * This function will return a pointer to the DER encoded DN structure
732
 * and the length.
733
 *
734
 * Returns: a negative error code on error, and (0) on success.
735
 *
736
 * Since: 2.12.0
737
 **/
738
int
739
gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl, gnutls_datum_t * dn)
740
0
{
741
0
  if (crl->raw_issuer_dn.size != 0) {
742
0
    return _gnutls_set_datum(dn, crl->raw_issuer_dn.data,
743
0
           crl->raw_issuer_dn.size);
744
0
  } else {
745
0
    return _gnutls_x509_get_raw_field(crl->crl,
746
0
              "tbsCertList.issuer.rdnSequence",
747
0
              dn);
748
0
  }
749
0
}
750
751
/**
752
 * gnutls_x509_crl_export:
753
 * @crl: Holds the revocation list
754
 * @format: the format of output params. One of PEM or DER.
755
 * @output_data: will contain a private key PEM or DER encoded
756
 * @output_data_size: holds the size of output_data (and will
757
 *   be replaced by the actual size of parameters)
758
 *
759
 * This function will export the revocation list to DER or PEM format.
760
 *
761
 * If the buffer provided is not long enough to hold the output, then
762
 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
763
 *
764
 * If the structure is PEM encoded, it will have a header
765
 * of "BEGIN X509 CRL".
766
 *
767
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
768
 *   negative error value.
769
 **/
770
int
771
gnutls_x509_crl_export(gnutls_x509_crl_t crl,
772
           gnutls_x509_crt_fmt_t format, void *output_data,
773
           size_t *output_data_size)
774
0
{
775
0
  if (crl == NULL) {
776
0
    gnutls_assert();
777
0
    return GNUTLS_E_INVALID_REQUEST;
778
0
  }
779
780
0
  return _gnutls_x509_export_int(crl->crl, format, PEM_CRL,
781
0
               output_data, output_data_size);
782
0
}
783
784
/**
785
 * gnutls_x509_crl_export2:
786
 * @crl: Holds the revocation list
787
 * @format: the format of output params. One of PEM or DER.
788
 * @out: will contain a private key PEM or DER encoded
789
 *
790
 * This function will export the revocation list to DER or PEM format.
791
 *
792
 * The output buffer is allocated using gnutls_malloc().
793
 *
794
 * If the structure is PEM encoded, it will have a header
795
 * of "BEGIN X509 CRL".
796
 *
797
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
798
 *   negative error value.
799
 *
800
 * Since 3.1.3
801
 **/
802
int
803
gnutls_x509_crl_export2(gnutls_x509_crl_t crl,
804
      gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
805
0
{
806
0
  if (crl == NULL) {
807
0
    gnutls_assert();
808
0
    return GNUTLS_E_INVALID_REQUEST;
809
0
  }
810
811
0
  return _gnutls_x509_export_int2(crl->crl, format, PEM_CRL, out);
812
0
}
813
814
/*-
815
 * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t type
816
 * @dest: The data where to copy
817
 * @src: The data to be copied
818
 *
819
 * This function will copy an X.509 certificate structure.
820
 *
821
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
822
 *   negative error value.
823
 -*/
824
int _gnutls_x509_crl_cpy(gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
825
0
{
826
0
  int ret;
827
0
  gnutls_datum_t tmp;
828
829
0
  ret = gnutls_x509_crl_export2(src, GNUTLS_X509_FMT_DER, &tmp);
830
0
  if (ret < 0)
831
0
    return gnutls_assert_val(ret);
832
833
0
  ret = gnutls_x509_crl_import(dest, &tmp, GNUTLS_X509_FMT_DER);
834
835
0
  gnutls_free(tmp.data);
836
837
0
  if (ret < 0) {
838
0
    gnutls_assert();
839
0
    return ret;
840
0
  }
841
842
0
  return 0;
843
844
0
}
845
846
static int
847
_get_authority_key_id(gnutls_x509_crl_t cert, asn1_node * c2,
848
          unsigned int *critical)
849
0
{
850
0
  int ret;
851
0
  gnutls_datum_t id;
852
853
0
  *c2 = NULL;
854
855
0
  if (cert == NULL) {
856
0
    gnutls_assert();
857
0
    return GNUTLS_E_INVALID_REQUEST;
858
0
  }
859
860
0
  if ((ret =
861
0
       _gnutls_x509_crl_get_extension(cert, "2.5.29.35", 0, &id,
862
0
              critical)) < 0) {
863
0
    return gnutls_assert_val(ret);
864
0
  }
865
866
0
  if (id.size == 0 || id.data == NULL) {
867
0
    gnutls_assert();
868
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
869
0
  }
870
871
0
  ret = asn1_create_element
872
0
      (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", c2);
873
0
  if (ret != ASN1_SUCCESS) {
874
0
    gnutls_assert();
875
0
    _gnutls_free_datum(&id);
876
0
    return _gnutls_asn2err(ret);
877
0
  }
878
879
0
  ret = _asn1_strict_der_decode(c2, id.data, id.size, NULL);
880
0
  _gnutls_free_datum(&id);
881
882
0
  if (ret != ASN1_SUCCESS) {
883
0
    gnutls_assert();
884
0
    asn1_delete_structure(c2);
885
0
    return _gnutls_asn2err(ret);
886
0
  }
887
888
0
  return 0;
889
0
}
890
891
/**
892
 * gnutls_x509_crl_get_authority_key_gn_serial:
893
 * @crl: should contain a #gnutls_x509_crl_t type
894
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
895
 * @alt: is the place where the alternative name will be copied to
896
 * @alt_size: holds the size of alt.
897
 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
898
 * @serial: buffer to store the serial number (may be null)
899
 * @serial_size: Holds the size of the serial field (may be null)
900
 * @critical: will be non-zero if the extension is marked as critical (may be null)
901
 *
902
 * This function will return the X.509 authority key
903
 * identifier when stored as a general name (authorityCertIssuer) 
904
 * and serial number.
905
 *
906
 * Because more than one general names might be stored
907
 * @seq can be used as a counter to request them all until 
908
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
909
 *
910
 * Returns: Returns 0 on success, or an error code.
911
 *
912
 * Since: 3.0
913
 **/
914
int
915
gnutls_x509_crl_get_authority_key_gn_serial(gnutls_x509_crl_t crl,
916
              unsigned int seq,
917
              void *alt,
918
              size_t *alt_size,
919
              unsigned int *alt_type,
920
              void *serial,
921
              size_t *serial_size,
922
              unsigned int *critical)
923
0
{
924
0
  int ret, result, len;
925
0
  asn1_node c2;
926
927
0
  ret = _get_authority_key_id(crl, &c2, critical);
928
0
  if (ret < 0)
929
0
    return gnutls_assert_val(ret);
930
931
0
  ret =
932
0
      _gnutls_parse_general_name(c2, "authorityCertIssuer", seq, alt,
933
0
               alt_size, alt_type, 0);
934
0
  if (ret < 0) {
935
0
    ret = gnutls_assert_val(ret);
936
0
    goto fail;
937
0
  }
938
939
0
  if (serial) {
940
0
    len = *serial_size;
941
0
    result =
942
0
        asn1_read_value(c2, "authorityCertSerialNumber",
943
0
            serial, &len);
944
945
0
    *serial_size = len;
946
947
0
    if (result < 0) {
948
0
      ret = _gnutls_asn2err(result);
949
0
      goto fail;
950
0
    }
951
952
0
  }
953
954
0
  ret = 0;
955
956
0
 fail:
957
0
  asn1_delete_structure(&c2);
958
959
0
  return ret;
960
0
}
961
962
/**
963
 * gnutls_x509_crl_get_authority_key_id:
964
 * @crl: should contain a #gnutls_x509_crl_t type
965
 * @id: The place where the identifier will be copied
966
 * @id_size: Holds the size of the result field.
967
 * @critical: will be non-zero if the extension is marked as critical
968
 *   (may be null)
969
 *
970
 * This function will return the CRL authority's key identifier.  This
971
 * is obtained by the X.509 Authority Key identifier extension field
972
 * (2.5.29.35).  Note that this function 
973
 * only returns the keyIdentifier field of the extension and
974
 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
975
 * the name and serial number of the certificate. In that case
976
 * gnutls_x509_crl_get_authority_key_gn_serial() may be used.
977
 *
978
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
979
 *   negative error code in case of an error.
980
 *
981
 * Since: 2.8.0
982
 **/
983
int
984
gnutls_x509_crl_get_authority_key_id(gnutls_x509_crl_t crl, void *id,
985
             size_t *id_size, unsigned int *critical)
986
0
{
987
0
  int result, len, ret;
988
0
  asn1_node c2;
989
990
0
  ret = _get_authority_key_id(crl, &c2, critical);
991
0
  if (ret < 0)
992
0
    return gnutls_assert_val(ret);
993
994
0
  len = *id_size;
995
0
  result = asn1_read_value(c2, "keyIdentifier", id, &len);
996
997
0
  *id_size = len;
998
0
  asn1_delete_structure(&c2);
999
1000
0
  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
1001
0
    return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1002
1003
0
  if (result != ASN1_SUCCESS) {
1004
0
    gnutls_assert();
1005
0
    return _gnutls_asn2err(result);
1006
0
  }
1007
1008
0
  return 0;
1009
0
}
1010
1011
/**
1012
 * gnutls_x509_crl_get_number:
1013
 * @crl: should contain a #gnutls_x509_crl_t type
1014
 * @ret: The place where the number will be copied
1015
 * @ret_size: Holds the size of the result field.
1016
 * @critical: will be non-zero if the extension is marked as critical
1017
 *   (may be null)
1018
 *
1019
 * This function will return the CRL number extension.  This is
1020
 * obtained by the CRL Number extension field (2.5.29.20).
1021
 *
1022
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1023
 *   negative error code in case of an error.
1024
 *
1025
 * Since: 2.8.0
1026
 **/
1027
int
1028
gnutls_x509_crl_get_number(gnutls_x509_crl_t crl, void *ret,
1029
         size_t *ret_size, unsigned int *critical)
1030
0
{
1031
0
  int result;
1032
0
  gnutls_datum_t id;
1033
1034
0
  if (crl == NULL) {
1035
0
    gnutls_assert();
1036
0
    return GNUTLS_E_INVALID_REQUEST;
1037
0
  }
1038
1039
0
  if (ret)
1040
0
    memset(ret, 0, *ret_size);
1041
0
  else
1042
0
    *ret_size = 0;
1043
1044
0
  if ((result =
1045
0
       _gnutls_x509_crl_get_extension(crl, "2.5.29.20", 0, &id,
1046
0
              critical)) < 0) {
1047
0
    return result;
1048
0
  }
1049
1050
0
  if (id.size == 0 || id.data == NULL) {
1051
0
    gnutls_assert();
1052
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1053
0
  }
1054
1055
0
  result =
1056
0
      _gnutls_x509_ext_extract_number(ret, ret_size, id.data, id.size);
1057
1058
0
  _gnutls_free_datum(&id);
1059
1060
0
  if (result < 0) {
1061
0
    gnutls_assert();
1062
0
    return result;
1063
0
  }
1064
1065
0
  return 0;
1066
0
}
1067
1068
/**
1069
 * gnutls_x509_crl_get_extension_oid:
1070
 * @crl: should contain a #gnutls_x509_crl_t type
1071
 * @indx: Specifies which extension OID to send, use (0) to get the first one.
1072
 * @oid: a pointer to store the OID (may be null)
1073
 * @sizeof_oid: initially holds the size of @oid
1074
 *
1075
 * This function will return the requested extension OID in the CRL.
1076
 * The extension OID will be stored as a string in the provided
1077
 * buffer.
1078
 *
1079
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1080
 *   negative error code in case of an error.  If your have reached the
1081
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1082
 *   will be returned.
1083
 *
1084
 * Since: 2.8.0
1085
 **/
1086
int
1087
gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl, unsigned indx,
1088
          void *oid, size_t *sizeof_oid)
1089
0
{
1090
0
  int result;
1091
1092
0
  if (crl == NULL) {
1093
0
    gnutls_assert();
1094
0
    return GNUTLS_E_INVALID_REQUEST;
1095
0
  }
1096
1097
0
  result = _gnutls_x509_crl_get_extension_oid(crl, indx, oid, sizeof_oid);
1098
0
  if (result < 0) {
1099
0
    return result;
1100
0
  }
1101
1102
0
  return 0;
1103
1104
0
}
1105
1106
/**
1107
 * gnutls_x509_crl_get_extension_info:
1108
 * @crl: should contain a #gnutls_x509_crl_t type
1109
 * @indx: Specifies which extension OID to send, use (0) to get the first one.
1110
 * @oid: a pointer to store the OID
1111
 * @sizeof_oid: initially holds the maximum size of @oid, on return
1112
 *   holds actual size of @oid.
1113
 * @critical: output variable with critical flag, may be NULL.
1114
 *
1115
 * This function will return the requested extension OID in the CRL,
1116
 * and the critical flag for it.  The extension OID will be stored as
1117
 * a string in the provided buffer.  Use
1118
 * gnutls_x509_crl_get_extension_data() to extract the data.
1119
 *
1120
 * If the buffer provided is not long enough to hold the output, then
1121
 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1122
 * returned.
1123
 *
1124
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1125
 *   negative error code in case of an error.  If your have reached the
1126
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1127
 *   will be returned.
1128
 *
1129
 * Since: 2.8.0
1130
 **/
1131
int
1132
gnutls_x509_crl_get_extension_info(gnutls_x509_crl_t crl, unsigned indx,
1133
           void *oid, size_t *sizeof_oid,
1134
           unsigned int *critical)
1135
0
{
1136
0
  int result;
1137
0
  char str_critical[10];
1138
0
  char name[MAX_NAME_SIZE];
1139
0
  int len;
1140
1141
0
  if (!crl) {
1142
0
    gnutls_assert();
1143
0
    return GNUTLS_E_INVALID_REQUEST;
1144
0
  }
1145
1146
0
  snprintf(name, sizeof(name),
1147
0
     "tbsCertList.crlExtensions.?%u.extnID", indx + 1);
1148
1149
0
  len = *sizeof_oid;
1150
0
  result = asn1_read_value(crl->crl, name, oid, &len);
1151
0
  *sizeof_oid = len;
1152
1153
0
  if (result == ASN1_ELEMENT_NOT_FOUND)
1154
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1155
0
  else if (result != ASN1_SUCCESS) {
1156
0
    gnutls_assert();
1157
0
    return _gnutls_asn2err(result);
1158
0
  }
1159
1160
0
  snprintf(name, sizeof(name),
1161
0
     "tbsCertList.crlExtensions.?%u.critical", indx + 1);
1162
0
  len = sizeof(str_critical);
1163
0
  result = asn1_read_value(crl->crl, name, str_critical, &len);
1164
0
  if (result != ASN1_SUCCESS) {
1165
0
    gnutls_assert();
1166
0
    return _gnutls_asn2err(result);
1167
0
  }
1168
1169
0
  if (critical) {
1170
0
    if (str_critical[0] == 'T')
1171
0
      *critical = 1;
1172
0
    else
1173
0
      *critical = 0;
1174
0
  }
1175
1176
0
  return 0;
1177
1178
0
}
1179
1180
/**
1181
 * gnutls_x509_crl_get_extension_data:
1182
 * @crl: should contain a #gnutls_x509_crl_t type
1183
 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1184
 * @data: a pointer to a structure to hold the data (may be null)
1185
 * @sizeof_data: initially holds the size of @oid
1186
 *
1187
 * This function will return the requested extension data in the CRL.
1188
 * The extension data will be stored as a string in the provided
1189
 * buffer.
1190
 *
1191
 * Use gnutls_x509_crl_get_extension_info() to extract the OID and
1192
 * critical flag.  Use gnutls_x509_crl_get_extension_info() instead,
1193
 * if you want to get data indexed by the extension OID rather than
1194
 * sequence.
1195
 *
1196
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1197
 *   negative error code in case of an error.  If your have reached the
1198
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1199
 *   will be returned.
1200
 *
1201
 * Since: 2.8.0
1202
 **/
1203
int
1204
gnutls_x509_crl_get_extension_data(gnutls_x509_crl_t crl, unsigned indx,
1205
           void *data, size_t *sizeof_data)
1206
0
{
1207
0
  int result, len;
1208
0
  char name[MAX_NAME_SIZE];
1209
1210
0
  if (!crl) {
1211
0
    gnutls_assert();
1212
0
    return GNUTLS_E_INVALID_REQUEST;
1213
0
  }
1214
1215
0
  snprintf(name, sizeof(name),
1216
0
     "tbsCertList.crlExtensions.?%u.extnValue", indx + 1);
1217
1218
0
  len = *sizeof_data;
1219
0
  result = asn1_read_value(crl->crl, name, data, &len);
1220
0
  *sizeof_data = len;
1221
1222
0
  if (result == ASN1_ELEMENT_NOT_FOUND)
1223
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1224
0
  else if (result < 0) {
1225
0
    gnutls_assert();
1226
0
    return _gnutls_asn2err(result);
1227
0
  }
1228
1229
0
  return 0;
1230
0
}
1231
1232
/**
1233
 * gnutls_x509_crl_list_import2:
1234
 * @crls: Will contain the parsed crl list.
1235
 * @size: It will contain the size of the list.
1236
 * @data: The CRL data.
1237
 * @format: One of DER or PEM.
1238
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1239
 *
1240
 * This function will convert the given CRL list
1241
 * to the native gnutls_x509_crl_t format. The output will be stored
1242
 * in @crls.  They will be automatically initialized.
1243
 *
1244
 * If the Certificate is PEM encoded it should have a header of "X509
1245
 * CRL".
1246
 *
1247
 * Returns: the number of certificates read or a negative error value.
1248
 *
1249
 * Since: 3.0
1250
 **/
1251
int
1252
gnutls_x509_crl_list_import2(gnutls_x509_crl_t ** crls,
1253
           unsigned int *size,
1254
           const gnutls_datum_t * data,
1255
           gnutls_x509_crt_fmt_t format, unsigned int flags)
1256
0
{
1257
0
  unsigned int init = 1024;
1258
0
  int ret;
1259
1260
0
  *crls = _gnutls_reallocarray(NULL, init, sizeof(gnutls_x509_crl_t));
1261
0
  if (*crls == NULL) {
1262
0
    gnutls_assert();
1263
0
    return GNUTLS_E_MEMORY_ERROR;
1264
0
  }
1265
1266
0
  ret =
1267
0
      gnutls_x509_crl_list_import(*crls, &init, data, format,
1268
0
          flags |
1269
0
          GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1270
0
  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
1271
0
    *crls = _gnutls_reallocarray_fast(*crls, init,
1272
0
              sizeof(gnutls_x509_crl_t));
1273
0
    if (*crls == NULL) {
1274
0
      gnutls_assert();
1275
0
      return GNUTLS_E_MEMORY_ERROR;
1276
0
    }
1277
1278
0
    ret =
1279
0
        gnutls_x509_crl_list_import(*crls, &init, data, format,
1280
0
            flags);
1281
0
  }
1282
1283
0
  if (ret < 0) {
1284
0
    gnutls_free(*crls);
1285
0
    *crls = NULL;
1286
0
    return ret;
1287
0
  }
1288
1289
0
  *size = init;
1290
0
  return 0;
1291
0
}
1292
1293
/**
1294
 * gnutls_x509_crl_list_import:
1295
 * @crls: Indicates where the parsed CRLs will be copied to. Must not be initialized.
1296
 * @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
1297
 * @data: The CRL data
1298
 * @format: One of DER or PEM.
1299
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1300
 *
1301
 * This function will convert the given CRL list
1302
 * to the native gnutls_x509_crl_t format. The output will be stored
1303
 * in @crls.  They will be automatically initialized.
1304
 *
1305
 * If the Certificate is PEM encoded it should have a header of "X509 CRL".
1306
 *
1307
 * Returns: the number of certificates read or a negative error value.
1308
 *
1309
 * Since: 3.0
1310
 **/
1311
int
1312
gnutls_x509_crl_list_import(gnutls_x509_crl_t * crls,
1313
          unsigned int *crl_max,
1314
          const gnutls_datum_t * data,
1315
          gnutls_x509_crt_fmt_t format, unsigned int flags)
1316
0
{
1317
0
  int size;
1318
0
  const char *ptr;
1319
0
  gnutls_datum_t tmp;
1320
0
  int ret, nocopy = 0;
1321
0
  unsigned int count = 0, j;
1322
1323
0
  if (format == GNUTLS_X509_FMT_DER) {
1324
0
    if (*crl_max < 1) {
1325
0
      *crl_max = 1;
1326
0
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
1327
0
    }
1328
1329
0
    count = 1;  /* import only the first one */
1330
1331
0
    ret = gnutls_x509_crl_init(&crls[0]);
1332
0
    if (ret < 0) {
1333
0
      gnutls_assert();
1334
0
      goto error;
1335
0
    }
1336
1337
0
    ret = gnutls_x509_crl_import(crls[0], data, format);
1338
0
    if (ret < 0) {
1339
0
      gnutls_assert();
1340
0
      goto error;
1341
0
    }
1342
1343
0
    *crl_max = 1;
1344
0
    return 1;
1345
0
  }
1346
1347
  /* move to the certificate
1348
   */
1349
0
  ptr = memmem(data->data, data->size,
1350
0
         PEM_CRL_SEP, sizeof(PEM_CRL_SEP) - 1);
1351
0
  if (ptr == NULL) {
1352
0
    gnutls_assert();
1353
0
    return GNUTLS_E_BASE64_DECODING_ERROR;
1354
0
  }
1355
1356
0
  count = 0;
1357
1358
0
  do {
1359
0
    if (count >= *crl_max) {
1360
0
      if (!
1361
0
          (flags &
1362
0
           GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) {
1363
0
        break;
1364
0
      } else if (nocopy == 0) {
1365
0
        for (j = 0; j < count; j++)
1366
0
          gnutls_x509_crl_deinit(crls[j]);
1367
0
        nocopy = 1;
1368
0
      }
1369
0
    }
1370
1371
0
    if (!nocopy) {
1372
0
      ret = gnutls_x509_crl_init(&crls[count]);
1373
0
      if (ret < 0) {
1374
0
        gnutls_assert();
1375
0
        goto error;
1376
0
      }
1377
1378
0
      tmp.data = (void *)ptr;
1379
0
      tmp.size = data->size - (ptr - (char *)data->data);
1380
0
      ret =
1381
0
          gnutls_x509_crl_import(crls[count], &tmp,
1382
0
               GNUTLS_X509_FMT_PEM);
1383
0
      if (ret < 0) {
1384
0
        gnutls_assert();
1385
0
        count++;
1386
0
        goto error;
1387
0
      }
1388
0
    }
1389
1390
    /* now we move ptr after the pem header 
1391
     */
1392
0
    ptr++;
1393
    /* find the next certificate (if any)
1394
     */
1395
0
    size = data->size - (ptr - (char *)data->data);
1396
1397
0
    if (size > 0) {
1398
0
      ptr =
1399
0
          memmem(ptr, size, PEM_CRL_SEP,
1400
0
           sizeof(PEM_CRL_SEP) - 1);
1401
0
    } else
1402
0
      ptr = NULL;
1403
1404
0
    count++;
1405
0
  }
1406
0
  while (ptr != NULL);
1407
1408
0
  *crl_max = count;
1409
1410
0
  if (nocopy == 0)
1411
0
    return count;
1412
0
  else
1413
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
1414
1415
0
 error:
1416
0
  for (j = 0; j < count; j++)
1417
0
    gnutls_x509_crl_deinit(crls[j]);
1418
0
  return ret;
1419
0
}