LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - crl.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 238 455 52.3 %
Date: 2020-10-30 04:50:48 Functions: 21 32 65.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14